Bond's TCP Library  1.0
Bond's TCP Client/Server Library
tcp::Client Class Reference

A blocking or non-blocking TCP client connection. More...

#include <tcpclient.h>

Collaboration diagram for tcp::Client:

Public Member Functions

 Client (EPoll &epoll, SSLContext *ctx, const int domain=AF_INET, bool blocking=false)
 Creates a blocking or a non-blocking client. More...
 
virtual ~Client ()
 Destroys the client. More...
 
SSLContextctx ()
 Returns the ssl context object. More...
 
SocketState state ()
 Return the client state. More...
 
in_port_t port ()
 Returns the port number used for the last call to connect()
 
in_addr_t addr ()
 Returns the ip address number used for the last call to connect()
 
virtual bool connect (const char *host, const char *service)
 Initiates a connection to a server. More...
 
- Public Member Functions inherited from tcp::DataSocket
 DataSocket (EPoll &epoll, const int domain=AF_INET, const int socket=0, const bool blocking=false, const int events=(EPOLLIN|EPOLLRDHUP))
 
size_t available ()
 Returns the number of bytes available in the inputBuffer.
 
size_t read (void *buffer, size_t size)
 Reads up to size bytes from inputBuffer into buffer. More...
 
size_t write (const void *buffer, size_t size)
 Writes the contents of buffer to the outputBuffer. More...
 
- Public Member Functions inherited from tcp::Socket
 Socket (EPoll &epoll, const int domain=AF_INET, const int socket=0, const bool blocking=false, const int events=(EPOLLIN|EPOLLRDHUP))
 Construct a blocking or non-blocking socket handle that responds to certain epoll events. More...
 
 ~Socket ()
 Closes and destroys the socket. More...
 
int socket () const
 Return the linux socket handle.
 
int domain () const
 Return the socket domain (AF_INET or AF_INET6)
 

Public Attributes

bool verifyPeer {false}
 If true, openSSL will attempt to verify the peer certificate.
 
string certfile
 The filename of the openSSL certificate in PEM format.
 
string keyfile
 The filename of the openSSL private key in PEM format.
 
string keypass
 The password for the private key file, if required.
 
bool checkPeerSubjectName { false }
 Check if the peer certificate subject name matches the host name. More...
 

Protected Member Functions

void handleEvents (uint32_t events) override
 Receive epoll events sent to this socket. More...
 
virtual void connected ()
 Called when the client connects to the server. More...
 
- Protected Member Functions inherited from tcp::DataSocket
void readToInputBuffer ()
 Reads all available data from the socket into inputBuffer.
 
void sendOutputBuffer ()
 Writes all available data from the outputBuffer to the socket. More...
 
void canSend (bool value)
 Sets the epoll event flags. More...
 
void handleEvents (uint32_t events) override
 Called by the EPoll class when the listening socket recieves an epoll event. More...
 
void disconnect () override
 Shuts down any SSL connection gracefully. More...
 
void disconnected () override
 Called when a connection is disconnected. More...
 
virtual void dataAvailable ()=0
 Called whenever new data is appended to the inputBuffer. More...
 
virtual SSLcreateSSL (SSLContext *context)
 Factory method for returning an SSL object. More...
 
- Protected Member Functions inherited from tcp::Socket
bool setEvents (int events)
 Changes which epoll events the socket listens for. More...
 
EPollepoll ()
 Returns a reference to the epoll instance used by this socket.
 

Friends

class SSL
 

Additional Inherited Members

- Protected Attributes inherited from tcp::DataSocket
SSLssl_ {nullptr}
 Exposes the underlying SSL record used for openSSL calls to descendant classes.
 
- Protected Attributes inherited from tcp::Socket
recursive_mutex mtx
 The mutex used to provide exclusive access to the socket.
 
SocketState state_
 Descendant classes can manipulate the socket state directly.
 

Detailed Description

A blocking or non-blocking TCP client connection.

Definition at line 35 of file tcpclient.h.

Constructor & Destructor Documentation

◆ Client()

tcp::Client::Client ( EPoll epoll,
SSLContext ctx,
const int  domain = AF_INET,
bool  blocking = false 
)
inline

Creates a blocking or a non-blocking client.

Parameters
doainEither AF_INET or AF_INET6
blockingIf true, a blocking socket will be created. Otherwise a non-blocking socket is created

Definition at line 42 of file tcpclient.h.

42 : DataSocket(epoll,domain,0,blocking), ctx_(ctx) {}

◆ ~Client()

tcp::Client::~Client ( )
virtual

Destroys the client.

Will call disconnect() first if necessary. This allows clients to be disconnected by destroying them.

Definition at line 9 of file tcpclient.cpp.

10 {
11  if (state_ == SocketState::CONNECTED) {
12  disconnect();
13  }
14 }

Member Function Documentation

◆ connect()

bool tcp::Client::connect ( const char *  host,
const char *  service 
)
virtual

Initiates a connection to a server.

If the client is a blocking client, the call blocks until a connection is established.

Parameters
host[in] The host or ip address of the server to connect to
service[in] The port number or service name to connect to
Remarks
Check the value of state() after a call to connect() to determine if the socket is CONNECTED or is CONNECTING
Returns
True if the connection was initiated

Definition at line 16 of file tcpclient.cpp.

17 {
18  struct addrinfo hints;
19  struct addrinfo *result, *rp;
20  int errorcode;
21 
22  if ( socket() == -1) {
23  return false;
24  }
25  mtx.lock();
26  memset(&result,0,sizeof(struct addrinfo));
27  memset(&hints,0,sizeof(struct addrinfo));
28  hints.ai_family = domain();
29  hints.ai_socktype = SOCK_STREAM;
30  hints.ai_flags |= AI_CANONNAME;
31  errorcode = getaddrinfo(host,service,&hints,&result);
32  if (errorcode != 0) {
33  fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(errorcode));
34  mtx.unlock();
35  return false;
36  }
37 
38  if (ssl_) {
39  delete ssl_;
40  ssl_ = nullptr;
41  }
42 
43  if (!certfile.empty() && !keyfile.empty()) {
44  ssl_ = createSSL(ctx_);
48  ssl_->setHostname(host);
49  }
50  if (!ssl_->setCertificateAndKey(certfile.c_str(),keyfile.c_str())) {
51  mtx.unlock();
52  return false;
53  }
54  if (!ssl_->setfd(socket())) {
55  mtx.unlock();
56  return false;
57  }
58  }
59 
60  log("Connecting to " + string(result->ai_canonname) + " on port " + string(service));
61 
62  for (rp = result; rp != nullptr; rp = rp->ai_next) {
63  if (::connect(socket(),rp->ai_addr,rp->ai_addrlen) == -1) {
64  if (errno == EINPROGRESS) {
65  state_ = SocketState::CONNECTING;
66  setEvents(EPOLLIN | EPOLLOUT | EPOLLRDHUP);
67  mtx.unlock();
68  return true;
69  } else {
70  setEvents(0);
71  error("connect",strerror(errno));
72  mtx.unlock();
73  return false;
74  }
75  } else {
76  connected();
77  mtx.unlock();
78  return true;
79  }
80  }
81  error("Could not find host " + string(host));
82  freeaddrinfo(result);
83  mtx.unlock();
84  return false;
85 }
Here is the call graph for this function:

◆ connected()

void tcp::Client::connected ( )
protectedvirtual

Called when the client connects to the server.

Override connected() to perform operations when a connection is established The default implementation initiates the SSL_connect handshake.

Returns
false if there is a peer certificate validation failure

Definition at line 87 of file tcpclient.cpp.

87  {
88  if (ssl_) {
89  mtx.lock();
90  ssl_->connect();
91  printSSLErrors();
93  mtx.unlock();
94  }
95 
96  state_ = SocketState::CONNECTED;
97  log("Connected");
98 }
Here is the call graph for this function:

◆ ctx()

SSLContext* tcp::Client::ctx ( )
inline

Returns the ssl context object.

A single SSLContext object is shared by all client connections in the library this allows default options, like a CA certificate, to be applied to all new client connections.

Definition at line 54 of file tcpclient.h.

54 { return ctx_; }

◆ handleEvents()

void tcp::Client::handleEvents ( uint32_t  events)
overrideprotectedvirtual

Receive epoll events sent to this socket.

Extends the behavior of DataSocket::handleEvents to monitors for an initial EPOLLIN signal when a new non-blocking connection has been established.

Implements tcp::Socket.

Definition at line 100 of file tcpclient.cpp.

101 {
102  if (state_ == SocketState::CONNECTING) {
103  if (events & EPOLLERR) {
104  error("handleEvents",strerror(errno));
105  }
106  if (events & EPOLLRDHUP) {
107  state_ = SocketState::UNCONNECTED;
108  return;
109  }
110  if (events & EPOLLOUT) {
111  connected();
112  }
113  } else {
114  DataSocket::handleEvents(events);
115  }
116 }

◆ state()

SocketState tcp::Client::state ( )
inline

Return the client state.

See the SocketState enum for possible values

Definition at line 57 of file tcpclient.h.

57 { return state_; }

Member Data Documentation

◆ checkPeerSubjectName

bool tcp::Client::checkPeerSubjectName { false }

Check if the peer certificate subject name matches the host name.

If true and verifyPeer is true then this flag will cause an additional check that the server certificates subject name == the hostname used in the connect string. If it does not match the connection will not complete.

Definition at line 81 of file tcpclient.h.


The documentation for this class was generated from the following files:
tcp::printSSLErrors
void printSSLErrors()
This method logs openSSL errors to cerr.
Definition: tcpssl.cpp:56
tcp::SSL::connect
bool connect()
Starts the SSL client handshake sequence.
Definition: tcpssl.cpp:558
tcp::DataSocket::createSSL
virtual SSL * createSSL(SSLContext *context)
Factory method for returning an SSL object.
Definition: tcpsocket.cpp:348
tcp::Socket::epoll
EPoll & epoll()
Returns a reference to the epoll instance used by this socket.
Definition: tcpsocket.h:144
tcp::error
void error(string msg)
Send an error message to the log stream.
Definition: tcpsocket.cpp:18
tcp::Socket::mtx
recursive_mutex mtx
The mutex used to provide exclusive access to the socket.
Definition: tcpsocket.h:141
tcp::SSL::requiresCertPostValidation
bool requiresCertPostValidation
If True, the certificate will be checked for validity on the first read/write operation.
Definition: tcpssl.h:195
tcp::DataSocket
Represents a buffered socket that can send and receive data using optional SSL encryption.
Definition: tcpsocket.h:159
tcp::DataSocket::readToInputBuffer
void readToInputBuffer()
Reads all available data from the socket into inputBuffer.
Definition: tcpsocket.cpp:214
tcp::Socket::state_
SocketState state_
Descendant classes can manipulate the socket state directly.
Definition: tcpsocket.h:147
tcp::Client::connected
virtual void connected()
Called when the client connects to the server.
Definition: tcpclient.cpp:87
tcp::SSL::setfd
bool setfd(int socket)
Sets the socket file descripter for this SSL object.
Definition: tcpssl.cpp:472
tcp::SSL::setOptions
void setOptions(bool verifypeer=false)
Sets default options for all SSL objects created from this context.
Definition: tcpssl.cpp:407
tcp::DataSocket::disconnect
void disconnect() override
Shuts down any SSL connection gracefully.
Definition: tcpsocket.cpp:189
tcp::SSL::setHostname
void setHostname(const string value)
A client/server may store the internal hostname property for certificate post validation.
Definition: tcpssl.h:198
tcp::Client::verifyPeer
bool verifyPeer
If true, openSSL will attempt to verify the peer certificate.
Definition: tcpclient.h:66
tcp::Socket::socket
int socket() const
Return the linux socket handle.
Definition: tcpsocket.h:115
tcp::Client::connect
virtual bool connect(const char *host, const char *service)
Initiates a connection to a server.
Definition: tcpclient.cpp:16
tcp::DataSocket::ssl_
SSL * ssl_
Exposes the underlying SSL record used for openSSL calls to descendant classes.
Definition: tcpsocket.h:213
tcp::Client::certfile
string certfile
The filename of the openSSL certificate in PEM format.
Definition: tcpclient.h:69
tcp::Client::checkPeerSubjectName
bool checkPeerSubjectName
Check if the peer certificate subject name matches the host name.
Definition: tcpclient.h:81
tcp::SSL::setCertificateAndKey
bool setCertificateAndKey(const char *certfile, const char *keyfile)
Sets the certificate filename and key filename.
Definition: tcpssl.cpp:418
tcp::DataSocket::handleEvents
void handleEvents(uint32_t events) override
Called by the EPoll class when the listening socket recieves an epoll event.
Definition: tcpsocket.cpp:255
tcp::Socket::setEvents
bool setEvents(int events)
Changes which epoll events the socket listens for.
Definition: tcpsocket.cpp:148
tcp::Socket::domain
int domain() const
Return the socket domain (AF_INET or AF_INET6)
Definition: tcpsocket.h:118
tcp::Client::keyfile
string keyfile
The filename of the openSSL private key in PEM format.
Definition: tcpclient.h:72
tcp::log
void log(string msg)
Send an log message to the log stream.
Definition: tcpsocket.cpp:22
tcp::Client::ctx
SSLContext * ctx()
Returns the ssl context object.
Definition: tcpclient.h:54