diff options
58 files changed, 3163 insertions, 2440 deletions
diff --git a/protocols/Tox/libtox/docs/CHANGELOG.md b/protocols/Tox/libtox/docs/CHANGELOG.md index b659e7a6d7..f0a24be0d8 100644 --- a/protocols/Tox/libtox/docs/CHANGELOG.md +++ b/protocols/Tox/libtox/docs/CHANGELOG.md @@ -1,22 +1,72 @@ +## v0.2.3 + +### Merged PRs: + +- [#951](https://github.com/TokTok/c-toxcore/pull/951) Only run astyle if the astyle binary exists. +- [#950](https://github.com/TokTok/c-toxcore/pull/950) Remove utils.c and utils.h from toxencryptsave build. +- [#949](https://github.com/TokTok/c-toxcore/pull/949) Fixes to the imported sodium sources to compile without warnings. +- [#948](https://github.com/TokTok/c-toxcore/pull/948) Add a MAX_HOSTNAME_LENGTH constant. +- [#947](https://github.com/TokTok/c-toxcore/pull/947) Remove the format test. +- [#937](https://github.com/TokTok/c-toxcore/pull/937) Add new Circle CI configuration. +- [#935](https://github.com/TokTok/c-toxcore/pull/935) Add a test for double conference invite. +- [#933](https://github.com/TokTok/c-toxcore/pull/933) Add Logger to various net_crypto functions, and add `const` to Logger where possible. +- [#931](https://github.com/TokTok/c-toxcore/pull/931) Avoid conditional-uninitialised warning for tcp test. +- [#930](https://github.com/TokTok/c-toxcore/pull/930) Disable UDP when proxy is enabled. +- [#928](https://github.com/TokTok/c-toxcore/pull/928) Use clang-format for C++ code. +- [#927](https://github.com/TokTok/c-toxcore/pull/927) Add assertions to bootstrap tests for correct connection type. +- [#926](https://github.com/TokTok/c-toxcore/pull/926) Make NULL options behave the same as default options. +- [#925](https://github.com/TokTok/c-toxcore/pull/925) Add tests for what happens when passing an invalid proxy host. +- [#924](https://github.com/TokTok/c-toxcore/pull/924) Make the net_crypto connection state an enum. +- [#922](https://github.com/TokTok/c-toxcore/pull/922) Clarify/Improve test_some test +- [#921](https://github.com/TokTok/c-toxcore/pull/921) Beginnings of a TCP_test.c overhaul +- [#920](https://github.com/TokTok/c-toxcore/pull/920) Add test for creating multiple conferences in one tox. +- [#918](https://github.com/TokTok/c-toxcore/pull/918) Merge irungentoo/master into toktok +- [#917](https://github.com/TokTok/c-toxcore/pull/917) Add random testing program. +- [#916](https://github.com/TokTok/c-toxcore/pull/916) Fix linking with address sanitizer. +- [#915](https://github.com/TokTok/c-toxcore/pull/915) Remove resource_leak_test. +- [#914](https://github.com/TokTok/c-toxcore/pull/914) Make dht_test more stable. +- [#913](https://github.com/TokTok/c-toxcore/pull/913) Minor cleanup: return early on error condition. +- [#906](https://github.com/TokTok/c-toxcore/pull/906) Sort bazel build file according to buildifier standard. +- [#905](https://github.com/TokTok/c-toxcore/pull/905) In DEBUG mode, make toxcore crash on signed integer overflow. +- [#902](https://github.com/TokTok/c-toxcore/pull/902) Log only the filename, not the full path in LOGGER. +- [#899](https://github.com/TokTok/c-toxcore/pull/899) Fix macOS macro because of GNU Mach +- [#898](https://github.com/TokTok/c-toxcore/pull/898) Fix enumeration of Crypto_Connection instances +- [#897](https://github.com/TokTok/c-toxcore/pull/897) Fix ipport_isset: port 0 is not a valid port. +- [#894](https://github.com/TokTok/c-toxcore/pull/894) Fix logging related crash in bootstrap node +- [#893](https://github.com/TokTok/c-toxcore/pull/893) Fix bootstrap crashes, still +- [#892](https://github.com/TokTok/c-toxcore/pull/892) Add empty logger to DHT bootstrap daemons. +- [#887](https://github.com/TokTok/c-toxcore/pull/887) Fix FreeBSD build on Travis +- [#884](https://github.com/TokTok/c-toxcore/pull/884) Fix the often call of event tox_friend_connection_status +- [#883](https://github.com/TokTok/c-toxcore/pull/883) Make toxcore compile on BSD +- [#878](https://github.com/TokTok/c-toxcore/pull/878) fix DHT_bootstrap key loading +- [#877](https://github.com/TokTok/c-toxcore/pull/877) Add minitox to under "Other resources" section in the README +- [#875](https://github.com/TokTok/c-toxcore/pull/875) Make bootstrap daemon use toxcore's version +- [#867](https://github.com/TokTok/c-toxcore/pull/867) Improve network error reporting on Windows +- [#841](https://github.com/TokTok/c-toxcore/pull/841) Only check full rtp offset if RTP_LARGE_FRAME is set +- [#823](https://github.com/TokTok/c-toxcore/pull/823) Finish @Diadlo's network Family abstraction. +- [#822](https://github.com/TokTok/c-toxcore/pull/822) Move system header includes from network.h to network.c + ## v0.2.2 ### Merged PRs: -- [#872](https://github.com/TokTok/c-toxcore/issues/872) Restrict packet kinds that can be sent through onion path. -- [#864](https://github.com/TokTok/c-toxcore/issues/864) CMake warn if libconfig not found -- [#863](https://github.com/TokTok/c-toxcore/issues/863) Remove broken and unmaintained scripts. -- [#859](https://github.com/TokTok/c-toxcore/issues/859) Add clarifying comment to cryptpacket_received function. -- [#857](https://github.com/TokTok/c-toxcore/issues/857) Avoid the use of rand() in tests. -- [#846](https://github.com/TokTok/c-toxcore/issues/846) Disallow stderr logger by default. -- [#845](https://github.com/TokTok/c-toxcore/issues/845) Fix coveralls reporting. -- [#844](https://github.com/TokTok/c-toxcore/issues/844) Add COVERAGE cmake flag for clang. -- [#825](https://github.com/TokTok/c-toxcore/issues/825) Add default stderr logger for logging to nullptr. -- [#824](https://github.com/TokTok/c-toxcore/issues/824) Simplify sendpacket function, deduplicate some logic. -- [#809](https://github.com/TokTok/c-toxcore/issues/809) Remove the use of the 'hh' format specifier. -- [#801](https://github.com/TokTok/c-toxcore/issues/801) Add logging to the onion_test. -- [#797](https://github.com/TokTok/c-toxcore/issues/797) Move struct DHT_Friend into DHT.c. +- [#872](https://github.com/TokTok/c-toxcore/pull/872) Restrict packet kinds that can be sent through onion path. +- [#864](https://github.com/TokTok/c-toxcore/pull/864) CMake warn if libconfig not found +- [#863](https://github.com/TokTok/c-toxcore/pull/863) Remove broken and unmaintained scripts. +- [#862](https://github.com/TokTok/c-toxcore/pull/862) Release v0.2.2 +- [#859](https://github.com/TokTok/c-toxcore/pull/859) Add clarifying comment to cryptpacket_received function. +- [#857](https://github.com/TokTok/c-toxcore/pull/857) Avoid the use of rand() in tests. +- [#852](https://github.com/TokTok/c-toxcore/pull/852) bugfix build error on MacOS +- [#846](https://github.com/TokTok/c-toxcore/pull/846) Disallow stderr logger by default. +- [#845](https://github.com/TokTok/c-toxcore/pull/845) Fix coveralls reporting. +- [#844](https://github.com/TokTok/c-toxcore/pull/844) Add COVERAGE cmake flag for clang. +- [#825](https://github.com/TokTok/c-toxcore/pull/825) Add default stderr logger for logging to nullptr. +- [#824](https://github.com/TokTok/c-toxcore/pull/824) Simplify sendpacket function, deduplicate some logic. +- [#809](https://github.com/TokTok/c-toxcore/pull/809) Remove the use of the 'hh' format specifier. +- [#801](https://github.com/TokTok/c-toxcore/pull/801) Add logging to the onion_test. +- [#797](https://github.com/TokTok/c-toxcore/pull/797) Move struct DHT_Friend into DHT.c. ## v0.2.1 diff --git a/protocols/Tox/libtox/docs/README.md b/protocols/Tox/libtox/docs/README.md index 5b38f37277..8e45ec00d7 100644 --- a/protocols/Tox/libtox/docs/README.md +++ b/protocols/Tox/libtox/docs/README.md @@ -1,7 +1,7 @@ -# ![Project Tox](https://raw.github.com/TokTok/toxcore/master/other/tox.png "Project Tox") +# ![Project Tox](https://raw.github.com/TokTok/c-toxcore/master/other/tox.png "Project Tox") **Current build status:** [![Build Status](https://travis-ci.org/TokTok/c-toxcore.svg?branch=master)](https://travis-ci.org/TokTok/c-toxcore) -**Current Coverage:** [![Coverage Status](https://coveralls.io/repos/github/TokTok/toxcore/badge.svg?branch=master)](https://coveralls.io/github/TokTok/toxcore?branch=master) +**Current Coverage:** [![Coverage Status](https://coveralls.io/repos/github/TokTok/c-toxcore/badge.svg?branch=master)](https://coveralls.io/github/TokTok/c-toxcore?branch=master) [**Website**](https://tox.chat) **|** [**Wiki**](https://wiki.tox.chat/) **|** [**Blog**](https://blog.tox.chat/) **|** [**FAQ**](https://wiki.tox.chat/doku.php?id=users:faq) **|** [**Binaries/Downloads**](https://wiki.tox.chat/Binaries) **|** [**Clients**](https://wiki.tox.chat/doku.php?id=clients) **|** [**Compiling**](/INSTALL.md) **|** [**Toxcore's Projects**](https://github.com/TokTok/c-toxcore/projects) @@ -171,3 +171,4 @@ the API documentation in [toxcore/tox.h](toxcore/tox.h) for more information. ### Other resources - [Another echo bot](https://wiki.tox.chat/developers/client_examples/echo_bot) +- [minitox](https://github.com/hqwrong/minitox) (A minimal tox client) diff --git a/protocols/Tox/libtox/src/libtox.def b/protocols/Tox/libtox/src/libtox.def index c8c75b267b..5540b08ac3 100644 --- a/protocols/Tox/libtox/src/libtox.def +++ b/protocols/Tox/libtox/src/libtox.def @@ -148,3 +148,5 @@ tox_version_is_compatible tox_version_major tox_version_minor tox_version_patch +tox_conference_get_uid +tox_conference_by_uid diff --git a/protocols/Tox/libtox/src/toxcore/DHT.c b/protocols/Tox/libtox/src/toxcore/DHT.c index f611fca61d..01fcfd66b1 100644 --- a/protocols/Tox/libtox/src/toxcore/DHT.c +++ b/protocols/Tox/libtox/src/toxcore/DHT.c @@ -3,7 +3,7 @@ */ /* - * Copyright © 2016-2017 The TokTok team. + * Copyright © 2016-2018 The TokTok team. * Copyright © 2013 Tox project. * * This file is part of Tox, the free peer to peer instant messenger. @@ -29,11 +29,15 @@ #include "LAN_discovery.h" #include "logger.h" +#include "mono_time.h" #include "network.h" #include "ping.h" +#include "state.h" #include "util.h" #include <assert.h> +#include <stdlib.h> +#include <string.h> /* The timeout after which a node is discarded completely. */ #define KILL_NODE_TIMEOUT (BAD_NODE_TIMEOUT + PING_INTERVAL) @@ -57,7 +61,11 @@ /* Number of get node requests to send to quickly find close nodes. */ #define MAX_BOOTSTRAP_TIMES 5 -#define ARRAY_SIZE(ARR) (sizeof (ARR) / sizeof (ARR)[0]) +typedef struct DHT_Friend_Callback { + dht_ip_cb *ip_callback; + void *data; + int32_t number; +} DHT_Friend_Callback; struct DHT_Friend { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -72,18 +80,19 @@ struct DHT_Friend { NAT nat; uint16_t lock_count; - struct { - void (*ip_callback)(void *, int32_t, IP_Port); - void *data; - int32_t number; - } callbacks[DHT_FRIEND_MAX_LOCKS]; + DHT_Friend_Callback callbacks[DHT_FRIEND_MAX_LOCKS]; Node_format to_bootstrap[MAX_SENT_NODES]; unsigned int num_to_bootstrap; }; +typedef struct Cryptopacket_Handler { + cryptopacket_handler_cb *function; + void *object; +} Cryptopacket_Handler; + struct DHT { - Logger *log; + const Logger *log; Networking_Core *net; bool hole_punching_enabled; @@ -111,7 +120,7 @@ struct DHT { Ping_Array *dht_harden_ping_array; uint64_t last_run; - Cryptopacket_Handles cryptopackethandlers[256]; + Cryptopacket_Handler cryptopackethandlers[256]; Node_format to_bootstrap[MAX_CLOSE_TO_BOOTSTRAP_NODES]; unsigned int num_to_bootstrap; @@ -281,7 +290,7 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t /* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key * for packets that we receive. */ -void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *public_key) +void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *public_key) { get_shared_key(&dht->shared_keys_recv, shared_key, dht->self_secret_key, public_key); } @@ -289,7 +298,7 @@ void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *publi /* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key * for packets that we send. */ -void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *public_key) +void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *public_key) { get_shared_key(&dht->shared_keys_sent, shared_key, dht->self_secret_key, public_key); } @@ -383,20 +392,17 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke /* Return packet size of packed node with ip_family on success. * Return -1 on failure. */ -int packed_node_size(uint8_t ip_family) +int packed_node_size(Family ip_family) { - switch (ip_family) { - case TOX_AF_INET: - case TCP_INET: - return PACKED_NODE_SIZE_IP4; - - case TOX_AF_INET6: - case TCP_INET6: - return PACKED_NODE_SIZE_IP6; + if (net_family_is_ipv4(ip_family) || net_family_is_tcp_ipv4(ip_family)) { + return PACKED_NODE_SIZE_IP4; + } - default: - return -1; + if (net_family_is_ipv6(ip_family) || net_family_is_tcp_ipv6(ip_family)) { + return PACKED_NODE_SIZE_IP6; } + + return -1; } @@ -414,17 +420,17 @@ int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port) bool is_ipv4; uint8_t net_family; - if (ip_port->ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(ip_port->ip.family)) { // TODO(irungentoo): use functions to convert endianness is_ipv4 = true; net_family = TOX_AF_INET; - } else if (ip_port->ip.family == TCP_INET) { + } else if (net_family_is_tcp_ipv4(ip_port->ip.family)) { is_ipv4 = true; net_family = TOX_TCP_INET; - } else if (ip_port->ip.family == TOX_AF_INET6) { + } else if (net_family_is_ipv6(ip_port->ip.family)) { is_ipv4 = false; net_family = TOX_AF_INET6; - } else if (ip_port->ip.family == TCP_INET6) { + } else if (net_family_is_tcp_ipv6(ip_port->ip.family)) { is_ipv4 = false; net_family = TOX_TCP_INET6; } else { @@ -456,7 +462,7 @@ int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port) } } -static int DHT_create_packet(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], +static int dht_create_packet(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t *shared_key, const uint8_t type, uint8_t *plain, size_t plain_length, uint8_t *packet) { VLA(uint8_t, encrypted, plain_length + CRYPTO_MAC_SIZE); @@ -490,28 +496,28 @@ int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, uint8 } bool is_ipv4; - uint8_t host_family; + Family host_family; if (data[0] == TOX_AF_INET) { is_ipv4 = true; - host_family = TOX_AF_INET; + host_family = net_family_ipv4; } else if (data[0] == TOX_TCP_INET) { if (!tcp_enabled) { return -1; } is_ipv4 = true; - host_family = TCP_INET; + host_family = net_family_tcp_ipv4; } else if (data[0] == TOX_AF_INET6) { is_ipv4 = false; - host_family = TOX_AF_INET6; + host_family = net_family_ipv6; } else if (data[0] == TOX_TCP_INET6) { if (!tcp_enabled) { return -1; } is_ipv4 = false; - host_family = TCP_INET6; + host_family = net_family_tcp_ipv6; } else { return -1; } @@ -617,28 +623,30 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed * * return index or UINT32_MAX if not found. */ -#define INDEX_OF_PK \ - for (uint32_t i = 0; i < size; i++) { \ - if (id_equal(array[i].public_key, pk)) { \ - return i; \ - } \ - } \ - \ - return UINT32_MAX; +#define INDEX_OF_PK(array, size, pk) \ + do { \ + for (uint32_t i = 0; i < size; ++i) { \ + if (id_equal(array[i].public_key, pk)) { \ + return i; \ + } \ + } \ + \ + return UINT32_MAX; \ + } while (0) static uint32_t index_of_client_pk(const Client_data *array, uint32_t size, const uint8_t *pk) { - INDEX_OF_PK + INDEX_OF_PK(array, size, pk); } static uint32_t index_of_friend_pk(const DHT_Friend *array, uint32_t size, const uint8_t *pk) { - INDEX_OF_PK + INDEX_OF_PK(array, size, pk); } static uint32_t index_of_node_pk(const Node_format *array, uint32_t size, const uint8_t *pk) { - INDEX_OF_PK + INDEX_OF_PK(array, size, pk); } /* Find index of Client_data with ip_port equal to param ip_port. @@ -648,8 +656,8 @@ static uint32_t index_of_node_pk(const Node_format *array, uint32_t size, const static uint32_t index_of_client_ip_port(const Client_data *array, uint32_t size, const IP_Port *ip_port) { for (uint32_t i = 0; i < size; ++i) { - if ((ip_port->ip.family == TOX_AF_INET && ipport_equal(&array[i].assoc4.ip_port, ip_port)) || - (ip_port->ip.family == TOX_AF_INET6 && ipport_equal(&array[i].assoc6.ip_port, ip_port))) { + if ((net_family_is_ipv4(ip_port->ip.family) && ipport_equal(&array[i].assoc4.ip_port, ip_port)) || + (net_family_is_ipv6(ip_port->ip.family) && ipport_equal(&array[i].assoc6.ip_port, ip_port))) { return i; } } @@ -659,15 +667,15 @@ static uint32_t index_of_client_ip_port(const Client_data *array, uint32_t size, /* Update ip_port of client if it's needed. */ -static void update_client(Logger *log, int index, Client_data *client, IP_Port ip_port) +static void update_client(const Logger *log, int index, Client_data *client, IP_Port ip_port) { IPPTsPng *assoc; int ip_version; - if (ip_port.ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(ip_port.ip.family)) { assoc = &client->assoc4; ip_version = 4; - } else if (ip_port.ip.family == TOX_AF_INET6) { + } else if (net_family_is_ipv6(ip_port.ip.family)) { assoc = &client->assoc6; ip_version = 6; } else { @@ -699,7 +707,7 @@ static void update_client(Logger *log, int index, Client_data *client, IP_Port i * * return True(1) or False(0) */ -static int client_or_ip_port_in_list(Logger *log, Client_data *list, uint16_t length, const uint8_t *public_key, +static int client_or_ip_port_in_list(const Logger *log, Client_data *list, uint16_t length, const uint8_t *public_key, IP_Port ip_port) { const uint64_t temp_time = unix_time(); @@ -725,7 +733,7 @@ static int client_or_ip_port_in_list(Logger *log, Client_data *list, uint16_t le IPPTsPng *assoc; int ip_version; - if (ip_port.ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(ip_port.ip.family)) { assoc = &list[index].assoc4; ip_version = 4; } else { @@ -789,13 +797,13 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_ Family sa_family, const Client_data *client_list, uint32_t client_list_length, uint32_t *num_nodes_ptr, uint8_t is_LAN, uint8_t want_good) { - if ((sa_family != TOX_AF_INET) && (sa_family != TOX_AF_INET6) && (sa_family != 0)) { + if (!net_family_is_ipv4(sa_family) && !net_family_is_ipv6(sa_family) && !net_family_is_unspec(sa_family)) { return; } uint32_t num_nodes = *num_nodes_ptr; - for (uint32_t i = 0; i < client_list_length; i++) { + for (uint32_t i = 0; i < client_list_length; ++i) { const Client_data *const client = &client_list[i]; /* node already in list? */ @@ -805,9 +813,9 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_ const IPPTsPng *ipptp = nullptr; - if (sa_family == TOX_AF_INET) { + if (net_family_is_ipv4(sa_family)) { ipptp = &client->assoc4; - } else if (sa_family == TOX_AF_INET6) { + } else if (net_family_is_ipv6(sa_family)) { ipptp = &client->assoc6; } else if (client->assoc4.timestamp >= client->assoc6.timestamp) { ipptp = &client->assoc4; @@ -833,7 +841,7 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_ if (num_nodes < MAX_SENT_NODES) { memcpy(nodes_list[num_nodes].public_key, client->public_key, CRYPTO_PUBLIC_KEY_SIZE); nodes_list[num_nodes].ip_port = ipptp->ip_port; - num_nodes++; + ++num_nodes; } else { add_to_list(nodes_list, MAX_SENT_NODES, client->public_key, ipptp->ip_port, public_key); } @@ -884,11 +892,21 @@ int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *node return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family, is_LAN, want_good); } -typedef struct { +typedef struct DHT_Cmp_data { const uint8_t *base_public_key; Client_data entry; } DHT_Cmp_data; +static bool assoc_timeout(const IPPTsPng *assoc) +{ + return is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT); +} + +static bool incorrect_hardening(const IPPTsPng *assoc) +{ + return hardening_correct(&assoc->hardening) != HARDENING_ALL_OK; +} + static int cmp_dht_entry(const void *a, const void *b) { DHT_Cmp_data cmp1, cmp2; @@ -898,10 +916,8 @@ static int cmp_dht_entry(const void *a, const void *b) const Client_data entry2 = cmp2.entry; const uint8_t *cmp_public_key = cmp1.base_public_key; -#define ASSOC_TIMEOUT(assoc) is_timeout((assoc).timestamp, BAD_NODE_TIMEOUT) - - bool t1 = ASSOC_TIMEOUT(entry1.assoc4) && ASSOC_TIMEOUT(entry1.assoc6); - bool t2 = ASSOC_TIMEOUT(entry2.assoc4) && ASSOC_TIMEOUT(entry2.assoc6); + bool t1 = assoc_timeout(&entry1.assoc4) && assoc_timeout(&entry1.assoc6); + bool t2 = assoc_timeout(&entry2.assoc4) && assoc_timeout(&entry2.assoc6); if (t1 && t2) { return 0; @@ -915,10 +931,8 @@ static int cmp_dht_entry(const void *a, const void *b) return 1; } -#define INCORRECT_HARDENING(assoc) hardening_correct(&(assoc).hardening) != HARDENING_ALL_OK - - t1 = INCORRECT_HARDENING(entry1.assoc4) && INCORRECT_HARDENING(entry1.assoc6); - t2 = INCORRECT_HARDENING(entry2.assoc4) && INCORRECT_HARDENING(entry2.assoc6); + t1 = incorrect_hardening(&entry1.assoc4) && incorrect_hardening(&entry1.assoc6); + t2 = incorrect_hardening(&entry2.assoc4) && incorrect_hardening(&entry2.assoc6); if (t1 && !t2) { return -1; @@ -959,14 +973,14 @@ static void sort_client_list(Client_data *list, unsigned int length, const uint8 // comparison function can use it as the base of comparison. VLA(DHT_Cmp_data, cmp_list, length); - for (uint32_t i = 0; i < length; i++) { + for (uint32_t i = 0; i < length; ++i) { cmp_list[i].base_public_key = comp_public_key; cmp_list[i].entry = list[i]; } qsort(cmp_list, length, sizeof(DHT_Cmp_data), cmp_dht_entry); - for (uint32_t i = 0; i < length; i++) { + for (uint32_t i = 0; i < length; ++i) { list[i] = cmp_list[i].entry; } } @@ -976,7 +990,7 @@ static void update_client_with_reset(Client_data *client, const IP_Port *ip_port IPPTsPng *ipptp_write = nullptr; IPPTsPng *ipptp_clear = nullptr; - if (ip_port->ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(ip_port->ip.family)) { ipptp_write = &client->assoc4; ipptp_clear = &client->assoc6; } else { @@ -1014,7 +1028,7 @@ static bool replace_all(Client_data *list, IP_Port ip_port, const uint8_t *comp_public_key) { - if ((ip_port.ip.family != TOX_AF_INET) && (ip_port.ip.family != TOX_AF_INET6)) { + if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) { return false; } @@ -1085,7 +1099,7 @@ static bool is_pk_in_client_list(const Client_data *list, unsigned int client_li return 0; } - const IPPTsPng *assoc = ip_port.ip.family == TOX_AF_INET + const IPPTsPng *assoc = net_family_is_ipv4(ip_port.ip.family) ? &list[index].assoc4 : &list[index].assoc6; @@ -1178,8 +1192,8 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key) uint32_t used = 0; /* convert IPv4-in-IPv6 to IPv4 */ - if ((ip_port.ip.family == TOX_AF_INET6) && IPV6_IPV4_IN_V6(ip_port.ip.ip.v6)) { - ip_port.ip.family = TOX_AF_INET; + if (net_family_is_ipv6(ip_port.ip.family) && ipv6_ipv4_in_v6(ip_port.ip.ip.v6)) { + ip_port.ip.family = net_family_ipv4; ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3]; } @@ -1191,7 +1205,7 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key) /* add_to_close should be called only if !in_list (don't extract to variable) */ if (in_close_list || add_to_close(dht, public_key, ip_port, 0)) { - used++; + ++used; } DHT_Friend *friend_foundip = nullptr; @@ -1209,7 +1223,7 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key) friend_foundip = dht_friend; } - used++; + ++used; } } @@ -1239,9 +1253,9 @@ static bool update_client_data(Client_data *array, size_t size, IP_Port ip_port, Client_data *const data = &array[index]; IPPTsPng *assoc; - if (ip_port.ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(ip_port.ip.family)) { assoc = &data->assoc4; - } else if (ip_port.ip.family == TOX_AF_INET6) { + } else if (net_family_is_ipv6(ip_port.ip.family)) { assoc = &data->assoc6; } else { return true; @@ -1258,8 +1272,8 @@ static bool update_client_data(Client_data *array, size_t size, IP_Port ip_port, static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const uint8_t *nodepublic_key) { /* convert IPv4-in-IPv6 to IPv4 */ - if ((ip_port.ip.family == TOX_AF_INET6) && IPV6_IPV4_IN_V6(ip_port.ip.ip.v6)) { - ip_port.ip.family = TOX_AF_INET; + if (net_family_is_ipv6(ip_port.ip.family) && ipv6_ipv4_in_v6(ip_port.ip.ip.v6)) { + ip_port.ip.family = net_family_ipv4; ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3]; } @@ -1316,9 +1330,9 @@ static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, &ping_id, sizeof(ping_id)); uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; - DHT_get_shared_key_sent(dht, shared_key, public_key); + dht_get_shared_key_sent(dht, shared_key, public_key); - const int len = DHT_create_packet(dht->self_public_key, shared_key, NET_PACKET_GET_NODES, + const int len = dht_create_packet(dht->self_public_key, shared_key, NET_PACKET_GET_NODES, plain, sizeof(plain), data); if (len != sizeof(data)) { @@ -1344,7 +1358,8 @@ static int sendnodes_ipv6(const DHT *dht, IP_Port ip_port, const uint8_t *public const size_t node_format_size = sizeof(Node_format); Node_format nodes_list[MAX_SENT_NODES]; - const uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, 0, ip_is_lan(ip_port.ip) == 0, 1); + const uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, net_family_unspec, ip_is_lan(ip_port.ip) == 0, + 1); VLA(uint8_t, plain, 1 + node_format_size * MAX_SENT_NODES + length); @@ -1364,7 +1379,7 @@ static int sendnodes_ipv6(const DHT *dht, IP_Port ip_port, const uint8_t *public const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE; VLA(uint8_t, data, 1 + nodes_length + length + crypto_size); - const int len = DHT_create_packet(dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6, + const int len = dht_create_packet(dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6, plain, 1 + nodes_length + length, data); if (len != SIZEOF_VLA(data)) { @@ -1392,7 +1407,7 @@ static int handle_getnodes(void *object, IP_Port source, const uint8_t *packet, uint8_t plain[CRYPTO_NODE_SIZE]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; - DHT_get_shared_key_recv(dht, shared_key, packet + 1); + dht_get_shared_key_recv(dht, shared_key, packet + 1); const int len = decrypt_data_symmetric( shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, @@ -1462,7 +1477,7 @@ static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *pa VLA(uint8_t, plain, 1 + data_size + sizeof(uint64_t)); uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; - DHT_get_shared_key_sent(dht, shared_key, packet + 1); + dht_get_shared_key_sent(dht, shared_key, packet + 1); const int len = decrypt_data_symmetric( shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, @@ -1525,7 +1540,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *pa return 0; } - for (uint32_t i = 0; i < num_nodes; i++) { + for (uint32_t i = 0; i < num_nodes; ++i) { if (ipport_isset(&plain_nodes[i].ip_port)) { ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key, plain_nodes[i].ip_port); returnedip_ports(dht, plain_nodes[i].ip_port, plain_nodes[i].public_key, packet + 1); @@ -1538,7 +1553,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *pa /*----------------------------------------------------------------------------------*/ /*------------------------END of packet handling functions--------------------------*/ -int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void *data, int32_t number, IP_Port), +int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback, void *data, int32_t number, uint16_t *lock_count) { const uint32_t friend_num = index_of_friend_pk(dht->friends_list, dht->num_friends, public_key); @@ -1576,7 +1591,7 @@ int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void memset(dht_friend, 0, sizeof(DHT_Friend)); memcpy(dht_friend->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); - dht_friend->nat.NATping_id = random_u64(); + dht_friend->nat.nat_ping_id = random_u64(); ++dht->num_friends; lock_num = dht_friend->lock_count; @@ -1589,12 +1604,13 @@ int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void *lock_count = lock_num + 1; } - dht_friend->num_to_bootstrap = get_close_nodes(dht, dht_friend->public_key, dht_friend->to_bootstrap, 0, 1, 0); + dht_friend->num_to_bootstrap = get_close_nodes(dht, dht_friend->public_key, dht_friend->to_bootstrap, net_family_unspec, + 1, 0); return 0; } -int DHT_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count) +int dht_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count) { const uint32_t friend_num = index_of_friend_pk(dht->friends_list, dht->num_friends, public_key); @@ -1638,7 +1654,7 @@ int DHT_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count) } /* TODO(irungentoo): Optimize this. */ -int DHT_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port) +int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port) { ip_reset(&ip_port->ip); ip_port->port = 0; @@ -1657,10 +1673,10 @@ int DHT_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port) } const Client_data *const client = &frnd->client_list[client_index]; - const IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4 }; + const IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4, nullptr }; - for (size_t i = 0; i < ARRAY_SIZE(assocs); i++) { - const IPPTsPng *const assoc = assocs[i]; + for (const IPPTsPng * const *it = assocs; *it; ++it) { + const IPPTsPng *const assoc = *it; if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) { *ip_port = assoc->ip_port; @@ -1684,18 +1700,20 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co unsigned int sort = 0; bool sort_ok = false; - for (uint32_t i = 0; i < list_count; i++) { + for (uint32_t i = 0; i < list_count; ++i) { /* If node is not dead. */ Client_data *client = &list[i]; - IPPTsPng *assocs[] = { &client->assoc6, &client->assoc4 }; + IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4, nullptr }; + + uint32_t j = 0; - for (size_t j = 0; j < ARRAY_SIZE(assocs); j++) { - IPPTsPng *assoc = assocs[j]; + for (IPPTsPng * const *it = assocs; *it; ++it, ++j) { + IPPTsPng *const assoc = *it; if (!is_timeout(assoc->timestamp, KILL_NODE_TIMEOUT)) { sort = 0; - not_kill++; + ++not_kill; if (is_timeout(assoc->last_pinged, PING_INTERVAL)) { getnodes(dht, assoc->ip_port, client->public_key, public_key, nullptr); @@ -1742,7 +1760,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list. */ -static void do_DHT_friends(DHT *dht) +static void do_dht_friends(DHT *dht) { for (size_t i = 0; i < dht->num_friends; ++i) { DHT_Friend *const dht_friend = &dht->friends_list[i]; @@ -1787,13 +1805,13 @@ static void do_Close(DHT *dht) * KILL_NODE_TIMEOUT, so we at least keep trying pings */ const uint64_t badonly = unix_time() - BAD_NODE_TIMEOUT; - for (size_t i = 0; i < LCLIENT_LIST; i++) { + for (size_t i = 0; i < LCLIENT_LIST; ++i) { Client_data *const client = &dht->close_clientlist[i]; - IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4 }; + IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4, nullptr }; - for (size_t j = 0; j < ARRAY_SIZE(assocs); j++) { - IPPTsPng *const assoc = assocs[j]; + for (IPPTsPng * const *it = assocs; *it; ++it) { + IPPTsPng *const assoc = *it; if (assoc->timestamp) { assoc->timestamp = badonly; @@ -1802,16 +1820,16 @@ static void do_Close(DHT *dht) } } -void DHT_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, const uint8_t *which_id) +void dht_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, const uint8_t *which_id) { getnodes(dht, *from_ipp, from_id, which_id, nullptr); } -void DHT_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key) +void dht_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key) { getnodes(dht, ip_port, public_key, dht->self_public_key, nullptr); } -int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, +int dht_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, const uint8_t *public_key) { IP_Port ip_port_v64; @@ -1821,18 +1839,18 @@ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable if (ipv6enabled) { /* setup for getting BOTH: an IPv6 AND an IPv4 address */ - ip_port_v64.ip.family = TOX_AF_UNSPEC; + ip_port_v64.ip.family = net_family_unspec; ip_reset(&ip_port_v4.ip); ip_extra = &ip_port_v4.ip; } if (addr_resolve_or_parse_ip(address, &ip_port_v64.ip, ip_extra)) { ip_port_v64.port = port; - DHT_bootstrap(dht, ip_port_v64, public_key); + dht_bootstrap(dht, ip_port_v64, public_key); if ((ip_extra != nullptr) && ip_isset(ip_extra)) { ip_port_v4.port = port; - DHT_bootstrap(dht, ip_port_v4, public_key); + dht_bootstrap(dht, ip_port_v4, public_key); } return 1; @@ -1850,10 +1868,10 @@ int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packe for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { if (id_equal(public_key, dht->close_clientlist[i].public_key)) { const Client_data *const client = &dht->close_clientlist[i]; - const IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4 }; + const IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4, nullptr }; - for (size_t j = 0; j < ARRAY_SIZE(assocs); j++) { - const IPPTsPng *const assoc = assocs[j]; + for (const IPPTsPng * const *it = assocs; *it; ++it) { + const IPPTsPng *const assoc = *it; if (ip_isset(&assoc->ip_port.ip)) { return sendpacket(dht->net, assoc->ip_port, packet, length); @@ -1975,10 +1993,10 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack } const Client_data *const client = &dht_friend->client_list[i]; - const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6 }; + const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6, nullptr }; - for (size_t j = 0; j < ARRAY_SIZE(assocs); j++) { - const IPPTsPng *const assoc = assocs[j]; + for (const IPPTsPng * const *it = assocs; *it; ++it) { + const IPPTsPng *const assoc = *it; /* If ip is not zero and node is good. */ if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { @@ -2017,10 +2035,10 @@ static int routeone_tofriend(DHT *dht, const uint8_t *friend_id, const uint8_t * for (uint32_t i = 0; i < MAX_FRIEND_CLIENTS; ++i) { const Client_data *const client = &dht_friend->client_list[i]; - const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6 }; + const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6, nullptr }; - for (size_t j = 0; j < ARRAY_SIZE(assocs); j++) { - const IPPTsPng *assoc = assocs[j]; + for (const IPPTsPng * const *it = assocs; *it; ++it) { + const IPPTsPng *const assoc = *it; /* If ip is not zero and node is good. */ if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { @@ -2100,13 +2118,13 @@ static int handle_NATping(void *object, IP_Port source, const uint8_t *source_pu if (packet[0] == NAT_PING_REQUEST) { /* 1 is reply */ send_NATping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE); - dht_friend->nat.recvNATping_timestamp = unix_time(); + dht_friend->nat.recv_nat_ping_timestamp = unix_time(); return 0; } if (packet[0] == NAT_PING_RESPONSE) { - if (dht_friend->nat.NATping_id == ping_id) { - dht_friend->nat.NATping_id = random_u64(); + if (dht_friend->nat.nat_ping_id == ping_id) { + dht_friend->nat.nat_ping_id = random_u64(); dht_friend->nat.hole_punching = 1; return 0; } @@ -2121,7 +2139,7 @@ static int handle_NATping(void *object, IP_Port source, const uint8_t *source_pu * * return ip of 0 if failure. */ -static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) +static IP nat_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) { IP zero; ip_reset(&zero); @@ -2153,7 +2171,7 @@ static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) * * return number of ports and puts the list of ports in portlist. */ -static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip) +static uint16_t nat_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip) { uint16_t num = 0; @@ -2238,16 +2256,16 @@ static void do_NAT(DHT *dht) continue; } - if (dht->friends_list[i].nat.NATping_timestamp + PUNCH_INTERVAL < temp_time) { - send_NATping(dht, dht->friends_list[i].public_key, dht->friends_list[i].nat.NATping_id, NAT_PING_REQUEST); - dht->friends_list[i].nat.NATping_timestamp = temp_time; + if (dht->friends_list[i].nat.nat_ping_timestamp + PUNCH_INTERVAL < temp_time) { + send_NATping(dht, dht->friends_list[i].public_key, dht->friends_list[i].nat.nat_ping_id, NAT_PING_REQUEST); + dht->friends_list[i].nat.nat_ping_timestamp = temp_time; } if (dht->friends_list[i].nat.hole_punching == 1 && dht->friends_list[i].nat.punching_timestamp + PUNCH_INTERVAL < temp_time && - dht->friends_list[i].nat.recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { + dht->friends_list[i].nat.recv_nat_ping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { - const IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); + const IP ip = nat_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); if (!ip_isset(&ip)) { continue; @@ -2260,7 +2278,7 @@ static void do_NAT(DHT *dht) } uint16_t port_list[MAX_FRIEND_CLIENTS]; - const uint16_t numports = NAT_getports(port_list, ip_list, num, ip); + const uint16_t numports = nat_getports(port_list, ip_list, num, ip); punch_holes(dht, ip, port_list, numports, i); dht->friends_list[i].nat.punching_timestamp = temp_time; @@ -2273,16 +2291,16 @@ static void do_NAT(DHT *dht) /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ #define DHT_HARDENING 0 -#define HARDREQ_DATA_SIZE 384 /* Attempt to prevent amplification/other attacks*/ +#define HARDREQ_DATA_SIZE 384 // Attempt to prevent amplification/other attacks -enum { +typedef enum Check_Type { CHECK_TYPE_ROUTE_REQ = 0, CHECK_TYPE_ROUTE_RES = 1, CHECK_TYPE_GETNODE_REQ = 2, CHECK_TYPE_GETNODE_RES = 3, CHECK_TYPE_TEST_REQ = 4, CHECK_TYPE_TEST_RES = 5, -}; +} Check_Type; #if DHT_HARDENING static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8_t *contents, uint16_t length) @@ -2348,11 +2366,11 @@ static IPPTsPng *get_closelist_IPPTsPng(DHT *dht, const uint8_t *public_key, Fam continue; } - if (sa_family == TOX_AF_INET) { + if (net_family_is_ipv4(sa_family)) { return &dht->close_clientlist[i].assoc4; } - if (sa_family == TOX_AF_INET6) { + if (net_family_is_ipv6(sa_family)) { return &dht->close_clientlist[i].assoc6; } } @@ -2577,10 +2595,10 @@ static void do_hardening(DHT *dht) if (i % 2 == 0) { cur_iptspng = &dht->close_clientlist[i / 2].assoc4; - sa_family = TOX_AF_INET; + sa_family = net_family_ipv4; } else { cur_iptspng = &dht->close_clientlist[i / 2].assoc6; - sa_family = TOX_AF_INET6; + sa_family = net_family_ipv6; } if (is_timeout(cur_iptspng->timestamp, BAD_NODE_TIMEOUT)) { @@ -2622,7 +2640,7 @@ static void do_hardening(DHT *dht) /*----------------------------------------------------------------------------------*/ -void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_callback cb, void *object) +void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_cb *cb, void *object) { dht->cryptopackethandlers[byte].function = cb; dht->cryptopackethandlers[byte].object = object; @@ -2672,7 +2690,7 @@ static int cryptopacket_handle(void *object, IP_Port source, const uint8_t *pack /*----------------------------------------------------------------------------------*/ -DHT *new_DHT(Logger *log, Networking_Core *net, bool holepunching_enabled) +DHT *new_dht(const Logger *log, Networking_Core *net, bool holepunching_enabled) { /* init time */ unix_time_update(); @@ -2695,7 +2713,7 @@ DHT *new_DHT(Logger *log, Networking_Core *net, bool holepunching_enabled) dht->ping = ping_new(dht); if (dht->ping == nullptr) { - kill_DHT(dht); + kill_dht(dht); return nullptr; } @@ -2714,8 +2732,8 @@ DHT *new_DHT(Logger *log, Networking_Core *net, bool holepunching_enabled) uint8_t random_key_bytes[CRYPTO_PUBLIC_KEY_SIZE]; random_bytes(random_key_bytes, sizeof(random_key_bytes)); - if (DHT_addfriend(dht, random_key_bytes, nullptr, nullptr, 0, nullptr) != 0) { - kill_DHT(dht); + if (dht_addfriend(dht, random_key_bytes, nullptr, nullptr, 0, nullptr) != 0) { + kill_dht(dht); return nullptr; } } @@ -2723,7 +2741,7 @@ DHT *new_DHT(Logger *log, Networking_Core *net, bool holepunching_enabled) return dht; } -void do_DHT(DHT *dht) +void do_dht(DHT *dht) { unix_time_update(); @@ -2731,13 +2749,13 @@ void do_DHT(DHT *dht) return; } - // Load friends/clients if first call to do_DHT + // Load friends/clients if first call to do_dht if (dht->loaded_num_nodes) { - DHT_connect_after_load(dht); + dht_connect_after_load(dht); } do_Close(dht); - do_DHT_friends(dht); + do_dht_friends(dht); do_NAT(dht); ping_iterate(dht->ping); #if DHT_HARDENING @@ -2746,7 +2764,7 @@ void do_DHT(DHT *dht) dht->last_run = unix_time(); } -void kill_DHT(DHT *dht) +void kill_dht(DHT *dht) { networking_registerhandler(dht->net, NET_PACKET_GET_NODES, nullptr, nullptr); networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, nullptr, nullptr); @@ -2770,7 +2788,7 @@ void kill_DHT(DHT *dht) #define MAX_SAVED_DHT_NODES (((DHT_FAKE_FRIEND_NUMBER * MAX_FRIEND_CLIENTS) + LCLIENT_LIST) * 2) /* Get the size of the DHT (for saving). */ -uint32_t DHT_size(const DHT *dht) +uint32_t dht_size(const DHT *dht) { uint32_t numv4 = 0; uint32_t numv6 = 0; @@ -2792,10 +2810,10 @@ uint32_t DHT_size(const DHT *dht) const uint32_t size32 = sizeof(uint32_t); const uint32_t sizesubhead = size32 * 2; - return size32 + sizesubhead + (packed_node_size(TOX_AF_INET) * numv4) + (packed_node_size(TOX_AF_INET6) * numv6); + return size32 + sizesubhead + packed_node_size(net_family_ipv4) * numv4 + packed_node_size(net_family_ipv6) * numv6; } -static uint8_t *DHT_save_subheader(uint8_t *data, uint32_t len, uint16_t type) +static uint8_t *dht_save_subheader(uint8_t *data, uint32_t len, uint16_t type) { host_to_lendian32(data, len); data += sizeof(uint32_t); @@ -2805,8 +2823,8 @@ static uint8_t *DHT_save_subheader(uint8_t *data, uint32_t len, uint16_t type) } -/* Save the DHT in data where data is an array of size DHT_size(). */ -void DHT_save(const DHT *dht, uint8_t *data) +/* Save the DHT in data where data is an array of size dht_size(). */ +void dht_save(const DHT *dht, uint8_t *data) { host_to_lendian32(data, DHT_STATE_COOKIE_GLOBAL); data += sizeof(uint32_t); @@ -2814,7 +2832,7 @@ void DHT_save(const DHT *dht, uint8_t *data) uint8_t *const old_data = data; /* get right offset. we write the actual header later. */ - data = DHT_save_subheader(data, 0, 0); + data = dht_save_subheader(data, 0, 0); Node_format clients[MAX_SAVED_DHT_NODES]; @@ -2852,14 +2870,14 @@ void DHT_save(const DHT *dht, uint8_t *data) } } - DHT_save_subheader(old_data, pack_nodes(data, sizeof(Node_format) * num, clients, num), DHT_STATE_TYPE_NODES); + dht_save_subheader(old_data, pack_nodes(data, sizeof(Node_format) * num, clients, num), DHT_STATE_TYPE_NODES); } -/* Bootstrap from this number of nodes every time DHT_connect_after_load() is called */ +/* Bootstrap from this number of nodes every time dht_connect_after_load() is called */ #define SAVE_BOOTSTAP_FREQUENCY 8 /* Start sending packets after DHT loaded_friends_list and loaded_clients_list are set */ -int DHT_connect_after_load(DHT *dht) +int dht_connect_after_load(DHT *dht) { if (dht == nullptr) { return -1; @@ -2870,7 +2888,7 @@ int DHT_connect_after_load(DHT *dht) } /* DHT is connected, stop. */ - if (DHT_non_lan_connected(dht)) { + if (dht_non_lan_connected(dht)) { free(dht->loaded_nodes_list); dht->loaded_nodes_list = nullptr; dht->loaded_num_nodes = 0; @@ -2879,14 +2897,14 @@ int DHT_connect_after_load(DHT *dht) for (uint32_t i = 0; i < dht->loaded_num_nodes && i < SAVE_BOOTSTAP_FREQUENCY; ++i) { const unsigned int index = dht->loaded_nodes_index % dht->loaded_num_nodes; - DHT_bootstrap(dht, dht->loaded_nodes_list[index].ip_port, dht->loaded_nodes_list[index].public_key); + dht_bootstrap(dht, dht->loaded_nodes_list[index].ip_port, dht->loaded_nodes_list[index].public_key); ++dht->loaded_nodes_index; } return 0; } -static int dht_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) +static State_Load_Status dht_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) { DHT *dht = (DHT *)outer; @@ -2917,7 +2935,7 @@ static int dht_load_state_callback(void *outer, const uint8_t *data, uint32_t le break; } - return 0; + return STATE_LOAD_STATUS_CONTINUE; } /* Load the DHT from data of size size. @@ -2925,7 +2943,7 @@ static int dht_load_state_callback(void *outer, const uint8_t *data, uint32_t le * return -1 if failure. * return 0 if success. */ -int DHT_load(DHT *dht, const uint8_t *data, uint32_t length) +int dht_load(DHT *dht, const uint8_t *data, uint32_t length) { const uint32_t cookie_len = sizeof(uint32_t); @@ -2934,7 +2952,7 @@ int DHT_load(DHT *dht, const uint8_t *data, uint32_t length) lendian_to_host32(&data32, data); if (data32 == DHT_STATE_COOKIE_GLOBAL) { - return load_state(dht_load_state_callback, dht->log, dht, data + cookie_len, + return state_load(dht->log, dht_load_state_callback, dht, data + cookie_len, length - cookie_len, DHT_STATE_COOKIE_TYPE); } } @@ -2945,7 +2963,7 @@ int DHT_load(DHT *dht, const uint8_t *data, uint32_t length) /* return false if we are not connected to the DHT. * return true if we are. */ -bool DHT_isconnected(const DHT *dht) +bool dht_isconnected(const DHT *dht) { unix_time_update(); @@ -2964,7 +2982,7 @@ bool DHT_isconnected(const DHT *dht) /* return false if we are not connected or only connected to lan peers with the DHT. * return true if we are. */ -bool DHT_non_lan_connected(const DHT *dht) +bool dht_non_lan_connected(const DHT *dht) { unix_time_update(); diff --git a/protocols/Tox/libtox/src/toxcore/DHT.h b/protocols/Tox/libtox/src/toxcore/DHT.h index 3c87804fdc..0852827c8d 100644 --- a/protocols/Tox/libtox/src/toxcore/DHT.h +++ b/protocols/Tox/libtox/src/toxcore/DHT.h @@ -64,10 +64,10 @@ #define MAX_CRYPTO_REQUEST_SIZE 1024 -#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */ -#define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */ +#define CRYPTO_PACKET_FRIEND_REQ 32 // Friend request crypto packet ID. +#define CRYPTO_PACKET_HARDENING 48 // Hardening crypto packet ID. #define CRYPTO_PACKET_DHTPK 156 -#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */ +#define CRYPTO_PACKET_NAT_PING 254 // NAT ping crypto packet ID. /* Create a request to peer. * send_public_key and send_secret_key are the pub/secret keys of the sender. @@ -89,12 +89,12 @@ int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_ke int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, uint8_t *request_id, const uint8_t *packet, uint16_t length); -typedef struct { +typedef struct IPPTs { IP_Port ip_port; uint64_t timestamp; } IPPTs; -typedef struct { +typedef struct Hardening { /* Node routes request correctly (true (1) or false/didn't check (0)) */ uint8_t routes_requests_ok; /* Time which we last checked this.*/ @@ -112,7 +112,7 @@ typedef struct { uint8_t testing_pingedid[CRYPTO_PUBLIC_KEY_SIZE]; } Hardening; -typedef struct { +typedef struct IPPTsPng { IP_Port ip_port; uint64_t timestamp; uint64_t last_pinged; @@ -123,7 +123,7 @@ typedef struct { uint64_t ret_timestamp; } IPPTsPng; -typedef struct { +typedef struct Client_data { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; IPPTsPng assoc4; IPPTsPng assoc6; @@ -131,7 +131,7 @@ typedef struct { /*----------------------------------------------------------------------------------*/ -typedef struct { +typedef struct NAT { /* 1 if currently hole punching, otherwise 0 */ uint8_t hole_punching; uint32_t punching_index; @@ -139,18 +139,17 @@ typedef struct { uint32_t punching_index2; uint64_t punching_timestamp; - uint64_t recvNATping_timestamp; - uint64_t NATping_id; - uint64_t NATping_timestamp; + uint64_t recv_nat_ping_timestamp; + uint64_t nat_ping_id; + uint64_t nat_ping_timestamp; } NAT; #define DHT_FRIEND_MAX_LOCKS 32 -typedef struct { +typedef struct Node_format { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; IP_Port ip_port; -} -Node_format; +} Node_format; typedef struct DHT_Friend DHT_Friend; @@ -160,7 +159,7 @@ const Client_data *dht_friend_client(const DHT_Friend *dht_friend, size_t index) /* Return packet size of packed node with ip_family on success. * Return -1 on failure. */ -int packed_node_size(uint8_t ip_family); +int packed_node_size(Family ip_family); /* Packs an IP_Port structure into data of max size length. * @@ -199,7 +198,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed #define MAX_KEYS_PER_SLOT 4 #define KEYS_TIMEOUT 600 -typedef struct { +typedef struct Shared_Key { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint32_t times_requested; @@ -207,19 +206,14 @@ typedef struct { uint64_t time_last_requested; } Shared_Key; -typedef struct { +typedef struct Shared_Keys { Shared_Key keys[256 * MAX_KEYS_PER_SLOT]; } Shared_Keys; /*----------------------------------------------------------------------------------*/ -typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, const uint8_t *source_pubkey, - const uint8_t *data, uint16_t len, void *userdata); - -typedef struct { - cryptopacket_handler_callback function; - void *object; -} Cryptopacket_Handles; +typedef int cryptopacket_handler_cb(void *object, IP_Port ip_port, const uint8_t *source_pubkey, + const uint8_t *data, uint16_t len, void *userdata); #define DHT_DEFINED typedef struct DHT DHT; @@ -252,14 +246,16 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t /* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key * for packets that we receive. */ -void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *public_key); +void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *public_key); /* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key * for packets that we send. */ -void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *public_key); +void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *public_key); + +void dht_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, const uint8_t *which_id); -void DHT_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, const uint8_t *which_id); +typedef void dht_ip_cb(void *object, int32_t number, IP_Port ip_port); /* Add a new friend to the friends list. * public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long. @@ -267,13 +263,13 @@ void DHT_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, con * ip_callback is the callback of a function that will be called when the ip address * is found along with arguments data and number. * - * lock_count will be set to a non zero number that must be passed to DHT_delfriend() + * lock_count will be set to a non zero number that must be passed to dht_delfriend() * to properly remove the callback. * * return 0 if success. * return -1 if failure (friends list is full). */ -int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void *data, int32_t number, IP_Port), +int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback, void *data, int32_t number, uint16_t *lock_count); /* Delete a friend from the friends list. @@ -282,20 +278,20 @@ int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void * return 0 if success. * return -1 if failure (public_key not in friends list). */ -int DHT_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count); +int dht_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count); /* Get ip of friend. * public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long. * ip must be 4 bytes long. * port must be 2 bytes long. * - * int DHT_getfriendip(DHT *dht, uint8_t *public_key, IP_Port *ip_port); + * int dht_getfriendip(DHT *dht, uint8_t *public_key, IP_Port *ip_port); * * return -1, -- if public_key does NOT refer to a friend * return 0, -- if public_key refers to a friend and we failed to find the friend (yet) * return 1, ip if public_key refers to a friend and we found him */ -int DHT_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port); +int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port); /* Compares pk1 and pk2 with pk. * @@ -341,7 +337,7 @@ uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num); uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num); /* Run this function at least a couple times per second (It's the main loop). */ -void do_DHT(DHT *dht); +void do_dht(DHT *dht); /* * Use these two functions to bootstrap the client. @@ -349,7 +345,7 @@ void do_DHT(DHT *dht); /* Sends a "get nodes" request to the given node with ip, port and public_key * to setup connections */ -void DHT_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key); +void dht_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key); /* Resolves address into an IP address. If successful, sends a "get nodes" * request to the given node with ip, port and public_key to setup connections * @@ -361,7 +357,7 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key); * returns 1 if the address could be converted into an IP address * returns 0 otherwise */ -int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, +int dht_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, const uint8_t *public_key); /* Start sending packets after DHT loaded_friends_list and loaded_clients_list are set. @@ -369,7 +365,7 @@ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable * returns 0 if successful * returns -1 otherwise */ -int DHT_connect_after_load(DHT *dht); +int dht_connect_after_load(DHT *dht); /* ROUTING FUNCTIONS */ @@ -387,37 +383,37 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack /* Function to handle crypto packets. */ -void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_callback cb, void *object); +void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_cb *cb, void *object); /* SAVE/LOAD functions */ /* Get the size of the DHT (for saving). */ -uint32_t DHT_size(const DHT *dht); +uint32_t dht_size(const DHT *dht); -/* Save the DHT in data where data is an array of size DHT_size(). */ -void DHT_save(const DHT *dht, uint8_t *data); +/* Save the DHT in data where data is an array of size dht_size(). */ +void dht_save(const DHT *dht, uint8_t *data); /* Load the DHT from data of size size. * * return -1 if failure. * return 0 if success. */ -int DHT_load(DHT *dht, const uint8_t *data, uint32_t length); +int dht_load(DHT *dht, const uint8_t *data, uint32_t length); /* Initialize DHT. */ -DHT *new_DHT(Logger *log, Networking_Core *net, bool holepunching_enabled); +DHT *new_dht(const Logger *log, Networking_Core *net, bool holepunching_enabled); -void kill_DHT(DHT *dht); +void kill_dht(DHT *dht); /* return false if we are not connected to the DHT. * return true if we are. */ -bool DHT_isconnected(const DHT *dht); +bool dht_isconnected(const DHT *dht); /* return false if we are not connected or only connected to lan peers with the DHT. * return true if we are. */ -bool DHT_non_lan_connected(const DHT *dht); +bool dht_non_lan_connected(const DHT *dht); uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key); diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c index 70b71fea02..0b2a87831b 100644 --- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c +++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c @@ -27,6 +27,8 @@ #include "LAN_discovery.h" +#include <string.h> + #include "util.h" #define MAX_INTERFACES 16 @@ -34,10 +36,21 @@ /* TODO: multiple threads might concurrently try to set these, and it isn't clear that this couldn't lead to undesirable * behaviour. Consider storing the data in per-instance variables instead. */ +//!TOKSTYLE- +// No global mutable state in Tokstyle. static int broadcast_count = -1; static IP_Port broadcast_ip_ports[MAX_INTERFACES]; +//!TOKSTYLE+ + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) +// The mingw32/64 Windows library warns about including winsock2.h after +// windows.h even though with the above it's a valid thing to do. So, to make +// mingw32 headers happy, we include winsock2.h first. +#include <winsock2.h> + +#include <windows.h> +#include <ws2tcpip.h> #include <iphlpapi.h> @@ -66,9 +79,9 @@ static void fetch_broadcast_info(uint16_t port) int count = 0; IP_Port ip_ports[MAX_INTERFACES]; - int ret; + const int ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); - if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { + if (ret == NO_ERROR) { IP_ADAPTER_INFO *pAdapter = pAdapterInfo; while (pAdapter) { @@ -76,14 +89,14 @@ static void fetch_broadcast_info(uint16_t port) if (addr_parse_ip(pAdapter->IpAddressList.IpMask.String, &subnet_mask) && addr_parse_ip(pAdapter->GatewayList.IpAddress.String, &gateway)) { - if (gateway.family == TOX_AF_INET && subnet_mask.family == TOX_AF_INET) { + if (net_family_is_ipv4(gateway.family) && net_family_is_ipv4(subnet_mask.family)) { IP_Port *ip_port = &ip_ports[count]; - ip_port->ip.family = TOX_AF_INET; + ip_port->ip.family = net_family_ipv4; uint32_t gateway_ip = net_ntohl(gateway.ip.v4.uint32), subnet_ip = net_ntohl(subnet_mask.ip.v4.uint32); uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1; ip_port->ip.ip.v4.uint32 = net_htonl(broadcast_ip); ip_port->port = port; - count++; + ++count; if (count >= MAX_INTERFACES) { break; @@ -101,13 +114,19 @@ static void fetch_broadcast_info(uint16_t port) broadcast_count = count; - for (uint32_t i = 0; i < count; i++) { + for (uint32_t i = 0; i < count; ++i) { broadcast_ip_ports[i] = ip_ports[i]; } } #elif defined(__linux__) || defined(__FreeBSD__) +#include <netinet/in.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> + #ifdef __linux__ #include <linux/netdevice.h> #endif @@ -116,8 +135,6 @@ static void fetch_broadcast_info(uint16_t port) #include <net/if.h> #endif -#include <sys/ioctl.h> - static void fetch_broadcast_info(uint16_t port) { /* Not sure how many platforms this will run on, @@ -125,9 +142,9 @@ static void fetch_broadcast_info(uint16_t port) * Definitely won't work like this on Windows... */ broadcast_count = 0; - const Socket sock = net_socket(TOX_AF_INET, TOX_SOCK_STREAM, 0); + const Socket sock = net_socket(net_family_ipv4, TOX_SOCK_STREAM, 0); - if (sock < 0) { + if (!sock_valid(sock)) { return; } @@ -135,12 +152,12 @@ static void fetch_broadcast_info(uint16_t port) struct ifreq i_faces[MAX_INTERFACES]; memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES); - struct ifconf ifconf; - ifconf.ifc_buf = (char *)i_faces; - ifconf.ifc_len = sizeof(i_faces); + struct ifconf ifc; + ifc.ifc_buf = (char *)i_faces; + ifc.ifc_len = sizeof(i_faces); - if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0) { - close(sock); + if (ioctl(sock.socket, SIOCGIFCONF, &ifc) < 0) { + kill_sock(sock); return; } @@ -151,21 +168,21 @@ static void fetch_broadcast_info(uint16_t port) int count = 0; IP_Port ip_ports[MAX_INTERFACES]; - /* ifconf.ifc_len is set by the ioctl() to the actual length used; + /* ifc.ifc_len is set by the ioctl() to the actual length used; * on usage of the complete array the call should be repeated with * a larger array, not done (640kB and 16 interfaces shall be * enough, for everybody!) */ - int n = ifconf.ifc_len / sizeof(struct ifreq); + int n = ifc.ifc_len / sizeof(struct ifreq); - for (int i = 0; i < n; i++) { + for (int i = 0; i < n; ++i) { /* there are interfaces with are incapable of broadcast */ - if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) { + if (ioctl(sock.socket, SIOCGIFBRDADDR, &i_faces[i]) < 0) { continue; } - /* moot check: only TOX_AF_INET returned (backwards compat.) */ - if (i_faces[i].ifr_broadaddr.sa_family != TOX_AF_INET) { + /* moot check: only AF_INET returned (backwards compat.) */ + if (i_faces[i].ifr_broadaddr.sa_family != AF_INET) { continue; } @@ -176,7 +193,7 @@ static void fetch_broadcast_info(uint16_t port) } IP_Port *ip_port = &ip_ports[count]; - ip_port->ip.family = TOX_AF_INET; + ip_port->ip.family = net_family_ipv4; ip_port->ip.ip.v4.uint32 = sock4->sin_addr.s_addr; if (ip_port->ip.ip.v4.uint32 == 0) { @@ -184,14 +201,14 @@ static void fetch_broadcast_info(uint16_t port) } ip_port->port = port; - count++; + ++count; } - close(sock); + kill_sock(sock); broadcast_count = count; - for (uint32_t i = 0; i < count; i++) { + for (uint32_t i = 0; i < count; ++i) { broadcast_ip_ports[i] = ip_ports[i]; } } @@ -221,7 +238,7 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, const uint8 return 0; } - for (int i = 0; i < broadcast_count; i++) { + for (int i = 0; i < broadcast_count; ++i) { sendpacket(net, broadcast_ip_ports[i], data, length); } @@ -234,24 +251,22 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast) IP ip; ip_reset(&ip); - if (family_socket == TOX_AF_INET6) { - if (family_broadcast == TOX_AF_INET6) { - ip.family = TOX_AF_INET6; + if (net_family_is_ipv6(family_socket)) { + if (net_family_is_ipv6(family_broadcast)) { + ip.family = net_family_ipv6; /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ /* FE80::*: MUST be exact, for that we would need to look over all * interfaces and check in which status they are */ ip.ip.v6.uint8[ 0] = 0xFF; ip.ip.v6.uint8[ 1] = 0x02; ip.ip.v6.uint8[15] = 0x01; - } else if (family_broadcast == TOX_AF_INET) { - ip.family = TOX_AF_INET6; - ip.ip.v6 = IP6_BROADCAST; - } - } else if (family_socket == TOX_AF_INET) { - if (family_broadcast == TOX_AF_INET) { - ip.family = TOX_AF_INET; - ip.ip.v4 = IP4_BROADCAST; + } else if (net_family_is_ipv4(family_broadcast)) { + ip.family = net_family_ipv6; + ip.ip.v6 = ip6_broadcast; } + } else if (net_family_is_ipv4(family_socket) && net_family_is_ipv4(family_broadcast)) { + ip.family = net_family_ipv4; + ip.ip.v4 = ip4_broadcast; } return ip; @@ -260,7 +275,7 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast) /* Is IP a local ip or not. */ bool ip_is_local(IP ip) { - if (ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(ip.family)) { IP4 ip4 = ip.ip.v4; /* Loopback. */ @@ -269,9 +284,9 @@ bool ip_is_local(IP ip) } } else { /* embedded IPv4-in-IPv6 */ - if (IPV6_IPV4_IN_V6(ip.ip.v6)) { + if (ipv6_ipv4_in_v6(ip.ip.v6)) { IP ip4; - ip4.family = TOX_AF_INET; + ip4.family = net_family_ipv4; ip4.ip.v4.uint32 = ip.ip.v6.uint32[3]; return ip_is_local(ip4); } @@ -294,7 +309,7 @@ int ip_is_lan(IP ip) return 0; } - if (ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(ip.family)) { IP4 ip4 = ip.ip.v4; /* 10.0.0.0 to 10.255.255.255 range. */ @@ -323,7 +338,7 @@ int ip_is_lan(IP ip) if ((ip4.uint8[0] == 100) && ((ip4.uint8[1] & 0xC0) == 0x40)) { return 0; } - } else if (ip.family == TOX_AF_INET6) { + } else if (net_family_is_ipv6(ip.family)) { /* autogenerated for each interface: FE80::* (up to FEBF::*) FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ @@ -333,9 +348,9 @@ int ip_is_lan(IP ip) } /* embedded IPv4-in-IPv6 */ - if (IPV6_IPV4_IN_V6(ip.ip.v6)) { + if (ipv6_ipv4_in_v6(ip.ip.v6)) { IP ip4; - ip4.family = TOX_AF_INET; + ip4.family = net_family_ipv4; ip4.ip.v4.uint32 = ip.ip.v6.uint32[3]; return ip_is_lan(ip4); } @@ -359,7 +374,7 @@ static int handle_LANdiscovery(void *object, IP_Port source, const uint8_t *pack return 1; } - DHT_bootstrap(dht, source, packet + 1); + dht_bootstrap(dht, source, packet + 1); return 0; } @@ -377,8 +392,8 @@ int lan_discovery_send(uint16_t port, DHT *dht) ip_port.port = port; /* IPv6 multicast */ - if (net_family(dht_get_net(dht)) == TOX_AF_INET6) { - ip_port.ip = broadcast_ip(TOX_AF_INET6, TOX_AF_INET6); + if (net_family_is_ipv6(net_family(dht_get_net(dht)))) { + ip_port.ip = broadcast_ip(net_family_ipv6, net_family_ipv6); if (ip_isset(&ip_port.ip)) { if (sendpacket(dht_get_net(dht), ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE) > 0) { @@ -387,8 +402,8 @@ int lan_discovery_send(uint16_t port, DHT *dht) } } - /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is TOX_AF_INET6 */ - ip_port.ip = broadcast_ip(net_family(dht_get_net(dht)), TOX_AF_INET); + /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is IPv6 */ + ip_port.ip = broadcast_ip(net_family(dht_get_net(dht)), net_family_ipv4); if (ip_isset(&ip_port.ip)) { if (sendpacket(dht_get_net(dht), ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE)) { diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.c b/protocols/Tox/libtox/src/toxcore/Messenger.c index 0ea7894ec8..416b937c91 100644 --- a/protocols/Tox/libtox/src/toxcore/Messenger.c +++ b/protocols/Tox/libtox/src/toxcore/Messenger.c @@ -27,12 +27,18 @@ #include "Messenger.h" +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + #include "logger.h" +#include "mono_time.h" #include "network.h" +#include "state.h" #include "util.h" -#include <assert.h> - static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data, uint32_t length, uint8_t congestion_control); @@ -379,7 +385,7 @@ static int do_receipts(Messenger *m, int32_t friendnumber, void *userdata) } if (m->read_receipt) { - (*m->read_receipt)(m, friendnumber, receipts->msg_id, userdata); + m->read_receipt(m, friendnumber, receipts->msg_id, userdata); } struct Receipts *r_next = receipts->next; @@ -489,18 +495,22 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con uint32_t *message_id) { if (type > MESSAGE_ACTION) { + LOGGER_ERROR(m->log, "Message type %d is invalid", type); return -5; } if (friend_not_valid(m, friendnumber)) { + LOGGER_ERROR(m->log, "Friend number %d is invalid", friendnumber); return -1; } if (length >= MAX_CRYPTO_DATA_SIZE) { + LOGGER_ERROR(m->log, "Message length %d is too large", friendnumber); return -2; } if (m->friendlist[friendnumber].status != FRIEND_ONLINE) { + LOGGER_ERROR(m->log, "Friend %d is not online", friendnumber); return -3; } @@ -515,6 +525,8 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con m->friendlist[friendnumber].friendcon_id), packet, length + 1, 0); if (packet_num == -1) { + LOGGER_ERROR(m->log, "Failed to write crypto packet for message of length %d to friend %d", + length, friendnumber); return -4; } @@ -674,7 +686,7 @@ int m_set_userstatus(Messenger *m, uint8_t status) return 0; } - m->userstatus = (USERSTATUS)status; + m->userstatus = (Userstatus)status; uint32_t i; for (i = 0; i < m->numfriends; ++i) { @@ -705,7 +717,9 @@ int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf, return -1; } - int msglen = MIN(maxlen, m->friendlist[friendnumber].statusmessage_length); + // TODO(iphydf): This should be uint16_t and min_u16. If maxlen exceeds + // uint16_t's range, it won't affect the result. + uint32_t msglen = min_u32(maxlen, m->friendlist[friendnumber].statusmessage_length); memcpy(buf, m->friendlist[friendnumber].statusmessage, msglen); memset(buf + msglen, 0, maxlen - msglen); @@ -820,7 +834,7 @@ static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, co static void set_friend_userstatus(const Messenger *m, int32_t friendnumber, uint8_t status) { - m->friendlist[friendnumber].userstatus = (USERSTATUS)status; + m->friendlist[friendnumber].userstatus = (Userstatus)status; } static void set_friend_typing(const Messenger *m, int32_t friendnumber, uint8_t is_typing) @@ -834,55 +848,53 @@ void m_callback_log(Messenger *m, logger_cb *function, void *context, void *user } /* Set the function that will be executed when a friend request is received. */ -void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const uint8_t *, const uint8_t *, size_t, - void *)) +void m_callback_friendrequest(Messenger *m, m_friend_request_cb *function) { - callback_friendrequest(m->fr, (void (*)(void *, const uint8_t *, const uint8_t *, size_t, void *))function, m); + callback_friendrequest(m->fr, (fr_friend_request_cb *)function, m); } /* Set the function that will be executed when a message from a friend is received. */ -void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, uint32_t, unsigned int, const uint8_t *, - size_t, void *)) +void m_callback_friendmessage(Messenger *m, m_friend_message_cb *function) { m->friend_message = function; } -void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, size_t, void *)) +void m_callback_namechange(Messenger *m, m_friend_name_cb *function) { m->friend_namechange = function; } -void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, size_t, void *)) +void m_callback_statusmessage(Messenger *m, m_friend_status_message_cb *function) { m->friend_statusmessagechange = function; } -void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, uint32_t, unsigned int, void *)) +void m_callback_userstatus(Messenger *m, m_friend_status_cb *function) { m->friend_userstatuschange = function; } -void m_callback_typingchange(Messenger *m, void(*function)(Messenger *m, uint32_t, bool, void *)) +void m_callback_typingchange(Messenger *m, m_friend_typing_cb *function) { m->friend_typingchange = function; } -void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, uint32_t, uint32_t, void *)) +void m_callback_read_receipt(Messenger *m, m_friend_read_receipt_cb *function) { m->read_receipt = function; } -void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, uint32_t, unsigned int, void *)) +void m_callback_connectionstatus(Messenger *m, m_friend_connection_status_cb *function) { m->friend_connectionstatuschange = function; } -void m_callback_core_connection(Messenger *m, void (*function)(Messenger *m, unsigned int, void *)) +void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *function) { m->core_connection_change = function; } -void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, void *), +void m_callback_connectionstatus_internal_av(Messenger *m, m_friend_connectionstatuschange_internal_cb *function, void *userdata) { m->friend_connectionstatuschange_internal = function; @@ -983,8 +995,7 @@ static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_ * * Function(Messenger *m, uint32_t friendnumber, uint8_t *data, uint16_t length, void *userdata) */ -void m_callback_conference_invite(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, uint16_t, - void *)) +void m_callback_conference_invite(Messenger *m, m_conference_invite_cb *function) { m->conference_invite = function; } @@ -1007,8 +1018,7 @@ int send_conference_invite_packet(const Messenger *m, int32_t friendnumber, cons * * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint32_t filetype, uint64_t filesize, uint8_t *filename, size_t filename_length, void *userdata) */ -void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, uint32_t, uint32_t, uint32_t, uint64_t, - const uint8_t *, size_t, void *)) +void callback_file_sendrequest(Messenger *m, m_file_recv_cb *function) { m->file_sendrequest = function; } @@ -1018,7 +1028,7 @@ void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, uin * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, unsigned int control_type, void *userdata) * */ -void callback_file_control(Messenger *m, void (*function)(Messenger *m, uint32_t, uint32_t, unsigned int, void *)) +void callback_file_control(Messenger *m, m_file_recv_control_cb *function) { m->file_filecontrol = function; } @@ -1028,8 +1038,7 @@ void callback_file_control(Messenger *m, void (*function)(Messenger *m, uint32_t * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, uint8_t *data, size_t length, void *userdata) * */ -void callback_file_data(Messenger *m, void (*function)(Messenger *m, uint32_t, uint32_t, uint64_t, const uint8_t *, - size_t, void *)) +void callback_file_data(Messenger *m, m_file_recv_chunk_cb *function) { m->file_filedata = function; } @@ -1039,7 +1048,7 @@ void callback_file_data(Messenger *m, void (*function)(Messenger *m, uint32_t, u * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, size_t length, void *userdata) * */ -void callback_file_reqchunk(Messenger *m, void (*function)(Messenger *m, uint32_t, uint32_t, uint64_t, size_t, void *)) +void callback_file_reqchunk(Messenger *m, m_file_chunk_request_cb *function) { m->file_reqchunk = function; } @@ -1569,7 +1578,7 @@ static bool do_all_filetransfers(Messenger *m, int32_t friendnumber, void *userd } // Allocate 1 slot to this file transfer. - ft->slots_allocated++; + ++ft->slots_allocated; const uint16_t length = min_u64(ft->size - ft->requested, MAX_FILE_DATA_SIZE); const uint64_t position = ft->requested; @@ -1618,11 +1627,11 @@ static void do_reqchunk_filecb(Messenger *m, int32_t friendnumber, void *userdat // // TODO(zoff99): Fix this to exit the loop properly when we're done // requesting all chunks for all file transfers. - const uint32_t MAX_FT_LOOPS = 16; + const uint32_t max_ft_loops = 16; - while (((free_slots > 0) || loop_counter == 0) && any_active_fts && (loop_counter < MAX_FT_LOOPS)) { + while (((free_slots > 0) || loop_counter == 0) && any_active_fts && (loop_counter < max_ft_loops)) { any_active_fts = do_all_filetransfers(m, friendnumber, userdata, &free_slots); - loop_counter++; + ++loop_counter; } } @@ -1758,12 +1767,13 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv if (position >= ft->size) { LOGGER_DEBUG(m->log, - "file control (friend %d, file %d): seek position %lld exceeds file size %lld", - friendnumber, filenumber, (unsigned long long)position, (unsigned long long)ft->size); + "file control (friend %d, file %d): seek position %ld exceeds file size %ld", + friendnumber, filenumber, (unsigned long)position, (unsigned long)ft->size); return -1; } - ft->transferred = ft->requested = position; + ft->requested = position; + ft->transferred = position; return 0; } @@ -1781,8 +1791,7 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv * * Function(Messenger *m, int friendnumber, uint8_t *data, uint16_t length, void *userdata) */ -void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, uint16_t, void *), - void *userdata) +void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata) { m->msi_packet = function; m->msi_packet_userdata = userdata; @@ -1824,14 +1833,13 @@ static int m_handle_custom_lossy_packet(void *object, int friend_num, const uint return 1; } -void custom_lossy_packet_registerhandler(Messenger *m, void (*lossy_packethandler)(Messenger *m, - uint32_t friendnumber, const uint8_t *data, size_t len, void *object)) +void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb *lossy_packethandler) { m->lossy_packethandler = lossy_packethandler; } -int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, int (*function)(Messenger *m, - uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object), void *object) +int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, m_lossy_rtp_packet_cb *function, + void *object) { if (friend_not_valid(m, friendnumber)) { return -1; @@ -1905,8 +1913,7 @@ static int handle_custom_lossless_packet(void *object, int friend_num, const uin return 1; } -void custom_lossless_packet_registerhandler(Messenger *m, void (*lossless_packethandler)(Messenger *m, - uint32_t friendnumber, const uint8_t *data, size_t len, void *object)) +void custom_lossless_packet_registerhandler(Messenger *m, m_friend_lossless_packet_cb *lossless_packethandler) { m->lossless_packethandler = lossless_packethandler; } @@ -1989,6 +1996,12 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) unsigned int net_err = 0; + if (!options->udp_disabled && options->proxy_info.proxy_type != TCP_PROXY_NONE) { + // We don't currently support UDP over proxy. + LOGGER_WARNING(m->log, "UDP enabled and proxy set: disabling UDP"); + options->udp_disabled = true; + } + if (options->udp_disabled) { m->net = new_networking_no_udp(m->log); } else { @@ -2009,7 +2022,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) return nullptr; } - m->dht = new_DHT(m->log, m->net, options->hole_punching_enabled); + m->dht = new_dht(m->log, m->net, options->hole_punching_enabled); if (m->dht == nullptr) { kill_networking(m->net); @@ -2023,7 +2036,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) if (m->net_crypto == nullptr) { kill_networking(m->net); - kill_DHT(m->dht); + kill_dht(m->dht); friendreq_kill(m->fr); logger_kill(m->log); free(m); @@ -2041,7 +2054,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) kill_onion_announce(m->onion_a); kill_onion_client(m->onion_c); kill_net_crypto(m->net_crypto); - kill_DHT(m->dht); + kill_dht(m->dht); kill_networking(m->net); friendreq_kill(m->fr); logger_kill(m->log); @@ -2059,7 +2072,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) kill_onion_announce(m->onion_a); kill_onion_client(m->onion_c); kill_net_crypto(m->net_crypto); - kill_DHT(m->dht); + kill_dht(m->dht); kill_networking(m->net); friendreq_kill(m->fr); logger_kill(m->log); @@ -2105,7 +2118,7 @@ void kill_messenger(Messenger *m) kill_onion_announce(m->onion_a); kill_onion_client(m->onion_c); kill_net_crypto(m->net_crypto); - kill_DHT(m->dht); + kill_dht(m->dht); kill_networking(m->net); for (i = 0; i < m->numfriends; ++i) { @@ -2225,7 +2238,7 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le break; } - USERSTATUS status = (USERSTATUS)data[0]; + Userstatus status = (Userstatus)data[0]; if (status >= USERSTATUS_INVALID) { break; @@ -2520,12 +2533,12 @@ static void do_friends(Messenger *m, void *userdata) do_receipts(m, i, userdata); do_reqchunk_filecb(m, i, userdata); - m->friendlist[i].last_seen_time = (uint64_t) time(0); + m->friendlist[i].last_seen_time = (uint64_t) time(nullptr); } } } -static void connection_status_cb(Messenger *m, void *userdata) +static void connection_status_callback(Messenger *m, void *userdata) { unsigned int conn_status = onion_connection_status(m->onion_c); @@ -2550,7 +2563,7 @@ static char *id_to_string(const uint8_t *pk, char *id_str, size_t length) return id_str; } - for (uint32_t i = 0; i < CRYPTO_PUBLIC_KEY_SIZE; i++) { + for (uint32_t i = 0; i < CRYPTO_PUBLIC_KEY_SIZE; ++i) { sprintf(&id_str[i * 2], "%02X", pk[i]); } @@ -2595,7 +2608,7 @@ void do_messenger(Messenger *m, void *userdata) /* Add self tcp server. */ IP_Port local_ip_port; local_ip_port.port = m->options.tcp_server_port; - local_ip_port.ip.family = TOX_AF_INET; + local_ip_port.ip.family = net_family_ipv4; local_ip_port.ip.ip.v4 = get_ip4_loopback(); add_tcp_relay(m->net_crypto, local_ip_port, tcp_server_public_key(m->tcp_server)); @@ -2606,7 +2619,7 @@ void do_messenger(Messenger *m, void *userdata) if (!m->options.udp_disabled) { networking_poll(m->net, userdata); - do_DHT(m->dht); + do_dht(m->dht); } if (m->tcp_server) { @@ -2617,18 +2630,18 @@ void do_messenger(Messenger *m, void *userdata) do_onion_client(m->onion_c); do_friend_connections(m->fr_c, userdata); do_friends(m, userdata); - connection_status_cb(m, userdata); + connection_status_callback(m, userdata); if (unix_time() > m->lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) { m->lastdump = unix_time(); uint32_t client, last_pinged; - for (client = 0; client < LCLIENT_LIST; client++) { + for (client = 0; client < LCLIENT_LIST; ++client) { const Client_data *cptr = dht_get_close_client(m->dht, client); const IPPTsPng *assoc = nullptr; uint32_t a; - for (a = 0, assoc = &cptr->assoc4; a < 2; a++, assoc = &cptr->assoc6) { + for (a = 0, assoc = &cptr->assoc4; a < 2; ++a, assoc = &cptr->assoc6) { if (ip_isset(&assoc->ip_port.ip)) { last_pinged = m->lastdump - assoc->last_pinged; @@ -2654,7 +2667,7 @@ void do_messenger(Messenger *m, void *userdata) VLA(int32_t, m2dht, num_dhtfriends); VLA(int32_t, dht2m, num_dhtfriends); - for (friend_idx = 0; friend_idx < num_dhtfriends; friend_idx++) { + for (friend_idx = 0; friend_idx < num_dhtfriends; ++friend_idx) { m2dht[friend_idx] = -1; dht2m[friend_idx] = -1; @@ -2662,7 +2675,7 @@ void do_messenger(Messenger *m, void *userdata) continue; } - for (dhtfriend = 0; dhtfriend < dht_get_num_friends(m->dht); dhtfriend++) { + for (dhtfriend = 0; dhtfriend < dht_get_num_friends(m->dht); ++dhtfriend) { if (id_equal(m->friendlist[friend_idx].real_pk, dht_get_friend_public_key(m->dht, dhtfriend))) { m2dht[friend_idx] = dhtfriend; break; @@ -2670,7 +2683,7 @@ void do_messenger(Messenger *m, void *userdata) } } - for (friend_idx = 0; friend_idx < num_dhtfriends; friend_idx++) { + for (friend_idx = 0; friend_idx < num_dhtfriends; ++friend_idx) { if (m2dht[friend_idx] >= 0) { dht2m[m2dht[friend_idx]] = friend_idx; } @@ -2683,7 +2696,7 @@ void do_messenger(Messenger *m, void *userdata) Friend *msgfptr; DHT_Friend *dhtfptr; - for (friend_idx = 0; friend_idx < num_dhtfriends; friend_idx++) { + for (friend_idx = 0; friend_idx < num_dhtfriends; ++friend_idx) { if (dht2m[friend_idx] >= 0) { msgfptr = &m->friendlist[dht2m[friend_idx]]; } else { @@ -2703,11 +2716,11 @@ void do_messenger(Messenger *m, void *userdata) id_to_string(dht_friend_public_key(dhtfptr), id_str, sizeof(id_str))); } - for (client = 0; client < MAX_FRIEND_CLIENTS; client++) { + for (client = 0; client < MAX_FRIEND_CLIENTS; ++client) { const Client_data *cptr = dht_friend_client(dhtfptr, client); const IPPTsPng *const assocs[] = {&cptr->assoc4, &cptr->assoc6}; - for (size_t a = 0; a < sizeof(assocs) / sizeof(assocs[0]); a++) { + for (size_t a = 0; a < sizeof(assocs) / sizeof(assocs[0]); ++a) { const IPPTsPng *const assoc = assocs[a]; if (ip_isset(&assoc->ip_port.ip)) { @@ -2748,7 +2761,7 @@ void do_messenger(Messenger *m, void *userdata) #define SAVED_FRIEND_REQUEST_SIZE 1024 #define NUM_SAVED_PATH_NODES 8 -struct SAVED_FRIEND { +struct Saved_Friend { uint8_t status; uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t info[SAVED_FRIEND_REQUEST_SIZE]; // the data that is sent during the friend requests we do. @@ -2765,21 +2778,21 @@ struct SAVED_FRIEND { static uint32_t friend_size(void) { uint32_t data = 0; - const struct SAVED_FRIEND *const temp = nullptr; + const struct Saved_Friend *const temp = nullptr; -#define VALUE_MEMBER(NAME) data += sizeof(temp->NAME) -#define ARRAY_MEMBER(NAME) data += sizeof(temp->NAME) +#define VALUE_MEMBER(name) do { data += sizeof(temp->name); } while (0) +#define ARRAY_MEMBER(name) do { data += sizeof(temp->name); } while (0) // Exactly the same in friend_load, friend_save, and friend_size VALUE_MEMBER(status); ARRAY_MEMBER(real_pk); ARRAY_MEMBER(info); - data++; // padding + ++data; // padding VALUE_MEMBER(info_size); ARRAY_MEMBER(name); VALUE_MEMBER(name_length); ARRAY_MEMBER(statusmessage); - data++; // padding + ++data; // padding VALUE_MEMBER(statusmessage_length); VALUE_MEMBER(userstatus); data += 3; // padding @@ -2797,26 +2810,28 @@ static uint32_t saved_friendslist_size(const Messenger *m) return count_friendlist(m) * friend_size(); } -static uint8_t *friend_save(const struct SAVED_FRIEND *temp, uint8_t *data) +static uint8_t *friend_save(const struct Saved_Friend *temp, uint8_t *data) { -#define VALUE_MEMBER(NAME) \ - memcpy(data, &temp->NAME, sizeof(temp->NAME)); \ - data += sizeof(temp->NAME) +#define VALUE_MEMBER(name) do { \ + memcpy(data, &temp->name, sizeof(temp->name)); \ + data += sizeof(temp->name); \ +} while (0) -#define ARRAY_MEMBER(NAME) \ - memcpy(data, temp->NAME, sizeof(temp->NAME)); \ - data += sizeof(temp->NAME) +#define ARRAY_MEMBER(name) do { \ + memcpy(data, temp->name, sizeof(temp->name)); \ + data += sizeof(temp->name); \ +} while (0) // Exactly the same in friend_load, friend_save, and friend_size VALUE_MEMBER(status); ARRAY_MEMBER(real_pk); ARRAY_MEMBER(info); - data++; // padding + ++data; // padding VALUE_MEMBER(info_size); ARRAY_MEMBER(name); VALUE_MEMBER(name_length); ARRAY_MEMBER(statusmessage); - data++; // padding + ++data; // padding VALUE_MEMBER(statusmessage_length); VALUE_MEMBER(userstatus); data += 3; // padding @@ -2835,16 +2850,17 @@ static uint32_t friends_list_save(const Messenger *m, uint8_t *data) uint32_t num = 0; uint8_t *cur_data = data; - for (i = 0; i < m->numfriends; i++) { + for (i = 0; i < m->numfriends; ++i) { if (m->friendlist[i].status > 0) { - struct SAVED_FRIEND temp = { 0 }; + struct Saved_Friend temp = { 0 }; temp.status = m->friendlist[i].status; memcpy(temp.real_pk, m->friendlist[i].real_pk, CRYPTO_PUBLIC_KEY_SIZE); if (temp.status < 3) { + // TODO(iphydf): Use uint16_t and min_u16 here. const size_t friendrequest_length = - MIN(m->friendlist[i].info_size, - MIN(SAVED_FRIEND_REQUEST_SIZE, MAX_FRIEND_REQUEST_DATA_SIZE)); + min_u32(m->friendlist[i].info_size, + min_u32(SAVED_FRIEND_REQUEST_SIZE, MAX_FRIEND_REQUEST_DATA_SIZE)); memcpy(temp.info, m->friendlist[i].info, friendrequest_length); temp.info_size = net_htons(m->friendlist[i].info_size); @@ -2868,7 +2884,7 @@ static uint32_t friends_list_save(const Messenger *m, uint8_t *data) assert(memcmp(cur_data, &temp, friend_size()) == 0); #endif cur_data = next_data; - num++; + ++num; } } @@ -2876,26 +2892,28 @@ static uint32_t friends_list_save(const Messenger *m, uint8_t *data) return cur_data - data; } -static const uint8_t *friend_load(struct SAVED_FRIEND *temp, const uint8_t *data) +static const uint8_t *friend_load(struct Saved_Friend *temp, const uint8_t *data) { -#define VALUE_MEMBER(NAME) \ - memcpy(&temp->NAME, data, sizeof(temp->NAME)); \ - data += sizeof(temp->NAME) +#define VALUE_MEMBER(name) do { \ + memcpy(&temp->name, data, sizeof(temp->name)); \ + data += sizeof(temp->name); \ +} while (0) -#define ARRAY_MEMBER(NAME) \ - memcpy(temp->NAME, data, sizeof(temp->NAME)); \ - data += sizeof(temp->NAME) +#define ARRAY_MEMBER(name) do { \ + memcpy(temp->name, data, sizeof(temp->name)); \ + data += sizeof(temp->name); \ +} while (0) // Exactly the same in friend_load, friend_save, and friend_size VALUE_MEMBER(status); ARRAY_MEMBER(real_pk); ARRAY_MEMBER(info); - data++; // padding + ++data; // padding VALUE_MEMBER(info_size); ARRAY_MEMBER(name); VALUE_MEMBER(name_length); ARRAY_MEMBER(statusmessage); - data++; // padding + ++data; // padding VALUE_MEMBER(statusmessage_length); VALUE_MEMBER(userstatus); data += 3; // padding @@ -2919,7 +2937,7 @@ static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length) const uint8_t *cur_data = data; for (i = 0; i < num; ++i) { - struct SAVED_FRIEND temp = { 0 }; + struct Saved_Friend temp = { 0 }; const uint8_t *next_data = friend_load(&temp, cur_data); assert(next_data - cur_data == friend_size()); #ifdef __LP64__ @@ -2961,13 +2979,13 @@ uint32_t messenger_size(const Messenger *m) uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2; return size32 * 2 // global cookie + sizesubhead + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE - + sizesubhead + DHT_size(m->dht) // DHT + + sizesubhead + dht_size(m->dht) // DHT + sizesubhead + saved_friendslist_size(m) // Friendlist itself. + sizesubhead + m->name_length // Own nickname. + sizesubhead + m->statusmessage_length // status message + sizesubhead + 1 // status - + sizesubhead + NUM_SAVED_TCP_RELAYS * packed_node_size(TCP_INET6) //TCP relays - + sizesubhead + NUM_SAVED_PATH_NODES * packed_node_size(TCP_INET6) //saved path nodes + + sizesubhead + NUM_SAVED_TCP_RELAYS * packed_node_size(net_family_tcp_ipv6) // TCP relays + + sizesubhead + NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6) // saved path nodes + sizesubhead; } @@ -3026,10 +3044,10 @@ void messenger_save(const Messenger *m, uint8_t *data) *data = m->userstatus; data += len; - len = DHT_size(m->dht); + len = dht_size(m->dht); type = MESSENGER_STATE_TYPE_DHT; data = messenger_save_subheader(data, len, type); - DHT_save(m->dht, data); + dht_save(m->dht, data); data += len; Node_format relays[NUM_SAVED_TCP_RELAYS]; @@ -3037,7 +3055,7 @@ void messenger_save(const Messenger *m, uint8_t *data) uint8_t *temp_data = data; data = messenger_save_subheader(temp_data, 0, type); unsigned int num = copy_connected_tcp_relays(m->net_crypto, relays, NUM_SAVED_TCP_RELAYS); - int l = pack_nodes(data, NUM_SAVED_TCP_RELAYS * packed_node_size(TCP_INET6), relays, num); + int l = pack_nodes(data, NUM_SAVED_TCP_RELAYS * packed_node_size(net_family_tcp_ipv6), relays, num); if (l > 0) { len = l; @@ -3051,7 +3069,7 @@ void messenger_save(const Messenger *m, uint8_t *data) data = messenger_save_subheader(data, 0, type); memset(nodes, 0, sizeof(nodes)); num = onion_backup_nodes(m->onion_c, nodes, NUM_SAVED_PATH_NODES); - l = pack_nodes(data, NUM_SAVED_PATH_NODES * packed_node_size(TCP_INET6), nodes, num); + l = pack_nodes(data, NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6), nodes, num); if (l > 0) { len = l; @@ -3062,7 +3080,7 @@ void messenger_save(const Messenger *m, uint8_t *data) messenger_save_subheader(data, 0, MESSENGER_STATE_TYPE_END); } -static int messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) +static State_Load_Status messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) { Messenger *m = (Messenger *)outer; @@ -3073,16 +3091,16 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3 load_secret_key(m->net_crypto, (&data[sizeof(uint32_t)]) + CRYPTO_PUBLIC_KEY_SIZE); if (public_key_cmp((&data[sizeof(uint32_t)]), nc_get_self_public_key(m->net_crypto)) != 0) { - return -1; + return STATE_LOAD_STATUS_ERROR; } } else { - return -1; /* critical */ + return STATE_LOAD_STATUS_ERROR; /* critical */ } break; case MESSENGER_STATE_TYPE_DHT: - DHT_load(m->dht, data, length); + dht_load(m->dht, data, length); break; case MESSENGER_STATE_TYPE_FRIENDS: @@ -3139,10 +3157,10 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3 case MESSENGER_STATE_TYPE_END: { if (length != 0) { - return -1; + return STATE_LOAD_STATUS_ERROR; } - return -2; + return STATE_LOAD_STATUS_END; } default: @@ -3151,7 +3169,7 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3 break; } - return 0; + return STATE_LOAD_STATUS_CONTINUE; } /* Load the messenger from data of size length. */ @@ -3168,7 +3186,7 @@ int messenger_load(Messenger *m, const uint8_t *data, uint32_t length) lendian_to_host32(data32 + 1, data + sizeof(uint32_t)); if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL)) { - return load_state(messenger_load_state_callback, m->log, m, data + cookie_len, + return state_load(m->log, messenger_load_state_callback, m, data + cookie_len, length - cookie_len, MESSENGER_STATE_COOKIE_TYPE); } @@ -3183,9 +3201,9 @@ uint32_t count_friendlist(const Messenger *m) uint32_t ret = 0; uint32_t i; - for (i = 0; i < m->numfriends; i++) { + for (i = 0; i < m->numfriends; ++i) { if (m->friendlist[i].status > 0) { - ret++; + ++ret; } } @@ -3210,14 +3228,14 @@ uint32_t copy_friendlist(Messenger const *m, uint32_t *out_list, uint32_t list_s uint32_t i; uint32_t ret = 0; - for (i = 0; i < m->numfriends; i++) { + for (i = 0; i < m->numfriends; ++i) { if (ret >= list_size) { break; /* Abandon ship */ } if (m->friendlist[i].status > 0) { out_list[ret] = i; - ret++; + ++ret; } } diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.h b/protocols/Tox/libtox/src/toxcore/Messenger.h index 402eb91650..833e6b2bfb 100644 --- a/protocols/Tox/libtox/src/toxcore/Messenger.h +++ b/protocols/Tox/libtox/src/toxcore/Messenger.h @@ -44,10 +44,10 @@ #define FRIEND_ADDRESS_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) -enum { +typedef enum Message_Type { MESSAGE_NORMAL, MESSAGE_ACTION -}; +} Message_Type; /* NOTE: Packet ids below 24 must never be used. */ #define PACKET_ID_ONLINE 24 @@ -57,7 +57,7 @@ enum { #define PACKET_ID_USERSTATUS 50 #define PACKET_ID_TYPING 51 #define PACKET_ID_MESSAGE 64 -#define PACKET_ID_ACTION (PACKET_ID_MESSAGE + MESSAGE_ACTION) /* 65 */ +#define PACKET_ID_ACTION (PACKET_ID_MESSAGE + MESSAGE_ACTION) // 65 #define PACKET_ID_MSI 69 #define PACKET_ID_FILE_SENDREQUEST 80 #define PACKET_ID_FILE_CONTROL 81 @@ -71,9 +71,9 @@ enum { /* All packets starting with a byte in this range can be used for anything. */ #define PACKET_ID_LOSSLESS_RANGE_START 160 #define PACKET_ID_LOSSLESS_RANGE_SIZE 32 -#define PACKET_LOSSY_AV_RESERVED 8 /* Number of lossy packet types at start of range reserved for A/V. */ +#define PACKET_LOSSY_AV_RESERVED 8 // Number of lossy packet types at start of range reserved for A/V. -typedef struct { +typedef struct Messenger_Options { bool ipv6enabled; bool udp_disabled; TCP_Proxy_Info proxy_info; @@ -95,18 +95,18 @@ struct Receipts { }; /* Status definitions. */ -enum { +typedef enum Friend_Status { NOFRIEND, FRIEND_ADDED, FRIEND_REQUESTED, FRIEND_CONFIRMED, FRIEND_ONLINE, -}; +} Friend_Status; /* Errors for m_addfriend * FAERR - Friend Add Error */ -enum { +typedef enum Friend_Add_Error { FAERR_TOOLONG = -1, FAERR_NOMESSAGE = -2, FAERR_OWNKEY = -3, @@ -114,30 +114,29 @@ enum { FAERR_BADCHECKSUM = -6, FAERR_SETNEWNOSPAM = -7, FAERR_NOMEM = -8 -}; +} Friend_Add_Error; /* Default start timeout in seconds between friend requests. */ -#define FRIENDREQUEST_TIMEOUT 5; +#define FRIENDREQUEST_TIMEOUT 5 -enum { +typedef enum Connection_Status { CONNECTION_NONE, CONNECTION_TCP, CONNECTION_UDP, CONNECTION_UNKNOWN -}; +} Connection_Status; /* USERSTATUS - * Represents userstatuses someone can have. */ -typedef enum { +typedef enum Userstatus { USERSTATUS_NONE, USERSTATUS_AWAY, USERSTATUS_BUSY, USERSTATUS_INVALID -} -USERSTATUS; +} Userstatus; #define FILE_ID_LENGTH 32 @@ -151,37 +150,76 @@ struct File_Transfers { unsigned int slots_allocated; /* number of slots allocated to this transfer. */ uint8_t id[FILE_ID_LENGTH]; }; -enum { +typedef enum Filestatus { FILESTATUS_NONE, FILESTATUS_NOT_ACCEPTED, FILESTATUS_TRANSFERRING, - //FILESTATUS_BROKEN, + // FILESTATUS_BROKEN, FILESTATUS_FINISHED -}; +} Filestatus; -enum { +typedef enum File_Pause { FILE_PAUSE_NOT, FILE_PAUSE_US, FILE_PAUSE_OTHER, FILE_PAUSE_BOTH -}; +} File_Pause; -enum { +typedef enum Filecontrol { FILECONTROL_ACCEPT, FILECONTROL_PAUSE, FILECONTROL_KILL, FILECONTROL_SEEK -}; +} Filecontrol; -enum { +typedef enum Filekind { FILEKIND_DATA, FILEKIND_AVATAR -}; +} Filekind; typedef struct Messenger Messenger; -typedef struct { +typedef void m_self_connection_status_cb(Messenger *m, unsigned int connection_status, void *user_data); +typedef void m_friend_status_cb(Messenger *m, uint32_t friend_number, unsigned int status, void *user_data); +typedef void m_friend_connection_status_cb(Messenger *m, uint32_t friend_number, unsigned int connection_status, + void *user_data); +typedef void m_friend_message_cb(Messenger *m, uint32_t friend_number, unsigned int message_type, + const uint8_t *message, size_t length, void *user_data); +typedef void m_file_recv_control_cb(Messenger *m, uint32_t friend_number, uint32_t file_number, unsigned int control, + void *user_data); +typedef void m_friend_request_cb(Messenger *m, const uint8_t *public_key, const uint8_t *message, size_t length, + void *user_data); +typedef void m_friend_name_cb(Messenger *m, uint32_t friend_number, const uint8_t *name, size_t length, + void *user_data); +typedef void m_friend_status_message_cb(Messenger *m, uint32_t friend_number, const uint8_t *message, size_t length, + void *user_data); +typedef void m_friend_typing_cb(Messenger *m, uint32_t friend_number, bool is_typing, void *user_data); +typedef void m_friend_read_receipt_cb(Messenger *m, uint32_t friend_number, uint32_t message_id, void *user_data); +typedef void m_file_recv_cb(Messenger *m, uint32_t friend_number, uint32_t file_number, uint32_t kind, + uint64_t file_size, const uint8_t *filename, size_t filename_length, void *user_data); +typedef void m_file_chunk_request_cb(Messenger *m, uint32_t friend_number, uint32_t file_number, uint64_t position, + size_t length, void *user_data); +typedef void m_file_recv_chunk_cb(Messenger *m, uint32_t friend_number, uint32_t file_number, uint64_t position, + const uint8_t *data, size_t length, void *user_data); +typedef void m_friend_lossy_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, size_t length, + void *user_data); +typedef void m_friend_lossless_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, size_t length, + void *user_data); +typedef void m_friend_connectionstatuschange_internal_cb(Messenger *m, uint32_t friend_number, + uint8_t connection_status, void *user_data); +typedef void m_conference_invite_cb(Messenger *m, uint32_t friend_number, const uint8_t *cookie, uint16_t length, + void *user_data); +typedef void m_msi_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, + void *user_data); +typedef int m_lossy_rtp_packet_cb(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object); + +typedef struct RTP_Packet_Handler { + m_lossy_rtp_packet_cb *function; + void *object; +} RTP_Packet_Handler; + +typedef struct Friend { uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; int friendcon_id; @@ -195,7 +233,7 @@ typedef struct { uint8_t statusmessage[MAX_STATUSMESSAGE_LENGTH]; uint16_t statusmessage_length; uint8_t statusmessage_sent; - USERSTATUS userstatus; + Userstatus userstatus; uint8_t userstatus_sent; uint8_t user_istyping; uint8_t user_istyping_sent; @@ -209,10 +247,7 @@ typedef struct { uint32_t num_sending_files; struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES]; - struct { - int (*function)(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object); - void *object; - } lossy_rtp_packethandlers[PACKET_LOSSY_AV_RESERVED]; + RTP_Packet_Handler lossy_rtp_packethandlers[PACKET_LOSSY_AV_RESERVED]; struct Receipts *receipts_start; struct Receipts *receipts_end; @@ -239,7 +274,7 @@ struct Messenger { uint8_t statusmessage[MAX_STATUSMESSAGE_LENGTH]; uint16_t statusmessage_length; - USERSTATUS userstatus; + Userstatus userstatus; Friend *friendlist; uint32_t numfriends; @@ -249,32 +284,31 @@ struct Messenger { uint8_t has_added_relays; // If the first connection has occurred in do_messenger Node_format loaded_relays[NUM_SAVED_TCP_RELAYS]; // Relays loaded from config - void (*friend_message)(struct Messenger *m, uint32_t, unsigned int, const uint8_t *, size_t, void *); - void (*friend_namechange)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *); - void (*friend_statusmessagechange)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *); - void (*friend_userstatuschange)(struct Messenger *m, uint32_t, unsigned int, void *); - void (*friend_typingchange)(struct Messenger *m, uint32_t, bool, void *); - void (*read_receipt)(struct Messenger *m, uint32_t, uint32_t, void *); - void (*friend_connectionstatuschange)(struct Messenger *m, uint32_t, unsigned int, void *); - void (*friend_connectionstatuschange_internal)(struct Messenger *m, uint32_t, uint8_t, void *); + m_friend_message_cb *friend_message; + m_friend_name_cb *friend_namechange; + m_friend_status_message_cb *friend_statusmessagechange; + m_friend_status_cb *friend_userstatuschange; + m_friend_typing_cb *friend_typingchange; + m_friend_read_receipt_cb *read_receipt; + m_friend_connection_status_cb *friend_connectionstatuschange; + m_friend_connectionstatuschange_internal_cb *friend_connectionstatuschange_internal; void *friend_connectionstatuschange_internal_userdata; void *conferences_object; /* Set by new_groupchats()*/ - void (*conference_invite)(struct Messenger *m, uint32_t, const uint8_t *, uint16_t, void *); + m_conference_invite_cb *conference_invite; - void (*file_sendrequest)(struct Messenger *m, uint32_t, uint32_t, uint32_t, uint64_t, const uint8_t *, size_t, - void *); - void (*file_filecontrol)(struct Messenger *m, uint32_t, uint32_t, unsigned int, void *); - void (*file_filedata)(struct Messenger *m, uint32_t, uint32_t, uint64_t, const uint8_t *, size_t, void *); - void (*file_reqchunk)(struct Messenger *m, uint32_t, uint32_t, uint64_t, size_t, void *); + m_file_recv_cb *file_sendrequest; + m_file_recv_control_cb *file_filecontrol; + m_file_recv_chunk_cb *file_filedata; + m_file_chunk_request_cb *file_reqchunk; - void (*msi_packet)(struct Messenger *m, uint32_t, const uint8_t *, uint16_t, void *); + m_msi_packet_cb *msi_packet; void *msi_packet_userdata; - void (*lossy_packethandler)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *); - void (*lossless_packethandler)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *); + m_friend_lossy_packet_cb *lossy_packethandler; + m_friend_lossless_packet_cb *lossless_packethandler; - void (*core_connection_change)(struct Messenger *m, unsigned int, void *); + m_self_connection_status_cb *core_connection_change; unsigned int last_connection_status; Messenger_Options options; @@ -440,9 +474,9 @@ int m_get_self_statusmessage_size(const Messenger *m); int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf, uint32_t maxlen); int m_copy_self_statusmessage(const Messenger *m, uint8_t *buf); -/* return one of USERSTATUS values. +/* return one of Userstatus values. * Values unknown to your application should be represented as USERSTATUS_NONE. - * As above, the self variant will return our own USERSTATUS. + * As above, the self variant will return our own Userstatus. * If friendnumber is invalid, this shall return USERSTATUS_INVALID. */ uint8_t m_get_userstatus(const Messenger *m, int32_t friendnumber); @@ -476,37 +510,35 @@ void m_callback_log(Messenger *m, logger_cb *function, void *context, void *user /* Set the function that will be executed when a friend request is received. * Function format is function(uint8_t * public_key, uint8_t * data, size_t length) */ -void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const uint8_t *, const uint8_t *, size_t, - void *)); +void m_callback_friendrequest(Messenger *m, m_friend_request_cb *function); /* Set the function that will be executed when a message from a friend is received. * Function format is: function(uint32_t friendnumber, unsigned int type, uint8_t * message, uint32_t length) */ -void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, uint32_t, unsigned int, const uint8_t *, - size_t, void *)); +void m_callback_friendmessage(Messenger *m, m_friend_message_cb *function); /* Set the callback for name changes. * Function(uint32_t friendnumber, uint8_t *newname, size_t length) * You are not responsible for freeing newname. */ -void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, size_t, void *)); +void m_callback_namechange(Messenger *m, m_friend_name_cb *function); /* Set the callback for status message changes. * Function(uint32_t friendnumber, uint8_t *newstatus, size_t length) * * You are not responsible for freeing newstatus */ -void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, size_t, void *)); +void m_callback_statusmessage(Messenger *m, m_friend_status_message_cb *function); /* Set the callback for status type changes. - * Function(uint32_t friendnumber, USERSTATUS kind) + * Function(uint32_t friendnumber, Userstatus kind) */ -void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, uint32_t, unsigned int, void *)); +void m_callback_userstatus(Messenger *m, m_friend_status_cb *function); /* Set the callback for typing changes. * Function(uint32_t friendnumber, uint8_t is_typing) */ -void m_callback_typingchange(Messenger *m, void(*function)(Messenger *m, uint32_t, bool, void *)); +void m_callback_typingchange(Messenger *m, m_friend_typing_cb *function); /* Set the callback for read receipts. * Function(uint32_t friendnumber, uint32_t receipt) @@ -517,7 +549,7 @@ void m_callback_typingchange(Messenger *m, void(*function)(Messenger *m, uint32_ * Since core doesn't track ids for you, receipt may not correspond to any message. * In that case, you should discard it. */ -void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, uint32_t, uint32_t, void *)); +void m_callback_read_receipt(Messenger *m, m_friend_read_receipt_cb *function); /* Set the callback for connection status changes. * function(uint32_t friendnumber, uint8_t status) @@ -530,17 +562,17 @@ void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, uint32 * being previously online" part. * It's assumed that when adding friends, their connection status is offline. */ -void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, uint32_t, unsigned int, void *)); +void m_callback_connectionstatus(Messenger *m, m_friend_connection_status_cb *function); /* Same as previous but for internal A/V core usage only */ -void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, void *), +void m_callback_connectionstatus_internal_av(Messenger *m, m_friend_connectionstatuschange_internal_cb *function, void *userdata); /* Set the callback for typing changes. * Function(unsigned int connection_status (0 = not connected, 1 = TCP only, 2 = UDP + TCP)) */ -void m_callback_core_connection(Messenger *m, void (*function)(Messenger *m, unsigned int, void *)); +void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *function); /**********CONFERENCES************/ @@ -548,8 +580,7 @@ void m_callback_core_connection(Messenger *m, void (*function)(Messenger *m, uns * * Function(Messenger *m, uint32_t friendnumber, uint8_t *data, uint16_t length, void *userdata) */ -void m_callback_conference_invite(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, uint16_t, - void *)); +void m_callback_conference_invite(Messenger *m, m_conference_invite_cb *function); /* Send a conference invite packet. * @@ -565,8 +596,7 @@ int send_conference_invite_packet(const Messenger *m, int32_t friendnumber, cons * * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint32_t filetype, uint64_t filesize, uint8_t *filename, size_t filename_length, void *userdata) */ -void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, uint32_t, uint32_t, uint32_t, uint64_t, - const uint8_t *, size_t, void *)); +void callback_file_sendrequest(Messenger *m, m_file_recv_cb *function); /* Set the callback for file control requests. @@ -574,22 +604,21 @@ void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, uin * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, unsigned int control_type, void *userdata) * */ -void callback_file_control(Messenger *m, void (*function)(Messenger *m, uint32_t, uint32_t, unsigned int, void *)); +void callback_file_control(Messenger *m, m_file_recv_control_cb *function); /* Set the callback for file data. * * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, uint8_t *data, size_t length, void *userdata) * */ -void callback_file_data(Messenger *m, void (*function)(Messenger *m, uint32_t, uint32_t, uint64_t, const uint8_t *, - size_t, void *)); +void callback_file_data(Messenger *m, m_file_recv_chunk_cb *function); /* Set the callback for file request chunk. * * Function(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, size_t length, void *userdata) * */ -void callback_file_reqchunk(Messenger *m, void (*function)(Messenger *m, uint32_t, uint32_t, uint64_t, size_t, void *)); +void callback_file_reqchunk(Messenger *m, m_file_chunk_request_cb *function); /* Copy the file transfer file id to file_id @@ -668,8 +697,7 @@ uint64_t file_dataremaining(const Messenger *m, int32_t friendnumber, uint8_t fi * * Function(Messenger *m, uint32_t friendnumber, uint8_t *data, uint16_t length, void *userdata) */ -void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, uint16_t, void *), - void *userdata); +void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata); /* Send an msi packet. * @@ -683,16 +711,15 @@ int m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, * return -1 on failure. * return 0 on success. */ -int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, int (*packet_handler_callback)(Messenger *m, - uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object), void *object); +int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, + m_lossy_rtp_packet_cb *packet_handler_callback, void *object); /**********************************************/ /* Set handlers for custom lossy packets. * */ -void custom_lossy_packet_registerhandler(Messenger *m, void (*packet_handler_callback)(Messenger *m, - uint32_t friendnumber, const uint8_t *data, size_t len, void *object)); +void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb *packet_handler_callback); /* High level function to send custom lossy packets. * @@ -709,8 +736,7 @@ int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const u /* Set handlers for custom lossless packets. * */ -void custom_lossless_packet_registerhandler(Messenger *m, void (*packet_handler_callback)(Messenger *m, - uint32_t friendnumber, const uint8_t *data, size_t len, void *object)); +void custom_lossless_packet_registerhandler(Messenger *m, m_friend_lossless_packet_cb *packet_handler_callback); /* High level function to send custom lossless packets. * @@ -725,12 +751,12 @@ int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const /**********************************************/ -enum { +typedef enum Messenger_Error { MESSENGER_ERROR_NONE, MESSENGER_ERROR_PORT, MESSENGER_ERROR_TCP_SERVER, MESSENGER_ERROR_OTHER -}; +} Messenger_Error; /* Run this at startup. * return allocated instance of Messenger on success. diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.c b/protocols/Tox/libtox/src/toxcore/TCP_client.c index a6c32f9c64..381d9b801a 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_client.c +++ b/protocols/Tox/libtox/src/toxcore/TCP_client.c @@ -27,14 +27,22 @@ #include "TCP_client.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mono_time.h" #include "util.h" -#if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32) -#include <sys/ioctl.h> -#endif +typedef struct TCP_Client_Conn { + // TODO(iphydf): Add an enum for this. + uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint32_t number; +} TCP_Client_Conn; struct TCP_Client_Connection { - TCP_CLIENT_STATUS status; + TCP_Client_Status status; Socket sock; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */ uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */ @@ -51,7 +59,8 @@ struct TCP_Client_Connection { uint16_t last_packet_length; uint16_t last_packet_sent; - TCP_Priority_List *priority_queue_start, *priority_queue_end; + TCP_Priority_List *priority_queue_start; + TCP_Priority_List *priority_queue_end; uint64_t kill_at; @@ -61,22 +70,17 @@ struct TCP_Client_Connection { uint64_t ping_response_id; uint64_t ping_request_id; - struct { - uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint32_t number; - } connections[NUM_CLIENT_CONNECTIONS]; - int (*response_callback)(void *object, uint8_t connection_id, const uint8_t *public_key); + TCP_Client_Conn connections[NUM_CLIENT_CONNECTIONS]; + tcp_routing_response_cb *response_callback; void *response_callback_object; - int (*status_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t status); + tcp_routing_status_cb *status_callback; void *status_callback_object; - int (*data_callback)(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length, - void *userdata); + tcp_routing_data_cb *data_callback; void *data_callback_object; - int (*oob_data_callback)(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata); + tcp_oob_data_cb *oob_data_callback; void *oob_data_callback_object; - int (*onion_callback)(void *object, const uint8_t *data, uint16_t length, void *userdata); + tcp_onion_response_cb *onion_callback; void *onion_callback_object; /* Can be used by user. */ @@ -94,7 +98,7 @@ IP_Port tcp_con_ip_port(const TCP_Client_Connection *con) return con->ip_port; } -TCP_CLIENT_STATUS tcp_con_status(const TCP_Client_Connection *con) +TCP_Client_Status tcp_con_status(const TCP_Client_Connection *con) { return con->status; } @@ -132,7 +136,7 @@ static int connect_sock_to(Socket sock, IP_Port ip_port, TCP_Proxy_Info *proxy_i /* return 1 on success. * return 0 on failure. */ -static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_conn) +static int proxy_http_generate_connection_request(TCP_Client_Connection *tcp_conn) { char one[] = "CONNECT "; char two[] = " HTTP/1.1\nHost: "; @@ -140,20 +144,20 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con char ip[TOX_INET6_ADDRSTRLEN]; - if (!ip_parse_addr(&TCP_conn->ip_port.ip, ip, sizeof(ip))) { + if (!ip_parse_addr(&tcp_conn->ip_port.ip, ip, sizeof(ip))) { return 0; } - const uint16_t port = net_ntohs(TCP_conn->ip_port.port); - const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, + const uint16_t port = net_ntohs(tcp_conn->ip_port.port); + const int written = snprintf((char *)tcp_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, ip, port, three); if (written < 0 || MAX_PACKET_SIZE < written) { return 0; } - TCP_conn->last_packet_length = written; - TCP_conn->last_packet_sent = 0; + tcp_conn->last_packet_length = written; + tcp_conn->last_packet_sent = 0; return 1; } @@ -162,12 +166,12 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con * return 0 if no data received. * return -1 on failure (connection refused). */ -static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) +static int proxy_http_read_connection_response(TCP_Client_Connection *tcp_conn) { char success[] = "200"; uint8_t data[16]; // draining works the best if the length is a power of 2 - int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data) - 1); + int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data) - 1); if (ret == -1) { return 0; @@ -177,11 +181,11 @@ static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) if (strstr((char *)data, success)) { // drain all data - unsigned int data_left = TCP_socket_data_recv_buffer(TCP_conn->sock); + unsigned int data_left = net_socket_data_recv_buffer(tcp_conn->sock); if (data_left) { VLA(uint8_t, temp_data, data_left); - read_TCP_packet(TCP_conn->sock, temp_data, data_left); + read_TCP_packet(tcp_conn->sock, temp_data, data_left); } return 1; @@ -190,24 +194,24 @@ static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) return -1; } -static void proxy_socks5_generate_handshake(TCP_Client_Connection *TCP_conn) +static void proxy_socks5_generate_handshake(TCP_Client_Connection *tcp_conn) { - TCP_conn->last_packet[0] = 5; /* SOCKSv5 */ - TCP_conn->last_packet[1] = 1; /* number of authentication methods supported */ - TCP_conn->last_packet[2] = 0; /* No authentication */ + tcp_conn->last_packet[0] = 5; /* SOCKSv5 */ + tcp_conn->last_packet[1] = 1; /* number of authentication methods supported */ + tcp_conn->last_packet[2] = 0; /* No authentication */ - TCP_conn->last_packet_length = 3; - TCP_conn->last_packet_sent = 0; + tcp_conn->last_packet_length = 3; + tcp_conn->last_packet_sent = 0; } /* return 1 on success. * return 0 if no data received. * return -1 on failure (connection refused). */ -static int socks5_read_handshake_response(TCP_Client_Connection *TCP_conn) +static int socks5_read_handshake_response(TCP_Client_Connection *tcp_conn) { uint8_t data[2]; - int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); + int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data)); if (ret == -1) { return 0; @@ -220,41 +224,41 @@ static int socks5_read_handshake_response(TCP_Client_Connection *TCP_conn) return -1; } -static void proxy_socks5_generate_connection_request(TCP_Client_Connection *TCP_conn) +static void proxy_socks5_generate_connection_request(TCP_Client_Connection *tcp_conn) { - TCP_conn->last_packet[0] = 5; /* SOCKSv5 */ - TCP_conn->last_packet[1] = 1; /* command code: establish a TCP/IP stream connection */ - TCP_conn->last_packet[2] = 0; /* reserved, must be 0 */ + tcp_conn->last_packet[0] = 5; /* SOCKSv5 */ + tcp_conn->last_packet[1] = 1; /* command code: establish a TCP/IP stream connection */ + tcp_conn->last_packet[2] = 0; /* reserved, must be 0 */ uint16_t length = 3; - if (TCP_conn->ip_port.ip.family == TOX_AF_INET) { - TCP_conn->last_packet[3] = 1; /* IPv4 address */ + if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) { + tcp_conn->last_packet[3] = 1; /* IPv4 address */ ++length; - memcpy(TCP_conn->last_packet + length, TCP_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4)); + memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4)); length += sizeof(IP4); } else { - TCP_conn->last_packet[3] = 4; /* IPv6 address */ + tcp_conn->last_packet[3] = 4; /* IPv6 address */ ++length; - memcpy(TCP_conn->last_packet + length, TCP_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6)); + memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6)); length += sizeof(IP6); } - memcpy(TCP_conn->last_packet + length, &TCP_conn->ip_port.port, sizeof(uint16_t)); + memcpy(tcp_conn->last_packet + length, &tcp_conn->ip_port.port, sizeof(uint16_t)); length += sizeof(uint16_t); - TCP_conn->last_packet_length = length; - TCP_conn->last_packet_sent = 0; + tcp_conn->last_packet_length = length; + tcp_conn->last_packet_sent = 0; } /* return 1 on success. * return 0 if no data received. * return -1 on failure (connection refused). */ -static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn) +static int proxy_socks5_read_connection_response(TCP_Client_Connection *tcp_conn) { - if (TCP_conn->ip_port.ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) { uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)]; - int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); + int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data)); if (ret == -1) { return 0; @@ -265,7 +269,7 @@ static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn } } else { uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)]; - int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); + int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data)); if (ret == -1) { return 0; @@ -282,23 +286,23 @@ static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn /* return 0 on success. * return -1 on failure. */ -static int generate_handshake(TCP_Client_Connection *TCP_conn) +static int generate_handshake(TCP_Client_Connection *tcp_conn) { uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; - crypto_new_keypair(plain, TCP_conn->temp_secret_key); - random_nonce(TCP_conn->sent_nonce); - memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, TCP_conn->sent_nonce, CRYPTO_NONCE_SIZE); - memcpy(TCP_conn->last_packet, TCP_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); - random_nonce(TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE); - int len = encrypt_data_symmetric(TCP_conn->shared_key, TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, - sizeof(plain), TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); + crypto_new_keypair(plain, tcp_conn->temp_secret_key); + random_nonce(tcp_conn->sent_nonce); + memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->sent_nonce, CRYPTO_NONCE_SIZE); + memcpy(tcp_conn->last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + random_nonce(tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE); + int len = encrypt_data_symmetric(tcp_conn->shared_key, tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, + sizeof(plain), tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); if (len != sizeof(plain) + CRYPTO_MAC_SIZE) { return -1; } - TCP_conn->last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE; - TCP_conn->last_packet_sent = 0; + tcp_conn->last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE; + tcp_conn->last_packet_sent = 0; return 0; } @@ -307,19 +311,19 @@ static int generate_handshake(TCP_Client_Connection *TCP_conn) * return 0 on success. * return -1 on failure. */ -static int handle_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *data) +static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data) { uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; - int len = decrypt_data_symmetric(TCP_conn->shared_key, data, data + CRYPTO_NONCE_SIZE, + int len = decrypt_data_symmetric(tcp_conn->shared_key, data, data + CRYPTO_NONCE_SIZE, TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain); if (len != sizeof(plain)) { return -1; } - memcpy(TCP_conn->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - encrypt_precompute(plain, TCP_conn->temp_secret_key, TCP_conn->shared_key); - crypto_memzero(TCP_conn->temp_secret_key, CRYPTO_SECRET_KEY_SIZE); + memcpy(tcp_conn->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + encrypt_precompute(plain, tcp_conn->temp_secret_key, tcp_conn->shared_key); + crypto_memzero(tcp_conn->temp_secret_key, CRYPTO_SECRET_KEY_SIZE); return 0; } @@ -332,9 +336,8 @@ static int client_send_pending_data_nonpriority(TCP_Client_Connection *con) return 0; } - uint16_t left = con->last_packet_length - con->last_packet_sent; - const char *data = (const char *)(con->last_packet + con->last_packet_sent); - int len = send(con->sock, data, left, MSG_NOSIGNAL); + const uint16_t left = con->last_packet_length - con->last_packet_sent; + const int len = net_send(con->sock, con->last_packet + con->last_packet_sent, left); if (len <= 0) { return -1; @@ -363,8 +366,8 @@ static int client_send_pending_data(TCP_Client_Connection *con) TCP_Priority_List *p = con->priority_queue_start; while (p) { - uint16_t left = p->size - p->sent; - int len = send(con->sock, (const char *)(p->data + p->sent), left, MSG_NOSIGNAL); + const uint16_t left = p->size - p->sent; + const int len = net_send(con->sock, p->data + p->sent, left); if (len != left) { if (len > 0) { @@ -459,7 +462,7 @@ static int write_packet_TCP_client_secure_connection(TCP_Client_Connection *con, } if (priority) { - len = sendpriority ? send(con->sock, (const char *)packet, SIZEOF_VLA(packet), MSG_NOSIGNAL) : 0; + len = sendpriority ? net_send(con->sock, packet, SIZEOF_VLA(packet)) : 0; if (len <= 0) { len = 0; @@ -474,7 +477,7 @@ static int write_packet_TCP_client_secure_connection(TCP_Client_Connection *con, return client_add_priority(con, packet, SIZEOF_VLA(packet), len); } - len = send(con->sock, (const char *)packet, SIZEOF_VLA(packet), MSG_NOSIGNAL); + len = net_send(con->sock, packet, SIZEOF_VLA(packet)); if (len <= 0) { return 0; @@ -504,15 +507,13 @@ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key) return write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); } -void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, - const uint8_t *public_key), void *object) +void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object) { con->response_callback = response_callback; con->response_callback_object = object; } -void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number, - uint8_t connection_id, uint8_t status), void *object) +void routing_status_handler(TCP_Client_Connection *con, tcp_routing_status_cb *status_callback, void *object) { con->status_callback = status_callback; con->status_callback_object = object; @@ -584,15 +585,13 @@ int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32 return 0; } -void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, - uint8_t connection_id, const uint8_t *data, uint16_t length, void *userdata), void *object) +void routing_data_handler(TCP_Client_Connection *con, tcp_routing_data_cb *data_callback, void *object) { con->data_callback = data_callback; con->data_callback_object = object; } -void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, const uint8_t *public_key, - const uint8_t *data, uint16_t length, void *userdata), void *object) +void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object) { con->oob_data_callback = oob_data_callback; con->oob_data_callback_object = object; @@ -623,9 +622,9 @@ static int tcp_send_ping_request(TCP_Client_Connection *con) uint8_t packet[1 + sizeof(uint64_t)]; packet[0] = TCP_PACKET_PING; memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t)); - int ret; + const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); - if ((ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1)) == 1) { + if (ret == 1) { con->ping_request_id = 0; } @@ -645,9 +644,9 @@ static int tcp_send_ping_response(TCP_Client_Connection *con) uint8_t packet[1 + sizeof(uint64_t)]; packet[0] = TCP_PACKET_PONG; memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t)); - int ret; + const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); - if ((ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1)) == 1) { + if (ret == 1) { con->ping_response_id = 0; } @@ -681,8 +680,7 @@ int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0); } -void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, - uint16_t length, void *userdata), void *object) +void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object) { con->onion_callback = onion_callback; con->onion_callback_object = object; @@ -697,7 +695,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public return nullptr; } - if (ip_port.ip.family != TOX_AF_INET && ip_port.ip.family != TOX_AF_INET6) { + if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) { return nullptr; } @@ -708,7 +706,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public proxy_info = &default_proxyinfo; } - uint8_t family = ip_port.ip.family; + Family family = ip_port.ip.family; if (proxy_info->proxy_type != TCP_PROXY_NONE) { family = proxy_info->ip_port.ip.family; @@ -928,15 +926,35 @@ static int handle_TCP_client_packet(TCP_Client_Connection *conn, const uint8_t * return 0; } +static bool tcp_process_packet(TCP_Client_Connection *conn, void *userdata) +{ + uint8_t packet[MAX_PACKET_SIZE]; + const int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, + conn->recv_nonce, packet, sizeof(packet)); + + if (len == 0) { + return false; + } + + if (len == -1) { + conn->status = TCP_CLIENT_DISCONNECTED; + return false; + } + + if (handle_TCP_client_packet(conn, packet, len, userdata) == -1) { + conn->status = TCP_CLIENT_DISCONNECTED; + return false; + } + + return true; +} + static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) { client_send_pending_data(conn); tcp_send_ping_response(conn); tcp_send_ping_request(conn); - uint8_t packet[MAX_PACKET_SIZE]; - int len; - if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) { uint64_t ping_id = random_u64(); @@ -944,7 +962,8 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) ++ping_id; } - conn->ping_request_id = conn->ping_id = ping_id; + conn->ping_request_id = ping_id; + conn->ping_id = ping_id; tcp_send_ping_request(conn); conn->last_pinged = unix_time(); } @@ -954,17 +973,9 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) return 0; } - while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, - conn->recv_nonce, packet, sizeof(packet)))) { - if (len == -1) { - conn->status = TCP_CLIENT_DISCONNECTED; - break; - } - - if (handle_TCP_client_packet(conn, packet, len, userdata) == -1) { - conn->status = TCP_CLIENT_DISCONNECTED; - break; - } + while (tcp_process_packet(conn, userdata)) { + // Keep reading until error or out of data. + continue; } return 0; @@ -972,102 +983,102 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) /* Run the TCP connection */ -void do_TCP_connection(TCP_Client_Connection *TCP_connection, void *userdata) +void do_TCP_connection(TCP_Client_Connection *tcp_connection, void *userdata) { unix_time_update(); - if (TCP_connection->status == TCP_CLIENT_DISCONNECTED) { + if (tcp_connection->status == TCP_CLIENT_DISCONNECTED) { return; } - if (TCP_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) { - if (client_send_pending_data(TCP_connection) == 0) { - int ret = proxy_http_read_connection_response(TCP_connection); + if (tcp_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) { + if (client_send_pending_data(tcp_connection) == 0) { + int ret = proxy_http_read_connection_response(tcp_connection); if (ret == -1) { - TCP_connection->kill_at = 0; - TCP_connection->status = TCP_CLIENT_DISCONNECTED; + tcp_connection->kill_at = 0; + tcp_connection->status = TCP_CLIENT_DISCONNECTED; } if (ret == 1) { - generate_handshake(TCP_connection); - TCP_connection->status = TCP_CLIENT_CONNECTING; + generate_handshake(tcp_connection); + tcp_connection->status = TCP_CLIENT_CONNECTING; } } } - if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) { - if (client_send_pending_data(TCP_connection) == 0) { - int ret = socks5_read_handshake_response(TCP_connection); + if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) { + if (client_send_pending_data(tcp_connection) == 0) { + int ret = socks5_read_handshake_response(tcp_connection); if (ret == -1) { - TCP_connection->kill_at = 0; - TCP_connection->status = TCP_CLIENT_DISCONNECTED; + tcp_connection->kill_at = 0; + tcp_connection->status = TCP_CLIENT_DISCONNECTED; } if (ret == 1) { - proxy_socks5_generate_connection_request(TCP_connection); - TCP_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED; + proxy_socks5_generate_connection_request(tcp_connection); + tcp_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED; } } } - if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) { - if (client_send_pending_data(TCP_connection) == 0) { - int ret = proxy_socks5_read_connection_response(TCP_connection); + if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) { + if (client_send_pending_data(tcp_connection) == 0) { + int ret = proxy_socks5_read_connection_response(tcp_connection); if (ret == -1) { - TCP_connection->kill_at = 0; - TCP_connection->status = TCP_CLIENT_DISCONNECTED; + tcp_connection->kill_at = 0; + tcp_connection->status = TCP_CLIENT_DISCONNECTED; } if (ret == 1) { - generate_handshake(TCP_connection); - TCP_connection->status = TCP_CLIENT_CONNECTING; + generate_handshake(tcp_connection); + tcp_connection->status = TCP_CLIENT_CONNECTING; } } } - if (TCP_connection->status == TCP_CLIENT_CONNECTING) { - if (client_send_pending_data(TCP_connection) == 0) { - TCP_connection->status = TCP_CLIENT_UNCONFIRMED; + if (tcp_connection->status == TCP_CLIENT_CONNECTING) { + if (client_send_pending_data(tcp_connection) == 0) { + tcp_connection->status = TCP_CLIENT_UNCONFIRMED; } } - if (TCP_connection->status == TCP_CLIENT_UNCONFIRMED) { + if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) { uint8_t data[TCP_SERVER_HANDSHAKE_SIZE]; - int len = read_TCP_packet(TCP_connection->sock, data, sizeof(data)); + int len = read_TCP_packet(tcp_connection->sock, data, sizeof(data)); if (sizeof(data) == len) { - if (handle_handshake(TCP_connection, data) == 0) { - TCP_connection->kill_at = ~0; - TCP_connection->status = TCP_CLIENT_CONFIRMED; + if (handle_handshake(tcp_connection, data) == 0) { + tcp_connection->kill_at = ~0; + tcp_connection->status = TCP_CLIENT_CONFIRMED; } else { - TCP_connection->kill_at = 0; - TCP_connection->status = TCP_CLIENT_DISCONNECTED; + tcp_connection->kill_at = 0; + tcp_connection->status = TCP_CLIENT_DISCONNECTED; } } } - if (TCP_connection->status == TCP_CLIENT_CONFIRMED) { - do_confirmed_TCP(TCP_connection, userdata); + if (tcp_connection->status == TCP_CLIENT_CONFIRMED) { + do_confirmed_TCP(tcp_connection, userdata); } - if (TCP_connection->kill_at <= unix_time()) { - TCP_connection->status = TCP_CLIENT_DISCONNECTED; + if (tcp_connection->kill_at <= unix_time()) { + tcp_connection->status = TCP_CLIENT_DISCONNECTED; } } /* Kill the TCP connection */ -void kill_TCP_connection(TCP_Client_Connection *TCP_connection) +void kill_TCP_connection(TCP_Client_Connection *tcp_connection) { - if (TCP_connection == nullptr) { + if (tcp_connection == nullptr) { return; } - wipe_priority_list(TCP_connection); - kill_sock(TCP_connection->sock); - crypto_memzero(TCP_connection, sizeof(TCP_Client_Connection)); - free(TCP_connection); + wipe_priority_list(tcp_connection); + kill_sock(tcp_connection->sock); + crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection)); + free(tcp_connection); } diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.h b/protocols/Tox/libtox/src/toxcore/TCP_client.h index 96e04d6791..8bfe415563 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_client.h +++ b/protocols/Tox/libtox/src/toxcore/TCP_client.h @@ -29,18 +29,18 @@ #define TCP_CONNECTION_TIMEOUT 10 -typedef enum { +typedef enum TCP_Proxy_Type { TCP_PROXY_NONE, TCP_PROXY_HTTP, TCP_PROXY_SOCKS5 -} TCP_PROXY_TYPE; +} TCP_Proxy_Type; -typedef struct { +typedef struct TCP_Proxy_Info { IP_Port ip_port; uint8_t proxy_type; // a value from TCP_PROXY_TYPE } TCP_Proxy_Info; -typedef enum { +typedef enum TCP_Client_Status { TCP_CLIENT_NO_STATUS, TCP_CLIENT_PROXY_HTTP_CONNECTING, TCP_CLIENT_PROXY_SOCKS5_CONNECTING, @@ -49,12 +49,13 @@ typedef enum { TCP_CLIENT_UNCONFIRMED, TCP_CLIENT_CONFIRMED, TCP_CLIENT_DISCONNECTED, -} TCP_CLIENT_STATUS; +} TCP_Client_Status; + typedef struct TCP_Client_Connection TCP_Client_Connection; const uint8_t *tcp_con_public_key(const TCP_Client_Connection *con); IP_Port tcp_con_ip_port(const TCP_Client_Connection *con); -TCP_CLIENT_STATUS tcp_con_status(const TCP_Client_Connection *con); +TCP_Client_Status tcp_con_status(const TCP_Client_Connection *con); void *tcp_con_custom_object(const TCP_Client_Connection *con); uint32_t tcp_con_custom_uint(const TCP_Client_Connection *con); @@ -68,29 +69,31 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public /* Run the TCP connection */ -void do_TCP_connection(TCP_Client_Connection *TCP_connection, void *userdata); +void do_TCP_connection(TCP_Client_Connection *tcp_connection, void *userdata); /* Kill the TCP connection */ -void kill_TCP_connection(TCP_Client_Connection *TCP_connection); +void kill_TCP_connection(TCP_Client_Connection *tcp_connection); + +typedef int tcp_onion_response_cb(void *object, const uint8_t *data, uint16_t length, void *userdata); /* return 1 on success. * return 0 if could not send packet. * return -1 on failure (connection must be killed). */ int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length); -void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, - uint16_t length, void *userdata), void *object); +void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object); + +typedef int tcp_routing_response_cb(void *object, uint8_t connection_id, const uint8_t *public_key); +typedef int tcp_routing_status_cb(void *object, uint32_t number, uint8_t connection_id, uint8_t status); /* return 1 on success. * return 0 if could not send packet. * return -1 on failure (connection must be killed). */ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key); -void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, - const uint8_t *public_key), void *object); -void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number, - uint8_t connection_id, uint8_t status), void *object); +void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object); +void routing_status_handler(TCP_Client_Connection *con, tcp_routing_status_cb *status_callback, void *object); /* return 1 on success. * return 0 if could not send packet. @@ -107,21 +110,25 @@ int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id); */ int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32_t number); +typedef int tcp_routing_data_cb(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, + uint16_t length, void *userdata); + /* return 1 on success. * return 0 if could not send packet. * return -1 on failure. */ int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length); -void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, - uint8_t connection_id, const uint8_t *data, uint16_t length, void *userdata), void *object); +void routing_data_handler(TCP_Client_Connection *con, tcp_routing_data_cb *data_callback, void *object); + +typedef int tcp_oob_data_cb(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length, + void *userdata); /* return 1 on success. * return 0 if could not send packet. * return -1 on failure. */ int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length); -void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, const uint8_t *public_key, - const uint8_t *data, uint16_t length, void *userdata), void *object); +void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object); #endif diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.c b/protocols/Tox/libtox/src/toxcore/TCP_connection.c index d10114f625..2d2dd47028 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_connection.c +++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.c @@ -27,9 +27,12 @@ #include "TCP_connection.h" -#include "util.h" - #include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include "mono_time.h" +#include "util.h" struct TCP_Connections { @@ -44,14 +47,13 @@ struct TCP_Connections { TCP_con *tcp_connections; uint32_t tcp_connections_length; /* Length of tcp_connections array. */ - int (*tcp_data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); + tcp_data_cb *tcp_data_callback; void *tcp_data_callback_object; - int (*tcp_oob_callback)(void *object, const uint8_t *public_key, unsigned int tcp_connections_number, - const uint8_t *data, uint16_t length, void *userdata); + tcp_oob_cb *tcp_oob_callback; void *tcp_oob_callback_object; - int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length, void *userdata); + tcp_onion_cb *tcp_onion_callback; void *tcp_onion_callback_object; TCP_Proxy_Info proxy_info; @@ -72,28 +74,44 @@ const uint8_t *tcp_connections_public_key(const TCP_Connections *tcp_c) * return -1 if realloc fails. * return 0 if it succeeds. */ -#define MAKE_REALLOC(T) \ -static int realloc_##T(T **array, size_t num) \ -{ \ - if (!num) { \ - free(*array); \ - *array = nullptr; \ - return 0; \ - } \ - \ - T *temp_pointer = (T *)realloc(*array, num * sizeof(T)); \ - \ - if (!temp_pointer) { \ - return -1; \ - } \ - \ - *array = temp_pointer; \ - \ - return 0; \ +static int realloc_TCP_Connection_to(TCP_Connection_to **array, size_t num) +{ + if (!num) { + free(*array); + *array = nullptr; + return 0; + } + + TCP_Connection_to *temp_pointer = + (TCP_Connection_to *)realloc(*array, num * sizeof(TCP_Connection_to)); + + if (!temp_pointer) { + return -1; + } + + *array = temp_pointer; + + return 0; } -MAKE_REALLOC(TCP_Connection_to) -MAKE_REALLOC(TCP_con) +static int realloc_TCP_con(TCP_con **array, size_t num) +{ + if (!num) { + free(*array); + *array = nullptr; + return 0; + } + + TCP_con *temp_pointer = (TCP_con *)realloc(*array, num * sizeof(TCP_con)); + + if (!temp_pointer) { + return -1; + } + + *array = temp_pointer; + + return 0; +} /* return 1 if the connections_number is not valid. @@ -418,8 +436,7 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num /* Set the callback for TCP data packets. */ -void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_callback)(void *object, int id, - const uint8_t *data, uint16_t length, void *userdata), void *object) +void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_data_cb *tcp_data_callback, void *object) { tcp_c->tcp_data_callback = tcp_data_callback; tcp_c->tcp_data_callback_object = object; @@ -427,9 +444,7 @@ void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_c /* Set the callback for TCP onion packets. */ -void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oob_callback)(void *object, - const uint8_t *public_key, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length, void *userdata), - void *object) +void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_oob_cb *tcp_oob_callback, void *object) { tcp_c->tcp_oob_callback = tcp_oob_callback; tcp_c->tcp_oob_callback_object = object; @@ -437,8 +452,7 @@ void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oo /* Set the callback for TCP oob data packets. */ -void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_onion_callback)(void *object, - const uint8_t *data, uint16_t length, void *userdata), void *object) +void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_onion_cb *tcp_onion_callback, void *object) { tcp_c->tcp_onion_callback = tcp_onion_callback; tcp_c->tcp_onion_callback_object = object; @@ -912,10 +926,10 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key) { - TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; - TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); + TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con); - unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); + unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con); TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); if (!tcp_con) { @@ -945,10 +959,10 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status) { - TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; - TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); + TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con); - unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); + unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con); TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); TCP_Connection_to *con_to = get_connection(tcp_c, number); @@ -988,10 +1002,10 @@ static int tcp_conn_data_callback(void *object, uint32_t number, uint8_t connect return -1; } - TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; - TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); + TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con); - unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); + unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con); TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); if (!tcp_con) { @@ -1018,10 +1032,10 @@ static int tcp_conn_oob_callback(void *object, const uint8_t *public_key, const return -1; } - TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; - TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); + TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con); - unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); + unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con); TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); if (!tcp_con) { @@ -1123,13 +1137,13 @@ static int tcp_relay_on_online(TCP_Connections *tcp_c, int tcp_connections_numbe static int add_tcp_relay_instance(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk) { - if (ip_port.ip.family == TCP_INET) { - ip_port.ip.family = TOX_AF_INET; - } else if (ip_port.ip.family == TCP_INET6) { - ip_port.ip.family = TOX_AF_INET6; + if (net_family_is_tcp_ipv4(ip_port.ip.family)) { + ip_port.ip.family = net_family_ipv4; + } else if (net_family_is_tcp_ipv6(ip_port.ip.family)) { + ip_port.ip.family = net_family_ipv6; } - if (ip_port.ip.family != TOX_AF_INET && ip_port.ip.family != TOX_AF_INET6) { + if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) { return -1; } @@ -1284,10 +1298,12 @@ unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_ memcpy(tcp_relays[copied].public_key, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); tcp_relays[copied].ip_port = tcp_con_ip_port(tcp_con->connection); - if (tcp_relays[copied].ip_port.ip.family == TOX_AF_INET) { - tcp_relays[copied].ip_port.ip.family = TCP_INET; - } else if (tcp_relays[copied].ip_port.ip.family == TOX_AF_INET6) { - tcp_relays[copied].ip_port.ip.family = TCP_INET6; + Family *const family = &tcp_relays[copied].ip_port.ip.family; + + if (net_family_is_ipv4(*family)) { + *family = net_family_tcp_ipv4; + } else if (net_family_is_ipv6(*family)) { + *family = net_family_tcp_ipv6; } ++copied; diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.h b/protocols/Tox/libtox/src/toxcore/TCP_connection.h index a45129a7e8..658ee1f46f 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_connection.h +++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.h @@ -51,20 +51,22 @@ /* Number of TCP connections used for onion purposes. */ #define NUM_ONION_TCP_CONNECTIONS RECOMMENDED_FRIEND_TCP_CONNECTIONS -typedef struct { +typedef struct TCP_Conn_to { + uint32_t tcp_connection; + unsigned int status; + unsigned int connection_id; +} TCP_Conn_to; + +typedef struct TCP_Connection_to { uint8_t status; uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ - struct { - uint32_t tcp_connection; - unsigned int status; - unsigned int connection_id; - } connections[MAX_FRIEND_TCP_CONNECTIONS]; + TCP_Conn_to connections[MAX_FRIEND_TCP_CONNECTIONS]; int id; /* id used in callbacks. */ } TCP_Connection_to; -typedef struct { +typedef struct TCP_con { uint8_t status; TCP_Client_Connection *connection; uint64_t connected_time; @@ -124,21 +126,24 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status); int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *public_key, const uint8_t *packet, uint16_t length); +typedef int tcp_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); + /* Set the callback for TCP data packets. */ -void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_callback)(void *object, int id, - const uint8_t *data, uint16_t length, void *userdata), void *object); +void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_data_cb *tcp_data_callback, void *object); + +typedef int tcp_onion_cb(void *object, const uint8_t *data, uint16_t length, void *userdata); /* Set the callback for TCP onion packets. */ -void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_onion_callback)(void *object, - const uint8_t *data, uint16_t length, void *userdata), void *object); +void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_onion_cb *tcp_onion_callback, void *object); + +typedef int tcp_oob_cb(void *object, const uint8_t *public_key, unsigned int tcp_connections_number, + const uint8_t *data, uint16_t length, void *userdata); /* Set the callback for TCP oob data packets. */ -void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oob_callback)(void *object, - const uint8_t *public_key, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length, void *userdata), - void *object); +void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_oob_cb *tcp_oob_callback, void *object); /* Create a new TCP connection to public_key. * diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.c b/protocols/Tox/libtox/src/toxcore/TCP_server.c index 4541fce0ce..cc59d08824 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_server.c +++ b/protocols/Tox/libtox/src/toxcore/TCP_server.c @@ -27,12 +27,36 @@ #include "TCP_server.h" -#include "util.h" - +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32) #include <sys/ioctl.h> #endif +#ifdef TCP_SERVER_USE_EPOLL +#include <sys/epoll.h> +#include <unistd.h> +#endif + +#include "mono_time.h" +#include "util.h" + +#ifdef TCP_SERVER_USE_EPOLL +#define TCP_SOCKET_LISTENING 0 +#define TCP_SOCKET_INCOMING 1 +#define TCP_SOCKET_UNCONFIRMED 2 +#define TCP_SOCKET_CONFIRMED 3 +#endif + +typedef struct TCP_Secure_Conn { + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint32_t index; + // TODO(iphydf): Add an enum for this (same as in TCP_client.c, probably). + uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ + uint8_t other_id; +} TCP_Secure_Conn; + typedef struct TCP_Secure_Connection { Socket sock; uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -40,18 +64,14 @@ typedef struct TCP_Secure_Connection { uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint16_t next_packet_length; - struct { - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint32_t index; - uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ - uint8_t other_id; - } connections[NUM_CLIENT_CONNECTIONS]; + TCP_Secure_Conn connections[NUM_CLIENT_CONNECTIONS]; uint8_t last_packet[2 + MAX_PACKET_SIZE]; uint8_t status; uint16_t last_packet_length; uint16_t last_packet_sent; - TCP_Priority_List *priority_queue_start, *priority_queue_end; + TCP_Priority_List *priority_queue_start; + TCP_Priority_List *priority_queue_end; uint64_t identifier; @@ -83,7 +103,7 @@ struct TCP_Server { uint64_t counter; - BS_LIST accepted_key_list; + BS_List accepted_key_list; }; const uint8_t *tcp_server_public_key(const TCP_Server *tcp_server) @@ -109,74 +129,74 @@ size_t tcp_server_listen_count(const TCP_Server *tcp_server) * return -1 if realloc fails. * return 0 if it succeeds. */ -static int realloc_connection(TCP_Server *TCP_server, uint32_t num) +static int realloc_connection(TCP_Server *tcp_server, uint32_t num) { if (num == 0) { - free(TCP_server->accepted_connection_array); - TCP_server->accepted_connection_array = nullptr; - TCP_server->size_accepted_connections = 0; + free(tcp_server->accepted_connection_array); + tcp_server->accepted_connection_array = nullptr; + tcp_server->size_accepted_connections = 0; return 0; } - if (num == TCP_server->size_accepted_connections) { + if (num == tcp_server->size_accepted_connections) { return 0; } TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc( - TCP_server->accepted_connection_array, + tcp_server->accepted_connection_array, num * sizeof(TCP_Secure_Connection)); if (new_connections == nullptr) { return -1; } - if (num > TCP_server->size_accepted_connections) { - uint32_t old_size = TCP_server->size_accepted_connections; + if (num > tcp_server->size_accepted_connections) { + uint32_t old_size = tcp_server->size_accepted_connections; uint32_t size_new_entries = (num - old_size) * sizeof(TCP_Secure_Connection); memset(new_connections + old_size, 0, size_new_entries); } - TCP_server->accepted_connection_array = new_connections; - TCP_server->size_accepted_connections = num; + tcp_server->accepted_connection_array = new_connections; + tcp_server->size_accepted_connections = num; return 0; } /* return index corresponding to connection with peer on success * return -1 on failure. */ -static int get_TCP_connection_index(const TCP_Server *TCP_server, const uint8_t *public_key) +static int get_TCP_connection_index(const TCP_Server *tcp_server, const uint8_t *public_key) { - return bs_list_find(&TCP_server->accepted_key_list, public_key); + return bs_list_find(&tcp_server->accepted_key_list, public_key); } -static int kill_accepted(TCP_Server *TCP_server, int index); +static int kill_accepted(TCP_Server *tcp_server, int index); /* Add accepted TCP connection to the list. * * return index on success * return -1 on failure */ -static int add_accepted(TCP_Server *TCP_server, const TCP_Secure_Connection *con) +static int add_accepted(TCP_Server *tcp_server, const TCP_Secure_Connection *con) { - int index = get_TCP_connection_index(TCP_server, con->public_key); + int index = get_TCP_connection_index(tcp_server, con->public_key); if (index != -1) { /* If an old connection to the same public key exists, kill it. */ - kill_accepted(TCP_server, index); + kill_accepted(tcp_server, index); index = -1; } - if (TCP_server->size_accepted_connections == TCP_server->num_accepted_connections) { - if (realloc_connection(TCP_server, TCP_server->size_accepted_connections + 4) == -1) { + if (tcp_server->size_accepted_connections == tcp_server->num_accepted_connections) { + if (realloc_connection(tcp_server, tcp_server->size_accepted_connections + 4) == -1) { return -1; } - index = TCP_server->num_accepted_connections; + index = tcp_server->num_accepted_connections; } else { uint32_t i; - for (i = TCP_server->size_accepted_connections; i != 0; --i) { - if (TCP_server->accepted_connection_array[i - 1].status == TCP_STATUS_NO_STATUS) { + for (i = tcp_server->size_accepted_connections; i != 0; --i) { + if (tcp_server->accepted_connection_array[i - 1].status == TCP_STATUS_NO_STATUS) { index = i - 1; break; } @@ -188,16 +208,16 @@ static int add_accepted(TCP_Server *TCP_server, const TCP_Secure_Connection *con return -1; } - if (!bs_list_add(&TCP_server->accepted_key_list, con->public_key, index)) { + if (!bs_list_add(&tcp_server->accepted_key_list, con->public_key, index)) { return -1; } - memcpy(&TCP_server->accepted_connection_array[index], con, sizeof(TCP_Secure_Connection)); - TCP_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED; - ++TCP_server->num_accepted_connections; - TCP_server->accepted_connection_array[index].identifier = ++TCP_server->counter; - TCP_server->accepted_connection_array[index].last_pinged = unix_time(); - TCP_server->accepted_connection_array[index].ping_id = 0; + memcpy(&tcp_server->accepted_connection_array[index], con, sizeof(TCP_Secure_Connection)); + tcp_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED; + ++tcp_server->num_accepted_connections; + tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter; + tcp_server->accepted_connection_array[index].last_pinged = unix_time(); + tcp_server->accepted_connection_array[index].ping_id = 0; return index; } @@ -207,46 +227,30 @@ static int add_accepted(TCP_Server *TCP_server, const TCP_Secure_Connection *con * return 0 on success * return -1 on failure */ -static int del_accepted(TCP_Server *TCP_server, int index) +static int del_accepted(TCP_Server *tcp_server, int index) { - if ((uint32_t)index >= TCP_server->size_accepted_connections) { + if ((uint32_t)index >= tcp_server->size_accepted_connections) { return -1; } - if (TCP_server->accepted_connection_array[index].status == TCP_STATUS_NO_STATUS) { + if (tcp_server->accepted_connection_array[index].status == TCP_STATUS_NO_STATUS) { return -1; } - if (!bs_list_remove(&TCP_server->accepted_key_list, TCP_server->accepted_connection_array[index].public_key, index)) { + if (!bs_list_remove(&tcp_server->accepted_key_list, tcp_server->accepted_connection_array[index].public_key, index)) { return -1; } - crypto_memzero(&TCP_server->accepted_connection_array[index], sizeof(TCP_Secure_Connection)); - --TCP_server->num_accepted_connections; + crypto_memzero(&tcp_server->accepted_connection_array[index], sizeof(TCP_Secure_Connection)); + --tcp_server->num_accepted_connections; - if (TCP_server->num_accepted_connections == 0) { - realloc_connection(TCP_server, 0); + if (tcp_server->num_accepted_connections == 0) { + realloc_connection(tcp_server, 0); } return 0; } -/* return the amount of data in the tcp recv buffer. - * return 0 on failure. - */ -unsigned int TCP_socket_data_recv_buffer(Socket sock) -{ -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) - unsigned long count = 0; - ioctlsocket(sock, FIONREAD, &count); -#else - int count = 0; - ioctl(sock, FIONREAD, &count); -#endif - - return count; -} - /* Read the next two bytes in TCP stream then convert them to * length (host byte order). * @@ -256,11 +260,11 @@ unsigned int TCP_socket_data_recv_buffer(Socket sock) */ uint16_t read_TCP_length(Socket sock) { - unsigned int count = TCP_socket_data_recv_buffer(sock); + const unsigned int count = net_socket_data_recv_buffer(sock); if (count >= sizeof(uint16_t)) { uint16_t length; - int len = recv(sock, (char *)&length, sizeof(uint16_t), MSG_NOSIGNAL); + const int len = net_recv(sock, &length, sizeof(uint16_t)); if (len != sizeof(uint16_t)) { fprintf(stderr, "FAIL recv packet\n"); @@ -286,10 +290,10 @@ uint16_t read_TCP_length(Socket sock) */ int read_TCP_packet(Socket sock, uint8_t *data, uint16_t length) { - unsigned int count = TCP_socket_data_recv_buffer(sock); + unsigned int count = net_socket_data_recv_buffer(sock); if (count >= length) { - int len = recv(sock, (char *)data, length, MSG_NOSIGNAL); + const int len = net_recv(sock, data, length); if (len != length) { fprintf(stderr, "FAIL recv packet\n"); @@ -356,8 +360,8 @@ static int send_pending_data_nonpriority(TCP_Secure_Connection *con) return 0; } - uint16_t left = con->last_packet_length - con->last_packet_sent; - int len = send(con->sock, (const char *)(con->last_packet + con->last_packet_sent), left, MSG_NOSIGNAL); + const uint16_t left = con->last_packet_length - con->last_packet_sent; + const int len = net_send(con->sock, con->last_packet + con->last_packet_sent, left); if (len <= 0) { return -1; @@ -386,8 +390,8 @@ static int send_pending_data(TCP_Secure_Connection *con) TCP_Priority_List *p = con->priority_queue_start; while (p) { - uint16_t left = p->size - p->sent; - int len = send(con->sock, (const char *)(p->data + p->sent), left, MSG_NOSIGNAL); + const uint16_t left = p->size - p->sent; + const int len = net_send(con->sock, p->data + p->sent, left); if (len != left) { if (len > 0) { @@ -462,7 +466,7 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE); - uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); + const uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); memcpy(packet, &c_length, sizeof(uint16_t)); int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); @@ -471,7 +475,7 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const } if (priority) { - len = sendpriority ? send(con->sock, (const char *)packet, SIZEOF_VLA(packet), MSG_NOSIGNAL) : 0; + len = sendpriority ? net_send(con->sock, packet, SIZEOF_VLA(packet)) : 0; if (len <= 0) { len = 0; @@ -486,7 +490,7 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const return add_priority(con, packet, SIZEOF_VLA(packet), len); } - len = send(con->sock, (const char *)packet, SIZEOF_VLA(packet), MSG_NOSIGNAL); + len = net_send(con->sock, packet, SIZEOF_VLA(packet)); if (len <= 0) { return 0; @@ -512,28 +516,28 @@ static void kill_TCP_secure_connection(TCP_Secure_Connection *con) crypto_memzero(con, sizeof(TCP_Secure_Connection)); } -static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t con_number); +static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number); /* Kill an accepted TCP_Secure_Connection * * return -1 on failure. * return 0 on success. */ -static int kill_accepted(TCP_Server *TCP_server, int index) +static int kill_accepted(TCP_Server *tcp_server, int index) { - if ((uint32_t)index >= TCP_server->size_accepted_connections) { + if ((uint32_t)index >= tcp_server->size_accepted_connections) { return -1; } uint32_t i; for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { - rm_connection_index(TCP_server, &TCP_server->accepted_connection_array[index], i); + rm_connection_index(tcp_server, &tcp_server->accepted_connection_array[index], i); } - Socket sock = TCP_server->accepted_connection_array[index].sock; + Socket sock = tcp_server->accepted_connection_array[index].sock; - if (del_accepted(TCP_server, index) != 0) { + if (del_accepted(tcp_server, index) != 0) { return -1; } @@ -583,7 +587,7 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, const uint8_t *data, return -1; } - if (TCP_SERVER_HANDSHAKE_SIZE != send(con->sock, (const char *)response, TCP_SERVER_HANDSHAKE_SIZE, MSG_NOSIGNAL)) { + if (TCP_SERVER_HANDSHAKE_SIZE != net_send(con->sock, response, TCP_SERVER_HANDSHAKE_SIZE)) { return -1; } @@ -599,9 +603,9 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, const uint8_t *data, static int read_connection_handshake(TCP_Secure_Connection *con, const uint8_t *self_secret_key) { uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE]; - int len = 0; + const int len = read_TCP_packet(con->sock, data, TCP_CLIENT_HANDSHAKE_SIZE); - if ((len = read_TCP_packet(con->sock, data, TCP_CLIENT_HANDSHAKE_SIZE)) != -1) { + if (len != -1) { return handle_TCP_handshake(con, data, len, self_secret_key); } @@ -645,11 +649,11 @@ static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id) /* return 0 on success. * return -1 on failure (connection must be killed). */ -static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *public_key) +static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key) { uint32_t i; uint32_t index = ~0; - TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; + TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id]; /* If person tries to cennect to himself we deny the request*/ if (public_key_cmp(con->public_key, public_key) == 0) { @@ -694,11 +698,11 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const con->connections[index].status = 1; memcpy(con->connections[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); - int other_index = get_TCP_connection_index(TCP_server, public_key); + int other_index = get_TCP_connection_index(tcp_server, public_key); if (other_index != -1) { uint32_t other_id = ~0; - TCP_Secure_Connection *other_conn = &TCP_server->accepted_connection_array[other_index]; + TCP_Secure_Connection *other_conn = &tcp_server->accepted_connection_array[other_index]; for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { if (other_conn->connections[i].status == 1 @@ -727,23 +731,23 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const /* return 0 on success. * return -1 on failure (connection must be killed). */ -static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data, +static int handle_TCP_oob_send(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data, uint16_t length) { if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) { return -1; } - TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; + TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id]; - int other_index = get_TCP_connection_index(TCP_server, public_key); + int other_index = get_TCP_connection_index(tcp_server, public_key); if (other_index != -1) { VLA(uint8_t, resp_packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length); resp_packet[0] = TCP_PACKET_OOB_RECV; memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length); - write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[other_index], resp_packet, + write_packet_TCP_secure_connection(&tcp_server->accepted_connection_array[other_index], resp_packet, SIZEOF_VLA(resp_packet), 0); } @@ -755,7 +759,7 @@ static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const ui * return -1 on failure. * return 0 on success. */ -static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t con_number) +static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number) { if (con_number >= NUM_CLIENT_CONNECTIONS) { return -1; @@ -767,15 +771,15 @@ static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *co if (con->connections[con_number].status == 2) { - if (index >= TCP_server->size_accepted_connections) { + if (index >= tcp_server->size_accepted_connections) { return -1; } - TCP_server->accepted_connection_array[index].connections[other_id].other_id = 0; - TCP_server->accepted_connection_array[index].connections[other_id].index = 0; - TCP_server->accepted_connection_array[index].connections[other_id].status = 1; + tcp_server->accepted_connection_array[index].connections[other_id].other_id = 0; + tcp_server->accepted_connection_array[index].connections[other_id].index = 0; + tcp_server->accepted_connection_array[index].connections[other_id].status = 1; // TODO(irungentoo): return values? - send_disconnect_notification(&TCP_server->accepted_connection_array[index], other_id); + send_disconnect_notification(&tcp_server->accepted_connection_array[index], other_id); } con->connections[con_number].index = 0; @@ -789,14 +793,14 @@ static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *co static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data, uint16_t length) { - TCP_Server *TCP_server = (TCP_Server *)object; + TCP_Server *tcp_server = (TCP_Server *)object; uint32_t index = dest.ip.ip.v6.uint32[0]; - if (index >= TCP_server->size_accepted_connections) { + if (index >= tcp_server->size_accepted_connections) { return 1; } - TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[index]; + TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[index]; if (con->identifier != dest.ip.ip.v6.uint64[1]) { return 1; @@ -816,13 +820,13 @@ static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data, /* return 0 on success * return -1 on failure */ -static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *data, uint16_t length) +static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *data, uint16_t length) { if (length == 0) { return -1; } - TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; + TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id]; switch (data[0]) { case TCP_PACKET_ROUTING_REQUEST: { @@ -830,7 +834,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint return -1; } - return handle_TCP_routing_req(TCP_server, con_id, data + 1); + return handle_TCP_routing_req(tcp_server, con_id, data + 1); } case TCP_PACKET_CONNECTION_NOTIFICATION: { @@ -846,7 +850,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint return -1; } - return rm_connection_index(TCP_server, con, data[1] - NUM_RESERVED_PORTS); + return rm_connection_index(tcp_server, con, data[1] - NUM_RESERVED_PORTS); } case TCP_PACKET_PING: { @@ -885,23 +889,23 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint return -1; } - return handle_TCP_oob_send(TCP_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE, + return handle_TCP_oob_send(tcp_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_PUBLIC_KEY_SIZE)); } case TCP_PACKET_ONION_REQUEST: { - if (TCP_server->onion) { + if (tcp_server->onion) { if (length <= 1 + CRYPTO_NONCE_SIZE + ONION_SEND_BASE * 2) { return -1; } IP_Port source; source.port = 0; // dummy initialise - source.ip.family = TCP_ONION_FAMILY; + source.ip.family = net_family_tcp_onion; source.ip.ip.v6.uint32[0] = con_id; source.ip.ip.v6.uint32[1] = 0; source.ip.ip.v6.uint64[1] = con->identifier; - onion_send_1(TCP_server->onion, data + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), source, + onion_send_1(tcp_server->onion, data + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), source, data + 1); } @@ -936,7 +940,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint VLA(uint8_t, new_data, length); memcpy(new_data, data, length); new_data[0] = other_c_id; - int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length, 0); + int ret = write_packet_TCP_secure_connection(&tcp_server->accepted_connection_array[index], new_data, length, 0); if (ret == -1) { return -1; @@ -950,10 +954,10 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint } -static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection *con, const uint8_t *data, +static int confirm_TCP_connection(TCP_Server *tcp_server, TCP_Secure_Connection *con, const uint8_t *data, uint16_t length) { - int index = add_accepted(TCP_server, con); + int index = add_accepted(tcp_server, con); if (index == -1) { kill_TCP_secure_connection(con); @@ -962,8 +966,8 @@ static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection crypto_memzero(con, sizeof(TCP_Secure_Connection)); - if (handle_TCP_packet(TCP_server, index, data, length) == -1) { - kill_accepted(TCP_server, index); + if (handle_TCP_packet(tcp_server, index, data, length) == -1) { + kill_accepted(tcp_server, index); return -1; } @@ -973,7 +977,7 @@ static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection /* return index on success * return -1 on failure */ -static int accept_connection(TCP_Server *TCP_server, Socket sock) +static int accept_connection(TCP_Server *tcp_server, Socket sock) { if (!sock_valid(sock)) { return -1; @@ -989,9 +993,9 @@ static int accept_connection(TCP_Server *TCP_server, Socket sock) return -1; } - uint16_t index = TCP_server->incoming_connection_queue_index % MAX_INCOMING_CONNECTIONS; + uint16_t index = tcp_server->incoming_connection_queue_index % MAX_INCOMING_CONNECTIONS; - TCP_Secure_Connection *conn = &TCP_server->incoming_connection_queue[index]; + TCP_Secure_Connection *conn = &tcp_server->incoming_connection_queue[index]; if (conn->status != TCP_STATUS_NO_STATUS) { kill_TCP_secure_connection(conn); @@ -1001,21 +1005,21 @@ static int accept_connection(TCP_Server *TCP_server, Socket sock) conn->sock = sock; conn->next_packet_length = 0; - ++TCP_server->incoming_connection_queue_index; + ++tcp_server->incoming_connection_queue_index; return index; } -static Socket new_listening_TCP_socket(int family, uint16_t port) +static Socket new_listening_TCP_socket(Family family, uint16_t port) { Socket sock = net_socket(family, TOX_SOCK_STREAM, TOX_PROTO_TCP); if (!sock_valid(sock)) { - return ~0; + return net_invalid_socket; } int ok = set_socket_nonblock(sock); - if (ok && family == TOX_AF_INET6) { + if (ok && net_family_is_ipv6(family)) { ok = set_socket_dualstack(sock); } @@ -1023,11 +1027,11 @@ static Socket new_listening_TCP_socket(int family, uint16_t port) ok = set_socket_reuseaddr(sock); } - ok = ok && bind_to_port(sock, family, port) && (listen(sock, TCP_MAX_BACKLOG) == 0); + ok = ok && bind_to_port(sock, family, port) && (net_listen(sock, TCP_MAX_BACKLOG) == 0); if (!ok) { kill_sock(sock); - return ~0; + return net_invalid_socket; } return sock; @@ -1068,13 +1072,7 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin #endif - uint8_t family; - - if (ipv6_enabled) { - family = TOX_AF_INET6; - } else { - family = TOX_AF_INET; - } + const Family family = ipv6_enabled ? net_family_ipv6 : net_family_ipv4; uint32_t i; #ifdef TCP_SERVER_USE_EPOLL @@ -1087,9 +1085,9 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin if (sock_valid(sock)) { #ifdef TCP_SERVER_USE_EPOLL ev.events = EPOLLIN | EPOLLET; - ev.data.u64 = sock | ((uint64_t)TCP_SOCKET_LISTENING << 32); + ev.data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_LISTENING << 32); - if (epoll_ctl(temp->efd, EPOLL_CTL_ADD, sock, &ev) == -1) { + if (epoll_ctl(temp->efd, EPOLL_CTL_ADD, sock.socket, &ev) == -1) { continue; } @@ -1119,35 +1117,35 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin return temp; } -static void do_TCP_accept_new(TCP_Server *TCP_server) +#ifndef TCP_SERVER_USE_EPOLL +static void do_TCP_accept_new(TCP_Server *tcp_server) { uint32_t i; - for (i = 0; i < TCP_server->num_listening_socks; ++i) { - struct sockaddr_storage addr; - socklen_t addrlen = sizeof(addr); + for (i = 0; i < tcp_server->num_listening_socks; ++i) { Socket sock; do { - sock = accept(TCP_server->socks_listening[i], (struct sockaddr *)&addr, &addrlen); - } while (accept_connection(TCP_server, sock) != -1); + sock = net_accept(tcp_server->socks_listening[i]); + } while (accept_connection(tcp_server, sock) != -1); } } +#endif -static int do_incoming(TCP_Server *TCP_server, uint32_t i) +static int do_incoming(TCP_Server *tcp_server, uint32_t i) { - if (TCP_server->incoming_connection_queue[i].status != TCP_STATUS_CONNECTED) { + if (tcp_server->incoming_connection_queue[i].status != TCP_STATUS_CONNECTED) { return -1; } - int ret = read_connection_handshake(&TCP_server->incoming_connection_queue[i], TCP_server->secret_key); + int ret = read_connection_handshake(&tcp_server->incoming_connection_queue[i], tcp_server->secret_key); if (ret == -1) { - kill_TCP_secure_connection(&TCP_server->incoming_connection_queue[i]); + kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[i]); } else if (ret == 1) { - int index_new = TCP_server->unconfirmed_connection_queue_index % MAX_INCOMING_CONNECTIONS; - TCP_Secure_Connection *conn_old = &TCP_server->incoming_connection_queue[i]; - TCP_Secure_Connection *conn_new = &TCP_server->unconfirmed_connection_queue[index_new]; + int index_new = tcp_server->unconfirmed_connection_queue_index % MAX_INCOMING_CONNECTIONS; + TCP_Secure_Connection *conn_old = &tcp_server->incoming_connection_queue[i]; + TCP_Secure_Connection *conn_new = &tcp_server->unconfirmed_connection_queue[index_new]; if (conn_new->status != TCP_STATUS_NO_STATUS) { kill_TCP_secure_connection(conn_new); @@ -1155,7 +1153,7 @@ static int do_incoming(TCP_Server *TCP_server, uint32_t i) memcpy(conn_new, conn_old, sizeof(TCP_Secure_Connection)); crypto_memzero(conn_old, sizeof(TCP_Secure_Connection)); - ++TCP_server->unconfirmed_connection_queue_index; + ++tcp_server->unconfirmed_connection_queue_index; return index_new; } @@ -1163,9 +1161,9 @@ static int do_incoming(TCP_Server *TCP_server, uint32_t i) return -1; } -static int do_unconfirmed(TCP_Server *TCP_server, uint32_t i) +static int do_unconfirmed(TCP_Server *tcp_server, uint32_t i) { - TCP_Secure_Connection *conn = &TCP_server->unconfirmed_connection_queue[i]; + TCP_Secure_Connection *conn = &tcp_server->unconfirmed_connection_queue[i]; if (conn->status != TCP_STATUS_UNCONFIRMED) { return -1; @@ -1184,62 +1182,76 @@ static int do_unconfirmed(TCP_Server *TCP_server, uint32_t i) return -1; } - return confirm_TCP_connection(TCP_server, conn, packet, len); + return confirm_TCP_connection(tcp_server, conn, packet, len); } -static void do_confirmed_recv(TCP_Server *TCP_server, uint32_t i) +static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i) { - TCP_Secure_Connection *conn = &TCP_server->accepted_connection_array[i]; + TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i]; uint8_t packet[MAX_PACKET_SIZE]; - int len; + int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, + conn->recv_nonce, packet, sizeof(packet)); - while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, - conn->recv_nonce, packet, sizeof(packet)))) { - if (len == -1) { - kill_accepted(TCP_server, i); - break; - } + if (len == 0) { + return false; + } - if (handle_TCP_packet(TCP_server, i, packet, len) == -1) { - kill_accepted(TCP_server, i); - break; - } + if (len == -1) { + kill_accepted(tcp_server, i); + return false; } + + if (handle_TCP_packet(tcp_server, i, packet, len) == -1) { + kill_accepted(tcp_server, i); + return false; + } + + return true; } -static void do_TCP_incoming(TCP_Server *TCP_server) +static void do_confirmed_recv(TCP_Server *tcp_server, uint32_t i) +{ + while (tcp_process_secure_packet(tcp_server, i)) { + // Keep reading until an error occurs or there is no more data to read. + continue; + } +} + +#ifndef TCP_SERVER_USE_EPOLL +static void do_TCP_incoming(TCP_Server *tcp_server) { uint32_t i; for (i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) { - do_incoming(TCP_server, i); + do_incoming(tcp_server, i); } } -static void do_TCP_unconfirmed(TCP_Server *TCP_server) +static void do_TCP_unconfirmed(TCP_Server *tcp_server) { uint32_t i; for (i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) { - do_unconfirmed(TCP_server, i); + do_unconfirmed(tcp_server, i); } } +#endif -static void do_TCP_confirmed(TCP_Server *TCP_server) +static void do_TCP_confirmed(TCP_Server *tcp_server) { #ifdef TCP_SERVER_USE_EPOLL - if (TCP_server->last_run_pinged == unix_time()) { + if (tcp_server->last_run_pinged == unix_time()) { return; } - TCP_server->last_run_pinged = unix_time(); + tcp_server->last_run_pinged = unix_time(); #endif uint32_t i; - for (i = 0; i < TCP_server->size_accepted_connections; ++i) { - TCP_Secure_Connection *conn = &TCP_server->accepted_connection_array[i]; + for (i = 0; i < tcp_server->size_accepted_connections; ++i) { + TCP_Secure_Connection *conn = &tcp_server->accepted_connection_array[i]; if (conn->status != TCP_STATUS_CONFIRMED) { continue; @@ -1262,14 +1274,14 @@ static void do_TCP_confirmed(TCP_Server *TCP_server) conn->ping_id = ping_id; } else { if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) { - kill_accepted(TCP_server, i); + kill_accepted(tcp_server, i); continue; } } } if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) { - kill_accepted(TCP_server, i); + kill_accepted(tcp_server, i); continue; } @@ -1277,170 +1289,174 @@ static void do_TCP_confirmed(TCP_Server *TCP_server) #ifndef TCP_SERVER_USE_EPOLL - do_confirmed_recv(TCP_server, i); + do_confirmed_recv(tcp_server, i); #endif } } #ifdef TCP_SERVER_USE_EPOLL -static void do_TCP_epoll(TCP_Server *TCP_server) +static bool tcp_epoll_process(TCP_Server *tcp_server) { #define MAX_EVENTS 16 struct epoll_event events[MAX_EVENTS]; - int nfds; - - while ((nfds = epoll_wait(TCP_server->efd, events, MAX_EVENTS, 0)) > 0) { - int n; + const int nfds = epoll_wait(tcp_server->efd, events, MAX_EVENTS, 0); +#undef MAX_EVENTS - for (n = 0; n < nfds; ++n) { - Socket sock = events[n].data.u64 & 0xFFFFFFFF; - int status = (events[n].data.u64 >> 32) & 0xFF, index = (events[n].data.u64 >> 40); + for (int n = 0; n < nfds; ++n) { + const Socket sock = {(int)(events[n].data.u64 & 0xFFFFFFFF)}; + const int status = (events[n].data.u64 >> 32) & 0xFF; + const int index = events[n].data.u64 >> 40; - if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP) || (events[n].events & EPOLLRDHUP)) { - switch (status) { - case TCP_SOCKET_LISTENING: { - //should never happen - break; - } - - case TCP_SOCKET_INCOMING: { - kill_TCP_secure_connection(&TCP_server->incoming_connection_queue[index]); - break; - } + if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP) || (events[n].events & EPOLLRDHUP)) { + switch (status) { + case TCP_SOCKET_LISTENING: { + // should never happen + break; + } - case TCP_SOCKET_UNCONFIRMED: { - kill_TCP_secure_connection(&TCP_server->unconfirmed_connection_queue[index]); - break; - } + case TCP_SOCKET_INCOMING: { + kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index]); + break; + } - case TCP_SOCKET_CONFIRMED: { - kill_accepted(TCP_server, index); - break; - } + case TCP_SOCKET_UNCONFIRMED: { + kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index]); + break; } - continue; + case TCP_SOCKET_CONFIRMED: { + kill_accepted(tcp_server, index); + break; + } } + continue; + } + - if (!(events[n].events & EPOLLIN)) { - continue; - } + if (!(events[n].events & EPOLLIN)) { + continue; + } - switch (status) { - case TCP_SOCKET_LISTENING: { - //socket is from socks_listening, accept connection - struct sockaddr_storage addr; - socklen_t addrlen = sizeof(addr); + switch (status) { + case TCP_SOCKET_LISTENING: { + // socket is from socks_listening, accept connection + while (1) { + Socket sock_new = net_accept(sock); - while (1) { - Socket sock_new = accept(sock, (struct sockaddr *)&addr, &addrlen); + if (!sock_valid(sock_new)) { + break; + } + + int index_new = accept_connection(tcp_server, sock_new); - if (!sock_valid(sock_new)) { - break; - } + if (index_new == -1) { + continue; + } - int index_new = accept_connection(TCP_server, sock_new); + struct epoll_event ev; - if (index_new == -1) { - continue; - } + ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP; - struct epoll_event ev = { - .events = EPOLLIN | EPOLLET | EPOLLRDHUP, - .data.u64 = sock_new | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40) - }; + ev.data.u64 = sock_new.socket | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40); - if (epoll_ctl(TCP_server->efd, EPOLL_CTL_ADD, sock_new, &ev) == -1) { - kill_TCP_secure_connection(&TCP_server->incoming_connection_queue[index_new]); - continue; - } + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, sock_new.socket, &ev) == -1) { + kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index_new]); + continue; } - - break; } - case TCP_SOCKET_INCOMING: { - int index_new; + break; + } - if ((index_new = do_incoming(TCP_server, index)) != -1) { - events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; - events[n].data.u64 = sock | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40); + case TCP_SOCKET_INCOMING: { + const int index_new = do_incoming(tcp_server, index); - if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock, &events[n]) == -1) { - kill_TCP_secure_connection(&TCP_server->unconfirmed_connection_queue[index_new]); - break; - } - } + if (index_new != -1) { + events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; + events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40); - break; + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) { + kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]); + break; + } } - case TCP_SOCKET_UNCONFIRMED: { - int index_new; + break; + } - if ((index_new = do_unconfirmed(TCP_server, index)) != -1) { - events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; - events[n].data.u64 = sock | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40); + case TCP_SOCKET_UNCONFIRMED: { + const int index_new = do_unconfirmed(tcp_server, index); - if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock, &events[n]) == -1) { - //remove from confirmed connections - kill_accepted(TCP_server, index_new); - break; - } - } + if (index_new != -1) { + events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; + events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40); - break; + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) { + // remove from confirmed connections + kill_accepted(tcp_server, index_new); + break; + } } - case TCP_SOCKET_CONFIRMED: { - do_confirmed_recv(TCP_server, index); - break; - } + break; + } + + case TCP_SOCKET_CONFIRMED: { + do_confirmed_recv(tcp_server, index); + break; } } } -#undef MAX_EVENTS + return nfds > 0; +} + +static void do_TCP_epoll(TCP_Server *tcp_server) +{ + while (tcp_epoll_process(tcp_server)) { + // Keep processing packets until there are no more FDs ready for reading. + continue; + } } #endif -void do_TCP_server(TCP_Server *TCP_server) +void do_TCP_server(TCP_Server *tcp_server) { unix_time_update(); #ifdef TCP_SERVER_USE_EPOLL - do_TCP_epoll(TCP_server); + do_TCP_epoll(tcp_server); #else - do_TCP_accept_new(TCP_server); - do_TCP_incoming(TCP_server); - do_TCP_unconfirmed(TCP_server); + do_TCP_accept_new(tcp_server); + do_TCP_incoming(tcp_server); + do_TCP_unconfirmed(tcp_server); #endif - do_TCP_confirmed(TCP_server); + do_TCP_confirmed(tcp_server); } -void kill_TCP_server(TCP_Server *TCP_server) +void kill_TCP_server(TCP_Server *tcp_server) { uint32_t i; - for (i = 0; i < TCP_server->num_listening_socks; ++i) { - kill_sock(TCP_server->socks_listening[i]); + for (i = 0; i < tcp_server->num_listening_socks; ++i) { + kill_sock(tcp_server->socks_listening[i]); } - if (TCP_server->onion) { - set_callback_handle_recv_1(TCP_server->onion, nullptr, nullptr); + if (tcp_server->onion) { + set_callback_handle_recv_1(tcp_server->onion, nullptr, nullptr); } - bs_list_free(&TCP_server->accepted_key_list); + bs_list_free(&tcp_server->accepted_key_list); #ifdef TCP_SERVER_USE_EPOLL - close(TCP_server->efd); + close(tcp_server->efd); #endif - free(TCP_server->socks_listening); - free(TCP_server->accepted_connection_array); - free(TCP_server); + free(tcp_server->socks_listening); + free(tcp_server->accepted_connection_array); + free(tcp_server); } diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.h b/protocols/Tox/libtox/src/toxcore/TCP_server.h index 234f5ad12e..632a5e79b9 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_server.h +++ b/protocols/Tox/libtox/src/toxcore/TCP_server.h @@ -28,15 +28,6 @@ #include "list.h" #include "onion.h" -#ifdef TCP_SERVER_USE_EPOLL -#include <sys/epoll.h> -#endif - -// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD -#if !defined(MSG_NOSIGNAL) -#define MSG_NOSIGNAL 0 -#endif - #define MAX_INCOMING_CONNECTIONS 256 #define TCP_MAX_BACKLOG MAX_INCOMING_CONNECTIONS @@ -68,25 +59,19 @@ #define TCP_PING_FREQUENCY 30 #define TCP_PING_TIMEOUT 10 -#ifdef TCP_SERVER_USE_EPOLL -#define TCP_SOCKET_LISTENING 0 -#define TCP_SOCKET_INCOMING 1 -#define TCP_SOCKET_UNCONFIRMED 2 -#define TCP_SOCKET_CONFIRMED 3 -#endif - -enum { +typedef enum TCP_Status { TCP_STATUS_NO_STATUS, TCP_STATUS_CONNECTED, TCP_STATUS_UNCONFIRMED, TCP_STATUS_CONFIRMED, -}; +} TCP_Status; typedef struct TCP_Priority_List TCP_Priority_List; struct TCP_Priority_List { TCP_Priority_List *next; - uint16_t size, sent; + uint16_t size; + uint16_t sent; uint8_t data[]; }; @@ -102,16 +87,11 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin /* Run the TCP_server */ -void do_TCP_server(TCP_Server *TCP_server); +void do_TCP_server(TCP_Server *tcp_server); /* Kill the TCP server */ -void kill_TCP_server(TCP_Server *TCP_server); - -/* return the amount of data in the tcp recv buffer. - * return 0 on failure. - */ -unsigned int TCP_socket_data_recv_buffer(Socket sock); +void kill_TCP_server(TCP_Server *tcp_server); /* Read the next two bytes in TCP stream then convert them to * length (host byte order). diff --git a/protocols/Tox/libtox/src/toxcore/ccompat.h b/protocols/Tox/libtox/src/toxcore/ccompat.h index b70850d2d3..5b37a29457 100644 --- a/protocols/Tox/libtox/src/toxcore/ccompat.h +++ b/protocols/Tox/libtox/src/toxcore/ccompat.h @@ -22,13 +22,13 @@ // Emulation using alloca. #ifdef _WIN32 #include <malloc.h> -#elif defined(__FreeBSD__) +#elif defined(__linux__) +#include <alloca.h> +#else #include <stdlib.h> #if !defined(alloca) && defined(__GNUC__) #define alloca __builtin_alloca #endif -#else -#include <alloca.h> #endif #define VLA(type, name, size) \ @@ -38,7 +38,7 @@ #endif -#ifndef __cplusplus +#if !defined(__cplusplus) || __cplusplus < 201103L #define nullptr NULL #endif diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.api.h b/protocols/Tox/libtox/src/toxcore/crypto_core.api.h index e9e8aeb273..4b40860d44 100644 --- a/protocols/Tox/libtox/src/toxcore/crypto_core.api.h +++ b/protocols/Tox/libtox/src/toxcore/crypto_core.api.h @@ -26,8 +26,8 @@ #define CRYPTO_CORE_H #include <stdbool.h> +#include <stddef.h> #include <stdint.h> -#include <stdlib.h> #ifdef __cplusplus extern "C" { diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.c b/protocols/Tox/libtox/src/toxcore/crypto_core.c index b2f0e5f0d3..b9ec23a80d 100644 --- a/protocols/Tox/libtox/src/toxcore/crypto_core.c +++ b/protocols/Tox/libtox/src/toxcore/crypto_core.c @@ -47,70 +47,71 @@ #endif #if CRYPTO_PUBLIC_KEY_SIZE != crypto_box_PUBLICKEYBYTES -#error CRYPTO_PUBLIC_KEY_SIZE should be equal to crypto_box_PUBLICKEYBYTES +#error "CRYPTO_PUBLIC_KEY_SIZE should be equal to crypto_box_PUBLICKEYBYTES" #endif #if CRYPTO_SECRET_KEY_SIZE != crypto_box_SECRETKEYBYTES -#error CRYPTO_SECRET_KEY_SIZE should be equal to crypto_box_SECRETKEYBYTES +#error "CRYPTO_SECRET_KEY_SIZE should be equal to crypto_box_SECRETKEYBYTES" #endif #if CRYPTO_SHARED_KEY_SIZE != crypto_box_BEFORENMBYTES -#error CRYPTO_SHARED_KEY_SIZE should be equal to crypto_box_BEFORENMBYTES +#error "CRYPTO_SHARED_KEY_SIZE should be equal to crypto_box_BEFORENMBYTES" #endif #if CRYPTO_SYMMETRIC_KEY_SIZE != crypto_box_BEFORENMBYTES -#error CRYPTO_SYMMETRIC_KEY_SIZE should be equal to crypto_box_BEFORENMBYTES +#error "CRYPTO_SYMMETRIC_KEY_SIZE should be equal to crypto_box_BEFORENMBYTES" #endif #if CRYPTO_MAC_SIZE != crypto_box_MACBYTES -#error CRYPTO_MAC_SIZE should be equal to crypto_box_MACBYTES +#error "CRYPTO_MAC_SIZE should be equal to crypto_box_MACBYTES" #endif #if CRYPTO_NONCE_SIZE != crypto_box_NONCEBYTES -#error CRYPTO_NONCE_SIZE should be equal to crypto_box_NONCEBYTES +#error "CRYPTO_NONCE_SIZE should be equal to crypto_box_NONCEBYTES" #endif #if CRYPTO_SHA256_SIZE != crypto_hash_sha256_BYTES -#error CRYPTO_SHA256_SIZE should be equal to crypto_hash_sha256_BYTES +#error "CRYPTO_SHA256_SIZE should be equal to crypto_hash_sha256_BYTES" #endif #if CRYPTO_SHA512_SIZE != crypto_hash_sha512_BYTES -#error CRYPTO_SHA512_SIZE should be equal to crypto_hash_sha512_BYTES +#error "CRYPTO_SHA512_SIZE should be equal to crypto_hash_sha512_BYTES" #endif -int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2) -{ #if CRYPTO_PUBLIC_KEY_SIZE != 32 -#error CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_cmp to work, +#error "CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_cmp to work," #endif + +int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2) +{ return crypto_verify_32(pk1, pk2); } uint8_t random_u08(void) { uint8_t randnum; - randombytes(&randnum, 1); + random_bytes(&randnum, 1); return randnum; } uint16_t random_u16(void) { uint16_t randnum; - randombytes((uint8_t *)&randnum, sizeof(randnum)); + random_bytes((uint8_t *)&randnum, sizeof(randnum)); return randnum; } uint32_t random_u32(void) { uint32_t randnum; - randombytes((uint8_t *)&randnum, sizeof(randnum)); + random_bytes((uint8_t *)&randnum, sizeof(randnum)); return randnum; } uint64_t random_u64(void) { uint64_t randnum; - randombytes((uint8_t *)&randnum, sizeof(randnum)); + random_bytes((uint8_t *)&randnum, sizeof(randnum)); return randnum; } @@ -186,7 +187,7 @@ int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t k[crypto_box_BEFORENMBYTES]; encrypt_precompute(public_key, secret_key, k); int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted); - crypto_memzero(k, sizeof k); + crypto_memzero(k, sizeof(k)); return ret; } @@ -200,7 +201,7 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t k[crypto_box_BEFORENMBYTES]; encrypt_precompute(public_key, secret_key, k); int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain); - crypto_memzero(k, sizeof k); + crypto_memzero(k, sizeof(k)); return ret; } @@ -258,7 +259,7 @@ void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num) for (; i != 0; --i) { carry += (uint_fast16_t) nonce[i - 1] + (uint_fast16_t) num_as_nonce[i - 1]; - nonce[i - 1] = (unsigned char) carry; + nonce[i - 1] = (uint8_t)carry; carry >>= 8; } } @@ -266,13 +267,13 @@ void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num) /* Fill the given nonce with random bytes. */ void random_nonce(uint8_t *nonce) { - randombytes(nonce, crypto_box_NONCEBYTES); + random_bytes(nonce, crypto_box_NONCEBYTES); } /* Fill a key CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes */ void new_symmetric_key(uint8_t *key) { - randombytes(key, CRYPTO_SYMMETRIC_KEY_SIZE); + random_bytes(key, CRYPTO_SYMMETRIC_KEY_SIZE); } int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key) diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.h b/protocols/Tox/libtox/src/toxcore/crypto_core.h index e7e913b681..18c1339e65 100644 --- a/protocols/Tox/libtox/src/toxcore/crypto_core.h +++ b/protocols/Tox/libtox/src/toxcore/crypto_core.h @@ -25,8 +25,8 @@ #define CRYPTO_CORE_H #include <stdbool.h> +#include <stddef.h> #include <stdint.h> -#include <stdlib.h> #ifdef __cplusplus extern "C" { diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core_test.cpp b/protocols/Tox/libtox/src/toxcore/crypto_core_test.cpp deleted file mode 100644 index 8f91dce842..0000000000 --- a/protocols/Tox/libtox/src/toxcore/crypto_core_test.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "crypto_core.h" - -#include <algorithm> - -#include <gtest/gtest.h> - -namespace -{ - -enum { - /** - * The size of the arrays to compare. This was chosen to take around 2000 - * CPU clocks on x86_64. - */ - CRYPTO_TEST_MEMCMP_SIZE = 1024 * 1024, // 1 MiB - /** - * The number of times we run memcmp in the test. - * - * We compute the median time taken to reduce error margins. - */ - CRYPTO_TEST_MEMCMP_ITERATIONS = 500, - /** - * The margin of error (in clocks) we allow for this test. - * - * Should be within 0.5% of ~2000 CPU clocks. In reality, the code is much - * more precise and is usually within 1 CPU clock. - */ - CRYPTO_TEST_MEMCMP_EPS = 10, -}; - -clock_t memcmp_time(void *a, void *b, size_t len) -{ - clock_t start = clock(); - crypto_memcmp(a, b, len); - return clock() - start; -} - -/** - * This function performs the actual timing. It interleaves comparison of - * equal and non-equal arrays to reduce the influence of external effects - * such as the machine being a little more busy 1 second later. - */ -void memcmp_median(void *src, void *same, void *not_same, size_t len, - clock_t *same_median, clock_t *not_same_median) -{ - clock_t same_results[CRYPTO_TEST_MEMCMP_ITERATIONS]; - clock_t not_same_results[CRYPTO_TEST_MEMCMP_ITERATIONS]; - - for (size_t i = 0; i < CRYPTO_TEST_MEMCMP_ITERATIONS; i++) { - same_results[i] = memcmp_time(src, same, len); - not_same_results[i] = memcmp_time(src, not_same, len); - } - - std::sort(same_results, same_results + CRYPTO_TEST_MEMCMP_ITERATIONS); - *same_median = same_results[CRYPTO_TEST_MEMCMP_ITERATIONS / 2]; - std::sort(not_same_results, not_same_results + CRYPTO_TEST_MEMCMP_ITERATIONS); - *not_same_median = not_same_results[CRYPTO_TEST_MEMCMP_ITERATIONS / 2]; -} - -/** - * This test checks whether crypto_memcmp takes the same time for equal and - * non-equal chunks of memory. - */ -TEST(CryptoCore, MemcmpTimingIsDataIndependent) -{ - // A random piece of memory. - uint8_t *src = new uint8_t[CRYPTO_TEST_MEMCMP_SIZE]; - random_bytes(src, CRYPTO_TEST_MEMCMP_SIZE); - - // A separate piece of memory containing the same data. - uint8_t *same = new uint8_t[CRYPTO_TEST_MEMCMP_SIZE]; - memcpy(same, src, CRYPTO_TEST_MEMCMP_SIZE); - - // Another piece of memory containing different data. - uint8_t *not_same = new uint8_t[CRYPTO_TEST_MEMCMP_SIZE]; - random_bytes(not_same, CRYPTO_TEST_MEMCMP_SIZE); - - clock_t same_median; - clock_t not_same_median; - memcmp_median(src, same, not_same, CRYPTO_TEST_MEMCMP_SIZE, &same_median, ¬_same_median); - - delete[] not_same; - delete[] same; - delete[] src; - - clock_t const delta = same_median > not_same_median - ? same_median - not_same_median - : not_same_median - same_median; - - EXPECT_LT(delta, CRYPTO_TEST_MEMCMP_EPS) - << "Delta time is too long (" << delta << " >= " << CRYPTO_TEST_MEMCMP_EPS << ")\n" - << "Time of the same data comparation: " << same_median << " clocks\n" - << "Time of the different data comparation: " << not_same_median << " clocks"; -} - -} // namespace diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.c b/protocols/Tox/libtox/src/toxcore/friend_connection.c index 6f5685fb5d..4d24587147 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_connection.c +++ b/protocols/Tox/libtox/src/toxcore/friend_connection.c @@ -27,33 +27,42 @@ #include "friend_connection.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mono_time.h" #include "util.h" #define PORTS_PER_DISCOVERY 10 -typedef struct { +typedef struct Friend_Conn_Callbacks { + fc_status_cb *status_callback; + fc_data_cb *data_callback; + fc_lossy_data_cb *lossy_data_callback; + + void *callback_object; + int callback_id; +} Friend_Conn_Callbacks; + +typedef struct Friend_Conn { uint8_t status; uint8_t real_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t dht_temp_pk[CRYPTO_PUBLIC_KEY_SIZE]; uint16_t dht_lock; IP_Port dht_ip_port; - uint64_t dht_pk_lastrecv, dht_ip_port_lastrecv; + uint64_t dht_pk_lastrecv; + uint64_t dht_ip_port_lastrecv; int onion_friendnum; int crypt_connection_id; - uint64_t ping_lastrecv, ping_lastsent; + uint64_t ping_lastrecv; + uint64_t ping_lastsent; uint64_t share_relays_lastsent; - struct { - int (*status_callback)(void *object, int id, uint8_t status, void *userdata); - int (*data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); - int (*lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); - - void *callback_object; - int callback_id; - } callbacks[MAX_FRIEND_CONNECTION_CALLBACKS]; + Friend_Conn_Callbacks callbacks[MAX_FRIEND_CONNECTION_CALLBACKS]; uint16_t lock_count; @@ -72,12 +81,11 @@ struct Friend_Connections { Friend_Conn *conns; uint32_t num_cons; - int (*fr_request_callback)(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t len, - void *userdata); + fr_request_cb *fr_request_callback; void *fr_request_object; - uint64_t last_LANdiscovery; - uint16_t next_LANport; + uint64_t last_lan_discovery; + uint16_t next_lan_port; bool local_discovery_enabled; }; @@ -217,7 +225,7 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_ /* Local ip and same pk means that they are hosting a TCP relay. */ if (ip_is_local(ip_port.ip) && public_key_cmp(friend_con->dht_temp_pk, public_key) == 0) { - if (friend_con->dht_ip_port.ip.family != 0) { + if (!net_family_is_unspec(friend_con->dht_ip_port.ip.family)) { ip_port.ip = friend_con->dht_ip_port.ip; } else { friend_con->hosting_tcp_relay = 0; @@ -227,7 +235,7 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_ const uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS; for (unsigned i = 0; i < FRIEND_MAX_STORED_TCP_RELAYS; ++i) { - if (friend_con->tcp_relays[i].ip_port.ip.family != 0 + if (!net_family_is_unspec(friend_con->tcp_relays[i].ip_port.ip.family) && public_key_cmp(friend_con->tcp_relays[i].public_key, public_key) == 0) { memset(&friend_con->tcp_relays[i], 0, sizeof(Node_format)); } @@ -252,7 +260,7 @@ static void connect_to_saved_tcp_relays(Friend_Connections *fr_c, int friendcon_ for (unsigned i = 0; (i < FRIEND_MAX_STORED_TCP_RELAYS) && (number != 0); ++i) { const uint16_t index = (friend_con->tcp_relay_counter - (i + 1)) % FRIEND_MAX_STORED_TCP_RELAYS; - if (friend_con->tcp_relays[index].ip_port.ip.family) { + if (!net_family_is_unspec(friend_con->tcp_relays[index].ip_port.ip.family)) { if (add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->tcp_relays[index].ip_port, friend_con->tcp_relays[index].public_key) == 0) { --number; @@ -350,7 +358,7 @@ static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint friend_con->dht_pk_lastrecv = unix_time(); if (friend_con->dht_lock) { - if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) { + if (dht_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) { printf("a. Could not delete dht peer. Please report this.\n"); return; } @@ -358,7 +366,7 @@ static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint friend_con->dht_lock = 0; } - DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, fr_c, friendcon_id, &friend_con->dht_lock); + dht_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, fr_c, friendcon_id, &friend_con->dht_lock); memcpy(friend_con->dht_temp_pk, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); } @@ -371,17 +379,17 @@ static int handle_status(void *object, int number, uint8_t status, void *userdat return -1; } - bool call_cb = 0; + bool status_changed = 0; if (status) { /* Went online. */ - call_cb = 1; + status_changed = 1; friend_con->status = FRIENDCONN_STATUS_CONNECTED; friend_con->ping_lastrecv = unix_time(); friend_con->share_relays_lastsent = 0; onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); } else { /* Went offline. */ if (friend_con->status != FRIENDCONN_STATUS_CONNECTING) { - call_cb = 1; + status_changed = 1; friend_con->dht_pk_lastrecv = unix_time(); onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); } @@ -391,7 +399,7 @@ static int handle_status(void *object, int number, uint8_t status, void *userdat friend_con->hosting_tcp_relay = 0; } - if (call_cb) { + if (status_changed) { unsigned int i; for (i = 0; i < MAX_FRIEND_CONNECTION_CALLBACKS; ++i) { @@ -467,7 +475,7 @@ static int handle_packet(void *object, int number, const uint8_t *data, uint16_t return -1; } - for (int j = 0; j < n; j++) { + for (int j = 0; j < n; ++j) { friend_add_tcp_relay(fr_c, number, nodes[j].ip_port, nodes[j].public_key); } @@ -546,7 +554,7 @@ static int handle_new_connections(void *object, New_Connection *n_c) connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id); friend_con->crypt_connection_id = id; - if (n_c->source.ip.family != TOX_AF_INET && n_c->source.ip.family != TOX_AF_INET6) { + if (!net_family_is_ipv4(n_c->source.ip.family) && !net_family_is_ipv6(n_c->source.ip.family)) { set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port, 0); } else { friend_con->dht_ip_port = n_c->source; @@ -682,9 +690,9 @@ void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t * * return -1 on failure */ int friend_connection_callbacks(Friend_Connections *fr_c, int friendcon_id, unsigned int index, - int (*status_callback)(void *object, int id, uint8_t status, void *userdata), - int (*data_callback)(void *object, int id, const uint8_t *data, uint16_t len, void *userdata), - int (*lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata), + fc_status_cb *status_callback, + fc_data_cb *data_callback, + fc_lossy_data_cb *lossy_data_callback, void *object, int number) { Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id); @@ -785,7 +793,7 @@ int kill_friend_connection(Friend_Connections *fr_c, int friendcon_id) crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id); if (friend_con->dht_lock) { - DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock); + dht_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock); } return wipe_friend_conn(fr_c, friendcon_id); @@ -796,8 +804,7 @@ int kill_friend_connection(Friend_Connections *fr_c, int friendcon_id) * * This function will be called every time a friend request packet is received. */ -void set_friend_request_callback(Friend_Connections *fr_c, int (*fr_request_callback)(void *, const uint8_t *, - const uint8_t *, uint16_t, void *), void *object) +void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_request_callback, void *object) { fr_c->fr_request_callback = fr_request_callback; fr_c->fr_request_object = object; @@ -860,7 +867,7 @@ Friend_Connections *new_friend_connections(Onion_Client *onion_c, bool local_dis temp->onion_c = onion_c; temp->local_discovery_enabled = local_discovery_enabled; // Don't include default port in port range - temp->next_LANport = TOX_PORTRANGE_FROM + 1; + temp->next_lan_port = TOX_PORTRANGE_FROM + 1; new_connection_handler(temp->net_crypto, &handle_new_connections, temp); @@ -872,10 +879,10 @@ Friend_Connections *new_friend_connections(Onion_Client *onion_c, bool local_dis } /* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */ -static void LANdiscovery(Friend_Connections *fr_c) +static void lan_discovery(Friend_Connections *fr_c) { - if (fr_c->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) { - const uint16_t first = fr_c->next_LANport; + if (fr_c->last_lan_discovery + LAN_DISCOVERY_INTERVAL < unix_time()) { + const uint16_t first = fr_c->next_lan_port; uint16_t last = first + PORTS_PER_DISCOVERY; last = last > TOX_PORTRANGE_TO ? TOX_PORTRANGE_TO : last; @@ -883,13 +890,13 @@ static void LANdiscovery(Friend_Connections *fr_c) lan_discovery_send(net_htons(TOX_PORT_DEFAULT), fr_c->dht); // And check some extra ports - for (uint16_t port = first; port < last; port++) { + for (uint16_t port = first; port < last; ++port) { lan_discovery_send(net_htons(port), fr_c->dht); } // Don't include default port in port range - fr_c->next_LANport = last != TOX_PORTRANGE_TO ? last : TOX_PORTRANGE_FROM + 1; - fr_c->last_LANdiscovery = unix_time(); + fr_c->next_lan_port = last != TOX_PORTRANGE_TO ? last : TOX_PORTRANGE_FROM + 1; + fr_c->last_lan_discovery = unix_time(); } } @@ -905,14 +912,14 @@ void do_friend_connections(Friend_Connections *fr_c, void *userdata) if (friend_con->status == FRIENDCONN_STATUS_CONNECTING) { if (friend_con->dht_pk_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) { if (friend_con->dht_lock) { - DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock); + dht_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock); friend_con->dht_lock = 0; memset(friend_con->dht_temp_pk, 0, CRYPTO_PUBLIC_KEY_SIZE); } } if (friend_con->dht_ip_port_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) { - friend_con->dht_ip_port.ip.family = 0; + friend_con->dht_ip_port.ip.family = net_family_unspec; } if (friend_con->dht_lock) { @@ -941,7 +948,7 @@ void do_friend_connections(Friend_Connections *fr_c, void *userdata) } if (fr_c->local_discovery_enabled) { - LANdiscovery(fr_c); + lan_discovery(fr_c); } } diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.h b/protocols/Tox/libtox/src/toxcore/friend_connection.h index f4d53c7a29..024befeec8 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_connection.h +++ b/protocols/Tox/libtox/src/toxcore/friend_connection.h @@ -55,11 +55,11 @@ #define SHARE_RELAYS_INTERVAL (5 * 60) -enum { +typedef enum Friendconn_Status { FRIENDCONN_STATUS_NONE, FRIENDCONN_STATUS_CONNECTING, FRIENDCONN_STATUS_CONNECTED -}; +} Friendconn_Status; typedef struct Friend_Connections Friend_Connections; @@ -101,6 +101,10 @@ void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t * */ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key); +typedef int fc_status_cb(void *object, int id, uint8_t status, void *userdata); +typedef int fc_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); +typedef int fc_lossy_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); + /* Set the callbacks for the friend connection. * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array. * @@ -108,9 +112,9 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_ * return -1 on failure */ int friend_connection_callbacks(Friend_Connections *fr_c, int friendcon_id, unsigned int index, - int (*status_callback)(void *object, int id, uint8_t status, void *userdata), - int (*data_callback)(void *object, int id, const uint8_t *data, uint16_t len, void *userdata), - int (*lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata), + fc_status_cb *status_callback, + fc_data_cb *data_callback, + fc_lossy_data_cb *lossy_data_callback, void *object, int number); /* return the crypt_connection_id for the connection. @@ -144,12 +148,14 @@ int kill_friend_connection(Friend_Connections *fr_c, int friendcon_id); int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint32_t nospam_num, const uint8_t *data, uint16_t length); +typedef int fr_request_cb(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t len, + void *userdata); + /* Set friend request callback. * * This function will be called every time a friend request is received. */ -void set_friend_request_callback(Friend_Connections *fr_c, int (*fr_request_callback)(void *, const uint8_t *, - const uint8_t *, uint16_t, void *), void *object); +void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_request_callback, void *object); /* Create new friend_connections instance. */ Friend_Connections *new_friend_connections(Onion_Client *onion_c, bool local_discovery_enabled); diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.c b/protocols/Tox/libtox/src/toxcore/friend_requests.c index 13c89eae13..c4f2512722 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_requests.c +++ b/protocols/Tox/libtox/src/toxcore/friend_requests.c @@ -27,24 +27,31 @@ #include "friend_requests.h" +#include <stdlib.h> +#include <string.h> + #include "util.h" +/* NOTE: The following is just a temporary fix for the multiple friend requests received at the same time problem. + * TODO(irungentoo): Make this better (This will most likely tie in with the way we will handle spam.) + */ +#define MAX_RECEIVED_STORED 32 + +struct Received_Requests { + uint8_t requests[MAX_RECEIVED_STORED][CRYPTO_PUBLIC_KEY_SIZE]; + uint16_t requests_index; +}; + struct Friend_Requests { uint32_t nospam; - void (*handle_friendrequest)(void *, const uint8_t *, const uint8_t *, size_t, void *); + fr_friend_request_cb *handle_friendrequest; uint8_t handle_friendrequest_isset; void *handle_friendrequest_object; - int (*filter_function)(const uint8_t *, void *); + filter_function_cb *filter_function; void *filter_function_userdata; - /* NOTE: The following is just a temporary fix for the multiple friend requests received at the same time problem. - * TODO(irungentoo): Make this better (This will most likely tie in with the way we will handle spam.) - */ - -#define MAX_RECEIVED_STORED 32 - uint8_t received_requests[MAX_RECEIVED_STORED][CRYPTO_PUBLIC_KEY_SIZE]; - uint16_t received_requests_index; + struct Received_Requests received; }; /* Set and get the nospam variable used to prevent one type of friend request spam. */ @@ -60,8 +67,7 @@ uint32_t get_nospam(const Friend_Requests *fr) /* Set the function that will be executed when a friend request is received. */ -void callback_friendrequest(Friend_Requests *fr, void (*function)(void *, const uint8_t *, const uint8_t *, size_t, - void *), void *object) +void callback_friendrequest(Friend_Requests *fr, fr_friend_request_cb *function, void *object) { fr->handle_friendrequest = function; fr->handle_friendrequest_isset = 1; @@ -69,7 +75,7 @@ void callback_friendrequest(Friend_Requests *fr, void (*function)(void *, const } /* Set the function used to check if a friend request should be displayed to the user or not. */ -void set_filter_function(Friend_Requests *fr, int (*function)(const uint8_t *, void *), void *userdata) +void set_filter_function(Friend_Requests *fr, filter_function_cb *function, void *userdata) { fr->filter_function = function; fr->filter_function_userdata = userdata; @@ -78,12 +84,12 @@ void set_filter_function(Friend_Requests *fr, int (*function)(const uint8_t *, v /* Add to list of received friend requests. */ static void addto_receivedlist(Friend_Requests *fr, const uint8_t *real_pk) { - if (fr->received_requests_index >= MAX_RECEIVED_STORED) { - fr->received_requests_index = 0; + if (fr->received.requests_index >= MAX_RECEIVED_STORED) { + fr->received.requests_index = 0; } - id_copy(fr->received_requests[fr->received_requests_index], real_pk); - ++fr->received_requests_index; + id_copy(fr->received.requests[fr->received.requests_index], real_pk); + ++fr->received.requests_index; } /* Check if a friend request was already received. @@ -94,7 +100,7 @@ static void addto_receivedlist(Friend_Requests *fr, const uint8_t *real_pk) static bool request_received(const Friend_Requests *fr, const uint8_t *real_pk) { for (uint32_t i = 0; i < MAX_RECEIVED_STORED; ++i) { - if (id_equal(fr->received_requests[i], real_pk)) { + if (id_equal(fr->received.requests[i], real_pk)) { return true; } } @@ -102,7 +108,7 @@ static bool request_received(const Friend_Requests *fr, const uint8_t *real_pk) return false; } -/* Remove real pk from received_requests list. +/* Remove real pk from received.requests list. * * return 0 if it removed it successfully. * return -1 if it didn't find it. @@ -110,8 +116,8 @@ static bool request_received(const Friend_Requests *fr, const uint8_t *real_pk) int remove_request_received(Friend_Requests *fr, const uint8_t *real_pk) { for (uint32_t i = 0; i < MAX_RECEIVED_STORED; ++i) { - if (id_equal(fr->received_requests[i], real_pk)) { - crypto_memzero(fr->received_requests[i], CRYPTO_PUBLIC_KEY_SIZE); + if (id_equal(fr->received.requests[i], real_pk)) { + crypto_memzero(fr->received.requests[i], CRYPTO_PUBLIC_KEY_SIZE); return 0; } } diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.h b/protocols/Tox/libtox/src/toxcore/friend_requests.h index e6948b6cd1..77c3af6890 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_requests.h +++ b/protocols/Tox/libtox/src/toxcore/friend_requests.h @@ -41,17 +41,21 @@ uint32_t get_nospam(const Friend_Requests *fr); */ int remove_request_received(Friend_Requests *fr, const uint8_t *real_pk); +typedef void fr_friend_request_cb(void *object, const uint8_t *public_key, const uint8_t *message, size_t length, + void *user_data); + /* Set the function that will be executed when a friend request for us is received. * Function format is function(uint8_t * public_key, uint8_t * data, size_t length, void * userdata) */ -void callback_friendrequest(Friend_Requests *fr, void (*function)(void *, const uint8_t *, const uint8_t *, size_t, - void *), void *object); +void callback_friendrequest(Friend_Requests *fr, fr_friend_request_cb *function, void *object); + +typedef int filter_function_cb(const uint8_t *public_key, void *user_data); /* Set the function used to check if a friend request should be displayed to the user or not. * Function format is int function(uint8_t * public_key, void * userdata) * It must return 0 if the request is ok (anything else if it is bad.) */ -void set_filter_function(Friend_Requests *fr, int (*function)(const uint8_t *, void *), void *userdata); +void set_filter_function(Friend_Requests *fr, filter_function_cb *function, void *userdata); /* Sets up friendreq packet handlers. */ void friendreq_init(Friend_Requests *fr, Friend_Connections *fr_c); diff --git a/protocols/Tox/libtox/src/toxcore/group.c b/protocols/Tox/libtox/src/toxcore/group.c index 37b4437d79..2ee81de820 100644 --- a/protocols/Tox/libtox/src/toxcore/group.c +++ b/protocols/Tox/libtox/src/toxcore/group.c @@ -27,74 +27,80 @@ #include "group.h" +#include <stdlib.h> +#include <string.h> + +#include "mono_time.h" #include "util.h" -/* return 1 if the groupnumber is not valid. - * return 0 if the groupnumber is valid. +/* return false if the groupnumber is not valid. + * return true if the groupnumber is valid. */ -static uint8_t groupnumber_not_valid(const Group_Chats *g_c, uint32_t groupnumber) +static bool is_groupnumber_valid(const Group_Chats *g_c, uint32_t groupnumber) { if (groupnumber >= g_c->num_chats) { - return 1; + return false; } if (g_c->chats == nullptr) { - return 1; + return false; } if (g_c->chats[groupnumber].status == GROUPCHAT_STATUS_NONE) { - return 1; + return false; } - return 0; + return true; } /* Set the size of the groupchat list to num. * - * return -1 if realloc fails. - * return 0 if it succeeds. + * return false if realloc fails. + * return true if it succeeds. */ -static int realloc_groupchats(Group_Chats *g_c, uint32_t num) +static bool realloc_conferences(Group_Chats *g_c, uint16_t num) { if (num == 0) { free(g_c->chats); g_c->chats = nullptr; - return 0; + return true; } Group_c *newgroup_chats = (Group_c *)realloc(g_c->chats, num * sizeof(Group_c)); if (newgroup_chats == nullptr) { - return -1; + return false; } g_c->chats = newgroup_chats; - return 0; + return true; } +static void setup_conference(Group_c *g) +{ + memset(g, 0, sizeof(Group_c)); +} /* Create a new empty groupchat connection. * * return -1 on failure. * return groupnumber on success. */ -static int create_group_chat(Group_Chats *g_c) +static int32_t create_group_chat(Group_Chats *g_c) { - uint32_t i; - - for (i = 0; i < g_c->num_chats; ++i) { + for (uint16_t i = 0; i < g_c->num_chats; ++i) { if (g_c->chats[i].status == GROUPCHAT_STATUS_NONE) { return i; } } - int id = -1; + int32_t id = -1; - if (realloc_groupchats(g_c, g_c->num_chats + 1) == 0) { + if (realloc_conferences(g_c, g_c->num_chats + 1)) { id = g_c->num_chats; ++g_c->num_chats; - memset(&g_c->chats[id], 0, sizeof(Group_c)); + setup_conference(&g_c->chats[id]); } return id; @@ -108,11 +114,11 @@ static int create_group_chat(Group_Chats *g_c) */ static int wipe_group_chat(Group_Chats *g_c, uint32_t groupnumber) { - if (groupnumber_not_valid(g_c, groupnumber)) { + if (!is_groupnumber_valid(g_c, groupnumber)) { return -1; } - uint32_t i; + uint16_t i; crypto_memzero(&g_c->chats[groupnumber], sizeof(Group_c)); for (i = g_c->num_chats; i != 0; --i) { @@ -123,7 +129,7 @@ static int wipe_group_chat(Group_Chats *g_c, uint32_t groupnumber) if (g_c->num_chats != i) { g_c->num_chats = i; - realloc_groupchats(g_c, g_c->num_chats); + realloc_conferences(g_c, g_c->num_chats); } return 0; @@ -131,7 +137,7 @@ static int wipe_group_chat(Group_Chats *g_c, uint32_t groupnumber) static Group_c *get_group_c(const Group_Chats *g_c, uint32_t groupnumber) { - if (groupnumber_not_valid(g_c, groupnumber)) { + if (!is_groupnumber_valid(g_c, groupnumber)) { return nullptr; } @@ -149,9 +155,7 @@ static Group_c *get_group_c(const Group_Chats *g_c, uint32_t groupnumber) static int peer_in_chat(const Group_c *chat, const uint8_t *real_pk) { - uint32_t i; - - for (i = 0; i < chat->numpeers; ++i) { + for (uint32_t i = 0; i < chat->numpeers; ++i) { if (id_equal(chat->group[i].real_pk, real_pk)) { return i; } @@ -168,11 +172,9 @@ static int peer_in_chat(const Group_c *chat, const uint8_t *real_pk) * * TODO(irungentoo): make this more efficient and maybe use constant time comparisons? */ -static int get_group_num(const Group_Chats *g_c, const uint8_t *identifier) +static int32_t get_group_num(const Group_Chats *g_c, const uint8_t *identifier) { - uint32_t i; - - for (i = 0; i < g_c->num_chats; ++i) { + for (uint16_t i = 0; i < g_c->num_chats; ++i) { if (crypto_memcmp(g_c->chats[i].identifier, identifier, GROUP_IDENTIFIER_LENGTH) == 0) { return i; } @@ -181,6 +183,17 @@ static int get_group_num(const Group_Chats *g_c, const uint8_t *identifier) return -1; } +int32_t conference_by_uid(const Group_Chats *g_c, const uint8_t *uid) +{ + for (uint16_t i = 0; i < g_c->num_chats; ++i) { + if (crypto_memcmp(g_c->chats[i].identifier + 1, uid, GROUP_IDENTIFIER_LENGTH - 1) == 0) { + return i; + } + } + + return -1; +} + /* * check if peer with peer_number is in peer array. * @@ -191,9 +204,7 @@ static int get_group_num(const Group_Chats *g_c, const uint8_t *identifier) */ static int get_peer_index(Group_c *g, uint16_t peer_number) { - uint32_t i; - - for (i = 0; i < g->numpeers; ++i) { + for (uint32_t i = 0; i < g->numpeers; ++i) { if (g->group[i].peer_number == peer_number) { return i; } @@ -217,11 +228,11 @@ static uint64_t calculate_comp_value(const uint8_t *pk1, const uint8_t *pk2) return (cmp1 - cmp2); } -enum { +typedef enum Groupchat_Closest { GROUPCHAT_CLOSEST_NONE, GROUPCHAT_CLOSEST_ADDED, GROUPCHAT_CLOSEST_REMOVED -}; +} Groupchat_Closest; static int friend_in_close(Group_c *g, int friendcon_id); static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, uint32_t groupnumber, uint8_t closest, @@ -341,15 +352,13 @@ static int connect_to_closest(Group_Chats *g_c, uint32_t groupnumber, void *user return 0; } - unsigned int i; - if (g->changed == GROUPCHAT_CLOSEST_REMOVED) { - for (i = 0; i < g->numpeers; ++i) { + for (uint32_t i = 0; i < g->numpeers; ++i) { add_to_closest(g_c, groupnumber, g->group[i].real_pk, g->group[i].temp_pk); } } - for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { + for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { if (g->close[i].type == GROUPCHAT_CLOSE_NONE) { continue; } @@ -368,7 +377,7 @@ static int connect_to_closest(Group_Chats *g_c, uint32_t groupnumber, void *user } } - for (i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) { + for (uint32_t i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) { if (!g->closest_peers[i].entry) { continue; } @@ -463,7 +472,7 @@ static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_p g->peer_on_join(g->object, groupnumber, g->numpeers - 1); } - return (g->numpeers - 1); + return g->numpeers - 1; } static int remove_close_conn(Group_Chats *g_c, uint32_t groupnumber, int friendcon_id) @@ -548,7 +557,7 @@ static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void } if (g->peer_on_leave) { - g->peer_on_leave(g->object, groupnumber, peer_index, peer_object); + g->peer_on_leave(g->object, groupnumber, peer_object); } return 0; @@ -653,9 +662,7 @@ static void set_conns_type_close(Group_Chats *g_c, uint32_t groupnumber, int fri /* Set the type for all close connections with friendcon_id */ static void set_conns_status_groups(Group_Chats *g_c, int friendcon_id, uint8_t type) { - uint32_t i; - - for (i = 0; i < g_c->num_chats; ++i) { + for (uint16_t i = 0; i < g_c->num_chats; ++i) { set_conns_type_close(g_c, i, friendcon_id, type); } } @@ -732,7 +739,7 @@ static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, uint32_t gr */ int add_groupchat(Group_Chats *g_c, uint8_t type) { - int groupnumber = create_group_chat(g_c); + int32_t groupnumber = create_group_chat(g_c); if (groupnumber == -1) { return -1; @@ -784,10 +791,8 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber) kill_friend_connection(g_c->fr_c, g->close[i].number); } - for (i = 0; i < g->numpeers; ++i) { - if (g->peer_on_leave) { - g->peer_on_leave(g->object, groupnumber, i, g->group[i].object); - } + if (g->peer_on_leave) { + g->peer_on_leave(g->object, groupnumber, g->group[i].object); } free(g->group); @@ -948,7 +953,7 @@ int group_peernumber_is_ours(const Group_Chats *g_c, uint32_t groupnumber, int p */ int group_get_type(const Group_Chats *g_c, uint32_t groupnumber) { - Group_c *g = get_group_c(g_c, groupnumber); + const Group_c *g = get_group_c(g_c, groupnumber); if (!g) { return -1; @@ -957,6 +962,26 @@ int group_get_type(const Group_Chats *g_c, uint32_t groupnumber) return g->identifier[0]; } +/* Copies the unique id of group_chat[groupnumber] into uid. +* +* return false on failure. +* return true on success. +*/ +bool conference_get_uid(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *uid) +{ + const Group_c *g = get_group_c(g_c, groupnumber); + + if (!g) { + return false; + } + + if (uid != nullptr) { + memcpy(uid, g->identifier + 1, sizeof(g->identifier) - 1); + } + + return true; +} + /* Send a group packet to friendcon_id. * * return 1 on success @@ -1112,9 +1137,7 @@ int join_groupchat(Group_Chats *g_c, uint32_t friendnumber, uint8_t expected_typ * * Function(void *group object (set with group_set_object), uint32_t groupnumber, uint32_t friendgroupnumber, void *group peer object (set with group_peer_set_object), const uint8_t *packet, uint16_t length) */ -void group_lossy_packet_registerhandler(Group_Chats *g_c, uint8_t byte, int (*function)(void *, uint32_t, uint32_t, - void *, - const uint8_t *, uint16_t)) +void group_lossy_packet_registerhandler(Group_Chats *g_c, uint8_t byte, lossy_packet_cb *function) { g_c->lossy_packethandlers[byte].function = function; } @@ -1125,8 +1148,7 @@ void group_lossy_packet_registerhandler(Group_Chats *g_c, uint8_t byte, int (*fu * * data of length is what needs to be passed to join_groupchat(). */ -void g_callback_group_invite(Group_Chats *g_c, void (*function)(Messenger *m, uint32_t, int, const uint8_t *, - size_t, void *)) +void g_callback_group_invite(Group_Chats *g_c, g_conference_invite_cb *function) { g_c->invite_callback = function; } @@ -1136,8 +1158,7 @@ void g_callback_group_invite(Group_Chats *g_c, void (*function)(Messenger *m, ui * * Function(Group_Chats *g_c, uint32_t groupnumber, uint32_t friendgroupnumber, uint8_t * message, size_t length, void *userdata) */ -void g_callback_group_message(Group_Chats *g_c, void (*function)(Messenger *m, uint32_t, uint32_t, int, const uint8_t *, - size_t, void *)) +void g_callback_group_message(Group_Chats *g_c, g_conference_message_cb *function) { g_c->message_callback = function; } @@ -1147,8 +1168,7 @@ void g_callback_group_message(Group_Chats *g_c, void (*function)(Messenger *m, u * It gets called every time a peer changes their nickname. * Function(Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, const uint8_t *nick, size_t nick_len, void *userdata) */ -void g_callback_peer_name(Group_Chats *g_c, void (*function)(Messenger *m, uint32_t, uint32_t, const uint8_t *, - size_t, void *)) +void g_callback_peer_name(Group_Chats *g_c, peer_name_cb *function) { g_c->peer_name_callback = function; } @@ -1158,7 +1178,7 @@ void g_callback_peer_name(Group_Chats *g_c, void (*function)(Messenger *m, uint3 * It gets called every time the name list changes(new peer, deleted peer) * Function(Group_Chats *g_c, uint32_t groupnumber, void *userdata) */ -void g_callback_peer_list_changed(Group_Chats *g_c, void (*function)(Messenger *m, uint32_t, void *)) +void g_callback_peer_list_changed(Group_Chats *g_c, peer_list_changed_cb *function) { g_c->peer_list_changed_callback = function; } @@ -1169,8 +1189,7 @@ void g_callback_peer_list_changed(Group_Chats *g_c, void (*function)(Messenger * * Function(Group_Chats *g_c, int groupnumber, int friendgroupnumber, uint8_t * title, uint8_t length, void *userdata) * if friendgroupnumber == -1, then author is unknown (e.g. initial joining the group) */ -void g_callback_group_title(Group_Chats *g_c, void (*function)(Messenger *m, uint32_t, uint32_t, const uint8_t *, - size_t, void *)) +void g_callback_group_title(Group_Chats *g_c, title_cb *function) { g_c->title_callback = function; } @@ -1182,8 +1201,7 @@ void g_callback_group_title(Group_Chats *g_c, void (*function)(Messenger *m, uin * return 0 on success. * return -1 on failure. */ -int callback_groupchat_peer_new(const Group_Chats *g_c, uint32_t groupnumber, void (*function)(void *, uint32_t, - uint32_t)) +int callback_groupchat_peer_new(const Group_Chats *g_c, uint32_t groupnumber, peer_on_join_cb *function) { Group_c *g = get_group_c(g_c, groupnumber); @@ -1202,8 +1220,7 @@ int callback_groupchat_peer_new(const Group_Chats *g_c, uint32_t groupnumber, vo * return 0 on success. * return -1 on failure. */ -int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, void (*function)(void *, uint32_t, uint32_t, - void *)) +int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, peer_on_leave_cb *function) { Group_c *g = get_group_c(g_c, groupnumber); @@ -1222,7 +1239,7 @@ int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, void * return 0 on success. * return -1 on failure. */ -int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, void (*function)(void *, uint32_t)) +int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, group_on_delete_cb *function) { Group_c *g = get_group_c(g_c, groupnumber); @@ -1413,7 +1430,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con if (groupnumber == -1) { if (g_c->invite_callback) { - g_c->invite_callback(m, friendnumber, *(invite_data + sizeof(uint16_t)), invite_data, invite_length, userdata); + g_c->invite_callback(m, friendnumber, invite_data[sizeof(uint16_t)], invite_data, invite_length, userdata); } return; @@ -1630,22 +1647,24 @@ static unsigned int send_peers(Group_Chats *g_c, uint32_t groupnumber, int frien return 0; } - uint8_t packet[MAX_CRYPTO_DATA_SIZE - (1 + sizeof(uint16_t))]; - packet[0] = PEER_RESPONSE_ID; - uint8_t *p = packet + 1; + uint8_t response_packet[MAX_CRYPTO_DATA_SIZE - (1 + sizeof(uint16_t))]; + response_packet[0] = PEER_RESPONSE_ID; + uint8_t *p = response_packet + 1; uint16_t sent = 0; - unsigned int i; + uint32_t i; for (i = 0; i < g->numpeers; ++i) { - if ((p - packet) + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE * 2 + 1 + g->group[i].nick_len > sizeof(packet)) { - if (send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, packet, (p - packet))) { + if ((p - response_packet) + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE * 2 + 1 + g->group[i].nick_len > sizeof( + response_packet)) { + if (send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, response_packet, + (p - response_packet))) { sent = i; } else { return sent; } - p = packet + 1; + p = response_packet + 1; } uint16_t peer_num = net_htons(g->group[i].peer_number); @@ -1662,16 +1681,18 @@ static unsigned int send_peers(Group_Chats *g_c, uint32_t groupnumber, int frien } if (sent != i) { - if (send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, packet, (p - packet))) { + if (send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, response_packet, + (p - response_packet))) { sent = i; } } if (g->title_len) { - VLA(uint8_t, Packet, 1 + g->title_len); - Packet[0] = PEER_TITLE_ID; - memcpy(Packet + 1, g->title, g->title_len); - send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, Packet, SIZEOF_VLA(Packet)); + VLA(uint8_t, title_packet, 1 + g->title_len); + title_packet[0] = PEER_TITLE_ID; + memcpy(title_packet + 1, g->title, g->title_len); + send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, title_packet, + SIZEOF_VLA(title_packet)); } return sent; @@ -2427,9 +2448,7 @@ static int groupchat_clear_timedout(Group_Chats *g_c, uint32_t groupnumber, void return -1; } - uint32_t i; - - for (i = 0; i < g->numpeers; ++i) { + for (uint32_t i = 0; i < g->numpeers; ++i) { if (g->peer_number != g->group[i].peer_number && is_timeout(g->group[i].last_recv, GROUP_PING_INTERVAL * 3)) { delpeer(g_c, groupnumber, i, userdata); } @@ -2446,9 +2465,7 @@ static int groupchat_clear_timedout(Group_Chats *g_c, uint32_t groupnumber, void */ void send_name_all_groups(Group_Chats *g_c) { - unsigned int i; - - for (i = 0; i < g_c->num_chats; ++i) { + for (uint16_t i = 0; i < g_c->num_chats; ++i) { Group_c *g = get_group_c(g_c, i); if (!g) { @@ -2485,9 +2502,7 @@ Group_Chats *new_groupchats(Messenger *m) /* main groupchats loop. */ void do_groupchats(Group_Chats *g_c, void *userdata) { - unsigned int i; - - for (i = 0; i < g_c->num_chats; ++i) { + for (uint16_t i = 0; i < g_c->num_chats; ++i) { Group_c *g = get_group_c(g_c, i); if (!g) { @@ -2507,9 +2522,7 @@ void do_groupchats(Group_Chats *g_c, void *userdata) /* Free everything related with group chats. */ void kill_groupchats(Group_Chats *g_c) { - unsigned int i; - - for (i = 0; i < g_c->num_chats; ++i) { + for (uint16_t i = 0; i < g_c->num_chats; ++i) { del_groupchat(g_c, i); } @@ -2522,14 +2535,13 @@ void kill_groupchats(Group_Chats *g_c) * You should use this to determine how much memory to allocate * for copy_chatlist. */ -uint32_t count_chatlist(Group_Chats *g_c) +uint32_t count_chatlist(const Group_Chats *g_c) { uint32_t ret = 0; - uint32_t i; - for (i = 0; i < g_c->num_chats; i++) { + for (uint16_t i = 0; i < g_c->num_chats; ++i) { if (g_c->chats[i].status != GROUPCHAT_STATUS_NONE) { - ret++; + ++ret; } } @@ -2541,7 +2553,7 @@ uint32_t count_chatlist(Group_Chats *g_c) * Otherwise, returns the number of elements copied. * If the array was too small, the contents * of out_list will be truncated to list_size. */ -uint32_t copy_chatlist(Group_Chats *g_c, uint32_t *out_list, uint32_t list_size) +uint32_t copy_chatlist(const Group_Chats *g_c, uint32_t *out_list, uint32_t list_size) { if (!out_list) { return 0; @@ -2551,16 +2563,16 @@ uint32_t copy_chatlist(Group_Chats *g_c, uint32_t *out_list, uint32_t list_size) return 0; } - uint32_t i, ret = 0; + uint32_t ret = 0; - for (i = 0; i < g_c->num_chats; ++i) { + for (uint16_t i = 0; i < g_c->num_chats; ++i) { if (ret >= list_size) { break; /* Abandon ship */ } if (g_c->chats[i].status > GROUPCHAT_STATUS_NONE) { out_list[ret] = i; - ret++; + ++ret; } } diff --git a/protocols/Tox/libtox/src/toxcore/group.h b/protocols/Tox/libtox/src/toxcore/group.h index a81dac39db..9b4541c471 100644 --- a/protocols/Tox/libtox/src/toxcore/group.h +++ b/protocols/Tox/libtox/src/toxcore/group.h @@ -26,20 +26,20 @@ #include "Messenger.h" -enum { +typedef enum Groupchat_Status { GROUPCHAT_STATUS_NONE, GROUPCHAT_STATUS_VALID, GROUPCHAT_STATUS_CONNECTED -}; +} Groupchat_Status; -enum { +typedef enum Groupchat_Type { GROUPCHAT_TYPE_TEXT, GROUPCHAT_TYPE_AV -}; +} Groupchat_Type; #define MAX_LOSSY_COUNT 256 -typedef struct { +typedef struct Group_Peer { uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE]; @@ -52,40 +52,49 @@ typedef struct { uint16_t peer_number; uint8_t recv_lossy[MAX_LOSSY_COUNT]; - uint16_t bottom_lossy_number, top_lossy_number; + uint16_t bottom_lossy_number; + uint16_t top_lossy_number; void *object; } Group_Peer; #define DESIRED_CLOSE_CONNECTIONS 4 #define MAX_GROUP_CONNECTIONS 16 -#define GROUP_IDENTIFIER_LENGTH (1 + CRYPTO_SYMMETRIC_KEY_SIZE) /* type + CRYPTO_SYMMETRIC_KEY_SIZE so we can use new_symmetric_key(...) to fill it */ +#define GROUP_IDENTIFIER_LENGTH (1 + CRYPTO_SYMMETRIC_KEY_SIZE) // type + CRYPTO_SYMMETRIC_KEY_SIZE so we can use new_symmetric_key(...) to fill it -enum { +typedef enum Groupchat_Close_Type { GROUPCHAT_CLOSE_NONE, GROUPCHAT_CLOSE_CONNECTION, GROUPCHAT_CLOSE_ONLINE -}; +} Groupchat_Close_Type; -typedef struct { +typedef struct Groupchat_Close { + uint8_t type; /* GROUPCHAT_CLOSE_* */ + uint8_t closest; + uint32_t number; + uint16_t group_number; +} Groupchat_Close; + +typedef struct Groupchat_Close_Connection { + uint8_t entry; + uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE]; +} Groupchat_Close_Connection; + +typedef void peer_on_join_cb(void *object, uint32_t conference_number, uint32_t peer_number); +typedef void peer_on_leave_cb(void *object, uint32_t conference_number, void *peer_object); +typedef void group_on_delete_cb(void *object, uint32_t conference_number); + +typedef struct Group_c { uint8_t status; Group_Peer *group; uint32_t numpeers; - struct { - uint8_t type; /* GROUPCHAT_CLOSE_* */ - uint8_t closest; - uint32_t number; - uint16_t group_number; - } close[MAX_GROUP_CONNECTIONS]; + Groupchat_Close close[MAX_GROUP_CONNECTIONS]; uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - struct { - uint8_t entry; - uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE]; - } closest_peers[DESIRED_CLOSE_CONNECTIONS]; + Groupchat_Close_Connection closest_peers[DESIRED_CLOSE_CONNECTIONS]; uint8_t changed; uint8_t identifier[GROUP_IDENTIFIER_LENGTH]; @@ -103,27 +112,41 @@ typedef struct { void *object; - void (*peer_on_join)(void *, uint32_t, uint32_t); - void (*peer_on_leave)(void *, uint32_t, uint32_t, void *); - void (*group_on_delete)(void *, uint32_t); + peer_on_join_cb *peer_on_join; + peer_on_leave_cb *peer_on_leave; + group_on_delete_cb *group_on_delete; } Group_c; -typedef struct { +typedef void g_conference_invite_cb(Messenger *m, uint32_t friend_number, int type, const uint8_t *cookie, + size_t length, void *user_data); +typedef void g_conference_message_cb(Messenger *m, uint32_t conference_number, uint32_t peer_number, int type, + const uint8_t *message, size_t length, void *user_data); +typedef void peer_name_cb(Messenger *m, uint32_t conference_number, uint32_t peer_number, const uint8_t *name, + size_t length, void *user_data); +typedef void peer_list_changed_cb(Messenger *m, uint32_t conference_number, void *user_data); +typedef void title_cb(Messenger *m, uint32_t conference_number, uint32_t peer_number, const uint8_t *title, + size_t length, void *user_data); +typedef int lossy_packet_cb(void *object, uint32_t conference_number, uint32_t peer_number, void *peer_object, + const uint8_t *packet, uint16_t length); + +typedef struct Group_Lossy_Handler { + lossy_packet_cb *function; +} Group_Lossy_Handler; + +typedef struct Group_Chats { Messenger *m; Friend_Connections *fr_c; Group_c *chats; - uint32_t num_chats; + uint16_t num_chats; - void (*invite_callback)(Messenger *m, uint32_t, int, const uint8_t *, size_t, void *); - void (*message_callback)(Messenger *m, uint32_t, uint32_t, int, const uint8_t *, size_t, void *); - void (*peer_name_callback)(Messenger *m, uint32_t, uint32_t, const uint8_t *, size_t, void *); - void (*peer_list_changed_callback)(Messenger *m, uint32_t, void *); - void (*title_callback)(Messenger *m, uint32_t, uint32_t, const uint8_t *, size_t, void *); + g_conference_invite_cb *invite_callback; + g_conference_message_cb *message_callback; + peer_name_cb *peer_name_callback; + peer_list_changed_cb *peer_list_changed_callback; + title_cb *title_callback; - struct { - int (*function)(void *, uint32_t, uint32_t, void *, const uint8_t *, uint16_t); - } lossy_packethandlers[256]; + Group_Lossy_Handler lossy_packethandlers[256]; } Group_Chats; /* Set the callback for group invites. @@ -132,15 +155,13 @@ typedef struct { * * data of length is what needs to be passed to join_groupchat(). */ -void g_callback_group_invite(Group_Chats *g_c, void (*function)(Messenger *m, uint32_t, int, const uint8_t *, - size_t, void *)); +void g_callback_group_invite(Group_Chats *g_c, g_conference_invite_cb *function); /* Set the callback for group messages. * * Function(Group_Chats *g_c, uint32_t groupnumber, uint32_t friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) */ -void g_callback_group_message(Group_Chats *g_c, void (*function)(Messenger *m, uint32_t, uint32_t, int, const uint8_t *, - size_t, void *)); +void g_callback_group_message(Group_Chats *g_c, g_conference_message_cb *function); /* Set callback function for title changes. @@ -148,23 +169,21 @@ void g_callback_group_message(Group_Chats *g_c, void (*function)(Messenger *m, u * Function(Group_Chats *g_c, uint32_t groupnumber, uint32_t friendgroupnumber, uint8_t * title, uint8_t length, void *userdata) * if friendgroupnumber == -1, then author is unknown (e.g. initial joining the group) */ -void g_callback_group_title(Group_Chats *g_c, void (*function)(Messenger *m, uint32_t, uint32_t, const uint8_t *, - size_t, void *)); +void g_callback_group_title(Group_Chats *g_c, title_cb *function); /* Set callback function for peer nickname changes. * * It gets called every time a peer changes their nickname. * Function(Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, const uint8_t *nick, size_t nick_len, void *userdata) */ -void g_callback_peer_name(Group_Chats *g_c, void (*function)(Messenger *m, uint32_t, uint32_t, const uint8_t *, - size_t, void *)); +void g_callback_peer_name(Group_Chats *g_c, peer_name_cb *function); /* Set callback function for peer list changes. * * It gets called every time the name list changes(new peer, deleted peer) * Function(Group_Chats *g_c, uint32_t groupnumber, void *userdata) */ -void g_callback_peer_list_changed(Group_Chats *g_c, void (*function)(Messenger *m, uint32_t, void *)); +void g_callback_peer_list_changed(Group_Chats *g_c, peer_list_changed_cb *function); /* Creates a new groupchat and puts it in the chats array. * @@ -299,9 +318,7 @@ int group_names(const Group_Chats *g_c, uint32_t groupnumber, uint8_t names[][MA * * Function(void *group object (set with group_set_object), uint32_t groupnumber, uint32_t friendgroupnumber, void *group peer object (set with group_peer_set_object), const uint8_t *packet, uint16_t length) */ -void group_lossy_packet_registerhandler(Group_Chats *g_c, uint8_t byte, int (*function)(void *, uint32_t, uint32_t, - void *, - const uint8_t *, uint16_t)); +void group_lossy_packet_registerhandler(Group_Chats *g_c, uint8_t byte, lossy_packet_cb *function); /* High level function to send custom lossy packets. * @@ -314,14 +331,14 @@ int send_group_lossy_packet(const Group_Chats *g_c, uint32_t groupnumber, const * You should use this to determine how much memory to allocate * for copy_chatlist. */ -uint32_t count_chatlist(Group_Chats *g_c); +uint32_t count_chatlist(const Group_Chats *g_c); /* Copy a list of valid chat IDs into the array out_list. * If out_list is NULL, returns 0. * Otherwise, returns the number of elements copied. * If the array was too small, the contents * of out_list will be truncated to list_size. */ -uint32_t copy_chatlist(Group_Chats *g_c, uint32_t *out_list, uint32_t list_size); +uint32_t copy_chatlist(const Group_Chats *g_c, uint32_t *out_list, uint32_t list_size); /* return the type of groupchat (GROUPCHAT_TYPE_) that groupnumber is. * @@ -330,6 +347,15 @@ uint32_t copy_chatlist(Group_Chats *g_c, uint32_t *out_list, uint32_t list_size) */ int group_get_type(const Group_Chats *g_c, uint32_t groupnumber); +/* Copies the unique id of group_chat[groupnumber] into uid. +* +* return false on failure. +* return true on success. +*/ +bool conference_get_uid(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *uid); + +int32_t conference_by_uid(const Group_Chats *g_c, const uint8_t *uid); + /* Send current name (set in messenger) to all online groups. */ void send_name_all_groups(Group_Chats *g_c); @@ -369,18 +395,16 @@ void *group_peer_get_object(const Group_Chats *g_c, uint32_t groupnumber, int pe * return 0 on success. * return -1 on failure. */ -int callback_groupchat_peer_new(const Group_Chats *g_c, uint32_t groupnumber, void (*function)(void *, uint32_t, - uint32_t)); +int callback_groupchat_peer_new(const Group_Chats *g_c, uint32_t groupnumber, peer_on_join_cb *function); /* Set a function to be called when a peer leaves a group chat. * - * Function(void *group object (set with group_set_object), uint32_t groupnumber, uint32_t friendgroupnumber, void *group peer object (set with group_peer_set_object)) + * Function(void *group object (set with group_set_object), uint32_t groupnumber, void *group peer object (set with group_peer_set_object)) * * return 0 on success. * return -1 on failure. */ -int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, void (*function)(void *, uint32_t, uint32_t, - void *)); +int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, peer_on_leave_cb *function); /* Set a function to be called when the group chat is deleted. * @@ -389,7 +413,7 @@ int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, void * return 0 on success. * return -1 on failure. */ -int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, void (*function)(void *, uint32_t)); +int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, group_on_delete_cb *function); /* Create new groupchat instance. */ Group_Chats *new_groupchats(Messenger *m); diff --git a/protocols/Tox/libtox/src/toxcore/list.c b/protocols/Tox/libtox/src/toxcore/list.c index 8fd1f5fb4c..4846ce2540 100644 --- a/protocols/Tox/libtox/src/toxcore/list.c +++ b/protocols/Tox/libtox/src/toxcore/list.c @@ -29,6 +29,9 @@ #include "list.h" +#include <stdlib.h> +#include <string.h> + #include "ccompat.h" /* Basically, the elements in the list are placed in order so that they can be searched for easily @@ -42,31 +45,35 @@ * -some considerations since the array size is never perfect */ -#define INDEX(i) (~i) +static int32_t +list_index(uint32_t i) +{ + return ~i; +} /* Find data in list * * return value: * >= 0 : index of data in array - * < 0 : no match, returns index (return value is INDEX(index)) where + * < 0 : no match, returns index (return value is list_index(index)) where * the data should be inserted */ -static int find(const BS_LIST *list, const uint8_t *data) +static int find(const BS_List *list, const uint8_t *data) { - //should work well, but could be improved + // should work well, but could be improved if (list->n == 0) { - return INDEX(0); + return list_index(0); } - uint32_t i = list->n / 2; //current position in the array - uint32_t delta = i / 2; //how much we move in the array + uint32_t i = list->n / 2; // current position in the array + uint32_t delta = i / 2; // how much we move in the array if (!delta) { delta = 1; } - int d = -1; //used to determine if closest match is found - //closest match is found if we move back to where we have already been + int d = -1; // used to determine if closest match is found + // closest match is found if we move back to where we have already been while (1) { int r = memcmp(data, list->data + list->element_size * i, list->element_size); @@ -76,13 +83,13 @@ static int find(const BS_LIST *list, const uint8_t *data) } if (r > 0) { - //data is greater - //move down + // data is greater + // move down i += delta; if (d == 0 || i == list->n) { - //reached bottom of list, or closest match - return INDEX(i); + // reached bottom of list, or closest match + return list_index(i); } delta = (delta) / 2; @@ -92,13 +99,13 @@ static int find(const BS_LIST *list, const uint8_t *data) d = 1; } } else { - //data is smaller + // data is smaller if (d == 1 || i == 0) { - //reached top or list or closest match - return INDEX(i); + // reached top or list or closest match + return list_index(i); } - //move up + // move up i -= delta; delta = (delta) / 2; @@ -117,7 +124,7 @@ static int find(const BS_LIST *list, const uint8_t *data) * 1 : success * 0 : failure */ -static int resize(BS_LIST *list, uint32_t new_size) +static int resize(BS_List *list, uint32_t new_size) { if (new_size == 0) { bs_list_free(list); @@ -144,9 +151,9 @@ static int resize(BS_LIST *list, uint32_t new_size) } -int bs_list_init(BS_LIST *list, uint32_t element_size, uint32_t initial_capacity) +int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity) { - //set initial values + // set initial values list->n = 0; list->element_size = element_size; list->capacity = 0; @@ -164,9 +171,9 @@ int bs_list_init(BS_LIST *list, uint32_t element_size, uint32_t initial_capacity return 1; } -void bs_list_free(BS_LIST *list) +void bs_list_free(BS_List *list) { - //free both arrays + // free both arrays free(list->data); list->data = nullptr; @@ -174,11 +181,11 @@ void bs_list_free(BS_LIST *list) list->ids = nullptr; } -int bs_list_find(const BS_LIST *list, const uint8_t *data) +int bs_list_find(const BS_List *list, const uint8_t *data) { int r = find(list, data); - //return only -1 and positive values + // return only -1 and positive values if (r < 0) { return -1; } @@ -186,20 +193,20 @@ int bs_list_find(const BS_LIST *list, const uint8_t *data) return list->ids[r]; } -int bs_list_add(BS_LIST *list, const uint8_t *data, int id) +int bs_list_add(BS_List *list, const uint8_t *data, int id) { - //find where the new element should be inserted - //see: return value of find() + // find where the new element should be inserted + // see: return value of find() int i = find(list, data); if (i >= 0) { - //already in list + // already in list return 0; } i = ~i; - //increase the size of the arrays if needed + // increase the size of the arrays if needed if (list->n == list->capacity) { // 1.5 * n + 1 const uint32_t new_capacity = list->n + list->n / 2 + 1; @@ -211,22 +218,22 @@ int bs_list_add(BS_LIST *list, const uint8_t *data, int id) list->capacity = new_capacity; } - //insert data to element array + // insert data to element array memmove(list->data + (i + 1) * list->element_size, list->data + i * list->element_size, (list->n - i) * list->element_size); memcpy(list->data + i * list->element_size, data, list->element_size); - //insert id to id array + // insert id to id array memmove(&list->ids[i + 1], &list->ids[i], (list->n - i) * sizeof(int)); list->ids[i] = id; - //increase n - list->n++; + // increase n + ++list->n; return 1; } -int bs_list_remove(BS_LIST *list, const uint8_t *data, int id) +int bs_list_remove(BS_List *list, const uint8_t *data, int id) { int i = find(list, data); @@ -235,11 +242,11 @@ int bs_list_remove(BS_LIST *list, const uint8_t *data, int id) } if (list->ids[i] != id) { - //this should never happen + // this should never happen return 0; } - //decrease the size of the arrays if needed + // decrease the size of the arrays if needed if (list->n < list->capacity / 2) { const uint32_t new_capacity = list->capacity / 2; @@ -248,7 +255,7 @@ int bs_list_remove(BS_LIST *list, const uint8_t *data, int id) } } - list->n--; + --list->n; memmove(list->data + i * list->element_size, list->data + (i + 1) * list->element_size, (list->n - i) * list->element_size); @@ -257,7 +264,7 @@ int bs_list_remove(BS_LIST *list, const uint8_t *data, int id) return 1; } -int bs_list_trim(BS_LIST *list) +int bs_list_trim(BS_List *list) { if (!resize(list, list->n)) { return 0; diff --git a/protocols/Tox/libtox/src/toxcore/list.h b/protocols/Tox/libtox/src/toxcore/list.h index cb3b328c5a..628b46a051 100644 --- a/protocols/Tox/libtox/src/toxcore/list.h +++ b/protocols/Tox/libtox/src/toxcore/list.h @@ -27,16 +27,14 @@ #define LIST_H #include <stdint.h> -#include <stdlib.h> -#include <string.h> -typedef struct { - uint32_t n; //number of elements - uint32_t capacity; //number of elements memory is allocated for - uint32_t element_size; //size of the elements - uint8_t *data; //array of elements - int *ids; //array of element ids -} BS_LIST; +typedef struct BS_List { + uint32_t n; // number of elements + uint32_t capacity; // number of elements memory is allocated for + uint32_t element_size; // size of the elements + uint8_t *data; // array of elements + int *ids; // array of element ids +} BS_List; /* Initialize a list, element_size is the size of the elements in the list and * initial_capacity is the number of elements the memory will be initially allocated for @@ -45,10 +43,10 @@ typedef struct { * 1 : success * 0 : failure */ -int bs_list_init(BS_LIST *list, uint32_t element_size, uint32_t initial_capacity); +int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity); /* Free a list initiated with list_init */ -void bs_list_free(BS_LIST *list); +void bs_list_free(BS_List *list); /* Retrieve the id of an element in the list * @@ -56,7 +54,7 @@ void bs_list_free(BS_LIST *list); * >= 0 : id associated with data * -1 : failure */ -int bs_list_find(const BS_LIST *list, const uint8_t *data); +int bs_list_find(const BS_List *list, const uint8_t *data); /* Add an element with associated id to the list * @@ -64,7 +62,7 @@ int bs_list_find(const BS_LIST *list, const uint8_t *data); * 1 : success * 0 : failure (data already in list) */ -int bs_list_add(BS_LIST *list, const uint8_t *data, int id); +int bs_list_add(BS_List *list, const uint8_t *data, int id); /* Remove element from the list * @@ -72,7 +70,7 @@ int bs_list_add(BS_LIST *list, const uint8_t *data, int id); * 1 : success * 0 : failure (element not found or id does not match) */ -int bs_list_remove(BS_LIST *list, const uint8_t *data, int id); +int bs_list_remove(BS_List *list, const uint8_t *data, int id); /* Removes the memory overhead * @@ -80,6 +78,6 @@ int bs_list_remove(BS_LIST *list, const uint8_t *data, int id); * 1 : success * 0 : failure */ -int bs_list_trim(BS_LIST *list); +int bs_list_trim(BS_List *list); #endif diff --git a/protocols/Tox/libtox/src/toxcore/logger.c b/protocols/Tox/libtox/src/toxcore/logger.c index ff34f994ea..ac80b194ab 100644 --- a/protocols/Tox/libtox/src/toxcore/logger.c +++ b/protocols/Tox/libtox/src/toxcore/logger.c @@ -31,6 +31,7 @@ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> struct Logger { @@ -40,7 +41,7 @@ struct Logger { }; #ifdef USE_STDERR_LOGGER -static const char *logger_level_name(LOGGER_LEVEL level) +static const char *logger_level_name(Logger_Level level) { switch (level) { case LOG_TRACE: @@ -62,7 +63,7 @@ static const char *logger_level_name(LOGGER_LEVEL level) return "<unknown>"; } -static void logger_stderr_handler(void *context, LOGGER_LEVEL level, const char *file, int line, const char *func, +static void logger_stderr_handler(void *context, Logger_Level level, const char *file, int line, const char *func, const char *message, void *userdata) { // GL stands for "global logger". @@ -96,7 +97,7 @@ void logger_callback_log(Logger *log, logger_cb *function, void *context, void * log->userdata = userdata; } -void logger_write(const Logger *log, LOGGER_LEVEL level, const char *file, int line, const char *func, +void logger_write(const Logger *log, Logger_Level level, const char *file, int line, const char *func, const char *format, ...) { if (!log) { @@ -111,11 +112,23 @@ void logger_write(const Logger *log, LOGGER_LEVEL level, const char *file, int l return; } - /* Format message */ + // Only pass the file name, not the entire file path, for privacy reasons. + // The full path may contain PII of the person compiling toxcore (their + // username and directory layout). + const char *filename = strrchr(file, '/'); + file = filename ? filename + 1 : file; +#if defined(_WIN32) || defined(__CYGWIN__) + // On Windows, the path separator *may* be a backslash, so we look for that + // one too. + const char *windows_filename = strrchr(file, '\\'); + file = windows_filename ? windows_filename + 1 : file; +#endif + + // Format message char msg[1024]; va_list args; va_start(args, format); - vsnprintf(msg, sizeof msg, format, args); + vsnprintf(msg, sizeof(msg), format, args); va_end(args); log->callback(log->context, level, file, line, func, msg, log->userdata); diff --git a/protocols/Tox/libtox/src/toxcore/logger.h b/protocols/Tox/libtox/src/toxcore/logger.h index acd21fb803..38cc0ac9fb 100644 --- a/protocols/Tox/libtox/src/toxcore/logger.h +++ b/protocols/Tox/libtox/src/toxcore/logger.h @@ -32,17 +32,17 @@ #define MIN_LOGGER_LEVEL LOG_INFO #endif -typedef enum { +typedef enum Logger_Level { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR -} LOGGER_LEVEL; +} Logger_Level; typedef struct Logger Logger; -typedef void logger_cb(void *context, LOGGER_LEVEL level, const char *file, int line, +typedef void logger_cb(void *context, Logger_Level level, const char *file, int line, const char *func, const char *message, void *userdata); /** @@ -72,7 +72,7 @@ void logger_callback_log(Logger *log, logger_cb *function, void *context, void * * assertion failure otherwise. */ 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, ...) GNU_PRINTF(6, 7); diff --git a/protocols/Tox/libtox/src/toxcore/mono_time.c b/protocols/Tox/libtox/src/toxcore/mono_time.c new file mode 100644 index 0000000000..415981d9eb --- /dev/null +++ b/protocols/Tox/libtox/src/toxcore/mono_time.c @@ -0,0 +1,163 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 600 +#endif + +#if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) +#define OS_WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#endif + +#ifdef __APPLE__ +#include <mach/clock.h> +#include <mach/mach.h> +#endif + +#ifndef OS_WIN32 +#include <sys/time.h> +#endif + +#include "mono_time.h" + +#include <stdlib.h> +#include <time.h> + +#include "ccompat.h" + +/* don't call into system billions of times for no reason */ +struct Mono_Time { + uint64_t time; + uint64_t base_time; +}; + +Mono_Time *mono_time_new(void) +{ + Mono_Time *monotime = (Mono_Time *)malloc(sizeof(Mono_Time)); + + if (monotime == nullptr) { + return nullptr; + } + + monotime->time = 0; + monotime->base_time = 0; + + return monotime; +} + +void mono_time_free(Mono_Time *monotime) +{ + free(monotime); +} + +void mono_time_update(Mono_Time *monotime) +{ + if (monotime->base_time == 0) { + monotime->base_time = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); + } + + monotime->time = (current_time_monotonic() / 1000ULL) + monotime->base_time; +} + +uint64_t mono_time_get(const Mono_Time *monotime) +{ + return monotime->time; +} + +bool mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_t timeout) +{ + return timestamp + timeout <= mono_time_get(monotime); +} + + +//!TOKSTYLE- +// No global mutable state in Tokstyle. +static Mono_Time global_time; +//!TOKSTYLE+ + +/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of + * unix_time() may fail to increase monotonically with increasing time */ +void unix_time_update(void) +{ + mono_time_update(&global_time); +} +uint64_t unix_time(void) +{ + return mono_time_get(&global_time); +} +int is_timeout(uint64_t timestamp, uint64_t timeout) +{ + return mono_time_is_timeout(&global_time, timestamp, timeout); +} + + + +/* return current UNIX time in microseconds (us). */ +uint64_t current_time_actual(void) +{ + uint64_t time; +#ifdef OS_WIN32 + /* This probably works fine */ + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + time = ft.dwHighDateTime; + time <<= 32; + time |= ft.dwLowDateTime; + time -= 116444736000000000ULL; + return time / 10; +#else + struct timeval a; + gettimeofday(&a, nullptr); + time = 1000000ULL * a.tv_sec + a.tv_usec; + return time; +#endif +} + + +//!TOKSTYLE- +// No global mutable state in Tokstyle. +#ifdef OS_WIN32 +static uint64_t last_monotime; +static uint64_t add_monotime; +#endif +//!TOKSTYLE+ + +/* return current monotonic time in milliseconds (ms). */ +uint64_t current_time_monotonic(void) +{ + uint64_t time; +#ifdef OS_WIN32 + uint64_t old_add_monotime = add_monotime; + time = (uint64_t)GetTickCount() + add_monotime; + + /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race + * conditions when multiple threads call this function at once */ + if (time + 0x10000 < last_monotime) { + uint32_t add = ~0; + /* use old_add_monotime rather than simply incrementing add_monotime, to handle the case that many threads + * simultaneously detect an overflow */ + add_monotime = old_add_monotime + add; + time += add; + } + + last_monotime = time; +#else + struct timespec monotime; +#if defined(__linux__) && defined(CLOCK_MONOTONIC_RAW) + clock_gettime(CLOCK_MONOTONIC_RAW, &monotime); +#elif defined(__APPLE__) + clock_serv_t muhclock; + mach_timespec_t machtime; + + host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock); + clock_get_time(muhclock, &machtime); + mach_port_deallocate(mach_task_self(), muhclock); + + monotime.tv_sec = machtime.tv_sec; + monotime.tv_nsec = machtime.tv_nsec; +#else + clock_gettime(CLOCK_MONOTONIC, &monotime); +#endif + time = 1000ULL * monotime.tv_sec + (monotime.tv_nsec / 1000000ULL); +#endif + return time; +} diff --git a/protocols/Tox/libtox/src/toxcore/mono_time.h b/protocols/Tox/libtox/src/toxcore/mono_time.h new file mode 100644 index 0000000000..63e0f49df7 --- /dev/null +++ b/protocols/Tox/libtox/src/toxcore/mono_time.h @@ -0,0 +1,35 @@ +#ifndef C_TOXCORE_TOXCORE_MONO_TIME_H +#define C_TOXCORE_TOXCORE_MONO_TIME_H + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Mono_Time Mono_Time; + +Mono_Time *mono_time_new(void); +void mono_time_free(Mono_Time *monotime); + +void mono_time_update(Mono_Time *monotime); +uint64_t mono_time_get(const Mono_Time *monotime); +bool mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_t timeout); + +// TODO(#405): Use per-tox monotime, delete these functions. +void unix_time_update(void); +uint64_t unix_time(void); +int is_timeout(uint64_t timestamp, uint64_t timeout); + +/* return current UNIX time in microseconds (us). */ +uint64_t current_time_actual(void); + +/* return current monotonic time in milliseconds (ms). */ +uint64_t current_time_monotonic(void); + +#ifdef __cplusplus +} +#endif + +#endif // C_TOXCORE_TOXCORE_MONO_TIME_H diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.c b/protocols/Tox/libtox/src/toxcore/net_crypto.c index 2e8299f10b..b9ffaf2149 100644 --- a/protocols/Tox/libtox/src/toxcore/net_crypto.c +++ b/protocols/Tox/libtox/src/toxcore/net_crypto.c @@ -29,23 +29,26 @@ #include "net_crypto.h" -#include "util.h" - #include <math.h> +#include <stdlib.h> +#include <string.h> + +#include "mono_time.h" +#include "util.h" -typedef struct { +typedef struct Packet_Data { uint64_t sent_time; uint16_t length; uint8_t data[MAX_CRYPTO_DATA_SIZE]; } Packet_Data; -typedef struct { +typedef struct Packets_Array { Packet_Data *buffer[CRYPTO_PACKET_BUFFER_SIZE]; uint32_t buffer_start; uint32_t buffer_end; /* packet numbers in array: {buffer_start, buffer_end) */ } Packets_Array; -typedef struct { +typedef struct Crypto_Connection { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ @@ -53,11 +56,14 @@ typedef struct { uint8_t sessionsecret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private key for this session. */ uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. */ - uint8_t status; /* 0 if no connection, 1 we are sending cookie request packets, - * 2 if we are sending handshake packets - * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet), - * 4 if the connection is established. - */ + /** + * 0 if no connection, + * 1 we are sending cookie request packets, + * 2 if we are sending handshake packets, + * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet), + * 4 if the connection is established. + */ + Crypto_Conn_State status; uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ @@ -76,15 +82,15 @@ typedef struct { Packets_Array send_array; Packets_Array recv_array; - int (*connection_status_callback)(void *object, int id, uint8_t status, void *userdata); + connection_status_cb *connection_status_callback; void *connection_status_callback_object; int connection_status_callback_id; - int (*connection_data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); + connection_data_cb *connection_data_callback; void *connection_data_callback_object; int connection_data_callback_id; - int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); + connection_lossy_data_cb *connection_lossy_data_callback; void *connection_lossy_data_callback_object; int connection_lossy_data_callback_id; @@ -105,10 +111,12 @@ typedef struct { uint64_t last_packets_left_requested_set; double last_packets_left_requested_rem; - uint32_t last_sendqueue_size[CONGESTION_QUEUE_ARRAY_SIZE], last_sendqueue_counter; - long signed int last_num_packets_sent[CONGESTION_LAST_SENT_ARRAY_SIZE], - last_num_packets_resent[CONGESTION_LAST_SENT_ARRAY_SIZE]; - uint32_t packets_sent, packets_resent; + uint32_t last_sendqueue_size[CONGESTION_QUEUE_ARRAY_SIZE]; + uint32_t last_sendqueue_counter; + long signed int last_num_packets_sent[CONGESTION_LAST_SENT_ARRAY_SIZE]; + long signed int last_num_packets_resent[CONGESTION_LAST_SENT_ARRAY_SIZE]; + uint32_t packets_sent; + uint32_t packets_resent; uint64_t last_congestion_event; uint64_t rtt_time; @@ -119,13 +127,13 @@ typedef struct { pthread_mutex_t mutex; - void (*dht_pk_callback)(void *data, int32_t number, const uint8_t *dht_public_key, void *userdata); + dht_pk_cb *dht_pk_callback; void *dht_pk_callback_object; uint32_t dht_pk_callback_number; } Crypto_Connection; struct Net_Crypto { - Logger *log; + const Logger *log; DHT *dht; TCP_Connections *tcp_c; @@ -145,13 +153,13 @@ struct Net_Crypto { /* The secret key used for cookies */ uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; - int (*new_connection_callback)(void *object, New_Connection *n_c); + new_connection_cb *new_connection_callback; void *new_connection_callback_object; /* The current optimal sleep time */ uint32_t current_sleep_time; - BS_LIST ip_port_list; + BS_List ip_port_list; }; const uint8_t *nc_get_self_public_key(const Net_Crypto *c) @@ -193,13 +201,13 @@ static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_conn /* cookie timeout in seconds */ #define COOKIE_TIMEOUT 15 -#define COOKIE_DATA_LENGTH (CRYPTO_PUBLIC_KEY_SIZE * 2) -#define COOKIE_CONTENTS_LENGTH (sizeof(uint64_t) + COOKIE_DATA_LENGTH) -#define COOKIE_LENGTH (CRYPTO_NONCE_SIZE + COOKIE_CONTENTS_LENGTH + CRYPTO_MAC_SIZE) +#define COOKIE_DATA_LENGTH (uint16_t)(CRYPTO_PUBLIC_KEY_SIZE * 2) +#define COOKIE_CONTENTS_LENGTH (uint16_t)(sizeof(uint64_t) + COOKIE_DATA_LENGTH) +#define COOKIE_LENGTH (uint16_t)(CRYPTO_NONCE_SIZE + COOKIE_CONTENTS_LENGTH + CRYPTO_MAC_SIZE) -#define COOKIE_REQUEST_PLAIN_LENGTH (COOKIE_DATA_LENGTH + sizeof(uint64_t)) -#define COOKIE_REQUEST_LENGTH (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) -#define COOKIE_RESPONSE_LENGTH (1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE) +#define COOKIE_REQUEST_PLAIN_LENGTH (uint16_t)(COOKIE_DATA_LENGTH + sizeof(uint64_t)) +#define COOKIE_REQUEST_LENGTH (uint16_t)(1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) +#define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE) /* Create a cookie request packet and put it in packet. * dht_public_key is the dht public key of the other @@ -219,7 +227,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, uint8_t * memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, padding, CRYPTO_PUBLIC_KEY_SIZE); memcpy(plain + (CRYPTO_PUBLIC_KEY_SIZE * 2), &number, sizeof(uint64_t)); - DHT_get_shared_key_sent(c->dht, shared_key, dht_public_key); + dht_get_shared_key_sent(c->dht, shared_key, dht_public_key); uint8_t nonce[CRYPTO_NONCE_SIZE]; random_nonce(nonce); packet[0] = NET_PACKET_COOKIE_REQUEST; @@ -240,10 +248,10 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, uint8_t * * return -1 on failure. * return 0 on success. */ -static int create_cookie(uint8_t *cookie, const uint8_t *bytes, const uint8_t *encryption_key) +static int create_cookie(const Logger *log, uint8_t *cookie, const uint8_t *bytes, const uint8_t *encryption_key) { uint8_t contents[COOKIE_CONTENTS_LENGTH]; - uint64_t temp_time = unix_time(); + const uint64_t temp_time = unix_time(); memcpy(contents, &temp_time, sizeof(temp_time)); memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH); random_nonce(cookie); @@ -261,11 +269,11 @@ static int create_cookie(uint8_t *cookie, const uint8_t *bytes, const uint8_t *e * return -1 on failure. * return 0 on success. */ -static int open_cookie(uint8_t *bytes, const uint8_t *cookie, const uint8_t *encryption_key) +static int open_cookie(const Logger *log, uint8_t *bytes, const uint8_t *cookie, const uint8_t *encryption_key) { uint8_t contents[COOKIE_CONTENTS_LENGTH]; - int len = decrypt_data_symmetric(encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE, - COOKIE_LENGTH - CRYPTO_NONCE_SIZE, contents); + const int len = decrypt_data_symmetric(encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE, + COOKIE_LENGTH - CRYPTO_NONCE_SIZE, contents); if (len != sizeof(contents)) { return -1; @@ -273,7 +281,7 @@ static int open_cookie(uint8_t *bytes, const uint8_t *cookie, const uint8_t *enc uint64_t cookie_time; memcpy(&cookie_time, contents, sizeof(cookie_time)); - uint64_t temp_time = unix_time(); + const uint64_t temp_time = unix_time(); if (cookie_time + COOKIE_TIMEOUT < temp_time || temp_time < cookie_time) { return -1; @@ -299,7 +307,7 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; - if (create_cookie(plain, cookie_plain, c->secret_symmetric_key) != 0) { + if (create_cookie(c->log, plain, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } @@ -330,7 +338,7 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui } memcpy(dht_public_key, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); - DHT_get_shared_key_sent(c->dht, shared_key, dht_public_key); + dht_get_shared_key_sent(c->dht, shared_key, dht_public_key); int len = decrypt_data_symmetric(shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE, request_plain); @@ -426,7 +434,8 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c * return -1 on failure. * return COOKIE_LENGTH on success. */ -static int handle_cookie_response(uint8_t *cookie, uint64_t *number, const uint8_t *packet, uint16_t length, +static int handle_cookie_response(const Logger *log, uint8_t *cookie, uint64_t *number, + const uint8_t *packet, uint16_t length, const uint8_t *shared_key) { if (length != COOKIE_RESPONSE_LENGTH) { @@ -434,8 +443,8 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, const uint8 } uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; - int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, - length - (1 + CRYPTO_NONCE_SIZE), plain); + const int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, + length - (1 + CRYPTO_NONCE_SIZE), plain); if (len != sizeof(plain)) { return -1; @@ -466,7 +475,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - if (create_cookie(plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, cookie_plain, + if (create_cookie(c->log, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } @@ -512,7 +521,7 @@ static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - if (open_cookie(cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { + if (open_cookie(c->log, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { return -1; } @@ -571,7 +580,7 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Por return -1; } - if (ip_port.ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(ip_port.ip.family)) { if (!ipport_equal(&ip_port, &conn->ip_portv4) && ip_is_lan(conn->ip_portv4.ip) != 0) { if (!bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id)) { return -1; @@ -581,7 +590,7 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Por conn->ip_portv4 = ip_port; return 0; } - } else if (ip_port.ip.family == TOX_AF_INET6) { + } else if (net_family_is_ipv6(ip_port.ip.family)) { if (!ipport_equal(&ip_port, &conn->ip_portv6)) { if (!bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id)) { return -1; @@ -603,7 +612,7 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Por */ static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id) { - const IP_Port empty = {{0}}; + const IP_Port empty = {{{0}}}; Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -626,11 +635,11 @@ static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id) return conn->ip_portv4; } - if (v6 && conn->ip_portv6.ip.family == TOX_AF_INET6) { + if (v6 && net_family_is_ipv6(conn->ip_portv6.ip.family)) { return conn->ip_portv6; } - if (conn->ip_portv4.ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(conn->ip_portv4.ip.family)) { return conn->ip_portv4; } @@ -657,7 +666,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); // TODO(irungentoo): on bad networks, direct connections might not last indefinitely. - if (ip_port.ip.family != 0) { + if (!net_family_is_unspec(ip_port.ip.family)) { bool direct_connected = 0; crypto_connection_status(c, crypt_connection_id, &direct_connected, nullptr); @@ -719,9 +728,9 @@ static uint32_t num_packets_array(const Packets_Array *array) * return -1 on failure. * return 0 on success. */ -static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packet_Data *data) +static int add_data_to_buffer(const Logger *log, Packets_Array *array, uint32_t number, const Packet_Data *data) { - if (number - array->buffer_start > CRYPTO_PACKET_BUFFER_SIZE) { + if (number - array->buffer_start >= CRYPTO_PACKET_BUFFER_SIZE) { return -1; } @@ -740,7 +749,7 @@ static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packe memcpy(new_d, data, sizeof(Packet_Data)); array->buffer[num] = new_d; - if ((number - array->buffer_start) >= (array->buffer_end - array->buffer_start)) { + if (number - array->buffer_start >= num_packets_array(array)) { array->buffer_end = number + 1; } @@ -753,9 +762,9 @@ static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packe * return 0 if data at number is empty. * return 1 if data pointer was put in data. */ -static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint32_t number) +static int get_data_pointer(const Logger *log, const Packets_Array *array, Packet_Data **data, uint32_t number) { - uint32_t num_spots = array->buffer_end - array->buffer_start; + const uint32_t num_spots = num_packets_array(array); if (array->buffer_end - number > num_spots || number - array->buffer_start >= num_spots) { return -1; @@ -776,9 +785,11 @@ static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint * return -1 on failure. * return packet number on success. */ -static int64_t add_data_end_of_buffer(Packets_Array *array, const Packet_Data *data) +static int64_t add_data_end_of_buffer(const Logger *log, Packets_Array *array, const Packet_Data *data) { - if (num_packets_array(array) >= CRYPTO_PACKET_BUFFER_SIZE) { + const uint32_t num_spots = num_packets_array(array); + + if (num_spots >= CRYPTO_PACKET_BUFFER_SIZE) { return -1; } @@ -795,18 +806,18 @@ static int64_t add_data_end_of_buffer(Packets_Array *array, const Packet_Data *d return id; } -/* Read data from begginning of array. +/* Read data from beginning of array. * * return -1 on failure. * return packet number on success. */ -static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data) +static int64_t read_data_beg_buffer(const Logger *log, Packets_Array *array, Packet_Data *data) { if (array->buffer_end == array->buffer_start) { return -1; } - uint32_t num = array->buffer_start % CRYPTO_PACKET_BUFFER_SIZE; + const uint32_t num = array->buffer_start % CRYPTO_PACKET_BUFFER_SIZE; if (!array->buffer[num]) { return -1; @@ -825,9 +836,9 @@ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data) * return -1 on failure. * return 0 on success */ -static int clear_buffer_until(Packets_Array *array, uint32_t number) +static int clear_buffer_until(const Logger *log, Packets_Array *array, uint32_t number) { - uint32_t num_spots = array->buffer_end - array->buffer_start; + const uint32_t num_spots = num_packets_array(array); if (array->buffer_end - number >= num_spots || number - array->buffer_start > num_spots) { return -1; @@ -870,13 +881,13 @@ static int clear_buffer(Packets_Array *array) * return -1 on failure. * return 0 on success. */ -static int set_buffer_end(Packets_Array *array, uint32_t number) +static int set_buffer_end(const Logger *log, Packets_Array *array, uint32_t number) { - if ((number - array->buffer_start) > CRYPTO_PACKET_BUFFER_SIZE) { + if (number - array->buffer_start > CRYPTO_PACKET_BUFFER_SIZE) { return -1; } - if ((number - array->buffer_end) > CRYPTO_PACKET_BUFFER_SIZE) { + if (number - array->buffer_end > CRYPTO_PACKET_BUFFER_SIZE) { return -1; } @@ -890,7 +901,7 @@ static int set_buffer_end(Packets_Array *array, uint32_t number) * return -1 on failure. * return length of packet on success. */ -static int generate_request_packet(uint8_t *data, uint16_t length, const Packets_Array *recv_array) +static int generate_request_packet(const Logger *log, uint8_t *data, uint16_t length, const Packets_Array *recv_array) { if (length == 0) { return -1; @@ -943,10 +954,10 @@ static int generate_request_packet(uint8_t *data, uint16_t length, const Packets * return -1 on failure. * return number of requested packets on success. */ -static int handle_request_packet(Packets_Array *send_array, const uint8_t *data, uint16_t length, +static int handle_request_packet(const Logger *log, Packets_Array *send_array, const uint8_t *data, uint16_t length, uint64_t *latest_send_time, uint64_t rtt_time) { - if (length < 1) { + if (length == 0) { return -1; } @@ -961,13 +972,13 @@ static int handle_request_packet(Packets_Array *send_array, const uint8_t *data, ++data; --length; - uint32_t i, n = 1; + uint32_t n = 1; uint32_t requested = 0; - uint64_t temp_time = current_time_monotonic(); + const uint64_t temp_time = current_time_monotonic(); uint64_t l_sent_time = ~0; - for (i = send_array->buffer_start; i != send_array->buffer_end; ++i) { + for (uint32_t i = send_array->buffer_start; i != send_array->buffer_end; ++i) { if (length == 0) { break; } @@ -1032,7 +1043,9 @@ static int handle_request_packet(Packets_Array *send_array, const uint8_t *data, */ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) { - if (length == 0 || length + (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE) > MAX_CRYPTO_PACKET_SIZE) { + const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE); + + if (length == 0 || length > max_length) { return -1; } @@ -1046,7 +1059,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ VLA(uint8_t, packet, 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE); packet[0] = NET_PACKET_CRYPTO_DATA; memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); - int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); + const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); if (len + 1 + sizeof(uint16_t) != SIZEOF_VLA(packet)) { pthread_mutex_unlock(&conn->mutex); @@ -1095,27 +1108,19 @@ static int reset_max_speed_reached(Net_Crypto *c, int crypt_connection_id) If sending it fails we won't be able to send the new packet. */ if (conn->maximum_speed_reached) { Packet_Data *dt = nullptr; - uint32_t packet_num = conn->send_array.buffer_end - 1; - int ret = get_data_pointer(&conn->send_array, &dt, packet_num); - - uint8_t send_failed = 0; + const uint32_t packet_num = conn->send_array.buffer_end - 1; + const int ret = get_data_pointer(c->log, &conn->send_array, &dt, packet_num); - if (ret == 1) { - if (!dt->sent_time) { - if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data, - dt->length) != 0) { - send_failed = 1; - } else { - dt->sent_time = current_time_monotonic(); - } + if (ret == 1 && dt->sent_time == 0) { + if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, + dt->data, dt->length) != 0) { + return -1; } - } - if (!send_failed) { - conn->maximum_speed_reached = 0; - } else { - return -1; + dt->sent_time = current_time_monotonic(); } + + conn->maximum_speed_reached = 0; } return 0; @@ -1150,7 +1155,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons dt.length = length; memcpy(dt.data, data, length); pthread_mutex_lock(&conn->mutex); - int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt); + int64_t packet_num = add_data_end_of_buffer(c->log, &conn->send_array, &dt); pthread_mutex_unlock(&conn->mutex); if (packet_num == -1) { @@ -1164,12 +1169,12 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, data, length) == 0) { Packet_Data *dt1 = nullptr; - if (get_data_pointer(&conn->send_array, &dt1, packet_num) == 1) { + if (get_data_pointer(c->log, &conn->send_array, &dt1, packet_num) == 1) { dt1->sent_time = current_time_monotonic(); } } else { conn->maximum_speed_reached = 1; - LOGGER_ERROR(c->log, "send_data_packet failed\n"); + LOGGER_ERROR(c->log, "send_data_packet failed"); } return packet_num; @@ -1197,7 +1202,9 @@ static uint16_t get_nonce_uint16(const uint8_t *nonce) static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint8_t *data, const uint8_t *packet, uint16_t length) { - if (length <= (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE) || length > MAX_CRYPTO_PACKET_SIZE) { + const uint16_t crypto_packet_overhead = 1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE; + + if (length <= crypto_packet_overhead || length > MAX_CRYPTO_PACKET_SIZE) { return -1; } @@ -1211,14 +1218,13 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint memcpy(nonce, conn->recv_nonce, CRYPTO_NONCE_SIZE); uint16_t num_cur_nonce = get_nonce_uint16(nonce); uint16_t num; - memcpy(&num, packet + 1, sizeof(uint16_t)); - num = net_ntohs(num); + net_unpack_u16(packet + 1, &num); uint16_t diff = num - num_cur_nonce; increment_nonce_number(nonce, diff); int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data); - if ((unsigned int)len != length - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE)) { + if ((unsigned int)len != length - crypto_packet_overhead) { return -1; } @@ -1243,7 +1249,7 @@ static int send_request_packet(Net_Crypto *c, int crypt_connection_id) } uint8_t data[MAX_CRYPTO_DATA_SIZE]; - int len = generate_request_packet(data, sizeof(data), &conn->recv_array); + int len = generate_request_packet(c->log, data, sizeof(data), &conn->recv_array); if (len == -1) { return -1; @@ -1270,13 +1276,13 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32 return -1; } - uint64_t temp_time = current_time_monotonic(); + const uint64_t temp_time = current_time_monotonic(); uint32_t i, num_sent = 0, array_size = num_packets_array(&conn->send_array); for (i = 0; i < array_size; ++i) { Packet_Data *dt; - uint32_t packet_num = (i + conn->send_array.buffer_start); - int ret = get_data_pointer(&conn->send_array, &dt, packet_num); + const uint32_t packet_num = i + conn->send_array.buffer_start; + const int ret = get_data_pointer(c->log, &conn->send_array, &dt, packet_num); if (ret == -1) { return -1; @@ -1491,11 +1497,11 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (buffer_start != conn->send_array.buffer_start) { Packet_Data *packet_time; - if (get_data_pointer(&conn->send_array, &packet_time, conn->send_array.buffer_start) == 1) { + if (get_data_pointer(c->log, &conn->send_array, &packet_time, conn->send_array.buffer_start) == 1) { rtt_calc_time = packet_time->sent_time; } - if (clear_buffer_until(&conn->send_array, buffer_start) != 0) { + if (clear_buffer_until(c->log, &conn->send_array, buffer_start) != 0) { return -1; } } @@ -1536,25 +1542,25 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const rtt_time = DEFAULT_TCP_PING_CONNECTION; } - int requested = handle_request_packet(&conn->send_array, real_data, real_length, &rtt_calc_time, rtt_time); + int requested = handle_request_packet(c->log, &conn->send_array, real_data, real_length, &rtt_calc_time, rtt_time); if (requested == -1) { return -1; } - set_buffer_end(&conn->recv_array, num); + set_buffer_end(c->log, &conn->recv_array, num); } else if (real_data[0] >= CRYPTO_RESERVED_PACKETS && real_data[0] < PACKET_ID_LOSSY_RANGE_START) { - Packet_Data dt; + Packet_Data dt = {0}; dt.length = real_length; memcpy(dt.data, real_data, real_length); - if (add_data_to_buffer(&conn->recv_array, num, &dt) != 0) { + if (add_data_to_buffer(c->log, &conn->recv_array, num, &dt) != 0) { return -1; } while (1) { pthread_mutex_lock(&conn->mutex); - int ret = read_data_beg_buffer(&conn->recv_array, &dt); + int ret = read_data_beg_buffer(c->log, &conn->recv_array, &dt); pthread_mutex_unlock(&conn->mutex); if (ret == -1) { @@ -1579,7 +1585,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const } else if (real_data[0] >= PACKET_ID_LOSSY_RANGE_START && real_data[0] < (PACKET_ID_LOSSY_RANGE_START + PACKET_ID_LOSSY_RANGE_SIZE)) { - set_buffer_end(&conn->recv_array, num); + set_buffer_end(c->log, &conn->recv_array, num); if (conn->connection_lossy_data_callback) { conn->connection_lossy_data_callback(conn->connection_lossy_data_callback_object, @@ -1627,7 +1633,7 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons uint8_t cookie[COOKIE_LENGTH]; uint64_t number; - if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) { + if (handle_cookie_response(c->log, cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) { return -1; } @@ -1644,45 +1650,46 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons } case NET_PACKET_CRYPTO_HS: { - if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT - || conn->status == CRYPTO_CONN_NOT_CONFIRMED) { - uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t cookie[COOKIE_LENGTH]; - - if (handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, - packet, length, conn->public_key) != 0) { - return -1; - } + if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING + && conn->status != CRYPTO_CONN_HANDSHAKE_SENT + && conn->status != CRYPTO_CONN_NOT_CONFIRMED) { + return -1; + } - if (public_key_cmp(dht_public_key, conn->dht_public_key) == 0) { - encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t cookie[COOKIE_LENGTH]; - if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { - if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { - return -1; - } - } + if (handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + packet, length, conn->public_key) != 0) { + return -1; + } - conn->status = CRYPTO_CONN_NOT_CONFIRMED; - } else { - if (conn->dht_pk_callback) { - conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key, userdata); + if (public_key_cmp(dht_public_key, conn->dht_public_key) == 0) { + encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + + if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { + if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { + return -1; } } + + conn->status = CRYPTO_CONN_NOT_CONFIRMED; } else { - return -1; + if (conn->dht_pk_callback) { + conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key, userdata); + } } return 0; } case NET_PACKET_CRYPTO_DATA: { - if (conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) { - return handle_data_packet_core(c, crypt_connection_id, packet, length, udp, userdata); + if (conn->status != CRYPTO_CONN_NOT_CONFIRMED && conn->status != CRYPTO_CONN_ESTABLISHED) { + return -1; } - return -1; + return handle_data_packet_core(c, crypt_connection_id, packet, length, udp, userdata); } default: { @@ -1723,9 +1730,7 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) */ static int create_crypto_connection(Net_Crypto *c) { - uint32_t i; - - for (i = 0; i < c->crypto_connections_length; ++i) { + for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) { return i; } @@ -1805,9 +1810,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) */ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key) { - uint32_t i; - - for (i = 0; i < c->crypto_connections_length; ++i) { + for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION) { if (public_key_cmp(public_key, c->crypto_connections[i].public_key) == 0) { return i; @@ -1833,12 +1836,12 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, return -1; } - if (source.ip.family == TOX_AF_INET || source.ip.family == TOX_AF_INET6) { + if (net_family_is_ipv4(source.ip.family) || net_family_is_ipv6(source.ip.family)) { if (add_ip_port_connection(c, crypt_connection_id, source) != 0) { return -1; } - if (source.ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(source.ip.family)) { conn->direct_lastrecv_timev4 = unix_time(); } else { conn->direct_lastrecv_timev6 = unix_time(); @@ -1847,7 +1850,7 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, return 0; } - if (source.ip.family == TCP_FAMILY) { + if (net_family_is_tcp_family(source.ip.family)) { if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip.v6.uint32[0]) == 0) { return 1; } @@ -1863,8 +1866,7 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, * * n_c is only valid for the duration of the function call. */ -void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c), - void *object) +void new_connection_handler(Net_Crypto *c, new_connection_cb *new_connection_callback, void *object) { c->new_connection_callback = new_connection_callback; c->new_connection_callback_object = object; @@ -1895,31 +1897,37 @@ static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, const return -1; } - int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); + const int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); if (crypt_connection_id != -1) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + if (conn == nullptr) { + return -1; + } + if (public_key_cmp(n_c.dht_public_key, conn->dht_public_key) != 0) { connection_kill(c, crypt_connection_id, userdata); } else { - int ret = -1; + if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { + free(n_c.cookie); + return -1; + } - if (conn && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) { - memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); - memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); - encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); + memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); + encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); - crypto_connection_add_source(c, crypt_connection_id, source); + crypto_connection_add_source(c, crypt_connection_id, source); - if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) { - conn->status = CRYPTO_CONN_NOT_CONFIRMED; - ret = 0; - } + if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) { + free(n_c.cookie); + return -1; } + conn->status = CRYPTO_CONN_NOT_CONFIRMED; free(n_c.cookie); - return ret; + return 0; } } @@ -1939,9 +1947,10 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) return -1; } - int crypt_connection_id = create_crypto_connection(c); + const int crypt_connection_id = create_crypto_connection(c); if (crypt_connection_id == -1) { + LOGGER_ERROR(c->log, "Could not create new crypto connection"); return -1; } @@ -1952,7 +1961,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) } pthread_mutex_lock(&c->tcp_mutex); - int connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->dht_public_key, crypt_connection_id); + const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->dht_public_key, crypt_connection_id); pthread_mutex_unlock(&c->tcp_mutex); if (connection_number_tcp == -1) { @@ -2007,12 +2016,8 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; - if (conn == nullptr) { - return -1; - } - pthread_mutex_lock(&c->tcp_mutex); - int connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id); + const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id); pthread_mutex_unlock(&c->tcp_mutex); if (connection_number_tcp == -1) { @@ -2061,37 +2066,32 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, return -1; } - if (add_ip_port_connection(c, crypt_connection_id, ip_port) == 0) { - if (connected) { - if (ip_port.ip.family == TOX_AF_INET) { - conn->direct_lastrecv_timev4 = unix_time(); - } else { - conn->direct_lastrecv_timev6 = unix_time(); - } - } else { - if (ip_port.ip.family == TOX_AF_INET) { - conn->direct_lastrecv_timev4 = 0; - } else { - conn->direct_lastrecv_timev6 = 0; - } - } + if (add_ip_port_connection(c, crypt_connection_id, ip_port) != 0) { + return -1; + } - return 0; + const uint64_t direct_lastrecv_time = connected ? unix_time() : 0; + + if (net_family_is_ipv4(ip_port.ip.family)) { + conn->direct_lastrecv_timev4 = direct_lastrecv_time; + } else { + conn->direct_lastrecv_timev6 = direct_lastrecv_time; } - return -1; + return 0; } -static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t length, void *userdata) +static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_t *data, uint16_t length, + void *userdata) { + Net_Crypto *c = (Net_Crypto *)object; + if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; } - Net_Crypto *c = (Net_Crypto *)object; - - Crypto_Connection *conn = get_crypto_connection(c, id); + Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { return -1; @@ -2104,7 +2104,7 @@ static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t // This unlocks the mutex that at this point is locked by do_tcp before // calling do_tcp_connections. pthread_mutex_unlock(&c->tcp_mutex); - int ret = handle_packet_connection(c, id, data, length, 0, userdata); + int ret = handle_packet_connection(c, crypt_connection_id, data, length, 0, userdata); pthread_mutex_lock(&c->tcp_mutex); if (ret != 0) { @@ -2118,12 +2118,12 @@ static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length, void *userdata) { + Net_Crypto *c = (Net_Crypto *)object; + if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; } - Net_Crypto *c = (Net_Crypto *)object; - if (data[0] == NET_PACKET_COOKIE_REQUEST) { return tcp_oob_handle_cookie_request(c, tcp_connections_number, public_key, data, length); } @@ -2131,7 +2131,7 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in if (data[0] == NET_PACKET_CRYPTO_HS) { IP_Port source; source.port = 0; - source.ip.family = TCP_FAMILY; + source.ip.family = net_family_tcp_family; source.ip.ip.v6.uint32[0] = tcp_connections_number; if (handle_new_connection_handshake(c, source, data, length, userdata) != 0) { @@ -2238,7 +2238,7 @@ static void do_tcp(Net_Crypto *c, void *userdata) Crypto_Connection *conn = get_crypto_connection(c, i); if (conn == nullptr) { - return; + continue; } if (conn->status == CRYPTO_CONN_ESTABLISHED) { @@ -2269,7 +2269,7 @@ static void do_tcp(Net_Crypto *c, void *userdata) * return 0 on success. */ int connection_status_handler(const Net_Crypto *c, int crypt_connection_id, - int (*connection_status_callback)(void *object, int id, uint8_t status, void *userdata), void *object, int id) + connection_status_cb *connection_status_callback, void *object, int id) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2291,8 +2291,8 @@ int connection_status_handler(const Net_Crypto *c, int crypt_connection_id, * return -1 on failure. * return 0 on success. */ -int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object, - int id, const uint8_t *data, uint16_t length, void *userdata), void *object, int id) +int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, + connection_data_cb *connection_data_callback, void *object, int id) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2315,7 +2315,7 @@ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, int (* * return 0 on success. */ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, - int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata), + connection_lossy_data_cb *connection_lossy_data_callback, void *object, int id) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2341,8 +2341,7 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, * return -1 on failure. * return 0 on success. */ -int nc_dht_pk_callback(Net_Crypto *c, int crypt_connection_id, void (*function)(void *data, int32_t number, - const uint8_t *dht_public_key, void *userdata), void *object, uint32_t number) +int nc_dht_pk_callback(Net_Crypto *c, int crypt_connection_id, dht_pk_cb *function, void *object, uint32_t number) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2378,12 +2377,13 @@ static int crypto_id_ip_port(const Net_Crypto *c, IP_Port ip_port) */ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata) { + Net_Crypto *c = (Net_Crypto *)object; + if (length <= CRYPTO_MIN_PACKET_SIZE || length > MAX_CRYPTO_PACKET_SIZE) { return 1; } - Net_Crypto *c = (Net_Crypto *)object; - int crypt_connection_id = crypto_id_ip_port(c, source); + const int crypt_connection_id = crypto_id_ip_port(c, source); if (crypt_connection_id == -1) { if (packet[0] != NET_PACKET_CRYPTO_HS) { @@ -2409,7 +2409,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet pthread_mutex_lock(&conn->mutex); - if (source.ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(source.ip.family)) { conn->direct_lastrecv_timev4 = unix_time(); } else { conn->direct_lastrecv_timev6 = unix_time(); @@ -2439,24 +2439,23 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet static void send_crypto_packets(Net_Crypto *c) { - uint32_t i; - uint64_t temp_time = current_time_monotonic(); + const uint64_t temp_time = current_time_monotonic(); double total_send_rate = 0; uint32_t peak_request_packet_interval = ~0; - for (i = 0; i < c->crypto_connections_length; ++i) { + for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { Crypto_Connection *conn = get_crypto_connection(c, i); if (conn == nullptr) { - return; + continue; } - if (CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time < temp_time) { + if ((CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time) < temp_time) { send_temp_packet(c, i); } if ((conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) - && ((CRYPTO_SEND_PACKET_INTERVAL) + conn->last_request_packet_sent) < temp_time) { + && (CRYPTO_SEND_PACKET_INTERVAL + conn->last_request_packet_sent) < temp_time) { if (send_request_packet(c, i) == 0) { conn->last_request_packet_sent = temp_time; } @@ -2494,8 +2493,7 @@ static void send_crypto_packets(Net_Crypto *c) } if ((PACKET_COUNTER_AVERAGE_INTERVAL + conn->packet_counter_set) < temp_time) { - - double dt = temp_time - conn->packet_counter_set; + const double dt = temp_time - conn->packet_counter_set; conn->packet_recv_rate = (double)conn->packet_counter / (dt / 1000.0); conn->packet_counter = 0; @@ -2526,9 +2524,8 @@ static void send_crypto_packets(Net_Crypto *c) bool direct_connected = 0; crypto_connection_status(c, i, &direct_connected, nullptr); - if (direct_connected && conn->last_tcp_sent + CONGESTION_EVENT_TIMEOUT > temp_time) { - /* When switching from TCP to UDP, don't change the packet send rate for CONGESTION_EVENT_TIMEOUT ms. */ - } else { + /* When switching from TCP to UDP, don't change the packet send rate for CONGESTION_EVENT_TIMEOUT ms. */ + if (!(direct_connected && conn->last_tcp_sent + CONGESTION_EVENT_TIMEOUT > temp_time)) { long signed int total_sent = 0, total_resent = 0; // TODO(irungentoo): use real delay @@ -2589,8 +2586,10 @@ static void send_crypto_packets(Net_Crypto *c) } if (conn->last_packets_left_set == 0 || conn->last_packets_left_requested_set == 0) { - conn->last_packets_left_requested_set = conn->last_packets_left_set = temp_time; - conn->packets_left_requested = conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; + conn->last_packets_left_requested_set = temp_time; + conn->last_packets_left_set = temp_time; + conn->packets_left_requested = CRYPTO_MIN_QUEUE_LENGTH; + conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; } else { if (((uint64_t)((1000.0 / conn->packet_send_rate) + 0.5) + conn->last_packets_left_set) <= temp_time) { double n_packets = conn->packet_send_rate * (((double)(temp_time - conn->last_packets_left_set)) / 1000.0); @@ -2743,7 +2742,7 @@ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t if (congestion_control) { --conn->packets_left; --conn->packets_left_requested; - conn->packets_sent++; + ++conn->packets_sent; } return ret; @@ -2758,7 +2757,7 @@ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t * * Note: The condition `buffer_end - buffer_start < packet_number - buffer_start` is * a trick which handles situations `buffer_end >= buffer_start` and - * `buffer_end < buffer_start`(when buffer_end overflowed) both correctly + * `buffer_end < buffer_start` (when buffer_end overflowed) both correctly. * * It CANNOT be simplified to `packet_number < buffer_start`, as it will fail * when `buffer_end < buffer_start`. @@ -2771,14 +2770,14 @@ int cryptpacket_received(Net_Crypto *c, int crypt_connection_id, uint32_t packet return -1; } - uint32_t num = conn->send_array.buffer_end - conn->send_array.buffer_start; + uint32_t num = num_packets_array(&conn->send_array); uint32_t num1 = packet_number - conn->send_array.buffer_start; - if (num < num1) { - return 0; + if (num >= num1) { + return -1; } - return -1; + return 0; } /* return -1 on failure. @@ -2796,7 +2795,7 @@ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t return -1; } - if (data[0] >= (PACKET_ID_LOSSY_RANGE_START + PACKET_ID_LOSSY_RANGE_SIZE)) { + if (data[0] >= PACKET_ID_LOSSY_RANGE_START + PACKET_ID_LOSSY_RANGE_SIZE) { return -1; } @@ -2871,8 +2870,8 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. * sets online_tcp_relays to the number of connected tcp relays this connection has. */ -unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, - unsigned int *online_tcp_relays) +Crypto_Conn_State crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, + unsigned int *online_tcp_relays) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2929,7 +2928,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk) /* Run this to (re)initialize net_crypto. * Sets all the global connection variables to their default values. */ -Net_Crypto *new_net_crypto(Logger *log, DHT *dht, TCP_Proxy_Info *proxy_info) +Net_Crypto *new_net_crypto(const Logger *log, DHT *dht, TCP_Proxy_Info *proxy_info) { unix_time_update(); @@ -2981,14 +2980,11 @@ Net_Crypto *new_net_crypto(Logger *log, DHT *dht, TCP_Proxy_Info *proxy_info) static void kill_timedout(Net_Crypto *c, void *userdata) { - uint32_t i; - //uint64_t temp_time = current_time_monotonic(); - - for (i = 0; i < c->crypto_connections_length; ++i) { + for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { Crypto_Connection *conn = get_crypto_connection(c, i); if (conn == nullptr) { - return; + continue; } if (conn->status == CRYPTO_CONN_NO_CONNECTION) { @@ -3008,6 +3004,7 @@ static void kill_timedout(Net_Crypto *c, void *userdata) if (conn->status == CRYPTO_CONN_ESTABLISHED) { // TODO(irungentoo): add a timeout here? + do_timeout_here(); } #endif diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.h b/protocols/Tox/libtox/src/toxcore/net_crypto.h index bd00a3fe33..2ed35883d3 100644 --- a/protocols/Tox/libtox/src/toxcore/net_crypto.h +++ b/protocols/Tox/libtox/src/toxcore/net_crypto.h @@ -31,11 +31,13 @@ #include <pthread.h> -#define CRYPTO_CONN_NO_CONNECTION 0 -#define CRYPTO_CONN_COOKIE_REQUESTING 1 //send cookie request packets -#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets -#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets, we have received one from the other -#define CRYPTO_CONN_ESTABLISHED 4 +typedef enum Crypto_Conn_State { + CRYPTO_CONN_NO_CONNECTION = 0, + CRYPTO_CONN_COOKIE_REQUESTING = 1, // send cookie request packets + CRYPTO_CONN_HANDSHAKE_SENT = 2, // send handshake packets + CRYPTO_CONN_NOT_CONFIRMED = 3, // send handshake packets, we have received one from the other + CRYPTO_CONN_ESTABLISHED = 4, +} Crypto_Conn_State; /* Maximum size of receiving and sending packet buffers. */ #define CRYPTO_PACKET_BUFFER_SIZE 32768 /* Must be a power of 2 */ @@ -47,12 +49,12 @@ #define CRYPTO_MIN_QUEUE_LENGTH 64 /* Maximum total size of packets that net_crypto sends. */ -#define MAX_CRYPTO_PACKET_SIZE 1400 +#define MAX_CRYPTO_PACKET_SIZE (uint16_t)1400 -#define CRYPTO_DATA_PACKET_MIN_SIZE (1 + sizeof(uint16_t) + (sizeof(uint32_t) + sizeof(uint32_t)) + CRYPTO_MAC_SIZE) +#define CRYPTO_DATA_PACKET_MIN_SIZE (uint16_t)(1 + sizeof(uint16_t) + (sizeof(uint32_t) + sizeof(uint32_t)) + CRYPTO_MAC_SIZE) /* Max size of data in packets */ -#define MAX_CRYPTO_DATA_SIZE (MAX_CRYPTO_PACKET_SIZE - CRYPTO_DATA_PACKET_MIN_SIZE) +#define MAX_CRYPTO_DATA_SIZE (uint16_t)(MAX_CRYPTO_PACKET_SIZE - CRYPTO_DATA_PACKET_MIN_SIZE) /* Interval in ms between sending cookie request/handshake packets. */ #define CRYPTO_SEND_PACKET_INTERVAL 1000 @@ -62,7 +64,7 @@ #define MAX_NUM_SENDPACKET_TRIES 8 /* The timeout of no received UDP packets before the direct UDP connection is considered dead. */ -#define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 1000) +#define UDP_DIRECT_TIMEOUT 8 #define PACKET_ID_PADDING 0 /* Denotes padding */ #define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */ @@ -106,14 +108,19 @@ typedef struct New_Connection { uint8_t cookie_length; } New_Connection; +typedef int connection_status_cb(void *object, int id, uint8_t status, void *userdata); +typedef int connection_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); +typedef int connection_lossy_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); +typedef void dht_pk_cb(void *data, int32_t number, const uint8_t *dht_public_key, void *userdata); +typedef int new_connection_cb(void *object, New_Connection *n_c); + /* Set function to be called when someone requests a new connection to us. * * The set function should return -1 on failure and 0 on success. * * n_c is only valid for the duration of the function call. */ -void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c), - void *object); +void new_connection_handler(Net_Crypto *c, new_connection_cb *new_connection_callback, void *object); /* Accept a crypto connection. * @@ -150,7 +157,7 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, * return 0 on success. */ int connection_status_handler(const Net_Crypto *c, int crypt_connection_id, - int (*connection_status_callback)(void *object, int id, uint8_t status, void *userdata), void *object, int id); + connection_status_cb *connection_status_callback, void *object, int id); /* Set function to be called when connection with crypt_connection_id receives a lossless data packet of length. * @@ -160,8 +167,8 @@ int connection_status_handler(const Net_Crypto *c, int crypt_connection_id, * return -1 on failure. * return 0 on success. */ -int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object, - int id, const uint8_t *data, uint16_t length, void *userdata), void *object, int id); +int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, + connection_data_cb *connection_data_callback, void *object, int id); /* Set function to be called when connection with crypt_connection_id receives a lossy data packet of length. @@ -173,9 +180,7 @@ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, int (* * return 0 on success. */ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, - int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata), - void *object, - int id); + connection_lossy_data_cb *connection_lossy_data_callback, void *object, int id); /* Set the function for this friend that will be callbacked with object and number if * the friend sends us a different dht public key than we have associated to him. @@ -187,8 +192,7 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, * return -1 on failure. * return 0 on success. */ -int nc_dht_pk_callback(Net_Crypto *c, int crypt_connection_id, void (*function)(void *data, int32_t number, - const uint8_t *dht_public_key, void *userdata), void *object, uint32_t number); +int nc_dht_pk_callback(Net_Crypto *c, int crypt_connection_id, dht_pk_cb *function, void *object, uint32_t number); /* returns the number of packet slots left in the sendbuffer. * return 0 if failure. @@ -276,8 +280,8 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id); * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. * sets online_tcp_relays to the number of connected tcp relays this connection has. */ -unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, - unsigned int *online_tcp_relays); +Crypto_Conn_State crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, + unsigned int *online_tcp_relays); /* Generate our public and private keys. * Only call this function the first time the program starts. @@ -297,7 +301,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk); /* Create new instance of Net_Crypto. * Sets all the global connection variables to their default values. */ -Net_Crypto *new_net_crypto(Logger *log, DHT *dht, TCP_Proxy_Info *proxy_info); +Net_Crypto *new_net_crypto(const Logger *log, DHT *dht, TCP_Proxy_Info *proxy_info); /* return the optimal interval in ms for running do_net_crypto. */ diff --git a/protocols/Tox/libtox/src/toxcore/network.c b/protocols/Tox/libtox/src/toxcore/network.c index 984071d4e3..3c262bab89 100644 --- a/protocols/Tox/libtox/src/toxcore/network.c +++ b/protocols/Tox/libtox/src/toxcore/network.c @@ -30,7 +30,7 @@ #endif #ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 600 +#define _XOPEN_SOURCE 700 #endif #if defined(_WIN32) && _WIN32_WINNT >= _WIN32_WINNT_WINXP @@ -38,44 +38,65 @@ #define _WIN32_WINNT 0x501 #endif -#include "network.h" +#if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) +#define OS_WIN32 +#endif -#include "logger.h" -#include "util.h" +#ifdef OS_WIN32 +#ifndef WINVER +// Windows XP +#define WINVER 0x0501 +#endif +#endif -#include <assert.h> -#ifdef __APPLE__ -#include <mach/clock.h> -#include <mach/mach.h> +#ifdef PLAN9 +#include <u.h> // Plan 9 requires this is imported first +// Comment line here to avoid reordering by source code formatters. +#include <libc.h> #endif -#ifndef IPV6_ADD_MEMBERSHIP -#ifdef IPV6_JOIN_GROUP -#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +#ifdef OS_WIN32 /* Put win32 includes here */ +// The mingw32/64 Windows library warns about including winsock2.h after +// windows.h even though with the above it's a valid thing to do. So, to make +// mingw32 headers happy, we include winsock2.h first. +#include <winsock2.h> +// Comment line here to avoid reordering by source code formatters. +#include <windows.h> +#include <ws2tcpip.h> #endif + +#include "network.h" + +#ifdef __APPLE__ +#include <mach/clock.h> +#include <mach/mach.h> #endif -#if !(defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) +#if !defined(OS_WIN32) +#include <arpa/inet.h> #include <errno.h> #include <fcntl.h> #include <netdb.h> +#include <netinet/in.h> +#include <sys/ioctl.h> +#include <sys/socket.h> #include <sys/time.h> #include <sys/types.h> +#include <unistd.h> #define TOX_EWOULDBLOCK EWOULDBLOCK #else - #ifndef IPV6_V6ONLY #define IPV6_V6ONLY 27 #endif #define TOX_EWOULDBLOCK WSAEWOULDBLOCK -static const char *inet_ntop(Family family, const void *addr, char *buf, size_t bufsize) +static const char *inet_ntop(int family, const void *addr, char *buf, size_t bufsize) { - if (family == TOX_AF_INET) { + if (family == AF_INET) { struct sockaddr_in saddr; memset(&saddr, 0, sizeof(saddr)); @@ -89,7 +110,7 @@ static const char *inet_ntop(Family family, const void *addr, char *buf, size_t } return buf; - } else if (family == TOX_AF_INET6) { + } else if (family == AF_INET6) { struct sockaddr_in6 saddr; memset(&saddr, 0, sizeof(saddr)); @@ -108,9 +129,9 @@ static const char *inet_ntop(Family family, const void *addr, char *buf, size_t return nullptr; } -static int inet_pton(Family family, const char *addrString, void *addrbuf) +static int inet_pton(int family, const char *addrString, void *addrbuf) { - if (family == TOX_AF_INET) { + if (family == AF_INET) { struct sockaddr_in saddr; memset(&saddr, 0, sizeof(saddr)); @@ -123,7 +144,7 @@ static int inet_pton(Family family, const char *addrString, void *addrbuf) *(struct in_addr *)addrbuf = saddr.sin_addr; return 1; - } else if (family == TOX_AF_INET6) { + } else if (family == AF_INET6) { struct sockaddr_in6 saddr; memset(&saddr, 0, sizeof(saddr)); @@ -143,18 +164,70 @@ static int inet_pton(Family family, const char *addrString, void *addrbuf) #endif +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "logger.h" +#include "mono_time.h" +#include "util.h" + +// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD +#if !defined(MSG_NOSIGNAL) +#define MSG_NOSIGNAL 0 +#endif + +#ifndef IPV6_ADD_MEMBERSHIP +#ifdef IPV6_JOIN_GROUP +#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +#endif +#endif + #if TOX_INET6_ADDRSTRLEN < INET6_ADDRSTRLEN -#error TOX_INET6_ADDRSTRLEN should be greater or equal to INET6_ADDRSTRLEN (#INET6_ADDRSTRLEN) +#error "TOX_INET6_ADDRSTRLEN should be greater or equal to INET6_ADDRSTRLEN (#INET6_ADDRSTRLEN)" #endif #if TOX_INET_ADDRSTRLEN < INET_ADDRSTRLEN -#error TOX_INET_ADDRSTRLEN should be greater or equal to INET_ADDRSTRLEN (#INET_ADDRSTRLEN) +#error "TOX_INET_ADDRSTRLEN should be greater or equal to INET_ADDRSTRLEN (#INET_ADDRSTRLEN)" #endif static int make_proto(int proto); static int make_socktype(int type); -static int make_family(int tox_family); -static int make_tox_family(int family); + +static int make_family(Family tox_family) +{ + switch (tox_family.value) { + case TOX_AF_INET: + return AF_INET; + + case TOX_AF_INET6: + return AF_INET6; + + case TOX_AF_UNSPEC: + return AF_UNSPEC; + + default: + return tox_family.value; + } +} + +static const Family *make_tox_family(int family) +{ + switch (family) { + case AF_INET: + return &net_family_ipv4; + + case AF_INET6: + return &net_family_ipv6; + + case AF_UNSPEC: + return &net_family_unspec; + + default: + return nullptr; + } +} static void get_ip4(IP4 *result, const struct in_addr *addr) { @@ -182,8 +255,8 @@ static void fill_addr6(IP6 ip, struct in6_addr *addr) #define INADDR_LOOPBACK 0x7f000001 #endif -const IP4 IP4_BROADCAST = { INADDR_BROADCAST }; -const IP6 IP6_BROADCAST = { +const IP4 ip4_broadcast = { INADDR_BROADCAST }; +const IP6 ip6_broadcast = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; @@ -201,6 +274,67 @@ IP6 get_ip6_loopback(void) return loopback; } +#ifndef OS_WIN32 +#define INVALID_SOCKET -1 +#endif + +const Socket net_invalid_socket = { (int)INVALID_SOCKET }; + +const Family net_family_unspec = {TOX_AF_UNSPEC}; +const Family net_family_ipv4 = {TOX_AF_INET}; +const Family net_family_ipv6 = {TOX_AF_INET6}; +const Family net_family_tcp_family = {TCP_FAMILY}; +const Family net_family_tcp_onion = {TCP_ONION_FAMILY}; +const Family net_family_tcp_ipv4 = {TCP_INET}; +const Family net_family_tcp_ipv6 = {TCP_INET6}; +const Family net_family_tox_tcp_ipv4 = {TOX_TCP_INET}; +const Family net_family_tox_tcp_ipv6 = {TOX_TCP_INET6}; + +bool net_family_is_unspec(Family family) +{ + return family.value == net_family_unspec.value; +} + +bool net_family_is_ipv4(Family family) +{ + return family.value == net_family_ipv4.value; +} + +bool net_family_is_ipv6(Family family) +{ + return family.value == net_family_ipv6.value; +} + +bool net_family_is_tcp_family(Family family) +{ + return family.value == net_family_tcp_family.value; +} + +bool net_family_is_tcp_onion(Family family) +{ + return family.value == net_family_tcp_onion.value; +} + +bool net_family_is_tcp_ipv4(Family family) +{ + return family.value == net_family_tcp_ipv4.value; +} + +bool net_family_is_tcp_ipv6(Family family) +{ + return family.value == net_family_tcp_ipv6.value; +} + +bool net_family_is_tox_tcp_ipv4(Family family) +{ + return family.value == net_family_tox_tcp_ipv4.value; +} + +bool net_family_is_tox_tcp_ipv6(Family family) +{ + return family.value == net_family_tox_tcp_ipv6.value; +} + /* Check if socket is valid. * * return 1 if valid @@ -208,27 +342,17 @@ IP6 get_ip6_loopback(void) */ int sock_valid(Socket sock) { -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) - - if (sock == INVALID_SOCKET) { -#else - - if (sock < 0) { -#endif - return 0; - } - - return 1; + return sock.socket != net_invalid_socket.socket; } /* Close the socket. */ void kill_sock(Socket sock) { -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) - closesocket(sock); +#ifdef OS_WIN32 + closesocket(sock.socket); #else - close(sock); + close(sock.socket); #endif } @@ -239,11 +363,11 @@ void kill_sock(Socket sock) */ int set_socket_nonblock(Socket sock) { -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) +#ifdef OS_WIN32 u_long mode = 1; - return (ioctlsocket(sock, FIONBIO, &mode) == 0); + return (ioctlsocket(sock.socket, FIONBIO, &mode) == 0); #else - return (fcntl(sock, F_SETFL, O_NONBLOCK, 1) == 0); + return (fcntl(sock.socket, F_SETFL, O_NONBLOCK, 1) == 0); #endif } @@ -254,9 +378,9 @@ int set_socket_nonblock(Socket sock) */ int set_socket_nosigpipe(Socket sock) { -#if defined(__MACH__) +#if defined(__APPLE__) int set = 1; - return (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (const char *)&set, sizeof(int)) == 0); + return setsockopt(sock.socket, SOL_SOCKET, SO_NOSIGPIPE, (const char *)&set, sizeof(int)) == 0; #else return 1; #endif @@ -270,7 +394,7 @@ int set_socket_nosigpipe(Socket sock) int set_socket_reuseaddr(Socket sock) { int set = 1; - return (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&set, sizeof(set)) == 0); + return setsockopt(sock.socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&set, sizeof(set)) == 0; } /* Set socket to dual (IPv4 + IPv6 socket) @@ -282,95 +406,32 @@ int set_socket_dualstack(Socket sock) { int ipv6only = 0; socklen_t optsize = sizeof(ipv6only); - int res = getsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, &optsize); + int res = getsockopt(sock.socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, &optsize); if ((res == 0) && (ipv6only == 0)) { return 1; } ipv6only = 0; - return (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&ipv6only, sizeof(ipv6only)) == 0); -} - - -/* return current UNIX time in microseconds (us). */ -static uint64_t current_time_actual(void) -{ - uint64_t time; -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) - /* This probably works fine */ - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - time = ft.dwHighDateTime; - time <<= 32; - time |= ft.dwLowDateTime; - time -= 116444736000000000ULL; - return time / 10; -#else - struct timeval a; - gettimeofday(&a, nullptr); - time = 1000000ULL * a.tv_sec + a.tv_usec; - return time; -#endif + return setsockopt(sock.socket, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&ipv6only, sizeof(ipv6only)) == 0; } -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) -static uint64_t last_monotime; -static uint64_t add_monotime; -#endif - -/* return current monotonic time in milliseconds (ms). */ -uint64_t current_time_monotonic(void) -{ - uint64_t time; -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) - uint64_t old_add_monotime = add_monotime; - time = (uint64_t)GetTickCount() + add_monotime; - - /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race - * conditions when multiple threads call this function at once */ - if (time + 0x10000 < last_monotime) { - uint32_t add = ~0; - /* use old_add_monotime rather than simply incrementing add_monotime, to handle the case that many threads - * simultaneously detect an overflow */ - add_monotime = old_add_monotime + add; - time += add; - } - - last_monotime = time; -#else - struct timespec monotime; -#if defined(__linux__) && defined(CLOCK_MONOTONIC_RAW) - clock_gettime(CLOCK_MONOTONIC_RAW, &monotime); -#elif defined(__APPLE__) - clock_serv_t muhclock; - mach_timespec_t machtime; - - host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock); - clock_get_time(muhclock, &machtime); - mach_port_deallocate(mach_task_self(), muhclock); - - monotime.tv_sec = machtime.tv_sec; - monotime.tv_nsec = machtime.tv_nsec; -#else - clock_gettime(CLOCK_MONOTONIC, &monotime); -#endif - time = 1000ULL * monotime.tv_sec + (monotime.tv_nsec / 1000000ULL); -#endif - return time; -} - static uint32_t data_0(uint16_t buflen, const uint8_t *buffer) { - return buflen > 4 ? net_ntohl(*(const uint32_t *)&buffer[1]) : 0; + // TODO(iphydf): Do this differently. Right now this is most likely a + // misaligned memory access in reality, and definitely undefined behaviour + // in terms of C standard. + const uint8_t *const start = buffer + 1; + return buflen > 4 ? net_ntohl(*(const uint32_t *)start) : 0; } static uint32_t data_1(uint16_t buflen, const uint8_t *buffer) { - return buflen > 7 ? net_ntohl(*(const uint32_t *)&buffer[5]) : 0; + const uint8_t *const start = buffer + 5; + return buflen > 7 ? net_ntohl(*(const uint32_t *)start) : 0; } -static void loglogdata(Logger *log, const char *message, const uint8_t *buffer, +static void loglogdata(const Logger *log, const char *message, const uint8_t *buffer, uint16_t buflen, IP_Port ip_port, int res) { char ip_str[IP_NTOA_LEN]; @@ -396,13 +457,13 @@ static void loglogdata(Logger *log, const char *message, const uint8_t *buffer, } } -typedef struct { - packet_handler_callback function; +typedef struct Packet_Handler { + packet_handler_cb *function; void *object; } Packet_Handler; struct Networking_Core { - Logger *log; + const Logger *log; Packet_Handler packethandlers[256]; Family family; @@ -426,20 +487,19 @@ uint16_t net_port(const Networking_Core *net) */ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length) { - if (net->family == TOX_AF_UNSPEC) { /* Socket not initialized */ + if (net_family_is_unspec(net->family)) { /* Socket not initialized */ + LOGGER_ERROR(net->log, "attempted to send message of length %u on uninitialised socket", (unsigned)length); return -1; } /* socket TOX_AF_INET, but target IP NOT: can't send */ - if ((net->family == TOX_AF_INET) && (ip_port.ip.family != TOX_AF_INET)) { + if (net_family_is_ipv4(net->family) && !net_family_is_ipv4(ip_port.ip.family)) { + LOGGER_ERROR(net->log, "attempted to send message with network family %d (probably IPv6) on IPv4 socket", + ip_port.ip.family.value); return -1; } - struct sockaddr_storage addr; - - size_t addrsize = 0; - - if (ip_port.ip.family == TOX_AF_INET && net->family == TOX_AF_INET6) { + if (net_family_is_ipv4(ip_port.ip.family) && net_family_is_ipv6(net->family)) { /* must convert to IPV4-in-IPV6 address */ IP6 ip6; @@ -450,33 +510,37 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1 ip6.uint32[2] = net_htonl(0xFFFF); ip6.uint32[3] = ip_port.ip.ip.v4.uint32; - ip_port.ip.family = TOX_AF_INET6; + ip_port.ip.family = net_family_ipv6; ip_port.ip.ip.v6 = ip6; } - if (ip_port.ip.family == TOX_AF_INET) { - struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; + struct sockaddr_storage addr; + + size_t addrsize; + + if (net_family_is_ipv4(ip_port.ip.family)) { + struct sockaddr_in *const addr4 = (struct sockaddr_in *)&addr; addrsize = sizeof(struct sockaddr_in); - fill_addr4(ip_port.ip.ip.v4, &addr4->sin_addr); addr4->sin_family = AF_INET; addr4->sin_port = ip_port.port; - } else if (ip_port.ip.family == TOX_AF_INET6) { - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; + fill_addr4(ip_port.ip.ip.v4, &addr4->sin_addr); + } else if (net_family_is_ipv6(ip_port.ip.family)) { + struct sockaddr_in6 *const addr6 = (struct sockaddr_in6 *)&addr; addrsize = sizeof(struct sockaddr_in6); - fill_addr6(ip_port.ip.ip.v6, &addr6->sin6_addr); addr6->sin6_family = AF_INET6; addr6->sin6_port = ip_port.port; + fill_addr6(ip_port.ip.ip.v6, &addr6->sin6_addr); addr6->sin6_flowinfo = 0; addr6->sin6_scope_id = 0; } else { - /* unknown address type*/ + LOGGER_WARNING(net->log, "unknown address type: %d", ip_port.ip.family.value); return -1; } - const int res = sendto(net->sock, (const char *) data, length, 0, (struct sockaddr *)&addr, addrsize); + const int res = sendto(net->sock.socket, (const char *)data, length, 0, (struct sockaddr *)&addr, addrsize); loglogdata(net->log, "O=>", data, length, ip_port, res); @@ -488,17 +552,17 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1 * Packet data is put into data. * Packet length is put into length. */ -static int receivepacket(Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) +static int receivepacket(const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) { memset(ip_port, 0, sizeof(IP_Port)); struct sockaddr_storage addr; -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) +#ifdef OS_WIN32 int addrlen = sizeof(addr); #else socklen_t addrlen = sizeof(addr); #endif *length = 0; - int fail_or_len = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); + int fail_or_len = recvfrom(sock.socket, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); if (fail_or_len < 0) { int error = net_error(); @@ -517,17 +581,31 @@ static int receivepacket(Logger *log, Socket sock, IP_Port *ip_port, uint8_t *da if (addr.ss_family == AF_INET) { struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; - ip_port->ip.family = make_tox_family(addr_in->sin_family); + const Family *const family = make_tox_family(addr_in->sin_family); + assert(family != nullptr); + + if (family == nullptr) { + return -1; + } + + ip_port->ip.family = *family; get_ip4(&ip_port->ip.ip.v4, &addr_in->sin_addr); ip_port->port = addr_in->sin_port; } else if (addr.ss_family == AF_INET6) { struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr; - ip_port->ip.family = make_tox_family(addr_in6->sin6_family); + const Family *const family = make_tox_family(addr_in6->sin6_family); + assert(family != nullptr); + + if (family == nullptr) { + return -1; + } + + ip_port->ip.family = *family; get_ip6(&ip_port->ip.ip.v6, &addr_in6->sin6_addr); ip_port->port = addr_in6->sin6_port; - if (IPV6_IPV4_IN_V6(ip_port->ip.ip.v6)) { - ip_port->ip.family = TOX_AF_INET; + if (ipv6_ipv4_in_v6(ip_port->ip.ip.v6)) { + ip_port->ip.family = net_family_ipv4; ip_port->ip.ip.v4.uint32 = ip_port->ip.ip.v6.uint32[3]; } } else { @@ -539,7 +617,7 @@ static int receivepacket(Logger *log, Socket sock, IP_Port *ip_port, uint8_t *da return 0; } -void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object) +void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_cb *cb, void *object) { net->packethandlers[byte].function = cb; net->packethandlers[byte].object = object; @@ -547,7 +625,8 @@ void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handl void networking_poll(Networking_Core *net, void *userdata) { - if (net->family == 0) { /* Socket not initialized */ + if (net_family_is_unspec(net->family)) { + /* Socket not initialized */ return; } @@ -576,7 +655,10 @@ void networking_poll(Networking_Core *net, void *userdata) #include <sodium.h> #endif +//!TOKSTYLE- +// Global mutable state is not allowed in Tokstyle. static uint8_t at_startup_ran = 0; +//!TOKSTYLE+ int networking_at_startup(void) { if (at_startup_ran != 0) { @@ -597,7 +679,7 @@ int networking_at_startup(void) #endif/*VANILLA_NACL*/ -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) +#ifdef OS_WIN32 WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { @@ -614,7 +696,7 @@ int networking_at_startup(void) #if 0 static void at_shutdown(void) { -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) +#ifdef OS_WIN32 WSACleanup(); #endif } @@ -623,7 +705,7 @@ static void at_shutdown(void) /* Initialize networking. * Added for reverse compatibility with old new_networking calls. */ -Networking_Core *new_networking(Logger *log, IP ip, uint16_t port) +Networking_Core *new_networking(const Logger *log, IP ip, uint16_t port) { return new_networking_ex(log, ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), nullptr); } @@ -638,7 +720,7 @@ Networking_Core *new_networking(Logger *log, IP ip, uint16_t port) * * If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other. */ -Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error) +Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error) { /* If both from and to are 0, use default port range * If one is 0 and the other is non-0, use the non-0 value as only port @@ -662,8 +744,8 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 } /* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */ - if (ip.family != TOX_AF_INET && ip.family != TOX_AF_INET6) { - LOGGER_ERROR(log, "Invalid address family: %u", ip.family); + if (!net_family_is_ipv4(ip.family) && !net_family_is_ipv6(ip.family)) { + LOGGER_ERROR(log, "invalid address family: %u\n", ip.family.value); return nullptr; } @@ -703,12 +785,12 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 /* Functions to increase the size of the send and receive UDP buffers. */ int n = 1024 * 1024 * 2; - setsockopt(temp->sock, SOL_SOCKET, SO_RCVBUF, (const char *)&n, sizeof(n)); - setsockopt(temp->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof(n)); + setsockopt(temp->sock.socket, SOL_SOCKET, SO_RCVBUF, (const char *)&n, sizeof(n)); + setsockopt(temp->sock.socket, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof(n)); /* Enable broadcast on socket */ int broadcast = 1; - setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (const char *)&broadcast, sizeof(broadcast)); + setsockopt(temp->sock.socket, SOL_SOCKET, SO_BROADCAST, (const char *)&broadcast, sizeof(broadcast)); /* iOS UDP sockets are weird and apparently can SIGPIPE */ if (!set_socket_nosigpipe(temp->sock)) { @@ -739,7 +821,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 memset(&addr, 0, sizeof(struct sockaddr_storage)); - if (temp->family == TOX_AF_INET) { + if (net_family_is_ipv4(temp->family)) { struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; addrsize = sizeof(struct sockaddr_in); @@ -748,7 +830,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 fill_addr4(ip.ip.v4, &addr4->sin_addr); portptr = &addr4->sin_port; - } else if (temp->family == TOX_AF_INET6) { + } else if (net_family_is_ipv6(temp->family)) { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; addrsize = sizeof(struct sockaddr_in6); @@ -765,8 +847,8 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 return nullptr; } - if (ip.family == TOX_AF_INET6) { - int is_dualstack = set_socket_dualstack(temp->sock); + if (net_family_is_ipv6(ip.family)) { + const int is_dualstack = set_socket_dualstack(temp->sock); LOGGER_DEBUG(log, "Dual-stack socket: %s", is_dualstack ? "enabled" : "Failed to enable, won't be able to receive from/send to IPv4 addresses"); /* multicast local nodes */ @@ -776,12 +858,12 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02; mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01; mreq.ipv6mr_interface = 0; - int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq)); + const int res = setsockopt(temp->sock.socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq)); int neterror = net_error(); const char *strerror = net_new_strerror(neterror); LOGGER_DEBUG(log, res < 0 ? "Failed to activate local multicast membership. (%d, %s)" : - "Local multicast group FF02::1 joined successfully", neterror, strerror); + "Local multicast group FF02::1 joined successfully. (%d, %s)", neterror, strerror); net_kill_strerror(strerror); } @@ -805,8 +887,8 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 *portptr = net_htons(port_to_try); int tries; - for (tries = port_from; tries <= port_to; tries++) { - int res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); + for (tries = port_from; tries <= port_to; ++tries) { + int res = bind(temp->sock.socket, (struct sockaddr *)&addr, addrsize); if (!res) { temp->port = *portptr; @@ -829,7 +911,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 return temp; } - port_to_try++; + ++port_to_try; if (port_to_try > port_to) { port_to_try = port_from; @@ -853,7 +935,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 return nullptr; } -Networking_Core *new_networking_no_udp(Logger *log) +Networking_Core *new_networking_no_udp(const Logger *log) { /* this is the easiest way to completely disable UDP without changing too much code. */ Networking_Core *net = (Networking_Core *)calloc(1, sizeof(Networking_Core)); @@ -874,7 +956,8 @@ void kill_networking(Networking_Core *net) return; } - if (net->family != 0) { /* Socket not initialized */ + if (!net_family_is_unspec(net->family)) { + /* Socket is initialized, so we close it. */ kill_sock(net->sock); } @@ -895,8 +978,8 @@ int ip_equal(const IP *a, const IP *b) } /* same family */ - if (a->family == b->family) { - if (a->family == TOX_AF_INET || a->family == TCP_INET) { + if (a->family.value == b->family.value) { + if (net_family_is_ipv4(a->family) || net_family_is_tcp_ipv4(a->family)) { struct in_addr addr_a; struct in_addr addr_b; fill_addr4(a->ip.v4, &addr_a); @@ -904,7 +987,7 @@ int ip_equal(const IP *a, const IP *b) return addr_a.s_addr == addr_b.s_addr; } - if (a->family == TOX_AF_INET6 || a->family == TCP_INET6) { + if (net_family_is_ipv6(a->family) || net_family_is_tcp_ipv6(a->family)) { return a->ip.v6.uint64[0] == b->ip.v6.uint64[0] && a->ip.v6.uint64[1] == b->ip.v6.uint64[1]; } @@ -913,14 +996,14 @@ int ip_equal(const IP *a, const IP *b) } /* different family: check on the IPv6 one if it is the IPv4 one embedded */ - if ((a->family == TOX_AF_INET) && (b->family == TOX_AF_INET6)) { - if (IPV6_IPV4_IN_V6(b->ip.v6)) { + if (net_family_is_ipv4(a->family) && net_family_is_ipv6(b->family)) { + if (ipv6_ipv4_in_v6(b->ip.v6)) { struct in_addr addr_a; fill_addr4(a->ip.v4, &addr_a); return addr_a.s_addr == b->ip.v6.uint32[3]; } - } else if ((a->family == TOX_AF_INET6) && (b->family == TOX_AF_INET)) { - if (IPV6_IPV4_IN_V6(a->ip.v6)) { + } else if (net_family_is_ipv6(a->family) && net_family_is_ipv4(b->family)) { + if (ipv6_ipv4_in_v6(a->ip.v6)) { struct in_addr addr_b; fill_addr4(b->ip.v4, &addr_b); return a->ip.v6.uint32[3] == addr_b.s_addr; @@ -967,28 +1050,28 @@ void ip_init(IP *ip, bool ipv6enabled) } memset(ip, 0, sizeof(IP)); - ip->family = ipv6enabled ? TOX_AF_INET6 : TOX_AF_INET; + ip->family = ipv6enabled ? net_family_ipv6 : net_family_ipv4; } /* checks if ip is valid */ -int ip_isset(const IP *ip) +bool ip_isset(const IP *ip) { if (!ip) { - return 0; + return false; } - return (ip->family != 0); + return !net_family_is_unspec(ip->family); } /* checks if ip is valid */ -int ipport_isset(const IP_Port *ipport) +bool ipport_isset(const IP_Port *ipport) { if (!ipport) { - return 0; + return false; } if (!ipport->port) { - return 0; + return false; } return ip_isset(&ipport->ip); @@ -1033,14 +1116,14 @@ const char *ip_ntoa(const IP *ip, char *ip_str, size_t length) if (ip) { const int family = make_family(ip->family); - if (ip->family == TOX_AF_INET) { + if (net_family_is_ipv4(ip->family)) { /* returns standard quad-dotted notation */ struct in_addr addr; fill_addr4(ip->ip.v4, &addr); ip_str[0] = 0; inet_ntop(family, &addr, ip_str, length); - } else if (ip->family == TOX_AF_INET6) { + } else if (net_family_is_ipv6(ip->family)) { /* returns hex-groups enclosed into square brackets */ struct in6_addr addr; fill_addr6(ip->ip.v6, &addr); @@ -1051,7 +1134,7 @@ const char *ip_ntoa(const IP *ip, char *ip_str, size_t length) ip_str[len] = ']'; ip_str[len + 1] = 0; } else { - snprintf(ip_str, length, "(IP invalid, family %u)", ip->family); + snprintf(ip_str, length, "(IP invalid, family %u)", ip->family.value); } } else { snprintf(ip_str, length, "(IP invalid: NULL)"); @@ -1083,14 +1166,14 @@ int ip_parse_addr(const IP *ip, char *address, size_t length) return 0; } - if (ip->family == TOX_AF_INET) { + if (net_family_is_ipv4(ip->family)) { const struct in_addr *addr = (const struct in_addr *)&ip->ip.v4; - return inet_ntop(ip->family, addr, address, length) != nullptr; + return inet_ntop(make_family(ip->family), addr, address, length) != nullptr; } - if (ip->family == TOX_AF_INET6) { + if (net_family_is_ipv6(ip->family)) { const struct in6_addr *addr = (const struct in6_addr *)&ip->ip.v6; - return inet_ntop(ip->family, addr, address, length) != nullptr; + return inet_ntop(make_family(ip->family), addr, address, length) != nullptr; } return 0; @@ -1118,7 +1201,7 @@ int addr_parse_ip(const char *address, IP *to) struct in_addr addr4; if (inet_pton(AF_INET, address, &addr4) == 1) { - to->family = TOX_AF_INET; + to->family = net_family_ipv4; get_ip4(&to->ip.v4, &addr4); return 1; } @@ -1126,7 +1209,7 @@ int addr_parse_ip(const char *address, IP *to) struct in6_addr addr6; if (inet_pton(AF_INET6, address, &addr6) == 1) { - to->family = TOX_AF_INET6; + to->family = net_family_ipv6; get_ip6(&to->ip.v6, &addr6); return 1; } @@ -1158,7 +1241,7 @@ int addr_resolve(const char *address, IP *to, IP *extra) } Family tox_family = to->family; - Family family = make_family(tox_family); + int family = make_family(tox_family); struct addrinfo *server = nullptr; struct addrinfo *walker = nullptr; @@ -1272,14 +1355,14 @@ int net_connect(Socket sock, IP_Port ip_port) struct sockaddr_storage addr = {0}; size_t addrsize; - if (ip_port.ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(ip_port.ip.family)) { struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; addrsize = sizeof(struct sockaddr_in); addr4->sin_family = AF_INET; fill_addr4(ip_port.ip.ip.v4, &addr4->sin_addr); addr4->sin_port = ip_port.port; - } else if (ip_port.ip.family == TOX_AF_INET6) { + } else if (net_family_is_ipv6(ip_port.ip.family)) { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; addrsize = sizeof(struct sockaddr_in6); @@ -1290,7 +1373,7 @@ int net_connect(Socket sock, IP_Port ip_port) return 0; } - return connect(sock, (struct sockaddr *)&addr, addrsize); + return connect(sock.socket, (struct sockaddr *)&addr, addrsize); } int32_t net_getipport(const char *node, IP_Port **res, int tox_type) @@ -1304,12 +1387,12 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type) } // Used to avoid malloc parameter overflow - const size_t MAX_COUNT = MIN(SIZE_MAX, INT32_MAX) / sizeof(IP_Port); + const size_t max_count = min_u64(SIZE_MAX, INT32_MAX) / sizeof(IP_Port); int type = make_socktype(tox_type); struct addrinfo *cur; size_t count = 0; - for (cur = infos; count < MAX_COUNT && cur != nullptr; cur = cur->ai_next) { + for (cur = infos; count < max_count && cur != nullptr; cur = cur->ai_next) { if (cur->ai_socktype && type > 0 && cur->ai_socktype != type) { continue; } @@ -1318,10 +1401,10 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type) continue; } - count++; + ++count; } - assert(count <= MAX_COUNT); + assert(count <= max_count); if (count == 0) { freeaddrinfo(infos); @@ -1352,9 +1435,17 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type) continue; } - ip_port->ip.family = make_tox_family(cur->ai_family); + const Family *const family = make_tox_family(cur->ai_family); + assert(family != nullptr); + + if (family == nullptr) { + freeaddrinfo(infos); + return -1; + } - ip_port++; + ip_port->ip.family = *family; + + ++ip_port; } freeaddrinfo(infos); @@ -1370,18 +1461,18 @@ void net_freeipport(IP_Port *ip_ports) /* return 1 on success * return 0 on failure */ -int bind_to_port(Socket sock, int family, uint16_t port) +int bind_to_port(Socket sock, Family family, uint16_t port) { struct sockaddr_storage addr = {0}; size_t addrsize; - if (family == TOX_AF_INET) { + if (net_family_is_ipv4(family)) { struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; addrsize = sizeof(struct sockaddr_in); addr4->sin_family = AF_INET; addr4->sin_port = net_htons(port); - } else if (family == TOX_AF_INET6) { + } else if (net_family_is_ipv6(family)) { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; addrsize = sizeof(struct sockaddr_in6); @@ -1391,41 +1482,7 @@ int bind_to_port(Socket sock, int family, uint16_t port) return 0; } - return (bind(sock, (struct sockaddr *)&addr, addrsize) == 0); -} - -static int make_tox_family(int family) -{ - switch (family) { - case AF_INET: - return TOX_AF_INET; - - case AF_INET6: - return TOX_AF_INET6; - - case AF_UNSPEC: - return TOX_AF_UNSPEC; - - default: - return family; - } -} - -static int make_family(int tox_family) -{ - switch (tox_family) { - case TOX_AF_INET: - return AF_INET; - - case TOX_AF_INET6: - return AF_INET6; - - case TOX_AF_UNSPEC: - return AF_UNSPEC; - - default: - return tox_family; - } + return bind(sock.socket, (struct sockaddr *)&addr, addrsize) == 0; } static int make_socktype(int type) @@ -1456,12 +1513,47 @@ static int make_proto(int proto) } } -Socket net_socket(int domain, int type, int protocol) +Socket net_socket(Family domain, int type, int protocol) +{ + const int platform_domain = make_family(domain); + const int platform_type = make_socktype(type); + const int platform_prot = make_proto(protocol); + const Socket sock = {(int)socket(platform_domain, platform_type, platform_prot)}; + return sock; +} + +int net_send(Socket sock, const void *buf, size_t len) +{ + return send(sock.socket, (const char *)buf, len, MSG_NOSIGNAL); +} + +int net_recv(Socket sock, void *buf, size_t len) +{ + return recv(sock.socket, (char *)buf, len, MSG_NOSIGNAL); +} + +int net_listen(Socket sock, int backlog) { - int platform_domain = make_family(domain); - int platform_type = make_socktype(type); - int platform_prot = make_proto(protocol); - return socket(platform_domain, platform_type, platform_prot); + return listen(sock.socket, backlog); +} + +Socket net_accept(Socket sock) +{ + const Socket newsock = {accept(sock.socket, nullptr, nullptr)}; + return newsock; +} + +size_t net_socket_data_recv_buffer(Socket sock) +{ +#ifdef OS_WIN32 + unsigned long count = 0; + ioctlsocket(sock.socket, FIONREAD, &count); +#else + int count = 0; + ioctl(sock.socket, FIONREAD, &count); +#endif + + return count; } uint32_t net_htonl(uint32_t hostlong) @@ -1535,6 +1627,11 @@ size_t net_unpack_u64(const uint8_t *bytes, uint64_t *v) return p - bytes; } +bool ipv6_ipv4_in_v6(IP6 a) +{ + return a.uint64[0] == 0 && a.uint32[2] == net_htonl(0xffff); +} + int net_error(void) { #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) diff --git a/protocols/Tox/libtox/src/toxcore/network.h b/protocols/Tox/libtox/src/toxcore/network.h index 10ddef0217..7f7cde60cc 100644 --- a/protocols/Tox/libtox/src/toxcore/network.h +++ b/protocols/Tox/libtox/src/toxcore/network.h @@ -24,58 +24,81 @@ #ifndef NETWORK_H #define NETWORK_H -#ifdef PLAN9 -#include <u.h> // Plan 9 requires this is imported first -// Comment line here to avoid reordering by source code formatters. -#include <libc.h> -#endif - -#include "ccompat.h" #include "logger.h" -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) /* Put win32 includes here */ -#ifndef WINVER -//Windows XP -#define WINVER 0x0501 -#endif - -// The mingw32/64 Windows library warns about including winsock2.h after -// windows.h even though with the above it's a valid thing to do. So, to make -// mingw32 headers happy, we include winsock2.h first. -#include <winsock2.h> - -#include <windows.h> -#include <ws2tcpip.h> - -#else // UNIX includes - -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <unistd.h> - -#endif +#include <stdbool.h> // bool +#include <stddef.h> // size_t +#include <stdint.h> // uint*_t #ifdef __cplusplus extern "C" { #endif -typedef short Family; +typedef struct Family { + uint8_t value; +} Family; + +bool net_family_is_unspec(Family family); +bool net_family_is_ipv4(Family family); +bool net_family_is_ipv6(Family family); +bool net_family_is_tcp_family(Family family); +bool net_family_is_tcp_onion(Family family); +bool net_family_is_tcp_ipv4(Family family); +bool net_family_is_tcp_ipv6(Family family); +bool net_family_is_tox_tcp_ipv4(Family family); +bool net_family_is_tox_tcp_ipv6(Family family); + +extern const Family net_family_unspec; +extern const Family net_family_ipv4; +extern const Family net_family_ipv6; +extern const Family net_family_tcp_family; +extern const Family net_family_tcp_onion; +extern const Family net_family_tcp_ipv4; +extern const Family net_family_tcp_ipv6; +extern const Family net_family_tox_tcp_ipv4; +extern const Family net_family_tox_tcp_ipv6; + +typedef struct Socket { + int socket; +} Socket; + +Socket net_socket(Family domain, int type, int protocol); + +/* Check if socket is valid. + * + * return 1 if valid + * return 0 if not valid + */ +int sock_valid(Socket sock); + +extern const Socket net_invalid_socket; + +/** + * Calls send(sockfd, buf, len, MSG_NOSIGNAL). + */ +int net_send(Socket sockfd, const void *buf, size_t len); +/** + * Calls recv(sockfd, buf, len, MSG_NOSIGNAL). + */ +int net_recv(Socket sockfd, void *buf, size_t len); +/** + * Calls listen(sockfd, backlog). + */ +int net_listen(Socket sockfd, int backlog); +/** + * Calls accept(sockfd, nullptr, nullptr). + */ +Socket net_accept(Socket sockfd); -typedef int Socket; -Socket net_socket(int domain, int type, int protocol); +/** + * return the amount of data in the tcp recv buffer. + * return 0 on failure. + */ +size_t net_socket_data_recv_buffer(Socket sock); #define MAX_UDP_PACKET_SIZE 2048 -typedef enum NET_PACKET_TYPE { +typedef enum Net_Packet_Type { NET_PACKET_PING_REQUEST = 0x00, /* Ping request packet ID. */ NET_PACKET_PING_RESPONSE = 0x01, /* Ping response packet ID. */ NET_PACKET_GET_NODES = 0x02, /* Get nodes request packet ID. */ @@ -104,7 +127,7 @@ typedef enum NET_PACKET_TYPE { BOOTSTRAP_INFO_PACKET_ID = 0xf0, /* Only used for bootstrap nodes */ NET_PACKET_MAX = 0xff, /* This type must remain within a single uint8. */ -} NET_PACKET_TYPE; +} Net_Packet_Type; #define TOX_PORTRANGE_FROM 33445 @@ -137,7 +160,7 @@ typedef union IP4 { } IP4; IP4 get_ip4_loopback(void); -extern const IP4 IP4_BROADCAST; +extern const IP4 ip4_broadcast; typedef union IP6 { uint8_t uint8[16]; @@ -147,15 +170,17 @@ typedef union IP6 { } IP6; IP6 get_ip6_loopback(void); -extern const IP6 IP6_BROADCAST; +extern const IP6 ip6_broadcast; + +typedef union IP_Union { + IP4 v4; + IP6 v6; +} IP_Union; #define IP_DEFINED typedef struct IP { - uint8_t family; - union { - IP4 v4; - IP6 v6; - } ip; + Family family; + IP_Union ip; } IP; #define IP_PORT_DEFINED @@ -180,7 +205,7 @@ size_t net_unpack_u32(const uint8_t *bytes, uint32_t *v); size_t net_unpack_u64(const uint8_t *bytes, uint64_t *v); /* Does the IP6 struct a contain an IPv4 address in an IPv6 one? */ -#define IPV6_IPV4_IN_V6(a) ((a.uint64[0] == 0) && (a.uint32[2] == net_htonl (0xffff))) +bool ipv6_ipv4_in_v6(IP6 a); #define SIZE_IP4 4 #define SIZE_IP6 16 @@ -263,9 +288,9 @@ void ip_reset(IP *ip); /* nulls out ip, sets family according to flag */ void ip_init(IP *ip, bool ipv6enabled); /* checks if ip is valid */ -int ip_isset(const IP *ip); +bool ip_isset(const IP *ip); /* checks if ip is valid */ -int ipport_isset(const IP_Port *ipport); +bool ipport_isset(const IP_Port *ipport); /* copies an ip structure */ void ip_copy(IP *target, const IP *source); /* copies an ip_port structure */ @@ -311,8 +336,7 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra); * Packet data is put into data. * Packet length is put into length. */ -typedef int (*packet_handler_callback)(void *object, IP_Port ip_port, const uint8_t *data, uint16_t len, - void *userdata); +typedef int packet_handler_cb(void *object, IP_Port ip_port, const uint8_t *data, uint16_t len, void *userdata); typedef struct Networking_Core Networking_Core; @@ -326,13 +350,6 @@ uint16_t net_port(const Networking_Core *net); */ int networking_at_startup(void); -/* Check if socket is valid. - * - * return 1 if valid - * return 0 if not valid - */ -int sock_valid(Socket sock); - /* Close the socket. */ void kill_sock(Socket sock); @@ -365,16 +382,13 @@ int set_socket_reuseaddr(Socket sock); */ int set_socket_dualstack(Socket sock); -/* return current monotonic time in milliseconds (ms). */ -uint64_t current_time_monotonic(void); - /* Basic network functions: */ /* Function to send packet(data) of length length to ip_port. */ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length); /* Function to call when packet beginning with byte is received. */ -void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object); +void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_cb *cb, void *object); /* Call this several times a second. */ void networking_poll(Networking_Core *net, void *userdata); @@ -402,7 +416,7 @@ void net_freeipport(IP_Port *ip_ports); /* return 1 on success * return 0 on failure */ -int bind_to_port(Socket sock, int family, uint16_t port); +int bind_to_port(Socket sock, Family family, uint16_t port); /* Get the last networking error code. * @@ -442,9 +456,9 @@ void net_kill_strerror(const char *strerror); * * If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other. */ -Networking_Core *new_networking(Logger *log, IP ip, uint16_t port); -Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error); -Networking_Core *new_networking_no_udp(Logger *log); +Networking_Core *new_networking(const Logger *log, IP ip, uint16_t port); +Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error); +Networking_Core *new_networking_no_udp(const Logger *log); /* Function to cleanup networking stuff (doesn't do much right now). */ void kill_networking(Networking_Core *net); diff --git a/protocols/Tox/libtox/src/toxcore/onion.c b/protocols/Tox/libtox/src/toxcore/onion.c index 740c25ce10..5ba716fd6d 100644 --- a/protocols/Tox/libtox/src/toxcore/onion.c +++ b/protocols/Tox/libtox/src/toxcore/onion.c @@ -3,7 +3,7 @@ */ /* - * Copyright © 2016-2017 The TokTok team. + * Copyright © 2016-2018 The TokTok team. * Copyright © 2013 Tox project. * * This file is part of Tox, the free peer to peer instant messenger. @@ -27,6 +27,10 @@ #include "onion.h" +#include <stdlib.h> +#include <string.h> + +#include "mono_time.h" #include "util.h" #define RETURN_1 ONION_RETURN_1 @@ -51,9 +55,9 @@ static void change_symmetric_key(Onion *onion) /* packing and unpacking functions */ static void ip_pack(uint8_t *data, IP source) { - data[0] = source.family; + data[0] = source.family.value; - if (source.family == TOX_AF_INET || source.family == TOX_TCP_INET) { + if (net_family_is_ipv4(source.family) || net_family_is_tox_tcp_ipv4(source.family)) { memset(data + 1, 0, SIZE_IP6); memcpy(data + 1, source.ip.v4.uint8, SIZE_IP4); } else { @@ -68,17 +72,18 @@ static int ip_unpack(IP *target, const uint8_t *data, unsigned int data_size, bo return -1; } - target->family = data[0]; + // TODO(iphydf): Validate input. + target->family.value = data[0]; - if (target->family == TOX_AF_INET || target->family == TOX_TCP_INET) { + if (net_family_is_ipv4(target->family) || net_family_is_tox_tcp_ipv4(target->family)) { memcpy(target->ip.v4.uint8, data + 1, SIZE_IP4); } else { memcpy(target->ip.v6.uint8, data + 1, SIZE_IP6); } bool valid = disable_family_check || - target->family == TOX_AF_INET || - target->family == TOX_AF_INET6; + net_family_is_ipv4(target->family) || + net_family_is_ipv6(target->family); return valid ? 0 : -1; } @@ -639,8 +644,8 @@ static int handle_recv_1(void *object, IP_Port source, const uint8_t *packet, ui uint16_t data_len = length - (1 + RETURN_1); if (onion->recv_1_function && - send_to.ip.family != TOX_AF_INET && - send_to.ip.family != TOX_AF_INET6) { + !net_family_is_ipv4(send_to.ip.family) && + !net_family_is_ipv6(send_to.ip.family)) { return onion->recv_1_function(onion->callback_object, send_to, packet + (1 + RETURN_1), data_len); } @@ -651,7 +656,7 @@ static int handle_recv_1(void *object, IP_Port source, const uint8_t *packet, ui return 0; } -void set_callback_handle_recv_1(Onion *onion, int (*function)(void *, IP_Port, const uint8_t *, uint16_t), void *object) +void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object) { onion->recv_1_function = function; onion->callback_object = object; diff --git a/protocols/Tox/libtox/src/toxcore/onion.h b/protocols/Tox/libtox/src/toxcore/onion.h index e81b3a52ae..0e025a1ceb 100644 --- a/protocols/Tox/libtox/src/toxcore/onion.h +++ b/protocols/Tox/libtox/src/toxcore/onion.h @@ -26,7 +26,9 @@ #include "DHT.h" -typedef struct { +typedef int onion_recv_1_cb(void *object, IP_Port dest, const uint8_t *data, uint16_t length); + +typedef struct Onion { DHT *dht; Networking_Core *net; uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; @@ -36,7 +38,7 @@ typedef struct { Shared_Keys shared_keys_2; Shared_Keys shared_keys_3; - int (*recv_1_function)(void *, IP_Port, const uint8_t *, uint16_t); + onion_recv_1_cb *recv_1_function; void *callback_object; } Onion; @@ -56,7 +58,7 @@ typedef struct { #define ONION_PATH_LENGTH 3 -typedef struct { +typedef struct Onion_Path { uint8_t shared_key1[CRYPTO_SHARED_KEY_SIZE]; uint8_t shared_key2[CRYPTO_SHARED_KEY_SIZE]; uint8_t shared_key3[CRYPTO_SHARED_KEY_SIZE]; @@ -154,8 +156,7 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, IP_Port * * Format: function(void *object, IP_Port dest, uint8_t *data, uint16_t length) */ -void set_callback_handle_recv_1(Onion *onion, int (*function)(void *, IP_Port, const uint8_t *, uint16_t), - void *object); +void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object); Onion *new_onion(DHT *dht); diff --git a/protocols/Tox/libtox/src/toxcore/onion_announce.c b/protocols/Tox/libtox/src/toxcore/onion_announce.c index 8e49f7bdc7..d368facee8 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_announce.c +++ b/protocols/Tox/libtox/src/toxcore/onion_announce.c @@ -27,7 +27,11 @@ #include "onion_announce.h" +#include <stdlib.h> +#include <string.h> + #include "LAN_discovery.h" +#include "mono_time.h" #include "util.h" #define PING_ID_TIMEOUT ONION_ANNOUNCE_TIMEOUT @@ -37,7 +41,7 @@ #define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE #define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3) -typedef struct { +typedef struct Onion_Announce_Entry { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; IP_Port ret_ip_port; uint8_t ret[ONION_RETURN_3]; @@ -261,7 +265,7 @@ static int in_entries(const Onion_Announce *onion_a, const uint8_t *public_key) return -1; } -typedef struct { +typedef struct Cmp_data { const uint8_t *base_public_key; Onion_Announce_Entry entry; } Cmp_data; @@ -309,14 +313,14 @@ static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int le // comparison function can use it as the base of comparison. VLA(Cmp_data, cmp_list, length); - for (uint32_t i = 0; i < length; i++) { + for (uint32_t i = 0; i < length; ++i) { cmp_list[i].base_public_key = comp_public_key; cmp_list[i].entry = list[i]; } qsort(cmp_list, length, sizeof(Cmp_data), cmp_entry); - for (uint32_t i = 0; i < length; i++) { + for (uint32_t i = 0; i < length; ++i) { list[i] = cmp_list[i].entry; } } @@ -402,7 +406,7 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t * /*Respond with a announce response packet*/ Node_format nodes_list[MAX_SENT_NODES]; - unsigned int num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, 0, + unsigned int num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, net_family_unspec, ip_is_lan(source.ip) == 0, 1); uint8_t nonce[CRYPTO_NONCE_SIZE]; random_nonce(nonce); diff --git a/protocols/Tox/libtox/src/toxcore/onion_announce.h b/protocols/Tox/libtox/src/toxcore/onion_announce.h index 36484ff22a..84e76a38a1 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_announce.h +++ b/protocols/Tox/libtox/src/toxcore/onion_announce.h @@ -40,7 +40,7 @@ #define ONION_DATA_RESPONSE_MIN_SIZE (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE) #if ONION_PING_ID_SIZE != CRYPTO_PUBLIC_KEY_SIZE -#error announce response packets assume that ONION_PING_ID_SIZE is equal to CRYPTO_PUBLIC_KEY_SIZE +#error "announce response packets assume that ONION_PING_ID_SIZE is equal to CRYPTO_PUBLIC_KEY_SIZE" #endif #define ONION_DATA_REQUEST_MIN_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE) diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.c b/protocols/Tox/libtox/src/toxcore/onion_client.c index c4eb3fc175..9c59343dd7 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_client.c +++ b/protocols/Tox/libtox/src/toxcore/onion_client.c @@ -28,7 +28,11 @@ #include "onion_client.h" +#include <stdlib.h> +#include <string.h> + #include "LAN_discovery.h" +#include "mono_time.h" #include "util.h" /* defines for the array size and @@ -36,7 +40,7 @@ #define ANNOUNCE_ARRAY_SIZE 256 #define ANNOUNCE_TIMEOUT 10 -typedef struct { +typedef struct Onion_Node { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; IP_Port ip_port; uint8_t ping_id[ONION_PING_ID_SIZE]; @@ -54,7 +58,7 @@ typedef struct { uint32_t path_used; } Onion_Node; -typedef struct { +typedef struct Onion_Client_Paths { Onion_Path paths[NUMBER_ONION_PATHS]; uint64_t last_path_success[NUMBER_ONION_PATHS]; uint64_t last_path_used[NUMBER_ONION_PATHS]; @@ -63,12 +67,12 @@ typedef struct { unsigned int last_path_used_times[NUMBER_ONION_PATHS]; } Onion_Client_Paths; -typedef struct { +typedef struct Last_Pinged { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint64_t timestamp; } Last_Pinged; -typedef struct { +typedef struct Onion_Friend { uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/ uint8_t is_online; /* Set by the onion_set_friend_status function. */ @@ -92,17 +96,22 @@ typedef struct { Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; uint8_t last_pinged_index; - int (*tcp_relay_node_callback)(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key); + recv_tcp_relay_cb *tcp_relay_node_callback; void *tcp_relay_node_callback_object; uint32_t tcp_relay_node_callback_number; - void (*dht_pk_callback)(void *data, int32_t number, const uint8_t *dht_public_key, void *userdata); + onion_dht_pk_cb *dht_pk_callback; void *dht_pk_callback_object; uint32_t dht_pk_callback_number; uint32_t run_count; } Onion_Friend; +typedef struct Onion_Data_Handler { + oniondata_handler_cb *function; + void *object; +} Onion_Data_Handler; + struct Onion_Client { DHT *dht; Net_Crypto *c; @@ -117,7 +126,8 @@ struct Onion_Client { Onion_Client_Paths onion_paths_friends; uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; - uint64_t last_run, first_run; + uint64_t last_run; + uint64_t first_run; uint8_t temp_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE]; @@ -132,15 +142,12 @@ struct Onion_Client { Ping_Array *announce_ping_array; uint8_t last_pinged_index; - struct { - oniondata_handler_callback function; - void *object; - } Onion_Data_Handlers[256]; + Onion_Data_Handler onion_data_handlers[256]; uint64_t last_packet_recv; unsigned int onion_connected; - bool UDP_connected; + bool udp_connected; }; DHT *onion_get_dht(const Onion_Client *onion_c) @@ -160,7 +167,7 @@ Net_Crypto *onion_get_net_crypto(const Onion_Client *onion_c) */ int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key) { - if (ip_port.ip.family != TOX_AF_INET && ip_port.ip.family != TOX_AF_INET6) { + if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) { return -1; } @@ -193,7 +200,7 @@ int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t */ static int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key) { - if (ip_port.ip.family != TOX_AF_INET && ip_port.ip.family != TOX_AF_INET6) { + if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) { return -1; } @@ -262,8 +269,8 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format unsigned int num_nodes = (onion_c->path_nodes_index < MAX_PATH_NODES) ? onion_c->path_nodes_index : MAX_PATH_NODES; - //if (DHT_non_lan_connected(onion_c->dht)) { - if (DHT_isconnected(onion_c->dht)) { + // if (dht_non_lan_connected(onion_c->dht)) { + if (dht_isconnected(onion_c->dht)) { if (num_nodes == 0) { return 0; } @@ -279,7 +286,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format } if (num_nodes >= 2) { - nodes[0].ip_port.ip.family = TCP_FAMILY; + nodes[0].ip_port.ip.family = net_family_tcp_family; nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp; for (i = 1; i < max_num; ++i) { @@ -293,7 +300,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format return 0; } - nodes[0].ip_port.ip.family = TCP_FAMILY; + nodes[0].ip_port.ip.family = net_family_tcp_family; nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp; for (i = 1; i < max_num; ++i) { @@ -462,7 +469,7 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Path *path, IP_Port dest, const uint8_t *data, uint16_t length) { - if (path->ip_port1.ip.family == TOX_AF_INET || path->ip_port1.ip.family == TOX_AF_INET6) { + if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) { uint8_t packet[ONION_MAX_PACKET_SIZE]; int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length); @@ -477,7 +484,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa return 0; } - if (path->ip_port1.ip.family == TCP_FAMILY) { + if (net_family_is_tcp_family(path->ip_port1.ip.family)) { uint8_t packet[ONION_MAX_PACKET_SIZE]; int len = create_onion_packet_tcp(packet, sizeof(packet), path, dest, data, length); @@ -603,7 +610,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_ return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len); } -typedef struct { +typedef struct Onion_Client_Cmp_data { const uint8_t *base_public_key; Onion_Node entry; } Onion_Client_Cmp_data; @@ -651,14 +658,14 @@ static void sort_onion_node_list(Onion_Node *list, unsigned int length, const ui // comparison function can use it as the base of comparison. VLA(Onion_Client_Cmp_data, cmp_list, length); - for (uint32_t i = 0; i < length; i++) { + for (uint32_t i = 0; i < length; ++i) { cmp_list[i].base_public_key = comp_public_key; cmp_list[i].entry = list[i]; } qsort(cmp_list, length, sizeof(Onion_Client_Cmp_data), onion_client_cmp_entry); - for (uint32_t i = 0; i < length; i++) { + for (uint32_t i = 0; i < length; ++i) { list[i] = cmp_list[i].entry; } } @@ -923,11 +930,11 @@ static int handle_data_response(void *object, IP_Port source, const uint8_t *pac return 1; } - if (!onion_c->Onion_Data_Handlers[plain[0]].function) { + if (!onion_c->onion_data_handlers[plain[0]].function) { return 1; } - return onion_c->Onion_Data_Handlers[plain[0]].function(onion_c->Onion_Data_Handlers[plain[0]].object, temp_plain, plain, + return onion_c->onion_data_handlers[plain[0]].function(onion_c->onion_data_handlers[plain[0]].object, temp_plain, plain, SIZEOF_VLA(plain), userdata); } @@ -984,11 +991,11 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con int i; for (i = 0; i < num_nodes; ++i) { - uint8_t family = nodes[i].ip_port.ip.family; + const Family family = nodes[i].ip_port.ip.family; - if (family == TOX_AF_INET || family == TOX_AF_INET6) { - DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key); - } else if (family == TCP_INET || family == TCP_INET6) { + if (net_family_is_ipv4(family) || net_family_is_ipv6(family)) { + dht_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key); + } else if (net_family_is_tcp_ipv4(family) || net_family_is_tcp_ipv6(family)) { if (onion_c->friends_list[friend_num].tcp_relay_node_callback) { void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object; uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number; @@ -1007,8 +1014,8 @@ static int handle_tcp_onion(void *object, const uint8_t *data, uint16_t length, return 1; } - IP_Port ip_port = {{0}}; - ip_port.ip.family = TCP_FAMILY; + IP_Port ip_port = {{{0}}}; + ip_port.ip.family = net_family_tcp_family; if (data[0] == NET_PACKET_ANNOUNCE_RESPONSE) { return handle_announce_response(object, ip_port, data, length, userdata); @@ -1022,7 +1029,7 @@ static int handle_tcp_onion(void *object, const uint8_t *data, uint16_t length, } /* Send data of length length to friendnum. - * This data will be received by the friend using the Onion_Data_Handlers callbacks. + * This data will be received by the friend using the onion_data_handlers callbacks. * * Even if this function succeeds, the friend might not receive any data. * @@ -1323,8 +1330,13 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num) return -1; } - //if (onion_c->friends_list[friend_num].know_dht_public_key) - // DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, 0); +#if 0 + + if (onion_c->friends_list[friend_num].know_dht_public_key) { + dht_delfriend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, 0); + } + +#endif crypto_memzero(&onion_c->friends_list[friend_num], sizeof(Onion_Friend)); unsigned int i; @@ -1351,8 +1363,8 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num) * return -1 on failure. * return 0 on success. */ -int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*callback)(void *object, - uint32_t number, IP_Port ip_port, const uint8_t *public_key), void *object, uint32_t number) +int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, + recv_tcp_relay_cb *callback, void *object, uint32_t number) { if ((uint32_t)friend_num >= onion_c->num_friends) { return -1; @@ -1372,8 +1384,8 @@ int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*callback * return -1 on failure. * return 0 on success. */ -int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num, void (*function)(void *data, int32_t number, - const uint8_t *dht_public_key, void *userdata), void *object, uint32_t number) +int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num, + onion_dht_pk_cb *function, void *object, uint32_t number) { if ((uint32_t)friend_num >= onion_c->num_friends) { return -1; @@ -1453,7 +1465,7 @@ int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_p return -1; } - return DHT_getfriendip(onion_c->dht, dht_public_key, ip_port); + return dht_getfriendip(onion_c->dht, dht_public_key, ip_port); } @@ -1504,7 +1516,7 @@ static void populate_path_nodes_tcp(Onion_Client *onion_c) { Node_format nodes_list[MAX_SENT_NODES]; - unsigned int num_nodes = copy_connected_tcp_relays(onion_c->c, nodes_list, MAX_SENT_NODES);; + unsigned int num_nodes = copy_connected_tcp_relays(onion_c->c, nodes_list, MAX_SENT_NODES); unsigned int i; for (i = 0; i < num_nodes; ++i) { @@ -1638,10 +1650,10 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum) /* Function to call when onion data packet with contents beginning with byte is received. */ -void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object) +void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_cb *cb, void *object) { - onion_c->Onion_Data_Handlers[byte].function = cb; - onion_c->Onion_Data_Handlers[byte].object = object; + onion_c->onion_data_handlers[byte].function = cb; + onion_c->onion_data_handlers[byte].object = object; } #define ANNOUNCE_INTERVAL_NOT_ANNOUNCED 3 @@ -1788,7 +1800,7 @@ static int onion_isconnected(const Onion_Client *onion_c) unsigned int onion_connection_status(const Onion_Client *onion_c) { if (onion_c->onion_connected >= ONION_CONNECTION_SECONDS) { - if (onion_c->UDP_connected) { + if (onion_c->udp_connected) { return 2; } @@ -1821,13 +1833,13 @@ void do_onion_client(Onion_Client *onion_c) } } - bool UDP_connected = DHT_non_lan_connected(onion_c->dht); + bool udp_connected = dht_non_lan_connected(onion_c->dht); if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS * 2)) { - set_tcp_onion_status(nc_get_tcp_c(onion_c->c), !UDP_connected); + set_tcp_onion_status(nc_get_tcp_c(onion_c->c), !udp_connected); } - onion_c->UDP_connected = UDP_connected + onion_c->udp_connected = udp_connected || get_random_tcp_onion_conn_number(nc_get_tcp_c(onion_c->c)) == -1; /* Check if connected to any TCP relays. */ if (onion_connection_status(onion_c)) { diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.h b/protocols/Tox/libtox/src/toxcore/onion_client.h index 327d492326..6e73c3abc7 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_client.h +++ b/protocols/Tox/libtox/src/toxcore/onion_client.h @@ -30,7 +30,7 @@ #include "ping_array.h" #define MAX_ONION_CLIENTS 8 -#define MAX_ONION_CLIENTS_ANNOUNCE 12 /* Number of nodes to announce ourselves to. */ +#define MAX_ONION_CLIENTS_ANNOUNCE 12 // Number of nodes to announce ourselves to. #define ONION_NODE_PING_INTERVAL 15 #define ONION_NODE_TIMEOUT ONION_NODE_PING_INTERVAL @@ -124,6 +124,8 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on */ int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port); +typedef int recv_tcp_relay_cb(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key); + /* Set the function for this friend that will be callbacked with object and number * when that friends gives us one of the TCP relays he is connected to. * @@ -132,9 +134,10 @@ int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_p * return -1 on failure. * return 0 on success. */ -int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object, - uint32_t number, IP_Port ip_port, const uint8_t *public_key), void *object, uint32_t number); +int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, + recv_tcp_relay_cb *tcp_relay_node_callback, void *object, uint32_t number); +typedef void onion_dht_pk_cb(void *data, int32_t number, const uint8_t *dht_public_key, void *userdata); /* Set the function for this friend that will be callbacked with object and number * when that friend gives us his DHT temporary public key. @@ -144,8 +147,8 @@ int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_rela * return -1 on failure. * return 0 on success. */ -int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num, void (*function)(void *data, int32_t number, - const uint8_t *dht_public_key, void *userdata), void *object, uint32_t number); +int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num, onion_dht_pk_cb *function, void *object, + uint32_t number); /* Set a friends DHT public key. * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to @@ -177,11 +180,11 @@ unsigned int onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_ */ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length); -typedef int (*oniondata_handler_callback)(void *object, const uint8_t *source_pubkey, const uint8_t *data, - uint16_t len, void *userdata); +typedef int oniondata_handler_cb(void *object, const uint8_t *source_pubkey, const uint8_t *data, + uint16_t len, void *userdata); /* Function to call when onion data packet with contents beginning with byte is received. */ -void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object); +void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_cb *cb, void *object); void do_onion_client(Onion_Client *onion_c); diff --git a/protocols/Tox/libtox/src/toxcore/ping.c b/protocols/Tox/libtox/src/toxcore/ping.c index bede07a117..1bf096bfcc 100644 --- a/protocols/Tox/libtox/src/toxcore/ping.c +++ b/protocols/Tox/libtox/src/toxcore/ping.c @@ -29,13 +29,15 @@ #include "ping.h" +#include <stdlib.h> +#include <string.h> + #include "DHT.h" +#include "mono_time.h" #include "network.h" #include "ping_array.h" #include "util.h" -#include <stdint.h> - #define PING_NUM_MAX 512 /* Maximum newly announced nodes to ping per TIME_TO_PING seconds. */ @@ -71,7 +73,7 @@ int32_t ping_send_request(Ping *ping, IP_Port ipp, const uint8_t *public_key) uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; // generate key to encrypt ping_id with recipient privkey - DHT_get_shared_key_sent(ping->dht, shared_key, public_key); + dht_get_shared_key_sent(ping->dht, shared_key, public_key); // Generate random ping_id. uint8_t data[PING_DATA_SIZE]; id_copy(data, public_key); @@ -153,7 +155,7 @@ static int handle_ping_request(void *object, IP_Port source, const uint8_t *pack uint8_t ping_plain[PING_PLAIN_SIZE]; // Decrypt ping_id - DHT_get_shared_key_recv(dht, shared_key, packet + 1); + dht_get_shared_key_recv(dht, shared_key, packet + 1); rc = decrypt_data_symmetric(shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, @@ -195,7 +197,7 @@ static int handle_ping_response(void *object, IP_Port source, const uint8_t *pac uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; // generate key to encrypt ping_id with recipient privkey - DHT_get_shared_key_sent(ping->dht, shared_key, packet + 1); + dht_get_shared_key_sent(ping->dht, shared_key, packet + 1); uint8_t ping_plain[PING_PLAIN_SIZE]; // Decrypt ping_id @@ -249,7 +251,7 @@ static int in_list(const Client_data *list, uint16_t length, const uint8_t *publ if (id_equal(list[i].public_key, public_key)) { const IPPTsPng *ipptp; - if (ip_port.ip.family == TOX_AF_INET) { + if (net_family_is_ipv4(ip_port.ip.family)) { ipptp = &list[i].assoc4; } else { ipptp = &list[i].assoc6; @@ -290,7 +292,7 @@ int32_t ping_add(Ping *ping, const uint8_t *public_key, IP_Port ip_port) IP_Port temp; - if (DHT_getfriendip(ping->dht, public_key, &temp) == 0) { + if (dht_getfriendip(ping->dht, public_key, &temp) == 0) { ping_send_request(ping, ip_port, public_key); return -1; } diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.c b/protocols/Tox/libtox/src/toxcore/ping_array.c index a54ebfe209..142640dd23 100644 --- a/protocols/Tox/libtox/src/toxcore/ping_array.c +++ b/protocols/Tox/libtox/src/toxcore/ping_array.c @@ -27,11 +27,15 @@ #include "ping_array.h" +#include <stdlib.h> +#include <string.h> + #include "crypto_core.h" +#include "mono_time.h" #include "util.h" -typedef struct { +typedef struct Ping_Array_Entry { void *data; uint32_t length; uint64_t time; @@ -73,7 +77,8 @@ Ping_Array *ping_array_new(uint32_t size, uint32_t timeout) return nullptr; } - empty_array->last_deleted = empty_array->last_added = 0; + empty_array->last_deleted = 0; + empty_array->last_added = 0; empty_array->total_size = size; empty_array->timeout = timeout; return empty_array; @@ -83,9 +88,9 @@ static void clear_entry(Ping_Array *array, uint32_t index) { free(array->entries[index].data); array->entries[index].data = nullptr; - array->entries[index].length = - array->entries[index].time = - array->entries[index].ping_id = 0; + array->entries[index].length = 0; + array->entries[index].time = 0; + array->entries[index].ping_id = 0; } /* Free all the allocated memory in a Ping_Array. diff --git a/protocols/Tox/libtox/src/toxcore/state.c b/protocols/Tox/libtox/src/toxcore/state.c new file mode 100644 index 0000000000..8da061f4a6 --- /dev/null +++ b/protocols/Tox/libtox/src/toxcore/state.c @@ -0,0 +1,90 @@ +#include "state.h" + +#include <string.h> + +/* state load/save */ +int state_load(const Logger *log, state_load_cb *state_load_callback, void *outer, + const uint8_t *data, uint32_t length, uint16_t cookie_inner) +{ + if (state_load_callback == nullptr || data == nullptr) { + LOGGER_ERROR(log, "state_load() called with invalid args.\n"); + return -1; + } + + + const uint32_t size_head = sizeof(uint32_t) * 2; + + while (length >= size_head) { + uint32_t length_sub; + lendian_to_host32(&length_sub, data); + + uint32_t cookie_type; + lendian_to_host32(&cookie_type, data + sizeof(uint32_t)); + + data += size_head; + length -= size_head; + + if (length < length_sub) { + /* file truncated */ + LOGGER_ERROR(log, "state file too short: %u < %u\n", length, length_sub); + return -1; + } + + if (lendian_to_host16((cookie_type >> 16)) != cookie_inner) { + /* something is not matching up in a bad way, give up */ + LOGGER_ERROR(log, "state file garbled: %04x != %04x\n", cookie_type >> 16, cookie_inner); + return -1; + } + + const uint16_t type = lendian_to_host16(cookie_type & 0xFFFF); + + switch (state_load_callback(outer, data, length_sub, type)) { + case STATE_LOAD_STATUS_CONTINUE: + data += length_sub; + length -= length_sub; + break; + + case STATE_LOAD_STATUS_ERROR: + return -1; + + case STATE_LOAD_STATUS_END: + return 0; + } + } + + if (length != 0) { + LOGGER_ERROR(log, "unparsed data in state file of length %u\n", length); + return -1; + } + + return 0; +} + +uint16_t lendian_to_host16(uint16_t lendian) +{ +#ifdef WORDS_BIGENDIAN + return (lendian << 8) | (lendian >> 8); +#else + return lendian; +#endif +} + +void host_to_lendian32(uint8_t *dest, uint32_t num) +{ +#ifdef WORDS_BIGENDIAN + num = ((num << 8) & 0xFF00FF00) | ((num >> 8) & 0xFF00FF); + num = (num << 16) | (num >> 16); +#endif + memcpy(dest, &num, sizeof(uint32_t)); +} + +void lendian_to_host32(uint32_t *dest, const uint8_t *lendian) +{ + uint32_t d; + memcpy(&d, lendian, sizeof(uint32_t)); +#ifdef WORDS_BIGENDIAN + d = ((d << 8) & 0xFF00FF00) | ((d >> 8) & 0xFF00FF); + d = (d << 16) | (d >> 16); +#endif + *dest = d; +} diff --git a/protocols/Tox/libtox/src/toxcore/state.h b/protocols/Tox/libtox/src/toxcore/state.h new file mode 100644 index 0000000000..3f7ff04333 --- /dev/null +++ b/protocols/Tox/libtox/src/toxcore/state.h @@ -0,0 +1,49 @@ +/** + * The state module is responsible for parsing the Tox save data format and for + * saving state in that format. + * + * This module provides functions for iterating over serialised data sections + * and reading/writing numbers in the correct format (little endian). + * + * Note that unlike the Tox network protocol, the save data stores its values in + * little endian, which is native to most desktop and server architectures in + * 2018. + */ +#ifndef C_TOXCORE_TOXCORE_STATE_H +#define C_TOXCORE_TOXCORE_STATE_H + +#include "logger.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Returned by the state_load_cb to instruct the loader on what to do next. +typedef enum State_Load_Status { + // Continue loading state data sections. + STATE_LOAD_STATUS_CONTINUE, + // An error occurred. Stop loading sections. + STATE_LOAD_STATUS_ERROR, + // We're at the end of the save data, terminate loading successfully. + STATE_LOAD_STATUS_END, +} State_Load_Status; + +typedef State_Load_Status state_load_cb(void *outer, const uint8_t *data, uint32_t len, uint16_t type); + +// state load/save +int state_load(const Logger *log, state_load_cb *state_load_callback, void *outer, + const uint8_t *data, uint32_t length, uint16_t cookie_inner); + +// Utilities for state data serialisation. + +uint16_t lendian_to_host16(uint16_t lendian); +#define host_tolendian16(x) lendian_to_host16(x) + +void host_to_lendian32(uint8_t *dest, uint32_t num); +void lendian_to_host32(uint32_t *dest, const uint8_t *lendian); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // C_TOXCORE_TOXCORE_STATE_H diff --git a/protocols/Tox/libtox/src/toxcore/tox.api.h b/protocols/Tox/libtox/src/toxcore/tox.api.h index 1c3b112115..632d79c530 100644 --- a/protocols/Tox/libtox/src/toxcore/tox.api.h +++ b/protocols/Tox/libtox/src/toxcore/tox.api.h @@ -42,7 +42,8 @@ extern "C" { *****************************************************************************/ -/** \page core Public core API for Tox clients. +/** + * @page core Public core API for Tox clients. * * Every function that can fail takes a function-specific error code pointer * that can be used to diagnose problems with the Tox state or the function @@ -81,7 +82,8 @@ extern "C" { * part of the ABI. */ -/** \subsection events Events and callbacks +/** + * @subsection events Events and callbacks * * Events are handled by callbacks. One callback can be registered per event. * All events have a callback function type named `tox_{event}_cb` and a @@ -104,7 +106,8 @@ extern "C" { * their own user data pointer of their own type. */ -/** \subsection threading Threading implications +/** + * @subsection threading Threading implications * * It is possible to run multiple concurrent threads with a Tox instance for * each thread. It is also possible to run all Tox instances in the same thread. @@ -126,12 +129,12 @@ extern "C" { * * E.g. to get the current nickname, one would write * - * \code + * @code * size_t length = ${tox.self.name.size}(tox); * uint8_t *name = malloc(length); * if (!name) abort(); * ${tox.self.name.get}(tox, name); - * \endcode + * @endcode * * If any other thread calls ${tox.self.name.set} while this thread is allocating * memory, the length may have become invalid, and the call to @@ -179,7 +182,7 @@ const VERSION_MINOR = 2; * The patch or revision number. Incremented when bugfixes are applied without * changing any functionality or API or ABI. */ -const VERSION_PATCH = 2; +const VERSION_PATCH = 3; /** * A macro to check at preprocessing time whether the client code is compatible @@ -241,6 +244,11 @@ const PUBLIC_KEY_SIZE = 32; const SECRET_KEY_SIZE = 32; /** + * The size of a Tox Conference unique id in bytes. + */ +const CONFERENCE_UID_SIZE = 32; + +/** * The size of the nospam in bytes when written in a Tox address. */ const NOSPAM_SIZE = sizeof(uint32_t); @@ -307,6 +315,16 @@ const FILE_ID_LENGTH = 32; */ const MAX_FILENAME_LENGTH = 255; +/** + * Maximum length of a hostname, e.g. proxy or bootstrap node names. + * + * This length includes the NUL byte. Hostnames are NUL-terminated C strings, so + * they are 255 characters plus one NUL byte. + * + * @deprecated The macro will be removed in 0.3.0. Use the function instead. + */ +const MAX_HOSTNAME_LENGTH = 256; + /******************************************************************************* * @@ -473,7 +491,9 @@ static class options { * * Setting this to false will force Tox to use TCP only. Communications will * need to be relayed through a TCP relay node, potentially slowing them down. - * Disabling UDP support is necessary when using anonymous proxies or Tor. + * + * If a proxy is enabled, UDP will be disabled if either toxcore or the + * proxy don't support proxying UDP messages. */ bool udp_enabled; @@ -494,8 +514,8 @@ static class options { * The IP address or DNS name of the proxy to be used. * * If used, this must be non-NULL and be a valid DNS name. The name must not - * exceed 255 characters, and be in a NUL-terminated C string format - * (255 chars + 1 NUL byte). + * exceed $MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C string + * format ($MAX_HOSTNAME_LENGTH includes the NUL byte). * * This member is ignored (it can be NULL) if proxy_type is ${PROXY_TYPE.NONE}. * @@ -744,17 +764,18 @@ uint8_t[size] savedata { * This function will attempt to connect to the node using UDP. You must use * this function even if ${options.this.udp_enabled} was set to false. * - * @param address The hostname or IP address (IPv4 or IPv6) of the node. + * @param host The hostname or IP address (IPv4 or IPv6) of the node. Must be + * at most $MAX_HOSTNAME_LENGTH chars, including the NUL byte. * @param port The port on the host on which the bootstrap Tox instance is * listening. * @param public_key The long term public key of the bootstrap node * ($PUBLIC_KEY_SIZE bytes). * @return true on success. */ -bool bootstrap(string address, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] public_key) { +bool bootstrap(string host, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] public_key) { NULL, /** - * The address could not be resolved to an IP address, or the IP address + * The hostname could not be resolved to an IP address, or the IP address * passed was invalid. */ BAD_HOST, @@ -772,13 +793,14 @@ bool bootstrap(string address, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] pub * the same bootstrap node, or to add TCP relays without using them as * bootstrap nodes. * - * @param address The hostname or IP address (IPv4 or IPv6) of the TCP relay. + * @param host The hostname or IP address (IPv4 or IPv6) of the TCP relay. + * Must be at most $MAX_HOSTNAME_LENGTH chars, including the NUL byte. * @param port The port on the host on which the TCP relay is listening. * @param public_key The long term public key of the TCP relay * ($PUBLIC_KEY_SIZE bytes). * @return true on success. */ -bool add_tcp_relay(string address, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] public_key) +bool add_tcp_relay(string host, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] public_key) with error for bootstrap; @@ -1064,7 +1086,7 @@ namespace friend { * @param message The message that will be sent along with the friend request. * @param length The length of the data byte array. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. */ uint32_t add( const uint8_t[ADDRESS_SIZE] address, @@ -1120,7 +1142,7 @@ namespace friend { * @param public_key A byte array of length $PUBLIC_KEY_SIZE containing the * Public Key (not the Address) of the friend to add. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. * @see $add for a more detailed description of friend numbers. */ uint32_t add_norequest(const uint8_t[PUBLIC_KEY_SIZE] public_key) @@ -1159,7 +1181,7 @@ namespace friend { /** * Return the friend number associated with that Public Key. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. * @param public_key A byte array containing the Public Key. */ const uint32_t by_public_key(const uint8_t[PUBLIC_KEY_SIZE] public_key) { @@ -1633,6 +1655,14 @@ static bool hash(uint8_t[HASH_LENGTH] hash, const uint8_t[length] data); namespace file { + /** + * A list of pre-defined file kinds. Toxcore itself does not behave + * differently for different file kinds. These are a hint to the client + * telling it what use the sender intended for the file. The `kind` parameter + * in the send function and recv callback are `uint32_t`, not $KIND, because + * clients can invent their own file kind. Unknown file kinds should be + * treated as ${KIND.DATA}. + */ enum KIND { /** * Arbitrary file data. Clients can choose to handle it based on the file name @@ -1879,7 +1909,7 @@ namespace file { * * @return A file number used as an identifier in subsequent callbacks. This * number is per friend. File numbers are reused after a transfer terminates. - * On failure, this function returns UINT32_MAX. Any pattern in file numbers + * On failure, this function returns an unspecified value. Any pattern in file numbers * should not be relied on. */ uint32_t send(uint32_t friend_number, uint32_t kind, uint64_t file_size, @@ -2017,7 +2047,7 @@ namespace file { * transfer request. * @param file_number The friend-specific file number the data received is * associated with. - * @param kind The meaning of the file to be sent. + * @param kind The meaning of the file that was sent. * @param file_size Size in bytes of the file the client wants to send, * UINT64_MAX if unknown or streaming. * @param filename Name of the file. Does not need to be the actual name. This @@ -2164,7 +2194,7 @@ namespace conference { * * This function creates a new text conference. * - * @return conference number on success, or UINT32_MAX on failure. + * @return conference number on success, or an unspecified value on failure. */ uint32_t new() { /** @@ -2279,7 +2309,7 @@ namespace conference { * @param cookie Received via the `${event invite}` event. * @param length The size of cookie. * - * @return conference number on success, UINT32_MAX on failure. + * @return conference number on success, an unspecified value on failure. */ uint32_t join(uint32_t friend_number, const uint8_t[length] cookie) { /** @@ -2431,6 +2461,32 @@ namespace conference { } } + /** + * Get the conference unique ID. + * + * If uid is NULL, this function has no effect. + * + * @param uid A memory region large enough to store $CONFERENCE_UID_SIZE bytes. + * + * @return true on success. + */ + const bool get_uid(uint32_t conference_number, uint8_t[CONFERENCE_UID_SIZE] uid); + + /** + * Return the conference number associated with the specified uid. + * + * @param uid A byte array containing the conference id ($CONFERENCE_UID_SIZE). + * + * @return the conference number on success, an unspecified value on failure. + */ + const uint32_t by_uid(const uint8_t[CONFERENCE_UID_SIZE] uid) { + NULL, + /** + * No conference with the given uid exists on the conference list. + */ + NOT_FOUND, + } + } @@ -2602,5 +2658,42 @@ inline namespace self { } #endif +typedef TOX_ERR_OPTIONS_NEW Tox_Err_Options_New; +typedef TOX_ERR_NEW Tox_Err_New; +typedef TOX_ERR_BOOTSTRAP Tox_Err_Bootstrap; +typedef TOX_ERR_SET_INFO Tox_Err_Set_Info; +typedef TOX_ERR_FRIEND_ADD Tox_Err_Friend_Add; +typedef TOX_ERR_FRIEND_DELETE Tox_Err_Friend_Delete; +typedef TOX_ERR_FRIEND_BY_PUBLIC_KEY Tox_Err_Friend_By_Public_Key; +typedef TOX_ERR_FRIEND_GET_PUBLIC_KEY Tox_Err_Friend_Get_Public_Key; +typedef TOX_ERR_FRIEND_GET_LAST_ONLINE Tox_Err_Friend_Get_Last_Online; +typedef TOX_ERR_FRIEND_QUERY Tox_Err_Friend_Query; +typedef TOX_ERR_SET_TYPING Tox_Err_Set_Typing; +typedef TOX_ERR_FRIEND_SEND_MESSAGE Tox_Err_Friend_Send_Message; +typedef TOX_ERR_FILE_CONTROL Tox_Err_File_Control; +typedef TOX_ERR_FILE_SEEK Tox_Err_File_Seek; +typedef TOX_ERR_FILE_GET Tox_Err_File_Get; +typedef TOX_ERR_FILE_SEND Tox_Err_File_Send; +typedef TOX_ERR_FILE_SEND_CHUNK Tox_Err_File_Send_Chunk; +typedef TOX_ERR_CONFERENCE_NEW Tox_Err_Conference_New; +typedef TOX_ERR_CONFERENCE_DELETE Tox_Err_Conference_Delete; +typedef TOX_ERR_CONFERENCE_PEER_QUERY Tox_Err_Conference_Peer_Query; +typedef TOX_ERR_CONFERENCE_BY_UID Tox_Err_Conference_By_Uid; +typedef TOX_ERR_CONFERENCE_INVITE Tox_Err_Conference_Invite; +typedef TOX_ERR_CONFERENCE_JOIN Tox_Err_Conference_Join; +typedef TOX_ERR_CONFERENCE_SEND_MESSAGE Tox_Err_Conference_Send_Message; +typedef TOX_ERR_CONFERENCE_TITLE Tox_Err_Conference_Title; +typedef TOX_ERR_CONFERENCE_GET_TYPE Tox_Err_Conference_Get_Type; +typedef TOX_ERR_FRIEND_CUSTOM_PACKET Tox_Err_Friend_Custom_Packet; +typedef TOX_ERR_GET_PORT Tox_Err_Get_Port; +typedef TOX_USER_STATUS Tox_User_Status; +typedef TOX_MESSAGE_TYPE Tox_Message_Type; +typedef TOX_PROXY_TYPE Tox_Proxy_Type; +typedef TOX_SAVEDATA_TYPE Tox_Savedata_Type; +typedef TOX_LOG_LEVEL Tox_Log_Level; +typedef TOX_CONNECTION Tox_Connection; +typedef TOX_FILE_CONTROL Tox_File_Control; +typedef TOX_CONFERENCE_TYPE Tox_Conference_Type; + #endif %} diff --git a/protocols/Tox/libtox/src/toxcore/tox.c b/protocols/Tox/libtox/src/toxcore/tox.c index 3db2bd35f3..cae2dcb36b 100644 --- a/protocols/Tox/libtox/src/toxcore/tox.c +++ b/protocols/Tox/libtox/src/toxcore/tox.c @@ -31,44 +31,47 @@ typedef struct Messenger Tox; #include "tox.h" +#include <assert.h> +#include <string.h> + #include "Messenger.h" #include "group.h" #include "logger.h" #include "../toxencryptsave/defines.h" -#define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} +#define SET_ERROR_PARAMETER(param, x) do { if (param) { *param = x; } } while (0) #if TOX_HASH_LENGTH != CRYPTO_SHA256_SIZE -#error TOX_HASH_LENGTH is assumed to be equal to CRYPTO_SHA256_SIZE +#error "TOX_HASH_LENGTH is assumed to be equal to CRYPTO_SHA256_SIZE" #endif #if FILE_ID_LENGTH != CRYPTO_SYMMETRIC_KEY_SIZE -#error FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE +#error "FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE" #endif #if TOX_FILE_ID_LENGTH != CRYPTO_SYMMETRIC_KEY_SIZE -#error TOX_FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE +#error "TOX_FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE" #endif #if TOX_FILE_ID_LENGTH != TOX_HASH_LENGTH -#error TOX_FILE_ID_LENGTH is assumed to be equal to TOX_HASH_LENGTH +#error "TOX_FILE_ID_LENGTH is assumed to be equal to TOX_HASH_LENGTH" #endif #if TOX_PUBLIC_KEY_SIZE != CRYPTO_PUBLIC_KEY_SIZE -#error TOX_PUBLIC_KEY_SIZE is assumed to be equal to CRYPTO_PUBLIC_KEY_SIZE +#error "TOX_PUBLIC_KEY_SIZE is assumed to be equal to CRYPTO_PUBLIC_KEY_SIZE" #endif #if TOX_SECRET_KEY_SIZE != CRYPTO_SECRET_KEY_SIZE -#error TOX_SECRET_KEY_SIZE is assumed to be equal to CRYPTO_SECRET_KEY_SIZE +#error "TOX_SECRET_KEY_SIZE is assumed to be equal to CRYPTO_SECRET_KEY_SIZE" #endif #if TOX_MAX_NAME_LENGTH != MAX_NAME_LENGTH -#error TOX_MAX_NAME_LENGTH is assumed to be equal to MAX_NAME_LENGTH +#error "TOX_MAX_NAME_LENGTH is assumed to be equal to MAX_NAME_LENGTH" #endif #if TOX_MAX_STATUS_MESSAGE_LENGTH != MAX_STATUSMESSAGE_LENGTH -#error TOX_MAX_STATUS_MESSAGE_LENGTH is assumed to be equal to MAX_STATUSMESSAGE_LENGTH +#error "TOX_MAX_STATUS_MESSAGE_LENGTH is assumed to be equal to MAX_STATUSMESSAGE_LENGTH" #endif @@ -78,92 +81,114 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch) } -Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error) +Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) { Messenger_Options m_options = {0}; bool load_savedata_sk = false, load_savedata_tox = false; + struct Tox_Options *default_options = nullptr; + if (options == nullptr) { - m_options.ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; - } else { - if (tox_options_get_savedata_type(options) != TOX_SAVEDATA_TYPE_NONE) { - if (tox_options_get_savedata_data(options) == nullptr || tox_options_get_savedata_length(options) == 0) { - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); + Tox_Err_Options_New err; + default_options = tox_options_new(&err); + + switch (err) { + case TOX_ERR_OPTIONS_NEW_OK: + break; + + case TOX_ERR_OPTIONS_NEW_MALLOC: + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); return nullptr; - } } + } - if (tox_options_get_savedata_type(options) == TOX_SAVEDATA_TYPE_SECRET_KEY) { - if (tox_options_get_savedata_length(options) != TOX_SECRET_KEY_SIZE) { - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); - return nullptr; - } + const struct Tox_Options *const opts = options != nullptr ? options : default_options; + assert(opts != nullptr); - load_savedata_sk = true; - } else if (tox_options_get_savedata_type(options) == TOX_SAVEDATA_TYPE_TOX_SAVE) { - if (tox_options_get_savedata_length(options) < TOX_ENC_SAVE_MAGIC_LENGTH) { - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); - return nullptr; - } + if (tox_options_get_savedata_type(opts) != TOX_SAVEDATA_TYPE_NONE) { + if (tox_options_get_savedata_data(opts) == nullptr || tox_options_get_savedata_length(opts) == 0) { + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); + tox_options_free(default_options); + return nullptr; + } + } - if (crypto_memcmp(tox_options_get_savedata_data(options), TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) { - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED); - return nullptr; - } + if (tox_options_get_savedata_type(opts) == TOX_SAVEDATA_TYPE_SECRET_KEY) { + if (tox_options_get_savedata_length(opts) != TOX_SECRET_KEY_SIZE) { + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); + tox_options_free(default_options); + return nullptr; + } - load_savedata_tox = true; + load_savedata_sk = true; + } else if (tox_options_get_savedata_type(opts) == TOX_SAVEDATA_TYPE_TOX_SAVE) { + if (tox_options_get_savedata_length(opts) < TOX_ENC_SAVE_MAGIC_LENGTH) { + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); + tox_options_free(default_options); + return nullptr; } - m_options.ipv6enabled = tox_options_get_ipv6_enabled(options); - m_options.udp_disabled = !tox_options_get_udp_enabled(options); - m_options.port_range[0] = tox_options_get_start_port(options); - m_options.port_range[1] = tox_options_get_end_port(options); - m_options.tcp_server_port = tox_options_get_tcp_port(options); - m_options.hole_punching_enabled = tox_options_get_hole_punching_enabled(options); - m_options.local_discovery_enabled = tox_options_get_local_discovery_enabled(options); + if (crypto_memcmp(tox_options_get_savedata_data(opts), TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) { + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED); + tox_options_free(default_options); + return nullptr; + } - m_options.log_callback = (logger_cb *)tox_options_get_log_callback(options); - m_options.log_user_data = tox_options_get_log_user_data(options); + load_savedata_tox = true; + } - switch (tox_options_get_proxy_type(options)) { - case TOX_PROXY_TYPE_HTTP: - m_options.proxy_info.proxy_type = TCP_PROXY_HTTP; - break; + m_options.ipv6enabled = tox_options_get_ipv6_enabled(opts); + m_options.udp_disabled = !tox_options_get_udp_enabled(opts); + m_options.port_range[0] = tox_options_get_start_port(opts); + m_options.port_range[1] = tox_options_get_end_port(opts); + m_options.tcp_server_port = tox_options_get_tcp_port(opts); + m_options.hole_punching_enabled = tox_options_get_hole_punching_enabled(opts); + m_options.local_discovery_enabled = tox_options_get_local_discovery_enabled(opts); - case TOX_PROXY_TYPE_SOCKS5: - m_options.proxy_info.proxy_type = TCP_PROXY_SOCKS5; - break; + m_options.log_callback = (logger_cb *)tox_options_get_log_callback(opts); + m_options.log_user_data = tox_options_get_log_user_data(opts); - case TOX_PROXY_TYPE_NONE: - m_options.proxy_info.proxy_type = TCP_PROXY_NONE; - break; + switch (tox_options_get_proxy_type(opts)) { + case TOX_PROXY_TYPE_HTTP: + m_options.proxy_info.proxy_type = TCP_PROXY_HTTP; + break; - default: - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_TYPE); - return nullptr; - } + case TOX_PROXY_TYPE_SOCKS5: + m_options.proxy_info.proxy_type = TCP_PROXY_SOCKS5; + break; - if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) { - if (tox_options_get_proxy_port(options) == 0) { - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_PORT); - return nullptr; - } + case TOX_PROXY_TYPE_NONE: + m_options.proxy_info.proxy_type = TCP_PROXY_NONE; + break; + + default: + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_TYPE); + tox_options_free(default_options); + return nullptr; + } - ip_init(&m_options.proxy_info.ip_port.ip, m_options.ipv6enabled); + if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) { + if (tox_options_get_proxy_port(opts) == 0) { + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_PORT); + tox_options_free(default_options); + return nullptr; + } - if (m_options.ipv6enabled) { - m_options.proxy_info.ip_port.ip.family = TOX_AF_UNSPEC; - } + ip_init(&m_options.proxy_info.ip_port.ip, m_options.ipv6enabled); - if (addr_resolve_or_parse_ip(tox_options_get_proxy_host(options), &m_options.proxy_info.ip_port.ip, nullptr) == 0) { - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST); - // TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain. - return nullptr; - } + if (m_options.ipv6enabled) { + m_options.proxy_info.ip_port.ip.family = net_family_unspec; + } - m_options.proxy_info.ip_port.port = net_htons(tox_options_get_proxy_port(options)); + if (addr_resolve_or_parse_ip(tox_options_get_proxy_host(opts), &m_options.proxy_info.ip_port.ip, nullptr) == 0) { + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST); + // TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain. + tox_options_free(default_options); + return nullptr; } + + m_options.proxy_info.ip_port.port = net_htons(tox_options_get_proxy_port(opts)); } unsigned int m_error; @@ -180,19 +205,21 @@ Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error) SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); } + tox_options_free(default_options); return nullptr; } if (load_savedata_tox - && messenger_load(m, tox_options_get_savedata_data(options), tox_options_get_savedata_length(options)) == -1) { + && messenger_load(m, tox_options_get_savedata_data(opts), tox_options_get_savedata_length(opts)) == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); } else if (load_savedata_sk) { - load_secret_key(m->net_crypto, tox_options_get_savedata_data(options)); + load_secret_key(m->net_crypto, tox_options_get_savedata_data(opts)); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK); } else { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK); } + tox_options_free(default_options); return m; } @@ -221,9 +248,9 @@ void tox_get_savedata(const Tox *tox, uint8_t *savedata) } } -bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error) +bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, Tox_Err_Bootstrap *error) { - if (!address || !public_key) { + if (!host || !public_key) { SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_NULL); return 0; } @@ -235,7 +262,7 @@ bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t * IP_Port *root; - int32_t count = net_getipport(address, &root, TOX_SOCK_DGRAM); + int32_t count = net_getipport(host, &root, TOX_SOCK_DGRAM); if (count == -1) { net_freeipport(root); @@ -245,12 +272,12 @@ bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t * unsigned int i; - for (i = 0; i < count; i++) { + for (i = 0; i < count; ++i) { root[i].port = net_htons(port); Messenger *m = tox; onion_add_bs_path_node(m->onion_c, root[i], public_key); - DHT_bootstrap(m->dht, root[i], public_key); + dht_bootstrap(m->dht, root[i], public_key); } net_freeipport(root); @@ -264,10 +291,10 @@ bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t * return 0; } -bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, - TOX_ERR_BOOTSTRAP *error) +bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, + Tox_Err_Bootstrap *error) { - if (!address || !public_key) { + if (!host || !public_key) { SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_NULL); return 0; } @@ -279,7 +306,7 @@ bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8 IP_Port *root; - int32_t count = net_getipport(address, &root, TOX_SOCK_STREAM); + int32_t count = net_getipport(host, &root, TOX_SOCK_STREAM); if (count == -1) { net_freeipport(root); @@ -289,7 +316,7 @@ bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8 unsigned int i; - for (i = 0; i < count; i++) { + for (i = 0; i < count; ++i) { root[i].port = net_htons(port); Messenger *m = tox; @@ -307,7 +334,7 @@ bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8 return 0; } -TOX_CONNECTION tox_self_get_connection_status(const Tox *tox) +Tox_Connection tox_self_get_connection_status(const Tox *tox) { const Messenger *m = tox; @@ -328,7 +355,7 @@ TOX_CONNECTION tox_self_get_connection_status(const Tox *tox) void tox_callback_self_connection_status(Tox *tox, tox_self_connection_status_cb *callback) { Messenger *m = tox; - m_callback_core_connection(m, (void (*)(Messenger *, unsigned int, void *))callback); + m_callback_core_connection(m, (m_self_connection_status_cb *)callback); } uint32_t tox_iteration_interval(const Tox *tox) @@ -382,7 +409,7 @@ void tox_self_get_secret_key(const Tox *tox, uint8_t *secret_key) } } -bool tox_self_set_name(Tox *tox, const uint8_t *name, size_t length, TOX_ERR_SET_INFO *error) +bool tox_self_set_name(Tox *tox, const uint8_t *name, size_t length, Tox_Err_Set_Info *error) { if (!name && length != 0) { SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_NULL); @@ -416,7 +443,7 @@ void tox_self_get_name(const Tox *tox, uint8_t *name) } } -bool tox_self_set_status_message(Tox *tox, const uint8_t *status_message, size_t length, TOX_ERR_SET_INFO *error) +bool tox_self_set_status_message(Tox *tox, const uint8_t *status_message, size_t length, Tox_Err_Set_Info *error) { if (!status_message && length != 0) { SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_NULL); @@ -448,20 +475,20 @@ void tox_self_get_status_message(const Tox *tox, uint8_t *status_message) } } -void tox_self_set_status(Tox *tox, TOX_USER_STATUS status) +void tox_self_set_status(Tox *tox, Tox_User_Status status) { Messenger *m = tox; m_set_userstatus(m, status); } -TOX_USER_STATUS tox_self_get_status(const Tox *tox) +Tox_User_Status tox_self_get_status(const Tox *tox) { const Messenger *m = tox; const uint8_t status = m_get_self_userstatus(m); - return (TOX_USER_STATUS)status; + return (Tox_User_Status)status; } -static void set_friend_error(int32_t ret, TOX_ERR_FRIEND_ADD *error) +static void set_friend_error(int32_t ret, Tox_Err_Friend_Add *error) { switch (ret) { case FAERR_TOOLONG: @@ -491,11 +518,16 @@ static void set_friend_error(int32_t ret, TOX_ERR_FRIEND_ADD *error) case FAERR_NOMEM: SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_MALLOC); break; + + default: + /* can't happen */ + assert(!"impossible: unknown friend-add error"); + break; } } uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message, size_t length, - TOX_ERR_FRIEND_ADD *error) + Tox_Err_Friend_Add *error) { if (!address || !message) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_NULL); @@ -514,7 +546,7 @@ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message return UINT32_MAX; } -uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_ADD *error) +uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, Tox_Err_Friend_Add *error) { if (!public_key) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_NULL); @@ -533,7 +565,7 @@ uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, TOX_ERR_F return UINT32_MAX; } -bool tox_friend_delete(Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_DELETE *error) +bool tox_friend_delete(Tox *tox, uint32_t friend_number, Tox_Err_Friend_Delete *error) { Messenger *m = tox; int ret = m_delfriend(m, friend_number); @@ -548,7 +580,7 @@ bool tox_friend_delete(Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_DELETE * return 1; } -uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_BY_PUBLIC_KEY *error) +uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, Tox_Err_Friend_By_Public_Key *error) { if (!public_key) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL); @@ -568,7 +600,7 @@ uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, TOX } bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *public_key, - TOX_ERR_FRIEND_GET_PUBLIC_KEY *error) + Tox_Err_Friend_Get_Public_Key *error) { if (!public_key) { return 0; @@ -591,13 +623,13 @@ bool tox_friend_exists(const Tox *tox, uint32_t friend_number) return m_friend_exists(m, friend_number); } -uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_GET_LAST_ONLINE *error) +uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Get_Last_Online *error) { const Messenger *m = tox; uint64_t timestamp = m_get_last_online(m, friend_number); if (timestamp == UINT64_MAX) { - SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND) + SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND); return UINT64_MAX; } @@ -620,7 +652,7 @@ void tox_self_get_friend_list(const Tox *tox, uint32_t *friend_list) } } -size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error) +size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error) { const Messenger *m = tox; int ret = m_get_name_size(m, friend_number); @@ -634,7 +666,7 @@ size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, TOX_ERR_ return ret; } -bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, TOX_ERR_FRIEND_QUERY *error) +bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, Tox_Err_Friend_Query *error) { if (!name) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_NULL); @@ -659,7 +691,7 @@ void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *callback) m_callback_namechange(m, callback); } -size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error) +size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error) { const Messenger *m = tox; int ret = m_get_statusmessage_size(m, friend_number); @@ -674,7 +706,7 @@ size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number } bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8_t *status_message, - TOX_ERR_FRIEND_QUERY *error) + Tox_Err_Friend_Query *error) { if (!status_message) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_NULL); @@ -700,7 +732,7 @@ void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb * m_callback_statusmessage(m, callback); } -TOX_USER_STATUS tox_friend_get_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error) +Tox_User_Status tox_friend_get_status(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error) { const Messenger *m = tox; @@ -708,20 +740,20 @@ TOX_USER_STATUS tox_friend_get_status(const Tox *tox, uint32_t friend_number, TO if (ret == USERSTATUS_INVALID) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND); - return (TOX_USER_STATUS)(TOX_USER_STATUS_BUSY + 1); + return (Tox_User_Status)(TOX_USER_STATUS_BUSY + 1); } SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK); - return (TOX_USER_STATUS)ret; + return (Tox_User_Status)ret; } void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *callback) { Messenger *m = tox; - m_callback_userstatus(m, (void (*)(Messenger *, uint32_t, unsigned int, void *))callback); + m_callback_userstatus(m, (m_friend_status_cb *)callback); } -TOX_CONNECTION tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error) +Tox_Connection tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error) { const Messenger *m = tox; @@ -733,16 +765,16 @@ TOX_CONNECTION tox_friend_get_connection_status(const Tox *tox, uint32_t friend_ } SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK); - return (TOX_CONNECTION)ret; + return (Tox_Connection)ret; } void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_status_cb *callback) { Messenger *m = tox; - m_callback_connectionstatus(m, (void (*)(Messenger *, uint32_t, unsigned int, void *))callback); + m_callback_connectionstatus(m, (m_friend_connection_status_cb *)callback); } -bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error) +bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error) { const Messenger *m = tox; int ret = m_get_istyping(m, friend_number); @@ -762,7 +794,7 @@ void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *callback) m_callback_typingchange(m, callback); } -bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool typing, TOX_ERR_SET_TYPING *error) +bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool typing, Tox_Err_Set_Typing *error) { Messenger *m = tox; @@ -775,7 +807,7 @@ bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool typing, TOX_ERR_ return 1; } -static void set_message_error(int ret, TOX_ERR_FRIEND_SEND_MESSAGE *error) +static void set_message_error(int ret, Tox_Err_Friend_Send_Message *error) { switch (ret) { case 0: @@ -799,13 +831,15 @@ static void set_message_error(int ret, TOX_ERR_FRIEND_SEND_MESSAGE *error) break; case -5: + default: /* can't happen */ + assert(!"impossible: unknown send-message error"); break; } } -uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message, - size_t length, TOX_ERR_FRIEND_SEND_MESSAGE *error) +uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type, const uint8_t *message, + size_t length, Tox_Err_Friend_Send_Message *error) { if (!message) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_NULL); @@ -838,7 +872,7 @@ void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *callback) void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *callback) { Messenger *m = tox; - m_callback_friendmessage(m, (void (*)(Messenger *, uint32_t, unsigned int, const uint8_t *, size_t, void *))callback); + m_callback_friendmessage(m, (m_friend_message_cb *)callback); } bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length) @@ -851,8 +885,8 @@ bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length) return 1; } -bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control, - TOX_ERR_FILE_CONTROL *error) +bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control, + Tox_Err_File_Control *error) { Messenger *m = tox; int ret = file_control(m, friend_number, file_number, control); @@ -901,7 +935,7 @@ bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TO } bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, - TOX_ERR_FILE_SEEK *error) + Tox_Err_File_Seek *error) { Messenger *m = tox; int ret = file_seek(m, friend_number, file_number, position); @@ -945,11 +979,11 @@ bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint6 void tox_callback_file_recv_control(Tox *tox, tox_file_recv_control_cb *callback) { Messenger *m = tox; - callback_file_control(m, (void (*)(Messenger *, uint32_t, uint32_t, unsigned int, void *))callback); + callback_file_control(m, (m_file_recv_control_cb *)callback); } bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_number, uint8_t *file_id, - TOX_ERR_FILE_GET *error) + Tox_Err_File_Get *error) { if (!file_id) { SET_ERROR_PARAMETER(error, TOX_ERR_FILE_GET_NULL); @@ -974,7 +1008,7 @@ bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_ } uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t *file_id, - const uint8_t *filename, size_t filename_length, TOX_ERR_FILE_SEND *error) + const uint8_t *filename, size_t filename_length, Tox_Err_File_Send *error) { if (filename_length && !filename) { SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_NULL); @@ -1020,7 +1054,7 @@ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t } bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data, - size_t length, TOX_ERR_FILE_SEND_CHUNK *error) + size_t length, Tox_Err_File_Send_Chunk *error) { Messenger *m = tox; int ret = file_data(m, friend_number, file_number, position, data, length); @@ -1085,17 +1119,13 @@ void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *callback) void tox_callback_conference_invite(Tox *tox, tox_conference_invite_cb *callback) { Messenger *m = tox; - g_callback_group_invite((Group_Chats *)m->conferences_object, (void (*)(Messenger * m, uint32_t, int, const uint8_t *, - size_t, - void *))callback); + g_callback_group_invite((Group_Chats *)m->conferences_object, (g_conference_invite_cb *)callback); } void tox_callback_conference_message(Tox *tox, tox_conference_message_cb *callback) { Messenger *m = tox; - g_callback_group_message((Group_Chats *)m->conferences_object, (void (*)(Messenger * m, uint32_t, uint32_t, int, - const uint8_t *, - size_t, void *))callback); + g_callback_group_message((Group_Chats *)m->conferences_object, (g_conference_message_cb *)callback); } void tox_callback_conference_title(Tox *tox, tox_conference_title_cb *callback) @@ -1116,7 +1146,7 @@ void tox_callback_conference_peer_list_changed(Tox *tox, tox_conference_peer_lis g_callback_peer_list_changed((Group_Chats *)m->conferences_object, callback); } -uint32_t tox_conference_new(Tox *tox, TOX_ERR_CONFERENCE_NEW *error) +uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error) { Messenger *m = tox; int ret = add_groupchat((Group_Chats *)m->conferences_object, GROUPCHAT_TYPE_TEXT); @@ -1130,7 +1160,7 @@ uint32_t tox_conference_new(Tox *tox, TOX_ERR_CONFERENCE_NEW *error) return ret; } -bool tox_conference_delete(Tox *tox, uint32_t conference_number, TOX_ERR_CONFERENCE_DELETE *error) +bool tox_conference_delete(Tox *tox, uint32_t conference_number, Tox_Err_Conference_Delete *error) { Messenger *m = tox; int ret = del_groupchat((Group_Chats *)m->conferences_object, conference_number); @@ -1144,7 +1174,7 @@ bool tox_conference_delete(Tox *tox, uint32_t conference_number, TOX_ERR_CONFERE return true; } -uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, TOX_ERR_CONFERENCE_PEER_QUERY *error) +uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Peer_Query *error) { const Messenger *m = tox; int ret = group_number_peers((Group_Chats *)m->conferences_object, conference_number); @@ -1159,7 +1189,7 @@ uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, T } size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_number, uint32_t peer_number, - TOX_ERR_CONFERENCE_PEER_QUERY *error) + Tox_Err_Conference_Peer_Query *error) { const Messenger *m = tox; int ret = group_peername_size((Group_Chats *)m->conferences_object, conference_number, peer_number); @@ -1179,7 +1209,7 @@ size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_num } bool tox_conference_peer_get_name(const Tox *tox, uint32_t conference_number, uint32_t peer_number, uint8_t *name, - TOX_ERR_CONFERENCE_PEER_QUERY *error) + Tox_Err_Conference_Peer_Query *error) { const Messenger *m = tox; int ret = group_peername((Group_Chats *)m->conferences_object, conference_number, peer_number, name); @@ -1199,7 +1229,7 @@ bool tox_conference_peer_get_name(const Tox *tox, uint32_t conference_number, ui } bool tox_conference_peer_get_public_key(const Tox *tox, uint32_t conference_number, uint32_t peer_number, - uint8_t *public_key, TOX_ERR_CONFERENCE_PEER_QUERY *error) + uint8_t *public_key, Tox_Err_Conference_Peer_Query *error) { const Messenger *m = tox; int ret = group_peer_pubkey((Group_Chats *)m->conferences_object, conference_number, peer_number, public_key); @@ -1219,7 +1249,7 @@ bool tox_conference_peer_get_public_key(const Tox *tox, uint32_t conference_numb } bool tox_conference_peer_number_is_ours(const Tox *tox, uint32_t conference_number, uint32_t peer_number, - TOX_ERR_CONFERENCE_PEER_QUERY *error) + Tox_Err_Conference_Peer_Query *error) { const Messenger *m = tox; int ret = group_peernumber_is_ours((Group_Chats *)m->conferences_object, conference_number, peer_number); @@ -1243,7 +1273,7 @@ bool tox_conference_peer_number_is_ours(const Tox *tox, uint32_t conference_numb } bool tox_conference_invite(Tox *tox, uint32_t friend_number, uint32_t conference_number, - TOX_ERR_CONFERENCE_INVITE *error) + Tox_Err_Conference_Invite *error) { Messenger *m = tox; int ret = invite_friend((Group_Chats *)m->conferences_object, friend_number, conference_number); @@ -1263,7 +1293,7 @@ bool tox_conference_invite(Tox *tox, uint32_t friend_number, uint32_t conference } uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *cookie, size_t length, - TOX_ERR_CONFERENCE_JOIN *error) + Tox_Err_Conference_Join *error) { Messenger *m = tox; int ret = join_groupchat((Group_Chats *)m->conferences_object, friend_number, GROUPCHAT_TYPE_TEXT, cookie, length); @@ -1298,8 +1328,8 @@ uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *co return ret; } -bool tox_conference_send_message(Tox *tox, uint32_t conference_number, TOX_MESSAGE_TYPE type, const uint8_t *message, - size_t length, TOX_ERR_CONFERENCE_SEND_MESSAGE *error) +bool tox_conference_send_message(Tox *tox, uint32_t conference_number, Tox_Message_Type type, const uint8_t *message, + size_t length, Tox_Err_Conference_Send_Message *error) { Messenger *m = tox; int ret = 0; @@ -1332,7 +1362,7 @@ bool tox_conference_send_message(Tox *tox, uint32_t conference_number, TOX_MESSA return true; } -size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number, TOX_ERR_CONFERENCE_TITLE *error) +size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Title *error) { const Messenger *m = tox; int ret = group_title_get_size((Group_Chats *)m->conferences_object, conference_number); @@ -1352,7 +1382,7 @@ size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number, } bool tox_conference_get_title(const Tox *tox, uint32_t conference_number, uint8_t *title, - TOX_ERR_CONFERENCE_TITLE *error) + Tox_Err_Conference_Title *error) { const Messenger *m = tox; int ret = group_title_get((Group_Chats *)m->conferences_object, conference_number, title); @@ -1372,7 +1402,7 @@ bool tox_conference_get_title(const Tox *tox, uint32_t conference_number, uint8_ } bool tox_conference_set_title(Tox *tox, uint32_t conference_number, const uint8_t *title, size_t length, - TOX_ERR_CONFERENCE_TITLE *error) + Tox_Err_Conference_Title *error) { Messenger *m = tox; int ret = group_title_send((Group_Chats *)m->conferences_object, conference_number, title, length); @@ -1408,22 +1438,47 @@ void tox_conference_get_chatlist(const Tox *tox, uint32_t *chatlist) copy_chatlist((Group_Chats *)m->conferences_object, chatlist, list_size); } -TOX_CONFERENCE_TYPE tox_conference_get_type(const Tox *tox, uint32_t conference_number, - TOX_ERR_CONFERENCE_GET_TYPE *error) +Tox_Conference_Type tox_conference_get_type(const Tox *tox, uint32_t conference_number, + Tox_Err_Conference_Get_Type *error) { const Messenger *m = tox; int ret = group_get_type((Group_Chats *)m->conferences_object, conference_number); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND); - return (TOX_CONFERENCE_TYPE)ret; + return (Tox_Conference_Type)ret; } SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_GET_TYPE_OK); - return (TOX_CONFERENCE_TYPE)ret; + return (Tox_Conference_Type)ret; +} + +bool tox_conference_get_uid(const Tox *tox, uint32_t conference_number, uint8_t *uid /* TOX_CONFERENCE_ID_SIZE bytes */) +{ + const Messenger *m = tox; + return conference_get_uid((Group_Chats *)m->conferences_object, conference_number, uid); +} + +uint32_t tox_conference_by_uid(const Tox *tox, const uint8_t *uid, Tox_Err_Conference_By_Uid *error) +{ + if (!uid) { + SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_UID_NULL); + return UINT32_MAX; + } + + const Messenger *m = tox; + int32_t ret = conference_by_uid((Group_Chats *)m->conferences_object, uid); + + if (ret == -1) { + SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_UID_NOT_FOUND); + return UINT32_MAX; + } + + SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_UID_OK); + return ret; } -static void set_custom_packet_error(int ret, TOX_ERR_FRIEND_CUSTOM_PACKET *error) +static void set_custom_packet_error(int ret, Tox_Err_Friend_Custom_Packet *error) { switch (ret) { case 0: @@ -1453,7 +1508,7 @@ static void set_custom_packet_error(int ret, TOX_ERR_FRIEND_CUSTOM_PACKET *error } bool tox_friend_send_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, - TOX_ERR_FRIEND_CUSTOM_PACKET *error) + Tox_Err_Friend_Custom_Packet *error) { if (!data) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_NULL); @@ -1490,7 +1545,7 @@ void tox_callback_friend_lossy_packet(Tox *tox, tox_friend_lossy_packet_cb *call } bool tox_friend_send_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, - TOX_ERR_FRIEND_CUSTOM_PACKET *error) + Tox_Err_Friend_Custom_Packet *error) { if (!data) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_NULL); @@ -1529,7 +1584,7 @@ void tox_self_get_dht_id(const Tox *tox, uint8_t *dht_id) } } -uint16_t tox_self_get_udp_port(const Tox *tox, TOX_ERR_GET_PORT *error) +uint16_t tox_self_get_udp_port(const Tox *tox, Tox_Err_Get_Port *error) { const Messenger *m = tox; uint16_t port = net_htons(net_port(m->net)); @@ -1543,7 +1598,7 @@ uint16_t tox_self_get_udp_port(const Tox *tox, TOX_ERR_GET_PORT *error) return port; } -uint16_t tox_self_get_tcp_port(const Tox *tox, TOX_ERR_GET_PORT *error) +uint16_t tox_self_get_tcp_port(const Tox *tox, Tox_Err_Get_Port *error) { const Messenger *m = tox; diff --git a/protocols/Tox/libtox/src/toxcore/tox.h b/protocols/Tox/libtox/src/toxcore/tox.h index d58340950d..6a4df16dce 100644 --- a/protocols/Tox/libtox/src/toxcore/tox.h +++ b/protocols/Tox/libtox/src/toxcore/tox.h @@ -41,7 +41,8 @@ extern "C" { -/** \page core Public core API for Tox clients. +/** + * @page core Public core API for Tox clients. * * Every function that can fail takes a function-specific error code pointer * that can be used to diagnose problems with the Tox state or the function @@ -79,7 +80,8 @@ extern "C" { * Integer constants and the memory layout of publicly exposed structs are not * part of the ABI. */ -/** \subsection events Events and callbacks +/** + * @subsection events Events and callbacks * * Events are handled by callbacks. One callback can be registered per event. * All events have a callback function type named `tox_{event}_cb` and a @@ -101,7 +103,8 @@ extern "C" { * receive that pointer as argument when they are called. They can each have * their own user data pointer of their own type. */ -/** \subsection threading Threading implications +/** + * @subsection threading Threading implications * * It is possible to run multiple concurrent threads with a Tox instance for * each thread. It is also possible to run all Tox instances in the same thread. @@ -123,12 +126,12 @@ extern "C" { * * E.g. to get the current nickname, one would write * - * \code + * @code * size_t length = tox_self_get_name_size(tox); * uint8_t *name = malloc(length); * if (!name) abort(); * tox_self_get_name(tox, name); - * \endcode + * @endcode * * If any other thread calls tox_self_set_name while this thread is allocating * memory, the length may have become invalid, and the call to @@ -180,7 +183,7 @@ uint32_t tox_version_minor(void); * The patch or revision number. Incremented when bugfixes are applied without * changing any functionality or API or ABI. */ -#define TOX_VERSION_PATCH 2 +#define TOX_VERSION_PATCH 3 uint32_t tox_version_patch(void); @@ -246,6 +249,13 @@ uint32_t tox_public_key_size(void); uint32_t tox_secret_key_size(void); /** + * The size of a Tox Conference unique id in bytes. + */ +#define TOX_CONFERENCE_UID_SIZE 32 + +uint32_t tox_conference_uid_size(void); + +/** * The size of the nospam in bytes when written in a Tox address. */ #define TOX_NOSPAM_SIZE (sizeof(uint32_t)) @@ -332,6 +342,18 @@ uint32_t tox_file_id_length(void); uint32_t tox_max_filename_length(void); +/** + * Maximum length of a hostname, e.g. proxy or bootstrap node names. + * + * This length includes the NUL byte. Hostnames are NUL-terminated C strings, so + * they are 255 characters plus one NUL byte. + * + * @deprecated The macro will be removed in 0.3.0. Use the function instead. + */ +#define TOX_MAX_HOSTNAME_LENGTH 256 + +uint32_t tox_max_hostname_length(void); + /******************************************************************************* * @@ -526,7 +548,9 @@ struct Tox_Options { * * Setting this to false will force Tox to use TCP only. Communications will * need to be relayed through a TCP relay node, potentially slowing them down. - * Disabling UDP support is necessary when using anonymous proxies or Tor. + * + * If a proxy is enabled, UDP will be disabled if either toxcore or the + * proxy don't support proxying UDP messages. */ bool udp_enabled; @@ -549,8 +573,8 @@ struct Tox_Options { * The IP address or DNS name of the proxy to be used. * * If used, this must be non-NULL and be a valid DNS name. The name must not - * exceed 255 characters, and be in a NUL-terminated C string format - * (255 chars + 1 NUL byte). + * exceed TOX_MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C string + * format (TOX_MAX_HOSTNAME_LENGTH includes the NUL byte). * * This member is ignored (it can be NULL) if proxy_type is TOX_PROXY_TYPE_NONE. * @@ -891,7 +915,7 @@ typedef enum TOX_ERR_BOOTSTRAP { TOX_ERR_BOOTSTRAP_NULL, /** - * The address could not be resolved to an IP address, or the IP address + * The hostname could not be resolved to an IP address, or the IP address * passed was invalid. */ TOX_ERR_BOOTSTRAP_BAD_HOST, @@ -911,14 +935,15 @@ typedef enum TOX_ERR_BOOTSTRAP { * This function will attempt to connect to the node using UDP. You must use * this function even if Tox_Options.udp_enabled was set to false. * - * @param address The hostname or IP address (IPv4 or IPv6) of the node. + * @param host The hostname or IP address (IPv4 or IPv6) of the node. Must be + * at most TOX_MAX_HOSTNAME_LENGTH chars, including the NUL byte. * @param port The port on the host on which the bootstrap Tox instance is * listening. * @param public_key The long term public key of the bootstrap node * (TOX_PUBLIC_KEY_SIZE bytes). * @return true on success. */ -bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error); +bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error); /** * Adds additional host:port pair as TCP relay. @@ -927,14 +952,14 @@ bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t * * the same bootstrap node, or to add TCP relays without using them as * bootstrap nodes. * - * @param address The hostname or IP address (IPv4 or IPv6) of the TCP relay. + * @param host The hostname or IP address (IPv4 or IPv6) of the TCP relay. + * Must be at most TOX_MAX_HOSTNAME_LENGTH chars, including the NUL byte. * @param port The port on the host on which the TCP relay is listening. * @param public_key The long term public key of the TCP relay * (TOX_PUBLIC_KEY_SIZE bytes). * @return true on success. */ -bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, - TOX_ERR_BOOTSTRAP *error); +bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error); /** * Protocols that can be used to connect to the network or friends. @@ -1254,7 +1279,7 @@ typedef enum TOX_ERR_FRIEND_ADD { * @param message The message that will be sent along with the friend request. * @param length The length of the data byte array. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. */ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message, size_t length, TOX_ERR_FRIEND_ADD *error); @@ -1274,7 +1299,7 @@ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message * @param public_key A byte array of length TOX_PUBLIC_KEY_SIZE containing the * Public Key (not the Address) of the friend to add. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. * @see tox_friend_add for a more detailed description of friend numbers. */ uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_ADD *error); @@ -1339,7 +1364,7 @@ typedef enum TOX_ERR_FRIEND_BY_PUBLIC_KEY { /** * Return the friend number associated with that Public Key. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. * @param public_key A byte array containing the Public Key. */ uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_BY_PUBLIC_KEY *error); @@ -1818,6 +1843,14 @@ void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *callback); */ bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length); +/** + * A list of pre-defined file kinds. Toxcore itself does not behave + * differently for different file kinds. These are a hint to the client + * telling it what use the sender intended for the file. The `kind` parameter + * in the send function and recv callback are `uint32_t`, not TOX_FILE_KIND, because + * clients can invent their own file kind. Unknown file kinds should be + * treated as TOX_FILE_KIND_DATA. + */ enum TOX_FILE_KIND { /** @@ -2149,7 +2182,7 @@ typedef enum TOX_ERR_FILE_SEND { * * @return A file number used as an identifier in subsequent callbacks. This * number is per friend. File numbers are reused after a transfer terminates. - * On failure, this function returns UINT32_MAX. Any pattern in file numbers + * On failure, this function returns an unspecified value. Any pattern in file numbers * should not be relied on. */ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t *file_id, @@ -2280,7 +2313,7 @@ void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *callba * transfer request. * @param file_number The friend-specific file number the data received is * associated with. - * @param kind The meaning of the file to be sent. + * @param kind The meaning of the file that was sent. * @param file_size Size in bytes of the file the client wants to send, * UINT64_MAX if unknown or streaming. * @param filename Name of the file. Does not need to be the actual name. This @@ -2463,7 +2496,7 @@ typedef enum TOX_ERR_CONFERENCE_NEW { * * This function creates a new text conference. * - * @return conference number on success, or UINT32_MAX on failure. + * @return conference number on success, or an unspecified value on failure. */ uint32_t tox_conference_new(Tox *tox, TOX_ERR_CONFERENCE_NEW *error); @@ -2632,7 +2665,7 @@ typedef enum TOX_ERR_CONFERENCE_JOIN { * @param cookie Received via the `conference_invite` event. * @param length The size of cookie. * - * @return conference number on success, UINT32_MAX on failure. + * @return conference number on success, an unspecified value on failure. */ uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *cookie, size_t length, TOX_ERR_CONFERENCE_JOIN *error); @@ -2781,6 +2814,46 @@ typedef enum TOX_ERR_CONFERENCE_GET_TYPE { TOX_CONFERENCE_TYPE tox_conference_get_type(const Tox *tox, uint32_t conference_number, TOX_ERR_CONFERENCE_GET_TYPE *error); +/** + * Get the conference unique ID. + * + * If uid is NULL, this function has no effect. + * + * @param uid A memory region large enough to store TOX_CONFERENCE_UID_SIZE bytes. + * + * @return true on success. + */ +bool tox_conference_get_uid(const Tox *tox, uint32_t conference_number, uint8_t *uid); + +typedef enum TOX_ERR_CONFERENCE_BY_UID { + + /** + * The function returned successfully. + */ + TOX_ERR_CONFERENCE_BY_UID_OK, + + /** + * One of the arguments to the function was NULL when it was not expected. + */ + TOX_ERR_CONFERENCE_BY_UID_NULL, + + /** + * No conference with the given uid exists on the conference list. + */ + TOX_ERR_CONFERENCE_BY_UID_NOT_FOUND, + +} TOX_ERR_CONFERENCE_BY_UID; + + +/** + * Return the conference number associated with the specified uid. + * + * @param uid A byte array containing the conference id (TOX_CONFERENCE_UID_SIZE). + * + * @return the conference number on success, an unspecified value on failure. + */ +uint32_t tox_conference_by_uid(const Tox *tox, const uint8_t *uid, TOX_ERR_CONFERENCE_BY_UID *error); + /******************************************************************************* * @@ -2961,4 +3034,41 @@ uint16_t tox_self_get_tcp_port(const Tox *tox, TOX_ERR_GET_PORT *error); } #endif +typedef TOX_ERR_OPTIONS_NEW Tox_Err_Options_New; +typedef TOX_ERR_NEW Tox_Err_New; +typedef TOX_ERR_BOOTSTRAP Tox_Err_Bootstrap; +typedef TOX_ERR_SET_INFO Tox_Err_Set_Info; +typedef TOX_ERR_FRIEND_ADD Tox_Err_Friend_Add; +typedef TOX_ERR_FRIEND_DELETE Tox_Err_Friend_Delete; +typedef TOX_ERR_FRIEND_BY_PUBLIC_KEY Tox_Err_Friend_By_Public_Key; +typedef TOX_ERR_FRIEND_GET_PUBLIC_KEY Tox_Err_Friend_Get_Public_Key; +typedef TOX_ERR_FRIEND_GET_LAST_ONLINE Tox_Err_Friend_Get_Last_Online; +typedef TOX_ERR_FRIEND_QUERY Tox_Err_Friend_Query; +typedef TOX_ERR_SET_TYPING Tox_Err_Set_Typing; +typedef TOX_ERR_FRIEND_SEND_MESSAGE Tox_Err_Friend_Send_Message; +typedef TOX_ERR_FILE_CONTROL Tox_Err_File_Control; +typedef TOX_ERR_FILE_SEEK Tox_Err_File_Seek; +typedef TOX_ERR_FILE_GET Tox_Err_File_Get; +typedef TOX_ERR_FILE_SEND Tox_Err_File_Send; +typedef TOX_ERR_FILE_SEND_CHUNK Tox_Err_File_Send_Chunk; +typedef TOX_ERR_CONFERENCE_NEW Tox_Err_Conference_New; +typedef TOX_ERR_CONFERENCE_DELETE Tox_Err_Conference_Delete; +typedef TOX_ERR_CONFERENCE_PEER_QUERY Tox_Err_Conference_Peer_Query; +typedef TOX_ERR_CONFERENCE_BY_UID Tox_Err_Conference_By_Uid; +typedef TOX_ERR_CONFERENCE_INVITE Tox_Err_Conference_Invite; +typedef TOX_ERR_CONFERENCE_JOIN Tox_Err_Conference_Join; +typedef TOX_ERR_CONFERENCE_SEND_MESSAGE Tox_Err_Conference_Send_Message; +typedef TOX_ERR_CONFERENCE_TITLE Tox_Err_Conference_Title; +typedef TOX_ERR_CONFERENCE_GET_TYPE Tox_Err_Conference_Get_Type; +typedef TOX_ERR_FRIEND_CUSTOM_PACKET Tox_Err_Friend_Custom_Packet; +typedef TOX_ERR_GET_PORT Tox_Err_Get_Port; +typedef TOX_USER_STATUS Tox_User_Status; +typedef TOX_MESSAGE_TYPE Tox_Message_Type; +typedef TOX_PROXY_TYPE Tox_Proxy_Type; +typedef TOX_SAVEDATA_TYPE Tox_Savedata_Type; +typedef TOX_LOG_LEVEL Tox_Log_Level; +typedef TOX_CONNECTION Tox_Connection; +typedef TOX_FILE_CONTROL Tox_File_Control; +typedef TOX_CONFERENCE_TYPE Tox_Conference_Type; + #endif diff --git a/protocols/Tox/libtox/src/toxcore/tox_api.c b/protocols/Tox/libtox/src/toxcore/tox_api.c index 8fee8c804a..871239686a 100644 --- a/protocols/Tox/libtox/src/toxcore/tox_api.c +++ b/protocols/Tox/libtox/src/toxcore/tox_api.c @@ -5,7 +5,7 @@ #include <stdlib.h> #include <string.h> -#define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} +#define SET_ERROR_PARAMETER(param, x) do { if (param) { *param = x; } } while (0) #define CONST_FUNCTION(lowercase, uppercase) \ @@ -29,6 +29,7 @@ CONST_FUNCTION(max_custom_packet_size, MAX_CUSTOM_PACKET_SIZE) CONST_FUNCTION(hash_length, HASH_LENGTH) CONST_FUNCTION(file_id_length, FILE_ID_LENGTH) CONST_FUNCTION(max_filename_length, MAX_FILENAME_LENGTH) +CONST_FUNCTION(max_hostname_length, MAX_HOSTNAME_LENGTH) #define ACCESSORS(type, ns, name) \ diff --git a/protocols/Tox/libtox/src/toxcore/util.c b/protocols/Tox/libtox/src/toxcore/util.c index 853899909f..f349e8fe0e 100644 --- a/protocols/Tox/libtox/src/toxcore/util.c +++ b/protocols/Tox/libtox/src/toxcore/util.c @@ -34,37 +34,12 @@ #include "util.h" #include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */ -#include "network.h" /* for current_time_monotonic */ +#include <stdlib.h> +#include <string.h> #include <time.h> -/* don't call into system billions of times for no reason */ -static uint64_t unix_time_value; -static uint64_t unix_base_time_value; - -/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of - * unix_time() may fail to increase monotonically with increasing time */ -void unix_time_update(void) -{ - if (unix_base_time_value == 0) { - unix_base_time_value = ((uint64_t)time(0) - (current_time_monotonic() / 1000ULL)); - } - - unix_time_value = (current_time_monotonic() / 1000ULL) + unix_base_time_value; -} - -uint64_t unix_time(void) -{ - return unix_time_value; -} - -int is_timeout(uint64_t timestamp, uint64_t timeout) -{ - return timestamp + timeout <= unix_time(); -} - - /* id functions */ bool id_equal(const uint8_t *dest, const uint8_t *src) { @@ -91,83 +66,9 @@ void host_to_net(uint8_t *num, uint16_t numbytes) #endif } -uint16_t lendian_to_host16(uint16_t lendian) -{ -#ifdef WORDS_BIGENDIAN - return (lendian << 8) | (lendian >> 8); -#else - return lendian; -#endif -} - -void host_to_lendian32(uint8_t *dest, uint32_t num) -{ -#ifdef WORDS_BIGENDIAN - num = ((num << 8) & 0xFF00FF00) | ((num >> 8) & 0xFF00FF); - num = (num << 16) | (num >> 16); -#endif - memcpy(dest, &num, sizeof(uint32_t)); -} - -void lendian_to_host32(uint32_t *dest, const uint8_t *lendian) +void net_to_host(uint8_t *num, uint16_t numbytes) { - uint32_t d; - memcpy(&d, lendian, sizeof(uint32_t)); -#ifdef WORDS_BIGENDIAN - d = ((d << 8) & 0xFF00FF00) | ((d >> 8) & 0xFF00FF); - d = (d << 16) | (d >> 16); -#endif - *dest = d; -} - -/* state load/save */ -int load_state(load_state_callback_func load_state_callback, Logger *log, void *outer, - const uint8_t *data, uint32_t length, uint16_t cookie_inner) -{ - if (!load_state_callback || !data) { - LOGGER_ERROR(log, "load_state() called with invalid args.\n"); - return -1; - } - - - uint32_t length_sub, cookie_type; - uint32_t size_head = sizeof(uint32_t) * 2; - - while (length >= size_head) { - lendian_to_host32(&length_sub, data); - lendian_to_host32(&cookie_type, data + sizeof(length_sub)); - data += size_head; - length -= size_head; - - if (length < length_sub) { - /* file truncated */ - LOGGER_ERROR(log, "state file too short: %u < %u\n", length, length_sub); - return -1; - } - - if (lendian_to_host16((cookie_type >> 16)) != cookie_inner) { - /* something is not matching up in a bad way, give up */ - LOGGER_ERROR(log, "state file garbled: %04x != %04x\n", (cookie_type >> 16), cookie_inner); - return -1; - } - - const uint16_t type = lendian_to_host16(cookie_type & 0xFFFF); - const int ret = load_state_callback(outer, data, length_sub, type); - - if (ret == -1) { - return -1; - } - - /* -2 means end of save. */ - if (ret == -2) { - return 0; - } - - data += length_sub; - length -= length_sub; - } - - return length == 0 ? 0 : -1; + host_to_net(num, numbytes); } int create_recursive_mutex(pthread_mutex_t *mutex) @@ -199,6 +100,11 @@ int32_t max_s32(int32_t a, int32_t b) return a > b ? a : b; } +uint32_t min_u32(uint32_t a, uint32_t b) +{ + return a < b ? a : b; +} + uint64_t min_u64(uint64_t a, uint64_t b) { return a < b ? a : b; diff --git a/protocols/Tox/libtox/src/toxcore/util.h b/protocols/Tox/libtox/src/toxcore/util.h index a9faa86349..76951fff31 100644 --- a/protocols/Tox/libtox/src/toxcore/util.h +++ b/protocols/Tox/libtox/src/toxcore/util.h @@ -36,36 +36,18 @@ extern "C" { #endif -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; } - -void unix_time_update(void); -uint64_t unix_time(void); -int is_timeout(uint64_t timestamp, uint64_t timeout); - - /* id functions */ bool id_equal(const uint8_t *dest, const uint8_t *src); uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */ void host_to_net(uint8_t *num, uint16_t numbytes); -#define net_to_host(x, y) host_to_net(x, y) - -uint16_t lendian_to_host16(uint16_t lendian); -#define host_tolendian16(x) lendian_to_host16(x) - -void host_to_lendian32(uint8_t *dest, uint32_t num); -void lendian_to_host32(uint32_t *dest, const uint8_t *lendian); - -/* state load/save */ -typedef int (*load_state_callback_func)(void *outer, const uint8_t *data, uint32_t len, uint16_t type); -int load_state(load_state_callback_func load_state_callback, Logger *log, void *outer, - const uint8_t *data, uint32_t length, uint16_t cookie_inner); +void net_to_host(uint8_t *num, uint16_t numbytes); /* Returns -1 if failed or 0 if success */ int create_recursive_mutex(pthread_mutex_t *mutex); int32_t max_s32(int32_t a, int32_t b); +uint32_t min_u32(uint32_t a, uint32_t b); uint64_t min_u64(uint64_t a, uint64_t b); #ifdef __cplusplus diff --git a/protocols/Tox/libtox/src/toxcore/util_test.cpp b/protocols/Tox/libtox/src/toxcore/util_test.cpp deleted file mode 100644 index 8de6384848..0000000000 --- a/protocols/Tox/libtox/src/toxcore/util_test.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "util.h" - -#include "crypto_core.h" - -#include <gtest/gtest.h> - -TEST(Util, UnixTimeIncreasesOverTime) -{ - unix_time_update(); - uint64_t const start = unix_time(); - - while (start == unix_time()) { - unix_time_update(); - } - - uint64_t const end = unix_time(); - EXPECT_GT(end, start); -} - -TEST(Util, IsTimeout) -{ - uint64_t const start = unix_time(); - EXPECT_FALSE(is_timeout(start, 1)); - - while (start == unix_time()) { - unix_time_update(); - } - - EXPECT_TRUE(is_timeout(start, 1)); -} - -TEST(Util, TwoRandomIdsAreNotEqual) -{ - uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; - uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; - - crypto_new_keypair(pk1, sk1); - crypto_new_keypair(pk2, sk2); - - EXPECT_FALSE(id_equal(pk1, pk2)); -} - -TEST(Util, IdCopyMakesKeysEqual) -{ - uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; - uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0}; - - crypto_new_keypair(pk1, sk1); - id_copy(pk2, pk1); - - EXPECT_TRUE(id_equal(pk1, pk2)); -} diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c index 5a5c5525f3..d3e420e068 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c +++ b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c @@ -29,7 +29,7 @@ #include "crypto_pwhash_scryptsalsa208sha256.h" #include "crypto_scrypt.h" #include "runtime.h" -#include "utils.h" +#include "../../toxcore/crypto_core.h" static const char * const itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -147,11 +147,11 @@ escrypt_r(escrypt_local_t * local, const uint8_t * passwd, size_t passwdlen, prefixlen = src - setting; salt = src; - src = (uint8_t *) strrchr((char *)salt, '$'); + src = (uint8_t *) strrchr((const char *)salt, '$'); if (src) { saltlen = src - salt; } else { - saltlen = strlen((char *)salt); + saltlen = strlen((const char *)salt); } need = prefixlen + saltlen + 1 + crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1; @@ -175,7 +175,7 @@ escrypt_r(escrypt_local_t * local, const uint8_t * passwd, size_t passwdlen, *dst++ = '$'; dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash)); - sodium_memzero(hash, sizeof hash); + crypto_memzero(hash, sizeof hash); if (!dst || dst >= buf + buflen) { /* Can't happen */ return NULL; } diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c index 3dfe54db5f..c69d7c22e7 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c +++ b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c @@ -40,7 +40,7 @@ #include "pbkdf2-sha256.h" #include "sysendian.h" -#include "utils.h" +#include "../../toxcore/crypto_core.h" /** * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): @@ -61,8 +61,8 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t clen; if (passwdlen > 32) { - /* For some reason libsodium allows 64byte keys meaning keys - * between 32byte and 64bytes are not compatible with libsodium. + /* For some reason libsodium allows 64byte keys meaning keys + * between 32byte and 64bytes are not compatible with libsodium. toxencryptsave should only give 32byte passwds so this isn't an issue here.*/ crypto_hash_sha256(key, passwd, passwdlen); } else { @@ -91,7 +91,7 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, } memcpy(&buf[i * 32], T, clen); } - sodium_memzero((void *) key, sizeof(key)); + crypto_memzero((void *) key, sizeof(key)); } #endif diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c index 52c51abc3b..e2de3e5f74 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c +++ b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c @@ -12,8 +12,7 @@ #include "crypto_pwhash_scryptsalsa208sha256.h" #include "crypto_scrypt.h" -#include "randombytes.h" -#include "utils.h" +#include "../../toxcore/crypto_core.h" #define SETTING_SIZE(saltbytes) \ (sizeof "$7$" - 1U) + \ @@ -150,7 +149,7 @@ crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha2 errno = EINVAL; return -1; } - randombytes(salt, sizeof salt); + random_bytes(salt, sizeof salt); if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt, (uint8_t *) setting, sizeof setting) == NULL) { errno = EINVAL; @@ -202,8 +201,8 @@ crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryp return -1; } escrypt_free_local(&escrypt_local); - ret = sodium_memcmp(wanted, str, sizeof wanted); - sodium_memzero(wanted, sizeof wanted); + ret = crypto_memcmp(wanted, str, sizeof wanted); + crypto_memzero(wanted, sizeof wanted); return ret; } diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c index 9b5c513193..a813b50609 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c +++ b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c @@ -18,8 +18,12 @@ typedef struct CPUFeatures_ { static CPUFeatures _cpu_features; +#ifdef HAVE_EMMINTRIN_H #define CPUID_SSE2 0x04000000 +#endif +#ifdef HAVE_PMMINTRIN_H #define CPUIDECX_SSE3 0x00000001 +#endif static int _sodium_runtime_arm_cpu_features(CPUFeatures * const cpu_features) diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c index 856a655e3f..7f01523861 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c +++ b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c @@ -396,3 +396,6 @@ escrypt_kdf_sse(escrypt_local_t * local, #endif #endif + +/* ISO C requires a translation unit to contain at least one declaration */ +extern int non_empty_tu_decl; diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c index b83d6f1c6c..7c81f72272 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c +++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c @@ -29,7 +29,7 @@ #include "../toxcore/crypto_core.h" #include "defines.h" #include "toxencryptsave.h" -#define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} +#define SET_ERROR_PARAMETER(param, x) do { if (param) { *param = x; } } while (0) #ifdef VANILLA_NACL #include <crypto_box.h> @@ -40,6 +40,7 @@ #include <sodium.h> #endif +#include <stdlib.h> #include <string.h> #if TOX_PASS_SALT_LENGTH != crypto_pwhash_scryptsalsa208sha256_SALTBYTES @@ -123,7 +124,7 @@ Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t pplength, TOX_ERR_KEY_DERIVATION *error) { uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; - randombytes(salt, sizeof salt); + random_bytes(salt, sizeof salt); return tox_pass_key_derive_with_salt(passphrase, pplength, salt, error); } @@ -156,7 +157,7 @@ Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, size_t pp return nullptr; } - sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ + crypto_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ Tox_Pass_Key *out_key = (Tox_Pass_Key *)malloc(sizeof(Tox_Pass_Key)); |