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() = default;
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  virtual void set_event_handler(event_handler* pEvtHandler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) = 0;
368 
369  virtual native_string peer_host() const = 0;
370  virtual int peer_port(int& error) const = 0;
371 
372  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) = 0;
373 
374  virtual fz::socket_state get_state() const = 0;
375 
386  virtual int shutdown() = 0;
387 
389  virtual int shutdown_read() = 0;
390 
391 protected:
392  socket_interface() = default;
393 
394  explicit socket_interface(socket_event_source * root)
395  : socket_event_source(root)
396  {}
397 };
398 
407 class FZ_PUBLIC_SYMBOL socket final : public socket_base, public socket_interface
408 {
409  friend class socket_thread;
410 public:
411  socket(thread_pool& pool, event_handler* evt_handler);
412  virtual ~socket();
413 
414  socket(socket const&) = delete;
415  socket& operator=(socket const&) = delete;
416 
417  static std::unique_ptr<socket> from_descriptor(socket_descriptor && desc, thread_pool & pool, int & error, fz::event_handler * handler = nullptr);
418 
419  socket_state get_state() const override;
420  bool is_connected() const {
421  socket_state s = get_state();
423  };
424 
438  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override;
439 
455  virtual int read(void *buffer, unsigned int size, int& error) override;
456 
472  virtual int write(void const* buffer, unsigned int size, int& error) override;
473 
479  std::string peer_ip(bool strip_zone_index = false) const;
480 
482  virtual native_string peer_host() const override;
483 
489  virtual int peer_port(int& error) const override;
490 
497  int ideal_send_buffer_size();
498 
499  virtual int shutdown() override;
500 
513  virtual void set_event_handler(event_handler* pEvtHandler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) override;
514 
515  enum
516  {
518  flag_nodelay = 0x01,
519 
521  flag_keepalive = 0x02
522  };
523 
524  int flags() const { return flags_; }
525 
527  void set_flags(int flags, bool enable);
528 
530  void set_flags(int flags);
531 
537  void set_keepalive_interval(duration const& d);
538 
539  virtual int shutdown_read() override { return 0; }
540 
541 private:
542  friend class socket_base;
543  friend class listen_socket;
544  native_string host_;
545 
546  duration keepalive_interval_;
547 
548  int flags_{};
549  socket_state state_{};
550 };
551 
567 class FZ_PUBLIC_SYMBOL socket_layer : public socket_interface
568 {
569 public:
570  explicit socket_layer(event_handler* handler, socket_interface& next_layer, bool event_passthrough);
571  virtual ~socket_layer();
572 
573  socket_layer(socket_layer const&) = delete;
574  socket_layer& operator=(socket_layer const&) = delete;
575 
577  virtual void set_event_handler(event_handler* handler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) override;
578 
584  virtual native_string peer_host() const override { return next_layer_.peer_host(); }
585 
591  virtual int peer_port(int& error) const override { return next_layer_.peer_port(error); }
592 
594  socket_interface& next() { return next_layer_; }
595 
617  virtual int shutdown_read() override;
618 
619 protected:
625  void forward_socket_event(socket_event_source* source, socket_event_flag t, int error);
626 
632  void forward_hostaddress_event(socket_event_source* source, std::string const& address);
633 
638  void set_event_passthrough(socket_event_flag retrigger_block = socket_event_flag{});
639 
640  event_handler* event_handler_{};
641  socket_interface& next_layer_;
642  bool event_passthrough_{};
643 };
644 
653 std::string FZ_PUBLIC_SYMBOL socket_error_string(int error);
654 
658 native_string FZ_PUBLIC_SYMBOL socket_error_description(int error);
659 
660 
661 #ifdef FZ_WINDOWS
662 
663 #ifndef EISCONN
664 #define EISCONN WSAEISCONN
665 #endif
666 #ifndef EINPROGRESS
667 #define EINPROGRESS WSAEINPROGRESS
668 #endif
669 #ifndef EAFNOSUPPORT
670 #define EAFNOSUPPORT WSAEAFNOSUPPORT
671 #endif
672 #ifndef EADDRINUSE
673 #define EADDRINUSE WSAEADDRINUSE
674 #endif
675 #ifndef ENOBUFS
676 #define ENOBUFS WSAENOBUFS
677 #endif
678 #ifndef EPROTONOSUPPORT
679 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
680 #endif
681 #ifndef EALREADY
682 #define EALREADY WSAEALREADY
683 #endif
684 #ifndef ECONNREFUSED
685 #define ECONNREFUSED WSAECONNREFUSED
686 #endif
687 #ifndef ENOTSOCK
688 #define ENOTSOCK WSAENOTSOCK
689 #endif
690 #ifndef ETIMEDOUT
691 #define ETIMEDOUT WSAETIMEDOUT
692 #endif
693 #ifndef ENETUNREACH
694 #define ENETUNREACH WSAENETUNREACH
695 #endif
696 #ifndef EHOSTUNREACH
697 #define EHOSTUNREACH WSAEHOSTUNREACH
698 #endif
699 #ifndef ENOTCONN
700 #define ENOTCONN WSAENOTCONN
701 #endif
702 #ifndef ENETRESET
703 #define ENETRESET WSAENETRESET
704 #endif
705 #ifndef EOPNOTSUPP
706 #define EOPNOTSUPP WSAEOPNOTSUPP
707 #endif
708 #ifndef ESHUTDOWN
709 #define ESHUTDOWN WSAESHUTDOWN
710 #endif
711 #ifndef EMSGSIZE
712 #define EMSGSIZE WSAEMSGSIZE
713 #endif
714 #ifndef ECONNABORTED
715 #define ECONNABORTED WSAECONNABORTED
716 #endif
717 #ifndef ECONNRESET
718 #define ECONNRESET WSAECONNRESET
719 #endif
720 #ifndef EHOSTDOWN
721 #define EHOSTDOWN WSAEHOSTDOWN
722 #endif
723 
724 // For the future:
725 // Handle ERROR_NETNAME_DELETED=64
726 #endif //FZ_WINDOWS
727 
728 }
729 
730 #endif
fz::socket_event_flag::connection
@ connection
fz::socket_error_string
std::string socket_error_string(int error)
Gets a symbolic name for socket errors.
fz::buffer
The buffer class is a simple buffer where data can be appended at the end and consumed at the front....
Definition: buffer.hpp:25
fz::listen_socket_state
listen_socket_state
Definition: socket.hpp:239
fz::socket_layer::peer_port
virtual int peer_port(int &error) const override
Definition: socket.hpp:591
fz::socket_state
socket_state
State transitions are monotonically increasing.
Definition: socket.hpp:326
fz::socket_state::connecting
@ connecting
fz::listen_socket_state::none
@ none
How the socket is initially.
fz::duration
The duration class represents a time interval in milliseconds.
Definition: time.hpp:271
fz::socket_state::shut_down
@ shut_down
Write side has finished shutting down. Receive still working normally.
fz::simple_event
This is the recommended event class.
Definition: event.hpp:65
fz::listen_socket_state::listening
@ listening
Only in listening state you can get a connection event.
fz::socket_event_flag::write
@ write
fz::socket_state::failed
@ failed
Socket has failed. Further events disabled.
fz::socket_event_flag::read
@ read
fz::socket_layer
A base class for socket layers.
Definition: socket.hpp:567
fz::change_socket_event_handler
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.
fz::socket
IPv6 capable, non-blocking socket class.
Definition: socket.hpp:407
fz::socket_event_flag
socket_event_flag
The type of a socket event.
Definition: socket.hpp:33
fz::socket_event_source::root
socket_event_source * root() const
Gets the root source.
Definition: socket.hpp:92
fz::socket_state::connected
@ connected
Socket is in its normal working state. You can get send and receive events.
event_handler.hpp
Declares the event_handler class.
fz::native_string
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
fz::socket::shutdown_read
virtual int shutdown_read() override
Definition: socket.hpp:539
fz::remove_socket_events
void remove_socket_events(event_handler *handler, socket_event_source const *const source)
Remove all pending socket events from source sent to handler.
fz::socket_event_flag::connection_next
@ connection_next
fz::socket_layer::peer_host
virtual native_string peer_host() const override
Definition: socket.hpp:584
fz::socket_descriptor
Lightweight holder for socket descriptors.
Definition: socket.hpp:249
fz::listen_socket
Simple Listen socket.
Definition: socket.hpp:284
fz::socket_event
simple_event< socket_event_type, socket_event_source *, socket_event_flag, int > socket_event
Definition: socket.hpp:106
fz::socket_state::closed
@ closed
Socket has been closed. Further events disabled.
fz::socket_interface
Interface for sockets.
Definition: socket.hpp:358
iputils.hpp
Various functions to deal with IP address strings.
fz::socket_error_description
native_string socket_error_description(int error)
Gets a human-readable, translated description of the error.
fz::socket_event_source
All classes sending socket events should derive from this.
Definition: socket.hpp:83
fz::event_handler
Simple handler for asynchronous event processing.
Definition: event_handler.hpp:54
libfilezilla.hpp
Sets some global macros and further includes string.hpp.
fz::scoped_lock
A simple scoped lock.
Definition: mutex.hpp:64
fz::socket_state::none
@ none
How the socket is initially.
fz::socket_layer::next
socket_interface & next()
The next layer further down. Usually another layer or the actual socket.
Definition: socket.hpp:594
fz::thread_pool
A dumb thread-pool for asynchronous tasks.
Definition: thread_pool.hpp:62
fz::socket_base
Common base clase for fz::socket and fz::listen_socket.
Definition: socket.hpp:165
fz::socket_state::shutting_down
@ shutting_down
fz::hostaddress_event
simple_event< hostaddress_event_type, socket_event_source *, std::string > hostaddress_event
Definition: socket.hpp:138
fz
The namespace used by libfilezilla.
Definition: apply.hpp:17