ssb: Indicate which muxrpc sends failed, and use that to fix some replication nonsense and log noise.
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build Tilde Friends / Build-All (push) Successful in 15m22s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build Tilde Friends / Build-All (push) Successful in 15m22s
				
			This commit is contained in:
		| @@ -982,12 +982,7 @@ static bool _is_filename_safe(const char* filename) | ||||
| 	} | ||||
| 	for (const char* p = filename; *p; p++) | ||||
| 	{ | ||||
| 		if ((*p <= 'a' && *p >= 'z') && | ||||
| 			(*p <= 'A' && *p >= 'Z') && | ||||
| 			(*p <= '0' && *p >= '9') && | ||||
| 			*p != '.' && | ||||
| 			*p != '-' && | ||||
| 			*p != '_') | ||||
| 		if ((*p <= 'a' && *p >= 'z') && (*p <= 'A' && *p >= 'Z') && (*p <= '0' && *p >= '9') && *p != '.' && *p != '-' && *p != '_') | ||||
| 		{ | ||||
| 			return false; | ||||
| 		} | ||||
| @@ -1049,9 +1044,12 @@ static void _httpd_endpoint_view_after_work(tf_ssb_t* ssb, int status, void* use | ||||
| 		snprintf(content_disposition, sizeof(content_disposition), "attachment; filename=%s", filename); | ||||
| 	} | ||||
| 	const char* headers[] = { | ||||
| 		"Content-Security-Policy", "sandbox allow-downloads allow-top-navigation-by-user-activation", | ||||
| 		"Content-Type", view->data ? _httpd_mime_type_from_magic_bytes_internal(view->data, view->size) : "text/plain", | ||||
| 		filename ? "Content-Disposition" : NULL, filename ? content_disposition : NULL, | ||||
| 		"Content-Security-Policy", | ||||
| 		"sandbox allow-downloads allow-top-navigation-by-user-activation", | ||||
| 		"Content-Type", | ||||
| 		view->data ? _httpd_mime_type_from_magic_bytes_internal(view->data, view->size) : "text/plain", | ||||
| 		filename ? "Content-Disposition" : NULL, | ||||
| 		filename ? content_disposition : NULL, | ||||
| 	}; | ||||
| 	int count = filename ? tf_countof(headers) / 2 : (tf_countof(headers) / 2 - 1); | ||||
| 	if (view->not_modified) | ||||
|   | ||||
							
								
								
									
										27
									
								
								src/ssb.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/ssb.c
									
									
									
									
									
								
							| @@ -835,7 +835,7 @@ void tf_ssb_connection_remove_request(tf_ssb_connection_t* connection, int32_t r | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* new_request_name, const uint8_t* message, size_t size, | ||||
| bool tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* new_request_name, const uint8_t* message, size_t size, | ||||
| 	tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data) | ||||
| { | ||||
| 	if (!connection) | ||||
| @@ -844,7 +844,7 @@ void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, | ||||
| 		{ | ||||
| 			cleanup(NULL, user_data); | ||||
| 		} | ||||
| 		return; | ||||
| 		return false; | ||||
| 	} | ||||
| 	if (flags & k_ssb_rpc_flag_new_request) | ||||
| 	{ | ||||
| @@ -856,13 +856,13 @@ void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, | ||||
| 	{ | ||||
| 		if (flags & k_ssb_rpc_flag_binary) | ||||
| 		{ | ||||
| 			tf_printf("Dropping message with no active request (%d): (%zd bytes).\n", request_number, size); | ||||
| 			tf_printf(MAGENTA "%s RPC DROP" RESET " message with no active request (%d): (%zd bytes).\n", connection->name, request_number, size); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			tf_printf("Dropping message with no active request (%d): %.*s\n", request_number, (int)size, message); | ||||
| 			tf_printf(MAGENTA "%s RPC DROP" RESET " message with no active request (%d): %.*s\n", connection->name, request_number, (int)size, message); | ||||
| 		} | ||||
| 		return; | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	uint8_t* combined = tf_malloc(9 + size); | ||||
| @@ -890,22 +890,24 @@ void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, | ||||
| 	{ | ||||
| 		tf_ssb_connection_add_request(connection, request_number, new_request_name, callback, cleanup, user_data, NULL); | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void tf_ssb_connection_rpc_send_json(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* new_request_name, JSValue message, | ||||
| bool tf_ssb_connection_rpc_send_json(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* new_request_name, JSValue message, | ||||
| 	tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data) | ||||
| { | ||||
| 	JSContext* context = connection->ssb->context; | ||||
| 	JSValue json = JS_JSONStringify(context, message, JS_NULL, JS_NULL); | ||||
| 	size_t size = 0; | ||||
| 	const char* json_string = JS_ToCStringLen(context, &size, json); | ||||
| 	tf_ssb_connection_rpc_send( | ||||
| 	bool result = tf_ssb_connection_rpc_send( | ||||
| 		connection, k_ssb_rpc_flag_json | (flags & ~k_ssb_rpc_mask_type), request_number, new_request_name, (const uint8_t*)json_string, size, callback, cleanup, user_data); | ||||
| 	JS_FreeCString(context, json_string); | ||||
| 	JS_FreeValue(context, json); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| void tf_ssb_connection_rpc_send_error(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* error) | ||||
| bool tf_ssb_connection_rpc_send_error(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* error) | ||||
| { | ||||
| 	JSContext* context = connection->ssb->context; | ||||
| 	JSValue message = JS_NewObject(context); | ||||
| @@ -913,17 +915,18 @@ void tf_ssb_connection_rpc_send_error(tf_ssb_connection_t* connection, uint8_t f | ||||
| 	JS_SetPropertyStr(context, message, "name", JS_NewString(context, "Error")); | ||||
| 	JS_SetPropertyStr(context, message, "stack", JS_NewString(context, stack ? stack : "stack unavailable")); | ||||
| 	JS_SetPropertyStr(context, message, "message", JS_NewString(context, error)); | ||||
| 	tf_ssb_connection_rpc_send_json( | ||||
| 	bool result = tf_ssb_connection_rpc_send_json( | ||||
| 		connection, ((flags & k_ssb_rpc_flag_stream) ? (k_ssb_rpc_flag_stream) : 0) | k_ssb_rpc_flag_end_error, request_number, NULL, message, NULL, NULL, NULL); | ||||
| 	JS_FreeValue(context, message); | ||||
| 	tf_free((void*)stack); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| void tf_ssb_connection_rpc_send_error_method_not_allowed(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* name) | ||||
| bool tf_ssb_connection_rpc_send_error_method_not_allowed(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* name) | ||||
| { | ||||
| 	char buffer[1024]; | ||||
| 	char buffer[1024] = ""; | ||||
| 	snprintf(buffer, sizeof(buffer), "method '%s' is not in list of allowed methods", name); | ||||
| 	tf_ssb_connection_rpc_send_error(connection, flags, request_number, buffer); | ||||
| 	return tf_ssb_connection_rpc_send_error(connection, flags, request_number, buffer); | ||||
| } | ||||
|  | ||||
| static int _utf8_len(uint8_t ch) | ||||
|   | ||||
							
								
								
									
										12
									
								
								src/ssb.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/ssb.h
									
									
									
									
									
								
							| @@ -714,8 +714,9 @@ void tf_ssb_remove_rpc_callback(tf_ssb_t* ssb, const char** name, tf_ssb_rpc_cal | ||||
| ** @param callback A callback to call if a response is received. | ||||
| ** @param cleanup A callback to call if the callback is removed. | ||||
| ** @param user_data User data to pass to the callback. | ||||
| ** @return true If the message was queued to send, false if the connection or request were invalid. | ||||
| */ | ||||
| void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* new_request_name, const uint8_t* message, size_t size, | ||||
| bool tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* new_request_name, const uint8_t* message, size_t size, | ||||
| 	tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data); | ||||
|  | ||||
| /** | ||||
| @@ -728,8 +729,9 @@ void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, | ||||
| ** @param callback A callback to call if a response is received. | ||||
| ** @param cleanup A callback to call if the callback is removed. | ||||
| ** @param user_data User data to pass to the callback. | ||||
| ** @return true If the message was queued to send, false if the connection or request were invalid. | ||||
| */ | ||||
| void tf_ssb_connection_rpc_send_json(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* new_request_name, JSValue message, | ||||
| bool tf_ssb_connection_rpc_send_json(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* new_request_name, JSValue message, | ||||
| 	tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data); | ||||
|  | ||||
| /** | ||||
| @@ -738,8 +740,9 @@ void tf_ssb_connection_rpc_send_json(tf_ssb_connection_t* connection, uint8_t fl | ||||
| ** @param flags The message flags. | ||||
| ** @param request_number The request number. | ||||
| ** @param error The error string. | ||||
| ** @return true If the message was queued to send, false if the connection or request were invalid. | ||||
| */ | ||||
| void tf_ssb_connection_rpc_send_error(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* error); | ||||
| bool tf_ssb_connection_rpc_send_error(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* error); | ||||
|  | ||||
| /** | ||||
| ** Send a MUXRPC "method not allowed" error message. | ||||
| @@ -747,8 +750,9 @@ void tf_ssb_connection_rpc_send_error(tf_ssb_connection_t* connection, uint8_t f | ||||
| ** @param flags The message flags. | ||||
| ** @param request_number The request number. | ||||
| ** @param name The name of the not-allowed method. | ||||
| ** @return true If the message was queued to send, false if the connection or request were invalid. | ||||
| */ | ||||
| void tf_ssb_connection_rpc_send_error_method_not_allowed(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* name); | ||||
| bool tf_ssb_connection_rpc_send_error_method_not_allowed(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* name); | ||||
|  | ||||
| /** | ||||
| ** Register a callback to be called when a message is received for the given | ||||
|   | ||||
| @@ -2484,8 +2484,7 @@ static void _tf_ssb_set_user_permission_after_work(tf_ssb_t* ssb, int status, vo | ||||
| static JSValue _tf_ssb_set_user_permission(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) | ||||
| { | ||||
| 	set_user_permission_t* set = tf_malloc(sizeof(set_user_permission_t)); | ||||
| 	*set = (set_user_permission_t) | ||||
| 	{ | ||||
| 	*set = (set_user_permission_t) { | ||||
| 		.ssb = JS_GetOpaque(this_val, _tf_ssb_classId), | ||||
| 		.context = context, | ||||
| 		.user = JS_ToCString(context, argv[0]), | ||||
|   | ||||
| @@ -18,7 +18,8 @@ | ||||
| #define _countof(a) ((int)(sizeof((a)) / sizeof(*(a)))) | ||||
| #endif | ||||
|  | ||||
| static void _tf_ssb_connection_send_history_stream(tf_ssb_connection_t* connection, int32_t request_number, const char* author, int64_t sequence, bool keys, bool live); | ||||
| static void _tf_ssb_connection_send_history_stream( | ||||
| 	tf_ssb_connection_t* connection, int32_t request_number, const char* author, int64_t sequence, bool keys, bool live, bool end_request); | ||||
| static void _tf_ssb_rpc_send_peers_exchange(tf_ssb_connection_t* connection); | ||||
| static void _tf_ssb_rpc_start_delete_blobs(tf_ssb_t* ssb, int delay_ms); | ||||
|  | ||||
| @@ -92,8 +93,11 @@ static void _tf_ssb_rpc_blobs_get_after_work(tf_ssb_connection_t* connection, in | ||||
| 		const size_t k_send_max = 8192; | ||||
| 		for (size_t offset = 0; offset < work->size; offset += k_send_max) | ||||
| 		{ | ||||
| 			tf_ssb_connection_rpc_send(connection, k_ssb_rpc_flag_binary | k_ssb_rpc_flag_stream, -work->request_number, NULL, work->blob + offset, | ||||
| 				offset + k_send_max <= work->size ? k_send_max : (work->size - offset), NULL, NULL, NULL); | ||||
| 			if (!tf_ssb_connection_rpc_send(connection, k_ssb_rpc_flag_binary | k_ssb_rpc_flag_stream, -work->request_number, NULL, work->blob + offset, | ||||
| 					offset + k_send_max <= work->size ? k_send_max : (work->size - offset), NULL, NULL, NULL)) | ||||
| 			{ | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		tf_free(work->blob); | ||||
| 	} | ||||
| @@ -260,11 +264,12 @@ static void _tf_ssb_request_blob_wants_after_work(tf_ssb_connection_t* connectio | ||||
| 	{ | ||||
| 		JSContext* context = tf_ssb_connection_get_context(connection); | ||||
| 		tf_ssb_blob_wants_t* blob_wants = tf_ssb_connection_get_blob_wants_state(connection); | ||||
| 		for (int i = 0; i < work->out_id_count; i++) | ||||
| 		bool send_failed = false; | ||||
| 		for (int i = 0; i < work->out_id_count && !send_failed; i++) | ||||
| 		{ | ||||
| 			JSValue message = JS_NewObject(context); | ||||
| 			JS_SetPropertyStr(context, message, work->out_id[i], JS_NewInt32(context, -1)); | ||||
| 			tf_ssb_connection_rpc_send_json(connection, k_ssb_rpc_flag_stream, -blob_wants->request_number, NULL, message, NULL, NULL, NULL); | ||||
| 			send_failed = !tf_ssb_connection_rpc_send_json(connection, k_ssb_rpc_flag_stream, -blob_wants->request_number, NULL, message, NULL, NULL, NULL); | ||||
| 			JS_FreeValue(context, message); | ||||
| 			blob_wants->wants_sent++; | ||||
| 		} | ||||
| @@ -769,6 +774,7 @@ typedef struct _tf_ssb_connection_send_history_stream_t | ||||
| 	int64_t sequence; | ||||
| 	bool keys; | ||||
| 	bool live; | ||||
| 	bool end_request; | ||||
|  | ||||
| 	bool out_finished; | ||||
| 	int64_t out_max_sequence_seen; | ||||
| @@ -855,15 +861,18 @@ static void _tf_ssb_connection_send_history_stream_after_work(tf_ssb_connection_ | ||||
| 	{ | ||||
| 		for (int i = 0; i < request->out_messages_count; i++) | ||||
| 		{ | ||||
| 			tf_ssb_connection_rpc_send(connection, k_ssb_rpc_flag_stream | k_ssb_rpc_flag_json, request->request_number, NULL, (const uint8_t*)request->out_messages[i], | ||||
| 				strlen(request->out_messages[i]), NULL, NULL, NULL); | ||||
| 			if (!tf_ssb_connection_rpc_send(connection, k_ssb_rpc_flag_stream | k_ssb_rpc_flag_json, request->request_number, NULL, (const uint8_t*)request->out_messages[i], | ||||
| 					strlen(request->out_messages[i]), NULL, NULL, NULL)) | ||||
| 			{ | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		bool live = request->live && (tf_ssb_connection_get_flags(connection) & k_tf_ssb_connect_flag_one_shot) == 0; | ||||
| 		if (!request->out_finished) | ||||
| 		{ | ||||
| 			_tf_ssb_connection_send_history_stream(connection, request->request_number, request->author, request->out_max_sequence_seen, request->keys, live); | ||||
| 			_tf_ssb_connection_send_history_stream( | ||||
| 				connection, request->request_number, request->author, request->out_max_sequence_seen, request->keys, request->live, request->end_request); | ||||
| 		} | ||||
| 		else if (!live) | ||||
| 		else if (!request->live && request->end_request) | ||||
| 		{ | ||||
| 			tf_ssb_connection_rpc_send(connection, k_ssb_rpc_flag_json, request->request_number, NULL, (const uint8_t*)"false", strlen("false"), NULL, NULL, NULL); | ||||
| 		} | ||||
| @@ -889,7 +898,8 @@ static void _tf_ssb_connection_send_history_stream_callback(tf_ssb_connection_t* | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void _tf_ssb_connection_send_history_stream(tf_ssb_connection_t* connection, int32_t request_number, const char* author, int64_t sequence, bool keys, bool live) | ||||
| static void _tf_ssb_connection_send_history_stream( | ||||
| 	tf_ssb_connection_t* connection, int32_t request_number, const char* author, int64_t sequence, bool keys, bool live, bool end_request) | ||||
| { | ||||
| 	tf_ssb_connection_send_history_stream_t* async = tf_malloc(sizeof(tf_ssb_connection_send_history_stream_t)); | ||||
| 	*async = (tf_ssb_connection_send_history_stream_t) { | ||||
| @@ -897,6 +907,7 @@ static void _tf_ssb_connection_send_history_stream(tf_ssb_connection_t* connecti | ||||
| 		.sequence = sequence, | ||||
| 		.keys = keys, | ||||
| 		.live = live, | ||||
| 		.end_request = end_request, | ||||
| 	}; | ||||
| 	snprintf(async->author, sizeof(async->author), "%s", author); | ||||
| 	tf_ssb_connection_schedule_idle(connection, _tf_ssb_connection_send_history_stream_callback, async); | ||||
| @@ -928,7 +939,7 @@ static void _tf_ssb_rpc_createHistoryStream( | ||||
| 	JS_ToInt64(context, &sequence, seq); | ||||
| 	const char* author = JS_ToCString(context, id); | ||||
|  | ||||
| 	_tf_ssb_connection_send_history_stream(connection, -request_number, author, sequence, is_keys, is_live); | ||||
| 	_tf_ssb_connection_send_history_stream(connection, -request_number, author, sequence, is_keys, is_live, true); | ||||
|  | ||||
| 	if (is_live) | ||||
| 	{ | ||||
| @@ -1110,7 +1121,7 @@ static void _tf_ssb_rpc_ebt_replicate_send_messages(tf_ssb_connection_t* connect | ||||
| 				{ | ||||
| 					int32_t request_number = tf_ssb_connection_get_ebt_request_number(connection); | ||||
| 					bool live = (tf_ssb_connection_get_flags(connection) & k_tf_ssb_connect_flag_one_shot) == 0; | ||||
| 					_tf_ssb_connection_send_history_stream(connection, request_number, author, sequence >> 1, false, live); | ||||
| 					_tf_ssb_connection_send_history_stream(connection, request_number, author, sequence >> 1, false, live, false); | ||||
| 					if (live) | ||||
| 					{ | ||||
| 						tf_ssb_connection_add_new_message_request(connection, author, request_number, false); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user