ssb: Before destroying a connection, show a message on why it is going away in the UI.
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build Tilde Friends / Build-All (push) Successful in 20m6s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build Tilde Friends / Build-All (push) Successful in 20m6s
				
			This commit is contained in:
		
							
								
								
									
										53
									
								
								src/ssb.c
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								src/ssb.c
									
									
									
									
									
								
							| @@ -273,6 +273,7 @@ typedef struct _tf_ssb_connection_t | ||||
| 	uv_async_t async; | ||||
| 	uv_async_t scheduled_async; | ||||
| 	uv_timer_t handshake_timer; | ||||
| 	uv_timer_t linger_timer; | ||||
| 	bool closing; | ||||
|  | ||||
| 	tf_ssb_connection_t* tunnel_connection; | ||||
| @@ -1839,10 +1840,21 @@ JSValue tf_ssb_sign_message(tf_ssb_t* ssb, const char* author, const uint8_t* pr | ||||
| 	return root; | ||||
| } | ||||
|  | ||||
| static void _tf_ssb_connection_linger_timer(uv_timer_t* timer) | ||||
| { | ||||
| 	tf_ssb_connection_t* connection = timer->data; | ||||
| 	uv_close((uv_handle_t*)&connection->linger_timer, _tf_ssb_connection_on_close); | ||||
| } | ||||
|  | ||||
| static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const char* reason) | ||||
| { | ||||
| 	tf_ssb_t* ssb = connection->ssb; | ||||
| 	connection->closing = true; | ||||
| 	if (!connection->closing) | ||||
| 	{ | ||||
| 		connection->closing = true; | ||||
| 		uv_timer_start(&connection->linger_timer, _tf_ssb_connection_linger_timer, 5000, 0); | ||||
| 		_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_update, connection); | ||||
| 	} | ||||
| 	if (connection->connect_callback) | ||||
| 	{ | ||||
| 		PRE_CALLBACK(connection->ssb, connection->connect_callback); | ||||
| @@ -1853,7 +1865,7 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch | ||||
| 	} | ||||
| 	if (!connection->destroy_reason) | ||||
| 	{ | ||||
| 		connection->destroy_reason = reason; | ||||
| 		connection->destroy_reason = tf_strdup(reason); | ||||
| 	} | ||||
| 	_tf_ssb_connection_dispatch_scheduled(connection); | ||||
| 	tf_free(connection->scheduled); | ||||
| @@ -1879,14 +1891,6 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch | ||||
| 				tf_ssb_connection_remove_request(*it, (*it)->requests[i].request_number); | ||||
| 			} | ||||
| 		} | ||||
| 		if (*it == connection) | ||||
| 		{ | ||||
| 			*it = connection->next; | ||||
| 			connection->next = NULL; | ||||
| 			ssb->connections_count--; | ||||
| 			_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_remove, connection); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	bool again = true; | ||||
| 	while (again) | ||||
| @@ -1934,16 +1938,29 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch | ||||
| 	} | ||||
|  | ||||
| 	if (JS_IsUndefined(connection->object) && !connection->async.data && !connection->scheduled_async.data && !connection->tcp.data && !connection->connect.data && | ||||
| 		!connection->handshake_timer.data && connection->ref_count == 0) | ||||
| 		!connection->handshake_timer.data && !connection->linger_timer.data && connection->ref_count == 0) | ||||
| 	{ | ||||
| 		tf_free(connection->message_requests); | ||||
| 		connection->message_requests = NULL; | ||||
| 		connection->message_requests_count = 0; | ||||
|  | ||||
| 		for (tf_ssb_connection_t** it = &connection->ssb->connections; *it; it = &(*it)->next) | ||||
| 		{ | ||||
| 			if (*it == connection) | ||||
| 			{ | ||||
| 				*it = connection->next; | ||||
| 				connection->next = NULL; | ||||
| 				ssb->connections_count--; | ||||
| 				_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_remove, connection); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (--connection->ssb->connection_ref_count == 0 && connection->ssb->shutting_down_deferred) | ||||
| 		{ | ||||
| 			tf_ssb_destroy(connection->ssb); | ||||
| 		} | ||||
| 		tf_free((void*)connection->destroy_reason); | ||||
| 		tf_free(connection); | ||||
| 	} | ||||
| } | ||||
| @@ -2723,6 +2740,9 @@ static tf_ssb_connection_t* _tf_ssb_connection_create( | ||||
| 	uv_timer_init(ssb->loop, &connection->handshake_timer); | ||||
| 	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->object = JS_NewObjectClass(ssb->context, _connection_class_id); | ||||
| 	JS_SetOpaque(connection->object, connection); | ||||
| 	char public_key_str[k_id_base64_len] = { 0 }; | ||||
| @@ -2796,6 +2816,9 @@ tf_ssb_connection_t* tf_ssb_connection_tunnel_create(tf_ssb_t* ssb, const char* | ||||
| 	uv_timer_init(ssb->loop, &tunnel->handshake_timer); | ||||
| 	uv_timer_start(&tunnel->handshake_timer, _tf_ssb_connection_handshake_timer_callback, k_handshake_timeout_ms, 0); | ||||
|  | ||||
| 	tunnel->linger_timer.data = tunnel; | ||||
| 	uv_timer_init(ssb->loop, &tunnel->linger_timer); | ||||
|  | ||||
| 	tunnel->object = JS_NewObjectClass(ssb->context, _connection_class_id); | ||||
| 	JS_SetOpaque(tunnel->object, tunnel); | ||||
| 	JS_SetPropertyStr(context, tunnel->object, "id", JS_NewString(context, target_id)); | ||||
| @@ -2956,6 +2979,9 @@ static void _tf_ssb_on_connection(uv_stream_t* stream, int status) | ||||
| 	uv_timer_init(ssb->loop, &connection->handshake_timer); | ||||
| 	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); | ||||
|  | ||||
| 	struct sockaddr_storage addr = { 0 }; | ||||
| 	int size = sizeof(addr); | ||||
| 	if (uv_tcp_getpeername(&connection->tcp, (struct sockaddr*)&addr, &size) == 0) | ||||
| @@ -4265,6 +4291,11 @@ void tf_ssb_connection_adjust_write_count(tf_ssb_connection_t* connection, int d | ||||
| 	uv_async_send(&connection->scheduled_async); | ||||
| } | ||||
|  | ||||
| const char* tf_ssb_connection_get_destroy_reason(tf_ssb_connection_t* connection) | ||||
| { | ||||
| 	return connection ? connection->destroy_reason : NULL; | ||||
| } | ||||
|  | ||||
| void tf_ssb_sync_start(tf_ssb_t* ssb) | ||||
| { | ||||
| 	tf_ssb_connections_sync_start(ssb->connections_tracker); | ||||
|   | ||||
| @@ -1093,6 +1093,13 @@ void tf_ssb_connection_adjust_read_backpressure(tf_ssb_connection_t* connection, | ||||
| */ | ||||
| void tf_ssb_connection_adjust_write_count(tf_ssb_connection_t* connection, int delta); | ||||
|  | ||||
| /** | ||||
| ** Get the reason why a connection is going away. | ||||
| ** @param connection The connection. | ||||
| ** @return The reason or NULL. | ||||
| */ | ||||
| const char* tf_ssb_connection_get_destroy_reason(tf_ssb_connection_t* connection); | ||||
|  | ||||
| /** | ||||
| ** Initiate a tunnel connection. | ||||
| ** @param ssb The SSB instance. | ||||
|   | ||||
| @@ -1120,6 +1120,11 @@ static JSValue _tf_ssb_connections(JSContext* context, JSValueConst this_val, in | ||||
| 			int flags = tf_ssb_connection_get_flags(connection); | ||||
| 			JS_SetPropertyStr(context, flags_object, "one_shot", JS_NewBool(context, (flags & k_tf_ssb_connect_flag_one_shot) != 0)); | ||||
| 			JS_SetPropertyStr(context, object, "flags", flags_object); | ||||
| 			const char* destroy_reason = tf_ssb_connection_get_destroy_reason(connection); | ||||
| 			if (destroy_reason) | ||||
| 			{ | ||||
| 				JS_SetPropertyStr(context, object, "destroy_reason", JS_NewString(context, destroy_reason)); | ||||
| 			} | ||||
| 			JS_SetPropertyUint32(context, result, i, object); | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user