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:
@ -6,6 +6,8 @@ exports_files(
|
||||
"tox.h",
|
||||
"tox_dispatch.h",
|
||||
"tox_events.h",
|
||||
"tox_log_level.h",
|
||||
"tox_options.h",
|
||||
"tox_private.h",
|
||||
],
|
||||
visibility = ["//c-toxcore:__subpackages__"],
|
||||
@ -192,6 +194,7 @@ cc_library(
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
":mem",
|
||||
"//c-toxcore/third_party:cmp",
|
||||
],
|
||||
)
|
||||
@ -204,6 +207,7 @@ cc_test(
|
||||
":bin_pack",
|
||||
":bin_unpack",
|
||||
":logger",
|
||||
":mem",
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
@ -766,6 +770,23 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_fuzz_test(
|
||||
name = "net_crypto_fuzz_test",
|
||||
size = "small",
|
||||
testonly = True,
|
||||
srcs = ["net_crypto_fuzz_test.cc"],
|
||||
corpus = ["//tools/toktok-fuzzer/corpus:net_crypto_fuzz_test"],
|
||||
deps = [
|
||||
":DHT",
|
||||
":TCP_client",
|
||||
":mem_test_util",
|
||||
":net_crypto",
|
||||
":network",
|
||||
"//c-toxcore/testing/fuzzing:fuzz_support",
|
||||
"//c-toxcore/testing/fuzzing:fuzz_tox",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "onion_announce",
|
||||
srcs = ["onion_announce.c"],
|
||||
@ -1070,6 +1091,25 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "tox_options",
|
||||
srcs = ["tox_options.c"],
|
||||
hdrs = ["tox_options.h"],
|
||||
copts = ["-UTOX_HIDE_DEPRECATED"],
|
||||
visibility = ["//c-toxcore:__subpackages__"],
|
||||
deps = [
|
||||
":ccompat",
|
||||
":tox_log_level",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "tox_log_level",
|
||||
srcs = ["tox_log_level.c"],
|
||||
hdrs = ["tox_log_level.h"],
|
||||
visibility = ["//c-toxcore:__subpackages__"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "tox",
|
||||
srcs = [
|
||||
@ -1102,6 +1142,8 @@ cc_library(
|
||||
":network",
|
||||
":onion_client",
|
||||
":state",
|
||||
":tox_log_level",
|
||||
":tox_options",
|
||||
":util",
|
||||
"//c-toxcore/toxencryptsave:defines",
|
||||
"@pthread",
|
||||
@ -1115,6 +1157,8 @@ cc_test(
|
||||
deps = [
|
||||
":crypto_core",
|
||||
":tox",
|
||||
":tox_log_level",
|
||||
":tox_options",
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
|
@ -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);
|
||||
|
@ -36,7 +36,7 @@ extern "C" {
|
||||
|
||||
#define MAX_CLOSE_TO_BOOTSTRAP_NODES 8
|
||||
|
||||
/** The max number of nodes to send with send nodes. */
|
||||
/** The max number of nodes to send with nodes response. */
|
||||
#define MAX_SENT_NODES 4
|
||||
|
||||
/** Ping timeout in seconds */
|
||||
@ -259,21 +259,21 @@ non_null()
|
||||
const uint8_t *dht_get_shared_key_sent(DHT *dht, const uint8_t *public_key);
|
||||
|
||||
/**
|
||||
* Sends a getnodes request to `ip_port` with the public key `public_key` for nodes
|
||||
* Sends a nodes request to `ip_port` with the public key `public_key` for nodes
|
||||
* that are close to `client_id`.
|
||||
*
|
||||
* @retval true on success.
|
||||
*/
|
||||
non_null()
|
||||
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);
|
||||
|
||||
typedef void dht_ip_cb(void *object, int32_t number, const IP_Port *ip_port);
|
||||
|
||||
typedef void dht_get_nodes_response_cb(const DHT *dht, const Node_format *node, void *user_data);
|
||||
typedef void dht_nodes_response_cb(const DHT *dht, const Node_format *node, void *user_data);
|
||||
|
||||
/** Sets the callback to be triggered on a getnodes response. */
|
||||
/** Sets the callback to be triggered on a nodes response. */
|
||||
non_null(1) nullable(2)
|
||||
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);
|
||||
|
||||
/** @brief Add a new friend to the friends list.
|
||||
* @param public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long.
|
||||
@ -390,7 +390,7 @@ void do_dht(DHT *dht);
|
||||
* Use these two functions to bootstrap the client.
|
||||
*/
|
||||
/**
|
||||
* @brief Sends a "get nodes" request to the given node with ip, port and public_key
|
||||
* @brief Sends a "nodes request" to the given node with ip, port and public_key
|
||||
* to setup connections
|
||||
*/
|
||||
non_null()
|
||||
@ -398,7 +398,7 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key);
|
||||
|
||||
/** @brief Resolves address into an IP address.
|
||||
*
|
||||
* If successful, sends a "get nodes" request to the given node with ip, port
|
||||
* If successful, sends a "nodes request" to the given node with ip, port
|
||||
* and public_key to setup connections
|
||||
*
|
||||
* @param address can be a hostname or an IP address (IPv4 or IPv6).
|
||||
|
@ -1,26 +1,20 @@
|
||||
lib_LTLIBRARIES += libtoxcore.la
|
||||
|
||||
libtoxcore_la_include_HEADERS = \
|
||||
../toxcore/tox.h
|
||||
../toxcore/tox.h \
|
||||
../toxcore/tox_options.h
|
||||
|
||||
libtoxcore_la_includedir = $(includedir)/tox
|
||||
|
||||
libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
|
||||
../third_party/cmp/cmp.h \
|
||||
../toxcore/attributes.h \
|
||||
../toxcore/bin_pack.c \
|
||||
../toxcore/bin_pack.h \
|
||||
../toxcore/bin_unpack.c \
|
||||
../toxcore/bin_unpack.h \
|
||||
../toxcore/ccompat.c \
|
||||
../toxcore/ccompat.h \
|
||||
../toxcore/events/conference_connected.c \
|
||||
../toxcore/events/conference_invite.c \
|
||||
../toxcore/events/conference_message.c \
|
||||
../toxcore/events/conference_peer_list_changed.c \
|
||||
../toxcore/events/conference_peer_name.c \
|
||||
../toxcore/events/conference_title.c \
|
||||
../toxcore/events/dht_get_nodes_response.c \
|
||||
../toxcore/events/dht_nodes_response.c \
|
||||
../toxcore/events/events_alloc.c \
|
||||
../toxcore/events/events_alloc.h \
|
||||
../toxcore/events/file_chunk_request.c \
|
||||
@ -56,97 +50,108 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
|
||||
../toxcore/events/group_topic.c \
|
||||
../toxcore/events/group_topic_lock.c \
|
||||
../toxcore/events/group_voice_state.c \
|
||||
../toxcore/DHT.h \
|
||||
../toxcore/DHT.c \
|
||||
../toxcore/mem.h \
|
||||
../toxcore/mem.c \
|
||||
../toxcore/mono_time.h \
|
||||
../toxcore/mono_time.c \
|
||||
../toxcore/network.h \
|
||||
../toxcore/network.c \
|
||||
../toxcore/crypto_core.h \
|
||||
../toxcore/crypto_core.c \
|
||||
../toxcore/crypto_core_pack.h \
|
||||
../toxcore/announce.c \
|
||||
../toxcore/announce.h \
|
||||
../toxcore/attributes.h \
|
||||
../toxcore/bin_pack.c \
|
||||
../toxcore/bin_pack.h \
|
||||
../toxcore/bin_unpack.c \
|
||||
../toxcore/bin_unpack.h \
|
||||
../toxcore/ccompat.c \
|
||||
../toxcore/ccompat.h \
|
||||
../toxcore/crypto_core_pack.c \
|
||||
../toxcore/timed_auth.h \
|
||||
../toxcore/timed_auth.c \
|
||||
../toxcore/ping_array.h \
|
||||
../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 \
|
||||
../toxcore/LAN_discovery.c \
|
||||
../toxcore/friend_connection.h \
|
||||
../toxcore/crypto_core_pack.h \
|
||||
../toxcore/crypto_core.c \
|
||||
../toxcore/crypto_core.h \
|
||||
../toxcore/DHT.c \
|
||||
../toxcore/DHT.h \
|
||||
../toxcore/forwarding.c \
|
||||
../toxcore/forwarding.h \
|
||||
../toxcore/friend_connection.c \
|
||||
../toxcore/Messenger.h \
|
||||
../toxcore/Messenger.c \
|
||||
../toxcore/ping.h \
|
||||
../toxcore/ping.c \
|
||||
../toxcore/shared_key_cache.h \
|
||||
../toxcore/shared_key_cache.c \
|
||||
../toxcore/sort.h \
|
||||
../toxcore/sort.c \
|
||||
../toxcore/state.h \
|
||||
../toxcore/state.c \
|
||||
../toxcore/tox.h \
|
||||
../toxcore/tox.c \
|
||||
../toxcore/tox_dispatch.h \
|
||||
../toxcore/tox_dispatch.c \
|
||||
../toxcore/tox_event.h \
|
||||
../toxcore/tox_event.c \
|
||||
../toxcore/tox_events.h \
|
||||
../toxcore/tox_events.c \
|
||||
../toxcore/tox_pack.h \
|
||||
../toxcore/tox_pack.c \
|
||||
../toxcore/tox_unpack.h \
|
||||
../toxcore/tox_unpack.c \
|
||||
../toxcore/tox_private.c \
|
||||
../toxcore/tox_private.h \
|
||||
../toxcore/tox_struct.h \
|
||||
../toxcore/tox_api.c \
|
||||
../toxcore/util.h \
|
||||
../toxcore/util.c \
|
||||
../toxcore/group.h \
|
||||
../toxcore/group.c \
|
||||
../toxcore/group_announce.h \
|
||||
../toxcore/friend_connection.h \
|
||||
../toxcore/friend_requests.c \
|
||||
../toxcore/friend_requests.h \
|
||||
../toxcore/group_announce.c \
|
||||
../toxcore/group_onion_announce.c \
|
||||
../toxcore/group_onion_announce.h \
|
||||
../toxcore/group_chats.h \
|
||||
../toxcore/group_announce.h \
|
||||
../toxcore/group_chats.c \
|
||||
../toxcore/group_chats.h \
|
||||
../toxcore/group_common.h \
|
||||
../toxcore/group_connection.c \
|
||||
../toxcore/group_connection.h \
|
||||
../toxcore/group_pack.c \
|
||||
../toxcore/group_pack.h \
|
||||
../toxcore/group_moderation.c \
|
||||
../toxcore/group_moderation.h \
|
||||
../toxcore/onion.h \
|
||||
../toxcore/onion.c \
|
||||
../toxcore/logger.h \
|
||||
../toxcore/logger.c \
|
||||
../toxcore/onion_announce.h \
|
||||
../toxcore/onion_announce.c \
|
||||
../toxcore/onion_client.h \
|
||||
../toxcore/onion_client.c \
|
||||
../toxcore/announce.h \
|
||||
../toxcore/announce.c \
|
||||
../toxcore/forwarding.h \
|
||||
../toxcore/forwarding.c \
|
||||
../toxcore/TCP_client.h \
|
||||
../toxcore/TCP_client.c \
|
||||
../toxcore/TCP_common.h \
|
||||
../toxcore/TCP_common.c \
|
||||
../toxcore/TCP_server.h \
|
||||
../toxcore/TCP_server.c \
|
||||
../toxcore/TCP_connection.h \
|
||||
../toxcore/TCP_connection.c \
|
||||
../toxcore/group_onion_announce.c \
|
||||
../toxcore/group_onion_announce.h \
|
||||
../toxcore/group_pack.c \
|
||||
../toxcore/group_pack.h \
|
||||
../toxcore/group.c \
|
||||
../toxcore/group.h \
|
||||
../toxcore/LAN_discovery.c \
|
||||
../toxcore/LAN_discovery.h \
|
||||
../toxcore/list.c \
|
||||
../toxcore/list.h
|
||||
../toxcore/list.h \
|
||||
../toxcore/logger.c \
|
||||
../toxcore/logger.h \
|
||||
../toxcore/mem.c \
|
||||
../toxcore/mem.h \
|
||||
../toxcore/Messenger.c \
|
||||
../toxcore/Messenger.h \
|
||||
../toxcore/mono_time.c \
|
||||
../toxcore/mono_time.h \
|
||||
../toxcore/net_crypto.c \
|
||||
../toxcore/net_crypto.h \
|
||||
../toxcore/net_profile.c \
|
||||
../toxcore/net_profile.h \
|
||||
../toxcore/network.c \
|
||||
../toxcore/network.h \
|
||||
../toxcore/onion_announce.c \
|
||||
../toxcore/onion_announce.h \
|
||||
../toxcore/onion_client.c \
|
||||
../toxcore/onion_client.h \
|
||||
../toxcore/onion.c \
|
||||
../toxcore/onion.h \
|
||||
../toxcore/ping_array.c \
|
||||
../toxcore/ping_array.h \
|
||||
../toxcore/ping.c \
|
||||
../toxcore/ping.h \
|
||||
../toxcore/shared_key_cache.c \
|
||||
../toxcore/shared_key_cache.h \
|
||||
../toxcore/sort.c \
|
||||
../toxcore/sort.h \
|
||||
../toxcore/state.c \
|
||||
../toxcore/state.h \
|
||||
../toxcore/TCP_client.c \
|
||||
../toxcore/TCP_client.h \
|
||||
../toxcore/TCP_common.c \
|
||||
../toxcore/TCP_common.h \
|
||||
../toxcore/TCP_connection.c \
|
||||
../toxcore/TCP_connection.h \
|
||||
../toxcore/TCP_server.c \
|
||||
../toxcore/TCP_server.h \
|
||||
../toxcore/timed_auth.c \
|
||||
../toxcore/timed_auth.h \
|
||||
../toxcore/tox_api.c \
|
||||
../toxcore/tox_dispatch.c \
|
||||
../toxcore/tox_dispatch.h \
|
||||
../toxcore/tox_event.c \
|
||||
../toxcore/tox_event.h \
|
||||
../toxcore/tox_events.c \
|
||||
../toxcore/tox_events.h \
|
||||
../toxcore/tox_log_level.c \
|
||||
../toxcore/tox_log_level.h \
|
||||
../toxcore/tox_options.c \
|
||||
../toxcore/tox_options.h \
|
||||
../toxcore/tox_pack.c \
|
||||
../toxcore/tox_pack.h \
|
||||
../toxcore/tox_private.c \
|
||||
../toxcore/tox_private.h \
|
||||
../toxcore/tox_struct.h \
|
||||
../toxcore/tox_unpack.c \
|
||||
../toxcore/tox_unpack.h \
|
||||
../toxcore/tox.c \
|
||||
../toxcore/tox.h \
|
||||
../toxcore/util.c \
|
||||
../toxcore/util.h
|
||||
|
||||
libtoxcore_la_CFLAGS = -I$(top_srcdir) \
|
||||
-I$(top_srcdir)/toxcore \
|
||||
|
@ -3171,7 +3171,7 @@ static bool handle_groups_load(void *obj, Bin_Unpack *bu)
|
||||
non_null()
|
||||
static State_Load_Status groups_load(Messenger *m, const uint8_t *data, uint32_t length)
|
||||
{
|
||||
if (!bin_unpack_obj(handle_groups_load, m, data, length)) {
|
||||
if (!bin_unpack_obj(m->mem, handle_groups_load, m, data, length)) {
|
||||
LOGGER_ERROR(m->log, "msgpack failed to unpack groupchats array");
|
||||
return STATE_LOAD_STATUS_ERROR;
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ int read_tcp_packet(
|
||||
* return -1 on failure.
|
||||
*/
|
||||
non_null()
|
||||
static uint16_t read_tcp_length(const Logger *logger, const Memory *mem, const Network *ns, Socket sock, const IP_Port *ip_port)
|
||||
static uint16_t read_tcp_length(const Logger *logger, const Network *ns, Socket sock, const IP_Port *ip_port)
|
||||
{
|
||||
const uint16_t count = net_socket_data_recv_buffer(ns, sock);
|
||||
|
||||
@ -275,7 +275,7 @@ int read_packet_tcp_secure_connection(
|
||||
uint16_t max_len, const IP_Port *ip_port)
|
||||
{
|
||||
if (*next_packet_length == 0) {
|
||||
const uint16_t len = read_tcp_length(logger, mem, ns, sock, ip_port);
|
||||
const uint16_t len = read_tcp_length(logger, ns, sock, ip_port);
|
||||
|
||||
if (len == (uint16_t) -1) {
|
||||
return -1;
|
||||
|
@ -920,7 +920,7 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock)
|
||||
}
|
||||
|
||||
non_null()
|
||||
static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns, Family family, uint16_t port)
|
||||
static Socket new_listening_tcp_socket(const Logger *logger, const Memory *mem, const Network *ns, Family family, uint16_t port)
|
||||
{
|
||||
const Socket sock = net_socket(ns, family, TOX_SOCK_STREAM, TOX_PROTO_TCP);
|
||||
|
||||
@ -942,10 +942,9 @@ static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns,
|
||||
ok = ok && bind_to_port(ns, sock, family, port) && (net_listen(ns, sock, TCP_MAX_BACKLOG) == 0);
|
||||
|
||||
if (!ok) {
|
||||
char *const error = net_new_strerror(net_error());
|
||||
Net_Strerror error_str;
|
||||
LOGGER_WARNING(logger, "could not bind to TCP port %d (family = %d): %s",
|
||||
port, family.value, error != nullptr ? error : "(null)");
|
||||
net_kill_strerror(error);
|
||||
port, family.value, net_strerror(net_error(), &error_str));
|
||||
kill_sock(ns, sock);
|
||||
return net_invalid_socket();
|
||||
}
|
||||
@ -1015,7 +1014,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
|
||||
const Family family = ipv6_enabled ? net_family_ipv6() : net_family_ipv4();
|
||||
|
||||
for (uint32_t i = 0; i < num_sockets; ++i) {
|
||||
const Socket sock = new_listening_tcp_socket(logger, ns, family, ports[i]);
|
||||
const Socket sock = new_listening_tcp_socket(logger, mem, ns, family, ports[i]);
|
||||
|
||||
if (!sock_valid(sock)) {
|
||||
continue;
|
||||
|
@ -3,11 +3,10 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "bin_unpack.h"
|
||||
#include "logger.h"
|
||||
#include "mem.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -24,6 +23,7 @@ TEST(BinPack, TooSmallBufferIsNotExceeded)
|
||||
|
||||
TEST(BinPack, PackedUint64CanBeUnpacked)
|
||||
{
|
||||
const Memory *mem = os_memory();
|
||||
const uint64_t orig = 1234567812345678LL;
|
||||
std::array<uint8_t, 8> buf;
|
||||
EXPECT_TRUE(bin_pack_obj(
|
||||
@ -34,6 +34,7 @@ TEST(BinPack, PackedUint64CanBeUnpacked)
|
||||
|
||||
uint64_t unpacked = 0;
|
||||
EXPECT_TRUE(bin_unpack_obj(
|
||||
mem,
|
||||
[](void *obj, Bin_Unpack *bu) {
|
||||
return bin_unpack_u64_b(bu, static_cast<uint64_t *>(obj));
|
||||
},
|
||||
@ -43,6 +44,7 @@ TEST(BinPack, PackedUint64CanBeUnpacked)
|
||||
|
||||
TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32)
|
||||
{
|
||||
const Memory *mem = os_memory();
|
||||
const uint8_t orig = 123;
|
||||
std::array<uint8_t, 2> buf;
|
||||
EXPECT_TRUE(bin_pack_obj(
|
||||
@ -53,6 +55,7 @@ TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32)
|
||||
|
||||
uint32_t unpacked = 0;
|
||||
EXPECT_TRUE(bin_unpack_obj(
|
||||
mem,
|
||||
[](void *obj, Bin_Unpack *bu) { return bin_unpack_u32(bu, static_cast<uint32_t *>(obj)); },
|
||||
&unpacked, buf.data(), buf.size()));
|
||||
EXPECT_EQ(unpacked, 123);
|
||||
@ -60,6 +63,7 @@ TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32)
|
||||
|
||||
TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough)
|
||||
{
|
||||
const Memory *mem = os_memory();
|
||||
const uint32_t orig = 123;
|
||||
std::array<uint8_t, 2> buf;
|
||||
EXPECT_TRUE(bin_pack_obj(
|
||||
@ -70,6 +74,7 @@ TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough)
|
||||
|
||||
uint8_t unpacked = 0;
|
||||
EXPECT_TRUE(bin_unpack_obj(
|
||||
mem,
|
||||
[](void *obj, Bin_Unpack *bu) { return bin_unpack_u08(bu, static_cast<uint8_t *>(obj)); },
|
||||
&unpacked, buf.data(), buf.size()));
|
||||
|
||||
@ -78,6 +83,7 @@ TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough)
|
||||
|
||||
TEST(BinPack, LargeMsgPackedUint32CannotBeUnpackedAsUint8)
|
||||
{
|
||||
const Memory *mem = os_memory();
|
||||
const uint32_t orig = 1234567;
|
||||
std::array<uint8_t, 5> buf;
|
||||
EXPECT_TRUE(bin_pack_obj(
|
||||
@ -88,12 +94,14 @@ TEST(BinPack, LargeMsgPackedUint32CannotBeUnpackedAsUint8)
|
||||
|
||||
uint8_t unpacked = 0;
|
||||
EXPECT_FALSE(bin_unpack_obj(
|
||||
mem,
|
||||
[](void *obj, Bin_Unpack *bu) { return bin_unpack_u08(bu, static_cast<uint8_t *>(obj)); },
|
||||
&unpacked, buf.data(), buf.size()));
|
||||
}
|
||||
|
||||
TEST(BinPack, BinCanHoldPackedInts)
|
||||
{
|
||||
const Memory *mem = os_memory();
|
||||
struct Stuff {
|
||||
uint64_t u64;
|
||||
uint16_t u16;
|
||||
@ -113,6 +121,7 @@ TEST(BinPack, BinCanHoldPackedInts)
|
||||
|
||||
Stuff unpacked;
|
||||
EXPECT_TRUE(bin_unpack_obj(
|
||||
mem,
|
||||
[](void *obj, Bin_Unpack *bu) {
|
||||
Stuff *stuff = static_cast<Stuff *>(obj);
|
||||
uint32_t size;
|
||||
@ -128,6 +137,7 @@ TEST(BinPack, BinCanHoldPackedInts)
|
||||
|
||||
TEST(BinPack, BinCanHoldArbitraryData)
|
||||
{
|
||||
const Memory *mem = os_memory();
|
||||
std::array<uint8_t, 7> buf;
|
||||
EXPECT_TRUE(bin_pack_obj(
|
||||
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
|
||||
@ -138,6 +148,7 @@ TEST(BinPack, BinCanHoldArbitraryData)
|
||||
|
||||
std::array<uint8_t, 5> str;
|
||||
EXPECT_TRUE(bin_unpack_obj(
|
||||
mem,
|
||||
[](void *obj, Bin_Unpack *bu) {
|
||||
uint8_t *data = static_cast<uint8_t *>(obj);
|
||||
return bin_unpack_bin_fixed(bu, data, 5);
|
||||
@ -148,10 +159,12 @@ TEST(BinPack, BinCanHoldArbitraryData)
|
||||
|
||||
TEST(BinPack, OversizedArrayFailsUnpack)
|
||||
{
|
||||
const Memory *mem = os_memory();
|
||||
std::array<uint8_t, 1> buf = {0x91};
|
||||
|
||||
uint32_t size;
|
||||
EXPECT_FALSE(bin_unpack_obj(
|
||||
mem,
|
||||
[](void *obj, Bin_Unpack *bu) {
|
||||
uint32_t *size_ptr = static_cast<uint32_t *>(obj);
|
||||
return bin_unpack_array(bu, size_ptr);
|
||||
|
@ -5,14 +5,16 @@
|
||||
#include "bin_unpack.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../third_party/cmp/cmp.h"
|
||||
#include "attributes.h"
|
||||
#include "ccompat.h"
|
||||
#include "mem.h"
|
||||
|
||||
struct Bin_Unpack {
|
||||
const Memory *mem;
|
||||
|
||||
const uint8_t *bytes;
|
||||
uint32_t bytes_size;
|
||||
cmp_ctx_t ctx;
|
||||
@ -54,17 +56,18 @@ static size_t null_writer(cmp_ctx_t *ctx, const void *data, size_t count)
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void bin_unpack_init(Bin_Unpack *bu, const uint8_t *buf, uint32_t buf_size)
|
||||
static void bin_unpack_init(Bin_Unpack *bu, const Memory *mem, const uint8_t *buf, uint32_t buf_size)
|
||||
{
|
||||
bu->mem = mem;
|
||||
bu->bytes = buf;
|
||||
bu->bytes_size = buf_size;
|
||||
cmp_init(&bu->ctx, bu, buf_reader, buf_skipper, null_writer);
|
||||
}
|
||||
|
||||
bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size)
|
||||
bool bin_unpack_obj(const Memory *mem, bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size)
|
||||
{
|
||||
Bin_Unpack bu;
|
||||
bin_unpack_init(&bu, buf, buf_size);
|
||||
bin_unpack_init(&bu, mem, buf, buf_size);
|
||||
return callback(obj, &bu);
|
||||
}
|
||||
|
||||
@ -120,10 +123,14 @@ bool bin_unpack_bin(Bin_Unpack *bu, uint8_t **data_ptr, uint32_t *data_length_pt
|
||||
// There aren't as many bytes as this bin claims to want to allocate.
|
||||
return false;
|
||||
}
|
||||
uint8_t *const data = (uint8_t *)malloc(bin_size);
|
||||
uint8_t *const data = (uint8_t *)mem_balloc(bu->mem, bin_size);
|
||||
|
||||
if (data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!bin_unpack_bin_b(bu, data, bin_size)) {
|
||||
free(data);
|
||||
mem_delete(bu->mem, data);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -46,7 +47,7 @@ typedef bool bin_unpack_cb(void *obj, Bin_Unpack *bu);
|
||||
* @retval false if an error occurred (e.g. buffer overrun).
|
||||
*/
|
||||
non_null()
|
||||
bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size);
|
||||
bool bin_unpack_obj(const Memory *mem, bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size);
|
||||
|
||||
/** @brief Start unpacking a MessagePack array.
|
||||
*
|
||||
|
@ -1,227 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2022-2025 The TokTok team.
|
||||
*/
|
||||
|
||||
#include "events_alloc.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../attributes.h"
|
||||
#include "../bin_pack.h"
|
||||
#include "../bin_unpack.h"
|
||||
#include "../ccompat.h"
|
||||
#include "../mem.h"
|
||||
#include "../tox.h"
|
||||
#include "../tox_event.h"
|
||||
#include "../tox_events.h"
|
||||
#include "../tox_private.h"
|
||||
|
||||
/*****************************************************
|
||||
*
|
||||
* :: struct and accessors
|
||||
*
|
||||
*****************************************************/
|
||||
|
||||
struct Tox_Event_Dht_Get_Nodes_Response {
|
||||
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
|
||||
uint8_t *ip;
|
||||
uint32_t ip_length;
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
non_null()
|
||||
static bool tox_event_dht_get_nodes_response_set_public_key(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE])
|
||||
{
|
||||
memcpy(dht_get_nodes_response->public_key, public_key, TOX_PUBLIC_KEY_SIZE);
|
||||
return true;
|
||||
}
|
||||
const uint8_t *tox_event_dht_get_nodes_response_get_public_key(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response)
|
||||
{
|
||||
return dht_get_nodes_response->public_key;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool tox_event_dht_get_nodes_response_set_ip(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response,
|
||||
const char *ip, uint32_t ip_length, const Memory *mem)
|
||||
{
|
||||
if (dht_get_nodes_response->ip != nullptr) {
|
||||
mem_delete(mem, dht_get_nodes_response->ip);
|
||||
dht_get_nodes_response->ip = nullptr;
|
||||
dht_get_nodes_response->ip_length = 0;
|
||||
}
|
||||
|
||||
uint8_t *ip_tmp = (uint8_t *)mem_balloc(mem, ip_length);
|
||||
|
||||
if (ip_tmp == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ip_tmp, ip, ip_length);
|
||||
dht_get_nodes_response->ip = ip_tmp;
|
||||
dht_get_nodes_response->ip_length = ip_length;
|
||||
return true;
|
||||
}
|
||||
uint32_t tox_event_dht_get_nodes_response_get_ip_length(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response)
|
||||
{
|
||||
return dht_get_nodes_response->ip_length;
|
||||
}
|
||||
const uint8_t *tox_event_dht_get_nodes_response_get_ip(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response)
|
||||
{
|
||||
return dht_get_nodes_response->ip;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool tox_event_dht_get_nodes_response_set_port(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, uint16_t port)
|
||||
{
|
||||
dht_get_nodes_response->port = port;
|
||||
return true;
|
||||
}
|
||||
uint16_t tox_event_dht_get_nodes_response_get_port(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response)
|
||||
{
|
||||
return dht_get_nodes_response->port;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void tox_event_dht_get_nodes_response_construct(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response)
|
||||
{
|
||||
*dht_get_nodes_response = (Tox_Event_Dht_Get_Nodes_Response) {
|
||||
{
|
||||
0
|
||||
}
|
||||
};
|
||||
}
|
||||
non_null()
|
||||
static void tox_event_dht_get_nodes_response_destruct(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem)
|
||||
{
|
||||
mem_delete(mem, dht_get_nodes_response->ip);
|
||||
}
|
||||
|
||||
bool tox_event_dht_get_nodes_response_pack(
|
||||
const Tox_Event_Dht_Get_Nodes_Response *event, Bin_Pack *bp)
|
||||
{
|
||||
return bin_pack_array(bp, 3)
|
||||
&& bin_pack_bin(bp, event->public_key, TOX_PUBLIC_KEY_SIZE)
|
||||
&& bin_pack_bin(bp, event->ip, event->ip_length)
|
||||
&& bin_pack_u16(bp, event->port);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool tox_event_dht_get_nodes_response_unpack_into(
|
||||
Tox_Event_Dht_Get_Nodes_Response *event, Bin_Unpack *bu)
|
||||
{
|
||||
if (!bin_unpack_array_fixed(bu, 3, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return bin_unpack_bin_fixed(bu, event->public_key, TOX_PUBLIC_KEY_SIZE)
|
||||
&& bin_unpack_bin(bu, &event->ip, &event->ip_length)
|
||||
&& bin_unpack_u16(bu, &event->port);
|
||||
}
|
||||
|
||||
const Tox_Event_Dht_Get_Nodes_Response *tox_event_get_dht_get_nodes_response(
|
||||
const Tox_Event *event)
|
||||
{
|
||||
return event->type == TOX_EVENT_DHT_GET_NODES_RESPONSE ? event->data.dht_get_nodes_response : nullptr;
|
||||
}
|
||||
|
||||
Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_new(const Memory *mem)
|
||||
{
|
||||
Tox_Event_Dht_Get_Nodes_Response *const dht_get_nodes_response =
|
||||
(Tox_Event_Dht_Get_Nodes_Response *)mem_alloc(mem, sizeof(Tox_Event_Dht_Get_Nodes_Response));
|
||||
|
||||
if (dht_get_nodes_response == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tox_event_dht_get_nodes_response_construct(dht_get_nodes_response);
|
||||
return dht_get_nodes_response;
|
||||
}
|
||||
|
||||
void tox_event_dht_get_nodes_response_free(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem)
|
||||
{
|
||||
if (dht_get_nodes_response != nullptr) {
|
||||
tox_event_dht_get_nodes_response_destruct(dht_get_nodes_response, mem);
|
||||
}
|
||||
mem_delete(mem, dht_get_nodes_response);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static Tox_Event_Dht_Get_Nodes_Response *tox_events_add_dht_get_nodes_response(Tox_Events *events, const Memory *mem)
|
||||
{
|
||||
Tox_Event_Dht_Get_Nodes_Response *const dht_get_nodes_response = tox_event_dht_get_nodes_response_new(mem);
|
||||
|
||||
if (dht_get_nodes_response == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Tox_Event event;
|
||||
event.type = TOX_EVENT_DHT_GET_NODES_RESPONSE;
|
||||
event.data.dht_get_nodes_response = dht_get_nodes_response;
|
||||
|
||||
if (!tox_events_add(events, &event)) {
|
||||
tox_event_dht_get_nodes_response_free(dht_get_nodes_response, mem);
|
||||
return nullptr;
|
||||
}
|
||||
return dht_get_nodes_response;
|
||||
}
|
||||
|
||||
bool tox_event_dht_get_nodes_response_unpack(
|
||||
Tox_Event_Dht_Get_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem)
|
||||
{
|
||||
*event = tox_event_dht_get_nodes_response_new(mem);
|
||||
|
||||
if (*event == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tox_event_dht_get_nodes_response_unpack_into(*event, bu);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_alloc(void *user_data)
|
||||
{
|
||||
Tox_Events_State *state = tox_events_alloc(user_data);
|
||||
assert(state != nullptr);
|
||||
|
||||
if (state->events == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response = tox_events_add_dht_get_nodes_response(state->events, state->mem);
|
||||
|
||||
if (dht_get_nodes_response == nullptr) {
|
||||
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dht_get_nodes_response;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
*
|
||||
* :: event handler
|
||||
*
|
||||
*****************************************************/
|
||||
|
||||
void tox_events_handle_dht_get_nodes_response(
|
||||
Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE],
|
||||
const char *ip, uint16_t port, void *user_data)
|
||||
{
|
||||
Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response = tox_event_dht_get_nodes_response_alloc(user_data);
|
||||
|
||||
if (dht_get_nodes_response == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t ip_length = strlen(ip);
|
||||
if (ip_length >= UINT32_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Tox_System *sys = tox_get_system(tox);
|
||||
|
||||
tox_event_dht_get_nodes_response_set_public_key(dht_get_nodes_response, public_key);
|
||||
tox_event_dht_get_nodes_response_set_ip(dht_get_nodes_response, ip, ip_length + 1, sys->mem);
|
||||
tox_event_dht_get_nodes_response_set_port(dht_get_nodes_response, port);
|
||||
}
|
222
toxcore/events/dht_nodes_response.c
Normal file
222
toxcore/events/dht_nodes_response.c
Normal file
@ -0,0 +1,222 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2022-2025 The TokTok team.
|
||||
*/
|
||||
|
||||
#include "events_alloc.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../attributes.h"
|
||||
#include "../bin_pack.h"
|
||||
#include "../bin_unpack.h"
|
||||
#include "../ccompat.h"
|
||||
#include "../mem.h"
|
||||
#include "../tox.h"
|
||||
#include "../tox_event.h"
|
||||
#include "../tox_events.h"
|
||||
#include "../tox_private.h"
|
||||
|
||||
/*****************************************************
|
||||
*
|
||||
* :: struct and accessors
|
||||
*
|
||||
*****************************************************/
|
||||
|
||||
struct Tox_Event_Dht_Nodes_Response {
|
||||
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
|
||||
uint8_t *ip;
|
||||
uint32_t ip_length;
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
non_null()
|
||||
static bool tox_event_dht_nodes_response_set_public_key(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE])
|
||||
{
|
||||
memcpy(dht_nodes_response->public_key, public_key, TOX_PUBLIC_KEY_SIZE);
|
||||
return true;
|
||||
}
|
||||
const uint8_t *tox_event_dht_nodes_response_get_public_key(const Tox_Event_Dht_Nodes_Response *dht_nodes_response)
|
||||
{
|
||||
return dht_nodes_response->public_key;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool tox_event_dht_nodes_response_set_ip(Tox_Event_Dht_Nodes_Response *dht_nodes_response,
|
||||
const char *ip, uint32_t ip_length, const Memory *mem)
|
||||
{
|
||||
if (dht_nodes_response->ip != nullptr) {
|
||||
mem_delete(mem, dht_nodes_response->ip);
|
||||
dht_nodes_response->ip = nullptr;
|
||||
dht_nodes_response->ip_length = 0;
|
||||
}
|
||||
|
||||
uint8_t *ip_tmp = (uint8_t *)mem_balloc(mem, ip_length + 1);
|
||||
|
||||
if (ip_tmp == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ip_tmp, ip, ip_length + 1);
|
||||
dht_nodes_response->ip = ip_tmp;
|
||||
dht_nodes_response->ip_length = ip_length;
|
||||
return true;
|
||||
}
|
||||
uint32_t tox_event_dht_nodes_response_get_ip_length(const Tox_Event_Dht_Nodes_Response *dht_nodes_response)
|
||||
{
|
||||
return dht_nodes_response->ip_length;
|
||||
}
|
||||
const uint8_t *tox_event_dht_nodes_response_get_ip(const Tox_Event_Dht_Nodes_Response *dht_nodes_response)
|
||||
{
|
||||
return dht_nodes_response->ip;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool tox_event_dht_nodes_response_set_port(Tox_Event_Dht_Nodes_Response *dht_nodes_response, uint16_t port)
|
||||
{
|
||||
dht_nodes_response->port = port;
|
||||
return true;
|
||||
}
|
||||
uint16_t tox_event_dht_nodes_response_get_port(const Tox_Event_Dht_Nodes_Response *dht_nodes_response)
|
||||
{
|
||||
return dht_nodes_response->port;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void tox_event_dht_nodes_response_construct(Tox_Event_Dht_Nodes_Response *dht_nodes_response)
|
||||
{
|
||||
*dht_nodes_response = (Tox_Event_Dht_Nodes_Response) {
|
||||
{
|
||||
0
|
||||
}
|
||||
};
|
||||
}
|
||||
non_null()
|
||||
static void tox_event_dht_nodes_response_destruct(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const Memory *mem)
|
||||
{
|
||||
mem_delete(mem, dht_nodes_response->ip);
|
||||
}
|
||||
|
||||
bool tox_event_dht_nodes_response_pack(
|
||||
const Tox_Event_Dht_Nodes_Response *event, Bin_Pack *bp)
|
||||
{
|
||||
return bin_pack_array(bp, 3)
|
||||
&& bin_pack_bin(bp, event->public_key, TOX_PUBLIC_KEY_SIZE)
|
||||
&& bin_pack_bin(bp, event->ip, event->ip_length)
|
||||
&& bin_pack_u16(bp, event->port);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool tox_event_dht_nodes_response_unpack_into(
|
||||
Tox_Event_Dht_Nodes_Response *event, Bin_Unpack *bu)
|
||||
{
|
||||
if (!bin_unpack_array_fixed(bu, 3, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return bin_unpack_bin_fixed(bu, event->public_key, TOX_PUBLIC_KEY_SIZE)
|
||||
&& bin_unpack_bin(bu, &event->ip, &event->ip_length)
|
||||
&& bin_unpack_u16(bu, &event->port);
|
||||
}
|
||||
|
||||
const Tox_Event_Dht_Nodes_Response *tox_event_get_dht_nodes_response(
|
||||
const Tox_Event *event)
|
||||
{
|
||||
return event->type == TOX_EVENT_DHT_GET_NODES_RESPONSE ? event->data.dht_nodes_response : nullptr;
|
||||
}
|
||||
|
||||
Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_new(const Memory *mem)
|
||||
{
|
||||
Tox_Event_Dht_Nodes_Response *const dht_nodes_response =
|
||||
(Tox_Event_Dht_Nodes_Response *)mem_alloc(mem, sizeof(Tox_Event_Dht_Nodes_Response));
|
||||
|
||||
if (dht_nodes_response == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tox_event_dht_nodes_response_construct(dht_nodes_response);
|
||||
return dht_nodes_response;
|
||||
}
|
||||
|
||||
void tox_event_dht_nodes_response_free(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const Memory *mem)
|
||||
{
|
||||
if (dht_nodes_response != nullptr) {
|
||||
tox_event_dht_nodes_response_destruct(dht_nodes_response, mem);
|
||||
}
|
||||
mem_delete(mem, dht_nodes_response);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static Tox_Event_Dht_Nodes_Response *tox_events_add_dht_nodes_response(Tox_Events *events, const Memory *mem)
|
||||
{
|
||||
Tox_Event_Dht_Nodes_Response *const dht_nodes_response = tox_event_dht_nodes_response_new(mem);
|
||||
|
||||
if (dht_nodes_response == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Tox_Event event;
|
||||
event.type = TOX_EVENT_DHT_GET_NODES_RESPONSE;
|
||||
event.data.dht_nodes_response = dht_nodes_response;
|
||||
|
||||
if (!tox_events_add(events, &event)) {
|
||||
tox_event_dht_nodes_response_free(dht_nodes_response, mem);
|
||||
return nullptr;
|
||||
}
|
||||
return dht_nodes_response;
|
||||
}
|
||||
|
||||
bool tox_event_dht_nodes_response_unpack(
|
||||
Tox_Event_Dht_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem)
|
||||
{
|
||||
*event = tox_event_dht_nodes_response_new(mem);
|
||||
|
||||
if (*event == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tox_event_dht_nodes_response_unpack_into(*event, bu);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_alloc(void *user_data)
|
||||
{
|
||||
Tox_Events_State *state = tox_events_alloc(user_data);
|
||||
assert(state != nullptr);
|
||||
|
||||
if (state->events == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Tox_Event_Dht_Nodes_Response *dht_nodes_response = tox_events_add_dht_nodes_response(state->events, state->mem);
|
||||
|
||||
if (dht_nodes_response == nullptr) {
|
||||
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dht_nodes_response;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
*
|
||||
* :: event handler
|
||||
*
|
||||
*****************************************************/
|
||||
|
||||
void tox_events_handle_dht_nodes_response(
|
||||
Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE],
|
||||
const char *ip, uint32_t ip_length, uint16_t port, void *user_data)
|
||||
{
|
||||
Tox_Event_Dht_Nodes_Response *dht_nodes_response = tox_event_dht_nodes_response_alloc(user_data);
|
||||
|
||||
if (dht_nodes_response == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Tox_System *sys = tox_get_system(tox);
|
||||
|
||||
tox_event_dht_nodes_response_set_public_key(dht_nodes_response, public_key);
|
||||
tox_event_dht_nodes_response_set_ip(dht_nodes_response, ip, ip_length, sys->mem);
|
||||
tox_event_dht_nodes_response_set_port(dht_nodes_response, port);
|
||||
}
|
@ -35,7 +35,7 @@ tox_conference_message_cb tox_events_handle_conference_message;
|
||||
tox_conference_peer_list_changed_cb tox_events_handle_conference_peer_list_changed;
|
||||
tox_conference_peer_name_cb tox_events_handle_conference_peer_name;
|
||||
tox_conference_title_cb tox_events_handle_conference_title;
|
||||
tox_dht_get_nodes_response_cb tox_events_handle_dht_get_nodes_response;
|
||||
tox_dht_nodes_response_cb tox_events_handle_dht_nodes_response;
|
||||
tox_file_chunk_request_cb tox_events_handle_file_chunk_request;
|
||||
tox_file_recv_cb tox_events_handle_file_recv;
|
||||
tox_file_recv_chunk_cb tox_events_handle_file_recv_chunk;
|
||||
|
@ -13,11 +13,11 @@ namespace {
|
||||
std::optional<std::tuple<IP_Port, IP_Port, const uint8_t *, size_t>> prepare(Fuzz_Data &input)
|
||||
{
|
||||
CONSUME_OR_RETURN_VAL(const uint8_t *ipp_packed, input, SIZE_IP_PORT, std::nullopt);
|
||||
IP_Port ipp;
|
||||
IP_Port ipp{};
|
||||
unpack_ip_port(&ipp, ipp_packed, SIZE_IP6, true);
|
||||
|
||||
CONSUME_OR_RETURN_VAL(const uint8_t *forwarder_packed, input, SIZE_IP_PORT, std::nullopt);
|
||||
IP_Port forwarder;
|
||||
IP_Port forwarder{};
|
||||
unpack_ip_port(&forwarder, forwarder_packed, SIZE_IP6, true);
|
||||
|
||||
// 2 bytes: size of the request
|
||||
@ -37,22 +37,22 @@ void TestSendForwardRequest(Fuzz_Data &input)
|
||||
const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE;
|
||||
CONSUME_OR_RETURN(const uint8_t *chain_keys, input, chain_keys_size);
|
||||
|
||||
auto prep = prepare(input);
|
||||
const auto prep = prepare(input);
|
||||
if (!prep.has_value()) {
|
||||
return;
|
||||
}
|
||||
auto [ipp, forwarder, data, data_size] = prep.value();
|
||||
const auto [ipp, forwarder, data, data_size] = prep.value();
|
||||
|
||||
// rest of the fuzz data is input for malloc and network
|
||||
Fuzz_System sys(input);
|
||||
|
||||
Ptr<Logger> logger(logger_new(sys.mem.get()), logger_kill);
|
||||
const Ptr<Logger> logger(logger_new(sys.mem.get()), logger_kill);
|
||||
if (logger == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), &ipp.ip,
|
||||
ipp.port, ipp.port + 100, nullptr),
|
||||
const Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(),
|
||||
&ipp.ip, ipp.port, ipp.port + 100, nullptr),
|
||||
kill_networking);
|
||||
if (net == nullptr) {
|
||||
return;
|
||||
@ -66,22 +66,22 @@ void TestForwardReply(Fuzz_Data &input)
|
||||
CONSUME1_OR_RETURN(const uint16_t, sendback_length, input);
|
||||
CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length);
|
||||
|
||||
auto prep = prepare(input);
|
||||
const auto prep = prepare(input);
|
||||
if (!prep.has_value()) {
|
||||
return;
|
||||
}
|
||||
auto [ipp, forwarder, data, data_size] = prep.value();
|
||||
const auto [ipp, forwarder, data, data_size] = prep.value();
|
||||
|
||||
// rest of the fuzz data is input for malloc and network
|
||||
Fuzz_System sys(input);
|
||||
|
||||
Ptr<Logger> logger(logger_new(sys.mem.get()), logger_kill);
|
||||
const Ptr<Logger> logger(logger_new(sys.mem.get()), logger_kill);
|
||||
if (logger == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), &ipp.ip,
|
||||
ipp.port, ipp.port + 100, nullptr),
|
||||
const Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(),
|
||||
&ipp.ip, ipp.port, ipp.port + 100, nullptr),
|
||||
kill_networking);
|
||||
if (net == nullptr) {
|
||||
return;
|
||||
|
@ -168,8 +168,6 @@ non_null() static void group_delete(GC_Session *c, GC_Chat *chat);
|
||||
non_null() static void group_cleanup(const GC_Session *c, GC_Chat *chat);
|
||||
non_null() static bool group_exists(const GC_Session *c, const uint8_t *chat_id);
|
||||
non_null() static void add_tcp_relays_to_chat(const GC_Session *c, GC_Chat *chat);
|
||||
non_null(1, 2) nullable(4)
|
||||
static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number, void *userdata);
|
||||
non_null() static void create_gc_session_keypair(const Logger *log, const Random *rng, uint8_t *public_key,
|
||||
uint8_t *secret_key);
|
||||
non_null() static size_t load_gc_peers(GC_Chat *chat, const GC_SavedPeerInfo *addrs, uint16_t num_addrs);
|
||||
@ -837,6 +835,21 @@ static int saved_peer_index(const GC_Chat *chat, const uint8_t *public_key)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** @brief Removes entry containing `public_key` from the saved peers list. */
|
||||
non_null()
|
||||
static void saved_peers_remove_entry(GC_Chat *chat, const uint8_t *public_key)
|
||||
{
|
||||
const int idx = saved_peer_index(chat, public_key);
|
||||
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
chat->saved_peers[idx] = (GC_SavedPeerInfo) {
|
||||
0
|
||||
};
|
||||
}
|
||||
|
||||
/** @brief Returns the index of the first vacant entry in saved peers list.
|
||||
*
|
||||
* If `public_key` is non-null and already exists in the list, its index will be returned.
|
||||
@ -6701,6 +6714,7 @@ void gc_callback_rejected(const Messenger *m, gc_rejected_cb *function)
|
||||
*
|
||||
* Return true on success.
|
||||
*/
|
||||
non_null(1, 2) nullable(4)
|
||||
static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number, void *userdata)
|
||||
{
|
||||
GC_Peer *peer = get_gc_peer(chat, peer_number);
|
||||
@ -6709,17 +6723,23 @@ static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number
|
||||
return false;
|
||||
}
|
||||
|
||||
GC_Connection *gconn = &peer->gconn;
|
||||
|
||||
// We need to save some peer info for the callback before deleting it
|
||||
const bool peer_confirmed = peer->gconn.confirmed;
|
||||
const bool peer_confirmed = gconn->confirmed;
|
||||
const GC_Peer_Id peer_id = peer->peer_id;
|
||||
uint8_t nick[MAX_GC_NICK_SIZE];
|
||||
const uint16_t nick_length = peer->nick_length;
|
||||
const GC_Exit_Info exit_info = peer->gconn.exit_info;
|
||||
const GC_Exit_Info exit_info = gconn->exit_info;
|
||||
|
||||
assert(nick_length <= MAX_GC_NICK_SIZE);
|
||||
memcpy(nick, peer->nick, nick_length);
|
||||
|
||||
gcc_peer_cleanup(chat->mem, &peer->gconn);
|
||||
if (exit_info.exit_type == GC_EXIT_TYPE_KICKED) {
|
||||
saved_peers_remove_entry(chat, gconn->addr.public_key.enc);
|
||||
}
|
||||
|
||||
gcc_peer_cleanup(chat->mem, gconn);
|
||||
|
||||
--chat->numpeers;
|
||||
|
||||
|
@ -20,6 +20,10 @@
|
||||
#include "net_profile.h"
|
||||
#include "network.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*** Crypto payloads. */
|
||||
|
||||
/*** Ranges. */
|
||||
@ -422,4 +426,8 @@ void kill_net_crypto(Net_Crypto *c);
|
||||
non_null()
|
||||
const Net_Profile *nc_get_tcp_client_net_profile(const Net_Crypto *c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* C_TOXCORE_TOXCORE_NET_CRYPTO_H */
|
||||
|
93
toxcore/net_crypto_fuzz_test.cc
Normal file
93
toxcore/net_crypto_fuzz_test.cc
Normal file
@ -0,0 +1,93 @@
|
||||
#include "net_crypto.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "../testing/fuzzing/fuzz_support.hh"
|
||||
#include "../testing/fuzzing/fuzz_tox.hh"
|
||||
#include "DHT.h"
|
||||
#include "TCP_client.h"
|
||||
#include "network.h"
|
||||
|
||||
namespace {
|
||||
|
||||
std::optional<std::tuple<IP_Port, uint8_t>> prepare(Fuzz_Data &input)
|
||||
{
|
||||
IP_Port ipp;
|
||||
ip_init(&ipp.ip, true);
|
||||
ipp.port = 33445;
|
||||
|
||||
CONSUME_OR_RETURN_VAL(const uint8_t *iterations_packed, input, 1, std::nullopt);
|
||||
uint8_t iterations = *iterations_packed;
|
||||
|
||||
return {{ipp, iterations}};
|
||||
}
|
||||
|
||||
void TestNetCrypto(Fuzz_Data &input)
|
||||
{
|
||||
const auto prep = prepare(input);
|
||||
if (!prep.has_value()) {
|
||||
return;
|
||||
}
|
||||
const auto [ipp, iterations] = prep.value();
|
||||
|
||||
// rest of the fuzz data is input for malloc and network
|
||||
Fuzz_System sys(input);
|
||||
|
||||
const Ptr<Logger> logger(logger_new(sys.mem.get()), logger_kill);
|
||||
if (logger == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(),
|
||||
&ipp.ip, ipp.port, ipp.port + 100, nullptr),
|
||||
kill_networking);
|
||||
if (net == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::unique_ptr<Mono_Time, std::function<void(Mono_Time *)>> mono_time(
|
||||
mono_time_new(
|
||||
sys.mem.get(), [](void *user_data) { return *static_cast<uint64_t *>(user_data); },
|
||||
&sys.clock),
|
||||
[mem = sys.mem.get()](Mono_Time *ptr) { mono_time_free(mem, ptr); });
|
||||
if (mono_time == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Ptr<DHT> dht(new_dht(logger.get(), sys.mem.get(), sys.rng.get(), sys.ns.get(),
|
||||
mono_time.get(), net.get(), false, false),
|
||||
kill_dht);
|
||||
if (dht == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const TCP_Proxy_Info proxy_info = {0};
|
||||
|
||||
const Ptr<Net_Crypto> net_crypto(new_net_crypto(logger.get(), sys.mem.get(), sys.rng.get(),
|
||||
sys.ns.get(), mono_time.get(), dht.get(), &proxy_info),
|
||||
kill_net_crypto);
|
||||
if (net_crypto == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < iterations; ++i) {
|
||||
networking_poll(net.get(), nullptr);
|
||||
do_dht(dht.get());
|
||||
do_net_crypto(net_crypto.get(), nullptr);
|
||||
// "Sleep"
|
||||
sys.clock += System::BOOTSTRAP_ITERATION_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
fuzz_select_target<TestNetCrypto>(data, size);
|
||||
return 0;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2023-2024 The TokTok team.
|
||||
* Copyright © 2023-2025 The TokTok team.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2023-2024 The TokTok team.
|
||||
* Copyright © 2023-2025 The TokTok team.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -264,9 +264,11 @@ static int make_family(Family tox_family)
|
||||
{
|
||||
switch (tox_family.value) {
|
||||
case TOX_AF_INET:
|
||||
case TCP_INET:
|
||||
return AF_INET;
|
||||
|
||||
case TOX_AF_INET6:
|
||||
case TCP_INET6:
|
||||
return AF_INET6;
|
||||
|
||||
case TOX_AF_UNSPEC:
|
||||
@ -590,7 +592,11 @@ static int sys_getsockopt(void *obj, Socket sock, int level, int optname, void *
|
||||
non_null()
|
||||
static int sys_setsockopt(void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen)
|
||||
{
|
||||
#ifdef EMSCRIPTEN
|
||||
return 0;
|
||||
#else
|
||||
return setsockopt(net_socket_to_native(sock), level, optname, (const char *)optval, optlen);
|
||||
#endif /* EMSCRIPTEN */
|
||||
}
|
||||
|
||||
// sets and fills an array of addrs for address
|
||||
@ -770,11 +776,11 @@ static const char *net_packet_type_name(Net_Packet_Type type)
|
||||
case NET_PACKET_PING_RESPONSE:
|
||||
return "PING_RESPONSE";
|
||||
|
||||
case NET_PACKET_GET_NODES:
|
||||
return "GET_NODES";
|
||||
case NET_PACKET_NODES_REQUEST:
|
||||
return "NODES_REQUEST";
|
||||
|
||||
case NET_PACKET_SEND_NODES_IPV6:
|
||||
return "SEND_NODES_IPV6";
|
||||
case NET_PACKET_NODES_RESPONSE:
|
||||
return "NODES_RESPONSE";
|
||||
|
||||
case NET_PACKET_COOKIE_REQUEST:
|
||||
return "COOKIE_REQUEST";
|
||||
@ -883,13 +889,12 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu
|
||||
if (res < 0) { /* Windows doesn't necessarily know `%zu` */
|
||||
Ip_Ntoa ip_str;
|
||||
const int error = net_error();
|
||||
char *strerror = net_new_strerror(error);
|
||||
Net_Strerror error_str;
|
||||
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,
|
||||
strerror, data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]);
|
||||
net_kill_strerror(strerror);
|
||||
net_strerror(error, &error_str), data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]);
|
||||
} else if ((res > 0) && ((size_t)res <= buflen)) {
|
||||
Ip_Ntoa ip_str;
|
||||
LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x",
|
||||
@ -1048,7 +1053,7 @@ int send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packe
|
||||
|
||||
if (net_family_is_unspec(net->family)) { /* Socket not initialized */
|
||||
// TODO(iphydf): Make this an error. Currently, the onion client calls
|
||||
// this via DHT getnodes.
|
||||
// this via DHT nodes requests.
|
||||
LOGGER_WARNING(net->log, "attempted to send message of length %u on uninitialised socket", packet.length);
|
||||
return -1;
|
||||
}
|
||||
@ -1131,7 +1136,7 @@ int sendpacket(const Networking_Core *net, const IP_Port *ip_port, const uint8_t
|
||||
* Packet length is put into length.
|
||||
*/
|
||||
non_null()
|
||||
static int receivepacket(const Network *ns, const Memory *mem, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
|
||||
static int receivepacket(const Network *ns, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
|
||||
{
|
||||
memset(ip_port, 0, sizeof(IP_Port));
|
||||
Network_Addr addr = {{0}};
|
||||
@ -1144,9 +1149,8 @@ static int receivepacket(const Network *ns, const Memory *mem, const Logger *log
|
||||
const int error = net_error();
|
||||
|
||||
if (!should_ignore_recv_error(error)) {
|
||||
char *strerror = net_new_strerror(error);
|
||||
LOGGER_ERROR(log, "unexpected error reading from socket: %u, %s", error, strerror);
|
||||
net_kill_strerror(strerror);
|
||||
Net_Strerror error_str;
|
||||
LOGGER_ERROR(log, "unexpected error reading from socket: %u, %s", error, net_strerror(error, &error_str));
|
||||
}
|
||||
|
||||
return -1; /* Nothing received. */
|
||||
@ -1210,7 +1214,7 @@ void networking_poll(const Networking_Core *net, void *userdata)
|
||||
uint8_t data[MAX_UDP_PACKET_SIZE] = {0};
|
||||
uint32_t length;
|
||||
|
||||
while (receivepacket(net->ns, net->mem, net->log, net->sock, &ip_port, data, &length) != -1) {
|
||||
while (receivepacket(net->ns, net->log, net->sock, &ip_port, data, &length) != -1) {
|
||||
if (length < 1) {
|
||||
continue;
|
||||
}
|
||||
@ -1298,9 +1302,8 @@ Networking_Core *new_networking_ex(
|
||||
/* Check for socket error. */
|
||||
if (!sock_valid(temp->sock)) {
|
||||
const int neterror = net_error();
|
||||
char *strerror = net_new_strerror(neterror);
|
||||
LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, strerror);
|
||||
net_kill_strerror(strerror);
|
||||
Net_Strerror error_str;
|
||||
LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, net_strerror(neterror, &error_str));
|
||||
netprof_kill(mem, temp->udp_net_profile);
|
||||
mem_delete(mem, temp);
|
||||
|
||||
@ -1402,15 +1405,13 @@ Networking_Core *new_networking_ex(
|
||||
const int res = net_setsockopt(ns, temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||
|
||||
const int neterror = net_error();
|
||||
char *strerror = net_new_strerror(neterror);
|
||||
Net_Strerror error_str;
|
||||
|
||||
if (res < 0) {
|
||||
LOGGER_INFO(log, "Failed to activate local multicast membership in FF02::1. (%d, %s)", neterror, strerror);
|
||||
LOGGER_INFO(log, "Failed to activate local multicast membership in FF02::1. (%d, %s)", neterror, net_strerror(neterror, &error_str));
|
||||
} else {
|
||||
LOGGER_TRACE(log, "Local multicast group joined successfully. (%d, %s)", neterror, strerror);
|
||||
LOGGER_TRACE(log, "Local multicast group joined successfully. (%d, %s)", neterror, net_strerror(neterror, &error_str));
|
||||
}
|
||||
|
||||
net_kill_strerror(strerror);
|
||||
#endif /* ESP_PLATFORM */
|
||||
}
|
||||
|
||||
@ -1468,10 +1469,9 @@ Networking_Core *new_networking_ex(
|
||||
|
||||
Ip_Ntoa ip_str;
|
||||
const int neterror = net_error();
|
||||
char *strerror = net_new_strerror(neterror);
|
||||
Net_Strerror error_str;
|
||||
LOGGER_ERROR(log, "failed to bind socket: %d, %s IP: %s port_from: %u port_to: %u",
|
||||
neterror, strerror, net_ip_ntoa(ip, &ip_str), port_from, port_to);
|
||||
net_kill_strerror(strerror);
|
||||
neterror, net_strerror(neterror, &error_str), net_ip_ntoa(ip, &ip_str), port_from, port_to);
|
||||
kill_networking(temp);
|
||||
|
||||
if (error != nullptr) {
|
||||
@ -1878,14 +1878,14 @@ bool ip_parse_addr(const IP *ip, char *address, size_t length)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (net_family_is_ipv4(ip->family)) {
|
||||
if (net_family_is_ipv4(ip->family) || net_family_is_tcp_ipv4(ip->family)) {
|
||||
struct in_addr addr;
|
||||
assert(make_family(ip->family) == AF_INET);
|
||||
fill_addr4(&ip->ip.v4, &addr);
|
||||
return inet_ntop4(&addr, address, length) != nullptr;
|
||||
}
|
||||
|
||||
if (net_family_is_ipv6(ip->family)) {
|
||||
if (net_family_is_ipv6(ip->family) || net_family_is_tcp_ipv6(ip->family)) {
|
||||
struct in6_addr addr;
|
||||
assert(make_family(ip->family) == AF_INET6);
|
||||
fill_addr6(&ip->ip.v6, &addr);
|
||||
@ -2097,10 +2097,9 @@ bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket
|
||||
|
||||
// Non-blocking socket: "Operation in progress" means it's connecting.
|
||||
if (!should_ignore_connect_error(error)) {
|
||||
char *net_strerror = net_new_strerror(error);
|
||||
Net_Strerror error_str;
|
||||
LOGGER_WARNING(log, "failed to connect to %s:%d: %d (%s)",
|
||||
net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error, net_strerror);
|
||||
net_kill_strerror(net_strerror);
|
||||
net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error, net_strerror(error, &error_str));
|
||||
*err = NET_ERR_CONNECT_FAILED;
|
||||
return false;
|
||||
}
|
||||
@ -2367,19 +2366,11 @@ int net_error(void)
|
||||
}
|
||||
|
||||
#ifdef OS_WIN32
|
||||
char *net_new_strerror(int error)
|
||||
char *net_strerror(int error, Net_Strerror *buf)
|
||||
{
|
||||
char *str = nullptr;
|
||||
// Windows API is weird. The 5th function arg is of char* type, but we
|
||||
// have to pass char** so that it could assign new memory block to our
|
||||
// pointer, so we have to cast our char** to char* for the compilation
|
||||
// not to fail (otherwise it would fail to find a variant of this function
|
||||
// accepting char** as the 5th arg) and Windows inside casts it back
|
||||
// to char** to do the assignment. So no, this cast you see here, although
|
||||
// it looks weird, is not a mistake.
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
|
||||
error, 0, (char *)&str, 0, nullptr);
|
||||
return str;
|
||||
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
|
||||
error, 0, buf->data, NET_STRERROR_SIZE, nullptr);
|
||||
return buf->data;
|
||||
}
|
||||
#else
|
||||
#if defined(_GNU_SOURCE) && defined(__GLIBC__)
|
||||
@ -2407,36 +2398,19 @@ static const char *net_strerror_r(int error, char *tmp, size_t tmp_size)
|
||||
return tmp;
|
||||
}
|
||||
#endif /* GNU */
|
||||
char *net_new_strerror(int error)
|
||||
char *net_strerror(int error, Net_Strerror *buf)
|
||||
{
|
||||
char tmp[256];
|
||||
|
||||
errno = 0;
|
||||
|
||||
const char *retstr = net_strerror_r(error, tmp, sizeof(tmp));
|
||||
const char *retstr = net_strerror_r(error, buf->data, NET_STRERROR_SIZE);
|
||||
const size_t retstr_len = strlen(retstr);
|
||||
assert(retstr_len < NET_STRERROR_SIZE);
|
||||
buf->size = (uint16_t)retstr_len;
|
||||
|
||||
char *str = (char *)malloc(retstr_len + 1);
|
||||
|
||||
if (str == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
memcpy(str, retstr, retstr_len + 1);
|
||||
|
||||
return str;
|
||||
return buf->data;
|
||||
}
|
||||
#endif /* OS_WIN32 */
|
||||
|
||||
void net_kill_strerror(char *strerror)
|
||||
{
|
||||
#ifdef OS_WIN32
|
||||
LocalFree((char *)strerror);
|
||||
#else
|
||||
free(strerror);
|
||||
#endif /* OS_WIN32 */
|
||||
}
|
||||
|
||||
const Net_Profile *net_get_net_profile(const Networking_Core *net)
|
||||
{
|
||||
if (net == nullptr) {
|
||||
|
@ -113,8 +113,8 @@ Family net_family_tox_tcp_ipv6(void);
|
||||
typedef enum Net_Packet_Type {
|
||||
NET_PACKET_PING_REQUEST = 0x00, /* Ping request packet ID. */
|
||||
NET_PACKET_PING_RESPONSE = 0x01, /* Ping response packet ID. */
|
||||
NET_PACKET_GET_NODES = 0x02, /* Get nodes request packet ID. */
|
||||
NET_PACKET_SEND_NODES_IPV6 = 0x04, /* Send nodes response packet ID for other addresses. */
|
||||
NET_PACKET_NODES_REQUEST = 0x02, /* Nodes request packet ID. */
|
||||
NET_PACKET_NODES_RESPONSE = 0x04, /* Nodes response packet ID. */
|
||||
NET_PACKET_COOKIE_REQUEST = 0x18, /* Cookie request packet */
|
||||
NET_PACKET_COOKIE_RESPONSE = 0x19, /* Cookie response packet */
|
||||
NET_PACKET_CRYPTO_HS = 0x1a, /* Crypto handshake packet */
|
||||
@ -236,12 +236,27 @@ Socket net_invalid_socket(void);
|
||||
|
||||
/**
|
||||
* Calls send(sockfd, buf, len, MSG_NOSIGNAL).
|
||||
*
|
||||
* @param ns System network object.
|
||||
* @param log Logger object.
|
||||
* @param sock Socket to send data with.
|
||||
* @param buf Data to send.
|
||||
* @param len Length of data.
|
||||
* @param ip_port IP and port to send data to.
|
||||
* @param net_profile Network profile to record the packet.
|
||||
*/
|
||||
non_null(1, 2, 4, 6) nullable(7)
|
||||
int net_send(const Network *ns, const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port,
|
||||
Net_Profile *net_profile);
|
||||
/**
|
||||
* Calls recv(sockfd, buf, len, MSG_NOSIGNAL).
|
||||
*
|
||||
* @param ns System network object.
|
||||
* @param log Logger object.
|
||||
* @param sock Socket to receive data with.
|
||||
* @param buf Buffer to store received data.
|
||||
* @param len Length of buffer.
|
||||
* @param ip_port IP and port of the sender.
|
||||
*/
|
||||
non_null()
|
||||
int net_recv(const Network *ns, const Logger *log, Socket sock, uint8_t *buf, size_t len, const IP_Port *ip_port);
|
||||
@ -582,26 +597,32 @@ bool bind_to_port(const Network *ns, Socket sock, Family family, uint16_t port);
|
||||
* Note that different platforms may return different codes for the same error,
|
||||
* so you likely shouldn't be checking the value returned by this function
|
||||
* unless you know what you are doing, you likely just want to use it in
|
||||
* combination with `net_new_strerror()` to print the error.
|
||||
* combination with `net_strerror()` to print the error.
|
||||
*
|
||||
* return platform-dependent network error code, if any.
|
||||
*/
|
||||
int net_error(void);
|
||||
|
||||
#define NET_STRERROR_SIZE 256
|
||||
|
||||
/** @brief Contains a null terminated formatted error message.
|
||||
*
|
||||
* This struct should not contain more than at most the 2 fields.
|
||||
*/
|
||||
typedef struct Net_Strerror {
|
||||
char data[NET_STRERROR_SIZE];
|
||||
uint16_t size;
|
||||
} Net_Strerror;
|
||||
|
||||
/** @brief Get a text explanation for the error code from `net_error()`.
|
||||
*
|
||||
* return NULL on failure.
|
||||
* return pointer to a NULL-terminated string describing the error code on
|
||||
* success. The returned string must be freed using `net_kill_strerror()`.
|
||||
* @param error The error code to get a string for.
|
||||
* @param buf The struct to store the error message in (usually on stack).
|
||||
*
|
||||
* @return pointer to a NULL-terminated string describing the error code.
|
||||
*/
|
||||
char *net_new_strerror(int error);
|
||||
|
||||
/** @brief Frees the string returned by `net_new_strerror()`.
|
||||
* It's valid to pass NULL as the argument, the function does nothing in this
|
||||
* case.
|
||||
*/
|
||||
nullable(1)
|
||||
void net_kill_strerror(char *strerror);
|
||||
non_null()
|
||||
char *net_strerror(int error, Net_Strerror *buf);
|
||||
|
||||
/** @brief Initialize networking.
|
||||
* Bind to ip and port.
|
||||
|
@ -470,6 +470,7 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
|
||||
|
||||
onion_paths->paths[pathnum].path_num = path_num;
|
||||
} else {
|
||||
assert(0 <= n && n < NUMBER_ONION_PATHS);
|
||||
pathnum = n;
|
||||
}
|
||||
}
|
||||
@ -1264,7 +1265,7 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con
|
||||
const Family family = nodes[i].ip_port.ip.family;
|
||||
|
||||
if (net_family_is_ipv4(family) || net_family_is_ipv6(family)) {
|
||||
dht_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key);
|
||||
dht_send_nodes_request(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key);
|
||||
} else if (net_family_is_tcp_ipv4(family) || net_family_is_tcp_ipv6(family)) {
|
||||
if (onion_c->friends_list[friend_num].tcp_relay_node_callback != nullptr) {
|
||||
void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object;
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include "network.h"
|
||||
#include "onion_client.h"
|
||||
#include "state.h"
|
||||
#include "tox_log_level.h"
|
||||
#include "tox_options.h"
|
||||
#include "tox_private.h"
|
||||
#include "tox_struct.h" // IWYU pragma: keep
|
||||
#include "util.h"
|
||||
@ -360,20 +362,22 @@ static void tox_conference_peer_list_changed_handler(Messenger *m, uint32_t conf
|
||||
}
|
||||
}
|
||||
|
||||
static dht_get_nodes_response_cb tox_dht_get_nodes_response_handler;
|
||||
static dht_nodes_response_cb tox_dht_nodes_response_handler;
|
||||
non_null(1, 2) nullable(3)
|
||||
static void tox_dht_get_nodes_response_handler(const DHT *dht, const Node_format *node, void *user_data)
|
||||
static void tox_dht_nodes_response_handler(const DHT *dht, const Node_format *node, void *user_data)
|
||||
{
|
||||
struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data;
|
||||
|
||||
if (tox_data->tox->dht_get_nodes_response_callback == nullptr) {
|
||||
if (tox_data->tox->dht_nodes_response_callback == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ip_Ntoa ip_str;
|
||||
net_ip_ntoa(&node->ip_port.ip, &ip_str);
|
||||
|
||||
tox_unlock(tox_data->tox);
|
||||
tox_data->tox->dht_get_nodes_response_callback(
|
||||
tox_data->tox, node->public_key, net_ip_ntoa(&node->ip_port.ip, &ip_str), net_ntohs(node->ip_port.port),
|
||||
tox_data->tox->dht_nodes_response_callback(
|
||||
tox_data->tox, node->public_key, ip_str.buf, ip_str.length, net_ntohs(node->ip_port.port),
|
||||
tox_data->user_data);
|
||||
tox_lock(tox_data->tox);
|
||||
}
|
||||
@ -986,7 +990,7 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error
|
||||
callback_file_reqchunk(tox->m, tox_file_chunk_request_handler);
|
||||
callback_file_sendrequest(tox->m, tox_file_recv_handler);
|
||||
callback_file_data(tox->m, tox_file_recv_chunk_handler);
|
||||
dht_callback_get_nodes_response(tox->m->dht, tox_dht_get_nodes_response_handler);
|
||||
dht_callback_nodes_response(tox->m->dht, tox_dht_nodes_response_handler);
|
||||
g_callback_group_invite(tox->m->conferences_object, tox_conference_invite_handler);
|
||||
g_callback_group_connected(tox->m->conferences_object, tox_conference_connected_handler);
|
||||
g_callback_group_message(tox->m->conferences_object, tox_conference_message_handler);
|
||||
|
443
toxcore/tox.h
443
toxcore/tox.h
@ -102,14 +102,14 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "tox_options.h" // IWYU pragma: export
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @{ @namespace tox */
|
||||
|
||||
#ifndef TOX_DEFINED
|
||||
#define TOX_DEFINED
|
||||
/**
|
||||
* @brief The Tox instance type.
|
||||
*
|
||||
@ -120,7 +120,6 @@ extern "C" {
|
||||
* limiting factor is the number of usable ports on a device.
|
||||
*/
|
||||
typedef struct Tox Tox;
|
||||
#endif /* TOX_DEFINED */
|
||||
|
||||
/** @{
|
||||
* @name API version
|
||||
@ -155,7 +154,7 @@ uint32_t tox_version_minor(void);
|
||||
* Incremented when bugfixes are applied without changing any functionality or
|
||||
* API or ABI.
|
||||
*/
|
||||
#define TOX_VERSION_PATCH 20
|
||||
#define TOX_VERSION_PATCH 21
|
||||
|
||||
uint32_t tox_version_patch(void);
|
||||
|
||||
@ -393,439 +392,6 @@ const char *tox_message_type_to_string(Tox_Message_Type value);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @{
|
||||
* @name Startup options
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Type of proxy used to connect to TCP relays.
|
||||
*/
|
||||
typedef enum Tox_Proxy_Type {
|
||||
|
||||
/**
|
||||
* Don't use a proxy.
|
||||
*/
|
||||
TOX_PROXY_TYPE_NONE,
|
||||
|
||||
/**
|
||||
* HTTP proxy using CONNECT.
|
||||
*/
|
||||
TOX_PROXY_TYPE_HTTP,
|
||||
|
||||
/**
|
||||
* SOCKS proxy for simple socket pipes.
|
||||
*/
|
||||
TOX_PROXY_TYPE_SOCKS5,
|
||||
|
||||
} Tox_Proxy_Type;
|
||||
|
||||
const char *tox_proxy_type_to_string(Tox_Proxy_Type value);
|
||||
|
||||
/**
|
||||
* @brief Type of savedata to create the Tox instance from.
|
||||
*/
|
||||
typedef enum Tox_Savedata_Type {
|
||||
|
||||
/**
|
||||
* No savedata.
|
||||
*/
|
||||
TOX_SAVEDATA_TYPE_NONE,
|
||||
|
||||
/**
|
||||
* Savedata is one that was obtained from tox_get_savedata.
|
||||
*/
|
||||
TOX_SAVEDATA_TYPE_TOX_SAVE,
|
||||
|
||||
/**
|
||||
* Savedata is a secret key of length TOX_SECRET_KEY_SIZE.
|
||||
*/
|
||||
TOX_SAVEDATA_TYPE_SECRET_KEY,
|
||||
|
||||
} Tox_Savedata_Type;
|
||||
|
||||
const char *tox_savedata_type_to_string(Tox_Savedata_Type value);
|
||||
|
||||
/**
|
||||
* @brief Severity level of log messages.
|
||||
*/
|
||||
typedef enum Tox_Log_Level {
|
||||
|
||||
/**
|
||||
* Very detailed traces including all network activity.
|
||||
*/
|
||||
TOX_LOG_LEVEL_TRACE,
|
||||
|
||||
/**
|
||||
* Debug messages such as which port we bind to.
|
||||
*/
|
||||
TOX_LOG_LEVEL_DEBUG,
|
||||
|
||||
/**
|
||||
* Informational log messages such as video call status changes.
|
||||
*/
|
||||
TOX_LOG_LEVEL_INFO,
|
||||
|
||||
/**
|
||||
* Warnings about internal inconsistency or logic errors.
|
||||
*/
|
||||
TOX_LOG_LEVEL_WARNING,
|
||||
|
||||
/**
|
||||
* Severe unexpected errors caused by external or internal inconsistency.
|
||||
*/
|
||||
TOX_LOG_LEVEL_ERROR,
|
||||
|
||||
} Tox_Log_Level;
|
||||
|
||||
const char *tox_log_level_to_string(Tox_Log_Level value);
|
||||
|
||||
/**
|
||||
* @brief This event is triggered when Tox logs an internal message.
|
||||
*
|
||||
* This is mostly useful for debugging. This callback can be called from any
|
||||
* function, not just tox_iterate. This means the user data lifetime must at
|
||||
* least extend between registering and unregistering it or tox_kill.
|
||||
*
|
||||
* Other toxcore modules such as toxav may concurrently call this callback at
|
||||
* any time. Thus, user code must make sure it is equipped to handle concurrent
|
||||
* execution, e.g. by employing appropriate mutex locking.
|
||||
*
|
||||
* When using the experimental_thread_safety option, no Tox API functions can
|
||||
* be called from within the log callback.
|
||||
*
|
||||
* @param level The severity of the log message.
|
||||
* @param file The source file from which the message originated.
|
||||
* @param line The source line from which the message originated.
|
||||
* @param func The function from which the message originated.
|
||||
* @param message The log message.
|
||||
* @param user_data The user data pointer passed to tox_new in options.
|
||||
*/
|
||||
typedef void tox_log_cb(Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func,
|
||||
const char *message, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief This struct contains all the startup options for Tox.
|
||||
*
|
||||
* You must tox_options_new to allocate an object of this type.
|
||||
*
|
||||
* WARNING: Although this struct happens to be visible in the API, it is
|
||||
* effectively private. Do not allocate this yourself or access members
|
||||
* directly, as it *will* break binary compatibility frequently.
|
||||
*
|
||||
* @deprecated The memory layout of this struct (size, alignment, and field
|
||||
* order) is not part of the ABI. To remain compatible, prefer to use
|
||||
* tox_options_new to allocate the object and accessor functions to set the
|
||||
* members. The struct will become opaque (i.e. the definition will become
|
||||
* private) in v0.3.0.
|
||||
*/
|
||||
typedef struct Tox_Options Tox_Options;
|
||||
#ifndef TOX_HIDE_DEPRECATED
|
||||
struct Tox_Options {
|
||||
|
||||
/**
|
||||
* The type of socket to create.
|
||||
*
|
||||
* If this is set to false, an IPv4 socket is created, which subsequently
|
||||
* only allows IPv4 communication.
|
||||
* If it is set to true, an IPv6 socket is created, allowing both IPv4 and
|
||||
* IPv6 communication.
|
||||
*/
|
||||
bool ipv6_enabled;
|
||||
|
||||
/**
|
||||
* Enable the use of UDP communication when available.
|
||||
*
|
||||
* Setting this to false will force Tox to use TCP only. Communications will
|
||||
* need to be relayed through a TCP relay node, potentially slowing them
|
||||
* down.
|
||||
*
|
||||
* If a proxy is enabled, UDP will be disabled if either the Tox library or
|
||||
* the proxy don't support proxying UDP messages.
|
||||
*/
|
||||
bool udp_enabled;
|
||||
|
||||
/**
|
||||
* Enable local network peer discovery.
|
||||
*
|
||||
* Disabling this will cause Tox to not look for peers on the local network.
|
||||
*/
|
||||
bool local_discovery_enabled;
|
||||
|
||||
/**
|
||||
* Enable storing DHT announcements and forwarding corresponding requests.
|
||||
*
|
||||
* Disabling this will cause Tox to ignore the relevant packets.
|
||||
*/
|
||||
bool dht_announcements_enabled;
|
||||
|
||||
/**
|
||||
* Pass communications through a proxy.
|
||||
*/
|
||||
Tox_Proxy_Type proxy_type;
|
||||
|
||||
/**
|
||||
* The IP address or DNS name of the proxy to be used.
|
||||
*
|
||||
* If used, this must be non-NULL and be a valid DNS name. The name must not
|
||||
* exceed TOX_MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C
|
||||
* string format (TOX_MAX_HOSTNAME_LENGTH includes the NUL byte).
|
||||
*
|
||||
* This member is ignored (it can be NULL) if proxy_type is
|
||||
* TOX_PROXY_TYPE_NONE.
|
||||
*
|
||||
* The data pointed at by this member is owned by the user, so must
|
||||
* outlive the options object.
|
||||
*/
|
||||
const char *proxy_host;
|
||||
|
||||
/**
|
||||
* The port to use to connect to the proxy server.
|
||||
*
|
||||
* Ports must be in the range (1, 65535). The value is ignored if
|
||||
* proxy_type is TOX_PROXY_TYPE_NONE.
|
||||
*/
|
||||
uint16_t proxy_port;
|
||||
|
||||
/**
|
||||
* The start port of the inclusive port range to attempt to use.
|
||||
*
|
||||
* If both start_port and end_port are 0, the default port range will be
|
||||
* used: `[33445, 33545]`.
|
||||
*
|
||||
* If either start_port or end_port is 0 while the other is non-zero, the
|
||||
* non-zero port will be the only port in the range.
|
||||
*
|
||||
* Having start_port > end_port will yield the same behavior as if
|
||||
* start_port and end_port were swapped.
|
||||
*/
|
||||
uint16_t start_port;
|
||||
|
||||
/**
|
||||
* The end port of the inclusive port range to attempt to use.
|
||||
*/
|
||||
uint16_t end_port;
|
||||
|
||||
/**
|
||||
* The port to use for the TCP server (relay). If 0, the TCP server is
|
||||
* disabled.
|
||||
*
|
||||
* Enabling it is not required for Tox to function properly.
|
||||
*
|
||||
* When enabled, your Tox instance can act as a TCP relay for other Tox
|
||||
* instance. This leads to increased traffic, thus when writing a client
|
||||
* it is recommended to enable TCP server only if the user has an option
|
||||
* to disable it.
|
||||
*/
|
||||
uint16_t tcp_port;
|
||||
|
||||
/**
|
||||
* Enables or disables UDP hole-punching. (Default: enabled).
|
||||
*/
|
||||
bool hole_punching_enabled;
|
||||
|
||||
/**
|
||||
* The type of savedata to load from.
|
||||
*/
|
||||
Tox_Savedata_Type savedata_type;
|
||||
|
||||
/**
|
||||
* The savedata.
|
||||
*
|
||||
* The data pointed at by this member is owned by the user, so must outlive
|
||||
* the options object.
|
||||
*/
|
||||
const uint8_t *savedata_data;
|
||||
|
||||
/**
|
||||
* The length of the savedata.
|
||||
*/
|
||||
size_t savedata_length;
|
||||
|
||||
/**
|
||||
* Logging callback for the new Tox instance.
|
||||
*/
|
||||
tox_log_cb *log_callback;
|
||||
|
||||
/**
|
||||
* User data pointer passed to the logging callback.
|
||||
*/
|
||||
void *log_user_data;
|
||||
|
||||
/**
|
||||
* These options are experimental, so avoid writing code that depends on
|
||||
* them. Options marked "experimental" may change their behaviour or go away
|
||||
* entirely in the future, or may be renamed to something non-experimental
|
||||
* if they become part of the supported API.
|
||||
*/
|
||||
/**
|
||||
* Make public API functions thread-safe using a per-instance lock.
|
||||
*
|
||||
* Default: false.
|
||||
*/
|
||||
bool experimental_thread_safety;
|
||||
|
||||
/**
|
||||
* Enable saving DHT-based group chats to Tox save data (via
|
||||
* `tox_get_savedata`). This format will change in the future, so don't rely
|
||||
* on it.
|
||||
*
|
||||
* As an alternative, clients can save the group chat ID in client-owned
|
||||
* savedata. Then, when the client starts, it can use `tox_group_join`
|
||||
* with the saved chat ID to recreate the group chat.
|
||||
*
|
||||
* Default: false.
|
||||
*/
|
||||
bool experimental_groups_persistence;
|
||||
|
||||
/**
|
||||
* @brief Disable DNS hostname resolution.
|
||||
*
|
||||
* Hostnames or IP addresses are passed to the bootstrap/add_tcp_relay
|
||||
* function and proxy host options. If disabled (this flag is true), only
|
||||
* IP addresses are allowed.
|
||||
*
|
||||
* If this is set to true, the library will not attempt to resolve
|
||||
* hostnames. This is useful for clients that want to resolve hostnames
|
||||
* themselves and pass the resolved IP addresses to the library (e.g. in
|
||||
* case it wants to use Tor).
|
||||
* Passing hostnames will result in a TOX_ERR_BOOTSTRAP_BAD_HOST error if
|
||||
* this is set to true.
|
||||
*
|
||||
* Default: false. May become true in the future (0.3.0).
|
||||
*/
|
||||
bool experimental_disable_dns;
|
||||
};
|
||||
#endif /* TOX_HIDE_DEPRECATED */
|
||||
|
||||
bool tox_options_get_ipv6_enabled(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled);
|
||||
|
||||
bool tox_options_get_udp_enabled(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled);
|
||||
|
||||
bool tox_options_get_local_discovery_enabled(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled);
|
||||
|
||||
bool tox_options_get_dht_announcements_enabled(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled);
|
||||
|
||||
Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type);
|
||||
|
||||
const char *tox_options_get_proxy_host(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host);
|
||||
|
||||
uint16_t tox_options_get_proxy_port(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port);
|
||||
|
||||
uint16_t tox_options_get_start_port(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_start_port(Tox_Options *options, uint16_t start_port);
|
||||
|
||||
uint16_t tox_options_get_end_port(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_end_port(Tox_Options *options, uint16_t end_port);
|
||||
|
||||
uint16_t tox_options_get_tcp_port(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port);
|
||||
|
||||
bool tox_options_get_hole_punching_enabled(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled);
|
||||
|
||||
Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type);
|
||||
|
||||
const uint8_t *tox_options_get_savedata_data(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_savedata_data(Tox_Options *options, const uint8_t savedata_data[], size_t length);
|
||||
|
||||
size_t tox_options_get_savedata_length(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length);
|
||||
|
||||
tox_log_cb *tox_options_get_log_callback(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback);
|
||||
|
||||
void *tox_options_get_log_user_data(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data);
|
||||
|
||||
bool tox_options_get_experimental_thread_safety(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_experimental_thread_safety(Tox_Options *options, bool experimental_thread_safety);
|
||||
|
||||
bool tox_options_get_experimental_groups_persistence(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_experimental_groups_persistence(Tox_Options *options, bool experimental_groups_persistence);
|
||||
|
||||
bool tox_options_get_experimental_disable_dns(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns);
|
||||
|
||||
/**
|
||||
* @brief Initialises a Tox_Options object with the default options.
|
||||
*
|
||||
* The result of this function is independent of the original options. All
|
||||
* values will be overwritten, no values will be read (so it is permissible
|
||||
* to pass an uninitialised object).
|
||||
*
|
||||
* If options is NULL, this function has no effect.
|
||||
*
|
||||
* @param options An options object to be filled with default options.
|
||||
*/
|
||||
void tox_options_default(Tox_Options *options);
|
||||
|
||||
typedef enum Tox_Err_Options_New {
|
||||
|
||||
/**
|
||||
* The function returned successfully.
|
||||
*/
|
||||
TOX_ERR_OPTIONS_NEW_OK,
|
||||
|
||||
/**
|
||||
* The function failed to allocate enough memory for the options struct.
|
||||
*/
|
||||
TOX_ERR_OPTIONS_NEW_MALLOC,
|
||||
|
||||
} Tox_Err_Options_New;
|
||||
|
||||
const char *tox_err_options_new_to_string(Tox_Err_Options_New value);
|
||||
|
||||
/**
|
||||
* @brief Allocates a new Tox_Options object and initialises it with the default
|
||||
* options.
|
||||
*
|
||||
* This function can be used to preserve long term ABI compatibility by
|
||||
* giving the responsibility of allocation and deallocation to the Tox library.
|
||||
*
|
||||
* Objects returned from this function must be freed using the tox_options_free
|
||||
* function.
|
||||
*
|
||||
* @return A new Tox_Options object with default options or NULL on failure.
|
||||
*/
|
||||
Tox_Options *tox_options_new(Tox_Err_Options_New *error);
|
||||
|
||||
/**
|
||||
* @brief Releases all resources associated with an options objects.
|
||||
*
|
||||
* Passing a pointer that was not returned by tox_options_new results in
|
||||
* undefined behaviour.
|
||||
*/
|
||||
void tox_options_free(Tox_Options *options);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @{
|
||||
* @name Creation and destruction
|
||||
*/
|
||||
@ -974,7 +540,7 @@ typedef enum Tox_Err_Bootstrap {
|
||||
const char *tox_err_bootstrap_to_string(Tox_Err_Bootstrap value);
|
||||
|
||||
/**
|
||||
* @brief Sends a "get nodes" request to the given bootstrap node with IP, port,
|
||||
* @brief Sends a "nodes request" to the given bootstrap node with IP, port,
|
||||
* and public key to setup connections.
|
||||
*
|
||||
* This function will attempt to connect to the node using UDP. You must use
|
||||
@ -5795,7 +5361,6 @@ typedef Tox_User_Status TOX_USER_STATUS;
|
||||
typedef Tox_Message_Type TOX_MESSAGE_TYPE;
|
||||
typedef Tox_Proxy_Type TOX_PROXY_TYPE;
|
||||
typedef Tox_Savedata_Type TOX_SAVEDATA_TYPE;
|
||||
typedef Tox_Log_Level TOX_LOG_LEVEL;
|
||||
typedef Tox_Connection TOX_CONNECTION;
|
||||
typedef Tox_File_Control TOX_FILE_CONTROL;
|
||||
typedef Tox_Conference_Type TOX_CONFERENCE_TYPE;
|
||||
|
@ -1,20 +1,11 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2016-2025 The TokTok team.
|
||||
*/
|
||||
#include "tox.h"
|
||||
#include "tox.h" // IWYU pragma: associated
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ccompat.h"
|
||||
#include "tox_options.h"
|
||||
#include "tox_private.h"
|
||||
|
||||
#define SET_ERROR_PARAMETER(param, x) \
|
||||
do { \
|
||||
if (param != nullptr) { \
|
||||
*param = x; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
uint32_t tox_version_major(void)
|
||||
{
|
||||
return TOX_VERSION_MAJOR;
|
||||
@ -136,200 +127,6 @@ uint32_t tox_dht_node_public_key_size(void)
|
||||
return TOX_DHT_NODE_PUBLIC_KEY_SIZE;
|
||||
}
|
||||
|
||||
bool tox_options_get_ipv6_enabled(const Tox_Options *options)
|
||||
{
|
||||
return options->ipv6_enabled;
|
||||
}
|
||||
void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled)
|
||||
{
|
||||
options->ipv6_enabled = ipv6_enabled;
|
||||
}
|
||||
bool tox_options_get_udp_enabled(const Tox_Options *options)
|
||||
{
|
||||
return options->udp_enabled;
|
||||
}
|
||||
void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled)
|
||||
{
|
||||
options->udp_enabled = udp_enabled;
|
||||
}
|
||||
Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options)
|
||||
{
|
||||
return options->proxy_type;
|
||||
}
|
||||
void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type)
|
||||
{
|
||||
options->proxy_type = proxy_type;
|
||||
}
|
||||
const char *tox_options_get_proxy_host(const Tox_Options *options)
|
||||
{
|
||||
return options->proxy_host;
|
||||
}
|
||||
void tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host)
|
||||
{
|
||||
options->proxy_host = proxy_host;
|
||||
}
|
||||
uint16_t tox_options_get_proxy_port(const Tox_Options *options)
|
||||
{
|
||||
return options->proxy_port;
|
||||
}
|
||||
void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port)
|
||||
{
|
||||
options->proxy_port = proxy_port;
|
||||
}
|
||||
uint16_t tox_options_get_start_port(const Tox_Options *options)
|
||||
{
|
||||
return options->start_port;
|
||||
}
|
||||
void tox_options_set_start_port(Tox_Options *options, uint16_t start_port)
|
||||
{
|
||||
options->start_port = start_port;
|
||||
}
|
||||
uint16_t tox_options_get_end_port(const Tox_Options *options)
|
||||
{
|
||||
return options->end_port;
|
||||
}
|
||||
void tox_options_set_end_port(Tox_Options *options, uint16_t end_port)
|
||||
{
|
||||
options->end_port = end_port;
|
||||
}
|
||||
uint16_t tox_options_get_tcp_port(const Tox_Options *options)
|
||||
{
|
||||
return options->tcp_port;
|
||||
}
|
||||
void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port)
|
||||
{
|
||||
options->tcp_port = tcp_port;
|
||||
}
|
||||
bool tox_options_get_hole_punching_enabled(const Tox_Options *options)
|
||||
{
|
||||
return options->hole_punching_enabled;
|
||||
}
|
||||
void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled)
|
||||
{
|
||||
options->hole_punching_enabled = hole_punching_enabled;
|
||||
}
|
||||
Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options)
|
||||
{
|
||||
return options->savedata_type;
|
||||
}
|
||||
void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type)
|
||||
{
|
||||
options->savedata_type = savedata_type;
|
||||
}
|
||||
size_t tox_options_get_savedata_length(const Tox_Options *options)
|
||||
{
|
||||
return options->savedata_length;
|
||||
}
|
||||
void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length)
|
||||
{
|
||||
options->savedata_length = savedata_length;
|
||||
}
|
||||
tox_log_cb *tox_options_get_log_callback(const Tox_Options *options)
|
||||
{
|
||||
return options->log_callback;
|
||||
}
|
||||
void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback)
|
||||
{
|
||||
options->log_callback = log_callback;
|
||||
}
|
||||
void *tox_options_get_log_user_data(const Tox_Options *options)
|
||||
{
|
||||
return options->log_user_data;
|
||||
}
|
||||
void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data)
|
||||
{
|
||||
options->log_user_data = log_user_data;
|
||||
}
|
||||
bool tox_options_get_local_discovery_enabled(const Tox_Options *options)
|
||||
{
|
||||
return options->local_discovery_enabled;
|
||||
}
|
||||
void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled)
|
||||
{
|
||||
options->local_discovery_enabled = local_discovery_enabled;
|
||||
}
|
||||
bool tox_options_get_dht_announcements_enabled(const Tox_Options *options)
|
||||
{
|
||||
return options->dht_announcements_enabled;
|
||||
}
|
||||
void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled)
|
||||
{
|
||||
options->dht_announcements_enabled = dht_announcements_enabled;
|
||||
}
|
||||
bool tox_options_get_experimental_thread_safety(const Tox_Options *options)
|
||||
{
|
||||
return options->experimental_thread_safety;
|
||||
}
|
||||
void tox_options_set_experimental_thread_safety(
|
||||
Tox_Options *options, bool experimental_thread_safety)
|
||||
{
|
||||
options->experimental_thread_safety = experimental_thread_safety;
|
||||
}
|
||||
bool tox_options_get_experimental_groups_persistence(const Tox_Options *options)
|
||||
{
|
||||
return options->experimental_groups_persistence;
|
||||
}
|
||||
void tox_options_set_experimental_groups_persistence(
|
||||
Tox_Options *options, bool experimental_groups_persistence)
|
||||
{
|
||||
options->experimental_groups_persistence = experimental_groups_persistence;
|
||||
}
|
||||
bool tox_options_get_experimental_disable_dns(const Tox_Options *options)
|
||||
{
|
||||
return options->experimental_disable_dns;
|
||||
}
|
||||
void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns)
|
||||
{
|
||||
options->experimental_disable_dns = experimental_disable_dns;
|
||||
}
|
||||
|
||||
const uint8_t *tox_options_get_savedata_data(const Tox_Options *options)
|
||||
{
|
||||
return options->savedata_data;
|
||||
}
|
||||
|
||||
void tox_options_set_savedata_data(Tox_Options *options, const uint8_t *savedata_data, size_t length)
|
||||
{
|
||||
options->savedata_data = savedata_data;
|
||||
options->savedata_length = length;
|
||||
}
|
||||
|
||||
void tox_options_default(Tox_Options *options)
|
||||
{
|
||||
if (options != nullptr) {
|
||||
const Tox_Options default_options = {false};
|
||||
*options = default_options;
|
||||
tox_options_set_ipv6_enabled(options, true);
|
||||
tox_options_set_udp_enabled(options, true);
|
||||
tox_options_set_proxy_type(options, TOX_PROXY_TYPE_NONE);
|
||||
tox_options_set_hole_punching_enabled(options, true);
|
||||
tox_options_set_local_discovery_enabled(options, true);
|
||||
tox_options_set_dht_announcements_enabled(options, true);
|
||||
tox_options_set_experimental_thread_safety(options, false);
|
||||
tox_options_set_experimental_groups_persistence(options, false);
|
||||
tox_options_set_experimental_disable_dns(options, false);
|
||||
}
|
||||
}
|
||||
|
||||
Tox_Options *tox_options_new(Tox_Err_Options_New *error)
|
||||
{
|
||||
Tox_Options *options = (Tox_Options *)calloc(1, sizeof(Tox_Options));
|
||||
|
||||
if (options != nullptr) {
|
||||
tox_options_default(options);
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK);
|
||||
return options;
|
||||
}
|
||||
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void tox_options_free(Tox_Options *options)
|
||||
{
|
||||
free(options);
|
||||
}
|
||||
|
||||
const char *tox_user_status_to_string(Tox_User_Status value)
|
||||
{
|
||||
switch (value) {
|
||||
@ -387,27 +184,6 @@ const char *tox_savedata_type_to_string(Tox_Savedata_Type value)
|
||||
|
||||
return "<invalid Tox_Savedata_Type>";
|
||||
}
|
||||
const char *tox_log_level_to_string(Tox_Log_Level value)
|
||||
{
|
||||
switch (value) {
|
||||
case TOX_LOG_LEVEL_TRACE:
|
||||
return "TOX_LOG_LEVEL_TRACE";
|
||||
|
||||
case TOX_LOG_LEVEL_DEBUG:
|
||||
return "TOX_LOG_LEVEL_DEBUG";
|
||||
|
||||
case TOX_LOG_LEVEL_INFO:
|
||||
return "TOX_LOG_LEVEL_INFO";
|
||||
|
||||
case TOX_LOG_LEVEL_WARNING:
|
||||
return "TOX_LOG_LEVEL_WARNING";
|
||||
|
||||
case TOX_LOG_LEVEL_ERROR:
|
||||
return "TOX_LOG_LEVEL_ERROR";
|
||||
}
|
||||
|
||||
return "<invalid Tox_Log_Level>";
|
||||
}
|
||||
const char *tox_err_options_new_to_string(Tox_Err_Options_New value)
|
||||
{
|
||||
switch (value) {
|
||||
|
@ -53,7 +53,7 @@ struct Tox_Dispatch {
|
||||
tox_events_group_self_join_cb *group_self_join_callback;
|
||||
tox_events_group_join_fail_cb *group_join_fail_callback;
|
||||
tox_events_group_moderation_cb *group_moderation_callback;
|
||||
tox_events_dht_get_nodes_response_cb *dht_get_nodes_response_callback;
|
||||
tox_events_dht_nodes_response_cb *dht_nodes_response_callback;
|
||||
};
|
||||
|
||||
Tox_Dispatch *tox_dispatch_new(Tox_Err_Dispatch_New *error)
|
||||
@ -279,10 +279,10 @@ void tox_events_callback_group_moderation(
|
||||
{
|
||||
dispatch->group_moderation_callback = callback;
|
||||
}
|
||||
void tox_events_callback_dht_get_nodes_response(
|
||||
Tox_Dispatch *dispatch, tox_events_dht_get_nodes_response_cb *callback)
|
||||
void tox_events_callback_dht_nodes_response(
|
||||
Tox_Dispatch *dispatch, tox_events_dht_nodes_response_cb *callback)
|
||||
{
|
||||
dispatch->dht_get_nodes_response_callback = callback;
|
||||
dispatch->dht_nodes_response_callback = callback;
|
||||
}
|
||||
|
||||
non_null(1, 2) nullable(3)
|
||||
@ -602,8 +602,8 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev
|
||||
}
|
||||
|
||||
case TOX_EVENT_DHT_GET_NODES_RESPONSE: {
|
||||
if (dispatch->dht_get_nodes_response_callback != nullptr) {
|
||||
dispatch->dht_get_nodes_response_callback(event->data.dht_get_nodes_response, user_data);
|
||||
if (dispatch->dht_nodes_response_callback != nullptr) {
|
||||
dispatch->dht_nodes_response_callback(event->data.dht_nodes_response, user_data);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -136,8 +136,8 @@ typedef void tox_events_group_join_fail_cb(
|
||||
const Tox_Event_Group_Join_Fail *event, void *user_data);
|
||||
typedef void tox_events_group_moderation_cb(
|
||||
const Tox_Event_Group_Moderation *event, void *user_data);
|
||||
typedef void tox_events_dht_get_nodes_response_cb(
|
||||
const Tox_Event_Dht_Get_Nodes_Response *event, void *user_data);
|
||||
typedef void tox_events_dht_nodes_response_cb(
|
||||
const Tox_Event_Dht_Nodes_Response *event, void *user_data);
|
||||
|
||||
void tox_events_callback_conference_connected(
|
||||
Tox_Dispatch *dispatch, tox_events_conference_connected_cb *callback);
|
||||
@ -217,8 +217,8 @@ void tox_events_callback_group_join_fail(
|
||||
Tox_Dispatch *dispatch, tox_events_group_join_fail_cb *callback);
|
||||
void tox_events_callback_group_moderation(
|
||||
Tox_Dispatch *dispatch, tox_events_group_moderation_cb *callback);
|
||||
void tox_events_callback_dht_get_nodes_response(
|
||||
Tox_Dispatch *dispatch, tox_events_dht_get_nodes_response_cb *callback);
|
||||
void tox_events_callback_dht_nodes_response(
|
||||
Tox_Dispatch *dispatch, tox_events_dht_nodes_response_cb *callback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -351,7 +351,7 @@ bool tox_event_construct(Tox_Event *event, Tox_Event_Type type, const Memory *me
|
||||
}
|
||||
|
||||
case TOX_EVENT_DHT_GET_NODES_RESPONSE: {
|
||||
event->data.dht_get_nodes_response = tox_event_dht_get_nodes_response_new(mem);
|
||||
event->data.dht_nodes_response = tox_event_dht_nodes_response_new(mem);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -566,7 +566,7 @@ void tox_event_destruct(Tox_Event *event, const Memory *mem)
|
||||
}
|
||||
|
||||
case TOX_EVENT_DHT_GET_NODES_RESPONSE: {
|
||||
tox_event_dht_get_nodes_response_free(event->data.dht_get_nodes_response, mem);
|
||||
tox_event_dht_nodes_response_free(event->data.dht_nodes_response, mem);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -706,7 +706,7 @@ static bool tox_event_data_pack(Tox_Event_Type type, const Tox_Event_Data *data,
|
||||
return tox_event_group_moderation_pack(data->group_moderation, bp);
|
||||
|
||||
case TOX_EVENT_DHT_GET_NODES_RESPONSE:
|
||||
return tox_event_dht_get_nodes_response_pack(data->dht_get_nodes_response, bp);
|
||||
return tox_event_dht_nodes_response_pack(data->dht_nodes_response, bp);
|
||||
|
||||
case TOX_EVENT_INVALID:
|
||||
return false;
|
||||
@ -1070,7 +1070,7 @@ static bool tox_event_data_unpack(Tox_Event_Type type, Tox_Event_Data *data, Bin
|
||||
return tox_event_group_moderation_unpack(&data->group_moderation, bu, mem);
|
||||
|
||||
case TOX_EVENT_DHT_GET_NODES_RESPONSE:
|
||||
return tox_event_dht_get_nodes_response_unpack(&data->dht_get_nodes_response, bu, mem);
|
||||
return tox_event_dht_nodes_response_unpack(&data->dht_nodes_response, bu, mem);
|
||||
|
||||
case TOX_EVENT_INVALID:
|
||||
return false;
|
||||
|
@ -61,7 +61,7 @@ typedef union Tox_Event_Data {
|
||||
Tox_Event_Group_Self_Join *group_self_join;
|
||||
Tox_Event_Group_Join_Fail *group_join_fail;
|
||||
Tox_Event_Group_Moderation *group_moderation;
|
||||
Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response;
|
||||
Tox_Event_Dht_Nodes_Response *dht_nodes_response;
|
||||
} Tox_Event_Data;
|
||||
|
||||
struct Tox_Event {
|
||||
@ -113,7 +113,7 @@ non_null() Tox_Event_Group_Peer_Exit *tox_event_group_peer_exit_new(const Memory
|
||||
non_null() Tox_Event_Group_Self_Join *tox_event_group_self_join_new(const Memory *mem);
|
||||
non_null() Tox_Event_Group_Join_Fail *tox_event_group_join_fail_new(const Memory *mem);
|
||||
non_null() Tox_Event_Group_Moderation *tox_event_group_moderation_new(const Memory *mem);
|
||||
non_null() Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_new(const Memory *mem);
|
||||
non_null() Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_new(const Memory *mem);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@ -159,7 +159,7 @@ non_null(2) nullable(1) void tox_event_group_peer_exit_free(Tox_Event_Group_Peer
|
||||
non_null(2) nullable(1) void tox_event_group_self_join_free(Tox_Event_Group_Self_Join *group_self_join, const Memory *mem);
|
||||
non_null(2) nullable(1) void tox_event_group_join_fail_free(Tox_Event_Group_Join_Fail *group_join_fail, const Memory *mem);
|
||||
non_null(2) nullable(1) void tox_event_group_moderation_free(Tox_Event_Group_Moderation *group_moderation, const Memory *mem);
|
||||
non_null(2) nullable(1) void tox_event_dht_get_nodes_response_free(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem);
|
||||
non_null(2) nullable(1) void tox_event_dht_nodes_response_free(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const Memory *mem);
|
||||
|
||||
/**
|
||||
* Pack into msgpack.
|
||||
@ -205,7 +205,7 @@ non_null() bool tox_event_group_peer_exit_pack(const Tox_Event_Group_Peer_Exit *
|
||||
non_null() bool tox_event_group_self_join_pack(const Tox_Event_Group_Self_Join *event, Bin_Pack *bp);
|
||||
non_null() bool tox_event_group_join_fail_pack(const Tox_Event_Group_Join_Fail *event, Bin_Pack *bp);
|
||||
non_null() bool tox_event_group_moderation_pack(const Tox_Event_Group_Moderation *event, Bin_Pack *bp);
|
||||
non_null() bool tox_event_dht_get_nodes_response_pack(const Tox_Event_Dht_Get_Nodes_Response *event, Bin_Pack *bp);
|
||||
non_null() bool tox_event_dht_nodes_response_pack(const Tox_Event_Dht_Nodes_Response *event, Bin_Pack *bp);
|
||||
|
||||
/**
|
||||
* Unpack from msgpack.
|
||||
@ -251,7 +251,7 @@ non_null() bool tox_event_group_peer_exit_unpack(Tox_Event_Group_Peer_Exit **eve
|
||||
non_null() bool tox_event_group_self_join_unpack(Tox_Event_Group_Self_Join **event, Bin_Unpack *bu, const Memory *mem);
|
||||
non_null() bool tox_event_group_join_fail_unpack(Tox_Event_Group_Join_Fail **event, Bin_Unpack *bu, const Memory *mem);
|
||||
non_null() bool tox_event_group_moderation_unpack(Tox_Event_Group_Moderation **event, Bin_Unpack *bu, const Memory *mem);
|
||||
non_null() bool tox_event_dht_get_nodes_response_unpack(Tox_Event_Dht_Get_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem);
|
||||
non_null() bool tox_event_dht_nodes_response_unpack(Tox_Event_Dht_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "tox.h"
|
||||
#include "tox_event.h"
|
||||
#include "tox_private.h"
|
||||
#include "tox_struct.h"
|
||||
#include "tox_struct.h" // IWYU pragma: keep
|
||||
|
||||
/*****************************************************
|
||||
*
|
||||
@ -66,7 +66,7 @@ void tox_events_init(Tox *tox)
|
||||
tox_callback_group_self_join(tox, tox_events_handle_group_self_join);
|
||||
tox_callback_group_join_fail(tox, tox_events_handle_group_join_fail);
|
||||
tox_callback_group_moderation(tox, tox_events_handle_group_moderation);
|
||||
tox_callback_dht_get_nodes_response(tox, tox_events_handle_dht_get_nodes_response);
|
||||
tox_callback_dht_nodes_response(tox, tox_events_handle_dht_nodes_response);
|
||||
}
|
||||
|
||||
uint32_t tox_events_get_size(const Tox_Events *events)
|
||||
@ -173,7 +173,7 @@ Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_
|
||||
};
|
||||
events->mem = sys->mem;
|
||||
|
||||
if (!bin_unpack_obj(tox_events_unpack_handler, events, bytes, bytes_size)) {
|
||||
if (!bin_unpack_obj(sys->mem, tox_events_unpack_handler, events, bytes, bytes_size)) {
|
||||
tox_events_free(events);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -352,15 +352,15 @@ uint32_t tox_event_group_moderation_get_target_peer_id(
|
||||
Tox_Group_Mod_Event tox_event_group_moderation_get_mod_type(
|
||||
const Tox_Event_Group_Moderation *group_moderation);
|
||||
|
||||
typedef struct Tox_Event_Dht_Get_Nodes_Response Tox_Event_Dht_Get_Nodes_Response;
|
||||
const uint8_t *tox_event_dht_get_nodes_response_get_public_key(
|
||||
const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response);
|
||||
const uint8_t *tox_event_dht_get_nodes_response_get_ip(
|
||||
const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response);
|
||||
uint32_t tox_event_dht_get_nodes_response_get_ip_length(
|
||||
const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response);
|
||||
uint16_t tox_event_dht_get_nodes_response_get_port(
|
||||
const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response);
|
||||
typedef struct Tox_Event_Dht_Nodes_Response Tox_Event_Dht_Nodes_Response;
|
||||
const uint8_t *tox_event_dht_nodes_response_get_public_key(
|
||||
const Tox_Event_Dht_Nodes_Response *dht_nodes_response);
|
||||
const uint8_t *tox_event_dht_nodes_response_get_ip(
|
||||
const Tox_Event_Dht_Nodes_Response *dht_nodes_response);
|
||||
uint32_t tox_event_dht_nodes_response_get_ip_length(
|
||||
const Tox_Event_Dht_Nodes_Response *dht_nodes_response);
|
||||
uint16_t tox_event_dht_nodes_response_get_port(
|
||||
const Tox_Event_Dht_Nodes_Response *dht_nodes_response);
|
||||
|
||||
typedef enum Tox_Event_Type {
|
||||
TOX_EVENT_SELF_CONNECTION_STATUS = 0,
|
||||
@ -507,7 +507,7 @@ const Tox_Event_Group_Join_Fail *tox_event_get_group_join_fail(
|
||||
const Tox_Event *event);
|
||||
const Tox_Event_Group_Moderation *tox_event_get_group_moderation(
|
||||
const Tox_Event *event);
|
||||
const Tox_Event_Dht_Get_Nodes_Response *tox_event_get_dht_get_nodes_response(
|
||||
const Tox_Event_Dht_Nodes_Response *tox_event_get_dht_nodes_response(
|
||||
const Tox_Event *event);
|
||||
|
||||
/**
|
||||
|
27
toxcore/tox_log_level.c
Normal file
27
toxcore/tox_log_level.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2016-2025 The TokTok team.
|
||||
* Copyright © 2013 Tox project.
|
||||
*/
|
||||
#include "tox_log_level.h"
|
||||
|
||||
const char *tox_log_level_to_string(Tox_Log_Level value)
|
||||
{
|
||||
switch (value) {
|
||||
case TOX_LOG_LEVEL_TRACE:
|
||||
return "TOX_LOG_LEVEL_TRACE";
|
||||
|
||||
case TOX_LOG_LEVEL_DEBUG:
|
||||
return "TOX_LOG_LEVEL_DEBUG";
|
||||
|
||||
case TOX_LOG_LEVEL_INFO:
|
||||
return "TOX_LOG_LEVEL_INFO";
|
||||
|
||||
case TOX_LOG_LEVEL_WARNING:
|
||||
return "TOX_LOG_LEVEL_WARNING";
|
||||
|
||||
case TOX_LOG_LEVEL_ERROR:
|
||||
return "TOX_LOG_LEVEL_ERROR";
|
||||
}
|
||||
|
||||
return "<invalid Tox_Log_Level>";
|
||||
}
|
58
toxcore/tox_log_level.h
Normal file
58
toxcore/tox_log_level.h
Normal file
@ -0,0 +1,58 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2022-2025 The TokTok team.
|
||||
*/
|
||||
|
||||
#ifndef C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H
|
||||
#define C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Severity level of log messages.
|
||||
*/
|
||||
typedef enum Tox_Log_Level {
|
||||
/**
|
||||
* Very detailed traces including all network activity.
|
||||
*/
|
||||
TOX_LOG_LEVEL_TRACE,
|
||||
|
||||
/**
|
||||
* Debug messages such as which port we bind to.
|
||||
*/
|
||||
TOX_LOG_LEVEL_DEBUG,
|
||||
|
||||
/**
|
||||
* Informational log messages such as video call status changes.
|
||||
*/
|
||||
TOX_LOG_LEVEL_INFO,
|
||||
|
||||
/**
|
||||
* Warnings about internal inconsistency or logic errors.
|
||||
*/
|
||||
TOX_LOG_LEVEL_WARNING,
|
||||
|
||||
/**
|
||||
* Severe unexpected errors caused by external or internal inconsistency.
|
||||
*/
|
||||
TOX_LOG_LEVEL_ERROR,
|
||||
} Tox_Log_Level;
|
||||
|
||||
const char *tox_log_level_to_string(Tox_Log_Level value);
|
||||
|
||||
//!TOKSTYLE-
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
|
||||
#ifndef TOX_HIDE_DEPRECATED
|
||||
typedef Tox_Log_Level TOX_LOG_LEVEL;
|
||||
#endif /* TOX_HIDE_DEPRECATED */
|
||||
|
||||
#endif
|
||||
//!TOKSTYLE+
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H */
|
285
toxcore/tox_options.c
Normal file
285
toxcore/tox_options.c
Normal file
@ -0,0 +1,285 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2016-2025 The TokTok team.
|
||||
* Copyright © 2013 Tox project.
|
||||
*/
|
||||
|
||||
#include "tox_options.h"
|
||||
|
||||
#include <stdlib.h> // free, malloc, calloc
|
||||
#include <string.h> // memcpy, strlen
|
||||
|
||||
#include "ccompat.h" // nullptr
|
||||
|
||||
#define SET_ERROR_PARAMETER(param, x) \
|
||||
do { \
|
||||
if (param != nullptr) { \
|
||||
*param = x; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
bool tox_options_get_ipv6_enabled(const Tox_Options *options)
|
||||
{
|
||||
return options->ipv6_enabled;
|
||||
}
|
||||
void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled)
|
||||
{
|
||||
options->ipv6_enabled = ipv6_enabled;
|
||||
}
|
||||
bool tox_options_get_udp_enabled(const Tox_Options *options)
|
||||
{
|
||||
return options->udp_enabled;
|
||||
}
|
||||
void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled)
|
||||
{
|
||||
options->udp_enabled = udp_enabled;
|
||||
}
|
||||
Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options)
|
||||
{
|
||||
return options->proxy_type;
|
||||
}
|
||||
void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type)
|
||||
{
|
||||
options->proxy_type = proxy_type;
|
||||
}
|
||||
const char *tox_options_get_proxy_host(const Tox_Options *options)
|
||||
{
|
||||
return options->proxy_host;
|
||||
}
|
||||
bool tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host)
|
||||
{
|
||||
if (!options->experimental_owned_data) {
|
||||
options->proxy_host = proxy_host;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (options->owned_proxy_host != nullptr) {
|
||||
free(options->owned_proxy_host);
|
||||
options->owned_proxy_host = nullptr;
|
||||
}
|
||||
if (proxy_host == nullptr) {
|
||||
options->proxy_host = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
const size_t proxy_host_length = strlen(proxy_host) + 1;
|
||||
char *owned_ptr = (char *)malloc(proxy_host_length);
|
||||
if (owned_ptr == nullptr) {
|
||||
options->proxy_host = proxy_host;
|
||||
options->owned_proxy_host = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(owned_ptr, proxy_host, proxy_host_length);
|
||||
options->proxy_host = owned_ptr;
|
||||
options->owned_proxy_host = owned_ptr;
|
||||
return true;
|
||||
}
|
||||
uint16_t tox_options_get_proxy_port(const Tox_Options *options)
|
||||
{
|
||||
return options->proxy_port;
|
||||
}
|
||||
void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port)
|
||||
{
|
||||
options->proxy_port = proxy_port;
|
||||
}
|
||||
uint16_t tox_options_get_start_port(const Tox_Options *options)
|
||||
{
|
||||
return options->start_port;
|
||||
}
|
||||
void tox_options_set_start_port(Tox_Options *options, uint16_t start_port)
|
||||
{
|
||||
options->start_port = start_port;
|
||||
}
|
||||
uint16_t tox_options_get_end_port(const Tox_Options *options)
|
||||
{
|
||||
return options->end_port;
|
||||
}
|
||||
void tox_options_set_end_port(Tox_Options *options, uint16_t end_port)
|
||||
{
|
||||
options->end_port = end_port;
|
||||
}
|
||||
uint16_t tox_options_get_tcp_port(const Tox_Options *options)
|
||||
{
|
||||
return options->tcp_port;
|
||||
}
|
||||
void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port)
|
||||
{
|
||||
options->tcp_port = tcp_port;
|
||||
}
|
||||
bool tox_options_get_hole_punching_enabled(const Tox_Options *options)
|
||||
{
|
||||
return options->hole_punching_enabled;
|
||||
}
|
||||
void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled)
|
||||
{
|
||||
options->hole_punching_enabled = hole_punching_enabled;
|
||||
}
|
||||
Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options)
|
||||
{
|
||||
return options->savedata_type;
|
||||
}
|
||||
void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type)
|
||||
{
|
||||
options->savedata_type = savedata_type;
|
||||
}
|
||||
size_t tox_options_get_savedata_length(const Tox_Options *options)
|
||||
{
|
||||
return options->savedata_length;
|
||||
}
|
||||
void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length)
|
||||
{
|
||||
options->savedata_length = savedata_length;
|
||||
}
|
||||
tox_log_cb *tox_options_get_log_callback(const Tox_Options *options)
|
||||
{
|
||||
return options->log_callback;
|
||||
}
|
||||
void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback)
|
||||
{
|
||||
options->log_callback = log_callback;
|
||||
}
|
||||
void *tox_options_get_log_user_data(const Tox_Options *options)
|
||||
{
|
||||
return options->log_user_data;
|
||||
}
|
||||
void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data)
|
||||
{
|
||||
options->log_user_data = log_user_data;
|
||||
}
|
||||
bool tox_options_get_local_discovery_enabled(const Tox_Options *options)
|
||||
{
|
||||
return options->local_discovery_enabled;
|
||||
}
|
||||
void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled)
|
||||
{
|
||||
options->local_discovery_enabled = local_discovery_enabled;
|
||||
}
|
||||
bool tox_options_get_dht_announcements_enabled(const Tox_Options *options)
|
||||
{
|
||||
return options->dht_announcements_enabled;
|
||||
}
|
||||
void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled)
|
||||
{
|
||||
options->dht_announcements_enabled = dht_announcements_enabled;
|
||||
}
|
||||
bool tox_options_get_experimental_thread_safety(const Tox_Options *options)
|
||||
{
|
||||
return options->experimental_thread_safety;
|
||||
}
|
||||
void tox_options_set_experimental_thread_safety(
|
||||
Tox_Options *options, bool experimental_thread_safety)
|
||||
{
|
||||
options->experimental_thread_safety = experimental_thread_safety;
|
||||
}
|
||||
bool tox_options_get_experimental_groups_persistence(const Tox_Options *options)
|
||||
{
|
||||
return options->experimental_groups_persistence;
|
||||
}
|
||||
void tox_options_set_experimental_groups_persistence(
|
||||
Tox_Options *options, bool experimental_groups_persistence)
|
||||
{
|
||||
options->experimental_groups_persistence = experimental_groups_persistence;
|
||||
}
|
||||
bool tox_options_get_experimental_disable_dns(const Tox_Options *options)
|
||||
{
|
||||
return options->experimental_disable_dns;
|
||||
}
|
||||
void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns)
|
||||
{
|
||||
options->experimental_disable_dns = experimental_disable_dns;
|
||||
}
|
||||
bool tox_options_get_experimental_owned_data(const Tox_Options *options)
|
||||
{
|
||||
return options->experimental_owned_data;
|
||||
}
|
||||
void tox_options_set_experimental_owned_data(
|
||||
Tox_Options *options, bool experimental_owned_data)
|
||||
{
|
||||
options->experimental_owned_data = experimental_owned_data;
|
||||
}
|
||||
|
||||
const uint8_t *tox_options_get_savedata_data(const Tox_Options *options)
|
||||
{
|
||||
return options->savedata_data;
|
||||
}
|
||||
|
||||
bool tox_options_set_savedata_data(Tox_Options *options, const uint8_t *savedata_data, size_t length)
|
||||
{
|
||||
if (!options->experimental_owned_data) {
|
||||
options->savedata_data = savedata_data;
|
||||
options->savedata_length = length;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (options->owned_savedata_data != nullptr) {
|
||||
free(options->owned_savedata_data);
|
||||
options->owned_savedata_data = nullptr;
|
||||
}
|
||||
if (savedata_data == nullptr) {
|
||||
options->savedata_data = nullptr;
|
||||
options->savedata_length = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t *owned_ptr = (uint8_t *)malloc(length);
|
||||
if (owned_ptr == nullptr) {
|
||||
options->savedata_data = savedata_data;
|
||||
options->savedata_length = length;
|
||||
options->owned_savedata_data = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(owned_ptr, savedata_data, length);
|
||||
options->savedata_data = owned_ptr;
|
||||
options->savedata_length = length;
|
||||
options->owned_savedata_data = owned_ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
void tox_options_default(Tox_Options *options)
|
||||
{
|
||||
if (options != nullptr) {
|
||||
// Free any owned data.
|
||||
tox_options_set_proxy_host(options, nullptr);
|
||||
tox_options_set_savedata_data(options, nullptr, 0);
|
||||
|
||||
// Set the rest to default values.
|
||||
const Tox_Options default_options = {false};
|
||||
*options = default_options;
|
||||
tox_options_set_ipv6_enabled(options, true);
|
||||
tox_options_set_udp_enabled(options, true);
|
||||
tox_options_set_proxy_type(options, TOX_PROXY_TYPE_NONE);
|
||||
tox_options_set_hole_punching_enabled(options, true);
|
||||
tox_options_set_local_discovery_enabled(options, true);
|
||||
tox_options_set_dht_announcements_enabled(options, true);
|
||||
tox_options_set_experimental_thread_safety(options, false);
|
||||
tox_options_set_experimental_groups_persistence(options, false);
|
||||
tox_options_set_experimental_disable_dns(options, false);
|
||||
tox_options_set_experimental_owned_data(options, false);
|
||||
}
|
||||
}
|
||||
|
||||
Tox_Options *tox_options_new(Tox_Err_Options_New *error)
|
||||
{
|
||||
Tox_Options *options = (Tox_Options *)calloc(1, sizeof(Tox_Options));
|
||||
|
||||
if (options != nullptr) {
|
||||
tox_options_default(options);
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK);
|
||||
return options;
|
||||
}
|
||||
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void tox_options_free(Tox_Options *options)
|
||||
{
|
||||
if (options != nullptr) {
|
||||
// Free any owned data.
|
||||
tox_options_set_proxy_host(options, nullptr);
|
||||
tox_options_set_savedata_data(options, nullptr, 0);
|
||||
free(options);
|
||||
}
|
||||
}
|
455
toxcore/tox_options.h
Normal file
455
toxcore/tox_options.h
Normal file
@ -0,0 +1,455 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2016-2025 The TokTok team.
|
||||
* Copyright © 2013 Tox project.
|
||||
*/
|
||||
|
||||
#ifndef C_TOXCORE_TOXCORE_TOX_OPTIONS_H
|
||||
#define C_TOXCORE_TOXCORE_TOX_OPTIONS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "tox_log_level.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Tox;
|
||||
|
||||
/** @{
|
||||
* @name Startup options
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Type of proxy used to connect to TCP relays.
|
||||
*/
|
||||
typedef enum Tox_Proxy_Type {
|
||||
/**
|
||||
* Don't use a proxy.
|
||||
*/
|
||||
TOX_PROXY_TYPE_NONE,
|
||||
|
||||
/**
|
||||
* HTTP proxy using CONNECT.
|
||||
*/
|
||||
TOX_PROXY_TYPE_HTTP,
|
||||
|
||||
/**
|
||||
* SOCKS proxy for simple socket pipes.
|
||||
*/
|
||||
TOX_PROXY_TYPE_SOCKS5,
|
||||
} Tox_Proxy_Type;
|
||||
|
||||
const char *tox_proxy_type_to_string(Tox_Proxy_Type value);
|
||||
|
||||
/**
|
||||
* @brief Type of savedata to create the Tox instance from.
|
||||
*/
|
||||
typedef enum Tox_Savedata_Type {
|
||||
/**
|
||||
* No savedata.
|
||||
*/
|
||||
TOX_SAVEDATA_TYPE_NONE,
|
||||
|
||||
/**
|
||||
* Savedata is one that was obtained from tox_get_savedata.
|
||||
*/
|
||||
TOX_SAVEDATA_TYPE_TOX_SAVE,
|
||||
|
||||
/**
|
||||
* Savedata is a secret key of length TOX_SECRET_KEY_SIZE.
|
||||
*/
|
||||
TOX_SAVEDATA_TYPE_SECRET_KEY,
|
||||
} Tox_Savedata_Type;
|
||||
|
||||
const char *tox_savedata_type_to_string(Tox_Savedata_Type value);
|
||||
|
||||
/**
|
||||
* @brief This event is triggered when Tox logs an internal message.
|
||||
*
|
||||
* This is mostly useful for debugging. This callback can be called from any
|
||||
* function, not just tox_iterate. This means the user data lifetime must at
|
||||
* least extend between registering and unregistering it or tox_kill.
|
||||
*
|
||||
* Other toxcore modules such as toxav may concurrently call this callback at
|
||||
* any time. Thus, user code must make sure it is equipped to handle concurrent
|
||||
* execution, e.g. by employing appropriate mutex locking.
|
||||
*
|
||||
* When using the experimental_thread_safety option, no Tox API functions can
|
||||
* be called from within the log callback.
|
||||
*
|
||||
* @param level The severity of the log message.
|
||||
* @param file The source file from which the message originated.
|
||||
* @param line The source line from which the message originated.
|
||||
* @param func The function from which the message originated.
|
||||
* @param message The log message.
|
||||
* @param user_data The user data pointer passed to tox_new in options.
|
||||
*/
|
||||
typedef void tox_log_cb(struct Tox *tox, Tox_Log_Level level, const char *file,
|
||||
uint32_t line, const char *func, const char *message,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* @brief This struct contains all the startup options for Tox.
|
||||
*
|
||||
* You must tox_options_new to allocate an object of this type.
|
||||
*
|
||||
* WARNING: Although this struct happens to be visible in the API, it is
|
||||
* effectively private. Do not allocate this yourself or access members
|
||||
* directly, as it *will* break binary compatibility frequently.
|
||||
*
|
||||
* @deprecated The memory layout of this struct (size, alignment, and field
|
||||
* order) is not part of the ABI. To remain compatible, prefer to use
|
||||
* tox_options_new to allocate the object and accessor functions to set the
|
||||
* members. The struct will become opaque (i.e. the definition will become
|
||||
* private) in v0.3.0.
|
||||
*/
|
||||
typedef struct Tox_Options Tox_Options;
|
||||
|
||||
#ifndef TOX_HIDE_DEPRECATED
|
||||
struct Tox_Options {
|
||||
/**
|
||||
* The type of socket to create.
|
||||
*
|
||||
* If this is set to false, an IPv4 socket is created, which subsequently
|
||||
* only allows IPv4 communication.
|
||||
* If it is set to true, an IPv6 socket is created, allowing both IPv4 and
|
||||
* IPv6 communication.
|
||||
*/
|
||||
bool ipv6_enabled;
|
||||
|
||||
/**
|
||||
* Enable the use of UDP communication when available.
|
||||
*
|
||||
* Setting this to false will force Tox to use TCP only. Communications will
|
||||
* need to be relayed through a TCP relay node, potentially slowing them
|
||||
* down.
|
||||
*
|
||||
* If a proxy is enabled, UDP will be disabled if either the Tox library or
|
||||
* the proxy don't support proxying UDP messages.
|
||||
*/
|
||||
bool udp_enabled;
|
||||
|
||||
/**
|
||||
* Enable local network peer discovery.
|
||||
*
|
||||
* Disabling this will cause Tox to not look for peers on the local network.
|
||||
*/
|
||||
bool local_discovery_enabled;
|
||||
|
||||
/**
|
||||
* Enable storing DHT announcements and forwarding corresponding requests.
|
||||
*
|
||||
* Disabling this will cause Tox to ignore the relevant packets.
|
||||
*/
|
||||
bool dht_announcements_enabled;
|
||||
|
||||
/**
|
||||
* Pass communications through a proxy.
|
||||
*/
|
||||
Tox_Proxy_Type proxy_type;
|
||||
|
||||
/**
|
||||
* The IP address or DNS name of the proxy to be used.
|
||||
*
|
||||
* If used, this must be non-NULL and be a valid DNS name. The name must not
|
||||
* exceed TOX_MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C
|
||||
* string format (TOX_MAX_HOSTNAME_LENGTH includes the NUL byte).
|
||||
*
|
||||
* This member is ignored (it can be NULL) if proxy_type is
|
||||
* TOX_PROXY_TYPE_NONE.
|
||||
*
|
||||
* The data pointed at by this member is owned by the user, so must
|
||||
* outlive the options object (unless experimental_owned_data is set).
|
||||
*/
|
||||
const char *proxy_host;
|
||||
|
||||
/**
|
||||
* The port to use to connect to the proxy server.
|
||||
*
|
||||
* Ports must be in the range (1, 65535). The value is ignored if
|
||||
* proxy_type is TOX_PROXY_TYPE_NONE.
|
||||
*/
|
||||
uint16_t proxy_port;
|
||||
|
||||
/**
|
||||
* The start port of the inclusive port range to attempt to use.
|
||||
*
|
||||
* If both start_port and end_port are 0, the default port range will be
|
||||
* used: `[33445, 33545]`.
|
||||
*
|
||||
* If either start_port or end_port is 0 while the other is non-zero, the
|
||||
* non-zero port will be the only port in the range.
|
||||
*
|
||||
* Having start_port > end_port will yield the same behavior as if
|
||||
* start_port and end_port were swapped.
|
||||
*/
|
||||
uint16_t start_port;
|
||||
|
||||
/**
|
||||
* The end port of the inclusive port range to attempt to use.
|
||||
*/
|
||||
uint16_t end_port;
|
||||
|
||||
/**
|
||||
* The port to use for the TCP server (relay). If 0, the TCP server is
|
||||
* disabled.
|
||||
*
|
||||
* Enabling it is not required for Tox to function properly.
|
||||
*
|
||||
* When enabled, your Tox instance can act as a TCP relay for other Tox
|
||||
* instance. This leads to increased traffic, thus when writing a client
|
||||
* it is recommended to enable TCP server only if the user has an option
|
||||
* to disable it.
|
||||
*/
|
||||
uint16_t tcp_port;
|
||||
|
||||
/**
|
||||
* Enables or disables UDP hole-punching. (Default: enabled).
|
||||
*/
|
||||
bool hole_punching_enabled;
|
||||
|
||||
/**
|
||||
* The type of savedata to load from.
|
||||
*/
|
||||
Tox_Savedata_Type savedata_type;
|
||||
|
||||
/**
|
||||
* The savedata (either a Tox save or a secret key) to load from.
|
||||
*
|
||||
* The data pointed at by this member is owned by the user, so must
|
||||
* outlive the options object (unless experimental_owned_data is set).
|
||||
*/
|
||||
const uint8_t *savedata_data;
|
||||
|
||||
/**
|
||||
* The length of the savedata.
|
||||
*/
|
||||
size_t savedata_length;
|
||||
|
||||
/**
|
||||
* Logging callback for the new Tox instance.
|
||||
*/
|
||||
tox_log_cb *log_callback;
|
||||
|
||||
/**
|
||||
* User data pointer passed to the logging callback.
|
||||
*/
|
||||
void *log_user_data;
|
||||
|
||||
/**
|
||||
* These options are experimental, so avoid writing code that depends on
|
||||
* them. Options marked "experimental" may change their behaviour or go away
|
||||
* entirely in the future, or may be renamed to something non-experimental
|
||||
* if they become part of the supported API.
|
||||
*/
|
||||
/**
|
||||
* Make public API functions thread-safe using a per-instance lock.
|
||||
*
|
||||
* Default: false.
|
||||
*/
|
||||
bool experimental_thread_safety;
|
||||
|
||||
/**
|
||||
* Enable saving DHT-based group chats to Tox save data (via
|
||||
* `tox_get_savedata`). This format will change in the future, so don't rely
|
||||
* on it.
|
||||
*
|
||||
* As an alternative, clients can save the group chat ID in client-owned
|
||||
* savedata. Then, when the client starts, it can use `tox_group_join`
|
||||
* with the saved chat ID to recreate the group chat.
|
||||
*
|
||||
* Default: false.
|
||||
*/
|
||||
bool experimental_groups_persistence;
|
||||
|
||||
/**
|
||||
* @brief Disable DNS hostname resolution.
|
||||
*
|
||||
* Hostnames or IP addresses are passed to the bootstrap/add_tcp_relay
|
||||
* function and proxy host options. If disabled (this flag is true), only
|
||||
* IP addresses are allowed.
|
||||
*
|
||||
* If this is set to true, the library will not attempt to resolve
|
||||
* hostnames. This is useful for clients that want to resolve hostnames
|
||||
* themselves and pass the resolved IP addresses to the library (e.g. in
|
||||
* case it wants to use Tor).
|
||||
* Passing hostnames will result in a TOX_ERR_BOOTSTRAP_BAD_HOST error if
|
||||
* this is set to true.
|
||||
*
|
||||
* Default: false. May become true in the future (0.3.0).
|
||||
*/
|
||||
bool experimental_disable_dns;
|
||||
|
||||
/**
|
||||
* @brief Whether the savedata data is owned by the Tox_Options object.
|
||||
*
|
||||
* If true, the setters for savedata and proxy_host try to copy the string.
|
||||
* If that fails, the value is not copied and the member is set to the
|
||||
* user-provided pointer. In that case, the user must not free the string
|
||||
* until the Tox_Options object is freed. Client code can check whether
|
||||
* allocation succeeded by checking the returned bool. If
|
||||
* experimental_owned_data is false, it will always return true. If set to
|
||||
* true, the return value will be false on allocation failure.
|
||||
*
|
||||
* If set to true, this must be set before any other member that allocates
|
||||
* memory is set.
|
||||
*/
|
||||
bool experimental_owned_data;
|
||||
|
||||
/**
|
||||
* @brief Owned pointer to the savedata data.
|
||||
* @private
|
||||
*/
|
||||
uint8_t *owned_savedata_data;
|
||||
|
||||
/**
|
||||
* @brief Owned pointer to the proxy host.
|
||||
* @private
|
||||
*/
|
||||
char *owned_proxy_host;
|
||||
};
|
||||
#endif /* TOX_HIDE_DEPRECATED */
|
||||
|
||||
bool tox_options_get_ipv6_enabled(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled);
|
||||
|
||||
bool tox_options_get_udp_enabled(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled);
|
||||
|
||||
bool tox_options_get_local_discovery_enabled(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled);
|
||||
|
||||
bool tox_options_get_dht_announcements_enabled(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_dht_announcements_enabled(
|
||||
Tox_Options *options, bool dht_announcements_enabled);
|
||||
|
||||
Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type);
|
||||
|
||||
const char *tox_options_get_proxy_host(const Tox_Options *options);
|
||||
|
||||
bool tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host);
|
||||
|
||||
uint16_t tox_options_get_proxy_port(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port);
|
||||
|
||||
uint16_t tox_options_get_start_port(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_start_port(Tox_Options *options, uint16_t start_port);
|
||||
|
||||
uint16_t tox_options_get_end_port(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_end_port(Tox_Options *options, uint16_t end_port);
|
||||
|
||||
uint16_t tox_options_get_tcp_port(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port);
|
||||
|
||||
bool tox_options_get_hole_punching_enabled(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled);
|
||||
|
||||
Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type);
|
||||
|
||||
const uint8_t *tox_options_get_savedata_data(const Tox_Options *options);
|
||||
|
||||
bool tox_options_set_savedata_data(
|
||||
Tox_Options *options, const uint8_t savedata_data[], size_t length);
|
||||
|
||||
size_t tox_options_get_savedata_length(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length);
|
||||
|
||||
tox_log_cb *tox_options_get_log_callback(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback);
|
||||
|
||||
void *tox_options_get_log_user_data(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data);
|
||||
|
||||
bool tox_options_get_experimental_owned_data(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_experimental_owned_data(Tox_Options *options, bool experimental_owned_data);
|
||||
|
||||
bool tox_options_get_experimental_thread_safety(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_experimental_thread_safety(
|
||||
Tox_Options *options, bool experimental_thread_safety);
|
||||
|
||||
bool tox_options_get_experimental_groups_persistence(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_experimental_groups_persistence(
|
||||
Tox_Options *options, bool experimental_groups_persistence);
|
||||
|
||||
bool tox_options_get_experimental_disable_dns(const Tox_Options *options);
|
||||
|
||||
void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns);
|
||||
|
||||
/**
|
||||
* @brief Initialises a Tox_Options object with the default options.
|
||||
*
|
||||
* The result of this function is independent of the original options. All
|
||||
* values will be overwritten, no values will be read (so it is permissible
|
||||
* to pass an uninitialised object).
|
||||
*
|
||||
* If options is NULL, this function has no effect.
|
||||
*
|
||||
* @param options An options object to be filled with default options.
|
||||
*/
|
||||
void tox_options_default(Tox_Options *options);
|
||||
|
||||
typedef enum Tox_Err_Options_New {
|
||||
/**
|
||||
* The function returned successfully.
|
||||
*/
|
||||
TOX_ERR_OPTIONS_NEW_OK,
|
||||
|
||||
/**
|
||||
* The function failed to allocate enough memory for the options struct.
|
||||
*/
|
||||
TOX_ERR_OPTIONS_NEW_MALLOC,
|
||||
} Tox_Err_Options_New;
|
||||
|
||||
const char *tox_err_options_new_to_string(Tox_Err_Options_New value);
|
||||
|
||||
/**
|
||||
* @brief Allocates a new Tox_Options object and initialises it with the default
|
||||
* options.
|
||||
*
|
||||
* This function can be used to preserve long term ABI compatibility by
|
||||
* giving the responsibility of allocation and deallocation to the Tox library.
|
||||
*
|
||||
* Objects returned from this function must be freed using the tox_options_free
|
||||
* function.
|
||||
*
|
||||
* @return A new Tox_Options object with default options or NULL on failure.
|
||||
*/
|
||||
Tox_Options *tox_options_new(Tox_Err_Options_New *error);
|
||||
|
||||
/**
|
||||
* @brief Releases all resources associated with an options objects.
|
||||
*
|
||||
* Passing a pointer that was not returned by tox_options_new results in
|
||||
* undefined behaviour.
|
||||
*/
|
||||
void tox_options_free(Tox_Options *options);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* C_TOXCORE_TOXCORE_TOX_OPTIONS_H */
|
@ -11,8 +11,8 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "DHT.h"
|
||||
#include "Messenger.h"
|
||||
#include "TCP_server.h"
|
||||
#include "attributes.h"
|
||||
#include "ccompat.h"
|
||||
#include "crypto_core.h"
|
||||
#include "group_chats.h"
|
||||
@ -23,7 +23,7 @@
|
||||
#include "net_profile.h"
|
||||
#include "network.h"
|
||||
#include "tox.h"
|
||||
#include "tox_struct.h"
|
||||
#include "tox_struct.h" // IWYU pragma: keep
|
||||
|
||||
#define SET_ERROR_PARAMETER(param, x) \
|
||||
do { \
|
||||
@ -94,33 +94,33 @@ void *tox_get_av_object(const Tox *tox)
|
||||
return object;
|
||||
}
|
||||
|
||||
void tox_callback_dht_get_nodes_response(Tox *tox, tox_dht_get_nodes_response_cb *callback)
|
||||
void tox_callback_dht_nodes_response(Tox *tox, tox_dht_nodes_response_cb *callback)
|
||||
{
|
||||
assert(tox != nullptr);
|
||||
tox->dht_get_nodes_response_callback = callback;
|
||||
tox->dht_nodes_response_callback = callback;
|
||||
}
|
||||
|
||||
bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
|
||||
const uint8_t *target_public_key, Tox_Err_Dht_Get_Nodes *error)
|
||||
bool tox_dht_send_nodes_request(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
|
||||
const uint8_t *target_public_key, Tox_Err_Dht_Send_Nodes_Request *error)
|
||||
{
|
||||
assert(tox != nullptr);
|
||||
|
||||
tox_lock(tox);
|
||||
|
||||
if (tox->m->options.udp_disabled) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_UDP_DISABLED);
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_UDP_DISABLED);
|
||||
tox_unlock(tox);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (public_key == nullptr || ip == nullptr || target_public_key == nullptr) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_NULL);
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_NULL);
|
||||
tox_unlock(tox);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (port == 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_PORT);
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_PORT);
|
||||
tox_unlock(tox);
|
||||
return false;
|
||||
}
|
||||
@ -130,7 +130,7 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip
|
||||
const int32_t count = net_getipport(tox->sys.ns, tox->sys.mem, ip, &root, TOX_SOCK_DGRAM, tox->m->options.dns_enabled);
|
||||
|
||||
if (count < 1) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_IP);
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_IP);
|
||||
net_freeipport(tox->sys.mem, root);
|
||||
tox_unlock(tox);
|
||||
return false;
|
||||
@ -141,7 +141,7 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip
|
||||
for (int32_t i = 0; i < count; ++i) {
|
||||
root[i].port = net_htons(port);
|
||||
|
||||
if (dht_getnodes(tox->m->dht, &root[i], public_key, target_public_key)) {
|
||||
if (dht_send_nodes_request(tox->m->dht, &root[i], public_key, target_public_key)) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
@ -151,11 +151,11 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip
|
||||
net_freeipport(tox->sys.mem, root);
|
||||
|
||||
if (!success) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_FAIL);
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_FAIL);
|
||||
return false;
|
||||
}
|
||||
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_OK);
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_OK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "tox.h"
|
||||
#include "tox_options.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -92,52 +93,53 @@ uint32_t tox_dht_node_public_key_size(void);
|
||||
* @param ip The node's IP address, represented as a NUL-terminated C string.
|
||||
* @param port The node's port.
|
||||
*/
|
||||
typedef void tox_dht_get_nodes_response_cb(Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
|
||||
void *user_data);
|
||||
typedef void tox_dht_nodes_response_cb(
|
||||
Tox *tox, const uint8_t *public_key, const char *ip, uint32_t ip_length,
|
||||
uint16_t port, void *user_data);
|
||||
|
||||
/**
|
||||
* Set the callback for the `dht_get_nodes_response` event. Pass NULL to unset.
|
||||
* Set the callback for the `dht_nodes_response` event. Pass NULL to unset.
|
||||
*
|
||||
* This event is triggered when a getnodes response is received from a DHT peer.
|
||||
* This event is triggered when a nodes response is received from a DHT peer.
|
||||
*/
|
||||
void tox_callback_dht_get_nodes_response(Tox *tox, tox_dht_get_nodes_response_cb *callback);
|
||||
void tox_callback_dht_nodes_response(Tox *tox, tox_dht_nodes_response_cb *callback);
|
||||
|
||||
typedef enum Tox_Err_Dht_Get_Nodes {
|
||||
typedef enum Tox_Err_Dht_Send_Nodes_Request {
|
||||
/**
|
||||
* The function returned successfully.
|
||||
*/
|
||||
TOX_ERR_DHT_GET_NODES_OK,
|
||||
TOX_ERR_DHT_SEND_NODES_REQUEST_OK,
|
||||
|
||||
/**
|
||||
* UDP is disabled in Tox options; the DHT can only be queried when UDP is
|
||||
* enabled.
|
||||
*/
|
||||
TOX_ERR_DHT_GET_NODES_UDP_DISABLED,
|
||||
TOX_ERR_DHT_SEND_NODES_REQUEST_UDP_DISABLED,
|
||||
|
||||
/**
|
||||
* One of the arguments to the function was NULL when it was not expected.
|
||||
*/
|
||||
TOX_ERR_DHT_GET_NODES_NULL,
|
||||
TOX_ERR_DHT_SEND_NODES_REQUEST_NULL,
|
||||
|
||||
/**
|
||||
* The supplied port is invalid.
|
||||
*/
|
||||
TOX_ERR_DHT_GET_NODES_BAD_PORT,
|
||||
TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_PORT,
|
||||
|
||||
/**
|
||||
* The supplied IP address is invalid.
|
||||
*/
|
||||
TOX_ERR_DHT_GET_NODES_BAD_IP,
|
||||
TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_IP,
|
||||
|
||||
/**
|
||||
* The getnodes request failed. This usually means the packet failed to
|
||||
* The nodes request failed. This usually means the packet failed to
|
||||
* send.
|
||||
*/
|
||||
TOX_ERR_DHT_GET_NODES_FAIL,
|
||||
} Tox_Err_Dht_Get_Nodes;
|
||||
TOX_ERR_DHT_SEND_NODES_REQUEST_FAIL,
|
||||
} Tox_Err_Dht_Send_Nodes_Request;
|
||||
|
||||
/**
|
||||
* This function sends a getnodes request to a DHT node for its peers that
|
||||
* This function sends a nodes request to a DHT node for its peers that
|
||||
* are "close" to the passed target public key according to the distance metric
|
||||
* used by the DHT implementation.
|
||||
*
|
||||
@ -151,8 +153,8 @@ typedef enum Tox_Err_Dht_Get_Nodes {
|
||||
*
|
||||
* @return true on success.
|
||||
*/
|
||||
bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
|
||||
const uint8_t *target_public_key, Tox_Err_Dht_Get_Nodes *error);
|
||||
bool tox_dht_send_nodes_request(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
|
||||
const uint8_t *target_public_key, Tox_Err_Dht_Send_Nodes_Request *error);
|
||||
|
||||
/**
|
||||
* This function returns the number of DHT nodes in the closelist.
|
||||
@ -201,7 +203,7 @@ typedef enum Tox_Netprof_Packet_Id {
|
||||
TOX_NETPROF_PACKET_ID_ONE = 0x01,
|
||||
|
||||
/**
|
||||
* Get nodes request packet (UDP).
|
||||
* Nodes request packet (UDP).
|
||||
* Connection notification (TCP).
|
||||
*/
|
||||
TOX_NETPROF_PACKET_ID_TWO = 0x02,
|
||||
@ -212,7 +214,7 @@ typedef enum Tox_Netprof_Packet_Id {
|
||||
TOX_NETPROF_PACKET_ID_TCP_DISCONNECT = 0x03,
|
||||
|
||||
/**
|
||||
* Send nodes response packet (UDP).
|
||||
* Nodes response packet (UDP).
|
||||
* Ping packet (TCP).
|
||||
*/
|
||||
TOX_NETPROF_PACKET_ID_FOUR = 0x04,
|
||||
|
@ -8,10 +8,9 @@
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "Messenger.h"
|
||||
#include "mem.h"
|
||||
#include "mono_time.h"
|
||||
#include "tox.h"
|
||||
#include "tox_options.h" // tox_log_cb
|
||||
#include "tox_private.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -19,7 +18,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct Tox {
|
||||
Messenger *m;
|
||||
struct Messenger *m;
|
||||
Mono_Time *mono_time;
|
||||
Tox_System sys;
|
||||
pthread_mutex_t *mutex;
|
||||
@ -44,7 +43,7 @@ struct Tox {
|
||||
tox_conference_title_cb *conference_title_callback;
|
||||
tox_conference_peer_name_cb *conference_peer_name_callback;
|
||||
tox_conference_peer_list_changed_cb *conference_peer_list_changed_callback;
|
||||
tox_dht_get_nodes_response_cb *dht_get_nodes_response_callback;
|
||||
tox_dht_nodes_response_cb *dht_nodes_response_callback;
|
||||
tox_friend_lossy_packet_cb *friend_lossy_packet_callback_per_pktid[UINT8_MAX + 1];
|
||||
tox_friend_lossless_packet_cb *friend_lossless_packet_callback_per_pktid[UINT8_MAX + 1];
|
||||
tox_group_peer_name_cb *group_peer_name_callback;
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "crypto_core.h"
|
||||
#include "tox_log_level.h"
|
||||
#include "tox_options.h"
|
||||
#include "tox_private.h"
|
||||
|
||||
namespace {
|
||||
|
Reference in New Issue
Block a user