Skip to content

Commit

Permalink
fix: Fix bootstrap on emscripten/wasm.
Browse files Browse the repository at this point in the history
Also added a whole bunch of logging that I needed while debugging the
issue. The solution in the end is that bootstrap needs to resolve IPs,
and getaddrinfo fails in the browser. Most of the time we bootstrap
against IPs anyway, so trying to parse as IP address first will shortcut
that.
  • Loading branch information
iphydf committed Feb 1, 2022
1 parent da4ef64 commit 211f1d5
Show file tree
Hide file tree
Showing 15 changed files with 369 additions and 267 deletions.
131 changes: 72 additions & 59 deletions auto_tests/TCP_test.c

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions other/bootstrap_daemon/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ COPY CMakeLists.txt so.version ./

RUN cmake -B_build -H. \
-GNinja \
-DCMAKE_C_FLAGS=-DTCP_SERVER_USE_EPOLL \
-DMIN_LOGGER_LEVEL=DEBUG \
-DCMAKE_BUILD_TYPE=Release \
-DFULLY_STATIC=ON \
-DBUILD_TOXAV=OFF \
Expand Down
2 changes: 1 addition & 1 deletion other/bootstrap_daemon/docker/tox-bootstrapd.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
33548aa46a757ac403a823dbd02151580ead0fe51ea4f334cfeddaefb5391150 /usr/local/bin/tox-bootstrapd
43f09f0e054355d37a774a57beded8b371de085ae321d4208b46785f430613c1 /usr/local/bin/tox-bootstrapd
2 changes: 1 addition & 1 deletion other/bootstrap_daemon/docker/update-sha256
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh

set -eux

Expand Down
88 changes: 46 additions & 42 deletions toxcore/TCP_client.c

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions toxcore/TCP_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);

/** Create new TCP connection to ip_port/public_key
*/
TCP_Client_Connection *new_TCP_connection(const Mono_Time *mono_time, IP_Port ip_port, const uint8_t *public_key,
const uint8_t *self_public_key, const uint8_t *self_secret_key, const TCP_Proxy_Info *proxy_info);
TCP_Client_Connection *new_TCP_connection(const Logger *logger, const Mono_Time *mono_time, IP_Port ip_port,
const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
const TCP_Proxy_Info *proxy_info);

/** Run the TCP connection
*/
Expand All @@ -67,7 +68,7 @@ typedef int tcp_onion_response_cb(void *object, const uint8_t *data, uint16_t le
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length);
int send_onion_request(const Logger *logger, TCP_Client_Connection *con, const uint8_t *data, uint16_t length);
void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object);

typedef int tcp_routing_response_cb(void *object, uint8_t connection_id, const uint8_t *public_key);
Expand All @@ -77,15 +78,15 @@ typedef int tcp_routing_status_cb(void *object, uint32_t number, uint8_t connect
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
int send_routing_request(TCP_Client_Connection *con, const uint8_t *public_key);
int send_routing_request(const Logger *logger, TCP_Client_Connection *con, const uint8_t *public_key);
void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object);
void routing_status_handler(TCP_Client_Connection *con, tcp_routing_status_cb *status_callback, void *object);

/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id);
int send_disconnect_request(const Logger *logger, TCP_Client_Connection *con, uint8_t con_id);

/** Set the number that will be used as an argument in the callbacks related to con_id.
*
Expand All @@ -103,7 +104,7 @@ typedef int tcp_routing_data_cb(void *object, uint32_t number, uint8_t connectio
* return 0 if could not send packet.
* return -1 on failure.
*/
int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length);
int send_data(const Logger *logger, TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length);
void routing_data_handler(TCP_Client_Connection *con, tcp_routing_data_cb *data_callback, void *object);

typedef int tcp_oob_data_cb(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length,
Expand All @@ -113,7 +114,8 @@ typedef int tcp_oob_data_cb(void *object, const uint8_t *public_key, const uint8
* return 0 if could not send packet.
* return -1 on failure.
*/
int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length);
int send_oob_packet(const Logger *logger, TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data,
uint16_t length);
void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object);


Expand Down
59 changes: 33 additions & 26 deletions toxcore/TCP_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ void wipe_priority_list(TCP_Priority_List *p)
/** return 0 if pending data was sent completely
* return -1 if it wasn't
*/
int send_pending_data_nonpriority(TCP_Connection *con)
int send_pending_data_nonpriority(const Logger *logger, TCP_Connection *con)
{
if (con->last_packet_length == 0) {
return 0;
}

const uint16_t left = con->last_packet_length - con->last_packet_sent;
const int len = net_send(con->sock, con->last_packet + con->last_packet_sent, left);
const int len = net_send(logger, con->sock, con->last_packet + con->last_packet_sent, left, con->ip_port);

if (len <= 0) {
return -1;
Expand All @@ -47,18 +47,18 @@ int send_pending_data_nonpriority(TCP_Connection *con)
/** return 0 if pending data was sent completely
* return -1 if it wasn't
*/
int send_pending_data(TCP_Connection *con)
int send_pending_data(const Logger *logger, TCP_Connection *con)
{
/* finish sending current non-priority packet */
if (send_pending_data_nonpriority(con) == -1) {
if (send_pending_data_nonpriority(logger, con) == -1) {
return -1;
}

TCP_Priority_List *p = con->priority_queue_start;

while (p) {
const uint16_t left = p->size - p->sent;
const int len = net_send(con->sock, p->data + p->sent, left);
const int len = net_send(logger, con->sock, p->data + p->sent, left, con->ip_port);

if (len != left) {
if (len > 0) {
Expand Down Expand Up @@ -122,15 +122,16 @@ bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t size, uin
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
int write_packet_TCP_secure_connection(TCP_Connection *con, const uint8_t *data, uint16_t length, bool priority)
int write_packet_TCP_secure_connection(const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length,
bool priority)
{
if (length + CRYPTO_MAC_SIZE > MAX_PACKET_SIZE) {
return -1;
}

bool sendpriority = 1;

if (send_pending_data(con) == -1) {
if (send_pending_data(logger, con) == -1) {
if (priority) {
sendpriority = 0;
} else {
Expand All @@ -149,7 +150,7 @@ int write_packet_TCP_secure_connection(TCP_Connection *con, const uint8_t *data,
}

if (priority) {
len = sendpriority ? net_send(con->sock, packet, SIZEOF_VLA(packet)) : 0;
len = sendpriority ? net_send(logger, con->sock, packet, SIZEOF_VLA(packet), con->ip_port) : 0;

if (len <= 0) {
len = 0;
Expand All @@ -164,7 +165,7 @@ int write_packet_TCP_secure_connection(TCP_Connection *con, const uint8_t *data,
return add_priority(con, packet, SIZEOF_VLA(packet), len);
}

len = net_send(con->sock, packet, SIZEOF_VLA(packet));
len = net_send(logger, con->sock, packet, SIZEOF_VLA(packet), con->ip_port);

if (len <= 0) {
return 0;
Expand All @@ -187,22 +188,23 @@ int write_packet_TCP_secure_connection(TCP_Connection *con, const uint8_t *data,
* return length on success
* return -1 on failure/no data in buffer.
*/
int read_TCP_packet(const Logger *logger, Socket sock, uint8_t *data, uint16_t length)
int read_TCP_packet(const Logger *logger, Socket sock, uint8_t *data, uint16_t length, IP_Port ip_port)
{
const uint16_t count = net_socket_data_recv_buffer(sock);

if (count >= length) {
const int len = net_recv(sock, data, length);
if (count < length) {
LOGGER_INFO(logger, "recv buffer has %d bytes, but requested %d bytes", count, length);
return -1;
}

if (len != length) {
LOGGER_ERROR(logger, "FAIL recv packet");
return -1;
}
const int len = net_recv(logger, sock, data, length, ip_port);

return len;
if (len != length) {
LOGGER_ERROR(logger, "FAIL recv packet");
return -1;
}

return -1;
return len;
}

/** Read the next two bytes in TCP stream then convert them to
Expand All @@ -212,22 +214,24 @@ int read_TCP_packet(const Logger *logger, Socket sock, uint8_t *data, uint16_t l
* return 0 if nothing has been read from socket.
* return -1 on failure.
*/
static uint16_t read_TCP_length(const Logger *logger, Socket sock)
static uint16_t read_TCP_length(const Logger *logger, Socket sock, IP_Port ip_port)
{
const uint16_t count = net_socket_data_recv_buffer(sock);

if (count >= sizeof(uint16_t)) {
uint16_t length;
const int len = net_recv(sock, &length, sizeof(uint16_t));
uint8_t length_buf[sizeof(uint16_t)];
const int len = net_recv(logger, sock, length_buf, sizeof(length_buf), ip_port);

if (len != sizeof(uint16_t)) {
LOGGER_ERROR(logger, "FAIL recv packet");
return 0;
}

length = net_ntohs(length);
uint16_t length;
net_unpack_u16(length_buf, &length);

if (length > MAX_PACKET_SIZE) {
LOGGER_WARNING(logger, "TCP packet too large: %d > %d", length, MAX_PACKET_SIZE);
return -1;
}

Expand All @@ -242,10 +246,10 @@ static uint16_t read_TCP_length(const Logger *logger, Socket sock)
* return -1 on failure (connection must be killed).
*/
int read_packet_TCP_secure_connection(const Logger *logger, Socket sock, uint16_t *next_packet_length,
const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, uint16_t max_len)
const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, uint16_t max_len, IP_Port ip_port)
{
if (*next_packet_length == 0) {
uint16_t len = read_TCP_length(logger, sock);
const uint16_t len = read_TCP_length(logger, sock, ip_port);

if (len == (uint16_t) -1) {
return -1;
Expand All @@ -259,21 +263,24 @@ int read_packet_TCP_secure_connection(const Logger *logger, Socket sock, uint16_
}

if (max_len + CRYPTO_MAC_SIZE < *next_packet_length) {
LOGGER_DEBUG(logger, "packet too large");
return -1;
}

VLA(uint8_t, data_encrypted, *next_packet_length);
int len_packet = read_TCP_packet(logger, sock, data_encrypted, *next_packet_length);
const int len_packet = read_TCP_packet(logger, sock, data_encrypted, *next_packet_length, ip_port);

if (len_packet != *next_packet_length) {
LOGGER_WARNING(logger, "invalid packet length: %d, expected %d", len_packet, *next_packet_length);
return 0;
}

*next_packet_length = 0;

int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data);
const int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data);

if (len + CRYPTO_MAC_SIZE != len_packet) {
LOGGER_WARNING(logger, "decrypted length %d does not match expected length %d", len + CRYPTO_MAC_SIZE, len_packet);
return -1;
}

Expand Down
12 changes: 7 additions & 5 deletions toxcore/TCP_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void wipe_priority_list(TCP_Priority_List *p);

typedef struct TCP_Connection {
Socket sock;
IP_Port ip_port; // for debugging.
uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
uint8_t last_packet[2 + MAX_PACKET_SIZE];
Expand All @@ -59,12 +60,12 @@ typedef struct TCP_Connection {
/** return 0 if pending data was sent completely
* return -1 if it wasn't
*/
int send_pending_data_nonpriority(TCP_Connection *con);
int send_pending_data_nonpriority(const Logger *logger, TCP_Connection *con);

/** return 0 if pending data was sent completely
* return -1 if it wasn't
*/
int send_pending_data(TCP_Connection *con);
int send_pending_data(const Logger *logger, TCP_Connection *con);

/** return 0 on failure (only if calloc fails)
* return 1 on success
Expand All @@ -75,20 +76,21 @@ bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t size, uin
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
int write_packet_TCP_secure_connection(TCP_Connection *con, const uint8_t *data, uint16_t length, bool priority);
int write_packet_TCP_secure_connection(const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length,
bool priority);

/** Read length bytes from socket.
*
* return length on success
* return -1 on failure/no data in buffer.
*/
int read_TCP_packet(const Logger *logger, Socket sock, uint8_t *data, uint16_t length);
int read_TCP_packet(const Logger *logger, Socket sock, uint8_t *data, uint16_t length, IP_Port ip_port);

/** return length of received packet on success.
* return 0 if could not read any packet.
* return -1 on failure (connection must be killed).
*/
int read_packet_TCP_secure_connection(const Logger *logger, Socket sock, uint16_t *next_packet_length,
const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, uint16_t max_len);
const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, uint16_t max_len, IP_Port ip_port);

#endif
Loading

0 comments on commit 211f1d5

Please sign in to comment.