diff --git a/CMakeLists.txt b/CMakeLists.txt index f743df4a..ee30c21a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -435,6 +435,7 @@ unit_test(toxcore bin_pack) unit_test(toxcore crypto_core) unit_test(toxcore group_announce) unit_test(toxcore group_moderation) +unit_test(toxcore list) unit_test(toxcore mem) unit_test(toxcore mono_time) unit_test(toxcore ping_array) diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index 6975c3ec..8a5a821c 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c @@ -53,7 +53,7 @@ static int handle_test_1(void *object, const IP_Port *source, const uint8_t *pac res_packet[0] = NET_PACKET_ANNOUNCE_RESPONSE; memcpy(res_packet + 1, res_message, sizeof(res_message)); - if (send_onion_response(onion->net, source, res_packet, sizeof(res_packet), + if (send_onion_response(onion->log, onion->net, source, res_packet, sizeof(res_packet), packet + sizeof(res_packet)) == -1) { return 1; } @@ -293,7 +293,7 @@ static void test_basic(void) uint64_t s; memcpy(&s, sb_data, sizeof(uint64_t)); memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE); - int ret = send_announce_request(onion1->net, rng, &path, &nodes[3], + int ret = send_announce_request(log1, onion1->net, rng, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), zeroes, @@ -315,7 +315,7 @@ static void test_basic(void) memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE); onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2)); networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1); - send_announce_request(onion1->net, rng, &path, &nodes[3], + send_announce_request(log1, onion1->net, rng, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), test_3_ping_id, @@ -340,7 +340,7 @@ static void test_basic(void) ck_assert_msg((onion3 != nullptr), "Onion failed initializing."); random_nonce(rng, nonce); - ret = send_data_request(onion3->net, rng, &path, &nodes[3].ip_port, + ret = send_data_request(log3, onion3->net, rng, &path, &nodes[3].ip_port, dht_get_self_public_key(onion1->dht), dht_get_self_public_key(onion1->dht), nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo")); diff --git a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index efc3f0a0..4f67d0d6 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -849ec5686eeaea448f4ef99650b016c883e6ea13d5fa2e7b2a344c9275a10431 /usr/local/bin/tox-bootstrapd +d9f100677e54c65fc1651da701a59c7a184ffe06381c6376102c668a8034a570 /usr/local/bin/tox-bootstrapd diff --git a/toxav/msi.c b/toxav/msi.c index 9b016ade..e243884a 100644 --- a/toxav/msi.c +++ b/toxav/msi.c @@ -821,6 +821,7 @@ static void handle_pop(MSICall *call, const MSIMessage *msg) switch (call->state) { case MSI_CALL_INACTIVE: { LOGGER_FATAL(call->session->messenger->log, "Handling what should be impossible case"); + break; } case MSI_CALL_ACTIVE: { diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 46d1cb40..56693417 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -201,6 +201,7 @@ cc_library( ":attributes", ":ccompat", ":mem", + ":util", "@pthread", ], ) @@ -230,6 +231,7 @@ cc_library( deps = [ ":ccompat", ":crypto_core", + ":logger", ":mem", ":mono_time", ], diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 397e18cf..9a418039 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -1828,7 +1828,9 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co ++not_kill; if (mono_time_is_timeout(dht->mono_time, assoc->last_pinged, PING_INTERVAL)) { - dht_getnodes(dht, &assoc->ip_port, client->public_key, public_key); + const IP_Port *target = &assoc->ip_port; + const uint8_t *target_key = client->public_key; + dht_getnodes(dht, target, target_key, public_key); assoc->last_pinged = temp_time; } @@ -1861,7 +1863,9 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co rand_node += random_range_u32(dht->rng, num_nodes - (rand_node + 1)); } - dht_getnodes(dht, &assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, public_key); + const IP_Port *target = &assoc_list[rand_node]->ip_port; + const uint8_t *target_key = client_list[rand_node]->public_key; + dht_getnodes(dht, target, target_key, public_key); *lastgetnode = temp_time; ++*bootstrap_times; @@ -1890,8 +1894,7 @@ static void do_dht_friends(DHT *dht) dht_friend->num_to_bootstrap = 0; do_ping_and_sendnode_requests(dht, &dht_friend->lastgetnode, dht_friend->public_key, dht_friend->client_list, - MAX_FRIEND_CLIENTS, - &dht_friend->bootstrap_times, true); + MAX_FRIEND_CLIENTS, &dht_friend->bootstrap_times, true); } } @@ -2634,6 +2637,7 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw DHT *const dht = (DHT *)mem_alloc(mem, sizeof(DHT)); if (dht == nullptr) { + LOGGER_ERROR(log, "failed to allocate DHT struct (%ld bytes)", (unsigned long)sizeof(DHT)); return nullptr; } @@ -2651,6 +2655,7 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw dht->ping = ping_new(mem, mono_time, rng, dht); if (dht->ping == nullptr) { + LOGGER_ERROR(log, "failed to initialise ping"); kill_dht(dht); return nullptr; } @@ -2667,10 +2672,11 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw crypto_new_keypair(rng, dht->self_public_key, dht->self_secret_key); - dht->shared_keys_recv = shared_key_cache_new(mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); - dht->shared_keys_sent = shared_key_cache_new(mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + dht->shared_keys_recv = shared_key_cache_new(log, mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + dht->shared_keys_sent = shared_key_cache_new(log, mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); if (dht->shared_keys_recv == nullptr || dht->shared_keys_sent == nullptr) { + LOGGER_ERROR(log, "failed to initialise shared key cache"); kill_dht(dht); return nullptr; } @@ -2679,6 +2685,7 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw dht->dht_ping_array = ping_array_new(mem, DHT_PING_ARRAY_SIZE, PING_TIMEOUT); if (dht->dht_ping_array == nullptr) { + LOGGER_ERROR(log, "failed to initialise ping array"); kill_dht(dht); return nullptr; } @@ -2691,6 +2698,7 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw uint32_t token; // We don't intend to delete these ever, but need to pass the token if (dht_addfriend(dht, random_public_key_bytes, nullptr, nullptr, 0, &token) != 0) { + LOGGER_ERROR(log, "failed to add initial random seed DHT friends"); kill_dht(dht); return nullptr; } diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index cd1e53d9..cf6f613d 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -3583,6 +3583,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * mem_delete(mem, m); if (error != nullptr && net_err == 1) { + LOGGER_WARNING(m->log, "network initialisation failed (no ports available)"); *error = MESSENGER_ERROR_PORT; } @@ -3602,6 +3603,8 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info); if (m->net_crypto == nullptr) { + LOGGER_WARNING(m->log, "net_crypto initialisation failed"); + kill_dht(m->dht); kill_networking(m->net); friendreq_kill(m->fr); @@ -3614,6 +3617,8 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * m->group_announce = new_gca_list(); if (m->group_announce == nullptr) { + LOGGER_WARNING(m->log, "DHT group chats initialisation failed"); + kill_net_crypto(m->net_crypto); kill_dht(m->dht); kill_networking(m->net); @@ -3642,6 +3647,8 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) || m->onion == nullptr || m->onion_a == nullptr || m->onion_c == nullptr || m->fr_c == nullptr) { + LOGGER_WARNING(m->log, "onion initialisation failed"); + kill_onion(m->onion); kill_onion_announce(m->onion_a); kill_onion_client(m->onion_c); @@ -3666,6 +3673,8 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * m->group_handler = new_dht_groupchats(m); if (m->group_handler == nullptr) { + LOGGER_WARNING(m->log, "conferences initialisation failed"); + kill_onion(m->onion); kill_onion_announce(m->onion_a); kill_onion_client(m->onion_c); @@ -3690,6 +3699,8 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * m->onion, m->forwarding); if (m->tcp_server == nullptr) { + LOGGER_WARNING(m->log, "TCP server initialisation failed"); + kill_onion(m->onion); kill_onion_announce(m->onion_a); #ifndef VANILLA_NACL diff --git a/toxcore/TCP_common.c b/toxcore/TCP_common.c index 5d001948..4d0d009f 100644 --- a/toxcore/TCP_common.c +++ b/toxcore/TCP_common.c @@ -201,7 +201,11 @@ int read_tcp_packet( const uint16_t count = net_socket_data_recv_buffer(ns, sock); if (count < length) { - LOGGER_TRACE(logger, "recv buffer has %d bytes, but requested %d bytes", count, length); + if (count != 0) { + // Only log when there are some bytes available, as empty buffer + // is a very common case and this spams our logs. + LOGGER_TRACE(logger, "recv buffer has %d bytes, but requested %d bytes", count, length); + } return -1; } diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index f01e7054..04b48525 100644 --- a/toxcore/TCP_connection.h +++ b/toxcore/TCP_connection.h @@ -120,7 +120,7 @@ bool tcp_get_random_conn_ip_port(const TCP_Connections *tcp_c, IP_Port *ip_port) * return -1 on failure. */ non_null() -int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data, +int tcp_send_onion_request(TCP_Connections *tcp_c, uint32_t tcp_connections_number, const uint8_t *data, uint16_t length); /** @brief Set if we want TCP_connection to allocate some connection for onion use. diff --git a/toxcore/announce.c b/toxcore/announce.c index fbbb2350..402d1136 100644 --- a/toxcore/announce.c +++ b/toxcore/announce.c @@ -660,7 +660,7 @@ Announcements *new_announcements(const Logger *log, const Memory *mem, const Ran announce->public_key = dht_get_self_public_key(announce->dht); announce->secret_key = dht_get_self_secret_key(announce->dht); new_hmac_key(announce->rng, announce->hmac_key); - announce->shared_keys = shared_key_cache_new(mono_time, mem, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + announce->shared_keys = shared_key_cache_new(log, mono_time, mem, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); if (announce->shared_keys == nullptr) { free(announce); return nullptr; diff --git a/toxcore/logger.c b/toxcore/logger.c index d281a660..6c532623 100644 --- a/toxcore/logger.c +++ b/toxcore/logger.c @@ -117,3 +117,8 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, int l log->callback(log->context, level, file, line, func, msg, log->userdata); } + +void logger_abort(void) +{ + abort(); +} diff --git a/toxcore/logger.h b/toxcore/logger.h index ee5838ae..8388b166 100644 --- a/toxcore/logger.h +++ b/toxcore/logger.h @@ -67,6 +67,9 @@ void logger_write( const Logger *log, Logger_Level level, const char *file, int line, const char *func, const char *format, ...); +/* @brief Terminate the program with a signal. */ +void logger_abort(void); + #define LOGGER_WRITE(log, level, ...) \ do { \ @@ -85,7 +88,7 @@ void logger_write( #define LOGGER_FATAL(log, ...) \ do { \ LOGGER_ERROR(log, __VA_ARGS__); \ - abort(); \ + logger_abort(); \ } while (0) #define LOGGER_ASSERT(log, cond, ...) \ diff --git a/toxcore/mono_time.c b/toxcore/mono_time.c index 2ce817f6..7076cb07 100644 --- a/toxcore/mono_time.c +++ b/toxcore/mono_time.c @@ -32,6 +32,7 @@ #include #include "ccompat.h" +#include "util.h" /** don't call into system billions of times for no reason */ struct Mono_Time { @@ -165,7 +166,9 @@ Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_t // Maximum reproducibility. Never return time = 0. mono_time->base_time = 1; #else - mono_time->base_time = (uint64_t)time(nullptr) * 1000ULL - current_time_monotonic(mono_time); + // Never return time = 0 in case time() returns 0 (e.g. on microcontrollers + // without battery-powered RTC or ones where NTP didn't initialise it yet). + mono_time->base_time = max_u64(1, (uint64_t)time(nullptr)) * 1000ULL - current_time_monotonic(mono_time); #endif mono_time_update(mono_time); diff --git a/toxcore/network.c b/toxcore/network.c index 3e0e6f49..6228317a 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2016-2018 The TokTok team. + * Copyright © 2016-2023 The TokTok team. * Copyright © 2013 Tox project. */ @@ -778,7 +778,7 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu Ip_Ntoa ip_str; const int error = net_error(); char *strerror = net_new_strerror(error); - LOGGER_TRACE(log, "[%02x = %-20s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x", + LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x", buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message, min_u16(buflen, 999), 'E', net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error, @@ -786,14 +786,14 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu net_kill_strerror(strerror); } else if ((res > 0) && ((size_t)res <= buflen)) { Ip_Ntoa ip_str; - LOGGER_TRACE(log, "[%02x = %-20s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x", + LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x", buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message, min_u16(res, 999), (size_t)res < buflen ? '<' : '=', net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), 0, "OK", data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]); } else { /* empty or overwrite */ Ip_Ntoa ip_str; - LOGGER_TRACE(log, "[%02x = %-20s] %s %lu%c%u %s:%u (%u: %s) | %08x%08x...%02x", + LOGGER_TRACE(log, "[%02x = %-21s] %s %lu%c%u %s:%u (%u: %s) | %08x%08x...%02x", buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message, res, res == 0 ? '!' : '>', buflen, net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), 0, "OK", diff --git a/toxcore/onion.c b/toxcore/onion.c index d7ec8bfd..80bb4920 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -283,22 +283,27 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac * return -1 on failure. * return 0 on success. */ -int send_onion_response(const Networking_Core *net, const IP_Port *dest, const uint8_t *data, uint16_t length, +int send_onion_response(const Logger *log, const Networking_Core *net, + const IP_Port *dest, const uint8_t *data, uint16_t length, const uint8_t *ret) { if (length > ONION_RESPONSE_MAX_DATA_SIZE || length == 0) { return -1; } - VLA(uint8_t, packet, 1 + RETURN_3 + length); + const uint16_t packet_size = 1 + RETURN_3 + length; + VLA(uint8_t, packet, packet_size); packet[0] = NET_PACKET_ONION_RECV_3; memcpy(packet + 1, ret, RETURN_3); memcpy(packet + 1 + RETURN_3, data, length); - if ((uint32_t)sendpacket(net, dest, packet, SIZEOF_VLA(packet)) != SIZEOF_VLA(packet)) { + if ((uint16_t)sendpacket(net, dest, packet, packet_size) != packet_size) { return -1; } + Ip_Ntoa ip_str; + LOGGER_TRACE(log, "forwarded onion RECV_3 to %s:%d (%02x in %02x, %d bytes)", + net_ip_ntoa(&dest->ip, &ip_str), net_ntohs(dest->port), data[0], packet[0], packet_size); return 0; } @@ -309,28 +314,42 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_ Onion *onion = (Onion *)object; if (length > ONION_MAX_PACKET_SIZE) { + LOGGER_TRACE(onion->log, "invalid initial onion packet length: %u (max: %u)", + length, ONION_MAX_PACKET_SIZE); return 1; } if (length <= 1 + SEND_1) { + LOGGER_TRACE(onion->log, "initial onion packet cannot contain SEND_1 packet: %u <= %u", + length, 1 + SEND_1); return 1; } change_symmetric_key(onion); + const int nonce_start = 1; + const int public_key_start = nonce_start + CRYPTO_NONCE_SIZE; + const int ciphertext_start = public_key_start + CRYPTO_PUBLIC_KEY_SIZE; + + const int ciphertext_length = length - ciphertext_start; + const int plaintext_length = ciphertext_length - CRYPTO_MAC_SIZE; + uint8_t plain[ONION_MAX_PACKET_SIZE]; - const uint8_t *public_key = packet + 1 + CRYPTO_NONCE_SIZE; + const uint8_t *public_key = &packet[public_key_start]; const uint8_t *shared_key = shared_key_cache_lookup(onion->shared_keys_1, public_key); if (shared_key == nullptr) { /* Error looking up/deriving the shared key */ + LOGGER_TRACE(onion->log, "shared onion key lookup failed for pk %02x%02x...", + public_key[0], public_key[1]); return 1; } - const int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, - length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), plain); + const int len = decrypt_data_symmetric( + shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain); - if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)) { + if (len != plaintext_length) { + LOGGER_TRACE(onion->log, "decrypt failed: %d != %d", len, plaintext_length); return 1; } @@ -339,7 +358,9 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const IP_Port *source, const uint8_t *nonce) { - if (len > ONION_MAX_PACKET_SIZE + SIZE_IPPORT - (1 + CRYPTO_NONCE_SIZE + ONION_RETURN_1)) { + const uint16_t max_len = ONION_MAX_PACKET_SIZE + SIZE_IPPORT - (1 + CRYPTO_NONCE_SIZE + ONION_RETURN_1); + if (len > max_len) { + LOGGER_TRACE(onion->log, "invalid SEND_1 length: %d > %d", len, max_len); return 1; } @@ -376,6 +397,9 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const I return 1; } + Ip_Ntoa ip_str; + LOGGER_TRACE(onion->log, "forwarded onion packet to %s:%d, level 1 (%02x in %02x, %d bytes)", + net_ip_ntoa(&send_to.ip, &ip_str), net_ntohs(send_to.port), plain[0], data[0], data_len); return 0; } @@ -439,6 +463,9 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac return 1; } + Ip_Ntoa ip_str; + LOGGER_TRACE(onion->log, "forwarded onion packet to %s:%d, level 2 (%02x in %02x, %d bytes)", + net_ip_ntoa(&send_to.ip, &ip_str), net_ntohs(send_to.port), packet[0], data[0], data_len); return 0; } @@ -509,6 +536,9 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac return 1; } + Ip_Ntoa ip_str; + LOGGER_TRACE(onion->log, "forwarded onion packet to %s:%d, level 3 (%02x in %02x, %d bytes)", + net_ip_ntoa(&send_to.ip, &ip_str), net_ntohs(send_to.port), packet[0], data[0], data_len); return 0; } @@ -546,6 +576,7 @@ static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *pac IP_Port send_to; if (ipport_unpack(&send_to, plain, len, false) == -1) { + LOGGER_DEBUG(onion->log, "failed to unpack IP/Port"); return 1; } @@ -559,6 +590,9 @@ static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *pac return 1; } + Ip_Ntoa ip_str; + LOGGER_TRACE(onion->log, "forwarded onion RECV_2 to %s:%d (%02x in %02x, %d bytes)", + net_ip_ntoa(&send_to.ip, &ip_str), net_ntohs(send_to.port), packet[0], data[0], data_len); return 0; } @@ -608,6 +642,9 @@ static int handle_recv_2(void *object, const IP_Port *source, const uint8_t *pac return 1; } + Ip_Ntoa ip_str; + LOGGER_TRACE(onion->log, "forwarded onion RECV_1 to %s:%d (%02x in %02x, %d bytes)", + net_ip_ntoa(&send_to.ip, &ip_str), net_ntohs(send_to.port), packet[0], data[0], data_len); return 0; } @@ -644,6 +681,7 @@ static int handle_recv_1(void *object, const IP_Port *source, const uint8_t *pac IP_Port send_to; if (ipport_unpack(&send_to, plain, len, true) == -1) { + LOGGER_DEBUG(onion->log, "failed to unpack IP/Port"); return 1; } @@ -690,9 +728,9 @@ Onion *new_onion(const Logger *log, const Memory *mem, const Mono_Time *mono_tim onion->timestamp = mono_time_get(onion->mono_time); const uint8_t *secret_key = dht_get_self_secret_key(dht); - onion->shared_keys_1 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); - onion->shared_keys_2 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); - onion->shared_keys_3 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + onion->shared_keys_1 = shared_key_cache_new(log, mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + onion->shared_keys_2 = shared_key_cache_new(log, mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + onion->shared_keys_3 = shared_key_cache_new(log, mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); if (onion->shared_keys_1 == nullptr || onion->shared_keys_2 == nullptr || diff --git a/toxcore/onion.h b/toxcore/onion.h index 7f71c249..732d926c 100644 --- a/toxcore/onion.h +++ b/toxcore/onion.h @@ -127,7 +127,8 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac * return 0 on success. */ non_null() -int send_onion_response(const Networking_Core *net, const IP_Port *dest, const uint8_t *data, uint16_t length, +int send_onion_response(const Logger *log, const Networking_Core *net, + const IP_Port *dest, const uint8_t *data, uint16_t length, const uint8_t *ret); /** @brief Function to handle/send received decrypted versions of the packet created by create_onion_packet. diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index 551e7b1f..d4a37ad9 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -186,11 +186,12 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ * return -1 on failure. * return 0 on success. */ -int send_announce_request(const Networking_Core *net, const Random *rng, - const Onion_Path *path, const Node_format *dest, - const uint8_t *public_key, const uint8_t *secret_key, - const uint8_t *ping_id, const uint8_t *client_id, - const uint8_t *data_public_key, uint64_t sendback_data) +int send_announce_request( + const Logger *log, const Networking_Core *net, const Random *rng, + const Onion_Path *path, const Node_format *dest, + const uint8_t *public_key, const uint8_t *secret_key, + const uint8_t *ping_id, const uint8_t *client_id, + const uint8_t *data_public_key, uint64_t sendback_data) { uint8_t request[ONION_ANNOUNCE_REQUEST_MIN_SIZE]; int len = create_announce_request(rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id, @@ -230,9 +231,10 @@ int send_announce_request(const Networking_Core *net, const Random *rng, * return -1 on failure. * return 0 on success. */ -int send_data_request(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, - const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, - const uint8_t *data, uint16_t length) +int send_data_request( + const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, + const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, + const uint8_t *data, uint16_t length) { uint8_t request[ONION_MAX_DATA_SIZE]; int len = create_data_request(rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length); @@ -549,7 +551,7 @@ static int handle_announce_request_common( ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, CRYPTO_NONCE_SIZE); - if (send_onion_response(onion_a->net, source, data, + if (send_onion_response(onion_a->log, onion_a->net, source, data, 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len, packet + (length - ONION_RETURN_3)) == -1) { mem_delete(onion_a->mem, response); @@ -634,7 +636,7 @@ static int handle_data_request(void *object, const IP_Port *source, const uint8_ data[0] = NET_PACKET_ONION_DATA_RESPONSE; memcpy(data + 1, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3)); - if (send_onion_response(onion_a->net, &onion_a->entries[index].ret_ip_port, data, SIZEOF_VLA(data), + if (send_onion_response(onion_a->log, onion_a->net, &onion_a->entries[index].ret_ip_port, data, SIZEOF_VLA(data), onion_a->entries[index].ret) == -1) { return 1; } @@ -665,7 +667,7 @@ Onion_Announce *new_onion_announce(const Logger *log, const Memory *mem, const R onion_a->extra_data_object = nullptr; new_hmac_key(rng, onion_a->hmac_key); - onion_a->shared_keys_recv = shared_key_cache_new(mono_time, mem, dht_get_self_secret_key(dht), KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + onion_a->shared_keys_recv = shared_key_cache_new(log, mono_time, mem, dht_get_self_secret_key(dht), KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); if (onion_a->shared_keys_recv == nullptr) { kill_onion_announce(onion_a); return nullptr; diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 857f4706..90195351 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -94,11 +94,12 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ * return 0 on success. */ non_null() -int send_announce_request(const Networking_Core *net, const Random *rng, - const Onion_Path *path, const Node_format *dest, - const uint8_t *public_key, const uint8_t *secret_key, - const uint8_t *ping_id, const uint8_t *client_id, - const uint8_t *data_public_key, uint64_t sendback_data); +int send_announce_request( + const Logger *log, const Networking_Core *net, const Random *rng, + const Onion_Path *path, const Node_format *dest, + const uint8_t *public_key, const uint8_t *secret_key, + const uint8_t *ping_id, const uint8_t *client_id, + const uint8_t *data_public_key, uint64_t sendback_data); /** @brief Create and send an onion data request packet. * @@ -117,9 +118,10 @@ int send_announce_request(const Networking_Core *net, const Random *rng, * return 0 on success. */ non_null() -int send_data_request(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, - const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, - const uint8_t *data, uint16_t length); +int send_data_request( + const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, + const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, + const uint8_t *data, uint16_t length); typedef int pack_extra_data_cb(void *object, const Logger *logger, const Mono_Time *mono_time, diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index c15eb555..cdf0b85d 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -582,6 +582,7 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *publ *sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, onion_c->rng, data, sizeof(data)); if (*sendback == 0) { + LOGGER_TRACE(onion_c->logger, "generating sendback in announce ping array failed"); return -1; } @@ -624,6 +625,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con const uint8_t *dest_pubkey, const uint8_t *ping_id, uint32_t pathnum) { if (num > onion_c->num_friends) { + LOGGER_TRACE(onion_c->logger, "not sending announce to out of bounds friend %u (num friends: %u)", num, onion_c->num_friends); return -1; } @@ -632,10 +634,12 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con if (num == 0) { if (random_path(onion_c, &onion_c->onion_paths_self, pathnum, &path) == -1) { + LOGGER_TRACE(onion_c->logger, "cannot find path to self"); return -1; } } else { if (random_path(onion_c, &onion_c->onion_paths_friends, pathnum, &path) == -1) { + LOGGER_TRACE(onion_c->logger, "cannot find path to friend"); return -1; } } @@ -682,9 +686,13 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con } if (len == -1) { + LOGGER_TRACE(onion_c->logger, "failed to create announce request"); return -1; } + Ip_Ntoa ip_str; + LOGGER_TRACE(onion_c->logger, "sending onion packet to %s:%d (%02x, %d bytes)", + net_ip_ntoa(&dest->ip, &ip_str), net_ntohs(dest->port), request[0], len); return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len); } @@ -934,6 +942,8 @@ static int handle_announce_response(void *object, const IP_Port *source, const u Onion_Client *onion_c = (Onion_Client *)object; if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) { + LOGGER_TRACE(onion_c->logger, "invalid announce response length: %u (min: %u, max: %u)", + length, (unsigned int)ONION_ANNOUNCE_RESPONSE_MIN_SIZE, (unsigned int)ONION_ANNOUNCE_RESPONSE_MAX_SIZE); return 1; } @@ -949,30 +959,37 @@ static int handle_announce_response(void *object, const IP_Port *source, const u uint8_t plain[1 + ONION_PING_ID_SIZE + ONION_ANNOUNCE_RESPONSE_MAX_SIZE - ONION_ANNOUNCE_RESPONSE_MIN_SIZE]; const int plain_size = 1 + ONION_PING_ID_SIZE + length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE; int len; + const uint16_t nonce_start = 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH; + const uint16_t ciphertext_start = nonce_start + CRYPTO_NONCE_SIZE; + const uint16_t ciphertext_size = length - ciphertext_start; if (num == 0) { len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c), - packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, - packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, - length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain); + &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); } else { if (!onion_c->friends_list[num - 1].is_valid) { + LOGGER_TRACE(onion_c->logger, "friend number %lu is invalid", (unsigned long)(num - 1)); return 1; } len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key, - packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, - packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, - length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain); + &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); + } + + if (len < 0) { + // This happens a lot, so don't log it. + return 1; } if ((uint32_t)len != plain_size) { + LOGGER_WARNING(onion_c->logger, "decrypted size (%lu) is not the expected plain text size (%lu)", (unsigned long)len, (unsigned long)plain_size); return 1; } const uint32_t path_used = set_path_timeouts(onion_c, num, path_num); if (client_add_to_list(onion_c, num, public_key, &ip_port, plain[0], plain + 1, path_used) == -1) { + LOGGER_WARNING(onion_c->logger, "failed to add client to list"); return 1; } @@ -989,10 +1006,12 @@ static int handle_announce_response(void *object, const IP_Port *source, const u plain_size - 2 - ONION_PING_ID_SIZE, false); if (num_nodes < 0) { + LOGGER_WARNING(onion_c->logger, "no nodes to unpack in onion response"); return 1; } if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) { + LOGGER_WARNING(onion_c->logger, "pinging %d nodes failed", num_nodes); return 1; } } @@ -1011,6 +1030,8 @@ static int handle_announce_response(void *object, const IP_Port *source, const u // TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline? onion_c->last_packet_recv = mono_time_get(onion_c->mono_time); + LOGGER_TRACE(onion_c->logger, "onion has received a packet at %llu", + (unsigned long long)onion_c->last_packet_recv); return 0; } @@ -1023,6 +1044,8 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con Onion_Client *onion_c = (Onion_Client *)object; if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) { + LOGGER_TRACE(onion_c->logger, "invalid announce response length: %u (min: %u, max: %u)", + length, (unsigned int)ONION_ANNOUNCE_RESPONSE_MIN_SIZE, (unsigned int)ONION_ANNOUNCE_RESPONSE_MAX_SIZE); return 1; } @@ -1039,30 +1062,37 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con VLA(uint8_t, plain, 1 + ONION_PING_ID_SIZE + len_nodes); int len; + const uint16_t nonce_start = 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH; + const uint16_t ciphertext_start = nonce_start + CRYPTO_NONCE_SIZE; + const uint16_t ciphertext_size = length - ciphertext_start; if (num == 0) { len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c), - packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, - packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, - length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain); + &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); } else { if (!onion_c->friends_list[num - 1].is_valid) { + LOGGER_TRACE(onion_c->logger, "friend number %lu is invalid", (unsigned long)(num - 1)); return 1; } len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key, - packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, - packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, - length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain); + &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); + } + + if (len < 0) { + // This happens a lot, so don't log it. + return 1; } if ((uint32_t)len != SIZEOF_VLA(plain)) { + LOGGER_WARNING(onion_c->logger, "decrypted size (%lu) is not the expected plain text size (%lu)", (unsigned long)len, (unsigned long)SIZEOF_VLA(plain)); return 1; } const uint32_t path_used = set_path_timeouts(onion_c, num, path_num); if (client_add_to_list(onion_c, num, public_key, &ip_port, plain[0], plain + 1, path_used) == -1) { + LOGGER_WARNING(onion_c->logger, "failed to add client to list"); return 1; } @@ -1071,16 +1101,21 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con const int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, nullptr, plain + 1 + ONION_PING_ID_SIZE, len_nodes, false); if (num_nodes <= 0) { + LOGGER_WARNING(onion_c->logger, "no nodes to unpack in onion response"); return 1; } if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) { + LOGGER_WARNING(onion_c->logger, "pinging %d nodes failed", num_nodes); return 1; } } // TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline? onion_c->last_packet_recv = mono_time_get(onion_c->mono_time); + LOGGER_TRACE(onion_c->logger, "onion has received a packet at %llu", + (unsigned long long)onion_c->last_packet_recv); + return 0; } @@ -1378,6 +1413,7 @@ static int handle_dht_dhtpk(void *object, const IP_Port *source, const uint8_t * return handle_dhtpk_announce(onion_c, packet, plain, len, userdata); } + /** @brief Send the packets to tell our friends what our DHT public key is. * * if onion_dht_both is 0, use only the onion to send the packet. @@ -1857,6 +1893,18 @@ void onion_group_announce_register(Onion_Client *onion_c, onion_group_announce_c #define TIME_TO_STABLE (ONION_NODE_PING_INTERVAL * 6) #define ANNOUNCE_INTERVAL_STABLE (ONION_NODE_PING_INTERVAL * 8) +non_null() +static bool key_list_contains(const uint8_t *const *keys, uint16_t keys_size, const uint8_t *public_key) +{ + for (uint16_t i = 0; i < keys_size; ++i) { + if (memeq(keys[i], CRYPTO_PUBLIC_KEY_SIZE, public_key, CRYPTO_PUBLIC_KEY_SIZE)) { + return true; + } + } + + return false; +} + non_null() static void do_announce(Onion_Client *onion_c) { @@ -1945,9 +1993,27 @@ static void do_announce(Onion_Client *onion_c) return; } - for (unsigned int i = 0; i < (MAX_ONION_CLIENTS_ANNOUNCE / 2); ++i) { + // Don't send announces to the same node twice. If we don't have many nodes, + // the random selection below may have overlaps. This ensures that we deduplicate + // nodes before sending packets to save some bandwidth. + const uint8_t *targets[MAX_ONION_CLIENTS_ANNOUNCE / 2]; + unsigned int targets_count = 0; + + for (unsigned int i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE / 2; ++i) { const uint32_t num = random_range_u32(onion_c->rng, num_nodes); - client_send_announce_request(onion_c, 0, &path_nodes[num].ip_port, path_nodes[num].public_key, nullptr, -1); + const Node_format *target = &path_nodes[num]; + + if (!key_list_contains(targets, targets_count, target->public_key)) { + client_send_announce_request(onion_c, 0, &target->ip_port, target->public_key, nullptr, -1); + + targets[targets_count] = target->public_key; + ++targets_count; + assert(targets_count <= MAX_ONION_CLIENTS_ANNOUNCE / 2); + } else { + Ip_Ntoa ip_str; + LOGGER_TRACE(onion_c->logger, "not sending repeated announce request to %s:%d", + net_ip_ntoa(&target->ip_port.ip, &ip_str), net_ntohs(target->ip_port.port)); + } } } } @@ -1959,22 +2025,25 @@ static void do_announce(Onion_Client *onion_c) non_null() static bool onion_isconnected(Onion_Client *onion_c) { - unsigned int num = 0; + unsigned int live = 0; unsigned int announced = 0; if (mono_time_is_timeout(onion_c->mono_time, onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) { + LOGGER_TRACE(onion_c->logger, "onion is NOT connected: last packet received at %llu (timeout=%u)", + (unsigned long long)onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT); onion_c->last_populated = 0; return false; } if (onion_c->path_nodes_index == 0) { + LOGGER_TRACE(onion_c->logger, "onion is NOT connected: no path nodes available"); onion_c->last_populated = 0; return false; } for (unsigned int i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) { if (!onion_node_timed_out(&onion_c->clients_announce_list[i], onion_c->mono_time)) { - ++num; + ++live; if (onion_c->clients_announce_list[i].is_stored != 0) { ++announced; @@ -1990,14 +2059,18 @@ static bool onion_isconnected(Onion_Client *onion_c) /* Consider ourselves online if we are announced to half or more nodes * we are connected to */ - if (num != 0 && announced != 0) { - if ((num / 2) <= announced && (pnodes / 2) <= num) { + if (live != 0 && announced != 0) { + if ((live / 2) <= announced && (pnodes / 2) <= live) { + LOGGER_TRACE(onion_c->logger, "onion is connected: %u live nodes, %u announced, %d path nodes", + live, announced, pnodes); return true; } } onion_c->last_populated = 0; + LOGGER_TRACE(onion_c->logger, "onion is NOT connected: %u live nodes, %u announced, %d path nodes", + live, announced, pnodes); return false; } diff --git a/toxcore/shared_key_cache.c b/toxcore/shared_key_cache.c index 4b87945c..0adc1e82 100644 --- a/toxcore/shared_key_cache.c +++ b/toxcore/shared_key_cache.c @@ -24,12 +24,13 @@ struct Shared_Key_Cache { uint64_t timeout; /** After this time (in seconds), a key is erased on the next housekeeping cycle */ const Mono_Time *mono_time; const Memory *mem; + const Logger *log; uint8_t keys_per_slot; }; non_null() -static bool shared_key_is_empty(const Shared_Key *k) { - assert(k != nullptr); +static bool shared_key_is_empty(const Logger *log, const Shared_Key *k) { + LOGGER_ASSERT(log, k != nullptr, "shared key must not be NULL"); /* * Since time can never be 0, we use that to determine if a key slot is empty. * Additionally this allows us to use crypto_memzero and leave the slot in a valid state. @@ -38,12 +39,12 @@ static bool shared_key_is_empty(const Shared_Key *k) { } non_null() -static void shared_key_set_empty(Shared_Key *k) { +static void shared_key_set_empty(const Logger *log, Shared_Key *k) { crypto_memzero(k, sizeof (Shared_Key)); - assert(shared_key_is_empty(k)); + LOGGER_ASSERT(log, shared_key_is_empty(log, k), "shared key must be empty after clearing it"); } -Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory *mem, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot) +Shared_Key_Cache *shared_key_cache_new(const Logger *log, const Mono_Time *mono_time, const Memory *mem, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot) { if (mono_time == nullptr || self_secret_key == nullptr || timeout == 0 || keys_per_slot == 0) { return nullptr; @@ -52,7 +53,7 @@ Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory // Time must not be zero, since we use that as special value for empty slots if (mono_time_get(mono_time) == 0) { // Fail loudly in debug environments - assert(false); + LOGGER_FATAL(log, "time must not be zero (mono_time not initialised?)"); return nullptr; } @@ -64,6 +65,7 @@ Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory res->self_secret_key = self_secret_key; res->mono_time = mono_time; res->mem = mem; + res->log = log; res->keys_per_slot = keys_per_slot; // We take one byte from the public key for each bucket and store keys_per_slot elements there const size_t cache_size = 256 * keys_per_slot; @@ -106,7 +108,7 @@ const uint8_t *shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t pu // Perform lookup for(size_t i = 0; i < cache->keys_per_slot; ++i) { - if (shared_key_is_empty(&bucket_start[i])) { + if (shared_key_is_empty(cache->log, &bucket_start[i])) { continue; } @@ -119,13 +121,13 @@ const uint8_t *shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t pu // Perform housekeeping for this bucket for (size_t i = 0; i < cache->keys_per_slot; ++i) { - if (shared_key_is_empty(&bucket_start[i])) { + if (shared_key_is_empty(cache->log, &bucket_start[i])) { continue; } const bool timed_out = (bucket_start[i].time_last_requested + cache->timeout) < cur_time; if (timed_out) { - shared_key_set_empty(&bucket_start[i]); + shared_key_set_empty(cache->log, &bucket_start[i]); } } diff --git a/toxcore/shared_key_cache.h b/toxcore/shared_key_cache.h index dc42b380..b7112720 100644 --- a/toxcore/shared_key_cache.h +++ b/toxcore/shared_key_cache.h @@ -8,6 +8,7 @@ #include // uint*_t #include "crypto_core.h" +#include "logger.h" #include "mem.h" #include "mono_time.h" @@ -27,9 +28,10 @@ typedef struct Shared_Key_Cache Shared_Key_Cache; * @return nullptr on error. */ non_null() -Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory *mem, - const uint8_t *self_secret_key, - uint64_t timeout, uint8_t keys_per_slot); +Shared_Key_Cache *shared_key_cache_new( + const Logger *log, const Mono_Time *mono_time, const Memory *mem, + const uint8_t *self_secret_key, + uint64_t timeout, uint8_t keys_per_slot); /** * @brief Deletes the cache and frees all resources. diff --git a/toxcore/tox.c b/toxcore/tox.c index 768d5f9e..05d94013 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -2810,7 +2810,7 @@ uint16_t tox_self_get_udp_port(const Tox *tox, Tox_Err_Get_Port *error) { assert(tox != nullptr); tox_lock(tox); - const uint16_t port = net_htons(net_port(tox->m->net)); + const uint16_t port = tox->m == nullptr || tox->m->net == nullptr ? 0 : net_htons(net_port(tox->m->net)); tox_unlock(tox); if (port == 0) { @@ -2827,7 +2827,7 @@ uint16_t tox_self_get_tcp_port(const Tox *tox, Tox_Err_Get_Port *error) assert(tox != nullptr); tox_lock(tox); - if (tox->m->tcp_server != nullptr) { + if (tox->m != nullptr && tox->m->tcp_server != nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_OK); const uint16_t ret = tox->m->options.tcp_server_port; tox_unlock(tox); diff --git a/toxcore/util.c b/toxcore/util.c index 3b3779bd..507524df 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -107,6 +107,10 @@ int64_t min_s64(int64_t a, int64_t b) return a < b ? a : b; } +uint8_t max_u08(uint8_t a, uint8_t b) +{ + return a > b ? a : b; +} uint16_t max_u16(uint16_t a, uint16_t b) { return a > b ? a : b; diff --git a/toxcore/util.h b/toxcore/util.h index 44091b36..c16605c1 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -53,6 +53,7 @@ int16_t min_s16(int16_t a, int16_t b); int32_t min_s32(int32_t a, int32_t b); int64_t min_s64(int64_t a, int64_t b); +uint8_t max_u08(uint8_t a, uint8_t b); uint16_t max_u16(uint16_t a, uint16_t b); uint32_t max_u32(uint32_t a, uint32_t b); uint64_t max_u64(uint64_t a, uint64_t b);