clang-format the source. Not exactly how I want it, but automated is better than perfect.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4845 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
310
src/ssb.c
310
src/ssb.c
@ -42,22 +42,18 @@ static_assert(k_id_base64_len == sodium_base64_ENCODED_LEN(9 + crypto_box_PUBLIC
|
||||
static_assert(k_id_bin_len == crypto_box_PUBLICKEYBYTES, "k_id_bin_len");
|
||||
static_assert(k_blob_id_len == (sodium_base64_ENCODED_LEN(crypto_hash_sha256_BYTES, sodium_base64_VARIANT_ORIGINAL) + 8), "k_blob_id_len");
|
||||
|
||||
const uint8_t k_ssb_network[] = {
|
||||
0xd4, 0xa1, 0xcb, 0x88, 0xa6, 0x6f, 0x02, 0xf8,
|
||||
0xdb, 0x63, 0x5c, 0xe2, 0x64, 0x41, 0xcc, 0x5d,
|
||||
0xac, 0x1b, 0x08, 0x42, 0x0c, 0xea, 0xac, 0x23,
|
||||
0x08, 0x39, 0xb7, 0x55, 0x84, 0x5a, 0x9f, 0xfb
|
||||
};
|
||||
const uint8_t k_ssb_network[] = { 0xd4, 0xa1, 0xcb, 0x88, 0xa6, 0x6f, 0x02, 0xf8, 0xdb, 0x63, 0x5c, 0xe2, 0x64, 0x41, 0xcc, 0x5d, 0xac, 0x1b, 0x08, 0x42, 0x0c, 0xea, 0xac, 0x23,
|
||||
0x08, 0x39, 0xb7, 0x55, 0x84, 0x5a, 0x9f, 0xfb };
|
||||
|
||||
const char* k_ssb_type_names[] =
|
||||
{
|
||||
const char* k_ssb_type_names[] = {
|
||||
"binary",
|
||||
"utf8",
|
||||
"json",
|
||||
"unknown",
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
k_tf_ssb_state_invalid,
|
||||
k_tf_ssb_state_connected,
|
||||
k_tf_ssb_state_sent_hello,
|
||||
@ -71,7 +67,8 @@ typedef enum {
|
||||
k_tf_ssb_state_closing,
|
||||
} tf_ssb_state_t;
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
k_connections_changed_callbacks_max = 8,
|
||||
k_tf_ssb_rpc_message_body_length_max = 1 * 1024 * 1024,
|
||||
k_debug_close_message_count = 256,
|
||||
@ -406,8 +403,7 @@ static void _tf_ssb_connection_add_debug_message(tf_ssb_connection_t* connection
|
||||
connection->debug_messages[i] = connection->debug_messages[i - 1];
|
||||
}
|
||||
tf_ssb_debug_message_t* message = tf_malloc(sizeof(tf_ssb_debug_message_t) + size);
|
||||
*message = (tf_ssb_debug_message_t)
|
||||
{
|
||||
*message = (tf_ssb_debug_message_t) {
|
||||
.outgoing = outgoing,
|
||||
.flags = flags,
|
||||
.request_number = request_number,
|
||||
@ -440,8 +436,7 @@ static void _tf_ssb_connection_close(tf_ssb_connection_t* connection, const char
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (connection->state == k_tf_ssb_state_verified ||
|
||||
connection->state == k_tf_ssb_state_server_verified)
|
||||
else if (connection->state == k_tf_ssb_state_verified || connection->state == k_tf_ssb_state_server_verified)
|
||||
{
|
||||
tf_printf("Connection %s %p is closing: %s.\n", connection->name, connection, reason);
|
||||
_tf_ssb_add_debug_close(connection->ssb, connection, reason);
|
||||
@ -488,14 +483,7 @@ static void _tf_ssb_write(tf_ssb_connection_t* connection, void* data, size_t si
|
||||
else if (connection->tunnel_connection)
|
||||
{
|
||||
tf_ssb_connection_rpc_send(
|
||||
connection->tunnel_connection,
|
||||
k_ssb_rpc_flag_binary | k_ssb_rpc_flag_stream,
|
||||
-connection->tunnel_request_number,
|
||||
data,
|
||||
size,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
connection->tunnel_connection, k_ssb_rpc_flag_binary | k_ssb_rpc_flag_stream, -connection->tunnel_request_number, data, size, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,8 +606,7 @@ static void _tf_ssb_connection_box_stream_send(tf_ssb_connection_t* connection,
|
||||
void tf_ssb_connection_schedule_idle(tf_ssb_connection_t* connection, tf_ssb_scheduled_callback_t* callback, void* user_data)
|
||||
{
|
||||
connection->scheduled = tf_resize_vec(connection->scheduled, sizeof(tf_ssb_connection_scheduled_t) * (connection->scheduled_count + 1));
|
||||
connection->scheduled[connection->scheduled_count++] = (tf_ssb_connection_scheduled_t)
|
||||
{
|
||||
connection->scheduled[connection->scheduled_count++] = (tf_ssb_connection_scheduled_t) {
|
||||
.callback = callback,
|
||||
.user_data = user_data,
|
||||
};
|
||||
@ -655,9 +642,11 @@ static bool _tf_ssb_connection_get_request_callback(tf_ssb_connection_t* connect
|
||||
return false;
|
||||
}
|
||||
|
||||
void tf_ssb_connection_add_request(tf_ssb_connection_t* connection, int32_t request_number, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data, tf_ssb_connection_t* dependent_connection)
|
||||
void tf_ssb_connection_add_request(tf_ssb_connection_t* connection, int32_t request_number, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data,
|
||||
tf_ssb_connection_t* dependent_connection)
|
||||
{
|
||||
tf_ssb_request_t* existing = connection->requests_count ? bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare) : NULL;
|
||||
tf_ssb_request_t* existing =
|
||||
connection->requests_count ? bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare) : NULL;
|
||||
if (existing)
|
||||
{
|
||||
assert(!existing->callback);
|
||||
@ -672,8 +661,7 @@ void tf_ssb_connection_add_request(tf_ssb_connection_t* connection, int32_t requ
|
||||
else
|
||||
{
|
||||
tf_ssb_connection_remove_request(connection, request_number);
|
||||
tf_ssb_request_t request =
|
||||
{
|
||||
tf_ssb_request_t request = {
|
||||
.request_number = request_number,
|
||||
.callback = callback,
|
||||
.cleanup = cleanup,
|
||||
@ -702,7 +690,8 @@ static int _message_request_compare(const void* a, const void* b)
|
||||
|
||||
void tf_ssb_connection_add_new_message_request(tf_ssb_connection_t* connection, const char* author, int32_t request_number, bool keys)
|
||||
{
|
||||
int index = tf_util_insert_index(author, connection->message_requests, connection->message_requests_count, sizeof(tf_ssb_connection_message_request_t), _message_request_compare);
|
||||
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;
|
||||
@ -712,10 +701,10 @@ void tf_ssb_connection_add_new_message_request(tf_ssb_connection_t* connection,
|
||||
connection->message_requests = tf_resize_vec(connection->message_requests, sizeof(tf_ssb_connection_message_request_t) * (connection->message_requests_count + 1));
|
||||
if (connection->message_requests_count - index)
|
||||
{
|
||||
memmove(connection->message_requests + index + 1, connection->message_requests + index, sizeof(tf_ssb_connection_message_request_t) * (connection->message_requests_count - index));
|
||||
memmove(connection->message_requests + index + 1, connection->message_requests + index,
|
||||
sizeof(tf_ssb_connection_message_request_t) * (connection->message_requests_count - index));
|
||||
}
|
||||
connection->message_requests[index] = (tf_ssb_connection_message_request_t)
|
||||
{
|
||||
connection->message_requests[index] = (tf_ssb_connection_message_request_t) {
|
||||
.request_number = request_number,
|
||||
.keys = keys,
|
||||
};
|
||||
@ -725,19 +714,20 @@ void tf_ssb_connection_add_new_message_request(tf_ssb_connection_t* connection,
|
||||
|
||||
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);
|
||||
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 - 1));
|
||||
memmove(connection->message_requests + index, connection->message_requests + index + 1,
|
||||
sizeof(tf_ssb_connection_message_request_t) * (connection->message_requests_count - index - 1));
|
||||
connection->message_requests_count--;
|
||||
}
|
||||
}
|
||||
|
||||
void tf_ssb_connection_remove_request(tf_ssb_connection_t* connection, int32_t request_number)
|
||||
{
|
||||
tf_ssb_request_t* request = connection->requests_count ?
|
||||
bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare) :
|
||||
NULL;
|
||||
tf_ssb_request_t* request =
|
||||
connection->requests_count ? bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare) : NULL;
|
||||
if (request)
|
||||
{
|
||||
if (request->cleanup)
|
||||
@ -752,7 +742,8 @@ 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 uint8_t* message, size_t size, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data)
|
||||
void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const uint8_t* message, size_t size, tf_ssb_rpc_callback_t* callback,
|
||||
tf_ssb_callback_cleanup_t* cleanup, void* user_data)
|
||||
{
|
||||
if (!connection)
|
||||
{
|
||||
@ -782,15 +773,9 @@ void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags,
|
||||
memcpy(combined + 1 + 2 * sizeof(uint32_t), message, size);
|
||||
if (connection->ssb->verbose)
|
||||
{
|
||||
tf_printf(MAGENTA "%s RPC SEND" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B] %.*s\n",
|
||||
connection->name,
|
||||
(flags & k_ssb_rpc_flag_end_error) ? "true" : "false",
|
||||
(flags & k_ssb_rpc_flag_stream) ? "true" : "false",
|
||||
k_ssb_type_names[flags & k_ssb_rpc_mask_type],
|
||||
request_number,
|
||||
size,
|
||||
(flags & k_ssb_rpc_mask_type) == k_ssb_rpc_flag_binary ? 0 : (int)size,
|
||||
message);
|
||||
tf_printf(MAGENTA "%s RPC SEND" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B] %.*s\n", connection->name,
|
||||
(flags & k_ssb_rpc_flag_end_error) ? "true" : "false", (flags & k_ssb_rpc_flag_stream) ? "true" : "false", k_ssb_type_names[flags & k_ssb_rpc_mask_type],
|
||||
request_number, size, (flags & k_ssb_rpc_mask_type) == k_ssb_rpc_flag_binary ? 0 : (int)size, message);
|
||||
}
|
||||
_tf_ssb_connection_add_debug_message(connection, true, flags & k_ssb_rpc_mask_send, request_number, message, size);
|
||||
_tf_ssb_connection_box_stream_send(connection, combined, 1 + 2 * sizeof(uint32_t) + size);
|
||||
@ -806,21 +791,15 @@ void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags,
|
||||
}
|
||||
}
|
||||
|
||||
void tf_ssb_connection_rpc_send_json(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue message, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data)
|
||||
void tf_ssb_connection_rpc_send_json(
|
||||
tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, 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(
|
||||
connection,
|
||||
k_ssb_rpc_flag_json | (flags & ~k_ssb_rpc_mask_type),
|
||||
request_number,
|
||||
(const uint8_t*)json_string,
|
||||
size,
|
||||
callback,
|
||||
cleanup,
|
||||
user_data);
|
||||
connection, k_ssb_rpc_flag_json | (flags & ~k_ssb_rpc_mask_type), request_number, (const uint8_t*)json_string, size, callback, cleanup, user_data);
|
||||
JS_FreeCString(context, json_string);
|
||||
JS_FreeValue(context, json);
|
||||
}
|
||||
@ -833,7 +812,8 @@ 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(connection, ((flags & k_ssb_rpc_flag_stream) ? (k_ssb_rpc_flag_stream) : 0) | k_ssb_rpc_flag_end_error, request_number, message, NULL, NULL, NULL);
|
||||
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, message, NULL, NULL, NULL);
|
||||
JS_FreeValue(context, message);
|
||||
tf_free((void*)stack);
|
||||
}
|
||||
@ -847,10 +827,7 @@ void tf_ssb_connection_rpc_send_error_method_not_allowed(tf_ssb_connection_t* co
|
||||
|
||||
static int _utf8_len(uint8_t ch)
|
||||
{
|
||||
static const uint8_t k_length[] =
|
||||
{
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 3, 4
|
||||
};
|
||||
static const uint8_t k_length[] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 3, 4 };
|
||||
return k_length[(ch & 0xf0) >> 4];
|
||||
}
|
||||
|
||||
@ -859,10 +836,7 @@ static uint32_t _utf8_decode(uint32_t c)
|
||||
if (c > 0x7f)
|
||||
{
|
||||
uint32_t mask = (c <= 0x00efbfbf) ? 0x000f0000 : 0x003f0000;
|
||||
c = ((c & 0x07000000) >> 6) |
|
||||
((c & mask) >> 4) |
|
||||
((c & 0x00003f00) >> 2) |
|
||||
(c & 0x0000003f);
|
||||
c = ((c & 0x07000000) >> 6) | ((c & mask) >> 4) | ((c & 0x00003f00) >> 2) | (c & 0x0000003f);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
@ -996,7 +970,7 @@ static bool _tf_ssb_verify_and_strip_signature_internal(JSContext* context, JSVa
|
||||
verified = r == 0;
|
||||
if (!verified)
|
||||
{
|
||||
//tf_printf("crypto_sign_verify_detached fail (r=%d)\n", r);
|
||||
// tf_printf("crypto_sign_verify_detached fail (r=%d)\n", r);
|
||||
if (false)
|
||||
{
|
||||
tf_printf("val=[%.*s]\n", (int)strlen(sigstr), sigstr);
|
||||
@ -1031,7 +1005,8 @@ static bool _tf_ssb_verify_and_strip_signature_internal(JSContext* context, JSVa
|
||||
return verified;
|
||||
}
|
||||
|
||||
bool tf_ssb_verify_and_strip_signature(JSContext* context, JSValue val, char* out_id, size_t out_id_size, char* out_signature, size_t out_signature_size, bool* out_sequence_before_author)
|
||||
bool tf_ssb_verify_and_strip_signature(
|
||||
JSContext* context, JSValue val, char* out_id, size_t out_id_size, char* out_signature, size_t out_signature_size, bool* out_sequence_before_author)
|
||||
{
|
||||
if (_tf_ssb_verify_and_strip_signature_internal(context, val, out_id, out_id_size, out_signature, out_signature_size))
|
||||
{
|
||||
@ -1237,9 +1212,7 @@ bool tf_ssb_connection_is_client(tf_ssb_connection_t* connection)
|
||||
|
||||
bool tf_ssb_connection_is_connected(tf_ssb_connection_t* connection)
|
||||
{
|
||||
return
|
||||
connection->state == k_tf_ssb_state_verified ||
|
||||
connection->state == k_tf_ssb_state_server_verified;
|
||||
return connection->state == k_tf_ssb_state_verified || connection->state == k_tf_ssb_state_server_verified;
|
||||
}
|
||||
|
||||
const char* tf_ssb_connection_get_host(tf_ssb_connection_t* connection)
|
||||
@ -1254,10 +1227,7 @@ 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
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
tf_ssb_connection_t* tf_ssb_connection_get_tunnel(tf_ssb_connection_t* connection)
|
||||
@ -1558,15 +1528,9 @@ 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)
|
||||
{
|
||||
tf_printf(CYAN "%s RPC RECV" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B] %.*s\n",
|
||||
connection->name,
|
||||
(flags & k_ssb_rpc_flag_end_error) ? "true" : "false",
|
||||
(flags & k_ssb_rpc_flag_stream) ? "true" : "false",
|
||||
k_ssb_type_names[flags & k_ssb_rpc_mask_type],
|
||||
request_number,
|
||||
size,
|
||||
(int)size,
|
||||
message);
|
||||
tf_printf(CYAN "%s RPC RECV" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B] %.*s\n", connection->name,
|
||||
(flags & k_ssb_rpc_flag_end_error) ? "true" : "false", (flags & k_ssb_rpc_flag_stream) ? "true" : "false",
|
||||
k_ssb_type_names[flags & k_ssb_rpc_mask_type], request_number, size, (int)size, message);
|
||||
}
|
||||
JSContext* context = connection->ssb->context;
|
||||
JSValue val = JS_ParseJSON(context, (const char*)message, size, NULL);
|
||||
@ -1612,7 +1576,6 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t
|
||||
tf_ssb_connection_rpc_send_error_method_not_allowed(connection, flags, -request_number, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1626,13 +1589,9 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t
|
||||
{
|
||||
if (connection->ssb->verbose)
|
||||
{
|
||||
tf_printf(CYAN "%s RPC RECV" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B]\n",
|
||||
connection->name,
|
||||
(flags & k_ssb_rpc_flag_end_error) ? "true" : "false",
|
||||
(flags & k_ssb_rpc_flag_stream) ? "true" : "false",
|
||||
k_ssb_type_names[flags & k_ssb_rpc_mask_type],
|
||||
request_number,
|
||||
size);
|
||||
tf_printf(CYAN "%s RPC RECV" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B]\n", connection->name,
|
||||
(flags & k_ssb_rpc_flag_end_error) ? "true" : "false", (flags & k_ssb_rpc_flag_stream) ? "true" : "false",
|
||||
k_ssb_type_names[flags & k_ssb_rpc_mask_type], request_number, size);
|
||||
}
|
||||
tf_ssb_rpc_callback_t* callback = NULL;
|
||||
void* user_data = NULL;
|
||||
@ -1667,7 +1626,8 @@ static void _tf_ssb_connection_rpc_recv_push(tf_ssb_connection_t* connection, co
|
||||
size_t size_processed = 0;
|
||||
while (size_left > 0)
|
||||
{
|
||||
size_t copy_size = (connection->rpc_recv_size + size_left > sizeof(connection->rpc_recv_buffer)) ? sizeof(connection->rpc_recv_buffer) - connection->rpc_recv_size : size_left;
|
||||
size_t copy_size =
|
||||
(connection->rpc_recv_size + size_left > sizeof(connection->rpc_recv_buffer)) ? sizeof(connection->rpc_recv_buffer) - connection->rpc_recv_size : size_left;
|
||||
if (copy_size == 0)
|
||||
{
|
||||
_tf_ssb_connection_close(connection, "recv buffer overflow");
|
||||
@ -1740,7 +1700,8 @@ static bool _tf_ssb_connection_box_stream_recv(tf_ssb_connection_t* connection)
|
||||
memcpy(connection->box_stream_buf, connection->body_auth_tag, sizeof(connection->body_auth_tag));
|
||||
if (_tf_ssb_connection_recv_pop(connection, connection->box_stream_buf + 16, connection->body_len))
|
||||
{
|
||||
if (crypto_secretbox_open_easy(connection->secretbox_buf, connection->box_stream_buf, 16 + connection->body_len, connection->nonce, connection->s_to_c_box_key) != 0)
|
||||
if (crypto_secretbox_open_easy(
|
||||
connection->secretbox_buf, connection->box_stream_buf, 16 + connection->body_len, connection->nonce, connection->s_to_c_box_key) != 0)
|
||||
{
|
||||
_tf_ssb_connection_close(connection, "failed to open secret box");
|
||||
return false;
|
||||
@ -1905,11 +1866,7 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch
|
||||
uv_close((uv_handle_t*)&connection->tcp, _tf_ssb_connection_on_close);
|
||||
}
|
||||
|
||||
if (JS_IsUndefined(connection->object) &&
|
||||
!connection->async.data &&
|
||||
!connection->tcp.data &&
|
||||
!connection->connect.data &&
|
||||
connection->ref_count == 0)
|
||||
if (JS_IsUndefined(connection->object) && !connection->async.data && !connection->tcp.data && !connection->connect.data && connection->ref_count == 0)
|
||||
{
|
||||
JS_FreeValue(ssb->context, connection->ebt_send_clock);
|
||||
connection->ebt_send_clock = JS_UNDEFINED;
|
||||
@ -1923,8 +1880,7 @@ static void _tf_ssb_connection_destroy(tf_ssb_connection_t* connection, const ch
|
||||
connection->debug_messages[i] = NULL;
|
||||
}
|
||||
|
||||
if (--connection->ssb->connection_ref_count == 0 &&
|
||||
connection->ssb->shutting_down)
|
||||
if (--connection->ssb->connection_ref_count == 0 && connection->ssb->shutting_down)
|
||||
{
|
||||
tf_ssb_destroy(connection->ssb);
|
||||
}
|
||||
@ -2108,8 +2064,7 @@ static void _tf_ssb_trace_timer(uv_timer_t* timer)
|
||||
{
|
||||
tf_ssb_t* ssb = timer->data;
|
||||
|
||||
const char* names[] =
|
||||
{
|
||||
const char* names[] = {
|
||||
"connections",
|
||||
"broadcasts",
|
||||
"rpc",
|
||||
@ -2118,8 +2073,7 @@ static void _tf_ssb_trace_timer(uv_timer_t* timer)
|
||||
"blob_want_added",
|
||||
"broadcasts_changed",
|
||||
};
|
||||
int64_t values[] =
|
||||
{
|
||||
int64_t values[] = {
|
||||
ssb->connections_count,
|
||||
ssb->broadcasts_count,
|
||||
ssb->rpc_count,
|
||||
@ -2186,8 +2140,7 @@ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, const char* db_path
|
||||
uv_mutex_init(&ssb->db_writer_lock);
|
||||
|
||||
JS_NewClassID(&_connection_class_id);
|
||||
JSClassDef def =
|
||||
{
|
||||
JSClassDef def = {
|
||||
.class_name = "connection",
|
||||
.finalizer = _tf_ssb_connection_finalizer,
|
||||
};
|
||||
@ -2423,13 +2376,8 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
|
||||
|
||||
tf_printf("Waiting for closes.\n");
|
||||
|
||||
while (ssb->broadcast_listener.data ||
|
||||
ssb->broadcast_sender.data ||
|
||||
ssb->broadcast_timer.data ||
|
||||
ssb->broadcast_cleanup_timer.data ||
|
||||
ssb->trace_timer.data ||
|
||||
ssb->server.data ||
|
||||
ssb->ref_count)
|
||||
while (ssb->broadcast_listener.data || ssb->broadcast_sender.data || ssb->broadcast_timer.data || ssb->broadcast_cleanup_timer.data || ssb->trace_timer.data ||
|
||||
ssb->server.data || ssb->ref_count)
|
||||
{
|
||||
uv_run(ssb->loop, UV_RUN_ONCE);
|
||||
}
|
||||
@ -2656,26 +2604,12 @@ tf_ssb_connection_t* tf_ssb_connection_create(tf_ssb_t* ssb, const char* host, c
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_tunnel_callback(
|
||||
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_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
||||
{
|
||||
tf_ssb_connection_t* tunnel = user_data;
|
||||
if (flags & k_ssb_rpc_flag_end_error)
|
||||
{
|
||||
tf_ssb_connection_rpc_send(
|
||||
connection,
|
||||
flags,
|
||||
-request_number,
|
||||
(const uint8_t*)"false",
|
||||
strlen("false"),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
tf_ssb_connection_rpc_send(connection, flags, -request_number, (const uint8_t*)"false", strlen("false"), NULL, NULL, NULL);
|
||||
tf_ssb_connection_close(tunnel);
|
||||
}
|
||||
else
|
||||
@ -2712,13 +2646,7 @@ tf_ssb_connection_t* tf_ssb_connection_tunnel_create(tf_ssb_t* ssb, const char*
|
||||
ssb->connections_count++;
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_create, tunnel);
|
||||
|
||||
tf_ssb_connection_add_request(
|
||||
connection,
|
||||
request_number,
|
||||
_tf_ssb_connection_tunnel_callback,
|
||||
NULL,
|
||||
tunnel,
|
||||
tunnel);
|
||||
tf_ssb_connection_add_request(connection, request_number, _tf_ssb_connection_tunnel_callback, NULL, tunnel, tunnel);
|
||||
if (request_number > 0)
|
||||
{
|
||||
tunnel->state = k_tf_ssb_state_connected;
|
||||
@ -2732,7 +2660,8 @@ tf_ssb_connection_t* tf_ssb_connection_tunnel_create(tf_ssb_t* ssb, const char*
|
||||
return tunnel;
|
||||
}
|
||||
|
||||
typedef struct _connect_t {
|
||||
typedef struct _connect_t
|
||||
{
|
||||
tf_ssb_t* ssb;
|
||||
uv_getaddrinfo_t req;
|
||||
char host[256];
|
||||
@ -2760,8 +2689,7 @@ static void _tf_on_connect_getaddrinfo(uv_getaddrinfo_t* addrinfo, int result, s
|
||||
void tf_ssb_connect(tf_ssb_t* ssb, const char* host, int port, const uint8_t* key)
|
||||
{
|
||||
connect_t* connect = tf_malloc(sizeof(connect_t));
|
||||
*connect = (connect_t)
|
||||
{
|
||||
*connect = (connect_t) {
|
||||
.ssb = ssb,
|
||||
.port = port,
|
||||
.req.data = connect,
|
||||
@ -2866,9 +2794,7 @@ static void _tf_ssb_send_broadcast(tf_ssb_t* ssb, struct sockaddr_in* address, s
|
||||
struct sockaddr_in broadcast_addr = { 0 };
|
||||
broadcast_addr.sin_family = AF_INET;
|
||||
broadcast_addr.sin_port = htons(8008);
|
||||
broadcast_addr.sin_addr.s_addr =
|
||||
(address->sin_addr.s_addr & netmask->sin_addr.s_addr) |
|
||||
(INADDR_BROADCAST & ~netmask->sin_addr.s_addr);
|
||||
broadcast_addr.sin_addr.s_addr = (address->sin_addr.s_addr & netmask->sin_addr.s_addr) | (INADDR_BROADCAST & ~netmask->sin_addr.s_addr);
|
||||
r = uv_udp_try_send(&ssb->broadcast_sender, &buf, 1, (struct sockaddr*)&broadcast_addr);
|
||||
if (r < 0)
|
||||
{
|
||||
@ -2887,8 +2813,7 @@ static void _tf_ssb_broadcast_timer(uv_timer_t* timer)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (!info[i].is_internal &&
|
||||
info[i].address.address4.sin_family == AF_INET)
|
||||
if (!info[i].is_internal && info[i].address.address4.sin_family == AF_INET)
|
||||
{
|
||||
_tf_ssb_send_broadcast(ssb, &info[i].address.address4, &info[i].netmask.netmask4);
|
||||
}
|
||||
@ -3011,8 +2936,7 @@ static void _tf_ssb_add_broadcast(tf_ssb_t* ssb, const tf_ssb_broadcast_t* broad
|
||||
{
|
||||
for (tf_ssb_broadcast_t* node = ssb->broadcasts; node; node = node->next)
|
||||
{
|
||||
if (node->tunnel_connection == broadcast->tunnel_connection &&
|
||||
memcmp(node->pub, broadcast->pub, sizeof(node->pub)) == 0)
|
||||
if (node->tunnel_connection == broadcast->tunnel_connection && memcmp(node->pub, broadcast->pub, sizeof(node->pub)) == 0)
|
||||
{
|
||||
node->mtime = time(NULL);
|
||||
return;
|
||||
@ -3023,10 +2947,8 @@ static void _tf_ssb_add_broadcast(tf_ssb_t* ssb, const tf_ssb_broadcast_t* broad
|
||||
{
|
||||
for (tf_ssb_broadcast_t* node = ssb->broadcasts; node; node = node->next)
|
||||
{
|
||||
if (node->addr.sin_family == broadcast->addr.sin_family &&
|
||||
node->addr.sin_port == broadcast->addr.sin_port &&
|
||||
node->addr.sin_addr.s_addr == broadcast->addr.sin_addr.s_addr &&
|
||||
memcmp(node->pub, broadcast->pub, sizeof(node->pub)) == 0)
|
||||
if (node->addr.sin_family == broadcast->addr.sin_family && node->addr.sin_port == broadcast->addr.sin_port &&
|
||||
node->addr.sin_addr.s_addr == broadcast->addr.sin_addr.s_addr && memcmp(node->pub, broadcast->pub, sizeof(node->pub)) == 0)
|
||||
{
|
||||
node->mtime = time(NULL);
|
||||
return;
|
||||
@ -3077,7 +2999,8 @@ static void _tf_ssb_on_broadcast_listener_recv(uv_udp_t* handle, ssize_t nread,
|
||||
tf_free(buf->base);
|
||||
}
|
||||
|
||||
void tf_ssb_visit_broadcasts(tf_ssb_t* ssb, void (*callback)(const char* host, const struct sockaddr_in* addr, tf_ssb_connection_t* tunnel, const uint8_t* pub, void* user_data), void* user_data)
|
||||
void tf_ssb_visit_broadcasts(
|
||||
tf_ssb_t* ssb, void (*callback)(const char* host, const struct sockaddr_in* addr, tf_ssb_connection_t* tunnel, const uint8_t* pub, void* user_data), void* user_data)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
tf_ssb_broadcast_t* next = NULL;
|
||||
@ -3165,8 +3088,7 @@ void tf_ssb_broadcast_sender_start(tf_ssb_t* ssb)
|
||||
|
||||
ssb->broadcast_sender.data = ssb;
|
||||
uv_udp_init(ssb->loop, &ssb->broadcast_sender);
|
||||
struct sockaddr_in broadcast_from =
|
||||
{
|
||||
struct sockaddr_in broadcast_from = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = INADDR_ANY,
|
||||
};
|
||||
@ -3231,9 +3153,7 @@ const char** tf_ssb_get_connection_ids(tf_ssb_t* ssb)
|
||||
int tf_ssb_get_connections(tf_ssb_t* ssb, tf_ssb_connection_t** out_connections, int out_connections_count)
|
||||
{
|
||||
int i = 0;
|
||||
for (tf_ssb_connection_t* connection = ssb->connections;
|
||||
connection && i < out_connections_count;
|
||||
connection = connection->next)
|
||||
for (tf_ssb_connection_t* connection = ssb->connections; connection && i < out_connections_count; connection = connection->next)
|
||||
{
|
||||
out_connections[i++] = connection;
|
||||
}
|
||||
@ -3243,8 +3163,7 @@ int tf_ssb_get_connections(tf_ssb_t* ssb, tf_ssb_connection_t** out_connections,
|
||||
void tf_ssb_add_broadcasts_changed_callback(tf_ssb_t* ssb, tf_ssb_broadcasts_changed_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data)
|
||||
{
|
||||
tf_ssb_broadcasts_changed_callback_node_t* node = tf_malloc(sizeof(tf_ssb_broadcasts_changed_callback_node_t));
|
||||
*node = (tf_ssb_broadcasts_changed_callback_node_t)
|
||||
{
|
||||
*node = (tf_ssb_broadcasts_changed_callback_node_t) {
|
||||
.callback = callback,
|
||||
.cleanup = cleanup,
|
||||
.user_data = user_data,
|
||||
@ -3259,8 +3178,7 @@ void tf_ssb_remove_broadcasts_changed_callback(tf_ssb_t* ssb, tf_ssb_broadcasts_
|
||||
tf_ssb_broadcasts_changed_callback_node_t** it = &ssb->broadcasts_changed;
|
||||
while (*it)
|
||||
{
|
||||
if ((*it)->callback == callback &&
|
||||
(*it)->user_data == user_data)
|
||||
if ((*it)->callback == callback && (*it)->user_data == user_data)
|
||||
{
|
||||
tf_ssb_broadcasts_changed_callback_node_t* node = *it;
|
||||
*it = node->next;
|
||||
@ -3281,8 +3199,7 @@ void tf_ssb_remove_broadcasts_changed_callback(tf_ssb_t* ssb, tf_ssb_broadcasts_
|
||||
void tf_ssb_add_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_connections_changed_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data)
|
||||
{
|
||||
tf_ssb_connections_changed_callback_node_t* node = tf_malloc(sizeof(tf_ssb_connections_changed_callback_node_t));
|
||||
*node = (tf_ssb_connections_changed_callback_node_t)
|
||||
{
|
||||
*node = (tf_ssb_connections_changed_callback_node_t) {
|
||||
.callback = callback,
|
||||
.cleanup = cleanup,
|
||||
.user_data = user_data,
|
||||
@ -3297,8 +3214,7 @@ void tf_ssb_remove_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_connection
|
||||
tf_ssb_connections_changed_callback_node_t** it = &ssb->connections_changed;
|
||||
while (*it)
|
||||
{
|
||||
if ((*it)->callback == callback &&
|
||||
(*it)->user_data == user_data)
|
||||
if ((*it)->callback == callback && (*it)->user_data == user_data)
|
||||
{
|
||||
tf_ssb_connections_changed_callback_node_t* node = *it;
|
||||
*it = node->next;
|
||||
@ -3325,13 +3241,8 @@ void tf_ssb_add_rpc_callback(tf_ssb_t* ssb, const char** name, tf_ssb_rpc_callba
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
.name = (const char**)(node + 1),
|
||||
.flattened_name = (const char*)(node + 1) + (name_count + 1) * sizeof(const char*) + name_len,
|
||||
.callback = callback,
|
||||
@ -3391,11 +3302,11 @@ JSValue tf_ssb_connection_get_object(tf_ssb_connection_t* connection)
|
||||
return connection ? connection->object : JS_UNDEFINED;
|
||||
}
|
||||
|
||||
void tf_ssb_add_message_added_callback(tf_ssb_t* ssb, void (*callback)(tf_ssb_t* ssb, const char* id, void* user_data), void (*cleanup)(tf_ssb_t* ssb, void* user_data), void* user_data)
|
||||
void tf_ssb_add_message_added_callback(
|
||||
tf_ssb_t* ssb, void (*callback)(tf_ssb_t* ssb, const char* id, void* user_data), void (*cleanup)(tf_ssb_t* ssb, void* user_data), void* user_data)
|
||||
{
|
||||
tf_ssb_message_added_callback_node_t* node = tf_malloc(sizeof(tf_ssb_message_added_callback_node_t));
|
||||
*node = (tf_ssb_message_added_callback_node_t)
|
||||
{
|
||||
*node = (tf_ssb_message_added_callback_node_t) {
|
||||
.callback = callback,
|
||||
.cleanup = cleanup,
|
||||
.user_data = user_data,
|
||||
@ -3410,8 +3321,7 @@ void tf_ssb_remove_message_added_callback(tf_ssb_t* ssb, tf_ssb_message_added_ca
|
||||
tf_ssb_message_added_callback_node_t** it = &ssb->message_added;
|
||||
while (*it)
|
||||
{
|
||||
if ((*it)->callback == callback &&
|
||||
(*it)->user_data == user_data)
|
||||
if ((*it)->callback == callback && (*it)->user_data == user_data)
|
||||
{
|
||||
tf_ssb_message_added_callback_node_t* node = *it;
|
||||
*it = node->next;
|
||||
@ -3459,23 +3369,12 @@ void tf_ssb_notify_message_added(tf_ssb_t* ssb, const char* id, JSValue message_
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tf_ssb_connection_message_request_t* message_request =
|
||||
bsearch(
|
||||
author_string,
|
||||
connection->message_requests,
|
||||
connection->message_requests_count,
|
||||
sizeof(tf_ssb_connection_message_request_t),
|
||||
_message_request_compare);
|
||||
tf_ssb_connection_message_request_t* message_request = bsearch(
|
||||
author_string, connection->message_requests, connection->message_requests_count, sizeof(tf_ssb_connection_message_request_t), _message_request_compare);
|
||||
if (message_request)
|
||||
{
|
||||
tf_ssb_connection_rpc_send_json(
|
||||
connection,
|
||||
k_ssb_rpc_flag_stream,
|
||||
message_request->request_number,
|
||||
message_request->keys ? message_keys : message,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
connection, k_ssb_rpc_flag_stream, message_request->request_number, message_request->keys ? message_keys : message, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3485,11 +3384,11 @@ void tf_ssb_notify_message_added(tf_ssb_t* ssb, const char* id, JSValue message_
|
||||
}
|
||||
}
|
||||
|
||||
void tf_ssb_add_blob_want_added_callback(tf_ssb_t* ssb, void (*callback)(tf_ssb_t* ssb, const char* id, void* user_data), void (*cleanup)(tf_ssb_t* ssb, void* user_data), void* user_data)
|
||||
void tf_ssb_add_blob_want_added_callback(
|
||||
tf_ssb_t* ssb, void (*callback)(tf_ssb_t* ssb, const char* id, void* user_data), void (*cleanup)(tf_ssb_t* ssb, void* user_data), void* user_data)
|
||||
{
|
||||
tf_ssb_blob_want_added_callback_node_t* node = tf_malloc(sizeof(tf_ssb_blob_want_added_callback_node_t));
|
||||
*node = (tf_ssb_blob_want_added_callback_node_t)
|
||||
{
|
||||
*node = (tf_ssb_blob_want_added_callback_node_t) {
|
||||
.callback = callback,
|
||||
.cleanup = cleanup,
|
||||
.user_data = user_data,
|
||||
@ -3504,8 +3403,7 @@ void tf_ssb_remove_blob_want_added_callback(tf_ssb_t* ssb, tf_ssb_blob_want_adde
|
||||
tf_ssb_blob_want_added_callback_node_t** it = &ssb->blob_want_added;
|
||||
while (*it)
|
||||
{
|
||||
if ((*it)->callback == callback &&
|
||||
(*it)->user_data == user_data)
|
||||
if ((*it)->callback == callback && (*it)->user_data == user_data)
|
||||
{
|
||||
tf_ssb_blob_want_added_callback_node_t* node = *it;
|
||||
*it = node->next;
|
||||
@ -3537,8 +3435,7 @@ void tf_ssb_notify_blob_want_added(tf_ssb_t* ssb, const char* id)
|
||||
|
||||
void tf_ssb_connection_add_room_attendant(tf_ssb_connection_t* connection, const char* id)
|
||||
{
|
||||
tf_ssb_broadcast_t broadcast =
|
||||
{
|
||||
tf_ssb_broadcast_t broadcast = {
|
||||
.tunnel_connection = connection,
|
||||
};
|
||||
tf_ssb_id_str_to_bin(broadcast.pub, id);
|
||||
@ -3553,8 +3450,7 @@ void tf_ssb_connection_remove_room_attendant(tf_ssb_connection_t* connection, co
|
||||
int modified = 0;
|
||||
for (tf_ssb_broadcast_t** it = &connection->ssb->broadcasts; *it;)
|
||||
{
|
||||
if ((*it)->tunnel_connection == connection &&
|
||||
memcmp((*it)->pub, pub, k_id_bin_len) == 0)
|
||||
if ((*it)->tunnel_connection == connection && memcmp((*it)->pub, pub, k_id_bin_len) == 0)
|
||||
{
|
||||
tf_ssb_broadcast_t* node = *it;
|
||||
*it = node->next;
|
||||
@ -3651,8 +3547,7 @@ void tf_ssb_verify_strip_and_store_message(tf_ssb_t* ssb, JSValue value, tf_ssb_
|
||||
{
|
||||
JSContext* context = tf_ssb_get_context(ssb);
|
||||
store_t* async = tf_malloc(sizeof(store_t));
|
||||
*async = (store_t)
|
||||
{
|
||||
*async = (store_t) {
|
||||
.ssb = ssb,
|
||||
.callback = callback,
|
||||
.user_data = user_data,
|
||||
@ -3729,7 +3624,8 @@ JSValue tf_ssb_get_disconnection_debug(tf_ssb_t* ssb, JSContext* context)
|
||||
JS_SetPropertyStr(context, message, "flags", JS_NewInt32(context, ssb->debug_close[i].messages[j]->flags));
|
||||
JS_SetPropertyStr(context, message, "request_number", JS_NewInt32(context, ssb->debug_close[i].messages[j]->request_number));
|
||||
JS_SetPropertyStr(context, message, "timestamp", JS_NewFloat64(context, ssb->debug_close[i].messages[j]->timestamp));
|
||||
JS_SetPropertyStr(context, message, "payload", JS_NewStringLen(context, (const char*)ssb->debug_close[i].messages[j]->data, ssb->debug_close[i].messages[j]->size));
|
||||
JS_SetPropertyStr(context, message, "payload",
|
||||
JS_NewStringLen(context, (const char*)ssb->debug_close[i].messages[j]->data, ssb->debug_close[i].messages[j]->size));
|
||||
JS_SetPropertyUint32(context, messages, j, message);
|
||||
}
|
||||
}
|
||||
@ -3815,19 +3711,15 @@ static void _tf_ssb_connection_after_work_callback(uv_work_t* work, int status)
|
||||
data->after_work_callback(data->connection, status, data->user_data);
|
||||
}
|
||||
data->connection->ref_count--;
|
||||
if (data->connection->ref_count == 0 &&
|
||||
data->connection->closing)
|
||||
if (data->connection->ref_count == 0 && data->connection->closing)
|
||||
{
|
||||
_tf_ssb_connection_destroy(data->connection, "work completed");
|
||||
}
|
||||
tf_free(data);
|
||||
}
|
||||
|
||||
void tf_ssb_connection_run_work(
|
||||
tf_ssb_connection_t* connection,
|
||||
void (*work_callback)(tf_ssb_connection_t* connection, void* user_data),
|
||||
void (*after_work_callback)(tf_ssb_connection_t* connection, int result, void* user_data),
|
||||
void* user_data)
|
||||
void tf_ssb_connection_run_work(tf_ssb_connection_t* connection, void (*work_callback)(tf_ssb_connection_t* connection, void* user_data),
|
||||
void (*after_work_callback)(tf_ssb_connection_t* connection, int result, void* user_data), void* user_data)
|
||||
{
|
||||
connection_work_t* work = tf_malloc(sizeof(connection_work_t));
|
||||
*work = (connection_work_t)
|
||||
|
Reference in New Issue
Block a user