diff options
Diffstat (limited to 'protocols/Tox/libtox/src')
42 files changed, 1272 insertions, 792 deletions
diff --git a/protocols/Tox/libtox/src/libtox.def b/protocols/Tox/libtox/src/libtox.def index 8c7855296a..7d27a74f5e 100644 --- a/protocols/Tox/libtox/src/libtox.def +++ b/protocols/Tox/libtox/src/libtox.def @@ -121,7 +121,6 @@ tox_pass_key_derive_with_salt tox_pass_key_encrypt tox_pass_key_free tox_pass_key_length -tox_pass_key_new tox_pass_salt_length tox_public_key_size tox_secret_key_size diff --git a/protocols/Tox/libtox/src/toxcore/DHT.c b/protocols/Tox/libtox/src/toxcore/DHT.c index 4ebe7f3344..a42515181c 100644 --- a/protocols/Tox/libtox/src/toxcore/DHT.c +++ b/protocols/Tox/libtox/src/toxcore/DHT.c @@ -68,7 +68,6 @@ int id_closest(const uint8_t *pk, const uint8_t *pk1, const uint8_t *pk2) { for (size_t i = 0; i < CRYPTO_PUBLIC_KEY_SIZE; ++i) { - uint8_t distance1 = pk[i] ^ pk1[i]; uint8_t distance2 = pk[i] ^ pk2[i]; @@ -287,7 +286,7 @@ int packed_node_size(uint8_t ip_family) * Returns size of packed IP_Port data on success * Return -1 on failure. */ -static int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port) +int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port) { if (data == NULL) { return -1; @@ -365,7 +364,7 @@ static int DHT_create_packet(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], * Return size of unpacked ip_port on success. * Return -1 on failure. */ -static int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, uint8_t tcp_enabled) +int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, uint8_t tcp_enabled) { if (data == NULL) { return -1; @@ -566,7 +565,7 @@ static void update_client(Logger *log, int index, Client_data *client, IP_Port i net_ntohs(ip_port.port)); } - if (LAN_ip(assoc->ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0) { + if (ip_is_lan(assoc->ip_port.ip) != 0 && ip_is_lan(ip_port.ip) == 0) { return; } @@ -703,11 +702,11 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_ } /* don't send LAN ips to non LAN peers */ - if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN) { + if (ip_is_lan(ipptp->ip_port.ip) == 0 && !is_LAN) { continue; } - if (LAN_ip(ipptp->ip_port.ip) != 0 && want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK + if (ip_is_lan(ipptp->ip_port.ip) != 0 && want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK && !id_equal(public_key, client->public_key)) { continue; } @@ -1180,9 +1179,9 @@ static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const if (sendback_node != NULL) { memcpy(plain_message + sizeof(receiver), sendback_node, sizeof(Node_format)); - ping_id = ping_array_add(&dht->dht_harden_ping_array, plain_message, sizeof(plain_message)); + ping_id = ping_array_add(dht->dht_harden_ping_array, plain_message, sizeof(plain_message)); } else { - ping_id = ping_array_add(&dht->dht_ping_array, plain_message, sizeof(receiver)); + ping_id = ping_array_add(dht->dht_ping_array, plain_message, sizeof(receiver)); } if (ping_id == 0) { @@ -1224,7 +1223,7 @@ static int sendnodes_ipv6(const DHT *dht, IP_Port ip_port, const uint8_t *public size_t Node_format_size = sizeof(Node_format); Node_format nodes_list[MAX_SENT_NODES]; - uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, 0, LAN_ip(ip_port.ip) == 0, 1); + uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, 0, ip_is_lan(ip_port.ip) == 0, 1); VLA(uint8_t, plain, 1 + Node_format_size * MAX_SENT_NODES + length); @@ -1273,11 +1272,12 @@ static int handle_getnodes(void *object, IP_Port source, const uint8_t *packet, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; DHT_get_shared_key_recv(dht, shared_key, packet + 1); - int len = decrypt_data_symmetric(shared_key, - packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, - packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, - CRYPTO_NODE_SIZE + CRYPTO_MAC_SIZE, - plain); + int len = decrypt_data_symmetric( + shared_key, + packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, + packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + CRYPTO_NODE_SIZE + CRYPTO_MAC_SIZE, + plain); if (len != CRYPTO_NODE_SIZE) { return 1; @@ -1285,7 +1285,7 @@ static int handle_getnodes(void *object, IP_Port source, const uint8_t *packet, sendnodes_ipv6(dht, source, packet + 1, plain, plain + CRYPTO_PUBLIC_KEY_SIZE, sizeof(uint64_t), shared_key); - add_to_ping(dht->ping, packet + 1, source); + ping_add(dht->ping, packet + 1, source); return 0; } @@ -1296,9 +1296,9 @@ static uint8_t sent_getnode_to_node(DHT *dht, const uint8_t *public_key, IP_Port { uint8_t data[sizeof(Node_format) * 2]; - if (ping_array_check(data, sizeof(data), &dht->dht_ping_array, ping_id) == sizeof(Node_format)) { + if (ping_array_check(dht->dht_ping_array, data, sizeof(data), ping_id) == sizeof(Node_format)) { memset(sendback_node, 0, sizeof(Node_format)); - } else if (ping_array_check(data, sizeof(data), &dht->dht_harden_ping_array, ping_id) == sizeof(data)) { + } else if (ping_array_check(dht->dht_harden_ping_array, data, sizeof(data), ping_id) == sizeof(data)) { memcpy(sendback_node, data + sizeof(Node_format), sizeof(Node_format)); } else { return 0; @@ -1454,7 +1454,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_64b(); + dht_friend->nat.NATping_id = random_u64(); ++dht->num_friends; lock_num = dht_friend->lock_count; @@ -1763,7 +1763,7 @@ static int friend_iplist(const DHT *dht, IP_Port *ip_portlist, uint16_t friend_n int num_ipv6s = 0; for (size_t i = 0; i < MAX_FRIEND_CLIENTS; ++i) { - client = &(dht_friend->client_list[i]); + client = &dht_friend->client_list[i]; /* If ip is not zero and node is good. */ if (ip_isset(&client->assoc4.ret_ip_port.ip) && !is_timeout(client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) { @@ -1985,7 +1985,7 @@ static int handle_NATping(void *object, IP_Port source, const uint8_t *source_pu if (packet[0] == NAT_PING_RESPONSE) { if (dht_friend->nat.NATping_id == ping_id) { - dht_friend->nat.NATping_id = random_64b(); + dht_friend->nat.NATping_id = random_u64(); dht_friend->nat.hole_punching = 1; return 0; } @@ -2069,7 +2069,7 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, IP_Port pinging; ip_copy(&pinging.ip, &ip); pinging.port = net_htons(first_port); - send_ping_request(dht->ping, pinging, dht->friends_list[friend_num].public_key); + ping_send_request(dht->ping, pinging, dht->friends_list[friend_num].public_key); } else { for (i = 0; i < MAX_PUNCHING_PORTS; ++i) { /* TODO(irungentoo): Improve port guessing algorithm. */ @@ -2081,7 +2081,7 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, IP_Port pinging; ip_copy(&pinging.ip, &ip); pinging.port = net_htons(port); - send_ping_request(dht->ping, pinging, dht->friends_list[friend_num].public_key); + ping_send_request(dht->ping, pinging, dht->friends_list[friend_num].public_key); } dht->friends_list[friend_num].nat.punching_index += i; @@ -2095,7 +2095,7 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, for (i = 0; i < MAX_PUNCHING_PORTS; ++i) { uint32_t it = i + dht->friends_list[friend_num].nat.punching_index2; pinging.port = net_htons(port + it); - send_ping_request(dht->ping, pinging, dht->friends_list[friend_num].public_key); + ping_send_request(dht->ping, pinging, dht->friends_list[friend_num].public_key); } dht->friends_list[friend_num].nat.punching_index2 += i - (MAX_PUNCHING_PORTS / 2); @@ -2562,7 +2562,7 @@ DHT *new_DHT(Logger *log, Networking_Core *net, bool holepunching_enabled) dht->hole_punching_enabled = holepunching_enabled; - dht->ping = new_ping(dht); + dht->ping = ping_new(dht); if (dht->ping == NULL) { kill_DHT(dht); @@ -2578,8 +2578,8 @@ DHT *new_DHT(Logger *log, Networking_Core *net, bool holepunching_enabled) new_symmetric_key(dht->secret_symmetric_key); crypto_new_keypair(dht->self_public_key, dht->self_secret_key); - ping_array_init(&dht->dht_ping_array, DHT_PING_ARRAY_SIZE, PING_TIMEOUT); - ping_array_init(&dht->dht_harden_ping_array, DHT_PING_ARRAY_SIZE, PING_TIMEOUT); + dht->dht_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT); + dht->dht_harden_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT); for (uint32_t i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) { uint8_t random_key_bytes[CRYPTO_PUBLIC_KEY_SIZE]; @@ -2610,7 +2610,7 @@ void do_DHT(DHT *dht) do_Close(dht); do_DHT_friends(dht); do_NAT(dht); - do_to_ping(dht->ping); + ping_iterate(dht->ping); #if DHT_HARDENING do_hardening(dht); #endif @@ -2622,9 +2622,9 @@ void kill_DHT(DHT *dht) networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, NULL, NULL); cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, NULL, NULL); cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, NULL, NULL); - ping_array_free_all(&dht->dht_ping_array); - ping_array_free_all(&dht->dht_harden_ping_array); - kill_ping(dht->ping); + ping_array_kill(dht->dht_ping_array); + ping_array_kill(dht->dht_harden_ping_array); + ping_kill(dht->ping); free(dht->friends_list); free(dht->loaded_nodes_list); free(dht); @@ -2840,11 +2840,11 @@ int DHT_non_lan_connected(const DHT *dht) for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { const Client_data *client = &dht->close_clientlist[i]; - if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && LAN_ip(client->assoc4.ip_port.ip) == -1) { + if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && ip_is_lan(client->assoc4.ip_port.ip) == -1) { return 1; } - if (!is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT) && LAN_ip(client->assoc6.ip_port.ip) == -1) { + if (!is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT) && ip_is_lan(client->assoc6.ip_port.ip) == -1) { return 1; } } diff --git a/protocols/Tox/libtox/src/toxcore/DHT.h b/protocols/Tox/libtox/src/toxcore/DHT.h index 510b3c5c92..8fdd80b04d 100644 --- a/protocols/Tox/libtox/src/toxcore/DHT.h +++ b/protocols/Tox/libtox/src/toxcore/DHT.h @@ -180,6 +180,20 @@ typedef struct { */ int packed_node_size(uint8_t ip_family); +/* Packs an IP_Port structure into data of max size length. + * + * Returns size of packed IP_Port data on success + * Return -1 on failure. + */ +int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port); + +/* Unpack IP_Port structure from data of max size length into ip_port. + * + * Return size of unpacked ip_port on success. + * Return -1 on failure. + */ +int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, uint8_t tcp_enabled); + /* Pack number of nodes into data of maxlength length. * * return length of packed nodes on success. @@ -225,7 +239,8 @@ typedef struct { void *object; } Cryptopacket_Handles; -typedef struct { +#define DHT_DEFINED +typedef struct DHT { Logger *log; Networking_Core *net; @@ -251,9 +266,9 @@ typedef struct { Shared_Keys shared_keys_recv; Shared_Keys shared_keys_sent; - struct PING *ping; - Ping_Array dht_ping_array; - Ping_Array dht_harden_ping_array; + struct Ping *ping; + Ping_Array *dht_ping_array; + Ping_Array *dht_harden_ping_array; uint64_t last_run; Cryptopacket_Handles cryptopackethandlers[256]; diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h b/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h new file mode 100644 index 0000000000..9e6c648164 --- /dev/null +++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h @@ -0,0 +1,73 @@ +%{ +/* + * LAN discovery implementation. + */ + +/* + * Copyright © 2016-2017 The TokTok team. + * Copyright © 2013 Tox project. + * + * This file is part of Tox, the free peer to peer instant messenger. + * + * Tox is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tox is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tox. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef LAN_DISCOVERY_H +#define LAN_DISCOVERY_H + +#include "DHT.h" +%} + +class dHT { struct this; } +class iP { struct this; } + +namespace lan_discovery { + +/** + * Interval in seconds between LAN discovery packet sending. + */ +const INTERVAL = 10; + +/** + * Send a LAN discovery pcaket to the broadcast address with port port. + */ +static int32_t send(uint16_t port, dHT::this *dht); + +/** + * Sets up packet handlers. + */ +static void init(dHT::this *dht); + +/** + * Clear packet handlers. + */ +static void kill(dHT::this *dht); + +} + +/** + * Is IP a local ip or not. + */ +static bool ip_is_local(iP::this ip); + +/** + * checks if a given IP isn't routable + * + * return 0 if ip is a LAN ip. + * return -1 if it is not. + */ +static int32_t ip_is_lan(iP::this ip); + +%{ +#endif +%} diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c index b95e401d05..b5cf2c525b 100644 --- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c +++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c @@ -256,7 +256,7 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast) } /* Is IP a local ip or not. */ -bool Local_ip(IP ip) +bool ip_is_local(IP ip) { if (ip.family == TOX_AF_INET) { IP4 ip4 = ip.ip4; @@ -271,7 +271,7 @@ bool Local_ip(IP ip) IP ip4; ip4.family = TOX_AF_INET; ip4.ip4.uint32 = ip.ip6.uint32[3]; - return Local_ip(ip4); + return ip_is_local(ip4); } /* localhost in IPv6 (::1) */ @@ -286,9 +286,9 @@ bool Local_ip(IP ip) /* return 0 if ip is a LAN ip. * return -1 if it is not. */ -int LAN_ip(IP ip) +int ip_is_lan(IP ip) { - if (Local_ip(ip)) { + if (ip_is_local(ip)) { return 0; } @@ -335,7 +335,7 @@ int LAN_ip(IP ip) IP ip4; ip4.family = TOX_AF_INET; ip4.ip4.uint32 = ip.ip6.uint32[3]; - return LAN_ip(ip4); + return ip_is_lan(ip4); } } @@ -346,7 +346,7 @@ static int handle_LANdiscovery(void *object, IP_Port source, const uint8_t *pack { DHT *dht = (DHT *)object; - if (LAN_ip(source.ip) == -1) { + if (ip_is_lan(source.ip) == -1) { return 1; } @@ -356,14 +356,14 @@ static int handle_LANdiscovery(void *object, IP_Port source, const uint8_t *pack char ip_str[IP_NTOA_LEN] = { 0 }; ip_ntoa(&source.ip, ip_str, sizeof(ip_str)); - LOGGER_INFO(dht->log, "Found node in LAN: %s", ip_str); + LOGGER_DEBUG(dht->log, "Found node in LAN: %s", ip_str); DHT_bootstrap(dht, source, packet + 1); return 0; } -int send_LANdiscovery(uint16_t port, DHT *dht) +int lan_discovery_send(uint16_t port, DHT *dht) { uint8_t data[CRYPTO_PUBLIC_KEY_SIZE + 1]; data[0] = NET_PACKET_LAN_DISCOVERY; @@ -376,7 +376,7 @@ int send_LANdiscovery(uint16_t port, DHT *dht) ip_port.port = port; /* IPv6 multicast */ - if (dht->net->family == TOX_AF_INET6) { + if (net_family(dht->net) == TOX_AF_INET6) { ip_port.ip = broadcast_ip(TOX_AF_INET6, TOX_AF_INET6); if (ip_isset(&ip_port.ip)) { @@ -387,7 +387,7 @@ int send_LANdiscovery(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(dht->net->family, TOX_AF_INET); + ip_port.ip = broadcast_ip(net_family(dht->net), TOX_AF_INET); if (ip_isset(&ip_port.ip)) { if (sendpacket(dht->net, ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE)) { @@ -399,12 +399,12 @@ int send_LANdiscovery(uint16_t port, DHT *dht) } -void LANdiscovery_init(DHT *dht) +void lan_discovery_init(DHT *dht) { networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht); } -void LANdiscovery_kill(DHT *dht) +void lan_discovery_kill(DHT *dht) { networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, NULL, NULL); } diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.h b/protocols/Tox/libtox/src/toxcore/LAN_discovery.h index 753de5249f..6d9d17b664 100644 --- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.h +++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.h @@ -26,27 +26,49 @@ #include "DHT.h" -/* Interval in seconds between LAN discovery packet sending. */ -#define LAN_DISCOVERY_INTERVAL 10 +#ifndef DHT_DEFINED +#define DHT_DEFINED +typedef struct DHT DHT; +#endif /* DHT_DEFINED */ -/* Send a LAN discovery pcaket to the broadcast address with port port. */ -int send_LANdiscovery(uint16_t port, DHT *dht); +#ifndef IP_DEFINED +#define IP_DEFINED +typedef struct IP IP; +#endif /* IP_DEFINED */ -/* Sets up packet handlers. */ -void LANdiscovery_init(DHT *dht); +/** + * Interval in seconds between LAN discovery packet sending. + */ +#define LAN_DISCOVERY_INTERVAL 10 -/* Clear packet handlers. */ -void LANdiscovery_kill(DHT *dht); +uint32_t lan_discovery_interval(void); -/* Is IP a local ip or not. */ -bool Local_ip(IP ip); +/** + * Send a LAN discovery pcaket to the broadcast address with port port. + */ +int32_t lan_discovery_send(uint16_t port, DHT *dht); -/* checks if a given IP isn't routable +/** + * Sets up packet handlers. + */ +void lan_discovery_init(DHT *dht); + +/** + * Clear packet handlers. + */ +void lan_discovery_kill(DHT *dht); + +/** + * Is IP a local ip or not. + */ +bool ip_is_local(IP ip); + +/** + * checks if a given IP isn't routable * * return 0 if ip is a LAN ip. * return -1 if it is not. */ -int LAN_ip(IP ip); - +int32_t ip_is_lan(IP ip); #endif diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.c b/protocols/Tox/libtox/src/toxcore/Messenger.c index e821f53530..fcee455ccc 100644 --- a/protocols/Tox/libtox/src/toxcore/Messenger.c +++ b/protocols/Tox/libtox/src/toxcore/Messenger.c @@ -140,8 +140,8 @@ static uint16_t address_checksum(const uint8_t *address, uint32_t len) */ void getaddress(const Messenger *m, uint8_t *address) { - id_copy(address, m->net_crypto->self_public_key); - uint32_t nospam = get_nospam(&(m->fr)); + id_copy(address, nc_get_self_public_key(m->net_crypto)); + uint32_t nospam = get_nospam(m->fr); memcpy(address + CRYPTO_PUBLIC_KEY_SIZE, &nospam, sizeof(nospam)); uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); memcpy(address + CRYPTO_PUBLIC_KEY_SIZE + sizeof(nospam), &checksum, sizeof(checksum)); @@ -177,7 +177,7 @@ static int32_t init_new_friend(Messenger *m, const uint8_t *real_pk, uint8_t sta return FAERR_NOMEM; } - memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); + memset(&m->friendlist[m->numfriends], 0, sizeof(Friend)); int friendcon_id = new_friend_connection(m->fr_c, real_pk); @@ -255,7 +255,7 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u return FAERR_NOMESSAGE; } - if (id_equal(real_pk, m->net_crypto->self_public_key)) { + if (id_equal(real_pk, nc_get_self_public_key(m->net_crypto))) { return FAERR_OWNKEY; } @@ -286,7 +286,7 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u m->friendlist[ret].friendrequest_timeout = FRIENDREQUEST_TIMEOUT; memcpy(m->friendlist[ret].info, data, length); m->friendlist[ret].info_size = length; - memcpy(&(m->friendlist[ret].friendrequest_nospam), address + CRYPTO_PUBLIC_KEY_SIZE, sizeof(uint32_t)); + memcpy(&m->friendlist[ret].friendrequest_nospam, address + CRYPTO_PUBLIC_KEY_SIZE, sizeof(uint32_t)); return ret; } @@ -301,7 +301,7 @@ int32_t m_addfriend_norequest(Messenger *m, const uint8_t *real_pk) return FAERR_BADCHECKSUM; } - if (id_equal(real_pk, m->net_crypto->self_public_key)) { + if (id_equal(real_pk, nc_get_self_public_key(m->net_crypto))) { return FAERR_OWNKEY; } @@ -415,7 +415,7 @@ int m_delfriend(Messenger *m, int32_t friendnumber) } clear_receipts(m, friendnumber); - remove_request_received(&(m->fr), m->friendlist[friendnumber].real_pk); + remove_request_received(m->fr, m->friendlist[friendnumber].real_pk); friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0); if (friend_con_connected(m->fr_c, m->friendlist[friendnumber].friendcon_id) == FRIENDCONN_STATUS_CONNECTED) { @@ -423,7 +423,7 @@ int m_delfriend(Messenger *m, int32_t friendnumber) } kill_friend_connection(m->fr_c, m->friendlist[friendnumber].friendcon_id); - memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); + memset(&m->friendlist[friendnumber], 0, sizeof(Friend)); uint32_t i; for (i = m->numfriends; i != 0; --i) { @@ -488,7 +488,8 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber) int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, const uint8_t *message, uint32_t length, uint32_t *message_id) { - if (type > MESSAGE_ACTION) { + /* MESSAGE_LAST itself is incorrect value */ + if (type >= MESSAGE_LAST) { return -5; } @@ -837,7 +838,7 @@ void m_callback_log(Messenger *m, logger_cb *function, void *context, void *user void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const uint8_t *, const uint8_t *, size_t, void *)) { - callback_friendrequest(&(m->fr), (void (*)(void *, const uint8_t *, const uint8_t *, size_t, void *))function, m); + callback_friendrequest(m->fr, (void (*)(void *, const uint8_t *, const uint8_t *, size_t, void *))function, m); } /* Set the function that will be executed when a message from a friend is received. */ @@ -1921,16 +1922,23 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) return NULL; } - Messenger *m = (Messenger *)calloc(1, sizeof(Messenger)); - if (error) { *error = MESSENGER_ERROR_OTHER; } + Messenger *m = (Messenger *)calloc(1, sizeof(Messenger)); + if (!m) { return NULL; } + m->fr = friendreq_new(); + + if (!m->fr) { + free(m); + return NULL; + } + Logger *log = NULL; if (options->log_callback) { @@ -1946,8 +1954,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) unsigned int net_err = 0; if (options->udp_disabled) { - /* this is the easiest way to completely disable UDP without changing too much code. */ - m->net = (Networking_Core *)calloc(1, sizeof(Networking_Core)); + m->net = new_networking_no_udp(log); } else { IP ip; ip_init(&ip, options->ipv6enabled); @@ -1955,6 +1962,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) } if (m->net == NULL) { + friendreq_kill(m->fr); free(m); if (error && net_err == 1) { @@ -1968,6 +1976,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) if (m->dht == NULL) { kill_networking(m->net); + friendreq_kill(m->fr); free(m); return NULL; } @@ -1977,6 +1986,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) if (m->net_crypto == NULL) { kill_networking(m->net); kill_DHT(m->dht); + friendreq_kill(m->fr); free(m); return NULL; } @@ -1994,6 +2004,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) kill_net_crypto(m->net_crypto); kill_DHT(m->dht); kill_networking(m->net); + friendreq_kill(m->fr); free(m); return NULL; } @@ -2009,6 +2020,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) kill_net_crypto(m->net_crypto); kill_DHT(m->dht); kill_networking(m->net); + friendreq_kill(m->fr); free(m); if (error) { @@ -2020,9 +2032,9 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) } m->options = *options; - friendreq_init(&(m->fr), m->fr_c); - set_nospam(&(m->fr), random_int()); - set_filter_function(&(m->fr), &friend_already_added, m); + friendreq_init(m->fr, m->fr_c); + set_nospam(m->fr, random_u32()); + set_filter_function(m->fr, &friend_already_added, m); m->lastdump = 0; @@ -2060,6 +2072,7 @@ void kill_messenger(Messenger *m) logger_kill(m->log); free(m->friendlist); + friendreq_kill(m->fr); free(m); } @@ -2201,7 +2214,8 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le } case PACKET_ID_MESSAGE: // fall-through - case PACKET_ID_ACTION: { + case PACKET_ID_ACTION: + case PACKET_ID_CORRECTION: { if (data_length == 0) { break; } @@ -2877,7 +2891,7 @@ static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length) /* TODO(irungentoo): This is not a good way to do this. */ uint8_t address[FRIEND_ADDRESS_SIZE]; id_copy(address, temp.real_pk); - memcpy(address + CRYPTO_PUBLIC_KEY_SIZE, &(temp.friendrequest_nospam), sizeof(uint32_t)); + memcpy(address + CRYPTO_PUBLIC_KEY_SIZE, &temp.friendrequest_nospam, sizeof(uint32_t)); uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); memcpy(address + CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint32_t), &checksum, sizeof(checksum)); m_addfriend(m, address, temp.info, net_ntohs(temp.info_size)); @@ -2926,11 +2940,11 @@ void messenger_save(const Messenger *m, uint8_t *data) host_to_lendian32(data, MESSENGER_STATE_COOKIE_GLOBAL); data += size32; - assert(sizeof(get_nospam(&m->fr)) == sizeof(uint32_t)); + assert(sizeof(get_nospam(m->fr)) == sizeof(uint32_t)); len = size32 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE; type = MESSENGER_STATE_TYPE_NOSPAMKEYS; data = messenger_save_subheader(data, len, type); - *(uint32_t *)data = get_nospam(&(m->fr)); + *(uint32_t *)data = get_nospam(m->fr); save_keys(m->net_crypto, data + size32); data += len; @@ -3001,10 +3015,10 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3 switch (type) { case MESSENGER_STATE_TYPE_NOSPAMKEYS: if (length == CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE + sizeof(uint32_t)) { - set_nospam(&(m->fr), *(const uint32_t *)data); + set_nospam(m->fr, *(const uint32_t *)data); load_secret_key(m->net_crypto, (&data[sizeof(uint32_t)]) + CRYPTO_PUBLIC_KEY_SIZE); - if (public_key_cmp((&data[sizeof(uint32_t)]), m->net_crypto->self_public_key) != 0) { + if (public_key_cmp((&data[sizeof(uint32_t)]), nc_get_self_public_key(m->net_crypto)) != 0) { return -1; } } else { diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.h b/protocols/Tox/libtox/src/toxcore/Messenger.h index e1dba69886..a261a507db 100644 --- a/protocols/Tox/libtox/src/toxcore/Messenger.h +++ b/protocols/Tox/libtox/src/toxcore/Messenger.h @@ -42,7 +42,9 @@ enum { MESSAGE_NORMAL, - MESSAGE_ACTION + MESSAGE_ACTION, + MESSAGE_CORRECTION, + MESSAGE_LAST }; /* NOTE: Packet ids below 24 must never be used. */ @@ -54,6 +56,7 @@ enum { #define PACKET_ID_TYPING 51 #define PACKET_ID_MESSAGE 64 #define PACKET_ID_ACTION (PACKET_ID_MESSAGE + MESSAGE_ACTION) /* 65 */ +#define PACKET_ID_CORRECTION (PACKET_ID_MESSAGE + MESSAGE_CORRECTION) /* 66 */ #define PACKET_ID_MSI 69 #define PACKET_ID_FILE_SENDREQUEST 80 #define PACKET_ID_FILE_CONTROL 81 @@ -228,7 +231,7 @@ struct Messenger { Friend_Connections *fr_c; TCP_Server *tcp_server; - Friend_Requests fr; + Friend_Requests *fr; uint8_t name[MAX_NAME_LENGTH]; uint16_t name_length; diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.c b/protocols/Tox/libtox/src/toxcore/TCP_client.c index 8a14c7cd70..b4092f803d 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_client.c +++ b/protocols/Tox/libtox/src/toxcore/TCP_client.c @@ -33,6 +33,88 @@ #include <sys/ioctl.h> #endif +struct TCP_Client_Connection { + 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 */ + IP_Port ip_port; /* The ip and port of the server */ + TCP_Proxy_Info proxy_info; + uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ + uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; + uint16_t next_packet_length; + + uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE]; + + uint8_t last_packet[2 + MAX_PACKET_SIZE]; + uint16_t last_packet_length; + uint16_t last_packet_sent; + + TCP_Priority_List *priority_queue_start, *priority_queue_end; + + uint64_t kill_at; + + uint64_t last_pinged; + uint64_t ping_id; + + 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); + void *response_callback_object; + int (*status_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t status); + 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); + void *data_callback_object; + int (*oob_data_callback)(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata); + void *oob_data_callback_object; + + int (*onion_callback)(void *object, const uint8_t *data, uint16_t length, void *userdata); + void *onion_callback_object; + + /* Can be used by user. */ + void *custom_object; + uint32_t custom_uint; +}; + +const uint8_t *tcp_con_public_key(const TCP_Client_Connection *con) +{ + return con->public_key; +} + +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) +{ + return con->status; +} +void *tcp_con_custom_object(const TCP_Client_Connection *con) +{ + return con->custom_object; +} +uint32_t tcp_con_custom_uint(const TCP_Client_Connection *con) +{ + return con->custom_uint; +} +void tcp_con_set_custom_object(TCP_Client_Connection *con, void *object) +{ + con->custom_object = object; +} +void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t uint) +{ + con->custom_uint = uint; +} + /* return 1 on success * return 0 on failure */ @@ -856,7 +938,7 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) int len; if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) { - uint64_t ping_id = random_64b(); + uint64_t ping_id = random_u64(); if (!ping_id) { ++ping_id; diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.h b/protocols/Tox/libtox/src/toxcore/TCP_client.h index 212543147c..96e04d6791 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_client.h +++ b/protocols/Tox/libtox/src/toxcore/TCP_client.h @@ -40,7 +40,7 @@ typedef struct { uint8_t proxy_type; // a value from TCP_PROXY_TYPE } TCP_Proxy_Info; -enum { +typedef enum { TCP_CLIENT_NO_STATUS, TCP_CLIENT_PROXY_HTTP_CONNECTING, TCP_CLIENT_PROXY_SOCKS5_CONNECTING, @@ -49,57 +49,17 @@ enum { TCP_CLIENT_UNCONFIRMED, TCP_CLIENT_CONFIRMED, TCP_CLIENT_DISCONNECTED, -}; -typedef struct { - uint8_t 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 */ - IP_Port ip_port; /* The ip and port of the server */ - TCP_Proxy_Info proxy_info; - uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ - uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ - uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; - uint16_t next_packet_length; - - uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE]; - - uint8_t last_packet[2 + MAX_PACKET_SIZE]; - uint16_t last_packet_length; - uint16_t last_packet_sent; - - TCP_Priority_List *priority_queue_start, *priority_queue_end; - - uint64_t kill_at; - - uint64_t last_pinged; - uint64_t ping_id; - - 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); - void *response_callback_object; - int (*status_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t status); - 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); - void *data_callback_object; - int (*oob_data_callback)(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata); - void *oob_data_callback_object; - - int (*onion_callback)(void *object, const uint8_t *data, uint16_t length, void *userdata); - void *onion_callback_object; - - /* Can be used by user. */ - void *custom_object; - uint32_t custom_uint; -} TCP_Client_Connection; +} 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); + +void *tcp_con_custom_object(const TCP_Client_Connection *con); +uint32_t tcp_con_custom_uint(const TCP_Client_Connection *con); +void tcp_con_set_custom_object(TCP_Client_Connection *con, void *object); +void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t uint); /* Create new TCP connection to ip_port/public_key */ diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.c b/protocols/Tox/libtox/src/toxcore/TCP_connection.c index 251594912a..a43069da68 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_connection.c +++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.c @@ -144,7 +144,7 @@ static int create_connection(TCP_Connections *tcp_c) temp_pointer) == 0) { id = tcp_c->connections_length; ++tcp_c->connections_length; - memset(&(tcp_c->connections[id]), 0, sizeof(TCP_Connection_to)); + memset(&tcp_c->connections[id], 0, sizeof(TCP_Connection_to)); } return id; @@ -172,7 +172,7 @@ static int create_tcp_connection(TCP_Connections *tcp_c) if (realloc_tox_array(tcp_c->tcp_connections, TCP_con, tcp_c->tcp_connections_length + 1, temp_pointer) == 0) { id = tcp_c->tcp_connections_length; ++tcp_c->tcp_connections_length; - memset(&(tcp_c->tcp_connections[id]), 0, sizeof(TCP_con)); + memset(&tcp_c->tcp_connections[id], 0, sizeof(TCP_con)); } return id; @@ -190,7 +190,7 @@ static int wipe_connection(TCP_Connections *tcp_c, int connections_number) } uint32_t i; - memset(&(tcp_c->connections[connections_number]), 0 , sizeof(TCP_Connection_to)); + memset(&tcp_c->connections[connections_number], 0, sizeof(TCP_Connection_to)); for (i = tcp_c->connections_length; i != 0; --i) { if (tcp_c->connections[i - 1].status != TCP_CONN_NONE) { @@ -219,7 +219,7 @@ static int wipe_tcp_connection(TCP_Connections *tcp_c, int tcp_connections_numbe } uint32_t i; - memset(&(tcp_c->tcp_connections[tcp_connections_number]), 0 , sizeof(TCP_con)); + memset(&tcp_c->tcp_connections[tcp_connections_number], 0, sizeof(TCP_con)); for (i = tcp_c->tcp_connections_length; i != 0; --i) { if (tcp_c->tcp_connections[i - 1].status != TCP_CONN_NONE) { @@ -477,7 +477,7 @@ static int find_tcp_connection_relay(TCP_Connections *tcp_c, const uint8_t *rela return i; } } else { - if (public_key_cmp(tcp_con->connection->public_key, relay_pk) == 0) { + if (public_key_cmp(tcp_con_public_key(tcp_con->connection), relay_pk) == 0) { return i; } } @@ -768,9 +768,9 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec return -1; } - IP_Port ip_port = tcp_con->connection->ip_port; + IP_Port ip_port = tcp_con_ip_port(tcp_con->connection); uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE]; - memcpy(relay_pk, tcp_con->connection->public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); kill_TCP_connection(tcp_con->connection); tcp_con->connection = new_TCP_connection(ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); @@ -820,8 +820,8 @@ static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connection return -1; } - tcp_con->ip_port = tcp_con->connection->ip_port; - memcpy(tcp_con->relay_pk, tcp_con->connection->public_key, CRYPTO_PUBLIC_KEY_SIZE); + tcp_con->ip_port = tcp_con_ip_port(tcp_con->connection); + memcpy(tcp_con->relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); kill_TCP_connection(tcp_con->connection); tcp_con->connection = NULL; @@ -905,9 +905,9 @@ 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_client_con->custom_object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); - unsigned int tcp_connections_number = TCP_client_con->custom_uint; + 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) { @@ -938,9 +938,9 @@ 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_client_con->custom_object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); - unsigned int tcp_connections_number = TCP_client_con->custom_uint; + 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); @@ -981,9 +981,9 @@ static int tcp_conn_data_callback(void *object, uint32_t number, uint8_t connect } TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; - TCP_Connections *tcp_c = (TCP_Connections *)TCP_client_con->custom_object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); - unsigned int tcp_connections_number = TCP_client_con->custom_uint; + 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) { @@ -1011,9 +1011,9 @@ static int tcp_conn_oob_callback(void *object, const uint8_t *public_key, const } TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; - TCP_Connections *tcp_c = (TCP_Connections *)TCP_client_con->custom_object; + TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); - unsigned int tcp_connections_number = TCP_client_con->custom_uint; + 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) { @@ -1062,8 +1062,8 @@ static int tcp_relay_set_callbacks(TCP_Connections *tcp_c, int tcp_connections_n TCP_Client_Connection *con = tcp_con->connection; - con->custom_object = tcp_c; - con->custom_uint = tcp_connections_number; + tcp_con_set_custom_object(con, tcp_c); + tcp_con_set_custom_uint(con, tcp_connections_number); onion_response_handler(con, &tcp_onion_callback, tcp_c); routing_response_handler(con, &tcp_response_callback, con); routing_status_handler(con, &tcp_status_callback, con); @@ -1273,8 +1273,8 @@ unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_ } if (tcp_con->status == TCP_CONN_CONNECTED) { - memcpy(tcp_relays[copied].public_key, tcp_con->connection->public_key, CRYPTO_PUBLIC_KEY_SIZE); - tcp_relays[copied].ip_port = tcp_con->connection->ip_port; + 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; @@ -1402,7 +1402,7 @@ static void do_tcp_conns(TCP_Connections *tcp_c, void *userdata) // Make sure the TCP connection wasn't dropped in any of the callbacks. assert(tcp_con != NULL); - if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) { + if (tcp_con_status(tcp_con->connection) == TCP_CLIENT_DISCONNECTED) { if (tcp_con->status == TCP_CONN_CONNECTED) { reconnect_tcp_relay_connection(tcp_c, i); } else { @@ -1412,7 +1412,7 @@ static void do_tcp_conns(TCP_Connections *tcp_c, void *userdata) continue; } - if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) { + if (tcp_con->status == TCP_CONN_VALID && tcp_con_status(tcp_con->connection) == TCP_CLIENT_CONFIRMED) { tcp_relay_on_online(tcp_c, i); } diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.c b/protocols/Tox/libtox/src/toxcore/TCP_server.c index 9b94667aa1..e86776e59e 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_server.c +++ b/protocols/Tox/libtox/src/toxcore/TCP_server.c @@ -33,6 +33,33 @@ #include <sys/ioctl.h> #endif +typedef struct TCP_Secure_Connection { + Socket sock; + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ + 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]; + 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; + + uint64_t identifier; + + uint64_t last_pinged; + uint64_t ping_id; +} TCP_Secure_Connection; + + struct TCP_Server { Onion *onion; @@ -1219,7 +1246,7 @@ static void do_TCP_confirmed(TCP_Server *TCP_server) if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) { uint8_t ping[1 + sizeof(uint64_t)]; ping[0] = TCP_PACKET_PING; - uint64_t ping_id = random_64b(); + uint64_t ping_id = random_u64(); if (!ping_id) { ++ping_id; diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.h b/protocols/Tox/libtox/src/toxcore/TCP_server.h index f213c078e6..234f5ad12e 100644 --- a/protocols/Tox/libtox/src/toxcore/TCP_server.h +++ b/protocols/Tox/libtox/src/toxcore/TCP_server.h @@ -90,33 +90,6 @@ struct TCP_Priority_List { uint8_t data[]; }; -typedef struct TCP_Secure_Connection { - Socket sock; - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ - 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]; - 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; - - uint64_t identifier; - - uint64_t last_pinged; - uint64_t ping_id; -} TCP_Secure_Connection; - - typedef struct TCP_Server TCP_Server; const uint8_t *tcp_server_public_key(const TCP_Server *tcp_server); diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.api.h b/protocols/Tox/libtox/src/toxcore/crypto_core.api.h index cef1a52c14..0ba28c0c1b 100644 --- a/protocols/Tox/libtox/src/toxcore/crypto_core.api.h +++ b/protocols/Tox/libtox/src/toxcore/crypto_core.api.h @@ -110,15 +110,34 @@ static int32_t public_key_cmp( const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] pk1, const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] pk2); +namespace random { + +/** + * Return a random 16 bit integer. + */ +static uint16_t u16(); + /** * Return a random 32 bit integer. */ -static uint32_t random_int(); +static uint32_t u32(); /** * Return a random 64 bit integer. */ -static uint64_t random_64b(); +static uint64_t u64(); + +/** + * Fill the given nonce with random bytes. + */ +static void nonce(uint8_t[CRYPTO_NONCE_SIZE] nonce); + +/** + * Fill an array of bytes with random values. + */ +static void bytes(uint8_t[length] bytes); + +} /** * Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not. This @@ -227,20 +246,10 @@ static void increment_nonce(uint8_t[CRYPTO_NONCE_SIZE] nonce); static void increment_nonce_number(uint8_t[CRYPTO_NONCE_SIZE] nonce, uint32_t host_order_num); /** - * Fill the given nonce with random bytes. - */ -static void random_nonce(uint8_t[CRYPTO_NONCE_SIZE] nonce); - -/** * Fill a key CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes. */ static void new_symmetric_key(uint8_t[CRYPTO_SYMMETRIC_KEY_SIZE] key); -/** - * Fill an array of bytes with random values. - */ -static void random_bytes(uint8_t[length] bytes); - %{ #endif /* CRYPTO_CORE_H */ %} diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.c b/protocols/Tox/libtox/src/toxcore/crypto_core.c index 8e34b5876a..d5333e6760 100644 --- a/protocols/Tox/libtox/src/toxcore/crypto_core.c +++ b/protocols/Tox/libtox/src/toxcore/crypto_core.c @@ -86,14 +86,21 @@ int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2) return crypto_verify_32(pk1, pk2); } -uint32_t random_int(void) +uint16_t random_u16(void) +{ + uint16_t randnum; + randombytes((uint8_t *)&randnum, sizeof(randnum)); + return randnum; +} + +uint32_t random_u32(void) { uint32_t randnum; - randombytes((uint8_t *)&randnum , sizeof(randnum)); + randombytes((uint8_t *)&randnum, sizeof(randnum)); return randnum; } -uint64_t random_64b(void) +uint64_t random_u64(void) { uint64_t randnum; randombytes((uint8_t *)&randnum, sizeof(randnum)); diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.h b/protocols/Tox/libtox/src/toxcore/crypto_core.h index fc5756c1d2..d2742a8b72 100644 --- a/protocols/Tox/libtox/src/toxcore/crypto_core.h +++ b/protocols/Tox/libtox/src/toxcore/crypto_core.h @@ -123,14 +123,29 @@ void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length); int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2); /** + * Return a random 16 bit integer. + */ +uint16_t random_u16(void); + +/** * Return a random 32 bit integer. */ -uint32_t random_int(void); +uint32_t random_u32(void); /** * Return a random 64 bit integer. */ -uint64_t random_64b(void); +uint64_t random_u64(void); + +/** + * Fill the given nonce with random bytes. + */ +void random_nonce(uint8_t *nonce); + +/** + * Fill an array of bytes with random values. + */ +void random_bytes(uint8_t *bytes, size_t length); /** * Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not. This @@ -217,18 +232,8 @@ void increment_nonce(uint8_t *nonce); 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); - -/** * Fill a key CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes. */ void new_symmetric_key(uint8_t *key); -/** - * Fill an array of bytes with random values. - */ -void random_bytes(uint8_t *bytes, size_t length); - #endif /* CRYPTO_CORE_H */ diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.c b/protocols/Tox/libtox/src/toxcore/friend_connection.c index 9f0677b109..2ebc0d9bc0 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_connection.c +++ b/protocols/Tox/libtox/src/toxcore/friend_connection.c @@ -31,6 +31,63 @@ #define PORTS_PER_DISCOVERY 10 +typedef struct { + 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; + + int onion_friendnum; + int crypt_connection_id; + + uint64_t ping_lastrecv, 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]; + + uint16_t lock_count; + + Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS]; + uint16_t tcp_relay_counter; + + bool hosting_tcp_relay; +} Friend_Conn; + + +struct Friend_Connections { + Net_Crypto *net_crypto; + DHT *dht; + Onion_Client *onion_c; + + 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); + void *fr_request_object; + + uint64_t last_LANdiscovery; + uint16_t next_LANport; + + bool local_discovery_enabled; +}; + +Net_Crypto *friendconn_net_crypto(const Friend_Connections *fr_c) +{ + return fr_c->net_crypto; +} + + /* return 1 if the friendcon_id is not valid. * return 0 if the friendcon_id is valid. */ @@ -95,7 +152,7 @@ static int create_friend_conn(Friend_Connections *fr_c) if (realloc_friendconns(fr_c, fr_c->num_cons + 1) == 0) { id = fr_c->num_cons; ++fr_c->num_cons; - memset(&(fr_c->conns[id]), 0, sizeof(Friend_Conn)); + memset(&fr_c->conns[id], 0, sizeof(Friend_Conn)); } return id; @@ -113,7 +170,7 @@ static int wipe_friend_conn(Friend_Connections *fr_c, int friendcon_id) } uint32_t i; - memset(&(fr_c->conns[friendcon_id]), 0 , sizeof(Friend_Conn)); + memset(&fr_c->conns[friendcon_id], 0, sizeof(Friend_Conn)); for (i = fr_c->num_cons; i != 0; --i) { if (fr_c->conns[i - 1].status != FRIENDCONN_STATUS_NONE) { @@ -172,7 +229,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 (Local_ip(ip_port.ip) && public_key_cmp(friend_con->dht_temp_pk, public_key) == 0) { + 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) { ip_port.ip = friend_con->dht_ip_port.ip; } else { @@ -825,8 +882,8 @@ Friend_Connections *new_friend_connections(Onion_Client *onion_c, bool local_dis return NULL; } - temp->dht = onion_c->dht; - temp->net_crypto = onion_c->c; + temp->dht = onion_get_dht(onion_c); + temp->net_crypto = onion_get_net_crypto(onion_c); temp->onion_c = onion_c; temp->local_discovery_enabled = local_discovery_enabled; // Don't include default port in port range @@ -835,7 +892,7 @@ Friend_Connections *new_friend_connections(Onion_Client *onion_c, bool local_dis new_connection_handler(temp->net_crypto, &handle_new_connections, temp); if (temp->local_discovery_enabled) { - LANdiscovery_init(temp->dht); + lan_discovery_init(temp->dht); } return temp; @@ -850,11 +907,11 @@ static void LANdiscovery(Friend_Connections *fr_c) last = last > TOX_PORTRANGE_TO ? TOX_PORTRANGE_TO : last; // Always send to default port - send_LANdiscovery(net_htons(TOX_PORT_DEFAULT), fr_c->dht); + lan_discovery_send(net_htons(TOX_PORT_DEFAULT), fr_c->dht); // And check some extra ports for (uint16_t port = first; port < last; port++) { - send_LANdiscovery(net_htons(port), fr_c->dht); + lan_discovery_send(net_htons(port), fr_c->dht); } // Don't include default port in port range @@ -930,7 +987,7 @@ void kill_friend_connections(Friend_Connections *fr_c) } if (fr_c->local_discovery_enabled) { - LANdiscovery_kill(fr_c->dht); + lan_discovery_kill(fr_c->dht); } free(fr_c); diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.h b/protocols/Tox/libtox/src/toxcore/friend_connection.h index e993a103d3..f4d53c7a29 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_connection.h +++ b/protocols/Tox/libtox/src/toxcore/friend_connection.h @@ -61,56 +61,9 @@ enum { FRIENDCONN_STATUS_CONNECTED }; -typedef struct { - uint8_t status; +typedef struct Friend_Connections Friend_Connections; - 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; - - int onion_friendnum; - int crypt_connection_id; - - uint64_t ping_lastrecv, 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]; - - uint16_t lock_count; - - Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS]; - uint16_t tcp_relay_counter; - - bool hosting_tcp_relay; -} Friend_Conn; - - -typedef struct { - Net_Crypto *net_crypto; - DHT *dht; - Onion_Client *onion_c; - - 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); - void *fr_request_object; - - uint64_t last_LANdiscovery; - uint16_t next_LANport; - - bool local_discovery_enabled; -} Friend_Connections; +Net_Crypto *friendconn_net_crypto(const Friend_Connections *fr_c); /* return friendcon_id corresponding to the real public key on success. * return -1 on failure. diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.c b/protocols/Tox/libtox/src/toxcore/friend_requests.c index ba782e2b01..4a06654deb 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_requests.c +++ b/protocols/Tox/libtox/src/toxcore/friend_requests.c @@ -29,6 +29,24 @@ #include "util.h" +struct Friend_Requests { + uint32_t nospam; + void (*handle_friendrequest)(void *, const uint8_t *, const uint8_t *, size_t, void *); + uint8_t handle_friendrequest_isset; + void *handle_friendrequest_object; + + int (*filter_function)(const uint8_t *, void *); + 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; +}; + /* Set and get the nospam variable used to prevent one type of friend request spam. */ void set_nospam(Friend_Requests *fr, uint32_t num) { @@ -150,3 +168,13 @@ void friendreq_init(Friend_Requests *fr, Friend_Connections *fr_c) { set_friend_request_callback(fr_c, &friendreq_handlepacket, fr); } + +Friend_Requests *friendreq_new(void) +{ + return (Friend_Requests *)calloc(1, sizeof(Friend_Requests)); +} + +void friendreq_kill(Friend_Requests *fr) +{ + free(fr); +} diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.h b/protocols/Tox/libtox/src/toxcore/friend_requests.h index 316e1c671f..e6948b6cd1 100644 --- a/protocols/Tox/libtox/src/toxcore/friend_requests.h +++ b/protocols/Tox/libtox/src/toxcore/friend_requests.h @@ -28,23 +28,7 @@ #define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - (1 + sizeof(uint32_t))) -typedef struct { - uint32_t nospam; - void (*handle_friendrequest)(void *, const uint8_t *, const uint8_t *, size_t, void *); - uint8_t handle_friendrequest_isset; - void *handle_friendrequest_object; - - int (*filter_function)(const uint8_t *, void *); - 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; -} Friend_Requests; +typedef struct Friend_Requests Friend_Requests; /* Set and get the nospam variable used to prevent one type of friend request spam. */ void set_nospam(Friend_Requests *fr, uint32_t num); @@ -72,5 +56,7 @@ void set_filter_function(Friend_Requests *fr, int (*function)(const uint8_t *, v /* Sets up friendreq packet handlers. */ void friendreq_init(Friend_Requests *fr, Friend_Connections *fr_c); +Friend_Requests *friendreq_new(void); +void friendreq_kill(Friend_Requests *fr); #endif diff --git a/protocols/Tox/libtox/src/toxcore/group.c b/protocols/Tox/libtox/src/toxcore/group.c index d3f068dfce..30f241ade5 100644 --- a/protocols/Tox/libtox/src/toxcore/group.c +++ b/protocols/Tox/libtox/src/toxcore/group.c @@ -94,7 +94,7 @@ static int create_group_chat(Group_Chats *g_c) if (realloc_groupchats(g_c, g_c->num_chats + 1) == 0) { id = g_c->num_chats; ++g_c->num_chats; - memset(&(g_c->chats[id]), 0, sizeof(Group_c)); + memset(&g_c->chats[id], 0, sizeof(Group_c)); } return id; @@ -113,7 +113,7 @@ static int wipe_group_chat(Group_Chats *g_c, int groupnumber) } uint32_t i; - crypto_memzero(&(g_c->chats[groupnumber]), sizeof(Group_c)); + crypto_memzero(&g_c->chats[groupnumber], sizeof(Group_c)); for (i = g_c->num_chats; i != 0; --i) { if (g_c->chats[i - 1].status != GROUPCHAT_STATUS_NONE) { @@ -442,7 +442,7 @@ static int addpeer(Group_Chats *g_c, int groupnumber, const uint8_t *real_pk, co return -1; } - memset(&(temp[g->numpeers]), 0, sizeof(Group_Peer)); + memset(&temp[g->numpeers], 0, sizeof(Group_Peer)); g->group = temp; id_copy(g->group[g->numpeers].real_pk, real_pk); @@ -743,7 +743,7 @@ int add_groupchat(Group_Chats *g_c, uint8_t type) new_symmetric_key(g->identifier + 1); g->identifier[0] = type; g->peer_number = 0; /* Founder is peer 0. */ - memcpy(g->real_pk, g_c->m->net_crypto->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(g->real_pk, nc_get_self_public_key(g_c->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE); int peer_index = addpeer(g_c, groupnumber, g->real_pk, g_c->m->dht->self_public_key, 0, NULL, false); if (peer_index == -1) { @@ -973,7 +973,7 @@ static unsigned int send_packet_group_peer(Friend_Connections *fr_c, int friendc packet[0] = packet_id; memcpy(packet + 1, &group_num, sizeof(uint16_t)); memcpy(packet + 1 + sizeof(uint16_t), data, length); - return write_cryptpacket(fr_c->net_crypto, friend_connection_crypt_connection_id(fr_c, friendcon_id), packet, + return write_cryptpacket(friendconn_net_crypto(fr_c), friend_connection_crypt_connection_id(fr_c, friendcon_id), packet, SIZEOF_VLA(packet), 0) != -1; } @@ -994,8 +994,8 @@ static unsigned int send_lossy_group_peer(Friend_Connections *fr_c, int friendco packet[0] = packet_id; memcpy(packet + 1, &group_num, sizeof(uint16_t)); memcpy(packet + 1 + sizeof(uint16_t), data, length); - return send_lossy_cryptpacket(fr_c->net_crypto, friend_connection_crypt_connection_id(fr_c, friendcon_id), packet, - SIZEOF_VLA(packet)) != -1; + return send_lossy_cryptpacket(friendconn_net_crypto(fr_c), friend_connection_crypt_connection_id(fr_c, friendcon_id), + packet, SIZEOF_VLA(packet)) != -1; } #define INVITE_PACKET_SIZE (1 + sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH) @@ -1077,7 +1077,7 @@ int join_groupchat(Group_Chats *g_c, int32_t friendnumber, uint8_t expected_type uint16_t group_num = net_htons(groupnumber); g->status = GROUPCHAT_STATUS_VALID; g->number_joined = -1; - memcpy(g->real_pk, g_c->m->net_crypto->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(g->real_pk, nc_get_self_public_key(g_c->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE); uint8_t response[INVITE_RESPONSE_PACKET_SIZE]; response[0] = INVITE_RESPONSE_ID; @@ -1511,7 +1511,7 @@ static int send_packet_online(Friend_Connections *fr_c, int friendcon_id, uint16 packet[0] = PACKET_ID_ONLINE_PACKET; memcpy(packet + 1, &group_num, sizeof(uint16_t)); memcpy(packet + 1 + sizeof(uint16_t), identifier, GROUP_IDENTIFIER_LENGTH); - return write_cryptpacket(fr_c->net_crypto, friend_connection_crypt_connection_id(fr_c, friendcon_id), packet, + return write_cryptpacket(friendconn_net_crypto(fr_c), friend_connection_crypt_connection_id(fr_c, friendcon_id), packet, sizeof(packet), 0) != -1; } @@ -1681,7 +1681,7 @@ static int handle_send_peers(Group_Chats *g_c, int groupnumber, const uint8_t *d } if (g->status == GROUPCHAT_STATUS_VALID - && public_key_cmp(d, g_c->m->net_crypto->self_public_key) == 0) { + && public_key_cmp(d, nc_get_self_public_key(g_c->m->net_crypto)) == 0) { g->peer_number = peer_num; g->status = GROUPCHAT_STATUS_CONNECTED; group_name_send(g_c, groupnumber, g_c->m->name, g_c->m->name_length); @@ -1832,8 +1832,8 @@ static unsigned int send_lossy_all_close(const Group_Chats *g_c, int groupnumber uint64_t comp_val_old = ~0; for (i = 0; i < num_connected_closest; ++i) { - uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t dht_temp_pk[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0}; + uint8_t dht_temp_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0}; get_friendcon_public_keys(real_pk, dht_temp_pk, g_c->fr_c, g->close[connected_closest[i]].number); uint64_t comp_val = calculate_comp_value(g->real_pk, real_pk); @@ -1852,8 +1852,8 @@ static unsigned int send_lossy_all_close(const Group_Chats *g_c, int groupnumber comp_val_old = ~0; for (i = 0; i < num_connected_closest; ++i) { - uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t dht_temp_pk[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0}; + uint8_t dht_temp_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0}; get_friendcon_public_keys(real_pk, dht_temp_pk, g_c->fr_c, g->close[connected_closest[i]].number); uint64_t comp_val = calculate_comp_value(real_pk, g->real_pk); @@ -1956,6 +1956,21 @@ int group_action_send(const Group_Chats *g_c, int groupnumber, const uint8_t *ac return ret; } +/* send a group correction message + * return 0 on success + * see: send_message_group() for error codes. + */ +int group_correction_send(const Group_Chats *g_c, int groupnumber, const uint8_t *action, uint16_t length) +{ + int ret = send_message_group(g_c, groupnumber, PACKET_ID_CORRECTION, action, length); + + if (ret > 0) { + return 0; + } + + return ret; +} + /* High level function to send custom lossy packets. * * return -1 on failure. @@ -2083,24 +2098,9 @@ static void handle_message_packet_group(Group_Chats *g_c, int groupnumber, const } break; - case PACKET_ID_MESSAGE: { - if (msg_data_len == 0) { - return; - } - - VLA(uint8_t, newmsg, msg_data_len + 1); - memcpy(newmsg, msg_data, msg_data_len); - newmsg[msg_data_len] = 0; - - // TODO(irungentoo): - if (g_c->message_callback) { - g_c->message_callback(g_c->m, groupnumber, index, 0, newmsg, msg_data_len, userdata); - } - - break; - } - - case PACKET_ID_ACTION: { + case PACKET_ID_MESSAGE: + case PACKET_ID_ACTION: + case PACKET_ID_CORRECTION: { if (msg_data_len == 0) { return; } @@ -2111,7 +2111,9 @@ static void handle_message_packet_group(Group_Chats *g_c, int groupnumber, const // TODO(irungentoo): if (g_c->message_callback) { - g_c->message_callback(g_c->m, groupnumber, index, 1, newmsg, msg_data_len, userdata); + uint8_t chat_message_id = message_id - PACKET_ID_MESSAGE; + g_c->message_callback(g_c->m, groupnumber, index, chat_message_id, + newmsg, msg_data_len, userdata); } break; diff --git a/protocols/Tox/libtox/src/toxcore/group.h b/protocols/Tox/libtox/src/toxcore/group.h index 2e014da36d..6c0baebffb 100644 --- a/protocols/Tox/libtox/src/toxcore/group.h +++ b/protocols/Tox/libtox/src/toxcore/group.h @@ -238,6 +238,12 @@ int group_message_send(const Group_Chats *g_c, int groupnumber, const uint8_t *m */ int group_action_send(const Group_Chats *g_c, int groupnumber, const uint8_t *action, uint16_t length); +/* send a group correction message + * return 0 on success + * see: send_message_group() for error codes. + */ +int group_correction_send(const Group_Chats *g_c, int groupnumber, const uint8_t *action, uint16_t length); + /* set the group's title, limited to MAX_NAME_LENGTH * return 0 on success * return -1 if groupnumber is invalid. diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.c b/protocols/Tox/libtox/src/toxcore/net_crypto.c index 440db94abd..521dad2f1c 100644 --- a/protocols/Tox/libtox/src/toxcore/net_crypto.c +++ b/protocols/Tox/libtox/src/toxcore/net_crypto.c @@ -33,6 +33,146 @@ #include <math.h> +typedef struct { + uint64_t sent_time; + uint16_t length; + uint8_t data[MAX_CRYPTO_DATA_SIZE]; +} Packet_Data; + +typedef struct { + 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 { + 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. */ + uint8_t sessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public key for this session. */ + 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. + */ + 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 */ + + uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ + uint16_t temp_packet_length; + uint64_t temp_packet_sent_time; /* The time at which the last temp_packet was sent in ms. */ + uint32_t temp_packet_num_sent; + + IP_Port ip_portv4; /* The ip and port to contact this guy directly.*/ + IP_Port ip_portv6; + uint64_t direct_lastrecv_timev4; /* The Time at which we last received a direct packet in ms. */ + uint64_t direct_lastrecv_timev6; + + uint64_t last_tcp_sent; /* Time the last TCP packet was sent. */ + + Packets_Array send_array; + Packets_Array recv_array; + + int (*connection_status_callback)(void *object, int id, uint8_t status, void *userdata); + 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); + 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); + void *connection_lossy_data_callback_object; + int connection_lossy_data_callback_id; + + uint64_t last_request_packet_sent; + uint64_t direct_send_attempt_time; + + uint32_t packet_counter; + double packet_recv_rate; + uint64_t packet_counter_set; + + double packet_send_rate; + uint32_t packets_left; + uint64_t last_packets_left_set; + double last_packets_left_rem; + + double packet_send_rate_requested; + uint32_t packets_left_requested; + 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; + uint64_t last_congestion_event; + uint64_t rtt_time; + + /* TCP_connection connection_number */ + unsigned int connection_number_tcp; + + uint8_t maximum_speed_reached; + + pthread_mutex_t mutex; + + void (*dht_pk_callback)(void *data, int32_t number, const uint8_t *dht_public_key, void *userdata); + void *dht_pk_callback_object; + uint32_t dht_pk_callback_number; +} Crypto_Connection; + +struct Net_Crypto { + Logger *log; + + DHT *dht; + TCP_Connections *tcp_c; + + Crypto_Connection *crypto_connections; + pthread_mutex_t tcp_mutex; + + pthread_mutex_t connections_mutex; + unsigned int connection_use_counter; + + uint32_t crypto_connections_length; /* Length of connections array. */ + + /* Our public and secret keys. */ + uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; + + /* 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); + void *new_connection_callback_object; + + /* The current optimal sleep time */ + uint32_t current_sleep_time; + + BS_LIST ip_port_list; +}; + +const uint8_t *nc_get_self_public_key(const Net_Crypto *c) +{ + return c->self_public_key; +} + +const uint8_t *nc_get_self_secret_key(const Net_Crypto *c) +{ + return c->self_secret_key; +} + +TCP_Connections *nc_get_tcp_c(const Net_Crypto *c) +{ + return c->tcp_c; +} + +DHT *nc_get_dht(const Net_Crypto *c) +{ + return c->dht; +} static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id) { @@ -432,7 +572,7 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Por } if (ip_port.ip.family == TOX_AF_INET) { - if (!ipport_equal(&ip_port, &conn->ip_portv4) && LAN_ip(conn->ip_portv4.ip) != 0) { + 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; } @@ -482,7 +622,7 @@ static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id) v6 = 1; } - if (v4 && LAN_ip(conn->ip_portv4.ip) == 0) { + if (v4 && ip_is_lan(conn->ip_portv4.ip) == 0) { return conn->ip_portv4; } @@ -1608,7 +1748,7 @@ static int create_crypto_connection(Net_Crypto *c) if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == 0) { id = c->crypto_connections_length; ++c->crypto_connections_length; - memset(&(c->crypto_connections[id]), 0, sizeof(Crypto_Connection)); + memset(&c->crypto_connections[id], 0, sizeof(Crypto_Connection)); // Memsetting float/double to 0 is non-portable, so we explicitly set them to 0 c->crypto_connections[id].packet_recv_rate = 0; c->crypto_connections[id].packet_send_rate = 0; @@ -1641,7 +1781,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) /* Keep mutex, only destroy it when connection is realloced out. */ pthread_mutex_t mutex = c->crypto_connections[crypt_connection_id].mutex; - crypto_memzero(&(c->crypto_connections[crypt_connection_id]), sizeof(Crypto_Connection)); + crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection)); c->crypto_connections[crypt_connection_id].mutex = mutex; for (i = c->crypto_connections_length; i != 0; --i) { @@ -1892,7 +2032,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u conn->rtt_time = DEFAULT_PING_CONNECTION; memcpy(conn->dht_public_key, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); - conn->cookie_request_number = random_64b(); + conn->cookie_request_number = random_u64(); uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.h b/protocols/Tox/libtox/src/toxcore/net_crypto.h index 5ec5ca94fb..bd00a3fe33 100644 --- a/protocols/Tox/libtox/src/toxcore/net_crypto.h +++ b/protocols/Tox/libtox/src/toxcore/net_crypto.h @@ -89,98 +89,14 @@ #define DEFAULT_PING_CONNECTION 1000 #define DEFAULT_TCP_PING_CONNECTION 500 -typedef struct { - uint64_t sent_time; - uint16_t length; - uint8_t data[MAX_CRYPTO_DATA_SIZE]; -} Packet_Data; - -typedef struct { - 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 { - 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. */ - uint8_t sessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public key for this session. */ - 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. - */ - 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 */ - - uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ - uint16_t temp_packet_length; - uint64_t temp_packet_sent_time; /* The time at which the last temp_packet was sent in ms. */ - uint32_t temp_packet_num_sent; - - IP_Port ip_portv4; /* The ip and port to contact this guy directly.*/ - IP_Port ip_portv6; - uint64_t direct_lastrecv_timev4; /* The Time at which we last received a direct packet in ms. */ - uint64_t direct_lastrecv_timev6; - - uint64_t last_tcp_sent; /* Time the last TCP packet was sent. */ - - Packets_Array send_array; - Packets_Array recv_array; - - int (*connection_status_callback)(void *object, int id, uint8_t status, void *userdata); - 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); - 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); - void *connection_lossy_data_callback_object; - int connection_lossy_data_callback_id; - - uint64_t last_request_packet_sent; - uint64_t direct_send_attempt_time; - - uint32_t packet_counter; - double packet_recv_rate; - uint64_t packet_counter_set; - - double packet_send_rate; - uint32_t packets_left; - uint64_t last_packets_left_set; - double last_packets_left_rem; - - double packet_send_rate_requested; - uint32_t packets_left_requested; - 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; - uint64_t last_congestion_event; - uint64_t rtt_time; - - /* TCP_connection connection_number */ - unsigned int connection_number_tcp; - - uint8_t maximum_speed_reached; - - pthread_mutex_t mutex; - - void (*dht_pk_callback)(void *data, int32_t number, const uint8_t *dht_public_key, void *userdata); - void *dht_pk_callback_object; - uint32_t dht_pk_callback_number; -} Crypto_Connection; - -typedef struct { +typedef struct Net_Crypto Net_Crypto; + +const uint8_t *nc_get_self_public_key(const Net_Crypto *c); +const uint8_t *nc_get_self_secret_key(const Net_Crypto *c); +TCP_Connections *nc_get_tcp_c(const Net_Crypto *c); +DHT *nc_get_dht(const Net_Crypto *c); + +typedef struct New_Connection { IP_Port source; uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer. */ @@ -190,37 +106,6 @@ typedef struct { uint8_t cookie_length; } New_Connection; -typedef struct { - Logger *log; - - DHT *dht; - TCP_Connections *tcp_c; - - Crypto_Connection *crypto_connections; - pthread_mutex_t tcp_mutex; - - pthread_mutex_t connections_mutex; - unsigned int connection_use_counter; - - uint32_t crypto_connections_length; /* Length of connections array. */ - - /* Our public and secret keys. */ - uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; - - /* 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); - void *new_connection_callback_object; - - /* The current optimal sleep time */ - uint32_t current_sleep_time; - - BS_LIST ip_port_list; -} Net_Crypto; - - /* 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. diff --git a/protocols/Tox/libtox/src/toxcore/network.c b/protocols/Tox/libtox/src/toxcore/network.c index 7587826b51..fb4748d4ec 100644 --- a/protocols/Tox/libtox/src/toxcore/network.c +++ b/protocols/Tox/libtox/src/toxcore/network.c @@ -388,6 +388,31 @@ static void loglogdata(Logger *log, const char *message, const uint8_t *buffer, } } +typedef struct { + packet_handler_callback function; + void *object; +} Packet_Handler; + +struct Networking_Core { + Logger *log; + Packet_Handler packethandlers[256]; + + Family family; + uint16_t port; + /* Our UDP socket. */ + Socket sock; +}; + +Family net_family(const Networking_Core *net) +{ + return net->family; +} + +uint16_t net_port(const Networking_Core *net) +{ + return net->port; +} + /* Basic network functions: * Function to send packet(data) of length length to ip_port. */ @@ -816,6 +841,20 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1 return NULL; } +Networking_Core *new_networking_no_udp(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)); + + if (net == NULL) { + return NULL; + } + + net->log = log; + + return net; +} + /* Function to cleanup networking stuff. */ void kill_networking(Networking_Core *net) { @@ -1273,12 +1312,14 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type) assert(count <= MAX_COUNT); if (count == 0) { + freeaddrinfo(infos); return 0; } *res = (IP_Port *)malloc(sizeof(IP_Port) * count); if (*res == NULL) { + freeaddrinfo(infos); return -1; } diff --git a/protocols/Tox/libtox/src/toxcore/network.h b/protocols/Tox/libtox/src/toxcore/network.h index 41d1307a36..d3b80218b0 100644 --- a/protocols/Tox/libtox/src/toxcore/network.h +++ b/protocols/Tox/libtox/src/toxcore/network.h @@ -140,26 +140,25 @@ typedef union { uint16_t uint16[8]; uint32_t uint32[4]; uint64_t uint64[2]; -} -IP6; +} IP6; IP6 get_ip6_loopback(void); extern const IP6 IP6_BROADCAST; +#define IP_DEFINED typedef struct { uint8_t family; GNU_EXTENSION union { IP4 ip4; IP6 ip6; }; -} -IP; +} IP; -typedef struct { +#define IP_PORT_DEFINED +typedef struct IP_Port { IP ip; uint16_t port; -} -IP_Port; +} IP_Port; /* Convert values between host and network byte order. */ @@ -303,20 +302,10 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra); typedef int (*packet_handler_callback)(void *object, IP_Port ip_port, const uint8_t *data, uint16_t len, void *userdata); -typedef struct { - packet_handler_callback function; - void *object; -} Packet_Handles; - -typedef struct { - Logger *log; - Packet_Handles packethandlers[256]; +typedef struct Networking_Core Networking_Core; - Family family; - uint16_t port; - /* Our UDP socket. */ - Socket sock; -} Networking_Core; +Family net_family(const Networking_Core *net); +uint16_t net_port(const Networking_Core *net); /* Run this before creating sockets. * @@ -415,6 +404,7 @@ int bind_to_port(Socket sock, int family, uint16_t port); */ 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); /* 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_announce.c b/protocols/Tox/libtox/src/toxcore/onion_announce.c index c093800719..ab96a546fb 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_announce.c +++ b/protocols/Tox/libtox/src/toxcore/onion_announce.c @@ -37,6 +37,34 @@ #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 { + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; + IP_Port ret_ip_port; + uint8_t ret[ONION_RETURN_3]; + uint8_t data_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint64_t time; +} Onion_Announce_Entry; + +struct Onion_Announce { + DHT *dht; + Networking_Core *net; + Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES]; + /* This is CRYPTO_SYMMETRIC_KEY_SIZE long just so we can use new_symmetric_key() to fill it */ + uint8_t secret_bytes[CRYPTO_SYMMETRIC_KEY_SIZE]; + + Shared_Keys shared_keys_recv; +}; + +uint8_t *onion_announce_entry_public_key(Onion_Announce *onion_a, uint32_t entry) +{ + return onion_a->entries[entry].public_key; +} + +void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint64_t time) +{ + onion_a->entries[entry].time = time; +} + /* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_ANNOUNCE_REQUEST_SIZE). * * dest_client_id is the public key of the node the packet will be sent to. @@ -377,7 +405,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, - LAN_ip(source.ip) == 0, 1); + 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 548d4b798b..36484ff22a 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_announce.h +++ b/protocols/Tox/libtox/src/toxcore/onion_announce.h @@ -46,23 +46,11 @@ #define ONION_DATA_REQUEST_MIN_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE) #define MAX_DATA_REQUEST_SIZE (ONION_MAX_DATA_SIZE - ONION_DATA_REQUEST_MIN_SIZE) -typedef struct { - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; - IP_Port ret_ip_port; - uint8_t ret[ONION_RETURN_3]; - uint8_t data_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint64_t time; -} Onion_Announce_Entry; - -typedef struct { - DHT *dht; - Networking_Core *net; - Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES]; - /* This is CRYPTO_SYMMETRIC_KEY_SIZE long just so we can use new_symmetric_key() to fill it */ - uint8_t secret_bytes[CRYPTO_SYMMETRIC_KEY_SIZE]; - - Shared_Keys shared_keys_recv; -} Onion_Announce; +typedef struct Onion_Announce Onion_Announce; + +/* These two are not public; they are for tests only! */ +uint8_t *onion_announce_entry_public_key(Onion_Announce *onion_a, uint32_t entry); +void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint64_t time); /* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_ANNOUNCE_REQUEST_SIZE). * diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.c b/protocols/Tox/libtox/src/toxcore/onion_client.c index 94e9c91652..f7ff41bd7a 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_client.c +++ b/protocols/Tox/libtox/src/toxcore/onion_client.c @@ -36,6 +36,123 @@ #define ANNOUNCE_ARRAY_SIZE 256 #define ANNOUNCE_TIMEOUT 10 +typedef struct { + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; + IP_Port ip_port; + uint8_t ping_id[ONION_PING_ID_SIZE]; + uint8_t data_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t is_stored; + + uint64_t added_time; + + uint64_t timestamp; + + uint64_t last_pinged; + + uint8_t unsuccessful_pings; + + uint32_t path_used; +} Onion_Node; + +typedef struct { + Onion_Path paths[NUMBER_ONION_PATHS]; + uint64_t last_path_success[NUMBER_ONION_PATHS]; + uint64_t last_path_used[NUMBER_ONION_PATHS]; + uint64_t path_creation_time[NUMBER_ONION_PATHS]; + /* number of times used without success. */ + unsigned int last_path_used_times[NUMBER_ONION_PATHS]; +} Onion_Client_Paths; + +typedef struct { + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint64_t timestamp; +} Last_Pinged; + +typedef struct { + 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. */ + + uint8_t know_dht_public_key; /* 0 if we don't know the dht public key of the other, 1 if we do. */ + uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t real_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + + Onion_Node clients_list[MAX_ONION_CLIENTS]; + uint8_t temp_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE]; + + uint64_t last_reported_announced; + + uint64_t last_dht_pk_onion_sent; + uint64_t last_dht_pk_dht_sent; + + uint64_t last_noreplay; + + uint64_t last_seen; + + 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); + 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); + void *dht_pk_callback_object; + uint32_t dht_pk_callback_number; + + uint32_t run_count; +} Onion_Friend; + +struct Onion_Client { + DHT *dht; + Net_Crypto *c; + Networking_Core *net; + Onion_Friend *friends_list; + uint16_t num_friends; + + Onion_Node clients_announce_list[MAX_ONION_CLIENTS_ANNOUNCE]; + uint64_t last_announce; + + Onion_Client_Paths onion_paths_self; + Onion_Client_Paths onion_paths_friends; + + uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; + uint64_t last_run, first_run; + + uint8_t temp_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE]; + + Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; + + Node_format path_nodes[MAX_PATH_NODES]; + uint16_t path_nodes_index; + + Node_format path_nodes_bs[MAX_PATH_NODES]; + uint16_t path_nodes_index_bs; + + Ping_Array *announce_ping_array; + uint8_t last_pinged_index; + struct { + oniondata_handler_callback function; + void *object; + } Onion_Data_Handlers[256]; + + uint64_t last_packet_recv; + + unsigned int onion_connected; + bool UDP_connected; +}; + +DHT *onion_get_dht(const Onion_Client *onion_c) +{ + return onion_c->dht; +} + +Net_Crypto *onion_get_net_crypto(const Onion_Client *onion_c) +{ + return onion_c->c; +} + /* Add a node to the path_nodes bootstrap array. * * return -1 on failure @@ -397,7 +514,7 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *publ memcpy(data + sizeof(uint32_t), public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, &ip_port, sizeof(IP_Port)); memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), &path_num, sizeof(uint32_t)); - *sendback = ping_array_add(&onion_c->announce_ping_array, data, sizeof(data)); + *sendback = ping_array_add(onion_c->announce_ping_array, data, sizeof(data)); if (*sendback == 0) { return -1; @@ -423,7 +540,7 @@ static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, u memcpy(&sback, sendback, sizeof(uint64_t)); uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)]; - if (ping_array_check(data, sizeof(data), &onion_c->announce_ping_array, sback) != sizeof(data)) { + if (ping_array_check(onion_c->announce_ping_array, data, sizeof(data), sback) != sizeof(data)) { return ~0; } @@ -470,12 +587,13 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_ int len; if (num == 0) { - len = create_announce_request(request, sizeof(request), dest_pubkey, onion_c->c->self_public_key, - onion_c->c->self_secret_key, ping_id, onion_c->c->self_public_key, onion_c->temp_public_key, sendback); + len = create_announce_request(request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c), + nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c), + onion_c->temp_public_key, sendback); } else { len = create_announce_request(request, sizeof(request), dest_pubkey, onion_c->friends_list[num - 1].temp_public_key, - onion_c->friends_list[num - 1].temp_secret_key, ping_id, onion_c->friends_list[num - 1].real_public_key, zero_ping_id, - sendback); + onion_c->friends_list[num - 1].temp_secret_key, ping_id, + onion_c->friends_list[num - 1].real_public_key, zero_ping_id, sendback); } if (len == -1) { @@ -553,12 +671,12 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t } Onion_Node *list_nodes = NULL; - uint8_t *reference_id = NULL; + const uint8_t *reference_id = NULL; unsigned int list_length; if (num == 0) { list_nodes = onion_c->clients_announce_list; - reference_id = onion_c->c->self_public_key; + reference_id = nc_get_self_public_key(onion_c->c); list_length = MAX_ONION_CLIENTS_ANNOUNCE; if (is_stored == 1 && public_key_cmp(pingid_or_key, onion_c->temp_public_key) != 0) { @@ -655,7 +773,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for } Onion_Node *list_nodes = NULL; - uint8_t *reference_id = NULL; + const uint8_t *reference_id = NULL; unsigned int list_length; Last_Pinged *last_pinged = NULL; @@ -663,7 +781,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for if (num == 0) { list_nodes = onion_c->clients_announce_list; - reference_id = onion_c->c->self_public_key; + reference_id = nc_get_self_public_key(onion_c->c); list_length = MAX_ONION_CLIENTS_ANNOUNCE; last_pinged = onion_c->last_pinged; last_pinged_index = &onion_c->last_pinged_index; @@ -676,12 +794,12 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for } unsigned int i, j; - int lan_ips_accepted = (LAN_ip(source.ip) == 0); + int lan_ips_accepted = (ip_is_lan(source.ip) == 0); for (i = 0; i < num_nodes; ++i) { if (!lan_ips_accepted) { - if (LAN_ip(nodes[i].ip_port.ip) == 0) { + if (ip_is_lan(nodes[i].ip_port.ip) == 0) { continue; } } @@ -730,7 +848,8 @@ static int handle_announce_response(void *object, IP_Port source, const uint8_t int len = -1; if (num == 0) { - len = decrypt_data(public_key, onion_c->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, + len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c), + packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain); } else { @@ -796,7 +915,8 @@ static int handle_data_response(void *object, IP_Port source, const uint8_t *pac } VLA(uint8_t, plain, SIZEOF_VLA(temp_plain) - DATA_IN_RESPONSE_MIN_SIZE); - len = decrypt_data(temp_plain, onion_c->c->self_secret_key, packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE, + len = decrypt_data(temp_plain, nc_get_self_secret_key(onion_c->c), + packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE, SIZEOF_VLA(temp_plain) - CRYPTO_PUBLIC_KEY_SIZE, plain); if ((uint32_t)len != SIZEOF_VLA(plain)) { @@ -947,8 +1067,9 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, random_nonce(nonce); VLA(uint8_t, packet, DATA_IN_RESPONSE_MIN_SIZE + length); - memcpy(packet, onion_c->c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); - int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, onion_c->c->self_secret_key, nonce, data, + memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE); + int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, + nc_get_self_secret_key(onion_c->c), nonce, data, length, packet + CRYPTO_PUBLIC_KEY_SIZE); if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE != SIZEOF_VLA(packet)) { @@ -1001,9 +1122,10 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin random_nonce(nonce); VLA(uint8_t, temp, DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE + length); - memcpy(temp, onion_c->c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(temp, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE); memcpy(temp + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); - int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, onion_c->c->self_secret_key, nonce, data, + int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, + nc_get_self_secret_key(onion_c->c), nonce, data, length, temp + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE != SIZEOF_VLA(temp)) { @@ -1035,7 +1157,8 @@ static int handle_dht_dhtpk(void *object, IP_Port source, const uint8_t *source_ } uint8_t plain[DHTPK_DATA_MAX_LENGTH]; - int len = decrypt_data(packet, onion_c->c->self_secret_key, packet + CRYPTO_PUBLIC_KEY_SIZE, + int len = decrypt_data(packet, nc_get_self_secret_key(onion_c->c), + packet + CRYPTO_PUBLIC_KEY_SIZE, packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, length - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), plain); @@ -1179,7 +1302,7 @@ int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key) } index = onion_c->num_friends; - memset(&(onion_c->friends_list[onion_c->num_friends]), 0, sizeof(Onion_Friend)); + memset(&onion_c->friends_list[onion_c->num_friends], 0, sizeof(Onion_Friend)); ++onion_c->num_friends; } @@ -1203,7 +1326,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num) //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); - crypto_memzero(&(onion_c->friends_list[friend_num]), sizeof(Onion_Friend)); + crypto_memzero(&onion_c->friends_list[friend_num], sizeof(Onion_Friend)); unsigned int i; for (i = onion_c->num_friends; i != 0; --i) { @@ -1702,11 +1825,11 @@ void do_onion_client(Onion_Client *onion_c) 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(onion_c->c->tcp_c, !UDP_connected); + set_tcp_onion_status(nc_get_tcp_c(onion_c->c), !UDP_connected); } onion_c->UDP_connected = UDP_connected - || get_random_tcp_onion_conn_number(onion_c->c->tcp_c) == -1; /* Check if connected to any TCP relays. */ + || 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)) { for (i = 0; i < onion_c->num_friends; ++i) { @@ -1733,13 +1856,15 @@ Onion_Client *new_onion_client(Net_Crypto *c) return NULL; } - if (ping_array_init(&onion_c->announce_ping_array, ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT) != 0) { + onion_c->announce_ping_array = ping_array_new(ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT); + + if (onion_c->announce_ping_array == NULL) { free(onion_c); return NULL; } - onion_c->dht = c->dht; - onion_c->net = c->dht->net; + onion_c->dht = nc_get_dht(c); + onion_c->net = onion_c->dht->net; onion_c->c = c; new_symmetric_key(onion_c->secret_symmetric_key); crypto_new_keypair(onion_c->temp_public_key, onion_c->temp_secret_key); @@ -1747,7 +1872,7 @@ Onion_Client *new_onion_client(Net_Crypto *c) networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c); cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c); - set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, &handle_tcp_onion, onion_c); + set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), &handle_tcp_onion, onion_c); return onion_c; } @@ -1758,14 +1883,13 @@ void kill_onion_client(Onion_Client *onion_c) return; } - ping_array_free_all(&onion_c->announce_ping_array); + ping_array_kill(onion_c->announce_ping_array); realloc_onion_friends(onion_c, 0); networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL); networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL); cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, NULL, NULL); - set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, NULL, NULL); + set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), NULL, NULL); crypto_memzero(onion_c, sizeof(Onion_Client)); free(onion_c); } - diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.h b/protocols/Tox/libtox/src/toxcore/onion_client.h index 216dbec050..327d492326 100644 --- a/protocols/Tox/libtox/src/toxcore/onion_client.h +++ b/protocols/Tox/libtox/src/toxcore/onion_client.h @@ -65,116 +65,10 @@ #define ONION_DATA_FRIEND_REQ CRYPTO_PACKET_FRIEND_REQ #define ONION_DATA_DHTPK CRYPTO_PACKET_DHTPK -typedef struct { - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; - IP_Port ip_port; - uint8_t ping_id[ONION_PING_ID_SIZE]; - uint8_t data_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t is_stored; - - uint64_t added_time; - - uint64_t timestamp; - - uint64_t last_pinged; - - uint8_t unsuccessful_pings; - - uint32_t path_used; -} Onion_Node; - -typedef struct { - Onion_Path paths[NUMBER_ONION_PATHS]; - uint64_t last_path_success[NUMBER_ONION_PATHS]; - uint64_t last_path_used[NUMBER_ONION_PATHS]; - uint64_t path_creation_time[NUMBER_ONION_PATHS]; - /* number of times used without success. */ - unsigned int last_path_used_times[NUMBER_ONION_PATHS]; -} Onion_Client_Paths; - -typedef struct { - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint64_t timestamp; -} Last_Pinged; - -typedef struct { - 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. */ - - uint8_t know_dht_public_key; /* 0 if we don't know the dht public key of the other, 1 if we do. */ - uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t real_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - - Onion_Node clients_list[MAX_ONION_CLIENTS]; - uint8_t temp_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE]; - - uint64_t last_reported_announced; - - uint64_t last_dht_pk_onion_sent; - uint64_t last_dht_pk_dht_sent; - - uint64_t last_noreplay; - - uint64_t last_seen; - - 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); - 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); - void *dht_pk_callback_object; - uint32_t dht_pk_callback_number; - - uint32_t run_count; -} Onion_Friend; - -typedef int (*oniondata_handler_callback)(void *object, const uint8_t *source_pubkey, const uint8_t *data, - uint16_t len, void *userdata); - -typedef struct { - DHT *dht; - Net_Crypto *c; - Networking_Core *net; - Onion_Friend *friends_list; - uint16_t num_friends; - - Onion_Node clients_announce_list[MAX_ONION_CLIENTS_ANNOUNCE]; - uint64_t last_announce; - - Onion_Client_Paths onion_paths_self; - Onion_Client_Paths onion_paths_friends; - - uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; - uint64_t last_run, first_run; - - uint8_t temp_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE]; - - Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; - - Node_format path_nodes[MAX_PATH_NODES]; - uint16_t path_nodes_index; - - Node_format path_nodes_bs[MAX_PATH_NODES]; - uint16_t path_nodes_index_bs; - - Ping_Array announce_ping_array; - uint8_t last_pinged_index; - struct { - oniondata_handler_callback function; - void *object; - } Onion_Data_Handlers[256]; - - uint64_t last_packet_recv; - - unsigned int onion_connected; - bool UDP_connected; -} Onion_Client; +typedef struct Onion_Client Onion_Client; +DHT *onion_get_dht(const Onion_Client *onion_c); +Net_Crypto *onion_get_net_crypto(const Onion_Client *onion_c); /* Add a node to the path_nodes bootstrap array. * @@ -283,6 +177,9 @@ 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); + /* 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); diff --git a/protocols/Tox/libtox/src/toxcore/ping.api.h b/protocols/Tox/libtox/src/toxcore/ping.api.h new file mode 100644 index 0000000000..edc04723a0 --- /dev/null +++ b/protocols/Tox/libtox/src/toxcore/ping.api.h @@ -0,0 +1,65 @@ +%{ +/* + * Buffered pinging using cyclic arrays. + */ + +/* + * Copyright © 2016-2017 The TokTok team. + * Copyright © 2013 Tox project. + * Copyright © 2013 plutooo + * + * This file is part of Tox, the free peer to peer instant messenger. + * This file is donated to the Tox Project. + * + * Tox is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tox is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tox. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef PING_H +#define PING_H + +#include "DHT.h" +#include "network.h" + +#include <stdint.h> +%} + +class iP_Port { struct this; } +class dHT { struct this; } + +class ping { + +struct this; + +static this new(dHT::this *dht); +void kill(); + +/** Add nodes to the to_ping list. + * All nodes in this list are pinged every TIME_TOPING seconds + * and are then removed from the list. + * If the list is full the nodes farthest from our public_key are replaced. + * The purpose of this list is to enable quick integration of new nodes into the + * network while preventing amplification attacks. + * + * return 0 if node was added. + * return -1 if node was not added. + */ +int32_t add(const uint8_t *public_key, iP_Port::this ip_port); +void iterate(); + +int32_t send_request(iP_Port::this ipp, const uint8_t *public_key); + +} + +%{ +#endif /* PING_H */ +%} diff --git a/protocols/Tox/libtox/src/toxcore/ping.c b/protocols/Tox/libtox/src/toxcore/ping.c index 72b3fe6259..f2f560136f 100644 --- a/protocols/Tox/libtox/src/toxcore/ping.c +++ b/protocols/Tox/libtox/src/toxcore/ping.c @@ -45,10 +45,10 @@ #define TIME_TO_PING 2 -struct PING { +struct Ping { DHT *dht; - Ping_Array ping_array; + Ping_Array *ping_array; Node_format to_ping[MAX_TO_PING]; uint64_t last_to_ping; }; @@ -58,7 +58,7 @@ struct PING { #define DHT_PING_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + PING_PLAIN_SIZE + CRYPTO_MAC_SIZE) #define PING_DATA_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port)) -int send_ping_request(PING *ping, IP_Port ipp, const uint8_t *public_key) +int32_t ping_send_request(Ping *ping, IP_Port ipp, const uint8_t *public_key) { uint8_t pk[DHT_PING_SIZE]; int rc; @@ -76,7 +76,7 @@ int send_ping_request(PING *ping, IP_Port ipp, const uint8_t *public_key) uint8_t data[PING_DATA_SIZE]; id_copy(data, public_key); memcpy(data + CRYPTO_PUBLIC_KEY_SIZE, &ipp, sizeof(IP_Port)); - ping_id = ping_array_add(&ping->ping_array, data, sizeof(data)); + ping_id = ping_array_add(ping->ping_array, data, sizeof(data)); if (ping_id == 0) { return 1; @@ -103,7 +103,7 @@ int send_ping_request(PING *ping, IP_Port ipp, const uint8_t *public_key) return sendpacket(ping->dht->net, ipp, pk, sizeof(pk)); } -static int send_ping_response(PING *ping, IP_Port ipp, const uint8_t *public_key, uint64_t ping_id, +static int ping_send_response(Ping *ping, IP_Port ipp, const uint8_t *public_key, uint64_t ping_id, uint8_t *shared_encryption_key) { uint8_t pk[DHT_PING_SIZE]; @@ -143,7 +143,7 @@ static int handle_ping_request(void *object, IP_Port source, const uint8_t *pack return 1; } - PING *ping = dht->ping; + Ping *ping = dht->ping; if (id_equal(packet + 1, ping->dht->self_public_key)) { return 1; @@ -171,8 +171,8 @@ static int handle_ping_request(void *object, IP_Port source, const uint8_t *pack uint64_t ping_id; memcpy(&ping_id, ping_plain + 1, sizeof(ping_id)); // Send response - send_ping_response(ping, source, packet + 1, ping_id, shared_key); - add_to_ping(ping, packet + 1, source); + ping_send_response(ping, source, packet + 1, ping_id, shared_key); + ping_add(ping, packet + 1, source); return 0; } @@ -186,7 +186,7 @@ static int handle_ping_response(void *object, IP_Port source, const uint8_t *pac return 1; } - PING *ping = dht->ping; + Ping *ping = dht->ping; if (id_equal(packet + 1, ping->dht->self_public_key)) { return 1; @@ -217,7 +217,7 @@ static int handle_ping_response(void *object, IP_Port source, const uint8_t *pac memcpy(&ping_id, ping_plain + 1, sizeof(ping_id)); uint8_t data[PING_DATA_SIZE]; - if (ping_array_check(data, sizeof(data), &ping->ping_array, ping_id) != sizeof(data)) { + if (ping_array_check(ping->ping_array, data, sizeof(data), ping_id) != sizeof(data)) { return 1; } @@ -274,7 +274,7 @@ static int in_list(const Client_data *list, uint16_t length, const uint8_t *publ * return 0 if node was added. * return -1 if node was not added. */ -int add_to_ping(PING *ping, const uint8_t *public_key, IP_Port ip_port) +int32_t ping_add(Ping *ping, const uint8_t *public_key, IP_Port ip_port) { if (!ip_isset(&ip_port.ip)) { return -1; @@ -291,7 +291,7 @@ int add_to_ping(PING *ping, const uint8_t *public_key, IP_Port ip_port) IP_Port temp; if (DHT_getfriendip(ping->dht, public_key, &temp) == 0) { - send_ping_request(ping, ip_port, public_key); + ping_send_request(ping, ip_port, public_key); return -1; } @@ -320,7 +320,7 @@ int add_to_ping(PING *ping, const uint8_t *public_key, IP_Port ip_port) /* Ping all the valid nodes in the to_ping list every TIME_TO_PING seconds. * This function must be run at least once every TIME_TO_PING seconds. */ -void do_to_ping(PING *ping) +void ping_iterate(Ping *ping) { if (!is_timeout(ping->last_to_ping, TIME_TO_PING)) { return; @@ -341,7 +341,7 @@ void do_to_ping(PING *ping) continue; } - send_ping_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].public_key); + ping_send_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].public_key); ip_reset(&ping->to_ping[i].ip_port.ip); } @@ -351,15 +351,17 @@ void do_to_ping(PING *ping) } -PING *new_ping(DHT *dht) +Ping *ping_new(DHT *dht) { - PING *ping = (PING *)calloc(1, sizeof(PING)); + Ping *ping = (Ping *)calloc(1, sizeof(Ping)); if (ping == NULL) { return NULL; } - if (ping_array_init(&ping->ping_array, PING_NUM_MAX, PING_TIMEOUT) != 0) { + ping->ping_array = ping_array_new(PING_NUM_MAX, PING_TIMEOUT); + + if (ping->ping_array == NULL) { free(ping); return NULL; } @@ -371,11 +373,11 @@ PING *new_ping(DHT *dht) return ping; } -void kill_ping(PING *ping) +void ping_kill(Ping *ping) { networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, NULL, NULL); networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, NULL, NULL); - ping_array_free_all(&ping->ping_array); + ping_array_kill(ping->ping_array); free(ping); } diff --git a/protocols/Tox/libtox/src/toxcore/ping.h b/protocols/Tox/libtox/src/toxcore/ping.h index cc3428c548..61875a0bd8 100644 --- a/protocols/Tox/libtox/src/toxcore/ping.h +++ b/protocols/Tox/libtox/src/toxcore/ping.h @@ -31,9 +31,26 @@ #include <stdint.h> -typedef struct PING PING; +#ifndef IP_PORT_DEFINED +#define IP_PORT_DEFINED +typedef struct IP_Port IP_Port; +#endif /* IP_PORT_DEFINED */ -/* Add nodes to the to_ping list. +#ifndef DHT_DEFINED +#define DHT_DEFINED +typedef struct DHT DHT; +#endif /* DHT_DEFINED */ + +#ifndef PING_DEFINED +#define PING_DEFINED +typedef struct Ping Ping; +#endif /* PING_DEFINED */ + +Ping *ping_new(DHT *dht); + +void ping_kill(Ping *ping); + +/** Add nodes to the to_ping list. * All nodes in this list are pinged every TIME_TOPING seconds * and are then removed from the list. * If the list is full the nodes farthest from our public_key are replaced. @@ -43,12 +60,10 @@ typedef struct PING PING; * return 0 if node was added. * return -1 if node was not added. */ -int add_to_ping(PING *ping, const uint8_t *public_key, IP_Port ip_port); -void do_to_ping(PING *ping); +int32_t ping_add(Ping *ping, const uint8_t *public_key, struct IP_Port ip_port); -PING *new_ping(DHT *dht); -void kill_ping(PING *ping); +void ping_iterate(Ping *ping); -int send_ping_request(PING *ping, IP_Port ipp, const uint8_t *public_key); +int32_t ping_send_request(Ping *ping, struct IP_Port ipp, const uint8_t *public_key); #endif /* PING_H */ diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.api.h b/protocols/Tox/libtox/src/toxcore/ping_array.api.h new file mode 100644 index 0000000000..55b8057056 --- /dev/null +++ b/protocols/Tox/libtox/src/toxcore/ping_array.api.h @@ -0,0 +1,72 @@ +%{ +/* + * Implementation of an efficient array to store that we pinged something. + */ + +/* + * Copyright © 2016-2017 The TokTok team. + * Copyright © 2013 Tox project. + * + * This file is part of Tox, the free peer to peer instant messenger. + * + * Tox is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tox is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tox. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef PING_ARRAY_H +#define PING_ARRAY_H + +#include "network.h" +%} + +class ping_Array { + +struct this; + +/** + * Initialize a Ping_Array. + * size represents the total size of the array and should be a power of 2. + * timeout represents the maximum timeout in seconds for the entry. + * + * return 0 on success. + * return -1 on failure. + */ +static this new(uint32_t size, uint32_t timeout); + +/** + * Free all the allocated memory in a Ping_Array. + */ +void kill(); + +/** + * Add a data with length to the Ping_Array list and return a ping_id. + * + * return ping_id on success. + * return 0 on failure. + */ +uint64_t add(const uint8_t *data, uint32_t length); + +/** + * Check if ping_id is valid and not timed out. + * + * On success, copies the data into data of length, + * + * return length of data copied on success. + * return -1 on failure. + */ +int32_t check(uint8_t[length] data, uint64_t ping_id); + +} + +%{ +#endif +%} diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.c b/protocols/Tox/libtox/src/toxcore/ping_array.c index ea3e5101b1..627f8d5a64 100644 --- a/protocols/Tox/libtox/src/toxcore/ping_array.c +++ b/protocols/Tox/libtox/src/toxcore/ping_array.c @@ -30,6 +30,55 @@ #include "crypto_core.h" #include "util.h" + +typedef struct { + void *data; + uint32_t length; + uint64_t time; + uint64_t ping_id; +} Ping_Array_Entry; + +struct Ping_Array { + Ping_Array_Entry *entries; + + uint32_t last_deleted; /* number representing the next entry to be deleted. */ + uint32_t last_added; /* number representing the last entry to be added. */ + uint32_t total_size; /* The length of entries */ + uint32_t timeout; /* The timeout after which entries are cleared. */ +}; + +/* Initialize a Ping_Array. + * size represents the total size of the array and should be a power of 2. + * timeout represents the maximum timeout in seconds for the entry. + * + * return 0 on success. + * return -1 on failure. + */ +Ping_Array *ping_array_new(uint32_t size, uint32_t timeout) +{ + if (size == 0 || timeout == 0) { + return NULL; + } + + Ping_Array *empty_array = (Ping_Array *)calloc(1, sizeof(Ping_Array)); + + if (empty_array == NULL) { + return NULL; + } + + empty_array->entries = (Ping_Array_Entry *)calloc(size, sizeof(Ping_Array_Entry)); + + if (empty_array->entries == NULL) { + free(empty_array); + return NULL; + } + + empty_array->last_deleted = empty_array->last_added = 0; + empty_array->total_size = size; + empty_array->timeout = timeout; + return empty_array; +} + static void clear_entry(Ping_Array *array, uint32_t index) { free(array->entries[index].data); @@ -39,6 +88,20 @@ static void clear_entry(Ping_Array *array, uint32_t index) array->entries[index].ping_id = 0; } +/* Free all the allocated memory in a Ping_Array. + */ +void ping_array_kill(Ping_Array *array) +{ + while (array->last_deleted != array->last_added) { + uint32_t index = array->last_deleted % array->total_size; + clear_entry(array, index); + ++array->last_deleted; + } + + free(array->entries); + free(array); +} + /* Clear timed out entries. */ static void ping_array_clear_timedout(Ping_Array *array) @@ -80,7 +143,7 @@ uint64_t ping_array_add(Ping_Array *array, const uint8_t *data, uint32_t length) array->entries[index].length = length; array->entries[index].time = unix_time(); ++array->last_added; - uint64_t ping_id = random_64b(); + uint64_t ping_id = random_u64(); ping_id /= array->total_size; ping_id *= array->total_size; ping_id += index; @@ -101,7 +164,7 @@ uint64_t ping_array_add(Ping_Array *array, const uint8_t *data, uint32_t length) * return length of data copied on success. * return -1 on failure. */ -int ping_array_check(uint8_t *data, uint32_t length, Ping_Array *array, uint64_t ping_id) +int32_t ping_array_check(Ping_Array *array, uint8_t *data, size_t length, uint64_t ping_id) { if (ping_id == 0) { return -1; @@ -130,43 +193,3 @@ int ping_array_check(uint8_t *data, uint32_t length, Ping_Array *array, uint64_t clear_entry(array, index); return len; } - -/* Initialize a Ping_Array. - * size represents the total size of the array and should be a power of 2. - * timeout represents the maximum timeout in seconds for the entry. - * - * return 0 on success. - * return -1 on failure. - */ -int ping_array_init(Ping_Array *empty_array, uint32_t size, uint32_t timeout) -{ - if (size == 0 || timeout == 0 || empty_array == NULL) { - return -1; - } - - empty_array->entries = (Ping_Array_Entry *)calloc(size, sizeof(Ping_Array_Entry)); - - if (empty_array->entries == NULL) { - return -1; - } - - empty_array->last_deleted = empty_array->last_added = 0; - empty_array->total_size = size; - empty_array->timeout = timeout; - return 0; -} - -/* Free all the allocated memory in a Ping_Array. - */ -void ping_array_free_all(Ping_Array *array) -{ - while (array->last_deleted != array->last_added) { - uint32_t index = array->last_deleted % array->total_size; - clear_entry(array, index); - ++array->last_deleted; - } - - free(array->entries); - array->entries = NULL; -} - diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.h b/protocols/Tox/libtox/src/toxcore/ping_array.h index bdf3c6db3d..b927bbd42b 100644 --- a/protocols/Tox/libtox/src/toxcore/ping_array.h +++ b/protocols/Tox/libtox/src/toxcore/ping_array.h @@ -26,51 +26,42 @@ #include "network.h" -typedef struct { - void *data; - uint32_t length; - uint64_t time; - uint64_t ping_id; -} Ping_Array_Entry; +#ifndef PING_ARRAY_DEFINED +#define PING_ARRAY_DEFINED +typedef struct Ping_Array Ping_Array; +#endif /* PING_ARRAY_DEFINED */ +/** + * Initialize a Ping_Array. + * size represents the total size of the array and should be a power of 2. + * timeout represents the maximum timeout in seconds for the entry. + * + * return 0 on success. + * return -1 on failure. + */ +struct Ping_Array *ping_array_new(uint32_t size, uint32_t timeout); -typedef struct { - Ping_Array_Entry *entries; - - uint32_t last_deleted; /* number representing the next entry to be deleted. */ - uint32_t last_added; /* number representing the last entry to be added. */ - uint32_t total_size; /* The length of entries */ - uint32_t timeout; /* The timeout after which entries are cleared. */ -} Ping_Array; - +/** + * Free all the allocated memory in a Ping_Array. + */ +void ping_array_kill(struct Ping_Array *_array); -/* Add a data with length to the Ping_Array list and return a ping_id. +/** + * Add a data with length to the Ping_Array list and return a ping_id. * * return ping_id on success. * return 0 on failure. */ -uint64_t ping_array_add(Ping_Array *array, const uint8_t *data, uint32_t length); +uint64_t ping_array_add(struct Ping_Array *_array, const uint8_t *data, uint32_t length); -/* Check if ping_id is valid and not timed out. +/** + * Check if ping_id is valid and not timed out. * * On success, copies the data into data of length, * * return length of data copied on success. * return -1 on failure. */ -int ping_array_check(uint8_t *data, uint32_t length, Ping_Array *array, uint64_t ping_id); - -/* Initialize a Ping_Array. - * size represents the total size of the array and should be a power of 2. - * timeout represents the maximum timeout in seconds for the entry. - * - * return 0 on success. - * return -1 on failure. - */ -int ping_array_init(Ping_Array *empty_array, uint32_t size, uint32_t timeout); - -/* Free all the allocated memory in a Ping_Array. - */ -void ping_array_free_all(Ping_Array *array); +int32_t ping_array_check(struct Ping_Array *_array, uint8_t *data, size_t length, uint64_t ping_id); #endif diff --git a/protocols/Tox/libtox/src/toxcore/tox.api.h b/protocols/Tox/libtox/src/toxcore/tox.api.h index ce0b3a36c4..7f3d8d4cff 100644 --- a/protocols/Tox/libtox/src/toxcore/tox.api.h +++ b/protocols/Tox/libtox/src/toxcore/tox.api.h @@ -173,13 +173,13 @@ const VERSION_MAJOR = 0; * breaking the API or ABI. Set to 0 when the major version number is * incremented. */ -const VERSION_MINOR = 1; +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 = 11; +const VERSION_PATCH = 0; /** * A macro to check at preprocessing time whether the client code is compatible @@ -338,6 +338,11 @@ enum class MESSAGE_TYPE { * on IRC. */ ACTION, + /** + * Correction of the last message. With empty message body can be used to mark + * last message as deleted. + */ + CORRECTION, } diff --git a/protocols/Tox/libtox/src/toxcore/tox.c b/protocols/Tox/libtox/src/toxcore/tox.c index 12f3762083..2fd478dc8c 100644 --- a/protocols/Tox/libtox/src/toxcore/tox.c +++ b/protocols/Tox/libtox/src/toxcore/tox.c @@ -355,13 +355,13 @@ void tox_self_get_address(const Tox *tox, uint8_t *address) void tox_self_set_nospam(Tox *tox, uint32_t nospam) { Messenger *m = tox; - set_nospam(&(m->fr), net_htonl(nospam)); + set_nospam(m->fr, net_htonl(nospam)); } uint32_t tox_self_get_nospam(const Tox *tox) { const Messenger *m = tox; - return net_ntohl(get_nospam(&(m->fr))); + return net_ntohl(get_nospam(m->fr)); } void tox_self_get_public_key(const Tox *tox, uint8_t *public_key) @@ -369,7 +369,7 @@ void tox_self_get_public_key(const Tox *tox, uint8_t *public_key) const Messenger *m = tox; if (public_key) { - memcpy(public_key, m->net_crypto->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(public_key, nc_get_self_public_key(m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE); } } @@ -378,7 +378,7 @@ void tox_self_get_secret_key(const Tox *tox, uint8_t *secret_key) const Messenger *m = tox; if (secret_key) { - memcpy(secret_key, m->net_crypto->self_secret_key, CRYPTO_SECRET_KEY_SIZE); + memcpy(secret_key, nc_get_self_secret_key(m->net_crypto), CRYPTO_SECRET_KEY_SIZE); } } @@ -1526,7 +1526,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) { const Messenger *m = tox; - uint16_t port = net_htons(m->net->port); + uint16_t port = net_htons(net_port(m->net)); if (port) { SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_OK); diff --git a/protocols/Tox/libtox/src/toxcore/tox.h b/protocols/Tox/libtox/src/toxcore/tox.h index cb9c4fa0e0..f4f3d06639 100644 --- a/protocols/Tox/libtox/src/toxcore/tox.h +++ b/protocols/Tox/libtox/src/toxcore/tox.h @@ -172,7 +172,7 @@ uint32_t tox_version_major(void); * breaking the API or ABI. Set to 0 when the major version number is * incremented. */ -#define TOX_VERSION_MINOR 1 +#define TOX_VERSION_MINOR 2 uint32_t tox_version_minor(void); @@ -180,7 +180,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 11 +#define TOX_VERSION_PATCH 0 uint32_t tox_version_patch(void); @@ -371,6 +371,12 @@ typedef enum TOX_MESSAGE_TYPE { */ TOX_MESSAGE_TYPE_ACTION, + /** + * Correction of the last message. With empty message body can be used to mark + * last message as deleted. + */ + TOX_MESSAGE_TYPE_CORRECTION, + } TOX_MESSAGE_TYPE; diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h index 61f685f86b..3adf3a9def 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h +++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h @@ -82,8 +82,7 @@ error for key_derivation { NULL, /** * The crypto lib was unable to derive a key from the given passphrase, - * which is usually a lack of memory issue. The functions accepting keys - * do not produce this error. + * which is usually a lack of memory issue. */ FAILED, } @@ -192,21 +191,12 @@ class pass_Key { * for encryption and decryption. It is derived from a salt and the user- * provided password. * - * The $this structure is hidden in the implementation. It can be allocated - * using $new and must be deallocated using $free. + * The $this structure is hidden in the implementation. It can be created + * using $derive or $derive_with_salt and must be deallocated using $free. */ struct this; /** - * Create a new $this. The initial value of it is indeterminate. To - * initialise it, use one of the derive_* functions below. - * - * In case of failure, this function returns NULL. The only failure mode at - * this time is memory allocation failure, so this function has no error code. - */ - static this new(); - - /** * Deallocate a $this. This function behaves like free(), so NULL is an * acceptable argument value. */ @@ -227,7 +217,7 @@ class pass_Key { * * @return true on success. */ - bool derive(const uint8_t[passphrase_len] passphrase) + static this derive(const uint8_t[passphrase_len] passphrase) with error for key_derivation; /** @@ -239,7 +229,7 @@ class pass_Key { * * @return true on success. */ - bool derive_with_salt(const uint8_t[passphrase_len] passphrase, const uint8_t[PASS_SALT_LENGTH] salt) + static this derive_with_salt(const uint8_t[passphrase_len] passphrase, const uint8_t[PASS_SALT_LENGTH] salt) with error for key_derivation; /** diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c index 5640e82fc7..b7360b5650 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c +++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c @@ -71,11 +71,6 @@ struct Tox_Pass_Key { uint8_t key[TOX_PASS_KEY_LENGTH]; }; -Tox_Pass_Key *tox_pass_key_new(void) -{ - return (Tox_Pass_Key *)malloc(sizeof(Tox_Pass_Key)); -} - void tox_pass_key_free(Tox_Pass_Key *pass_key) { free(pass_key); @@ -123,23 +118,23 @@ bool tox_get_salt(const uint8_t *data, uint8_t *salt, TOX_ERR_GET_SALT *error) * * returns true on success */ -bool tox_pass_key_derive(Tox_Pass_Key *out_key, const uint8_t *passphrase, size_t pplength, - TOX_ERR_KEY_DERIVATION *error) +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); - return tox_pass_key_derive_with_salt(out_key, passphrase, pplength, salt, error); + return tox_pass_key_derive_with_salt(passphrase, pplength, salt, error); } /* Same as above, except with use the given salt for deterministic key derivation. * The salt must be TOX_PASS_SALT_LENGTH bytes in length. */ -bool tox_pass_key_derive_with_salt(Tox_Pass_Key *out_key, const uint8_t *passphrase, size_t pplength, - const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error) +Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, size_t pplength, + const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error) { - if (!salt || !out_key || (!passphrase && pplength != 0)) { + if (!salt || (!passphrase && pplength != 0)) { SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL); - return 0; + return NULL; } uint8_t passkey[crypto_hash_sha256_BYTES]; @@ -157,14 +152,22 @@ bool tox_pass_key_derive_with_salt(Tox_Pass_Key *out_key, const uint8_t *passphr crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { /* out of memory most likely */ SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED); - return 0; + return NULL; } sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ + + Tox_Pass_Key *out_key = (Tox_Pass_Key *)malloc(sizeof(Tox_Pass_Key)); + + if (!out_key) { + SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED); + return NULL; + } + memcpy(out_key->salt, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); memcpy(out_key->key, key, CRYPTO_SHARED_KEY_SIZE); SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK); - return 1; + return out_key; } /* Encrypt arbitrary with a key produced by tox_derive_key_*. The output @@ -224,10 +227,10 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t *data, size_t d bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passphrase, size_t pplength, uint8_t *out, TOX_ERR_ENCRYPTION *error) { - Tox_Pass_Key key; TOX_ERR_KEY_DERIVATION _error; + Tox_Pass_Key *key = tox_pass_key_derive(passphrase, pplength, &_error); - if (!tox_pass_key_derive(&key, passphrase, pplength, &_error)) { + if (!key) { if (_error == TOX_ERR_KEY_DERIVATION_NULL) { SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL); } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) { @@ -237,7 +240,9 @@ bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passp return 0; } - return tox_pass_key_encrypt(&key, data, data_len, out, error); + bool result = tox_pass_key_encrypt(key, data, data_len, out, error); + tox_pass_key_free(key); + return result; } /* This is the inverse of tox_pass_key_encrypt, also using only keys produced by @@ -315,15 +320,17 @@ bool tox_pass_decrypt(const uint8_t *data, size_t length, const uint8_t *passphr memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); /* derive the key */ - Tox_Pass_Key key; + Tox_Pass_Key *key = tox_pass_key_derive_with_salt(passphrase, pplength, salt, NULL); - if (!tox_pass_key_derive_with_salt(&key, passphrase, pplength, salt, NULL)) { + if (!key) { /* out of memory most likely */ SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED); return 0; } - return tox_pass_key_decrypt(&key, data, length, out, error); + bool result = tox_pass_key_decrypt(key, data, length, out, error); + tox_pass_key_free(key); + return result; } /* Determines whether or not the given data is encrypted (by checking the magic number) diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h index ef1ab15289..c5a1dff961 100644 --- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h +++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h @@ -99,8 +99,7 @@ typedef enum TOX_ERR_KEY_DERIVATION { /** * The crypto lib was unable to derive a key from the given passphrase, - * which is usually a lack of memory issue. The functions accepting keys - * do not produce this error. + * which is usually a lack of memory issue. */ TOX_ERR_KEY_DERIVATION_FAILED, @@ -241,8 +240,8 @@ bool tox_pass_decrypt(const uint8_t *ciphertext, size_t ciphertext_len, const ui * for encryption and decryption. It is derived from a salt and the user- * provided password. * - * The Tox_Pass_Key structure is hidden in the implementation. It can be allocated - * using tox_pass_key_new and must be deallocated using tox_pass_key_free. + * The Tox_Pass_Key structure is hidden in the implementation. It can be created + * using tox_pass_key_derive or tox_pass_key_derive_with_salt and must be deallocated using tox_pass_key_free. */ #ifndef TOX_PASS_KEY_DEFINED #define TOX_PASS_KEY_DEFINED @@ -250,15 +249,6 @@ typedef struct Tox_Pass_Key Tox_Pass_Key; #endif /* TOX_PASS_KEY_DEFINED */ /** - * Create a new Tox_Pass_Key. The initial value of it is indeterminate. To - * initialise it, use one of the derive_* functions below. - * - * In case of failure, this function returns NULL. The only failure mode at - * this time is memory allocation failure, so this function has no error code. - */ -struct Tox_Pass_Key *tox_pass_key_new(void); - -/** * Deallocate a Tox_Pass_Key. This function behaves like free(), so NULL is an * acceptable argument value. */ @@ -279,8 +269,8 @@ void tox_pass_key_free(struct Tox_Pass_Key *_key); * * @return true on success. */ -bool tox_pass_key_derive(struct Tox_Pass_Key *_key, const uint8_t *passphrase, size_t passphrase_len, - TOX_ERR_KEY_DERIVATION *error); +struct Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t passphrase_len, + TOX_ERR_KEY_DERIVATION *error); /** * Same as above, except use the given salt for deterministic key derivation. @@ -291,8 +281,8 @@ bool tox_pass_key_derive(struct Tox_Pass_Key *_key, const uint8_t *passphrase, s * * @return true on success. */ -bool tox_pass_key_derive_with_salt(struct Tox_Pass_Key *_key, const uint8_t *passphrase, size_t passphrase_len, - const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error); +struct Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, size_t passphrase_len, + const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error); /** * Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt. |