diff --git a/src/ssb.c b/src/ssb.c index 27af7d29..ca340261 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -61,7 +61,7 @@ typedef enum { enum { k_connections_changed_callbacks_max = 8, - k_tf_ssb_rpc_message_body_length_max = 64 * 1024, + k_tf_ssb_rpc_message_body_length_max = 1 * 1024 * 1024, }; typedef struct _tf_ssb_broadcast_t tf_ssb_broadcast_t; @@ -245,6 +245,9 @@ typedef struct _tf_ssb_connection_t uint8_t pad; size_t rpc_recv_size; + uint8_t box_stream_buf[16 + k_tf_ssb_rpc_message_body_length_max]; + uint8_t secretbox_buf[k_tf_ssb_rpc_message_body_length_max]; + uint32_t send_request_number; tf_ssb_connection_t* next; @@ -430,41 +433,39 @@ static void _tf_ssb_nonce_inc(uint8_t* nonce) static void _tf_ssb_connection_box_stream_send(tf_ssb_connection_t* connection, const uint8_t* message, size_t size) { - uint8_t* message_enc = tf_malloc(size + 34); - - uint8_t nonce1[crypto_secretbox_NONCEBYTES]; - memcpy(nonce1, connection->send_nonce, sizeof(nonce1)); - _tf_ssb_nonce_inc(connection->send_nonce); - uint8_t nonce2[crypto_secretbox_NONCEBYTES]; - memcpy(nonce2, connection->send_nonce, sizeof(nonce2)); - _tf_ssb_nonce_inc(connection->send_nonce); - - if (crypto_secretbox_easy(message_enc + 34 - 16, message, size, nonce2, connection->c_to_s_box_key) != 0) + const size_t k_send_max = 65535; + for (size_t offset = 0; offset < size; offset += k_send_max) { - _tf_ssb_connection_close(connection, "unable to secretbox message"); - tf_free(message_enc); - return; - } + size_t send_size = size - offset > k_send_max ? k_send_max : size - offset; + uint8_t* message_enc = tf_malloc(send_size + 34); - if (size > 65535) - { - _tf_ssb_connection_close(connection, "sending message that is too big"); - tf_free(message_enc); - return; - } + uint8_t nonce1[crypto_secretbox_NONCEBYTES]; + memcpy(nonce1, connection->send_nonce, sizeof(nonce1)); + _tf_ssb_nonce_inc(connection->send_nonce); + uint8_t nonce2[crypto_secretbox_NONCEBYTES]; + memcpy(nonce2, connection->send_nonce, sizeof(nonce2)); + _tf_ssb_nonce_inc(connection->send_nonce); - uint8_t header[18]; - *(uint16_t*)header = htons((uint16_t)size); - memcpy(header + sizeof(uint16_t), message_enc + 34 - 16, 16); - if (crypto_secretbox_easy(message_enc, header, sizeof(header), nonce1, connection->c_to_s_box_key) != 0) - { - _tf_ssb_connection_close(connection, "unable to secretbox header"); - tf_free(message_enc); - return; - } + if (crypto_secretbox_easy(message_enc + 34 - 16, message + offset, send_size, nonce2, connection->c_to_s_box_key) != 0) + { + _tf_ssb_connection_close(connection, "unable to secretbox message"); + tf_free(message_enc); + return; + } - _tf_ssb_write(connection, message_enc, size + 34); - tf_free(message_enc); + uint8_t header[18]; + *(uint16_t*)header = htons((uint16_t)send_size); + memcpy(header + sizeof(uint16_t), message_enc + 34 - 16, 16); + if (crypto_secretbox_easy(message_enc, header, sizeof(header), nonce1, connection->c_to_s_box_key) != 0) + { + _tf_ssb_connection_close(connection, "unable to secretbox header"); + tf_free(message_enc); + return; + } + + _tf_ssb_write(connection, message_enc, send_size + 34); + tf_free(message_enc); + } } static int _request_compare(const void* a, const void* b) @@ -1460,18 +1461,16 @@ static bool _tf_ssb_connection_box_stream_recv(tf_ssb_connection_t* connection) if (connection->body_len) { - uint8_t buf[16 + k_tf_ssb_rpc_message_body_length_max]; - memcpy(buf, connection->body_auth_tag, sizeof(connection->body_auth_tag)); - if (_tf_ssb_connection_recv_pop(connection, buf + 16, connection->body_len)) + 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)) { - uint8_t body[k_tf_ssb_rpc_message_body_length_max]; - if (crypto_secretbox_open_easy(body, 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; } _tf_ssb_nonce_inc(connection->nonce); - _tf_ssb_connection_rpc_recv_push(connection, body, connection->body_len); + _tf_ssb_connection_rpc_recv_push(connection, connection->secretbox_buf, connection->body_len); connection->body_len = 0; } else