2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 14:05:33 +00:00

[#2583] Incremental changes to lib/tcp

Interrim commit, still does nothing.
Unit test fleshed out but disabled.
This commit is contained in:
Thomas Markwalder
2022-10-05 14:11:26 -04:00
parent 7b076e938c
commit 85c76d6ea1
5 changed files with 62 additions and 31 deletions

View File

@@ -43,8 +43,10 @@ TcpConnection::TcpConnection(asiolink::IOService& io_service,
const TlsContextPtr& tls_context, const TlsContextPtr& tls_context,
TcpConnectionPool& connection_pool, TcpConnectionPool& connection_pool,
const TcpConnectionAcceptorCallback& callback, const TcpConnectionAcceptorCallback& callback,
const long request_timeout,
const long idle_timeout) const long idle_timeout)
: request_timer_(io_service), : request_timer_(io_service),
request_timeout_(request_timeout),
tls_context_(tls_context), tls_context_(tls_context),
idle_timeout_(idle_timeout), idle_timeout_(idle_timeout),
tcp_socket_(), tcp_socket_(),
@@ -211,16 +213,15 @@ TcpConnection::doHandshake() {
} }
void void
TcpConnection::doRead(TcpRequestPtr /* request */) { TcpConnection::doRead(TcpRequestPtr request) {
#if 0
try { try {
TCPEndpoint endpoint; TCPEndpoint endpoint;
// Transaction hasn't been created if we are starting to read the // Request hasn't been created if we are starting to read the
// new request. // new request.
if (!transaction) { if (!request) {
transaction = Transaction::create(response_creator_); request.reset(new TcpRequest());
recordParameters(transaction->getRequest()); // recordParameters(transaction->getRequest());
} }
// Create instance of the callback. It is safe to pass the local instance // Create instance of the callback. It is safe to pass the local instance
@@ -228,27 +229,25 @@ TcpConnection::doRead(TcpRequestPtr /* request */) {
// as needed. // as needed.
SocketCallback cb(std::bind(&TcpConnection::socketReadCallback, SocketCallback cb(std::bind(&TcpConnection::socketReadCallback,
shared_from_this(), shared_from_this(),
transaction, request,
ph::_1, // error ph::_1, // error
ph::_2)); //bytes_transferred ph::_2)); // bytes_transferred
if (tcp_socket_) { if (tcp_socket_) {
tcp_socket_->asyncReceive(static_cast<void*>(transaction->getInputBufData()), tcp_socket_->asyncReceive(static_cast<void*>(request->getInputBufData()),
transaction->getInputBufSize(), request->getInputBufSize(),
0, &endpoint, cb); 0, &endpoint, cb);
return; return;
} }
if (tls_socket_) { if (tls_socket_) {
tls_socket_->asyncReceive(static_cast<void*>(transaction->getInputBufData()), tls_socket_->asyncReceive(static_cast<void*>(request->getInputBufData()),
transaction->getInputBufSize(), request->getInputBufSize(),
0, &endpoint, cb); 0, &endpoint, cb);
return; return;
} }
} catch (...) { } catch (...) {
stopThisConnection(); stopThisConnection();
} }
#else
isc_throw(NotImplemented, "TcpConnection::doRead()");
#endif
} }
void void

View File

@@ -22,8 +22,26 @@
namespace isc { namespace isc {
namespace tcp { namespace tcp {
/// @todo TKM these are place holders while I think output how it should work class TcpRequest {
typedef util::InputBuffer TcpRequest; public:
/// @brief Constructor.
TcpRequest(){};
/// @brief Returns pointer to the first byte of the input buffer.
char* getInputBufData() {
return (input_buf_.data());
}
/// @brief Returns input buffer size (i.e. capacity).
size_t getInputBufSize() const {
return (input_buf_.size());
}
private:
/// @brief Buffer for received data.
std::array<char, 32768> input_buf_;
};
typedef boost::shared_ptr<TcpRequest> TcpRequestPtr; typedef boost::shared_ptr<TcpRequest> TcpRequestPtr;
typedef util::OutputBuffer TcpResponse; typedef util::OutputBuffer TcpResponse;
@@ -107,6 +125,7 @@ public:
const asiolink::TlsContextPtr& tls_context, const asiolink::TlsContextPtr& tls_context,
TcpConnectionPool& connection_pool, TcpConnectionPool& connection_pool,
const TcpConnectionAcceptorCallback& callback, const TcpConnectionAcceptorCallback& callback,
const long request_timeout,
const long idle_timeout); const long idle_timeout);
/// @brief Destructor. /// @brief Destructor.

View File

@@ -18,9 +18,11 @@ TcpListener::TcpListener(IOService& io_service,
const IOAddress& server_address, const IOAddress& server_address,
const unsigned short server_port, const unsigned short server_port,
const TlsContextPtr& tls_context, const TlsContextPtr& tls_context,
const RequestTimeout& request_timeout,
const IdleTimeout& idle_timeout) const IdleTimeout& idle_timeout)
: io_service_(io_service), tls_context_(tls_context), acceptor_(), : io_service_(io_service), tls_context_(tls_context), acceptor_(),
endpoint_(), connections_(), idle_timeout_(idle_timeout.value_) { endpoint_(), connections_(), request_timeout_(request_timeout.value_),
idle_timeout_(idle_timeout.value_) {
// Create the TCP or TLS acceptor. // Create the TCP or TLS acceptor.
if (!tls_context) { if (!tls_context) {
@@ -37,6 +39,12 @@ TcpListener::TcpListener(IOService& io_service,
<< server_address << ":" << server_port); << server_address << ":" << server_port);
} }
// Request timeout is signed and must be greater than 0.
if (request_timeout_ <= 0) {
isc_throw(TcpListenerError, "Invalid desired TCP request timeout "
<< request_timeout_);
}
// Idle persistent connection timeout is signed and must be greater than 0. // Idle persistent connection timeout is signed and must be greater than 0.
if (idle_timeout_ <= 0) { if (idle_timeout_ <= 0) {
isc_throw(TcpListenerError, "Invalid desired TCP idle persistent connection" isc_throw(TcpListenerError, "Invalid desired TCP idle persistent connection"
@@ -99,8 +107,8 @@ TcpListener::createConnection(const TcpConnectionAcceptorCallback& /* callback *
/// @todo TKM - I think what we want is to define TcpConnectionFactory /// @todo TKM - I think what we want is to define TcpConnectionFactory
/// instead of a response creator. Let TcpListener accept a factory /// instead of a response creator. Let TcpListener accept a factory
/// for that, which is used here to create for BLQ an LeaseQueryConnection /// for that, which is used here to create for BLQ an LeaseQueryConnection
return (connection_factory_(io_service_, acceptor_, tls_context_, return (connectionFactory(io_service_, acceptor_, tls_context_,
connections_, callback, idle_timeout_)); connections_, callback, request_timeout_, idle_timeout_));
#endif #endif
} }

View File

@@ -60,6 +60,8 @@ public:
/// @param server_address Address on which the TCP service should run. /// @param server_address Address on which the TCP service should run.
/// @param server_port Port number on which the TCP service should run. /// @param server_port Port number on which the TCP service should run.
/// @param tls_context TLS context. /// @param tls_context TLS context.
/// @param request_timeout Timeout maximum amount of time allotted for
/// a request to be processed.
/// @param idle_timeout Timeout after which an idle persistent TCP /// @param idle_timeout Timeout after which an idle persistent TCP
/// connection is closed by the server. /// connection is closed by the server.
/// ///
@@ -69,6 +71,7 @@ public:
const asiolink::IOAddress& server_address, const asiolink::IOAddress& server_address,
const unsigned short server_port, const unsigned short server_port,
const asiolink::TlsContextPtr& tls_context, const asiolink::TlsContextPtr& tls_context,
const RequestTimeout& request_timeout,
const IdleTimeout& idle_timeout); const IdleTimeout& idle_timeout);
/// @brief Virtual destructor. /// @brief Virtual destructor.
@@ -138,6 +141,9 @@ protected:
/// @brief Pool of active connections. /// @brief Pool of active connections.
TcpConnectionPool connections_; TcpConnectionPool connections_;
/// @brief Maximum amount of time request to be processed.
long request_timeout_;
/// @brief Timeout after which idle persistent connection is closed by /// @brief Timeout after which idle persistent connection is closed by
/// the server. /// the server.
long idle_timeout_; long idle_timeout_;

View File

@@ -64,9 +64,10 @@ public:
const IOAddress& server_address, const IOAddress& server_address,
const unsigned short server_port, const unsigned short server_port,
const TlsContextPtr& tls_context, const TlsContextPtr& tls_context,
const RequestTimeout& request_timeout,
const IdleTimeout& idle_timeout) const IdleTimeout& idle_timeout)
: TcpListener(io_service, server_address, server_port, : TcpListener(io_service, server_address, server_port,
tls_context, idle_timeout) { tls_context, request_timeout, idle_timeout) {
} }
protected: protected:
@@ -82,7 +83,7 @@ protected:
TcpConnectionPtr TcpConnectionPtr
conn(new TcpConnection(io_service_, acceptor_, conn(new TcpConnection(io_service_, acceptor_,
tls_context_, connections_, tls_context_, connections_,
callback, idle_timeout_)); callback, request_timeout_, idle_timeout_));
return (conn); return (conn);
} }
}; };
@@ -246,16 +247,14 @@ public:
std::list<TcpTestClientPtr> clients_; std::list<TcpTestClientPtr> clients_;
}; };
// This test verifies that HTTP connection can be established and used to // This test verifies that A TCP connection can be established and used to
// transmit HTTP request and receive a response. // transmit a streamed request and receive a streamed response.
TEST_F(TcpListenerTest, listen) { TEST_F(TcpListenerTest, DISABLED_listen) {
const std::string request = "POST /foo/bar HTTP/1.1\r\n" const std::string request = "inbound message request";
"Content-Type: application/json\r\n"
"Content-Length: 3\r\n\r\n"
"{ }";
TcpListener listener(io_service_, IOAddress(SERVER_ADDRESS), SERVER_PORT, TcpTestListener listener(io_service_, IOAddress(SERVER_ADDRESS), SERVER_PORT,
TlsContextPtr(), TcpListener::IdleTimeout(IDLE_TIMEOUT)); TlsContextPtr(), TcpListener::RequestTimeout(REQUEST_TIMEOUT),
TcpListener::IdleTimeout(IDLE_TIMEOUT));
ASSERT_NO_THROW(listener.start()); ASSERT_NO_THROW(listener.start());
ASSERT_EQ(SERVER_ADDRESS, listener.getLocalAddress().toText()); ASSERT_EQ(SERVER_ADDRESS, listener.getLocalAddress().toText());
ASSERT_EQ(SERVER_PORT, listener.getLocalPort()); ASSERT_EQ(SERVER_PORT, listener.getLocalPort());