Move all the connect() logic from TCPSocketHandler into a subclass
This way, TCPSocketHandler only deal with the message sending/receiving, not the connect() or anything else. This will be used for implementing servers (because when a client is accepted, we don’t need all the connect() and dns resolution stuff).
This commit is contained in:
@@ -20,10 +20,8 @@
|
||||
#include <list>
|
||||
|
||||
/**
|
||||
* An interface, with a series of callbacks that should be implemented in
|
||||
* subclasses that deal with a socket. These callbacks are called on various events
|
||||
* (read/write/timeout, etc) when they are notified to a poller
|
||||
* (select/poll/epoll etc)
|
||||
* Does all the read/write, buffering etc. With optional tls.
|
||||
* But doesn’t do any connect() or accept() or anything else.
|
||||
*/
|
||||
class TCPSocketHandler: public SocketHandler
|
||||
{
|
||||
@@ -36,13 +34,6 @@ public:
|
||||
TCPSocketHandler& operator=(const TCPSocketHandler&) = delete;
|
||||
TCPSocketHandler& operator=(TCPSocketHandler&&) = delete;
|
||||
|
||||
/**
|
||||
* Connect to the remote server, and call on_connected() if this
|
||||
* succeeds. If tls is true, we set use_tls to true and will also call
|
||||
* start_tls() when the connection succeeds.
|
||||
*/
|
||||
void connect(const std::string& address, const std::string& port, const bool tls);
|
||||
void connect() override final;
|
||||
/**
|
||||
* Reads raw data from the socket. And pass it to parse_in_buffer()
|
||||
* If we are using TLS on this connection, we call tls_recv()
|
||||
@@ -67,25 +58,7 @@ public:
|
||||
/**
|
||||
* Close the connection, remove us from the poller
|
||||
*/
|
||||
void close();
|
||||
/**
|
||||
* Called by a TimedEvent, when the connection did not succeed or fail
|
||||
* after a given time.
|
||||
*/
|
||||
void on_connection_timeout();
|
||||
/**
|
||||
* Called when the connection is successful.
|
||||
*/
|
||||
virtual void on_connected() = 0;
|
||||
/**
|
||||
* Called when the connection fails. Not when it is closed later, just at
|
||||
* the connect() call.
|
||||
*/
|
||||
virtual void on_connection_failed(const std::string& reason) = 0;
|
||||
/**
|
||||
* Called when we detect a disconnection from the remote host.
|
||||
*/
|
||||
virtual void on_connection_close(const std::string& error) = 0;
|
||||
virtual void close();
|
||||
/**
|
||||
* Handle/consume (some of) the data received so far. The data to handle
|
||||
* may be in the in_buf buffer, or somewhere else, depending on what
|
||||
@@ -93,6 +66,9 @@ public:
|
||||
* should be truncated, only the unused data should be left untouched.
|
||||
*
|
||||
* The size argument is the size of the last chunk of data that was added to the buffer.
|
||||
*
|
||||
* The function should call consume_in_buffer, with the size that was consumed by the
|
||||
* “parsing”, and thus to be removed from the input buffer.
|
||||
*/
|
||||
virtual void parse_in_buffer(const size_t size) = 0;
|
||||
#ifdef BOTAN_FOUND
|
||||
@@ -105,18 +81,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
bool is_connected() const override final;
|
||||
bool is_connecting() const;
|
||||
bool is_using_tls() const;
|
||||
std::string get_port() const;
|
||||
std::chrono::system_clock::time_point connection_date;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Initialize the socket with the parameters contained in the given
|
||||
* addrinfo structure.
|
||||
*/
|
||||
void init_socket(const struct addrinfo* rp);
|
||||
/**
|
||||
* Reads from the socket into the provided buffer. If an error occurs
|
||||
* (read returns <= 0), the handling of the error is done here (close the
|
||||
@@ -137,12 +104,14 @@ private:
|
||||
void raw_send(std::string&& data);
|
||||
|
||||
#ifdef BOTAN_FOUND
|
||||
protected:
|
||||
/**
|
||||
* Create the TLS::Client object, with all the callbacks etc. This must be
|
||||
* called only when we know we are able to send TLS-encrypted data over
|
||||
* the socket.
|
||||
*/
|
||||
void start_tls();
|
||||
void start_tls(const std::string& address, const std::string& port);
|
||||
private:
|
||||
/**
|
||||
* An additional step to pass the data into our tls object to decrypt it
|
||||
* before passing it to parse_in_buffer.
|
||||
@@ -185,20 +154,11 @@ private:
|
||||
* Where data is added, when we want to send something to the client.
|
||||
*/
|
||||
std::vector<std::string> out_buf;
|
||||
/**
|
||||
* DNS resolver
|
||||
*/
|
||||
Resolver resolver;
|
||||
/**
|
||||
* Keep the details of the addrinfo returned by the resolver that
|
||||
* triggered a EINPROGRESS error when connect()ing to it, to reuse it
|
||||
* directly when connect() is called again.
|
||||
*/
|
||||
struct addrinfo addrinfo;
|
||||
struct sockaddr_in6 ai_addr;
|
||||
socklen_t ai_addrlen;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Whether we are using TLS on this connection or not.
|
||||
*/
|
||||
bool use_tls;
|
||||
/**
|
||||
* Where data read from the socket is added until we can extract a full
|
||||
* and meaningful “message” from it.
|
||||
@@ -207,9 +167,9 @@ protected:
|
||||
*/
|
||||
std::string in_buf;
|
||||
/**
|
||||
* Whether we are using TLS on this connection or not.
|
||||
* Remove the given “size” first bytes from our in_buf.
|
||||
*/
|
||||
bool use_tls;
|
||||
void consume_in_buffer(const std::size_t size);
|
||||
/**
|
||||
* Provide a buffer in which data can be directly received. This can be
|
||||
* used to avoid copying data into in_buf before using it. If no buffer
|
||||
@@ -219,31 +179,12 @@ protected:
|
||||
*/
|
||||
virtual void* get_receive_buffer(const size_t size) const;
|
||||
/**
|
||||
* Hostname we are connected/connecting to
|
||||
* Called when we detect a disconnection from the remote host.
|
||||
*/
|
||||
std::string address;
|
||||
/**
|
||||
* Port we are connected/connecting to
|
||||
*/
|
||||
std::string port;
|
||||
|
||||
bool connected;
|
||||
bool connecting;
|
||||
|
||||
bool hostname_resolution_failed;
|
||||
|
||||
/**
|
||||
* Address to bind the socket to, before calling connect().
|
||||
* If empty, it’s equivalent to binding to INADDR_ANY.
|
||||
*/
|
||||
std::string bind_addr;
|
||||
virtual void on_connection_close(const std::string& error) = 0;
|
||||
virtual void on_connection_failed(const std::string& error) = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Display the resolved IP, just for information purpose.
|
||||
*/
|
||||
void display_resolved_ip(struct addrinfo* rp) const;
|
||||
|
||||
#ifdef BOTAN_FOUND
|
||||
/**
|
||||
* Botan stuff to manipulate a TLS session.
|
||||
|
||||
Reference in New Issue
Block a user