Skip to content

Commit

Permalink
update connection timeout setting
Browse files Browse the repository at this point in the history
  • Loading branch information
maddsua committed Feb 2, 2025
1 parent 7583283 commit 8f5eb6b
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 46 deletions.
2 changes: 0 additions & 2 deletions v3/net/net.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ namespace Lambda::Net {
struct ListenOptions {
uint16_t port = 80;
bool fast_port_reuse = true;
std::optional<ConnectionTimeouts> connection_timeouts;
};

enum struct Transport {
Expand All @@ -77,7 +76,6 @@ namespace Lambda::Net {

public:
TcpConnection(SockHandle sock, const RemoteAddress& remote);
TcpConnection(SockHandle sock, const RemoteAddress& remote, ConnectionTimeouts timeouts);
TcpConnection(TcpConnection&& other) noexcept;
TcpConnection(const TcpConnection& other) = delete;
~TcpConnection();
Expand Down
62 changes: 27 additions & 35 deletions v3/net/tcp_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,6 @@ TcpConnection::TcpConnection(SockHandle sock_handle, const RemoteAddress& remote
this->m_id = gen_conn_id(this->m_sock, this->m_remote_addr.port);
}

TcpConnection::TcpConnection(SockHandle sock_handle, const RemoteAddress& remote, ConnectionTimeouts timeouts) {

if (sock_handle == LAMBDA_INVALID_SOCKET) {
throw Net::Error("TcpConnection: Invalid socket handle");
}

this->m_sock = sock_handle;
this->m_remote_addr = remote;
this->m_id = gen_conn_id(this->m_sock, this->m_remote_addr.port);

this->set_timeouts(timeouts);
}

TcpConnection::TcpConnection(TcpConnection&& other) noexcept {

// transfer socket ownership
Expand Down Expand Up @@ -128,29 +115,34 @@ void TcpConnection::set_timeouts(ConnectionTimeouts timeouts) {
throw Net::Error("TcpConnection: Set timeouts: TX value invalid");
}

#ifdef _WIN32
const auto timeout_val_read = timeouts.read;
const auto timeout_val_write = timeouts.write;
#else
timeval timeout_val_read = {
.tv_sec = timeouts.read / 1000,
.tv_usec = 0
};
timeval timeout_val_write = {
.tv_sec = timeouts.write / 1000,
.tv_usec = 0
};
#endif

if (setsockopt(this->m_sock, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&timeout_val_read), sizeof(timeout_val_read))) {
throw Net::Error("TcpConnection: Error setting read timeout", lambda_os_errno());
auto cast_timeout_value = [](uint32_t value_ms) {
#ifndef _WIN32
timeval value = {
.tv_sec = value_ms / 1000,
.tv_usec = 0
};
return value;
#else
return value_ms;
#endif
};

// only update modified values
if (timeouts.read != this->m_timeouts.read) {
auto value = cast_timeout_value(timeouts.read);
if (setsockopt(this->m_sock, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&value), sizeof(value))) {
throw Net::Error("TcpConnection: Error setting read timeout", lambda_os_errno());
}
this->m_timeouts.read = timeouts.read;
}

if (timeouts.write != this->m_timeouts.write) {
auto value = cast_timeout_value(timeouts.write);
if (setsockopt(this->m_sock, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<const char*>(&value), sizeof(value))) {
throw Net::Error("TcpConnection: Error setting write timeout", lambda_os_errno());
}
this->m_timeouts.write = timeouts.write;
}

if (setsockopt(this->m_sock, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<const char*>(&timeout_val_write), sizeof(timeout_val_write))) {
throw Net::Error("TcpConnection: Error setting write timeout", lambda_os_errno());
}

this->m_timeouts = timeouts;
}

void TcpConnection::close() noexcept {
Expand Down
7 changes: 1 addition & 6 deletions v3/net/tcp_listen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,7 @@ TcpConnection TcpListener::next() {
.transport = Transport::TCP
};

// todo: take from server
if (!this->options.connection_timeouts.has_value()) {
return TcpConnection(next_sock, remote_addr);
}

return TcpConnection(next_sock, remote_addr, this->options.connection_timeouts.value());
return TcpConnection(next_sock, remote_addr);
}

bool TcpListener::is_listening() const noexcept {
Expand Down
8 changes: 7 additions & 1 deletion v3/server/pipeline_h1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ using namespace Lambda;
using namespace Lambda::Pipelines::H1;

void Pipelines::H1::serve_conn(Net::TcpConnection&& conn, HandlerFn handler, ServerContext ctx) {


// todo: fix stream not disconnecting on idle
conn.set_timeouts({
.read = Server::DefaultIoTimeout,
.write = Server::DefaultIoTimeout
});

Impl::StreamState stream;

if (ctx.options().debug) {
Expand Down
1 change: 0 additions & 1 deletion v3/server/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ void Server::Serve() {

// create tcp listener
this->m_tcp.options.port = this->options.port;
this->m_tcp.options.connection_timeouts = { .read = Server::DefaultIoTimeout, .write = Server::DefaultIoTimeout };
this->m_tcp.bind_and_listen();

// start connection loop
Expand Down
2 changes: 1 addition & 1 deletion v3/server/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace Lambda {

public:

uint32_t DefaultIoTimeout = 15000;
static const uint32_t DefaultIoTimeout = 15000;

Server(HandlerFn handler) : m_handler(handler) {}
Server(HandlerFn handler, ServeOptions options) : m_handler(handler), options(options) {}
Expand Down

0 comments on commit 8f5eb6b

Please sign in to comment.