Squashed 'external/toxcore/c-toxcore/' changes from adbd5b32d8..e29e185c03
e29e185c03 feat: add ngc events 2b0dc0f46b add ngc related unpack functions b2315c50e0 Add groupchat API function that returns an IP address string for a peer 5f863a5492 feat: Add `to_string` functions for all public enums. 0c998a7598 add real timeout test 68c827609a chore: Move s390x build to post-merge. 028b017d79 perf: Slightly reduce bandwidth usage when there are few nodes. 90f7496819 feat: Enable ubsan on bootstrap nodes. 89b6450d66 test: Add check-c run to bazel build. REVERT: adbd5b32d8 feat: add ngc events git-subtree-dir: external/toxcore/c-toxcore git-subtree-split: e29e185c03fea7337036e5ef4d1d9080a6cee721
This commit is contained in:
parent
9ddeea3d06
commit
83e200df43
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@ -90,16 +90,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
file: other/docker/compcert/Dockerfile
|
file: other/docker/compcert/Dockerfile
|
||||||
|
|
||||||
build-alpine-s390x:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v1
|
|
||||||
- name: Docker Build
|
|
||||||
uses: docker/build-push-action@v2
|
|
||||||
with:
|
|
||||||
file: other/docker/alpine-s390x/Dockerfile
|
|
||||||
|
|
||||||
cimplefmt:
|
cimplefmt:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
16
.github/workflows/post-submit.yml
vendored
Normal file
16
.github/workflows/post-submit.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
name: post-submit
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-alpine-s390x:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
- name: Docker Build
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
file: other/docker/alpine-s390x/Dockerfile
|
@ -453,6 +453,7 @@ unit_test(toxcore bin_pack)
|
|||||||
unit_test(toxcore crypto_core)
|
unit_test(toxcore crypto_core)
|
||||||
unit_test(toxcore group_announce)
|
unit_test(toxcore group_announce)
|
||||||
unit_test(toxcore group_moderation)
|
unit_test(toxcore group_moderation)
|
||||||
|
unit_test(toxcore list)
|
||||||
unit_test(toxcore mem)
|
unit_test(toxcore mem)
|
||||||
unit_test(toxcore mono_time)
|
unit_test(toxcore mono_time)
|
||||||
unit_test(toxcore ping_array)
|
unit_test(toxcore ping_array)
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "auto_test_support.h"
|
#include "auto_test_support.h"
|
||||||
|
#include "../toxcore/tox_private.h"
|
||||||
|
|
||||||
typedef struct State {
|
typedef struct State {
|
||||||
size_t peer_joined_count;
|
size_t peer_joined_count;
|
||||||
@ -42,6 +43,22 @@ typedef struct State {
|
|||||||
|
|
||||||
#define PEER_LIMIT 20
|
#define PEER_LIMIT 20
|
||||||
|
|
||||||
|
static void print_ip(Tox *tox, uint32_t groupnumber, uint32_t peer_id)
|
||||||
|
{
|
||||||
|
Tox_Err_Group_Peer_Query err;
|
||||||
|
size_t length = tox_group_peer_get_ip_address_size(tox, groupnumber, peer_id, &err);
|
||||||
|
|
||||||
|
ck_assert_msg(err == TOX_ERR_GROUP_PEER_QUERY_OK, "failed to get ip address size: error %d", err);
|
||||||
|
|
||||||
|
uint8_t ip_str[TOX_GROUP_PEER_IP_STRING_MAX_LENGTH];
|
||||||
|
tox_group_peer_get_ip_address(tox, groupnumber, peer_id, ip_str, &err);
|
||||||
|
ip_str[length] = '\0';
|
||||||
|
|
||||||
|
ck_assert_msg(err == TOX_ERR_GROUP_PEER_QUERY_OK, "failed to get ip address: error %d", err);
|
||||||
|
|
||||||
|
fprintf(stderr, "%s\n", ip_str);
|
||||||
|
}
|
||||||
|
|
||||||
static bool all_group_peers_connected(AutoTox *autotoxes, uint32_t tox_count, uint32_t groupnumber, size_t name_length)
|
static bool all_group_peers_connected(AutoTox *autotoxes, uint32_t tox_count, uint32_t groupnumber, size_t name_length)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < tox_count; ++i) {
|
for (size_t i = 0; i < tox_count; ++i) {
|
||||||
@ -119,6 +136,9 @@ static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t pee
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "%s joined with IP: ", peer_name);
|
||||||
|
print_ip(tox, groupnumber, peer_id);
|
||||||
|
|
||||||
state->peer_id = peer_id;
|
state->peer_id = peer_id;
|
||||||
++state->peer_joined_count;
|
++state->peer_joined_count;
|
||||||
}
|
}
|
||||||
@ -178,6 +198,11 @@ static void group_peer_self_join_handler(Tox *tox, uint32_t groupnumber, void *u
|
|||||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", query_err);
|
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", query_err);
|
||||||
ck_assert(memcmp(topic, TOPIC, TOPIC_LEN) == 0);
|
ck_assert(memcmp(topic, TOPIC, TOPIC_LEN) == 0);
|
||||||
|
|
||||||
|
uint32_t peer_id = tox_group_self_get_peer_id(tox, groupnumber, nullptr);
|
||||||
|
|
||||||
|
fprintf(stderr, "self joined with IP: ");
|
||||||
|
print_ip(tox, groupnumber, peer_id);
|
||||||
|
|
||||||
++state->self_joined_count;
|
++state->self_joined_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,6 +366,7 @@ static void group_announce_test(AutoTox *autotoxes)
|
|||||||
ck_assert(memcmp(tox0_pk_query, tox0_self_pk, TOX_GROUP_PEER_PUBLIC_KEY_SIZE) == 0);
|
ck_assert(memcmp(tox0_pk_query, tox0_self_pk, TOX_GROUP_PEER_PUBLIC_KEY_SIZE) == 0);
|
||||||
|
|
||||||
fprintf(stderr, "Peer 0 disconnecting...\n");
|
fprintf(stderr, "Peer 0 disconnecting...\n");
|
||||||
|
|
||||||
// tox 0 disconnects then reconnects
|
// tox 0 disconnects then reconnects
|
||||||
Tox_Err_Group_Disconnect d_err;
|
Tox_Err_Group_Disconnect d_err;
|
||||||
tox_group_disconnect(tox0, groupnumber, &d_err);
|
tox_group_disconnect(tox0, groupnumber, &d_err);
|
||||||
|
@ -53,7 +53,7 @@ static int handle_test_1(void *object, const IP_Port *source, const uint8_t *pac
|
|||||||
res_packet[0] = NET_PACKET_ANNOUNCE_RESPONSE;
|
res_packet[0] = NET_PACKET_ANNOUNCE_RESPONSE;
|
||||||
memcpy(res_packet + 1, res_message, sizeof(res_message));
|
memcpy(res_packet + 1, res_message, sizeof(res_message));
|
||||||
|
|
||||||
if (send_onion_response(onion->net, source, res_packet, sizeof(res_packet),
|
if (send_onion_response(onion->log, onion->net, source, res_packet, sizeof(res_packet),
|
||||||
packet + sizeof(res_packet)) == -1) {
|
packet + sizeof(res_packet)) == -1) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -293,7 +293,7 @@ static void test_basic(void)
|
|||||||
uint64_t s;
|
uint64_t s;
|
||||||
memcpy(&s, sb_data, sizeof(uint64_t));
|
memcpy(&s, sb_data, sizeof(uint64_t));
|
||||||
memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||||
int ret = send_announce_request(onion1->net, rng, &path, &nodes[3],
|
int ret = send_announce_request(log1, onion1->net, rng, &path, &nodes[3],
|
||||||
dht_get_self_public_key(onion1->dht),
|
dht_get_self_public_key(onion1->dht),
|
||||||
dht_get_self_secret_key(onion1->dht),
|
dht_get_self_secret_key(onion1->dht),
|
||||||
zeroes,
|
zeroes,
|
||||||
@ -315,7 +315,7 @@ static void test_basic(void)
|
|||||||
memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE);
|
memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE);
|
||||||
onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2));
|
onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2));
|
||||||
networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1);
|
networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1);
|
||||||
send_announce_request(onion1->net, rng, &path, &nodes[3],
|
send_announce_request(log1, onion1->net, rng, &path, &nodes[3],
|
||||||
dht_get_self_public_key(onion1->dht),
|
dht_get_self_public_key(onion1->dht),
|
||||||
dht_get_self_secret_key(onion1->dht),
|
dht_get_self_secret_key(onion1->dht),
|
||||||
test_3_ping_id,
|
test_3_ping_id,
|
||||||
@ -340,7 +340,7 @@ static void test_basic(void)
|
|||||||
ck_assert_msg((onion3 != nullptr), "Onion failed initializing.");
|
ck_assert_msg((onion3 != nullptr), "Onion failed initializing.");
|
||||||
|
|
||||||
random_nonce(rng, nonce);
|
random_nonce(rng, nonce);
|
||||||
ret = send_data_request(onion3->net, rng, &path, &nodes[3].ip_port,
|
ret = send_data_request(log3, onion3->net, rng, &path, &nodes[3].ip_port,
|
||||||
dht_get_self_public_key(onion1->dht),
|
dht_get_self_public_key(onion1->dht),
|
||||||
dht_get_self_public_key(onion1->dht),
|
dht_get_self_public_key(onion1->dht),
|
||||||
nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo"));
|
nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo"));
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "../toxcore/tox.h"
|
#include "../toxcore/tox.h"
|
||||||
#include "../toxcore/tox_dispatch.h"
|
#include "../toxcore/tox_dispatch.h"
|
||||||
#include "../toxcore/tox_events.h"
|
#include "../toxcore/tox_events.h"
|
||||||
|
#include "../toxcore/tox_unpack.h"
|
||||||
#include "auto_test_support.h"
|
#include "auto_test_support.h"
|
||||||
#include "check_compat.h"
|
#include "check_compat.h"
|
||||||
|
|
||||||
@ -160,9 +161,22 @@ static void test_tox_events(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fake_test_unpack(void)
|
||||||
|
{
|
||||||
|
// TODO(Green-Sky): add proper unpack tests and/or implement ngc events
|
||||||
|
(void)tox_unpack_group_privacy_state;
|
||||||
|
(void)tox_unpack_group_privacy_state;
|
||||||
|
(void)tox_unpack_group_voice_state;
|
||||||
|
(void)tox_unpack_group_topic_lock;
|
||||||
|
(void)tox_unpack_group_join_fail;
|
||||||
|
(void)tox_unpack_group_mod_event;
|
||||||
|
(void)tox_unpack_group_exit_type;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||||
test_tox_events();
|
test_tox_events();
|
||||||
|
fake_test_unpack();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
###########################################################
|
###########################################################
|
||||||
# Builder image: we compile the code here (static build)
|
# Builder image: we compile the code here (static build)
|
||||||
FROM alpine:3.18.5 AS build
|
FROM alpine:3.19.0 AS build
|
||||||
|
|
||||||
RUN ["apk", "--no-cache", "add",\
|
RUN ["apk", "--no-cache", "add",\
|
||||||
"build-base",\
|
"clang",\
|
||||||
"cmake",\
|
"cmake",\
|
||||||
"linux-headers",\
|
"linux-headers",\
|
||||||
"libconfig-dev",\
|
"libconfig-dev",\
|
||||||
"libconfig-static",\
|
"libconfig-static",\
|
||||||
"libsodium-dev",\
|
"libsodium-dev",\
|
||||||
"libsodium-static",\
|
"libsodium-static",\
|
||||||
|
"musl-dev",\
|
||||||
"ninja",\
|
"ninja",\
|
||||||
"python3"\
|
"python3"\
|
||||||
]
|
]
|
||||||
@ -34,9 +35,9 @@ COPY CMakeLists.txt so.version ./
|
|||||||
COPY other/bootstrap_daemon/CMakeLists.txt other/bootstrap_daemon/CMakeLists.txt
|
COPY other/bootstrap_daemon/CMakeLists.txt other/bootstrap_daemon/CMakeLists.txt
|
||||||
COPY testing/CMakeLists.txt testing/CMakeLists.txt
|
COPY testing/CMakeLists.txt testing/CMakeLists.txt
|
||||||
|
|
||||||
RUN cmake -B_build -H. \
|
RUN CC=clang cmake -B_build -H. \
|
||||||
-GNinja \
|
-GNinja \
|
||||||
-DCMAKE_C_FLAGS="-DTCP_SERVER_USE_EPOLL -fstack-protector-all -fisolate-erroneous-paths-attribute" \
|
-DCMAKE_C_FLAGS="-DTCP_SERVER_USE_EPOLL -fsanitize=alignment,return,returns-nonnull-attribute,vla-bound,unreachable,float-cast-overflow,null -fsanitize-trap=all -fstack-protector-all" \
|
||||||
-DCMAKE_UNITY_BUILD=ON \
|
-DCMAKE_UNITY_BUILD=ON \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DFULLY_STATIC=ON \
|
-DFULLY_STATIC=ON \
|
||||||
|
@ -1 +1 @@
|
|||||||
5aac1df4d6c1de289e8e9f646d06099c84fd4d9b80d19f45e3254eec3ece2bff /usr/local/bin/tox-bootstrapd
|
21cf23b1a2e46712663dc4f8daa322991af51b9e82626a127cf1bc8dc583b598 /usr/local/bin/tox-bootstrapd
|
||||||
|
@ -22,6 +22,28 @@ sh_test(
|
|||||||
tags = ["haskell"],
|
tags = ["haskell"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
sh_test(
|
||||||
|
name = "c_test",
|
||||||
|
size = "small",
|
||||||
|
srcs = ["//hs-tokstyle/tools:check-c"],
|
||||||
|
args = [
|
||||||
|
"--cc=$(CC)",
|
||||||
|
"-Iexternal/libsodium/include",
|
||||||
|
"-Iexternal/libvpx",
|
||||||
|
"-Iexternal/opus/include",
|
||||||
|
"-Ihs-tokstyle/include",
|
||||||
|
] + ["$(locations %s)" % f for f in CIMPLE_FILES],
|
||||||
|
data = CIMPLE_FILES + [
|
||||||
|
"//c-toxcore/third_party:headers",
|
||||||
|
"//hs-tokstyle:headers",
|
||||||
|
"@libsodium//:headers",
|
||||||
|
"@libvpx//:headers",
|
||||||
|
"@opus//:headers",
|
||||||
|
],
|
||||||
|
tags = ["haskell"],
|
||||||
|
toolchains = ["@rules_cc//cc:current_cc_toolchain"],
|
||||||
|
)
|
||||||
|
|
||||||
sh_test(
|
sh_test(
|
||||||
name = "cimplefmt_test",
|
name = "cimplefmt_test",
|
||||||
size = "small",
|
size = "small",
|
||||||
|
6
third_party/BUILD.bazel
vendored
6
third_party/BUILD.bazel
vendored
@ -7,3 +7,9 @@ cc_library(
|
|||||||
copts = ["-DCMP_NO_FLOAT"],
|
copts = ["-DCMP_NO_FLOAT"],
|
||||||
visibility = ["//c-toxcore:__subpackages__"],
|
visibility = ["//c-toxcore:__subpackages__"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "headers",
|
||||||
|
srcs = ["cmp/cmp.h"],
|
||||||
|
visibility = ["//c-toxcore:__subpackages__"],
|
||||||
|
)
|
||||||
|
@ -821,6 +821,7 @@ static void handle_pop(MSICall *call, const MSIMessage *msg)
|
|||||||
switch (call->state) {
|
switch (call->state) {
|
||||||
case MSI_CALL_INACTIVE: {
|
case MSI_CALL_INACTIVE: {
|
||||||
LOGGER_FATAL(call->session->messenger->log, "Handling what should be impossible case");
|
LOGGER_FATAL(call->session->messenger->log, "Handling what should be impossible case");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MSI_CALL_ACTIVE: {
|
case MSI_CALL_ACTIVE: {
|
||||||
|
@ -201,6 +201,7 @@ cc_library(
|
|||||||
":attributes",
|
":attributes",
|
||||||
":ccompat",
|
":ccompat",
|
||||||
":mem",
|
":mem",
|
||||||
|
":util",
|
||||||
"@pthread",
|
"@pthread",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -230,6 +231,7 @@ cc_library(
|
|||||||
deps = [
|
deps = [
|
||||||
":ccompat",
|
":ccompat",
|
||||||
":crypto_core",
|
":crypto_core",
|
||||||
|
":logger",
|
||||||
":mem",
|
":mem",
|
||||||
":mono_time",
|
":mono_time",
|
||||||
],
|
],
|
||||||
|
@ -1828,7 +1828,9 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
|
|||||||
++not_kill;
|
++not_kill;
|
||||||
|
|
||||||
if (mono_time_is_timeout(dht->mono_time, assoc->last_pinged, PING_INTERVAL)) {
|
if (mono_time_is_timeout(dht->mono_time, assoc->last_pinged, PING_INTERVAL)) {
|
||||||
dht_getnodes(dht, &assoc->ip_port, client->public_key, public_key);
|
const IP_Port *target = &assoc->ip_port;
|
||||||
|
const uint8_t *target_key = client->public_key;
|
||||||
|
dht_getnodes(dht, target, target_key, public_key);
|
||||||
assoc->last_pinged = temp_time;
|
assoc->last_pinged = temp_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1861,7 +1863,9 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
|
|||||||
rand_node += random_range_u32(dht->rng, num_nodes - (rand_node + 1));
|
rand_node += random_range_u32(dht->rng, num_nodes - (rand_node + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
dht_getnodes(dht, &assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, public_key);
|
const IP_Port *target = &assoc_list[rand_node]->ip_port;
|
||||||
|
const uint8_t *target_key = client_list[rand_node]->public_key;
|
||||||
|
dht_getnodes(dht, target, target_key, public_key);
|
||||||
|
|
||||||
*lastgetnode = temp_time;
|
*lastgetnode = temp_time;
|
||||||
++*bootstrap_times;
|
++*bootstrap_times;
|
||||||
@ -1890,8 +1894,7 @@ static void do_dht_friends(DHT *dht)
|
|||||||
dht_friend->num_to_bootstrap = 0;
|
dht_friend->num_to_bootstrap = 0;
|
||||||
|
|
||||||
do_ping_and_sendnode_requests(dht, &dht_friend->lastgetnode, dht_friend->public_key, dht_friend->client_list,
|
do_ping_and_sendnode_requests(dht, &dht_friend->lastgetnode, dht_friend->public_key, dht_friend->client_list,
|
||||||
MAX_FRIEND_CLIENTS,
|
MAX_FRIEND_CLIENTS, &dht_friend->bootstrap_times, true);
|
||||||
&dht_friend->bootstrap_times, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2634,6 +2637,7 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw
|
|||||||
DHT *const dht = (DHT *)mem_alloc(mem, sizeof(DHT));
|
DHT *const dht = (DHT *)mem_alloc(mem, sizeof(DHT));
|
||||||
|
|
||||||
if (dht == nullptr) {
|
if (dht == nullptr) {
|
||||||
|
LOGGER_ERROR(log, "failed to allocate DHT struct (%ld bytes)", (unsigned long)sizeof(DHT));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2651,6 +2655,7 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw
|
|||||||
dht->ping = ping_new(mem, mono_time, rng, dht);
|
dht->ping = ping_new(mem, mono_time, rng, dht);
|
||||||
|
|
||||||
if (dht->ping == nullptr) {
|
if (dht->ping == nullptr) {
|
||||||
|
LOGGER_ERROR(log, "failed to initialise ping");
|
||||||
kill_dht(dht);
|
kill_dht(dht);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -2667,10 +2672,11 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw
|
|||||||
|
|
||||||
crypto_new_keypair(rng, dht->self_public_key, dht->self_secret_key);
|
crypto_new_keypair(rng, dht->self_public_key, dht->self_secret_key);
|
||||||
|
|
||||||
dht->shared_keys_recv = shared_key_cache_new(mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
dht->shared_keys_recv = shared_key_cache_new(log, mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||||
dht->shared_keys_sent = shared_key_cache_new(mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
dht->shared_keys_sent = shared_key_cache_new(log, mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||||
|
|
||||||
if (dht->shared_keys_recv == nullptr || dht->shared_keys_sent == nullptr) {
|
if (dht->shared_keys_recv == nullptr || dht->shared_keys_sent == nullptr) {
|
||||||
|
LOGGER_ERROR(log, "failed to initialise shared key cache");
|
||||||
kill_dht(dht);
|
kill_dht(dht);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -2679,6 +2685,7 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw
|
|||||||
dht->dht_ping_array = ping_array_new(mem, DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
|
dht->dht_ping_array = ping_array_new(mem, DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
|
||||||
|
|
||||||
if (dht->dht_ping_array == nullptr) {
|
if (dht->dht_ping_array == nullptr) {
|
||||||
|
LOGGER_ERROR(log, "failed to initialise ping array");
|
||||||
kill_dht(dht);
|
kill_dht(dht);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -2691,6 +2698,7 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw
|
|||||||
|
|
||||||
uint32_t token; // We don't intend to delete these ever, but need to pass the token
|
uint32_t token; // We don't intend to delete these ever, but need to pass the token
|
||||||
if (dht_addfriend(dht, random_public_key_bytes, nullptr, nullptr, 0, &token) != 0) {
|
if (dht_addfriend(dht, random_public_key_bytes, nullptr, nullptr, 0, &token) != 0) {
|
||||||
|
LOGGER_ERROR(log, "failed to add initial random seed DHT friends");
|
||||||
kill_dht(dht);
|
kill_dht(dht);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -3583,6 +3583,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
|
|||||||
mem_delete(mem, m);
|
mem_delete(mem, m);
|
||||||
|
|
||||||
if (error != nullptr && net_err == 1) {
|
if (error != nullptr && net_err == 1) {
|
||||||
|
LOGGER_WARNING(m->log, "network initialisation failed (no ports available)");
|
||||||
*error = MESSENGER_ERROR_PORT;
|
*error = MESSENGER_ERROR_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3602,6 +3603,8 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
|
|||||||
m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info);
|
m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info);
|
||||||
|
|
||||||
if (m->net_crypto == nullptr) {
|
if (m->net_crypto == nullptr) {
|
||||||
|
LOGGER_WARNING(m->log, "net_crypto initialisation failed");
|
||||||
|
|
||||||
kill_dht(m->dht);
|
kill_dht(m->dht);
|
||||||
kill_networking(m->net);
|
kill_networking(m->net);
|
||||||
friendreq_kill(m->fr);
|
friendreq_kill(m->fr);
|
||||||
@ -3614,6 +3617,8 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
|
|||||||
m->group_announce = new_gca_list();
|
m->group_announce = new_gca_list();
|
||||||
|
|
||||||
if (m->group_announce == nullptr) {
|
if (m->group_announce == nullptr) {
|
||||||
|
LOGGER_WARNING(m->log, "DHT group chats initialisation failed");
|
||||||
|
|
||||||
kill_net_crypto(m->net_crypto);
|
kill_net_crypto(m->net_crypto);
|
||||||
kill_dht(m->dht);
|
kill_dht(m->dht);
|
||||||
kill_networking(m->net);
|
kill_networking(m->net);
|
||||||
@ -3642,6 +3647,8 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
|
|||||||
|
|
||||||
if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) ||
|
if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) ||
|
||||||
m->onion == nullptr || m->onion_a == nullptr || m->onion_c == nullptr || m->fr_c == nullptr) {
|
m->onion == nullptr || m->onion_a == nullptr || m->onion_c == nullptr || m->fr_c == nullptr) {
|
||||||
|
LOGGER_WARNING(m->log, "onion initialisation failed");
|
||||||
|
|
||||||
kill_onion(m->onion);
|
kill_onion(m->onion);
|
||||||
kill_onion_announce(m->onion_a);
|
kill_onion_announce(m->onion_a);
|
||||||
kill_onion_client(m->onion_c);
|
kill_onion_client(m->onion_c);
|
||||||
@ -3666,6 +3673,8 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
|
|||||||
m->group_handler = new_dht_groupchats(m);
|
m->group_handler = new_dht_groupchats(m);
|
||||||
|
|
||||||
if (m->group_handler == nullptr) {
|
if (m->group_handler == nullptr) {
|
||||||
|
LOGGER_WARNING(m->log, "conferences initialisation failed");
|
||||||
|
|
||||||
kill_onion(m->onion);
|
kill_onion(m->onion);
|
||||||
kill_onion_announce(m->onion_a);
|
kill_onion_announce(m->onion_a);
|
||||||
kill_onion_client(m->onion_c);
|
kill_onion_client(m->onion_c);
|
||||||
@ -3690,6 +3699,8 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
|
|||||||
m->onion, m->forwarding);
|
m->onion, m->forwarding);
|
||||||
|
|
||||||
if (m->tcp_server == nullptr) {
|
if (m->tcp_server == nullptr) {
|
||||||
|
LOGGER_WARNING(m->log, "TCP server initialisation failed");
|
||||||
|
|
||||||
kill_onion(m->onion);
|
kill_onion(m->onion);
|
||||||
kill_onion_announce(m->onion_a);
|
kill_onion_announce(m->onion_a);
|
||||||
#ifndef VANILLA_NACL
|
#ifndef VANILLA_NACL
|
||||||
|
@ -201,7 +201,11 @@ int read_tcp_packet(
|
|||||||
const uint16_t count = net_socket_data_recv_buffer(ns, sock);
|
const uint16_t count = net_socket_data_recv_buffer(ns, sock);
|
||||||
|
|
||||||
if (count < length) {
|
if (count < length) {
|
||||||
|
if (count != 0) {
|
||||||
|
// Only log when there are some bytes available, as empty buffer
|
||||||
|
// is a very common case and this spams our logs.
|
||||||
LOGGER_TRACE(logger, "recv buffer has %d bytes, but requested %d bytes", count, length);
|
LOGGER_TRACE(logger, "recv buffer has %d bytes, but requested %d bytes", count, length);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ bool tcp_get_random_conn_ip_port(const TCP_Connections *tcp_c, IP_Port *ip_port)
|
|||||||
* return -1 on failure.
|
* return -1 on failure.
|
||||||
*/
|
*/
|
||||||
non_null()
|
non_null()
|
||||||
int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data,
|
int tcp_send_onion_request(TCP_Connections *tcp_c, uint32_t tcp_connections_number, const uint8_t *data,
|
||||||
uint16_t length);
|
uint16_t length);
|
||||||
|
|
||||||
/** @brief Set if we want TCP_connection to allocate some connection for onion use.
|
/** @brief Set if we want TCP_connection to allocate some connection for onion use.
|
||||||
|
@ -660,7 +660,7 @@ Announcements *new_announcements(const Logger *log, const Memory *mem, const Ran
|
|||||||
announce->public_key = dht_get_self_public_key(announce->dht);
|
announce->public_key = dht_get_self_public_key(announce->dht);
|
||||||
announce->secret_key = dht_get_self_secret_key(announce->dht);
|
announce->secret_key = dht_get_self_secret_key(announce->dht);
|
||||||
new_hmac_key(announce->rng, announce->hmac_key);
|
new_hmac_key(announce->rng, announce->hmac_key);
|
||||||
announce->shared_keys = shared_key_cache_new(mono_time, mem, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
announce->shared_keys = shared_key_cache_new(log, mono_time, mem, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||||
if (announce->shared_keys == nullptr) {
|
if (announce->shared_keys == nullptr) {
|
||||||
free(announce);
|
free(announce);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -3517,6 +3517,63 @@ int gc_get_peer_public_key_by_peer_id(const GC_Chat *chat, uint32_t peer_id, uin
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Puts a string of the IP associated with `ip_port` in `ip_str` if the
|
||||||
|
* connection is direct, otherwise puts a placeholder in the buffer indicating that
|
||||||
|
* the IP cannot be displayed.
|
||||||
|
*/
|
||||||
|
non_null()
|
||||||
|
static void get_gc_ip_ntoa(const IP_Port *ip_port, Ip_Ntoa *ip_str)
|
||||||
|
{
|
||||||
|
net_ip_ntoa(&ip_port->ip, ip_str);
|
||||||
|
|
||||||
|
if (!ip_str->ip_is_valid) {
|
||||||
|
ip_str->buf[0] = '-';
|
||||||
|
ip_str->buf[1] = '\0';
|
||||||
|
ip_str->length = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int gc_get_peer_ip_address_size(const GC_Chat *chat, uint32_t peer_id)
|
||||||
|
{
|
||||||
|
const int peer_number = get_peer_number_of_peer_id(chat, peer_id);
|
||||||
|
const GC_Connection *gconn = get_gc_connection(chat, peer_number);
|
||||||
|
|
||||||
|
if (gconn == nullptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IP_Port *ip_port = peer_number == 0 ? &chat->self_ip_port : &gconn->addr.ip_port;
|
||||||
|
|
||||||
|
Ip_Ntoa ip_str;
|
||||||
|
get_gc_ip_ntoa(ip_port, &ip_str);
|
||||||
|
|
||||||
|
return ip_str.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gc_get_peer_ip_address(const GC_Chat *chat, uint32_t peer_id, uint8_t *ip_addr)
|
||||||
|
{
|
||||||
|
const int peer_number = get_peer_number_of_peer_id(chat, peer_id);
|
||||||
|
const GC_Connection *gconn = get_gc_connection(chat, peer_number);
|
||||||
|
|
||||||
|
if (gconn == nullptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip_addr == nullptr) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IP_Port *ip_port = peer_number == 0 ? &chat->self_ip_port : &gconn->addr.ip_port;
|
||||||
|
|
||||||
|
Ip_Ntoa ip_str;
|
||||||
|
get_gc_ip_ntoa(ip_port, &ip_str);
|
||||||
|
|
||||||
|
assert(ip_str.length <= IP_NTOA_LEN);
|
||||||
|
memcpy(ip_addr, ip_str.buf, ip_str.length);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int gc_get_peer_connection_status(const GC_Chat *chat, uint32_t peer_id)
|
unsigned int gc_get_peer_connection_status(const GC_Chat *chat, uint32_t peer_id)
|
||||||
{
|
{
|
||||||
const int peer_number = get_peer_number_of_peer_id(chat, peer_id);
|
const int peer_number = get_peer_number_of_peer_id(chat, peer_id);
|
||||||
|
@ -390,6 +390,29 @@ int gc_get_peer_nick_size(const GC_Chat *chat, uint32_t peer_id);
|
|||||||
non_null(1) nullable(3)
|
non_null(1) nullable(3)
|
||||||
int gc_get_peer_public_key_by_peer_id(const GC_Chat *chat, uint32_t peer_id, uint8_t *public_key);
|
int gc_get_peer_public_key_by_peer_id(const GC_Chat *chat, uint32_t peer_id, uint8_t *public_key);
|
||||||
|
|
||||||
|
/** @brief Returns the length of the IP address for the peer designated by `peer_id`.
|
||||||
|
* Returns -1 if peer_id is invalid.
|
||||||
|
*/
|
||||||
|
non_null()
|
||||||
|
int gc_get_peer_ip_address_size(const GC_Chat *chat, uint32_t peer_id);
|
||||||
|
|
||||||
|
/** @brief Copies peer_id's IP address to `ip_addr`.
|
||||||
|
*
|
||||||
|
* If the peer is forcing TCP connections this will be a placeholder value indicating
|
||||||
|
* that their real IP address is unknown to us.
|
||||||
|
*
|
||||||
|
* If `peer_id` designates ourself, it will write either our own IP address or a
|
||||||
|
* placeholder value, depending on whether or not we're forcing TCP connections.
|
||||||
|
*
|
||||||
|
* `ip_addr` should have room for at least IP_NTOA_LEN bytes.
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
* Returns -1 if peer_id is invalid or doesn't correspond to a valid peer connection.
|
||||||
|
* Returns -2 if `ip_addr` is null.
|
||||||
|
*/
|
||||||
|
non_null(1) nullable(3)
|
||||||
|
int gc_get_peer_ip_address(const GC_Chat *chat, uint32_t peer_id, uint8_t *ip_addr);
|
||||||
|
|
||||||
/** @brief Gets the connection status for peer associated with `peer_id`.
|
/** @brief Gets the connection status for peer associated with `peer_id`.
|
||||||
*
|
*
|
||||||
* If `peer_id` designates ourself, the return value indicates whether we're capable
|
* If `peer_id` designates ourself, the return value indicates whether we're capable
|
||||||
|
@ -117,3 +117,8 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, int l
|
|||||||
|
|
||||||
log->callback(log->context, level, file, line, func, msg, log->userdata);
|
log->callback(log->context, level, file, line, func, msg, log->userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logger_abort(void)
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
@ -67,6 +67,9 @@ void logger_write(
|
|||||||
const Logger *log, Logger_Level level, const char *file, int line, const char *func,
|
const Logger *log, Logger_Level level, const char *file, int line, const char *func,
|
||||||
const char *format, ...);
|
const char *format, ...);
|
||||||
|
|
||||||
|
/* @brief Terminate the program with a signal. */
|
||||||
|
void logger_abort(void);
|
||||||
|
|
||||||
|
|
||||||
#define LOGGER_WRITE(log, level, ...) \
|
#define LOGGER_WRITE(log, level, ...) \
|
||||||
do { \
|
do { \
|
||||||
@ -85,7 +88,7 @@ void logger_write(
|
|||||||
#define LOGGER_FATAL(log, ...) \
|
#define LOGGER_FATAL(log, ...) \
|
||||||
do { \
|
do { \
|
||||||
LOGGER_ERROR(log, __VA_ARGS__); \
|
LOGGER_ERROR(log, __VA_ARGS__); \
|
||||||
abort(); \
|
logger_abort(); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LOGGER_ASSERT(log, cond, ...) \
|
#define LOGGER_ASSERT(log, cond, ...) \
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "ccompat.h"
|
#include "ccompat.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
/** don't call into system billions of times for no reason */
|
/** don't call into system billions of times for no reason */
|
||||||
struct Mono_Time {
|
struct Mono_Time {
|
||||||
@ -165,7 +166,9 @@ Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_t
|
|||||||
// Maximum reproducibility. Never return time = 0.
|
// Maximum reproducibility. Never return time = 0.
|
||||||
mono_time->base_time = 1;
|
mono_time->base_time = 1;
|
||||||
#else
|
#else
|
||||||
mono_time->base_time = (uint64_t)time(nullptr) * 1000ULL - current_time_monotonic(mono_time);
|
// Never return time = 0 in case time() returns 0 (e.g. on microcontrollers
|
||||||
|
// without battery-powered RTC or ones where NTP didn't initialise it yet).
|
||||||
|
mono_time->base_time = max_u64(1, (uint64_t)time(nullptr)) * 1000ULL - current_time_monotonic(mono_time);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mono_time_update(mono_time);
|
mono_time_update(mono_time);
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
TEST(MonoTime, UnixTimeIncreasesOverTime)
|
TEST(MonoTime, UnixTimeIncreasesOverTime)
|
||||||
@ -41,6 +44,24 @@ TEST(MonoTime, IsTimeout)
|
|||||||
mono_time_free(mem, mono_time);
|
mono_time_free(mem, mono_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(MonoTime, IsTimeoutReal)
|
||||||
|
{
|
||||||
|
const Memory *mem = system_memory();
|
||||||
|
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||||
|
ASSERT_NE(mono_time, nullptr);
|
||||||
|
|
||||||
|
uint64_t const start = mono_time_get(mono_time);
|
||||||
|
EXPECT_FALSE(mono_time_is_timeout(mono_time, start, 5));
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
mono_time_update(mono_time);
|
||||||
|
|
||||||
|
// should still not have timed out (5sec) after sleeping ~100ms
|
||||||
|
EXPECT_FALSE(mono_time_is_timeout(mono_time, start, 5));
|
||||||
|
|
||||||
|
mono_time_free(mem, mono_time);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(MonoTime, CustomTime)
|
TEST(MonoTime, CustomTime)
|
||||||
{
|
{
|
||||||
const Memory *mem = system_memory();
|
const Memory *mem = system_memory();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
* Copyright © 2016-2018 The TokTok team.
|
* Copyright © 2016-2023 The TokTok team.
|
||||||
* Copyright © 2013 Tox project.
|
* Copyright © 2013 Tox project.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -778,7 +778,7 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu
|
|||||||
Ip_Ntoa ip_str;
|
Ip_Ntoa ip_str;
|
||||||
const int error = net_error();
|
const int error = net_error();
|
||||||
char *strerror = net_new_strerror(error);
|
char *strerror = net_new_strerror(error);
|
||||||
LOGGER_TRACE(log, "[%02x = %-20s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x",
|
LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x",
|
||||||
buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message,
|
buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message,
|
||||||
min_u16(buflen, 999), 'E',
|
min_u16(buflen, 999), 'E',
|
||||||
net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error,
|
net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error,
|
||||||
@ -786,14 +786,14 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu
|
|||||||
net_kill_strerror(strerror);
|
net_kill_strerror(strerror);
|
||||||
} else if ((res > 0) && ((size_t)res <= buflen)) {
|
} else if ((res > 0) && ((size_t)res <= buflen)) {
|
||||||
Ip_Ntoa ip_str;
|
Ip_Ntoa ip_str;
|
||||||
LOGGER_TRACE(log, "[%02x = %-20s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x",
|
LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x",
|
||||||
buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message,
|
buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message,
|
||||||
min_u16(res, 999), (size_t)res < buflen ? '<' : '=',
|
min_u16(res, 999), (size_t)res < buflen ? '<' : '=',
|
||||||
net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), 0, "OK",
|
net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), 0, "OK",
|
||||||
data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]);
|
data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]);
|
||||||
} else { /* empty or overwrite */
|
} else { /* empty or overwrite */
|
||||||
Ip_Ntoa ip_str;
|
Ip_Ntoa ip_str;
|
||||||
LOGGER_TRACE(log, "[%02x = %-20s] %s %lu%c%u %s:%u (%u: %s) | %08x%08x...%02x",
|
LOGGER_TRACE(log, "[%02x = %-21s] %s %lu%c%u %s:%u (%u: %s) | %08x%08x...%02x",
|
||||||
buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message,
|
buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message,
|
||||||
res, res == 0 ? '!' : '>', buflen,
|
res, res == 0 ? '!' : '>', buflen,
|
||||||
net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), 0, "OK",
|
net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), 0, "OK",
|
||||||
@ -1514,30 +1514,29 @@ void ipport_copy(IP_Port *target, const IP_Port *source)
|
|||||||
*target = *source;
|
*target = *source;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Converts IP into a string.
|
|
||||||
*
|
|
||||||
* Writes error message into the buffer on error.
|
|
||||||
*
|
|
||||||
* @param ip_str contains a buffer of the required size.
|
|
||||||
*
|
|
||||||
* @return Pointer to the buffer inside `ip_str` containing the IP string.
|
|
||||||
*/
|
|
||||||
const char *net_ip_ntoa(const IP *ip, Ip_Ntoa *ip_str)
|
const char *net_ip_ntoa(const IP *ip, Ip_Ntoa *ip_str)
|
||||||
{
|
{
|
||||||
assert(ip_str != nullptr);
|
assert(ip_str != nullptr);
|
||||||
|
|
||||||
|
ip_str->ip_is_valid = false;
|
||||||
|
|
||||||
if (ip == nullptr) {
|
if (ip == nullptr) {
|
||||||
snprintf(ip_str->buf, sizeof(ip_str->buf), "(IP invalid: NULL)");
|
snprintf(ip_str->buf, sizeof(ip_str->buf), "(IP invalid: NULL)");
|
||||||
|
ip_str->length = (uint16_t)strlen(ip_str->buf);
|
||||||
return ip_str->buf;
|
return ip_str->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ip_parse_addr(ip, ip_str->buf, sizeof(ip_str->buf))) {
|
if (!ip_parse_addr(ip, ip_str->buf, sizeof(ip_str->buf))) {
|
||||||
snprintf(ip_str->buf, sizeof(ip_str->buf), "(IP invalid, family %u)", ip->family.value);
|
snprintf(ip_str->buf, sizeof(ip_str->buf), "(IP invalid, family %u)", ip->family.value);
|
||||||
|
ip_str->length = (uint16_t)strlen(ip_str->buf);
|
||||||
return ip_str->buf;
|
return ip_str->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* brute force protection against lacking termination */
|
/* brute force protection against lacking termination */
|
||||||
ip_str->buf[sizeof(ip_str->buf) - 1] = '\0';
|
ip_str->buf[sizeof(ip_str->buf) - 1] = '\0';
|
||||||
|
ip_str->length = (uint16_t)strlen(ip_str->buf);
|
||||||
|
ip_str->ip_is_valid = true;
|
||||||
|
|
||||||
return ip_str->buf;
|
return ip_str->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,11 +343,14 @@ bool ipv6_ipv4_in_v6(const IP6 *a);
|
|||||||
/** this would be TOX_INET6_ADDRSTRLEN, but it might be too short for the error message */
|
/** this would be TOX_INET6_ADDRSTRLEN, but it might be too short for the error message */
|
||||||
#define IP_NTOA_LEN 96 // TODO(irungentoo): magic number. Why not INET6_ADDRSTRLEN ?
|
#define IP_NTOA_LEN 96 // TODO(irungentoo): magic number. Why not INET6_ADDRSTRLEN ?
|
||||||
|
|
||||||
|
/** Contains a null terminated string of an IP address. */
|
||||||
typedef struct Ip_Ntoa {
|
typedef struct Ip_Ntoa {
|
||||||
char buf[IP_NTOA_LEN];
|
char buf[IP_NTOA_LEN]; // a string formatted IP address or an error message.
|
||||||
|
uint16_t length; // the length of the string (not including the null byte).
|
||||||
|
bool ip_is_valid; // if this is false `buf` will contain an error message.
|
||||||
} Ip_Ntoa;
|
} Ip_Ntoa;
|
||||||
|
|
||||||
/** @brief Converts IP into a string.
|
/** @brief Converts IP into a null terminated string.
|
||||||
*
|
*
|
||||||
* Writes error message into the buffer on error.
|
* Writes error message into the buffer on error.
|
||||||
*
|
*
|
||||||
|
@ -283,22 +283,27 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac
|
|||||||
* return -1 on failure.
|
* return -1 on failure.
|
||||||
* return 0 on success.
|
* return 0 on success.
|
||||||
*/
|
*/
|
||||||
int send_onion_response(const Networking_Core *net, const IP_Port *dest, const uint8_t *data, uint16_t length,
|
int send_onion_response(const Logger *log, const Networking_Core *net,
|
||||||
|
const IP_Port *dest, const uint8_t *data, uint16_t length,
|
||||||
const uint8_t *ret)
|
const uint8_t *ret)
|
||||||
{
|
{
|
||||||
if (length > ONION_RESPONSE_MAX_DATA_SIZE || length == 0) {
|
if (length > ONION_RESPONSE_MAX_DATA_SIZE || length == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
VLA(uint8_t, packet, 1 + RETURN_3 + length);
|
const uint16_t packet_size = 1 + RETURN_3 + length;
|
||||||
|
VLA(uint8_t, packet, packet_size);
|
||||||
packet[0] = NET_PACKET_ONION_RECV_3;
|
packet[0] = NET_PACKET_ONION_RECV_3;
|
||||||
memcpy(packet + 1, ret, RETURN_3);
|
memcpy(packet + 1, ret, RETURN_3);
|
||||||
memcpy(packet + 1 + RETURN_3, data, length);
|
memcpy(packet + 1 + RETURN_3, data, length);
|
||||||
|
|
||||||
if ((uint32_t)sendpacket(net, dest, packet, SIZEOF_VLA(packet)) != SIZEOF_VLA(packet)) {
|
if ((uint16_t)sendpacket(net, dest, packet, packet_size) != packet_size) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ip_Ntoa ip_str;
|
||||||
|
LOGGER_TRACE(log, "forwarded onion RECV_3 to %s:%d (%02x in %02x, %d bytes)",
|
||||||
|
net_ip_ntoa(&dest->ip, &ip_str), net_ntohs(dest->port), data[0], packet[0], packet_size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,28 +314,42 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_
|
|||||||
Onion *onion = (Onion *)object;
|
Onion *onion = (Onion *)object;
|
||||||
|
|
||||||
if (length > ONION_MAX_PACKET_SIZE) {
|
if (length > ONION_MAX_PACKET_SIZE) {
|
||||||
|
LOGGER_TRACE(onion->log, "invalid initial onion packet length: %u (max: %u)",
|
||||||
|
length, ONION_MAX_PACKET_SIZE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length <= 1 + SEND_1) {
|
if (length <= 1 + SEND_1) {
|
||||||
|
LOGGER_TRACE(onion->log, "initial onion packet cannot contain SEND_1 packet: %u <= %u",
|
||||||
|
length, 1 + SEND_1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
change_symmetric_key(onion);
|
change_symmetric_key(onion);
|
||||||
|
|
||||||
|
const int nonce_start = 1;
|
||||||
|
const int public_key_start = nonce_start + CRYPTO_NONCE_SIZE;
|
||||||
|
const int ciphertext_start = public_key_start + CRYPTO_PUBLIC_KEY_SIZE;
|
||||||
|
|
||||||
|
const int ciphertext_length = length - ciphertext_start;
|
||||||
|
const int plaintext_length = ciphertext_length - CRYPTO_MAC_SIZE;
|
||||||
|
|
||||||
uint8_t plain[ONION_MAX_PACKET_SIZE];
|
uint8_t plain[ONION_MAX_PACKET_SIZE];
|
||||||
const uint8_t *public_key = packet + 1 + CRYPTO_NONCE_SIZE;
|
const uint8_t *public_key = &packet[public_key_start];
|
||||||
const uint8_t *shared_key = shared_key_cache_lookup(onion->shared_keys_1, public_key);
|
const uint8_t *shared_key = shared_key_cache_lookup(onion->shared_keys_1, public_key);
|
||||||
|
|
||||||
if (shared_key == nullptr) {
|
if (shared_key == nullptr) {
|
||||||
/* Error looking up/deriving the shared key */
|
/* Error looking up/deriving the shared key */
|
||||||
|
LOGGER_TRACE(onion->log, "shared onion key lookup failed for pk %02x%02x...",
|
||||||
|
public_key[0], public_key[1]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
|
const int len = decrypt_data_symmetric(
|
||||||
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), plain);
|
shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain);
|
||||||
|
|
||||||
if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)) {
|
if (len != plaintext_length) {
|
||||||
|
LOGGER_TRACE(onion->log, "decrypt failed: %d != %d", len, plaintext_length);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,7 +358,9 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_
|
|||||||
|
|
||||||
int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const IP_Port *source, const uint8_t *nonce)
|
int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const IP_Port *source, const uint8_t *nonce)
|
||||||
{
|
{
|
||||||
if (len > ONION_MAX_PACKET_SIZE + SIZE_IPPORT - (1 + CRYPTO_NONCE_SIZE + ONION_RETURN_1)) {
|
const uint16_t max_len = ONION_MAX_PACKET_SIZE + SIZE_IPPORT - (1 + CRYPTO_NONCE_SIZE + ONION_RETURN_1);
|
||||||
|
if (len > max_len) {
|
||||||
|
LOGGER_TRACE(onion->log, "invalid SEND_1 length: %d > %d", len, max_len);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,6 +397,9 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const I
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ip_Ntoa ip_str;
|
||||||
|
LOGGER_TRACE(onion->log, "forwarded onion packet to %s:%d, level 1 (%02x in %02x, %d bytes)",
|
||||||
|
net_ip_ntoa(&send_to.ip, &ip_str), net_ntohs(send_to.port), plain[0], data[0], data_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,6 +463,9 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ip_Ntoa ip_str;
|
||||||
|
LOGGER_TRACE(onion->log, "forwarded onion packet to %s:%d, level 2 (%02x in %02x, %d bytes)",
|
||||||
|
net_ip_ntoa(&send_to.ip, &ip_str), net_ntohs(send_to.port), packet[0], data[0], data_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,6 +536,9 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ip_Ntoa ip_str;
|
||||||
|
LOGGER_TRACE(onion->log, "forwarded onion packet to %s:%d, level 3 (%02x in %02x, %d bytes)",
|
||||||
|
net_ip_ntoa(&send_to.ip, &ip_str), net_ntohs(send_to.port), packet[0], data[0], data_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,6 +576,7 @@ static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *pac
|
|||||||
IP_Port send_to;
|
IP_Port send_to;
|
||||||
|
|
||||||
if (ipport_unpack(&send_to, plain, len, false) == -1) {
|
if (ipport_unpack(&send_to, plain, len, false) == -1) {
|
||||||
|
LOGGER_DEBUG(onion->log, "failed to unpack IP/Port");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,6 +590,9 @@ static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *pac
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ip_Ntoa ip_str;
|
||||||
|
LOGGER_TRACE(onion->log, "forwarded onion RECV_2 to %s:%d (%02x in %02x, %d bytes)",
|
||||||
|
net_ip_ntoa(&send_to.ip, &ip_str), net_ntohs(send_to.port), packet[0], data[0], data_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,6 +642,9 @@ static int handle_recv_2(void *object, const IP_Port *source, const uint8_t *pac
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ip_Ntoa ip_str;
|
||||||
|
LOGGER_TRACE(onion->log, "forwarded onion RECV_1 to %s:%d (%02x in %02x, %d bytes)",
|
||||||
|
net_ip_ntoa(&send_to.ip, &ip_str), net_ntohs(send_to.port), packet[0], data[0], data_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -644,6 +681,7 @@ static int handle_recv_1(void *object, const IP_Port *source, const uint8_t *pac
|
|||||||
IP_Port send_to;
|
IP_Port send_to;
|
||||||
|
|
||||||
if (ipport_unpack(&send_to, plain, len, true) == -1) {
|
if (ipport_unpack(&send_to, plain, len, true) == -1) {
|
||||||
|
LOGGER_DEBUG(onion->log, "failed to unpack IP/Port");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,9 +728,9 @@ Onion *new_onion(const Logger *log, const Memory *mem, const Mono_Time *mono_tim
|
|||||||
onion->timestamp = mono_time_get(onion->mono_time);
|
onion->timestamp = mono_time_get(onion->mono_time);
|
||||||
|
|
||||||
const uint8_t *secret_key = dht_get_self_secret_key(dht);
|
const uint8_t *secret_key = dht_get_self_secret_key(dht);
|
||||||
onion->shared_keys_1 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
onion->shared_keys_1 = shared_key_cache_new(log, mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||||
onion->shared_keys_2 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
onion->shared_keys_2 = shared_key_cache_new(log, mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||||
onion->shared_keys_3 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
onion->shared_keys_3 = shared_key_cache_new(log, mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||||
|
|
||||||
if (onion->shared_keys_1 == nullptr ||
|
if (onion->shared_keys_1 == nullptr ||
|
||||||
onion->shared_keys_2 == nullptr ||
|
onion->shared_keys_2 == nullptr ||
|
||||||
|
@ -127,7 +127,8 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac
|
|||||||
* return 0 on success.
|
* return 0 on success.
|
||||||
*/
|
*/
|
||||||
non_null()
|
non_null()
|
||||||
int send_onion_response(const Networking_Core *net, const IP_Port *dest, const uint8_t *data, uint16_t length,
|
int send_onion_response(const Logger *log, const Networking_Core *net,
|
||||||
|
const IP_Port *dest, const uint8_t *data, uint16_t length,
|
||||||
const uint8_t *ret);
|
const uint8_t *ret);
|
||||||
|
|
||||||
/** @brief Function to handle/send received decrypted versions of the packet created by create_onion_packet.
|
/** @brief Function to handle/send received decrypted versions of the packet created by create_onion_packet.
|
||||||
|
@ -186,7 +186,8 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
|
|||||||
* return -1 on failure.
|
* return -1 on failure.
|
||||||
* return 0 on success.
|
* return 0 on success.
|
||||||
*/
|
*/
|
||||||
int send_announce_request(const Networking_Core *net, const Random *rng,
|
int send_announce_request(
|
||||||
|
const Logger *log, const Networking_Core *net, const Random *rng,
|
||||||
const Onion_Path *path, const Node_format *dest,
|
const Onion_Path *path, const Node_format *dest,
|
||||||
const uint8_t *public_key, const uint8_t *secret_key,
|
const uint8_t *public_key, const uint8_t *secret_key,
|
||||||
const uint8_t *ping_id, const uint8_t *client_id,
|
const uint8_t *ping_id, const uint8_t *client_id,
|
||||||
@ -230,7 +231,8 @@ int send_announce_request(const Networking_Core *net, const Random *rng,
|
|||||||
* return -1 on failure.
|
* return -1 on failure.
|
||||||
* return 0 on success.
|
* return 0 on success.
|
||||||
*/
|
*/
|
||||||
int send_data_request(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
|
int send_data_request(
|
||||||
|
const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
|
||||||
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
|
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
|
||||||
const uint8_t *data, uint16_t length)
|
const uint8_t *data, uint16_t length)
|
||||||
{
|
{
|
||||||
@ -549,7 +551,7 @@ static int handle_announce_request_common(
|
|||||||
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
|
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
|
||||||
memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, CRYPTO_NONCE_SIZE);
|
memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, CRYPTO_NONCE_SIZE);
|
||||||
|
|
||||||
if (send_onion_response(onion_a->net, source, data,
|
if (send_onion_response(onion_a->log, onion_a->net, source, data,
|
||||||
1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len,
|
1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len,
|
||||||
packet + (length - ONION_RETURN_3)) == -1) {
|
packet + (length - ONION_RETURN_3)) == -1) {
|
||||||
mem_delete(onion_a->mem, response);
|
mem_delete(onion_a->mem, response);
|
||||||
@ -634,7 +636,7 @@ static int handle_data_request(void *object, const IP_Port *source, const uint8_
|
|||||||
data[0] = NET_PACKET_ONION_DATA_RESPONSE;
|
data[0] = NET_PACKET_ONION_DATA_RESPONSE;
|
||||||
memcpy(data + 1, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3));
|
memcpy(data + 1, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3));
|
||||||
|
|
||||||
if (send_onion_response(onion_a->net, &onion_a->entries[index].ret_ip_port, data, SIZEOF_VLA(data),
|
if (send_onion_response(onion_a->log, onion_a->net, &onion_a->entries[index].ret_ip_port, data, SIZEOF_VLA(data),
|
||||||
onion_a->entries[index].ret) == -1) {
|
onion_a->entries[index].ret) == -1) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -665,7 +667,7 @@ Onion_Announce *new_onion_announce(const Logger *log, const Memory *mem, const R
|
|||||||
onion_a->extra_data_object = nullptr;
|
onion_a->extra_data_object = nullptr;
|
||||||
new_hmac_key(rng, onion_a->hmac_key);
|
new_hmac_key(rng, onion_a->hmac_key);
|
||||||
|
|
||||||
onion_a->shared_keys_recv = shared_key_cache_new(mono_time, mem, dht_get_self_secret_key(dht), KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
onion_a->shared_keys_recv = shared_key_cache_new(log, mono_time, mem, dht_get_self_secret_key(dht), KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||||
if (onion_a->shared_keys_recv == nullptr) {
|
if (onion_a->shared_keys_recv == nullptr) {
|
||||||
kill_onion_announce(onion_a);
|
kill_onion_announce(onion_a);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -94,7 +94,8 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
|
|||||||
* return 0 on success.
|
* return 0 on success.
|
||||||
*/
|
*/
|
||||||
non_null()
|
non_null()
|
||||||
int send_announce_request(const Networking_Core *net, const Random *rng,
|
int send_announce_request(
|
||||||
|
const Logger *log, const Networking_Core *net, const Random *rng,
|
||||||
const Onion_Path *path, const Node_format *dest,
|
const Onion_Path *path, const Node_format *dest,
|
||||||
const uint8_t *public_key, const uint8_t *secret_key,
|
const uint8_t *public_key, const uint8_t *secret_key,
|
||||||
const uint8_t *ping_id, const uint8_t *client_id,
|
const uint8_t *ping_id, const uint8_t *client_id,
|
||||||
@ -117,7 +118,8 @@ int send_announce_request(const Networking_Core *net, const Random *rng,
|
|||||||
* return 0 on success.
|
* return 0 on success.
|
||||||
*/
|
*/
|
||||||
non_null()
|
non_null()
|
||||||
int send_data_request(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
|
int send_data_request(
|
||||||
|
const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
|
||||||
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
|
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
|
||||||
const uint8_t *data, uint16_t length);
|
const uint8_t *data, uint16_t length);
|
||||||
|
|
||||||
|
@ -582,6 +582,7 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *publ
|
|||||||
*sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, onion_c->rng, data, sizeof(data));
|
*sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, onion_c->rng, data, sizeof(data));
|
||||||
|
|
||||||
if (*sendback == 0) {
|
if (*sendback == 0) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "generating sendback in announce ping array failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,6 +625,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
|
|||||||
const uint8_t *dest_pubkey, const uint8_t *ping_id, uint32_t pathnum)
|
const uint8_t *dest_pubkey, const uint8_t *ping_id, uint32_t pathnum)
|
||||||
{
|
{
|
||||||
if (num > onion_c->num_friends) {
|
if (num > onion_c->num_friends) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "not sending announce to out of bounds friend %u (num friends: %u)", num, onion_c->num_friends);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,10 +634,12 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
|
|||||||
|
|
||||||
if (num == 0) {
|
if (num == 0) {
|
||||||
if (random_path(onion_c, &onion_c->onion_paths_self, pathnum, &path) == -1) {
|
if (random_path(onion_c, &onion_c->onion_paths_self, pathnum, &path) == -1) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "cannot find path to self");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (random_path(onion_c, &onion_c->onion_paths_friends, pathnum, &path) == -1) {
|
if (random_path(onion_c, &onion_c->onion_paths_friends, pathnum, &path) == -1) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "cannot find path to friend");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -682,9 +686,13 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "failed to create announce request");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ip_Ntoa ip_str;
|
||||||
|
LOGGER_TRACE(onion_c->logger, "sending onion packet to %s:%d (%02x, %d bytes)",
|
||||||
|
net_ip_ntoa(&dest->ip, &ip_str), net_ntohs(dest->port), request[0], len);
|
||||||
return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len);
|
return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -934,6 +942,8 @@ static int handle_announce_response(void *object, const IP_Port *source, const u
|
|||||||
Onion_Client *onion_c = (Onion_Client *)object;
|
Onion_Client *onion_c = (Onion_Client *)object;
|
||||||
|
|
||||||
if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
|
if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "invalid announce response length: %u (min: %u, max: %u)",
|
||||||
|
length, (unsigned int)ONION_ANNOUNCE_RESPONSE_MIN_SIZE, (unsigned int)ONION_ANNOUNCE_RESPONSE_MAX_SIZE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -949,30 +959,37 @@ static int handle_announce_response(void *object, const IP_Port *source, const u
|
|||||||
uint8_t plain[1 + ONION_PING_ID_SIZE + ONION_ANNOUNCE_RESPONSE_MAX_SIZE - ONION_ANNOUNCE_RESPONSE_MIN_SIZE];
|
uint8_t plain[1 + ONION_PING_ID_SIZE + ONION_ANNOUNCE_RESPONSE_MAX_SIZE - ONION_ANNOUNCE_RESPONSE_MIN_SIZE];
|
||||||
const int plain_size = 1 + ONION_PING_ID_SIZE + length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE;
|
const int plain_size = 1 + ONION_PING_ID_SIZE + length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE;
|
||||||
int len;
|
int len;
|
||||||
|
const uint16_t nonce_start = 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH;
|
||||||
|
const uint16_t ciphertext_start = nonce_start + CRYPTO_NONCE_SIZE;
|
||||||
|
const uint16_t ciphertext_size = length - ciphertext_start;
|
||||||
|
|
||||||
if (num == 0) {
|
if (num == 0) {
|
||||||
len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
|
len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
|
||||||
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
|
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
|
||||||
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
|
|
||||||
length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain);
|
|
||||||
} else {
|
} else {
|
||||||
if (!onion_c->friends_list[num - 1].is_valid) {
|
if (!onion_c->friends_list[num - 1].is_valid) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "friend number %lu is invalid", (unsigned long)(num - 1));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
|
len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
|
||||||
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
|
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
|
||||||
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
|
}
|
||||||
length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain);
|
|
||||||
|
if (len < 0) {
|
||||||
|
// This happens a lot, so don't log it.
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uint32_t)len != plain_size) {
|
if ((uint32_t)len != plain_size) {
|
||||||
|
LOGGER_WARNING(onion_c->logger, "decrypted size (%lu) is not the expected plain text size (%lu)", (unsigned long)len, (unsigned long)plain_size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t path_used = set_path_timeouts(onion_c, num, path_num);
|
const uint32_t path_used = set_path_timeouts(onion_c, num, path_num);
|
||||||
|
|
||||||
if (client_add_to_list(onion_c, num, public_key, &ip_port, plain[0], plain + 1, path_used) == -1) {
|
if (client_add_to_list(onion_c, num, public_key, &ip_port, plain[0], plain + 1, path_used) == -1) {
|
||||||
|
LOGGER_WARNING(onion_c->logger, "failed to add client to list");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,10 +1006,12 @@ static int handle_announce_response(void *object, const IP_Port *source, const u
|
|||||||
plain_size - 2 - ONION_PING_ID_SIZE, false);
|
plain_size - 2 - ONION_PING_ID_SIZE, false);
|
||||||
|
|
||||||
if (num_nodes < 0) {
|
if (num_nodes < 0) {
|
||||||
|
LOGGER_WARNING(onion_c->logger, "no nodes to unpack in onion response");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) {
|
if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) {
|
||||||
|
LOGGER_WARNING(onion_c->logger, "pinging %d nodes failed", num_nodes);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1011,6 +1030,8 @@ static int handle_announce_response(void *object, const IP_Port *source, const u
|
|||||||
|
|
||||||
// TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline?
|
// TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline?
|
||||||
onion_c->last_packet_recv = mono_time_get(onion_c->mono_time);
|
onion_c->last_packet_recv = mono_time_get(onion_c->mono_time);
|
||||||
|
LOGGER_TRACE(onion_c->logger, "onion has received a packet at %llu",
|
||||||
|
(unsigned long long)onion_c->last_packet_recv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1023,6 +1044,8 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con
|
|||||||
Onion_Client *onion_c = (Onion_Client *)object;
|
Onion_Client *onion_c = (Onion_Client *)object;
|
||||||
|
|
||||||
if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
|
if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "invalid announce response length: %u (min: %u, max: %u)",
|
||||||
|
length, (unsigned int)ONION_ANNOUNCE_RESPONSE_MIN_SIZE, (unsigned int)ONION_ANNOUNCE_RESPONSE_MAX_SIZE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1039,30 +1062,37 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con
|
|||||||
|
|
||||||
VLA(uint8_t, plain, 1 + ONION_PING_ID_SIZE + len_nodes);
|
VLA(uint8_t, plain, 1 + ONION_PING_ID_SIZE + len_nodes);
|
||||||
int len;
|
int len;
|
||||||
|
const uint16_t nonce_start = 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH;
|
||||||
|
const uint16_t ciphertext_start = nonce_start + CRYPTO_NONCE_SIZE;
|
||||||
|
const uint16_t ciphertext_size = length - ciphertext_start;
|
||||||
|
|
||||||
if (num == 0) {
|
if (num == 0) {
|
||||||
len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
|
len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
|
||||||
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
|
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
|
||||||
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
|
|
||||||
length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain);
|
|
||||||
} else {
|
} else {
|
||||||
if (!onion_c->friends_list[num - 1].is_valid) {
|
if (!onion_c->friends_list[num - 1].is_valid) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "friend number %lu is invalid", (unsigned long)(num - 1));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
|
len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
|
||||||
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
|
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
|
||||||
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
|
}
|
||||||
length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain);
|
|
||||||
|
if (len < 0) {
|
||||||
|
// This happens a lot, so don't log it.
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uint32_t)len != SIZEOF_VLA(plain)) {
|
if ((uint32_t)len != SIZEOF_VLA(plain)) {
|
||||||
|
LOGGER_WARNING(onion_c->logger, "decrypted size (%lu) is not the expected plain text size (%lu)", (unsigned long)len, (unsigned long)SIZEOF_VLA(plain));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t path_used = set_path_timeouts(onion_c, num, path_num);
|
const uint32_t path_used = set_path_timeouts(onion_c, num, path_num);
|
||||||
|
|
||||||
if (client_add_to_list(onion_c, num, public_key, &ip_port, plain[0], plain + 1, path_used) == -1) {
|
if (client_add_to_list(onion_c, num, public_key, &ip_port, plain[0], plain + 1, path_used) == -1) {
|
||||||
|
LOGGER_WARNING(onion_c->logger, "failed to add client to list");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1071,16 +1101,21 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con
|
|||||||
const int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, nullptr, plain + 1 + ONION_PING_ID_SIZE, len_nodes, false);
|
const int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, nullptr, plain + 1 + ONION_PING_ID_SIZE, len_nodes, false);
|
||||||
|
|
||||||
if (num_nodes <= 0) {
|
if (num_nodes <= 0) {
|
||||||
|
LOGGER_WARNING(onion_c->logger, "no nodes to unpack in onion response");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) {
|
if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) {
|
||||||
|
LOGGER_WARNING(onion_c->logger, "pinging %d nodes failed", num_nodes);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline?
|
// TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline?
|
||||||
onion_c->last_packet_recv = mono_time_get(onion_c->mono_time);
|
onion_c->last_packet_recv = mono_time_get(onion_c->mono_time);
|
||||||
|
LOGGER_TRACE(onion_c->logger, "onion has received a packet at %llu",
|
||||||
|
(unsigned long long)onion_c->last_packet_recv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1378,6 +1413,7 @@ static int handle_dht_dhtpk(void *object, const IP_Port *source, const uint8_t *
|
|||||||
|
|
||||||
return handle_dhtpk_announce(onion_c, packet, plain, len, userdata);
|
return handle_dhtpk_announce(onion_c, packet, plain, len, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Send the packets to tell our friends what our DHT public key is.
|
/** @brief Send the packets to tell our friends what our DHT public key is.
|
||||||
*
|
*
|
||||||
* if onion_dht_both is 0, use only the onion to send the packet.
|
* if onion_dht_both is 0, use only the onion to send the packet.
|
||||||
@ -1857,6 +1893,18 @@ void onion_group_announce_register(Onion_Client *onion_c, onion_group_announce_c
|
|||||||
#define TIME_TO_STABLE (ONION_NODE_PING_INTERVAL * 6)
|
#define TIME_TO_STABLE (ONION_NODE_PING_INTERVAL * 6)
|
||||||
#define ANNOUNCE_INTERVAL_STABLE (ONION_NODE_PING_INTERVAL * 8)
|
#define ANNOUNCE_INTERVAL_STABLE (ONION_NODE_PING_INTERVAL * 8)
|
||||||
|
|
||||||
|
non_null()
|
||||||
|
static bool key_list_contains(const uint8_t *const *keys, uint16_t keys_size, const uint8_t *public_key)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < keys_size; ++i) {
|
||||||
|
if (memeq(keys[i], CRYPTO_PUBLIC_KEY_SIZE, public_key, CRYPTO_PUBLIC_KEY_SIZE)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
non_null()
|
non_null()
|
||||||
static void do_announce(Onion_Client *onion_c)
|
static void do_announce(Onion_Client *onion_c)
|
||||||
{
|
{
|
||||||
@ -1945,9 +1993,27 @@ static void do_announce(Onion_Client *onion_c)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < (MAX_ONION_CLIENTS_ANNOUNCE / 2); ++i) {
|
// Don't send announces to the same node twice. If we don't have many nodes,
|
||||||
|
// the random selection below may have overlaps. This ensures that we deduplicate
|
||||||
|
// nodes before sending packets to save some bandwidth.
|
||||||
|
const uint8_t *targets[MAX_ONION_CLIENTS_ANNOUNCE / 2];
|
||||||
|
unsigned int targets_count = 0;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE / 2; ++i) {
|
||||||
const uint32_t num = random_range_u32(onion_c->rng, num_nodes);
|
const uint32_t num = random_range_u32(onion_c->rng, num_nodes);
|
||||||
client_send_announce_request(onion_c, 0, &path_nodes[num].ip_port, path_nodes[num].public_key, nullptr, -1);
|
const Node_format *target = &path_nodes[num];
|
||||||
|
|
||||||
|
if (!key_list_contains(targets, targets_count, target->public_key)) {
|
||||||
|
client_send_announce_request(onion_c, 0, &target->ip_port, target->public_key, nullptr, -1);
|
||||||
|
|
||||||
|
targets[targets_count] = target->public_key;
|
||||||
|
++targets_count;
|
||||||
|
assert(targets_count <= MAX_ONION_CLIENTS_ANNOUNCE / 2);
|
||||||
|
} else {
|
||||||
|
Ip_Ntoa ip_str;
|
||||||
|
LOGGER_TRACE(onion_c->logger, "not sending repeated announce request to %s:%d",
|
||||||
|
net_ip_ntoa(&target->ip_port.ip, &ip_str), net_ntohs(target->ip_port.port));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1959,22 +2025,25 @@ static void do_announce(Onion_Client *onion_c)
|
|||||||
non_null()
|
non_null()
|
||||||
static bool onion_isconnected(Onion_Client *onion_c)
|
static bool onion_isconnected(Onion_Client *onion_c)
|
||||||
{
|
{
|
||||||
unsigned int num = 0;
|
unsigned int live = 0;
|
||||||
unsigned int announced = 0;
|
unsigned int announced = 0;
|
||||||
|
|
||||||
if (mono_time_is_timeout(onion_c->mono_time, onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) {
|
if (mono_time_is_timeout(onion_c->mono_time, onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "onion is NOT connected: last packet received at %llu (timeout=%u)",
|
||||||
|
(unsigned long long)onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT);
|
||||||
onion_c->last_populated = 0;
|
onion_c->last_populated = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onion_c->path_nodes_index == 0) {
|
if (onion_c->path_nodes_index == 0) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "onion is NOT connected: no path nodes available");
|
||||||
onion_c->last_populated = 0;
|
onion_c->last_populated = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) {
|
for (unsigned int i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) {
|
||||||
if (!onion_node_timed_out(&onion_c->clients_announce_list[i], onion_c->mono_time)) {
|
if (!onion_node_timed_out(&onion_c->clients_announce_list[i], onion_c->mono_time)) {
|
||||||
++num;
|
++live;
|
||||||
|
|
||||||
if (onion_c->clients_announce_list[i].is_stored != 0) {
|
if (onion_c->clients_announce_list[i].is_stored != 0) {
|
||||||
++announced;
|
++announced;
|
||||||
@ -1990,14 +2059,18 @@ static bool onion_isconnected(Onion_Client *onion_c)
|
|||||||
|
|
||||||
/* Consider ourselves online if we are announced to half or more nodes
|
/* Consider ourselves online if we are announced to half or more nodes
|
||||||
* we are connected to */
|
* we are connected to */
|
||||||
if (num != 0 && announced != 0) {
|
if (live != 0 && announced != 0) {
|
||||||
if ((num / 2) <= announced && (pnodes / 2) <= num) {
|
if ((live / 2) <= announced && (pnodes / 2) <= live) {
|
||||||
|
LOGGER_TRACE(onion_c->logger, "onion is connected: %u live nodes, %u announced, %d path nodes",
|
||||||
|
live, announced, pnodes);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onion_c->last_populated = 0;
|
onion_c->last_populated = 0;
|
||||||
|
|
||||||
|
LOGGER_TRACE(onion_c->logger, "onion is NOT connected: %u live nodes, %u announced, %d path nodes",
|
||||||
|
live, announced, pnodes);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,12 +24,13 @@ struct Shared_Key_Cache {
|
|||||||
uint64_t timeout; /** After this time (in seconds), a key is erased on the next housekeeping cycle */
|
uint64_t timeout; /** After this time (in seconds), a key is erased on the next housekeeping cycle */
|
||||||
const Mono_Time *mono_time;
|
const Mono_Time *mono_time;
|
||||||
const Memory *mem;
|
const Memory *mem;
|
||||||
|
const Logger *log;
|
||||||
uint8_t keys_per_slot;
|
uint8_t keys_per_slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
non_null()
|
non_null()
|
||||||
static bool shared_key_is_empty(const Shared_Key *k) {
|
static bool shared_key_is_empty(const Logger *log, const Shared_Key *k) {
|
||||||
assert(k != nullptr);
|
LOGGER_ASSERT(log, k != nullptr, "shared key must not be NULL");
|
||||||
/*
|
/*
|
||||||
* Since time can never be 0, we use that to determine if a key slot is empty.
|
* Since time can never be 0, we use that to determine if a key slot is empty.
|
||||||
* Additionally this allows us to use crypto_memzero and leave the slot in a valid state.
|
* Additionally this allows us to use crypto_memzero and leave the slot in a valid state.
|
||||||
@ -38,12 +39,12 @@ static bool shared_key_is_empty(const Shared_Key *k) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
non_null()
|
non_null()
|
||||||
static void shared_key_set_empty(Shared_Key *k) {
|
static void shared_key_set_empty(const Logger *log, Shared_Key *k) {
|
||||||
crypto_memzero(k, sizeof (Shared_Key));
|
crypto_memzero(k, sizeof (Shared_Key));
|
||||||
assert(shared_key_is_empty(k));
|
LOGGER_ASSERT(log, shared_key_is_empty(log, k), "shared key must be empty after clearing it");
|
||||||
}
|
}
|
||||||
|
|
||||||
Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory *mem, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot)
|
Shared_Key_Cache *shared_key_cache_new(const Logger *log, const Mono_Time *mono_time, const Memory *mem, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot)
|
||||||
{
|
{
|
||||||
if (mono_time == nullptr || self_secret_key == nullptr || timeout == 0 || keys_per_slot == 0) {
|
if (mono_time == nullptr || self_secret_key == nullptr || timeout == 0 || keys_per_slot == 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -52,7 +53,7 @@ Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory
|
|||||||
// Time must not be zero, since we use that as special value for empty slots
|
// Time must not be zero, since we use that as special value for empty slots
|
||||||
if (mono_time_get(mono_time) == 0) {
|
if (mono_time_get(mono_time) == 0) {
|
||||||
// Fail loudly in debug environments
|
// Fail loudly in debug environments
|
||||||
assert(false);
|
LOGGER_FATAL(log, "time must not be zero (mono_time not initialised?)");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +65,7 @@ Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory
|
|||||||
res->self_secret_key = self_secret_key;
|
res->self_secret_key = self_secret_key;
|
||||||
res->mono_time = mono_time;
|
res->mono_time = mono_time;
|
||||||
res->mem = mem;
|
res->mem = mem;
|
||||||
|
res->log = log;
|
||||||
res->keys_per_slot = keys_per_slot;
|
res->keys_per_slot = keys_per_slot;
|
||||||
// We take one byte from the public key for each bucket and store keys_per_slot elements there
|
// We take one byte from the public key for each bucket and store keys_per_slot elements there
|
||||||
const size_t cache_size = 256 * keys_per_slot;
|
const size_t cache_size = 256 * keys_per_slot;
|
||||||
@ -106,7 +108,7 @@ const uint8_t *shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t pu
|
|||||||
|
|
||||||
// Perform lookup
|
// Perform lookup
|
||||||
for(size_t i = 0; i < cache->keys_per_slot; ++i) {
|
for(size_t i = 0; i < cache->keys_per_slot; ++i) {
|
||||||
if (shared_key_is_empty(&bucket_start[i])) {
|
if (shared_key_is_empty(cache->log, &bucket_start[i])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,13 +121,13 @@ const uint8_t *shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t pu
|
|||||||
|
|
||||||
// Perform housekeeping for this bucket
|
// Perform housekeeping for this bucket
|
||||||
for (size_t i = 0; i < cache->keys_per_slot; ++i) {
|
for (size_t i = 0; i < cache->keys_per_slot; ++i) {
|
||||||
if (shared_key_is_empty(&bucket_start[i])) {
|
if (shared_key_is_empty(cache->log, &bucket_start[i])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool timed_out = (bucket_start[i].time_last_requested + cache->timeout) < cur_time;
|
const bool timed_out = (bucket_start[i].time_last_requested + cache->timeout) < cur_time;
|
||||||
if (timed_out) {
|
if (timed_out) {
|
||||||
shared_key_set_empty(&bucket_start[i]);
|
shared_key_set_empty(cache->log, &bucket_start[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <stdint.h> // uint*_t
|
#include <stdint.h> // uint*_t
|
||||||
|
|
||||||
#include "crypto_core.h"
|
#include "crypto_core.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "mono_time.h"
|
#include "mono_time.h"
|
||||||
|
|
||||||
@ -27,7 +28,8 @@ typedef struct Shared_Key_Cache Shared_Key_Cache;
|
|||||||
* @return nullptr on error.
|
* @return nullptr on error.
|
||||||
*/
|
*/
|
||||||
non_null()
|
non_null()
|
||||||
Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory *mem,
|
Shared_Key_Cache *shared_key_cache_new(
|
||||||
|
const Logger *log, const Mono_Time *mono_time, const Memory *mem,
|
||||||
const uint8_t *self_secret_key,
|
const uint8_t *self_secret_key,
|
||||||
uint64_t timeout, uint8_t keys_per_slot);
|
uint64_t timeout, uint8_t keys_per_slot);
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@ static_assert(FILE_ID_LENGTH == CRYPTO_SYMMETRIC_KEY_SIZE,
|
|||||||
"FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE");
|
"FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE");
|
||||||
static_assert(TOX_DHT_NODE_IP_STRING_SIZE == IP_NTOA_LEN,
|
static_assert(TOX_DHT_NODE_IP_STRING_SIZE == IP_NTOA_LEN,
|
||||||
"TOX_DHT_NODE_IP_STRING_SIZE is assumed to be equal to IP_NTOA_LEN");
|
"TOX_DHT_NODE_IP_STRING_SIZE is assumed to be equal to IP_NTOA_LEN");
|
||||||
|
static_assert(TOX_GROUP_PEER_IP_STRING_MAX_LENGTH == IP_NTOA_LEN,
|
||||||
|
"TOX_GROUP_PEER_IP_STRING_MAX_LENGTH is assumed to be equal to IP_NTOA_LEN");
|
||||||
static_assert(TOX_DHT_NODE_PUBLIC_KEY_SIZE == CRYPTO_PUBLIC_KEY_SIZE,
|
static_assert(TOX_DHT_NODE_PUBLIC_KEY_SIZE == CRYPTO_PUBLIC_KEY_SIZE,
|
||||||
"TOX_DHT_NODE_PUBLIC_KEY_SIZE is assumed to be equal to CRYPTO_PUBLIC_KEY_SIZE");
|
"TOX_DHT_NODE_PUBLIC_KEY_SIZE is assumed to be equal to CRYPTO_PUBLIC_KEY_SIZE");
|
||||||
static_assert(TOX_FILE_ID_LENGTH == CRYPTO_SYMMETRIC_KEY_SIZE,
|
static_assert(TOX_FILE_ID_LENGTH == CRYPTO_SYMMETRIC_KEY_SIZE,
|
||||||
@ -2810,7 +2812,7 @@ uint16_t tox_self_get_udp_port(const Tox *tox, Tox_Err_Get_Port *error)
|
|||||||
{
|
{
|
||||||
assert(tox != nullptr);
|
assert(tox != nullptr);
|
||||||
tox_lock(tox);
|
tox_lock(tox);
|
||||||
const uint16_t port = net_htons(net_port(tox->m->net));
|
const uint16_t port = tox->m == nullptr || tox->m->net == nullptr ? 0 : net_htons(net_port(tox->m->net));
|
||||||
tox_unlock(tox);
|
tox_unlock(tox);
|
||||||
|
|
||||||
if (port == 0) {
|
if (port == 0) {
|
||||||
@ -2827,7 +2829,7 @@ uint16_t tox_self_get_tcp_port(const Tox *tox, Tox_Err_Get_Port *error)
|
|||||||
assert(tox != nullptr);
|
assert(tox != nullptr);
|
||||||
tox_lock(tox);
|
tox_lock(tox);
|
||||||
|
|
||||||
if (tox->m->tcp_server != nullptr) {
|
if (tox->m != nullptr && tox->m->tcp_server != nullptr) {
|
||||||
SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_OK);
|
SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_OK);
|
||||||
const uint16_t ret = tox->m->options.tcp_server_port;
|
const uint16_t ret = tox->m->options.tcp_server_port;
|
||||||
tox_unlock(tox);
|
tox_unlock(tox);
|
||||||
|
142
toxcore/tox.h
142
toxcore/tox.h
@ -373,6 +373,8 @@ typedef enum Tox_User_Status {
|
|||||||
|
|
||||||
} Tox_User_Status;
|
} Tox_User_Status;
|
||||||
|
|
||||||
|
const char *tox_user_status_to_string(Tox_User_Status value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Represents message types for tox_friend_send_message and conference
|
* @brief Represents message types for tox_friend_send_message and conference
|
||||||
@ -393,6 +395,8 @@ typedef enum Tox_Message_Type {
|
|||||||
|
|
||||||
} Tox_Message_Type;
|
} Tox_Message_Type;
|
||||||
|
|
||||||
|
const char *tox_message_type_to_string(Tox_Message_Type value);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
@ -422,6 +426,8 @@ typedef enum Tox_Proxy_Type {
|
|||||||
|
|
||||||
} Tox_Proxy_Type;
|
} Tox_Proxy_Type;
|
||||||
|
|
||||||
|
const char *tox_proxy_type_to_string(Tox_Proxy_Type value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of savedata to create the Tox instance from.
|
* @brief Type of savedata to create the Tox instance from.
|
||||||
@ -445,6 +451,8 @@ typedef enum Tox_Savedata_Type {
|
|||||||
|
|
||||||
} Tox_Savedata_Type;
|
} Tox_Savedata_Type;
|
||||||
|
|
||||||
|
const char *tox_savedata_type_to_string(Tox_Savedata_Type value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Severity level of log messages.
|
* @brief Severity level of log messages.
|
||||||
@ -478,6 +486,8 @@ typedef enum Tox_Log_Level {
|
|||||||
|
|
||||||
} Tox_Log_Level;
|
} Tox_Log_Level;
|
||||||
|
|
||||||
|
const char *tox_log_level_to_string(Tox_Log_Level value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This event is triggered when the toxcore library logs an events_alloc message.
|
* @brief This event is triggered when the toxcore library logs an events_alloc message.
|
||||||
@ -791,6 +801,8 @@ typedef enum Tox_Err_Options_New {
|
|||||||
|
|
||||||
} Tox_Err_Options_New;
|
} Tox_Err_Options_New;
|
||||||
|
|
||||||
|
const char *tox_err_options_new_to_string(Tox_Err_Options_New value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocates a new Tox_Options object and initialises it with the default
|
* @brief Allocates a new Tox_Options object and initialises it with the default
|
||||||
@ -883,6 +895,8 @@ typedef enum Tox_Err_New {
|
|||||||
|
|
||||||
} Tox_Err_New;
|
} Tox_Err_New;
|
||||||
|
|
||||||
|
const char *tox_err_new_to_string(Tox_Err_New value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates and initialises a new Tox instance with the options passed.
|
* @brief Creates and initialises a new Tox instance with the options passed.
|
||||||
@ -962,6 +976,8 @@ typedef enum Tox_Err_Bootstrap {
|
|||||||
|
|
||||||
} Tox_Err_Bootstrap;
|
} Tox_Err_Bootstrap;
|
||||||
|
|
||||||
|
const char *tox_err_bootstrap_to_string(Tox_Err_Bootstrap value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sends a "get nodes" request to the given bootstrap node with IP, port,
|
* @brief Sends a "get nodes" request to the given bootstrap node with IP, port,
|
||||||
@ -1029,6 +1045,8 @@ typedef enum Tox_Connection {
|
|||||||
|
|
||||||
} Tox_Connection;
|
} Tox_Connection;
|
||||||
|
|
||||||
|
const char *tox_connection_to_string(Tox_Connection value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return whether we are connected to the DHT.
|
* @brief Return whether we are connected to the DHT.
|
||||||
*
|
*
|
||||||
@ -1155,6 +1173,8 @@ typedef enum Tox_Err_Set_Info {
|
|||||||
|
|
||||||
} Tox_Err_Set_Info;
|
} Tox_Err_Set_Info;
|
||||||
|
|
||||||
|
const char *tox_err_set_info_to_string(Tox_Err_Set_Info value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the nickname for the Tox client.
|
* @brief Set the nickname for the Tox client.
|
||||||
@ -1297,6 +1317,8 @@ typedef enum Tox_Err_Friend_Add {
|
|||||||
|
|
||||||
} Tox_Err_Friend_Add;
|
} Tox_Err_Friend_Add;
|
||||||
|
|
||||||
|
const char *tox_err_friend_add_to_string(Tox_Err_Friend_Add value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add a friend to the friend list and send a friend request.
|
* @brief Add a friend to the friend list and send a friend request.
|
||||||
@ -1358,6 +1380,8 @@ typedef enum Tox_Err_Friend_Delete {
|
|||||||
|
|
||||||
} Tox_Err_Friend_Delete;
|
} Tox_Err_Friend_Delete;
|
||||||
|
|
||||||
|
const char *tox_err_friend_delete_to_string(Tox_Err_Friend_Delete value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove a friend from the friend list.
|
* @brief Remove a friend from the friend list.
|
||||||
@ -1398,6 +1422,8 @@ typedef enum Tox_Err_Friend_By_Public_Key {
|
|||||||
|
|
||||||
} Tox_Err_Friend_By_Public_Key;
|
} Tox_Err_Friend_By_Public_Key;
|
||||||
|
|
||||||
|
const char *tox_err_friend_by_public_key_to_string(Tox_Err_Friend_By_Public_Key value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the friend number associated with that Public Key.
|
* @brief Return the friend number associated with that Public Key.
|
||||||
@ -1445,6 +1471,8 @@ typedef enum Tox_Err_Friend_Get_Public_Key {
|
|||||||
|
|
||||||
} Tox_Err_Friend_Get_Public_Key;
|
} Tox_Err_Friend_Get_Public_Key;
|
||||||
|
|
||||||
|
const char *tox_err_friend_get_public_key_to_string(Tox_Err_Friend_Get_Public_Key value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies the Public Key associated with a given friend number to a byte array.
|
* @brief Copies the Public Key associated with a given friend number to a byte array.
|
||||||
@ -1472,6 +1500,8 @@ typedef enum Tox_Err_Friend_Get_Last_Online {
|
|||||||
|
|
||||||
} Tox_Err_Friend_Get_Last_Online;
|
} Tox_Err_Friend_Get_Last_Online;
|
||||||
|
|
||||||
|
const char *tox_err_friend_get_last_online_to_string(Tox_Err_Friend_Get_Last_Online value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return a unix-time timestamp of the last time the friend associated with a given
|
* @brief Return a unix-time timestamp of the last time the friend associated with a given
|
||||||
@ -1514,6 +1544,8 @@ typedef enum Tox_Err_Friend_Query {
|
|||||||
|
|
||||||
} Tox_Err_Friend_Query;
|
} Tox_Err_Friend_Query;
|
||||||
|
|
||||||
|
const char *tox_err_friend_query_to_string(Tox_Err_Friend_Query value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the length of the friend's name.
|
* @brief Return the length of the friend's name.
|
||||||
@ -1726,6 +1758,8 @@ typedef enum Tox_Err_Set_Typing {
|
|||||||
|
|
||||||
} Tox_Err_Set_Typing;
|
} Tox_Err_Set_Typing;
|
||||||
|
|
||||||
|
const char *tox_err_set_typing_to_string(Tox_Err_Set_Typing value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the client's typing status for a friend.
|
* @brief Set the client's typing status for a friend.
|
||||||
@ -1778,6 +1812,8 @@ typedef enum Tox_Err_Friend_Send_Message {
|
|||||||
|
|
||||||
} Tox_Err_Friend_Send_Message;
|
} Tox_Err_Friend_Send_Message;
|
||||||
|
|
||||||
|
const char *tox_err_friend_send_message_to_string(Tox_Err_Friend_Send_Message value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a text chat message to an online friend.
|
* @brief Send a text chat message to an online friend.
|
||||||
@ -1960,6 +1996,8 @@ typedef enum Tox_File_Control {
|
|||||||
|
|
||||||
} Tox_File_Control;
|
} Tox_File_Control;
|
||||||
|
|
||||||
|
const char *tox_file_control_to_string(Tox_File_Control value);
|
||||||
|
|
||||||
|
|
||||||
typedef enum Tox_Err_File_Control {
|
typedef enum Tox_Err_File_Control {
|
||||||
|
|
||||||
@ -2006,6 +2044,8 @@ typedef enum Tox_Err_File_Control {
|
|||||||
|
|
||||||
} Tox_Err_File_Control;
|
} Tox_Err_File_Control;
|
||||||
|
|
||||||
|
const char *tox_err_file_control_to_string(Tox_Err_File_Control value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sends a file control command to a friend for a given file transfer.
|
* @brief Sends a file control command to a friend for a given file transfer.
|
||||||
@ -2082,6 +2122,8 @@ typedef enum Tox_Err_File_Seek {
|
|||||||
|
|
||||||
} Tox_Err_File_Seek;
|
} Tox_Err_File_Seek;
|
||||||
|
|
||||||
|
const char *tox_err_file_seek_to_string(Tox_Err_File_Seek value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sends a file seek control command to a friend for a given file transfer.
|
* @brief Sends a file seek control command to a friend for a given file transfer.
|
||||||
@ -2120,6 +2162,8 @@ typedef enum Tox_Err_File_Get {
|
|||||||
|
|
||||||
} Tox_Err_File_Get;
|
} Tox_Err_File_Get;
|
||||||
|
|
||||||
|
const char *tox_err_file_get_to_string(Tox_Err_File_Get value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copy the file id associated to the file transfer to a byte array.
|
* @brief Copy the file id associated to the file transfer to a byte array.
|
||||||
@ -2177,6 +2221,8 @@ typedef enum Tox_Err_File_Send {
|
|||||||
|
|
||||||
} Tox_Err_File_Send;
|
} Tox_Err_File_Send;
|
||||||
|
|
||||||
|
const char *tox_err_file_send_to_string(Tox_Err_File_Send value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a file transmission request.
|
* @brief Send a file transmission request.
|
||||||
@ -2291,6 +2337,8 @@ typedef enum Tox_Err_File_Send_Chunk {
|
|||||||
|
|
||||||
} Tox_Err_File_Send_Chunk;
|
} Tox_Err_File_Send_Chunk;
|
||||||
|
|
||||||
|
const char *tox_err_file_send_chunk_to_string(Tox_Err_File_Send_Chunk value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a chunk of file data to a friend.
|
* @brief Send a chunk of file data to a friend.
|
||||||
@ -2438,6 +2486,8 @@ typedef enum Tox_Conference_Type {
|
|||||||
|
|
||||||
} Tox_Conference_Type;
|
} Tox_Conference_Type;
|
||||||
|
|
||||||
|
const char *tox_conference_type_to_string(Tox_Conference_Type value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The invitation will remain valid until the inviting friend goes offline
|
* The invitation will remain valid until the inviting friend goes offline
|
||||||
@ -2571,6 +2621,8 @@ typedef enum Tox_Err_Conference_New {
|
|||||||
|
|
||||||
} Tox_Err_Conference_New;
|
} Tox_Err_Conference_New;
|
||||||
|
|
||||||
|
const char *tox_err_conference_new_to_string(Tox_Err_Conference_New value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a new conference.
|
* @brief Creates a new conference.
|
||||||
@ -2597,6 +2649,8 @@ typedef enum Tox_Err_Conference_Delete {
|
|||||||
|
|
||||||
} Tox_Err_Conference_Delete;
|
} Tox_Err_Conference_Delete;
|
||||||
|
|
||||||
|
const char *tox_err_conference_delete_to_string(Tox_Err_Conference_Delete value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function deletes a conference.
|
* @brief This function deletes a conference.
|
||||||
@ -2634,6 +2688,8 @@ typedef enum Tox_Err_Conference_Peer_Query {
|
|||||||
|
|
||||||
} Tox_Err_Conference_Peer_Query;
|
} Tox_Err_Conference_Peer_Query;
|
||||||
|
|
||||||
|
const char *tox_err_conference_peer_query_to_string(Tox_Err_Conference_Peer_Query value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the number of online peers in the conference.
|
* @brief Return the number of online peers in the conference.
|
||||||
@ -2742,6 +2798,8 @@ typedef enum Tox_Err_Conference_Set_Max_Offline {
|
|||||||
|
|
||||||
} Tox_Err_Conference_Set_Max_Offline;
|
} Tox_Err_Conference_Set_Max_Offline;
|
||||||
|
|
||||||
|
const char *tox_err_conference_set_max_offline_to_string(Tox_Err_Conference_Set_Max_Offline value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set maximum number of offline peers to store, overriding the default.
|
* @brief Set maximum number of offline peers to store, overriding the default.
|
||||||
@ -2773,6 +2831,8 @@ typedef enum Tox_Err_Conference_Invite {
|
|||||||
|
|
||||||
} Tox_Err_Conference_Invite;
|
} Tox_Err_Conference_Invite;
|
||||||
|
|
||||||
|
const char *tox_err_conference_invite_to_string(Tox_Err_Conference_Invite value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Invites a friend to a conference.
|
* @brief Invites a friend to a conference.
|
||||||
@ -2824,6 +2884,8 @@ typedef enum Tox_Err_Conference_Join {
|
|||||||
|
|
||||||
} Tox_Err_Conference_Join;
|
} Tox_Err_Conference_Join;
|
||||||
|
|
||||||
|
const char *tox_err_conference_join_to_string(Tox_Err_Conference_Join value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Joins a conference that the client has been invited to.
|
* @brief Joins a conference that the client has been invited to.
|
||||||
@ -2874,6 +2936,8 @@ typedef enum Tox_Err_Conference_Send_Message {
|
|||||||
|
|
||||||
} Tox_Err_Conference_Send_Message;
|
} Tox_Err_Conference_Send_Message;
|
||||||
|
|
||||||
|
const char *tox_err_conference_send_message_to_string(Tox_Err_Conference_Send_Message value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a text chat message to the conference.
|
* @brief Send a text chat message to the conference.
|
||||||
@ -2921,6 +2985,8 @@ typedef enum Tox_Err_Conference_Title {
|
|||||||
|
|
||||||
} Tox_Err_Conference_Title;
|
} Tox_Err_Conference_Title;
|
||||||
|
|
||||||
|
const char *tox_err_conference_title_to_string(Tox_Err_Conference_Title value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the length of the conference title.
|
* @brief Return the length of the conference title.
|
||||||
@ -3000,6 +3066,8 @@ typedef enum Tox_Err_Conference_Get_Type {
|
|||||||
|
|
||||||
} Tox_Err_Conference_Get_Type;
|
} Tox_Err_Conference_Get_Type;
|
||||||
|
|
||||||
|
const char *tox_err_conference_get_type_to_string(Tox_Err_Conference_Get_Type value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the type (text or A/V) for the conference.
|
* @brief Get the type (text or A/V) for the conference.
|
||||||
@ -3037,6 +3105,8 @@ typedef enum Tox_Err_Conference_By_Id {
|
|||||||
|
|
||||||
} Tox_Err_Conference_By_Id;
|
} Tox_Err_Conference_By_Id;
|
||||||
|
|
||||||
|
const char *tox_err_conference_by_id_to_string(Tox_Err_Conference_By_Id value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the conference number associated with the specified id.
|
* @brief Return the conference number associated with the specified id.
|
||||||
@ -3078,6 +3148,8 @@ typedef enum Tox_Err_Conference_By_Uid {
|
|||||||
|
|
||||||
} Tox_Err_Conference_By_Uid;
|
} Tox_Err_Conference_By_Uid;
|
||||||
|
|
||||||
|
const char *tox_err_conference_by_uid_to_string(Tox_Err_Conference_By_Uid value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the conference number associated with the specified uid.
|
* @brief Return the conference number associated with the specified uid.
|
||||||
@ -3141,6 +3213,8 @@ typedef enum Tox_Err_Friend_Custom_Packet {
|
|||||||
|
|
||||||
} Tox_Err_Friend_Custom_Packet;
|
} Tox_Err_Friend_Custom_Packet;
|
||||||
|
|
||||||
|
const char *tox_err_friend_custom_packet_to_string(Tox_Err_Friend_Custom_Packet value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a custom lossy packet to a friend.
|
* @brief Send a custom lossy packet to a friend.
|
||||||
@ -3237,6 +3311,8 @@ typedef enum Tox_Err_Get_Port {
|
|||||||
|
|
||||||
} Tox_Err_Get_Port;
|
} Tox_Err_Get_Port;
|
||||||
|
|
||||||
|
const char *tox_err_get_port_to_string(Tox_Err_Get_Port value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Writes the temporary DHT public key of this instance to a byte array.
|
* @brief Writes the temporary DHT public key of this instance to a byte array.
|
||||||
@ -3382,6 +3458,8 @@ typedef enum Tox_Group_Privacy_State {
|
|||||||
|
|
||||||
} Tox_Group_Privacy_State;
|
} Tox_Group_Privacy_State;
|
||||||
|
|
||||||
|
const char *tox_group_privacy_state_to_string(Tox_Group_Privacy_State value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the state of the group topic lock.
|
* Represents the state of the group topic lock.
|
||||||
@ -3400,6 +3478,8 @@ typedef enum Tox_Group_Topic_Lock {
|
|||||||
|
|
||||||
} Tox_Group_Topic_Lock;
|
} Tox_Group_Topic_Lock;
|
||||||
|
|
||||||
|
const char *tox_group_topic_lock_to_string(Tox_Group_Topic_Lock value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the group voice state, which determines which Group Roles have permission to speak
|
* Represents the group voice state, which determines which Group Roles have permission to speak
|
||||||
* in the group chat. The voice state does not have any effect private messages or topic setting.
|
* in the group chat. The voice state does not have any effect private messages or topic setting.
|
||||||
@ -3421,6 +3501,8 @@ typedef enum Tox_Group_Voice_State {
|
|||||||
TOX_GROUP_VOICE_STATE_FOUNDER,
|
TOX_GROUP_VOICE_STATE_FOUNDER,
|
||||||
} Tox_Group_Voice_State;
|
} Tox_Group_Voice_State;
|
||||||
|
|
||||||
|
const char *tox_group_voice_state_to_string(Tox_Group_Voice_State value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents group roles.
|
* Represents group roles.
|
||||||
*
|
*
|
||||||
@ -3453,6 +3535,8 @@ typedef enum Tox_Group_Role {
|
|||||||
|
|
||||||
} Tox_Group_Role;
|
} Tox_Group_Role;
|
||||||
|
|
||||||
|
const char *tox_group_role_to_string(Tox_Group_Role value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -3498,6 +3582,8 @@ typedef enum Tox_Err_Group_New {
|
|||||||
|
|
||||||
} Tox_Err_Group_New;
|
} Tox_Err_Group_New;
|
||||||
|
|
||||||
|
const char *tox_err_group_new_to_string(Tox_Err_Group_New value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new group chat.
|
* Creates a new group chat.
|
||||||
@ -3564,6 +3650,8 @@ typedef enum Tox_Err_Group_Join {
|
|||||||
|
|
||||||
} Tox_Err_Group_Join;
|
} Tox_Err_Group_Join;
|
||||||
|
|
||||||
|
const char *tox_err_group_join_to_string(Tox_Err_Group_Join value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Joins a group chat with specified Chat ID.
|
* Joins a group chat with specified Chat ID.
|
||||||
@ -3599,6 +3687,8 @@ typedef enum Tox_Err_Group_Is_Connected {
|
|||||||
|
|
||||||
} Tox_Err_Group_Is_Connected;
|
} Tox_Err_Group_Is_Connected;
|
||||||
|
|
||||||
|
const char *tox_err_group_is_connected_to_string(Tox_Err_Group_Is_Connected value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the group chat is currently connected or attempting to connect to other peers
|
* Returns true if the group chat is currently connected or attempting to connect to other peers
|
||||||
@ -3626,6 +3716,8 @@ typedef enum Tox_Err_Group_Disconnect {
|
|||||||
TOX_ERR_GROUP_DISCONNECT_ALREADY_DISCONNECTED,
|
TOX_ERR_GROUP_DISCONNECT_ALREADY_DISCONNECTED,
|
||||||
} Tox_Err_Group_Disconnect;
|
} Tox_Err_Group_Disconnect;
|
||||||
|
|
||||||
|
const char *tox_err_group_disconnect_to_string(Tox_Err_Group_Disconnect value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnects from a group chat while retaining the group state and credentials.
|
* Disconnects from a group chat while retaining the group state and credentials.
|
||||||
@ -3655,6 +3747,8 @@ typedef enum Tox_Err_Group_Reconnect {
|
|||||||
|
|
||||||
} Tox_Err_Group_Reconnect;
|
} Tox_Err_Group_Reconnect;
|
||||||
|
|
||||||
|
const char *tox_err_group_reconnect_to_string(Tox_Err_Group_Reconnect value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconnects to a group.
|
* Reconnects to a group.
|
||||||
@ -3691,6 +3785,8 @@ typedef enum Tox_Err_Group_Leave {
|
|||||||
TOX_ERR_GROUP_LEAVE_FAIL_SEND,
|
TOX_ERR_GROUP_LEAVE_FAIL_SEND,
|
||||||
} Tox_Err_Group_Leave;
|
} Tox_Err_Group_Leave;
|
||||||
|
|
||||||
|
const char *tox_err_group_leave_to_string(Tox_Err_Group_Leave value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Leaves a group.
|
* Leaves a group.
|
||||||
@ -3735,6 +3831,8 @@ typedef enum Tox_Err_Group_Self_Query {
|
|||||||
|
|
||||||
} Tox_Err_Group_Self_Query;
|
} Tox_Err_Group_Self_Query;
|
||||||
|
|
||||||
|
const char *tox_err_group_self_query_to_string(Tox_Err_Group_Self_Query value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error codes for self name setting.
|
* Error codes for self name setting.
|
||||||
@ -3768,6 +3866,8 @@ typedef enum Tox_Err_Group_Self_Name_Set {
|
|||||||
|
|
||||||
} Tox_Err_Group_Self_Name_Set;
|
} Tox_Err_Group_Self_Name_Set;
|
||||||
|
|
||||||
|
const char *tox_err_group_self_name_set_to_string(Tox_Err_Group_Self_Name_Set value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the client's nickname for the group instance designated by the given group number.
|
* Set the client's nickname for the group instance designated by the given group number.
|
||||||
@ -3831,6 +3931,8 @@ typedef enum Tox_Err_Group_Self_Status_Set {
|
|||||||
|
|
||||||
} Tox_Err_Group_Self_Status_Set;
|
} Tox_Err_Group_Self_Status_Set;
|
||||||
|
|
||||||
|
const char *tox_err_group_self_status_set_to_string(Tox_Err_Group_Self_Status_Set value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the client's status for the group instance. Status must be a Tox_User_Status.
|
* Set the client's status for the group instance. Status must be a Tox_User_Status.
|
||||||
@ -3906,6 +4008,8 @@ typedef enum Tox_Err_Group_Peer_Query {
|
|||||||
|
|
||||||
} Tox_Err_Group_Peer_Query;
|
} Tox_Err_Group_Peer_Query;
|
||||||
|
|
||||||
|
const char *tox_err_group_peer_query_to_string(Tox_Err_Group_Peer_Query value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the length of the peer's name. If the group number or ID is invalid, the
|
* Return the length of the peer's name. If the group number or ID is invalid, the
|
||||||
@ -4054,6 +4158,8 @@ typedef enum Tox_Err_Group_State_Queries {
|
|||||||
|
|
||||||
} Tox_Err_Group_State_Queries;
|
} Tox_Err_Group_State_Queries;
|
||||||
|
|
||||||
|
const char *tox_err_group_state_queries_to_string(Tox_Err_Group_State_Queries value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error codes for group topic setting.
|
* Error codes for group topic setting.
|
||||||
@ -4097,6 +4203,8 @@ typedef enum Tox_Err_Group_Topic_Set {
|
|||||||
|
|
||||||
} Tox_Err_Group_Topic_Set;
|
} Tox_Err_Group_Topic_Set;
|
||||||
|
|
||||||
|
const char *tox_err_group_topic_set_to_string(Tox_Err_Group_Topic_Set value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the group topic and broadcast it to the rest of the group.
|
* Set the group topic and broadcast it to the rest of the group.
|
||||||
@ -4384,6 +4492,8 @@ typedef enum Tox_Err_Group_Send_Message {
|
|||||||
|
|
||||||
} Tox_Err_Group_Send_Message;
|
} Tox_Err_Group_Send_Message;
|
||||||
|
|
||||||
|
const char *tox_err_group_send_message_to_string(Tox_Err_Group_Send_Message value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a text chat message to the group.
|
* Send a text chat message to the group.
|
||||||
@ -4458,6 +4568,8 @@ typedef enum Tox_Err_Group_Send_Private_Message {
|
|||||||
|
|
||||||
} Tox_Err_Group_Send_Private_Message;
|
} Tox_Err_Group_Send_Private_Message;
|
||||||
|
|
||||||
|
const char *tox_err_group_send_private_message_to_string(Tox_Err_Group_Send_Private_Message value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a text chat message to the specified peer in the specified group.
|
* Send a text chat message to the specified peer in the specified group.
|
||||||
@ -4516,6 +4628,8 @@ typedef enum Tox_Err_Group_Send_Custom_Packet {
|
|||||||
|
|
||||||
} Tox_Err_Group_Send_Custom_Packet;
|
} Tox_Err_Group_Send_Custom_Packet;
|
||||||
|
|
||||||
|
const char *tox_err_group_send_custom_packet_to_string(Tox_Err_Group_Send_Custom_Packet value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a custom packet to the group.
|
* Send a custom packet to the group.
|
||||||
@ -4592,6 +4706,8 @@ typedef enum Tox_Err_Group_Send_Custom_Private_Packet {
|
|||||||
|
|
||||||
} Tox_Err_Group_Send_Custom_Private_Packet;
|
} Tox_Err_Group_Send_Custom_Private_Packet;
|
||||||
|
|
||||||
|
const char *tox_err_group_send_custom_private_packet_to_string(Tox_Err_Group_Send_Custom_Private_Packet value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a custom private packet to a designated peer in the group.
|
* Send a custom private packet to a designated peer in the group.
|
||||||
*
|
*
|
||||||
@ -4743,6 +4859,8 @@ typedef enum Tox_Err_Group_Invite_Friend {
|
|||||||
|
|
||||||
} Tox_Err_Group_Invite_Friend;
|
} Tox_Err_Group_Invite_Friend;
|
||||||
|
|
||||||
|
const char *tox_err_group_invite_friend_to_string(Tox_Err_Group_Invite_Friend value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invite a friend to a group.
|
* Invite a friend to a group.
|
||||||
@ -4801,6 +4919,8 @@ typedef enum Tox_Err_Group_Invite_Accept {
|
|||||||
|
|
||||||
} Tox_Err_Group_Invite_Accept;
|
} Tox_Err_Group_Invite_Accept;
|
||||||
|
|
||||||
|
const char *tox_err_group_invite_accept_to_string(Tox_Err_Group_Invite_Accept value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accept an invite to a group chat that the client previously received from a friend. The invite
|
* Accept an invite to a group chat that the client previously received from a friend. The invite
|
||||||
@ -4891,6 +5011,8 @@ typedef enum Tox_Group_Exit_Type {
|
|||||||
|
|
||||||
} Tox_Group_Exit_Type;
|
} Tox_Group_Exit_Type;
|
||||||
|
|
||||||
|
const char *tox_group_exit_type_to_string(Tox_Group_Exit_Type value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param group_number The group number of the group in which a peer has left.
|
* @param group_number The group number of the group in which a peer has left.
|
||||||
@ -4951,6 +5073,8 @@ typedef enum Tox_Group_Join_Fail {
|
|||||||
|
|
||||||
} Tox_Group_Join_Fail;
|
} Tox_Group_Join_Fail;
|
||||||
|
|
||||||
|
const char *tox_group_join_fail_to_string(Tox_Group_Join_Fail value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param group_number The group number of the group for which the join has failed.
|
* @param group_number The group number of the group for which the join has failed.
|
||||||
@ -5014,6 +5138,8 @@ typedef enum Tox_Err_Group_Founder_Set_Password {
|
|||||||
|
|
||||||
} Tox_Err_Group_Founder_Set_Password;
|
} Tox_Err_Group_Founder_Set_Password;
|
||||||
|
|
||||||
|
const char *tox_err_group_founder_set_password_to_string(Tox_Err_Group_Founder_Set_Password value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set or unset the group password.
|
* Set or unset the group password.
|
||||||
@ -5070,6 +5196,8 @@ typedef enum Tox_Err_Group_Founder_Set_Topic_Lock {
|
|||||||
|
|
||||||
} Tox_Err_Group_Founder_Set_Topic_Lock;
|
} Tox_Err_Group_Founder_Set_Topic_Lock;
|
||||||
|
|
||||||
|
const char *tox_err_group_founder_set_topic_lock_to_string(Tox_Err_Group_Founder_Set_Topic_Lock value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the group topic lock state.
|
* Set the group topic lock state.
|
||||||
@ -5123,6 +5251,8 @@ typedef enum Tox_Err_Group_Founder_Set_Voice_State {
|
|||||||
|
|
||||||
} Tox_Err_Group_Founder_Set_Voice_State;
|
} Tox_Err_Group_Founder_Set_Voice_State;
|
||||||
|
|
||||||
|
const char *tox_err_group_founder_set_voice_state_to_string(Tox_Err_Group_Founder_Set_Voice_State value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the group voice state.
|
* Set the group voice state.
|
||||||
*
|
*
|
||||||
@ -5175,6 +5305,8 @@ typedef enum Tox_Err_Group_Founder_Set_Privacy_State {
|
|||||||
|
|
||||||
} Tox_Err_Group_Founder_Set_Privacy_State;
|
} Tox_Err_Group_Founder_Set_Privacy_State;
|
||||||
|
|
||||||
|
const char *tox_err_group_founder_set_privacy_state_to_string(Tox_Err_Group_Founder_Set_Privacy_State value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the group privacy state.
|
* Set the group privacy state.
|
||||||
*
|
*
|
||||||
@ -5227,6 +5359,8 @@ typedef enum Tox_Err_Group_Founder_Set_Peer_Limit {
|
|||||||
|
|
||||||
} Tox_Err_Group_Founder_Set_Peer_Limit;
|
} Tox_Err_Group_Founder_Set_Peer_Limit;
|
||||||
|
|
||||||
|
const char *tox_err_group_founder_set_peer_limit_to_string(Tox_Err_Group_Founder_Set_Peer_Limit value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the group peer limit.
|
* Set the group peer limit.
|
||||||
@ -5275,6 +5409,8 @@ typedef enum Tox_Err_Group_Set_Ignore {
|
|||||||
|
|
||||||
} Tox_Err_Group_Set_Ignore;
|
} Tox_Err_Group_Set_Ignore;
|
||||||
|
|
||||||
|
const char *tox_err_group_set_ignore_to_string(Tox_Err_Group_Set_Ignore value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore or unignore a peer.
|
* Ignore or unignore a peer.
|
||||||
@ -5329,6 +5465,8 @@ typedef enum Tox_Err_Group_Mod_Set_Role {
|
|||||||
|
|
||||||
} Tox_Err_Group_Mod_Set_Role;
|
} Tox_Err_Group_Mod_Set_Role;
|
||||||
|
|
||||||
|
const char *tox_err_group_mod_set_role_to_string(Tox_Err_Group_Mod_Set_Role value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a peer's role.
|
* Set a peer's role.
|
||||||
@ -5385,6 +5523,8 @@ typedef enum Tox_Err_Group_Mod_Kick_Peer {
|
|||||||
|
|
||||||
} Tox_Err_Group_Mod_Kick_Peer;
|
} Tox_Err_Group_Mod_Kick_Peer;
|
||||||
|
|
||||||
|
const char *tox_err_group_mod_kick_peer_to_string(Tox_Err_Group_Mod_Kick_Peer value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kick a peer.
|
* Kick a peer.
|
||||||
@ -5428,6 +5568,8 @@ typedef enum Tox_Group_Mod_Event {
|
|||||||
|
|
||||||
} Tox_Group_Mod_Event;
|
} Tox_Group_Mod_Event;
|
||||||
|
|
||||||
|
const char *tox_group_mod_event_to_string(Tox_Group_Mod_Event value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param group_number The group number of the group the event is intended for.
|
* @param group_number The group number of the group the event is intended for.
|
||||||
|
1394
toxcore/tox_api.c
1394
toxcore/tox_api.c
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "ccompat.h"
|
#include "ccompat.h"
|
||||||
|
#include "group_chats.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "tox_struct.h"
|
#include "tox_struct.h"
|
||||||
@ -166,3 +167,57 @@ uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox){
|
|||||||
return num_cap;
|
return num_cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef VANILLA_NACL
|
||||||
|
size_t tox_group_peer_get_ip_address_size(const Tox *tox, uint32_t group_number, uint32_t peer_id,
|
||||||
|
Tox_Err_Group_Peer_Query *error)
|
||||||
|
{
|
||||||
|
assert(tox != nullptr);
|
||||||
|
|
||||||
|
tox_lock(tox);
|
||||||
|
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
|
||||||
|
|
||||||
|
if (chat == nullptr) {
|
||||||
|
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_GROUP_NOT_FOUND);
|
||||||
|
tox_unlock(tox);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int ret = gc_get_peer_ip_address_size(chat, peer_id);
|
||||||
|
tox_unlock(tox);
|
||||||
|
|
||||||
|
if (ret == -1) {
|
||||||
|
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_PEER_NOT_FOUND);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tox_group_peer_get_ip_address(const Tox *tox, uint32_t group_number, uint32_t peer_id, uint8_t *ip_addr,
|
||||||
|
Tox_Err_Group_Peer_Query *error)
|
||||||
|
{
|
||||||
|
assert(tox != nullptr);
|
||||||
|
|
||||||
|
tox_lock(tox);
|
||||||
|
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
|
||||||
|
|
||||||
|
if (chat == nullptr) {
|
||||||
|
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_GROUP_NOT_FOUND);
|
||||||
|
tox_unlock(tox);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int ret = gc_get_peer_ip_address(chat, peer_id, ip_addr);
|
||||||
|
tox_unlock(tox);
|
||||||
|
|
||||||
|
if (ret == -1) {
|
||||||
|
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_PEER_NOT_FOUND);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* VANILLA_NACL */
|
||||||
|
@ -156,6 +156,51 @@ uint16_t tox_dht_get_num_closelist(const Tox *tox);
|
|||||||
*/
|
*/
|
||||||
uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox);
|
uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox);
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* :: DHT groupchat queries.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum size of a peer IP address string.
|
||||||
|
*/
|
||||||
|
#define TOX_GROUP_PEER_IP_STRING_MAX_LENGTH 96
|
||||||
|
|
||||||
|
uint32_t tox_group_peer_ip_string_max_length(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length of the peer's IP address in string form. If the group number or ID
|
||||||
|
* is invalid, the return value is unspecified.
|
||||||
|
*
|
||||||
|
* @param group_number The group number of the group we wish to query.
|
||||||
|
* @param peer_id The ID of the peer whose IP address length we want to retrieve.
|
||||||
|
*/
|
||||||
|
size_t tox_group_peer_get_ip_address_size(const Tox *tox, uint32_t group_number, uint32_t peer_id,
|
||||||
|
Tox_Err_Group_Peer_Query *error);
|
||||||
|
/**
|
||||||
|
* Write the IP address associated with the designated peer_id for the designated group number
|
||||||
|
* to ip_addr.
|
||||||
|
*
|
||||||
|
* If the peer is forcing TCP connections a placeholder value will be written instead,
|
||||||
|
* indicating that their real IP address is unknown to us.
|
||||||
|
*
|
||||||
|
* If `peer_id` designates ourself, it will write either our own IP address or a placeholder value,
|
||||||
|
* depending on whether or not we're forcing TCP connections.
|
||||||
|
*
|
||||||
|
* Call tox_group_peer_get_ip_address_size to determine the allocation size for the `ip_addr` parameter.
|
||||||
|
*
|
||||||
|
* @param group_number The group number of the group we wish to query.
|
||||||
|
* @param peer_id The ID of the peer whose public key we wish to retrieve.
|
||||||
|
* @param ip_addr A valid memory region large enough to store the IP address string.
|
||||||
|
* If this parameter is NULL, this function call has no effect.
|
||||||
|
*
|
||||||
|
* @return true on success.
|
||||||
|
*/
|
||||||
|
bool tox_group_peer_get_ip_address(const Tox *tox, uint32_t group_number, uint32_t peer_id, uint8_t *ip_addr,
|
||||||
|
Tox_Err_Group_Peer_Query *error);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -130,6 +130,17 @@ bool tox_unpack_user_status(Bin_Unpack *bu, Tox_User_Status *val)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Tox_Group_Privacy_State tox_group_privacy_state_from_int(uint32_t value)
|
||||||
|
{
|
||||||
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
return TOX_GROUP_PRIVACY_STATE_PUBLIC;
|
||||||
|
case 1:
|
||||||
|
return TOX_GROUP_PRIVACY_STATE_PRIVATE;
|
||||||
|
default:
|
||||||
|
return TOX_GROUP_PRIVACY_STATE_PRIVATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
bool tox_unpack_group_privacy_state(Bin_Unpack *bu, Tox_Group_Privacy_State *val)
|
bool tox_unpack_group_privacy_state(Bin_Unpack *bu, Tox_Group_Privacy_State *val)
|
||||||
{
|
{
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
@ -138,10 +149,22 @@ bool tox_unpack_group_privacy_state(Bin_Unpack *bu, Tox_Group_Privacy_State *val
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = (Tox_Group_Privacy_State)u32;
|
*val = tox_group_privacy_state_from_int(u32);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
static Tox_Group_Voice_State tox_group_voice_state_from_int(uint32_t value)
|
||||||
|
{
|
||||||
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
return TOX_GROUP_VOICE_STATE_ALL;
|
||||||
|
case 1:
|
||||||
|
return TOX_GROUP_VOICE_STATE_MODERATOR;
|
||||||
|
case 2:
|
||||||
|
return TOX_GROUP_VOICE_STATE_FOUNDER;
|
||||||
|
default:
|
||||||
|
return TOX_GROUP_VOICE_STATE_FOUNDER;
|
||||||
|
}
|
||||||
|
}
|
||||||
bool tox_unpack_group_voice_state(Bin_Unpack *bu, Tox_Group_Voice_State *val)
|
bool tox_unpack_group_voice_state(Bin_Unpack *bu, Tox_Group_Voice_State *val)
|
||||||
{
|
{
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
@ -150,10 +173,21 @@ bool tox_unpack_group_voice_state(Bin_Unpack *bu, Tox_Group_Voice_State *val)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = (Tox_Group_Voice_State)u32;
|
*val = tox_group_voice_state_from_int(u32);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Tox_Group_Topic_Lock tox_group_topic_lock_from_int(uint32_t value)
|
||||||
|
{
|
||||||
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
return TOX_GROUP_TOPIC_LOCK_ENABLED;
|
||||||
|
case 1:
|
||||||
|
return TOX_GROUP_TOPIC_LOCK_DISABLED;
|
||||||
|
default:
|
||||||
|
return TOX_GROUP_TOPIC_LOCK_ENABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
bool tox_unpack_group_topic_lock(Bin_Unpack *bu, Tox_Group_Topic_Lock *val)
|
bool tox_unpack_group_topic_lock(Bin_Unpack *bu, Tox_Group_Topic_Lock *val)
|
||||||
{
|
{
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
@ -162,10 +196,23 @@ bool tox_unpack_group_topic_lock(Bin_Unpack *bu, Tox_Group_Topic_Lock *val)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = (Tox_Group_Topic_Lock)u32;
|
*val = tox_group_topic_lock_from_int(u32);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Tox_Group_Join_Fail tox_group_join_fail_from_int(uint32_t value)
|
||||||
|
{
|
||||||
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
return TOX_GROUP_JOIN_FAIL_PEER_LIMIT;
|
||||||
|
case 1:
|
||||||
|
return TOX_GROUP_JOIN_FAIL_INVALID_PASSWORD;
|
||||||
|
case 2:
|
||||||
|
return TOX_GROUP_JOIN_FAIL_UNKNOWN;
|
||||||
|
default:
|
||||||
|
return TOX_GROUP_JOIN_FAIL_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
bool tox_unpack_group_join_fail(Bin_Unpack *bu, Tox_Group_Join_Fail *val)
|
bool tox_unpack_group_join_fail(Bin_Unpack *bu, Tox_Group_Join_Fail *val)
|
||||||
{
|
{
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
@ -174,10 +221,25 @@ bool tox_unpack_group_join_fail(Bin_Unpack *bu, Tox_Group_Join_Fail *val)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = (Tox_Group_Join_Fail)u32;
|
*val = tox_group_join_fail_from_int(u32);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Tox_Group_Mod_Event tox_group_mod_event_from_int(uint32_t value)
|
||||||
|
{
|
||||||
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
return TOX_GROUP_MOD_EVENT_KICK;
|
||||||
|
case 1:
|
||||||
|
return TOX_GROUP_MOD_EVENT_OBSERVER;
|
||||||
|
case 2:
|
||||||
|
return TOX_GROUP_MOD_EVENT_USER;
|
||||||
|
case 3:
|
||||||
|
return TOX_GROUP_MOD_EVENT_MODERATOR;
|
||||||
|
default:
|
||||||
|
return TOX_GROUP_MOD_EVENT_MODERATOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
bool tox_unpack_group_mod_event(Bin_Unpack *bu, Tox_Group_Mod_Event *val)
|
bool tox_unpack_group_mod_event(Bin_Unpack *bu, Tox_Group_Mod_Event *val)
|
||||||
{
|
{
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
@ -186,10 +248,29 @@ bool tox_unpack_group_mod_event(Bin_Unpack *bu, Tox_Group_Mod_Event *val)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = (Tox_Group_Mod_Event)u32;
|
*val = tox_group_mod_event_from_int(u32);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Tox_Group_Exit_Type tox_group_exit_type_from_int(uint32_t value)
|
||||||
|
{
|
||||||
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
return TOX_GROUP_EXIT_TYPE_QUIT;
|
||||||
|
case 1:
|
||||||
|
return TOX_GROUP_EXIT_TYPE_TIMEOUT;
|
||||||
|
case 2:
|
||||||
|
return TOX_GROUP_EXIT_TYPE_DISCONNECTED;
|
||||||
|
case 3:
|
||||||
|
return TOX_GROUP_EXIT_TYPE_SELF_DISCONNECTED;
|
||||||
|
case 4:
|
||||||
|
return TOX_GROUP_EXIT_TYPE_KICK;
|
||||||
|
case 5:
|
||||||
|
return TOX_GROUP_EXIT_TYPE_SYNC_ERROR;
|
||||||
|
default:
|
||||||
|
return TOX_GROUP_EXIT_TYPE_QUIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
bool tox_unpack_group_exit_type(Bin_Unpack *bu, Tox_Group_Exit_Type *val)
|
bool tox_unpack_group_exit_type(Bin_Unpack *bu, Tox_Group_Exit_Type *val)
|
||||||
{
|
{
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
@ -198,6 +279,6 @@ bool tox_unpack_group_exit_type(Bin_Unpack *bu, Tox_Group_Exit_Type *val)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = (Tox_Group_Exit_Type)u32;
|
*val = tox_group_exit_type_from_int(u32);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,10 @@ int64_t min_s64(int64_t a, int64_t b)
|
|||||||
return a < b ? a : b;
|
return a < b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t max_u08(uint8_t a, uint8_t b)
|
||||||
|
{
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
uint16_t max_u16(uint16_t a, uint16_t b)
|
uint16_t max_u16(uint16_t a, uint16_t b)
|
||||||
{
|
{
|
||||||
return a > b ? a : b;
|
return a > b ? a : b;
|
||||||
|
@ -53,6 +53,7 @@ int16_t min_s16(int16_t a, int16_t b);
|
|||||||
int32_t min_s32(int32_t a, int32_t b);
|
int32_t min_s32(int32_t a, int32_t b);
|
||||||
int64_t min_s64(int64_t a, int64_t b);
|
int64_t min_s64(int64_t a, int64_t b);
|
||||||
|
|
||||||
|
uint8_t max_u08(uint8_t a, uint8_t b);
|
||||||
uint16_t max_u16(uint16_t a, uint16_t b);
|
uint16_t max_u16(uint16_t a, uint16_t b);
|
||||||
uint32_t max_u32(uint32_t a, uint32_t b);
|
uint32_t max_u32(uint32_t a, uint32_t b);
|
||||||
uint64_t max_u64(uint64_t a, uint64_t b);
|
uint64_t max_u64(uint64_t a, uint64_t b);
|
||||||
|
Loading…
Reference in New Issue
Block a user