| Kea 3.0.2-git

tcp_connection.h
Go to the documentation of this file.
1// Copyright (C) 2022-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#ifndef TCP_CONNECTION_H
8#define TCP_CONNECTION_H
9
10#include <asiolink/asio_wrapper.h>
11#include <asiolink/interval_timer.h>
12#include <asiolink/io_service.h>
13#include <tcp/tcp_connection_acceptor.h>
14
15#include <boost/enable_shared_from_this.hpp>
16#include <boost/system/error_code.hpp>
17#include <boost/shared_ptr.hpp>
18
19#include <array>
20#include <functional>
21#include <string>
22#include <iostream>
23
24#include <mutex>
25
26 namespace isc {
27 namespace tcp {
28
30 typedef std::vector<uint8_t> WireData;
31 typedef boost::shared_ptr<WireData> WireDataPtr;
32
34 class TcpMessage {
35 public:
37 virtual ~TcpMessage(){
38 };
39
43 const uint8_t* getWireData() const {
44 if (wire_data_.empty()) {
45 isc_throw(InvalidOperation, "TcpMessage::getWireData() - cannot access empty wire data");
46 }
47
48 return (wire_data_.data());
49 }
50
52 size_t getWireDataSize() const {
53 return (wire_data_.size());
54 }
55
56 protected:
58 WireData wire_data_;
59};
60
62 class TcpRequest : public TcpMessage {
63 public:
65 virtual ~TcpRequest(){};
66
72 virtual size_t postBuffer(const void* buf, const size_t nbytes) = 0;
73
77 virtual bool needData() const = 0;
78
84 virtual std::string logFormatRequest(const size_t limit = 0) const = 0;
85
87 virtual void unpack() = 0;
88
89 private:
90
96 std::string logFormatRequestSafe(const size_t limit = 0) const;
97};
98
100 typedef boost::shared_ptr<TcpRequest> TcpRequestPtr;
101
103 class TcpResponse : public TcpMessage {
104 public:
106 TcpResponse()
107 : send_in_progress_(false) {};
108
110 virtual ~TcpResponse() {};
111
117 bool wireDataAvail() const {
118 return (!wire_data_.empty());
119 }
120
122 virtual void pack() = 0;
123
127 virtual void consumeWireData(const size_t length);
128
129 bool sendInProgress() {
130 return (send_in_progress_);
131 }
132
133 private:
135 bool send_in_progress_;
136};
137
138 typedef boost::shared_ptr<TcpResponse> TcpResponsePtr;
139
141 class TcpConnectionError : public Exception {
142 public:
143 TcpConnectionError(const char* file, size_t line, const char* what) :
144 isc::Exception(file, line, what) { }
145};
146
151 class TcpConnectionPool;
152
154 typedef std::function<bool(const boost::asio::ip::tcp::endpoint&)> TcpConnectionFilterCallback;
155
157 class TcpConnection : public boost::enable_shared_from_this<TcpConnection> {
158 private:
159
162 typedef std::function<void(boost::system::error_code ec, size_t length)>
163 SocketCallbackFunction;
164
168 class SocketCallback {
169 public:
170
175 SocketCallback(SocketCallbackFunction socket_callback)
176 : callback_(socket_callback) {
177 }
178
188 void operator()(boost::system::error_code ec, size_t length = 0);
189
190 private:
192 SocketCallbackFunction callback_;
193 };
194
195 public:
196
211 TcpConnection(const asiolink::IOServicePtr& io_service,
212 const TcpConnectionAcceptorPtr& acceptor,
213 const asiolink::TlsContextPtr& tls_context,
214 TcpConnectionPool& connection_pool,
215 const TcpConnectionAcceptorCallback& acceptor_callback,
216 const TcpConnectionFilterCallback& connection_filter,
217 const long idle_timeout,
218 const size_t read_max = 32768);
219
223 virtual ~TcpConnection();
224
229 void asyncAccept();
230
232 virtual void shutdown();
233
235 virtual void close();
236
241 void doHandshake();
242
255 void doRead(TcpRequestPtr request = TcpRequestPtr());
256
270 TcpRequestPtr postData(TcpRequestPtr request, WireData& input_data);
271
276 virtual void requestReceived(TcpRequestPtr request) = 0;
277
285 virtual TcpRequestPtr createRequest() = 0;
286
290 size_t getReadMax() const {
291 return (read_max_);
292 }
293
298 void setReadMax(const size_t read_max);
299
304 virtual bool responseSent(TcpResponsePtr response) = 0;
305
309 static const boost::asio::ip::tcp::endpoint& NO_ENDPOINT() {
310 static boost::asio::ip::tcp::endpoint endpoint;
311 return (endpoint);
312 }
313
318 const boost::asio::ip::tcp::endpoint getRemoteEndpoint() const {
319 return (remote_endpoint_);
320 }
321
322 protected:
323
332 void doWrite(TcpResponsePtr response);
333
339 void asyncSendResponse(TcpResponsePtr response);
340
349 void acceptorCallback(const boost::system::error_code& ec);
350
357 void handshakeCallback(const boost::system::error_code& ec);
358
369 void socketReadCallback(TcpRequestPtr request,
370 boost::system::error_code ec,
371 size_t length);
372
379 virtual void socketWriteCallback(TcpResponsePtr request,
380 boost::system::error_code ec,
381 size_t length);
382
390 void shutdownCallback(const boost::system::error_code& ec);
391
393 void setupIdleTimer();
394
396 void idleTimeoutCallback();
397
401 virtual void shutdownConnection();
402
404 virtual void stopThisConnection();
405
407 std::string getRemoteEndpointAddressAsText() const;
408
412 unsigned char* getInputBufData() {
413 if (input_buf_.empty()) {
414 isc_throw(InvalidOperation, "TcpConnection::getInputBufData() - cannot access empty buffer");
415 }
416
417 return (input_buf_.data());
418 }
419
421 size_t getInputBufSize() const {
422 return (input_buf_.size());
423 }
424
426 asiolink::IOServicePtr io_service_;
427
429 asiolink::TlsContextPtr tls_context_;
430
433 long idle_timeout_;
434
436 asiolink::IntervalTimer idle_timer_;
437
439 std::unique_ptr<asiolink::TCPSocket<SocketCallback> > tcp_socket_;
440
442 std::unique_ptr<asiolink::TLSSocket<SocketCallback> > tls_socket_;
443
445 TcpConnectionAcceptorPtr acceptor_;
446
448 TcpConnectionPool& connection_pool_;
449
451 TcpConnectionAcceptorCallback acceptor_callback_;
452
454 TcpConnectionFilterCallback connection_filter_;
455
457 size_t read_max_;
458
460 WireData input_buf_;
461
463 boost::asio::ip::tcp::endpoint remote_endpoint_;
464};
465
467 typedef boost::shared_ptr<TcpConnection> TcpConnectionPtr;
468
469} // end of namespace isc::tcp
470} // end of namespace isc
471
472#endif
asio_wrapper.h
isc::Exception::Exception
Exception(const char *file, size_t line, const char *what)
Constructor for a given type for exceptions with file name and file line number.
Definition exceptions/exceptions.cc:17
isc::Exception::what
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Definition exceptions/exceptions.cc:32
isc::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition exceptions/exceptions.h:143
isc::asiolink::IntervalTimer
The IntervalTimer class is a wrapper for the ASIO boost::asio::deadline_timer class.
Definition interval_timer.h:52
isc::tcp::TcpConnectionError::TcpConnectionError
TcpConnectionError(const char *file, size_t line, const char *what)
Definition tcp_connection.h:143
isc::tcp::TcpConnectionPool
Pool of active TCP connections.
Definition tcp_connection_pool.h:33
isc::tcp::TcpConnection::doWrite
void doWrite(TcpResponsePtr response)
Starts asynchronous write to the socket.
Definition tcp_connection.cc:231
isc::tcp::TcpConnection::createRequest
virtual TcpRequestPtr createRequest()=0
Creates a new, empty request.
isc::tcp::TcpConnection::shutdownCallback
void shutdownCallback(const boost::system::error_code &ec)
Callback invoked when TLS shutdown is performed.
Definition tcp_connection.cc:74
isc::tcp::TcpConnection::getInputBufData
unsigned char * getInputBufData()
Returns pointer to the first byte of the input buffer.
Definition tcp_connection.h:412
isc::tcp::TcpConnection::acceptorCallback
void acceptorCallback(const boost::system::error_code &ec)
Local callback invoked when new connection is accepted.
Definition tcp_connection.cc:282
isc::tcp::TcpConnection::asyncAccept
void asyncAccept()
Asynchronously accepts new connection.
Definition tcp_connection.cc:141
isc::tcp::TcpConnection::getInputBufSize
size_t getInputBufSize() const
Returns input buffer size.
Definition tcp_connection.h:421
isc::tcp::TcpConnection::shutdown
virtual void shutdown()
Shutdown the socket.
Definition tcp_connection.cc:79
isc::tcp::TcpConnection::getReadMax
size_t getReadMax() const
Fetches the maximum number of bytes read during single socket read.
Definition tcp_connection.h:290
isc::tcp::TcpConnection::remote_endpoint_
boost::asio::ip::tcp::endpoint remote_endpoint_
Remote endpoint.
Definition tcp_connection.h:463
isc::tcp::TcpConnection::requestReceived
virtual void requestReceived(TcpRequestPtr request)=0
Processes a request once it has been completely received.
isc::tcp::TcpConnection::shutdownConnection
virtual void shutdownConnection()
Shuts down current connection.
Definition tcp_connection.cc:117
isc::tcp::TcpConnection::stopThisConnection
virtual void stopThisConnection()
Stops current connection.
Definition tcp_connection.cc:129
isc::tcp::TcpConnection::setReadMax
void setReadMax(const size_t read_max)
Sets the maximum number of bytes read during single socket read.
Definition tcp_connection.cc:510
isc::tcp::TcpConnection::acceptor_
TcpConnectionAcceptorPtr acceptor_
Pointer to the TCP acceptor used to accept new connections.
Definition tcp_connection.h:445
isc::tcp::TcpConnection::close
virtual void close()
Closes the socket.
Definition tcp_connection.cc:100
isc::tcp::TcpConnection::tls_context_
asiolink::TlsContextPtr tls_context_
TLS context.
Definition tcp_connection.h:429
isc::tcp::TcpConnection::input_buf_
WireData input_buf_
Buffer for a single socket read.
Definition tcp_connection.h:460
isc::tcp::TcpConnection::socketReadCallback
void socketReadCallback(TcpRequestPtr request, boost::system::error_code ec, size_t length)
Callback invoked when new data is received over the socket.
Definition tcp_connection.cc:352
isc::tcp::TcpConnection::setupIdleTimer
void setupIdleTimer()
Reset timer for detecting idle timeout in connections.
Definition tcp_connection.cc:484
isc::tcp::TcpConnection::socketWriteCallback
virtual void socketWriteCallback(TcpResponsePtr request, boost::system::error_code ec, size_t length)
Callback invoked when data is sent over the socket.
Definition tcp_connection.cc:439
isc::tcp::TcpConnection::asyncSendResponse
void asyncSendResponse(TcpResponsePtr response)
Sends TCP response asynchronously.
Definition tcp_connection.cc:276
isc::tcp::TcpConnection::io_service_
asiolink::IOServicePtr io_service_
The IO service used to handle events.
Definition tcp_connection.h:426
isc::tcp::TcpConnection::getRemoteEndpointAddressAsText
std::string getRemoteEndpointAddressAsText() const
returns remote address in textual form
Definition tcp_connection.cc:501
isc::tcp::TcpConnection::connection_filter_
TcpConnectionFilterCallback connection_filter_
External callback for filtering connections by IP address.
Definition tcp_connection.h:454
isc::tcp::TcpConnection::getRemoteEndpoint
const boost::asio::ip::tcp::endpoint getRemoteEndpoint() const
Fetches the remote endpoint for the connection's socket.
Definition tcp_connection.h:318
isc::tcp::TcpConnection::tcp_socket_
std::unique_ptr< asiolink::TCPSocket< SocketCallback > > tcp_socket_
TCP socket used by this connection.
Definition tcp_connection.h:439
isc::tcp::TcpConnection::doRead
void doRead(TcpRequestPtr request=TcpRequestPtr())
Starts asynchronous read from the socket.
Definition tcp_connection.cc:194
isc::tcp::TcpConnection::NO_ENDPOINT
static const boost::asio::ip::tcp::endpoint & NO_ENDPOINT()
Returns an empty end point.
Definition tcp_connection.h:309
isc::tcp::TcpConnection::~TcpConnection
virtual ~TcpConnection()
Destructor.
Definition tcp_connection.cc:69
isc::tcp::TcpConnection::idle_timer_
asiolink::IntervalTimer idle_timer_
Timer used to detect idle Timeout.
Definition tcp_connection.h:436
isc::tcp::TcpConnection::responseSent
virtual bool responseSent(TcpResponsePtr response)=0
Determines behavior after a response has been sent.
isc::tcp::TcpConnection::acceptor_callback_
TcpConnectionAcceptorCallback acceptor_callback_
External TCP acceptor callback.
Definition tcp_connection.h:451
isc::tcp::TcpConnection::read_max_
size_t read_max_
Maximum bytes to read in a single socket read.
Definition tcp_connection.h:457
isc::tcp::TcpConnection::connection_pool_
TcpConnectionPool & connection_pool_
Connection pool holding this connection.
Definition tcp_connection.h:448
isc::tcp::TcpConnection::doHandshake
void doHandshake()
Asynchronously performs TLS handshake.
Definition tcp_connection.cc:169
isc::tcp::TcpConnection::postData
TcpRequestPtr postData(TcpRequestPtr request, WireData &input_data)
Appends newly received raw data to the given request.
Definition tcp_connection.cc:394
isc::tcp::TcpConnection::tls_socket_
std::unique_ptr< asiolink::TLSSocket< SocketCallback > > tls_socket_
TLS socket used by this connection.
Definition tcp_connection.h:442
isc::tcp::TcpConnection::handshakeCallback
void handshakeCallback(const boost::system::error_code &ec)
Local callback invoked when TLS handshake is performed.
Definition tcp_connection.cc:336
isc::tcp::TcpConnection::idleTimeoutCallback
void idleTimeoutCallback()
Callback invoked when the client has been idle.
Definition tcp_connection.cc:490
isc::tcp::TcpConnection::TcpConnection
TcpConnection(const asiolink::IOServicePtr &io_service, const TcpConnectionAcceptorPtr &acceptor, const asiolink::TlsContextPtr &tls_context, TcpConnectionPool &connection_pool, const TcpConnectionAcceptorCallback &acceptor_callback, const TcpConnectionFilterCallback &connection_filter, const long idle_timeout, const size_t read_max=32768)
Constructor.
Definition tcp_connection.cc:41
isc::tcp::TcpConnection::idle_timeout_
long idle_timeout_
Timeout after which the a TCP connection is shut down by the server.
Definition tcp_connection.h:433
isc::tcp::TcpMessage
Base class for TCP messages.
Definition tcp_connection.h:34
isc::tcp::TcpMessage::~TcpMessage
virtual ~TcpMessage()
Destructor.
Definition tcp_connection.h:37
isc::tcp::TcpMessage::wire_data_
WireData wire_data_
Buffer used for data in wire format data.
Definition tcp_connection.h:58
isc::tcp::TcpMessage::getWireDataSize
size_t getWireDataSize() const
Returns current size of the wire data.
Definition tcp_connection.h:52
isc::tcp::TcpMessage::getWireData
const uint8_t * getWireData() const
Returns pointer to the first byte of the wire data.
Definition tcp_connection.h:43
isc::tcp::TcpRequest
Abstract class used to receive an inbound message.
Definition tcp_connection.h:62
isc::tcp::TcpRequest::needData
virtual bool needData() const =0
Returns true if the request is incomplete.
isc::tcp::TcpRequest::logFormatRequest
virtual std::string logFormatRequest(const size_t limit=0) const =0
Returns request contents formatted for log output.
isc::tcp::TcpRequest::unpack
virtual void unpack()=0
Unpacks wire data once the message has been completely received.
isc::tcp::TcpRequest::postBuffer
virtual size_t postBuffer(const void *buf, const size_t nbytes)=0
Adds data to an incomplete request.
isc::tcp::TcpRequest::~TcpRequest
virtual ~TcpRequest()
Destructor.
Definition tcp_connection.h:65
isc::tcp::TcpResponse::~TcpResponse
virtual ~TcpResponse()
Destructor.
Definition tcp_connection.h:110
isc::tcp::TcpResponse::consumeWireData
virtual void consumeWireData(const size_t length)
Erases n bytes from the beginning of the wire data.
Definition tcp_connection.cc:27
isc::tcp::TcpResponse::sendInProgress
bool sendInProgress()
Definition tcp_connection.h:129
isc::tcp::TcpResponse::pack
virtual void pack()=0
Prepares the wire data content for writing.
isc::tcp::TcpResponse::wireDataAvail
bool wireDataAvail() const
Checks if the output buffer contains some data to be sent.
Definition tcp_connection.h:117
isc::tcp::TcpResponse::TcpResponse
TcpResponse()
Constructor.
Definition tcp_connection.h:106
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
interval_timer.h
io_service.h
isc::asiolink::TlsContextPtr
boost::shared_ptr< TlsContext > TlsContextPtr
The type of shared pointers to TlsContext objects.
Definition common_tls.h:37
isc::asiolink::IOServicePtr
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
Definition io_service.h:28
isc::tcp
Definition mt_tcp_listener_mgr.cc:23
isc::tcp::TcpConnectionFilterCallback
std::function< bool(const boost::asio::ip::tcp::endpoint &)> TcpConnectionFilterCallback
Type of the callback for filtering new connections by ip address.
Definition tcp_connection.h:154
isc::tcp::TcpConnectionAcceptorPtr
boost::shared_ptr< TcpConnectionAcceptor > TcpConnectionAcceptorPtr
Type of shared pointer to TCP acceptors.
Definition tcp_connection_acceptor.h:27
isc::tcp::TcpRequestPtr
boost::shared_ptr< TcpRequest > TcpRequestPtr
Defines a smart pointer to a TcpRequest.
Definition tcp_connection.h:100
isc::tcp::TcpConnectionPtr
boost::shared_ptr< TcpConnection > TcpConnectionPtr
Pointer to the TcpConnection.
Definition tcp_connection.h:467
isc::tcp::TcpResponsePtr
boost::shared_ptr< TcpResponse > TcpResponsePtr
Definition tcp_connection.h:138
isc::tcp::WireData
std::vector< uint8_t > WireData
Defines a data structure for storing raw bytes of data on the wire.
Definition tcp_connection.h:30
isc::tcp::WireDataPtr
boost::shared_ptr< WireData > WireDataPtr
Definition tcp_connection.h:31
isc::tcp::TcpConnectionAcceptorCallback
std::function< void(const boost::system::error_code &)> TcpConnectionAcceptorCallback
Type of the callback for the TCP acceptor used in this library.
Definition tcp_connection_acceptor.h:21
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
tcp_connection_acceptor.h