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 
28 {
35 
40  connection,
41 
46  read,
47 
52  write
53 };
54 
63 class FZ_PUBLIC_SYMBOL socket_event_source
64 {
65 public:
66  virtual ~socket_event_source() = default;
67 
73  return root_;
74  }
75 
76 protected:
77  socket_event_source() = default;
79  : root_(root)
80  {}
81 
82  socket_event_source* const root_{};
83 };
84 
86 struct socket_event_type;
87 
109 
111 struct hostaddress_event_type{};
112 
117 
124 void FZ_PUBLIC_SYMBOL remove_socket_events(event_handler * handler, socket_event_source const* const source);
125 
135 void FZ_PUBLIC_SYMBOL change_socket_event_handler(event_handler * old_handler, event_handler * new_handler, socket_event_source const* const source);
136 
138 class socket_thread;
139 
141 class FZ_PUBLIC_SYMBOL socket_base
142 {
143 public:
151  int set_buffer_sizes(int size_receive, int size_send);
152 
154  address_type address_family() const;
155 
161  std::string local_ip(bool strip_zone_index = false) const;
162 
168  int local_port(int& error) const;
169 
170  static std::string address_to_string(sockaddr const* addr, int addr_len, bool with_port = true, bool strip_zone_index = false);
171  static std::string address_to_string(char const* buf, int buf_len);
172 
178  bool bind(std::string const& address);
179 
180 #if FZ_WINDOWS
181  typedef intptr_t socket_t;
182 #else
183  typedef int socket_t;
184 #endif
185 
186 protected:
187  friend class socket_thread;
188 
189  socket_base(thread_pool& pool, event_handler* evt_handler, socket_event_source* ev_source);
190  virtual ~socket_base() = default;
191 
192  int close();
193 
194  void do_set_event_handler(event_handler* pEvtHandler);
195 
196  // Note: Unlocks the lock.
197  void detach_thread(scoped_lock & l);
198 
199  thread_pool & thread_pool_;
200  event_handler* evt_handler_;
201 
202  socket_thread* socket_thread_{};
203 
204  socket_event_source * const ev_source_{};
205 
206  socket_t fd_{-1};
207 
208  unsigned int port_{};
209 
210  int family_;
211 
212  int buffer_sizes_[2];
213 };
214 
215 class socket;
216 
218 {
220  none,
221 
223  listening,
224 };
225 
227 class FZ_PUBLIC_SYMBOL socket_descriptor final
228 {
229 public:
230  socket_descriptor() = default;
232  explicit socket_descriptor(socket_base::socket_t fd) noexcept : fd_(fd) {}
233 
234  socket_descriptor(socket_descriptor const&) = delete;
235  socket_descriptor& operator=(socket_descriptor const&) = delete;
236 
237  socket_descriptor(socket_descriptor && rhs) noexcept { std::swap(fd_, rhs.fd_); }
238  socket_descriptor& operator=(socket_descriptor && rhs) noexcept {
239  std::swap(fd_, rhs.fd_);
240  return *this;
241  }
242 
243  socket_base::socket_t detach() {
244  socket_base::socket_t ret = fd_;
245  fd_ = -1;
246  return ret;
247  }
248 
249  explicit operator bool() const { return fd_ != -1; }
250 
251 private:
252  socket_base::socket_t fd_{-1};
253 };
254 
262 class FZ_PUBLIC_SYMBOL listen_socket final : public socket_base, public socket_event_source
263 {
264  friend class socket_base;
265  friend class socket_thread;
266 public:
267  listen_socket(thread_pool& pool, event_handler* evt_handler);
268  virtual ~listen_socket();
269 
270  listen_socket(listen_socket const&) = delete;
271  listen_socket& operator=(listen_socket const&) = delete;
272 
281  int listen(address_type family, int port = 0);
282 
284  std::unique_ptr<socket> accept(int& error);
285 
292  socket_descriptor fast_accept(int& error);
293 
294  listen_socket_state get_state() const;
295 
296  void set_event_handler(event_handler* pEvtHandler) {
297  do_set_event_handler(pEvtHandler);
298  }
299 
300 private:
301  listen_socket_state state_{};
302 };
303 
304 
306 enum class socket_state : unsigned char
307 {
309  none,
310 
314  connecting,
315 
317  connected,
318 
322 
324  shut_down,
325 
327  closed,
328 
330  failed
331 };
332 
338 class FZ_PUBLIC_SYMBOL socket_interface : public socket_event_source
339 {
340 public:
341  socket_interface(socket_interface const&) = delete;
342  socket_interface& operator=(socket_interface const&) = delete;
343 
344  virtual int read(void* buffer, unsigned int size, int& error) = 0;
345  virtual int write(void const* buffer, unsigned int size, int& error) = 0;
346 
347  virtual void set_event_handler(event_handler* pEvtHandler) = 0;
348 
349  virtual native_string peer_host() const = 0;
350  virtual int peer_port(int& error) const = 0;
351 
352  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) = 0;
353 
354  virtual fz::socket_state get_state() const = 0;
355 
366  virtual int shutdown() = 0;
367 
369  virtual int shutdown_read() = 0;
370 
371 protected:
372  socket_interface() = default;
373 
374  explicit socket_interface(socket_event_source * root)
375  : socket_event_source(root)
376  {}
377 };
378 
387 class FZ_PUBLIC_SYMBOL socket final : public socket_base, public socket_interface
388 {
389  friend class socket_thread;
390 public:
391  socket(thread_pool& pool, event_handler* evt_handler);
392  virtual ~socket();
393 
394  socket(socket const&) = delete;
395  socket& operator=(socket const&) = delete;
396 
397  static std::unique_ptr<socket> from_descriptor(socket_descriptor && desc, thread_pool & pool, int & error);
398 
399  socket_state get_state() const override;
400  bool is_connected() const {
401  socket_state s = get_state();
403  };
404 
418  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override;
419 
435  virtual int read(void *buffer, unsigned int size, int& error) override;
436 
452  virtual int write(void const* buffer, unsigned int size, int& error) override;
453 
459  std::string peer_ip(bool strip_zone_index = false) const;
460 
462  virtual native_string peer_host() const override;
463 
469  virtual int peer_port(int& error) const override;
470 
477  int ideal_send_buffer_size();
478 
483  void retrigger(socket_event_flag event);
484 
485  virtual int shutdown() override;
486 
487  virtual void set_event_handler(event_handler* pEvtHandler) override;
488 
489  enum
490  {
492  flag_nodelay = 0x01,
493 
495  flag_keepalive = 0x02
496  };
497 
498  int flags() const { return flags_; }
499 
501  void set_flags(int flags, bool enable);
502 
504  void set_flags(int flags);
505 
511  void set_keepalive_interval(duration const& d);
512 
513  virtual int shutdown_read() override { return 0; }
514 
515 private:
516  friend class socket_base;
517  friend class listen_socket;
518  native_string host_;
519 
520  duration keepalive_interval_;
521 
522  int flags_{};
523  socket_state state_{};
524 };
525 
541 class FZ_PUBLIC_SYMBOL socket_layer : public socket_interface
542 {
543 public:
544  explicit socket_layer(event_handler* handler, socket_interface& next_layer, bool event_passthrough);
545  virtual ~socket_layer();
546 
547  socket_layer(socket_layer const&) = delete;
548  socket_layer& operator=(socket_layer const&) = delete;
549 
551  virtual void set_event_handler(event_handler* handler) override;
552 
558  virtual native_string peer_host() const override { return next_layer_.peer_host(); }
559 
565  virtual int peer_port(int& error) const override { return next_layer_.peer_port(error); }
566 
568  socket_interface& next() { return next_layer_; }
569 
591  virtual int shutdown_read() override;
592 
593 protected:
599  void forward_socket_event(socket_event_source* source, socket_event_flag t, int error);
600 
606  void forward_hostaddress_event(socket_event_source* source, std::string const& address);
607 
612  void set_event_passthrough();
613 
614  event_handler* event_handler_{};
615  socket_interface& next_layer_;
616  bool event_passthrough_{};
617 };
618 
627 std::string FZ_PUBLIC_SYMBOL socket_error_string(int error);
628 
632 native_string FZ_PUBLIC_SYMBOL socket_error_description(int error);
633 
634 
635 #ifdef FZ_WINDOWS
636 
637 #ifndef EISCONN
638 #define EISCONN WSAEISCONN
639 #endif
640 #ifndef EINPROGRESS
641 #define EINPROGRESS WSAEINPROGRESS
642 #endif
643 #ifndef EAFNOSUPPORT
644 #define EAFNOSUPPORT WSAEAFNOSUPPORT
645 #endif
646 #ifndef EADDRINUSE
647 #define EADDRINUSE WSAEADDRINUSE
648 #endif
649 #ifndef ENOBUFS
650 #define ENOBUFS WSAENOBUFS
651 #endif
652 #ifndef EPROTONOSUPPORT
653 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
654 #endif
655 #ifndef EALREADY
656 #define EALREADY WSAEALREADY
657 #endif
658 #ifndef ECONNREFUSED
659 #define ECONNREFUSED WSAECONNREFUSED
660 #endif
661 #ifndef ENOTSOCK
662 #define ENOTSOCK WSAENOTSOCK
663 #endif
664 #ifndef ETIMEDOUT
665 #define ETIMEDOUT WSAETIMEDOUT
666 #endif
667 #ifndef ENETUNREACH
668 #define ENETUNREACH WSAENETUNREACH
669 #endif
670 #ifndef EHOSTUNREACH
671 #define EHOSTUNREACH WSAEHOSTUNREACH
672 #endif
673 #ifndef ENOTCONN
674 #define ENOTCONN WSAENOTCONN
675 #endif
676 #ifndef ENETRESET
677 #define ENETRESET WSAENETRESET
678 #endif
679 #ifndef EOPNOTSUPP
680 #define EOPNOTSUPP WSAEOPNOTSUPP
681 #endif
682 #ifndef ESHUTDOWN
683 #define ESHUTDOWN WSAESHUTDOWN
684 #endif
685 #ifndef EMSGSIZE
686 #define EMSGSIZE WSAEMSGSIZE
687 #endif
688 #ifndef ECONNABORTED
689 #define ECONNABORTED WSAECONNABORTED
690 #endif
691 #ifndef ECONNRESET
692 #define ECONNRESET WSAECONNRESET
693 #endif
694 #ifndef EHOSTDOWN
695 #define EHOSTDOWN WSAEHOSTDOWN
696 #endif
697 
698 // For the future:
699 // Handle ERROR_NETNAME_DELETED=64
700 #endif //FZ_WINDOWS
701 
702 }
703 
704 #endif
std::string socket_error_string(int error)
Gets a symbolic name for socket errors.
A simple scoped lock.
Definition: mutex.hpp:64
Interface for sockets.
Definition: socket.hpp:338
Lightweight holder for socket descriptors.
Definition: socket.hpp:227
simple_event< socket_event_type, socket_event_source *, socket_event_flag, int > socket_event
Definition: socket.hpp:86
virtual int shutdown_read() override
Definition: socket.hpp:513
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:568
Declares the event_handler class.
Socket has failed. Further events disabled.
Common base clase for fz::socket and fz::listen_socket.
Definition: socket.hpp:141
Simple Listen socket.
Definition: socket.hpp:262
Various functions to deal with IP address strings.
Socket has been closed. Further events disabled.
void change_socket_event_handler(event_handler *old_handler, event_handler *new_handler, socket_event_source const *const source)
Changes all pending socket events from source.
This is the recommended event class.
Definition: event.hpp:63
simple_event< hostaddress_event_type, socket_event_source *, std::string > hostaddress_event
Definition: socket.hpp:116
IPv6 capable, non-blocking socket class.
Definition: socket.hpp:387
socket_event_source * root() const
Gets the root source.
Definition: socket.hpp:72
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:541
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:306
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:217
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.
All classes sending socket events should derive from this.
Definition: socket.hpp:63
The duration class represents a time interval in milliseconds.
Definition: time.hpp:271
Sets some global macros and further includes string.hpp.
How the socket is initially.
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:23
A dumb thread-pool for asynchronous tasks.
Definition: thread_pool.hpp:62
virtual native_string peer_host() const override
Definition: socket.hpp:558
virtual int peer_port(int &error) const override
Definition: socket.hpp:565
socket_event_flag
The type of a socket event.
Definition: socket.hpp:27