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 
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 
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 
592 
593  virtual int shutdown_read() override { return 0; }
594 
595  socket_t get_descriptor();
596 
597 #ifndef FZ_WINDOWS
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:
724 
730  void forward_hostaddress_event(socket_event_source* source, std::string const& address);
731 
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
The buffer class is a simple buffer where data can be appended at the end and consumed at the front....
Definition: buffer.hpp:27
The duration class represents a time interval in milliseconds.
Definition: time.hpp:291
Simple handler for asynchronous event processing.
Definition: event_handler.hpp:55
Simple Listen socket.
Definition: socket.hpp:300
socket_descriptor fast_accept(int &error)
Like accept, but only returns a socket descriptor.
int listen(address_type family, int port=0)
Starts listening.
std::unique_ptr< socket > accept(int &error, fz::event_handler *handler=nullptr)
Accepts incoming connection. If no socket is returned, error contains the reason.
A simple scoped lock.
Definition: mutex.hpp:93
This is the recommended event class.
Definition: event.hpp:68
Common base clase for fz::socket and fz::listen_socket.
Definition: socket.hpp:167
std::string local_ip(bool strip_zone_index=false) const
Returns local address of a connected socket.
int set_buffer_sizes(int size_receive, int size_send)
Sets socket buffer sizes.
address_type address_family() const
If connected, either ipv4, ipv6 or unix, unknown otherwise.
bool bind(std::string const &address)
Bind socket to the specific local IP.
int local_port(int &error) const
Returns local port of a connected socket.
Lightweight holder for socket descriptors.
Definition: socket.hpp:251
std::string peer_ip(bool strip_zone_index=false) const
Returns remote address of a connected socket.
int peer_port(int &error) const
Returns remote port of a connected socket.
All classes sending socket events should derive from this.
Definition: socket.hpp:85
socket_event_source * root() const
Gets the root source.
Definition: socket.hpp:93
Interface for sockets.
Definition: socket.hpp:375
virtual int shutdown()=0
Signals peers that we want to close the connections.
virtual int shutdown_read()=0
A base class for socket layers.
Definition: socket.hpp:654
void set_event_passthrough(socket_event_flag retrigger_block=socket_event_flag{})
virtual native_string peer_host() const override
Definition: socket.hpp:670
void forward_hostaddress_event(socket_event_source *source, std::string const &address)
virtual int shutdown() override
Signals peers that we want to close the connections.
Definition: socket.hpp:709
void forward_socket_event(socket_event_source *source, socket_event_flag t, int error)
socket_interface & next()
The next layer further down. Usually another layer or the actual socket.
Definition: socket.hpp:680
virtual void set_event_handler(event_handler *handler, fz::socket_event_flag retrigger_block=fz::socket_event_flag{}) override
The handler for any events generated (or forwarded) by this layer.
virtual int peer_port(int &error) const override
Definition: socket.hpp:677
virtual int shutdown_read() override
Check that all layers further down also have reached EOF.
IPv6 capable, non-blocking socket class.
Definition: socket.hpp:462
virtual native_string peer_host() const override
Returns the hostname passed to connect()
void set_flags(int flags, bool enable)
Enables or disabled the passed flags.
virtual int shutdown() override
Signals peers that we want to close the connections.
virtual int connect(native_string const &host, unsigned int port, address_type family=address_type::unknown) override
Starts connecting to the given host, given as name, IPv4 or IPv6 address.
virtual void set_event_handler(event_handler *pEvtHandler, fz::socket_event_flag retrigger_block=fz::socket_event_flag{}) override
Changes the associated event handler.
std::string peer_ip(bool strip_zone_index=false) const
Returns remote address of a connected socket.
void set_flags(int flags)
Sets the entire mask of enabled flag, disabling all others.
virtual int write(void const *buffer, unsigned int size, int &error) override
Write data to socket.
virtual int peer_port(int &error) const override
Returns remote port of a connected socket.
virtual int read(void *buffer, unsigned int size, int &error) override
Read data from socket.
int ideal_send_buffer_size()
void set_keepalive_interval(duration const &d)
virtual int shutdown_read() override
Definition: socket.hpp:593
A dumb thread-pool for asynchronous tasks.
Definition: thread_pool.hpp:64
Declares the event_handler class.
Various functions to deal with IP address strings.
Sets some global macros and further includes string.hpp.
The namespace used by libfilezilla.
Definition: apply.hpp:17
void remove_socket_events(event_handler *handler, socket_event_source const *const source)
Remove all pending socket events from source sent to handler.
native_string socket_error_description(int error)
Gets a human-readable, translated description of the error.
listen_socket_state
Definition: socket.hpp:241
@ none
How the socket is initially.
@ listening
Only in listening state you can get a connection event.
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::wstring native_string
A string in the system's native character type and encoding. Note: This typedef changes depending on...
Definition: string.hpp:34
simple_event< hostaddress_event_type, socket_event_source *, std::string > hostaddress_event
Definition: socket.hpp:139
socket_state
State transitions are monotonically increasing.
Definition: socket.hpp:343
@ connected
Socket is in its normal working state. You can get send and receive events.
@ shut_down
Write side has finished shutting down. Receive still working normally.
@ failed
Socket has failed. Further events disabled.
@ none
How the socket is initially.
@ closed
Socket has been closed. Further events disabled.
std::string socket_error_string(int error)
Gets a symbolic name for socket errors.
simple_event< socket_event_type, socket_event_source *, socket_event_flag, int > socket_event
Definition: socket.hpp:107
@ read
Data has become available.
@ write
data can be written.
socket_event_flag
The type of a socket event.
Definition: socket.hpp:35