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 
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  };
577 
578  int flags() const { return flags_; }
579 
581  void set_flags(int flags, bool enable);
582 
584  void set_flags(int flags);
585 
591  void set_keepalive_interval(duration const& d);
592 
593  virtual int shutdown_read() override { return 0; }
594 
595  socket_t get_descriptor();
596 
597 #ifndef FZ_WINDOWS
598 
613  int send_fd(fz::buffer & buf, int fd, int & error);
614 
624  int read_fd(fz::buffer & buf, int &fd, int & error);
625 #endif
626 
627 private:
628  friend class socket_base;
629  friend class listen_socket;
630  native_string host_;
631 
632  duration keepalive_interval_;
633 
634  int flags_{};
635  socket_state state_{};
636 };
637 
653 class FZ_PUBLIC_SYMBOL socket_layer : public socket_interface
654 {
655 public:
656  explicit socket_layer(event_handler* handler, socket_interface& next_layer, bool event_passthrough);
657  virtual ~socket_layer();
658 
659  socket_layer(socket_layer const&) = delete;
660  socket_layer& operator=(socket_layer const&) = delete;
661 
663  virtual void set_event_handler(event_handler* handler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) override;
664 
670  virtual native_string peer_host() const override { return next_layer_.peer_host(); }
671 
677  virtual int peer_port(int& error) const override { return next_layer_.peer_port(error); }
678 
680  socket_interface& next() { return next_layer_; }
681 
703  virtual int shutdown_read() override;
704 
705  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override {
706  return next_layer_.connect(host, port, family);
707  }
708 
709  virtual int shutdown() override {
710  return next_layer_.shutdown();
711  }
712 
713  virtual socket_state get_state() const override {
714  return next_layer_.get_state();
715  }
716 
717 protected:
723  void forward_socket_event(socket_event_source* source, socket_event_flag t, int error);
724 
730  void forward_hostaddress_event(socket_event_source* source, std::string const& address);
731 
736  void set_event_passthrough(socket_event_flag retrigger_block = socket_event_flag{});
737 
738  event_handler* event_handler_{};
739  socket_interface& next_layer_;
740  bool event_passthrough_{};
741 };
742 
751 std::string FZ_PUBLIC_SYMBOL socket_error_string(int error);
752 
756 native_string FZ_PUBLIC_SYMBOL socket_error_description(int error);
757 
758 
759 #ifdef FZ_WINDOWS
760 
762 class FZ_PRIVATE_SYMBOL winsock_initializer final
763 {
764 public:
765  winsock_initializer();
766  ~winsock_initializer();
767 
768 private:
769  bool initialized_{};
770 };
771 
772 #ifndef EISCONN
773 #define EISCONN WSAEISCONN
774 #endif
775 #ifndef EINPROGRESS
776 #define EINPROGRESS WSAEINPROGRESS
777 #endif
778 #ifndef EAFNOSUPPORT
779 #define EAFNOSUPPORT WSAEAFNOSUPPORT
780 #endif
781 #ifndef EADDRINUSE
782 #define EADDRINUSE WSAEADDRINUSE
783 #endif
784 #ifndef ENOBUFS
785 #define ENOBUFS WSAENOBUFS
786 #endif
787 #ifndef EPROTONOSUPPORT
788 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
789 #endif
790 #ifndef EALREADY
791 #define EALREADY WSAEALREADY
792 #endif
793 #ifndef ECONNREFUSED
794 #define ECONNREFUSED WSAECONNREFUSED
795 #endif
796 #ifndef ENOTSOCK
797 #define ENOTSOCK WSAENOTSOCK
798 #endif
799 #ifndef ETIMEDOUT
800 #define ETIMEDOUT WSAETIMEDOUT
801 #endif
802 #ifndef ENETUNREACH
803 #define ENETUNREACH WSAENETUNREACH
804 #endif
805 #ifndef EHOSTUNREACH
806 #define EHOSTUNREACH WSAEHOSTUNREACH
807 #endif
808 #ifndef ENOTCONN
809 #define ENOTCONN WSAENOTCONN
810 #endif
811 #ifndef ENETRESET
812 #define ENETRESET WSAENETRESET
813 #endif
814 #ifndef EOPNOTSUPP
815 #define EOPNOTSUPP WSAEOPNOTSUPP
816 #endif
817 #ifndef ESHUTDOWN
818 #define ESHUTDOWN WSAESHUTDOWN
819 #endif
820 #ifndef EMSGSIZE
821 #define EMSGSIZE WSAEMSGSIZE
822 #endif
823 #ifndef ECONNABORTED
824 #define ECONNABORTED WSAECONNABORTED
825 #endif
826 #ifndef ECONNRESET
827 #define ECONNRESET WSAECONNRESET
828 #endif
829 #ifndef EHOSTDOWN
830 #define EHOSTDOWN WSAEHOSTDOWN
831 #endif
832 
833 // For the future:
834 // Handle ERROR_NETNAME_DELETED=64
835 #endif //FZ_WINDOWS
836 
837 }
838 
839 #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: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:593
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:680
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:677
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:709
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:653
virtual native_string peer_host() const override
Definition: socket.hpp:670
std::wstring native_string
A string in the system's native character type and encoding. Note: This typedef changes depending on...
Definition: string.hpp:34
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
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.