libfilezilla
socket.hpp
1 #ifndef LIBFILEZILLA_SOCKET_HEADER
2 #define LIBFILEZILLA_SOCKET_HEADER
3 
4 #include "libfilezilla.hpp"
5 
6 #include "event_handler.hpp"
7 #include "iputils.hpp"
8 
9 #include <memory>
10 
11 #include <errno.h>
12 
14 struct sockaddr;
15 
16 namespace fz {
17 class thread_pool;
18 
19 enum class socket_event_flag
20 {
21  // This is a nonfatal condition. It
22  // means there are additional addresses to try.
23  connection_next,
24 
25  connection,
26  read,
27  write
28 };
29 
38 class FZ_PUBLIC_SYMBOL socket_event_source
39 {
40 public:
41  virtual ~socket_event_source() = default;
42 
48  return root_;
49  }
50 
51 protected:
52  socket_event_source() = default;
54  : root_(root)
55  {}
56 
57  socket_event_source* const root_{};
58 };
59 
61 struct socket_event_type;
62 
79 
81 struct hostaddress_event_type{};
82 
87 
94 void FZ_PUBLIC_SYMBOL remove_socket_events(event_handler * handler, socket_event_source const* const source);
95 
106 void FZ_PUBLIC_SYMBOL change_socket_event_handler(event_handler * old_handler, event_handler * new_handler, socket_event_source const* const source);
107 
109 class socket_thread;
110 
112 class FZ_PUBLIC_SYMBOL socket_base
113 {
114 public:
122  int set_buffer_sizes(int size_receive, int size_send);
123 
125  address_type address_family() const;
126 
132  std::string local_ip(bool strip_zone_index = false) const;
133 
139  int local_port(int& error) const;
140 
141  static std::string address_to_string(sockaddr const* addr, int addr_len, bool with_port = true, bool strip_zone_index = false);
142  static std::string address_to_string(char const* buf, int buf_len);
143 
149  bool bind(std::string const& address);
150 
151 #if FZ_WINDOWS
152  typedef intptr_t socket_t;
153 #else
154  typedef int socket_t;
155 #endif
156 
157 protected:
158  friend class socket_thread;
159 
160  socket_base(thread_pool& pool, event_handler* evt_handler, socket_event_source* ev_source);
161  virtual ~socket_base() = default;
162 
163  int close();
164 
165  void do_set_event_handler(event_handler* pEvtHandler);
166 
167  // Note: Unlocks the lock.
168  void detach_thread(scoped_lock & l);
169 
170  thread_pool & thread_pool_;
171  event_handler* evt_handler_;
172 
173  socket_t fd_{-1};
174 
175  socket_thread* socket_thread_{};
176 
177  unsigned int port_{};
178 
179  int family_;
180 
181  int buffer_sizes_[2];
182 
183  socket_event_source * const ev_source_{};
184 };
185 
186 class socket;
187 
189 {
191  none,
192 
194  listening,
195 };
196 
204 class FZ_PUBLIC_SYMBOL listen_socket final : public socket_base, public socket_event_source
205 {
206  friend class socket_base;
207  friend class socket_thread;
208 public:
209  listen_socket(thread_pool& pool, event_handler* evt_handler);
210  virtual ~listen_socket();
211 
212  listen_socket(listen_socket const&) = delete;
213  listen_socket& operator=(listen_socket const&) = delete;
214 
223  int listen(address_type family, int port = 0);
224 
226  std::unique_ptr<socket> accept(int& error);
227 
228  listen_socket_state get_state() const;
229 
230  void set_event_handler(event_handler* pEvtHandler) {
231  do_set_event_handler(pEvtHandler);
232  }
233 
234 private:
235  listen_socket_state state_{};
236 };
237 
238 
240 enum class socket_state
241 {
243  none,
244 
248  connecting,
249 
251  connected,
252 
256 
258  shut_down,
259 
261  closed,
262 
264  failed
265 };
266 
272 class FZ_PUBLIC_SYMBOL socket_interface : public socket_event_source
273 {
274 public:
275  socket_interface(socket_interface const&) = delete;
276  socket_interface& operator=(socket_interface const&) = delete;
277 
278  virtual int read(void* buffer, unsigned int size, int& error) = 0;
279  virtual int write(void const* buffer, unsigned int size, int& error) = 0;
280 
281  virtual void set_event_handler(event_handler* pEvtHandler) = 0;
282 
283  virtual native_string peer_host() const = 0;
284  virtual int peer_port(int& error) const = 0;
285 
286  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) = 0;
287 
288  virtual fz::socket_state get_state() const = 0;
289 
296  virtual int shutdown() = 0;
297 
298 protected:
299  socket_interface() = default;
300 
301  explicit socket_interface(socket_event_source * root)
302  : socket_event_source(root)
303  {}
304 };
305 
314 class FZ_PUBLIC_SYMBOL socket final : public socket_base, public socket_interface
315 {
316  friend class socket_thread;
317 public:
318  socket(thread_pool& pool, event_handler* evt_handler);
319  virtual ~socket();
320 
321  socket(socket const&) = delete;
322  socket& operator=(socket const&) = delete;
323 
324  socket_state get_state() const override;
325  bool is_connected() const {
326  socket_state s = get_state();
328  };
329 
343  virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override;
344 
360  virtual int read(void *buffer, unsigned int size, int& error) override;
361 
377  virtual int write(void const* buffer, unsigned int size, int& error) override;
378 
384  std::string peer_ip(bool strip_zone_index = false) const;
385 
387  virtual native_string peer_host() const override;
388 
394  virtual int peer_port(int& error) const override;
395 
402  int ideal_send_buffer_size();
403 
408  void retrigger(socket_event_flag event);
409 
410  virtual int shutdown() override;
411 
412  virtual void set_event_handler(event_handler* pEvtHandler) override;
413 
414  enum
415  {
417  flag_nodelay = 0x01,
418 
420  flag_keepalive = 0x02
421  };
422 
423  int flags() const { return flags_; }
424  void set_flags(int flags);
425 
431  void set_keepalive_interval(duration const& d);
432 
433 private:
434  friend class socket_base;
435  friend class listen_socket;
436  native_string host_;
437 
438  socket_state state_{};
439 
440  int flags_{};
441  duration keepalive_interval_;
442 };
443 
444 #ifdef FZ_WINDOWS
445 
446 #ifndef EISCONN
447 #define EISCONN WSAEISCONN
448 #endif
449 #ifndef EINPROGRESS
450 #define EINPROGRESS WSAEINPROGRESS
451 #endif
452 #ifndef EAFNOSUPPORT
453 #define EAFNOSUPPORT WSAEAFNOSUPPORT
454 #endif
455 #ifndef EADDRINUSE
456 #define EADDRINUSE WSAEADDRINUSE
457 #endif
458 #ifndef ENOBUFS
459 #define ENOBUFS WSAENOBUFS
460 #endif
461 #ifndef EPROTONOSUPPORT
462 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
463 #endif
464 #ifndef EALREADY
465 #define EALREADY WSAEALREADY
466 #endif
467 #ifndef ECONNREFUSED
468 #define ECONNREFUSED WSAECONNREFUSED
469 #endif
470 #ifndef ENOTSOCK
471 #define ENOTSOCK WSAENOTSOCK
472 #endif
473 #ifndef ETIMEDOUT
474 #define ETIMEDOUT WSAETIMEDOUT
475 #endif
476 #ifndef ENETUNREACH
477 #define ENETUNREACH WSAENETUNREACH
478 #endif
479 #ifndef EHOSTUNREACH
480 #define EHOSTUNREACH WSAEHOSTUNREACH
481 #endif
482 #ifndef ENOTCONN
483 #define ENOTCONN WSAENOTCONN
484 #endif
485 #ifndef ENETRESET
486 #define ENETRESET WSAENETRESET
487 #endif
488 #ifndef EOPNOTSUPP
489 #define EOPNOTSUPP WSAEOPNOTSUPP
490 #endif
491 #ifndef ESHUTDOWN
492 #define ESHUTDOWN WSAESHUTDOWN
493 #endif
494 #ifndef EMSGSIZE
495 #define EMSGSIZE WSAEMSGSIZE
496 #endif
497 #ifndef ECONNABORTED
498 #define ECONNABORTED WSAECONNABORTED
499 #endif
500 #ifndef ECONNRESET
501 #define ECONNRESET WSAECONNRESET
502 #endif
503 #ifndef EHOSTDOWN
504 #define EHOSTDOWN WSAEHOSTDOWN
505 #endif
506 
507 // For the future:
508 // Handle ERROR_NETNAME_DELETED=64
509 #endif //FZ_WINDOWS
510 
511 }
512 
513 #endif
A simple scoped lock.
Definition: mutex.hpp:61
Interface for sockets.
Definition: socket.hpp:272
simple_event< socket_event_type, socket_event_source *, socket_event_flag, int > socket_event
Definition: socket.hpp:61
Simple handler for asynchronous event processing.
Definition: event_handler.hpp:54
Declares the event_handler class.
Common base clase for fz::socket and fz::listen_socket.
Definition: socket.hpp:112
Socket has been closed. Further events disabled.
Definition: socket.hpp:204
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.
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:86
IPv6 capable, non-blocking socket class.
Definition: socket.hpp:314
socket_event_source * root() const
Gets the root source.
Definition: socket.hpp:47
void remove_socket_events(event_handler *handler, socket_event_source const *const source)
Remove all pending socket events from source sent to handler.
std::wstring native_string
A string in the system's native character type and encoding. Note: This typedef changes depending on...
Definition: string.hpp:32
socket_state
State transitions are monotonically increasing.
Definition: socket.hpp:240
Only in listening state you can get a connection event.
The namespace used by libfilezilla.
Definition: apply.hpp:16
listen_socket_state
Definition: socket.hpp:188
All classes sending socket events should derive from this.
Definition: socket.hpp:38
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
Definition: thread_pool.hpp:59
Write side has finished shutting down. Receive still working normally.