From 33407f88d7bc826f6a8904ee4063f6b2b16dff91 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Thu, 25 Jan 2024 20:50:32 -0800 Subject: [PATCH] make client idle timeout configurable --- src/Client.cc | 5 +++-- src/IPStackSimulator.cc | 11 ++++++++--- src/ServerState.cc | 3 +++ src/ServerState.hh | 2 ++ system/config.example.json | 9 +++++++++ tests/config.json | 3 +++ 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/Client.cc b/src/Client.cc index d3b4eb60..6530dc2d 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -240,9 +240,10 @@ void Client::reschedule_save_game_data_event() { } void Client::reschedule_ping_and_timeout_events() { - struct timeval ping_tv = usecs_to_timeval(30000000); // 30 seconds + auto s = this->require_server_state(); + struct timeval ping_tv = usecs_to_timeval(s->client_ping_interval_usecs); event_add(this->send_ping_event.get(), &ping_tv); - struct timeval idle_tv = usecs_to_timeval(60000000); // 1 minute + struct timeval idle_tv = usecs_to_timeval(s->client_idle_timeout_usecs); event_add(this->idle_timeout_event.get(), &idle_tv); } diff --git a/src/IPStackSimulator.cc b/src/IPStackSimulator.cc index 614d938c..61c55ce7 100644 --- a/src/IPStackSimulator.cc +++ b/src/IPStackSimulator.cc @@ -187,7 +187,8 @@ IPStackSimulator::IPClient::IPClient(shared_ptr sim, FrameInfo mac_addr(0), ipv4_addr(0), idle_timeout_event(event_new(sim->base.get(), -1, EV_TIMEOUT, &IPStackSimulator::IPClient::dispatch_on_idle_timeout, this), event_free) { - struct timeval tv = usecs_to_timeval(60 * 1000 * 1000); + uint64_t idle_timeout_usecs = sim->state->client_idle_timeout_usecs; + struct timeval tv = usecs_to_timeval(idle_timeout_usecs); event_add(this->idle_timeout_event.get(), &tv); } @@ -294,7 +295,9 @@ void IPStackSimulator::on_client_input(struct bufferevent* bev) { return; } - struct timeval tv = usecs_to_timeval(60 * 1000 * 1000); + auto sim = c->sim.lock(); + uint64_t idle_timeout_usecs = sim ? sim->state->client_idle_timeout_usecs : 60000000; + struct timeval tv = usecs_to_timeval(idle_timeout_usecs); event_add(c->idle_timeout_event.get(), &tv); while (evbuffer_get_length(buf) >= 2) { @@ -1426,7 +1429,9 @@ void IPStackSimulator::on_server_input(shared_ptr c, IPClient::TCPConn ip_stack_simulator_log.debug("Server input event: 0x%zX bytes to read", evbuffer_get_length(buf)); - struct timeval tv = usecs_to_timeval(60 * 1000 * 1000); + auto sim = c->sim.lock(); + uint64_t idle_timeout_usecs = sim ? sim->state->client_idle_timeout_usecs : 60000000; + struct timeval tv = usecs_to_timeval(idle_timeout_usecs); event_add(c->idle_timeout_event.get(), &tv); evbuffer_add_buffer(conn.pending_data.get(), buf); diff --git a/src/ServerState.cc b/src/ServerState.cc index fd9050fa..3cef7200 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -664,6 +664,9 @@ void ServerState::load_config() { this->all_addresses.erase(""); this->all_addresses.emplace("", this->external_address); + this->client_ping_interval_usecs = json.get_int("ClientPingInterval", this->client_ping_interval_usecs); + this->client_idle_timeout_usecs = json.get_int("ClientIdleTimeout", this->client_idle_timeout_usecs); + this->ip_stack_debug = json.get_bool("IPStackDebug", this->ip_stack_debug); this->allow_unregistered_users = json.get_bool("AllowUnregisteredUsers", this->allow_unregistered_users); this->allow_pc_nte = json.get_bool("AllowPCNTE", this->allow_pc_nte); diff --git a/src/ServerState.hh b/src/ServerState.hh index ead8d29c..8fc4fbab 100644 --- a/src/ServerState.hh +++ b/src/ServerState.hh @@ -79,6 +79,8 @@ struct ServerState : public std::enable_shared_from_this { uint16_t dns_server_port = 0; std::vector ip_stack_addresses; std::vector ppp_stack_addresses; + uint64_t client_ping_interval_usecs = 30000000; + uint64_t client_idle_timeout_usecs = 60000000; bool ip_stack_debug = false; bool allow_unregistered_users = false; bool allow_pc_nte = false; diff --git a/system/config.example.json b/system/config.example.json index 255974c6..523c0b59 100644 --- a/system/config.example.json +++ b/system/config.example.json @@ -174,6 +174,15 @@ // connect to newserv will be proxied to this destination. // "ProxyDestination-BB": "", + // The server automatically pings clients if they haven't sent anything for a + // while to make sure they're still alive. This option specifies how long a + // client must be idle for the server to send a ping. + "ClientPingInterval": 30000000, // 30 seconds + // If a client doesn't send anything for this long, they will be disconnected. + // This should always be longer than ClientPingInterval, since an alive client + // should have a chance to respond to the server's ping. + "ClientIdleTimeout": 60000000, // 1 minute + // There is a proxy option that allows users to save copies of various game // files on the server side. If you have external clients connecting to your // server, you can disable this option to prevent clients from generating diff --git a/tests/config.json b/tests/config.json index 452a1e8b..4de5c909 100644 --- a/tests/config.json +++ b/tests/config.json @@ -93,6 +93,9 @@ "Sylverant": "sylverant.net:9100", }, + "ClientPingInterval": 30000000, + "ClientIdleTimeout": 60000000, + "LogLevels": { "AXMessages": "INFO", "ChannelExceptions": "INFO",