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_t fd_{-1};
203 
204  socket_thread* socket_thread_{};
205 
206  unsigned int port_{};
207 
208  int family_;
209 
210  int buffer_sizes_[2];
211 
212  socket_event_source * const ev_source_{};
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
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  socket_state state_{};
521 
522  int flags_{};
523  duration keepalive_interval_;
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.
Common base clase for fz::socket and fz::listen_socket.
Definition: socket.hpp:141
Socket has been closed. Further events disabled.
Simple Listen socket.
Definition: socket.hpp:262
Various functions to deal with IP address strings.
Socket is in its normal working state. You can get send and receive events.
Socket has failed. 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&#39;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.
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.
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
Write side has finished shutting down. Receive still working normally.
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