libfilezilla
socket.hpp
Go to the documentation of this file.
1 #ifndef LIBFILEZILLA_SOCKET_HEADER
2 #define LIBFILEZILLA_SOCKET_HEADER
3 
11 #include "libfilezilla.hpp"
12 
13 #include "event_handler.hpp"
14 #include "iputils.hpp"
15 
16 #include <memory>
17 
18 #include <errno.h>
19 
21 struct sockaddr;
22 
23 namespace fz {
24 class thread_pool;
25 
34 {
40  connection_next = 0x1,
41 
46  connection = 0x2,
47 
52  read = 0x4,
53 
58  write = 0x8,
59 };
60 
61 inline bool operator&(socket_event_flag lhs, socket_event_flag rhs) {
62  return (static_cast<std::underlying_type_t<socket_event_flag>>(lhs) & static_cast<std::underlying_type_t<socket_event_flag>>(rhs)) != 0;
63 }
64 inline socket_event_flag operator|(socket_event_flag lhs, socket_event_flag rhs)
65 {
66  return static_cast<socket_event_flag>(static_cast<std::underlying_type_t<socket_event_flag>>(lhs) | static_cast<std::underlying_type_t<socket_event_flag>>(rhs));
67 }
68 inline socket_event_flag& operator|=(socket_event_flag& lhs, socket_event_flag rhs)
69 {
70  lhs = lhs | rhs;
71  return lhs;
72 }
73 
74 
83 class FZ_PUBLIC_SYMBOL socket_event_source
84 {
85 public:
86  virtual ~socket_event_source() = default;
87 
93  return root_;
94  }
95 
96 protected:
97  socket_event_source() = delete;
99  : root_(root)
100  {}
101 
102  socket_event_source* const root_{};
103 };
104 
106 struct socket_event_type;
107 
131 
133 struct hostaddress_event_type{};
134 
139 
146 void FZ_PUBLIC_SYMBOL remove_socket_events(event_handler * handler, socket_event_source const* const source);
147 
159 fz::socket_event_flag FZ_PUBLIC_SYMBOL change_socket_event_handler(event_handler * old_handler, event_handler * new_handler, socket_event_source const* const source, fz::socket_event_flag remove);
160 
162 class socket_thread;
163 
165 class FZ_PUBLIC_SYMBOL socket_base
166 {
167 public:
175  int set_buffer_sizes(int size_receive, int size_send);
176 
178  address_type address_family() const;
179 
185  std::string local_ip(bool strip_zone_index = false) const;
186 
192  int local_port(int& error) const;
193 
194  static std::string address_to_string(sockaddr const* addr, int addr_len, bool with_port = true, bool strip_zone_index = false);
195  static std::string address_to_string(char const* buf, int buf_len);
196 
202  bool bind(std::string const& address);
203 
204 #if FZ_WINDOWS
205  typedef intptr_t socket_t;
206 #else
207  typedef int socket_t;
208 #endif
209 
210 protected:
211  friend class socket_thread;
212 
213  socket_base(thread_pool& pool, event_handler* evt_handler, socket_event_source* ev_source);
214  virtual ~socket_base() = default;
215 
216  int close();
217 
218  // Note: Unlocks the lock.
219  void detach_thread(scoped_lock & l);
220 
221  thread_pool & thread_pool_;
222  event_handler* evt_handler_;
223 
224  socket_thread* socket_thread_{};
225 
226  socket_event_source * const ev_source_{};
227 
228  socket_t fd_{-1};
229 
230  unsigned int port_{};
231 
232  int family_;
233 
234  int buffer_sizes_[2];
235 };
236 
237 class socket;
238 
240 {
242  none,
243 
245  listening,
246 };
247 
249 class FZ_PUBLIC_SYMBOL socket_descriptor final
250 {
251 public:
252  socket_descriptor() = default;
254  explicit socket_descriptor(socket_base::socket_t fd) noexcept : fd_(fd) {}
255 
256  socket_descriptor(socket_descriptor const&) = delete;
257  socket_descriptor& operator=(socket_descriptor const&) = delete;
258 
259  socket_descriptor(socket_descriptor && rhs) noexcept { std::swap(fd_, rhs.fd_); }
260  socket_descriptor& operator=(socket_descriptor && rhs) noexcept {
261  std::swap(fd_, rhs.fd_);
262  return *this;
263  }
264 
265  socket_base::socket_t detach() {
266  socket_base::socket_t ret = fd_;
267  fd_ = -1;
268  return ret;
269  }
270 
271  explicit operator bool() const { return fd_ != -1; }
272 
273 private:
274  socket_base::socket_t fd_{-1};
275 };
276 
284 class FZ_PUBLIC_SYMBOL listen_socket final : public socket_base, public socket_event_source
285 {
286  friend class socket_base;
287  friend class socket_thread;
288 public:
289  listen_socket(thread_pool& pool, event_handler* evt_handler);
290  virtual ~listen_socket();
291 
292  listen_socket(listen_socket const&) = delete;
293  listen_socket& operator=(listen_socket const&) = delete;
294 
303  int listen(address_type family, int port = 0);
304 
306  std::unique_ptr<socket> accept(int& error, fz::event_handler * handler = nullptr);
307 
314  socket_descriptor fast_accept(int& error);
315 
316  listen_socket_state get_state() const;
317 
318  void set_event_handler(event_handler* pEvtHandler);
319 
320 private:
321  listen_socket_state state_{};
322 };
323 
324 
326 enum class socket_state : unsigned char
327 {
329  none,
330 
334  connecting,
335 
337  connected,
338 
342 
344  shut_down,
345 
347  closed,
348 
350  failed
351 };
352 
358 class FZ_PUBLIC_SYMBOL socket_interface : public socket_event_source
359 {
360 public:
361  socket_interface(socket_interface const&) = delete;
362  socket_interface& operator=(socket_interface const&) = delete;
363 
364  virtual int read(void* buffer, unsigned int size, int& error) = 0;
365  virtual int write(void const* buffer, unsigned int size, int& error) = 0;
366 
367  template<typename T, std::enable_if_t<std::is_signed_v<T>, int> = 0>
368  int read(void* buffer, T size, int& error)
369  {
370  if (size < 0) {
371  error = EINVAL;
372  return -1;
373  }
374 
375  return read(buffer, static_cast<unsigned int>(size), error);
376  }
377  template<typename T, std::enable_if_t<std::is_unsigned_v<T> && (sizeof(T) > sizeof(unsigned int)), int> = 0>
378  int read(void* buffer, T size, int& error)
379  {
380  if (size > std::numeric_limits<unsigned int>::max()) {
381  size = std::numeric_limits<unsigned int>::max();
382  }
383  return read(buffer, static_cast<unsigned int>(size), error);
384  }
385 
386  template<typename T, std::enable_if_t<std::is_signed_v<T>, int> = 0>
387  int write(void const* buffer, T size, int& error)
388  {
389  if (size < 0) {
390  error = EINVAL;
391  return -1;
392  }
393 
394  return write(buffer, static_cast<std::make_unsigned_t<T>>(size), error);
395  }
396  template<typename T, std::enable_if_t<std::is_unsigned_v<T> && (sizeof(T) > sizeof(unsigned int)), int> = 0>
397  int write(void const* buffer, T size, int& error)
398  {
399  if (size > std::numeric_limits<unsigned int>::max()) {
400  size = std::numeric_limits<unsigned int>::max();
401  }
402  return write(buffer, static_cast<unsigned int>(size), error);
403  }
404 
405  virtual void set_event_handler(event_handler* pEvtHandler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) = 0;
406 
407  virtual native_string peer_host() const = 0;
408  virtual int peer_port(int& error) const = 0;
409 
410  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) = 0;
411 
412  virtual fz::socket_state get_state() const = 0;
413 
424  virtual int shutdown() = 0;
425 
427  virtual int shutdown_read() = 0;
428 
429 protected:
430  socket_interface() = delete;
431 
432  explicit socket_interface(socket_event_source * root)
433  : socket_event_source(root)
434  {}
435 };
436 
445 class FZ_PUBLIC_SYMBOL socket final : public socket_base, public socket_interface
446 {
447  friend class socket_thread;
448 public:
449  socket(thread_pool& pool, event_handler* evt_handler);
450  virtual ~socket();
451 
452  socket(socket const&) = delete;
453  socket& operator=(socket const&) = delete;
454 
455  static std::unique_ptr<socket> from_descriptor(socket_descriptor && desc, thread_pool & pool, int & error, fz::event_handler * handler = nullptr);
456 
457  socket_state get_state() const override;
458  bool is_connected() const {
459  socket_state s = get_state();
461  };
462 
476  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override;
477 
493  virtual int read(void *buffer, unsigned int size, int& error) override;
494 
510  virtual int write(void const* buffer, unsigned int size, int& error) override;
511 
517  std::string peer_ip(bool strip_zone_index = false) const;
518 
520  virtual native_string peer_host() const override;
521 
527  virtual int peer_port(int& error) const override;
528 
535  int ideal_send_buffer_size();
536 
537  virtual int shutdown() override;
538 
551  virtual void set_event_handler(event_handler* pEvtHandler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) override;
552 
553  enum
554  {
556  flag_nodelay = 0x01,
557 
559  flag_keepalive = 0x02
560  };
561 
562  int flags() const { return flags_; }
563 
565  void set_flags(int flags, bool enable);
566 
568  void set_flags(int flags);
569 
575  void set_keepalive_interval(duration const& d);
576 
577  virtual int shutdown_read() override { return 0; }
578 
579 private:
580  friend class socket_base;
581  friend class listen_socket;
582  native_string host_;
583 
584  duration keepalive_interval_;
585 
586  int flags_{};
587  socket_state state_{};
588 };
589 
605 class FZ_PUBLIC_SYMBOL socket_layer : public socket_interface
606 {
607 public:
608  explicit socket_layer(event_handler* handler, socket_interface& next_layer, bool event_passthrough);
609  virtual ~socket_layer();
610 
611  socket_layer(socket_layer const&) = delete;
612  socket_layer& operator=(socket_layer const&) = delete;
613 
615  virtual void set_event_handler(event_handler* handler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) override;
616 
622  virtual native_string peer_host() const override { return next_layer_.peer_host(); }
623 
629  virtual int peer_port(int& error) const override { return next_layer_.peer_port(error); }
630 
632  socket_interface& next() { return next_layer_; }
633 
655  virtual int shutdown_read() override;
656 
657  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override {
658  return next_layer_.connect(host, port, family);
659  }
660 
661  virtual int shutdown() override {
662  return next_layer_.shutdown();
663  }
664 
665  virtual socket_state get_state() const override {
666  return next_layer_.get_state();
667  }
668 
669 protected:
675  void forward_socket_event(socket_event_source* source, socket_event_flag t, int error);
676 
682  void forward_hostaddress_event(socket_event_source* source, std::string const& address);
683 
688  void set_event_passthrough(socket_event_flag retrigger_block = socket_event_flag{});
689 
690  event_handler* event_handler_{};
691  socket_interface& next_layer_;
692  bool event_passthrough_{};
693 };
694 
703 std::string FZ_PUBLIC_SYMBOL socket_error_string(int error);
704 
708 native_string FZ_PUBLIC_SYMBOL socket_error_description(int error);
709 
710 
711 #ifdef FZ_WINDOWS
712 
713 #ifndef EISCONN
714 #define EISCONN WSAEISCONN
715 #endif
716 #ifndef EINPROGRESS
717 #define EINPROGRESS WSAEINPROGRESS
718 #endif
719 #ifndef EAFNOSUPPORT
720 #define EAFNOSUPPORT WSAEAFNOSUPPORT
721 #endif
722 #ifndef EADDRINUSE
723 #define EADDRINUSE WSAEADDRINUSE
724 #endif
725 #ifndef ENOBUFS
726 #define ENOBUFS WSAENOBUFS
727 #endif
728 #ifndef EPROTONOSUPPORT
729 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
730 #endif
731 #ifndef EALREADY
732 #define EALREADY WSAEALREADY
733 #endif
734 #ifndef ECONNREFUSED
735 #define ECONNREFUSED WSAECONNREFUSED
736 #endif
737 #ifndef ENOTSOCK
738 #define ENOTSOCK WSAENOTSOCK
739 #endif
740 #ifndef ETIMEDOUT
741 #define ETIMEDOUT WSAETIMEDOUT
742 #endif
743 #ifndef ENETUNREACH
744 #define ENETUNREACH WSAENETUNREACH
745 #endif
746 #ifndef EHOSTUNREACH
747 #define EHOSTUNREACH WSAEHOSTUNREACH
748 #endif
749 #ifndef ENOTCONN
750 #define ENOTCONN WSAENOTCONN
751 #endif
752 #ifndef ENETRESET
753 #define ENETRESET WSAENETRESET
754 #endif
755 #ifndef EOPNOTSUPP
756 #define EOPNOTSUPP WSAEOPNOTSUPP
757 #endif
758 #ifndef ESHUTDOWN
759 #define ESHUTDOWN WSAESHUTDOWN
760 #endif
761 #ifndef EMSGSIZE
762 #define EMSGSIZE WSAEMSGSIZE
763 #endif
764 #ifndef ECONNABORTED
765 #define ECONNABORTED WSAECONNABORTED
766 #endif
767 #ifndef ECONNRESET
768 #define ECONNRESET WSAECONNRESET
769 #endif
770 #ifndef EHOSTDOWN
771 #define EHOSTDOWN WSAEHOSTDOWN
772 #endif
773 
774 // For the future:
775 // Handle ERROR_NETNAME_DELETED=64
776 #endif //FZ_WINDOWS
777 
778 }
779 
780 #endif
fz::socket_event_flag change_socket_event_handler(event_handler *old_handler, event_handler *new_handler, socket_event_source const *const source, fz::socket_event_flag remove)
Changes all pending socket events from source.
std::string socket_error_string(int error)
Gets a symbolic name for socket errors.
A simple scoped lock.
Definition: mutex.hpp:64
Interface for sockets.
Definition: socket.hpp:358
Lightweight holder for socket descriptors.
Definition: socket.hpp:249
simple_event< socket_event_type, socket_event_source *, socket_event_flag, int > socket_event
Definition: socket.hpp:106
virtual int shutdown_read() override
Definition: socket.hpp:577
Simple handler for asynchronous event processing.
Definition: event_handler.hpp:54
socket_interface & next()
The next layer further down. Usually another layer or the actual socket.
Definition: socket.hpp:632
Declares the event_handler class.
Socket has failed. Further events disabled.
Common base clase for fz::socket and fz::listen_socket.
Definition: socket.hpp:165
Simple Listen socket.
Definition: socket.hpp:284
Various functions to deal with IP address strings.
Socket has been closed. Further events disabled.
socket_event_source * root() const
Gets the root source.
Definition: socket.hpp:92
This is the recommended event class.
Definition: event.hpp:65
virtual int peer_port(int &error) const override
Definition: socket.hpp:629
simple_event< hostaddress_event_type, socket_event_source *, std::string > hostaddress_event
Definition: socket.hpp:138
IPv6 capable, non-blocking socket class.
Definition: socket.hpp:445
virtual int shutdown() override
Signals peers that we want to close the connections.
Definition: socket.hpp:661
void remove_socket_events(event_handler *handler, socket_event_source const *const source)
Remove all pending socket events from source sent to handler.
A base class for socket layers.
Definition: socket.hpp:605
virtual native_string peer_host() const override
Definition: socket.hpp:622
std::wstring native_string
A string in the system's native character type and encoding. Note: This typedef changes depending on...
Definition: string.hpp:33
socket_state
State transitions are monotonically increasing.
Definition: socket.hpp:326
Only in listening state you can get a connection event.
The namespace used by libfilezilla.
Definition: apply.hpp:17
listen_socket_state
Definition: socket.hpp:239
native_string socket_error_description(int error)
Gets a human-readable, translated description of the error.
Socket is in its normal working state. You can get send and receive events.
All classes sending socket events should derive from this.
Definition: socket.hpp:83
The duration class represents a time interval in milliseconds.
Definition: time.hpp:285
Sets some global macros and further includes string.hpp.
Write side has finished shutting down. Receive still working normally.
The buffer class is a simple buffer where data can be appended at the end and consumed at the front...
Definition: buffer.hpp:25
A dumb thread-pool for asynchronous tasks.
Definition: thread_pool.hpp:62
socket_event_flag
The type of a socket event.
Definition: socket.hpp:33