diff --git a/src/control_server.c b/src/control_server.c index ce03140c..c89c1c65 100644 --- a/src/control_server.c +++ b/src/control_server.c @@ -425,6 +425,7 @@ static void accept_callback(socket_t fd, void* arg) { } client->subscribed_nodes = 0; client->write_registered = 0; + client->idle_timer = uasync_set_timeout(server->ua, 300000, client, control_client_idle_cb, "ctrl_idle"); /* Register with uasync */ client->socket_id = uasync_add_socket_t(server->ua, client_fd, @@ -604,6 +605,7 @@ static void client_write_callback(socket_t fd, void* arg) { uasync_set_socket_write(server->ua, client->socket_id, 0); client->write_registered = 0; + if (q->count > 128) DEBUG_WARN(DEBUG_CATEGORY_CONTROL, "ctrl_out: large output queue count=%d fd=%d", q->count, (int)client->fd); (void)fd; } @@ -634,9 +636,19 @@ static int control_client_send(struct control_server* server, struct control_cli return 0; } +static void control_client_idle_cb(void* arg) { + struct control_client* client = (struct control_client*)arg; + if (!client || !client->server) return; + client->idle_timer = NULL; + DEBUG_WARN(DEBUG_CATEGORY_CONTROL, "Control client idle timeout fd=%d, closing", client->fd); + close_client(client->server, client); +} + static void close_client(struct control_server* server, struct control_client* client) { if (!server || !client) return; + if (client->idle_timer) { uasync_cancel_timeout(server->ua, client->idle_timer); client->idle_timer = NULL; } + /* Log disconnection */ if (server->log_file) { fprintf(server->log_file, "%llu: [LOG] Client connection closed\n", @@ -843,6 +855,10 @@ static void handle_client_data(struct control_server* server, struct control_cli return; } + /* Reset idle timer on each valid command */ + if (client->idle_timer) { uasync_cancel_timeout(server->ua, client->idle_timer); } + client->idle_timer = uasync_set_timeout(server->ua, 300000, client, control_client_idle_cb, "ctrl_idle"); + /* Remove processed message from buffer */ uint16_t msg_size = hdr->size; if (client->recv_len > msg_size) { diff --git a/src/control_server.h b/src/control_server.h index 27de068b..e399a34b 100644 --- a/src/control_server.h +++ b/src/control_server.h @@ -40,6 +40,7 @@ struct control_client { uint64_t selected_peer_id; /* 0 = none selected */ struct ll_queue* output_queue; /* Output queue for async sends */ + void* idle_timer; /* Client idle timeout */ uint8_t subscribed_nodes; /* 1 = subscribed to node updates */ uint8_t write_registered; /* 1 = write events registered in uasync */ };