forked from cory/tildefriends
		
	ssb: Hook up some more disconnect messaging.
This commit is contained in:
		
							
								
								
									
										121
									
								
								src/ssb.c
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								src/ssb.c
									
									
									
									
									
								
							@@ -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 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_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_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_destroy(tf_ssb_connection_t* connection, const char* reason);
 | 
				
			||||||
static void _tf_ssb_connection_finalizer(JSRuntime* runtime, JSValue value);
 | 
					static void _tf_ssb_connection_finalizer(JSRuntime* runtime, JSValue value);
 | 
				
			||||||
static void _tf_ssb_connection_on_close(uv_handle_t* handle);
 | 
					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_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)
 | 
						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];
 | 
							char buffer[256];
 | 
				
			||||||
		snprintf(buffer, sizeof(buffer), "write failed asynchronously: %s", uv_strerror(status));
 | 
							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);
 | 
						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);
 | 
								tf_ssb_connection_adjust_write_count(connection, -1);
 | 
				
			||||||
			char buffer[256];
 | 
								char buffer[256];
 | 
				
			||||||
			snprintf(buffer, sizeof(buffer), "write failed : %s", uv_strerror(result));
 | 
								snprintf(buffer, sizeof(buffer), "write failed: %s", uv_strerror(result));
 | 
				
			||||||
			_tf_ssb_connection_close(connection, buffer);
 | 
								tf_ssb_connection_close(connection, buffer);
 | 
				
			||||||
			tf_free(write);
 | 
								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));
 | 
						memcpy(connection->serverepub, pubkey, sizeof(connection->serverepub));
 | 
				
			||||||
	if (crypto_auth_hmacsha512256_verify(hmac, connection->serverepub, 32, connection->ssb->network_key) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t shared_secret_ab[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
						uint8_t shared_secret_ab[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t servercurvepub[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
						uint8_t servercurvepub[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_sign_ed25519_pk_to_curve25519(servercurvepub, connection->serverpub) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t shared_secret_aB[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
						uint8_t shared_secret_aB[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_scalarmult_curve25519(shared_secret_aB, connection->epriv, servercurvepub) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -512,7 +511,7 @@ static void _tf_ssb_connection_send_identity(tf_ssb_connection_t* connection, ui
 | 
				
			|||||||
	unsigned long long siglen;
 | 
						unsigned long long siglen;
 | 
				
			||||||
	if (crypto_sign_detached(connection->detached_signature_A, &siglen, msg, sizeof(msg), connection->ssb->priv) != 0)
 | 
						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;
 | 
							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)];
 | 
						uint8_t c[crypto_secretbox_MACBYTES + sizeof(tosend)];
 | 
				
			||||||
	if (crypto_secretbox_easy(c, tosend, sizeof(tosend), nonce, hash2) != 0)
 | 
						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;
 | 
							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)
 | 
							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);
 | 
								tf_free(message_enc);
 | 
				
			||||||
			return;
 | 
								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);
 | 
							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)
 | 
							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);
 | 
								tf_free(message_enc);
 | 
				
			||||||
			return;
 | 
								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)
 | 
						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];
 | 
						uint8_t shared_secret_ab[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t servercurvepub[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
						uint8_t servercurvepub[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_sign_ed25519_pk_to_curve25519(servercurvepub, connection->serverpub) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t shared_secret_aB[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
						uint8_t shared_secret_aB[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_scalarmult_curve25519(shared_secret_aB, connection->epriv, servercurvepub) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t clientcurvepriv[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
						uint8_t clientcurvepriv[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_sign_ed25519_sk_to_curve25519(clientcurvepriv, connection->ssb->priv) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t shared_secret_Ab[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
						uint8_t shared_secret_Ab[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_scalarmult_curve25519(shared_secret_Ab, clientcurvepriv, connection->serverepub) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1238,7 +1237,7 @@ static void _tf_ssb_connection_verify_identity(tf_ssb_connection_t* connection,
 | 
				
			|||||||
	uint8_t m[80];
 | 
						uint8_t m[80];
 | 
				
			||||||
	if (crypto_secretbox_open_easy(m, message, len, nonce, hash2) != 0)
 | 
						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;
 | 
							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));
 | 
						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)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t nonce2[crypto_auth_hmacsha512256_BYTES];
 | 
						uint8_t nonce2[crypto_auth_hmacsha512256_BYTES];
 | 
				
			||||||
	if (crypto_auth_hmacsha512256(nonce2, connection->epub, sizeof(connection->epub), connection->ssb->network_key) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	memcpy(connection->nonce, nonce2, sizeof(connection->nonce));
 | 
						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];
 | 
						uint8_t nonce3[crypto_auth_hmacsha512256_BYTES];
 | 
				
			||||||
	if (crypto_auth_hmacsha512256(nonce3, connection->serverepub, sizeof(connection->serverepub), connection->ssb->network_key) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	memcpy(connection->send_nonce, nonce3, sizeof(connection->send_nonce));
 | 
						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];
 | 
						uint8_t shared_secret_ab[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_scalarmult_curve25519(shared_secret_ab, connection->epriv, connection->serverepub) != 0)
 | 
						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;
 | 
							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];
 | 
						uint8_t curvepriv[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_sign_ed25519_sk_to_curve25519(curvepriv, connection->ssb->priv) != 0)
 | 
						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;
 | 
							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)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1408,7 +1407,7 @@ static void _tf_ssb_connection_verify_client_identity(tf_ssb_connection_t* conne
 | 
				
			|||||||
	uint8_t m[96];
 | 
						uint8_t m[96];
 | 
				
			||||||
	if (crypto_secretbox_open_easy(m, message, len, nonce, hash2) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	uint8_t* detached_signature_A = m;
 | 
						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);
 | 
							tf_ssb_id_bin_to_str(id_base64, sizeof(id_base64), m + 64);
 | 
				
			||||||
		char reason[256];
 | 
							char reason[256];
 | 
				
			||||||
		snprintf(reason, sizeof(reason), "already connected: %s\n", id_base64);
 | 
							snprintf(reason, sizeof(reason), "already connected: %s\n", id_base64);
 | 
				
			||||||
		_tf_ssb_connection_close(connection, reason);
 | 
							tf_ssb_connection_close(connection, reason);
 | 
				
			||||||
		return;
 | 
							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));
 | 
						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)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t nonce2[crypto_auth_hmacsha512256_BYTES];
 | 
						uint8_t nonce2[crypto_auth_hmacsha512256_BYTES];
 | 
				
			||||||
	if (crypto_auth_hmacsha512256(nonce2, connection->epub, sizeof(connection->epub), connection->ssb->network_key) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	memcpy(connection->nonce, nonce2, sizeof(connection->nonce));
 | 
						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];
 | 
						uint8_t nonce3[crypto_auth_hmacsha512256_BYTES];
 | 
				
			||||||
	if (crypto_auth_hmacsha512256(nonce3, connection->serverepub, sizeof(connection->serverepub), connection->ssb->network_key) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	memcpy(connection->send_nonce, nonce3, sizeof(connection->send_nonce));
 | 
						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;
 | 
						unsigned long long siglen;
 | 
				
			||||||
	if (crypto_sign_detached(detached_signature_B, &siglen, sign_b, sizeof(sign_b), connection->ssb->priv) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t clientcurvepub[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
						uint8_t clientcurvepub[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_sign_ed25519_pk_to_curve25519(clientcurvepub, connection->serverpub) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t shared_secret_Ab[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
						uint8_t shared_secret_Ab[crypto_scalarmult_curve25519_SCALARBYTES];
 | 
				
			||||||
	if (crypto_scalarmult_curve25519(shared_secret_Ab, connection->epriv, clientcurvepub) != 0)
 | 
						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;
 | 
							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)];
 | 
						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)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1533,7 +1532,7 @@ static bool _tf_ssb_connection_recv_pop(tf_ssb_connection_t* connection, uint8_t
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		char message[256];
 | 
							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));
 | 
							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)
 | 
						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;
 | 
						bool close_connection = false;
 | 
				
			||||||
	if (size == 0)
 | 
						if (size == 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		_tf_ssb_connection_close(connection, "rpc recv zero");
 | 
							tf_ssb_connection_close(connection, "rpc recv zero");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (flags & k_ssb_rpc_flag_json)
 | 
						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)
 | 
						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;
 | 
								(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)
 | 
							if (copy_size == 0)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			_tf_ssb_connection_close(connection, "recv buffer overflow");
 | 
								tf_ssb_connection_close(connection, "recv buffer overflow");
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		memcpy(connection->rpc_recv_buffer + connection->rpc_recv_size, data + size_processed, copy_size);
 | 
							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];
 | 
								uint8_t header[18];
 | 
				
			||||||
			if (crypto_secretbox_open_easy(header, header_enc, sizeof(header_enc), connection->nonce, connection->s_to_c_box_key) != 0)
 | 
								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;
 | 
									return false;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_tf_ssb_nonce_inc(connection->nonce);
 | 
								_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));
 | 
								memcpy(connection->body_auth_tag, header + sizeof(uint16_t), sizeof(connection->body_auth_tag));
 | 
				
			||||||
			if (!connection->body_len)
 | 
								if (!connection->body_len)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				_tf_ssb_connection_close(connection, "empty body, graceful close");
 | 
									tf_ssb_connection_close(connection, "empty body, graceful close");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							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)
 | 
								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;
 | 
									return false;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_tf_ssb_nonce_inc(connection->nonce);
 | 
								_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)
 | 
								if (it->tunnel_connection == connection)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				it->tunnel_connection = NULL;
 | 
									it->tunnel_connection = NULL;
 | 
				
			||||||
				_tf_ssb_connection_close(it, "tunnel closed");
 | 
									tf_ssb_connection_close(it, "tunnel closed");
 | 
				
			||||||
				again = true;
 | 
									again = true;
 | 
				
			||||||
				break;
 | 
									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))
 | 
							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;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		memcpy(connection->recv_buffer + connection->recv_size, data, nread);
 | 
							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)
 | 
							switch (connection->state)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
		case k_tf_ssb_state_invalid:
 | 
							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;
 | 
								break;
 | 
				
			||||||
		case k_tf_ssb_state_connected:
 | 
							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;
 | 
								break;
 | 
				
			||||||
		case k_tf_ssb_state_sent_hello:
 | 
							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");
 | 
										static_assert(sizeof(connection->serverepub) == crypto_box_PUBLICKEYBYTES, "serverepub size");
 | 
				
			||||||
					if (crypto_auth_hmacsha512256_verify(hmac, connection->serverepub, 32, connection->ssb->network_key) != 0)
 | 
										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
 | 
										else
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
@@ -2059,7 +2060,7 @@ static void _tf_ssb_connection_on_tcp_recv_internal(tf_ssb_connection_t* connect
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						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)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t a[crypto_auth_hmacsha512256_BYTES];
 | 
						uint8_t a[crypto_auth_hmacsha512256_BYTES];
 | 
				
			||||||
	if (crypto_auth_hmacsha512256(a, connection->epub, sizeof(connection->epub), connection->ssb->network_key) != 0)
 | 
						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;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2102,7 +2103,7 @@ static bool _tf_ssb_connection_read_start(tf_ssb_connection_t* connection)
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		char reason[1024];
 | 
							char reason[1024];
 | 
				
			||||||
		snprintf(reason, sizeof(reason), "uv_read_start failed: %s", uv_strerror(result));
 | 
							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 false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
@@ -2115,7 +2116,7 @@ static bool _tf_ssb_connection_read_stop(tf_ssb_connection_t* connection)
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		char reason[1024];
 | 
							char reason[1024];
 | 
				
			||||||
		snprintf(reason, sizeof(reason), "uv_read_stop failed: %s", uv_strerror(result));
 | 
							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 false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
@@ -2137,7 +2138,7 @@ static void _tf_ssb_connection_on_connect(uv_connect_t* connect, int status)
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		char reason[1024];
 | 
							char reason[1024];
 | 
				
			||||||
		snprintf(reason, sizeof(reason), "uv_tcp_connect failed: %s", uv_strerror(status));
 | 
							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)
 | 
						while (connection)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		tf_ssb_connection_t* next = connection->next;
 | 
							tf_ssb_connection_t* next = connection->next;
 | 
				
			||||||
		tf_ssb_connection_close(connection);
 | 
							tf_ssb_connection_close(connection, "Shutting down.");
 | 
				
			||||||
		connection = next;
 | 
							connection = next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	uv_run(ssb->loop, UV_RUN_NOWAIT);
 | 
						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_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_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
 | 
						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)
 | 
					static void _tf_ssb_on_connection(uv_stream_t* stream, int status)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	tf_ssb_t* ssb = stream->data;
 | 
						tf_ssb_t* ssb = stream->data;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -514,8 +514,9 @@ JSContext* tf_ssb_connection_get_context(tf_ssb_connection_t* connection);
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
** Close a connection.
 | 
					** Close a connection.
 | 
				
			||||||
** @param connection The 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.
 | 
					** Check whether a connection is connected.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
						tf_ssb_connection_t* connection = tf_ssb_connection_get(ssb, id);
 | 
				
			||||||
	if (connection)
 | 
						if (connection)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		tf_ssb_connection_close(connection);
 | 
							tf_ssb_connection_close(connection, "Close requested by user.");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	JS_FreeCString(context, id);
 | 
						JS_FreeCString(context, id);
 | 
				
			||||||
	return connection ? JS_TRUE : JS_FALSE;
 | 
						return connection ? JS_TRUE : JS_FALSE;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
						if (flags & k_ssb_rpc_flag_end_error)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		tf_ssb_connection_remove_request(connection, request_number);
 | 
							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
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -536,7 +536,7 @@ void tf_ssb_test_rooms(const tf_test_options_t* options)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	uv_run(&loop, UV_RUN_NOWAIT);
 | 
						uv_run(&loop, UV_RUN_NOWAIT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tf_ssb_connection_close(tun0);
 | 
						tf_ssb_connection_close(tun0, "done");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uv_run(&loop, UV_RUN_NOWAIT);
 | 
						uv_run(&loop, UV_RUN_NOWAIT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user