diff --git a/src/ssb.c b/src/ssb.c index 916a463c..d6c2c7b3 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -211,10 +211,12 @@ typedef struct _tf_ssb_connection_t { tf_ssb_connection_t* next; tf_ssb_request_t* requests; + const char* destroy_reason; } tf_ssb_connection_t; static JSClassID _connection_class_id; +static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const char* reason); static void _tf_ssb_connection_client_send_hello(uv_stream_t* stream); static void _tf_ssb_connection_on_close(uv_handle_t* handle); static void _tf_ssb_connection_close(tf_ssb_connection_t* connection, const char* reason); @@ -235,10 +237,7 @@ static void _tf_ssb_connection_send_close(tf_ssb_connection_t* connection) { _tf_ssb_write(connection, message_enc, sizeof(message_enc)); } - else - { - _tf_ssb_connection_close(connection, "crypto_secretbox_easy close message"); - } + _tf_ssb_connection_close(connection, "crypto_secretbox_easy close message"); } static void _tf_ssb_connection_close(tf_ssb_connection_t* connection, const char* reason) @@ -254,11 +253,7 @@ static void _tf_ssb_connection_close(tf_ssb_connection_t* connection, const char connection->state = k_tf_ssb_state_closing; _tf_ssb_connection_send_close(connection); } - else - { - printf("closing: %s\n", reason); - uv_close((uv_handle_t*)&connection->tcp, _tf_ssb_connection_on_close); - } + _tf_ssb_connection_destroy(connection, reason); } static void _tf_ssb_connection_on_tcp_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) @@ -1096,7 +1091,7 @@ static bool _tf_ssb_connection_box_stream_recv(tf_ssb_connection_t* connection) memcpy(connection->body_auth_tag, header + sizeof(uint16_t), sizeof(connection->body_auth_tag)); if (!connection->body_len) { - uv_close((uv_handle_t*)&connection->tcp, _tf_ssb_connection_on_close); + _tf_ssb_connection_close(connection, "empty body, graceful close"); } } else @@ -1203,9 +1198,14 @@ void tf_ssb_append_message(tf_ssb_t* ssb, JSValue message) JS_FreeValue(context, root); } -void tf_ssb_connection_destroy(tf_ssb_connection_t* connection) +void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const char* reason) { tf_ssb_t* ssb = connection->ssb; + if (!connection->destroy_reason) + { + connection->destroy_reason = reason; + printf("destroying connection: %s\n", reason); + } for (tf_ssb_connection_t** it = &connection->ssb->connections; *it; it = &(*it)->next) { if (*it == connection) @@ -1254,7 +1254,10 @@ static void _tf_ssb_connection_on_close(uv_handle_t* handle) { tf_ssb_connection_t* connection = handle->data; handle->data = NULL; - tf_ssb_connection_destroy(connection); + if (connection) + { + _tf_ssb_connection_destroy(connection, "handle closed"); + } } static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) @@ -1310,8 +1313,7 @@ static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, c static_assert(sizeof(connection->serverepub) == crypto_box_PUBLICKEYBYTES, "serverepub size"); if (crypto_auth_hmacsha512256_verify(hmac, connection->serverepub, 32, k_ssb_network) != 0) { - printf("crypto_auth_hmacsha512256_verify failed\n"); - uv_close((uv_handle_t*)stream, _tf_ssb_connection_on_close); + _tf_ssb_connection_close(connection, "crypto_auth_hmacsha512256_verify failed"); } else { @@ -1344,7 +1346,7 @@ static void _tf_ssb_connection_on_tcp_recv(uv_stream_t* stream, ssize_t nread, c } else { - uv_close((uv_handle_t*)stream, _tf_ssb_connection_on_close); + _tf_ssb_connection_close(connection, "read zero"); } free(buf->base); } @@ -1386,7 +1388,7 @@ static void _tf_ssb_connection_on_connect(uv_connect_t* connect, int status) if (result) { printf("uv_read_start => %s\n", uv_strerror(status)); - uv_close((uv_handle_t*)&connection->tcp, _tf_ssb_connection_on_close); + _tf_ssb_connection_close(connection, "uv_read_start failed"); } else { @@ -1396,7 +1398,7 @@ static void _tf_ssb_connection_on_connect(uv_connect_t* connect, int status) else { printf("connect => %s\n", uv_strerror(status)); - uv_close((uv_handle_t*)&connection->tcp, _tf_ssb_connection_on_close); + _tf_ssb_connection_close(connection, "uv_tcp_connect failed"); } } @@ -1811,7 +1813,7 @@ static void _tf_ssb_connection_finalizer(JSRuntime* runtime, JSValue value) if (connection) { connection->object = JS_UNDEFINED; - tf_ssb_connection_destroy(connection); + _tf_ssb_connection_destroy(connection, "object finalized"); } } @@ -1912,7 +1914,7 @@ tf_ssb_connection_t* tf_ssb_connection_create(tf_ssb_t* ssb, const char* host, c if (result) { printf("uv_tcp_connect(%s): %s\n", host, uv_strerror(result)); - tf_ssb_connection_destroy(connection); + _tf_ssb_connection_destroy(connection, "connect failed"); } else { @@ -1991,15 +1993,13 @@ static void _tf_ssb_on_connection(uv_stream_t* stream, int status) if (uv_tcp_init(ssb->loop, &connection->tcp) != 0) { - printf("uv_tcp_init failed\n"); - tf_ssb_connection_destroy(connection); + _tf_ssb_connection_destroy(connection, "init failed"); return; } if (uv_accept(stream, (uv_stream_t*)&connection->tcp) != 0) { - printf("uv_accept failed\n"); - tf_ssb_connection_destroy(connection); + _tf_ssb_connection_destroy(connection, "accept failed"); return; }