diff --git a/src/ssb.c b/src/ssb.c index bb903489..287e60ac 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -294,7 +294,7 @@ static void _tf_ssb_connection_close(tf_ssb_connection_t* connection, const char else if (connection->state == k_tf_ssb_state_verified || connection->state == k_tf_ssb_state_server_verified) { - printf("Connection %p is closing: %s.\n", connection, reason); + printf("Connection %s %p is closing: %s.\n", connection->name, connection, reason); connection->state = k_tf_ssb_state_closing; _tf_ssb_connection_send_close(connection); } @@ -999,7 +999,10 @@ int tf_ssb_connection_get_port(tf_ssb_connection_t* connection) bool tf_ssb_connection_get_id(tf_ssb_connection_t* connection, char* out_id, size_t out_id_size) { - return tf_ssb_id_bin_to_str(out_id, out_id_size, connection->serverpub); + return + connection && + memcmp(connection->serverpub, (uint8_t[k_id_bin_len]) { 0 }, k_id_bin_len) != 0 && + tf_ssb_id_bin_to_str(out_id, out_id_size, connection->serverpub); } static bool _tf_ssb_is_already_connected(tf_ssb_t* ssb, uint8_t* id, tf_ssb_connection_t* ignore_connection) @@ -1273,7 +1276,7 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t connection->ssb->rpc_in++; if (size == 0) { - _tf_ssb_connection_close(connection, "read zero"); + _tf_ssb_connection_close(connection, "rpc recv zero"); return; } else if (flags & k_ssb_rpc_flag_json) @@ -1282,7 +1285,7 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t tf_ssb_id_bin_to_str(id, sizeof(id), connection->serverpub); if (connection->ssb->verbose) { - printf(CYAN "%s RPC RECV" RESET " from %s flags=%x RN=%d: %.*s\n", connection->name, id, flags, request_number, (int)size, message); + printf(CYAN "%s RPC RECV" RESET " from %s flags=%x RN=%d: [%zd B] %.*s\n", connection->name, id, flags, request_number, size, (int)size, message); } JSContext* context = connection->ssb->context; JSValue val = JS_ParseJSON(context, (const char*)message, size, NULL); @@ -1712,7 +1715,7 @@ static void _tf_ssb_connection_on_tcp_recv_internal(tf_ssb_connection_t* connect } else { - _tf_ssb_connection_close(connection, "read zero"); + _tf_ssb_connection_close(connection, uv_strerror(nread)); } } diff --git a/src/ssb.rpc.c b/src/ssb.rpc.c index f6fd1c36..f4a319f9 100644 --- a/src/ssb.rpc.c +++ b/src/ssb.rpc.c @@ -251,62 +251,65 @@ static void _tf_ssb_rpc_tunnel_connect(tf_ssb_connection_t* connection, uint8_t !JS_IsUndefined(portal) && !JS_IsUndefined(target)) { - const char* portal_str = JS_ToCString(context, portal); const char* target_str = JS_ToCString(context, target); tf_ssb_connection_t* target_connection = tf_ssb_connection_get(ssb, target_str); - int32_t tunnel_request_number = tf_ssb_connection_next_request_number(target_connection); - - JSValue message = JS_NewObject(context); - JSValue name = JS_NewArray(context); - JS_SetPropertyUint32(context, name, 0, JS_NewString(context, "tunnel")); - JS_SetPropertyUint32(context, name, 1, JS_NewString(context, "connect")); - JS_SetPropertyStr(context, message, "name", name); - JSValue arg_obj = JS_NewObject(context); - char origin_str[k_id_base64_len] = ""; - tf_ssb_connection_get_id(connection, origin_str, sizeof(origin_str)); - JS_SetPropertyStr(context, arg_obj, "origin", JS_NewString(context, origin_str)); - JS_SetPropertyStr(context, arg_obj, "portal", JS_NewString(context, portal_str)); - JS_SetPropertyStr(context, arg_obj, "target", JS_NewString(context, target_str)); - JSValue arg_array = JS_NewArray(context); - JS_SetPropertyUint32(context, arg_array, 0, arg_obj); - JS_SetPropertyStr(context, message, "args", arg_array); - JS_SetPropertyStr(context, message, "type", JS_NewString(context, "duplex")); - JSValue message_val = JS_JSONStringify(context, message, JS_NULL, JS_NULL); - size_t size; - const char* message_str = JS_ToCStringLen(context, &size, message_val); - - tf_ssb_connection_rpc_send( - target_connection, - k_ssb_rpc_flag_json | k_ssb_rpc_flag_stream, - tunnel_request_number, - (const uint8_t*)message_str, - size, - NULL, - NULL, - NULL); - - JS_FreeCString(context, message_str); - - tunnel_t* data0 = tf_malloc(sizeof(tunnel_t)); - *data0 = (tunnel_t) + if (target_connection) { - .connection = target_connection, - .request_number = tunnel_request_number, - }; - tunnel_t* data1 = tf_malloc(sizeof(tunnel_t)); - *data1 = (tunnel_t) - { - .connection = connection, - .request_number = -request_number, - }; - printf("MAKE TUNNEL %p %p\n", connection, target_connection); - tf_ssb_connection_add_request(connection, -request_number, _tf_ssb_rpc_tunnel_callback, _tf_ssb_rpc_tunnel_cleanup, data0, target_connection); - tf_ssb_connection_add_request(target_connection, tunnel_request_number, _tf_ssb_rpc_tunnel_callback, _tf_ssb_rpc_tunnel_cleanup, data1, connection); + int32_t tunnel_request_number = tf_ssb_connection_next_request_number(target_connection); + const char* portal_str = JS_ToCString(context, portal); - JS_FreeValue(context, message_val); - JS_FreeValue(context, message); - JS_FreeCString(context, portal_str); + JSValue message = JS_NewObject(context); + JSValue name = JS_NewArray(context); + JS_SetPropertyUint32(context, name, 0, JS_NewString(context, "tunnel")); + JS_SetPropertyUint32(context, name, 1, JS_NewString(context, "connect")); + JS_SetPropertyStr(context, message, "name", name); + JSValue arg_obj = JS_NewObject(context); + char origin_str[k_id_base64_len] = ""; + tf_ssb_connection_get_id(connection, origin_str, sizeof(origin_str)); + JS_SetPropertyStr(context, arg_obj, "origin", JS_NewString(context, origin_str)); + JS_SetPropertyStr(context, arg_obj, "portal", JS_NewString(context, portal_str)); + JS_SetPropertyStr(context, arg_obj, "target", JS_NewString(context, target_str)); + JSValue arg_array = JS_NewArray(context); + JS_SetPropertyUint32(context, arg_array, 0, arg_obj); + JS_SetPropertyStr(context, message, "args", arg_array); + JS_SetPropertyStr(context, message, "type", JS_NewString(context, "duplex")); + JSValue message_val = JS_JSONStringify(context, message, JS_NULL, JS_NULL); + size_t size; + const char* message_str = JS_ToCStringLen(context, &size, message_val); + + tf_ssb_connection_rpc_send( + target_connection, + k_ssb_rpc_flag_json | k_ssb_rpc_flag_stream, + tunnel_request_number, + (const uint8_t*)message_str, + size, + NULL, + NULL, + NULL); + + JS_FreeCString(context, message_str); + + tunnel_t* data0 = tf_malloc(sizeof(tunnel_t)); + *data0 = (tunnel_t) + { + .connection = target_connection, + .request_number = tunnel_request_number, + }; + tunnel_t* data1 = tf_malloc(sizeof(tunnel_t)); + *data1 = (tunnel_t) + { + .connection = connection, + .request_number = -request_number, + }; + printf("MAKE TUNNEL %p %p\n", connection, target_connection); + tf_ssb_connection_add_request(connection, -request_number, _tf_ssb_rpc_tunnel_callback, _tf_ssb_rpc_tunnel_cleanup, data0, target_connection); + tf_ssb_connection_add_request(target_connection, tunnel_request_number, _tf_ssb_rpc_tunnel_callback, _tf_ssb_rpc_tunnel_cleanup, data1, connection); + + JS_FreeValue(context, message_val); + JS_FreeValue(context, message); + JS_FreeCString(context, portal_str); + } JS_FreeCString(context, target_str); } else if (!JS_IsUndefined(origin) && @@ -330,7 +333,7 @@ static void _tf_ssb_rpc_tunnel_connect(tf_ssb_connection_t* connection, uint8_t JS_FreeValue(context, arg_array); } -static void _tf_ssb_rpc_tunnel_is_room(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data) +static void _tf_ssb_rpc_room_meta(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data) { tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection); JSContext* context = tf_ssb_get_context(ssb); @@ -345,12 +348,12 @@ static void _tf_ssb_rpc_tunnel_is_room(tf_ssb_connection_t* connection, uint8_t JSValue features = JS_NewArray(context); JS_SetPropertyUint32(context, features, 0, JS_NewString(context, "tunnel")); JS_SetPropertyUint32(context, features, 1, JS_NewString(context, "room1")); + JS_SetPropertyUint32(context, features, 2, JS_NewString(context, "room2")); JS_SetPropertyStr(context, response, "features", features); } - tf_ssb_connection_rpc_send_json( connection, - flags | k_ssb_rpc_flag_end_error, + flags, -request_number, response, NULL, @@ -383,6 +386,7 @@ static void _tf_ssb_rpc_room_attendants(tf_ssb_connection_t* connection, uint8_t int id_count = 0; tf_ssb_connection_t* connections[1024]; int count = tf_ssb_get_connections(ssb, connections, _countof(connections)); + for (int i = 0; i < count; i++) { char id[k_id_base64_len] = { 0 }; @@ -1043,7 +1047,8 @@ void tf_ssb_rpc_register(tf_ssb_t* ssb) tf_ssb_add_rpc_callback(ssb, (const char*[]) { "blobs", "has", NULL }, _tf_ssb_rpc_blobs_has, NULL, NULL); tf_ssb_add_rpc_callback(ssb, (const char*[]) { "blobs", "createWants", NULL }, _tf_ssb_rpc_blobs_createWants, NULL, NULL); tf_ssb_add_rpc_callback(ssb, (const char*[]) { "tunnel", "connect", NULL }, _tf_ssb_rpc_tunnel_connect, NULL, NULL); - tf_ssb_add_rpc_callback(ssb, (const char*[]) { "tunnel", "isRoom", NULL }, _tf_ssb_rpc_tunnel_is_room, NULL, NULL); + tf_ssb_add_rpc_callback(ssb, (const char*[]) { "tunnel", "isRoom", NULL }, _tf_ssb_rpc_room_meta, NULL, NULL); + tf_ssb_add_rpc_callback(ssb, (const char*[]) { "room", "meta", NULL }, _tf_ssb_rpc_room_meta, NULL, NULL); tf_ssb_add_rpc_callback(ssb, (const char*[]) { "room", "attendants", NULL }, _tf_ssb_rpc_room_attendants, NULL, NULL); tf_ssb_add_rpc_callback(ssb, (const char*[]) { "createHistoryStream", NULL }, _tf_ssb_rpc_createHistoryStream, NULL, NULL); tf_ssb_add_rpc_callback(ssb, (const char*[]) { "ebt", "replicate", NULL }, _tf_ssb_rpc_ebt_replicate_server, NULL, NULL);