From 681859531cb42c55e76cb8de5d0c437ea1946e39 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Wed, 2 Oct 2024 18:46:12 -0400 Subject: [PATCH] muxrpc: Simplifying comparing RPC names. This has just always bugged me. --- src/ssb.c | 133 +++++++++----------------------------------------- src/ssb.h | 4 +- src/ssb.rpc.c | 22 ++++----- 3 files changed, 37 insertions(+), 122 deletions(-) diff --git a/src/ssb.c b/src/ssb.c index 338919e4..28af7f49 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -131,8 +131,7 @@ typedef struct _tf_ssb_broadcast_t typedef struct _tf_ssb_rpc_callback_node_t tf_ssb_rpc_callback_node_t; typedef struct _tf_ssb_rpc_callback_node_t { - const char** name; - const char* flattened_name; + const char* name; tf_ssb_rpc_callback_t* callback; tf_ssb_callback_cleanup_t* cleanup; void* user_data; @@ -1521,60 +1520,28 @@ static bool _tf_ssb_connection_recv_pop(tf_ssb_connection_t* connection, uint8_t return true; } -static bool _tf_ssb_name_equals(JSContext* context, JSValue object, const char** match) +static void _tf_ssb_name_to_string(JSContext* context, JSValue object, char* buffer, size_t size) { - bool result = true; JSValue name = JS_GetPropertyStr(context, object, "name"); - if (JS_IsArray(context, name)) { int length = tf_util_get_length(context, name); + int offset = 0; for (int i = 0; i < length; i++) { - if (!match[i]) - { - result = false; - break; - } - - JSValue element = JS_GetPropertyUint32(context, name, i); - const char* str = JS_ToCString(context, element); - if (!str || strcmp(str, match[i]) != 0) - { - result = false; - } - JS_FreeCString(context, str); - JS_FreeValue(context, element); - } - if (result && match[length]) - { - result = false; + JSValue part = JS_GetPropertyUint32(context, name, i); + const char* part_str = JS_ToCString(context, part); + offset += snprintf(buffer + offset, size - offset, "%s%s", i == 0 ? "" : ".", part_str); + JS_FreeCString(context, part_str); + JS_FreeValue(context, part); } } else if (JS_IsString(name)) { - /* Manifest is traditionally sent as not an array for some reason. */ - const char* str = JS_ToCString(context, name); - result = str && match[0] && strcmp(str, match[0]) == 0 && !match[1]; - JS_FreeCString(context, str); + const char* part_str = JS_ToCString(context, name); + snprintf(buffer, size, "%s", part_str); + JS_FreeCString(context, part_str); } - else - { - result = false; - } - - JS_FreeValue(context, name); - return result; -} - -static void _tf_ssb_name_to_string(JSContext* context, JSValue object, char* buffer, size_t size) -{ - JSValue name = JS_GetPropertyStr(context, object, "name"); - JSValue json_val = JS_JSONStringify(context, name, JS_NULL, JS_NewInt32(context, 2)); - const char* value = JS_ToCString(context, json_val); - snprintf(buffer, size, "%s", value); - JS_FreeCString(context, value); - JS_FreeValue(context, json_val); JS_FreeValue(context, name); } @@ -1624,35 +1591,14 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t else if (JS_IsObject(val)) { bool found = false; - char namebuf[256] = ""; - JSValue name = JS_GetPropertyStr(context, val, "name"); - if (JS_IsArray(context, name)) - { - int length = tf_util_get_length(context, name); - int offset = 0; - for (int i = 0; i < length; i++) - { - JSValue part = JS_GetPropertyUint32(context, name, i); - const char* part_str = JS_ToCString(context, part); - offset += snprintf(namebuf + offset, sizeof(namebuf) - offset, "%s%s", i == 0 ? "" : ".", part_str); - JS_FreeCString(context, part_str); - JS_FreeValue(context, part); - } - } - else if (JS_IsString(name)) - { - const char* part_str = JS_ToCString(context, name); - snprintf(namebuf, sizeof(namebuf), "%s", part_str); - JS_FreeCString(context, part_str); - } - JS_FreeValue(context, name); - + char name[256] = ""; + _tf_ssb_name_to_string(context, val, name, sizeof(name)); for (tf_ssb_rpc_callback_node_t* it = connection->ssb->rpc; it; it = it->next) { - if (_tf_ssb_name_equals(context, val, it->name)) + if (strcmp(name, it->name) == 0) { - tf_ssb_connection_add_request(connection, -request_number, namebuf, NULL, NULL, NULL, NULL); - tf_trace_begin(connection->ssb->trace, it->flattened_name); + tf_ssb_connection_add_request(connection, -request_number, name, NULL, NULL, NULL, NULL); + tf_trace_begin(connection->ssb->trace, it->name); PRE_CALLBACK(connection->ssb, it->callback); it->callback(connection, flags, request_number, val, message, size, it->user_data); POST_CALLBACK(connection->ssb, it->callback); @@ -1661,12 +1607,10 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t break; } } - if (!found && !_tf_ssb_name_equals(context, val, (const char*[]) { "Error", NULL })) + if (!found && strcmp(name, "Error") != 0) { - tf_ssb_connection_add_request(connection, -request_number, namebuf, NULL, NULL, NULL, NULL); - char buffer[256]; - _tf_ssb_name_to_string(context, val, buffer, sizeof(buffer)); - tf_ssb_connection_rpc_send_error_method_not_allowed(connection, flags, -request_number, buffer); + tf_ssb_connection_add_request(connection, -request_number, name, NULL, NULL, NULL, NULL); + tf_ssb_connection_rpc_send_error_method_not_allowed(connection, flags, -request_number, name); } } } @@ -3479,47 +3423,18 @@ void tf_ssb_remove_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_connection } } -void tf_ssb_add_rpc_callback(tf_ssb_t* ssb, const char** name, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data) +void tf_ssb_add_rpc_callback(tf_ssb_t* ssb, const char* name, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data) { - size_t name_len = 0; - int name_count = 0; - for (int i = 0; name[i]; i++) - { - name_count++; - name_len += strlen(name[i]) + 1; - } - tf_ssb_rpc_callback_node_t* node = tf_malloc(sizeof(tf_ssb_rpc_callback_node_t) + (name_count + 1) * sizeof(const char*) + name_len + name_len + 3); + size_t name_len = strlen(name); + tf_ssb_rpc_callback_node_t* node = tf_malloc(sizeof(tf_ssb_rpc_callback_node_t) + name_len + 1); *node = (tf_ssb_rpc_callback_node_t) { - .name = (const char**)(node + 1), - .flattened_name = (const char*)(node + 1) + (name_count + 1) * sizeof(const char*) + name_len, + .name = (const char*)(node + 1), .callback = callback, .cleanup = cleanup, .user_data = user_data, .next = ssb->rpc, }; - char* p = (char*)(node + 1) + (name_count + 1) * sizeof(const char*); - for (int i = 0; i < name_count; i++) - { - size_t len = strlen(name[i]); - memcpy(p, name[i], len + 1); - node->name[i] = p; - p += len + 1; - } - char* flattened_name = (char*)node->flattened_name; - for (int i = 0; i < name_count; i++) - { - size_t length = strlen(name[i]); - memcpy(flattened_name, name[i], length); - flattened_name += length; - if (i != name_count - 1) - { - *flattened_name++ = '.'; - } - } - *flattened_name++ = '('; - *flattened_name++ = ')'; - *flattened_name++ = '\0'; - node->name[name_count] = NULL; + memcpy((char*)node->name, name, name_len + 1); ssb->rpc = node; ssb->rpc_count++; } diff --git a/src/ssb.h b/src/ssb.h index da4621e7..a5682f2b 100644 --- a/src/ssb.h +++ b/src/ssb.h @@ -676,12 +676,12 @@ typedef void(tf_ssb_rpc_callback_t)(tf_ssb_connection_t* connection, uint8_t fla /** ** Register a MUXRPC callback by name. ** @param ssb The SSB instance. -** @param name The NULL-terminated name. +** @param name The RPC name as a .-separated string. ** @param callback The callback. ** @param cleanup A function to be called when the callback is removed. ** @param user_data User data to pass to the callback. */ -void tf_ssb_add_rpc_callback(tf_ssb_t* ssb, const char** name, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data); +void tf_ssb_add_rpc_callback(tf_ssb_t* ssb, const char* name, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data); /** ** Remove a MUXRPC callback. diff --git a/src/ssb.rpc.c b/src/ssb.rpc.c index 9b8ddf0f..548739a0 100644 --- a/src/ssb.rpc.c +++ b/src/ssb.rpc.c @@ -1511,15 +1511,15 @@ static void _tf_ssb_rpc_peers_exchange(tf_ssb_connection_t* connection, uint8_t void tf_ssb_rpc_register(tf_ssb_t* ssb) { tf_ssb_add_connections_changed_callback(ssb, _tf_ssb_rpc_connections_changed_callback, NULL, NULL); - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "gossip", "ping", NULL }, _tf_ssb_rpc_gossip_ping, NULL, NULL); /* DUPLEX */ - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "blobs", "get", NULL }, _tf_ssb_rpc_blobs_get, NULL, NULL); /* SOURCE */ - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "blobs", "has", NULL }, _tf_ssb_rpc_blobs_has, NULL, NULL); /* ASYNC */ - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "blobs", "createWants", NULL }, _tf_ssb_rpc_blobs_createWants, NULL, NULL); /* SOURCE */ - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "tunnel", "connect", NULL }, _tf_ssb_rpc_tunnel_connect, NULL, NULL); /* DUPLEX */ - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "tunnel", "isRoom", NULL }, _tf_ssb_rpc_room_meta, NULL, NULL); /* FAKE-ASYNC */ - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "room", "metadata", NULL }, _tf_ssb_rpc_room_meta, NULL, NULL); /* ASYNC */ - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "room", "attendants", NULL }, _tf_ssb_rpc_room_attendants, NULL, NULL); /* SOURCE */ - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "createHistoryStream", NULL }, _tf_ssb_rpc_createHistoryStream, NULL, NULL); /* SOURCE */ - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "ebt", "replicate", NULL }, _tf_ssb_rpc_ebt_replicate_server, NULL, NULL); /* DUPLEX */ - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "peers", "exchange", NULL }, _tf_ssb_rpc_peers_exchange, NULL, NULL); /* ASYNC */ + tf_ssb_add_rpc_callback(ssb, "gossip.ping", _tf_ssb_rpc_gossip_ping, NULL, NULL); /* DUPLEX */ + tf_ssb_add_rpc_callback(ssb, "blobs.get", _tf_ssb_rpc_blobs_get, NULL, NULL); /* SOURCE */ + tf_ssb_add_rpc_callback(ssb, "blobs.has", _tf_ssb_rpc_blobs_has, NULL, NULL); /* ASYNC */ + tf_ssb_add_rpc_callback(ssb, "blobs.createWants", _tf_ssb_rpc_blobs_createWants, NULL, NULL); /* SOURCE */ + tf_ssb_add_rpc_callback(ssb, "tunnel.connect", _tf_ssb_rpc_tunnel_connect, NULL, NULL); /* DUPLEX */ + tf_ssb_add_rpc_callback(ssb, "tunnel.isRoom", _tf_ssb_rpc_room_meta, NULL, NULL); /* FAKE-ASYNC */ + tf_ssb_add_rpc_callback(ssb, "room.metadata", _tf_ssb_rpc_room_meta, NULL, NULL); /* ASYNC */ + tf_ssb_add_rpc_callback(ssb, "room.attendants", _tf_ssb_rpc_room_attendants, NULL, NULL); /* SOURCE */ + tf_ssb_add_rpc_callback(ssb, "createHistoryStream", _tf_ssb_rpc_createHistoryStream, NULL, NULL); /* SOURCE */ + tf_ssb_add_rpc_callback(ssb, "ebt.replicate", _tf_ssb_rpc_ebt_replicate_server, NULL, NULL); /* DUPLEX */ + tf_ssb_add_rpc_callback(ssb, "peers.exchange", _tf_ssb_rpc_peers_exchange, NULL, NULL); /* ASYNC */ }