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
21struct sockaddr;
22
23namespace fz {
24class thread_pool;
25
34{
40 connection_next = 0x1,
41
46 connection = 0x2,
47
52 read = 0x4,
53
58 write = 0x8,
59};
60
61inline 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}
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}
68inline socket_event_flag& operator|=(socket_event_flag& lhs, socket_event_flag rhs)
69{
70 lhs = lhs | rhs;
71 return lhs;
72}
73
74
83class FZ_PUBLIC_SYMBOL socket_event_source
84{
85public:
86 virtual ~socket_event_source() = default;
87
93 return root_;
94 }
95
96protected:
97 socket_event_source() = delete;
99 : root_(root)
100 {}
101
102 socket_event_source* const root_{};
103};
104
106struct socket_event_type;
107
131
133struct hostaddress_event_type{};
134
139
146void FZ_PUBLIC_SYMBOL remove_socket_events(event_handler * handler, socket_event_source const* const source);
147
159fz::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
162class socket_thread;
163
165class FZ_PUBLIC_SYMBOL socket_base
166{
167public:
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
210protected:
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
237class socket;
238
240{
242 none,
243
245 listening,
246};
247
249class FZ_PUBLIC_SYMBOL socket_descriptor final
250{
251public:
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
273private:
274 socket_base::socket_t fd_{-1};
275};
276
284class FZ_PUBLIC_SYMBOL listen_socket final : public socket_base, public socket_event_source
285{
286 friend class socket_base;
287 friend class socket_thread;
288public:
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
315
316 listen_socket_state get_state() const;
317
318 void set_event_handler(event_handler* pEvtHandler);
319
320private:
321 listen_socket_state state_{};
322};
323
324
326enum class socket_state : unsigned char
327{
329 none,
330
335
337 connected,
338
342
344 shut_down,
345
347 closed,
348
350 failed
351};
352
358class FZ_PUBLIC_SYMBOL socket_interface : public socket_event_source
359{
360public:
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 template<typename T, std::enable_if_t<std::is_signed_v<T>, int> = 0>
368 int read(void* buffer, T size, int& error)
369 {
370 if (size < 0) {
371 error = EINVAL;
372 return -1;
373 }
374
375 return read(buffer, static_cast<unsigned int>(size), error);
376 }
377 template<typename T, std::enable_if_t<std::is_unsigned_v<T> && (sizeof(T) > sizeof(unsigned int)), int> = 0>
378 int read(void* buffer, T size, int& error)
379 {
380 if (size > std::numeric_limits<unsigned int>::max()) {
381 size = std::numeric_limits<unsigned int>::max();
382 }
383 return read(buffer, static_cast<unsigned int>(size), error);
384 }
385
386 template<typename T, std::enable_if_t<std::is_signed_v<T>, int> = 0>
387 int write(void const* buffer, T size, int& error)
388 {
389 if (size < 0) {
390 error = EINVAL;
391 return -1;
392 }
393
394 return write(buffer, static_cast<std::make_unsigned_t<T>>(size), error);
395 }
396 template<typename T, std::enable_if_t<std::is_unsigned_v<T> && (sizeof(T) > sizeof(unsigned int)), int> = 0>
397 int write(void const* buffer, T size, int& error)
398 {
399 if (size > std::numeric_limits<unsigned int>::max()) {
400 size = std::numeric_limits<unsigned int>::max();
401 }
402 return write(buffer, static_cast<unsigned int>(size), error);
403 }
404
405 virtual void set_event_handler(event_handler* pEvtHandler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) = 0;
406
407 virtual native_string peer_host() const = 0;
408 virtual int peer_port(int& error) const = 0;
409
410 virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) = 0;
411
412 virtual fz::socket_state get_state() const = 0;
413
424 virtual int shutdown() = 0;
425
427 virtual int shutdown_read() = 0;
428
429protected:
430 socket_interface() = delete;
431
433 : socket_event_source(root)
434 {}
435};
436
445class FZ_PUBLIC_SYMBOL socket final : public socket_base, public socket_interface
446{
447 friend class socket_thread;
448public:
449 socket(thread_pool& pool, event_handler* evt_handler);
450 virtual ~socket();
451
452 socket(socket const&) = delete;
453 socket& operator=(socket const&) = delete;
454
455 static std::unique_ptr<socket> from_descriptor(socket_descriptor && desc, thread_pool & pool, int & error, fz::event_handler * handler = nullptr);
456
457 socket_state get_state() const override;
458 bool is_connected() const {
459 socket_state s = get_state();
461 };
462
476 virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override;
477
493 virtual int read(void *buffer, unsigned int size, int& error) override;
494
510 virtual int write(void const* buffer, unsigned int size, int& error) override;
511
517 std::string peer_ip(bool strip_zone_index = false) const;
518
520 virtual native_string peer_host() const override;
521
527 virtual int peer_port(int& error) const override;
528
536
537 virtual int shutdown() override;
538
551 virtual void set_event_handler(event_handler* pEvtHandler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) override;
552
553 enum
554 {
556 flag_nodelay = 0x01,
557
559 flag_keepalive = 0x02
560 };
561
562 int flags() const { return flags_; }
563
565 void set_flags(int flags, bool enable);
566
568 void set_flags(int flags);
569
576
577 virtual int shutdown_read() override { return 0; }
578
579private:
580 friend class socket_base;
581 friend class listen_socket;
582 native_string host_;
583
584 duration keepalive_interval_;
585
586 int flags_{};
587 socket_state state_{};
588};
589
605class FZ_PUBLIC_SYMBOL socket_layer : public socket_interface
606{
607public:
608 explicit socket_layer(event_handler* handler, socket_interface& next_layer, bool event_passthrough);
609 virtual ~socket_layer();
610
611 socket_layer(socket_layer const&) = delete;
612 socket_layer& operator=(socket_layer const&) = delete;
613
615 virtual void set_event_handler(event_handler* handler, fz::socket_event_flag retrigger_block = fz::socket_event_flag{}) override;
616
622 virtual native_string peer_host() const override { return next_layer_.peer_host(); }
623
629 virtual int peer_port(int& error) const override { return next_layer_.peer_port(error); }
630
632 socket_interface& next() { return next_layer_; }
633
655 virtual int shutdown_read() override;
656
657 virtual int connect(native_string const& host, unsigned int port, address_type family = address_type::unknown) override {
658 return next_layer_.connect(host, port, family);
659 }
660
661 virtual int shutdown() override {
662 return next_layer_.shutdown();
663 }
664
665 virtual socket_state get_state() const override {
666 return next_layer_.get_state();
667 }
668
669protected:
676
682 void forward_hostaddress_event(socket_event_source* source, std::string const& address);
683
689
690 event_handler* event_handler_{};
691 socket_interface& next_layer_;
692 bool event_passthrough_{};
693};
694
703std::string FZ_PUBLIC_SYMBOL socket_error_string(int error);
704
708native_string FZ_PUBLIC_SYMBOL socket_error_description(int error);
709
710
711#ifdef FZ_WINDOWS
712
713#ifndef EISCONN
714#define EISCONN WSAEISCONN
715#endif
716#ifndef EINPROGRESS
717#define EINPROGRESS WSAEINPROGRESS
718#endif
719#ifndef EAFNOSUPPORT
720#define EAFNOSUPPORT WSAEAFNOSUPPORT
721#endif
722#ifndef EADDRINUSE
723#define EADDRINUSE WSAEADDRINUSE
724#endif
725#ifndef ENOBUFS
726#define ENOBUFS WSAENOBUFS
727#endif
728#ifndef EPROTONOSUPPORT
729#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
730#endif
731#ifndef EALREADY
732#define EALREADY WSAEALREADY
733#endif
734#ifndef ECONNREFUSED
735#define ECONNREFUSED WSAECONNREFUSED
736#endif
737#ifndef ENOTSOCK
738#define ENOTSOCK WSAENOTSOCK
739#endif
740#ifndef ETIMEDOUT
741#define ETIMEDOUT WSAETIMEDOUT
742#endif
743#ifndef ENETUNREACH
744#define ENETUNREACH WSAENETUNREACH
745#endif
746#ifndef EHOSTUNREACH
747#define EHOSTUNREACH WSAEHOSTUNREACH
748#endif
749#ifndef ENOTCONN
750#define ENOTCONN WSAENOTCONN
751#endif
752#ifndef ENETRESET
753#define ENETRESET WSAENETRESET
754#endif
755#ifndef EOPNOTSUPP
756#define EOPNOTSUPP WSAEOPNOTSUPP
757#endif
758#ifndef ESHUTDOWN
759#define ESHUTDOWN WSAESHUTDOWN
760#endif
761#ifndef EMSGSIZE
762#define EMSGSIZE WSAEMSGSIZE
763#endif
764#ifndef ECONNABORTED
765#define ECONNABORTED WSAECONNABORTED
766#endif
767#ifndef ECONNRESET
768#define ECONNRESET WSAECONNRESET
769#endif
770#ifndef EHOSTDOWN
771#define EHOSTDOWN WSAEHOSTDOWN
772#endif
773
774// For the future:
775// Handle ERROR_NETNAME_DELETED=64
776#endif //FZ_WINDOWS
777
778}
779
780#endif
The buffer class is a simple buffer where data can be appended at the end and consumed at the front....
Definition: buffer.hpp:26
The duration class represents a time interval in milliseconds.
Definition: time.hpp:286
Simple handler for asynchronous event processing.
Definition: event_handler.hpp:55
Simple Listen socket.
Definition: socket.hpp:285
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:65
This is the recommended event class.
Definition: event.hpp:66
Common base clase for fz::socket and fz::listen_socket.
Definition: socket.hpp:166
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 or ipv6, 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:250
All classes sending socket events should derive from this.
Definition: socket.hpp:84
socket_event_source * root() const
Gets the root source.
Definition: socket.hpp:92
Interface for sockets.
Definition: socket.hpp:359
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:606
void set_event_passthrough(socket_event_flag retrigger_block=socket_event_flag{})
virtual native_string peer_host() const override
Definition: socket.hpp:622
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:661
void forward_socket_event(socket_event_source *source, socket_event_flag t, int error)
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:629
virtual int shutdown_read() override
Check that all layers further down also have reached EOF.
socket_interface & next()
The next layer further down. Usually another layer or the actual socket.
Definition: socket.hpp:632
IPv6 capable, non-blocking socket class.
Definition: socket.hpp:446
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:577
A dumb thread-pool for asynchronous tasks.
Definition: thread_pool.hpp:63
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:240
@ 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:33
simple_event< hostaddress_event_type, socket_event_source *, std::string > hostaddress_event
Definition: socket.hpp:138
socket_state
State transitions are monotonically increasing.
Definition: socket.hpp:327
@ 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.
@ 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:106
socket_event_flag
The type of a socket event.
Definition: socket.hpp:34