summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto_tests/onion_test.c16
-rw-r--r--auto_tests/tox_test.c23
-rw-r--r--docs/Prevent_Tracking.txt20
-rw-r--r--docs/updates/Crypto.md2
-rw-r--r--other/DHT_bootstrap.c12
-rw-r--r--toxcore/DHT.c135
-rw-r--r--toxcore/DHT.h8
-rw-r--r--toxcore/LAN_discovery.c16
-rw-r--r--toxcore/LAN_discovery.h2
-rw-r--r--toxcore/Messenger.c66
-rw-r--r--toxcore/Messenger.h7
-rw-r--r--toxcore/friend_requests.c46
-rw-r--r--toxcore/friend_requests.h6
-rw-r--r--toxcore/net_crypto.c4
-rw-r--r--toxcore/onion.c3
-rw-r--r--toxcore/onion_announce.c66
-rw-r--r--toxcore/onion_announce.h16
-rw-r--r--toxcore/onion_client.c254
-rw-r--r--toxcore/onion_client.h31
-rw-r--r--toxcore/ping.c40
-rw-r--r--toxcore/ping.h2
-rw-r--r--toxcore/util.c19
-rw-r--r--toxcore/util.h2
23 files changed, 543 insertions, 253 deletions
diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c
index 17151398..4dae2136 100644
--- a/auto_tests/onion_test.c
+++ b/auto_tests/onion_test.c
@@ -73,15 +73,15 @@ static int handle_test_3(void *object, IP_Port source, uint8_t *packet, uint32_t
73{ 73{
74 Onion *onion = object; 74 Onion *onion = object;
75 75
76 if (length != (1 + crypto_box_NONCEBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_hash_sha256_BYTES + 76 if (length != (1 + crypto_box_NONCEBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + 1 + crypto_hash_sha256_BYTES +
77 crypto_box_MACBYTES)) 77 crypto_box_MACBYTES))
78 return 1; 78 return 1;
79 79
80 uint8_t plain[crypto_hash_sha256_BYTES]; 80 uint8_t plain[1 + crypto_hash_sha256_BYTES];
81 //print_client_id(packet, length); 81 //print_client_id(packet, length);
82 int len = decrypt_data(test_3_pub_key, onion->dht->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, 82 int len = decrypt_data(test_3_pub_key, onion->dht->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
83 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES, 83 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES,
84 crypto_hash_sha256_BYTES + crypto_box_MACBYTES, plain); 84 1 + crypto_hash_sha256_BYTES + crypto_box_MACBYTES, plain);
85 85
86 if (len == -1) 86 if (len == -1)
87 return 1; 87 return 1;
@@ -90,7 +90,7 @@ static int handle_test_3(void *object, IP_Port source, uint8_t *packet, uint32_t
90 if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) 90 if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0)
91 return 1; 91 return 1;
92 92
93 memcpy(test_3_ping_id, plain, crypto_hash_sha256_BYTES); 93 memcpy(test_3_ping_id, plain + 1, crypto_hash_sha256_BYTES);
94 //print_client_id(test_3_ping_id, sizeof(test_3_ping_id)); 94 //print_client_id(test_3_ping_id, sizeof(test_3_ping_id));
95 handled_test_3 = 1; 95 handled_test_3 = 1;
96 return 0; 96 return 0;
@@ -174,7 +174,7 @@ START_TEST(test_basic)
174 randombytes(sb_data, sizeof(sb_data)); 174 randombytes(sb_data, sizeof(sb_data));
175 memcpy(test_3_pub_key, nodes[3].client_id, crypto_box_PUBLICKEYBYTES); 175 memcpy(test_3_pub_key, nodes[3].client_id, crypto_box_PUBLICKEYBYTES);
176 ret = send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key, 176 ret = send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key,
177 zeroes, onion1->dht->c->self_public_key, sb_data); 177 zeroes, onion1->dht->c->self_public_key, onion1->dht->c->self_public_key, sb_data);
178 ck_assert_msg(ret == 0, "Failed to create/send onion announce_request packet."); 178 ck_assert_msg(ret == 0, "Failed to create/send onion announce_request packet.");
179 handled_test_3 = 0; 179 handled_test_3 = 0;
180 180
@@ -188,7 +188,7 @@ START_TEST(test_basic)
188 onion2_a->entries[1].time = unix_time(); 188 onion2_a->entries[1].time = unix_time();
189 networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1); 189 networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1);
190 send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key, 190 send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key,
191 test_3_ping_id, onion1->dht->c->self_public_key, sb_data); 191 test_3_ping_id, onion1->dht->c->self_public_key, onion1->dht->c->self_public_key, sb_data);
192 192
193 while (memcmp(onion2_a->entries[ONION_ANNOUNCE_MAX_ENTRIES - 2].public_key, onion1->dht->c->self_public_key, 193 while (memcmp(onion2_a->entries[ONION_ANNOUNCE_MAX_ENTRIES - 2].public_key, onion1->dht->c->self_public_key,
194 crypto_box_PUBLICKEYBYTES) != 0) { 194 crypto_box_PUBLICKEYBYTES) != 0) {
@@ -202,8 +202,8 @@ START_TEST(test_basic)
202 ck_assert_msg((onion3 != NULL), "Onion failed initializing."); 202 ck_assert_msg((onion3 != NULL), "Onion failed initializing.");
203 203
204 new_nonce(nonce); 204 new_nonce(nonce);
205 ret = send_data_request(onion3->dht, nodes, onion1->dht->c->self_public_key, nonce, (uint8_t *)"Install gentoo", 205 ret = send_data_request(onion3->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_public_key,
206 sizeof("Install gentoo")); 206 nonce, (uint8_t *)"Install gentoo", sizeof("Install gentoo"));
207 ck_assert_msg(ret == 0, "Failed to create/send onion data_request packet."); 207 ck_assert_msg(ret == 0, "Failed to create/send onion data_request packet.");
208 handled_test_4 = 0; 208 handled_test_4 = 0;
209 209
diff --git a/auto_tests/tox_test.c b/auto_tests/tox_test.c
index 0f54ed7e..06e8e257 100644
--- a/auto_tests/tox_test.c
+++ b/auto_tests/tox_test.c
@@ -23,8 +23,9 @@ void accept_friend_request(uint8_t *public_key, uint8_t *data, uint16_t length,
23{ 23{
24 Tox *t = userdata; 24 Tox *t = userdata;
25 25
26 if (length == 7 && memcmp("Gentoo", data, 7) == 0) 26 if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
27 tox_add_friend_norequest(t, public_key); 27 tox_add_friend_norequest(t, public_key);
28 }
28} 29}
29uint32_t messages_received; 30uint32_t messages_received;
30 31
@@ -58,14 +59,22 @@ START_TEST(test_few_clients)
58 tox_callback_friend_request(tox2, accept_friend_request, tox2); 59 tox_callback_friend_request(tox2, accept_friend_request, tox2);
59 uint8_t address[TOX_FRIEND_ADDRESS_SIZE]; 60 uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
60 tox_get_address(tox2, address); 61 tox_get_address(tox2, address);
61 int test = tox_add_friend(tox3, address, "Gentoo", 7); 62 int test = tox_add_friend(tox3, address, (uint8_t *)"Gentoo", 7);
62 ck_assert_msg(test == 0, "Failed to add friend error code: %i", test); 63 ck_assert_msg(test == 0, "Failed to add friend error code: %i", test);
63 64
65 uint8_t off = 1;
66
64 while (1) { 67 while (1) {
65 tox_do(tox1); 68 tox_do(tox1);
66 tox_do(tox2); 69 tox_do(tox2);
67 tox_do(tox3); 70 tox_do(tox3);
68 71
72 if (tox_isconnected(tox1) && tox_isconnected(tox2) && tox_isconnected(tox3) && off) {
73 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time);
74 off = 0;
75 }
76
77
69 if (tox_get_friend_connection_status(tox2, 0) == 1 && tox_get_friend_connection_status(tox3, 0) == 1) 78 if (tox_get_friend_connection_status(tox2, 0) == 1 && tox_get_friend_connection_status(tox3, 0) == 1)
70 break; 79 break;
71 80
@@ -75,7 +84,7 @@ START_TEST(test_few_clients)
75 printf("tox clients connected\n"); 84 printf("tox clients connected\n");
76 uint32_t to_compare = 974536; 85 uint32_t to_compare = 974536;
77 tox_callback_friend_message(tox3, print_message, &to_compare); 86 tox_callback_friend_message(tox3, print_message, &to_compare);
78 tox_send_message(tox2, 0, "Install Gentoo", sizeof("Install Gentoo")); 87 tox_send_message(tox2, 0, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
79 88
80 while (1) { 89 while (1) {
81 messages_received = 0; 90 messages_received = 0;
@@ -92,7 +101,7 @@ START_TEST(test_few_clients)
92 printf("tox clients messaging succeeded\n"); 101 printf("tox clients messaging succeeded\n");
93 102
94 tox_callback_name_change(tox3, print_nickchange, &to_compare); 103 tox_callback_name_change(tox3, print_nickchange, &to_compare);
95 tox_set_name(tox2, "Gentoo", sizeof("Gentoo")); 104 tox_set_name(tox2, (uint8_t *)"Gentoo", sizeof("Gentoo"));
96 105
97 while (1) { 106 while (1) {
98 name_changes = 0; 107 name_changes = 0;
@@ -113,8 +122,8 @@ START_TEST(test_few_clients)
113} 122}
114END_TEST 123END_TEST
115 124
116#define NUM_TOXES 66 125#define NUM_TOXES 33
117#define NUM_FRIENDS 20 126#define NUM_FRIENDS 10
118 127
119START_TEST(test_many_clients) 128START_TEST(test_many_clients)
120{ 129{
@@ -140,7 +149,7 @@ loop_top:
140 pairs[i].tox1 = rand() % NUM_TOXES; 149 pairs[i].tox1 = rand() % NUM_TOXES;
141 pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES; 150 pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES;
142 tox_get_address(toxes[pairs[i].tox1], address); 151 tox_get_address(toxes[pairs[i].tox1], address);
143 int test = tox_add_friend(toxes[pairs[i].tox2], address, "Gentoo", 7); 152 int test = tox_add_friend(toxes[pairs[i].tox2], address, (uint8_t *)"Gentoo", 7);
144 153
145 if (test == TOX_FAERR_ALREADYSENT) { 154 if (test == TOX_FAERR_ALREADYSENT) {
146 goto loop_top; 155 goto loop_top;
diff --git a/docs/Prevent_Tracking.txt b/docs/Prevent_Tracking.txt
index 5f7aaf1e..07e8ae1e 100644
--- a/docs/Prevent_Tracking.txt
+++ b/docs/Prevent_Tracking.txt
@@ -97,7 +97,8 @@ Data sent to Node D:
97 97
98announce request packet: 98announce request packet:
99[uint8_t packet id (131)][nonce][our real long term public key or a temporary one (see next)] 99[uint8_t packet id (131)][nonce][our real long term public key or a temporary one (see next)]
100encrypted (with our real long term private key if we want to announce ourselves, a temporary one if we are searching for friends) and the pub key of Node D and the nonce:[[(32 bytes) ping_id][client id we are searching for][data to send back in response(fixed size)]] 100encrypted (with our real long term private key if we want to announce ourselves, a temporary one if we are searching for friends) and the pub key of Node D and the nonce:
101[[(32 bytes) ping_id][client id we are searching for][public key that we want those sending back data packets to use.][data to send back in response(fixed size)]]
101 102
102(if the ping id is zero, respond with a announce response packet) 103(if the ping id is zero, respond with a announce response packet)
103(If the ping id matches the one the node sent in the announce response and the public key matches the one being searched for, 104(If the ping id matches the one the node sent in the announce response and the public key matches the one being searched for,
@@ -105,7 +106,7 @@ add the part used to send data to our list (if the list is full make it replace
105 106
106data to route request packet: 107data to route request packet:
107[uint8_t packet id (133)][public key of destination node][nonce][temporary just generated public key] 108[uint8_t packet id (133)][public key of destination node][nonce][temporary just generated public key]
108encrypted with that temporary private key and the nonce and the real public key of the destination node:[data] 109encrypted with that temporary private key and the nonce and the public key from the announce response packet of the destination node:[data]
109(if Node D contains the ret data for the node, it sends the stuff in this packet as a data to route response packet to the right node) 110(if Node D contains the ret data for the node, it sends the stuff in this packet as a data to route response packet to the right node)
110 111
111The data in the previous packet is in format: [real public key of sender] 112The data in the previous packet is in format: [real public key of sender]
@@ -114,12 +115,13 @@ encrypted with real private key of the sender, the nonce in the data packet and
114Data sent to us: 115Data sent to us:
115announce response packet: 116announce response packet:
116[uint8_t packet id (132)][data to send back in response(fixed size)][nonce] 117[uint8_t packet id (132)][data to send back in response(fixed size)][nonce]
117encrypted with the DHT private key of Node D, the public key in the request and the nonce:[[(32 bytes) ping_id][Node_Format * (maximum of 8)]] 118encrypted with the DHT private key of Node D, the public key in the request and the nonce:[[uint8_t is_stored]
118(if the ping id is zero, it means the information to reach the client id we are searching for is stored on this node) 119[(32 bytes) ping_id if is_stored is 0, public key that must be used to send data packets if is_stored is not 0][Node_Format * (maximum of 8)]]
120(if the is_stored is not 0, it means the information to reach the client id we are searching for is stored on this node)
119 121
120data to route response packet: 122data to route response packet:
121[uint8_t packet id (134)][nonce][temporary just generated public key] 123[uint8_t packet id (134)][nonce][temporary just generated public key]
122encrypted with that temporary private key and the nonce and the real public key of the destination node:[data] 124encrypted with that temporary private key, the nonce and the public key from the announce response packet of the destination node:[data]
123 125
124 126
125Onion packet (response): 127Onion packet (response):
@@ -145,3 +147,11 @@ encrypted with temp symmetric key of Node A: [IP_Port (of us)][data to send back
145(sent from node A to us): 147(sent from node A to us):
146 148
147[data to send back] 149[data to send back]
150
151
152Data packets:
153
154To tell our friend what our DHT public key is so that he can connect to us we send a data packet with id 156 and
155the data being:[uint64_t (in network byte order) no_replay, the packet will only be accepted if this number is bigger than the last one recieved]
156[our dht public key][Node_Format * (maximum of 8) nodes closest to us so that the friend can find us faster]
157
diff --git a/docs/updates/Crypto.md b/docs/updates/Crypto.md
index 6b489c3b..a6c701d3 100644
--- a/docs/updates/Crypto.md
+++ b/docs/updates/Crypto.md
@@ -20,7 +20,7 @@ case 1: Alice adds Bobs public key and bob waits for Alice to attempt to connect
20case 2: Bob and Alice add their respective public keys to their friends list at the same time. 20case 2: Bob and Alice add their respective public keys to their friends list at the same time.
21 21
22case 1: 22case 1:
23Alice sends a crypto request packet to bob with the encrypted part containing the friends request like so: 23Alice sends a onion data (see: Prevent_tracking.txt) packet to bob with the encrypted part containing the friends request like so:
24``` 24```
25[char with a value of 32][nospam number (4 bytes)][Message] 25[char with a value of 32][nospam number (4 bytes)][Message]
26``` 26```
diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c
index 6561fe70..479e97a6 100644
--- a/other/DHT_bootstrap.c
+++ b/other/DHT_bootstrap.c
@@ -102,9 +102,19 @@ int main(int argc, char *argv[])
102 ip_init(&ip, ipv6enabled); 102 ip_init(&ip, ipv6enabled);
103 103
104 DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); 104 DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT)));
105 Onion *onion = new_onion(dht);
106 Onion_Announce *onion_a = new_onion_announce(dht);
107
108 if (!(onion && onion_a)) {
109 printf("Something failed to initialize.\n");
110 exit(1);
111 }
105 perror("Initialization"); 112 perror("Initialization");
106 113
107 manage_keys(dht); 114 manage_keys(dht);
115 /* We want our DHT public key to be the same as our internal one since this is a bootstrap server */
116 memcpy(dht->self_public_key, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES);
117 memcpy(dht->self_secret_key, dht->c->self_secret_key, crypto_box_SECRETKEYBYTES);
108 printf("Public key: "); 118 printf("Public key: ");
109 uint32_t i; 119 uint32_t i;
110 120
@@ -152,7 +162,7 @@ int main(int argc, char *argv[])
152 do_DHT(dht); 162 do_DHT(dht);
153 163
154 if (is_timeout(last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) { 164 if (is_timeout(last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) {
155 send_LANdiscovery(htons(PORT), dht->c); 165 send_LANdiscovery(htons(PORT), dht);
156 last_LANdiscovery = unix_time(); 166 last_LANdiscovery = unix_time();
157 } 167 }
158 168
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 454047db..61ec5034 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -28,7 +28,11 @@
28#endif 28#endif
29 29
30#include "DHT.h" 30#include "DHT.h"
31
32#ifdef ENABLE_ASSOC_DHT
31#include "assoc.h" 33#include "assoc.h"
34#endif
35
32#include "ping.h" 36#include "ping.h"
33 37
34#include "network.h" 38#include "network.h"
@@ -285,7 +289,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
285 */ 289 */
286 sa_family_t ip_treat_as_family = client_ip->family; 290 sa_family_t ip_treat_as_family = client_ip->family;
287 291
288 if ((dht->c->lossless_udp->net->family == AF_INET6) && 292 if ((dht->net->family == AF_INET6) &&
289 (client_ip->family == AF_INET6)) { 293 (client_ip->family == AF_INET6)) {
290 /* socket is AF_INET6, address claims AF_INET6: 294 /* socket is AF_INET6, address claims AF_INET6:
291 * check for embedded IPv4-in-IPv6 (shouldn't happen anymore, 295 * check for embedded IPv4-in-IPv6 (shouldn't happen anymore,
@@ -304,7 +308,8 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
304 if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN) 308 if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN)
305 continue; 309 continue;
306 310
307 if (want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK && !id_equal(client_id, client->client_id)) 311 if (LAN_ip(ipptp->ip_port.ip) != 0 && want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK
312 && !id_equal(client_id, client->client_id))
308 continue; 313 continue;
309 314
310 if (num_nodes < MAX_SENT_NODES) { 315 if (num_nodes < MAX_SENT_NODES) {
@@ -355,10 +360,16 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n
355 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 360 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
356 dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_good); 361 dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_good);
357 362
363 /*TODO uncomment this when hardening is added to close friend clients
364 for (i = 0; i < dht->num_friends; ++i)
365 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
366 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
367 &num_nodes, is_LAN, want_good);
368 */
358 for (i = 0; i < dht->num_friends; ++i) 369 for (i = 0; i < dht->num_friends; ++i)
359 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 370 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
360 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, 371 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
361 &num_nodes, is_LAN, want_good); 372 &num_nodes, is_LAN, 0);
362 373
363 return num_nodes; 374 return num_nodes;
364} 375}
@@ -366,9 +377,13 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n
366int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN, 377int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN,
367 uint8_t want_good) 378 uint8_t want_good)
368{ 379{
380#ifdef ENABLE_ASSOC_DHT
381
369 if (!dht->assoc) 382 if (!dht->assoc)
383#endif
370 return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good); 384 return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good);
371 385
386#ifdef ENABLE_ASSOC_DHT
372 Client_data *result[MAX_SENT_NODES]; 387 Client_data *result[MAX_SENT_NODES];
373 388
374 Assoc_close_entries request; 389 Assoc_close_entries request;
@@ -420,6 +435,7 @@ int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_fa
420 } 435 }
421 436
422 return num_returned; 437 return num_returned;
438#endif
423} 439}
424 440
425/* Replace first bad (or empty) node with this one. 441/* Replace first bad (or empty) node with this one.
@@ -566,7 +582,7 @@ static int replace_good( Client_data *list,
566 if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6)) 582 if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6))
567 return 1; 583 return 1;
568 584
569 sort_list(list, length, comp_client_id); 585 //sort_list(list, length, comp_client_id);
570 586
571 int8_t replace = -1; 587 int8_t replace = -1;
572 588
@@ -636,10 +652,10 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
636 if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 652 if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
637 if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 653 if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
638 if (replace_possible_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port, 654 if (replace_possible_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port,
639 dht->c->self_public_key)) { 655 dht->self_public_key)) {
640 /* If we can't replace bad nodes we try replacing good ones. */ 656 /* If we can't replace bad nodes we try replacing good ones. */
641 if (!replace_good(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port, 657 if (!replace_good(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port,
642 dht->c->self_public_key)) 658 dht->self_public_key))
643 used++; 659 used++;
644 } else 660 } else
645 used++; 661 used++;
@@ -669,6 +685,8 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
669 used++; 685 used++;
670 } 686 }
671 687
688#ifdef ENABLE_ASSOC_DHT
689
672 if (dht->assoc) { 690 if (dht->assoc) {
673 IPPTs ippts; 691 IPPTs ippts;
674 692
@@ -678,6 +696,7 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
678 Assoc_add_entry(dht->assoc, client_id, &ippts, NULL, used ? 1 : 0); 696 Assoc_add_entry(dht->assoc, client_id, &ippts, NULL, used ? 1 : 0);
679 } 697 }
680 698
699#endif
681 return used; 700 return used;
682} 701}
683 702
@@ -697,7 +716,7 @@ static int returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8
697 ip_port.ip.ip4.uint32 = ip_port.ip.ip6.uint32[3]; 716 ip_port.ip.ip4.uint32 = ip_port.ip.ip6.uint32[3];
698 } 717 }
699 718
700 if (id_equal(client_id, dht->c->self_public_key)) { 719 if (id_equal(client_id, dht->self_public_key)) {
701 for (i = 0; i < LCLIENT_LIST; ++i) { 720 for (i = 0; i < LCLIENT_LIST; ++i) {
702 if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) { 721 if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) {
703 if (ip_port.ip.family == AF_INET) { 722 if (ip_port.ip.family == AF_INET) {
@@ -734,6 +753,7 @@ static int returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8
734 } 753 }
735 754
736end: 755end:
756#ifdef ENABLE_ASSOC_DHT
737 757
738 if (dht->assoc) { 758 if (dht->assoc) {
739 IPPTs ippts; 759 IPPTs ippts;
@@ -744,6 +764,7 @@ end:
744 Assoc_add_entry(dht->assoc, client_id, &ippts, NULL, used ? 1 : 0); 764 Assoc_add_entry(dht->assoc, client_id, &ippts, NULL, used ? 1 : 0);
745 } 765 }
746 766
767#endif
747 return 0; 768 return 0;
748} 769}
749 770
@@ -754,7 +775,7 @@ end:
754static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, Node_format *sendback_node) 775static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, Node_format *sendback_node)
755{ 776{
756 /* Check if packet is going to be sent to ourself. */ 777 /* Check if packet is going to be sent to ourself. */
757 if (id_equal(public_key, dht->c->self_public_key)) 778 if (id_equal(public_key, dht->self_public_key))
758 return -1; 779 return -1;
759 780
760 uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH] = {0}; 781 uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH] = {0};
@@ -794,7 +815,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
794 memcpy(plain + CLIENT_ID_SIZE, encrypted_message, NODES_ENCRYPTED_MESSAGE_LENGTH); 815 memcpy(plain + CLIENT_ID_SIZE, encrypted_message, NODES_ENCRYPTED_MESSAGE_LENGTH);
795 816
796 int len = encrypt_data( public_key, 817 int len = encrypt_data( public_key,
797 dht->c->self_secret_key, 818 dht->self_secret_key,
798 nonce, 819 nonce,
799 plain, 820 plain,
800 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH, 821 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH,
@@ -804,11 +825,11 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
804 return -1; 825 return -1;
805 826
806 data[0] = NET_PACKET_GET_NODES; 827 data[0] = NET_PACKET_GET_NODES;
807 memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); 828 memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE);
808 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 829 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
809 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 830 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
810 831
811 return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data)); 832 return sendpacket(dht->net, ip_port, data, sizeof(data));
812} 833}
813 834
814/* Send a send nodes response. */ 835/* Send a send nodes response. */
@@ -818,7 +839,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
818static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data) 839static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data)
819{ 840{
820 /* Check if packet is going to be sent to ourself. */ 841 /* Check if packet is going to be sent to ourself. */
821 if (id_equal(public_key, dht->c->self_public_key)) 842 if (id_equal(public_key, dht->self_public_key))
822 return -1; 843 return -1;
823 844
824 size_t Node4_format_size = sizeof(Node4_format); 845 size_t Node4_format_size = sizeof(Node4_format);
@@ -863,7 +884,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
863 884
864 memcpy(plain + num_nodes * Node4_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH); 885 memcpy(plain + num_nodes * Node4_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
865 int len = encrypt_data( public_key, 886 int len = encrypt_data( public_key,
866 dht->c->self_secret_key, 887 dht->self_secret_key,
867 nonce, 888 nonce,
868 plain, 889 plain,
869 num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH, 890 num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
@@ -874,11 +895,11 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
874 return -1; 895 return -1;
875 896
876 data[0] = NET_PACKET_SEND_NODES; 897 data[0] = NET_PACKET_SEND_NODES;
877 memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); 898 memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE);
878 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 899 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
879 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 900 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
880 901
881 return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 902 return sendpacket(dht->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
882} 903}
883 904
884void to_net_family(IP *ip) 905void to_net_family(IP *ip)
@@ -904,7 +925,7 @@ void to_host_family(IP *ip)
904static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data) 925static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data)
905{ 926{
906 /* Check if packet is going to be sent to ourself. */ 927 /* Check if packet is going to be sent to ourself. */
907 if (id_equal(public_key, dht->c->self_public_key)) 928 if (id_equal(public_key, dht->self_public_key))
908 return -1; 929 return -1;
909 930
910 size_t Node_format_size = sizeof(Node_format); 931 size_t Node_format_size = sizeof(Node_format);
@@ -930,7 +951,7 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
930 memcpy(plain, nodes_list, num_nodes * Node_format_size); 951 memcpy(plain, nodes_list, num_nodes * Node_format_size);
931 memcpy(plain + num_nodes * Node_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH); 952 memcpy(plain + num_nodes * Node_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
932 int len = encrypt_data( public_key, 953 int len = encrypt_data( public_key,
933 dht->c->self_secret_key, 954 dht->self_secret_key,
934 nonce, 955 nonce,
935 plain, 956 plain,
936 num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH, 957 num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
@@ -940,11 +961,11 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
940 return -1; 961 return -1;
941 962
942 data[0] = NET_PACKET_SEND_NODES_IPV6; 963 data[0] = NET_PACKET_SEND_NODES_IPV6;
943 memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); 964 memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE);
944 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 965 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
945 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 966 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
946 967
947 return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 968 return sendpacket(dht->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
948} 969}
949 970
950static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 971static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
@@ -956,13 +977,13 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32
956 return 1; 977 return 1;
957 978
958 /* Check if packet is from ourself. */ 979 /* Check if packet is from ourself. */
959 if (id_equal(packet + 1, dht->c->self_public_key)) 980 if (id_equal(packet + 1, dht->self_public_key))
960 return 1; 981 return 1;
961 982
962 uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH]; 983 uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH];
963 984
964 int len = decrypt_data( packet + 1, 985 int len = decrypt_data( packet + 1,
965 dht->c->self_secret_key, 986 dht->self_secret_key,
966 packet + 1 + CLIENT_ID_SIZE, 987 packet + 1 + CLIENT_ID_SIZE,
967 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 988 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
968 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, 989 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
@@ -1038,7 +1059,7 @@ static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet,
1038 1059
1039 int len = decrypt_data( 1060 int len = decrypt_data(
1040 packet + 1, 1061 packet + 1,
1041 dht->c->self_secret_key, 1062 dht->self_secret_key,
1042 packet + 1 + CLIENT_ID_SIZE, 1063 packet + 1 + CLIENT_ID_SIZE,
1043 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 1064 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
1044 num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, 1065 num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
@@ -1140,6 +1161,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
1140/* 1161/*
1141 * Send get nodes requests with client_id to max_num peers in list of length length 1162 * Send get nodes requests with client_id to max_num peers in list of length length
1142 */ 1163 */
1164/*
1143static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id) 1165static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id)
1144{ 1166{
1145 uint32_t i, num = 0; 1167 uint32_t i, num = 0;
@@ -1159,7 +1181,7 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_
1159 } 1181 }
1160 } 1182 }
1161} 1183}
1162 1184*/
1163int DHT_addfriend(DHT *dht, uint8_t *client_id) 1185int DHT_addfriend(DHT *dht, uint8_t *client_id)
1164{ 1186{
1165 if (friend_number(dht, client_id) != -1) /* Is friend already in DHT? */ 1187 if (friend_number(dht, client_id) != -1) /* Is friend already in DHT? */
@@ -1177,6 +1199,7 @@ int DHT_addfriend(DHT *dht, uint8_t *client_id)
1177 1199
1178 dht->friends_list[dht->num_friends].nat.NATping_id = random_64b(); 1200 dht->friends_list[dht->num_friends].nat.NATping_id = random_64b();
1179 ++dht->num_friends; 1201 ++dht->num_friends;
1202#ifdef ENABLE_ASSOC_DHT
1180 1203
1181 if (dht->assoc) { 1204 if (dht->assoc) {
1182 /* get up to MAX_FRIEND_CLIENTS connectable nodes */ 1205 /* get up to MAX_FRIEND_CLIENTS connectable nodes */
@@ -1206,8 +1229,9 @@ int DHT_addfriend(DHT *dht, uint8_t *client_id)
1206 } 1229 }
1207 } 1230 }
1208 1231
1209 /*TODO: make this better?*/ 1232#endif
1210 get_bunchnodes(dht, dht->close_clientlist, LCLIENT_LIST, MAX_FRIEND_CLIENTS, client_id); 1233 /*this isn't really useful anymore.
1234 get_bunchnodes(dht, dht->close_clientlist, LCLIENT_LIST, MAX_FRIEND_CLIENTS, client_id);*/
1211 1235
1212 return 0; 1236 return 0;
1213} 1237}
@@ -1343,7 +1367,7 @@ static void do_DHT_friends(DHT *dht)
1343 */ 1367 */
1344static void do_Close(DHT *dht) 1368static void do_Close(DHT *dht)
1345{ 1369{
1346 uint8_t not_killed = do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->c->self_public_key, 1370 uint8_t not_killed = do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->self_public_key,
1347 dht->close_clientlist, LCLIENT_LIST); 1371 dht->close_clientlist, LCLIENT_LIST);
1348 1372
1349 if (!not_killed) { 1373 if (!not_killed) {
@@ -1374,16 +1398,17 @@ void DHT_getnodes(DHT *dht, IP_Port *from_ipp, uint8_t *from_id, uint8_t *which_
1374 1398
1375void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) 1399void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
1376{ 1400{
1377 /* 1401 /*#ifdef ENABLE_ASSOC_DHT
1378 if (dht->assoc) { 1402 if (dht->assoc) {
1379 IPPTs ippts; 1403 IPPTs ippts;
1380 ippts.ip_port = ip_port; 1404 ippts.ip_port = ip_port;
1381 ippts.timestamp = 0; 1405 ippts.timestamp = 0;
1382 1406
1383 Assoc_add_entry(dht->assoc, public_key, &ippts, NULL, 0); 1407 Assoc_add_entry(dht->assoc, public_key, &ippts, NULL, 0);
1384 }*/ 1408 }
1409 #endif*/
1385 1410
1386 getnodes(dht, ip_port, public_key, dht->c->self_public_key, NULL); 1411 getnodes(dht, ip_port, public_key, dht->self_public_key, NULL);
1387} 1412}
1388int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, 1413int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
1389 uint16_t port, uint8_t *public_key) 1414 uint16_t port, uint8_t *public_key)
@@ -1427,9 +1452,9 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
1427 Client_data *client = &dht->close_clientlist[i]; 1452 Client_data *client = &dht->close_clientlist[i];
1428 1453
1429 if (ip_isset(&client->assoc6.ip_port.ip)) 1454 if (ip_isset(&client->assoc6.ip_port.ip))
1430 return sendpacket(dht->c->lossless_udp->net, client->assoc6.ip_port, packet, length); 1455 return sendpacket(dht->net, client->assoc6.ip_port, packet, length);
1431 else if (ip_isset(&client->assoc4.ip_port.ip)) 1456 else if (ip_isset(&client->assoc4.ip_port.ip))
1432 return sendpacket(dht->c->lossless_udp->net, client->assoc4.ip_port, packet, length); 1457 return sendpacket(dht->net, client->assoc4.ip_port, packet, length);
1433 else 1458 else
1434 break; 1459 break;
1435 } 1460 }
@@ -1552,7 +1577,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
1552 /* If ip is not zero and node is good. */ 1577 /* If ip is not zero and node is good. */
1553 if (ip_isset(&assoc->ret_ip_port.ip) && 1578 if (ip_isset(&assoc->ret_ip_port.ip) &&
1554 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 1579 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1555 int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length); 1580 int retval = sendpacket(dht->net, assoc->ip_port, packet, length);
1556 1581
1557 if ((unsigned int)retval == length) { 1582 if ((unsigned int)retval == length) {
1558 ++sent; 1583 ++sent;
@@ -1606,7 +1631,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
1606 if (n < 1) 1631 if (n < 1)
1607 return 0; 1632 return 0;
1608 1633
1609 int retval = sendpacket(dht->c->lossless_udp->net, ip_list[rand() % n], packet, length); 1634 int retval = sendpacket(dht->net, ip_list[rand() % n], packet, length);
1610 1635
1611 if ((unsigned int)retval == length) 1636 if ((unsigned int)retval == length)
1612 return 1; 1637 return 1;
@@ -1647,7 +1672,7 @@ static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t
1647 data[0] = type; 1672 data[0] = type;
1648 memcpy(data + 1, &ping_id, sizeof(uint64_t)); 1673 memcpy(data + 1, &ping_id, sizeof(uint64_t));
1649 /* 254 is NAT ping request packet id */ 1674 /* 254 is NAT ping request packet id */
1650 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, data, 1675 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, public_key, data,
1651 sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING); 1676 sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING);
1652 1677
1653 if (len == -1) 1678 if (len == -1)
@@ -1821,7 +1846,7 @@ static void do_NAT(DHT *dht)
1821/*----------------------------------------------------------------------------------*/ 1846/*----------------------------------------------------------------------------------*/
1822/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ 1847/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/
1823 1848
1824#define HARDREQ_DATA_SIZE 768 /* Attempt to prevent amplification/other attacks*/ 1849#define HARDREQ_DATA_SIZE 384 /* Attempt to prevent amplification/other attacks*/
1825 1850
1826#define CHECK_TYPE_ROUTE_REQ 0 1851#define CHECK_TYPE_ROUTE_REQ 0
1827#define CHECK_TYPE_ROUTE_RES 1 1852#define CHECK_TYPE_ROUTE_RES 1
@@ -1839,13 +1864,13 @@ static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8
1839 uint8_t data[HARDREQ_DATA_SIZE] = {0}; 1864 uint8_t data[HARDREQ_DATA_SIZE] = {0};
1840 data[0] = type; 1865 data[0] = type;
1841 memcpy(data + 1, contents, length); 1866 memcpy(data + 1, contents, length);
1842 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data, 1867 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data,
1843 sizeof(data), CRYPTO_PACKET_HARDENING); 1868 sizeof(data), CRYPTO_PACKET_HARDENING);
1844 1869
1845 if (len == -1) 1870 if (len == -1)
1846 return -1; 1871 return -1;
1847 1872
1848 return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len); 1873 return sendpacket(dht->net, sendto->ip_port, packet, len);
1849} 1874}
1850 1875
1851/* Send a get node hardening request */ 1876/* Send a get node hardening request */
@@ -1869,13 +1894,13 @@ static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *qu
1869 data[0] = CHECK_TYPE_GETNODE_RES; 1894 data[0] = CHECK_TYPE_GETNODE_RES;
1870 memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE); 1895 memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE);
1871 memcpy(data + 1 + CLIENT_ID_SIZE, list, num_nodes * sizeof(Node_format)); 1896 memcpy(data + 1 + CLIENT_ID_SIZE, list, num_nodes * sizeof(Node_format));
1872 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data, 1897 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data,
1873 sizeof(data), CRYPTO_PACKET_HARDENING); 1898 sizeof(data), CRYPTO_PACKET_HARDENING);
1874 1899
1875 if (len == -1) 1900 if (len == -1)
1876 return -1; 1901 return -1;
1877 1902
1878 return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len); 1903 return sendpacket(dht->net, sendto->ip_port, packet, len);
1879} 1904}
1880 1905
1881/* TODO: improve */ 1906/* TODO: improve */
@@ -1906,7 +1931,7 @@ static uint32_t have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num)
1906 uint32_t i; 1931 uint32_t i;
1907 1932
1908 for (i = 0; i < num; ++i) { 1933 for (i = 0; i < num; ++i) {
1909 if (id_equal(nodes[i].client_id, dht->c->self_public_key)) { 1934 if (id_equal(nodes[i].client_id, dht->self_public_key)) {
1910 ++counter; 1935 ++counter;
1911 continue; 1936 continue;
1912 } 1937 }
@@ -2116,7 +2141,7 @@ uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num)
2116 uint32_t i; 2141 uint32_t i;
2117 2142
2118 for (i = 0; i < max_num; ++i) { 2143 for (i = 0; i < max_num; ++i) {
2119 uint16_t rand_num = rand() % dht->num_friends + 1; 2144 uint16_t rand_num = rand() % (dht->num_friends + 1);
2120 2145
2121 if (rand_num == dht->num_friends) { 2146 if (rand_num == dht->num_friends) {
2122 list = dht->close_clientlist; 2147 list = dht->close_clientlist;
@@ -2173,7 +2198,7 @@ void do_hardening(DHT *dht)
2173 memcpy(to_test.client_id, client_id, CLIENT_ID_SIZE); 2198 memcpy(to_test.client_id, client_id, CLIENT_ID_SIZE);
2174 2199
2175 //TODO: The search id should maybe not be ours? 2200 //TODO: The search id should maybe not be ours?
2176 if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->c->self_public_key) > 0) { 2201 if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) {
2177 memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.client_id, CLIENT_ID_SIZE); 2202 memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.client_id, CLIENT_ID_SIZE);
2178 cur_iptspng->hardening.send_nodes_timestamp = unix_time(); 2203 cur_iptspng->hardening.send_nodes_timestamp = unix_time();
2179 } 2204 }
@@ -2203,24 +2228,34 @@ DHT *new_DHT(Net_Crypto *c)
2203 if (dht == NULL) 2228 if (dht == NULL)
2204 return NULL; 2229 return NULL;
2205 2230
2206 dht->ping = new_ping(dht, c); 2231 dht->c = c;
2232 dht->net = c->lossless_udp->net;
2233 dht->ping = new_ping(dht);
2207 2234
2208 if (dht->ping == NULL) { 2235 if (dht->ping == NULL) {
2209 kill_DHT(dht); 2236 kill_DHT(dht);
2210 return NULL; 2237 return NULL;
2211 } 2238 }
2212 2239
2213 dht->c = c; 2240 networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
2214 networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); 2241 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht);
2215 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht); 2242 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
2216 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
2217 init_cryptopackets(dht); 2243 init_cryptopackets(dht);
2218 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); 2244 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
2219 cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht); 2245 cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht);
2220 2246
2221 new_symmetric_key(dht->secret_symmetric_key); 2247 new_symmetric_key(dht->secret_symmetric_key);
2222 crypto_box_keypair(dht->self_public_key, dht->self_secret_key); 2248 crypto_box_keypair(dht->self_public_key, dht->self_secret_key);
2223 dht->assoc = new_Assoc_default(dht->c->self_public_key); 2249#ifdef ENABLE_ASSOC_DHT
2250 dht->assoc = new_Assoc_default(dht->self_public_key);
2251#endif
2252 uint32_t i;
2253
2254 for (i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
2255 uint8_t random_key_bytes[CLIENT_ID_SIZE];
2256 randombytes(random_key_bytes, sizeof(random_key_bytes));
2257 DHT_addfriend(dht, random_key_bytes);
2258 }
2224 2259
2225 return dht; 2260 return dht;
2226} 2261}
@@ -2238,15 +2273,19 @@ void do_DHT(DHT *dht)
2238 do_NAT(dht); 2273 do_NAT(dht);
2239 do_toping(dht->ping); 2274 do_toping(dht->ping);
2240 do_hardening(dht); 2275 do_hardening(dht);
2276#ifdef ENABLE_ASSOC_DHT
2241 2277
2242 if (dht->assoc) 2278 if (dht->assoc)
2243 do_Assoc(dht->assoc, dht); 2279 do_Assoc(dht->assoc, dht);
2244 2280
2281#endif
2245 dht->last_run = unix_time(); 2282 dht->last_run = unix_time();
2246} 2283}
2247void kill_DHT(DHT *dht) 2284void kill_DHT(DHT *dht)
2248{ 2285{
2286#ifdef ENABLE_ASSOC_DHT
2249 kill_Assoc(dht->assoc); 2287 kill_Assoc(dht->assoc);
2288#endif
2250 kill_ping(dht->ping); 2289 kill_ping(dht->ping);
2251 free(dht->friends_list); 2290 free(dht->friends_list);
2252 free(dht); 2291 free(dht);
diff --git a/toxcore/DHT.h b/toxcore/DHT.h
index 5afc8ce8..eb889d5d 100644
--- a/toxcore/DHT.h
+++ b/toxcore/DHT.h
@@ -56,6 +56,9 @@
56#define TOX_AF_INET 2 56#define TOX_AF_INET 2
57#define TOX_AF_INET6 10 57#define TOX_AF_INET6 10
58 58
59/* The number of "fake" friends to add (for optimization purposes and so our paths for the onion part are more random) */
60#define DHT_FAKE_FRIEND_NUMBER 4
61
59/* Functions to transfer ips safely across wire. */ 62/* Functions to transfer ips safely across wire. */
60void to_net_family(IP *ip); 63void to_net_family(IP *ip);
61void to_host_family(IP *ip); 64void to_host_family(IP *ip);
@@ -139,6 +142,7 @@ typedef struct {
139 142
140typedef struct { 143typedef struct {
141 Net_Crypto *c; 144 Net_Crypto *c;
145 Networking_Core *net;
142 146
143 Client_data close_clientlist[LCLIENT_LIST]; 147 Client_data close_clientlist[LCLIENT_LIST];
144 uint64_t close_lastgetnodes; 148 uint64_t close_lastgetnodes;
@@ -153,9 +157,9 @@ typedef struct {
153 uint16_t num_friends; 157 uint16_t num_friends;
154 158
155 struct PING *ping; 159 struct PING *ping;
156 160#ifdef ENABLE_ASSOC_DHT
157 struct Assoc *assoc; 161 struct Assoc *assoc;
158 162#endif
159 uint64_t last_run; 163 uint64_t last_run;
160} DHT; 164} DHT;
161/*----------------------------------------------------------------------------------*/ 165/*----------------------------------------------------------------------------------*/
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index eadec9ec..bed14754 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -220,33 +220,33 @@ static int handle_LANdiscovery(void *object, IP_Port source, uint8_t *packet, ui
220} 220}
221 221
222 222
223int send_LANdiscovery(uint16_t port, Net_Crypto *c) 223int send_LANdiscovery(uint16_t port, DHT *dht)
224{ 224{
225 uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; 225 uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
226 data[0] = NET_PACKET_LAN_DISCOVERY; 226 data[0] = NET_PACKET_LAN_DISCOVERY;
227 id_copy(data + 1, c->self_public_key); 227 id_copy(data + 1, dht->self_public_key);
228 228
229#ifdef __linux 229#ifdef __linux
230 send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); 230 send_broadcasts(dht->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
231#endif 231#endif
232 int res = -1; 232 int res = -1;
233 IP_Port ip_port; 233 IP_Port ip_port;
234 ip_port.port = port; 234 ip_port.port = port;
235 235
236 /* IPv6 multicast */ 236 /* IPv6 multicast */
237 if (c->lossless_udp->net->family == AF_INET6) { 237 if (dht->net->family == AF_INET6) {
238 ip_port.ip = broadcast_ip(AF_INET6, AF_INET6); 238 ip_port.ip = broadcast_ip(AF_INET6, AF_INET6);
239 239
240 if (ip_isset(&ip_port.ip)) 240 if (ip_isset(&ip_port.ip))
241 if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES) > 0) 241 if (sendpacket(dht->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES) > 0)
242 res = 1; 242 res = 1;
243 } 243 }
244 244
245 /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is AF_INET6 */ 245 /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is AF_INET6 */
246 ip_port.ip = broadcast_ip(c->lossless_udp->net->family, AF_INET); 246 ip_port.ip = broadcast_ip(dht->net->family, AF_INET);
247 247
248 if (ip_isset(&ip_port.ip)) 248 if (ip_isset(&ip_port.ip))
249 if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES)) 249 if (sendpacket(dht->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES))
250 res = 1; 250 res = 1;
251 251
252 return res; 252 return res;
@@ -255,5 +255,5 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c)
255 255
256void LANdiscovery_init(DHT *dht) 256void LANdiscovery_init(DHT *dht)
257{ 257{
258 networking_registerhandler(dht->c->lossless_udp->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht); 258 networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht);
259} 259}
diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h
index 9d19114d..58bd2bee 100644
--- a/toxcore/LAN_discovery.h
+++ b/toxcore/LAN_discovery.h
@@ -39,7 +39,7 @@
39#define LAN_DISCOVERY_INTERVAL 60 39#define LAN_DISCOVERY_INTERVAL 60
40 40
41/* Send a LAN discovery pcaket to the broadcast address with port port. */ 41/* Send a LAN discovery pcaket to the broadcast address with port port. */
42int send_LANdiscovery(uint16_t port, Net_Crypto *c); 42int send_LANdiscovery(uint16_t port, DHT *dht);
43 43
44/* Sets up packet handlers. */ 44/* Sets up packet handlers. */
45void LANdiscovery_init(DHT *dht); 45void LANdiscovery_init(DHT *dht);
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index bb3a56f0..19246d7d 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -34,27 +34,6 @@
34#define MIN(a,b) (((a)<(b))?(a):(b)) 34#define MIN(a,b) (((a)<(b))?(a):(b))
35 35
36 36
37void host_to_net(uint8_t *num, uint16_t numbytes)
38{
39 union {
40 uint32_t i;
41 uint8_t c[4];
42 } a;
43 a.i = 1;
44
45 if (a.c[0] == 1) {
46 uint32_t i;
47 uint8_t buff[numbytes];
48
49 for (i = 0; i < numbytes; ++i) {
50 buff[i] = num[numbytes - i - 1];
51 }
52
53 memcpy(num, buff, numbytes);
54 }
55}
56#define net_to_host(x, y) host_to_net(x, y)
57
58static void set_friend_status(Messenger *m, int friendnumber, uint8_t status); 37static void set_friend_status(Messenger *m, int friendnumber, uint8_t status);
59static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length); 38static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length);
60 39
@@ -206,11 +185,16 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
206 185
207 memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); 186 memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend));
208 187
188 int onion_friendnum = onion_addfriend(m->onion_c, client_id);
189
190 if (onion_friendnum == -1)
191 return FAERR_UNKNOWN;
192
209 uint32_t i; 193 uint32_t i;
210 194
211 for (i = 0; i <= m->numfriends; ++i) { 195 for (i = 0; i <= m->numfriends; ++i) {
212 if (m->friendlist[i].status == NOFRIEND) { 196 if (m->friendlist[i].status == NOFRIEND) {
213 DHT_addfriend(m->dht, client_id); 197 m->friendlist[i].onion_friendnum = onion_friendnum;
214 m->friendlist[i].status = FRIEND_ADDED; 198 m->friendlist[i].status = FRIEND_ADDED;
215 m->friendlist[i].crypt_connection_id = -1; 199 m->friendlist[i].crypt_connection_id = -1;
216 m->friendlist[i].friendrequest_lastsent = 0; 200 m->friendlist[i].friendrequest_lastsent = 0;
@@ -249,11 +233,16 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
249 233
250 memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); 234 memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend));
251 235
236 int onion_friendnum = onion_addfriend(m->onion_c, client_id);
237
238 if (onion_friendnum == -1)
239 return FAERR_UNKNOWN;
240
252 uint32_t i; 241 uint32_t i;
253 242
254 for (i = 0; i <= m->numfriends; ++i) { 243 for (i = 0; i <= m->numfriends; ++i) {
255 if (m->friendlist[i].status == NOFRIEND) { 244 if (m->friendlist[i].status == NOFRIEND) {
256 DHT_addfriend(m->dht, client_id); 245 m->friendlist[i].onion_friendnum = onion_friendnum;
257 m->friendlist[i].status = FRIEND_CONFIRMED; 246 m->friendlist[i].status = FRIEND_CONFIRMED;
258 m->friendlist[i].crypt_connection_id = -1; 247 m->friendlist[i].crypt_connection_id = -1;
259 m->friendlist[i].friendrequest_lastsent = 0; 248 m->friendlist[i].friendrequest_lastsent = 0;
@@ -284,7 +273,7 @@ int m_delfriend(Messenger *m, int friendnumber)
284 if (friend_not_valid(m, friendnumber)) 273 if (friend_not_valid(m, friendnumber))
285 return -1; 274 return -1;
286 275
287 DHT_delfriend(m->dht, m->friendlist[friendnumber].client_id); 276 onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum);
288 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); 277 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id);
289 free(m->friendlist[friendnumber].statusmessage); 278 free(m->friendlist[friendnumber].statusmessage);
290 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); 279 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend));
@@ -673,6 +662,8 @@ static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_
673 const uint8_t was_online = m->friendlist[friendnumber].status == FRIEND_ONLINE; 662 const uint8_t was_online = m->friendlist[friendnumber].status == FRIEND_ONLINE;
674 const uint8_t is_online = status == FRIEND_ONLINE; 663 const uint8_t is_online = status == FRIEND_ONLINE;
675 664
665 onion_set_friend_online(m->onion_c, m->friendlist[friendnumber].onion_friendnum, is_online);
666
676 if (is_online != was_online) { 667 if (is_online != was_online) {
677 if (was_online) 668 if (was_online)
678 break_files(m, friendnumber); 669 break_files(m, friendnumber);
@@ -1513,7 +1504,7 @@ static int friend_already_added(uint8_t *client_id, void *data)
1513static void LANdiscovery(Messenger *m) 1504static void LANdiscovery(Messenger *m)
1514{ 1505{
1515 if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) { 1506 if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) {
1516 send_LANdiscovery(htons(TOX_PORT_DEFAULT), m->net_crypto); 1507 send_LANdiscovery(htons(TOX_PORT_DEFAULT), m->dht);
1517 m->last_LANdiscovery = unix_time(); 1508 m->last_LANdiscovery = unix_time();
1518 } 1509 }
1519} 1510}
@@ -1552,9 +1543,24 @@ Messenger *new_messenger(uint8_t ipv6enabled)
1552 return NULL; 1543 return NULL;
1553 } 1544 }
1554 1545
1546 m->onion = new_onion(m->dht);
1547 m->onion_a = new_onion_announce(m->dht);
1548 m->onion_c = new_onion_client(m->dht);
1549
1550 if (!(m->onion && m->onion_a && m->onion_c)) {
1551 kill_onion(m->onion);
1552 kill_onion_announce(m->onion_a);
1553 kill_onion_client(m->onion_c);
1554 kill_DHT(m->dht);
1555 kill_net_crypto(m->net_crypto);
1556 kill_networking(m->net);
1557 free(m);
1558 return NULL;
1559 }
1560
1555 m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online")); 1561 m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
1556 1562
1557 friendreq_init(&(m->fr), m->net_crypto); 1563 friendreq_init(&(m->fr), m->onion_c);
1558 LANdiscovery_init(m->dht); 1564 LANdiscovery_init(m->dht);
1559 set_nospam(&(m->fr), random_int()); 1565 set_nospam(&(m->fr), random_int());
1560 set_filter_function(&(m->fr), &friend_already_added, m); 1566 set_filter_function(&(m->fr), &friend_already_added, m);
@@ -1610,7 +1616,7 @@ void do_friends(Messenger *m)
1610 1616
1611 for (i = 0; i < m->numfriends; ++i) { 1617 for (i = 0; i < m->numfriends; ++i) {
1612 if (m->friendlist[i].status == FRIEND_ADDED) { 1618 if (m->friendlist[i].status == FRIEND_ADDED) {
1613 int fr = send_friendrequest(m->dht, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, 1619 int fr = send_friendrequest(m->onion_c, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam,
1614 m->friendlist[i].info, 1620 m->friendlist[i].info,
1615 m->friendlist[i].info_size); 1621 m->friendlist[i].info_size);
1616 1622
@@ -1630,7 +1636,7 @@ void do_friends(Messenger *m)
1630 } 1636 }
1631 1637
1632 IP_Port friendip; 1638 IP_Port friendip;
1633 int friendok = DHT_getfriendip(m->dht, m->friendlist[i].client_id, &friendip); 1639 int friendok = onion_getfriendip(m->onion_c, m->friendlist[i].onion_friendnum, &friendip);
1634 1640
1635 switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { 1641 switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) {
1636 case CRYPTO_CONN_NO_CONNECTION: 1642 case CRYPTO_CONN_NO_CONNECTION:
@@ -1957,6 +1963,7 @@ void do_messenger(Messenger *m)
1957 1963
1958 do_DHT(m->dht); 1964 do_DHT(m->dht);
1959 do_net_crypto(m->net_crypto); 1965 do_net_crypto(m->net_crypto);
1966 do_onion_client(m->onion_c);
1960 do_friends(m); 1967 do_friends(m);
1961 do_inbound(m); 1968 do_inbound(m);
1962 do_allgroupchats(m); 1969 do_allgroupchats(m);
@@ -2188,9 +2195,12 @@ static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t le
2188 if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) { 2195 if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) {
2189 set_nospam(&(m->fr), *(uint32_t *)data); 2196 set_nospam(&(m->fr), *(uint32_t *)data);
2190 load_keys(m->net_crypto, &data[sizeof(uint32_t)]); 2197 load_keys(m->net_crypto, &data[sizeof(uint32_t)]);
2198#ifdef ENABLE_ASSOC_DHT
2191 2199
2192 if (m->dht->assoc) 2200 if (m->dht->assoc)
2193 Assoc_self_client_id_changed(m->dht->assoc, m->net_crypto->self_public_key); 2201 Assoc_self_client_id_changed(m->dht->assoc, m->net_crypto->self_public_key);
2202
2203#endif
2194 } else 2204 } else
2195 return -1; /* critical */ 2205 return -1; /* critical */
2196 2206
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index 3cfd5065..e09b2f30 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -31,6 +31,7 @@
31#include "friend_requests.h" 31#include "friend_requests.h"
32#include "LAN_discovery.h" 32#include "LAN_discovery.h"
33#include "group_chats.h" 33#include "group_chats.h"
34#include "onion_client.h"
34 35
35#define MAX_NAME_LENGTH 128 36#define MAX_NAME_LENGTH 128
36#define MAX_STATUSMESSAGE_LENGTH 1007 37#define MAX_STATUSMESSAGE_LENGTH 1007
@@ -130,6 +131,7 @@ enum {
130 131
131typedef struct { 132typedef struct {
132 uint8_t client_id[CLIENT_ID_SIZE]; 133 uint8_t client_id[CLIENT_ID_SIZE];
134 uint32_t onion_friendnum;
133 int crypt_connection_id; 135 int crypt_connection_id;
134 uint64_t friendrequest_lastsent; // Time at which the last friend request was sent. 136 uint64_t friendrequest_lastsent; // Time at which the last friend request was sent.
135 uint32_t friendrequest_timeout; // The timeout between successful friendrequest sending attempts. 137 uint32_t friendrequest_timeout; // The timeout between successful friendrequest sending attempts.
@@ -160,6 +162,11 @@ typedef struct Messenger {
160 Networking_Core *net; 162 Networking_Core *net;
161 Net_Crypto *net_crypto; 163 Net_Crypto *net_crypto;
162 DHT *dht; 164 DHT *dht;
165
166 Onion *onion;
167 Onion_Announce *onion_a;
168 Onion_Client *onion_c;
169
163 Friend_Requests fr; 170 Friend_Requests fr;
164 uint8_t name[MAX_NAME_LENGTH]; 171 uint8_t name[MAX_NAME_LENGTH];
165 uint16_t name_length; 172 uint16_t name_length;
diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c
index 589bd315..5c294c76 100644
--- a/toxcore/friend_requests.c
+++ b/toxcore/friend_requests.c
@@ -35,41 +35,24 @@
35 * return 0 if it sent the friend request directly to the friend. 35 * return 0 if it sent the friend request directly to the friend.
36 * return the number of peers it was routed through if it did not send it directly. 36 * return the number of peers it was routed through if it did not send it directly.
37 */ 37 */
38int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) 38int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
39{ 39{
40 if (length + sizeof(nospam_num) > MAX_DATA_SIZE) 40 if (length + sizeof(nospam_num) > MAX_DATA_SIZE)
41 return -1; 41 return -1;
42 42
43 uint8_t temp[MAX_DATA_SIZE]; 43 uint8_t temp[MAX_DATA_SIZE];
44 memcpy(temp, &nospam_num, sizeof(nospam_num)); 44 temp[0] = CRYPTO_PACKET_FRIEND_REQ;
45 memcpy(temp + sizeof(nospam_num), data, length); 45 memcpy(temp + 1, &nospam_num, sizeof(nospam_num));
46 uint8_t packet[MAX_DATA_SIZE]; 46 memcpy(temp + 1 + sizeof(nospam_num), data, length);
47 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, temp,
48 length + sizeof(nospam_num),
49 CRYPTO_PACKET_FRIEND_REQ);
50
51 if (len == -1)
52 return -1;
53
54 IP_Port ip_port;
55 int friendok = DHT_getfriendip(dht, public_key, &ip_port);
56
57 // not a friend
58 if (friendok == -1)
59 return -1;
60 47
61 // is a friend and we know how to reach him 48 int friend_num = onion_friend_num(onion_c, public_key);
62 if (friendok == 1) {
63 if (sendpacket(dht->c->lossless_udp->net, ip_port, packet, len) != -1)
64 return 0;
65 49
50 if (friend_num == -1)
66 return -1; 51 return -1;
67 }
68 52
69 // is a friend, we DON'T know how to reach him 53 int num = send_onion_data(onion_c, friend_num, temp, 1 + sizeof(nospam_num) + length);
70 int num = route_tofriend(dht, public_key, packet, len);
71 54
72 if (num == 0) 55 if (num <= 0)
73 return -1; 56 return -1;
74 57
75 return num; 58 return num;
@@ -130,9 +113,14 @@ static int request_received(Friend_Requests *fr, uint8_t *client_id)
130} 113}
131 114
132 115
133static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, 116static int friendreq_handlepacket(void *object, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
134 uint32_t length)
135{ 117{
118 if (length == 0)
119 return 1;
120
121 ++packet;
122 --length;
123
136 Friend_Requests *fr = object; 124 Friend_Requests *fr = object;
137 125
138 if (fr->handle_friendrequest_isset == 0) 126 if (fr->handle_friendrequest_isset == 0)
@@ -156,7 +144,7 @@ static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_
156 return 0; 144 return 0;
157} 145}
158 146
159void friendreq_init(Friend_Requests *fr, Net_Crypto *c) 147void friendreq_init(Friend_Requests *fr, Onion_Client *onion_c)
160{ 148{
161 cryptopacket_registerhandler(c, CRYPTO_PACKET_FRIEND_REQ, &friendreq_handlepacket, fr); 149 oniondata_registerhandler(onion_c, CRYPTO_PACKET_FRIEND_REQ, &friendreq_handlepacket, fr);
162} 150}
diff --git a/toxcore/friend_requests.h b/toxcore/friend_requests.h
index c655669d..732dc4a2 100644
--- a/toxcore/friend_requests.h
+++ b/toxcore/friend_requests.h
@@ -24,7 +24,7 @@
24#ifndef FRIEND_REQUESTS_H 24#ifndef FRIEND_REQUESTS_H
25#define FRIEND_REQUESTS_H 25#define FRIEND_REQUESTS_H
26 26
27#include "DHT.h" 27#include "onion_client.h"
28#include "net_crypto.h" 28#include "net_crypto.h"
29 29
30 30
@@ -49,7 +49,7 @@ typedef struct {
49/* Try to send a friendrequest to peer with public_key. 49/* Try to send a friendrequest to peer with public_key.
50 * data is the data in the request and length is the length. 50 * data is the data in the request and length is the length.
51 */ 51 */
52int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length); 52int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
53/* Set and get the nospam variable used to prevent one type of friend request spam. */ 53/* Set and get the nospam variable used to prevent one type of friend request spam. */
54void set_nospam(Friend_Requests *fr, uint32_t num); 54void set_nospam(Friend_Requests *fr, uint32_t num);
55uint32_t get_nospam(Friend_Requests *fr); 55uint32_t get_nospam(Friend_Requests *fr);
@@ -67,7 +67,7 @@ void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uin
67void set_filter_function(Friend_Requests *fr, int (*function)(uint8_t *, void *), void *userdata); 67void set_filter_function(Friend_Requests *fr, int (*function)(uint8_t *, void *), void *userdata);
68 68
69/* Sets up friendreq packet handlers. */ 69/* Sets up friendreq packet handlers. */
70void friendreq_init(Friend_Requests *fr, Net_Crypto *c); 70void friendreq_init(Friend_Requests *fr, Onion_Client *onion_c);
71 71
72 72
73#endif 73#endif
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index a6c3ecd9..5c2691f3 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -365,11 +365,11 @@ static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, ui
365 length > MAX_DATA_SIZE + crypto_box_MACBYTES) 365 length > MAX_DATA_SIZE + crypto_box_MACBYTES)
366 return 1; 366 return 1;
367 367
368 if (memcmp(packet + 1, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us. 368 if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us.
369 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 369 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
370 uint8_t data[MAX_DATA_SIZE]; 370 uint8_t data[MAX_DATA_SIZE];
371 uint8_t number; 371 uint8_t number;
372 int len = handle_request(dht->c->self_public_key, dht->c->self_secret_key, public_key, data, &number, packet, length); 372 int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length);
373 373
374 if (len == -1 || len == 0) 374 if (len == -1 || len == 0)
375 return 1; 375 return 1;
diff --git a/toxcore/onion.c b/toxcore/onion.c
index 7ec6bb61..9819762d 100644
--- a/toxcore/onion.c
+++ b/toxcore/onion.c
@@ -363,6 +363,9 @@ Onion *new_onion(DHT *dht)
363 363
364void kill_onion(Onion *onion) 364void kill_onion(Onion *onion)
365{ 365{
366 if (onion == NULL)
367 return;
368
366 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, NULL, NULL); 369 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, NULL, NULL);
367 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_1, NULL, NULL); 370 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_1, NULL, NULL);
368 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_2, NULL, NULL); 371 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_2, NULL, NULL);
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c
index 92c9e940..8150974b 100644
--- a/toxcore/onion_announce.c
+++ b/toxcore/onion_announce.c
@@ -29,7 +29,7 @@
29 29
30#define PING_ID_TIMEOUT 20 30#define PING_ID_TIMEOUT 20
31 31
32#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES) 32#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES)
33#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3) 33#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3)
34 34
35#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) 35#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
@@ -43,6 +43,7 @@
43 * public_key and secret_key is the kepair which will be used to encrypt the request. 43 * public_key and secret_key is the kepair which will be used to encrypt the request.
44 * ping_id is the ping id that will be sent in the request. 44 * ping_id is the ping id that will be sent in the request.
45 * client_id is the client id of the node we are searching for. 45 * client_id is the client id of the node we are searching for.
46 * data_public_key is the public key we want others to encrypt their data packets with.
46 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to 47 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
47 * receive back in the response. 48 * receive back in the response.
48 * 49 *
@@ -50,12 +51,14 @@
50 * return 0 on success. 51 * return 0 on success.
51 */ 52 */
52int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, 53int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id,
53 uint8_t *client_id, uint8_t *sendback_data) 54 uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data)
54{ 55{
55 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 56 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
56 memcpy(plain, ping_id, ONION_PING_ID_SIZE); 57 memcpy(plain, ping_id, ONION_PING_ID_SIZE);
57 memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES); 58 memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES);
58 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, sendback_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); 59 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, data_public_key, crypto_box_PUBLICKEYBYTES);
60 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, sendback_data,
61 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
59 uint8_t packet[ANNOUNCE_REQUEST_SIZE]; 62 uint8_t packet[ANNOUNCE_REQUEST_SIZE];
60 packet[0] = NET_PACKET_ANNOUNCE_REQUEST; 63 packet[0] = NET_PACKET_ANNOUNCE_REQUEST;
61 new_nonce(packet + 1); 64 new_nonce(packet + 1);
@@ -78,12 +81,15 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin
78 * send the packet to that person in the form of a response) 81 * send the packet to that person in the form of a response)
79 * 82 *
80 * public_key is the real public key of the node which we want to send the data of length length to. 83 * public_key is the real public key of the node which we want to send the data of length length to.
84 * encrypt_public_key is the public key used to encrypt the data packet.
85 *
81 * nonce is the nonce to encrypt this packet with 86 * nonce is the nonce to encrypt this packet with
82 * 87 *
83 * return -1 on failure. 88 * return -1 on failure.
84 * return 0 on success. 89 * return 0 on success.
85 */ 90 */
86int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, uint16_t length) 91int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce,
92 uint8_t *data, uint16_t length)
87{ 93{
88 uint8_t packet[DATA_REQUEST_MIN_SIZE + length]; 94 uint8_t packet[DATA_REQUEST_MIN_SIZE + length];
89 packet[0] = NET_PACKET_ONION_DATA_REQUEST; 95 packet[0] = NET_PACKET_ONION_DATA_REQUEST;
@@ -96,7 +102,7 @@ int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t
96 102
97 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES); 103 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES);
98 104
99 int len = encrypt_data(public_key, random_secret_key, packet + 1 + crypto_box_PUBLICKEYBYTES, 105 int len = encrypt_data(encrypt_public_key, random_secret_key, packet + 1 + crypto_box_PUBLICKEYBYTES,
100 data, length, packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); 106 data, length, packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES);
101 107
102 if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(packet)) 108 if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(packet))
@@ -167,10 +173,11 @@ static int cmp_entry(const void *a, const void *b)
167 173
168/* add entry to entries list 174/* add entry to entries list
169 * 175 *
170 * return 0 if failure 176 * return -1 if failure
171 * return 1 if added 177 * return position if added
172 */ 178 */
173static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *ret) 179static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *data_public_key,
180 uint8_t *ret)
174{ 181{
175 182
176 int pos = in_entries(onion_a, public_key); 183 int pos = in_entries(onion_a, public_key);
@@ -190,16 +197,17 @@ static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t
190 } 197 }
191 198
192 if (pos == -1) 199 if (pos == -1)
193 return 0; 200 return -1;
194 201
195 memcpy(onion_a->entries[pos].public_key, public_key, crypto_box_PUBLICKEYBYTES); 202 memcpy(onion_a->entries[pos].public_key, public_key, crypto_box_PUBLICKEYBYTES);
196 onion_a->entries[pos].ret_ip_port = ret_ip_port; 203 onion_a->entries[pos].ret_ip_port = ret_ip_port;
197 memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3); 204 memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3);
205 memcpy(onion_a->entries[pos].data_public_key, data_public_key, crypto_box_PUBLICKEYBYTES);
198 onion_a->entries[pos].time = unix_time(); 206 onion_a->entries[pos].time = unix_time();
199 207
200 memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES); 208 memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
201 qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry); 209 qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry);
202 return 1; 210 return pos;
203} 211}
204 212
205static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) 213static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length)
@@ -209,10 +217,11 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
209 if (length != ANNOUNCE_REQUEST_SIZE_RECV) 217 if (length != ANNOUNCE_REQUEST_SIZE_RECV)
210 return 1; 218 return 1;
211 219
212 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 220 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
213 int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, packet + 1, 221 int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, packet + 1,
214 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 222 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
215 ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES, plain); 223 ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH +
224 crypto_box_MACBYTES, plain);
216 225
217 if ((uint32_t)len != sizeof(plain)) 226 if ((uint32_t)len != sizeof(plain))
218 return 1; 227 return 1;
@@ -223,13 +232,14 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
223 uint8_t ping_id2[ONION_PING_ID_SIZE]; 232 uint8_t ping_id2[ONION_PING_ID_SIZE];
224 generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet + 1 + crypto_box_NONCEBYTES, source, ping_id2); 233 generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet + 1 + crypto_box_NONCEBYTES, source, ping_id2);
225 234
226 int stored = 0; 235 int index = -1;
227 236
228 if (memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) { 237 if (memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) {
229 stored = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES, 238 index = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES,
230 packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3)); 239 plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES,
240 packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3));
231 } else { 241 } else {
232 stored = (in_entries(onion_a, plain + ONION_PING_ID_SIZE) != -1); 242 index = in_entries(onion_a, plain + ONION_PING_ID_SIZE);
233 } 243 }
234 244
235 /*Respond with a announce response packet*/ 245 /*Respond with a announce response packet*/
@@ -245,24 +255,29 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
245 uint8_t nonce[crypto_box_NONCEBYTES]; 255 uint8_t nonce[crypto_box_NONCEBYTES];
246 new_nonce(nonce); 256 new_nonce(nonce);
247 257
248 uint8_t pl[ONION_PING_ID_SIZE + sizeof(nodes_list)] = {0}; 258 uint8_t pl[1 + ONION_PING_ID_SIZE + sizeof(nodes_list)];
249 259
250 if (!stored) { 260 if (index == -1) {
251 memcpy(pl, ping_id2, ONION_PING_ID_SIZE); 261 pl[0] = 0;
262 memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE);
263 } else {
264 pl[0] = 1;
265 memcpy(pl + 1, onion_a->entries[index].data_public_key, crypto_box_PUBLICKEYBYTES);
252 } 266 }
253 267
254 memcpy(pl + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format)); 268 memcpy(pl + 1 + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format));
255 269
256 uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE]; 270 uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE];
257 len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl, 271 len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl,
258 ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format), 272 1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format),
259 data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES); 273 data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES);
260 274
261 if ((uint32_t)len != ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES) 275 if ((uint32_t)len != 1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES)
262 return 1; 276 return 1;
263 277
264 data[0] = NET_PACKET_ANNOUNCE_RESPONSE; 278 data[0] = NET_PACKET_ANNOUNCE_RESPONSE;
265 memcpy(data + 1, plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); 279 memcpy(data + 1, plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES,
280 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
266 memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, crypto_box_NONCEBYTES); 281 memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, crypto_box_NONCEBYTES);
267 282
268 if (send_onion_response(onion_a->net, source, data, 283 if (send_onion_response(onion_a->net, source, data,
@@ -321,6 +336,9 @@ Onion_Announce *new_onion_announce(DHT *dht)
321 336
322void kill_onion_announce(Onion_Announce *onion_a) 337void kill_onion_announce(Onion_Announce *onion_a)
323{ 338{
339 if (onion_a == NULL)
340 return;
341
324 networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, NULL, NULL); 342 networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, NULL, NULL);
325 networking_registerhandler(onion_a->net, NET_PACKET_ONION_DATA_REQUEST, NULL, NULL); 343 networking_registerhandler(onion_a->net, NET_PACKET_ONION_DATA_REQUEST, NULL, NULL);
326 free(onion_a); 344 free(onion_a);
diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h
index 01cd7243..27b25bd4 100644
--- a/toxcore/onion_announce.h
+++ b/toxcore/onion_announce.h
@@ -31,15 +31,20 @@
31 31
32#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES) 32#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES)
33 33
34#define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + ONION_PING_ID_SIZE + crypto_box_MACBYTES) 34#define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + 1 + ONION_PING_ID_SIZE + crypto_box_MACBYTES)
35#define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES) 35#define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES)
36 36
37#define ONION_DATA_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) 37#define ONION_DATA_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
38 38
39#if ONION_PING_ID_SIZE != crypto_box_PUBLICKEYBYTES
40#error announce response packets assume that ONION_PING_ID_SIZE is equal to crypto_box_PUBLICKEYBYTES
41#endif
42
39typedef struct { 43typedef struct {
40 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 44 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
41 IP_Port ret_ip_port; 45 IP_Port ret_ip_port;
42 uint8_t ret[ONION_RETURN_3]; 46 uint8_t ret[ONION_RETURN_3];
47 uint8_t data_public_key[crypto_box_PUBLICKEYBYTES];
43 uint64_t time; 48 uint64_t time;
44} Onion_Announce_Entry; 49} Onion_Announce_Entry;
45 50
@@ -59,6 +64,7 @@ typedef struct {
59 * public_key and secret_key is the kepair which will be used to encrypt the request. 64 * public_key and secret_key is the kepair which will be used to encrypt the request.
60 * ping_id is the ping id that will be sent in the request. 65 * ping_id is the ping id that will be sent in the request.
61 * client_id is the client id of the node we are searching for. 66 * client_id is the client id of the node we are searching for.
67 * data_public_key is the public key we want others to encrypt their data packets with.
62 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to 68 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
63 * receive back in the response. 69 * receive back in the response.
64 * 70 *
@@ -66,7 +72,7 @@ typedef struct {
66 * return 0 on success. 72 * return 0 on success.
67 */ 73 */
68int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, 74int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id,
69 uint8_t *client_id, uint8_t *sendback_data); 75 uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data);
70 76
71/* Create and send an onion data request packet. 77/* Create and send an onion data request packet.
72 * 78 *
@@ -75,13 +81,15 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin
75 * send the packet to that person in the form of a response) 81 * send the packet to that person in the form of a response)
76 * 82 *
77 * public_key is the real public key of the node which we want to send the data of length length to. 83 * public_key is the real public key of the node which we want to send the data of length length to.
84 * encrypt_public_key is the public key used to encrypt the data packet.
85 *
78 * nonce is the nonce to encrypt this packet with 86 * nonce is the nonce to encrypt this packet with
79 * 87 *
80 * return -1 on failure. 88 * return -1 on failure.
81 * return 0 on success. 89 * return 0 on success.
82 */ 90 */
83int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, 91int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce,
84 uint16_t length); 92 uint8_t *data, uint16_t length);
85 93
86 94
87Onion_Announce *new_onion_announce(DHT *dht); 95Onion_Announce *new_onion_announce(DHT *dht);
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 27823f0d..32928fd9 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -30,7 +30,6 @@
30 30
31#define ANNOUNCE_TIMEOUT 10 31#define ANNOUNCE_TIMEOUT 10
32 32
33static uint8_t zero_ping[ONION_PING_ID_SIZE];
34 33
35/* Creates a sendback for use in an announce request. 34/* Creates a sendback for use in an announce request.
36 * 35 *
@@ -107,7 +106,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
107 106
108 uint8_t sendback[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 107 uint8_t sendback[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
109 108
110 if (new_sendback(onion_c, 0, dest_pubkey, dest, sendback) == -1) 109 if (new_sendback(onion_c, num, dest_pubkey, dest, sendback) == -1)
111 return -1; 110 return -1;
112 111
113 uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0}; 112 uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0};
@@ -126,11 +125,11 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
126 if (num == 0) { 125 if (num == 0) {
127 return send_announce_request(onion_c->dht, nodes, onion_c->dht->c->self_public_key, 126 return send_announce_request(onion_c->dht, nodes, onion_c->dht->c->self_public_key,
128 onion_c->dht->c->self_secret_key, ping_id, 127 onion_c->dht->c->self_secret_key, ping_id,
129 onion_c->dht->c->self_public_key, sendback); 128 onion_c->dht->c->self_public_key, onion_c->temp_public_key, sendback);
130 } else { 129 } else {
131 return send_announce_request(onion_c->dht, nodes, onion_c->friends_list[num - 1].temp_public_key, 130 return send_announce_request(onion_c->dht, nodes, onion_c->friends_list[num - 1].temp_public_key,
132 onion_c->friends_list[num - 1].temp_secret_key, ping_id, 131 onion_c->friends_list[num - 1].temp_secret_key, ping_id,
133 onion_c->friends_list[num - 1].real_client_id, sendback); 132 onion_c->friends_list[num - 1].real_client_id, zero_ping_id, sendback);
134 } 133 }
135} 134}
136 135
@@ -164,7 +163,7 @@ static int cmp_entry(const void *a, const void *b)
164} 163}
165 164
166static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, 165static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port,
167 uint8_t *ping_id) 166 uint8_t is_stored, uint8_t *pingid_or_key)
168{ 167{
169 if (num > onion_c->num_friends) 168 if (num > onion_c->num_friends)
170 return -1; 169 return -1;
@@ -204,7 +203,14 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ
204 203
205 memcpy(list_nodes[index].client_id, public_key, CLIENT_ID_SIZE); 204 memcpy(list_nodes[index].client_id, public_key, CLIENT_ID_SIZE);
206 list_nodes[index].ip_port = ip_port; 205 list_nodes[index].ip_port = ip_port;
207 memcpy(list_nodes[index].ping_id, ping_id, ONION_PING_ID_SIZE); 206
207 if (is_stored) {
208 memcpy(list_nodes[index].data_public_key, pingid_or_key, crypto_box_PUBLICKEYBYTES);
209 } else {
210 memcpy(list_nodes[index].ping_id, pingid_or_key, ONION_PING_ID_SIZE);
211 }
212
213 list_nodes[index].is_stored = is_stored;
208 list_nodes[index].timestamp = unix_time(); 214 list_nodes[index].timestamp = unix_time();
209 list_nodes[index].last_pinged = 0; 215 list_nodes[index].last_pinged = 0;
210 return 0; 216 return 0;
@@ -230,7 +236,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
230 reference_id = onion_c->friends_list[num - 1].real_client_id; 236 reference_id = onion_c->friends_list[num - 1].real_client_id;
231 } 237 }
232 238
233 uint32_t i; 239 uint32_t i, j;
234 int lan_ips_accepted = (LAN_ip(source.ip) == 0); 240 int lan_ips_accepted = (LAN_ip(source.ip) == 0);
235 241
236 for (i = 0; i < num_nodes; ++i) { 242 for (i = 0; i < num_nodes; ++i) {
@@ -242,7 +248,15 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
242 248
243 if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT) 249 if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT)
244 || id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) { 250 || id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) {
245 client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL); 251 /* check if node is already in list. */
252 for (j = 0; j < MAX_ONION_CLIENTS; ++j) {
253 if (memcmp(list_nodes[j].client_id, nodes[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) {
254 break;
255 }
256 }
257
258 if (j == MAX_ONION_CLIENTS)
259 client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL);
246 } 260 }
247 } 261 }
248 262
@@ -268,7 +282,7 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
268 if (num > onion_c->num_friends) 282 if (num > onion_c->num_friends)
269 return 1; 283 return 1;
270 284
271 uint8_t plain[ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)]; 285 uint8_t plain[1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)];
272 int len = -1; 286 int len = -1;
273 287
274 if (num == 0) { 288 if (num == 0) {
@@ -289,10 +303,10 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
289 return 1; 303 return 1;
290 304
291 305
292 if (client_add_to_list(onion_c, num, public_key, ip_port, plain) == -1) 306 if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1) == -1)
293 return 1; 307 return 1;
294 308
295 if (client_ping_nodes(onion_c, num, (Node_format *)plain + ONION_PING_ID_SIZE, num_nodes, source) == -1) 309 if (client_ping_nodes(onion_c, num, (Node_format *)plain + 1 + ONION_PING_ID_SIZE, num_nodes, source) == -1)
296 return 1; 310 return 1;
297 311
298 return 0; 312 return 0;
@@ -311,7 +325,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u
311 return 1; 325 return 1;
312 326
313 uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE]; 327 uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE];
314 int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_c->dht->c->self_secret_key, packet + 1, 328 int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_c->temp_secret_key, packet + 1,
315 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 329 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
316 length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), temp_plain); 330 length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), temp_plain);
317 331
@@ -333,7 +347,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u
333} 347}
334 348
335#define FAKEID_DATA_ID 156 349#define FAKEID_DATA_ID 156
336#define FAKEID_DATA_MIN_LENGTH (1 + crypto_box_PUBLICKEYBYTES) 350#define FAKEID_DATA_MIN_LENGTH (1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES)
337#define FAKEID_DATA_MAX_LENGTH (FAKEID_DATA_MIN_LENGTH + sizeof(Node_format)*MAX_SENT_NODES) 351#define FAKEID_DATA_MAX_LENGTH (FAKEID_DATA_MIN_LENGTH + sizeof(Node_format)*MAX_SENT_NODES)
338static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t length) 352static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t length)
339{ 353{
@@ -353,19 +367,30 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
353 if (friend_num == -1) 367 if (friend_num == -1)
354 return 1; 368 return 1;
355 369
356 if (memcmp(data + 1, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES) != 0) { 370 uint64_t no_replay;
371 net_to_host(data + 1, sizeof(no_replay));
372 memcpy(&no_replay, data + 1, sizeof(uint64_t));
373
374 if (no_replay <= onion_c->friends_list[friend_num].last_noreplay)
375 return 1;
376
377 onion_c->friends_list[friend_num].last_noreplay = no_replay;
378
379 if (memcmp(data + 1 + sizeof(uint64_t), onion_c->friends_list[friend_num].fake_client_id,
380 crypto_box_PUBLICKEYBYTES) != 0) {
357 DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id); 381 DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
358 382
359 if (DHT_addfriend(onion_c->dht, data + 1) == 1) { 383 if (DHT_addfriend(onion_c->dht, data + 1 + sizeof(uint64_t)) == 1) {
360 return 1; 384 return 1;
361 } 385 }
362 386
363 memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1, crypto_box_PUBLICKEYBYTES); 387 onion_c->friends_list[friend_num].is_fake_clientid = 1;
388 memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
364 } 389 }
365 390
366 uint16_t num_nodes = (length - FAKEID_DATA_MIN_LENGTH) / sizeof(Node_format); 391 uint16_t num_nodes = (length - FAKEID_DATA_MIN_LENGTH) / sizeof(Node_format);
367 Node_format nodes[num_nodes]; 392 Node_format nodes[num_nodes];
368 memcpy(nodes, data + 1 + crypto_box_PUBLICKEYBYTES, sizeof(nodes)); 393 memcpy(nodes, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, sizeof(nodes));
369 uint32_t i; 394 uint32_t i;
370 395
371 for (i = 0; i < num_nodes; ++i) { 396 for (i = 0; i < num_nodes; ++i) {
@@ -373,7 +398,6 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
373 DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id); 398 DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id);
374 } 399 }
375 400
376 //TODO replay protection
377 return 0; 401 return 0;
378} 402}
379/* Send data of length length to friendnum. 403/* Send data of length length to friendnum.
@@ -413,7 +437,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
413 if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT)) 437 if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT))
414 continue; 438 continue;
415 439
416 if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) { 440 if (list_nodes[i].is_stored) {
417 Node_format nodes[4]; 441 Node_format nodes[4];
418 442
419 if (random_path(onion_c, nodes) == -1) 443 if (random_path(onion_c, nodes) == -1)
@@ -422,8 +446,8 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
422 memcpy(nodes[3].client_id, list_nodes[i].client_id, crypto_box_PUBLICKEYBYTES); 446 memcpy(nodes[3].client_id, list_nodes[i].client_id, crypto_box_PUBLICKEYBYTES);
423 nodes[3].ip_port = list_nodes[i].ip_port; 447 nodes[3].ip_port = list_nodes[i].ip_port;
424 448
425 if (send_data_request(onion_c->dht, nodes, onion_c->friends_list[friend_num].real_client_id, nonce, packet, 449 if (send_data_request(onion_c->dht, nodes, onion_c->friends_list[friend_num].real_client_id,
426 sizeof(packet)) == 0) 450 list_nodes[i].data_public_key, nonce, packet, sizeof(packet)) == 0)
427 ++good; 451 ++good;
428 } 452 }
429 } 453 }
@@ -431,24 +455,104 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
431 return good; 455 return good;
432} 456}
433 457
434/* Send the packets to tell our friends 458/* Try to send the fakeid via the DHT instead of onion
459 *
460 * Even if this function succeeds, the friend might not recieve any data.
461 *
435 * return the number of packets sent on success 462 * return the number of packets sent on success
436 * return -1 on failure. 463 * return -1 on failure.
437 */ 464 */
438static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num) 465static int send_dht_fakeid(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32_t length)
466{
467 if ((uint32_t)friend_num >= onion_c->num_friends)
468 return -1;
469
470 if (!onion_c->friends_list[friend_num].is_fake_clientid)
471 return -1;
472
473 uint8_t nonce[crypto_box_NONCEBYTES];
474 new_nonce(nonce);
475
476 uint8_t temp[DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES + length];
477 memcpy(temp, onion_c->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES);
478 memcpy(temp + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
479 int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->dht->c->self_secret_key, nonce, data,
480 length, temp + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
481
482 if ((uint32_t)len + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES != sizeof(temp))
483 return -1;
484
485 uint8_t packet[MAX_DATA_SIZE];
486 len = create_request(onion_c->dht->self_public_key, onion_c->dht->self_secret_key, packet,
487 onion_c->friends_list[friend_num].fake_client_id, temp, sizeof(temp), FAKEID_DATA_ID);
488
489 if (len == -1)
490 return -1;
491
492 return route_tofriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, packet, len);
493}
494
495static int handle_dht_fakeid(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
496{
497 Onion_Client *onion_c = object;
498
499 if (length < FAKEID_DATA_MIN_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)
500 return 1;
501
502 if (length > FAKEID_DATA_MAX_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)
503 return 1;
504
505 uint8_t plain[FAKEID_DATA_MAX_LENGTH];
506 int len = decrypt_data(packet, onion_c->dht->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES,
507 packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
508 length - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES), plain);
509
510 if ((uint32_t)len != length - (DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES))
511 return 1;
512
513 if (memcpy(source_pubkey, packet, crypto_box_PUBLICKEYBYTES) != 0)
514 return 1;
515
516 return handle_fakeid_announce(onion_c, packet, plain, len);
517}
518/* Send the packets to tell our friends what our DHT public key is.
519 *
520 * if onion_dht_both is 0, use only the onion to send the packet.
521 * if it is 1, use only the dht.
522 * if it is something else, use both.
523 *
524 * return the number of packets sent on success
525 * return -1 on failure.
526 */
527static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both)
439{ 528{
440 if (friend_num >= onion_c->num_friends) 529 if (friend_num >= onion_c->num_friends)
441 return -1; 530 return -1;
442 531
443 uint8_t data[FAKEID_DATA_MAX_LENGTH]; 532 uint8_t data[FAKEID_DATA_MAX_LENGTH];
444 data[0] = FAKEID_DATA_ID; 533 data[0] = FAKEID_DATA_ID;
445 memcpy(data + 1, onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); 534 uint64_t no_replay = unix_time();
535 host_to_net((uint8_t *)&no_replay, sizeof(no_replay));
536 memcpy(data + 1, &no_replay, sizeof(no_replay));
537 memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
446 Node_format nodes[MAX_SENT_NODES]; 538 Node_format nodes[MAX_SENT_NODES];
447 uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES); 539 uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES);
448 memcpy(data + FAKEID_DATA_MIN_LENGTH, nodes, sizeof(Node_format) * num_nodes); 540 memcpy(data + FAKEID_DATA_MIN_LENGTH, nodes, sizeof(Node_format) * num_nodes);
449 return send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes); 541 int num1 = -1, num2 = -1;
450 //TODO: somehow make this function send our DHT client id directly to the other if we know theirs but they don't 542
451 //seem to know ours. 543 if (onion_dht_both != 1)
544 num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);
545
546 if (onion_dht_both != 0)
547 num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);
548
549 if (num1 == -1)
550 return num2;
551
552 if (num2 == -1)
553 return num1;
554
555 return num1 + num2;
452} 556}
453 557
454/* Get the friend_num of a friend. 558/* Get the friend_num of a friend.
@@ -525,6 +629,7 @@ int onion_addfriend(Onion_Client *onion_c, uint8_t *client_id)
525 629
526 onion_c->friends_list[index].status = 1; 630 onion_c->friends_list[index].status = 1;
527 memcpy(onion_c->friends_list[index].real_client_id, client_id, crypto_box_PUBLICKEYBYTES); 631 memcpy(onion_c->friends_list[index].real_client_id, client_id, crypto_box_PUBLICKEYBYTES);
632 crypto_box_keypair(onion_c->friends_list[index].temp_public_key, onion_c->friends_list[index].temp_secret_key);
528 return index; 633 return index;
529} 634}
530 635
@@ -538,7 +643,9 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
538 if ((uint32_t)friend_num >= onion_c->num_friends) 643 if ((uint32_t)friend_num >= onion_c->num_friends)
539 return -1; 644 return -1;
540 645
541 DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id); 646 if (onion_c->friends_list[friend_num].is_fake_clientid)
647 DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
648
542 memset(&(onion_c->friends_list[friend_num]), 0, sizeof(Onion_Friend)); 649 memset(&(onion_c->friends_list[friend_num]), 0, sizeof(Onion_Friend));
543 uint32_t i; 650 uint32_t i;
544 651
@@ -557,8 +664,9 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
557 664
558/* Get the ip of friend friendnum and put it in ip_port 665/* Get the ip of friend friendnum and put it in ip_port
559 * 666 *
560 * return -1 on failure 667 * return -1, -- if client_id does NOT refer to a friend
561 * return 0 on success 668 * return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
669 * return 1, ip if client_id refers to a friend and we found him
562 * 670 *
563 */ 671 */
564int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port) 672int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
@@ -569,10 +677,31 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
569 if (onion_c->friends_list[friend_num].status == 0) 677 if (onion_c->friends_list[friend_num].status == 0)
570 return -1; 678 return -1;
571 679
572 if (DHT_getfriendip(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, ip_port) == 1) 680 if (!onion_c->friends_list[friend_num].is_fake_clientid)
573 return 0; 681 return -1;
574 682
575 return -1; 683 return DHT_getfriendip(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, ip_port);
684}
685
686/* Set if friend is online or not.
687 * NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
688 *
689 * is_online 1 means friend is online.
690 * is_online 0 means friend is offline
691 *
692 * return -1 on failure.
693 * return 0 on success.
694 */
695int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_online)
696{
697 if ((uint32_t)friend_num >= onion_c->num_friends)
698 return -1;
699
700 onion_c->friends_list[friend_num].is_online = is_online;
701 /* Should we reset the no_replay when the other goes offline?
702 if (!is_online)
703 onion_c->friends_list[friend_num].last_noreplay = 0; */
704 return 0;
576} 705}
577 706
578/* Takes 3 random nodes that we know and puts them in nodes 707/* Takes 3 random nodes that we know and puts them in nodes
@@ -591,7 +720,7 @@ int random_path(Onion_Client *onion_c, Node_format *nodes)
591 return 0; 720 return 0;
592} 721}
593 722
594#define ANNOUNCE_FRIEND 30 723#define ANNOUNCE_FRIEND 120
595 724
596static void do_friend(Onion_Client *onion_c, uint16_t friendnum) 725static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
597{ 726{
@@ -604,32 +733,39 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
604 uint32_t i, count = 0; 733 uint32_t i, count = 0;
605 Onion_Node *list_nodes = onion_c->friends_list[friendnum].clients_list; 734 Onion_Node *list_nodes = onion_c->friends_list[friendnum].clients_list;
606 735
607 for (i = 0; i < MAX_ONION_CLIENTS; ++i) { 736 if (!onion_c->friends_list[friendnum].is_online) {
608 if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT)) 737 for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
609 continue; 738 if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT))
739 continue;
610 740
611 ++count; 741 ++count;
612 742
613 if (is_timeout(list_nodes[i].last_pinged, ANNOUNCE_FRIEND)) { 743 if (is_timeout(list_nodes[i].last_pinged, ANNOUNCE_FRIEND)) {
614 if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0) == 0) { 744 if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0) == 0) {
615 list_nodes[i].last_pinged = unix_time(); 745 list_nodes[i].last_pinged = unix_time();
746 }
616 } 747 }
617 } 748 }
618 }
619 749
620 if (count < MAX_ONION_CLIENTS / 2) { 750 if (count < MAX_ONION_CLIENTS / 2) {
621 Node_format nodes_list[MAX_SENT_NODES]; 751 Node_format nodes_list[MAX_SENT_NODES];
622 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->friends_list[i].real_client_id, nodes_list, 752 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->friends_list[friendnum].real_client_id, nodes_list,
623 rand() % 2 ? AF_INET : AF_INET6, rand() % 2, 1); 753 rand() % 2 ? AF_INET : AF_INET6, 1, 0);
624 754
625 for (i = 0; i < num_nodes; ++i) 755 for (i = 0; i < num_nodes; ++i)
626 client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0); 756 client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0);
627 } 757 }
758
759
760 /* send packets to friend telling them our fake DHT id. */
761 if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_onion_sent, ONION_FAKEID_INTERVAL))
762 if (send_fakeid_announce(onion_c, friendnum, 0) > 1)
763 onion_c->friends_list[friendnum].last_fakeid_onion_sent = unix_time();
628 764
629 /* send packets to friend telling them our fake DHT id. */ 765 if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_dht_sent, DHT_FAKEID_INTERVAL))
630 if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_sent, ONION_FAKEID_INTERVAL)) 766 if (send_fakeid_announce(onion_c, friendnum, 1) > 1)
631 if (send_fakeid_announce(onion_c, friendnum) > 3) 767 onion_c->friends_list[friendnum].last_fakeid_dht_sent = unix_time();
632 onion_c->friends_list[friendnum].last_fakeid_sent = unix_time(); 768 }
633} 769}
634/* Function to call when onion data packet with contents beginning with byte is received. */ 770/* Function to call when onion data packet with contents beginning with byte is received. */
635void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object) 771void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object)
@@ -639,7 +775,7 @@ void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_ha
639} 775}
640 776
641#define ANNOUNCE_INTERVAL_NOT_ANNOUNCED 10 777#define ANNOUNCE_INTERVAL_NOT_ANNOUNCED 10
642#define ANNOUNCE_INTERVAL_ANNOUNCED 60 778#define ANNOUNCE_INTERVAL_ANNOUNCED 120
643 779
644static void do_announce(Onion_Client *onion_c) 780static void do_announce(Onion_Client *onion_c)
645{ 781{
@@ -653,7 +789,7 @@ static void do_announce(Onion_Client *onion_c)
653 ++count; 789 ++count;
654 uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED; 790 uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;
655 791
656 if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) { 792 if (list_nodes[i].is_stored) {
657 interval = ANNOUNCE_INTERVAL_ANNOUNCED; 793 interval = ANNOUNCE_INTERVAL_ANNOUNCED;
658 } 794 }
659 795
@@ -668,7 +804,7 @@ static void do_announce(Onion_Client *onion_c)
668 if (count < MAX_ONION_CLIENTS / 2) { 804 if (count < MAX_ONION_CLIENTS / 2) {
669 Node_format nodes_list[MAX_SENT_NODES]; 805 Node_format nodes_list[MAX_SENT_NODES];
670 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->dht->c->self_public_key, nodes_list, 806 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->dht->c->self_public_key, nodes_list,
671 rand() % 2 ? AF_INET : AF_INET6, rand() % 2, 1); 807 rand() % 2 ? AF_INET : AF_INET6, 1, 0);
672 808
673 for (i = 0; i < num_nodes; ++i) 809 for (i = 0; i < num_nodes; ++i)
674 client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0); 810 client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0);
@@ -704,16 +840,20 @@ Onion_Client *new_onion_client(DHT *dht)
704 onion_c->dht = dht; 840 onion_c->dht = dht;
705 onion_c->net = dht->c->lossless_udp->net; 841 onion_c->net = dht->c->lossless_udp->net;
706 new_symmetric_key(onion_c->secret_symmetric_key); 842 new_symmetric_key(onion_c->secret_symmetric_key);
707 843 crypto_box_keypair(onion_c->temp_public_key, onion_c->temp_secret_key);
708 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c); 844 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c);
709 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); 845 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
710 oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c); 846 oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c);
847 cryptopacket_registerhandler(onion_c->dht->c, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c);
711 848
712 return onion_c; 849 return onion_c;
713} 850}
714 851
715void kill_onion_client(Onion_Client *onion_c) 852void kill_onion_client(Onion_Client *onion_c)
716{ 853{
854 if (onion_c == NULL)
855 return;
856
717 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL); 857 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL);
718 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); 858 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL);
719 free(onion_c); 859 free(onion_c);
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h
index 181bc533..9491b0b7 100644
--- a/toxcore/onion_client.h
+++ b/toxcore/onion_client.h
@@ -27,15 +27,19 @@
27#include "onion_announce.h" 27#include "onion_announce.h"
28 28
29#define MAX_ONION_CLIENTS 8 29#define MAX_ONION_CLIENTS 8
30#define ONION_NODE_TIMEOUT 200 30#define ONION_NODE_TIMEOUT 240
31 31
32/* The interval in seconds at which to tell our friends where we are */ 32/* The interval in seconds at which to tell our friends where we are */
33#define ONION_FAKEID_INTERVAL 60 33#define ONION_FAKEID_INTERVAL 60
34#define DHT_FAKEID_INTERVAL 20
34 35
35typedef struct { 36typedef struct {
36 uint8_t client_id[CLIENT_ID_SIZE]; 37 uint8_t client_id[CLIENT_ID_SIZE];
37 IP_Port ip_port; 38 IP_Port ip_port;
38 uint8_t ping_id[ONION_PING_ID_SIZE]; 39 uint8_t ping_id[ONION_PING_ID_SIZE];
40 uint8_t data_public_key[crypto_box_PUBLICKEYBYTES];
41 uint8_t is_stored;
42
39 uint64_t timestamp; 43 uint64_t timestamp;
40 44
41 uint64_t last_pinged; 45 uint64_t last_pinged;
@@ -43,7 +47,9 @@ typedef struct {
43 47
44typedef struct { 48typedef struct {
45 uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/ 49 uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/
50 uint8_t is_online; /* Set by the onion_set_friend_status function. */
46 51
52 uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */
47 uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES]; 53 uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES];
48 uint8_t real_client_id[crypto_box_PUBLICKEYBYTES]; 54 uint8_t real_client_id[crypto_box_PUBLICKEYBYTES];
49 55
@@ -51,7 +57,10 @@ typedef struct {
51 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; 57 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
52 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; 58 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
53 59
54 uint64_t last_fakeid_sent; 60 uint64_t last_fakeid_onion_sent;
61 uint64_t last_fakeid_dht_sent;
62
63 uint64_t last_noreplay;
55} Onion_Friend; 64} Onion_Friend;
56 65
57typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len); 66typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
@@ -67,6 +76,8 @@ typedef struct {
67 uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES]; 76 uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES];
68 uint64_t last_run; 77 uint64_t last_run;
69 78
79 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
80 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
70 struct { 81 struct {
71 oniondata_handler_callback function; 82 oniondata_handler_callback function;
72 void *object; 83 void *object;
@@ -94,10 +105,22 @@ int onion_addfriend(Onion_Client *onion_c, uint8_t *client_id);
94 */ 105 */
95int onion_delfriend(Onion_Client *onion_c, int friend_num); 106int onion_delfriend(Onion_Client *onion_c, int friend_num);
96 107
108/* Set if friend is online or not.
109 * NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
110 *
111 * is_online 1 means friend is online.
112 * is_online 0 means friend is offline
113 *
114 * return -1 on failure.
115 * return 0 on success.
116 */
117int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_online);
118
97/* Get the ip of friend friendnum and put it in ip_port 119/* Get the ip of friend friendnum and put it in ip_port
98 * 120 *
99 * return -1 on failure 121 * return -1, -- if client_id does NOT refer to a friend
100 * return 0 on success 122 * return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
123 * return 1, ip if client_id refers to a friend and we found him
101 * 124 *
102 */ 125 */
103int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); 126int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
diff --git a/toxcore/ping.c b/toxcore/ping.c
index 6c368d0c..a37b531d 100644
--- a/toxcore/ping.c
+++ b/toxcore/ping.c
@@ -47,7 +47,7 @@ typedef struct {
47} pinged_t; 47} pinged_t;
48 48
49struct PING { 49struct PING {
50 Net_Crypto *c; 50 DHT *dht;
51 51
52 pinged_t pings[PING_NUM_MAX]; 52 pinged_t pings[PING_NUM_MAX];
53 size_t num_pings; 53 size_t num_pings;
@@ -148,19 +148,19 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
148 int rc; 148 int rc;
149 uint64_t ping_id; 149 uint64_t ping_id;
150 150
151 if (is_pinging(ping, ipp, 0) || id_equal(client_id, ping->c->self_public_key)) 151 if (is_pinging(ping, ipp, 0) || id_equal(client_id, ping->dht->self_public_key))
152 return 1; 152 return 1;
153 153
154 // Generate random ping_id. 154 // Generate random ping_id.
155 ping_id = add_ping(ping, ipp); 155 ping_id = add_ping(ping, ipp);
156 156
157 pk[0] = NET_PACKET_PING_REQUEST; 157 pk[0] = NET_PACKET_PING_REQUEST;
158 id_copy(pk + 1, ping->c->self_public_key); // Our pubkey 158 id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey
159 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce 159 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
160 160
161 // Encrypt ping_id using recipient privkey 161 // Encrypt ping_id using recipient privkey
162 rc = encrypt_data(client_id, 162 rc = encrypt_data(client_id,
163 ping->c->self_secret_key, 163 ping->dht->self_secret_key,
164 pk + 1 + CLIENT_ID_SIZE, 164 pk + 1 + CLIENT_ID_SIZE,
165 (uint8_t *) &ping_id, sizeof(ping_id), 165 (uint8_t *) &ping_id, sizeof(ping_id),
166 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES); 166 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES);
@@ -168,7 +168,7 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
168 if (rc != sizeof(ping_id) + crypto_box_MACBYTES) 168 if (rc != sizeof(ping_id) + crypto_box_MACBYTES)
169 return 1; 169 return 1;
170 170
171 return sendpacket(ping->c->lossless_udp->net, ipp, pk, sizeof(pk)); 171 return sendpacket(ping->dht->net, ipp, pk, sizeof(pk));
172} 172}
173 173
174static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint64_t ping_id) 174static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint64_t ping_id)
@@ -176,16 +176,16 @@ static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint6
176 uint8_t pk[DHT_PING_SIZE]; 176 uint8_t pk[DHT_PING_SIZE];
177 int rc; 177 int rc;
178 178
179 if (id_equal(client_id, ping->c->self_public_key)) 179 if (id_equal(client_id, ping->dht->self_public_key))
180 return 1; 180 return 1;
181 181
182 pk[0] = NET_PACKET_PING_RESPONSE; 182 pk[0] = NET_PACKET_PING_RESPONSE;
183 id_copy(pk + 1, ping->c->self_public_key); // Our pubkey 183 id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey
184 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce 184 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
185 185
186 // Encrypt ping_id using recipient privkey 186 // Encrypt ping_id using recipient privkey
187 rc = encrypt_data(client_id, 187 rc = encrypt_data(client_id,
188 ping->c->self_secret_key, 188 ping->dht->self_secret_key,
189 pk + 1 + CLIENT_ID_SIZE, 189 pk + 1 + CLIENT_ID_SIZE,
190 (uint8_t *) &ping_id, sizeof(ping_id), 190 (uint8_t *) &ping_id, sizeof(ping_id),
191 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES); 191 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES);
@@ -193,7 +193,7 @@ static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint6
193 if (rc != sizeof(ping_id) + crypto_box_MACBYTES) 193 if (rc != sizeof(ping_id) + crypto_box_MACBYTES)
194 return 1; 194 return 1;
195 195
196 return sendpacket(ping->c->lossless_udp->net, ipp, pk, sizeof(pk)); 196 return sendpacket(ping->dht->net, ipp, pk, sizeof(pk));
197} 197}
198 198
199static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint32_t length) 199static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint32_t length)
@@ -207,12 +207,12 @@ static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint
207 207
208 PING *ping = dht->ping; 208 PING *ping = dht->ping;
209 209
210 if (id_equal(packet + 1, ping->c->self_public_key)) 210 if (id_equal(packet + 1, ping->dht->self_public_key))
211 return 1; 211 return 1;
212 212
213 // Decrypt ping_id 213 // Decrypt ping_id
214 rc = decrypt_data(packet + 1, 214 rc = decrypt_data(packet + 1,
215 ping->c->self_secret_key, 215 ping->dht->self_secret_key,
216 packet + 1 + CLIENT_ID_SIZE, 216 packet + 1 + CLIENT_ID_SIZE,
217 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 217 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
218 sizeof(ping_id) + crypto_box_MACBYTES, 218 sizeof(ping_id) + crypto_box_MACBYTES,
@@ -239,12 +239,12 @@ static int handle_ping_response(void *_dht, IP_Port source, uint8_t *packet, uin
239 239
240 PING *ping = dht->ping; 240 PING *ping = dht->ping;
241 241
242 if (id_equal(packet + 1, ping->c->self_public_key)) 242 if (id_equal(packet + 1, ping->dht->self_public_key))
243 return 1; 243 return 1;
244 244
245 // Decrypt ping_id 245 // Decrypt ping_id
246 rc = decrypt_data(packet + 1, 246 rc = decrypt_data(packet + 1,
247 ping->c->self_secret_key, 247 ping->dht->self_secret_key,
248 packet + 1 + CLIENT_ID_SIZE, 248 packet + 1 + CLIENT_ID_SIZE,
249 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 249 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
250 sizeof(ping_id) + crypto_box_MACBYTES, 250 sizeof(ping_id) + crypto_box_MACBYTES,
@@ -291,7 +291,7 @@ int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port)
291 } 291 }
292 292
293 for (i = 0; i < MAX_TOPING; ++i) { 293 for (i = 0; i < MAX_TOPING; ++i) {
294 if (id_closest(ping->c->self_public_key, ping->toping[i].client_id, client_id) == 2) { 294 if (id_closest(ping->dht->self_public_key, ping->toping[i].client_id, client_id) == 2) {
295 memcpy(ping->toping[i].client_id, client_id, CLIENT_ID_SIZE); 295 memcpy(ping->toping[i].client_id, client_id, CLIENT_ID_SIZE);
296 ipport_copy(&ping->toping[i].ip_port, &ip_port); 296 ipport_copy(&ping->toping[i].ip_port, &ip_port);
297 return 0; 297 return 0;
@@ -323,24 +323,24 @@ void do_toping(PING *ping)
323} 323}
324 324
325 325
326PING *new_ping(DHT *dht, Net_Crypto *c) 326PING *new_ping(DHT *dht)
327{ 327{
328 PING *ping = calloc(1, sizeof(PING)); 328 PING *ping = calloc(1, sizeof(PING));
329 329
330 if (ping == NULL) 330 if (ping == NULL)
331 return NULL; 331 return NULL;
332 332
333 ping->c = c; 333 ping->dht = dht;
334 networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_REQUEST, &handle_ping_request, dht); 334 networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
335 networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, dht); 335 networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);
336 336
337 return ping; 337 return ping;
338} 338}
339 339
340void kill_ping(PING *ping) 340void kill_ping(PING *ping)
341{ 341{
342 networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_REQUEST, NULL, NULL); 342 networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, NULL, NULL);
343 networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_RESPONSE, NULL, NULL); 343 networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, NULL, NULL);
344 344
345 free(ping); 345 free(ping);
346} 346}
diff --git a/toxcore/ping.h b/toxcore/ping.h
index 00e1c697..a0008f3c 100644
--- a/toxcore/ping.h
+++ b/toxcore/ping.h
@@ -39,7 +39,7 @@ typedef struct PING PING;
39int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port); 39int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port);
40void do_toping(PING *ping); 40void do_toping(PING *ping);
41 41
42PING *new_ping(DHT *dht, Net_Crypto *c); 42PING *new_ping(DHT *dht);
43void kill_ping(PING *ping); 43void kill_ping(PING *ping);
44 44
45int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id); 45int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id);
diff --git a/toxcore/util.c b/toxcore/util.c
index 9af7262f..d56c446e 100644
--- a/toxcore/util.c
+++ b/toxcore/util.c
@@ -65,6 +65,25 @@ uint32_t id_copy(uint8_t *dest, uint8_t *src)
65 return CLIENT_ID_SIZE; 65 return CLIENT_ID_SIZE;
66} 66}
67 67
68void host_to_net(uint8_t *num, uint16_t numbytes)
69{
70 union {
71 uint32_t i;
72 uint8_t c[4];
73 } a;
74 a.i = 1;
75
76 if (a.c[0] == 1) {
77 uint32_t i;
78 uint8_t buff[numbytes];
79
80 for (i = 0; i < numbytes; ++i) {
81 buff[i] = num[numbytes - i - 1];
82 }
83
84 memcpy(num, buff, numbytes);
85 }
86}
68 87
69/* state load/save */ 88/* state load/save */
70int load_state(load_state_callback_func load_state_callback, void *outer, 89int load_state(load_state_callback_func load_state_callback, void *outer,
diff --git a/toxcore/util.h b/toxcore/util.h
index f05a9821..ae364d52 100644
--- a/toxcore/util.h
+++ b/toxcore/util.h
@@ -37,6 +37,8 @@ int is_timeout(uint64_t timestamp, uint64_t timeout);
37bool id_equal(uint8_t *dest, uint8_t *src); 37bool id_equal(uint8_t *dest, uint8_t *src);
38uint32_t id_copy(uint8_t *dest, uint8_t *src); /* return value is CLIENT_ID_SIZE */ 38uint32_t id_copy(uint8_t *dest, uint8_t *src); /* return value is CLIENT_ID_SIZE */
39 39
40void host_to_net(uint8_t *num, uint16_t numbytes);
41#define net_to_host(x, y) host_to_net(x, y)
40 42
41/* state load/save */ 43/* state load/save */
42typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type); 44typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type);