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 buffer;
25 class thread_pool;
26 
35 {
41  connection_next = 0x1,
42 
47  connection = 0x2,
48 
53  read = 0x4,
54 
59  write = 0x8,
60 };
61 
62 inline bool operator&(socket_event_flag lhs, socket_event_flag rhs) {
63  return (static_cast<std::underlying_type_t<socket_event_flag>>(lhs) & static_cast<std::underlying_type_t<socket_event_flag>>(rhs)) != 0;
64 }
65 inline socket_event_flag operator|(socket_event_flag lhs, socket_event_flag rhs)
66 {
67  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));
68 }
69 inline socket_event_flag& operator|=(socket_event_flag& lhs, socket_event_flag rhs)
70 {
71  lhs = lhs | rhs;
72  return lhs;
73 }
74 
75 
84 class FZ_PUBLIC_SYMBOL socket_event_source
85 {
86 public:
87  virtual ~socket_event_source() = default;
88 
94  return root_;
95  }
96 
97 protected:
98  socket_event_source() = delete;
100  : root_(root)
101  {}
102 
103  socket_event_source* const root_{};
104 };
105 
107 struct socket_event_type;
108 
132 
134 struct hostaddress_event_type{};
135 
140 
147 void FZ_PUBLIC_SYMBOL remove_socket_events(event_handler * handler, socket_event_source const* const source);
148 
160 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);
161 
163 class socket_thread;
164 
166 class FZ_PUBLIC_SYMBOL socket_base
167 {
168 public:
176  int set_buffer_sizes(int size_receive, int size_send);
177 
179  address_type address_family() const;
180 
186  std::string local_ip(bool strip_zone_index = false) const;
187 
193  int local_port(int& error) const;
194 
195  static std::string address_to_string(sockaddr const* addr, int addr_len, bool with_port = true, bool strip_zone_index = false);
196  static std::string address_to_string(char const* buf, int buf_len);
197 
203  bool bind(std::string const& address);
204 
205 #if FZ_WINDOWS
206  typedef intptr_t socket_t;
207 #else
208  typedef int socket_t;
209 #endif
210 
211  int close();
212 
213 protected:
214  friend class socket_thread;
215 
216  socket_base(thread_pool& pool, event_handler* evt_handler, socket_event_source* ev_source);
217  virtual ~socket_base() = default;
218 
219  // Note: Unlocks the lock.
220  void detach_thread(scoped_lock & l);
221 
222  thread_pool & thread_pool_;
223  event_handler* evt_handler_;
224 
225  socket_thread* socket_thread_{};
226 
227  socket_event_source * const ev_source_{};
228 
229  socket_t fd_{-1};
230 
231  unsigned int port_{};
232 
233  int family_;
234 
235  int buffer_sizes_[2];
236 };
237 
238 class socket;
239 
241 {
243  none,
244 
246  listening,
247 };
248 
250 class FZ_PUBLIC_SYMBOL socket_descriptor final
251 {
252 public:
253  socket_descriptor() = default;
255  explicit socket_descriptor(socket_base::socket_t fd) noexcept : fd_(fd) {}
256 
257  socket_descriptor(socket_descriptor const&) = delete;
258  socket_descriptor& operator=(socket_descriptor const&) = delete;
259 
260  socket_descriptor(socket_descriptor && rhs) noexcept { std::swap(fd_, rhs.fd_); }
261  socket_descriptor& operator=(socket_descriptor && rhs) noexcept {
262  std::swap(fd_, rhs.fd_);
263  return *this;
264  }
265 
266  socket_base::socket_t detach() {
267  socket_base::socket_t ret = fd_;
268  fd_ = -1;
269  return ret;
270  }
271 
272  explicit operator bool() const { return fd_ != -1; }
273 
279  std::string peer_ip(bool strip_zone_index = false) const;
280 
286  int peer_port(int& error) const;
287 
288 private:
289  socket_base::socket_t fd_{-1};
290 };
291 
299 class FZ_PUBLIC_SYMBOL listen_socket final : public socket_base, public socket_event_source
300 {
301  friend class socket_base;
302  friend class socket_thread;
303 public:
304  listen_socket(thread_pool& pool, event_handler* evt_handler);
305  virtual ~listen_socket();
306 
307  listen_socket(listen_socket const&) = delete;
308  listen_socket& operator=(listen_socket const&) = delete;
309 
310  static std::unique_ptr<listen_socket> from_descriptor(socket_descriptor && desc, thread_pool & pool, int & error, fz::event_handler * handler = nullptr);
311 
319  int listen(address_type family, int port = 0);
320 
322  std::unique_ptr<socket> accept(int& error, fz::event_handler * handler = nullptr);
323 
330  socket_descriptor fast_accept(int& error);
331 
332  listen_socket_state get_state() const;
333 
334  void set_event_handler(event_handler* pEvtHandler);
335 
336 private:
337  listen_socket_state state_{};
338 };
339 
340 
342 enum class socket_state : unsigned char
343 {
345  none,
346 
350  connecting,
351 
353  connected,
354 
358 
360  shut_down,
361 
363  closed,
364 
366  failed
367 };
368 
374 class FZ_PUBLIC_SYMBOL socket_interface : public socket_event_source
375 {
376 public:
377  socket_interface(socket_interface const&) = delete;
378  socket_interface& operator=(socket_interface const&) = delete;
379 
380  virtual int read(void* buffer, unsigned int size, int& error) = 0;
381  virtual int write(void const* buffer, unsigned int size, int& error) = 0;
382 
383  template<typename T, std::enable_if_t<std::is_signed_v<T>, int> = 0>
384  int read(void* buffer, T size, int& error)
385  {
386  if (size < 0) {
387  error = EINVAL;
388  return -1;
389  }
390 
391  return read(buffer, static_cast<unsigned int>(size), error);
392  }
393  template<typename T, std::enable_if_t<std::is_unsigned_v<T> && (sizeof(T) > sizeof(unsigned int)), int> = 0>
394  int read(void* buffer, T size, int& error)
395  {
396  if (size > std::numeric_limits<unsigned int>::max()) {
397  size = std::numeric_limits<unsigned int>::max();
398  }
399  return read(buffer, static_cast<unsigned int>(size), error);
400  }
401 
402  template<typename T, std::enable_if_t<std::is_signed_v<T>, int> = 0>
403  int write(void const* buffer, T size, int& error)
404  {
405  if (size < 0) {
406  error = EINVAL;
407  return -1;
408  }
409 
410  return write(buffer, static_cast<std::make_unsigned_t<T>>(size), error);
411  }
412  template<typename T, std::enable_if_t<std::is_unsigned_v<T> && (sizeof(T) > sizeof(unsigned int)), int> = 0>
413  int write(void const* buffer, T size, int& error)
414  {
415  if (size > std::numeric_limits<unsigned int>::max()) {
416  size = std::numeric_limits<unsigned int>::max();
417  }
418  return write(buffer, static_cast<unsigned int>(size), error);
419  }
420 
421  virtual void set_event_handler(event_handler* pEvtHandler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) = 0;
422 
423  virtual native_string peer_host() const = 0;
424  virtual int peer_port(int& error) const = 0;
425 
426  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) = 0;
427 
428  virtual fz::socket_state get_state() const = 0;
429 
440  virtual int shutdown() = 0;
441 
443  virtual int shutdown_read() = 0;
444 
445 protected:
446  socket_interface() = delete;
447 
448  explicit socket_interface(socket_event_source * root)
449  : socket_event_source(root)
450  {}
451 };
452 
461 class FZ_PUBLIC_SYMBOL socket final : public socket_base, public socket_interface
462 {
463  friend class socket_thread;
464 public:
465  socket(thread_pool& pool, event_handler* evt_handler);
466  virtual ~socket();
467 
468  socket(socket const&) = delete;
469  socket& operator=(socket const&) = delete;
470 
471  static std::unique_ptr<socket> from_descriptor(socket_descriptor && desc, thread_pool & pool, int & error, fz::event_handler * handler = nullptr);
472 
473  socket_state get_state() const override;
474  bool is_connected() const {
475  socket_state s = get_state();
477  };
478 
492  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override;
493 
509  virtual int read(void *buffer, unsigned int size, int& error) override;
510 
526  virtual int write(void const* buffer, unsigned int size, int& error) override;
527 
533  std::string peer_ip(bool strip_zone_index = false) const;
534 
536  virtual native_string peer_host() const override;
537 
543  virtual int peer_port(int& error) const override;
544 
551  int ideal_send_buffer_size();
552 
553  virtual int shutdown() override;
554 
567  virtual void set_event_handler(event_handler* pEvtHandler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) override;
568 
569  enum
570  {
572  flag_nodelay = 0x01,
573 
575  flag_keepalive = 0x02,
576 
578  flag_oobinline = 0x04
579  };
580 
581  int flags() const { return flags_; }
582 
584  void set_flags(int flags, bool enable);
585 
587  void set_flags(int flags);
588 
594  void set_keepalive_interval(duration const& d);
595 
596  virtual int shutdown_read() override { return 0; }
597 
598  socket_t get_descriptor();
599 
600 #ifndef FZ_WINDOWS
601 
616  int send_fd(fz::buffer & buf, int fd, int & error);
617 
627  int read_fd(fz::buffer & buf, int &fd, int & error);
628 #endif
629 
630 private:
631  friend class socket_base;
632  friend class listen_socket;
633  native_string host_;
634 
635  duration keepalive_interval_;
636 
637  int flags_{};
638  socket_state state_{};
639 };
640 
656 class FZ_PUBLIC_SYMBOL socket_layer : public socket_interface
657 {
658 public:
659  explicit socket_layer(event_handler* handler, socket_interface& next_layer, bool event_passthrough);
660  virtual ~socket_layer();
661 
662  socket_layer(socket_layer const&) = delete;
663  socket_layer& operator=(socket_layer const&) = delete;
664 
666  virtual void set_event_handler(event_handler* handler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) override;
667 
673  virtual native_string peer_host() const override { return next_layer_.peer_host(); }
674 
680  virtual int peer_port(int& error) const override { return next_layer_.peer_port(error); }
681 
683  socket_interface& next() { return next_layer_; }
684 
706  virtual int shutdown_read() override;
707 
708  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override {
709  return next_layer_.connect(host, port, family);
710  }
711 
712  virtual int shutdown() override {
713  return next_layer_.shutdown();
714  }
715 
716  virtual socket_state get_state() const override {
717  return next_layer_.get_state();
718  }
719 
720 protected:
726  void forward_socket_event(socket_event_source* source, socket_event_flag t, int error);
727 
733  void forward_hostaddress_event(socket_event_source* source, std::string const& address);
734 
739  void set_event_passthrough(socket_event_flag retrigger_block = socket_event_flag{});
740 
741  event_handler* event_handler_{};
742  socket_interface& next_layer_;
743  bool event_passthrough_{};
744 };
745 
754 std::string FZ_PUBLIC_SYMBOL socket_error_string(int error);
755 
759 native_string FZ_PUBLIC_SYMBOL socket_error_description(int error);
760 
772 std::optional<std::pair<std::unique_ptr<fz::socket>, std::unique_ptr<fz::socket>>> FZ_PUBLIC_SYMBOL create_tcp_socketpair(fz::thread_pool & pool);
773 
774 
775 #ifdef FZ_WINDOWS
776 
778 class FZ_PRIVATE_SYMBOL winsock_initializer final
779 {
780 public:
781  winsock_initializer();
782  ~winsock_initializer();
783 
784 private:
785  bool initialized_{};
786 };
787 
788 #ifndef EISCONN
789 #define EISCONN WSAEISCONN
790 #endif
791 #ifndef EINPROGRESS
792 #define EINPROGRESS WSAEINPROGRESS
793 #endif
794 #ifndef EAFNOSUPPORT
795 #define EAFNOSUPPORT WSAEAFNOSUPPORT
796 #endif
797 #ifndef EADDRINUSE
798 #define EADDRINUSE WSAEADDRINUSE
799 #endif
800 #ifndef ENOBUFS
801 #define ENOBUFS WSAENOBUFS
802 #endif
803 #ifndef EPROTONOSUPPORT
804 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
805 #endif
806 #ifndef EALREADY
807 #define EALREADY WSAEALREADY
808 #endif
809 #ifndef ECONNREFUSED
810 #define ECONNREFUSED WSAECONNREFUSED
811 #endif
812 #ifndef ENOTSOCK
813 #define ENOTSOCK WSAENOTSOCK
814 #endif
815 #ifndef ETIMEDOUT
816 #define ETIMEDOUT WSAETIMEDOUT
817 #endif
818 #ifndef ENETUNREACH
819 #define ENETUNREACH WSAENETUNREACH
820 #endif
821 #ifndef EHOSTUNREACH
822 #define EHOSTUNREACH WSAEHOSTUNREACH
823 #endif
824 #ifndef ENOTCONN
825 #define ENOTCONN WSAENOTCONN
826 #endif
827 #ifndef ENETRESET
828 #define ENETRESET WSAENETRESET
829 #endif
830 #ifndef EOPNOTSUPP
831 #define EOPNOTSUPP WSAEOPNOTSUPP
832 #endif
833 #ifndef ESHUTDOWN
834 #define ESHUTDOWN WSAESHUTDOWN
835 #endif
836 #ifndef EMSGSIZE
837 #define EMSGSIZE WSAEMSGSIZE
838 #endif
839 #ifndef ECONNABORTED
840 #define ECONNABORTED WSAECONNABORTED
841 #endif
842 #ifndef ECONNRESET
843 #define ECONNRESET WSAECONNRESET
844 #endif
845 #ifndef EHOSTDOWN
846 #define EHOSTDOWN WSAEHOSTDOWN
847 #endif
848 #ifndef ESOCKTNOSUPPORT
849 #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
850 #endif
851 
852 // For the future:
853 // Handle ERROR_NETNAME_DELETED=64
854 #endif //FZ_WINDOWS
855 
856 }
857 
858 #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.
Data has become available.
std::string socket_error_string(int error)
Gets a symbolic name for socket errors.
A simple scoped lock.
Definition: mutex.hpp:116
Interface for sockets.
Definition: socket.hpp:374
Lightweight holder for socket descriptors.
Definition: socket.hpp:250
simple_event< socket_event_type, socket_event_source *, socket_event_flag, int > socket_event
Definition: socket.hpp:107
virtual int shutdown_read() override
Definition: socket.hpp:596
Definition: event_handler.hpp:60
socket_interface & next()
The next layer further down. Usually another layer or the actual socket.
Definition: socket.hpp:683
Declares the event_handler class.
Socket has failed. Further events disabled.
Common base clase for fz::socket and fz::listen_socket.
Definition: socket.hpp:166
Simple Listen socket.
Definition: socket.hpp:299
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:93
This is the recommended event class.
Definition: event.hpp:67
virtual int peer_port(int &error) const override
Definition: socket.hpp:680
simple_event< hostaddress_event_type, socket_event_source *, std::string > hostaddress_event
Definition: socket.hpp:139
IPv6 capable, non-blocking socket class.
Definition: socket.hpp:461
virtual int shutdown() override
Signals peers that we want to close the connections.
Definition: socket.hpp:712
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:656
virtual native_string peer_host() const override
Definition: socket.hpp:673
std::wstring native_string
A string in the system's native character type and encoding. Note: This typedef changes depending on...
Definition: string.hpp:69
socket_state
State transitions are monotonically increasing.
Definition: socket.hpp:342
Only in listening state you can get a connection event.
The namespace used by libfilezilla.
Definition: apply.hpp:17
std::optional< std::pair< std::unique_ptr< fz::socket >, std::unique_ptr< fz::socket > > > create_tcp_socketpair(fz::thread_pool &pool)
Creates a pair of connected TCP sockets.
listen_socket_state
Definition: socket.hpp:240
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.
How the socket is initially.
All classes sending socket events should derive from this.
Definition: socket.hpp:84
The duration class represents a time interval in milliseconds.
Definition: time.hpp:290
Sets some global macros and further includes string.hpp.
How the socket is initially.
data can be written.
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:26
A dumb thread-pool for asynchronous tasks.
Definition: thread_pool.hpp:63
socket_event_flag
The type of a socket event.
Definition: socket.hpp:34
Operationf failed.