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 protected:
212  friend class socket_thread;
213 
214  socket_base(thread_pool& pool, event_handler* evt_handler, socket_event_source* ev_source);
215  virtual ~socket_base() = default;
216 
217  int close();
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 
274 private:
275  socket_base::socket_t fd_{-1};
276 };
277 
285 class FZ_PUBLIC_SYMBOL listen_socket final : public socket_base, public socket_event_source
286 {
287  friend class socket_base;
288  friend class socket_thread;
289 public:
290  listen_socket(thread_pool& pool, event_handler* evt_handler);
291  virtual ~listen_socket();
292 
293  listen_socket(listen_socket const&) = delete;
294  listen_socket& operator=(listen_socket const&) = delete;
295 
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  socket_t get_descriptor();
580 
581 #ifndef FZ_WINDOWS
582 
597  int send_fd(fz::buffer & buf, int fd, int & error);
598 
608  int read_fd(fz::buffer & buf, int &fd, int & error);
609 #endif
610 
611 private:
612  friend class socket_base;
613  friend class listen_socket;
614  native_string host_;
615 
616  duration keepalive_interval_;
617 
618  int flags_{};
619  socket_state state_{};
620 };
621 
637 class FZ_PUBLIC_SYMBOL socket_layer : public socket_interface
638 {
639 public:
640  explicit socket_layer(event_handler* handler, socket_interface& next_layer, bool event_passthrough);
641  virtual ~socket_layer();
642 
643  socket_layer(socket_layer const&) = delete;
644  socket_layer& operator=(socket_layer const&) = delete;
645 
647  virtual void set_event_handler(event_handler* handler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) override;
648 
654  virtual native_string peer_host() const override { return next_layer_.peer_host(); }
655 
661  virtual int peer_port(int& error) const override { return next_layer_.peer_port(error); }
662 
664  socket_interface& next() { return next_layer_; }
665 
687  virtual int shutdown_read() override;
688 
689  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override {
690  return next_layer_.connect(host, port, family);
691  }
692 
693  virtual int shutdown() override {
694  return next_layer_.shutdown();
695  }
696 
697  virtual socket_state get_state() const override {
698  return next_layer_.get_state();
699  }
700 
701 protected:
707  void forward_socket_event(socket_event_source* source, socket_event_flag t, int error);
708 
714  void forward_hostaddress_event(socket_event_source* source, std::string const& address);
715 
720  void set_event_passthrough(socket_event_flag retrigger_block = socket_event_flag{});
721 
722  event_handler* event_handler_{};
723  socket_interface& next_layer_;
724  bool event_passthrough_{};
725 };
726 
735 std::string FZ_PUBLIC_SYMBOL socket_error_string(int error);
736 
740 native_string FZ_PUBLIC_SYMBOL socket_error_description(int error);
741 
742 
743 #ifdef FZ_WINDOWS
744 
746 class FZ_PRIVATE_SYMBOL winsock_initializer final
747 {
748 public:
749  winsock_initializer();
750  ~winsock_initializer();
751 
752 private:
753  bool initialized_{};
754 };
755 
756 #ifndef EISCONN
757 #define EISCONN WSAEISCONN
758 #endif
759 #ifndef EINPROGRESS
760 #define EINPROGRESS WSAEINPROGRESS
761 #endif
762 #ifndef EAFNOSUPPORT
763 #define EAFNOSUPPORT WSAEAFNOSUPPORT
764 #endif
765 #ifndef EADDRINUSE
766 #define EADDRINUSE WSAEADDRINUSE
767 #endif
768 #ifndef ENOBUFS
769 #define ENOBUFS WSAENOBUFS
770 #endif
771 #ifndef EPROTONOSUPPORT
772 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
773 #endif
774 #ifndef EALREADY
775 #define EALREADY WSAEALREADY
776 #endif
777 #ifndef ECONNREFUSED
778 #define ECONNREFUSED WSAECONNREFUSED
779 #endif
780 #ifndef ENOTSOCK
781 #define ENOTSOCK WSAENOTSOCK
782 #endif
783 #ifndef ETIMEDOUT
784 #define ETIMEDOUT WSAETIMEDOUT
785 #endif
786 #ifndef ENETUNREACH
787 #define ENETUNREACH WSAENETUNREACH
788 #endif
789 #ifndef EHOSTUNREACH
790 #define EHOSTUNREACH WSAEHOSTUNREACH
791 #endif
792 #ifndef ENOTCONN
793 #define ENOTCONN WSAENOTCONN
794 #endif
795 #ifndef ENETRESET
796 #define ENETRESET WSAENETRESET
797 #endif
798 #ifndef EOPNOTSUPP
799 #define EOPNOTSUPP WSAEOPNOTSUPP
800 #endif
801 #ifndef ESHUTDOWN
802 #define ESHUTDOWN WSAESHUTDOWN
803 #endif
804 #ifndef EMSGSIZE
805 #define EMSGSIZE WSAEMSGSIZE
806 #endif
807 #ifndef ECONNABORTED
808 #define ECONNABORTED WSAECONNABORTED
809 #endif
810 #ifndef ECONNRESET
811 #define ECONNRESET WSAECONNRESET
812 #endif
813 #ifndef EHOSTDOWN
814 #define EHOSTDOWN WSAEHOSTDOWN
815 #endif
816 
817 // For the future:
818 // Handle ERROR_NETNAME_DELETED=64
819 #endif //FZ_WINDOWS
820 
821 }
822 
823 #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:92
Interface for sockets.
Definition: socket.hpp:358
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: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:664
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:285
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:661
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:445
virtual int shutdown() override
Signals peers that we want to close the connections.
Definition: socket.hpp:693
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:637
virtual native_string peer_host() const override
Definition: socket.hpp:654
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: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