diff --git a/src/ssb.c b/src/ssb.c index 3bd062a3..673ce389 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -74,6 +74,7 @@ enum k_udp_discovery_expires_seconds = 10, k_handshake_timeout_ms = 15000, k_rpc_active_ms = 3000, + k_activity_timeout_ms = 15000, }; typedef struct _tf_ssb_broadcast_t tf_ssb_broadcast_t; @@ -273,6 +274,7 @@ typedef struct _tf_ssb_connection_t uv_async_t scheduled_async; uv_timer_t handshake_timer; uv_timer_t linger_timer; + uv_timer_t activity_timer; bool is_closing; tf_ssb_connection_t* tunnel_connection; @@ -694,6 +696,11 @@ static void _tf_ssb_request_activity_timer(uv_timer_t* timer) } } +static void _tf_ssb_connection_activity_timer(uv_timer_t* timer) +{ + tf_ssb_connection_close(timer->data, "Inactivity"); +} + static bool _tf_ssb_connection_get_request_callback( tf_ssb_connection_t* connection, int32_t request_number, tf_ssb_rpc_callback_t** out_callback, void** out_user_data, const char** out_name) { @@ -717,6 +724,10 @@ static bool _tf_ssb_connection_get_request_callback( *out_name = request->name; } request->last_active = uv_now(connection->ssb->loop); + if (connection->flags & k_tf_ssb_connect_flag_one_shot) + { + uv_timer_start(&connection->activity_timer, _tf_ssb_connection_activity_timer, k_activity_timeout_ms, 0); + } if (uv_timer_get_due_in(&connection->ssb->request_activity_timer) == 0) { uv_timer_start(&connection->ssb->request_activity_timer, _tf_ssb_request_activity_timer, k_rpc_active_ms, 0); @@ -766,6 +777,10 @@ void tf_ssb_connection_add_request(tf_ssb_connection_t* connection, int32_t requ connection->requests_count++; connection->ssb->request_count++; } + if (connection->flags & k_tf_ssb_connect_flag_one_shot) + { + uv_timer_start(&connection->activity_timer, _tf_ssb_connection_activity_timer, k_activity_timeout_ms, 0); + } if (uv_timer_get_due_in(&connection->ssb->request_activity_timer) == 0) { uv_timer_start(&connection->ssb->request_activity_timer, _tf_ssb_request_activity_timer, k_rpc_active_ms, 0); @@ -1979,9 +1994,13 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch { uv_close((uv_handle_t*)&connection->handshake_timer, _tf_ssb_connection_on_close); } + if (connection->activity_timer.data && !uv_is_closing((uv_handle_t*)&connection->activity_timer)) + { + uv_close((uv_handle_t*)&connection->activity_timer, _tf_ssb_connection_on_close); + } if (JS_IsUndefined(connection->object) && !connection->async.data && !connection->scheduled_async.data && !connection->tcp.data && !connection->connect.data && - !connection->handshake_timer.data && !connection->linger_timer.data && connection->ref_count == 0) + !connection->handshake_timer.data && !connection->linger_timer.data && !connection->activity_timer.data && connection->ref_count == 0) { tf_free(connection->message_requests); connection->message_requests = NULL; @@ -2759,6 +2778,13 @@ static tf_ssb_connection_t* _tf_ssb_connection_create_internal(tf_ssb_t* ssb, co uv_timer_start(&connection->handshake_timer, _tf_ssb_connection_handshake_timer_callback, k_handshake_timeout_ms, 0); connection->linger_timer.data = connection; uv_timer_init(ssb->loop, &connection->linger_timer); + connection->activity_timer.data = connection; + uv_timer_init(ssb->loop, &connection->activity_timer); + + if (connection->flags & k_tf_ssb_connect_flag_one_shot) + { + uv_timer_start(&connection->activity_timer, _tf_ssb_connection_activity_timer, k_activity_timeout_ms, 0); + } connection->object = JS_NewObjectClass(ssb->context, _connection_class_id); JS_SetOpaque(connection->object, connection);