forked from cory/tildefriends
ssb.js is now entirely in C. Usual disclaimers about it not being amazingly well tested.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4111 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
135
src/ssb.c
135
src/ssb.c
@ -206,6 +206,9 @@ typedef struct _tf_ssb_connection_t
|
||||
int32_t tunnel_request_number;
|
||||
|
||||
tf_ssb_blob_wants_t blob_wants;
|
||||
bool sent_clock;
|
||||
int32_t ebt_request_number;
|
||||
JSValue ebt_send_clock;
|
||||
|
||||
JSValue object;
|
||||
|
||||
@ -521,6 +524,8 @@ void tf_ssb_connection_add_new_message_request(tf_ssb_connection_t* connection,
|
||||
int index = tf_util_insert_index(author, connection->message_requests, connection->message_requests_count, sizeof(tf_ssb_connection_message_request_t), _message_request_compare);
|
||||
if (index < connection->message_requests_count && strcmp(author, connection->message_requests[index].author) == 0)
|
||||
{
|
||||
connection->message_requests[index].request_number = request_number;
|
||||
connection->message_requests[index].keys = keys;
|
||||
return;
|
||||
}
|
||||
connection->message_requests = tf_resize_vec(connection->message_requests, sizeof(tf_ssb_connection_message_request_t) * (connection->message_requests_count + 1));
|
||||
@ -537,6 +542,16 @@ void tf_ssb_connection_add_new_message_request(tf_ssb_connection_t* connection,
|
||||
connection->message_requests_count++;
|
||||
}
|
||||
|
||||
void tf_ssb_connection_remove_new_message_request(tf_ssb_connection_t* connection, const char* author)
|
||||
{
|
||||
int index = tf_util_insert_index(author, connection->message_requests, connection->message_requests_count, sizeof(tf_ssb_connection_message_request_t), _message_request_compare);
|
||||
if (index < connection->message_requests_count && strcmp(author, connection->message_requests[index].author) == 0)
|
||||
{
|
||||
memmove(connection->message_requests + index, connection->message_requests + index + 1, sizeof(tf_ssb_connection_message_request_t) * (connection->message_requests_count - index));
|
||||
connection->message_requests_count--;
|
||||
}
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_remove_request(tf_ssb_connection_t* connection, int32_t request_number)
|
||||
{
|
||||
tf_ssb_request_t* request = bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare);
|
||||
@ -1593,6 +1608,8 @@ void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const char* rea
|
||||
!connection->tcp.data &&
|
||||
!connection->connect.data)
|
||||
{
|
||||
JS_FreeValue(ssb->context, connection->ebt_send_clock);
|
||||
connection->ebt_send_clock = JS_UNDEFINED;
|
||||
tf_free(connection->message_requests);
|
||||
connection->message_requests = NULL;
|
||||
connection->message_requests_count = 0;
|
||||
@ -2079,64 +2096,6 @@ static void _tf_ssb_connection_finalizer(JSRuntime* runtime, JSValue value)
|
||||
}
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_send_json_response(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
||||
{
|
||||
if (!user_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void _tf_ssb_on_rpc(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_on_rpc(connection, flags, request_number, args, message, size, user_data);
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_cleanup_value(tf_ssb_t* ssb, void* user_data)
|
||||
{
|
||||
if (user_data)
|
||||
{
|
||||
JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data);
|
||||
JS_FreeValue(tf_ssb_get_context(ssb), callback);
|
||||
}
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_connection_send_json_internal(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int flags)
|
||||
{
|
||||
tf_ssb_connection_t* connection = JS_GetOpaque(this_val, _connection_class_id);
|
||||
if (!connection)
|
||||
{
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
uint32_t request_number = tf_ssb_connection_next_request_number(connection);
|
||||
|
||||
JSValue message_val = JS_JSONStringify(context, argv[0], JS_NULL, JS_NULL);
|
||||
size_t size;
|
||||
const char* message = JS_ToCStringLen(context, &size, message_val);
|
||||
JS_FreeValue(context, message_val);
|
||||
|
||||
tf_ssb_connection_rpc_send(
|
||||
connection,
|
||||
flags,
|
||||
request_number,
|
||||
(const uint8_t*)message,
|
||||
size,
|
||||
_tf_ssb_connection_send_json_response,
|
||||
_tf_ssb_connection_cleanup_value,
|
||||
JS_IsFunction(context, argv[1]) ? JS_VALUE_GET_PTR(JS_DupValue(context, argv[1])) : NULL);
|
||||
JS_FreeCString(context, message);
|
||||
return JS_NewInt32(context, request_number);
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_connection_send_json(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
return _tf_ssb_connection_send_json_internal(context, this_val, argc, argv, k_ssb_rpc_flag_json | k_ssb_rpc_flag_stream);
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_connection_send_json_async(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
return _tf_ssb_connection_send_json_internal(context, this_val, argc, argv, k_ssb_rpc_flag_json);
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_process_message_async(uv_async_t* async)
|
||||
{
|
||||
tf_ssb_connection_t* connection = async->data;
|
||||
@ -2181,8 +2140,6 @@ tf_ssb_connection_t* tf_ssb_connection_create(tf_ssb_t* ssb, const char* host, c
|
||||
|
||||
connection->object = JS_NewObjectClass(ssb->context, _connection_class_id);
|
||||
JS_SetOpaque(connection->object, connection);
|
||||
JS_SetPropertyStr(context, connection->object, "send_json", JS_NewCFunction(context, _tf_ssb_connection_send_json, "send_json", 2));
|
||||
JS_SetPropertyStr(context, connection->object, "send_json_async", JS_NewCFunction(context, _tf_ssb_connection_send_json_async, "send_json_async", 2));
|
||||
char public_key_str[k_id_base64_len] = { 0 };
|
||||
if (tf_ssb_id_bin_to_str(public_key_str, sizeof(public_key_str), public_key))
|
||||
{
|
||||
@ -2240,8 +2197,6 @@ tf_ssb_connection_t* tf_ssb_connection_tunnel_create(tf_ssb_t* ssb, const char*
|
||||
|
||||
tunnel->object = JS_NewObjectClass(ssb->context, _connection_class_id);
|
||||
JS_SetOpaque(tunnel->object, tunnel);
|
||||
JS_SetPropertyStr(context, tunnel->object, "send_json", JS_NewCFunction(context, _tf_ssb_connection_send_json, "send_json", 2));
|
||||
JS_SetPropertyStr(context, tunnel->object, "send_json_async", JS_NewCFunction(context, _tf_ssb_connection_send_json_async, "send_json_async", 2));
|
||||
JS_SetPropertyStr(context, tunnel->object, "id", JS_NewString(context, target_id));
|
||||
JS_SetPropertyStr(context, tunnel->object, "is_client", JS_TRUE);
|
||||
|
||||
@ -2340,8 +2295,6 @@ static void _tf_ssb_on_connection(uv_stream_t* stream, int status)
|
||||
uv_async_init(ssb->loop, &connection->async, _tf_ssb_connection_process_message_async);
|
||||
|
||||
connection->object = JS_NewObjectClass(ssb->context, _connection_class_id);
|
||||
JS_SetPropertyStr(ssb->context, connection->object, "send_json", JS_NewCFunction(ssb->context, _tf_ssb_connection_send_json, "send_json", 2));
|
||||
JS_SetPropertyStr(ssb->context, connection->object, "send_json_async", JS_NewCFunction(ssb->context, _tf_ssb_connection_send_json_async, "send_json_async", 2));
|
||||
JS_SetOpaque(connection->object, connection);
|
||||
|
||||
if (uv_tcp_init(ssb->loop, &connection->tcp) != 0)
|
||||
@ -3118,3 +3071,57 @@ tf_ssb_blob_wants_t* tf_ssb_connection_get_blob_wants_state(tf_ssb_connection_t*
|
||||
{
|
||||
return connection ? &connection->blob_wants : NULL;
|
||||
}
|
||||
|
||||
bool tf_ssb_verify_strip_and_store_message(tf_ssb_t* ssb, JSValue value)
|
||||
{
|
||||
JSContext* context = tf_ssb_get_context(ssb);
|
||||
char signature[crypto_sign_BYTES + 128];
|
||||
char id[crypto_hash_sha256_BYTES * 2 + 1];
|
||||
bool sequence_before_author = false;
|
||||
if (tf_ssb_verify_and_strip_signature(context, value, id, sizeof(id), signature, sizeof(signature), &sequence_before_author))
|
||||
{
|
||||
if (tf_ssb_db_store_message(ssb, context, id, value, signature, sequence_before_author))
|
||||
{
|
||||
tf_ssb_notify_message_added(ssb, id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("failed to verify message\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tf_ssb_connection_get_sent_clock(tf_ssb_connection_t* connection)
|
||||
{
|
||||
return connection->sent_clock;
|
||||
}
|
||||
|
||||
void tf_ssb_connection_set_sent_clock(tf_ssb_connection_t* connection, bool sent_clock)
|
||||
{
|
||||
connection->sent_clock = sent_clock;
|
||||
}
|
||||
|
||||
int32_t tf_ssb_connection_get_ebt_request_number(tf_ssb_connection_t* connection)
|
||||
{
|
||||
return connection->ebt_request_number;
|
||||
}
|
||||
|
||||
void tf_ssb_connection_set_ebt_request_number(tf_ssb_connection_t* connection, int32_t request_number)
|
||||
{
|
||||
connection->ebt_request_number = request_number;
|
||||
}
|
||||
|
||||
JSValue tf_ssb_connection_get_ebt_send_clock(tf_ssb_connection_t* connection)
|
||||
{
|
||||
JSContext* context = connection->ssb->context;
|
||||
return JS_DupValue(context, connection->ebt_send_clock);
|
||||
}
|
||||
|
||||
void tf_ssb_connection_set_ebt_send_clock(tf_ssb_connection_t* connection, JSValue send_clock)
|
||||
{
|
||||
JSContext* context = connection->ssb->context;
|
||||
JS_FreeValue(context, connection->ebt_send_clock);
|
||||
connection->ebt_send_clock = JS_DupValue(context, send_clock);
|
||||
}
|
||||
|
Reference in New Issue
Block a user