Squashed 'external/toxcore/c-toxcore/' changes from d9b8fa6098d..81b1e4f6348

81b1e4f6348 chore: Release v0.2.21-rc.1
9303e2e49a1 chore: Update the pkgsrc versions in the update-versions tool
71ec4b3b1e9 chore: Update the version-sync script to work in a post-tox.api.h world
66da842f753 chore: Add version update script compatible with ci-tools.
199878f7660 chore: Use new bazel script for circle ci.
8278e9cda46 chore: Add release issue template and workflow.
a9bb3a1c4d1 chore: Fix alpine-s390x build.
6e0a641272e chore: Add a source tarball deploy workflow.
4adebe4d8b1 chore: Don't upload ios/macos variants in deploy workflows.
18f1d858ccb chore: Move one of the 3 freebsd builds to post-submit.
432ab60c002 feat: Add a Makefile for the single file deploy build.
a86c0011fd5 chore: Add deploy job for single C file library.
2e7495e8f2a docs: Update changelog format to use the new clog-compatible way.
a682da99e84 chore: Export wasmExports from the wasm binary.
12f34cdff27 chore: Add wasm to the nightly binary deploys.
1451029613f chore: Add strict-abi support for macOS/iOS.
c53c30e09d9 chore: Add time option to manual fuzz trigger.
2ccecdc2a1a chore: Add remaining fuzz tests to cflite.
4626c2e230e test: Add a Net_Crypto fuzz test.
b4a0e617c48 refactor: Use IP string length from ip_ntoa instead of strlen.
b85b91f22f6 cleanup: rename getnodes/sendnodes to nodes request/response This change alignes the naming to be closer to the spec and make it less ambiguous. This change also changes the naming of some private/experimental marked APIs. - tox_callback_dht_nodes_response() - tox_dht_nodes_request() - Tox_Event_Dht_Get_Nodes_Response
f1991aaa029 perf: Use stack allocation for strerror rendering.
3984211ccbf cleanup: remove kicked peers from saved peers list
26a991ed2be fix: ip to string function not accepting tcp families
712861f2e6d cleanup: Make websockify output qtox-compatible logging.
01932ea2f73 chore: Add opus and vpx to the toxcore wasm build.
d29c42ef631 refactor: don't fully discard received DHT nodes. This is mostly forward thinking, where we might introduce other ip families, in addition to ipv4, ipv6, tcp_ipv4 etc.
21e2325934f chore: Fix xcframework tarball creation.
b10c8b766ba chore: Fix xcframework checksum creation.
93787a9322e chore: Add ios/macos framework build.
9f723f891d3 fix: run do_gca also in bootstrap nodes
496cc703556 chore: Support arm64 iphone simulator.
aa0e2a8e928 chore: Add support for more iOS architectures.
13ad8e81cbf chore: Add binary deploy workflows.
c8344726378 refactor: Move tox_log_level out into its own file.
8799bea76c3 cleanup: Mark events/dispatch headers as experimental.
d4164edb548 refactor: Remove tox_types.h; use `struct` tags instead.
d408c982090 refactor: Move `Tox_Options` to `tox_options.h`.
5ab42d41209 chore: Move most cirrus jobs to circleci.
463eeae1144 cleanup: Avoid clashing with global define `DEBUG`.
92cc1e91747 refactor: Make Tox_Options own the passed proxy host and savedata.
f276b397226 test: Add some more asserts for I/O and alloc to succeed.
edb4dfc4869 fix: Don't crash on malloc failures in bin_unpack.
be457d5d0b2 cleanup: Use tox memory for bin_unpack and net_strerror.

git-subtree-dir: external/toxcore/c-toxcore
git-subtree-split: 81b1e4f6348124784088591c4fe9ab41e273031d
This commit is contained in:
Green Sky
2025-03-12 19:16:50 +01:00
parent 3b6bb15e86
commit 3105cc20ef
130 changed files with 3604 additions and 1776 deletions

View File

@ -30,8 +30,8 @@
/** The timeout after which a node is discarded completely. */
#define KILL_NODE_TIMEOUT (BAD_NODE_TIMEOUT + PING_INTERVAL)
/** Ping interval in seconds for each random sending of a get nodes request. */
#define GET_NODE_INTERVAL 20
/** Ping interval in seconds for each random sending of a nodes request. */
#define NODES_REQUEST_INTERVAL 20
#define MAX_PUNCHING_PORTS 48
@ -46,7 +46,7 @@
#define NAT_PING_REQUEST 0
#define NAT_PING_RESPONSE 1
/** Number of get node requests to send to quickly find close nodes. */
/** Number of node requests to send to quickly find close nodes. */
#define MAX_BOOTSTRAP_TIMES 5
// TODO(sudden6): find out why we need multiple callbacks and if we really need 32
@ -66,9 +66,9 @@ struct DHT_Friend {
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
Client_data client_list[MAX_FRIEND_CLIENTS];
/* Time at which the last get_nodes request was sent. */
uint64_t lastgetnode;
/* number of times get_node packets were sent. */
/* Time at which the last nodes request was sent. */
uint64_t last_nodes_request;
/* number of times nodes request packets were sent. */
uint32_t bootstrap_times;
/* Symmetric NAT hole punching stuff. */
@ -104,7 +104,7 @@ struct DHT {
bool lan_discovery_enabled;
Client_data close_clientlist[LCLIENT_LIST];
uint64_t close_lastgetnodes;
uint64_t close_last_nodes_request;
uint32_t close_bootstrap_times;
/* DHT keypair */
@ -130,7 +130,7 @@ struct DHT {
Node_format to_bootstrap[MAX_CLOSE_TO_BOOTSTRAP_NODES];
unsigned int num_to_bootstrap;
dht_get_nodes_response_cb *get_nodes_response;
dht_nodes_response_cb *nodes_response_callback;
};
const uint8_t *dht_friend_public_key(const DHT_Friend *dht_friend)
@ -431,7 +431,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
const int ipp_size = unpack_ip_port(&nodes[num].ip_port, data + len_processed, length - len_processed, tcp_enabled);
if (ipp_size == -1) {
return -1;
break;
}
len_processed += ipp_size;
@ -450,6 +450,10 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
#endif /* NDEBUG */
}
if (num == 0 && max_num_nodes > 0 && length > 0) {
return -1;
}
if (processed_data_len != nullptr) {
*processed_data_len = len_processed;
}
@ -708,7 +712,7 @@ static void get_close_nodes_inner(
}
/**
* Find MAX_SENT_NODES nodes closest to the public_key for the send nodes request:
* Find MAX_SENT_NODES nodes closest to the public_key for the nodes request:
* put them in the nodes_list and return how many were found.
*
* want_announce: return only nodes which implement the dht announcements protocol.
@ -1131,7 +1135,7 @@ static bool is_pk_in_close_list(const DHT *dht, const uint8_t *public_key, const
ip_port);
}
/** @brief Check if the node obtained with a get_nodes with public_key should be pinged.
/** @brief Check if the node obtained from a nodes response with public_key should be pinged.
*
* NOTE: for best results call it after addto_lists.
*
@ -1139,7 +1143,7 @@ static bool is_pk_in_close_list(const DHT *dht, const uint8_t *public_key, const
* return true if it should.
*/
non_null()
static bool ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port)
static bool ping_node_from_nodes_response_ok(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port)
{
bool ret = false;
@ -1310,7 +1314,7 @@ static void returnedip_ports(DHT *dht, const IP_Port *ip_port, const uint8_t *pu
}
}
bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id)
bool dht_send_nodes_request(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id)
{
/* Check if packet is going to be sent to ourself. */
if (pk_equal(public_key, dht->self_public_key)) {
@ -1345,21 +1349,21 @@ bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, c
const uint8_t *shared_key = dht_get_shared_key_sent(dht, public_key);
const int len = dht_create_packet(dht->mem, dht->rng,
dht->self_public_key, shared_key, NET_PACKET_GET_NODES,
dht->self_public_key, shared_key, NET_PACKET_NODES_REQUEST,
plain, sizeof(plain), data, sizeof(data));
if (len != sizeof(data)) {
LOGGER_ERROR(dht->log, "getnodes packet encryption failed");
LOGGER_ERROR(dht->log, "nodes request packet encryption failed");
return false;
}
return sendpacket(dht->net, ip_port, data, len) > 0;
}
/** Send a send nodes response: message for IPv6 nodes */
/** Send a nodes response */
non_null()
static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id,
const uint8_t *sendback_data, uint16_t length, const uint8_t *shared_encryption_key)
static int send_nodes_response(const DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id,
const uint8_t *sendback_data, uint16_t length, const uint8_t *shared_encryption_key)
{
/* Check if packet is going to be sent to ourself. */
if (pk_equal(public_key, dht->self_public_key)) {
@ -1396,7 +1400,7 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t
VLA(uint8_t, data, data_size);
const int len = dht_create_packet(dht->mem, dht->rng,
dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6,
dht->self_public_key, shared_encryption_key, NET_PACKET_NODES_RESPONSE,
plain, 1 + nodes_length + length, data, data_size);
if (len < 0 || (uint32_t)len != data_size) {
@ -1409,7 +1413,7 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t
#define CRYPTO_NODE_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint64_t))
non_null()
static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
static int handle_nodes_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{
DHT *const dht = (DHT *)object;
@ -1436,16 +1440,16 @@ static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *p
return 1;
}
sendnodes_ipv6(dht, source, packet + 1, plain, plain + CRYPTO_PUBLIC_KEY_SIZE, sizeof(uint64_t), shared_key);
send_nodes_response(dht, source, packet + 1, plain, plain + CRYPTO_PUBLIC_KEY_SIZE, sizeof(uint64_t), shared_key);
ping_add(dht->ping, packet + 1, source);
return 0;
}
/** Return true if we sent a getnode packet to the peer associated with the supplied info. */
/** Return true if we sent a nodes request packet to the peer associated with the supplied info. */
non_null()
static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, const IP_Port *node_ip_port, uint64_t ping_id)
static bool sent_nodes_request_to_node(DHT *dht, const uint8_t *public_key, const IP_Port *node_ip_port, uint64_t ping_id)
{
uint8_t data[sizeof(Node_format) * 2];
@ -1463,8 +1467,8 @@ static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, const IP_P
}
non_null()
static bool handle_sendnodes_core(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
Node_format *plain_nodes, uint16_t size_plain_nodes, uint32_t *num_nodes_out)
static bool handle_nodes_response_core(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
Node_format *plain_nodes, uint16_t size_plain_nodes, uint32_t *num_nodes_out)
{
DHT *const dht = (DHT *)object;
const uint32_t cid_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + 1 + sizeof(uint64_t) + CRYPTO_MAC_SIZE;
@ -1505,7 +1509,7 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin
uint64_t ping_id;
memcpy(&ping_id, plain + 1 + data_size, sizeof(ping_id));
if (!sent_getnode_to_node(dht, packet + 1, source, ping_id)) {
if (!sent_nodes_request_to_node(dht, packet + 1, source, ping_id)) {
return false;
}
@ -1533,14 +1537,14 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin
}
non_null()
static int handle_sendnodes_ipv6(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
static int handle_nodes_response(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
void *userdata)
{
DHT *const dht = (DHT *)object;
Node_format plain_nodes[MAX_SENT_NODES];
uint32_t num_nodes;
if (!handle_sendnodes_core(object, source, packet, length, plain_nodes, MAX_SENT_NODES, &num_nodes)) {
if (!handle_nodes_response_core(object, source, packet, length, plain_nodes, MAX_SENT_NODES, &num_nodes)) {
return 1;
}
@ -1550,11 +1554,11 @@ static int handle_sendnodes_ipv6(void *object, const IP_Port *source, const uint
for (uint32_t i = 0; i < num_nodes; ++i) {
if (ipport_isset(&plain_nodes[i].ip_port)) {
ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key, &plain_nodes[i].ip_port);
ping_node_from_nodes_response_ok(dht, plain_nodes[i].public_key, &plain_nodes[i].ip_port);
returnedip_ports(dht, &plain_nodes[i].ip_port, plain_nodes[i].public_key, packet + 1);
if (dht->get_nodes_response != nullptr) {
dht->get_nodes_response(dht, &plain_nodes[i], userdata);
if (dht->nodes_response_callback != nullptr) {
dht->nodes_response_callback(dht, &plain_nodes[i], userdata);
}
}
}
@ -1767,7 +1771,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
if (mono_time_is_timeout(dht->mono_time, assoc->last_pinged, PING_INTERVAL)) {
const IP_Port *target = &assoc->ip_port;
const uint8_t *target_key = client->public_key;
dht_getnodes(dht, target, target_key, public_key);
dht_send_nodes_request(dht, target, target_key, public_key);
assoc->last_pinged = temp_time;
}
@ -1792,7 +1796,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
sort_client_list(dht->mem, list, dht->cur_time, list_count, public_key);
}
if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL)
if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, NODES_REQUEST_INTERVAL)
|| *bootstrap_times < MAX_BOOTSTRAP_TIMES)) {
uint32_t rand_node = random_range_u32(dht->rng, num_nodes);
@ -1802,7 +1806,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
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);
dht_send_nodes_request(dht, target, target_key, public_key);
*lastgetnode = temp_time;
++*bootstrap_times;
@ -1815,7 +1819,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
/** @brief Ping each client in the "friends" list every PING_INTERVAL seconds.
*
* Send a get nodes request every GET_NODE_INTERVAL seconds to a random good
* Send a nodes request every NODES_REQUEST_INTERVAL seconds to a random good
* node for each "friend" in our "friends" list.
*/
non_null()
@ -1825,31 +1829,31 @@ static void do_dht_friends(DHT *dht)
DHT_Friend *const dht_friend = &dht->friends_list[i];
for (size_t j = 0; j < dht_friend->num_to_bootstrap; ++j) {
dht_getnodes(dht, &dht_friend->to_bootstrap[j].ip_port, dht_friend->to_bootstrap[j].public_key, dht_friend->public_key);
dht_send_nodes_request(dht, &dht_friend->to_bootstrap[j].ip_port, dht_friend->to_bootstrap[j].public_key, dht_friend->public_key);
}
dht_friend->num_to_bootstrap = 0;
do_ping_and_sendnode_requests(dht, &dht_friend->lastgetnode, dht_friend->public_key, dht_friend->client_list,
do_ping_and_sendnode_requests(dht, &dht_friend->last_nodes_request, dht_friend->public_key, dht_friend->client_list,
MAX_FRIEND_CLIENTS, &dht_friend->bootstrap_times, true);
}
}
/** @brief Ping each client in the close nodes list every PING_INTERVAL seconds.
*
* Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list.
* Send a nodes request every NODES_REQUEST_INTERVAL seconds to a random good node in the list.
*/
non_null()
static void do_close(DHT *dht)
{
for (size_t i = 0; i < dht->num_to_bootstrap; ++i) {
dht_getnodes(dht, &dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key);
dht_send_nodes_request(dht, &dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key);
}
dht->num_to_bootstrap = 0;
const uint8_t not_killed = do_ping_and_sendnode_requests(
dht, &dht->close_lastgetnodes, dht->self_public_key, dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times,
dht, &dht->close_last_nodes_request, dht->self_public_key, dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times,
false);
if (not_killed != 0) {
@ -1883,7 +1887,7 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key)
return true;
}
return dht_getnodes(dht, ip_port, public_key, dht->self_public_key);
return dht_send_nodes_request(dht, ip_port, public_key, dht->self_public_key);
}
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
@ -2530,9 +2534,9 @@ static int cryptopacket_handle(void *object, const IP_Port *source, const uint8_
return 1;
}
void dht_callback_get_nodes_response(DHT *dht, dht_get_nodes_response_cb *function)
void dht_callback_nodes_response(DHT *dht, dht_nodes_response_cb *function)
{
dht->get_nodes_response = function;
dht->nodes_response_callback = function;
}
non_null(1, 2, 3) nullable(5)
@ -2593,8 +2597,8 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw
return nullptr;
}
networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
networking_registerhandler(dht->net, NET_PACKET_NODES_REQUEST, &handle_nodes_request, dht);
networking_registerhandler(dht->net, NET_PACKET_NODES_RESPONSE, &handle_nodes_response, dht);
networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht);
networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_lan_discovery, dht);
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_nat_ping, dht);
@ -2672,8 +2676,8 @@ void kill_dht(DHT *dht)
return;
}
networking_registerhandler(dht->net, NET_PACKET_GET_NODES, nullptr, nullptr);
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, nullptr, nullptr);
networking_registerhandler(dht->net, NET_PACKET_NODES_REQUEST, nullptr, nullptr);
networking_registerhandler(dht->net, NET_PACKET_NODES_RESPONSE, nullptr, nullptr);
networking_registerhandler(dht->net, NET_PACKET_CRYPTO, nullptr, nullptr);
networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, nullptr, nullptr);
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, nullptr, nullptr);