ssb: Hook up some more disconnect messaging.

This commit is contained in:
Cory McWilliams 2024-12-26 20:12:04 -05:00
parent 8f51eb63b0
commit 7843168fad
5 changed files with 67 additions and 65 deletions

121
src/ssb.c
View File

@ -355,7 +355,6 @@ static void _tf_ssb_add_broadcast(tf_ssb_t* ssb, const tf_ssb_broadcast_t* broad
static uint64_t _tf_ssb_callback_pre(tf_ssb_t* ssb);
static void _tf_ssb_callback_post(tf_ssb_t* ssb, void* callback, uint64_t pre);
static void _tf_ssb_connection_client_send_hello(tf_ssb_connection_t* connection);
static void _tf_ssb_connection_close(tf_ssb_connection_t* connection, const char* reason);
static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const char* reason);
static void _tf_ssb_connection_finalizer(JSRuntime* runtime, JSValue value);
static void _tf_ssb_connection_on_close(uv_handle_t* handle);
@ -407,10 +406,10 @@ static void _tf_ssb_connection_send_close(tf_ssb_connection_t* connection)
{
_tf_ssb_write(connection, message_enc, sizeof(message_enc));
}
_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)
void tf_ssb_connection_close(tf_ssb_connection_t* connection, const char* reason)
{
if (connection->state == k_tf_ssb_state_closing)
{
@ -441,7 +440,7 @@ static void _tf_ssb_connection_on_write(uv_write_t* req, int status)
{
char buffer[256];
snprintf(buffer, sizeof(buffer), "write failed asynchronously: %s", uv_strerror(status));
_tf_ssb_connection_close(connection, buffer);
tf_ssb_connection_close(connection, buffer);
}
tf_free(req);
}
@ -459,8 +458,8 @@ static void _tf_ssb_write(tf_ssb_connection_t* connection, void* data, size_t si
{
tf_ssb_connection_adjust_write_count(connection, -1);
char buffer[256];
snprintf(buffer, sizeof(buffer), "write failed : %s", uv_strerror(result));
_tf_ssb_connection_close(connection, buffer);
snprintf(buffer, sizeof(buffer), "write failed: %s", uv_strerror(result));
tf_ssb_connection_close(connection, buffer);
tf_free(write);
}
}
@ -476,28 +475,28 @@ static void _tf_ssb_connection_send_identity(tf_ssb_connection_t* connection, ui
memcpy(connection->serverepub, pubkey, sizeof(connection->serverepub));
if (crypto_auth_hmacsha512256_verify(hmac, connection->serverepub, 32, connection->ssb->network_key) != 0)
{
_tf_ssb_connection_close(connection, "invalid server hello");
tf_ssb_connection_close(connection, "invalid server hello");
return;
}
uint8_t shared_secret_ab[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute shared_secret_ab as client");
tf_ssb_connection_close(connection, "unable to compute shared_secret_ab as client");
return;
}
uint8_t servercurvepub[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_sign_ed25519_pk_to_curve25519(servercurvepub, connection->serverpub) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute key to curve25519 as client");
tf_ssb_connection_close(connection, "unable to compute key to curve25519 as client");
return;
}
uint8_t shared_secret_aB[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_scalarmult_curve25519(shared_secret_aB, connection->epriv, servercurvepub) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute shared_secret_aB as client");
tf_ssb_connection_close(connection, "unable to compute shared_secret_aB as client");
return;
}
@ -512,7 +511,7 @@ static void _tf_ssb_connection_send_identity(tf_ssb_connection_t* connection, ui
unsigned long long siglen;
if (crypto_sign_detached(connection->detached_signature_A, &siglen, msg, sizeof(msg), connection->ssb->priv) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute detached_signature_A as client");
tf_ssb_connection_close(connection, "unable to compute detached_signature_A as client");
return;
}
@ -531,7 +530,7 @@ static void _tf_ssb_connection_send_identity(tf_ssb_connection_t* connection, ui
uint8_t c[crypto_secretbox_MACBYTES + sizeof(tosend)];
if (crypto_secretbox_easy(c, tosend, sizeof(tosend), nonce, hash2) != 0)
{
_tf_ssb_connection_close(connection, "unable to create initial secretbox as client");
tf_ssb_connection_close(connection, "unable to create initial secretbox as client");
return;
}
@ -566,7 +565,7 @@ static void _tf_ssb_connection_box_stream_send(tf_ssb_connection_t* connection,
if (crypto_secretbox_easy(message_enc + 34 - 16, message + offset, send_size, nonce2, connection->c_to_s_box_key) != 0)
{
_tf_ssb_connection_close(connection, "unable to secretbox message");
tf_ssb_connection_close(connection, "unable to secretbox message");
tf_free(message_enc);
return;
}
@ -576,7 +575,7 @@ static void _tf_ssb_connection_box_stream_send(tf_ssb_connection_t* connection,
memcpy(header + sizeof(uint16_t), message_enc + 34 - 16, 16);
if (crypto_secretbox_easy(message_enc, header, sizeof(header), nonce1, connection->c_to_s_box_key) != 0)
{
_tf_ssb_connection_close(connection, "unable to secretbox header");
tf_ssb_connection_close(connection, "unable to secretbox header");
tf_free(message_enc);
return;
}
@ -1122,7 +1121,7 @@ void tf_ssb_close_all(tf_ssb_t* ssb, const char* reason)
{
for (tf_ssb_connection_t* connection = ssb->connections; connection; connection = connection->next)
{
_tf_ssb_connection_close(connection, reason);
tf_ssb_connection_close(connection, reason);
}
}
@ -1185,35 +1184,35 @@ static void _tf_ssb_connection_verify_identity(tf_ssb_connection_t* connection,
uint8_t shared_secret_ab[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute shared_secret_ab");
tf_ssb_connection_close(connection, "unable to compute shared_secret_ab");
return;
}
uint8_t servercurvepub[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_sign_ed25519_pk_to_curve25519(servercurvepub, connection->serverpub) != 0)
{
_tf_ssb_connection_close(connection, "unable to convert key to curve25519");
tf_ssb_connection_close(connection, "unable to convert key to curve25519");
return;
}
uint8_t shared_secret_aB[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_scalarmult_curve25519(shared_secret_aB, connection->epriv, servercurvepub) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute shared_secret_aB");
tf_ssb_connection_close(connection, "unable to compute shared_secret_aB");
return;
}
uint8_t clientcurvepriv[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_sign_ed25519_sk_to_curve25519(clientcurvepriv, connection->ssb->priv) != 0)
{
_tf_ssb_connection_close(connection, "unable to convert key to curve25519");
tf_ssb_connection_close(connection, "unable to convert key to curve25519");
return;
}
uint8_t shared_secret_Ab[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_scalarmult_curve25519(shared_secret_Ab, clientcurvepriv, connection->serverepub) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute shared_secret_Ab");
tf_ssb_connection_close(connection, "unable to compute shared_secret_Ab");
return;
}
@ -1238,7 +1237,7 @@ static void _tf_ssb_connection_verify_identity(tf_ssb_connection_t* connection,
uint8_t m[80];
if (crypto_secretbox_open_easy(m, message, len, nonce, hash2) != 0)
{
_tf_ssb_connection_close(connection, "unable to open initial secret box as client");
tf_ssb_connection_close(connection, "unable to open initial secret box as client");
return;
}
@ -1252,14 +1251,14 @@ static void _tf_ssb_connection_verify_identity(tf_ssb_connection_t* connection,
memcpy(msg + sizeof(connection->ssb->network_key) + sizeof(connection->detached_signature_A) + sizeof(connection->ssb->pub), hash3, sizeof(hash3));
if (crypto_sign_verify_detached(m, msg, sizeof(msg), connection->serverpub) != 0)
{
_tf_ssb_connection_close(connection, "unable to verify server identity");
tf_ssb_connection_close(connection, "unable to verify server identity");
return;
}
uint8_t nonce2[crypto_auth_hmacsha512256_BYTES];
if (crypto_auth_hmacsha512256(nonce2, connection->epub, sizeof(connection->epub), connection->ssb->network_key) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute client recv nonce");
tf_ssb_connection_close(connection, "unable to compute client recv nonce");
return;
}
memcpy(connection->nonce, nonce2, sizeof(connection->nonce));
@ -1267,7 +1266,7 @@ static void _tf_ssb_connection_verify_identity(tf_ssb_connection_t* connection,
uint8_t nonce3[crypto_auth_hmacsha512256_BYTES];
if (crypto_auth_hmacsha512256(nonce3, connection->serverepub, sizeof(connection->serverepub), connection->ssb->network_key) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute client send nonce");
tf_ssb_connection_close(connection, "unable to compute client send nonce");
return;
}
memcpy(connection->send_nonce, nonce3, sizeof(connection->send_nonce));
@ -1357,7 +1356,7 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
uint8_t shared_secret_ab[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute shared_secret_ab");
tf_ssb_connection_close(connection, "unable to compute shared_secret_ab");
return;
}
@ -1370,7 +1369,7 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
uint8_t curvepriv[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_sign_ed25519_sk_to_curve25519(curvepriv, connection->ssb->priv) != 0)
{
_tf_ssb_connection_close(connection, "unable to convert key to curve25519");
tf_ssb_connection_close(connection, "unable to convert key to curve25519");
return;
}
@ -1379,7 +1378,7 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
if (crypto_scalarmult(shared_secret_aB, curvepriv, connection->serverepub) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute shared_secret_aB");
tf_ssb_connection_close(connection, "unable to compute shared_secret_aB");
return;
}
@ -1408,7 +1407,7 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
uint8_t m[96];
if (crypto_secretbox_open_easy(m, message, len, nonce, hash2) != 0)
{
_tf_ssb_connection_close(connection, "unable to open initial secret box as server");
tf_ssb_connection_close(connection, "unable to open initial secret box as server");
return;
}
uint8_t* detached_signature_A = m;
@ -1419,7 +1418,7 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
tf_ssb_id_bin_to_str(id_base64, sizeof(id_base64), m + 64);
char reason[256];
snprintf(reason, sizeof(reason), "already connected: %s\n", id_base64);
_tf_ssb_connection_close(connection, reason);
tf_ssb_connection_close(connection, reason);
return;
}
@ -1434,14 +1433,14 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
memcpy(msg + sizeof(connection->ssb->network_key) + sizeof(connection->ssb->pub), hash3, sizeof(hash3));
if (crypto_sign_verify_detached(detached_signature_A, msg, sizeof(msg), connection->serverpub) != 0)
{
_tf_ssb_connection_close(connection, "unable to verify client identity");
tf_ssb_connection_close(connection, "unable to verify client identity");
return;
}
uint8_t nonce2[crypto_auth_hmacsha512256_BYTES];
if (crypto_auth_hmacsha512256(nonce2, connection->epub, sizeof(connection->epub), connection->ssb->network_key) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute initial recv nonce as server");
tf_ssb_connection_close(connection, "unable to compute initial recv nonce as server");
return;
}
memcpy(connection->nonce, nonce2, sizeof(connection->nonce));
@ -1449,7 +1448,7 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
uint8_t nonce3[crypto_auth_hmacsha512256_BYTES];
if (crypto_auth_hmacsha512256(nonce3, connection->serverepub, sizeof(connection->serverepub), connection->ssb->network_key) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute initial send nonce as server");
tf_ssb_connection_close(connection, "unable to compute initial send nonce as server");
return;
}
memcpy(connection->send_nonce, nonce3, sizeof(connection->send_nonce));
@ -1465,21 +1464,21 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
unsigned long long siglen;
if (crypto_sign_detached(detached_signature_B, &siglen, sign_b, sizeof(sign_b), connection->ssb->priv) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute detached_signature_B as server");
tf_ssb_connection_close(connection, "unable to compute detached_signature_B as server");
return;
}
uint8_t clientcurvepub[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_sign_ed25519_pk_to_curve25519(clientcurvepub, connection->serverpub) != 0)
{
_tf_ssb_connection_close(connection, "unable to convert key to curve25519");
tf_ssb_connection_close(connection, "unable to convert key to curve25519");
return;
}
uint8_t shared_secret_Ab[crypto_scalarmult_curve25519_SCALARBYTES];
if (crypto_scalarmult_curve25519(shared_secret_Ab, connection->epriv, clientcurvepub) != 0)
{
_tf_ssb_connection_close(connection, "unable to compute shared_secret_Ab as server");
tf_ssb_connection_close(connection, "unable to compute shared_secret_Ab as server");
return;
}
@ -1505,7 +1504,7 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
uint8_t c[crypto_secretbox_MACBYTES + sizeof(detached_signature_B)];
if (crypto_secretbox_easy(c, detached_signature_B, sizeof(detached_signature_B), nonce, key_hash) != 0)
{
_tf_ssb_connection_close(connection, "unable to create initial secret box as server");
tf_ssb_connection_close(connection, "unable to create initial secret box as server");
return;
}
@ -1533,7 +1532,7 @@ static bool _tf_ssb_connection_recv_pop(tf_ssb_connection_t* connection, uint8_t
{
char message[256];
snprintf(message, sizeof(message), "Trying to pop a message (%zd) larger than the connection's receive buffer (%zd).", size, sizeof(connection->recv_buffer));
_tf_ssb_connection_close(connection, message);
tf_ssb_connection_close(connection, message);
}
if (connection->recv_size < size)
{
@ -1580,7 +1579,7 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t
bool close_connection = false;
if (size == 0)
{
_tf_ssb_connection_close(connection, "rpc recv zero");
tf_ssb_connection_close(connection, "rpc recv zero");
return;
}
else if (flags & k_ssb_rpc_flag_json)
@ -1680,7 +1679,9 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t
if (close_connection)
{
tf_ssb_connection_close(connection);
char buffer[1024];
snprintf(buffer, sizeof(buffer), "Failed to parse: %.*s", (int)size, message);
tf_ssb_connection_close(connection, buffer);
}
}
@ -1694,7 +1695,7 @@ static void _tf_ssb_connection_rpc_recv_push(tf_ssb_connection_t* connection, co
(connection->rpc_recv_size + size_left > sizeof(connection->rpc_recv_buffer)) ? sizeof(connection->rpc_recv_buffer) - connection->rpc_recv_size : size_left;
if (copy_size == 0)
{
_tf_ssb_connection_close(connection, "recv buffer overflow");
tf_ssb_connection_close(connection, "recv buffer overflow");
return;
}
memcpy(connection->rpc_recv_buffer + connection->rpc_recv_size, data + size_processed, copy_size);
@ -1742,7 +1743,7 @@ static bool _tf_ssb_connection_box_stream_recv(tf_ssb_connection_t* connection)
uint8_t header[18];
if (crypto_secretbox_open_easy(header, header_enc, sizeof(header_enc), connection->nonce, connection->s_to_c_box_key) != 0)
{
_tf_ssb_connection_close(connection, "failed to open header secret box");
tf_ssb_connection_close(connection, "failed to open header secret box");
return false;
}
_tf_ssb_nonce_inc(connection->nonce);
@ -1750,7 +1751,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)
{
_tf_ssb_connection_close(connection, "empty body, graceful close");
tf_ssb_connection_close(connection, "empty body, graceful close");
}
}
else
@ -1766,7 +1767,7 @@ static bool _tf_ssb_connection_box_stream_recv(tf_ssb_connection_t* connection)
{
if (crypto_secretbox_open_easy(connection->secretbox_buf, connection->box_stream_buf, 16 + connection->body_len, connection->nonce, connection->s_to_c_box_key) != 0)
{
_tf_ssb_connection_close(connection, "failed to open secret box");
tf_ssb_connection_close(connection, "failed to open secret box");
return false;
}
_tf_ssb_nonce_inc(connection->nonce);
@ -1901,7 +1902,7 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch
if (it->tunnel_connection == connection)
{
it->tunnel_connection = NULL;
_tf_ssb_connection_close(it, "tunnel closed");
tf_ssb_connection_close(it, "tunnel closed");
again = true;
break;
}
@ -1981,7 +1982,7 @@ static void _tf_ssb_connection_on_tcp_recv_internal(tf_ssb_connection_t* connect
{
if (connection->recv_size + nread > sizeof(connection->recv_buffer))
{
_tf_ssb_connection_close(connection, "recv buffer overflow");
tf_ssb_connection_close(connection, "recv buffer overflow");
return;
}
memcpy(connection->recv_buffer + connection->recv_size, data, nread);
@ -1990,10 +1991,10 @@ static void _tf_ssb_connection_on_tcp_recv_internal(tf_ssb_connection_t* connect
switch (connection->state)
{
case k_tf_ssb_state_invalid:
_tf_ssb_connection_close(connection, "received a message in invalid state");
tf_ssb_connection_close(connection, "received a message in invalid state");
break;
case k_tf_ssb_state_connected:
_tf_ssb_connection_close(connection, "received a message in connected state");
tf_ssb_connection_close(connection, "received a message in connected state");
break;
case k_tf_ssb_state_sent_hello:
{
@ -2026,7 +2027,7 @@ static void _tf_ssb_connection_on_tcp_recv_internal(tf_ssb_connection_t* connect
static_assert(sizeof(connection->serverepub) == crypto_box_PUBLICKEYBYTES, "serverepub size");
if (crypto_auth_hmacsha512256_verify(hmac, connection->serverepub, 32, connection->ssb->network_key) != 0)
{
_tf_ssb_connection_close(connection, "crypto_auth_hmacsha512256_verify failed");
tf_ssb_connection_close(connection, "crypto_auth_hmacsha512256_verify failed");
}
else
{
@ -2059,7 +2060,7 @@ static void _tf_ssb_connection_on_tcp_recv_internal(tf_ssb_connection_t* connect
}
else
{
_tf_ssb_connection_close(connection, uv_strerror(nread));
tf_ssb_connection_close(connection, uv_strerror(nread));
}
}
@ -2076,14 +2077,14 @@ static void _tf_ssb_connection_client_send_hello(tf_ssb_connection_t* connection
if (crypto_box_keypair(connection->epub, connection->epriv) != 0)
{
_tf_ssb_connection_close(connection, "failed to generate ephemeral keypair");
tf_ssb_connection_close(connection, "failed to generate ephemeral keypair");
return;
}
uint8_t a[crypto_auth_hmacsha512256_BYTES];
if (crypto_auth_hmacsha512256(a, connection->epub, sizeof(connection->epub), connection->ssb->network_key) != 0)
{
_tf_ssb_connection_close(connection, "failed to create hello message");
tf_ssb_connection_close(connection, "failed to create hello message");
return;
}
@ -2102,7 +2103,7 @@ static bool _tf_ssb_connection_read_start(tf_ssb_connection_t* connection)
{
char reason[1024];
snprintf(reason, sizeof(reason), "uv_read_start failed: %s", uv_strerror(result));
_tf_ssb_connection_close(connection, reason);
tf_ssb_connection_close(connection, reason);
return false;
}
return true;
@ -2115,7 +2116,7 @@ static bool _tf_ssb_connection_read_stop(tf_ssb_connection_t* connection)
{
char reason[1024];
snprintf(reason, sizeof(reason), "uv_read_stop failed: %s", uv_strerror(result));
_tf_ssb_connection_close(connection, reason);
tf_ssb_connection_close(connection, reason);
return false;
}
return true;
@ -2137,7 +2138,7 @@ static void _tf_ssb_connection_on_connect(uv_connect_t* connect, int status)
{
char reason[1024];
snprintf(reason, sizeof(reason), "uv_tcp_connect failed: %s", uv_strerror(status));
_tf_ssb_connection_close(connection, reason);
tf_ssb_connection_close(connection, reason);
}
}
@ -2575,7 +2576,7 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
while (connection)
{
tf_ssb_connection_t* next = connection->next;
tf_ssb_connection_close(connection);
tf_ssb_connection_close(connection, "Shutting down.");
connection = next;
}
uv_run(ssb->loop, UV_RUN_NOWAIT);
@ -2781,7 +2782,10 @@ static void _tf_ssb_connection_tunnel_callback(
{
tf_ssb_connection_remove_request(connection, -request_number);
tf_ssb_connection_rpc_send(connection, flags, -request_number, NULL, (const uint8_t*)"false", strlen("false"), NULL, NULL, NULL);
tf_ssb_connection_close(tunnel);
char buffer[1024];
snprintf(buffer, sizeof(buffer), "tunnel error: %.*s", (int)size, message);
tf_ssb_connection_close(tunnel, buffer);
}
else
{
@ -2928,11 +2932,6 @@ void tf_ssb_connect(tf_ssb_t* ssb, const char* host, int port, const uint8_t* ke
}
}
void tf_ssb_connection_close(tf_ssb_connection_t* connection)
{
_tf_ssb_connection_close(connection, "tf_ssb_connection_close");
}
static void _tf_ssb_on_connection(uv_stream_t* stream, int status)
{
tf_ssb_t* ssb = stream->data;

View File

@ -514,8 +514,9 @@ JSContext* tf_ssb_connection_get_context(tf_ssb_connection_t* connection);
/**
** Close a connection.
** @param connection The connection.
** @param reason Human-readable reason for closing the connection.
*/
void tf_ssb_connection_close(tf_ssb_connection_t* connection);
void tf_ssb_connection_close(tf_ssb_connection_t* connection, const char* reason);
/**
** Check whether a connection is connected.

View File

@ -1198,7 +1198,7 @@ static JSValue _tf_ssb_closeConnection(JSContext* context, JSValueConst this_val
tf_ssb_connection_t* connection = tf_ssb_connection_get(ssb, id);
if (connection)
{
tf_ssb_connection_close(connection);
tf_ssb_connection_close(connection, "Close requested by user.");
}
JS_FreeCString(context, id);
return connection ? JS_TRUE : JS_FALSE;

View File

@ -315,7 +315,9 @@ static void _tf_ssb_rpc_tunnel_callback(tf_ssb_connection_t* connection, uint8_t
if (flags & k_ssb_rpc_flag_end_error)
{
tf_ssb_connection_remove_request(connection, request_number);
tf_ssb_connection_close(tun->connection);
char buffer[1024];
snprintf(buffer, sizeof(buffer), "error from tunnel: %.*s", (int)size, message);
tf_ssb_connection_close(tun->connection, buffer);
}
else
{

View File

@ -536,7 +536,7 @@ void tf_ssb_test_rooms(const tf_test_options_t* options)
uv_run(&loop, UV_RUN_NOWAIT);
tf_ssb_connection_close(tun0);
tf_ssb_connection_close(tun0, "done");
uv_run(&loop, UV_RUN_NOWAIT);