refactor: decouple net_crypto from DHT

This introduces a vtable interface for the DHT dependency in net_crypto,
allowing us to break the dependency and make testing/mocking/fuzzing easier.
This commit is contained in:
iphydf
2026-01-04 20:00:26 +00:00
parent 1936d42965
commit 7740bb421f
9 changed files with 89 additions and 16 deletions
+23
View File
@@ -8,6 +8,8 @@
#include "../toxcore/tox_dispatch.h"
#include "../toxcore/tox_events.h"
#include "../toxcore/tox_struct.h"
#include "../toxcore/net_crypto.h"
#include "../toxcore/DHT.h"
#include "auto_test_support.h"
@@ -15,6 +17,27 @@
#define ABORT_ON_LOG_ERROR true
#endif
static const uint8_t *auto_test_nc_dht_get_shared_key_sent_wrapper(void *dht, const uint8_t *public_key)
{
return dht_get_shared_key_sent((DHT *)dht, public_key);
}
static const uint8_t *auto_test_nc_dht_get_self_public_key_wrapper(const void *dht)
{
return dht_get_self_public_key((const DHT *)dht);
}
static const uint8_t *auto_test_nc_dht_get_self_secret_key_wrapper(const void *dht)
{
return dht_get_self_secret_key((const DHT *)dht);
}
const Net_Crypto_DHT_Funcs auto_test_dht_funcs = {
auto_test_nc_dht_get_shared_key_sent_wrapper,
auto_test_nc_dht_get_self_public_key_wrapper,
auto_test_nc_dht_get_self_secret_key_wrapper,
};
#ifndef USE_IPV6
#define USE_IPV6 1
#endif
+3
View File
@@ -8,6 +8,7 @@
#include "../toxcore/Messenger.h"
#include "../toxcore/mono_time.h"
#include "../toxcore/tox_dispatch.h"
#include "../toxcore/net_crypto.h"
typedef struct AutoTox {
Tox *tox;
@@ -66,4 +67,6 @@ void print_debug_logger(void *context, Logger_Level level, const char *file, uin
Tox *tox_new_log(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data);
Tox *tox_new_log_lan(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data, bool lan_discovery);
extern const Net_Crypto_DHT_Funcs auto_test_dht_funcs;
#endif
+1 -1
View File
@@ -132,7 +132,7 @@ static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp,
ck_assert(subtox->tcp_np != nullptr);
const TCP_Proxy_Info inf = {{{{0}}}};
subtox->c = new_net_crypto(subtox->log, mem, rng, ns, subtox->mono_time, subtox->net, subtox->dht, &inf, subtox->tcp_np);
subtox->c = new_net_crypto(subtox->log, mem, rng, ns, subtox->mono_time, subtox->net, subtox->dht, &auto_test_dht_funcs, &inf, subtox->tcp_np);
subtox->forwarding = new_forwarding(subtox->log, mem, rng, subtox->mono_time, subtox->dht, subtox->net);
ck_assert(subtox->forwarding != nullptr);
+1 -1
View File
@@ -492,7 +492,7 @@ static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, u
}
TCP_Proxy_Info inf = {{{{0}}}};
on->nc = new_net_crypto(on->log, mem, rng, ns, on->mono_time, net, dht, &inf, on->tcp_np);
on->nc = new_net_crypto(on->log, mem, rng, ns, on->mono_time, net, dht, &auto_test_dht_funcs, &inf, on->tcp_np);
on->onion_c = new_onion_client(on->log, mem, rng, on->mono_time, on->nc, dht, net);
if (!on->onion_c) {
+1
View File
@@ -6,6 +6,7 @@
#define C_TOXCORE_TOXAV_MSI_H
#include <pthread.h>
#include <stddef.h>
#include <stdint.h>
#include "../toxcore/logger.h"
+25 -1
View File
@@ -47,6 +47,30 @@ static_assert(MAX_CONCURRENT_FILE_PIPES <= UINT8_MAX + 1,
static const Friend empty_friend = {{0}};
static const uint8_t *_Nullable nc_dht_get_shared_key_sent_wrapper(void *_Nonnull obj, const uint8_t *_Nonnull public_key)
{
DHT *dht = (DHT *)obj;
return dht_get_shared_key_sent(dht, public_key);
}
static const uint8_t *_Nonnull nc_dht_get_self_public_key_wrapper(const void *_Nonnull obj)
{
const DHT *dht = (const DHT *)obj;
return dht_get_self_public_key(dht);
}
static const uint8_t *_Nonnull nc_dht_get_self_secret_key_wrapper(const void *_Nonnull obj)
{
const DHT *dht = (const DHT *)obj;
return dht_get_self_secret_key(dht);
}
static const Net_Crypto_DHT_Funcs m_dht_funcs = {
nc_dht_get_shared_key_sent_wrapper,
nc_dht_get_self_public_key_wrapper,
nc_dht_get_self_secret_key_wrapper,
};
/**
* Determines if the friendnumber passed is valid in the Messenger object.
*
@@ -3443,7 +3467,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
return nullptr;
}
m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->net, m->dht, &options->proxy_info, m->tcp_np);
m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->net, m->dht, &m_dht_funcs, &options->proxy_info, m->tcp_np);
if (m->net_crypto == nullptr) {
LOGGER_WARNING(m->log, "net_crypto initialisation failed");
+14 -10
View File
@@ -13,7 +13,7 @@
#include <pthread.h>
#include <string.h>
#include "DHT.h"
#include "DHT.h" // Node_format
#include "LAN_discovery.h"
#include "TCP_client.h"
#include "TCP_connection.h"
@@ -139,7 +139,9 @@ struct Net_Crypto {
const Network *ns;
Networking_Core *net;
DHT *dht;
void *dht;
const Net_Crypto_DHT_Funcs *dht_funcs;
TCP_Connections *tcp_c;
Crypto_Connection *crypto_connections;
@@ -218,12 +220,12 @@ static int create_cookie_request(const Net_Crypto *_Nonnull c, uint8_t *_Nonnull
memcpy(plain, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
memzero(plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(plain + (CRYPTO_PUBLIC_KEY_SIZE * 2), &number, sizeof(uint64_t));
const uint8_t *tmp_shared_key = dht_get_shared_key_sent(c->dht, dht_public_key);
const uint8_t *tmp_shared_key = c->dht_funcs->get_shared_key_sent(c->dht, dht_public_key);
memcpy(shared_key, tmp_shared_key, CRYPTO_SHARED_KEY_SIZE);
uint8_t nonce[CRYPTO_NONCE_SIZE];
random_nonce(c->rng, nonce);
packet[0] = NET_PACKET_COOKIE_REQUEST;
memcpy(packet + 1, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE);
memcpy(packet + 1, c->dht_funcs->get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE);
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
const int len = encrypt_data_symmetric(c->mem, shared_key, nonce, plain, sizeof(plain),
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
@@ -330,12 +332,13 @@ static int handle_cookie_request(const Net_Crypto *_Nonnull c, uint8_t *_Nonnull
}
memcpy(dht_public_key, packet + 1, CRYPTO_PUBLIC_KEY_SIZE);
const uint8_t *tmp_shared_key = dht_get_shared_key_sent(c->dht, dht_public_key);
const uint8_t *tmp_shared_key = c->dht_funcs->get_shared_key_sent(c->dht, dht_public_key);
memcpy(shared_key, tmp_shared_key, CRYPTO_SHARED_KEY_SIZE);
const int len = decrypt_data_symmetric(c->mem, shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE,
request_plain);
if (len != COOKIE_REQUEST_PLAIN_LENGTH) {
return -1;
}
@@ -2911,9 +2914,9 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk)
* Sets all the global connection variables to their default values.
*/
Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
Mono_Time *mono_time, Networking_Core *net, DHT *dht, const TCP_Proxy_Info *proxy_info, Net_Profile *tcp_np)
Mono_Time *mono_time, Networking_Core *net, void *dht, const Net_Crypto_DHT_Funcs *dht_funcs, const TCP_Proxy_Info *proxy_info, Net_Profile *tcp_np)
{
if (dht == nullptr) {
if (dht == nullptr || dht_funcs == nullptr || dht_funcs->get_shared_key_sent == nullptr || dht_funcs->get_self_public_key == nullptr || dht_funcs->get_self_secret_key == nullptr) {
return nullptr;
}
@@ -2930,7 +2933,10 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r
temp->ns = ns;
temp->net = net;
temp->tcp_c = new_tcp_connections(log, mem, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info, tcp_np);
temp->dht = dht;
temp->dht_funcs = dht_funcs;
temp->tcp_c = new_tcp_connections(log, mem, rng, ns, mono_time, dht_funcs->get_self_secret_key(dht), proxy_info, tcp_np);
if (temp->tcp_c == nullptr) {
mem_delete(mem, temp);
@@ -2940,8 +2946,6 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r
set_packet_tcp_connection_callback(temp->tcp_c, &tcp_data_callback, temp);
set_oob_packet_tcp_connection_callback(temp->tcp_c, &tcp_oob_callback, temp);
temp->dht = dht;
new_keys(temp);
new_symmetric_key(rng, temp->secret_symmetric_key);
+12 -2
View File
@@ -9,7 +9,7 @@
#ifndef C_TOXCORE_TOXCORE_NET_CRYPTO_H
#define C_TOXCORE_TOXCORE_NET_CRYPTO_H
#include "DHT.h"
#include "DHT.h" // Node_format
#include "TCP_client.h"
#include "TCP_connection.h"
#include "attributes.h"
@@ -24,6 +24,16 @@
extern "C" {
#endif
typedef const uint8_t *_Nullable nc_dht_get_shared_key_sent_cb(void *_Nonnull obj, const uint8_t *_Nonnull public_key);
typedef const uint8_t *_Nonnull nc_dht_get_self_public_key_cb(const void *_Nonnull obj);
typedef const uint8_t *_Nonnull nc_dht_get_self_secret_key_cb(const void *_Nonnull obj);
typedef struct Net_Crypto_DHT_Funcs {
nc_dht_get_shared_key_sent_cb *_Nonnull get_shared_key_sent;
nc_dht_get_self_public_key_cb *_Nonnull get_self_public_key;
nc_dht_get_self_secret_key_cb *_Nonnull get_self_secret_key;
} Net_Crypto_DHT_Funcs;
/*** Crypto payloads. */
/*** Ranges. */
@@ -369,7 +379,7 @@ void load_secret_key(Net_Crypto *_Nonnull c, const uint8_t *_Nonnull sk);
* Sets all the global connection variables to their default values.
*/
Net_Crypto *_Nullable new_net_crypto(const Logger *_Nonnull log, const Memory *_Nonnull mem, const Random *_Nonnull rng, const Network *_Nonnull ns, Mono_Time *_Nonnull mono_time,
Networking_Core *_Nonnull net, DHT *_Nonnull dht,
Networking_Core *_Nonnull net, void *_Nonnull dht, const Net_Crypto_DHT_Funcs *_Nonnull dht_funcs,
const TCP_Proxy_Info *_Nonnull proxy_info, Net_Profile *_Nonnull tcp_np);
/** return the optimal interval in ms for running do_net_crypto. */
+9 -1
View File
@@ -27,6 +27,14 @@ std::optional<std::tuple<IP_Port, uint8_t>> prepare(Fuzz_Data &input)
return {{ipp, iterations}};
}
static constexpr Net_Crypto_DHT_Funcs dht_funcs = {
[](void *dht, const uint8_t *public_key) {
return dht_get_shared_key_sent(static_cast<DHT *>(dht), public_key);
},
[](const void *dht) { return dht_get_self_public_key(static_cast<const DHT *>(dht)); },
[](const void *dht) { return dht_get_self_secret_key(static_cast<const DHT *>(dht)); },
};
void TestNetCrypto(Fuzz_Data &input)
{
const auto prep = prepare(input);
@@ -76,7 +84,7 @@ void TestNetCrypto(Fuzz_Data &input)
const Ptr<Net_Crypto> net_crypto(
new_net_crypto(logger.get(), sys.mem.get(), sys.rng.get(), sys.ns.get(), mono_time.get(),
net.get(), dht.get(), &proxy_info, tcp_np),
net.get(), dht.get(), &dht_funcs, &proxy_info, tcp_np),
kill_net_crypto);
if (net_crypto == nullptr) {
netprof_kill(sys.mem.get(), tcp_np);