summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/DHT.c498
-rw-r--r--core/DHT.h93
-rw-r--r--core/LAN_discovery.c13
-rw-r--r--core/LAN_discovery.h4
-rw-r--r--core/Messenger.c56
-rw-r--r--core/Messenger.h2
-rw-r--r--core/friend_requests.c77
-rw-r--r--core/friend_requests.h25
-rw-r--r--core/net_crypto.c33
-rw-r--r--core/net_crypto.h36
-rw-r--r--core/network.c1
-rw-r--r--core/network.h1
-rw-r--r--core/ping.c31
-rw-r--r--testing/toxic/dhtstatus.c2
-rw-r--r--testing/toxic/main.c14
-rw-r--r--testing/toxic/prompt.c2
16 files changed, 461 insertions, 427 deletions
diff --git a/core/DHT.c b/core/DHT.c
index b2aa44f8..d58c6d2c 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -27,17 +27,6 @@
27#include "packets.h" 27#include "packets.h"
28#include "ping.h" 28#include "ping.h"
29 29
30/* maximum number of clients stored per friend. */
31#define MAX_FRIEND_CLIENTS 8
32
33/* A list of the clients mathematically closest to ours. */
34#define LCLIENT_LIST 32
35
36/* The list of ip ports along with the ping_id of what we sent them and a timestamp */
37#define LPING_ARRAY 256
38
39#define LSEND_NODES_ARRAY LPING_ARRAY/2
40
41/* the number of seconds for a non responsive node to become bad. */ 30/* the number of seconds for a non responsive node to become bad. */
42#define BAD_NODE_TIMEOUT 70 31#define BAD_NODE_TIMEOUT 70
43 32
@@ -61,59 +50,13 @@
61/*Interval in seconds between punching attempts*/ 50/*Interval in seconds between punching attempts*/
62#define PUNCH_INTERVAL 10 51#define PUNCH_INTERVAL 10
63 52
64/*Maximum newly announced nodes to ping per TIME_TOPING seconds*/ 53/*Ping newly announced nodes to ping per TIME_TOPING seconds*/
65#define MAX_TOPING 16
66
67#define TIME_TOPING 5 54#define TIME_TOPING 5
68/*----------------------------------------------------------------------------------*/
69
70typedef struct {
71 uint8_t client_id[CLIENT_ID_SIZE];
72 Client_data client_list[MAX_FRIEND_CLIENTS];
73
74 /* time at which the last get_nodes request was sent. */
75 uint64_t lastgetnode;
76
77 /* Symetric NAT hole punching stuff */
78
79 /* 1 if currently hole punching, otherwise 0 */
80 uint8_t hole_punching;
81 uint32_t punching_index;
82 uint64_t punching_timestamp;
83 uint64_t recvNATping_timestamp;
84 uint64_t NATping_id;
85 uint64_t NATping_timestamp;
86} Friend;
87
88typedef struct {
89 uint8_t client_id[CLIENT_ID_SIZE];
90 IP_Port ip_port;
91} Node_format;
92 55
93typedef struct {
94 IP_Port ip_port;
95 uint64_t ping_id;
96 uint64_t timestamp;
97} Pinged;
98 56
99/*----------------------------------------------------------------------------------*/ 57Client_data *DHT_get_close_list(DHT * dht)
100
101/* Our client id/public key */
102uint8_t self_public_key[CLIENT_ID_SIZE];
103uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
104static Client_data close_clientlist[LCLIENT_LIST];
105static Friend *friends_list;
106static uint16_t num_friends;
107static Pinged send_nodes[LSEND_NODES_ARRAY];
108static Node_format toping[MAX_TOPING];
109static uint64_t last_toping;
110
111/*----------------------------------------------------------------------------------*/
112
113
114Client_data *DHT_get_close_list(void)
115{ 58{
116 return close_clientlist; 59 return dht->close_clientlist;
117} 60}
118 61
119/* Compares client_id1 and client_id2 with client_id 62/* Compares client_id1 and client_id2 with client_id
@@ -203,12 +146,12 @@ static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *clien
203 146
204/* Returns the friend number from the client_id, or -1 if a failure occurs 147/* Returns the friend number from the client_id, or -1 if a failure occurs
205 */ 148 */
206static int friend_number(uint8_t *client_id) 149static int friend_number(DHT * dht, uint8_t *client_id)
207{ 150{
208 uint32_t i; 151 uint32_t i;
209 152
210 for (i = 0; i < num_friends; ++i) { 153 for (i = 0; i < dht->num_friends; ++i) {
211 if (id_equal(friends_list[i].client_id, client_id)) 154 if (id_equal(dht->friends_list[i].client_id, client_id))
212 return i; 155 return i;
213 } 156 }
214 157
@@ -220,15 +163,15 @@ static int friend_number(uint8_t *client_id)
220 * 163 *
221 * TODO: For the love of based Allah make this function cleaner and much more efficient. 164 * TODO: For the love of based Allah make this function cleaner and much more efficient.
222 */ 165 */
223static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) 166static int get_close_nodes(DHT * dht, uint8_t *client_id, Node_format *nodes_list)
224{ 167{
225 uint32_t i, j, k; 168 uint32_t i, j, k;
226 uint64_t temp_time = unix_time(); 169 uint64_t temp_time = unix_time();
227 int num_nodes = 0, closest, tout, inlist; 170 int num_nodes = 0, closest, tout, inlist;
228 171
229 for (i = 0; i < LCLIENT_LIST; ++i) { 172 for (i = 0; i < LCLIENT_LIST; ++i) {
230 tout = is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); 173 tout = is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT);
231 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id); 174 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, dht->close_clientlist[i].client_id);
232 175
233 /* if node isn't good or is already in list. */ 176 /* if node isn't good or is already in list. */
234 if (tout || inlist) 177 if (tout || inlist)
@@ -237,10 +180,10 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list)
237 if (num_nodes < MAX_SENT_NODES) { 180 if (num_nodes < MAX_SENT_NODES) {
238 181
239 memcpy( nodes_list[num_nodes].client_id, 182 memcpy( nodes_list[num_nodes].client_id,
240 close_clientlist[i].client_id, 183 dht->close_clientlist[i].client_id,
241 CLIENT_ID_SIZE ); 184 CLIENT_ID_SIZE );
242 185
243 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 186 nodes_list[num_nodes].ip_port = dht->close_clientlist[i].ip_port;
244 num_nodes++; 187 num_nodes++;
245 188
246 } else { 189 } else {
@@ -248,27 +191,27 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list)
248 for (j = 0; j < MAX_SENT_NODES; ++j) { 191 for (j = 0; j < MAX_SENT_NODES; ++j) {
249 closest = id_closest( client_id, 192 closest = id_closest( client_id,
250 nodes_list[j].client_id, 193 nodes_list[j].client_id,
251 close_clientlist[i].client_id ); 194 dht->close_clientlist[i].client_id );
252 195
253 if (closest == 2) { 196 if (closest == 2) {
254 memcpy( nodes_list[j].client_id, 197 memcpy( nodes_list[j].client_id,
255 close_clientlist[i].client_id, 198 dht->close_clientlist[i].client_id,
256 CLIENT_ID_SIZE); 199 CLIENT_ID_SIZE);
257 200
258 nodes_list[j].ip_port = close_clientlist[i].ip_port; 201 nodes_list[j].ip_port = dht->close_clientlist[i].ip_port;
259 break; 202 break;
260 } 203 }
261 } 204 }
262 } 205 }
263 } 206 }
264 207
265 for (i = 0; i < num_friends; ++i) { 208 for (i = 0; i < dht->num_friends; ++i) {
266 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 209 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
267 210
268 tout = is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT); 211 tout = is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT);
269 inlist = client_in_nodelist( nodes_list, 212 inlist = client_in_nodelist( nodes_list,
270 MAX_SENT_NODES, 213 MAX_SENT_NODES,
271 friends_list[i].client_list[j].client_id); 214 dht->friends_list[i].client_list[j].client_id);
272 215
273 /* if node isn't good or is already in list. */ 216 /* if node isn't good or is already in list. */
274 if (tout || inlist) 217 if (tout || inlist)
@@ -277,24 +220,24 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list)
277 if (num_nodes < MAX_SENT_NODES) { 220 if (num_nodes < MAX_SENT_NODES) {
278 221
279 memcpy( nodes_list[num_nodes].client_id, 222 memcpy( nodes_list[num_nodes].client_id,
280 friends_list[i].client_list[j].client_id, 223 dht->friends_list[i].client_list[j].client_id,
281 CLIENT_ID_SIZE); 224 CLIENT_ID_SIZE);
282 225
283 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; 226 nodes_list[num_nodes].ip_port = dht->friends_list[i].client_list[j].ip_port;
284 num_nodes++; 227 num_nodes++;
285 } else { 228 } else {
286 for (k = 0; k < MAX_SENT_NODES; ++k) { 229 for (k = 0; k < MAX_SENT_NODES; ++k) {
287 230
288 closest = id_closest( client_id, 231 closest = id_closest( client_id,
289 nodes_list[k].client_id, 232 nodes_list[k].client_id,
290 friends_list[i].client_list[j].client_id ); 233 dht->friends_list[i].client_list[j].client_id );
291 234
292 if (closest == 2) { 235 if (closest == 2) {
293 memcpy( nodes_list[k].client_id, 236 memcpy( nodes_list[k].client_id,
294 friends_list[i].client_list[j].client_id, 237 dht->friends_list[i].client_list[j].client_id,
295 CLIENT_ID_SIZE ); 238 CLIENT_ID_SIZE );
296 239
297 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; 240 nodes_list[k].ip_port = dht->friends_list[i].client_list[j].ip_port;
298 break; 241 break;
299 } 242 }
300 } 243 }
@@ -387,40 +330,40 @@ static int replace_good( Client_data *list,
387/* Attempt to add client with ip_port and client_id to the friends client list 330/* Attempt to add client with ip_port and client_id to the friends client list
388 * and close_clientlist 331 * and close_clientlist
389 */ 332 */
390void addto_lists(IP_Port ip_port, uint8_t *client_id) 333void addto_lists(DHT * dht, IP_Port ip_port, uint8_t *client_id)
391{ 334{
392 uint32_t i; 335 uint32_t i;
393 336
394 /* NOTE: current behavior if there are two clients with the same id is 337 /* NOTE: current behavior if there are two clients with the same id is
395 * to replace the first ip by the second. 338 * to replace the first ip by the second.
396 */ 339 */
397 if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 340 if (!client_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
398 if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 341 if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
399 /* if we can't replace bad nodes we try replacing good ones */ 342 /* if we can't replace bad nodes we try replacing good ones */
400 replace_good( close_clientlist, 343 replace_good( dht->close_clientlist,
401 LCLIENT_LIST, 344 LCLIENT_LIST,
402 client_id, 345 client_id,
403 ip_port, 346 ip_port,
404 self_public_key ); 347 dht->c->self_public_key );
405 } 348 }
406 } 349 }
407 350
408 for (i = 0; i < num_friends; ++i) { 351 for (i = 0; i < dht->num_friends; ++i) {
409 if (!client_in_list( friends_list[i].client_list, 352 if (!client_in_list( dht->friends_list[i].client_list,
410 MAX_FRIEND_CLIENTS, 353 MAX_FRIEND_CLIENTS,
411 client_id, 354 client_id,
412 ip_port )) { 355 ip_port )) {
413 356
414 if (replace_bad( friends_list[i].client_list, 357 if (replace_bad( dht->friends_list[i].client_list,
415 MAX_FRIEND_CLIENTS, 358 MAX_FRIEND_CLIENTS,
416 client_id, 359 client_id,
417 ip_port )) { 360 ip_port )) {
418 /* if we can't replace bad nodes we try replacing good ones. */ 361 /* if we can't replace bad nodes we try replacing good ones. */
419 replace_good( friends_list[i].client_list, 362 replace_good( dht->friends_list[i].client_list,
420 MAX_FRIEND_CLIENTS, 363 MAX_FRIEND_CLIENTS,
421 client_id, 364 client_id,
422 ip_port, 365 ip_port,
423 friends_list[i].client_id ); 366 dht->friends_list[i].client_id );
424 } 367 }
425 } 368 }
426 } 369 }
@@ -429,30 +372,30 @@ void addto_lists(IP_Port ip_port, uint8_t *client_id)
429/* If client_id is a friend or us, update ret_ip_port 372/* If client_id is a friend or us, update ret_ip_port
430 * nodeclient_id is the id of the node that sent us this info 373 * nodeclient_id is the id of the node that sent us this info
431 */ 374 */
432static void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) 375static void returnedip_ports(DHT * dht, IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id)
433{ 376{
434 uint32_t i, j; 377 uint32_t i, j;
435 uint64_t temp_time = unix_time(); 378 uint64_t temp_time = unix_time();
436 379
437 if (id_equal(client_id, self_public_key)) { 380 if (id_equal(client_id, dht->c->self_public_key)) {
438 381
439 for (i = 0; i < LCLIENT_LIST; ++i) { 382 for (i = 0; i < LCLIENT_LIST; ++i) {
440 if (id_equal(nodeclient_id, close_clientlist[i].client_id)) { 383 if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) {
441 close_clientlist[i].ret_ip_port = ip_port; 384 dht->close_clientlist[i].ret_ip_port = ip_port;
442 close_clientlist[i].ret_timestamp = temp_time; 385 dht->close_clientlist[i].ret_timestamp = temp_time;
443 return; 386 return;
444 } 387 }
445 } 388 }
446 389
447 } else { 390 } else {
448 391
449 for (i = 0; i < num_friends; ++i) { 392 for (i = 0; i < dht->num_friends; ++i) {
450 if (id_equal(client_id, friends_list[i].client_id)) { 393 if (id_equal(client_id, dht->friends_list[i].client_id)) {
451 394
452 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 395 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
453 if (id_equal(nodeclient_id, friends_list[i].client_list[j].client_id)) { 396 if (id_equal(nodeclient_id, dht->friends_list[i].client_list[j].client_id)) {
454 friends_list[i].client_list[j].ret_ip_port = ip_port; 397 dht->friends_list[i].client_list[j].ret_ip_port = ip_port;
455 friends_list[i].client_list[j].ret_timestamp = temp_time; 398 dht->friends_list[i].client_list[j].ret_timestamp = temp_time;
456 return; 399 return;
457 } 400 }
458 } 401 }
@@ -463,20 +406,20 @@ static void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodec
463} 406}
464 407
465/* Same as last function but for get_node requests. */ 408/* Same as last function but for get_node requests. */
466static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) 409static int is_gettingnodes(DHT * dht, IP_Port ip_port, uint64_t ping_id)
467{ 410{
468 uint32_t i; 411 uint32_t i;
469 uint8_t pinging; 412 uint8_t pinging;
470 uint64_t temp_time = unix_time(); 413 uint64_t temp_time = unix_time();
471 414
472 for (i = 0; i < LSEND_NODES_ARRAY; ++i ) { 415 for (i = 0; i < LSEND_NODES_ARRAY; ++i ) {
473 if (!is_timeout(temp_time, send_nodes[i].timestamp, PING_TIMEOUT)) { 416 if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) {
474 pinging = 0; 417 pinging = 0;
475 418
476 if (ip_port.ip.i != 0 && ipport_equal(send_nodes[i].ip_port, ip_port)) 419 if (ip_port.ip.i != 0 && ipport_equal(dht->send_nodes[i].ip_port, ip_port))
477 ++pinging; 420 ++pinging;
478 421
479 if (ping_id != 0 && send_nodes[i].ping_id == ping_id) 422 if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id)
480 ++pinging; 423 ++pinging;
481 424
482 if (pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 425 if (pinging == (ping_id != 0) + (ip_port.ip.i != 0))
@@ -488,7 +431,7 @@ static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
488} 431}
489 432
490/* Same but for get node requests */ 433/* Same but for get node requests */
491static uint64_t add_gettingnodes(IP_Port ip_port) 434static uint64_t add_gettingnodes(DHT * dht, IP_Port ip_port)
492{ 435{
493 uint32_t i, j; 436 uint32_t i, j;
494 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 437 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
@@ -496,10 +439,10 @@ static uint64_t add_gettingnodes(IP_Port ip_port)
496 439
497 for (i = 0; i < PING_TIMEOUT; ++i ) { 440 for (i = 0; i < PING_TIMEOUT; ++i ) {
498 for (j = 0; j < LSEND_NODES_ARRAY; ++j ) { 441 for (j = 0; j < LSEND_NODES_ARRAY; ++j ) {
499 if (is_timeout(temp_time, send_nodes[j].timestamp, PING_TIMEOUT - i)) { 442 if (is_timeout(temp_time, dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) {
500 send_nodes[j].timestamp = temp_time; 443 dht->send_nodes[j].timestamp = temp_time;
501 send_nodes[j].ip_port = ip_port; 444 dht->send_nodes[j].ip_port = ip_port;
502 send_nodes[j].ping_id = ping_id; 445 dht->send_nodes[j].ping_id = ping_id;
503 return ping_id; 446 return ping_id;
504 } 447 }
505 } 448 }
@@ -509,13 +452,13 @@ static uint64_t add_gettingnodes(IP_Port ip_port)
509} 452}
510 453
511/* send a getnodes request */ 454/* send a getnodes request */
512static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) 455static int getnodes(DHT * dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id)
513{ 456{
514 /* check if packet is gonna be sent to ourself */ 457 /* check if packet is gonna be sent to ourself */
515 if (id_equal(public_key, self_public_key) || is_gettingnodes(ip_port, 0)) 458 if (id_equal(public_key, dht->c->self_public_key) || is_gettingnodes(dht, ip_port, 0))
516 return 1; 459 return 1;
517 460
518 uint64_t ping_id = add_gettingnodes(ip_port); 461 uint64_t ping_id = add_gettingnodes(dht, ip_port);
519 462
520 if (ping_id == 0) 463 if (ping_id == 0)
521 return 1; 464 return 1;
@@ -530,7 +473,7 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id)
530 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); 473 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE);
531 474
532 int len = encrypt_data( public_key, 475 int len = encrypt_data( public_key,
533 self_secret_key, 476 dht->c->self_secret_key,
534 nonce, 477 nonce,
535 plain, 478 plain,
536 sizeof(ping_id) + CLIENT_ID_SIZE, 479 sizeof(ping_id) + CLIENT_ID_SIZE,
@@ -540,25 +483,25 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id)
540 return -1; 483 return -1;
541 484
542 data[0] = 2; 485 data[0] = 2;
543 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); 486 memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE);
544 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 487 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
545 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 488 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
546 489
547 return sendpacket(temp_net->sock, ip_port, data, sizeof(data)); 490 return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, sizeof(data));
548} 491}
549 492
550/* send a send nodes response */ 493/* send a send nodes response */
551static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) 494static int sendnodes(DHT * dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id)
552{ 495{
553 /* check if packet is gonna be sent to ourself */ 496 /* check if packet is gonna be sent to ourself */
554 if (id_equal(public_key, self_public_key)) 497 if (id_equal(public_key, dht->c->self_public_key))
555 return 1; 498 return 1;
556 499
557 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 500 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
558 + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; 501 + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
559 502
560 Node_format nodes_list[MAX_SENT_NODES]; 503 Node_format nodes_list[MAX_SENT_NODES];
561 int num_nodes = get_close_nodes(client_id, nodes_list); 504 int num_nodes = get_close_nodes(dht, client_id, nodes_list);
562 505
563 if (num_nodes == 0) 506 if (num_nodes == 0)
564 return 0; 507 return 0;
@@ -572,7 +515,7 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u
572 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); 515 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));
573 516
574 int len = encrypt_data( public_key, 517 int len = encrypt_data( public_key,
575 self_secret_key, 518 dht->c->self_secret_key,
576 nonce, 519 nonce,
577 plain, 520 plain,
578 sizeof(ping_id) + num_nodes * sizeof(Node_format), 521 sizeof(ping_id) + num_nodes * sizeof(Node_format),
@@ -582,15 +525,16 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u
582 return -1; 525 return -1;
583 526
584 data[0] = 3; 527 data[0] = 3;
585 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); 528 memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE);
586 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 529 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
587 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 530 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
588 531
589 return sendpacket(temp_net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 532 return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
590} 533}
591 534
592static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) 535static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length)
593{ 536{
537 DHT * dht = object;
594 uint64_t ping_id; 538 uint64_t ping_id;
595 539
596 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES 540 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
@@ -598,13 +542,13 @@ static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint3
598 return 1; 542 return 1;
599 543
600 /* check if packet is from ourself. */ 544 /* check if packet is from ourself. */
601 if (id_equal(packet + 1, self_public_key)) 545 if (id_equal(packet + 1, dht->c->self_public_key))
602 return 1; 546 return 1;
603 547
604 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 548 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
605 549
606 int len = decrypt_data( packet + 1, 550 int len = decrypt_data( packet + 1,
607 self_secret_key, 551 dht->c->self_secret_key,
608 packet + 1 + CLIENT_ID_SIZE, 552 packet + 1 + CLIENT_ID_SIZE,
609 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 553 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
610 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, 554 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING,
@@ -614,15 +558,16 @@ static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint3
614 return 1; 558 return 1;
615 559
616 memcpy(&ping_id, plain, sizeof(ping_id)); 560 memcpy(&ping_id, plain, sizeof(ping_id));
617 sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); 561 sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id);
618 562
619 //send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ 563 //send_ping_request(dht, source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */
620 564
621 return 0; 565 return 0;
622} 566}
623 567
624static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) 568static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length)
625{ 569{
570 DHT * dht = object;
626 uint64_t ping_id; 571 uint64_t ping_id;
627 uint32_t cid_size = 1 + CLIENT_ID_SIZE; 572 uint32_t cid_size = 1 + CLIENT_ID_SIZE;
628 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; 573 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
@@ -637,7 +582,7 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint
637 582
638 int len = decrypt_data( 583 int len = decrypt_data(
639 packet + 1, 584 packet + 1,
640 self_secret_key, 585 dht->c->self_secret_key,
641 packet + 1 + CLIENT_ID_SIZE, 586 packet + 1 + CLIENT_ID_SIZE,
642 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 587 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
643 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); 588 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain );
@@ -647,19 +592,19 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint
647 592
648 memcpy(&ping_id, plain, sizeof(ping_id)); 593 memcpy(&ping_id, plain, sizeof(ping_id));
649 594
650 if (!is_gettingnodes(source, ping_id)) 595 if (!is_gettingnodes(dht, source, ping_id))
651 return 1; 596 return 1;
652 597
653 Node_format nodes_list[MAX_SENT_NODES]; 598 Node_format nodes_list[MAX_SENT_NODES];
654 memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); 599 memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format));
655 600
656 addto_lists(source, packet + 1); 601 addto_lists(dht, source, packet + 1);
657 602
658 uint32_t i; 603 uint32_t i;
659 604
660 for (i = 0; i < num_nodes; ++i) { 605 for (i = 0; i < num_nodes; ++i) {
661 send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id); 606 send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id);
662 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 607 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
663 } 608 }
664 609
665 return 0; 610 return 0;
@@ -668,54 +613,54 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint
668/*----------------------------------------------------------------------------------*/ 613/*----------------------------------------------------------------------------------*/
669/*------------------------END of packet handling functions--------------------------*/ 614/*------------------------END of packet handling functions--------------------------*/
670 615
671int DHT_addfriend(uint8_t *client_id) 616int DHT_addfriend(DHT * dht, uint8_t *client_id)
672{ 617{
673 if (friend_number(client_id) != -1) /*Is friend already in DHT?*/ 618 if (friend_number(dht, client_id) != -1) /*Is friend already in DHT?*/
674 return 1; 619 return 1;
675 620
676 Friend *temp; 621 DHT_Friend *temp;
677 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); 622 temp = realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends + 1));
678 623
679 if (temp == NULL) 624 if (temp == NULL)
680 return 1; 625 return 1;
681 626
682 friends_list = temp; 627 dht->friends_list = temp;
683 memset(&friends_list[num_friends], 0, sizeof(Friend)); 628 memset(&dht->friends_list[dht->num_friends], 0, sizeof(DHT_Friend));
684 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); 629 memcpy(dht->friends_list[dht->num_friends].client_id, client_id, CLIENT_ID_SIZE);
685 630
686 friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); 631 dht->friends_list[dht->num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int();
687 ++num_friends; 632 ++dht->num_friends;
688 return 0; 633 return 0;
689} 634}
690 635
691int DHT_delfriend(uint8_t *client_id) 636int DHT_delfriend(DHT * dht, uint8_t *client_id)
692{ 637{
693 uint32_t i; 638 uint32_t i;
694 Friend *temp; 639 DHT_Friend *temp;
695 640
696 for (i = 0; i < num_friends; ++i) { 641 for (i = 0; i < dht->num_friends; ++i) {
697 /* Equal */ 642 /* Equal */
698 if (id_equal(friends_list[i].client_id, client_id)) { 643 if (id_equal(dht->friends_list[i].client_id, client_id)) {
699 --num_friends; 644 --dht->num_friends;
700 645
701 if (num_friends != i) { 646 if (dht->num_friends != i) {
702 memcpy( friends_list[i].client_id, 647 memcpy( dht->friends_list[i].client_id,
703 friends_list[num_friends].client_id, 648 dht->friends_list[dht->num_friends].client_id,
704 CLIENT_ID_SIZE ); 649 CLIENT_ID_SIZE );
705 } 650 }
706 651
707 if (num_friends == 0) { 652 if (dht->num_friends == 0) {
708 free(friends_list); 653 free(dht->friends_list);
709 friends_list = NULL; 654 dht->friends_list = NULL;
710 return 0; 655 return 0;
711 } 656 }
712 657
713 temp = realloc(friends_list, sizeof(Friend) * (num_friends)); 658 temp = realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends));
714 659
715 if (temp == NULL) 660 if (temp == NULL)
716 return 1; 661 return 1;
717 662
718 friends_list = temp; 663 dht->friends_list = temp;
719 return 0; 664 return 0;
720 } 665 }
721 } 666 }
@@ -724,19 +669,19 @@ int DHT_delfriend(uint8_t *client_id)
724} 669}
725 670
726/* TODO: Optimize this. */ 671/* TODO: Optimize this. */
727IP_Port DHT_getfriendip(uint8_t *client_id) 672IP_Port DHT_getfriendip(DHT * dht, uint8_t *client_id)
728{ 673{
729 uint32_t i, j; 674 uint32_t i, j;
730 uint64_t temp_time = unix_time(); 675 uint64_t temp_time = unix_time();
731 IP_Port empty = {{{0}}, 0}; 676 IP_Port empty = {{{0}}, 0};
732 677
733 for (i = 0; i < num_friends; ++i) { 678 for (i = 0; i < dht->num_friends; ++i) {
734 /* Equal */ 679 /* Equal */
735 if (id_equal(friends_list[i].client_id, client_id)) { 680 if (id_equal(dht->friends_list[i].client_id, client_id)) {
736 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 681 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
737 if (id_equal(friends_list[i].client_list[j].client_id, client_id) 682 if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id)
738 && !is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) 683 && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT))
739 return friends_list[i].client_list[j].ip_port; 684 return dht->friends_list[i].client_list[j].ip_port;
740 } 685 }
741 686
742 return empty; 687 return empty;
@@ -750,49 +695,47 @@ IP_Port DHT_getfriendip(uint8_t *client_id)
750/* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request 695/* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request
751 * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list. 696 * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list.
752 */ 697 */
753static void doDHTFriends(void) 698static void do_DHT_friends(DHT * dht)
754{ 699{
755 uint32_t i, j; 700 uint32_t i, j;
756 uint64_t temp_time = unix_time(); 701 uint64_t temp_time = unix_time();
757 uint32_t rand_node; 702 uint32_t rand_node;
758 uint32_t index[MAX_FRIEND_CLIENTS]; 703 uint32_t index[MAX_FRIEND_CLIENTS];
759 704
760 for (i = 0; i < num_friends; ++i) { 705 for (i = 0; i < dht->num_friends; ++i) {
761 uint32_t num_nodes = 0; 706 uint32_t num_nodes = 0;
762 707
763 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 708 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
764 /* if node is not dead. */ 709 /* if node is not dead. */
765 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { 710 if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) {
766 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 711 if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
767 send_ping_request( friends_list[i].client_list[j].ip_port, 712 send_ping_request( dht->friends_list[i].client_list[j].ip_port,
768 (clientid_t *) &friends_list[i].client_list[j].client_id ); 713 (clientid_t *) &dht->friends_list[i].client_list[j].client_id );
769 friends_list[i].client_list[j].last_pinged = temp_time; 714 dht->friends_list[i].client_list[j].last_pinged = temp_time;
770 } 715 }
771 716
772 /* if node is good. */ 717 /* if node is good. */
773 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { 718 if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) {
774 index[num_nodes] = j; 719 index[num_nodes] = j;
775 ++num_nodes; 720 ++num_nodes;
776 } 721 }
777 } 722 }
778 } 723 }
779 724
780 if (friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 725 if (dht->friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
781 rand_node = rand() % num_nodes; 726 rand_node = rand() % num_nodes;
782 getnodes( friends_list[i].client_list[index[rand_node]].ip_port, 727 getnodes(dht, dht->friends_list[i].client_list[index[rand_node]].ip_port,
783 friends_list[i].client_list[index[rand_node]].client_id, 728 dht->friends_list[i].client_list[index[rand_node]].client_id,
784 friends_list[i].client_id ); 729 dht->friends_list[i].client_id );
785 friends_list[i].lastgetnode = temp_time; 730 dht->friends_list[i].lastgetnode = temp_time;
786 } 731 }
787 } 732 }
788} 733}
789 734
790static uint64_t close_lastgetnodes;
791
792/* Ping each client in the close nodes list every PING_INTERVAL seconds. 735/* Ping each client in the close nodes list every PING_INTERVAL seconds.
793 * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list. 736 * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list.
794 */ 737 */
795static void doClose(void) 738static void do_Close(DHT * dht)
796{ 739{
797 uint32_t i; 740 uint32_t i;
798 uint64_t temp_time = unix_time(); 741 uint64_t temp_time = unix_time();
@@ -802,46 +745,47 @@ static void doClose(void)
802 745
803 for (i = 0; i < LCLIENT_LIST; ++i) { 746 for (i = 0; i < LCLIENT_LIST; ++i) {
804 /* if node is not dead. */ 747 /* if node is not dead. */
805 if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { 748 if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) {
806 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { 749 if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
807 send_ping_request( close_clientlist[i].ip_port, 750 send_ping_request( dht->close_clientlist[i].ip_port,
808 (clientid_t *) &close_clientlist[i].client_id ); 751 (clientid_t *) &dht->close_clientlist[i].client_id );
809 close_clientlist[i].last_pinged = temp_time; 752 dht->close_clientlist[i].last_pinged = temp_time;
810 } 753 }
811 754
812 /* if node is good. */ 755 /* if node is good. */
813 if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { 756 if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) {
814 index[num_nodes] = i; 757 index[num_nodes] = i;
815 ++num_nodes; 758 ++num_nodes;
816 } 759 }
817 } 760 }
818 } 761 }
819 762
820 if (close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 763 if (dht->close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
821 rand_node = rand() % num_nodes; 764 rand_node = rand() % num_nodes;
822 getnodes( close_clientlist[index[rand_node]].ip_port, 765 getnodes(dht, dht->close_clientlist[index[rand_node]].ip_port,
823 close_clientlist[index[rand_node]].client_id, 766 dht->close_clientlist[index[rand_node]].client_id,
824 self_public_key ); 767 dht->c->self_public_key );
825 close_lastgetnodes = temp_time; 768 dht->close_lastgetnodes = temp_time;
826 } 769 }
827} 770}
828 771
829void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key) 772void DHT_bootstrap(DHT * dht, IP_Port ip_port, uint8_t *public_key)
830{ 773{
831 getnodes(ip_port, public_key, self_public_key); 774 getnodes(dht, ip_port, public_key, dht->c->self_public_key);
775 //send_ping_request(dht, ip_port, (clientid_t *) public_key);
832 send_ping_request(ip_port, (clientid_t *) public_key); 776 send_ping_request(ip_port, (clientid_t *) public_key);
833} 777}
834 778
835/* send the given packet to node with client_id 779/* send the given packet to node with client_id
836 * returns -1 if failure 780 * returns -1 if failure
837 */ 781 */
838int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length) 782int route_packet(DHT * dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
839{ 783{
840 uint32_t i; 784 uint32_t i;
841 785
842 for (i = 0; i < LCLIENT_LIST; ++i) { 786 for (i = 0; i < LCLIENT_LIST; ++i) {
843 if (id_equal(client_id, close_clientlist[i].client_id)) 787 if (id_equal(client_id, dht->close_clientlist[i].client_id))
844 return sendpacket(temp_net->sock, close_clientlist[i].ip_port, packet, length); 788 return sendpacket(dht->c->lossless_udp->net->sock, dht->close_clientlist[i].ip_port, packet, length);
845 } 789 }
846 790
847 return -1; 791 return -1;
@@ -853,16 +797,16 @@ int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length)
853 * return 0 if we are connected to friend or if no ips were found. 797 * return 0 if we are connected to friend or if no ips were found.
854 * returns -1 if no such friend 798 * returns -1 if no such friend
855 */ 799 */
856static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num) 800static int friend_iplist(DHT * dht, IP_Port *ip_portlist, uint16_t friend_num)
857{ 801{
858 int num_ips = 0; 802 int num_ips = 0;
859 uint32_t i; 803 uint32_t i;
860 uint64_t temp_time = unix_time(); 804 uint64_t temp_time = unix_time();
861 805
862 if (friend_num >= num_friends) 806 if (friend_num >= dht->num_friends)
863 return -1; 807 return -1;
864 808
865 Friend *friend = &friends_list[friend_num]; 809 DHT_Friend *friend = &dht->friends_list[friend_num];
866 Client_data *client; 810 Client_data *client;
867 811
868 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 812 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
@@ -888,9 +832,9 @@ static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num)
888 * 832 *
889 * Only works if more than (MAX_FRIEND_CLIENTS / 2) return an ip for friend. 833 * Only works if more than (MAX_FRIEND_CLIENTS / 2) return an ip for friend.
890 */ 834 */
891int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) 835int route_tofriend(DHT * dht, uint8_t *friend_id, uint8_t *packet, uint32_t length)
892{ 836{
893 int num = friend_number(friend_id); 837 int num = friend_number(dht, friend_id);
894 838
895 if (num == -1) 839 if (num == -1)
896 return 0; 840 return 0;
@@ -898,13 +842,13 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length)
898 uint32_t i, sent = 0; 842 uint32_t i, sent = 0;
899 843
900 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 844 IP_Port ip_list[MAX_FRIEND_CLIENTS];
901 int ip_num = friend_iplist(ip_list, num); 845 int ip_num = friend_iplist(dht, ip_list, num);
902 846
903 if (ip_num < (MAX_FRIEND_CLIENTS / 2)) 847 if (ip_num < (MAX_FRIEND_CLIENTS / 2))
904 return 0; 848 return 0;
905 849
906 uint64_t temp_time = unix_time(); 850 uint64_t temp_time = unix_time();
907 Friend *friend = &friends_list[num]; 851 DHT_Friend *friend = &dht->friends_list[num];
908 Client_data *client; 852 Client_data *client;
909 853
910 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 854 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
@@ -912,7 +856,7 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length)
912 856
913 /*If ip is not zero and node is good */ 857 /*If ip is not zero and node is good */
914 if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { 858 if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
915 if (sendpacket(temp_net->sock, client->ip_port, packet, length) == length) 859 if (sendpacket(dht->c->lossless_udp->net->sock, client->ip_port, packet, length) == length)
916 ++sent; 860 ++sent;
917 } 861 }
918 } 862 }
@@ -923,14 +867,14 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length)
923/* Send the following packet to one random person who tells us they are connected to friend_id 867/* Send the following packet to one random person who tells us they are connected to friend_id
924* returns the number of nodes it sent the packet to 868* returns the number of nodes it sent the packet to
925*/ 869*/
926static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) 870static int routeone_tofriend(DHT * dht, uint8_t *friend_id, uint8_t *packet, uint32_t length)
927{ 871{
928 int num = friend_number(friend_id); 872 int num = friend_number(dht, friend_id);
929 873
930 if (num == -1) 874 if (num == -1)
931 return 0; 875 return 0;
932 876
933 Friend *friend = &friends_list[num]; 877 DHT_Friend *friend = &dht->friends_list[num];
934 Client_data *client; 878 Client_data *client;
935 879
936 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 880 IP_Port ip_list[MAX_FRIEND_CLIENTS];
@@ -951,7 +895,7 @@ static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t lengt
951 if (n < 1) 895 if (n < 1)
952 return 0; 896 return 0;
953 897
954 if (sendpacket(temp_net->sock, ip_list[rand() % n], packet, length) == length) 898 if (sendpacket(dht->c->lossless_udp->net->sock, ip_list[rand() % n], packet, length) == length)
955 return 1; 899 return 1;
956 900
957 return 0; 901 return 0;
@@ -963,14 +907,14 @@ static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t lengt
963 * return 0 if we are connected to friend or if no ips were found. 907 * return 0 if we are connected to friend or if no ips were found.
964 * returns -1 if no such friend 908 * returns -1 if no such friend
965 */ 909 */
966int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id) 910int friend_ips(DHT * dht, IP_Port *ip_portlist, uint8_t *friend_id)
967{ 911{
968 uint32_t i; 912 uint32_t i;
969 913
970 for (i = 0; i < num_friends; ++i) { 914 for (i = 0; i < dht->num_friends; ++i) {
971 /* Equal */ 915 /* Equal */
972 if (id_equal(friends_list[i].client_id, friend_id)) 916 if (id_equal(dht->friends_list[i].client_id, friend_id))
973 return friend_iplist(ip_portlist, i); 917 return friend_iplist(dht, ip_portlist, i);
974 } 918 }
975 919
976 return -1; 920 return -1;
@@ -979,7 +923,7 @@ int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id)
979/*----------------------------------------------------------------------------------*/ 923/*----------------------------------------------------------------------------------*/
980/*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ 924/*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/
981 925
982static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) 926static int send_NATping(DHT * dht, uint8_t *public_key, uint64_t ping_id, uint8_t type)
983{ 927{
984 uint8_t data[sizeof(uint64_t) + 1]; 928 uint8_t data[sizeof(uint64_t) + 1];
985 uint8_t packet[MAX_DATA_SIZE]; 929 uint8_t packet[MAX_DATA_SIZE];
@@ -989,15 +933,15 @@ static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type)
989 data[0] = type; 933 data[0] = type;
990 memcpy(data + 1, &ping_id, sizeof(uint64_t)); 934 memcpy(data + 1, &ping_id, sizeof(uint64_t));
991 /* 254 is NAT ping request packet id */ 935 /* 254 is NAT ping request packet id */
992 int len = create_request(self_public_key, self_secret_key, packet, public_key, data, sizeof(uint64_t) + 1, 254); 936 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, data, sizeof(uint64_t) + 1, 254);
993 937
994 if (len == -1) 938 if (len == -1)
995 return -1; 939 return -1;
996 940
997 if (type == 0) /*If packet is request use many people to route it*/ 941 if (type == 0) /*If packet is request use many people to route it*/
998 num = route_tofriend(public_key, packet, len); 942 num = route_tofriend(dht, public_key, packet, len);
999 else if (type == 1) /*If packet is response use only one person to route it*/ 943 else if (type == 1) /*If packet is response use only one person to route it*/
1000 num = routeone_tofriend(public_key, packet, len); 944 num = routeone_tofriend(dht, public_key, packet, len);
1001 945
1002 if (num == 0) 946 if (num == 0)
1003 return -1; 947 return -1;
@@ -1006,21 +950,22 @@ static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type)
1006} 950}
1007 951
1008/* Handle a received ping request for */ 952/* Handle a received ping request for */
1009static int handle_NATping(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) 953static int handle_NATping(void * object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
1010{ 954{
955 DHT * dht = object;
1011 uint64_t ping_id; 956 uint64_t ping_id;
1012 memcpy(&ping_id, packet + 1, sizeof(uint64_t)); 957 memcpy(&ping_id, packet + 1, sizeof(uint64_t));
1013 958
1014 int friendnumber = friend_number(source_pubkey); 959 int friendnumber = friend_number(dht, source_pubkey);
1015 960
1016 if (friendnumber == -1) 961 if (friendnumber == -1)
1017 return 1; 962 return 1;
1018 963
1019 Friend *friend = &friends_list[friendnumber]; 964 DHT_Friend *friend = &dht->friends_list[friendnumber];
1020 965
1021 if (packet[0] == 0) { 966 if (packet[0] == 0) {
1022 /* 1 is reply */ 967 /* 1 is reply */
1023 send_NATping(source_pubkey, ping_id, 1); 968 send_NATping(dht, source_pubkey, ping_id, 1);
1024 friend->recvNATping_timestamp = unix_time(); 969 friend->recvNATping_timestamp = unix_time();
1025 return 0; 970 return 0;
1026 } else if (packet[0] == 1) { 971 } else if (packet[0] == 1) {
@@ -1082,45 +1027,46 @@ static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t
1082 return num; 1027 return num;
1083} 1028}
1084 1029
1085static void punch_holes(IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) 1030static void punch_holes(DHT * dht, IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num)
1086{ 1031{
1087 if (numports > MAX_FRIEND_CLIENTS || numports == 0) 1032 if (numports > MAX_FRIEND_CLIENTS || numports == 0)
1088 return; 1033 return;
1089 1034
1090 uint32_t i; 1035 uint32_t i;
1091 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; 1036 uint32_t top = dht->friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS;
1092 1037
1093 for (i = friends_list[friend_num].punching_index; i != top; i++) { 1038 for (i = dht->friends_list[friend_num].punching_index; i != top; i++) {
1094 /*TODO: improve port guessing algorithm*/ 1039 /*TODO: improve port guessing algorithm*/
1095 uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); 1040 uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1);
1096 IP_Port pinging = {ip, htons(port)}; 1041 IP_Port pinging = {ip, htons(port)};
1097 send_ping_request(pinging, (clientid_t *) &friends_list[friend_num].client_id); 1042 //send_ping_request(dht, pinging, (clientid_t *) &dht->friends_list[friend_num].client_id);
1043 send_ping_request(pinging, (clientid_t *) &dht->friends_list[friend_num].client_id);
1098 } 1044 }
1099 1045
1100 friends_list[friend_num].punching_index = i; 1046 dht->friends_list[friend_num].punching_index = i;
1101} 1047}
1102 1048
1103static void doNAT(void) 1049static void do_NAT(DHT * dht)
1104{ 1050{
1105 uint32_t i; 1051 uint32_t i;
1106 uint64_t temp_time = unix_time(); 1052 uint64_t temp_time = unix_time();
1107 1053
1108 for (i = 0; i < num_friends; ++i) { 1054 for (i = 0; i < dht->num_friends; ++i) {
1109 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 1055 IP_Port ip_list[MAX_FRIEND_CLIENTS];
1110 int num = friend_iplist(ip_list, i); 1056 int num = friend_iplist(dht, ip_list, i);
1111 1057
1112 /*If already connected or friend is not online don't try to hole punch*/ 1058 /*If already connected or friend is not online don't try to hole punch*/
1113 if (num < MAX_FRIEND_CLIENTS / 2) 1059 if (num < MAX_FRIEND_CLIENTS / 2)
1114 continue; 1060 continue;
1115 1061
1116 if (friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { 1062 if (dht->friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) {
1117 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ 1063 send_NATping(dht, dht->friends_list[i].client_id, dht->friends_list[i].NATping_id, 0); /*0 is request*/
1118 friends_list[i].NATping_timestamp = temp_time; 1064 dht->friends_list[i].NATping_timestamp = temp_time;
1119 } 1065 }
1120 1066
1121 if (friends_list[i].hole_punching == 1 && 1067 if (dht->friends_list[i].hole_punching == 1 &&
1122 friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && 1068 dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time &&
1123 friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { 1069 dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
1124 1070
1125 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); 1071 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2);
1126 1072
@@ -1129,10 +1075,10 @@ static void doNAT(void)
1129 1075
1130 uint16_t port_list[MAX_FRIEND_CLIENTS]; 1076 uint16_t port_list[MAX_FRIEND_CLIENTS];
1131 uint16_t numports = NAT_getports(port_list, ip_list, num, ip); 1077 uint16_t numports = NAT_getports(port_list, ip_list, num, ip);
1132 punch_holes(ip, port_list, numports, i); 1078 punch_holes(dht, ip, port_list, numports, i);
1133 1079
1134 friends_list[i].punching_timestamp = temp_time; 1080 dht->friends_list[i].punching_timestamp = temp_time;
1135 friends_list[i].hole_punching = 0; 1081 dht->friends_list[i].hole_punching = 0;
1136 } 1082 }
1137 } 1083 }
1138} 1084}
@@ -1149,7 +1095,7 @@ static void doNAT(void)
1149 network while preventing amplification attacks. 1095 network while preventing amplification attacks.
1150 return 0 if node was added 1096 return 0 if node was added
1151 return -1 if node was not added */ 1097 return -1 if node was not added */
1152int add_toping(uint8_t *client_id, IP_Port ip_port) 1098int add_toping(DHT * dht, uint8_t *client_id, IP_Port ip_port)
1153{ 1099{
1154 if (ip_port.ip.i == 0) 1100 if (ip_port.ip.i == 0)
1155 return -1; 1101 return -1;
@@ -1157,19 +1103,19 @@ int add_toping(uint8_t *client_id, IP_Port ip_port)
1157 uint32_t i; 1103 uint32_t i;
1158 1104
1159 for (i = 0; i < MAX_TOPING; ++i) { 1105 for (i = 0; i < MAX_TOPING; ++i) {
1160 if (toping[i].ip_port.ip.i == 0) { 1106 if (dht->toping[i].ip_port.ip.i == 0) {
1161 memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); 1107 memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE);
1162 toping[i].ip_port.ip.i = ip_port.ip.i; 1108 dht->toping[i].ip_port.ip.i = ip_port.ip.i;
1163 toping[i].ip_port.port = ip_port.port; 1109 dht->toping[i].ip_port.port = ip_port.port;
1164 return 0; 1110 return 0;
1165 } 1111 }
1166 } 1112 }
1167 1113
1168 for (i = 0; i < MAX_TOPING; ++i) { 1114 for (i = 0; i < MAX_TOPING; ++i) {
1169 if (id_closest(self_public_key, toping[i].client_id, client_id) == 2) { 1115 if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) {
1170 memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); 1116 memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE);
1171 toping[i].ip_port.ip.i = ip_port.ip.i; 1117 dht->toping[i].ip_port.ip.i = ip_port.ip.i;
1172 toping[i].ip_port.port = ip_port.port; 1118 dht->toping[i].ip_port.port = ip_port.port;
1173 return 0; 1119 return 0;
1174 } 1120 }
1175 } 1121 }
@@ -1179,68 +1125,80 @@ int add_toping(uint8_t *client_id, IP_Port ip_port)
1179 1125
1180/*Ping all the valid nodes in the toping list every TIME_TOPING seconds 1126/*Ping all the valid nodes in the toping list every TIME_TOPING seconds
1181 this function must be run at least once every TIME_TOPING seconds*/ 1127 this function must be run at least once every TIME_TOPING seconds*/
1182static void do_toping() 1128static void do_toping(DHT * dht)
1183{ 1129{
1184 uint64_t temp_time = unix_time(); 1130 uint64_t temp_time = unix_time();
1185 1131
1186 if (!is_timeout(temp_time, last_toping, TIME_TOPING)) 1132 if (!is_timeout(temp_time, dht->last_toping, TIME_TOPING))
1187 return; 1133 return;
1188 1134
1189 last_toping = temp_time; 1135 dht->last_toping = temp_time;
1190 uint32_t i; 1136 uint32_t i;
1191 1137
1192 for (i = 0; i < MAX_TOPING; ++i) { 1138 for (i = 0; i < MAX_TOPING; ++i) {
1193 if (toping[i].ip_port.ip.i == 0) 1139 if (dht->toping[i].ip_port.ip.i == 0)
1194 return; 1140 return;
1195 1141
1196 send_ping_request(toping[i].ip_port, (clientid_t *) toping[i].client_id); 1142 //send_ping_request(dht, dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id);
1197 toping[i].ip_port.ip.i = 0; 1143 send_ping_request(dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id);
1144 dht->toping[i].ip_port.ip.i = 0;
1198 } 1145 }
1199} 1146}
1200 1147
1201 1148
1202void DHT_init(void) 1149DHT * new_DHT(Net_Crypto *c)
1203{ 1150{
1204 networking_registerhandler(temp_net, 0, &handle_ping_request, NULL); 1151 DHT * temp = calloc(1, sizeof(DHT));
1205 networking_registerhandler(temp_net, 1, &handle_ping_response, NULL); 1152 if (temp == NULL)
1206 networking_registerhandler(temp_net, 2, &handle_getnodes, NULL); 1153 return NULL;
1207 networking_registerhandler(temp_net, 3, &handle_sendnodes, NULL); 1154 temp->c = c;
1208 cryptopacket_registerhandler(temp_net_crypto, 254, &handle_NATping); 1155 networking_registerhandler(c->lossless_udp->net, 0, &handle_ping_request, temp);
1156 networking_registerhandler(c->lossless_udp->net, 1, &handle_ping_response, temp);
1157 networking_registerhandler(c->lossless_udp->net, 2, &handle_getnodes, temp);
1158 networking_registerhandler(c->lossless_udp->net, 3, &handle_sendnodes, temp);
1159 cryptopacket_registerhandler(c, 254, &handle_NATping, temp);
1160 temp_DHT = temp;
1161 return temp;
1209} 1162}
1210 1163
1211void doDHT(void) 1164void do_DHT(DHT * dht)
1165{
1166 do_Close(dht);
1167 do_DHT_friends(dht);
1168 do_NAT(dht);
1169 do_toping(dht);
1170}
1171void kill_DHT(DHT * dht)
1212{ 1172{
1213 doClose(); 1173 free(dht->friends_list);
1214 doDHTFriends(); 1174 free(dht);
1215 doNAT();
1216 do_toping();
1217} 1175}
1218 1176
1219/* get the size of the DHT (for saving) */ 1177/* get the size of the DHT (for saving) */
1220uint32_t DHT_size(void) 1178uint32_t DHT_size(DHT * dht)
1221{ 1179{
1222 return sizeof(close_clientlist) + sizeof(Friend) * num_friends; 1180 return sizeof(dht->close_clientlist) + sizeof(DHT_Friend) * dht->num_friends;
1223} 1181}
1224 1182
1225/* save the DHT in data where data is an array of size DHT_size() */ 1183/* save the DHT in data where data is an array of size DHT_size() */
1226void DHT_save(uint8_t *data) 1184void DHT_save(DHT * dht, uint8_t *data)
1227{ 1185{
1228 memcpy(data, close_clientlist, sizeof(close_clientlist)); 1186 memcpy(data, dht->close_clientlist, sizeof(dht->close_clientlist));
1229 memcpy(data + sizeof(close_clientlist), friends_list, sizeof(Friend) * num_friends); 1187 memcpy(data + sizeof(dht->close_clientlist), dht->friends_list, sizeof(DHT_Friend) * dht->num_friends);
1230} 1188}
1231 1189
1232/* load the DHT from data of size size; 1190/* load the DHT from data of size size;
1233 * return -1 if failure 1191 * return -1 if failure
1234 * return 0 if success 1192 * return 0 if success
1235 */ 1193 */
1236int DHT_load(uint8_t *data, uint32_t size) 1194int DHT_load(DHT * dht, uint8_t *data, uint32_t size)
1237{ 1195{
1238 init_ping(); 1196 init_ping();
1239 1197
1240 if (size < sizeof(close_clientlist)) 1198 if (size < sizeof(dht->close_clientlist))
1241 return -1; 1199 return -1;
1242 1200
1243 if ((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) 1201 if ((size - sizeof(dht->close_clientlist)) % sizeof(DHT_Friend) != 0)
1244 return -1; 1202 return -1;
1245 1203
1246 uint32_t i, j; 1204 uint32_t i, j;
@@ -1249,19 +1207,19 @@ int DHT_load(uint8_t *data, uint32_t size)
1249 1207
1250 Client_data *client; 1208 Client_data *client;
1251 1209
1252 temp = (size - sizeof(close_clientlist)) / sizeof(Friend); 1210 temp = (size - sizeof(dht->close_clientlist)) / sizeof(DHT_Friend);
1253 1211
1254 if (temp != 0) { 1212 if (temp != 0) {
1255 Friend *tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); 1213 DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist));
1256 1214
1257 for (i = 0; i < temp; ++i) { 1215 for (i = 0; i < temp; ++i) {
1258 DHT_addfriend(tempfriends_list[i].client_id); 1216 DHT_addfriend(dht, tempfriends_list[i].client_id);
1259 1217
1260 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 1218 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1261 client = &tempfriends_list[i].client_list[j]; 1219 client = &tempfriends_list[i].client_list[j];
1262 1220
1263 if (client->timestamp != 0) 1221 if (client->timestamp != 0)
1264 getnodes(client->ip_port, client->client_id, tempfriends_list[i].client_id); 1222 getnodes(dht, client->ip_port, client->client_id, tempfriends_list[i].client_id);
1265 } 1223 }
1266 } 1224 }
1267 } 1225 }
@@ -1270,7 +1228,7 @@ int DHT_load(uint8_t *data, uint32_t size)
1270 1228
1271 for (i = 0; i < LCLIENT_LIST; ++i) { 1229 for (i = 0; i < LCLIENT_LIST; ++i) {
1272 if (tempclose_clientlist[i].timestamp != 0) 1230 if (tempclose_clientlist[i].timestamp != 0)
1273 DHT_bootstrap( tempclose_clientlist[i].ip_port, 1231 DHT_bootstrap(dht, tempclose_clientlist[i].ip_port,
1274 tempclose_clientlist[i].client_id ); 1232 tempclose_clientlist[i].client_id );
1275 } 1233 }
1276 1234
@@ -1280,13 +1238,13 @@ int DHT_load(uint8_t *data, uint32_t size)
1280/* returns 0 if we are not connected to the DHT 1238/* returns 0 if we are not connected to the DHT
1281 * returns 1 if we are 1239 * returns 1 if we are
1282 */ 1240 */
1283int DHT_isconnected(void) 1241int DHT_isconnected(DHT * dht)
1284{ 1242{
1285 uint32_t i; 1243 uint32_t i;
1286 uint64_t temp_time = unix_time(); 1244 uint64_t temp_time = unix_time();
1287 1245
1288 for (i = 0; i < LCLIENT_LIST; ++i) { 1246 for (i = 0; i < LCLIENT_LIST; ++i) {
1289 if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) 1247 if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT))
1290 return 1; 1248 return 1;
1291 } 1249 }
1292 1250
diff --git a/core/DHT.h b/core/DHT.h
index 8cb0436a..0ecc0b50 100644
--- a/core/DHT.h
+++ b/core/DHT.h
@@ -34,6 +34,20 @@ extern "C" {
34/* size of the client_id in bytes */ 34/* size of the client_id in bytes */
35#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES 35#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
36 36
37/* maximum number of clients stored per friend. */
38#define MAX_FRIEND_CLIENTS 8
39
40/* A list of the clients mathematically closest to ours. */
41#define LCLIENT_LIST 32
42
43/* The list of ip ports along with the ping_id of what we sent them and a timestamp */
44#define LPING_ARRAY 256 //NOTE Deprecated (doesn't do anything)
45
46#define LSEND_NODES_ARRAY LPING_ARRAY/2
47
48/*Maximum newly announced nodes to ping per TIME_TOPING seconds*/
49#define MAX_TOPING 16
50
37typedef struct { 51typedef struct {
38 uint8_t client_id[CLIENT_ID_SIZE]; 52 uint8_t client_id[CLIENT_ID_SIZE];
39 IP_Port ip_port; 53 IP_Port ip_port;
@@ -45,19 +59,64 @@ typedef struct {
45 uint64_t ret_timestamp; 59 uint64_t ret_timestamp;
46} Client_data; 60} Client_data;
47 61
48Client_data *DHT_get_close_list(void); 62/*----------------------------------------------------------------------------------*/
63
64typedef struct {
65 uint8_t client_id[CLIENT_ID_SIZE];
66 Client_data client_list[MAX_FRIEND_CLIENTS];
67
68 /* time at which the last get_nodes request was sent. */
69 uint64_t lastgetnode;
70
71 /* Symetric NAT hole punching stuff */
72
73 /* 1 if currently hole punching, otherwise 0 */
74 uint8_t hole_punching;
75 uint32_t punching_index;
76 uint64_t punching_timestamp;
77 uint64_t recvNATping_timestamp;
78 uint64_t NATping_id;
79 uint64_t NATping_timestamp;
80} DHT_Friend;
81
82typedef struct {
83 uint8_t client_id[CLIENT_ID_SIZE];
84 IP_Port ip_port;
85} Node_format;
86
87typedef struct {
88 IP_Port ip_port;
89 uint64_t ping_id;
90 uint64_t timestamp;
91} Pinged;
92
93/*----------------------------------------------------------------------------------*/
94typedef struct {
95 Net_Crypto *c;
96 Client_data close_clientlist[LCLIENT_LIST];
97 DHT_Friend *friends_list;
98 uint16_t num_friends;
99 Pinged send_nodes[LSEND_NODES_ARRAY];
100 Node_format toping[MAX_TOPING];
101 uint64_t last_toping;
102 uint64_t close_lastgetnodes;
103} DHT;
104/*----------------------------------------------------------------------------------*/
105DHT * temp_DHT; //TODO: remove
106
107Client_data *DHT_get_close_list(DHT * dht);
49 108
50/* Add a new friend to the friends list 109/* Add a new friend to the friends list
51 client_id must be CLIENT_ID_SIZE bytes long. 110 client_id must be CLIENT_ID_SIZE bytes long.
52 returns 0 if success 111 returns 0 if success
53 returns 1 if failure (friends list is full) */ 112 returns 1 if failure (friends list is full) */
54int DHT_addfriend(uint8_t *client_id); 113int DHT_addfriend(DHT * dht, uint8_t *client_id);
55 114
56/* Delete a friend from the friends list 115/* Delete a friend from the friends list
57 client_id must be CLIENT_ID_SIZE bytes long. 116 client_id must be CLIENT_ID_SIZE bytes long.
58 returns 0 if success 117 returns 0 if success
59 returns 1 if failure (client_id not in friends list) */ 118 returns 1 if failure (client_id not in friends list) */
60int DHT_delfriend(uint8_t *client_id); 119int DHT_delfriend(DHT * dht, uint8_t *client_id);
61 120
62/* Get ip of friend 121/* Get ip of friend
63 client_id must be CLIENT_ID_SIZE bytes long. 122 client_id must be CLIENT_ID_SIZE bytes long.
@@ -66,14 +125,14 @@ int DHT_delfriend(uint8_t *client_id);
66 returns ip if success 125 returns ip if success
67 returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) 126 returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.)
68 returns ip of 1 if friend is not in list. */ 127 returns ip of 1 if friend is not in list. */
69IP_Port DHT_getfriendip(uint8_t *client_id); 128IP_Port DHT_getfriendip(DHT * dht, uint8_t *client_id);
70 129
71/* Run this function at least a couple times per second (It's the main loop) */ 130/* Run this function at least a couple times per second (It's the main loop) */
72void doDHT(void); 131void do_DHT(DHT * dht);
73 132
74/* Use this function to bootstrap the client 133/* Use this function to bootstrap the client
75 Sends a get nodes request to the given node with ip port and public_key */ 134 Sends a get nodes request to the given node with ip port and public_key */
76void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key); 135void DHT_bootstrap(DHT * dht, IP_Port ip_port, uint8_t *public_key);
77 136
78/* Add nodes to the toping list 137/* Add nodes to the toping list
79 all nodes in this list are pinged every TIME_TOPING seconds 138 all nodes in this list are pinged every TIME_TOPING seconds
@@ -83,17 +142,17 @@ void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key);
83 network while preventing amplification attacks. 142 network while preventing amplification attacks.
84 return 0 if node was added 143 return 0 if node was added
85 return -1 if node was not added */ 144 return -1 if node was not added */
86int add_toping(uint8_t *client_id, IP_Port ip_port); 145int add_toping(DHT * dht, uint8_t *client_id, IP_Port ip_port);
87 146
88/* ROUTING FUNCTIONS */ 147/* ROUTING FUNCTIONS */
89 148
90/* send the given packet to node with client_id 149/* send the given packet to node with client_id
91 returns -1 if failure */ 150 returns -1 if failure */
92int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length); 151int route_packet(DHT * dht, uint8_t *client_id, uint8_t *packet, uint32_t length);
93 152
94/* Send the following packet to everyone who tells us they are connected to friend_id 153/* Send the following packet to everyone who tells us they are connected to friend_id
95 returns the number of nodes it sent the packet to */ 154 returns the number of nodes it sent the packet to */
96int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length); 155int route_tofriend(DHT * dht, uint8_t *friend_id, uint8_t *packet, uint32_t length);
97 156
98/* NAT PUNCHING FUNCTIONS */ 157/* NAT PUNCHING FUNCTIONS */
99 158
@@ -101,29 +160,31 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length);
101 ip_portlist must be at least MAX_FRIEND_CLIENTS big 160 ip_portlist must be at least MAX_FRIEND_CLIENTS big
102 returns the number of ips returned 161 returns the number of ips returned
103 returns -1 if no such friend*/ 162 returns -1 if no such friend*/
104int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id); 163int friend_ips(DHT * dht, IP_Port *ip_portlist, uint8_t *friend_id);
105 164
106/* SAVE/LOAD functions */ 165/* SAVE/LOAD functions */
107 166
108/* get the size of the DHT (for saving) */ 167/* get the size of the DHT (for saving) */
109uint32_t DHT_size(void); 168uint32_t DHT_size(DHT * dht);
110 169
111/* save the DHT in data where data is an array of size DHT_size() */ 170/* save the DHT in data where data is an array of size DHT_size() */
112void DHT_save(uint8_t *data); 171void DHT_save(DHT * dht, uint8_t *data);
113 172
114/* init DHT */ 173/* init DHT */
115void DHT_init(void); 174DHT * new_DHT(Net_Crypto *c);
175
176void kill_DHT(DHT * dht);
116 177
117/* load the DHT from data of size size; 178/* load the DHT from data of size size;
118 return -1 if failure 179 return -1 if failure
119 return 0 if success */ 180 return 0 if success */
120int DHT_load(uint8_t *data, uint32_t size); 181int DHT_load(DHT * dht, uint8_t *data, uint32_t size);
121 182
122/* returns 0 if we are not connected to the DHT 183/* returns 0 if we are not connected to the DHT
123 returns 1 if we are */ 184 returns 1 if we are */
124int DHT_isconnected(); 185int DHT_isconnected(DHT * dht);
125 186
126void addto_lists(IP_Port ip_port, uint8_t *client_id); 187void addto_lists(DHT * dht, IP_Port ip_port, uint8_t *client_id);
127 188
128#ifdef __cplusplus 189#ifdef __cplusplus
129} 190}
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c
index 3045e215..07980d26 100644
--- a/core/LAN_discovery.c
+++ b/core/LAN_discovery.c
@@ -123,28 +123,29 @@ static int LAN_ip(IP ip)
123 123
124static int handle_LANdiscovery(void * object, IP_Port source, uint8_t *packet, uint32_t length) 124static int handle_LANdiscovery(void * object, IP_Port source, uint8_t *packet, uint32_t length)
125{ 125{
126 DHT *dht = object;
126 if (LAN_ip(source.ip) == -1) 127 if (LAN_ip(source.ip) == -1)
127 return 1; 128 return 1;
128 129
129 if (length != crypto_box_PUBLICKEYBYTES + 1) 130 if (length != crypto_box_PUBLICKEYBYTES + 1)
130 return 1; 131 return 1;
131 132
132 DHT_bootstrap(source, packet + 1); 133 DHT_bootstrap(dht, source, packet + 1);
133 return 0; 134 return 0;
134} 135}
135 136
136 137
137int send_LANdiscovery(uint16_t port) 138int send_LANdiscovery(uint16_t port, Net_Crypto *c)
138{ 139{
139 uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; 140 uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
140 data[0] = 33; 141 data[0] = 33;
141 memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); 142 memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES);
142 IP_Port ip_port = {broadcast_ip(), port}; 143 IP_Port ip_port = {broadcast_ip(), port};
143 return sendpacket(temp_net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); 144 return sendpacket(c->lossless_udp->net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES);
144} 145}
145 146
146 147
147void LANdiscovery_init(void) 148void LANdiscovery_init(DHT *dht)
148{ 149{
149 networking_registerhandler(temp_net, 33, &handle_LANdiscovery, NULL); 150 networking_registerhandler(dht->c->lossless_udp->net, 33, &handle_LANdiscovery, dht);
150} 151}
diff --git a/core/LAN_discovery.h b/core/LAN_discovery.h
index 6b5b8c75..5a790331 100644
--- a/core/LAN_discovery.h
+++ b/core/LAN_discovery.h
@@ -40,11 +40,11 @@ extern "C" {
40#endif 40#endif
41 41
42/*Send a LAN discovery pcaket to the broadcast address with port port*/ 42/*Send a LAN discovery pcaket to the broadcast address with port port*/
43int send_LANdiscovery(uint16_t port); 43int send_LANdiscovery(uint16_t port, Net_Crypto *c);
44 44
45 45
46/* sets up packet handlers */ 46/* sets up packet handlers */
47void LANdiscovery_init(void); 47void LANdiscovery_init(DHT *dht);
48 48
49 49
50 50
diff --git a/core/Messenger.c b/core/Messenger.c
index cb3d2551..25a4ff98 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -108,9 +108,8 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len)
108 */ 108 */
109void getaddress(Messenger *m, uint8_t *address) 109void getaddress(Messenger *m, uint8_t *address)
110{ 110{
111 //memcpy(address, m->public_key, crypto_box_PUBLICKEYBYTES); //TODO 111 memcpy(address, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES);
112 memcpy(address, self_public_key, crypto_box_PUBLICKEYBYTES); 112 uint32_t nospam = get_nospam(&(m->fr));
113 uint32_t nospam = get_nospam();
114 memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam)); 113 memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam));
115 uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); 114 uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
116 memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); 115 memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum));
@@ -150,7 +149,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
150 if (length < 1) 149 if (length < 1)
151 return FAERR_NOMESSAGE; 150 return FAERR_NOMESSAGE;
152 151
153 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 152 if (memcmp(client_id, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
154 return FAERR_OWNKEY; 153 return FAERR_OWNKEY;
155 154
156 int friend_id = getfriend_id(m, client_id); 155 int friend_id = getfriend_id(m, client_id);
@@ -176,7 +175,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
176 175
177 for (i = 0; i <= m->numfriends; ++i) { 176 for (i = 0; i <= m->numfriends; ++i) {
178 if (m->friendlist[i].status == NOFRIEND) { 177 if (m->friendlist[i].status == NOFRIEND) {
179 DHT_addfriend(client_id); 178 DHT_addfriend(m->dht, client_id);
180 m->friendlist[i].status = FRIEND_ADDED; 179 m->friendlist[i].status = FRIEND_ADDED;
181 m->friendlist[i].crypt_connection_id = -1; 180 m->friendlist[i].crypt_connection_id = -1;
182 m->friendlist[i].friendrequest_lastsent = 0; 181 m->friendlist[i].friendrequest_lastsent = 0;
@@ -216,7 +215,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
216 215
217 for (i = 0; i <= m->numfriends; ++i) { 216 for (i = 0; i <= m->numfriends; ++i) {
218 if (m->friendlist[i].status == NOFRIEND) { 217 if (m->friendlist[i].status == NOFRIEND) {
219 DHT_addfriend(client_id); 218 DHT_addfriend(m->dht, client_id);
220 m->friendlist[i].status = FRIEND_CONFIRMED; 219 m->friendlist[i].status = FRIEND_CONFIRMED;
221 m->friendlist[i].crypt_connection_id = -1; 220 m->friendlist[i].crypt_connection_id = -1;
222 m->friendlist[i].friendrequest_lastsent = 0; 221 m->friendlist[i].friendrequest_lastsent = 0;
@@ -245,7 +244,7 @@ int m_delfriend(Messenger *m, int friendnumber)
245 if (friendnumber >= m->numfriends || friendnumber < 0) 244 if (friendnumber >= m->numfriends || friendnumber < 0)
246 return -1; 245 return -1;
247 246
248 DHT_delfriend(m->friendlist[friendnumber].client_id); 247 DHT_delfriend(m->dht, m->friendlist[friendnumber].client_id);
249 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); 248 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id);
250 free(m->friendlist[friendnumber].statusmessage); 249 free(m->friendlist[friendnumber].statusmessage);
251 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); 250 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend));
@@ -522,7 +521,7 @@ void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno)
522/* set the function that will be executed when a friend request is received. */ 521/* set the function that will be executed when a friend request is received. */
523void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata) 522void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
524{ 523{
525 callback_friendrequest(function, userdata); 524 callback_friendrequest(&(m->fr), function, userdata);
526} 525}
527 526
528/* set the function that will be executed when a message from a friend is received. */ 527/* set the function that will be executed when a message from a friend is received. */
@@ -617,7 +616,7 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
617/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ 616/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
618int LANdiscovery(timer *t, void *arg) 617int LANdiscovery(timer *t, void *arg)
619{ 618{
620 send_LANdiscovery(htons(PORT)); 619 send_LANdiscovery(htons(PORT), temp_net_crypto);
621 timer_start(t, LAN_DISCOVERY_INTERVAL); 620 timer_start(t, LAN_DISCOVERY_INTERVAL);
622 return 0; 621 return 0;
623} 622}
@@ -637,19 +636,26 @@ Messenger *initMessenger(void)
637 } 636 }
638 m->net_crypto = new_net_crypto(m->net); 637 m->net_crypto = new_net_crypto(m->net);
639 if (m->net_crypto == NULL) { 638 if (m->net_crypto == NULL) {
639 kill_networking(m->net);
640 free(m);
641 return NULL;
642 }
643 m->dht = new_DHT(m->net_crypto);
644 if (m->dht == NULL) {
645 kill_net_crypto(m->net_crypto);
646 kill_networking(m->net);
640 free(m); 647 free(m);
641 free(m->net);
642 return NULL; 648 return NULL;
643 } 649 }
644 new_keys(m->net_crypto); 650 new_keys(m->net_crypto);
645 m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online")); 651 m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
646 652
647 DHT_init(); 653 friendreq_init(&(m->fr), m->net_crypto);
648 friendreq_init(); 654 LANdiscovery_init(m->dht);
649 LANdiscovery_init(); 655 set_nospam(&(m->fr), random_int());
650 set_nospam(random_int()); 656 init_cryptopackets(m->dht);
651 657
652 send_LANdiscovery(htons(PORT)); 658 send_LANdiscovery(htons(PORT), m->net_crypto);
653 timer_single(&LANdiscovery, 0, LAN_DISCOVERY_INTERVAL); 659 timer_single(&LANdiscovery, 0, LAN_DISCOVERY_INTERVAL);
654 660
655 return m; 661 return m;
@@ -661,7 +667,9 @@ void cleanupMessenger(Messenger *m)
661 /* FIXME TODO ideally cleanupMessenger will mirror initMessenger 667 /* FIXME TODO ideally cleanupMessenger will mirror initMessenger
662 * this requires the other modules to expose cleanup functions 668 * this requires the other modules to expose cleanup functions
663 */ 669 */
670 kill_DHT(m->dht);
664 kill_net_crypto(m->net_crypto); 671 kill_net_crypto(m->net_crypto);
672 kill_networking(m->net);
665 free(m->friendlist); 673 free(m->friendlist);
666 free(m); 674 free(m);
667} 675}
@@ -677,7 +685,7 @@ void doFriends(Messenger *m)
677 685
678 for (i = 0; i < m->numfriends; ++i) { 686 for (i = 0; i < m->numfriends; ++i) {
679 if (m->friendlist[i].status == FRIEND_ADDED) { 687 if (m->friendlist[i].status == FRIEND_ADDED) {
680 int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, 688 int fr = send_friendrequest(m->dht, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info,
681 m->friendlist[i].info_size); 689 m->friendlist[i].info_size);
682 690
683 if (fr >= 0) { 691 if (fr >= 0) {
@@ -699,7 +707,7 @@ void doFriends(Messenger *m)
699 } 707 }
700 } 708 }
701 709
702 IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id); 710 IP_Port friendip = DHT_getfriendip(m->dht, m->friendlist[i].client_id);
703 711
704 switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { 712 switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) {
705 case 0: 713 case 0:
@@ -883,7 +891,7 @@ void doMessenger(Messenger *m)
883{ 891{
884 networking_poll(m->net); 892 networking_poll(m->net);
885 893
886 doDHT(); 894 do_DHT(m->dht);
887 do_net_crypto(m->net_crypto); 895 do_net_crypto(m->net_crypto);
888 doInbound(m); 896 doInbound(m);
889 doFriends(m); 897 doFriends(m);
@@ -897,7 +905,7 @@ uint32_t Messenger_size(Messenger *m)
897 return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES 905 return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES
898 + sizeof(uint32_t) // nospam 906 + sizeof(uint32_t) // nospam
899 + sizeof(uint32_t) // DHT size 907 + sizeof(uint32_t) // DHT size
900 + DHT_size() // DHT itself 908 + DHT_size(m->dht) // DHT itself
901 + sizeof(uint32_t) // Friendlist size 909 + sizeof(uint32_t) // Friendlist size
902 + sizeof(Friend) * m->numfriends // Friendlist itself 910 + sizeof(Friend) * m->numfriends // Friendlist itself
903 + sizeof(uint16_t) // Own nickname length 911 + sizeof(uint16_t) // Own nickname length
@@ -910,13 +918,13 @@ void Messenger_save(Messenger *m, uint8_t *data)
910{ 918{
911 save_keys(m->net_crypto, data); 919 save_keys(m->net_crypto, data);
912 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 920 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
913 uint32_t nospam = get_nospam(); 921 uint32_t nospam = get_nospam(&(m->fr));
914 memcpy(data, &nospam, sizeof(nospam)); 922 memcpy(data, &nospam, sizeof(nospam));
915 data += sizeof(nospam); 923 data += sizeof(nospam);
916 uint32_t size = DHT_size(); 924 uint32_t size = DHT_size(m->dht);
917 memcpy(data, &size, sizeof(size)); 925 memcpy(data, &size, sizeof(size));
918 data += sizeof(size); 926 data += sizeof(size);
919 DHT_save(data); 927 DHT_save(m->dht, data);
920 data += size; 928 data += size;
921 size = sizeof(Friend) * m->numfriends; 929 size = sizeof(Friend) * m->numfriends;
922 memcpy(data, &size, sizeof(size)); 930 memcpy(data, &size, sizeof(size));
@@ -943,7 +951,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length)
943 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 951 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
944 uint32_t nospam; 952 uint32_t nospam;
945 memcpy(&nospam, data, sizeof(nospam)); 953 memcpy(&nospam, data, sizeof(nospam));
946 set_nospam(nospam); 954 set_nospam(&(m->fr), nospam);
947 data += sizeof(nospam); 955 data += sizeof(nospam);
948 uint32_t size; 956 uint32_t size;
949 memcpy(&size, data, sizeof(size)); 957 memcpy(&size, data, sizeof(size));
@@ -954,7 +962,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length)
954 962
955 length -= size; 963 length -= size;
956 964
957 if (DHT_load(data, size) == -1) 965 if (DHT_load(m->dht, data, size) == -1)
958 return -1; 966 return -1;
959 967
960 data += size; 968 data += size;
diff --git a/core/Messenger.h b/core/Messenger.h
index a2e8f16e..c4e7cc1e 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -115,6 +115,8 @@ typedef struct Messenger {
115 115
116 Networking_Core *net; 116 Networking_Core *net;
117 Net_Crypto * net_crypto; 117 Net_Crypto * net_crypto;
118 DHT * dht;
119 Friend_Requests fr;
118 uint8_t name[MAX_NAME_LENGTH]; 120 uint8_t name[MAX_NAME_LENGTH];
119 uint16_t name_length; 121 uint16_t name_length;
120 122
diff --git a/core/friend_requests.c b/core/friend_requests.c
index 7be7a4bd..b723de36 100644
--- a/core/friend_requests.c
+++ b/core/friend_requests.c
@@ -23,15 +23,12 @@
23 23
24#include "friend_requests.h" 24#include "friend_requests.h"
25 25
26uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
27uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
28
29/* Try to send a friendrequest to peer with public_key 26/* Try to send a friendrequest to peer with public_key
30 data is the data in the request and length is the length. 27 data is the data in the request and length is the length.
31 return -1 if failure. 28 return -1 if failure.
32 return 0 if it sent the friend request directly to the friend. 29 return 0 if it sent the friend request directly to the friend.
33 return the number of peers it was routed through if it did not send it directly.*/ 30 return the number of peers it was routed through if it did not send it directly.*/
34int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) 31int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
35{ 32{
36 if (length + sizeof(nospam_num) > MAX_DATA_SIZE) 33 if (length + sizeof(nospam_num) > MAX_DATA_SIZE)
37 return -1; 34 return -1;
@@ -40,25 +37,25 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data,
40 memcpy(temp, &nospam_num, sizeof(nospam_num)); 37 memcpy(temp, &nospam_num, sizeof(nospam_num));
41 memcpy(temp + sizeof(nospam_num), data, length); 38 memcpy(temp + sizeof(nospam_num), data, length);
42 uint8_t packet[MAX_DATA_SIZE]; 39 uint8_t packet[MAX_DATA_SIZE];
43 int len = create_request(self_public_key, self_secret_key, packet, public_key, temp, length + sizeof(nospam_num), 40 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, temp, length + sizeof(nospam_num),
44 32); /* 32 is friend request packet id */ 41 32); /* 32 is friend request packet id */
45 42
46 if (len == -1) 43 if (len == -1)
47 return -1; 44 return -1;
48 45
49 IP_Port ip_port = DHT_getfriendip(public_key); 46 IP_Port ip_port = DHT_getfriendip(dht, public_key);
50 47
51 if (ip_port.ip.i == 1) 48 if (ip_port.ip.i == 1)
52 return -1; 49 return -1;
53 50
54 if (ip_port.ip.i != 0) { 51 if (ip_port.ip.i != 0) {
55 if (sendpacket(temp_net->sock, ip_port, packet, len) != -1) 52 if (sendpacket(dht->c->lossless_udp->net->sock, ip_port, packet, len) != -1)
56 return 0; 53 return 0;
57 54
58 return -1; 55 return -1;
59 } 56 }
60 57
61 int num = route_tofriend(public_key, packet, len); 58 int num = route_tofriend(dht, public_key, packet, len);
62 59
63 if (num == 0) 60 if (num == 0)
64 return -1; 61 return -1;
@@ -66,58 +63,47 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data,
66 return num; 63 return num;
67} 64}
68 65
69static uint32_t nospam; 66
70/* 67/*
71 * Set and get the nospam variable used to prevent one type of friend request spam 68 * Set and get the nospam variable used to prevent one type of friend request spam
72 */ 69 */
73void set_nospam(uint32_t num) 70void set_nospam(Friend_Requests *fr, uint32_t num)
74{ 71{
75 nospam = num; 72 fr->nospam = num;
76} 73}
77 74
78uint32_t get_nospam() 75uint32_t get_nospam(Friend_Requests *fr)
79{ 76{
80 return nospam; 77 return fr->nospam;
81} 78}
82 79
83static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void *); 80
84static uint8_t handle_friendrequest_isset = 0;
85static void *handle_friendrequest_userdata;
86/* set the function that will be executed when a friend request is received. */ 81/* set the function that will be executed when a friend request is received. */
87void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata) 82void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
88{ 83{
89 handle_friendrequest = function; 84 fr->handle_friendrequest = function;
90 handle_friendrequest_isset = 1; 85 fr->handle_friendrequest_isset = 1;
91 handle_friendrequest_userdata = userdata; 86 fr->handle_friendrequest_userdata = userdata;
92} 87}
93 88
94
95/*NOTE: the following is just a temporary fix for the multiple friend requests received at the same time problem
96 TODO: Make this better (This will most likely tie in with the way we will handle spam.)*/
97
98#define MAX_RECEIVED_STORED 32
99
100static uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES];
101static uint16_t received_requests_index;
102
103/*Add to list of received friend requests*/ 89/*Add to list of received friend requests*/
104static void addto_receivedlist(uint8_t *client_id) 90static void addto_receivedlist(Friend_Requests *fr, uint8_t *client_id)
105{ 91{
106 if (received_requests_index >= MAX_RECEIVED_STORED) 92 if (fr->received_requests_index >= MAX_RECEIVED_STORED)
107 received_requests_index = 0; 93 fr->received_requests_index = 0;
108 94
109 memcpy(received_requests[received_requests_index], client_id, crypto_box_PUBLICKEYBYTES); 95 memcpy(fr->received_requests[fr->received_requests_index], client_id, crypto_box_PUBLICKEYBYTES);
110 ++received_requests_index; 96 ++fr->received_requests_index;
111} 97}
112 98
113/* Check if a friend request was already received 99/* Check if a friend request was already received
114 return 0 if not, 1 if we did */ 100 return 0 if not, 1 if we did */
115static int request_received(uint8_t *client_id) 101static int request_received(Friend_Requests *fr, uint8_t *client_id)
116{ 102{
117 uint32_t i; 103 uint32_t i;
118 104
119 for (i = 0; i < MAX_RECEIVED_STORED; ++i) { 105 for (i = 0; i < MAX_RECEIVED_STORED; ++i) {
120 if (memcmp(received_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0) 106 if (memcmp(fr->received_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0)
121 return 1; 107 return 1;
122 } 108 }
123 109
@@ -125,26 +111,27 @@ static int request_received(uint8_t *client_id)
125} 111}
126 112
127 113
128static int friendreq_handlepacket(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) 114static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
129{ 115{
130 if (handle_friendrequest_isset == 0) 116 Friend_Requests *fr = object;
117 if (fr->handle_friendrequest_isset == 0)
131 return 1; 118 return 1;
132 119
133 if (length <= sizeof(nospam)) 120 if (length <= sizeof(fr->nospam))
134 return 1; 121 return 1;
135 122
136 if (request_received(source_pubkey)) 123 if (request_received(fr, source_pubkey))
137 return 1; 124 return 1;
138 125
139 if (memcmp(packet, &nospam, sizeof(nospam)) != 0) 126 if (memcmp(packet, &fr->nospam, sizeof(fr->nospam)) != 0)
140 return 1; 127 return 1;
141 128
142 addto_receivedlist(source_pubkey); 129 addto_receivedlist(fr, source_pubkey);
143 (*handle_friendrequest)(source_pubkey, packet + 4, length - 4, handle_friendrequest_userdata); 130 (*fr->handle_friendrequest)(source_pubkey, packet + 4, length - 4, fr->handle_friendrequest_userdata);
144 return 0; 131 return 0;
145} 132}
146 133
147void friendreq_init(void) 134void friendreq_init(Friend_Requests *fr, Net_Crypto *c)
148{ 135{
149 cryptopacket_registerhandler(temp_net_crypto, 32, &friendreq_handlepacket); 136 cryptopacket_registerhandler(c, 32, &friendreq_handlepacket, fr);
150} 137}
diff --git a/core/friend_requests.h b/core/friend_requests.h
index 3ce0df8c..cc31155e 100644
--- a/core/friend_requests.h
+++ b/core/friend_requests.h
@@ -31,21 +31,36 @@
31extern "C" { 31extern "C" {
32#endif 32#endif
33 33
34typedef struct {
35 uint32_t nospam;
36 void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void *);
37 uint8_t handle_friendrequest_isset;
38 void *handle_friendrequest_userdata;
39
40 /*NOTE: the following is just a temporary fix for the multiple friend requests received at the same time problem
41 TODO: Make this better (This will most likely tie in with the way we will handle spam.)*/
42
43 #define MAX_RECEIVED_STORED 32
44
45 uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES];
46 uint16_t received_requests_index;
47} Friend_Requests;
48
34/* Try to send a friendrequest to peer with public_key 49/* Try to send a friendrequest to peer with public_key
35 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. */
36int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length); 51int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
37/* 52/*
38 * 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
39 */ 54 */
40void set_nospam(uint32_t num); 55void set_nospam(Friend_Requests *fr, uint32_t num);
41uint32_t get_nospam(); 56uint32_t get_nospam(Friend_Requests *fr);
42 57
43/* set the function that will be executed when a friend request for us is received. 58/* set the function that will be executed when a friend request for us is received.
44 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 59 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
45void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata); 60void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata);
46 61
47/* sets up friendreq packet handlers */ 62/* sets up friendreq packet handlers */
48void friendreq_init(void); 63void friendreq_init(Friend_Requests *fr, Net_Crypto *c);
49 64
50#ifdef __cplusplus 65#ifdef __cplusplus
51} 66}
diff --git a/core/net_crypto.c b/core/net_crypto.c
index dcf36a12..2e63d2f1 100644
--- a/core/net_crypto.c
+++ b/core/net_crypto.c
@@ -265,34 +265,35 @@ static int handle_request(Net_Crypto *c, uint8_t *public_key, uint8_t *data, uin
265 return -1; 265 return -1;
266} 266}
267 267
268void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb) 268void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object)
269{ 269{
270 c->cryptopackethandlers[byte] = cb; 270 c->cryptopackethandlers[byte].function = cb;
271 c->cryptopackethandlers[byte].object = object;
271} 272}
272 273
273static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length) 274static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length)
274{ 275{
275 Net_Crypto *c = object; 276 DHT *dht = object;
276 if (packet[0] == 32) { 277 if (packet[0] == 32) {
277 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || 278 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING ||
278 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) 279 length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
279 return 1; 280 return 1;
280 281
281 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. 282 if (memcmp(packet + 1, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us.
282 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 283 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
283 uint8_t data[MAX_DATA_SIZE]; 284 uint8_t data[MAX_DATA_SIZE];
284 uint8_t number; 285 uint8_t number;
285 int len = handle_request(c, public_key, data, &number, packet, length); 286 int len = handle_request(dht->c, public_key, data, &number, packet, length);
286 287
287 if (len == -1 || len == 0) 288 if (len == -1 || len == 0)
288 return 1; 289 return 1;
289 290
290 if (!c->cryptopackethandlers[number]) return 1; 291 if (!dht->c->cryptopackethandlers[number].function) return 1;
291 292
292 c->cryptopackethandlers[number](source, public_key, data, len); 293 dht->c->cryptopackethandlers[number].function(dht->c->cryptopackethandlers[number].object, source, public_key, data, len);
293 294
294 } else { /* if request is not for us, try routing it. */ 295 } else { /* if request is not for us, try routing it. */
295 if (route_packet(packet + 1, packet, length) == length) //NOTE 296 if (route_packet(dht, packet + 1, packet, length) == length) //NOTE
296 return 0; 297 return 0;
297 } 298 }
298 } 299 }
@@ -572,17 +573,9 @@ int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id)
572 return CONN_NO_CONNECTION; 573 return CONN_NO_CONNECTION;
573} 574}
574 575
575/* Generate our public and private keys
576 Only call this function the first time the program starts. */
577
578extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];//TODO: Remove this
579extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
580
581void new_keys(Net_Crypto *c) 576void new_keys(Net_Crypto *c)
582{ 577{
583 crypto_box_keypair(c->self_public_key, c->self_secret_key); 578 crypto_box_keypair(c->self_public_key, c->self_secret_key);
584 memcpy(self_public_key, c->self_public_key, crypto_box_PUBLICKEYBYTES);
585 memcpy(self_secret_key, c->self_secret_key, crypto_box_PUBLICKEYBYTES);
586} 579}
587 580
588/* save the public and private keys to the keys array 581/* save the public and private keys to the keys array
@@ -713,12 +706,16 @@ Net_Crypto * new_net_crypto(Networking_Core * net)
713 if (temp->lossless_udp == NULL) 706 if (temp->lossless_udp == NULL)
714 return NULL; 707 return NULL;
715 memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING); 708 memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING);
716 //networking_registerhandler(temp, 32, &cryptopacket_handle);
717 networking_registerhandler(net, 32, &cryptopacket_handle, temp);
718 temp_net_crypto = temp; //TODO remove 709 temp_net_crypto = temp; //TODO remove
719 return temp; 710 return temp;
720} 711}
721 712
713void init_cryptopackets(void *dht)
714{
715 DHT *s_dht = dht;
716 networking_registerhandler(s_dht->c->lossless_udp->net, 32, &cryptopacket_handle, s_dht);
717}
718
722static void kill_timedout(Net_Crypto *c) 719static void kill_timedout(Net_Crypto *c)
723{ 720{
724 uint32_t i; 721 uint32_t i;
diff --git a/core/net_crypto.h b/core/net_crypto.h
index 745f1f14..887b432b 100644
--- a/core/net_crypto.h
+++ b/core/net_crypto.h
@@ -25,7 +25,6 @@
25#define NET_CRYPTO_H 25#define NET_CRYPTO_H
26 26
27#include "Lossless_UDP.h" 27#include "Lossless_UDP.h"
28#include "DHT.h"
29 28
30#ifdef __cplusplus 29#ifdef __cplusplus
31extern "C" { 30extern "C" {
@@ -33,9 +32,6 @@ extern "C" {
33 32
34#define MAX_INCOMING 64 33#define MAX_INCOMING 64
35 34
36extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];//TODO: Remove this
37extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
38
39typedef struct { 35typedef struct {
40 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */ 36 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */
41 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */ 37 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */
@@ -51,25 +47,32 @@ typedef struct {
51 47
52} Crypto_Connection; 48} Crypto_Connection;
53 49
54typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len); 50typedef int (*cryptopacket_handler_callback)(void * object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
51
52typedef struct {
53 cryptopacket_handler_callback function;
54 void * object;
55}Cryptopacket_Handles;
55 56
56typedef struct { 57typedef struct {
57Lossless_UDP * lossless_udp; 58 Lossless_UDP * lossless_udp;
58 59
59Crypto_Connection *crypto_connections; 60 Crypto_Connection *crypto_connections;
60 61
61uint32_t crypto_connections_length; /* Length of connections array */ 62 uint32_t crypto_connections_length; /* Length of connections array */
62 63
63/* Our public and secret keys. */ 64 /* Our public and secret keys. */
64uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 65 uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
65uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; 66 uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
66 67
67/* keeps track of the connection numbers for friends request so we can check later if they were sent */ 68 /* keeps track of the connection numbers for friends request so we can check later if they were sent */
68int incoming_connections[MAX_INCOMING]; 69 int incoming_connections[MAX_INCOMING];
69 70
70cryptopacket_handler_callback cryptopackethandlers[256]; 71 Cryptopacket_Handles cryptopackethandlers[256];
71} Net_Crypto; 72} Net_Crypto;
72 73
74#include "DHT.h"
75
73Net_Crypto * temp_net_crypto; //TODO: remove this 76Net_Crypto * temp_net_crypto; //TODO: remove this
74 77
75#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) 78#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
@@ -130,7 +133,7 @@ int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *
130 133
131 134
132/* Function to call when request beginning with byte is received */ 135/* Function to call when request beginning with byte is received */
133void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb); 136void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void * object);
134 137
135/* Start a secure connection with other peer who has public_key and ip_port 138/* Start a secure connection with other peer who has public_key and ip_port
136 returns -1 if failure 139 returns -1 if failure
@@ -183,6 +186,9 @@ void do_net_crypto(Net_Crypto *c);
183 186
184void kill_net_crypto(Net_Crypto *c); 187void kill_net_crypto(Net_Crypto *c);
185 188
189/* Init the cryptopacket handling */
190void init_cryptopackets(void *dht);
191
186#ifdef __cplusplus 192#ifdef __cplusplus
187} 193}
188#endif 194#endif
diff --git a/core/network.c b/core/network.c
index 684a4227..9ec390fb 100644
--- a/core/network.c
+++ b/core/network.c
@@ -196,7 +196,6 @@ Networking_Core * new_networking(IP ip, uint16_t port)
196 /* Bind our socket to port PORT and address 0.0.0.0 */ 196 /* Bind our socket to port PORT and address 0.0.0.0 */
197 ADDR addr = {AF_INET, htons(port), ip}; 197 ADDR addr = {AF_INET, htons(port), ip};
198 bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr)); 198 bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr));
199 temp_net = temp;
200 return temp; 199 return temp;
201} 200}
202 201
diff --git a/core/network.h b/core/network.h
index 5ed25620..47d9fff2 100644
--- a/core/network.h
+++ b/core/network.h
@@ -112,7 +112,6 @@ typedef struct {
112 int sock; 112 int sock;
113}Networking_Core; 113}Networking_Core;
114 114
115Networking_Core * temp_net;
116/* returns current time in milleseconds since the epoch. */ 115/* returns current time in milleseconds since the epoch. */
117uint64_t current_time(void); 116uint64_t current_time(void);
118 117
diff --git a/core/ping.c b/core/ping.c
index d2b290a0..10b9b19f 100644
--- a/core/ping.c
+++ b/core/ping.c
@@ -26,7 +26,6 @@ typedef struct {
26static pinged_t pings[PING_NUM_MAX]; 26static pinged_t pings[PING_NUM_MAX];
27static size_t num_pings; 27static size_t num_pings;
28static size_t pos_pings; 28static size_t pos_pings;
29static clientid_t *self_id = (clientid_t *) &self_public_key;
30 29
31extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c 30extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c
32 31
@@ -115,19 +114,19 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id)
115 int rc; 114 int rc;
116 uint64_t ping_id; 115 uint64_t ping_id;
117 116
118 if (is_pinging(ipp, 0) || id_eq(client_id, self_id)) 117 if (is_pinging(ipp, 0) || id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key))
119 return 1; 118 return 1;
120 119
121 // Generate random ping_id 120 // Generate random ping_id
122 ping_id = add_ping(ipp); 121 ping_id = add_ping(ipp);
123 122
124 pk.magic = PACKET_PING_REQ; 123 pk.magic = PACKET_PING_REQ;
125 id_cpy(&pk.client_id, self_id); // Our pubkey 124 id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey
126 random_nonce((uint8_t *) &pk.nonce); // Generate random nonce 125 random_nonce((uint8_t *) &pk.nonce); // Generate random nonce
127 126
128 // Encrypt ping_id using recipient privkey 127 // Encrypt ping_id using recipient privkey
129 rc = encrypt_data((uint8_t *) client_id, 128 rc = encrypt_data((uint8_t *) client_id,
130 self_secret_key, 129 temp_net_crypto->self_secret_key,
131 (uint8_t *) &pk.nonce, 130 (uint8_t *) &pk.nonce,
132 (uint8_t *) &ping_id, sizeof(ping_id), 131 (uint8_t *) &ping_id, sizeof(ping_id),
133 (uint8_t *) &pk.ping_id); 132 (uint8_t *) &pk.ping_id);
@@ -135,7 +134,7 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id)
135 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) 134 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
136 return 1; 135 return 1;
137 136
138 return sendpacket(temp_net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); 137 return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk));
139} 138}
140 139
141int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) 140int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
@@ -143,16 +142,16 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
143 pingres_t pk; 142 pingres_t pk;
144 int rc; 143 int rc;
145 144
146 if (id_eq(client_id, self_id)) 145 if (id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key))
147 return 1; 146 return 1;
148 147
149 pk.magic = PACKET_PING_RES; 148 pk.magic = PACKET_PING_RES;
150 id_cpy(&pk.client_id, self_id); // Our pubkey 149 id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey
151 random_nonce((uint8_t *) &pk.nonce); // Generate random nonce 150 random_nonce((uint8_t *) &pk.nonce); // Generate random nonce
152 151
153 // Encrypt ping_id using recipient privkey 152 // Encrypt ping_id using recipient privkey
154 rc = encrypt_data((uint8_t *) client_id, 153 rc = encrypt_data((uint8_t *) client_id,
155 self_secret_key, 154 temp_net_crypto->self_secret_key,
156 (uint8_t *) &pk.nonce, 155 (uint8_t *) &pk.nonce,
157 (uint8_t *) &ping_id, sizeof(ping_id), 156 (uint8_t *) &ping_id, sizeof(ping_id),
158 (uint8_t *) &pk.ping_id); 157 (uint8_t *) &pk.ping_id);
@@ -160,21 +159,22 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
160 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) 159 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
161 return 1; 160 return 1;
162 161
163 return sendpacket(temp_net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); 162 return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk));
164} 163}
165 164
166int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length) 165int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length)
167{ 166{
167 DHT * dht = object;
168 pingreq_t *p = (pingreq_t *) packet; 168 pingreq_t *p = (pingreq_t *) packet;
169 int rc; 169 int rc;
170 uint64_t ping_id; 170 uint64_t ping_id;
171 171
172 if (length != sizeof(pingreq_t) || id_eq(&p->client_id, self_id)) 172 if (length != sizeof(pingreq_t) || id_eq(&p->client_id, (clientid_t *)dht->c->self_public_key))
173 return 1; 173 return 1;
174 174
175 // Decrypt ping_id 175 // Decrypt ping_id
176 rc = decrypt_data((uint8_t *) &p->client_id, 176 rc = decrypt_data((uint8_t *) &p->client_id,
177 self_secret_key, 177 dht->c->self_secret_key,
178 (uint8_t *) &p->nonce, 178 (uint8_t *) &p->nonce,
179 (uint8_t *) &p->ping_id, 179 (uint8_t *) &p->ping_id,
180 sizeof(ping_id) + ENCRYPTION_PADDING, 180 sizeof(ping_id) + ENCRYPTION_PADDING,
@@ -185,23 +185,24 @@ int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t
185 185
186 // Send response 186 // Send response
187 send_ping_response(source, &p->client_id, ping_id); 187 send_ping_response(source, &p->client_id, ping_id);
188 add_toping((uint8_t *) &p->client_id, source); 188 add_toping(dht, (uint8_t *) &p->client_id, source);
189 189
190 return 0; 190 return 0;
191} 191}
192 192
193int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length) 193int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length)
194{ 194{
195 DHT * dht = object;
195 pingres_t *p = (pingres_t *) packet; 196 pingres_t *p = (pingres_t *) packet;
196 int rc; 197 int rc;
197 uint64_t ping_id; 198 uint64_t ping_id;
198 199
199 if (length != sizeof(pingres_t) || id_eq(&p->client_id, self_id)) 200 if (length != sizeof(pingres_t) || id_eq(&p->client_id, (clientid_t *)dht->c->self_public_key))
200 return 1; 201 return 1;
201 202
202 // Decrypt ping_id 203 // Decrypt ping_id
203 rc = decrypt_data((uint8_t *) &p->client_id, 204 rc = decrypt_data((uint8_t *) &p->client_id,
204 self_secret_key, 205 dht->c->self_secret_key,
205 (uint8_t *) &p->nonce, 206 (uint8_t *) &p->nonce,
206 (uint8_t *) &p->ping_id, 207 (uint8_t *) &p->ping_id,
207 sizeof(ping_id) + ENCRYPTION_PADDING, 208 sizeof(ping_id) + ENCRYPTION_PADDING,
@@ -215,6 +216,6 @@ int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_
215 return 1; 216 return 1;
216 217
217 // Associate source ip with client_id 218 // Associate source ip with client_id
218 addto_lists(source, (uint8_t *) &p->client_id); 219 addto_lists(dht, source, (uint8_t *) &p->client_id);
219 return 0; 220 return 0;
220} 221}
diff --git a/testing/toxic/dhtstatus.c b/testing/toxic/dhtstatus.c
index a11dc616..c7a57c7d 100644
--- a/testing/toxic/dhtstatus.c
+++ b/testing/toxic/dhtstatus.c
@@ -36,7 +36,7 @@ static void dhtstatus_onKey(ToxWindow *self, Messenger *m, int key)
36 36
37static void dhtstatus_onDraw(ToxWindow *self) 37static void dhtstatus_onDraw(ToxWindow *self)
38{ 38{
39 Client_data *close_clientlist = DHT_get_close_list(); 39 Client_data *close_clientlist = DHT_get_close_list(temp_DHT);
40 curs_set(0); 40 curs_set(0);
41 werase(self->window); 41 werase(self->window);
42 42
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
index 9abe8de4..6f6c9db4 100644
--- a/testing/toxic/main.c
+++ b/testing/toxic/main.c
@@ -90,11 +90,11 @@ static Messenger *init_tox()
90#define MAXSERVERS 50 90#define MAXSERVERS 50
91 91
92/* Connects to a random DHT server listed in the DHTservers file */ 92/* Connects to a random DHT server listed in the DHTservers file */
93int init_connection(void) 93int init_connection(Messenger *m)
94{ 94{
95 FILE *fp = NULL; 95 FILE *fp = NULL;
96 96
97 if (DHT_isconnected()) 97 if (DHT_isconnected(m->dht))
98 return 0; 98 return 0;
99 99
100 fp = fopen(SRVLIST_FILE, "r"); 100 fp = fopen(SRVLIST_FILE, "r");
@@ -135,7 +135,7 @@ int init_connection(void)
135 135
136 dht.ip.i = resolved_address; 136 dht.ip.i = resolved_address;
137 unsigned char *binary_string = hex_string_to_bin(key); 137 unsigned char *binary_string = hex_string_to_bin(key);
138 DHT_bootstrap(dht, binary_string); 138 DHT_bootstrap(m->dht, dht, binary_string);
139 free(binary_string); 139 free(binary_string);
140 return 0; 140 return 0;
141} 141}
@@ -146,18 +146,18 @@ static void do_tox(Messenger *m, ToxWindow *prompt)
146 static int conn_err = 0; 146 static int conn_err = 0;
147 static bool dht_on = false; 147 static bool dht_on = false;
148 148
149 if (!dht_on && !DHT_isconnected() && !(conn_try++ % 100)) { 149 if (!dht_on && !DHT_isconnected(m->dht) && !(conn_try++ % 100)) {
150 if (!conn_err) { 150 if (!conn_err) {
151 conn_err = init_connection(); 151 conn_err = init_connection(m);
152 wprintw(prompt->window, "\nEstablishing connection...\n"); 152 wprintw(prompt->window, "\nEstablishing connection...\n");
153 153
154 if (conn_err) 154 if (conn_err)
155 wprintw(prompt->window, "\nAuto-connect failed with error code %d\n", conn_err); 155 wprintw(prompt->window, "\nAuto-connect failed with error code %d\n", conn_err);
156 } 156 }
157 } else if (!dht_on && DHT_isconnected()) { 157 } else if (!dht_on && DHT_isconnected(m->dht)) {
158 dht_on = true; 158 dht_on = true;
159 wprintw(prompt->window, "\nDHT connected.\n"); 159 wprintw(prompt->window, "\nDHT connected.\n");
160 } else if (dht_on && !DHT_isconnected()) { 160 } else if (dht_on && !DHT_isconnected(m->dht)) {
161 dht_on = false; 161 dht_on = false;
162 wprintw(prompt->window, "\nDHT disconnected. Attempting to reconnect.\n"); 162 wprintw(prompt->window, "\nDHT disconnected. Attempting to reconnect.\n");
163 } 163 }
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
index 81f00bce..204cd7e6 100644
--- a/testing/toxic/prompt.c
+++ b/testing/toxic/prompt.c
@@ -204,7 +204,7 @@ void cmd_connect(ToxWindow *self, Messenger *m, char **args)
204 204
205 dht.ip.i = resolved_address; 205 dht.ip.i = resolved_address;
206 unsigned char *binary_string = hex_string_to_bin(key); 206 unsigned char *binary_string = hex_string_to_bin(key);
207 DHT_bootstrap(dht, binary_string); 207 DHT_bootstrap(m->dht, dht, binary_string);
208 free(binary_string); 208 free(binary_string);
209} 209}
210 210