Skip to content

Commit

Permalink
Implement Tox network profiler
Browse files Browse the repository at this point in the history
  • Loading branch information
JFreegman committed Nov 23, 2023
1 parent d390947 commit 674f784
Show file tree
Hide file tree
Showing 28 changed files with 552 additions and 35 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ jobs:
llvm-dev
ninja-build
pkg-config
llvm-dev
- checkout
- run: git submodule update --init --recursive
- run: CC=clang .circleci/cmake-asan
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ testing/data

# Vim
*.swp
*.nvimlog

# Object files
*.o
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ set(toxcore_SOURCES
toxcore/mem.h
toxcore/mono_time.c
toxcore/mono_time.h
toxcore/net_profile.c
toxcore/net_profile.h
toxcore/net_crypto.c
toxcore/net_crypto.h
toxcore/network.c
Expand Down
22 changes: 11 additions & 11 deletions auto_tests/TCP_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ static IP get_loopback(void)
return ip;
}

static void do_tcp_server_delay(TCP_Server *tcp_s, Mono_Time *mono_time, int delay)
static void do_TCP_server_delay(TCP_Server *tcp_s, Mono_Time *mono_time, int delay)
{
c_sleep(delay);
mono_time_update(mono_time);
do_tcp_server(tcp_s, mono_time);
do_TCP_server(tcp_s, mono_time);
c_sleep(delay);
}
static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643};
Expand Down Expand Up @@ -111,12 +111,12 @@ static void test_basic(void)

// Sending the handshake
ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost, nullptr) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
"An attempt to send the initial handshake minus last byte failed.");

do_tcp_server_delay(tcp_s, mono_time, 50);

ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1,
ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost, nullptr) == 1,
"The attempt to send the last byte of handshake failed.");

free(handshake);
Expand Down Expand Up @@ -155,7 +155,7 @@ static void test_basic(void)
msg_length = sizeof(r_req) - i;
}

ck_assert_msg(net_send(ns, logger, sock, r_req + i, msg_length, &localhost) == msg_length,
ck_assert_msg(net_send(ns, logger, sock, r_req + i, msg_length, &localhost, nullptr) == msg_length,
"Failed to send request after completing the handshake.");
i += msg_length;

Expand Down Expand Up @@ -234,12 +234,12 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem,
"Failed to encrypt the outgoing handshake.");

ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost, nullptr) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
"Failed to send the first portion of the handshake to the TCP relay server.");

do_tcp_server_delay(tcp_s, mono_time, 50);

ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1,
ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost, nullptr) == 1,
"Failed to send last byte of handshake.");

do_tcp_server_delay(tcp_s, mono_time, 50);
Expand Down Expand Up @@ -282,7 +282,7 @@ static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP
localhost.ip = get_loopback();
localhost.port = 0;

ck_assert_msg(net_send(con->ns, logger, con->sock, packet, SIZEOF_VLA(packet), &localhost) == SIZEOF_VLA(packet),
ck_assert_msg(net_send(con->ns, logger, con->sock, packet, SIZEOF_VLA(packet), &localhost, nullptr) == SIZEOF_VLA(packet),
"Failed to send a packet.");
return 0;
}
Expand Down Expand Up @@ -523,7 +523,7 @@ static void test_client(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback();

TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr);
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr, nullptr);
do_tcp_connection(logger, mono_time, conn, nullptr);
c_sleep(50);

Expand Down Expand Up @@ -558,7 +558,7 @@ static void test_client(void)
crypto_new_keypair(rng, f2_public_key, f2_secret_key);
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
TCP_Client_Connection *conn2 = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key,
f2_secret_key, nullptr);
f2_secret_key, nullptr, nullptr);

// The client should call this function (defined earlier) during the routing process.
routing_response_handler(conn, response_callback, (char *)conn + 2);
Expand Down Expand Up @@ -654,7 +654,7 @@ static void test_client_invalid(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s,
self_public_key, f_public_key, f_secret_key, nullptr);
self_public_key, f_public_key, f_secret_key, nullptr, nullptr);

// Run the client's main loop but not the server.
mono_time_update(mono_time);
Expand Down
2 changes: 1 addition & 1 deletion other/bootstrap_node_packets.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static int handle_info_request(void *object, const IP_Port *source, const uint8_
return 1;
}

const Networking_Core *nc = (const Networking_Core *)object;
Networking_Core *nc = (Networking_Core *)object;

uint8_t data[1 + sizeof(bootstrap_version) + MAX_MOTD_LENGTH];
data[0] = BOOTSTRAP_INFO_PACKET_ID;
Expand Down
9 changes: 9 additions & 0 deletions toxcore/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,21 @@ cc_library(
":logger",
":mem",
":mono_time",
":net_profile",
":util",
"@libsodium",
"@psocket",
"@pthread",
],
)

cc_library(
name = "net_profile",
srcs = ["net_profile.c"],
hdrs = ["net_profile.h"],
deps = [":ccompat"],
)

cc_test(
name = "network_test",
size = "small",
Expand Down Expand Up @@ -500,6 +508,7 @@ cc_library(
":crypto_core",
":list",
":mono_time",
":net_profile",
":onion",
":util",
],
Expand Down
2 changes: 1 addition & 1 deletion toxcore/LAN_discovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
* @retval false on failure to find any valid broadcast target.
*/
non_null()
static bool send_broadcasts(const Networking_Core *net, const Broadcast_Info *broadcast, uint16_t port,
static bool send_broadcasts(Networking_Core *net, const Broadcast_Info *broadcast, uint16_t port,
const uint8_t *data, uint16_t length)
{
if (broadcast->count == 0) {
Expand Down
2 changes: 2 additions & 0 deletions toxcore/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/ping_array.c \
../toxcore/net_crypto.h \
../toxcore/net_crypto.c \
../toxcore/net_profile.c \
../toxcore/net_profile.h \
../toxcore/friend_requests.h \
../toxcore/friend_requests.c \
../toxcore/LAN_discovery.h \
Expand Down
17 changes: 16 additions & 1 deletion toxcore/TCP_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwa
TCP_Client_Connection *new_tcp_connection(
const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const 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)
const TCP_Proxy_Info *proxy_info, Net_Profile *net_profile)
{
assert(logger != nullptr);
assert(mem != nullptr);
Expand Down Expand Up @@ -625,6 +625,7 @@ TCP_Client_Connection *new_tcp_connection(
temp->con.rng = rng;
temp->con.sock = sock;
temp->con.ip_port = *ip_port;
temp->con.net_profile = net_profile;
memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(temp->self_public_key, self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
encrypt_precompute(temp->public_key, self_secret_key, temp->con.shared_key);
Expand Down Expand Up @@ -669,6 +670,8 @@ static int handle_tcp_client_routing_response(TCP_Client_Connection *conn, const
return -1;
}

netprof_record_packet(conn->con.net_profile, data[0], length, DIR_RECV);

if (data[1] < NUM_RESERVED_PORTS) {
return 0;
}
Expand Down Expand Up @@ -697,6 +700,8 @@ static int handle_tcp_client_connection_notification(TCP_Client_Connection *conn
return -1;
}

netprof_record_packet(conn->con.net_profile, data[0], length, DIR_RECV);

if (data[1] < NUM_RESERVED_PORTS) {
return -1;
}
Expand Down Expand Up @@ -724,6 +729,8 @@ static int handle_tcp_client_disconnect_notification(TCP_Client_Connection *conn
return -1;
}

netprof_record_packet(conn->con.net_profile, data[0], length, DIR_RECV);

if (data[1] < NUM_RESERVED_PORTS) {
return -1;
}
Expand Down Expand Up @@ -755,6 +762,8 @@ static int handle_tcp_client_ping(const Logger *logger, TCP_Client_Connection *c
return -1;
}

netprof_record_packet(conn->con.net_profile, data[0], length, DIR_RECV);

uint64_t ping_id;
memcpy(&ping_id, data + 1, sizeof(uint64_t));
conn->ping_response_id = ping_id;
Expand All @@ -769,6 +778,8 @@ static int handle_tcp_client_pong(TCP_Client_Connection *conn, const uint8_t *da
return -1;
}

netprof_record_packet(conn->con.net_profile, data[0], length, DIR_RECV);

uint64_t ping_id;
memcpy(&ping_id, data + 1, sizeof(uint64_t));

Expand All @@ -790,6 +801,8 @@ static int handle_tcp_client_oob_recv(TCP_Client_Connection *conn, const uint8_t
return -1;
}

netprof_record_packet(conn->con.net_profile, data[0], length, DIR_RECV);

if (conn->oob_data_callback != nullptr) {
conn->oob_data_callback(conn->oob_data_callback_object, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_PUBLIC_KEY_SIZE), userdata);
Expand All @@ -810,6 +823,8 @@ static int handle_tcp_client_packet(const Logger *logger, TCP_Client_Connection
return -1;
}

netprof_record_packet(conn->con.net_profile, data[0], length, DIR_RECV);

switch (data[0]) {
case TCP_PACKET_ROUTING_RESPONSE:
return handle_tcp_client_routing_response(conn, data, length);
Expand Down
4 changes: 2 additions & 2 deletions toxcore/TCP_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ non_null()
void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);

/** Create new TCP connection to ip_port/public_key */
non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10)
non_null(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) nullable(11)
TCP_Client_Connection *new_tcp_connection(
const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const 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);
const TCP_Proxy_Info *proxy_info, Net_Profile *net_profile);

/** Run the TCP connection */
non_null(1, 2, 3) nullable(4)
Expand Down
8 changes: 4 additions & 4 deletions toxcore/TCP_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ int send_pending_data_nonpriority(const Logger *logger, TCP_Connection *con)
}

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

if (len <= 0) {
return -1;
Expand Down Expand Up @@ -62,7 +62,7 @@ int send_pending_data(const Logger *logger, TCP_Connection *con)

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

if (len != left) {
if (len > 0) {
Expand Down Expand Up @@ -157,7 +157,7 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con
}

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

if (len <= 0) {
len = 0;
Expand All @@ -172,7 +172,7 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con
return add_priority(con, packet, SIZEOF_VLA(packet), len) ? 1 : 0;
}

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

if (len <= 0) {
return 0;
Expand Down
5 changes: 5 additions & 0 deletions toxcore/TCP_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "crypto_core.h"
#include "mem.h"
#include "net_profile.h"
#include "network.h"

typedef struct TCP_Priority_List TCP_Priority_List;
Expand Down Expand Up @@ -77,6 +78,10 @@ typedef struct TCP_Connection {

TCP_Priority_List *priority_queue_start;
TCP_Priority_List *priority_queue_end;

// This is a shared pointer to the parent's respective Net_Profile object
// (either TCP_Server for TCP server packets or TCP_Connections for TCP client packets).
Net_Profile *net_profile;
} TCP_Connection;

/**
Expand Down
18 changes: 15 additions & 3 deletions toxcore/TCP_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ struct TCP_Connections {

bool onion_status;
uint16_t onion_num_conns;

/* Network profile for all TCP client packets. */
Net_Profile net_profile;
};


Expand Down Expand Up @@ -925,7 +928,7 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
kill_tcp_connection(tcp_con->connection);
tcp_con->connection = new_tcp_connection(tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
tcp_con->connection = new_tcp_connection(tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info, &tcp_c->net_profile);

if (tcp_con->connection == nullptr) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
Expand Down Expand Up @@ -1014,7 +1017,7 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti

tcp_con->connection = new_tcp_connection(
tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port,
tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info, &tcp_c->net_profile);

if (tcp_con->connection == nullptr) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
Expand Down Expand Up @@ -1310,7 +1313,7 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port

tcp_con->connection = new_tcp_connection(
tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy,
relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info, &tcp_c->net_profile);

if (tcp_con->connection == nullptr) {
return -1;
Expand Down Expand Up @@ -1722,3 +1725,12 @@ void kill_tcp_connections(TCP_Connections *tcp_c)
mem_delete(tcp_c->mem, tcp_c->connections);
mem_delete(tcp_c->mem, tcp_c);
}

const Net_Profile *tcp_connection_get_client_net_profile(const TCP_Connections *tcp_c)
{
if (tcp_c == nullptr) {
return nullptr;
}

return &tcp_c->net_profile;
}
6 changes: 6 additions & 0 deletions toxcore/TCP_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "DHT.h" // for Node_format
#include "TCP_client.h"
#include "TCP_common.h"
#include "net_profile.h"

#define TCP_CONN_NONE 0
#define TCP_CONN_VALID 1
Expand Down Expand Up @@ -310,4 +311,9 @@ void do_tcp_connections(const Logger *logger, TCP_Connections *tcp_c, void *user
nullable(1)
void kill_tcp_connections(TCP_Connections *tcp_c);

/** Returns a pointer to the tcp client net profile associated with `tcp_c`.
* Returns null if `tcp_c` is null.
*/
const Net_Profile *tcp_connection_get_client_net_profile(const TCP_Connections *tcp_c);

#endif
Loading

0 comments on commit 674f784

Please sign in to comment.