Compare commits
2 Commits
5448f1ba2d
...
681859531c
Author | SHA1 | Date | |
---|---|---|---|
681859531c | |||
8e1ad6b16a |
@ -1351,4 +1351,4 @@ function storePermission(user, packageOwner, packageName, permission, allow) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {gGlobalSettings as globalSettings, invoke, getSessionProcessBlob};
|
export {invoke, getSessionProcessBlob};
|
||||||
|
133
src/ssb.c
133
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 tf_ssb_rpc_callback_node_t;
|
||||||
typedef struct _tf_ssb_rpc_callback_node_t
|
typedef struct _tf_ssb_rpc_callback_node_t
|
||||||
{
|
{
|
||||||
const char** name;
|
const char* name;
|
||||||
const char* flattened_name;
|
|
||||||
tf_ssb_rpc_callback_t* callback;
|
tf_ssb_rpc_callback_t* callback;
|
||||||
tf_ssb_callback_cleanup_t* cleanup;
|
tf_ssb_callback_cleanup_t* cleanup;
|
||||||
void* user_data;
|
void* user_data;
|
||||||
@ -1521,60 +1520,28 @@ static bool _tf_ssb_connection_recv_pop(tf_ssb_connection_t* connection, uint8_t
|
|||||||
return true;
|
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");
|
JSValue name = JS_GetPropertyStr(context, object, "name");
|
||||||
|
|
||||||
if (JS_IsArray(context, name))
|
if (JS_IsArray(context, name))
|
||||||
{
|
{
|
||||||
int length = tf_util_get_length(context, name);
|
int length = tf_util_get_length(context, name);
|
||||||
|
int offset = 0;
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
if (!match[i])
|
JSValue part = JS_GetPropertyUint32(context, name, i);
|
||||||
{
|
const char* part_str = JS_ToCString(context, part);
|
||||||
result = false;
|
offset += snprintf(buffer + offset, size - offset, "%s%s", i == 0 ? "" : ".", part_str);
|
||||||
break;
|
JS_FreeCString(context, part_str);
|
||||||
}
|
JS_FreeValue(context, part);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (JS_IsString(name))
|
else if (JS_IsString(name))
|
||||||
{
|
{
|
||||||
/* Manifest is traditionally sent as not an array for some reason. */
|
const char* part_str = JS_ToCString(context, name);
|
||||||
const char* str = JS_ToCString(context, name);
|
snprintf(buffer, size, "%s", part_str);
|
||||||
result = str && match[0] && strcmp(str, match[0]) == 0 && !match[1];
|
JS_FreeCString(context, part_str);
|
||||||
JS_FreeCString(context, 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);
|
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))
|
else if (JS_IsObject(val))
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
char namebuf[256] = "";
|
char name[256] = "";
|
||||||
JSValue name = JS_GetPropertyStr(context, val, "name");
|
_tf_ssb_name_to_string(context, val, name, sizeof(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);
|
|
||||||
|
|
||||||
for (tf_ssb_rpc_callback_node_t* it = connection->ssb->rpc; it; it = it->next)
|
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_ssb_connection_add_request(connection, -request_number, name, NULL, NULL, NULL, NULL);
|
||||||
tf_trace_begin(connection->ssb->trace, it->flattened_name);
|
tf_trace_begin(connection->ssb->trace, it->name);
|
||||||
PRE_CALLBACK(connection->ssb, it->callback);
|
PRE_CALLBACK(connection->ssb, it->callback);
|
||||||
it->callback(connection, flags, request_number, val, message, size, it->user_data);
|
it->callback(connection, flags, request_number, val, message, size, it->user_data);
|
||||||
POST_CALLBACK(connection->ssb, it->callback);
|
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;
|
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);
|
tf_ssb_connection_add_request(connection, -request_number, name, NULL, NULL, NULL, NULL);
|
||||||
char buffer[256];
|
tf_ssb_connection_rpc_send_error_method_not_allowed(connection, flags, -request_number, name);
|
||||||
_tf_ssb_name_to_string(context, val, buffer, sizeof(buffer));
|
|
||||||
tf_ssb_connection_rpc_send_error_method_not_allowed(connection, flags, -request_number, buffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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;
|
size_t name_len = strlen(name);
|
||||||
int name_count = 0;
|
tf_ssb_rpc_callback_node_t* node = tf_malloc(sizeof(tf_ssb_rpc_callback_node_t) + name_len + 1);
|
||||||
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);
|
|
||||||
*node = (tf_ssb_rpc_callback_node_t) {
|
*node = (tf_ssb_rpc_callback_node_t) {
|
||||||
.name = (const char**)(node + 1),
|
.name = (const char*)(node + 1),
|
||||||
.flattened_name = (const char*)(node + 1) + (name_count + 1) * sizeof(const char*) + name_len,
|
|
||||||
.callback = callback,
|
.callback = callback,
|
||||||
.cleanup = cleanup,
|
.cleanup = cleanup,
|
||||||
.user_data = user_data,
|
.user_data = user_data,
|
||||||
.next = ssb->rpc,
|
.next = ssb->rpc,
|
||||||
};
|
};
|
||||||
char* p = (char*)(node + 1) + (name_count + 1) * sizeof(const char*);
|
memcpy((char*)node->name, name, name_len + 1);
|
||||||
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;
|
|
||||||
ssb->rpc = node;
|
ssb->rpc = node;
|
||||||
ssb->rpc_count++;
|
ssb->rpc_count++;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
** Register a MUXRPC callback by name.
|
||||||
** @param ssb The SSB instance.
|
** @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 callback The callback.
|
||||||
** @param cleanup A function to be called when the callback is removed.
|
** @param cleanup A function to be called when the callback is removed.
|
||||||
** @param user_data User data to pass to the callback.
|
** @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.
|
** Remove a MUXRPC callback.
|
||||||
|
@ -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)
|
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_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, "gossip.ping", _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, "blobs.get", _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, "blobs.has", _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, "blobs.createWants", _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, "tunnel.connect", _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, "tunnel.isRoom", _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, "room.metadata", _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, "room.attendants", _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, "createHistoryStream", _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, "ebt.replicate", _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, "peers.exchange", _tf_ssb_rpc_peers_exchange, NULL, NULL); /* ASYNC */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user