update toxcore, includes ngc mem savings
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
Merge commit '261d2e53b7a513de7eb35e022fe3b2ae4efa835f'
This commit is contained in:
74
external/toxcore/c-toxcore/toxcore/BUILD.bazel
vendored
74
external/toxcore/c-toxcore/toxcore/BUILD.bazel
vendored
@@ -1,4 +1,4 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
|
||||
load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
|
||||
|
||||
exports_files(
|
||||
@@ -100,14 +100,58 @@ cc_test(
|
||||
size = "small",
|
||||
srcs = ["util_test.cc"],
|
||||
deps = [
|
||||
":crypto_core",
|
||||
":crypto_core_test_util",
|
||||
":util",
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "sort",
|
||||
srcs = ["sort.c"],
|
||||
hdrs = ["sort.h"],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
":util",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "sort_test_util",
|
||||
testonly = True,
|
||||
srcs = ["sort_test_util.cc"],
|
||||
hdrs = ["sort_test_util.hh"],
|
||||
deps = [
|
||||
":sort",
|
||||
":util",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "sort_test",
|
||||
size = "small",
|
||||
srcs = ["sort_test.cc"],
|
||||
deps = [
|
||||
":sort",
|
||||
":sort_test_util",
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "sort_bench",
|
||||
testonly = True,
|
||||
srcs = ["sort_bench.cc"],
|
||||
deps = [
|
||||
":mem",
|
||||
":sort",
|
||||
":sort_test_util",
|
||||
"@benchmark",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "logger",
|
||||
srcs = ["logger.c"],
|
||||
@@ -121,6 +165,7 @@ cc_library(
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
":mem",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -170,6 +215,7 @@ cc_library(
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
":mem",
|
||||
":util",
|
||||
"@libsodium",
|
||||
],
|
||||
@@ -208,6 +254,7 @@ cc_test(
|
||||
deps = [
|
||||
":crypto_core",
|
||||
":crypto_core_test_util",
|
||||
":mem_test_util",
|
||||
":util",
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
@@ -332,6 +379,7 @@ cc_library(
|
||||
hdrs = ["network_test_util.hh"],
|
||||
deps = [
|
||||
":crypto_core",
|
||||
":mem",
|
||||
":network",
|
||||
":test_util",
|
||||
],
|
||||
@@ -435,6 +483,7 @@ cc_library(
|
||||
":network",
|
||||
":ping_array",
|
||||
":shared_key_cache",
|
||||
":sort",
|
||||
":state",
|
||||
":util",
|
||||
],
|
||||
@@ -478,10 +527,12 @@ cc_test(
|
||||
cc_fuzz_test(
|
||||
name = "DHT_fuzz_test",
|
||||
size = "small",
|
||||
testonly = True,
|
||||
srcs = ["DHT_fuzz_test.cc"],
|
||||
corpus = ["//tools/toktok-fuzzer/corpus:DHT_fuzz_test"],
|
||||
deps = [
|
||||
":DHT",
|
||||
":mem_test_util",
|
||||
"//c-toxcore/testing/fuzzing:fuzz_support",
|
||||
],
|
||||
)
|
||||
@@ -490,7 +541,11 @@ cc_library(
|
||||
name = "onion",
|
||||
srcs = ["onion.c"],
|
||||
hdrs = ["onion.h"],
|
||||
visibility = ["//c-toxcore/auto_tests:__pkg__"],
|
||||
visibility = [
|
||||
"//c-toxcore/auto_tests:__pkg__",
|
||||
"//c-toxcore/other:__pkg__",
|
||||
"//c-toxcore/other/bootstrap_daemon:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
":DHT",
|
||||
":attributes",
|
||||
@@ -509,7 +564,11 @@ cc_library(
|
||||
name = "forwarding",
|
||||
srcs = ["forwarding.c"],
|
||||
hdrs = ["forwarding.h"],
|
||||
visibility = ["//c-toxcore/auto_tests:__pkg__"],
|
||||
visibility = [
|
||||
"//c-toxcore/auto_tests:__pkg__",
|
||||
"//c-toxcore/other:__pkg__",
|
||||
"//c-toxcore/other/bootstrap_daemon:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
":DHT",
|
||||
":attributes",
|
||||
@@ -704,6 +763,7 @@ cc_library(
|
||||
":network",
|
||||
":onion",
|
||||
":shared_key_cache",
|
||||
":sort",
|
||||
":timed_auth",
|
||||
":util",
|
||||
],
|
||||
@@ -777,6 +837,7 @@ cc_library(
|
||||
":crypto_core",
|
||||
":group_announce",
|
||||
":logger",
|
||||
":mem",
|
||||
":mono_time",
|
||||
":network",
|
||||
":onion_announce",
|
||||
@@ -806,6 +867,7 @@ cc_library(
|
||||
":onion",
|
||||
":onion_announce",
|
||||
":ping_array",
|
||||
":sort",
|
||||
":timed_auth",
|
||||
":util",
|
||||
],
|
||||
@@ -971,9 +1033,11 @@ cc_library(
|
||||
":crypto_core",
|
||||
":friend_connection",
|
||||
":logger",
|
||||
":mem",
|
||||
":mono_time",
|
||||
":net_crypto",
|
||||
":network",
|
||||
":sort",
|
||||
":state",
|
||||
":util",
|
||||
],
|
||||
|
192
external/toxcore/c-toxcore/toxcore/DHT.c
vendored
192
external/toxcore/c-toxcore/toxcore/DHT.c
vendored
@@ -9,7 +9,6 @@
|
||||
#include "DHT.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "LAN_discovery.h"
|
||||
@@ -24,7 +23,9 @@
|
||||
#include "ping.h"
|
||||
#include "ping_array.h"
|
||||
#include "shared_key_cache.h"
|
||||
#include "sort.h"
|
||||
#include "state.h"
|
||||
#include "util.h"
|
||||
|
||||
/** The timeout after which a node is discarded completely. */
|
||||
#define KILL_NODE_TIMEOUT (BAD_NODE_TIMEOUT + PING_INTERVAL)
|
||||
@@ -279,7 +280,7 @@ const uint8_t *dht_get_shared_key_sent(DHT *dht, const uint8_t *public_key)
|
||||
|
||||
#define CRYPTO_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE)
|
||||
|
||||
int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
|
||||
int create_request(const Memory *mem, const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
|
||||
uint8_t *packet, const uint8_t *recv_public_key,
|
||||
const uint8_t *data, uint32_t data_length, uint8_t request_id)
|
||||
{
|
||||
@@ -296,7 +297,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
|
||||
uint8_t temp[MAX_CRYPTO_REQUEST_SIZE] = {0};
|
||||
temp[0] = request_id;
|
||||
memcpy(temp + 1, data, data_length);
|
||||
const int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, data_length + 1,
|
||||
const int len = encrypt_data(mem, recv_public_key, send_secret_key, nonce, temp, data_length + 1,
|
||||
packet + CRYPTO_SIZE);
|
||||
|
||||
if (len == -1) {
|
||||
@@ -312,7 +313,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
|
||||
return len + CRYPTO_SIZE;
|
||||
}
|
||||
|
||||
int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
|
||||
int handle_request(const Memory *mem, const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
|
||||
uint8_t *request_id, const uint8_t *packet, uint16_t packet_length)
|
||||
{
|
||||
if (self_public_key == nullptr || public_key == nullptr || data == nullptr || request_id == nullptr
|
||||
@@ -331,7 +332,7 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke
|
||||
memcpy(public_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
const uint8_t *const nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2;
|
||||
uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
|
||||
int32_t len1 = decrypt_data(public_key, self_secret_key, nonce,
|
||||
int32_t len1 = decrypt_data(mem, public_key, self_secret_key, nonce,
|
||||
packet + CRYPTO_SIZE, packet_length - CRYPTO_SIZE, temp);
|
||||
|
||||
if (len1 == -1 || len1 == 0) {
|
||||
@@ -378,7 +379,7 @@ int dht_create_packet(const Memory *mem, const Random *rng,
|
||||
|
||||
random_nonce(rng, nonce);
|
||||
|
||||
const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted);
|
||||
const int encrypted_length = encrypt_data_symmetric(mem, shared_key, nonce, plain, plain_length, encrypted);
|
||||
|
||||
if (encrypted_length < 0) {
|
||||
mem_delete(mem, encrypted);
|
||||
@@ -755,49 +756,6 @@ int get_close_nodes(
|
||||
is_lan, want_announce);
|
||||
}
|
||||
|
||||
typedef struct DHT_Cmp_Data {
|
||||
uint64_t cur_time;
|
||||
const uint8_t *base_public_key;
|
||||
Client_data entry;
|
||||
} DHT_Cmp_Data;
|
||||
|
||||
non_null()
|
||||
static int dht_cmp_entry(const void *a, const void *b)
|
||||
{
|
||||
const DHT_Cmp_Data *cmp1 = (const DHT_Cmp_Data *)a;
|
||||
const DHT_Cmp_Data *cmp2 = (const DHT_Cmp_Data *)b;
|
||||
const Client_data entry1 = cmp1->entry;
|
||||
const Client_data entry2 = cmp2->entry;
|
||||
const uint8_t *cmp_public_key = cmp1->base_public_key;
|
||||
|
||||
const bool t1 = assoc_timeout(cmp1->cur_time, &entry1.assoc4) && assoc_timeout(cmp1->cur_time, &entry1.assoc6);
|
||||
const bool t2 = assoc_timeout(cmp2->cur_time, &entry2.assoc4) && assoc_timeout(cmp2->cur_time, &entry2.assoc6);
|
||||
|
||||
if (t1 && t2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (t1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (t2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
|
||||
|
||||
if (closest == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (closest == 2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CHECK_ANNOUNCE_NODE
|
||||
non_null()
|
||||
static void set_announce_node_in_list(Client_data *list, uint32_t list_len, const uint8_t *public_key)
|
||||
@@ -870,7 +828,7 @@ static int handle_data_search_response(void *object, const IP_Port *source,
|
||||
const uint8_t *public_key = packet + 1;
|
||||
const uint8_t *shared_key = dht_get_shared_key_recv(dht, public_key);
|
||||
|
||||
if (decrypt_data_symmetric(shared_key,
|
||||
if (decrypt_data_symmetric(dht->mem, shared_key,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
|
||||
plain_len + CRYPTO_MAC_SIZE,
|
||||
@@ -914,31 +872,117 @@ static bool store_node_ok(const Client_data *client, uint64_t cur_time, const ui
|
||||
|| id_closest(comp_public_key, client->public_key, public_key) == 2;
|
||||
}
|
||||
|
||||
typedef struct Client_data_Cmp {
|
||||
const Memory *mem;
|
||||
uint64_t cur_time;
|
||||
const uint8_t *comp_public_key;
|
||||
} Client_data_Cmp;
|
||||
|
||||
non_null()
|
||||
static int client_data_cmp(const Client_data_Cmp *cmp, const Client_data *entry1, const Client_data *entry2)
|
||||
{
|
||||
const bool t1 = assoc_timeout(cmp->cur_time, &entry1->assoc4) && assoc_timeout(cmp->cur_time, &entry1->assoc6);
|
||||
const bool t2 = assoc_timeout(cmp->cur_time, &entry2->assoc4) && assoc_timeout(cmp->cur_time, &entry2->assoc6);
|
||||
|
||||
if (t1 && t2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (t1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (t2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key);
|
||||
|
||||
if (closest == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (closest == 2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool client_data_less_handler(const void *object, const void *a, const void *b)
|
||||
{
|
||||
const Client_data_Cmp *cmp = (const Client_data_Cmp *)object;
|
||||
const Client_data *entry1 = (const Client_data *)a;
|
||||
const Client_data *entry2 = (const Client_data *)b;
|
||||
|
||||
return client_data_cmp(cmp, entry1, entry2) < 0;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static const void *client_data_get_handler(const void *arr, uint32_t index)
|
||||
{
|
||||
const Client_data *entries = (const Client_data *)arr;
|
||||
return &entries[index];
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void client_data_set_handler(void *arr, uint32_t index, const void *val)
|
||||
{
|
||||
Client_data *entries = (Client_data *)arr;
|
||||
const Client_data *entry = (const Client_data *)val;
|
||||
entries[index] = *entry;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void *client_data_subarr_handler(void *arr, uint32_t index, uint32_t size)
|
||||
{
|
||||
Client_data *entries = (Client_data *)arr;
|
||||
return &entries[index];
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void *client_data_alloc_handler(const void *object, uint32_t size)
|
||||
{
|
||||
const Client_data_Cmp *cmp = (const Client_data_Cmp *)object;
|
||||
Client_data *tmp = (Client_data *)mem_valloc(cmp->mem, size, sizeof(Client_data));
|
||||
|
||||
if (tmp == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void client_data_delete_handler(const void *object, void *arr, uint32_t size)
|
||||
{
|
||||
const Client_data_Cmp *cmp = (const Client_data_Cmp *)object;
|
||||
mem_delete(cmp->mem, arr);
|
||||
}
|
||||
|
||||
static const Sort_Funcs client_data_cmp_funcs = {
|
||||
client_data_less_handler,
|
||||
client_data_get_handler,
|
||||
client_data_set_handler,
|
||||
client_data_subarr_handler,
|
||||
client_data_alloc_handler,
|
||||
client_data_delete_handler,
|
||||
};
|
||||
|
||||
non_null()
|
||||
static void sort_client_list(const Memory *mem, Client_data *list, uint64_t cur_time, unsigned int length,
|
||||
const uint8_t *comp_public_key)
|
||||
{
|
||||
// Pass comp_public_key to qsort with each Client_data entry, so the
|
||||
// Pass comp_public_key to merge_sort with each Client_data entry, so the
|
||||
// comparison function can use it as the base of comparison.
|
||||
DHT_Cmp_Data *cmp_list = (DHT_Cmp_Data *)mem_valloc(mem, length, sizeof(DHT_Cmp_Data));
|
||||
const Client_data_Cmp cmp = {
|
||||
mem,
|
||||
cur_time,
|
||||
comp_public_key,
|
||||
};
|
||||
|
||||
if (cmp_list == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
cmp_list[i].cur_time = cur_time;
|
||||
cmp_list[i].base_public_key = comp_public_key;
|
||||
cmp_list[i].entry = list[i];
|
||||
}
|
||||
|
||||
qsort(cmp_list, length, sizeof(DHT_Cmp_Data), dht_cmp_entry);
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
list[i] = cmp_list[i].entry;
|
||||
}
|
||||
|
||||
mem_delete(mem, cmp_list);
|
||||
merge_sort(list, length, &cmp, &client_data_cmp_funcs);
|
||||
}
|
||||
|
||||
non_null()
|
||||
@@ -1381,6 +1425,7 @@ static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *p
|
||||
uint8_t plain[CRYPTO_NODE_SIZE];
|
||||
const uint8_t *shared_key = dht_get_shared_key_recv(dht, packet + 1);
|
||||
const int len = decrypt_data_symmetric(
|
||||
dht->mem,
|
||||
shared_key,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
|
||||
@@ -1442,6 +1487,7 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin
|
||||
VLA(uint8_t, plain, plain_size);
|
||||
const uint8_t *shared_key = dht_get_shared_key_sent(dht, packet + 1);
|
||||
const int len = decrypt_data_symmetric(
|
||||
dht->mem,
|
||||
shared_key,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
|
||||
@@ -1840,7 +1886,7 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key)
|
||||
return dht_getnodes(dht, ip_port, public_key, dht->self_public_key);
|
||||
}
|
||||
|
||||
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
|
||||
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
|
||||
uint16_t port, const uint8_t *public_key)
|
||||
{
|
||||
IP_Port ip_port_v64;
|
||||
@@ -1855,7 +1901,7 @@ bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
|
||||
ip_extra = &ip_port_v4.ip;
|
||||
}
|
||||
|
||||
if (addr_resolve_or_parse_ip(dht->ns, address, &ip_port_v64.ip, ip_extra)) {
|
||||
if (addr_resolve_or_parse_ip(dht->ns, dht->mem, address, &ip_port_v64.ip, ip_extra, dns_enabled)) {
|
||||
ip_port_v64.port = port;
|
||||
dht_bootstrap(dht, &ip_port_v64, public_key);
|
||||
|
||||
@@ -2123,7 +2169,7 @@ static int send_nat_ping(const DHT *dht, const uint8_t *public_key, uint64_t pin
|
||||
memcpy(data + 1, &ping_id, sizeof(uint64_t));
|
||||
/* 254 is NAT ping request packet id */
|
||||
const int len = create_request(
|
||||
dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key,
|
||||
dht->mem, dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key,
|
||||
data, sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING);
|
||||
|
||||
if (len == -1) {
|
||||
@@ -2458,7 +2504,7 @@ static int cryptopacket_handle(void *object, const IP_Port *source, const uint8_
|
||||
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t data[MAX_CRYPTO_REQUEST_SIZE];
|
||||
uint8_t number;
|
||||
const int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key,
|
||||
const int len = handle_request(dht->mem, dht->self_public_key, dht->self_secret_key, public_key,
|
||||
data, &number, packet, length);
|
||||
|
||||
if (len == -1 || len == 0) {
|
||||
|
7
external/toxcore/c-toxcore/toxcore/DHT.h
vendored
7
external/toxcore/c-toxcore/toxcore/DHT.h
vendored
@@ -99,7 +99,7 @@ extern "C" {
|
||||
* @return the length of the created packet on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
|
||||
int create_request(const Memory *mem, const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
|
||||
uint8_t *packet, const uint8_t *recv_public_key,
|
||||
const uint8_t *data, uint32_t data_length, uint8_t request_id);
|
||||
|
||||
@@ -127,7 +127,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
|
||||
*/
|
||||
non_null()
|
||||
int handle_request(
|
||||
const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
|
||||
const Memory *mem, const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
|
||||
uint8_t *request_id, const uint8_t *packet, uint16_t packet_length);
|
||||
|
||||
typedef struct IPPTs {
|
||||
@@ -404,12 +404,13 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key);
|
||||
* @param address can be a hostname or an IP address (IPv4 or IPv6).
|
||||
* @param ipv6enabled if false, the resolving sticks STRICTLY to IPv4 addresses.
|
||||
* Otherwise, the resolving looks for IPv6 addresses first, then IPv4 addresses.
|
||||
* @param dns_enabled if false, the resolving does not use DNS, only IP addresses are supported.
|
||||
*
|
||||
* @retval true if the address could be converted into an IP address
|
||||
* @retval false otherwise
|
||||
*/
|
||||
non_null()
|
||||
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
|
||||
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
|
||||
uint16_t port, const uint8_t *public_key);
|
||||
|
||||
/** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.
|
||||
|
@@ -6,19 +6,22 @@
|
||||
#include <vector>
|
||||
|
||||
#include "../testing/fuzzing/fuzz_support.hh"
|
||||
#include "mem_test_util.hh"
|
||||
|
||||
namespace {
|
||||
|
||||
void TestHandleRequest(Fuzz_Data &input)
|
||||
{
|
||||
const Test_Memory mem;
|
||||
|
||||
CONSUME_OR_RETURN(const uint8_t *self_public_key, input, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
CONSUME_OR_RETURN(const uint8_t *self_secret_key, input, CRYPTO_SECRET_KEY_SIZE);
|
||||
|
||||
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t request[MAX_CRYPTO_REQUEST_SIZE];
|
||||
uint8_t request_id;
|
||||
handle_request(self_public_key, self_secret_key, public_key, request, &request_id, input.data(),
|
||||
input.size());
|
||||
handle_request(mem, self_public_key, self_secret_key, public_key, request, &request_id,
|
||||
input.data(), input.size());
|
||||
}
|
||||
|
||||
void TestUnpackNodes(Fuzz_Data &input)
|
||||
@@ -31,7 +34,8 @@ void TestUnpackNodes(Fuzz_Data &input)
|
||||
const int packed_count = unpack_nodes(
|
||||
nodes, node_count, &processed_data_len, input.data(), input.size(), tcp_enabled);
|
||||
if (packed_count > 0) {
|
||||
Logger *logger = logger_new();
|
||||
const Memory *mem = os_memory();
|
||||
Logger *logger = logger_new(mem);
|
||||
std::vector<uint8_t> packed(packed_count * PACKED_NODE_SIZE_IP6);
|
||||
const int packed_size
|
||||
= pack_nodes(logger, packed.data(), packed.size(), nodes, packed_count);
|
||||
|
17
external/toxcore/c-toxcore/toxcore/DHT_test.cc
vendored
17
external/toxcore/c-toxcore/toxcore/DHT_test.cc
vendored
@@ -274,6 +274,7 @@ TEST(AddToList, KeepsKeysInOrder)
|
||||
|
||||
TEST(Request, CreateAndParse)
|
||||
{
|
||||
Test_Memory mem;
|
||||
Test_Random rng;
|
||||
|
||||
// Peers.
|
||||
@@ -293,32 +294,32 @@ TEST(Request, CreateAndParse)
|
||||
std::vector<uint8_t> outgoing(919);
|
||||
random_bytes(rng, outgoing.data(), outgoing.size());
|
||||
|
||||
EXPECT_LT(create_request(rng, sender.pk.data(), sender.sk.data(), packet.data(),
|
||||
EXPECT_LT(create_request(mem, rng, sender.pk.data(), sender.sk.data(), packet.data(),
|
||||
receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id),
|
||||
0);
|
||||
|
||||
// Pop one element so the payload is 918 bytes. Packing should now succeed.
|
||||
outgoing.pop_back();
|
||||
|
||||
const int max_sent_length = create_request(rng, sender.pk.data(), sender.sk.data(),
|
||||
const int max_sent_length = create_request(mem, rng, sender.pk.data(), sender.sk.data(),
|
||||
packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id);
|
||||
ASSERT_GT(max_sent_length, 0); // success.
|
||||
|
||||
// Check that handle_request rejects packets larger than the maximum created packet size.
|
||||
EXPECT_LT(handle_request(receiver.pk.data(), receiver.sk.data(), pk.data(), incoming.data(),
|
||||
&recvd_pkt_id, packet.data(), max_sent_length + 1),
|
||||
EXPECT_LT(handle_request(mem, receiver.pk.data(), receiver.sk.data(), pk.data(),
|
||||
incoming.data(), &recvd_pkt_id, packet.data(), max_sent_length + 1),
|
||||
0);
|
||||
|
||||
// Now try all possible packet sizes from max (918) to 0.
|
||||
while (!outgoing.empty()) {
|
||||
// Pack:
|
||||
const int sent_length = create_request(rng, sender.pk.data(), sender.sk.data(),
|
||||
const int sent_length = create_request(mem, rng, sender.pk.data(), sender.sk.data(),
|
||||
packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id);
|
||||
ASSERT_GT(sent_length, 0);
|
||||
|
||||
// Unpack:
|
||||
const int recvd_length = handle_request(receiver.pk.data(), receiver.sk.data(), pk.data(),
|
||||
incoming.data(), &recvd_pkt_id, packet.data(), sent_length);
|
||||
const int recvd_length = handle_request(mem, receiver.pk.data(), receiver.sk.data(),
|
||||
pk.data(), incoming.data(), &recvd_pkt_id, packet.data(), sent_length);
|
||||
ASSERT_GE(recvd_length, 0);
|
||||
|
||||
EXPECT_EQ(
|
||||
@@ -334,7 +335,7 @@ TEST(AnnounceNodes, SetAndTest)
|
||||
Test_Memory mem;
|
||||
Test_Network ns;
|
||||
|
||||
Logger *log = logger_new();
|
||||
Logger *log = logger_new(mem);
|
||||
ASSERT_NE(log, nullptr);
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
|
@@ -86,6 +86,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
|
||||
../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 \
|
||||
|
@@ -3482,7 +3482,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m->log = logger_new();
|
||||
m->log = logger_new(mem);
|
||||
|
||||
if (m->log == nullptr) {
|
||||
friendreq_kill(m->fr);
|
||||
|
@@ -86,6 +86,8 @@ typedef struct Messenger_Options {
|
||||
|
||||
Messenger_State_Plugin *state_plugins;
|
||||
uint8_t state_plugins_length;
|
||||
|
||||
bool dns_enabled;
|
||||
} Messenger_Options;
|
||||
|
||||
struct Receipts {
|
||||
|
12
external/toxcore/c-toxcore/toxcore/TCP_client.c
vendored
12
external/toxcore/c-toxcore/toxcore/TCP_client.c
vendored
@@ -107,12 +107,12 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value)
|
||||
* @retval false on failure
|
||||
*/
|
||||
non_null()
|
||||
static bool connect_sock_to(const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info)
|
||||
static bool connect_sock_to(const Network *ns, const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info)
|
||||
{
|
||||
if (proxy_info->proxy_type != TCP_PROXY_NONE) {
|
||||
return net_connect(mem, logger, sock, &proxy_info->ip_port);
|
||||
return net_connect(ns, mem, logger, sock, &proxy_info->ip_port);
|
||||
} else {
|
||||
return net_connect(mem, logger, sock, ip_port);
|
||||
return net_connect(ns, mem, logger, sock, ip_port);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ static int generate_handshake(TCP_Client_Connection *tcp_conn)
|
||||
memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->con.sent_nonce, CRYPTO_NONCE_SIZE);
|
||||
memcpy(tcp_conn->con.last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
random_nonce(tcp_conn->con.rng, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
const int len = encrypt_data_symmetric(tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
|
||||
const int len = encrypt_data_symmetric(tcp_conn->con.mem, tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
|
||||
sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != sizeof(plain) + CRYPTO_MAC_SIZE) {
|
||||
@@ -334,7 +334,7 @@ non_null()
|
||||
static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data)
|
||||
{
|
||||
uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE];
|
||||
const int len = decrypt_data_symmetric(tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE,
|
||||
const int len = decrypt_data_symmetric(tcp_conn->con.mem, tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE,
|
||||
TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain);
|
||||
|
||||
if (len != sizeof(plain)) {
|
||||
@@ -617,7 +617,7 @@ TCP_Client_Connection *new_tcp_connection(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!(set_socket_nonblock(ns, sock) && connect_sock_to(logger, mem, sock, ip_port, proxy_info))) {
|
||||
if (!(set_socket_nonblock(ns, sock) && connect_sock_to(ns, logger, mem, sock, ip_port, proxy_info))) {
|
||||
kill_sock(ns, sock);
|
||||
return nullptr;
|
||||
}
|
||||
|
@@ -157,7 +157,7 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con
|
||||
|
||||
uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
|
||||
memcpy(packet, &c_length, sizeof(uint16_t));
|
||||
int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
|
||||
int len = encrypt_data_symmetric(con->mem, con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
|
||||
|
||||
if ((unsigned int)len != (packet_size - sizeof(uint16_t))) {
|
||||
return -1;
|
||||
@@ -305,7 +305,7 @@ int read_packet_tcp_secure_connection(
|
||||
|
||||
*next_packet_length = 0;
|
||||
|
||||
const int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data);
|
||||
const int len = decrypt_data_symmetric(mem, shared_key, recv_nonce, data_encrypted, len_packet, data);
|
||||
|
||||
if (len + CRYPTO_MAC_SIZE != len_packet) {
|
||||
LOGGER_ERROR(logger, "decrypted length %d does not match expected length %d", len + CRYPTO_MAC_SIZE, len_packet);
|
||||
|
@@ -327,7 +327,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con
|
||||
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
|
||||
encrypt_precompute(data, self_secret_key, shared_key);
|
||||
uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE];
|
||||
int len = decrypt_data_symmetric(shared_key, data + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
int len = decrypt_data_symmetric(con->con.mem, shared_key, data + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE, plain);
|
||||
|
||||
if (len != TCP_HANDSHAKE_PLAIN_SIZE) {
|
||||
@@ -347,7 +347,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con
|
||||
uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
|
||||
random_nonce(con->con.rng, response);
|
||||
|
||||
len = encrypt_data_symmetric(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE,
|
||||
len = encrypt_data_symmetric(con->con.mem, shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE,
|
||||
response + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE) {
|
||||
|
@@ -451,7 +451,7 @@ static int create_reply_plain_store_announce_request(Announcements *announce,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (decrypt_data_symmetric(shared_key,
|
||||
if (decrypt_data_symmetric(announce->mem, shared_key,
|
||||
data + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
|
||||
plain_len + CRYPTO_MAC_SIZE,
|
||||
@@ -568,7 +568,7 @@ static int create_reply(Announcements *announce, const IP_Port *source,
|
||||
VLA(uint8_t, plain, plain_len);
|
||||
const uint8_t *shared_key = dht_get_shared_key_recv(announce->dht, data + 1);
|
||||
|
||||
if (decrypt_data_symmetric(shared_key,
|
||||
if (decrypt_data_symmetric(announce->mem, shared_key,
|
||||
data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
data + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
|
||||
plain_len + CRYPTO_MAC_SIZE,
|
||||
|
60
external/toxcore/c-toxcore/toxcore/crypto_core.c
vendored
60
external/toxcore/c-toxcore/toxcore/crypto_core.c
vendored
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "attributes.h"
|
||||
#include "ccompat.h"
|
||||
#include "mem.h"
|
||||
#include "util.h"
|
||||
|
||||
static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES,
|
||||
@@ -88,9 +89,10 @@ const uint8_t *get_chat_id(const Extended_Public_Key *key)
|
||||
}
|
||||
|
||||
#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
|
||||
static uint8_t *crypto_malloc(size_t bytes)
|
||||
non_null()
|
||||
static uint8_t *crypto_malloc(const Memory *mem, size_t bytes)
|
||||
{
|
||||
uint8_t *ptr = (uint8_t *)malloc(bytes);
|
||||
uint8_t *ptr = (uint8_t *)mem_balloc(mem, bytes);
|
||||
|
||||
if (ptr != nullptr) {
|
||||
crypto_memlock(ptr, bytes);
|
||||
@@ -99,15 +101,15 @@ static uint8_t *crypto_malloc(size_t bytes)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
nullable(1)
|
||||
static void crypto_free(uint8_t *ptr, size_t bytes)
|
||||
non_null(1) nullable(2)
|
||||
static void crypto_free(const Memory *mem, uint8_t *ptr, size_t bytes)
|
||||
{
|
||||
if (ptr != nullptr) {
|
||||
crypto_memzero(ptr, bytes);
|
||||
crypto_memunlock(ptr, bytes);
|
||||
}
|
||||
|
||||
free(ptr);
|
||||
mem_delete(mem, ptr);
|
||||
}
|
||||
#endif /* !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) */
|
||||
|
||||
@@ -240,7 +242,8 @@ int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
|
||||
}
|
||||
|
||||
int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
int32_t encrypt_data_symmetric(const Memory *mem,
|
||||
const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
const uint8_t nonce[CRYPTO_NONCE_SIZE],
|
||||
const uint8_t *plain, size_t length, uint8_t *encrypted)
|
||||
{
|
||||
@@ -258,12 +261,12 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
|
||||
const size_t size_temp_encrypted = length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES;
|
||||
|
||||
uint8_t *temp_plain = crypto_malloc(size_temp_plain);
|
||||
uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted);
|
||||
uint8_t *temp_plain = crypto_malloc(mem, size_temp_plain);
|
||||
uint8_t *temp_encrypted = crypto_malloc(mem, size_temp_encrypted);
|
||||
|
||||
if (temp_plain == nullptr || temp_encrypted == nullptr) {
|
||||
crypto_free(temp_plain, size_temp_plain);
|
||||
crypto_free(temp_encrypted, size_temp_encrypted);
|
||||
crypto_free(mem, temp_plain, size_temp_plain);
|
||||
crypto_free(mem, temp_encrypted, size_temp_encrypted);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -278,22 +281,23 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
|
||||
if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce,
|
||||
shared_key) != 0) {
|
||||
crypto_free(temp_plain, size_temp_plain);
|
||||
crypto_free(temp_encrypted, size_temp_encrypted);
|
||||
crypto_free(mem, temp_plain, size_temp_plain);
|
||||
crypto_free(mem, temp_encrypted, size_temp_encrypted);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Unpad the encrypted message.
|
||||
memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
|
||||
|
||||
crypto_free(temp_plain, size_temp_plain);
|
||||
crypto_free(temp_encrypted, size_temp_encrypted);
|
||||
crypto_free(mem, temp_plain, size_temp_plain);
|
||||
crypto_free(mem, temp_encrypted, size_temp_encrypted);
|
||||
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
|
||||
assert(length < INT32_MAX - crypto_box_MACBYTES);
|
||||
return (int32_t)(length + crypto_box_MACBYTES);
|
||||
}
|
||||
|
||||
int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
int32_t decrypt_data_symmetric(const Memory *mem,
|
||||
const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
const uint8_t nonce[CRYPTO_NONCE_SIZE],
|
||||
const uint8_t *encrypted, size_t length, uint8_t *plain)
|
||||
{
|
||||
@@ -310,12 +314,12 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
|
||||
const size_t size_temp_encrypted = length + crypto_box_BOXZEROBYTES;
|
||||
|
||||
uint8_t *temp_plain = crypto_malloc(size_temp_plain);
|
||||
uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted);
|
||||
uint8_t *temp_plain = crypto_malloc(mem, size_temp_plain);
|
||||
uint8_t *temp_encrypted = crypto_malloc(mem, size_temp_encrypted);
|
||||
|
||||
if (temp_plain == nullptr || temp_encrypted == nullptr) {
|
||||
crypto_free(temp_plain, size_temp_plain);
|
||||
crypto_free(temp_encrypted, size_temp_encrypted);
|
||||
crypto_free(mem, temp_plain, size_temp_plain);
|
||||
crypto_free(mem, temp_encrypted, size_temp_encrypted);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -330,22 +334,23 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
|
||||
if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce,
|
||||
shared_key) != 0) {
|
||||
crypto_free(temp_plain, size_temp_plain);
|
||||
crypto_free(temp_encrypted, size_temp_encrypted);
|
||||
crypto_free(mem, temp_plain, size_temp_plain);
|
||||
crypto_free(mem, temp_encrypted, size_temp_encrypted);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
|
||||
|
||||
crypto_free(temp_plain, size_temp_plain);
|
||||
crypto_free(temp_encrypted, size_temp_encrypted);
|
||||
crypto_free(mem, temp_plain, size_temp_plain);
|
||||
crypto_free(mem, temp_encrypted, size_temp_encrypted);
|
||||
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
|
||||
assert(length > crypto_box_MACBYTES);
|
||||
assert(length < INT32_MAX);
|
||||
return (int32_t)(length - crypto_box_MACBYTES);
|
||||
}
|
||||
|
||||
int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
int32_t encrypt_data(const Memory *mem,
|
||||
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
|
||||
const uint8_t nonce[CRYPTO_NONCE_SIZE],
|
||||
const uint8_t *plain, size_t length, uint8_t *encrypted)
|
||||
@@ -356,12 +361,13 @@ int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
|
||||
uint8_t k[crypto_box_BEFORENMBYTES];
|
||||
encrypt_precompute(public_key, secret_key, k);
|
||||
const int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted);
|
||||
const int ret = encrypt_data_symmetric(mem, k, nonce, plain, length, encrypted);
|
||||
crypto_memzero(k, sizeof(k));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
int32_t decrypt_data(const Memory *mem,
|
||||
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
|
||||
const uint8_t nonce[CRYPTO_NONCE_SIZE],
|
||||
const uint8_t *encrypted, size_t length, uint8_t *plain)
|
||||
@@ -372,7 +378,7 @@ int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
|
||||
uint8_t k[crypto_box_BEFORENMBYTES];
|
||||
encrypt_precompute(public_key, secret_key, k);
|
||||
const int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain);
|
||||
const int ret = decrypt_data_symmetric(mem, k, nonce, encrypted, length, plain);
|
||||
crypto_memzero(k, sizeof(k));
|
||||
return ret;
|
||||
}
|
||||
|
13
external/toxcore/c-toxcore/toxcore/crypto_core.h
vendored
13
external/toxcore/c-toxcore/toxcore/crypto_core.h
vendored
@@ -16,6 +16,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -386,7 +387,8 @@ void crypto_derive_public_key(uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
* @return length of encrypted data if everything was fine.
|
||||
*/
|
||||
non_null()
|
||||
int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
int32_t encrypt_data(const Memory *mem,
|
||||
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
|
||||
const uint8_t nonce[CRYPTO_NONCE_SIZE],
|
||||
const uint8_t *plain, size_t length, uint8_t *encrypted);
|
||||
@@ -403,7 +405,8 @@ int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
* @return length of plain text data if everything was fine.
|
||||
*/
|
||||
non_null()
|
||||
int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
int32_t decrypt_data(const Memory *mem,
|
||||
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
|
||||
const uint8_t nonce[CRYPTO_NONCE_SIZE],
|
||||
const uint8_t *encrypted, size_t length, uint8_t *plain);
|
||||
@@ -431,7 +434,8 @@ int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
* @return length of encrypted data if everything was fine.
|
||||
*/
|
||||
non_null()
|
||||
int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
int32_t encrypt_data_symmetric(const Memory *mem,
|
||||
const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
const uint8_t nonce[CRYPTO_NONCE_SIZE],
|
||||
const uint8_t *plain, size_t length, uint8_t *encrypted);
|
||||
|
||||
@@ -446,7 +450,8 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
* @return length of plain data if everything was fine.
|
||||
*/
|
||||
non_null()
|
||||
int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
int32_t decrypt_data_symmetric(const Memory *mem,
|
||||
const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
|
||||
const uint8_t nonce[CRYPTO_NONCE_SIZE],
|
||||
const uint8_t *encrypted, size_t length, uint8_t *plain);
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "crypto_core_test_util.hh"
|
||||
#include "mem_test_util.hh"
|
||||
#include "util.h"
|
||||
|
||||
namespace {
|
||||
@@ -17,8 +18,38 @@ using SecretKey = std::array<uint8_t, CRYPTO_SECRET_KEY_SIZE>;
|
||||
using Signature = std::array<uint8_t, CRYPTO_SIGNATURE_SIZE>;
|
||||
using Nonce = std::array<uint8_t, CRYPTO_NONCE_SIZE>;
|
||||
|
||||
TEST(PkEqual, TwoRandomIdsAreNotEqual)
|
||||
{
|
||||
std::mt19937 rng;
|
||||
std::uniform_int_distribution<unsigned short> dist{0, UINT8_MAX};
|
||||
|
||||
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
|
||||
std::generate(std::begin(pk1), std::end(pk1), [&]() { return dist(rng); });
|
||||
std::generate(std::begin(pk2), std::end(pk2), [&]() { return dist(rng); });
|
||||
|
||||
EXPECT_FALSE(pk_equal(pk1, pk2));
|
||||
}
|
||||
|
||||
TEST(PkEqual, IdCopyMakesKeysEqual)
|
||||
{
|
||||
std::mt19937 rng;
|
||||
std::uniform_int_distribution<unsigned short> dist{0, UINT8_MAX};
|
||||
|
||||
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
|
||||
|
||||
std::generate(std::begin(pk1), std::end(pk1), [&]() { return dist(rng); });
|
||||
|
||||
pk_copy(pk2, pk1);
|
||||
|
||||
EXPECT_TRUE(pk_equal(pk1, pk2));
|
||||
}
|
||||
|
||||
TEST(CryptoCore, EncryptLargeData)
|
||||
{
|
||||
Test_Memory mem;
|
||||
Test_Random rng;
|
||||
|
||||
Nonce nonce{};
|
||||
@@ -30,7 +61,8 @@ TEST(CryptoCore, EncryptLargeData)
|
||||
std::vector<uint8_t> plain(100 * 1024 * 1024);
|
||||
std::vector<uint8_t> encrypted(plain.size() + CRYPTO_MAC_SIZE);
|
||||
|
||||
encrypt_data(pk.data(), sk.data(), nonce.data(), plain.data(), plain.size(), encrypted.data());
|
||||
encrypt_data(
|
||||
mem, pk.data(), sk.data(), nonce.data(), plain.data(), plain.size(), encrypted.data());
|
||||
}
|
||||
|
||||
TEST(CryptoCore, IncrementNonce)
|
||||
|
@@ -158,7 +158,10 @@ static Tox_Event_Dht_Get_Nodes_Response *tox_events_add_dht_get_nodes_response(T
|
||||
event.type = TOX_EVENT_DHT_GET_NODES_RESPONSE;
|
||||
event.data.dht_get_nodes_response = dht_get_nodes_response;
|
||||
|
||||
tox_events_add(events, &event);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -46,7 +46,10 @@ void TestSendForwardRequest(Fuzz_Data &input)
|
||||
// rest of the fuzz data is input for malloc and network
|
||||
Fuzz_System sys(input);
|
||||
|
||||
Ptr<Logger> logger(logger_new(), logger_kill);
|
||||
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),
|
||||
@@ -72,7 +75,10 @@ void TestForwardReply(Fuzz_Data &input)
|
||||
// rest of the fuzz data is input for malloc and network
|
||||
Fuzz_System sys(input);
|
||||
|
||||
Ptr<Logger> logger(logger_new(), logger_kill);
|
||||
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),
|
||||
|
@@ -875,6 +875,10 @@ void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_req
|
||||
int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint32_t nospam_num, const uint8_t *data,
|
||||
uint16_t length)
|
||||
{
|
||||
// TODO(Jfreegman): This max packet size is too large to be handled by receiving clients
|
||||
// when sent via the onion. We currently limit the length at a higher level, but
|
||||
// this bounds check should be fixed to represent the max size of a packet that
|
||||
// the onion client can handle.
|
||||
if (1 + sizeof(nospam_num) + length > ONION_CLIENT_MAX_DATA_SIZE || length == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@@ -14,7 +14,8 @@
|
||||
#include "attributes.h"
|
||||
#include "friend_connection.h"
|
||||
|
||||
#define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - (1 + sizeof(uint32_t)))
|
||||
// TODO(Jfreegman): This should be the maximum size that an onion client can handle.
|
||||
#define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - 100)
|
||||
|
||||
typedef struct Friend_Requests Friend_Requests;
|
||||
|
||||
|
71
external/toxcore/c-toxcore/toxcore/group.c
vendored
71
external/toxcore/c-toxcore/toxcore/group.c
vendored
@@ -9,7 +9,7 @@
|
||||
#include "group.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdlib.h> // calloc, free
|
||||
#include <string.h>
|
||||
|
||||
#include "DHT.h"
|
||||
@@ -20,9 +20,11 @@
|
||||
#include "friend_connection.h"
|
||||
#include "group_common.h"
|
||||
#include "logger.h"
|
||||
#include "mem.h"
|
||||
#include "mono_time.h"
|
||||
#include "net_crypto.h"
|
||||
#include "network.h"
|
||||
#include "sort.h"
|
||||
#include "state.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -957,24 +959,75 @@ static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void
|
||||
|
||||
/** Order peers with friends first and with more recently active earlier */
|
||||
non_null()
|
||||
static int cmp_frozen(const void *a, const void *b)
|
||||
static bool group_peer_less_handler(const void *object, const void *a, const void *b)
|
||||
{
|
||||
const Group_Peer *pa = (const Group_Peer *)a;
|
||||
const Group_Peer *pb = (const Group_Peer *)b;
|
||||
|
||||
if (pa->is_friend ^ pb->is_friend) {
|
||||
return pa->is_friend ? -1 : 1;
|
||||
if (((pa->is_friend ? 1 : 0) ^ (pb->is_friend ? 1 : 0)) != 0) {
|
||||
return pa->is_friend;
|
||||
}
|
||||
|
||||
return cmp_uint(pb->last_active, pa->last_active);
|
||||
return cmp_uint(pb->last_active, pa->last_active) < 0;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static const void *group_peer_get_handler(const void *arr, uint32_t index)
|
||||
{
|
||||
const Group_Peer *entries = (const Group_Peer *)arr;
|
||||
return &entries[index];
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void group_peer_set_handler(void *arr, uint32_t index, const void *val)
|
||||
{
|
||||
Group_Peer *entries = (Group_Peer *)arr;
|
||||
const Group_Peer *entry = (const Group_Peer *)val;
|
||||
entries[index] = *entry;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void *group_peer_subarr_handler(void *arr, uint32_t index, uint32_t size)
|
||||
{
|
||||
Group_Peer *entries = (Group_Peer *)arr;
|
||||
return &entries[index];
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void *group_peer_alloc_handler(const void *object, uint32_t size)
|
||||
{
|
||||
const Memory *mem = (const Memory *)object;
|
||||
Group_Peer *tmp = (Group_Peer *)mem_valloc(mem, size, sizeof(Group_Peer));
|
||||
|
||||
if (tmp == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void group_peer_delete_handler(const void *object, void *arr, uint32_t size)
|
||||
{
|
||||
const Memory *mem = (const Memory *)object;
|
||||
mem_delete(mem, arr);
|
||||
}
|
||||
|
||||
static const Sort_Funcs group_peer_cmp_funcs = {
|
||||
group_peer_less_handler,
|
||||
group_peer_get_handler,
|
||||
group_peer_set_handler,
|
||||
group_peer_subarr_handler,
|
||||
group_peer_alloc_handler,
|
||||
group_peer_delete_handler,
|
||||
};
|
||||
|
||||
/** @brief Delete frozen peers as necessary to ensure at most `g->maxfrozen` remain.
|
||||
*
|
||||
* @retval true if any frozen peers are removed.
|
||||
*/
|
||||
non_null()
|
||||
static bool delete_old_frozen(Group_c *g)
|
||||
static bool delete_old_frozen(Group_c *g, const Memory *mem)
|
||||
{
|
||||
if (g->numfrozen <= g->maxfrozen) {
|
||||
return false;
|
||||
@@ -987,7 +1040,7 @@ static bool delete_old_frozen(Group_c *g)
|
||||
return true;
|
||||
}
|
||||
|
||||
qsort(g->frozen, g->numfrozen, sizeof(Group_Peer), cmp_frozen);
|
||||
merge_sort(g->frozen, g->numfrozen, mem, &group_peer_cmp_funcs);
|
||||
|
||||
Group_Peer *temp = (Group_Peer *)realloc(g->frozen, g->maxfrozen * sizeof(Group_Peer));
|
||||
|
||||
@@ -1032,7 +1085,7 @@ static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index,
|
||||
|
||||
++g->numfrozen;
|
||||
|
||||
delete_old_frozen(g);
|
||||
delete_old_frozen(g, g_c->m->mem);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1519,7 +1572,7 @@ int group_set_max_frozen(const Group_Chats *g_c, uint32_t groupnumber, uint32_t
|
||||
}
|
||||
|
||||
g->maxfrozen = maxfrozen;
|
||||
delete_old_frozen(g);
|
||||
delete_old_frozen(g, g_c->m->mem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -19,7 +19,8 @@ void TestUnpackAnnouncesList(Fuzz_Data &input)
|
||||
// TODO(iphydf): How do we know the packed size?
|
||||
CONSUME1_OR_RETURN(const uint16_t, packed_size, input);
|
||||
|
||||
Logger *logger = logger_new();
|
||||
Test_Memory mem;
|
||||
Logger *logger = logger_new(mem);
|
||||
if (gca_unpack_announces_list(logger, input.data(), input.size(), announces.data(), max_count)
|
||||
!= -1) {
|
||||
// Always allocate at least something to avoid passing nullptr to functions below.
|
||||
@@ -38,7 +39,8 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input)
|
||||
// TODO(iphydf): How do we know the packed size?
|
||||
CONSUME1_OR_RETURN(const uint16_t, packed_size, input);
|
||||
|
||||
Logger *logger = logger_new();
|
||||
Test_Memory mem;
|
||||
Logger *logger = logger_new(mem);
|
||||
if (gca_unpack_public_announce(logger, input.data(), input.size(), &public_announce) != -1) {
|
||||
// Always allocate at least something to avoid passing nullptr to functions below.
|
||||
std::vector<uint8_t> packed(packed_size + 1);
|
||||
@@ -50,7 +52,7 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input)
|
||||
void TestDoGca(Fuzz_Data &input)
|
||||
{
|
||||
Test_Memory mem;
|
||||
std::unique_ptr<Logger, void (*)(Logger *)> logger(logger_new(), logger_kill);
|
||||
std::unique_ptr<Logger, void (*)(Logger *)> logger(logger_new(mem), logger_kill);
|
||||
|
||||
uint64_t clock = 1;
|
||||
std::unique_ptr<Mono_Time, std::function<void(Mono_Time *)>> mono_time(
|
||||
|
@@ -118,11 +118,12 @@ TEST_F(Announces, AnnouncesGetAndCleanup)
|
||||
struct AnnouncesPack : ::testing::Test {
|
||||
protected:
|
||||
std::vector<GC_Announce> announces_;
|
||||
Test_Memory mem_;
|
||||
Logger *logger_ = nullptr;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
logger_ = logger_new();
|
||||
logger_ = logger_new(mem_);
|
||||
ASSERT_NE(logger_, nullptr);
|
||||
|
||||
// Add an announce without TCP relay.
|
||||
|
29
external/toxcore/c-toxcore/toxcore/group_chats.c
vendored
29
external/toxcore/c-toxcore/toxcore/group_chats.c
vendored
@@ -30,6 +30,7 @@
|
||||
#include "group_moderation.h"
|
||||
#include "group_pack.h"
|
||||
#include "logger.h"
|
||||
#include "mem.h"
|
||||
#include "mono_time.h"
|
||||
#include "net_crypto.h"
|
||||
#include "network.h"
|
||||
@@ -1473,8 +1474,8 @@ static bool sign_gc_shared_state(GC_Chat *chat)
|
||||
* Return -2 on decryption failure.
|
||||
* Return -3 if plaintext payload length is invalid.
|
||||
*/
|
||||
non_null(1, 2, 3, 5, 6) nullable(4)
|
||||
static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, uint8_t *data, uint64_t *message_id,
|
||||
non_null(1, 2, 3, 4, 6, 7) nullable(5)
|
||||
static int group_packet_unwrap(const Logger *log, const Memory *mem, const GC_Connection *gconn, uint8_t *data, uint64_t *message_id,
|
||||
uint8_t *packet_type, const uint8_t *packet, uint16_t length)
|
||||
{
|
||||
assert(data != nullptr);
|
||||
@@ -1492,7 +1493,7 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui
|
||||
return -1;
|
||||
}
|
||||
|
||||
int plain_len = decrypt_data_symmetric(gconn->session_shared_key, packet, packet + CRYPTO_NONCE_SIZE,
|
||||
int plain_len = decrypt_data_symmetric(mem, gconn->session_shared_key, packet, packet + CRYPTO_NONCE_SIZE,
|
||||
length - CRYPTO_NONCE_SIZE, plain);
|
||||
|
||||
if (plain_len <= 0) {
|
||||
@@ -1533,7 +1534,7 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui
|
||||
}
|
||||
|
||||
int group_packet_wrap(
|
||||
const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
|
||||
const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
|
||||
uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id,
|
||||
uint8_t gp_packet_type, Net_Packet_Type net_packet_type)
|
||||
{
|
||||
@@ -1588,7 +1589,7 @@ int group_packet_wrap(
|
||||
return -2;
|
||||
}
|
||||
|
||||
const int enc_len = encrypt_data_symmetric(shared_key, nonce, plain, plain_len, encrypt);
|
||||
const int enc_len = encrypt_data_symmetric(mem, shared_key, nonce, plain, plain_len, encrypt);
|
||||
|
||||
free(plain);
|
||||
|
||||
@@ -1634,7 +1635,7 @@ static bool send_lossy_group_packet(const GC_Chat *chat, const GC_Connection *gc
|
||||
}
|
||||
|
||||
const int len = group_packet_wrap(
|
||||
chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
|
||||
chat->log, chat->mem, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
|
||||
packet_size, data, length, 0, packet_type, NET_PACKET_GC_LOSSY);
|
||||
|
||||
if (len < 0) {
|
||||
@@ -5508,7 +5509,7 @@ static int handle_gc_broadcast(const GC_Session *c, GC_Chat *chat, uint32_t peer
|
||||
* Return -2 if decryption fails.
|
||||
*/
|
||||
non_null()
|
||||
static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_sk, const uint8_t *sender_pk,
|
||||
static int unwrap_group_handshake_packet(const Logger *log, const Memory *mem, const uint8_t *self_sk, const uint8_t *sender_pk,
|
||||
uint8_t *plain, size_t plain_size, const uint8_t *packet, uint16_t length)
|
||||
{
|
||||
if (length <= CRYPTO_NONCE_SIZE) {
|
||||
@@ -5516,7 +5517,7 @@ static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int plain_len = decrypt_data(sender_pk, self_sk, packet, packet + CRYPTO_NONCE_SIZE,
|
||||
const int plain_len = decrypt_data(mem, sender_pk, self_sk, packet, packet + CRYPTO_NONCE_SIZE,
|
||||
length - CRYPTO_NONCE_SIZE, plain);
|
||||
|
||||
if (plain_len < 0 || (uint32_t)plain_len != plain_size) {
|
||||
@@ -5539,7 +5540,7 @@ static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_
|
||||
*/
|
||||
non_null()
|
||||
static int wrap_group_handshake_packet(
|
||||
const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *self_sk,
|
||||
const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *self_sk,
|
||||
const uint8_t *target_pk, uint8_t *packet, uint32_t packet_size,
|
||||
const uint8_t *data, uint16_t length)
|
||||
{
|
||||
@@ -5558,7 +5559,7 @@ static int wrap_group_handshake_packet(
|
||||
return -2;
|
||||
}
|
||||
|
||||
const int enc_len = encrypt_data(target_pk, self_sk, nonce, data, length, encrypt);
|
||||
const int enc_len = encrypt_data(mem, target_pk, self_sk, nonce, data, length, encrypt);
|
||||
|
||||
if (enc_len < 0 || (size_t)enc_len != encrypt_buf_size) {
|
||||
LOGGER_ERROR(log, "Failed to encrypt group handshake packet (len: %d)", enc_len);
|
||||
@@ -5622,7 +5623,7 @@ static int make_gc_handshake_packet(const GC_Chat *chat, const GC_Connection *gc
|
||||
}
|
||||
|
||||
const int enc_len = wrap_group_handshake_packet(
|
||||
chat->log, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc,
|
||||
chat->log, chat->mem, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc,
|
||||
gconn->addr.public_key.enc, packet, (uint16_t)packet_size, data, length);
|
||||
|
||||
if (enc_len != GC_MIN_ENCRYPTED_HS_PAYLOAD_SIZE + nodes_size) {
|
||||
@@ -5951,7 +5952,7 @@ static int handle_gc_handshake_packet(GC_Chat *chat, const uint8_t *sender_pk, c
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int plain_len = unwrap_group_handshake_packet(chat->log, chat->self_secret_key.enc, sender_pk, data,
|
||||
const int plain_len = unwrap_group_handshake_packet(chat->log, chat->mem, chat->self_secret_key.enc, sender_pk, data,
|
||||
data_buf_size, packet, length);
|
||||
|
||||
if (plain_len < GC_MIN_HS_PACKET_PAYLOAD_SIZE) {
|
||||
@@ -6181,7 +6182,7 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const
|
||||
uint8_t packet_type;
|
||||
uint64_t message_id;
|
||||
|
||||
const int len = group_packet_unwrap(chat->log, gconn, data, &message_id, &packet_type, packet, length);
|
||||
const int len = group_packet_unwrap(chat->log, chat->mem, gconn, data, &message_id, &packet_type, packet, length);
|
||||
|
||||
if (len < 0) {
|
||||
Ip_Ntoa ip_str;
|
||||
@@ -6334,7 +6335,7 @@ static bool handle_gc_lossy_packet(const GC_Session *c, GC_Chat *chat, const uin
|
||||
|
||||
uint8_t packet_type;
|
||||
|
||||
const int len = group_packet_unwrap(chat->log, gconn, data, nullptr, &packet_type, packet, length);
|
||||
const int len = group_packet_unwrap(chat->log, chat->mem, gconn, data, nullptr, &packet_type, packet, length);
|
||||
|
||||
if (len <= 0) {
|
||||
Ip_Ntoa ip_str;
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "group_common.h"
|
||||
#include "group_connection.h"
|
||||
#include "logger.h"
|
||||
#include "mem.h"
|
||||
#include "network.h"
|
||||
|
||||
#define GC_PING_TIMEOUT 12
|
||||
@@ -141,9 +142,9 @@ int get_peer_number_of_enc_pk(const GC_Chat *chat, const uint8_t *public_enc_key
|
||||
* Return -2 if malloc fails.
|
||||
* Return -3 if encryption fails.
|
||||
*/
|
||||
non_null(1, 2, 3, 4, 5) nullable(7)
|
||||
non_null(1, 2, 3, 4, 5, 6) nullable(8)
|
||||
int group_packet_wrap(
|
||||
const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
|
||||
const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
|
||||
uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id,
|
||||
uint8_t gp_packet_type, Net_Packet_Type net_packet_type);
|
||||
|
||||
|
@@ -52,7 +52,7 @@
|
||||
#define MAX_GC_PACKET_SIZE (MAX_GC_PACKET_CHUNK_SIZE * 100)
|
||||
|
||||
/* Max number of messages to store in the send/recv arrays */
|
||||
#define GCC_BUFFER_SIZE 8192
|
||||
#define GCC_BUFFER_SIZE 2048
|
||||
|
||||
/** Self UDP status. Must correspond to return values from `ipport_self_copy()`. */
|
||||
typedef enum Self_UDP_Status {
|
||||
|
@@ -629,7 +629,7 @@ int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connectio
|
||||
}
|
||||
|
||||
const int enc_len = group_packet_wrap(
|
||||
chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
|
||||
chat->log, chat->mem, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
|
||||
packet_size, data, length, message_id, packet_type, NET_PACKET_GC_LOSSLESS);
|
||||
|
||||
if (enc_len < 0) {
|
||||
|
@@ -191,9 +191,9 @@ struct SanctionsListMod : ::testing::Test {
|
||||
protected:
|
||||
Extended_Public_Key pk;
|
||||
Extended_Secret_Key sk;
|
||||
Logger *log = logger_new();
|
||||
Test_Random rng;
|
||||
Test_Memory mem;
|
||||
Logger *log = logger_new(mem);
|
||||
Moderation mod{mem};
|
||||
|
||||
Mod_Sanction sanctions[2] = {};
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include "crypto_core.h"
|
||||
#include "group_announce.h"
|
||||
#include "logger.h"
|
||||
#include "mem.h"
|
||||
#include "mono_time.h"
|
||||
#include "network.h"
|
||||
#include "onion_announce.h"
|
||||
@@ -76,7 +77,7 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a)
|
||||
}
|
||||
|
||||
int create_gca_announce_request(
|
||||
const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id,
|
||||
const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data,
|
||||
const uint8_t *gc_data, uint16_t gc_data_length)
|
||||
@@ -108,7 +109,7 @@ int create_gca_announce_request(
|
||||
random_nonce(rng, packet + 1);
|
||||
memcpy(packet + 1 + CRYPTO_NONCE_SIZE, public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain,
|
||||
const int len = encrypt_data(mem, dest_client_id, secret_key, packet + 1, plain,
|
||||
encrypted_size, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
const uint32_t full_length = (uint32_t)len + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE;
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "attributes.h"
|
||||
#include "crypto_core.h"
|
||||
#include "group_announce.h"
|
||||
#include "mem.h"
|
||||
#include "onion_announce.h"
|
||||
|
||||
non_null()
|
||||
@@ -16,7 +17,7 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a);
|
||||
|
||||
non_null()
|
||||
int create_gca_announce_request(
|
||||
const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id,
|
||||
const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data,
|
||||
const uint8_t *gc_data, uint16_t gc_data_length);
|
||||
|
66
external/toxcore/c-toxcore/toxcore/logger.c
vendored
66
external/toxcore/c-toxcore/toxcore/logger.c
vendored
@@ -13,69 +13,41 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "ccompat.h"
|
||||
#include "mem.h"
|
||||
|
||||
struct Logger {
|
||||
const Memory *mem;
|
||||
|
||||
logger_cb *callback;
|
||||
void *context;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
#ifndef NDEBUG
|
||||
static const char *logger_level_name(Logger_Level level)
|
||||
{
|
||||
switch (level) {
|
||||
case LOGGER_LEVEL_TRACE:
|
||||
return "TRACE";
|
||||
|
||||
case LOGGER_LEVEL_DEBUG:
|
||||
return "DEBUG";
|
||||
|
||||
case LOGGER_LEVEL_INFO:
|
||||
return "INFO";
|
||||
|
||||
case LOGGER_LEVEL_WARNING:
|
||||
return "WARNING";
|
||||
|
||||
case LOGGER_LEVEL_ERROR:
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
return "<unknown>";
|
||||
}
|
||||
#endif /* NDEBUG */
|
||||
|
||||
non_null(1, 3, 5, 6) nullable(7)
|
||||
static void logger_stderr_handler(void *context, Logger_Level level, const char *file, int line, const char *func,
|
||||
const char *message, void *userdata)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
// GL stands for "global logger".
|
||||
fprintf(stderr, "[GL] %s %s:%d(%s): %s\n", logger_level_name(level), file, line, func, message);
|
||||
fprintf(stderr, "Default stderr logger triggered; aborting program\n");
|
||||
abort();
|
||||
#endif /* NDEBUG */
|
||||
}
|
||||
|
||||
static const Logger logger_stderr = {
|
||||
logger_stderr_handler,
|
||||
nullptr,
|
||||
nullptr,
|
||||
};
|
||||
|
||||
/*
|
||||
* Public Functions
|
||||
*/
|
||||
|
||||
Logger *logger_new(void)
|
||||
Logger *logger_new(const Memory *mem)
|
||||
{
|
||||
return (Logger *)calloc(1, sizeof(Logger));
|
||||
Logger *log = (Logger *)mem_alloc(mem, sizeof(Logger));
|
||||
|
||||
if (log == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
log->mem = mem;
|
||||
|
||||
return log;
|
||||
}
|
||||
|
||||
void logger_kill(Logger *log)
|
||||
{
|
||||
free(log);
|
||||
if (log == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
mem_delete(log->mem, log);
|
||||
}
|
||||
|
||||
void logger_callback_log(Logger *log, logger_cb *function, void *context, void *userdata)
|
||||
@@ -89,7 +61,7 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, int l
|
||||
const char *format, ...)
|
||||
{
|
||||
if (log == nullptr) {
|
||||
log = &logger_stderr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (log->callback == nullptr) {
|
||||
|
4
external/toxcore/c-toxcore/toxcore/logger.h
vendored
4
external/toxcore/c-toxcore/toxcore/logger.h
vendored
@@ -12,6 +12,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -38,7 +39,8 @@ typedef void logger_cb(void *context, Logger_Level level, const char *file, int
|
||||
/**
|
||||
* Creates a new logger with logging disabled (callback is NULL) by default.
|
||||
*/
|
||||
Logger *logger_new(void);
|
||||
non_null()
|
||||
Logger *logger_new(const Memory *mem);
|
||||
|
||||
/**
|
||||
* Frees all resources associated with the logger.
|
||||
|
34
external/toxcore/c-toxcore/toxcore/net_crypto.c
vendored
34
external/toxcore/c-toxcore/toxcore/net_crypto.c
vendored
@@ -230,7 +230,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin
|
||||
packet[0] = NET_PACKET_COOKIE_REQUEST;
|
||||
memcpy(packet + 1, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
|
||||
const int len = encrypt_data_symmetric(shared_key, nonce, plain, sizeof(plain),
|
||||
const int len = encrypt_data_symmetric(c->mem, shared_key, nonce, plain, sizeof(plain),
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) {
|
||||
@@ -246,7 +246,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin
|
||||
* @retval 0 on success.
|
||||
*/
|
||||
non_null()
|
||||
static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
|
||||
static int create_cookie(const Memory *mem, const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
|
||||
const uint8_t *encryption_key)
|
||||
{
|
||||
uint8_t contents[COOKIE_CONTENTS_LENGTH];
|
||||
@@ -254,7 +254,7 @@ static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t
|
||||
memcpy(contents, &temp_time, sizeof(temp_time));
|
||||
memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH);
|
||||
random_nonce(rng, cookie);
|
||||
const int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE);
|
||||
const int len = encrypt_data_symmetric(mem, encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != COOKIE_LENGTH - CRYPTO_NONCE_SIZE) {
|
||||
return -1;
|
||||
@@ -269,11 +269,11 @@ static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t
|
||||
* @retval 0 on success.
|
||||
*/
|
||||
non_null()
|
||||
static int open_cookie(const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie,
|
||||
static int open_cookie(const Memory *mem, const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie,
|
||||
const uint8_t *encryption_key)
|
||||
{
|
||||
uint8_t contents[COOKIE_CONTENTS_LENGTH];
|
||||
const int len = decrypt_data_symmetric(encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE,
|
||||
const int len = decrypt_data_symmetric(mem, encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE,
|
||||
COOKIE_LENGTH - CRYPTO_NONCE_SIZE, contents);
|
||||
|
||||
if (len != sizeof(contents)) {
|
||||
@@ -308,14 +308,14 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui
|
||||
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
|
||||
|
||||
if (create_cookie(c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
|
||||
if (create_cookie(c->mem, c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t));
|
||||
packet[0] = NET_PACKET_COOKIE_RESPONSE;
|
||||
random_nonce(c->rng, packet + 1);
|
||||
const int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE);
|
||||
const int len = encrypt_data_symmetric(c->mem, shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != COOKIE_RESPONSE_LENGTH - (1 + CRYPTO_NONCE_SIZE)) {
|
||||
return -1;
|
||||
@@ -342,7 +342,7 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui
|
||||
memcpy(dht_public_key, packet + 1, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
const uint8_t *tmp_shared_key = dht_get_shared_key_sent(c->dht, dht_public_key);
|
||||
memcpy(shared_key, tmp_shared_key, CRYPTO_SHARED_KEY_SIZE);
|
||||
const int len = decrypt_data_symmetric(shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
const int len = decrypt_data_symmetric(c->mem, shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE,
|
||||
request_plain);
|
||||
|
||||
@@ -439,7 +439,7 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c
|
||||
* @retval COOKIE_LENGTH on success.
|
||||
*/
|
||||
non_null()
|
||||
static int handle_cookie_response(uint8_t *cookie, uint64_t *number,
|
||||
static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t *number,
|
||||
const uint8_t *packet, uint16_t length,
|
||||
const uint8_t *shared_key)
|
||||
{
|
||||
@@ -448,7 +448,7 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number,
|
||||
}
|
||||
|
||||
uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
|
||||
const int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
|
||||
const int len = decrypt_data_symmetric(mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
|
||||
length - (1 + CRYPTO_NONCE_SIZE), plain);
|
||||
|
||||
if (len != sizeof(plain)) {
|
||||
@@ -481,13 +481,13 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u
|
||||
memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
if (create_cookie(c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
|
||||
if (create_cookie(c->mem, c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
|
||||
cookie_plain, c->secret_symmetric_key) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
random_nonce(c->rng, packet + 1 + COOKIE_LENGTH);
|
||||
const int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
|
||||
const int len = encrypt_data(c->mem, peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
|
||||
packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) {
|
||||
@@ -528,7 +528,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
|
||||
|
||||
uint8_t cookie_plain[COOKIE_DATA_LENGTH];
|
||||
|
||||
if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
|
||||
if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -540,7 +540,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
|
||||
crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH);
|
||||
|
||||
uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH];
|
||||
const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
|
||||
const int len = decrypt_data(c->mem, cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
|
||||
packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE,
|
||||
HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain);
|
||||
|
||||
@@ -1084,7 +1084,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_
|
||||
VLA(uint8_t, packet, packet_size);
|
||||
packet[0] = NET_PACKET_CRYPTO_DATA;
|
||||
memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t));
|
||||
const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t));
|
||||
const int len = encrypt_data_symmetric(c->mem, conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t));
|
||||
|
||||
if (len + 1 + sizeof(uint16_t) != packet_size) {
|
||||
LOGGER_ERROR(c->log, "encryption failed: %d", len);
|
||||
@@ -1255,7 +1255,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint
|
||||
net_unpack_u16(packet + 1, &num);
|
||||
const uint16_t diff = num - num_cur_nonce;
|
||||
increment_nonce_number(nonce, diff);
|
||||
const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t),
|
||||
const int len = decrypt_data_symmetric(c->mem, conn->shared_key, nonce, packet + 1 + sizeof(uint16_t),
|
||||
length - (1 + sizeof(uint16_t)), data);
|
||||
|
||||
if ((unsigned int)len != length - crypto_packet_overhead) {
|
||||
@@ -1662,7 +1662,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id,
|
||||
uint8_t cookie[COOKIE_LENGTH];
|
||||
uint64_t number;
|
||||
|
||||
if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) {
|
||||
if (handle_cookie_response(c->mem, cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
233
external/toxcore/c-toxcore/toxcore/network.c
vendored
233
external/toxcore/c-toxcore/toxcore/network.c
vendored
@@ -513,6 +513,12 @@ static int sys_listen(void *obj, Socket sock, int backlog)
|
||||
return listen(net_socket_to_native(sock), backlog);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int sys_connect(void *obj, Socket sock, const Network_Addr *addr)
|
||||
{
|
||||
return connect(net_socket_to_native(sock), (const struct sockaddr *)&addr->addr, addr->size);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int sys_recvbuf(void *obj, Socket sock)
|
||||
{
|
||||
@@ -586,11 +592,98 @@ static int sys_setsockopt(void *obj, Socket sock, int level, int optname, const
|
||||
return setsockopt(net_socket_to_native(sock), level, optname, (const char *)optval, optlen);
|
||||
}
|
||||
|
||||
// sets and fills an array of addrs for address
|
||||
// returns the number of entries in addrs
|
||||
non_null()
|
||||
static int sys_getaddrinfo(void *obj, const Memory *mem, const char *address, int family, int sock_type, Network_Addr **addrs)
|
||||
{
|
||||
assert(addrs != nullptr);
|
||||
|
||||
struct addrinfo hints = {0};
|
||||
hints.ai_family = family;
|
||||
|
||||
|
||||
// different platforms favour a different field
|
||||
// hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
|
||||
hints.ai_socktype = sock_type;
|
||||
// hints.ai_protocol = protocol;
|
||||
|
||||
struct addrinfo *infos = nullptr;
|
||||
|
||||
const int rc = getaddrinfo(address, nullptr, &hints, &infos);
|
||||
|
||||
// Lookup failed.
|
||||
if (rc != 0) {
|
||||
// TODO(Green-Sky): log error
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int32_t max_count = INT32_MAX / sizeof(Network_Addr);
|
||||
|
||||
// we count number of "valid" results
|
||||
int result = 0;
|
||||
for (struct addrinfo *walker = infos; walker != nullptr && result < max_count; walker = walker->ai_next) {
|
||||
if (walker->ai_family == family || family == AF_UNSPEC) {
|
||||
++result;
|
||||
}
|
||||
|
||||
// do we need to check socktype/protocol?
|
||||
}
|
||||
|
||||
assert(max_count >= result);
|
||||
|
||||
Network_Addr *tmp_addrs = (Network_Addr *)mem_valloc(mem, result, sizeof(Network_Addr));
|
||||
if (tmp_addrs == nullptr) {
|
||||
freeaddrinfo(infos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// now we fill in
|
||||
int i = 0;
|
||||
for (struct addrinfo *walker = infos; walker != nullptr; walker = walker->ai_next) {
|
||||
if (walker->ai_family == family || family == AF_UNSPEC) {
|
||||
tmp_addrs[i].size = sizeof(struct sockaddr_storage);
|
||||
tmp_addrs[i].addr.ss_family = walker->ai_family;
|
||||
|
||||
// according to spec, storage is supposed to be large enough (and source shows they are)
|
||||
// storage is 128 bytes
|
||||
assert(walker->ai_addrlen <= tmp_addrs[i].size);
|
||||
|
||||
memcpy(&tmp_addrs[i].addr, walker->ai_addr, walker->ai_addrlen);
|
||||
tmp_addrs[i].size = walker->ai_addrlen;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
assert(i == result);
|
||||
|
||||
freeaddrinfo(infos);
|
||||
|
||||
*addrs = tmp_addrs;
|
||||
|
||||
// number of entries in addrs
|
||||
return result;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int sys_freeaddrinfo(void *obj, const Memory *mem, Network_Addr *addrs)
|
||||
{
|
||||
if (addrs == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem_delete(mem, addrs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const Network_Funcs os_network_funcs = {
|
||||
sys_close,
|
||||
sys_accept,
|
||||
sys_bind,
|
||||
sys_listen,
|
||||
sys_connect,
|
||||
sys_recvbuf,
|
||||
sys_recv,
|
||||
sys_recvfrom,
|
||||
@@ -600,8 +693,10 @@ static const Network_Funcs os_network_funcs = {
|
||||
sys_socket_nonblock,
|
||||
sys_getsockopt,
|
||||
sys_setsockopt,
|
||||
sys_getaddrinfo,
|
||||
sys_freeaddrinfo,
|
||||
};
|
||||
static const Network os_network_obj = {&os_network_funcs};
|
||||
static const Network os_network_obj = {&os_network_funcs, nullptr};
|
||||
|
||||
const Network *os_network(void)
|
||||
{
|
||||
@@ -882,7 +977,11 @@ bool set_socket_nosigpipe(const Network *ns, Socket sock)
|
||||
bool set_socket_reuseaddr(const Network *ns, Socket sock)
|
||||
{
|
||||
int set = 1;
|
||||
#if defined(OS_WIN32)
|
||||
return net_setsockopt(ns, sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, &set, sizeof(set)) == 0;
|
||||
#else
|
||||
return net_setsockopt(ns, sock, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(set)) == 0;
|
||||
#endif /* OS_WIN32 */
|
||||
}
|
||||
|
||||
bool set_socket_dualstack(const Network *ns, Socket sock)
|
||||
@@ -1815,37 +1914,34 @@ bool addr_parse_ip(const char *address, IP *to)
|
||||
* prefers v6 if `ip.family` was TOX_AF_UNSPEC and both available
|
||||
* Returns in `*extra` an IPv4 address, if family was TOX_AF_UNSPEC and `*to` is TOX_AF_INET6
|
||||
*
|
||||
* @return 0 on failure, `TOX_ADDR_RESOLVE_*` on success.
|
||||
* @return false on failure, true on success.
|
||||
*/
|
||||
non_null(1, 2, 3) nullable(4)
|
||||
static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extra)
|
||||
non_null(1, 2, 3, 4) nullable(5)
|
||||
static bool addr_resolve(const Network *ns, const Memory *mem, const char *address, IP *to, IP *extra)
|
||||
{
|
||||
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
if ((true)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
|
||||
|
||||
if (address == nullptr || to == nullptr) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
const Family tox_family = to->family;
|
||||
const int family = make_family(tox_family);
|
||||
|
||||
struct addrinfo hints = {0};
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
|
||||
Network_Addr *addrs = nullptr;
|
||||
const int rc = ns->funcs->getaddrinfo(ns->obj, mem, address, family, 0, &addrs);
|
||||
|
||||
struct addrinfo *server = nullptr;
|
||||
|
||||
const int rc = getaddrinfo(address, nullptr, &hints, &server);
|
||||
|
||||
// Lookup failed.
|
||||
if (rc != 0) {
|
||||
return 0;
|
||||
// Lookup failed / empty.
|
||||
if (rc <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(addrs != nullptr);
|
||||
|
||||
IP ip4;
|
||||
ip_init(&ip4, false); // ipv6enabled = false
|
||||
IP ip6;
|
||||
@@ -1854,16 +1950,16 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr
|
||||
int result = 0;
|
||||
bool done = false;
|
||||
|
||||
for (struct addrinfo *walker = server; walker != nullptr && !done; walker = walker->ai_next) {
|
||||
switch (walker->ai_family) {
|
||||
for (int i = 0; i < rc && !done; ++i) {
|
||||
switch (addrs[i].addr.ss_family) {
|
||||
case AF_INET: {
|
||||
if (walker->ai_family == family) { /* AF_INET requested, done */
|
||||
const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)walker->ai_addr;
|
||||
if (addrs[i].addr.ss_family == family) { /* AF_INET requested, done */
|
||||
const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)&addrs[i].addr;
|
||||
get_ip4(&to->ip.v4, &addr->sin_addr);
|
||||
result = TOX_ADDR_RESOLVE_INET;
|
||||
done = true;
|
||||
} else if ((result & TOX_ADDR_RESOLVE_INET) == 0) { /* AF_UNSPEC requested, store away */
|
||||
const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)walker->ai_addr;
|
||||
const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)&addrs[i].addr;
|
||||
get_ip4(&ip4.ip.v4, &addr->sin_addr);
|
||||
result |= TOX_ADDR_RESOLVE_INET;
|
||||
}
|
||||
@@ -1872,16 +1968,16 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr
|
||||
}
|
||||
|
||||
case AF_INET6: {
|
||||
if (walker->ai_family == family) { /* AF_INET6 requested, done */
|
||||
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
|
||||
const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)walker->ai_addr;
|
||||
if (addrs[i].addr.ss_family == family) { /* AF_INET6 requested, done */
|
||||
if (addrs[i].size == sizeof(struct sockaddr_in6)) {
|
||||
const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)&addrs[i].addr;
|
||||
get_ip6(&to->ip.v6, &addr->sin6_addr);
|
||||
result = TOX_ADDR_RESOLVE_INET6;
|
||||
done = true;
|
||||
}
|
||||
} else if ((result & TOX_ADDR_RESOLVE_INET6) == 0) { /* AF_UNSPEC requested, store away */
|
||||
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
|
||||
const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)walker->ai_addr;
|
||||
if (addrs[i].size == sizeof(struct sockaddr_in6)) {
|
||||
const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)&addrs[i].addr;
|
||||
get_ip6(&ip6.ip.v6, &addr->sin6_addr);
|
||||
result |= TOX_ADDR_RESOLVE_INET6;
|
||||
}
|
||||
@@ -1906,37 +2002,34 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr
|
||||
}
|
||||
}
|
||||
|
||||
freeaddrinfo(server);
|
||||
return result;
|
||||
ns->funcs->freeaddrinfo(ns->obj, mem, addrs);
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra)
|
||||
bool addr_resolve_or_parse_ip(const Network *ns, const Memory *mem, const char *address, IP *to, IP *extra, bool dns_enabled)
|
||||
{
|
||||
if (addr_resolve(ns, address, to, extra) == 0) {
|
||||
if (!addr_parse_ip(address, to)) {
|
||||
return false;
|
||||
}
|
||||
if (dns_enabled && addr_resolve(ns, mem, address, to, extra)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return addr_parse_ip(address, to);
|
||||
}
|
||||
|
||||
bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port)
|
||||
bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port)
|
||||
{
|
||||
struct sockaddr_storage addr = {0};
|
||||
size_t addrsize;
|
||||
Network_Addr addr = {{0}};
|
||||
|
||||
if (net_family_is_ipv4(ip_port->ip.family)) {
|
||||
struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
|
||||
struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr.addr;
|
||||
|
||||
addrsize = sizeof(struct sockaddr_in);
|
||||
addr.size = sizeof(struct sockaddr_in);
|
||||
addr4->sin_family = AF_INET;
|
||||
fill_addr4(&ip_port->ip.ip.v4, &addr4->sin_addr);
|
||||
addr4->sin_port = ip_port->port;
|
||||
} else if (net_family_is_ipv6(ip_port->ip.family)) {
|
||||
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
|
||||
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr.addr;
|
||||
|
||||
addrsize = sizeof(struct sockaddr_in6);
|
||||
addr.size = sizeof(struct sockaddr_in6);
|
||||
addr6->sin6_family = AF_INET6;
|
||||
fill_addr6(&ip_port->ip.ip.v6, &addr6->sin6_addr);
|
||||
addr6->sin6_port = ip_port->port;
|
||||
@@ -1958,7 +2051,7 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por
|
||||
net_socket_to_native(sock), net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port));
|
||||
errno = 0;
|
||||
|
||||
if (connect(net_socket_to_native(sock), (struct sockaddr *)&addr, addrsize) == -1) {
|
||||
if (ns->funcs->connect(ns->obj, sock, &addr) == -1) {
|
||||
const int error = net_error();
|
||||
|
||||
// Non-blocking socket: "Operation in progress" means it's connecting.
|
||||
@@ -1974,7 +2067,7 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type)
|
||||
int32_t net_getipport(const Network *ns, const Memory *mem, const char *node, IP_Port **res, int tox_type, bool dns_enabled)
|
||||
{
|
||||
assert(node != nullptr);
|
||||
|
||||
@@ -1996,6 +2089,10 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!dns_enabled) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
if ((true)) {
|
||||
IP_Port *ip_port = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));
|
||||
@@ -2010,25 +2107,29 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
|
||||
}
|
||||
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
|
||||
|
||||
// It's not an IP address, so now we try doing a DNS lookup.
|
||||
struct addrinfo *infos;
|
||||
const int ret = getaddrinfo(node, nullptr, nullptr, &infos);
|
||||
int type = make_socktype(tox_type);
|
||||
// ugly
|
||||
if (tox_type == -1) {
|
||||
type = 0;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
// It's not an IP address, so now we try doing a DNS lookup.
|
||||
Network_Addr *addrs = nullptr;
|
||||
const int rc = ns->funcs->getaddrinfo(ns->obj, mem, node, AF_UNSPEC, type, &addrs);
|
||||
|
||||
// Lookup failed / empty.
|
||||
if (rc <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(addrs != nullptr);
|
||||
|
||||
// Used to avoid calloc parameter overflow
|
||||
const size_t max_count = min_u64(SIZE_MAX, INT32_MAX) / sizeof(IP_Port);
|
||||
const int type = make_socktype(tox_type);
|
||||
size_t count = 0;
|
||||
|
||||
for (struct addrinfo *cur = infos; count < max_count && cur != nullptr; cur = cur->ai_next) {
|
||||
if (cur->ai_socktype != 0 && type > 0 && cur->ai_socktype != type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cur->ai_family != AF_INET && cur->ai_family != AF_INET6) {
|
||||
for (int i = 0; i < rc && count < max_count; ++i) {
|
||||
if (addrs[i].addr.ss_family != AF_INET && addrs[i].addr.ss_family != AF_INET6) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2038,40 +2139,36 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
|
||||
assert(count <= max_count);
|
||||
|
||||
if (count == 0) {
|
||||
freeaddrinfo(infos);
|
||||
ns->funcs->freeaddrinfo(ns->obj, mem, addrs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IP_Port *ip_port = (IP_Port *)mem_valloc(mem, count, sizeof(IP_Port));
|
||||
|
||||
if (ip_port == nullptr) {
|
||||
freeaddrinfo(infos);
|
||||
ns->funcs->freeaddrinfo(ns->obj, mem, addrs);
|
||||
*res = nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*res = ip_port;
|
||||
|
||||
for (struct addrinfo *cur = infos; cur != nullptr; cur = cur->ai_next) {
|
||||
if (cur->ai_socktype != 0 && type > 0 && cur->ai_socktype != type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cur->ai_family == AF_INET) {
|
||||
const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)cur->ai_addr;
|
||||
for (int i = 0; i < rc && count < max_count; ++i) {
|
||||
if (addrs[i].addr.ss_family == AF_INET) {
|
||||
const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)&addrs[i].addr;
|
||||
ip_port->ip.ip.v4.uint32 = addr->sin_addr.s_addr;
|
||||
} else if (cur->ai_family == AF_INET6) {
|
||||
const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(const void *)cur->ai_addr;
|
||||
} else if (addrs[i].addr.ss_family == AF_INET6) {
|
||||
const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(const void *)&addrs[i].addr;
|
||||
memcpy(ip_port->ip.ip.v6.uint8, addr->sin6_addr.s6_addr, sizeof(IP6));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Family *const family = make_tox_family(cur->ai_family);
|
||||
const Family *const family = make_tox_family(addrs[i].addr.ss_family);
|
||||
assert(family != nullptr);
|
||||
|
||||
if (family == nullptr) {
|
||||
freeaddrinfo(infos);
|
||||
ns->funcs->freeaddrinfo(ns->obj, mem, addrs);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2080,7 +2177,7 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
|
||||
++ip_port;
|
||||
}
|
||||
|
||||
freeaddrinfo(infos);
|
||||
ns->funcs->freeaddrinfo(ns->obj, mem, addrs);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
39
external/toxcore/c-toxcore/toxcore/network.h
vendored
39
external/toxcore/c-toxcore/toxcore/network.h
vendored
@@ -39,6 +39,7 @@ typedef int net_close_cb(void *obj, Socket sock);
|
||||
typedef Socket net_accept_cb(void *obj, Socket sock);
|
||||
typedef int net_bind_cb(void *obj, Socket sock, const Network_Addr *addr);
|
||||
typedef int net_listen_cb(void *obj, Socket sock, int backlog);
|
||||
typedef int net_connect_cb(void *obj, Socket sock, const Network_Addr *addr);
|
||||
typedef int net_recvbuf_cb(void *obj, Socket sock);
|
||||
typedef int net_recv_cb(void *obj, Socket sock, uint8_t *buf, size_t len);
|
||||
typedef int net_recvfrom_cb(void *obj, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr);
|
||||
@@ -48,8 +49,8 @@ typedef Socket net_socket_cb(void *obj, int domain, int type, int proto);
|
||||
typedef int net_socket_nonblock_cb(void *obj, Socket sock, bool nonblock);
|
||||
typedef int net_getsockopt_cb(void *obj, Socket sock, int level, int optname, void *optval, size_t *optlen);
|
||||
typedef int net_setsockopt_cb(void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen);
|
||||
typedef int net_getaddrinfo_cb(void *obj, int family, Network_Addr **addrs);
|
||||
typedef int net_freeaddrinfo_cb(void *obj, Network_Addr *addrs);
|
||||
typedef int net_getaddrinfo_cb(void *obj, const Memory *mem, const char *address, int family, int protocol, Network_Addr **addrs);
|
||||
typedef int net_freeaddrinfo_cb(void *obj, const Memory *mem, Network_Addr *addrs);
|
||||
|
||||
/** @brief Functions wrapping POSIX network functions.
|
||||
*
|
||||
@@ -61,6 +62,7 @@ typedef struct Network_Funcs {
|
||||
net_accept_cb *accept;
|
||||
net_bind_cb *bind;
|
||||
net_listen_cb *listen;
|
||||
net_connect_cb *connect;
|
||||
net_recvbuf_cb *recvbuf;
|
||||
net_recv_cb *recv;
|
||||
net_recvfrom_cb *recvfrom;
|
||||
@@ -396,21 +398,23 @@ non_null()
|
||||
void ipport_copy(IP_Port *target, const IP_Port *source);
|
||||
|
||||
/**
|
||||
* Resolves string into an IP address
|
||||
* @brief Resolves string into an IP address.
|
||||
*
|
||||
* @param address a hostname (or something parseable to an IP address)
|
||||
* @param to to.family MUST be initialized, either set to a specific IP version
|
||||
* @param[in,out] ns Network object.
|
||||
* @param[in] address a hostname (or something parseable to an IP address).
|
||||
* @param[in,out] to to.family MUST be initialized, either set to a specific IP version
|
||||
* (TOX_AF_INET/TOX_AF_INET6) or to the unspecified TOX_AF_UNSPEC (0), if both
|
||||
* IP versions are acceptable
|
||||
* @param extra can be NULL and is only set in special circumstances, see returns
|
||||
* IP versions are acceptable.
|
||||
* @param[out] extra can be NULL and is only set in special circumstances, see returns.
|
||||
* @param[in] dns_enabled if false, DNS resolution is skipped.
|
||||
*
|
||||
* Returns in `*to` a matching address (IPv6 or IPv4)
|
||||
* Returns in `*extra`, if not NULL, an IPv4 address, if `to->family` was TOX_AF_UNSPEC
|
||||
* Returns in `*to` a matching address (IPv6 or IPv4).
|
||||
* Returns in `*extra`, if not NULL, an IPv4 address, if `to->family` was `TOX_AF_UNSPEC`.
|
||||
*
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
non_null(1, 2, 3) nullable(4)
|
||||
bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra);
|
||||
non_null(1, 2, 3, 4) nullable(5)
|
||||
bool addr_resolve_or_parse_ip(const Network *ns, const Memory *mem, const char *address, IP *to, IP *extra, bool dns_enabled);
|
||||
|
||||
/** @brief Function to receive data, ip and port of sender is put into ip_port.
|
||||
* Packet data is put into data.
|
||||
@@ -501,7 +505,7 @@ void networking_poll(const Networking_Core *net, void *userdata);
|
||||
* Return false on failure.
|
||||
*/
|
||||
non_null()
|
||||
bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port);
|
||||
bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port);
|
||||
|
||||
/** @brief High-level getaddrinfo implementation.
|
||||
*
|
||||
@@ -510,14 +514,21 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por
|
||||
* address that can be specified by calling `net_connect()`, the port is ignored.
|
||||
*
|
||||
* Skip all addresses with socktype != type (use type = -1 to get all addresses)
|
||||
* To correctly deallocate array memory use `net_freeipport()`
|
||||
* To correctly deallocate array memory use `net_freeipport()`.
|
||||
*
|
||||
* @param ns Network object.
|
||||
* @param mem Memory allocator.
|
||||
* @param node The node parameter identifies the host or service on which to connect.
|
||||
* @param[out] res An array of IP_Port structures will be allocated into this pointer.
|
||||
* @param tox_type The type of socket to use (stream or datagram), only relevant for DNS lookups.
|
||||
* @param dns_enabled If false, DNS resolution is skipped, when passed a hostname, this function will return an error.
|
||||
*
|
||||
* @return number of elements in res array.
|
||||
* @retval 0 if res array empty.
|
||||
* @retval -1 on error.
|
||||
*/
|
||||
non_null()
|
||||
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type);
|
||||
int32_t net_getipport(const Network *ns, const Memory *mem, const char *node, IP_Port **res, int tox_type, bool dns_enabled);
|
||||
|
||||
/** Deallocates memory allocated by net_getipport */
|
||||
non_null(1) nullable(2)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include <iomanip>
|
||||
|
||||
#include "crypto_core.h"
|
||||
#include "mem.h"
|
||||
#include "network.h"
|
||||
#include "test_util.hh"
|
||||
|
||||
@@ -11,6 +12,7 @@ Network_Funcs const Network_Class::vtable = {
|
||||
Method<net_accept_cb, Network_Class>::invoke<&Network_Class::accept>,
|
||||
Method<net_bind_cb, Network_Class>::invoke<&Network_Class::bind>,
|
||||
Method<net_listen_cb, Network_Class>::invoke<&Network_Class::listen>,
|
||||
Method<net_connect_cb, Network_Class>::invoke<&Network_Class::connect>,
|
||||
Method<net_recvbuf_cb, Network_Class>::invoke<&Network_Class::recvbuf>,
|
||||
Method<net_recv_cb, Network_Class>::invoke<&Network_Class::recv>,
|
||||
Method<net_recvfrom_cb, Network_Class>::invoke<&Network_Class::recvfrom>,
|
||||
@@ -34,6 +36,10 @@ int Test_Network::listen(void *obj, Socket sock, int backlog)
|
||||
{
|
||||
return net->funcs->listen(net->obj, sock, backlog);
|
||||
}
|
||||
int Test_Network::connect(void *obj, Socket sock, const Network_Addr *addr)
|
||||
{
|
||||
return net->funcs->connect(net->obj, sock, addr);
|
||||
}
|
||||
int Test_Network::recvbuf(void *obj, Socket sock) { return net->funcs->recvbuf(net->obj, sock); }
|
||||
int Test_Network::recv(void *obj, Socket sock, uint8_t *buf, size_t len)
|
||||
{
|
||||
@@ -70,13 +76,14 @@ int Test_Network::setsockopt(
|
||||
{
|
||||
return net->funcs->setsockopt(net->obj, sock, level, optname, optval, optlen);
|
||||
}
|
||||
int Test_Network::getaddrinfo(void *obj, int family, Network_Addr **addrs)
|
||||
int Test_Network::getaddrinfo(void *obj, const Memory *mem, const char *address, int family,
|
||||
int protocol, Network_Addr **addrs)
|
||||
{
|
||||
return net->funcs->getaddrinfo(net->obj, family, addrs);
|
||||
return net->funcs->getaddrinfo(net->obj, mem, address, family, protocol, addrs);
|
||||
}
|
||||
int Test_Network::freeaddrinfo(void *obj, Network_Addr *addrs)
|
||||
int Test_Network::freeaddrinfo(void *obj, const Memory *mem, Network_Addr *addrs)
|
||||
{
|
||||
return net->funcs->freeaddrinfo(net->obj, addrs);
|
||||
return net->funcs->freeaddrinfo(net->obj, mem, addrs);
|
||||
}
|
||||
|
||||
Network_Class::~Network_Class() = default;
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <iosfwd>
|
||||
|
||||
#include "crypto_core.h"
|
||||
#include "mem.h"
|
||||
#include "network.h"
|
||||
#include "test_util.hh"
|
||||
|
||||
@@ -24,6 +25,7 @@ struct Network_Class {
|
||||
virtual net_accept_cb accept = 0;
|
||||
virtual net_bind_cb bind = 0;
|
||||
virtual net_listen_cb listen = 0;
|
||||
virtual net_connect_cb connect = 0;
|
||||
virtual net_recvbuf_cb recvbuf = 0;
|
||||
virtual net_recv_cb recv = 0;
|
||||
virtual net_recvfrom_cb recvfrom = 0;
|
||||
@@ -48,6 +50,7 @@ class Test_Network : public Network_Class {
|
||||
Socket accept(void *obj, Socket sock) override;
|
||||
int bind(void *obj, Socket sock, const Network_Addr *addr) override;
|
||||
int listen(void *obj, Socket sock, int backlog) override;
|
||||
int connect(void *obj, Socket sock, const Network_Addr *addr) override;
|
||||
int recvbuf(void *obj, Socket sock) override;
|
||||
int recv(void *obj, Socket sock, uint8_t *buf, size_t len) override;
|
||||
int recvfrom(void *obj, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) override;
|
||||
@@ -60,8 +63,9 @@ class Test_Network : public Network_Class {
|
||||
void *obj, Socket sock, int level, int optname, void *optval, size_t *optlen) override;
|
||||
int setsockopt(
|
||||
void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen) override;
|
||||
int getaddrinfo(void *obj, int family, Network_Addr **addrs) override;
|
||||
int freeaddrinfo(void *obj, Network_Addr *addrs) override;
|
||||
int getaddrinfo(void *obj, const Memory *mem, const char *address, int family, int protocol,
|
||||
Network_Addr **addrs) override;
|
||||
int freeaddrinfo(void *obj, const Memory *mem, Network_Addr *addrs) override;
|
||||
};
|
||||
|
||||
template <>
|
||||
|
32
external/toxcore/c-toxcore/toxcore/onion.c
vendored
32
external/toxcore/c-toxcore/toxcore/onion.c
vendored
@@ -180,7 +180,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
|
||||
* return -1 on failure.
|
||||
* return length of created packet on success.
|
||||
*/
|
||||
int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
int create_onion_packet(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *data, uint16_t length)
|
||||
{
|
||||
@@ -202,7 +202,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
|
||||
ipport_pack(step2, &path->ip_port3);
|
||||
memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size,
|
||||
int len = encrypt_data_symmetric(mem, path->shared_key3, nonce, step1, step1_size,
|
||||
step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) {
|
||||
@@ -213,7 +213,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
|
||||
VLA(uint8_t, step3, step3_size);
|
||||
ipport_pack(step3, &path->ip_port2);
|
||||
memcpy(step3 + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size,
|
||||
len = encrypt_data_symmetric(mem, path->shared_key2, nonce, step2, step2_size,
|
||||
step3 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) {
|
||||
@@ -224,7 +224,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
|
||||
memcpy(packet + 1, nonce, CRYPTO_NONCE_SIZE);
|
||||
memcpy(packet + 1 + CRYPTO_NONCE_SIZE, path->public_key1, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
len = encrypt_data_symmetric(path->shared_key1, nonce, step3, step3_size,
|
||||
len = encrypt_data_symmetric(mem, path->shared_key1, nonce, step3, step3_size,
|
||||
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
if (len != SIZE_IPPORT + SEND_BASE * 2 + length + CRYPTO_MAC_SIZE) {
|
||||
@@ -243,7 +243,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
|
||||
* return -1 on failure.
|
||||
* return length of created packet on success.
|
||||
*/
|
||||
int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
int create_onion_packet_tcp(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *data, uint16_t length)
|
||||
{
|
||||
@@ -265,7 +265,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac
|
||||
ipport_pack(step2, &path->ip_port3);
|
||||
memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size,
|
||||
int len = encrypt_data_symmetric(mem, path->shared_key3, nonce, step1, step1_size,
|
||||
step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) {
|
||||
@@ -274,7 +274,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac
|
||||
|
||||
ipport_pack(packet + CRYPTO_NONCE_SIZE, &path->ip_port2);
|
||||
memcpy(packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size,
|
||||
len = encrypt_data_symmetric(mem, path->shared_key2, nonce, step2, step2_size,
|
||||
packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) {
|
||||
@@ -355,7 +355,7 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_
|
||||
}
|
||||
|
||||
const int len = decrypt_data_symmetric(
|
||||
shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain);
|
||||
onion->mem, shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain);
|
||||
|
||||
if (len != plaintext_length) {
|
||||
LOGGER_TRACE(onion->log, "decrypt failed: %d != %d", len, plaintext_length);
|
||||
@@ -393,7 +393,7 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const I
|
||||
uint16_t data_len = 1 + CRYPTO_NONCE_SIZE + (len - SIZE_IPPORT);
|
||||
uint8_t *ret_part = data + data_len;
|
||||
random_nonce(onion->rng, ret_part);
|
||||
len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT,
|
||||
len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT,
|
||||
ret_part + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != SIZE_IPPORT + CRYPTO_MAC_SIZE) {
|
||||
@@ -436,7 +436,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac
|
||||
return 1;
|
||||
}
|
||||
|
||||
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
int len = decrypt_data_symmetric(onion->mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1), plain);
|
||||
|
||||
if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1 + CRYPTO_MAC_SIZE)) {
|
||||
@@ -459,7 +459,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac
|
||||
uint8_t ret_data[RETURN_1 + SIZE_IPPORT];
|
||||
ipport_pack(ret_data, source);
|
||||
memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1);
|
||||
len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
|
||||
len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
|
||||
ret_part + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != RETURN_2 - CRYPTO_NONCE_SIZE) {
|
||||
@@ -502,7 +502,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac
|
||||
return 1;
|
||||
}
|
||||
|
||||
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
int len = decrypt_data_symmetric(onion->mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2), plain);
|
||||
|
||||
if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2 + CRYPTO_MAC_SIZE)) {
|
||||
@@ -532,7 +532,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac
|
||||
uint8_t ret_data[RETURN_2 + SIZE_IPPORT];
|
||||
ipport_pack(ret_data, source);
|
||||
memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2);
|
||||
len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
|
||||
len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
|
||||
ret_part + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != RETURN_3 - CRYPTO_NONCE_SIZE) {
|
||||
@@ -574,7 +574,7 @@ static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *pac
|
||||
change_symmetric_key(onion);
|
||||
|
||||
uint8_t plain[SIZE_IPPORT + RETURN_2];
|
||||
const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
|
||||
const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
|
||||
SIZE_IPPORT + RETURN_2 + CRYPTO_MAC_SIZE, plain);
|
||||
|
||||
if ((uint32_t)len != sizeof(plain)) {
|
||||
@@ -627,7 +627,7 @@ static int handle_recv_2(void *object, const IP_Port *source, const uint8_t *pac
|
||||
change_symmetric_key(onion);
|
||||
|
||||
uint8_t plain[SIZE_IPPORT + RETURN_1];
|
||||
const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
|
||||
const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
|
||||
SIZE_IPPORT + RETURN_1 + CRYPTO_MAC_SIZE, plain);
|
||||
|
||||
if ((uint32_t)len != sizeof(plain)) {
|
||||
@@ -679,7 +679,7 @@ static int handle_recv_1(void *object, const IP_Port *source, const uint8_t *pac
|
||||
change_symmetric_key(onion);
|
||||
|
||||
uint8_t plain[SIZE_IPPORT];
|
||||
const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
|
||||
const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
|
||||
SIZE_IPPORT + CRYPTO_MAC_SIZE, plain);
|
||||
|
||||
if ((uint32_t)len != SIZE_IPPORT) {
|
||||
|
4
external/toxcore/c-toxcore/toxcore/onion.h
vendored
4
external/toxcore/c-toxcore/toxcore/onion.h
vendored
@@ -105,7 +105,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
|
||||
* return length of created packet on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
int create_onion_packet(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *data, uint16_t length);
|
||||
|
||||
@@ -119,7 +119,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
|
||||
* return length of created packet on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
int create_onion_packet_tcp(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *data, uint16_t length);
|
||||
|
||||
|
135
external/toxcore/c-toxcore/toxcore/onion_announce.c
vendored
135
external/toxcore/c-toxcore/toxcore/onion_announce.c
vendored
@@ -9,7 +9,6 @@
|
||||
#include "onion_announce.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "DHT.h"
|
||||
@@ -23,6 +22,7 @@
|
||||
#include "network.h"
|
||||
#include "onion.h"
|
||||
#include "shared_key_cache.h"
|
||||
#include "sort.h"
|
||||
#include "timed_auth.h"
|
||||
|
||||
#define PING_ID_TIMEOUT ONION_ANNOUNCE_TIMEOUT
|
||||
@@ -103,7 +103,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint
|
||||
* return -1 on failure.
|
||||
* return packet length on success.
|
||||
*/
|
||||
int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
int create_announce_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
|
||||
const uint8_t *data_public_key, uint64_t sendback_data)
|
||||
{
|
||||
@@ -122,7 +122,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac
|
||||
packet[0] = NET_PACKET_ANNOUNCE_REQUEST_OLD;
|
||||
random_nonce(rng, packet + 1);
|
||||
|
||||
const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, sizeof(plain),
|
||||
const int len = encrypt_data(mem, dest_client_id, secret_key, packet + 1, plain, sizeof(plain),
|
||||
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
if ((uint32_t)len + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE != ONION_ANNOUNCE_REQUEST_MIN_SIZE) {
|
||||
@@ -146,7 +146,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
|
||||
int create_data_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
|
||||
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (DATA_REQUEST_MIN_SIZE + length > max_packet_length) {
|
||||
@@ -167,7 +167,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
|
||||
|
||||
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, random_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
const int len = encrypt_data(encrypt_public_key, random_secret_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length,
|
||||
const int len = encrypt_data(mem, encrypt_public_key, random_secret_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
if (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + len != DATA_REQUEST_MIN_SIZE +
|
||||
@@ -193,14 +193,14 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
|
||||
* return 0 on success.
|
||||
*/
|
||||
int send_announce_request(
|
||||
const Logger *log, const Networking_Core *net, const Random *rng,
|
||||
const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng,
|
||||
const Onion_Path *path, const Node_format *dest,
|
||||
const uint8_t *public_key, const uint8_t *secret_key,
|
||||
const uint8_t *ping_id, const uint8_t *client_id,
|
||||
const uint8_t *data_public_key, uint64_t sendback_data)
|
||||
{
|
||||
uint8_t request[ONION_ANNOUNCE_REQUEST_MIN_SIZE];
|
||||
int len = create_announce_request(rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id,
|
||||
int len = create_announce_request(mem, rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id,
|
||||
client_id, data_public_key, sendback_data);
|
||||
|
||||
if (len != sizeof(request)) {
|
||||
@@ -208,7 +208,7 @@ int send_announce_request(
|
||||
}
|
||||
|
||||
uint8_t packet[ONION_MAX_PACKET_SIZE];
|
||||
len = create_onion_packet(rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request));
|
||||
len = create_onion_packet(mem, rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request));
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
@@ -238,19 +238,19 @@ int send_announce_request(
|
||||
* return 0 on success.
|
||||
*/
|
||||
int send_data_request(
|
||||
const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
|
||||
const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
|
||||
const uint8_t *data, uint16_t length)
|
||||
{
|
||||
uint8_t request[ONION_MAX_DATA_SIZE];
|
||||
int len = create_data_request(rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length);
|
||||
int len = create_data_request(mem, rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t packet[ONION_MAX_PACKET_SIZE];
|
||||
len = create_onion_packet(rng, packet, sizeof(packet), path, dest, request, len);
|
||||
len = create_onion_packet(mem, rng, packet, sizeof(packet), path, dest, request, len);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
@@ -281,23 +281,17 @@ static int in_entries(const Onion_Announce *onion_a, const uint8_t *public_key)
|
||||
return -1;
|
||||
}
|
||||
|
||||
typedef struct Cmp_Data {
|
||||
typedef struct Onion_Announce_Entry_Cmp {
|
||||
const Memory *mem;
|
||||
const Mono_Time *mono_time;
|
||||
const uint8_t *base_public_key;
|
||||
Onion_Announce_Entry entry;
|
||||
} Cmp_Data;
|
||||
const uint8_t *comp_public_key;
|
||||
} Onion_Announce_Entry_Cmp;
|
||||
|
||||
non_null()
|
||||
static int cmp_entry(const void *a, const void *b)
|
||||
static int onion_announce_entry_cmp(const Onion_Announce_Entry_Cmp *cmp, const Onion_Announce_Entry *entry1, const Onion_Announce_Entry *entry2)
|
||||
{
|
||||
const Cmp_Data *cmp1 = (const Cmp_Data *)a;
|
||||
const Cmp_Data *cmp2 = (const Cmp_Data *)b;
|
||||
const Onion_Announce_Entry entry1 = cmp1->entry;
|
||||
const Onion_Announce_Entry entry2 = cmp2->entry;
|
||||
const uint8_t *cmp_public_key = cmp1->base_public_key;
|
||||
|
||||
const bool t1 = mono_time_is_timeout(cmp1->mono_time, entry1.announce_time, ONION_ANNOUNCE_TIMEOUT);
|
||||
const bool t2 = mono_time_is_timeout(cmp1->mono_time, entry2.announce_time, ONION_ANNOUNCE_TIMEOUT);
|
||||
const bool t1 = mono_time_is_timeout(cmp->mono_time, entry1->announce_time, ONION_ANNOUNCE_TIMEOUT);
|
||||
const bool t2 = mono_time_is_timeout(cmp->mono_time, entry2->announce_time, ONION_ANNOUNCE_TIMEOUT);
|
||||
|
||||
if (t1 && t2) {
|
||||
return 0;
|
||||
@@ -311,7 +305,7 @@ static int cmp_entry(const void *a, const void *b)
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
|
||||
const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key);
|
||||
|
||||
if (closest == 1) {
|
||||
return 1;
|
||||
@@ -324,32 +318,81 @@ static int cmp_entry(const void *a, const void *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool onion_announce_entry_less_handler(const void *object, const void *a, const void *b)
|
||||
{
|
||||
const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object;
|
||||
const Onion_Announce_Entry *entry1 = (const Onion_Announce_Entry *)a;
|
||||
const Onion_Announce_Entry *entry2 = (const Onion_Announce_Entry *)b;
|
||||
|
||||
return onion_announce_entry_cmp(cmp, entry1, entry2) < 0;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static const void *onion_announce_entry_get_handler(const void *arr, uint32_t index)
|
||||
{
|
||||
const Onion_Announce_Entry *entries = (const Onion_Announce_Entry *)arr;
|
||||
return &entries[index];
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void onion_announce_entry_set_handler(void *arr, uint32_t index, const void *val)
|
||||
{
|
||||
Onion_Announce_Entry *entries = (Onion_Announce_Entry *)arr;
|
||||
const Onion_Announce_Entry *entry = (const Onion_Announce_Entry *)val;
|
||||
entries[index] = *entry;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void *onion_announce_entry_subarr_handler(void *arr, uint32_t index, uint32_t size)
|
||||
{
|
||||
Onion_Announce_Entry *entries = (Onion_Announce_Entry *)arr;
|
||||
return &entries[index];
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void *onion_announce_entry_alloc_handler(const void *object, uint32_t size)
|
||||
{
|
||||
const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object;
|
||||
Onion_Announce_Entry *tmp = (Onion_Announce_Entry *)mem_valloc(cmp->mem, size, sizeof(Onion_Announce_Entry));
|
||||
|
||||
if (tmp == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void onion_announce_entry_delete_handler(const void *object, void *arr, uint32_t size)
|
||||
{
|
||||
const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object;
|
||||
mem_delete(cmp->mem, arr);
|
||||
}
|
||||
|
||||
static const Sort_Funcs onion_announce_entry_cmp_funcs = {
|
||||
onion_announce_entry_less_handler,
|
||||
onion_announce_entry_get_handler,
|
||||
onion_announce_entry_set_handler,
|
||||
onion_announce_entry_subarr_handler,
|
||||
onion_announce_entry_alloc_handler,
|
||||
onion_announce_entry_delete_handler,
|
||||
};
|
||||
|
||||
non_null()
|
||||
static void sort_onion_announce_list(const Memory *mem, const Mono_Time *mono_time,
|
||||
Onion_Announce_Entry *list, unsigned int length,
|
||||
const uint8_t *comp_public_key)
|
||||
{
|
||||
// Pass comp_public_key to qsort with each Client_data entry, so the
|
||||
// Pass comp_public_key to sort with each Onion_Announce_Entry entry, so the
|
||||
// comparison function can use it as the base of comparison.
|
||||
Cmp_Data *cmp_list = (Cmp_Data *)mem_valloc(mem, length, sizeof(Cmp_Data));
|
||||
const Onion_Announce_Entry_Cmp cmp = {
|
||||
mem,
|
||||
mono_time,
|
||||
comp_public_key,
|
||||
};
|
||||
|
||||
if (cmp_list == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
cmp_list[i].mono_time = mono_time;
|
||||
cmp_list[i].base_public_key = comp_public_key;
|
||||
cmp_list[i].entry = list[i];
|
||||
}
|
||||
|
||||
qsort(cmp_list, length, sizeof(Cmp_Data), cmp_entry);
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
list[i] = cmp_list[i].entry;
|
||||
}
|
||||
|
||||
mem_delete(mem, cmp_list);
|
||||
merge_sort(list, length, &cmp, &onion_announce_entry_cmp_funcs);
|
||||
}
|
||||
|
||||
/** @brief add entry to entries list
|
||||
@@ -455,7 +498,7 @@ static int handle_announce_request_common(
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int decrypted_len = decrypt_data_symmetric(shared_key, packet + 1,
|
||||
const int decrypted_len = decrypt_data_symmetric(onion_a->mem, shared_key, packet + 1,
|
||||
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, plain_size + CRYPTO_MAC_SIZE, plain);
|
||||
|
||||
if ((uint32_t)decrypted_len != plain_size) {
|
||||
@@ -542,7 +585,7 @@ static int handle_announce_request_common(
|
||||
offset += extra_size;
|
||||
|
||||
uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE];
|
||||
const int len = encrypt_data_symmetric(shared_key, nonce, response, offset,
|
||||
const int len = encrypt_data_symmetric(onion_a->mem, shared_key, nonce, response, offset,
|
||||
data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != offset + CRYPTO_MAC_SIZE) {
|
||||
|
@@ -65,7 +65,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint
|
||||
* return packet length on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
int create_announce_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
|
||||
const uint8_t *data_public_key, uint64_t sendback_data);
|
||||
|
||||
@@ -82,7 +82,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac
|
||||
* return 0 on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
|
||||
int create_data_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
|
||||
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length);
|
||||
|
||||
/** @brief Create and send an onion announce request packet.
|
||||
@@ -101,7 +101,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
|
||||
*/
|
||||
non_null()
|
||||
int send_announce_request(
|
||||
const Logger *log, const Networking_Core *net, const Random *rng,
|
||||
const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng,
|
||||
const Onion_Path *path, const Node_format *dest,
|
||||
const uint8_t *public_key, const uint8_t *secret_key,
|
||||
const uint8_t *ping_id, const uint8_t *client_id,
|
||||
@@ -125,7 +125,7 @@ int send_announce_request(
|
||||
*/
|
||||
non_null()
|
||||
int send_data_request(
|
||||
const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
|
||||
const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
|
||||
const uint8_t *data, uint16_t length);
|
||||
|
||||
|
143
external/toxcore/c-toxcore/toxcore/onion_client.c
vendored
143
external/toxcore/c-toxcore/toxcore/onion_client.c
vendored
@@ -10,7 +10,6 @@
|
||||
#include "onion_client.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "DHT.h"
|
||||
@@ -29,6 +28,7 @@
|
||||
#include "onion.h"
|
||||
#include "onion_announce.h"
|
||||
#include "ping_array.h"
|
||||
#include "sort.h"
|
||||
#include "timed_auth.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -528,7 +528,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
|
||||
{
|
||||
if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) {
|
||||
uint8_t packet[ONION_MAX_PACKET_SIZE];
|
||||
const int len = create_onion_packet(onion_c->rng, packet, sizeof(packet), path, dest, data, length);
|
||||
const int len = create_onion_packet(onion_c->mem, onion_c->rng, packet, sizeof(packet), path, dest, data, length);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
@@ -545,7 +545,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
|
||||
|
||||
if (ip_port_to_tcp_connections_number(&path->ip_port1, &tcp_connections_number)) {
|
||||
uint8_t packet[ONION_MAX_PACKET_SIZE];
|
||||
const int len = create_onion_packet_tcp(onion_c->rng, packet, sizeof(packet), path, dest, data, length);
|
||||
const int len = create_onion_packet_tcp(onion_c->mem, onion_c->rng, packet, sizeof(packet), path, dest, data, length);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
@@ -661,7 +661,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
|
||||
|
||||
if (num == 0) {
|
||||
len = create_announce_request(
|
||||
onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c),
|
||||
onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c),
|
||||
nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c),
|
||||
onion_c->temp_public_key, sendback);
|
||||
} else {
|
||||
@@ -669,14 +669,14 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
|
||||
|
||||
if (onion_friend->gc_data_length == 0) { // contact is a friend
|
||||
len = create_announce_request(
|
||||
onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
|
||||
onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
|
||||
onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key,
|
||||
zero_ping_id, sendback);
|
||||
} else { // contact is a gc
|
||||
onion_friend->is_groupchat = true;
|
||||
|
||||
len = create_gca_announce_request(
|
||||
onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
|
||||
onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
|
||||
onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key,
|
||||
zero_ping_id, sendback, onion_friend->gc_data,
|
||||
onion_friend->gc_data_length);
|
||||
@@ -694,23 +694,17 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
|
||||
return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len);
|
||||
}
|
||||
|
||||
typedef struct Onion_Client_Cmp_Data {
|
||||
typedef struct Onion_Node_Cmp {
|
||||
const Memory *mem;
|
||||
const Mono_Time *mono_time;
|
||||
const uint8_t *base_public_key;
|
||||
Onion_Node entry;
|
||||
} Onion_Client_Cmp_Data;
|
||||
const uint8_t *comp_public_key;
|
||||
} Onion_Node_Cmp;
|
||||
|
||||
non_null()
|
||||
static int onion_client_cmp_entry(const void *a, const void *b)
|
||||
static int onion_node_cmp(const Onion_Node_Cmp *cmp, const Onion_Node *entry1, const Onion_Node *entry2)
|
||||
{
|
||||
const Onion_Client_Cmp_Data *cmp1 = (const Onion_Client_Cmp_Data *)a;
|
||||
const Onion_Client_Cmp_Data *cmp2 = (const Onion_Client_Cmp_Data *)b;
|
||||
const Onion_Node entry1 = cmp1->entry;
|
||||
const Onion_Node entry2 = cmp2->entry;
|
||||
const uint8_t *cmp_public_key = cmp1->base_public_key;
|
||||
|
||||
const bool t1 = onion_node_timed_out(&entry1, cmp1->mono_time);
|
||||
const bool t2 = onion_node_timed_out(&entry2, cmp2->mono_time);
|
||||
const bool t1 = onion_node_timed_out(entry1, cmp->mono_time);
|
||||
const bool t2 = onion_node_timed_out(entry2, cmp->mono_time);
|
||||
|
||||
if (t1 && t2) {
|
||||
return 0;
|
||||
@@ -724,7 +718,7 @@ static int onion_client_cmp_entry(const void *a, const void *b)
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
|
||||
const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key);
|
||||
|
||||
if (closest == 1) {
|
||||
return 1;
|
||||
@@ -737,31 +731,80 @@ static int onion_client_cmp_entry(const void *a, const void *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool onion_node_less_handler(const void *object, const void *a, const void *b)
|
||||
{
|
||||
const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object;
|
||||
const Onion_Node *entry1 = (const Onion_Node *)a;
|
||||
const Onion_Node *entry2 = (const Onion_Node *)b;
|
||||
|
||||
return onion_node_cmp(cmp, entry1, entry2) < 0;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static const void *onion_node_get_handler(const void *arr, uint32_t index)
|
||||
{
|
||||
const Onion_Node *entries = (const Onion_Node *)arr;
|
||||
return &entries[index];
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void onion_node_set_handler(void *arr, uint32_t index, const void *val)
|
||||
{
|
||||
Onion_Node *entries = (Onion_Node *)arr;
|
||||
const Onion_Node *entry = (const Onion_Node *)val;
|
||||
entries[index] = *entry;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void *onion_node_subarr_handler(void *arr, uint32_t index, uint32_t size)
|
||||
{
|
||||
Onion_Node *entries = (Onion_Node *)arr;
|
||||
return &entries[index];
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void *onion_node_alloc_handler(const void *object, uint32_t size)
|
||||
{
|
||||
const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object;
|
||||
Onion_Node *tmp = (Onion_Node *)mem_valloc(cmp->mem, size, sizeof(Onion_Node));
|
||||
|
||||
if (tmp == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void onion_node_delete_handler(const void *object, void *arr, uint32_t size)
|
||||
{
|
||||
const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object;
|
||||
mem_delete(cmp->mem, arr);
|
||||
}
|
||||
|
||||
static const Sort_Funcs onion_node_cmp_funcs = {
|
||||
onion_node_less_handler,
|
||||
onion_node_get_handler,
|
||||
onion_node_set_handler,
|
||||
onion_node_subarr_handler,
|
||||
onion_node_alloc_handler,
|
||||
onion_node_delete_handler,
|
||||
};
|
||||
|
||||
non_null()
|
||||
static void sort_onion_node_list(const Memory *mem, const Mono_Time *mono_time,
|
||||
Onion_Node *list, unsigned int length, const uint8_t *comp_public_key)
|
||||
{
|
||||
// Pass comp_public_key to qsort with each Client_data entry, so the
|
||||
// Pass comp_public_key to sort with each Onion_Node entry, so the
|
||||
// comparison function can use it as the base of comparison.
|
||||
Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)mem_valloc(mem, length, sizeof(Onion_Client_Cmp_Data));
|
||||
const Onion_Node_Cmp cmp = {
|
||||
mem,
|
||||
mono_time,
|
||||
comp_public_key,
|
||||
};
|
||||
|
||||
if (cmp_list == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
cmp_list[i].mono_time = mono_time;
|
||||
cmp_list[i].base_public_key = comp_public_key;
|
||||
cmp_list[i].entry = list[i];
|
||||
}
|
||||
|
||||
qsort(cmp_list, length, sizeof(Onion_Client_Cmp_Data), onion_client_cmp_entry);
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
list[i] = cmp_list[i].entry;
|
||||
}
|
||||
|
||||
mem_delete(mem, cmp_list);
|
||||
merge_sort(list, length, &cmp, &onion_node_cmp_funcs);
|
||||
}
|
||||
|
||||
non_null()
|
||||
@@ -962,7 +1005,7 @@ static int handle_announce_response(void *object, const IP_Port *source, const u
|
||||
const uint16_t ciphertext_size = length - ciphertext_start;
|
||||
|
||||
if (num == 0) {
|
||||
len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
|
||||
len = decrypt_data(onion_c->mem, public_key, nc_get_self_secret_key(onion_c->c),
|
||||
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
|
||||
} else {
|
||||
if (!onion_c->friends_list[num - 1].is_valid) {
|
||||
@@ -970,7 +1013,7 @@ static int handle_announce_response(void *object, const IP_Port *source, const u
|
||||
return 1;
|
||||
}
|
||||
|
||||
len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
|
||||
len = decrypt_data(onion_c->mem, public_key, onion_c->friends_list[num - 1].temp_secret_key,
|
||||
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
|
||||
}
|
||||
|
||||
@@ -1066,7 +1109,7 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con
|
||||
const uint16_t ciphertext_size = length - ciphertext_start;
|
||||
|
||||
if (num == 0) {
|
||||
len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
|
||||
len = decrypt_data(onion_c->mem, public_key, nc_get_self_secret_key(onion_c->c),
|
||||
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
|
||||
} else {
|
||||
if (!onion_c->friends_list[num - 1].is_valid) {
|
||||
@@ -1074,7 +1117,7 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con
|
||||
return 1;
|
||||
}
|
||||
|
||||
len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
|
||||
len = decrypt_data(onion_c->mem, public_key, onion_c->friends_list[num - 1].temp_secret_key,
|
||||
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
|
||||
}
|
||||
|
||||
@@ -1136,7 +1179,7 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8
|
||||
|
||||
const uint16_t temp_plain_size = length - ONION_DATA_RESPONSE_MIN_SIZE;
|
||||
VLA(uint8_t, temp_plain, temp_plain_size);
|
||||
int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1,
|
||||
int len = decrypt_data(onion_c->mem, packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1,
|
||||
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), temp_plain);
|
||||
|
||||
@@ -1146,7 +1189,7 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8
|
||||
|
||||
const uint16_t plain_size = temp_plain_size - DATA_IN_RESPONSE_MIN_SIZE;
|
||||
VLA(uint8_t, plain, plain_size);
|
||||
len = decrypt_data(temp_plain, nc_get_self_secret_key(onion_c->c),
|
||||
len = decrypt_data(onion_c->mem, temp_plain, nc_get_self_secret_key(onion_c->c),
|
||||
packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
temp_plain_size - CRYPTO_PUBLIC_KEY_SIZE, plain);
|
||||
|
||||
@@ -1305,7 +1348,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
|
||||
const uint16_t packet_size = DATA_IN_RESPONSE_MIN_SIZE + length;
|
||||
VLA(uint8_t, packet, packet_size);
|
||||
memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key,
|
||||
int len = encrypt_data(onion_c->mem, onion_c->friends_list[friend_num].real_public_key,
|
||||
nc_get_self_secret_key(onion_c->c), nonce, data,
|
||||
length, packet + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
@@ -1324,7 +1367,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
|
||||
|
||||
uint8_t o_packet[ONION_MAX_PACKET_SIZE];
|
||||
len = create_data_request(
|
||||
onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key,
|
||||
onion_c->mem, onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key,
|
||||
node_list[good_nodes[i]].data_public_key, nonce, packet, packet_size);
|
||||
|
||||
if (len == -1) {
|
||||
@@ -1364,7 +1407,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin
|
||||
VLA(uint8_t, temp, temp_size);
|
||||
memcpy(temp, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(temp + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
|
||||
int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key,
|
||||
int len = encrypt_data(onion_c->mem, onion_c->friends_list[friend_num].real_public_key,
|
||||
nc_get_self_secret_key(onion_c->c), nonce, data,
|
||||
length, temp + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
|
||||
|
||||
@@ -1374,7 +1417,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin
|
||||
|
||||
uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE];
|
||||
len = create_request(
|
||||
onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data,
|
||||
onion_c->mem, onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data,
|
||||
onion_c->friends_list[friend_num].dht_public_key, temp, temp_size, CRYPTO_PACKET_DHTPK);
|
||||
assert(len <= UINT16_MAX);
|
||||
const Packet packet = {packet_data, (uint16_t)len};
|
||||
@@ -1401,7 +1444,7 @@ static int handle_dht_dhtpk(void *object, const IP_Port *source, const uint8_t *
|
||||
}
|
||||
|
||||
uint8_t plain[DHTPK_DATA_MAX_LENGTH];
|
||||
const int len = decrypt_data(packet, nc_get_self_secret_key(onion_c->c),
|
||||
const int len = decrypt_data(onion_c->mem, packet, nc_get_self_secret_key(onion_c->c),
|
||||
packet + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
|
||||
length - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), plain);
|
||||
|
@@ -183,6 +183,8 @@ non_null()
|
||||
unsigned int onion_getfriend_dht_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
|
||||
|
||||
#define ONION_DATA_IN_RESPONSE_MIN_SIZE (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)
|
||||
|
||||
// TODO(Jfreegman): This is not the correct value; data this large will be dropped by the onion client.
|
||||
#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
|
||||
|
||||
/** @brief Send data of length length to friendnum.
|
||||
|
10
external/toxcore/c-toxcore/toxcore/ping.c
vendored
10
external/toxcore/c-toxcore/toxcore/ping.c
vendored
@@ -31,6 +31,7 @@
|
||||
struct Ping {
|
||||
const Mono_Time *mono_time;
|
||||
const Random *rng;
|
||||
const Memory *mem;
|
||||
DHT *dht;
|
||||
|
||||
Ping_Array *ping_array;
|
||||
@@ -72,7 +73,7 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key
|
||||
pk_copy(pk + 1, dht_get_self_public_key(ping->dht)); // Our pubkey
|
||||
random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
|
||||
|
||||
rc = encrypt_data_symmetric(shared_key,
|
||||
rc = encrypt_data_symmetric(ping->mem, shared_key,
|
||||
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
ping_plain, sizeof(ping_plain),
|
||||
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
|
||||
@@ -104,7 +105,7 @@ static int ping_send_response(const Ping *ping, const IP_Port *ipp, const uint8_
|
||||
random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
|
||||
|
||||
// Encrypt ping_id using recipient privkey
|
||||
const int rc = encrypt_data_symmetric(shared_encryption_key,
|
||||
const int rc = encrypt_data_symmetric(ping->mem, shared_encryption_key,
|
||||
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
ping_plain, sizeof(ping_plain),
|
||||
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
|
||||
@@ -137,7 +138,7 @@ static int handle_ping_request(void *object, const IP_Port *source, const uint8_
|
||||
uint8_t ping_plain[PING_PLAIN_SIZE];
|
||||
|
||||
// Decrypt ping_id
|
||||
const int rc = decrypt_data_symmetric(shared_key,
|
||||
const int rc = decrypt_data_symmetric(ping->mem, shared_key,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
|
||||
PING_PLAIN_SIZE + CRYPTO_MAC_SIZE,
|
||||
@@ -182,7 +183,7 @@ static int handle_ping_response(void *object, const IP_Port *source, const uint8
|
||||
|
||||
uint8_t ping_plain[PING_PLAIN_SIZE];
|
||||
// Decrypt ping_id
|
||||
rc = decrypt_data_symmetric(shared_key,
|
||||
rc = decrypt_data_symmetric(ping->mem, shared_key,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
|
||||
PING_PLAIN_SIZE + CRYPTO_MAC_SIZE,
|
||||
@@ -348,6 +349,7 @@ Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng,
|
||||
|
||||
ping->mono_time = mono_time;
|
||||
ping->rng = rng;
|
||||
ping->mem = mem;
|
||||
ping->dht = dht;
|
||||
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
|
||||
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);
|
||||
|
182
external/toxcore/c-toxcore/toxcore/sort.c
vendored
Normal file
182
external/toxcore/c-toxcore/toxcore/sort.c
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2023-2024 The TokTok team.
|
||||
*/
|
||||
|
||||
#include "sort.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "ccompat.h"
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
* @brief Threshold for when to switch to insertion sort.
|
||||
*
|
||||
* This is a trade-off between the complexity of insertion sort and the
|
||||
* overhead of merge sort. The threshold is chosen to be the smallest value
|
||||
* that gives a measurable speedup for insertion sort over merge sort. This is
|
||||
* based on measurements done in sort_bench.cc. Starting from 32 elements,
|
||||
* merge sort is faster than insertion sort in all our tests (both unsorted
|
||||
* and mostly-sorted).
|
||||
*
|
||||
* Toxcore has a lot of small arrays it wants to sort, so this optimisation
|
||||
* makes sense.
|
||||
*/
|
||||
#define SMALL_ARRAY_THRESHOLD 16
|
||||
|
||||
non_null()
|
||||
static void merge_sort_merge_back(
|
||||
void *arr,
|
||||
const void *l_arr, uint32_t l_arr_size,
|
||||
const void *r_arr, uint32_t r_arr_size,
|
||||
uint32_t left_start,
|
||||
const void *object, const Sort_Funcs *funcs)
|
||||
{
|
||||
uint32_t li = 0;
|
||||
uint32_t ri = 0;
|
||||
uint32_t k = left_start;
|
||||
|
||||
while (li < l_arr_size && ri < r_arr_size) {
|
||||
const void *l = funcs->get_callback(l_arr, li);
|
||||
const void *r = funcs->get_callback(r_arr, ri);
|
||||
// !(r < l) <=> (r >= l) <=> (l <= r)
|
||||
if (!funcs->less_callback(object, r, l)) {
|
||||
funcs->set_callback(arr, k, l);
|
||||
++li;
|
||||
} else {
|
||||
funcs->set_callback(arr, k, r);
|
||||
++ri;
|
||||
}
|
||||
++k;
|
||||
}
|
||||
|
||||
/* Copy the remaining elements of `l_arr[]`, if there are any. */
|
||||
while (li < l_arr_size) {
|
||||
funcs->set_callback(arr, k, funcs->get_callback(l_arr, li));
|
||||
++li;
|
||||
++k;
|
||||
}
|
||||
|
||||
/* Copy the remaining elements of `r_arr[]`, if there are any. */
|
||||
while (ri < r_arr_size) {
|
||||
funcs->set_callback(arr, k, funcs->get_callback(r_arr, ri));
|
||||
++ri;
|
||||
++k;
|
||||
}
|
||||
}
|
||||
|
||||
/** Function to merge the two haves `arr[left_start..mid]` and `arr[mid+1..right_end]` of array `arr[]`. */
|
||||
non_null()
|
||||
static void merge_sort_merge(
|
||||
void *arr, uint32_t left_start, uint32_t mid, uint32_t right_end, void *tmp,
|
||||
const void *object, const Sort_Funcs *funcs)
|
||||
{
|
||||
const uint32_t l_arr_size = mid - left_start + 1;
|
||||
const uint32_t r_arr_size = right_end - mid;
|
||||
|
||||
/* Temporary arrays, using the tmp buffer created in `merge_sort` below. */
|
||||
void *l_arr = funcs->subarr_callback(tmp, 0, l_arr_size);
|
||||
void *r_arr = funcs->subarr_callback(tmp, l_arr_size, r_arr_size);
|
||||
|
||||
/* Copy data to temp arrays `l_arr[]` and `r_arr[]`.
|
||||
*
|
||||
* This is iterating and repeatedly calling `get` and `set`, which sounds
|
||||
* slow, but is only marginally slower than having a `copy` callback. With
|
||||
* a `copy` callback, we'd save 3-4% in time.
|
||||
*/
|
||||
for (uint32_t i = 0; i < l_arr_size; ++i) {
|
||||
funcs->set_callback(l_arr, i, funcs->get_callback(arr, left_start + i));
|
||||
}
|
||||
for (uint32_t i = 0; i < r_arr_size; ++i) {
|
||||
funcs->set_callback(r_arr, i, funcs->get_callback(arr, mid + 1 + i));
|
||||
}
|
||||
|
||||
/* Merge the temp arrays back into `arr[left_start..right_end]`. */
|
||||
merge_sort_merge_back(arr, l_arr, l_arr_size, r_arr, r_arr_size, left_start, object, funcs);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void insertion_sort_step(void *arr, void *tmp, uint32_t i, const void *object, const Sort_Funcs *funcs)
|
||||
{
|
||||
funcs->set_callback(tmp, 0, funcs->get_callback(arr, i));
|
||||
uint32_t j = i;
|
||||
|
||||
while (j > 0) {
|
||||
if (!funcs->less_callback(object, tmp, funcs->get_callback(arr, j - 1))) {
|
||||
break;
|
||||
}
|
||||
funcs->set_callback(arr, j, funcs->get_callback(arr, j - 1));
|
||||
--j;
|
||||
}
|
||||
|
||||
funcs->set_callback(arr, j, tmp);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void insertion_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs)
|
||||
{
|
||||
for (uint32_t i = 1; i < arr_size; ++i) {
|
||||
insertion_sort_step(arr, tmp, i, object, funcs);
|
||||
}
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool insertion_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs)
|
||||
{
|
||||
void *tmp = funcs->alloc_callback(object, 1);
|
||||
|
||||
if (tmp == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
insertion_sort_with_buf(arr, arr_size, tmp, 1, object, funcs);
|
||||
|
||||
funcs->delete_callback(object, tmp, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void merge_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs)
|
||||
{
|
||||
assert(tmp_size >= arr_size);
|
||||
|
||||
if (arr_size <= SMALL_ARRAY_THRESHOLD) {
|
||||
assert(tmp_size >= 1);
|
||||
insertion_sort_with_buf(arr, arr_size, tmp, tmp_size, object, funcs);
|
||||
return;
|
||||
}
|
||||
|
||||
// Merge subarrays in bottom up manner. First merge subarrays of
|
||||
// size 1 to create sorted subarrays of size 2, then merge subarrays
|
||||
// of size 2 to create sorted subarrays of size 4, and so on.
|
||||
for (uint32_t curr_size = 1; curr_size <= arr_size - 1; curr_size = 2 * curr_size) {
|
||||
// Pick starting point of different subarrays of current size
|
||||
for (uint32_t left_start = 0; left_start < arr_size - 1; left_start += 2 * curr_size) {
|
||||
// Find ending point of left subarray. mid+1 is starting
|
||||
// point of right
|
||||
const uint32_t mid = min_u32(left_start + curr_size - 1, arr_size - 1);
|
||||
const uint32_t right_end = min_u32(left_start + 2 * curr_size - 1, arr_size - 1);
|
||||
|
||||
// Merge Subarrays arr[left_start...mid] & arr[mid+1...right_end]
|
||||
merge_sort_merge(arr, left_start, mid, right_end, tmp, object, funcs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool merge_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs)
|
||||
{
|
||||
if (arr_size <= SMALL_ARRAY_THRESHOLD) {
|
||||
return insertion_sort(arr, arr_size, object, funcs);
|
||||
}
|
||||
|
||||
void *tmp = funcs->alloc_callback(object, arr_size);
|
||||
|
||||
if (tmp == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
merge_sort_with_buf(arr, arr_size, tmp, arr_size, object, funcs);
|
||||
|
||||
funcs->delete_callback(object, tmp, arr_size);
|
||||
return true;
|
||||
}
|
116
external/toxcore/c-toxcore/toxcore/sort.h
vendored
Normal file
116
external/toxcore/c-toxcore/toxcore/sort.h
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2023-2024 The TokTok team.
|
||||
*/
|
||||
|
||||
#ifndef C_TOXCORE_TOXCORE_SORT_H
|
||||
#define C_TOXCORE_TOXCORE_SORT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "attributes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @brief Compare elements with a less-than ordering: `a < b`. */
|
||||
typedef bool sort_less_cb(const void *object, const void *a, const void *b);
|
||||
/** @brief Get element from array at index. */
|
||||
typedef const void *sort_get_cb(const void *arr, uint32_t index);
|
||||
/** @brief Set element in array at index to new value (perform copy). */
|
||||
typedef void sort_set_cb(void *arr, uint32_t index, const void *val);
|
||||
/** @brief Get a sub-array at an index of a given size (mutable pointer).
|
||||
*
|
||||
* Used to index in the temporary array allocated by `sort_alloc_cb` and get
|
||||
* a sub-array for working memory.
|
||||
*/
|
||||
typedef void *sort_subarr_cb(void *arr, uint32_t index, uint32_t size);
|
||||
/** @brief Allocate a new array of the element type.
|
||||
*
|
||||
* @param size The array size in elements of type T (not byte size). This value
|
||||
* is always exactly the input array size as passed to `merge_sort`.
|
||||
*/
|
||||
typedef void *sort_alloc_cb(const void *object, uint32_t size);
|
||||
/** @brief Free the element type array. */
|
||||
typedef void sort_delete_cb(const void *object, void *arr, uint32_t size);
|
||||
|
||||
/** @brief Virtual function table for getting/setting elements in an array and
|
||||
* comparing them.
|
||||
*
|
||||
* Only the `less`, `alloc`, and `delete` functions get a `this`-pointer. We
|
||||
* assume that indexing in an array doesn't need any other information than the
|
||||
* array itself.
|
||||
*
|
||||
* For now, the `this`-pointer is const, because we assume sorting doesn't need
|
||||
* to mutate any state, but if necessary that can be changed in the future.
|
||||
*/
|
||||
typedef struct Sort_Funcs {
|
||||
sort_less_cb *less_callback;
|
||||
sort_get_cb *get_callback;
|
||||
sort_set_cb *set_callback;
|
||||
sort_subarr_cb *subarr_callback;
|
||||
sort_alloc_cb *alloc_callback;
|
||||
sort_delete_cb *delete_callback;
|
||||
} Sort_Funcs;
|
||||
|
||||
/** @brief Non-recursive merge sort function to sort `arr[0...arr_size-1]`.
|
||||
*
|
||||
* Avoids `memcpy` and avoids treating elements as byte arrays. Instead, uses
|
||||
* callbacks to index in arrays and copy elements. This makes it quite a bit
|
||||
* slower than `qsort`, but works with elements that require special care when
|
||||
* being copied (e.g. if they are part of a graph or other data structure that
|
||||
* with pointers or other invariants).
|
||||
*
|
||||
* This function actually uses insertion sort for small arrays (up to 16
|
||||
* elements), which is faster than merge sort for small arrays, especially
|
||||
* when mostly sorted (a common use case in toxcore).
|
||||
*
|
||||
* Allocates a single temporary array with the provided alloc callback, and
|
||||
* frees it at the end. This is significantly faster than an in-place
|
||||
* implementation.
|
||||
*
|
||||
* Complexity:
|
||||
* - Space: `O(n) where n = array_size`.
|
||||
* - Time: `O(n * log n) where n = array_size`.
|
||||
*
|
||||
* Compared to `qsort`, this is about 60-70% slower for large arrays. For small
|
||||
* arrays (up to 16 elements), it's about 50% faster than `qsort`.
|
||||
*
|
||||
* @param[in,out] arr An array of type T.
|
||||
* @param arr_size Number of elements in @p arr (count, not byte size).
|
||||
* @param[in] object Comparator object.
|
||||
* @param[in] funcs Callback struct for elements of type T.
|
||||
*/
|
||||
non_null()
|
||||
bool merge_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs);
|
||||
|
||||
/**
|
||||
* @brief Merge sort like above but with a pre-allocated buffer.
|
||||
*
|
||||
* This function is the same as `merge_sort` but uses a pre-allocated buffer
|
||||
* for temporary storage. This can be useful if the caller wants to avoid
|
||||
* dynamic memory allocation.
|
||||
*
|
||||
* This function is 1-2% faster than `merge_sort` for small arrays up to 1000
|
||||
* elements, and about 5-10% faster for large arrays (2000+ elements).
|
||||
*
|
||||
* The main upside is that `alloc` and `delete` callbacks don't need to be
|
||||
* implemented, and the caller can use a stack-allocated buffer.
|
||||
*
|
||||
* @param[in,out] arr An array of type T.
|
||||
* @param arr_size Number of elements in @p arr (count, not byte size).
|
||||
* @param[in,out] tmp A buffer of size `tmp_size` for temporary storage.
|
||||
* @param tmp_size Number of elements in @p tmp (count, not byte size). Must be
|
||||
* at least as large as `arr_size`.
|
||||
* @param[in] object Comparator object.
|
||||
* @param[in] funcs Callback struct for elements of type T.
|
||||
*/
|
||||
non_null()
|
||||
void merge_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* C_TOXCORE_TOXCORE_SORT_H */
|
140
external/toxcore/c-toxcore/toxcore/sort_bench.cc
vendored
Normal file
140
external/toxcore/c-toxcore/toxcore/sort_bench.cc
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2023-2024 The TokTok team.
|
||||
*/
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
|
||||
#include "mem.h"
|
||||
#include "sort.h"
|
||||
#include "sort_test_util.hh"
|
||||
|
||||
namespace {
|
||||
|
||||
std::pair<std::vector<Some_Type>, std::mt19937> random_vec(benchmark::State &state)
|
||||
{
|
||||
std::mt19937 rng;
|
||||
// INT_MAX-1 so later we have room to add 1 larger element if needed.
|
||||
std::uniform_int_distribution<uint32_t> dist{
|
||||
std::numeric_limits<uint32_t>::min(), std::numeric_limits<uint32_t>::max() - 1};
|
||||
|
||||
std::vector<Some_Type> vec(state.range(0));
|
||||
std::generate(std::begin(vec), std::end(vec), [&]() {
|
||||
std::array<uint32_t, 8> compare_value;
|
||||
std::generate(
|
||||
std::begin(compare_value), std::end(compare_value), [&]() { return dist(rng); });
|
||||
return Some_Type{nullptr, compare_value, "hello there"};
|
||||
});
|
||||
|
||||
return {vec, rng};
|
||||
}
|
||||
|
||||
std::vector<Some_Type> mostly_sorted_vec(benchmark::State &state)
|
||||
{
|
||||
auto [vec, rng] = random_vec(state);
|
||||
std::sort(vec.begin(), vec.end());
|
||||
|
||||
// Randomly swap 5% of the vector.
|
||||
std::uniform_int_distribution<std::size_t> dist{0, vec.size() - 1};
|
||||
for (std::size_t i = 0; i < vec.size() / 20; ++i) {
|
||||
const auto a = dist(rng);
|
||||
const auto b = dist(rng);
|
||||
std::swap(vec[a], vec[b]);
|
||||
}
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
void BM_merge_sort(benchmark::State &state)
|
||||
{
|
||||
const auto vec = random_vec(state).first;
|
||||
|
||||
for (auto _ : state) {
|
||||
auto unsorted = vec;
|
||||
merge_sort(unsorted.data(), unsorted.size(), &state, &Some_Type::funcs);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(BM_merge_sort)->RangeMultiplier(2)->Range(8, 8 << 8);
|
||||
|
||||
void BM_merge_sort_with_buf(benchmark::State &state)
|
||||
{
|
||||
const auto vec = random_vec(state).first;
|
||||
std::vector<Some_Type> buf(vec.size());
|
||||
|
||||
for (auto _ : state) {
|
||||
auto unsorted = vec;
|
||||
merge_sort_with_buf(
|
||||
unsorted.data(), unsorted.size(), buf.data(), buf.size(), &state, &Some_Type::funcs);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(BM_merge_sort_with_buf)->RangeMultiplier(2)->Range(8, 8 << 8);
|
||||
|
||||
void BM_merge_sort_mostly_sorted(benchmark::State &state)
|
||||
{
|
||||
auto vec = mostly_sorted_vec(state);
|
||||
|
||||
for (auto _ : state) {
|
||||
auto unsorted = vec;
|
||||
merge_sort(unsorted.data(), unsorted.size(), &state, &Some_Type::funcs);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(BM_merge_sort_mostly_sorted)->RangeMultiplier(2)->Range(8, 8 << 8);
|
||||
|
||||
void BM_qsort(benchmark::State &state)
|
||||
{
|
||||
const auto vec = random_vec(state).first;
|
||||
|
||||
for (auto _ : state) {
|
||||
auto unsorted = vec;
|
||||
qsort(unsorted.data(), unsorted.size(), sizeof(unsorted[0]), my_type_cmp);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(BM_qsort)->RangeMultiplier(2)->Range(8, 8 << 8);
|
||||
|
||||
void BM_qsort_mostly_sorted(benchmark::State &state)
|
||||
{
|
||||
auto vec = mostly_sorted_vec(state);
|
||||
|
||||
for (auto _ : state) {
|
||||
auto unsorted = vec;
|
||||
qsort(unsorted.data(), unsorted.size(), sizeof(unsorted[0]), my_type_cmp);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(BM_qsort_mostly_sorted)->RangeMultiplier(2)->Range(8, 8 << 8);
|
||||
|
||||
void BM_std_sort(benchmark::State &state)
|
||||
{
|
||||
const auto vec = random_vec(state).first;
|
||||
|
||||
for (auto _ : state) {
|
||||
auto unsorted = vec;
|
||||
std::sort(unsorted.begin(), unsorted.end());
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(BM_std_sort)->RangeMultiplier(2)->Range(8, 8 << 8);
|
||||
|
||||
void BM_std_sort_mostly_sorted(benchmark::State &state)
|
||||
{
|
||||
auto vec = mostly_sorted_vec(state);
|
||||
|
||||
for (auto _ : state) {
|
||||
auto unsorted = vec;
|
||||
std::sort(unsorted.begin(), unsorted.end());
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(BM_std_sort_mostly_sorted)->RangeMultiplier(2)->Range(8, 8 << 8);
|
||||
|
||||
}
|
||||
|
||||
BENCHMARK_MAIN();
|
79
external/toxcore/c-toxcore/toxcore/sort_test.cc
vendored
Normal file
79
external/toxcore/c-toxcore/toxcore/sort_test.cc
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2023-2024 The TokTok team.
|
||||
*/
|
||||
|
||||
#include "sort.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <limits>
|
||||
#include <random>
|
||||
|
||||
#include "sort_test_util.hh"
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(MergeSort, BehavesLikeStdSort)
|
||||
{
|
||||
std::mt19937 rng;
|
||||
// INT_MAX-1 so later we have room to add 1 larger element if needed.
|
||||
std::uniform_int_distribution<int> dist{
|
||||
std::numeric_limits<int>::min(), std::numeric_limits<int>::max() - 1};
|
||||
|
||||
constexpr auto int_funcs = sort_funcs<int>();
|
||||
|
||||
// Test with int arrays.
|
||||
for (uint32_t i = 1; i < 500; ++i) {
|
||||
std::vector<int> vec(i);
|
||||
std::generate(std::begin(vec), std::end(vec), [&]() { return dist(rng); });
|
||||
|
||||
auto sorted = vec;
|
||||
std::sort(sorted.begin(), sorted.end(), std::less<int>());
|
||||
|
||||
// If vec was accidentally sorted, add another larger element that almost definitely makes
|
||||
// it not sorted.
|
||||
if (vec == sorted) {
|
||||
int const largest = *std::prev(sorted.end()) + 1;
|
||||
sorted.push_back(largest);
|
||||
vec.insert(vec.begin(), largest);
|
||||
}
|
||||
ASSERT_NE(vec, sorted);
|
||||
|
||||
// Just pass some arbitrary "self" to make sure the callbacks pass it through.
|
||||
ASSERT_TRUE(merge_sort(vec.data(), vec.size(), &i, &int_funcs));
|
||||
ASSERT_EQ(vec, sorted);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MergeSort, WorksWithNonTrivialTypes)
|
||||
{
|
||||
std::mt19937 rng;
|
||||
std::uniform_int_distribution<int> dist{
|
||||
std::numeric_limits<int>::min(), std::numeric_limits<int>::max()};
|
||||
|
||||
constexpr auto string_funcs = sort_funcs<std::string>();
|
||||
|
||||
// Test with std::string arrays.
|
||||
for (uint32_t i = 1; i < 500; ++i) {
|
||||
std::vector<std::string> vec(i);
|
||||
std::generate(std::begin(vec), std::end(vec), [&]() { return std::to_string(dist(rng)); });
|
||||
|
||||
auto sorted = vec;
|
||||
std::sort(sorted.begin(), sorted.end(), std::less<std::string>());
|
||||
|
||||
// If vec was accidentally sorted, add another larger element that almost definitely makes
|
||||
// it not sorted.
|
||||
if (vec == sorted) {
|
||||
std::string const largest = "larger than largest int";
|
||||
sorted.push_back(largest);
|
||||
vec.insert(vec.begin(), largest);
|
||||
}
|
||||
ASSERT_NE(vec, sorted);
|
||||
|
||||
// Just pass some arbitrary "self" to make sure the callbacks pass it through.
|
||||
ASSERT_TRUE(merge_sort(vec.data(), vec.size(), &i, &string_funcs));
|
||||
ASSERT_EQ(vec, sorted);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
32
external/toxcore/c-toxcore/toxcore/sort_test_util.cc
vendored
Normal file
32
external/toxcore/c-toxcore/toxcore/sort_test_util.cc
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "sort_test_util.hh"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
#include "sort.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace {
|
||||
template <typename T, std::size_t N>
|
||||
int cmp_uint_array(const std::array<T, N> &a, const std::array<T, N> &b)
|
||||
{
|
||||
for (std::size_t i = 0; i < a.size(); ++i) {
|
||||
const int cmp = cmp_uint(a[i], b[i]);
|
||||
if (cmp != 0) {
|
||||
return cmp;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const Sort_Funcs Some_Type::funcs = sort_funcs<Some_Type>();
|
||||
|
||||
int my_type_cmp(const void *va, const void *vb)
|
||||
{
|
||||
const auto *a = static_cast<const Some_Type *>(va);
|
||||
const auto *b = static_cast<const Some_Type *>(vb);
|
||||
return cmp_uint_array(a->compare_value, b->compare_value);
|
||||
}
|
||||
|
||||
bool operator<(const Some_Type &a, const Some_Type &b) { return a.compare_value < b.compare_value; }
|
54
external/toxcore/c-toxcore/toxcore/sort_test_util.hh
vendored
Normal file
54
external/toxcore/c-toxcore/toxcore/sort_test_util.hh
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2023-2024 The TokTok team.
|
||||
*/
|
||||
|
||||
#ifndef C_TOXCORE_TOXCORE_SORT_TEST_UTIL_H
|
||||
#define C_TOXCORE_TOXCORE_SORT_TEST_UTIL_H
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "sort.h"
|
||||
|
||||
struct Memory;
|
||||
|
||||
template <typename T>
|
||||
constexpr Sort_Funcs sort_funcs()
|
||||
{
|
||||
return {
|
||||
[](const void *object, const void *va, const void *vb) {
|
||||
const T *a = static_cast<const T *>(va);
|
||||
const T *b = static_cast<const T *>(vb);
|
||||
|
||||
return *a < *b;
|
||||
},
|
||||
[](const void *arr, uint32_t index) -> const void * {
|
||||
const T *vec = static_cast<const T *>(arr);
|
||||
return &vec[index];
|
||||
},
|
||||
[](void *arr, uint32_t index, const void *val) {
|
||||
T *vec = static_cast<T *>(arr);
|
||||
const T *value = static_cast<const T *>(val);
|
||||
vec[index] = *value;
|
||||
},
|
||||
[](void *arr, uint32_t index, uint32_t size) -> void * {
|
||||
T *vec = static_cast<T *>(arr);
|
||||
return &vec[index];
|
||||
},
|
||||
[](const void *object, uint32_t size) -> void * { return new T[size]; },
|
||||
[](const void *object, void *arr, uint32_t size) { delete[] static_cast<T *>(arr); },
|
||||
};
|
||||
}
|
||||
|
||||
// A realistic test case where we have a struct with some stuff and an expensive value we compare.
|
||||
struct Some_Type {
|
||||
const Memory *mem;
|
||||
std::array<uint32_t, 8> compare_value;
|
||||
const char *name;
|
||||
|
||||
static const Sort_Funcs funcs;
|
||||
};
|
||||
|
||||
int my_type_cmp(const void *va, const void *vb);
|
||||
bool operator<(const Some_Type &a, const Some_Type &b);
|
||||
|
||||
#endif // C_TOXCORE_TOXCORE_SORT_TEST_UTIL_H
|
7
external/toxcore/c-toxcore/toxcore/tox.c
vendored
7
external/toxcore/c-toxcore/toxcore/tox.c
vendored
@@ -752,6 +752,8 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error
|
||||
|
||||
Messenger_Options m_options = {false};
|
||||
|
||||
m_options.dns_enabled = !tox_options_get_experimental_disable_dns(opts);
|
||||
|
||||
bool load_savedata_sk = false;
|
||||
bool load_savedata_tox = false;
|
||||
|
||||
@@ -855,9 +857,10 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error
|
||||
}
|
||||
|
||||
const char *const proxy_host = tox_options_get_proxy_host(opts);
|
||||
const bool dns_enabled = !tox_options_get_experimental_disable_dns(opts);
|
||||
|
||||
if (proxy_host == nullptr
|
||||
|| !addr_resolve_or_parse_ip(tox->sys.ns, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr)) {
|
||||
|| !addr_resolve_or_parse_ip(tox->sys.ns, tox->sys.mem, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr, dns_enabled)) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST);
|
||||
// TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain.
|
||||
mem_delete(sys->mem, tox);
|
||||
@@ -1139,7 +1142,7 @@ static int32_t resolve_bootstrap_node(Tox *tox, const char *host, uint16_t port,
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int32_t count = net_getipport(tox->sys.mem, host, root, TOX_SOCK_DGRAM);
|
||||
const int32_t count = net_getipport(tox->sys.ns, tox->sys.mem, host, root, TOX_SOCK_DGRAM, tox->m->options.dns_enabled);
|
||||
|
||||
if (count < 1) {
|
||||
LOGGER_DEBUG(tox->m->log, "could not resolve bootstrap node '%s'", host);
|
||||
|
26
external/toxcore/c-toxcore/toxcore/tox.h
vendored
26
external/toxcore/c-toxcore/toxcore/tox.h
vendored
@@ -148,7 +148,7 @@ uint32_t tox_version_minor(void);
|
||||
* Incremented when bugfixes are applied without changing any functionality or
|
||||
* API or ABI.
|
||||
*/
|
||||
#define TOX_VERSION_PATCH 19
|
||||
#define TOX_VERSION_PATCH 20
|
||||
|
||||
uint32_t tox_version_patch(void);
|
||||
|
||||
@@ -274,7 +274,7 @@ uint32_t tox_max_status_message_length(void);
|
||||
*
|
||||
* @deprecated The macro will be removed in 0.3.0. Use the function instead.
|
||||
*/
|
||||
#define TOX_MAX_FRIEND_REQUEST_LENGTH 1016
|
||||
#define TOX_MAX_FRIEND_REQUEST_LENGTH 921
|
||||
|
||||
uint32_t tox_max_friend_request_length(void);
|
||||
|
||||
@@ -668,6 +668,24 @@ struct Tox_Options {
|
||||
* 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;
|
||||
};
|
||||
|
||||
bool tox_options_get_ipv6_enabled(const Tox_Options *options);
|
||||
@@ -742,6 +760,10 @@ 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.
|
||||
*
|
||||
|
9
external/toxcore/c-toxcore/toxcore/tox_api.c
vendored
9
external/toxcore/c-toxcore/toxcore/tox_api.c
vendored
@@ -274,6 +274,14 @@ void tox_options_set_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)
|
||||
{
|
||||
@@ -299,6 +307,7 @@ void tox_options_default(Tox_Options *options)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -124,7 +124,7 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip
|
||||
|
||||
IP_Port *root;
|
||||
|
||||
const int32_t count = net_getipport(tox->sys.mem, ip, &root, TOX_SOCK_DGRAM);
|
||||
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);
|
||||
|
3
external/toxcore/c-toxcore/toxcore/util.c
vendored
3
external/toxcore/c-toxcore/toxcore/util.c
vendored
@@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2016-2018 The TokTok team.
|
||||
* Copyright © 2016-2024 The TokTok team.
|
||||
* Copyright © 2013 Tox project.
|
||||
* Copyright © 2013 plutooo
|
||||
*/
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "ccompat.h"
|
||||
#include "mem.h"
|
||||
|
||||
|
33
external/toxcore/c-toxcore/toxcore/util_test.cc
vendored
33
external/toxcore/c-toxcore/toxcore/util_test.cc
vendored
@@ -1,39 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2016-2024 The TokTok team.
|
||||
*/
|
||||
#include "util.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "crypto_core.h"
|
||||
#include "crypto_core_test_util.hh"
|
||||
#include <climits>
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(Util, TwoRandomIdsAreNotEqual)
|
||||
{
|
||||
Test_Random rng;
|
||||
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
|
||||
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t sk2[CRYPTO_SECRET_KEY_SIZE];
|
||||
|
||||
crypto_new_keypair(rng, pk1, sk1);
|
||||
crypto_new_keypair(rng, pk2, sk2);
|
||||
|
||||
EXPECT_FALSE(pk_equal(pk1, pk2));
|
||||
}
|
||||
|
||||
TEST(Util, IdCopyMakesKeysEqual)
|
||||
{
|
||||
Test_Random rng;
|
||||
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
|
||||
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
|
||||
|
||||
crypto_new_keypair(rng, pk1, sk1);
|
||||
pk_copy(pk2, pk1);
|
||||
|
||||
EXPECT_TRUE(pk_equal(pk1, pk2));
|
||||
}
|
||||
|
||||
TEST(Cmp, OrdersNumbersCorrectly)
|
||||
{
|
||||
EXPECT_EQ(cmp_uint(1, 2), -1);
|
||||
|
Reference in New Issue
Block a user