From 676d2702b748471856cc36cae2d3c1ee4be27dc7 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Fri, 11 Apr 2025 19:29:10 -0400 Subject: [PATCH] ssb: Read back-pressure on a tunnel connection affects the parent connection. This was causing spurrious disconnects. --- src/ssb.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/ssb.c b/src/ssb.c index 5830ee77..c1dbd1db 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -37,6 +37,8 @@ #define PRE_CALLBACK(ssb, cb) uint64_t pre_callback_hrtime_ns = _tf_ssb_callback_pre(ssb) #define POST_CALLBACK(ssb, cb) _tf_ssb_callback_post(ssb, cb, pre_callback_hrtime_ns) +const int k_read_back_pressure_threshold = 256; + static_assert(k_id_base64_len == sodium_base64_ENCODED_LEN(9 + crypto_box_PUBLICKEYBYTES, sodium_base64_VARIANT_ORIGINAL), "k_id_base64_len"); static_assert(k_id_bin_len == crypto_box_PUBLICKEYBYTES, "k_id_bin_len"); static_assert(k_blob_id_len == (sodium_base64_ENCODED_LEN(crypto_hash_sha256_BYTES, sodium_base64_VARIANT_ORIGINAL) + 8), "k_blob_id_len"); @@ -2080,6 +2082,11 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch JS_SetOpaque(object, NULL); JS_FreeValue(ssb->context, object); } + if (connection->read_back_pressure >= k_read_back_pressure_threshold && connection->tunnel_connection) + { + tf_ssb_connection_adjust_read_backpressure(connection->tunnel_connection, -1); + connection->read_back_pressure = 0; + } if (connection->async.data && !uv_is_closing((uv_handle_t*)&connection->async)) { uv_close((uv_handle_t*)&connection->async, _tf_ssb_connection_on_close); @@ -4555,19 +4562,32 @@ JSValue tf_ssb_connection_requests_to_object(tf_ssb_connection_t* connection) void tf_ssb_connection_adjust_read_backpressure(tf_ssb_connection_t* connection, int delta) { - const int k_threshold = 256; int old_pressure = connection->read_back_pressure; connection->read_back_pressure += delta; if (!connection->is_closing) { uv_async_send(&connection->scheduled_async); - if (old_pressure < k_threshold && connection->read_back_pressure >= k_threshold) + if (old_pressure < k_read_back_pressure_threshold && connection->read_back_pressure >= k_read_back_pressure_threshold) { - _tf_ssb_connection_read_stop(connection); + if (connection->tunnel_connection) + { + tf_ssb_connection_adjust_read_backpressure(connection->tunnel_connection, 1); + } + else + { + _tf_ssb_connection_read_stop(connection); + } } - else if (old_pressure >= k_threshold && connection->read_back_pressure < k_threshold) + else if (old_pressure >= k_read_back_pressure_threshold && connection->read_back_pressure < k_read_back_pressure_threshold) { - _tf_ssb_connection_read_start(connection); + if (connection->tunnel_connection) + { + tf_ssb_connection_adjust_read_backpressure(connection->tunnel_connection, -1); + } + else + { + _tf_ssb_connection_read_start(connection); + } } } connection->ref_count += delta;