From 5c584587c6697505cfb3f58097a788019a9a8778 Mon Sep 17 00:00:00 2001 From: iphydf Date: Thu, 12 Jul 2018 17:22:20 +0000 Subject: [PATCH] Style fixes in TCP code; remove MIN and PAIR from util.h. * Moved PAIR to toxav, where it's used (but really this should die). * Replace most MIN calls with typed `min_*` calls. Didn't replace the ones where the desired semantics are unclear. Moved the MIN macro to the one place where it's still used. * Avoid assignments in `while` loops. Instead, factored out the loop body into a separate `bool`-returning function. * Use named types for callbacks (`_cb` types). * Avoid assignments in `if` conditions. * Removed `MAKE_REALLOC` and expanded its two calls. We can't have templates in C, and this fake templating is ugly and hard to analyse and debug (it expands on a single line). * Moved epoll system include to the .c file, out of the .h file. * Avoid assignments in expressions (`a = b = c;`). * Avoid multiple declarators per struct member declaration. * Fix naming inconsistencies. * Replace `net_to_host` macro with function. --- CMakeLists.txt | 1 + auto_tests/file_transfer_test.c | 6 +- toxav/BUILD.bazel | 7 + toxav/Makefile.inc | 1 + toxav/audio.h | 1 + toxav/pair.h | 6 + toxav/toxav.c | 4 + toxav/video.h | 1 + toxcore/Messenger.c | 9 +- toxcore/TCP_client.c | 280 ++++++++++--------- toxcore/TCP_client.h | 43 +-- toxcore/TCP_connection.c | 97 ++++--- toxcore/TCP_connection.h | 33 ++- toxcore/TCP_server.c | 472 +++++++++++++++++--------------- toxcore/TCP_server.h | 22 +- toxcore/network.c | 2 +- toxcore/util.c | 10 + toxcore/util.h | 6 +- 18 files changed, 542 insertions(+), 459 deletions(-) create mode 100644 toxav/pair.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fe1c3c5f84..1bbff25519e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -261,6 +261,7 @@ if(BUILD_TOXAV) toxav/groupav.h toxav/msi.c toxav/msi.h + toxav/pair.h toxav/ring_buffer.c toxav/ring_buffer.h toxav/rtp.c diff --git a/auto_tests/file_transfer_test.c b/auto_tests/file_transfer_test.c index c861a3e0c83..6e8a3c53c29 100644 --- a/auto_tests/file_transfer_test.c +++ b/auto_tests/file_transfer_test.c @@ -286,7 +286,7 @@ static void file_transfer_test(void) printf("after %u iterations: %.2fMiB done\n", (unsigned int)i + 1, (double)size_recv / 1024 / 1024); } - c_sleep(MIN(tox1_interval, MIN(tox2_interval, tox3_interval))); + c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval))); } ck_assert_msg(file_sending_done, "file sending did not complete after %u iterations: sendf_ok:%u file_recv:%u " @@ -348,7 +348,7 @@ static void file_transfer_test(void) uint32_t tox2_interval = tox_iteration_interval(tox2); uint32_t tox3_interval = tox_iteration_interval(tox3); - c_sleep(MIN(tox1_interval, MIN(tox2_interval, tox3_interval))); + c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval))); } printf("Starting file 0 transfer test.\n"); @@ -397,7 +397,7 @@ static void file_transfer_test(void) uint32_t tox2_interval = tox_iteration_interval(tox2); uint32_t tox3_interval = tox_iteration_interval(tox3); - c_sleep(MIN(tox1_interval, MIN(tox2_interval, tox3_interval))); + c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval))); } printf("file_transfer_test succeeded, took %llu seconds\n", time(nullptr) - cur_time); diff --git a/toxav/BUILD.bazel b/toxav/BUILD.bazel index dbe57b6c02b..f6c92b52f6f 100644 --- a/toxav/BUILD.bazel +++ b/toxav/BUILD.bazel @@ -54,11 +54,17 @@ cc_test( ], ) +cc_library( + name = "pair", + hdrs = ["pair.h"], +) + cc_library( name = "audio", srcs = ["audio.c"], hdrs = ["audio.h"], deps = [ + ":pair", ":public", ":rtp", "//c-toxcore/toxcore:network", @@ -78,6 +84,7 @@ cc_library( ], deps = [ ":audio", + ":pair", ":public", "//c-toxcore/toxcore:network", "@libvpx", diff --git a/toxav/Makefile.inc b/toxav/Makefile.inc index 7b7881985c4..5f6342c0f96 100644 --- a/toxav/Makefile.inc +++ b/toxav/Makefile.inc @@ -16,6 +16,7 @@ libtoxav_la_SOURCES = ../toxav/rtp.h \ ../toxav/video.c \ ../toxav/bwcontroller.h \ ../toxav/bwcontroller.c \ + ../toxav/pair.h \ ../toxav/ring_buffer.h \ ../toxav/ring_buffer.c \ ../toxav/toxav.h \ diff --git a/toxav/audio.h b/toxav/audio.h index 64aa2f12d9d..39d534e03a4 100644 --- a/toxav/audio.h +++ b/toxav/audio.h @@ -24,6 +24,7 @@ #include "../toxcore/logger.h" #include "../toxcore/util.h" +#include "pair.h" #include #include diff --git a/toxav/pair.h b/toxav/pair.h new file mode 100644 index 00000000000..59ef2b62dce --- /dev/null +++ b/toxav/pair.h @@ -0,0 +1,6 @@ +#ifndef C_TOXCORE_TOXAV_PAIR_H +#define C_TOXCORE_TOXAV_PAIR_H + +#define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; } + +#endif // C_TOXCORE_TOXAV_PAIR_H diff --git a/toxav/toxav.c b/toxav/toxav.c index 5abe1130904..dcffca4d41a 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -242,6 +242,10 @@ void toxav_iterate(ToxAV *av) ac_iterate(i->audio.second); vc_iterate(i->video.second); + // TODO(iphydf): Find out what MIN-semantics are desired here and + // use a min_* function from util.h. +#define MIN(a,b) (((a)<(b))?(a):(b)) + if (i->msi_call->self_capabilities & msi_CapRAudio && i->msi_call->peer_capabilities & msi_CapSAudio) { rc = MIN(i->audio.second->lp_frame_duration, rc); diff --git a/toxav/video.h b/toxav/video.h index 616a866a92d..7a0913a0afd 100644 --- a/toxav/video.h +++ b/toxav/video.h @@ -24,6 +24,7 @@ #include "../toxcore/logger.h" #include "../toxcore/util.h" +#include "pair.h" #include #include diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index a5d15a34caf..416b937c918 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -717,7 +717,9 @@ int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf, return -1; } - int msglen = MIN(maxlen, m->friendlist[friendnumber].statusmessage_length); + // TODO(iphydf): This should be uint16_t and min_u16. If maxlen exceeds + // uint16_t's range, it won't affect the result. + uint32_t msglen = min_u32(maxlen, m->friendlist[friendnumber].statusmessage_length); memcpy(buf, m->friendlist[friendnumber].statusmessage, msglen); memset(buf + msglen, 0, maxlen - msglen); @@ -2855,9 +2857,10 @@ static uint32_t friends_list_save(const Messenger *m, uint8_t *data) memcpy(temp.real_pk, m->friendlist[i].real_pk, CRYPTO_PUBLIC_KEY_SIZE); if (temp.status < 3) { + // TODO(iphydf): Use uint16_t and min_u16 here. const size_t friendrequest_length = - MIN(m->friendlist[i].info_size, - MIN(SAVED_FRIEND_REQUEST_SIZE, MAX_FRIEND_REQUEST_DATA_SIZE)); + min_u32(m->friendlist[i].info_size, + min_u32(SAVED_FRIEND_REQUEST_SIZE, MAX_FRIEND_REQUEST_DATA_SIZE)); memcpy(temp.info, m->friendlist[i].info, friendrequest_length); temp.info_size = net_htons(m->friendlist[i].info_size); diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 1291d2763b4..da0af87702f 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -34,8 +34,14 @@ #include "mono_time.h" #include "util.h" +typedef struct TCP_Client_Conn { + uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint32_t number; +} TCP_Client_Conn; + struct TCP_Client_Connection { - TCP_CLIENT_STATUS status; + TCP_Client_Status status; Socket sock; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */ uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */ @@ -52,7 +58,8 @@ struct TCP_Client_Connection { uint16_t last_packet_length; uint16_t last_packet_sent; - TCP_Priority_List *priority_queue_start, *priority_queue_end; + TCP_Priority_List *priority_queue_start; + TCP_Priority_List *priority_queue_end; uint64_t kill_at; @@ -62,22 +69,17 @@ struct TCP_Client_Connection { uint64_t ping_response_id; uint64_t ping_request_id; - struct { - uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint32_t number; - } connections[NUM_CLIENT_CONNECTIONS]; - int (*response_callback)(void *object, uint8_t connection_id, const uint8_t *public_key); + TCP_Client_Conn connections[NUM_CLIENT_CONNECTIONS]; + tcp_routing_response_cb *response_callback; void *response_callback_object; - int (*status_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t status); + tcp_routing_status_cb *status_callback; void *status_callback_object; - int (*data_callback)(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length, - void *userdata); + tcp_routing_data_cb *data_callback; void *data_callback_object; - int (*oob_data_callback)(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata); + tcp_oob_data_cb *oob_data_callback; void *oob_data_callback_object; - int (*onion_callback)(void *object, const uint8_t *data, uint16_t length, void *userdata); + tcp_onion_response_cb *onion_callback; void *onion_callback_object; /* Can be used by user. */ @@ -95,7 +97,7 @@ IP_Port tcp_con_ip_port(const TCP_Client_Connection *con) return con->ip_port; } -TCP_CLIENT_STATUS tcp_con_status(const TCP_Client_Connection *con) +TCP_Client_Status tcp_con_status(const TCP_Client_Connection *con) { return con->status; } @@ -133,7 +135,7 @@ static int connect_sock_to(Socket sock, IP_Port ip_port, TCP_Proxy_Info *proxy_i /* return 1 on success. * return 0 on failure. */ -static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_conn) +static int proxy_http_generate_connection_request(TCP_Client_Connection *tcp_conn) { char one[] = "CONNECT "; char two[] = " HTTP/1.1\nHost: "; @@ -141,20 +143,20 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con char ip[TOX_INET6_ADDRSTRLEN]; - if (!ip_parse_addr(&TCP_conn->ip_port.ip, ip, sizeof(ip))) { + if (!ip_parse_addr(&tcp_conn->ip_port.ip, ip, sizeof(ip))) { return 0; } - const uint16_t port = net_ntohs(TCP_conn->ip_port.port); - const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, + const uint16_t port = net_ntohs(tcp_conn->ip_port.port); + const int written = snprintf((char *)tcp_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, ip, port, three); if (written < 0 || MAX_PACKET_SIZE < written) { return 0; } - TCP_conn->last_packet_length = written; - TCP_conn->last_packet_sent = 0; + tcp_conn->last_packet_length = written; + tcp_conn->last_packet_sent = 0; return 1; } @@ -163,12 +165,12 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con * return 0 if no data received. * return -1 on failure (connection refused). */ -static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) +static int proxy_http_read_connection_response(TCP_Client_Connection *tcp_conn) { char success[] = "200"; uint8_t data[16]; // draining works the best if the length is a power of 2 - int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data) - 1); + int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data) - 1); if (ret == -1) { return 0; @@ -178,11 +180,11 @@ static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) if (strstr((char *)data, success)) { // drain all data - unsigned int data_left = net_socket_data_recv_buffer(TCP_conn->sock); + unsigned int data_left = net_socket_data_recv_buffer(tcp_conn->sock); if (data_left) { VLA(uint8_t, temp_data, data_left); - read_TCP_packet(TCP_conn->sock, temp_data, data_left); + read_TCP_packet(tcp_conn->sock, temp_data, data_left); } return 1; @@ -191,24 +193,24 @@ static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) return -1; } -static void proxy_socks5_generate_handshake(TCP_Client_Connection *TCP_conn) +static void proxy_socks5_generate_handshake(TCP_Client_Connection *tcp_conn) { - TCP_conn->last_packet[0] = 5; /* SOCKSv5 */ - TCP_conn->last_packet[1] = 1; /* number of authentication methods supported */ - TCP_conn->last_packet[2] = 0; /* No authentication */ + tcp_conn->last_packet[0] = 5; /* SOCKSv5 */ + tcp_conn->last_packet[1] = 1; /* number of authentication methods supported */ + tcp_conn->last_packet[2] = 0; /* No authentication */ - TCP_conn->last_packet_length = 3; - TCP_conn->last_packet_sent = 0; + tcp_conn->last_packet_length = 3; + tcp_conn->last_packet_sent = 0; } /* return 1 on success. * return 0 if no data received. * return -1 on failure (connection refused). */ -static int socks5_read_handshake_response(TCP_Client_Connection *TCP_conn) +static int socks5_read_handshake_response(TCP_Client_Connection *tcp_conn) { uint8_t data[2]; - int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); + int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data)); if (ret == -1) { return 0; @@ -221,41 +223,41 @@ static int socks5_read_handshake_response(TCP_Client_Connection *TCP_conn) return -1; } -static void proxy_socks5_generate_connection_request(TCP_Client_Connection *TCP_conn) +static void proxy_socks5_generate_connection_request(TCP_Client_Connection *tcp_conn) { - TCP_conn->last_packet[0] = 5; /* SOCKSv5 */ - TCP_conn->last_packet[1] = 1; /* command code: establish a TCP/IP stream connection */ - TCP_conn->last_packet[2] = 0; /* reserved, must be 0 */ + tcp_conn->last_packet[0] = 5; /* SOCKSv5 */ + tcp_conn->last_packet[1] = 1; /* command code: establish a TCP/IP stream connection */ + tcp_conn->last_packet[2] = 0; /* reserved, must be 0 */ uint16_t length = 3; - if (net_family_is_ipv4(TCP_conn->ip_port.ip.family)) { - TCP_conn->last_packet[3] = 1; /* IPv4 address */ + if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) { + tcp_conn->last_packet[3] = 1; /* IPv4 address */ ++length; - memcpy(TCP_conn->last_packet + length, TCP_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4)); + memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4)); length += sizeof(IP4); } else { - TCP_conn->last_packet[3] = 4; /* IPv6 address */ + tcp_conn->last_packet[3] = 4; /* IPv6 address */ ++length; - memcpy(TCP_conn->last_packet + length, TCP_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6)); + memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6)); length += sizeof(IP6); } - memcpy(TCP_conn->last_packet + length, &TCP_conn->ip_port.port, sizeof(uint16_t)); + memcpy(tcp_conn->last_packet + length, &tcp_conn->ip_port.port, sizeof(uint16_t)); length += sizeof(uint16_t); - TCP_conn->last_packet_length = length; - TCP_conn->last_packet_sent = 0; + tcp_conn->last_packet_length = length; + tcp_conn->last_packet_sent = 0; } /* return 1 on success. * return 0 if no data received. * return -1 on failure (connection refused). */ -static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn) +static int proxy_socks5_read_connection_response(TCP_Client_Connection *tcp_conn) { - if (net_family_is_ipv4(TCP_conn->ip_port.ip.family)) { + if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) { uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)]; - int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); + int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data)); if (ret == -1) { return 0; @@ -266,7 +268,7 @@ static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn } } else { uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)]; - int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); + int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data)); if (ret == -1) { return 0; @@ -283,23 +285,23 @@ static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn /* return 0 on success. * return -1 on failure. */ -static int generate_handshake(TCP_Client_Connection *TCP_conn) +static int generate_handshake(TCP_Client_Connection *tcp_conn) { uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; - crypto_new_keypair(plain, TCP_conn->temp_secret_key); - random_nonce(TCP_conn->sent_nonce); - memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, TCP_conn->sent_nonce, CRYPTO_NONCE_SIZE); - memcpy(TCP_conn->last_packet, TCP_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); - random_nonce(TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE); - int len = encrypt_data_symmetric(TCP_conn->shared_key, TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, - sizeof(plain), TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); + crypto_new_keypair(plain, tcp_conn->temp_secret_key); + random_nonce(tcp_conn->sent_nonce); + memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->sent_nonce, CRYPTO_NONCE_SIZE); + memcpy(tcp_conn->last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + random_nonce(tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE); + int len = encrypt_data_symmetric(tcp_conn->shared_key, tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, + sizeof(plain), tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); if (len != sizeof(plain) + CRYPTO_MAC_SIZE) { return -1; } - TCP_conn->last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE; - TCP_conn->last_packet_sent = 0; + tcp_conn->last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE; + tcp_conn->last_packet_sent = 0; return 0; } @@ -308,19 +310,19 @@ static int generate_handshake(TCP_Client_Connection *TCP_conn) * return 0 on success. * return -1 on failure. */ -static int handle_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *data) +static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data) { uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; - int len = decrypt_data_symmetric(TCP_conn->shared_key, data, data + CRYPTO_NONCE_SIZE, + int len = decrypt_data_symmetric(tcp_conn->shared_key, data, data + CRYPTO_NONCE_SIZE, TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain); if (len != sizeof(plain)) { return -1; } - memcpy(TCP_conn->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - encrypt_precompute(plain, TCP_conn->temp_secret_key, TCP_conn->shared_key); - crypto_memzero(TCP_conn->temp_secret_key, CRYPTO_SECRET_KEY_SIZE); + memcpy(tcp_conn->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + encrypt_precompute(plain, tcp_conn->temp_secret_key, tcp_conn->shared_key); + crypto_memzero(tcp_conn->temp_secret_key, CRYPTO_SECRET_KEY_SIZE); return 0; } @@ -504,15 +506,13 @@ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key) return write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); } -void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, - const uint8_t *public_key), void *object) +void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object) { con->response_callback = response_callback; con->response_callback_object = object; } -void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number, - uint8_t connection_id, uint8_t status), void *object) +void routing_status_handler(TCP_Client_Connection *con, tcp_routing_status_cb *status_callback, void *object) { con->status_callback = status_callback; con->status_callback_object = object; @@ -584,15 +584,13 @@ int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32 return 0; } -void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, - uint8_t connection_id, const uint8_t *data, uint16_t length, void *userdata), void *object) +void routing_data_handler(TCP_Client_Connection *con, tcp_routing_data_cb *data_callback, void *object) { con->data_callback = data_callback; con->data_callback_object = object; } -void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, const uint8_t *public_key, - const uint8_t *data, uint16_t length, void *userdata), void *object) +void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object) { con->oob_data_callback = oob_data_callback; con->oob_data_callback_object = object; @@ -623,9 +621,9 @@ static int tcp_send_ping_request(TCP_Client_Connection *con) uint8_t packet[1 + sizeof(uint64_t)]; packet[0] = TCP_PACKET_PING; memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t)); - int ret; + const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); - if ((ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1)) == 1) { + if (ret == 1) { con->ping_request_id = 0; } @@ -645,9 +643,9 @@ static int tcp_send_ping_response(TCP_Client_Connection *con) uint8_t packet[1 + sizeof(uint64_t)]; packet[0] = TCP_PACKET_PONG; memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t)); - int ret; + const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); - if ((ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1)) == 1) { + if (ret == 1) { con->ping_response_id = 0; } @@ -681,8 +679,7 @@ int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0); } -void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, - uint16_t length, void *userdata), void *object) +void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object) { con->onion_callback = onion_callback; con->onion_callback_object = object; @@ -928,15 +925,35 @@ static int handle_TCP_client_packet(TCP_Client_Connection *conn, const uint8_t * return 0; } +static bool tcp_process_packet(TCP_Client_Connection *conn, void *userdata) +{ + uint8_t packet[MAX_PACKET_SIZE]; + const int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, + conn->recv_nonce, packet, sizeof(packet)); + + if (len == 0) { + return false; + } + + if (len == -1) { + conn->status = TCP_CLIENT_DISCONNECTED; + return false; + } + + if (handle_TCP_client_packet(conn, packet, len, userdata) == -1) { + conn->status = TCP_CLIENT_DISCONNECTED; + return false; + } + + return true; +} + static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) { client_send_pending_data(conn); tcp_send_ping_response(conn); tcp_send_ping_request(conn); - uint8_t packet[MAX_PACKET_SIZE]; - int len; - if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) { uint64_t ping_id = random_u64(); @@ -944,7 +961,8 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) ++ping_id; } - conn->ping_request_id = conn->ping_id = ping_id; + conn->ping_request_id = ping_id; + conn->ping_id = ping_id; tcp_send_ping_request(conn); conn->last_pinged = unix_time(); } @@ -954,17 +972,9 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) return 0; } - while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, - conn->recv_nonce, packet, sizeof(packet)))) { - if (len == -1) { - conn->status = TCP_CLIENT_DISCONNECTED; - break; - } - - if (handle_TCP_client_packet(conn, packet, len, userdata) == -1) { - conn->status = TCP_CLIENT_DISCONNECTED; - break; - } + while (tcp_process_packet(conn, userdata)) { + // Keep reading until error or out of data. + continue; } return 0; @@ -972,102 +982,102 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) /* Run the TCP connection */ -void do_TCP_connection(TCP_Client_Connection *TCP_connection, void *userdata) +void do_TCP_connection(TCP_Client_Connection *tcp_connection, void *userdata) { unix_time_update(); - if (TCP_connection->status == TCP_CLIENT_DISCONNECTED) { + if (tcp_connection->status == TCP_CLIENT_DISCONNECTED) { return; } - if (TCP_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) { - if (client_send_pending_data(TCP_connection) == 0) { - int ret = proxy_http_read_connection_response(TCP_connection); + if (tcp_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) { + if (client_send_pending_data(tcp_connection) == 0) { + int ret = proxy_http_read_connection_response(tcp_connection); if (ret == -1) { - TCP_connection->kill_at = 0; - TCP_connection->status = TCP_CLIENT_DISCONNECTED; + tcp_connection->kill_at = 0; + tcp_connection->status = TCP_CLIENT_DISCONNECTED; } if (ret == 1) { - generate_handshake(TCP_connection); - TCP_connection->status = TCP_CLIENT_CONNECTING; + generate_handshake(tcp_connection); + tcp_connection->status = TCP_CLIENT_CONNECTING; } } } - if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) { - if (client_send_pending_data(TCP_connection) == 0) { - int ret = socks5_read_handshake_response(TCP_connection); + if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) { + if (client_send_pending_data(tcp_connection) == 0) { + int ret = socks5_read_handshake_response(tcp_connection); if (ret == -1) { - TCP_connection->kill_at = 0; - TCP_connection->status = TCP_CLIENT_DISCONNECTED; + tcp_connection->kill_at = 0; + tcp_connection->status = TCP_CLIENT_DISCONNECTED; } if (ret == 1) { - proxy_socks5_generate_connection_request(TCP_connection); - TCP_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED; + proxy_socks5_generate_connection_request(tcp_connection); + tcp_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED; } } } - if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) { - if (client_send_pending_data(TCP_connection) == 0) { - int ret = proxy_socks5_read_connection_response(TCP_connection); + if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) { + if (client_send_pending_data(tcp_connection) == 0) { + int ret = proxy_socks5_read_connection_response(tcp_connection); if (ret == -1) { - TCP_connection->kill_at = 0; - TCP_connection->status = TCP_CLIENT_DISCONNECTED; + tcp_connection->kill_at = 0; + tcp_connection->status = TCP_CLIENT_DISCONNECTED; } if (ret == 1) { - generate_handshake(TCP_connection); - TCP_connection->status = TCP_CLIENT_CONNECTING; + generate_handshake(tcp_connection); + tcp_connection->status = TCP_CLIENT_CONNECTING; } } } - if (TCP_connection->status == TCP_CLIENT_CONNECTING) { - if (client_send_pending_data(TCP_connection) == 0) { - TCP_connection->status = TCP_CLIENT_UNCONFIRMED; + if (tcp_connection->status == TCP_CLIENT_CONNECTING) { + if (client_send_pending_data(tcp_connection) == 0) { + tcp_connection->status = TCP_CLIENT_UNCONFIRMED; } } - if (TCP_connection->status == TCP_CLIENT_UNCONFIRMED) { + if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) { uint8_t data[TCP_SERVER_HANDSHAKE_SIZE]; - int len = read_TCP_packet(TCP_connection->sock, data, sizeof(data)); + int len = read_TCP_packet(tcp_connection->sock, data, sizeof(data)); if (sizeof(data) == len) { - if (handle_handshake(TCP_connection, data) == 0) { - TCP_connection->kill_at = ~0; - TCP_connection->status = TCP_CLIENT_CONFIRMED; + if (handle_handshake(tcp_connection, data) == 0) { + tcp_connection->kill_at = ~0; + tcp_connection->status = TCP_CLIENT_CONFIRMED; } else { - TCP_connection->kill_at = 0; - TCP_connection->status = TCP_CLIENT_DISCONNECTED; + tcp_connection->kill_at = 0; + tcp_connection->status = TCP_CLIENT_DISCONNECTED; } } } - if (TCP_connection->status == TCP_CLIENT_CONFIRMED) { - do_confirmed_TCP(TCP_connection, userdata); + if (tcp_connection->status == TCP_CLIENT_CONFIRMED) { + do_confirmed_TCP(tcp_connection, userdata); } - if (TCP_connection->kill_at <= unix_time()) { - TCP_connection->status = TCP_CLIENT_DISCONNECTED; + if (tcp_connection->kill_at <= unix_time()) { + tcp_connection->status = TCP_CLIENT_DISCONNECTED; } } /* Kill the TCP connection */ -void kill_TCP_connection(TCP_Client_Connection *TCP_connection) +void kill_TCP_connection(TCP_Client_Connection *tcp_connection) { - if (TCP_connection == nullptr) { + if (tcp_connection == nullptr) { return; } - wipe_priority_list(TCP_connection); - kill_sock(TCP_connection->sock); - crypto_memzero(TCP_connection, sizeof(TCP_Client_Connection)); - free(TCP_connection); + wipe_priority_list(tcp_connection); + kill_sock(tcp_connection->sock); + crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection)); + free(tcp_connection); } diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index 96e04d67911..8bfe4155639 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h @@ -29,18 +29,18 @@ #define TCP_CONNECTION_TIMEOUT 10 -typedef enum { +typedef enum TCP_Proxy_Type { TCP_PROXY_NONE, TCP_PROXY_HTTP, TCP_PROXY_SOCKS5 -} TCP_PROXY_TYPE; +} TCP_Proxy_Type; -typedef struct { +typedef struct TCP_Proxy_Info { IP_Port ip_port; uint8_t proxy_type; // a value from TCP_PROXY_TYPE } TCP_Proxy_Info; -typedef enum { +typedef enum TCP_Client_Status { TCP_CLIENT_NO_STATUS, TCP_CLIENT_PROXY_HTTP_CONNECTING, TCP_CLIENT_PROXY_SOCKS5_CONNECTING, @@ -49,12 +49,13 @@ typedef enum { TCP_CLIENT_UNCONFIRMED, TCP_CLIENT_CONFIRMED, TCP_CLIENT_DISCONNECTED, -} TCP_CLIENT_STATUS; +} TCP_Client_Status; + typedef struct TCP_Client_Connection TCP_Client_Connection; const uint8_t *tcp_con_public_key(const TCP_Client_Connection *con); IP_Port tcp_con_ip_port(const TCP_Client_Connection *con); -TCP_CLIENT_STATUS tcp_con_status(const TCP_Client_Connection *con); +TCP_Client_Status tcp_con_status(const TCP_Client_Connection *con); void *tcp_con_custom_object(const TCP_Client_Connection *con); uint32_t tcp_con_custom_uint(const TCP_Client_Connection *con); @@ -68,29 +69,31 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public /* Run the TCP connection */ -void do_TCP_connection(TCP_Client_Connection *TCP_connection, void *userdata); +void do_TCP_connection(TCP_Client_Connection *tcp_connection, void *userdata); /* Kill the TCP connection */ -void kill_TCP_connection(TCP_Client_Connection *TCP_connection); +void kill_TCP_connection(TCP_Client_Connection *tcp_connection); + +typedef int tcp_onion_response_cb(void *object, const uint8_t *data, uint16_t length, void *userdata); /* return 1 on success. * 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); -void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, - uint16_t length, void *userdata), void *object); +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); +typedef int tcp_routing_status_cb(void *object, uint32_t number, uint8_t connection_id, uint8_t status); /* return 1 on success. * return 0 if could not send packet. * return -1 on failure (connection must be killed). */ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key); -void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, - const uint8_t *public_key), void *object); -void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number, - uint8_t connection_id, uint8_t status), void *object); +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. @@ -107,21 +110,25 @@ int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id); */ int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32_t number); +typedef int tcp_routing_data_cb(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, + uint16_t length, void *userdata); + /* return 1 on success. * 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); -void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, - uint8_t connection_id, const uint8_t *data, uint16_t length, void *userdata), void *object); +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, + void *userdata); /* return 1 on success. * 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); -void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, const uint8_t *public_key, - const uint8_t *data, uint16_t length, void *userdata), void *object); +void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object); #endif diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c index cd1fb5658d5..2d2dd470282 100644 --- a/toxcore/TCP_connection.c +++ b/toxcore/TCP_connection.c @@ -47,14 +47,13 @@ struct TCP_Connections { TCP_con *tcp_connections; uint32_t tcp_connections_length; /* Length of tcp_connections array. */ - int (*tcp_data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); + tcp_data_cb *tcp_data_callback; void *tcp_data_callback_object; - int (*tcp_oob_callback)(void *object, const uint8_t *public_key, unsigned int tcp_connections_number, - const uint8_t *data, uint16_t length, void *userdata); + tcp_oob_cb *tcp_oob_callback; void *tcp_oob_callback_object; - int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length, void *userdata); + tcp_onion_cb *tcp_onion_callback; void *tcp_onion_callback_object; TCP_Proxy_Info proxy_info; @@ -75,28 +74,44 @@ const uint8_t *tcp_connections_public_key(const TCP_Connections *tcp_c) * return -1 if realloc fails. * return 0 if it succeeds. */ -#define MAKE_REALLOC(T) \ -static int realloc_##T(T **array, size_t num) \ -{ \ - if (!num) { \ - free(*array); \ - *array = nullptr; \ - return 0; \ - } \ - \ - T *temp_pointer = (T *)realloc(*array, num * sizeof(T)); \ - \ - if (!temp_pointer) { \ - return -1; \ - } \ - \ - *array = temp_pointer; \ - \ - return 0; \ +static int realloc_TCP_Connection_to(TCP_Connection_to **array, size_t num) +{ + if (!num) { + free(*array); + *array = nullptr; + return 0; + } + + TCP_Connection_to *temp_pointer = + (TCP_Connection_to *)realloc(*array, num * sizeof(TCP_Connection_to)); + + if (!temp_pointer) { + return -1; + } + + *array = temp_pointer; + + return 0; } -MAKE_REALLOC(TCP_Connection_to) -MAKE_REALLOC(TCP_con) +static int realloc_TCP_con(TCP_con **array, size_t num) +{ + if (!num) { + free(*array); + *array = nullptr; + return 0; + } + + TCP_con *temp_pointer = (TCP_con *)realloc(*array, num * sizeof(TCP_con)); + + if (!temp_pointer) { + return -1; + } + + *array = temp_pointer; + + return 0; +} /* return 1 if the connections_number is not valid. @@ -421,8 +436,7 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num /* Set the callback for TCP data packets. */ -void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_callback)(void *object, int id, - const uint8_t *data, uint16_t length, void *userdata), void *object) +void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_data_cb *tcp_data_callback, void *object) { tcp_c->tcp_data_callback = tcp_data_callback; tcp_c->tcp_data_callback_object = object; @@ -430,9 +444,7 @@ void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_c /* Set the callback for TCP onion packets. */ -void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oob_callback)(void *object, - const uint8_t *public_key, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length, void *userdata), - void *object) +void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_oob_cb *tcp_oob_callback, void *object) { tcp_c->tcp_oob_callback = tcp_oob_callback; tcp_c->tcp_oob_callback_object = object; @@ -440,8 +452,7 @@ void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oo /* Set the callback for TCP oob data packets. */ -void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_onion_callback)(void *object, - const uint8_t *data, uint16_t length, void *userdata), void *object) +void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_onion_cb *tcp_onion_callback, void *object) { tcp_c->tcp_onion_callback = tcp_onion_callback; tcp_c->tcp_onion_callback_object = object; @@ -915,10 +926,10 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key) { - TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; - TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); + TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con); - unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); + unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con); TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); if (!tcp_con) { @@ -948,10 +959,10 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status) { - TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; - TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); + TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con); - unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); + unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con); TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); TCP_Connection_to *con_to = get_connection(tcp_c, number); @@ -991,10 +1002,10 @@ static int tcp_conn_data_callback(void *object, uint32_t number, uint8_t connect return -1; } - TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; - TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); + TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con); - unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); + unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con); TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); if (!tcp_con) { @@ -1021,10 +1032,10 @@ static int tcp_conn_oob_callback(void *object, const uint8_t *public_key, const return -1; } - TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; - TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); + TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con); - unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); + unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con); TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); if (!tcp_con) { diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index a45129a7e85..658ee1f46f9 100644 --- a/toxcore/TCP_connection.h +++ b/toxcore/TCP_connection.h @@ -51,20 +51,22 @@ /* Number of TCP connections used for onion purposes. */ #define NUM_ONION_TCP_CONNECTIONS RECOMMENDED_FRIEND_TCP_CONNECTIONS -typedef struct { +typedef struct TCP_Conn_to { + uint32_t tcp_connection; + unsigned int status; + unsigned int connection_id; +} TCP_Conn_to; + +typedef struct TCP_Connection_to { uint8_t status; uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ - struct { - uint32_t tcp_connection; - unsigned int status; - unsigned int connection_id; - } connections[MAX_FRIEND_TCP_CONNECTIONS]; + TCP_Conn_to connections[MAX_FRIEND_TCP_CONNECTIONS]; int id; /* id used in callbacks. */ } TCP_Connection_to; -typedef struct { +typedef struct TCP_con { uint8_t status; TCP_Client_Connection *connection; uint64_t connected_time; @@ -124,21 +126,24 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status); int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *public_key, const uint8_t *packet, uint16_t length); +typedef int tcp_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); + /* Set the callback for TCP data packets. */ -void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_callback)(void *object, int id, - const uint8_t *data, uint16_t length, void *userdata), void *object); +void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_data_cb *tcp_data_callback, void *object); + +typedef int tcp_onion_cb(void *object, const uint8_t *data, uint16_t length, void *userdata); /* Set the callback for TCP onion packets. */ -void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_onion_callback)(void *object, - const uint8_t *data, uint16_t length, void *userdata), void *object); +void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_onion_cb *tcp_onion_callback, void *object); + +typedef int tcp_oob_cb(void *object, const uint8_t *public_key, unsigned int tcp_connections_number, + const uint8_t *data, uint16_t length, void *userdata); /* Set the callback for TCP oob data packets. */ -void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oob_callback)(void *object, - const uint8_t *public_key, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length, void *userdata), - void *object); +void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_oob_cb *tcp_oob_callback, void *object); /* Create a new TCP connection to public_key. * diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index 032b07b3d49..a2b74dfd5ee 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -42,6 +42,20 @@ #include "mono_time.h" #include "util.h" +#ifdef TCP_SERVER_USE_EPOLL +#define TCP_SOCKET_LISTENING 0 +#define TCP_SOCKET_INCOMING 1 +#define TCP_SOCKET_UNCONFIRMED 2 +#define TCP_SOCKET_CONFIRMED 3 +#endif + +typedef struct TCP_Secure_Conn { + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint32_t index; + uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ + uint8_t other_id; +} TCP_Secure_Conn; + typedef struct TCP_Secure_Connection { Socket sock; uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -49,18 +63,14 @@ typedef struct TCP_Secure_Connection { uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint16_t next_packet_length; - struct { - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint32_t index; - uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ - uint8_t other_id; - } connections[NUM_CLIENT_CONNECTIONS]; + TCP_Secure_Conn connections[NUM_CLIENT_CONNECTIONS]; uint8_t last_packet[2 + MAX_PACKET_SIZE]; uint8_t status; uint16_t last_packet_length; uint16_t last_packet_sent; - TCP_Priority_List *priority_queue_start, *priority_queue_end; + TCP_Priority_List *priority_queue_start; + TCP_Priority_List *priority_queue_end; uint64_t identifier; @@ -118,74 +128,74 @@ size_t tcp_server_listen_count(const TCP_Server *tcp_server) * return -1 if realloc fails. * return 0 if it succeeds. */ -static int realloc_connection(TCP_Server *TCP_server, uint32_t num) +static int realloc_connection(TCP_Server *tcp_server, uint32_t num) { if (num == 0) { - free(TCP_server->accepted_connection_array); - TCP_server->accepted_connection_array = nullptr; - TCP_server->size_accepted_connections = 0; + free(tcp_server->accepted_connection_array); + tcp_server->accepted_connection_array = nullptr; + tcp_server->size_accepted_connections = 0; return 0; } - if (num == TCP_server->size_accepted_connections) { + if (num == tcp_server->size_accepted_connections) { return 0; } TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc( - TCP_server->accepted_connection_array, + tcp_server->accepted_connection_array, num * sizeof(TCP_Secure_Connection)); if (new_connections == nullptr) { return -1; } - if (num > TCP_server->size_accepted_connections) { - uint32_t old_size = TCP_server->size_accepted_connections; + if (num > tcp_server->size_accepted_connections) { + uint32_t old_size = tcp_server->size_accepted_connections; uint32_t size_new_entries = (num - old_size) * sizeof(TCP_Secure_Connection); memset(new_connections + old_size, 0, size_new_entries); } - TCP_server->accepted_connection_array = new_connections; - TCP_server->size_accepted_connections = num; + tcp_server->accepted_connection_array = new_connections; + tcp_server->size_accepted_connections = num; return 0; } /* return index corresponding to connection with peer on success * return -1 on failure. */ -static int get_TCP_connection_index(const TCP_Server *TCP_server, const uint8_t *public_key) +static int get_TCP_connection_index(const TCP_Server *tcp_server, const uint8_t *public_key) { - return bs_list_find(&TCP_server->accepted_key_list, public_key); + return bs_list_find(&tcp_server->accepted_key_list, public_key); } -static int kill_accepted(TCP_Server *TCP_server, int index); +static int kill_accepted(TCP_Server *tcp_server, int index); /* Add accepted TCP connection to the list. * * return index on success * return -1 on failure */ -static int add_accepted(TCP_Server *TCP_server, const TCP_Secure_Connection *con) +static int add_accepted(TCP_Server *tcp_server, const TCP_Secure_Connection *con) { - int index = get_TCP_connection_index(TCP_server, con->public_key); + int index = get_TCP_connection_index(tcp_server, con->public_key); if (index != -1) { /* If an old connection to the same public key exists, kill it. */ - kill_accepted(TCP_server, index); + kill_accepted(tcp_server, index); index = -1; } - if (TCP_server->size_accepted_connections == TCP_server->num_accepted_connections) { - if (realloc_connection(TCP_server, TCP_server->size_accepted_connections + 4) == -1) { + if (tcp_server->size_accepted_connections == tcp_server->num_accepted_connections) { + if (realloc_connection(tcp_server, tcp_server->size_accepted_connections + 4) == -1) { return -1; } - index = TCP_server->num_accepted_connections; + index = tcp_server->num_accepted_connections; } else { uint32_t i; - for (i = TCP_server->size_accepted_connections; i != 0; --i) { - if (TCP_server->accepted_connection_array[i - 1].status == TCP_STATUS_NO_STATUS) { + for (i = tcp_server->size_accepted_connections; i != 0; --i) { + if (tcp_server->accepted_connection_array[i - 1].status == TCP_STATUS_NO_STATUS) { index = i - 1; break; } @@ -197,16 +207,16 @@ static int add_accepted(TCP_Server *TCP_server, const TCP_Secure_Connection *con return -1; } - if (!bs_list_add(&TCP_server->accepted_key_list, con->public_key, index)) { + if (!bs_list_add(&tcp_server->accepted_key_list, con->public_key, index)) { return -1; } - memcpy(&TCP_server->accepted_connection_array[index], con, sizeof(TCP_Secure_Connection)); - TCP_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED; - ++TCP_server->num_accepted_connections; - TCP_server->accepted_connection_array[index].identifier = ++TCP_server->counter; - TCP_server->accepted_connection_array[index].last_pinged = unix_time(); - TCP_server->accepted_connection_array[index].ping_id = 0; + memcpy(&tcp_server->accepted_connection_array[index], con, sizeof(TCP_Secure_Connection)); + tcp_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED; + ++tcp_server->num_accepted_connections; + tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter; + tcp_server->accepted_connection_array[index].last_pinged = unix_time(); + tcp_server->accepted_connection_array[index].ping_id = 0; return index; } @@ -216,25 +226,25 @@ static int add_accepted(TCP_Server *TCP_server, const TCP_Secure_Connection *con * return 0 on success * return -1 on failure */ -static int del_accepted(TCP_Server *TCP_server, int index) +static int del_accepted(TCP_Server *tcp_server, int index) { - if ((uint32_t)index >= TCP_server->size_accepted_connections) { + if ((uint32_t)index >= tcp_server->size_accepted_connections) { return -1; } - if (TCP_server->accepted_connection_array[index].status == TCP_STATUS_NO_STATUS) { + if (tcp_server->accepted_connection_array[index].status == TCP_STATUS_NO_STATUS) { return -1; } - if (!bs_list_remove(&TCP_server->accepted_key_list, TCP_server->accepted_connection_array[index].public_key, index)) { + if (!bs_list_remove(&tcp_server->accepted_key_list, tcp_server->accepted_connection_array[index].public_key, index)) { return -1; } - crypto_memzero(&TCP_server->accepted_connection_array[index], sizeof(TCP_Secure_Connection)); - --TCP_server->num_accepted_connections; + crypto_memzero(&tcp_server->accepted_connection_array[index], sizeof(TCP_Secure_Connection)); + --tcp_server->num_accepted_connections; - if (TCP_server->num_accepted_connections == 0) { - realloc_connection(TCP_server, 0); + if (tcp_server->num_accepted_connections == 0) { + realloc_connection(tcp_server, 0); } return 0; @@ -505,28 +515,28 @@ static void kill_TCP_secure_connection(TCP_Secure_Connection *con) crypto_memzero(con, sizeof(TCP_Secure_Connection)); } -static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t con_number); +static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number); /* Kill an accepted TCP_Secure_Connection * * return -1 on failure. * return 0 on success. */ -static int kill_accepted(TCP_Server *TCP_server, int index) +static int kill_accepted(TCP_Server *tcp_server, int index) { - if ((uint32_t)index >= TCP_server->size_accepted_connections) { + if ((uint32_t)index >= tcp_server->size_accepted_connections) { return -1; } uint32_t i; for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { - rm_connection_index(TCP_server, &TCP_server->accepted_connection_array[index], i); + rm_connection_index(tcp_server, &tcp_server->accepted_connection_array[index], i); } - Socket sock = TCP_server->accepted_connection_array[index].sock; + Socket sock = tcp_server->accepted_connection_array[index].sock; - if (del_accepted(TCP_server, index) != 0) { + if (del_accepted(tcp_server, index) != 0) { return -1; } @@ -592,9 +602,9 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, const uint8_t *data, static int read_connection_handshake(TCP_Secure_Connection *con, const uint8_t *self_secret_key) { uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE]; - int len = 0; + const int len = read_TCP_packet(con->sock, data, TCP_CLIENT_HANDSHAKE_SIZE); - if ((len = read_TCP_packet(con->sock, data, TCP_CLIENT_HANDSHAKE_SIZE)) != -1) { + if (len != -1) { return handle_TCP_handshake(con, data, len, self_secret_key); } @@ -638,11 +648,11 @@ static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id) /* return 0 on success. * return -1 on failure (connection must be killed). */ -static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *public_key) +static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key) { uint32_t i; uint32_t index = ~0; - TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; + TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id]; /* If person tries to cennect to himself we deny the request*/ if (public_key_cmp(con->public_key, public_key) == 0) { @@ -687,11 +697,11 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const con->connections[index].status = 1; memcpy(con->connections[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); - int other_index = get_TCP_connection_index(TCP_server, public_key); + int other_index = get_TCP_connection_index(tcp_server, public_key); if (other_index != -1) { uint32_t other_id = ~0; - TCP_Secure_Connection *other_conn = &TCP_server->accepted_connection_array[other_index]; + TCP_Secure_Connection *other_conn = &tcp_server->accepted_connection_array[other_index]; for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { if (other_conn->connections[i].status == 1 @@ -720,23 +730,23 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const /* return 0 on success. * return -1 on failure (connection must be killed). */ -static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data, +static int handle_TCP_oob_send(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data, uint16_t length) { if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) { return -1; } - TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; + TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id]; - int other_index = get_TCP_connection_index(TCP_server, public_key); + int other_index = get_TCP_connection_index(tcp_server, public_key); if (other_index != -1) { VLA(uint8_t, resp_packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length); resp_packet[0] = TCP_PACKET_OOB_RECV; memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length); - write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[other_index], resp_packet, + write_packet_TCP_secure_connection(&tcp_server->accepted_connection_array[other_index], resp_packet, SIZEOF_VLA(resp_packet), 0); } @@ -748,7 +758,7 @@ static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const ui * return -1 on failure. * return 0 on success. */ -static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t con_number) +static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number) { if (con_number >= NUM_CLIENT_CONNECTIONS) { return -1; @@ -760,15 +770,15 @@ static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *co if (con->connections[con_number].status == 2) { - if (index >= TCP_server->size_accepted_connections) { + if (index >= tcp_server->size_accepted_connections) { return -1; } - TCP_server->accepted_connection_array[index].connections[other_id].other_id = 0; - TCP_server->accepted_connection_array[index].connections[other_id].index = 0; - TCP_server->accepted_connection_array[index].connections[other_id].status = 1; + tcp_server->accepted_connection_array[index].connections[other_id].other_id = 0; + tcp_server->accepted_connection_array[index].connections[other_id].index = 0; + tcp_server->accepted_connection_array[index].connections[other_id].status = 1; // TODO(irungentoo): return values? - send_disconnect_notification(&TCP_server->accepted_connection_array[index], other_id); + send_disconnect_notification(&tcp_server->accepted_connection_array[index], other_id); } con->connections[con_number].index = 0; @@ -782,14 +792,14 @@ static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *co static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data, uint16_t length) { - TCP_Server *TCP_server = (TCP_Server *)object; + TCP_Server *tcp_server = (TCP_Server *)object; uint32_t index = dest.ip.ip.v6.uint32[0]; - if (index >= TCP_server->size_accepted_connections) { + if (index >= tcp_server->size_accepted_connections) { return 1; } - TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[index]; + TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[index]; if (con->identifier != dest.ip.ip.v6.uint64[1]) { return 1; @@ -809,13 +819,13 @@ static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data, /* return 0 on success * return -1 on failure */ -static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *data, uint16_t length) +static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *data, uint16_t length) { if (length == 0) { return -1; } - TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; + TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id]; switch (data[0]) { case TCP_PACKET_ROUTING_REQUEST: { @@ -823,7 +833,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint return -1; } - return handle_TCP_routing_req(TCP_server, con_id, data + 1); + return handle_TCP_routing_req(tcp_server, con_id, data + 1); } case TCP_PACKET_CONNECTION_NOTIFICATION: { @@ -839,7 +849,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint return -1; } - return rm_connection_index(TCP_server, con, data[1] - NUM_RESERVED_PORTS); + return rm_connection_index(tcp_server, con, data[1] - NUM_RESERVED_PORTS); } case TCP_PACKET_PING: { @@ -878,12 +888,12 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint return -1; } - return handle_TCP_oob_send(TCP_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE, + return handle_TCP_oob_send(tcp_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_PUBLIC_KEY_SIZE)); } case TCP_PACKET_ONION_REQUEST: { - if (TCP_server->onion) { + if (tcp_server->onion) { if (length <= 1 + CRYPTO_NONCE_SIZE + ONION_SEND_BASE * 2) { return -1; } @@ -894,7 +904,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint source.ip.ip.v6.uint32[0] = con_id; source.ip.ip.v6.uint32[1] = 0; source.ip.ip.v6.uint64[1] = con->identifier; - onion_send_1(TCP_server->onion, data + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), source, + onion_send_1(tcp_server->onion, data + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), source, data + 1); } @@ -929,7 +939,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint VLA(uint8_t, new_data, length); memcpy(new_data, data, length); new_data[0] = other_c_id; - int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length, 0); + int ret = write_packet_TCP_secure_connection(&tcp_server->accepted_connection_array[index], new_data, length, 0); if (ret == -1) { return -1; @@ -943,10 +953,10 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint } -static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection *con, const uint8_t *data, +static int confirm_TCP_connection(TCP_Server *tcp_server, TCP_Secure_Connection *con, const uint8_t *data, uint16_t length) { - int index = add_accepted(TCP_server, con); + int index = add_accepted(tcp_server, con); if (index == -1) { kill_TCP_secure_connection(con); @@ -955,8 +965,8 @@ static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection crypto_memzero(con, sizeof(TCP_Secure_Connection)); - if (handle_TCP_packet(TCP_server, index, data, length) == -1) { - kill_accepted(TCP_server, index); + if (handle_TCP_packet(tcp_server, index, data, length) == -1) { + kill_accepted(tcp_server, index); return -1; } @@ -966,7 +976,7 @@ static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection /* return index on success * return -1 on failure */ -static int accept_connection(TCP_Server *TCP_server, Socket sock) +static int accept_connection(TCP_Server *tcp_server, Socket sock) { if (!sock_valid(sock)) { return -1; @@ -982,9 +992,9 @@ static int accept_connection(TCP_Server *TCP_server, Socket sock) return -1; } - uint16_t index = TCP_server->incoming_connection_queue_index % MAX_INCOMING_CONNECTIONS; + uint16_t index = tcp_server->incoming_connection_queue_index % MAX_INCOMING_CONNECTIONS; - TCP_Secure_Connection *conn = &TCP_server->incoming_connection_queue[index]; + TCP_Secure_Connection *conn = &tcp_server->incoming_connection_queue[index]; if (conn->status != TCP_STATUS_NO_STATUS) { kill_TCP_secure_connection(conn); @@ -994,7 +1004,7 @@ static int accept_connection(TCP_Server *TCP_server, Socket sock) conn->sock = sock; conn->next_packet_length = 0; - ++TCP_server->incoming_connection_queue_index; + ++tcp_server->incoming_connection_queue_index; return index; } @@ -1107,34 +1117,34 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin } #ifndef TCP_SERVER_USE_EPOLL -static void do_TCP_accept_new(TCP_Server *TCP_server) +static void do_TCP_accept_new(TCP_Server *tcp_server) { uint32_t i; - for (i = 0; i < TCP_server->num_listening_socks; ++i) { + for (i = 0; i < tcp_server->num_listening_socks; ++i) { Socket sock; do { - sock = net_accept(TCP_server->socks_listening[i]); - } while (accept_connection(TCP_server, sock) != -1); + sock = net_accept(tcp_server->socks_listening[i]); + } while (accept_connection(tcp_server, sock) != -1); } } #endif -static int do_incoming(TCP_Server *TCP_server, uint32_t i) +static int do_incoming(TCP_Server *tcp_server, uint32_t i) { - if (TCP_server->incoming_connection_queue[i].status != TCP_STATUS_CONNECTED) { + if (tcp_server->incoming_connection_queue[i].status != TCP_STATUS_CONNECTED) { return -1; } - int ret = read_connection_handshake(&TCP_server->incoming_connection_queue[i], TCP_server->secret_key); + int ret = read_connection_handshake(&tcp_server->incoming_connection_queue[i], tcp_server->secret_key); if (ret == -1) { - kill_TCP_secure_connection(&TCP_server->incoming_connection_queue[i]); + kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[i]); } else if (ret == 1) { - int index_new = TCP_server->unconfirmed_connection_queue_index % MAX_INCOMING_CONNECTIONS; - TCP_Secure_Connection *conn_old = &TCP_server->incoming_connection_queue[i]; - TCP_Secure_Connection *conn_new = &TCP_server->unconfirmed_connection_queue[index_new]; + int index_new = tcp_server->unconfirmed_connection_queue_index % MAX_INCOMING_CONNECTIONS; + TCP_Secure_Connection *conn_old = &tcp_server->incoming_connection_queue[i]; + TCP_Secure_Connection *conn_new = &tcp_server->unconfirmed_connection_queue[index_new]; if (conn_new->status != TCP_STATUS_NO_STATUS) { kill_TCP_secure_connection(conn_new); @@ -1142,7 +1152,7 @@ static int do_incoming(TCP_Server *TCP_server, uint32_t i) memcpy(conn_new, conn_old, sizeof(TCP_Secure_Connection)); crypto_memzero(conn_old, sizeof(TCP_Secure_Connection)); - ++TCP_server->unconfirmed_connection_queue_index; + ++tcp_server->unconfirmed_connection_queue_index; return index_new; } @@ -1150,9 +1160,9 @@ static int do_incoming(TCP_Server *TCP_server, uint32_t i) return -1; } -static int do_unconfirmed(TCP_Server *TCP_server, uint32_t i) +static int do_unconfirmed(TCP_Server *tcp_server, uint32_t i) { - TCP_Secure_Connection *conn = &TCP_server->unconfirmed_connection_queue[i]; + TCP_Secure_Connection *conn = &tcp_server->unconfirmed_connection_queue[i]; if (conn->status != TCP_STATUS_UNCONFIRMED) { return -1; @@ -1171,64 +1181,76 @@ static int do_unconfirmed(TCP_Server *TCP_server, uint32_t i) return -1; } - return confirm_TCP_connection(TCP_server, conn, packet, len); + return confirm_TCP_connection(tcp_server, conn, packet, len); } -static void do_confirmed_recv(TCP_Server *TCP_server, uint32_t i) +static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i) { - TCP_Secure_Connection *conn = &TCP_server->accepted_connection_array[i]; + TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i]; uint8_t packet[MAX_PACKET_SIZE]; - int len; + int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, + conn->recv_nonce, packet, sizeof(packet)); - while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, - conn->recv_nonce, packet, sizeof(packet)))) { - if (len == -1) { - kill_accepted(TCP_server, i); - break; - } + if (len == 0) { + return false; + } - if (handle_TCP_packet(TCP_server, i, packet, len) == -1) { - kill_accepted(TCP_server, i); - break; - } + if (len == -1) { + kill_accepted(tcp_server, i); + return false; + } + + if (handle_TCP_packet(tcp_server, i, packet, len) == -1) { + kill_accepted(tcp_server, i); + return false; + } + + return true; +} + +static void do_confirmed_recv(TCP_Server *tcp_server, uint32_t i) +{ + while (tcp_process_secure_packet(tcp_server, i)) { + // Keep reading until an error occurs or there is no more data to read. + continue; } } #ifndef TCP_SERVER_USE_EPOLL -static void do_TCP_incoming(TCP_Server *TCP_server) +static void do_TCP_incoming(TCP_Server *tcp_server) { uint32_t i; for (i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) { - do_incoming(TCP_server, i); + do_incoming(tcp_server, i); } } -static void do_TCP_unconfirmed(TCP_Server *TCP_server) +static void do_TCP_unconfirmed(TCP_Server *tcp_server) { uint32_t i; for (i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) { - do_unconfirmed(TCP_server, i); + do_unconfirmed(tcp_server, i); } } #endif -static void do_TCP_confirmed(TCP_Server *TCP_server) +static void do_TCP_confirmed(TCP_Server *tcp_server) { #ifdef TCP_SERVER_USE_EPOLL - if (TCP_server->last_run_pinged == unix_time()) { + if (tcp_server->last_run_pinged == unix_time()) { return; } - TCP_server->last_run_pinged = unix_time(); + tcp_server->last_run_pinged = unix_time(); #endif uint32_t i; - for (i = 0; i < TCP_server->size_accepted_connections; ++i) { - TCP_Secure_Connection *conn = &TCP_server->accepted_connection_array[i]; + for (i = 0; i < tcp_server->size_accepted_connections; ++i) { + TCP_Secure_Connection *conn = &tcp_server->accepted_connection_array[i]; if (conn->status != TCP_STATUS_CONFIRMED) { continue; @@ -1251,14 +1273,14 @@ static void do_TCP_confirmed(TCP_Server *TCP_server) conn->ping_id = ping_id; } else { if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) { - kill_accepted(TCP_server, i); + kill_accepted(tcp_server, i); continue; } } } if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) { - kill_accepted(TCP_server, i); + kill_accepted(tcp_server, i); continue; } @@ -1266,168 +1288,174 @@ static void do_TCP_confirmed(TCP_Server *TCP_server) #ifndef TCP_SERVER_USE_EPOLL - do_confirmed_recv(TCP_server, i); + do_confirmed_recv(tcp_server, i); #endif } } #ifdef TCP_SERVER_USE_EPOLL -static void do_TCP_epoll(TCP_Server *TCP_server) +static bool tcp_epoll_process(TCP_Server *tcp_server) { #define MAX_EVENTS 16 struct epoll_event events[MAX_EVENTS]; - int nfds; - - while ((nfds = epoll_wait(TCP_server->efd, events, MAX_EVENTS, 0)) > 0) { - int n; + const int nfds = epoll_wait(tcp_server->efd, events, MAX_EVENTS, 0); +#undef MAX_EVENTS - for (n = 0; n < nfds; ++n) { - const Socket sock = {(int)(events[n].data.u64 & 0xFFFFFFFF)}; - const int status = (events[n].data.u64 >> 32) & 0xFF; - const int index = events[n].data.u64 >> 40; + for (int n = 0; n < nfds; ++n) { + const Socket sock = {(int)(events[n].data.u64 & 0xFFFFFFFF)}; + const int status = (events[n].data.u64 >> 32) & 0xFF; + const int index = events[n].data.u64 >> 40; - if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP) || (events[n].events & EPOLLRDHUP)) { - switch (status) { - case TCP_SOCKET_LISTENING: { - //should never happen - break; - } - - case TCP_SOCKET_INCOMING: { - kill_TCP_secure_connection(&TCP_server->incoming_connection_queue[index]); - break; - } + if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP) || (events[n].events & EPOLLRDHUP)) { + switch (status) { + case TCP_SOCKET_LISTENING: { + // should never happen + break; + } - case TCP_SOCKET_UNCONFIRMED: { - kill_TCP_secure_connection(&TCP_server->unconfirmed_connection_queue[index]); - break; - } + case TCP_SOCKET_INCOMING: { + kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index]); + break; + } - case TCP_SOCKET_CONFIRMED: { - kill_accepted(TCP_server, index); - break; - } + case TCP_SOCKET_UNCONFIRMED: { + kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index]); + break; } - continue; + case TCP_SOCKET_CONFIRMED: { + kill_accepted(tcp_server, index); + break; + } } + continue; + } - if (!(events[n].events & EPOLLIN)) { - continue; - } - switch (status) { - case TCP_SOCKET_LISTENING: { - //socket is from socks_listening, accept connection - while (1) { - Socket sock_new = net_accept(sock); - - if (!sock_valid(sock_new)) { - break; - } + if (!(events[n].events & EPOLLIN)) { + continue; + } - int index_new = accept_connection(TCP_server, sock_new); + switch (status) { + case TCP_SOCKET_LISTENING: { + // socket is from socks_listening, accept connection + while (1) { + Socket sock_new = net_accept(sock); - if (index_new == -1) { - continue; - } + if (!sock_valid(sock_new)) { + break; + } - struct epoll_event ev = { - .events = EPOLLIN | EPOLLET | EPOLLRDHUP, - .data.u64 = sock_new.socket | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40) - }; + int index_new = accept_connection(tcp_server, sock_new); - if (epoll_ctl(TCP_server->efd, EPOLL_CTL_ADD, sock_new.socket, &ev) == -1) { - kill_TCP_secure_connection(&TCP_server->incoming_connection_queue[index_new]); - continue; - } + if (index_new == -1) { + continue; } - break; - } + struct epoll_event ev; - case TCP_SOCKET_INCOMING: { - int index_new; + ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP; - if ((index_new = do_incoming(TCP_server, index)) != -1) { - events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; - events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40); + ev.data.u64 = sock_new.socket | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40); - if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) { - kill_TCP_secure_connection(&TCP_server->unconfirmed_connection_queue[index_new]); - break; - } + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, sock_new.socket, &ev) == -1) { + kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index_new]); + continue; } - - break; } - case TCP_SOCKET_UNCONFIRMED: { - int index_new; + break; + } - if ((index_new = do_unconfirmed(TCP_server, index)) != -1) { - events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; - events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40); + case TCP_SOCKET_INCOMING: { + const int index_new = do_incoming(tcp_server, index); - if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) { - //remove from confirmed connections - kill_accepted(TCP_server, index_new); - break; - } - } + if (index_new != -1) { + events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; + events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40); - break; + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) { + kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]); + break; + } } - case TCP_SOCKET_CONFIRMED: { - do_confirmed_recv(TCP_server, index); - break; + break; + } + + case TCP_SOCKET_UNCONFIRMED: { + const int index_new = do_unconfirmed(tcp_server, index); + + if (index_new != -1) { + events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; + events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40); + + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) { + // remove from confirmed connections + kill_accepted(tcp_server, index_new); + break; + } } + + break; + } + + case TCP_SOCKET_CONFIRMED: { + do_confirmed_recv(tcp_server, index); + break; } } } -#undef MAX_EVENTS + return nfds > 0; +} + +static void do_TCP_epoll(TCP_Server *tcp_server) +{ + while (tcp_epoll_process(tcp_server)) { + // Keep processing packets until there are no more FDs ready for reading. + continue; + } } #endif -void do_TCP_server(TCP_Server *TCP_server) +void do_TCP_server(TCP_Server *tcp_server) { unix_time_update(); #ifdef TCP_SERVER_USE_EPOLL - do_TCP_epoll(TCP_server); + do_TCP_epoll(tcp_server); #else - do_TCP_accept_new(TCP_server); - do_TCP_incoming(TCP_server); - do_TCP_unconfirmed(TCP_server); + do_TCP_accept_new(tcp_server); + do_TCP_incoming(tcp_server); + do_TCP_unconfirmed(tcp_server); #endif - do_TCP_confirmed(TCP_server); + do_TCP_confirmed(tcp_server); } -void kill_TCP_server(TCP_Server *TCP_server) +void kill_TCP_server(TCP_Server *tcp_server) { uint32_t i; - for (i = 0; i < TCP_server->num_listening_socks; ++i) { - kill_sock(TCP_server->socks_listening[i]); + for (i = 0; i < tcp_server->num_listening_socks; ++i) { + kill_sock(tcp_server->socks_listening[i]); } - if (TCP_server->onion) { - set_callback_handle_recv_1(TCP_server->onion, nullptr, nullptr); + if (tcp_server->onion) { + set_callback_handle_recv_1(tcp_server->onion, nullptr, nullptr); } - bs_list_free(&TCP_server->accepted_key_list); + bs_list_free(&tcp_server->accepted_key_list); #ifdef TCP_SERVER_USE_EPOLL - close(TCP_server->efd); + close(tcp_server->efd); #endif - free(TCP_server->socks_listening); - free(TCP_server->accepted_connection_array); - free(TCP_server); + free(tcp_server->socks_listening); + free(tcp_server->accepted_connection_array); + free(tcp_server); } diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h index c8cbeda021a..632a5e79b9a 100644 --- a/toxcore/TCP_server.h +++ b/toxcore/TCP_server.h @@ -28,10 +28,6 @@ #include "list.h" #include "onion.h" -#ifdef TCP_SERVER_USE_EPOLL -#include -#endif - #define MAX_INCOMING_CONNECTIONS 256 #define TCP_MAX_BACKLOG MAX_INCOMING_CONNECTIONS @@ -63,25 +59,19 @@ #define TCP_PING_FREQUENCY 30 #define TCP_PING_TIMEOUT 10 -#ifdef TCP_SERVER_USE_EPOLL -#define TCP_SOCKET_LISTENING 0 -#define TCP_SOCKET_INCOMING 1 -#define TCP_SOCKET_UNCONFIRMED 2 -#define TCP_SOCKET_CONFIRMED 3 -#endif - -enum { +typedef enum TCP_Status { TCP_STATUS_NO_STATUS, TCP_STATUS_CONNECTED, TCP_STATUS_UNCONFIRMED, TCP_STATUS_CONFIRMED, -}; +} TCP_Status; typedef struct TCP_Priority_List TCP_Priority_List; struct TCP_Priority_List { TCP_Priority_List *next; - uint16_t size, sent; + uint16_t size; + uint16_t sent; uint8_t data[]; }; @@ -97,11 +87,11 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin /* Run the TCP_server */ -void do_TCP_server(TCP_Server *TCP_server); +void do_TCP_server(TCP_Server *tcp_server); /* Kill the TCP server */ -void kill_TCP_server(TCP_Server *TCP_server); +void kill_TCP_server(TCP_Server *tcp_server); /* Read the next two bytes in TCP stream then convert them to * length (host byte order). diff --git a/toxcore/network.c b/toxcore/network.c index 24e53c47d7b..c831ba8bf0b 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -1381,7 +1381,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type) } // Used to avoid malloc parameter overflow - const size_t MAX_COUNT = MIN(SIZE_MAX, INT32_MAX) / sizeof(IP_Port); + const size_t MAX_COUNT = min_u64(SIZE_MAX, INT32_MAX) / sizeof(IP_Port); int type = make_socktype(tox_type); struct addrinfo *cur; size_t count = 0; diff --git a/toxcore/util.c b/toxcore/util.c index 5ab092ce060..f349e8fe0ef 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -66,6 +66,11 @@ void host_to_net(uint8_t *num, uint16_t numbytes) #endif } +void net_to_host(uint8_t *num, uint16_t numbytes) +{ + host_to_net(num, numbytes); +} + int create_recursive_mutex(pthread_mutex_t *mutex) { pthread_mutexattr_t attr; @@ -95,6 +100,11 @@ int32_t max_s32(int32_t a, int32_t b) return a > b ? a : b; } +uint32_t min_u32(uint32_t a, uint32_t b) +{ + return a < b ? a : b; +} + uint64_t min_u64(uint64_t a, uint64_t b) { return a < b ? a : b; diff --git a/toxcore/util.h b/toxcore/util.h index 4c5023cf43a..76951fff314 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -36,20 +36,18 @@ extern "C" { #endif -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; } - /* id functions */ bool id_equal(const uint8_t *dest, const uint8_t *src); uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */ void host_to_net(uint8_t *num, uint16_t numbytes); -#define net_to_host(x, y) host_to_net(x, y) +void net_to_host(uint8_t *num, uint16_t numbytes); /* Returns -1 if failed or 0 if success */ int create_recursive_mutex(pthread_mutex_t *mutex); int32_t max_s32(int32_t a, int32_t b); +uint32_t min_u32(uint32_t a, uint32_t b); uint64_t min_u64(uint64_t a, uint64_t b); #ifdef __cplusplus