diff options
author | irungentoo <irungentoo@gmail.com> | 2013-07-12 16:27:19 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2013-07-12 16:27:19 -0400 |
commit | 79aa715514e7d587695ce0182fdf97537d9d9b85 (patch) | |
tree | 213a0566099fadd3b49f9e11cbb4c70053999360 /core/DHT.c | |
parent | e830861a9d96f4a8e8ea203e24cfe431f7960c04 (diff) |
First part of DHT hardening done.
Added crypto to the DHT communications.
This defeats completely the first attack mentioned in
docs/DHT_hardening.
Also updated the build system to build the latest test (it links it with
libsodium)
Diffstat (limited to 'core/DHT.c')
-rw-r--r-- | core/DHT.c | 277 |
1 files changed, 196 insertions, 81 deletions
@@ -54,36 +54,36 @@ typedef struct | |||
54 | typedef struct | 54 | typedef struct |
55 | { | 55 | { |
56 | IP_Port ip_port; | 56 | IP_Port ip_port; |
57 | uint32_t ping_id; | 57 | uint64_t ping_id; |
58 | uint32_t timestamp; | 58 | uint32_t timestamp; |
59 | 59 | ||
60 | }Pinged; | 60 | }Pinged; |
61 | 61 | ||
62 | 62 | //Our client id/public key | |
63 | uint8_t self_client_id[CLIENT_ID_SIZE]; | 63 | uint8_t self_public_key[CLIENT_ID_SIZE]; |
64 | 64 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | |
65 | 65 | ||
66 | //TODO: Move these out of here and put them into the .c file. | 66 | //TODO: Move these out of here and put them into the .c file. |
67 | //A list of the clients mathematically closest to ours. | 67 | //A list of the clients mathematically closest to ours. |
68 | #define LCLIENT_LIST 32 | 68 | #define LCLIENT_LIST 32 |
69 | Client_data close_clientlist[LCLIENT_LIST]; | 69 | static Client_data close_clientlist[LCLIENT_LIST]; |
70 | 70 | ||
71 | 71 | ||
72 | //Hard maximum number of friends | 72 | //Hard maximum number of friends |
73 | #define MAX_FRIENDS 256 | 73 | #define MAX_FRIENDS 256 |
74 | 74 | ||
75 | //Let's start with a static array for testing. | 75 | //Let's start with a static array for testing. |
76 | Friend friends_list[MAX_FRIENDS]; | 76 | static Friend friends_list[MAX_FRIENDS]; |
77 | uint16_t num_friends; | 77 | static uint16_t num_friends; |
78 | 78 | ||
79 | //The list of ip ports along with the ping_id of what we sent them and a timestamp | 79 | //The list of ip ports along with the ping_id of what we sent them and a timestamp |
80 | #define LPING_ARRAY 128 | 80 | #define LPING_ARRAY 128 |
81 | 81 | ||
82 | Pinged pings[LPING_ARRAY]; | 82 | static Pinged pings[LPING_ARRAY]; |
83 | 83 | ||
84 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 | 84 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 |
85 | 85 | ||
86 | Pinged send_nodes[LSEND_NODES_ARRAY]; | 86 | static Pinged send_nodes[LSEND_NODES_ARRAY]; |
87 | 87 | ||
88 | 88 | ||
89 | //Compares client_id1 and client_id2 with client_id | 89 | //Compares client_id1 and client_id2 with client_id |
@@ -298,7 +298,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id) | |||
298 | if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) | 298 | if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) |
299 | { | 299 | { |
300 | //if we can't replace bad nodes we try replacing good ones | 300 | //if we can't replace bad nodes we try replacing good ones |
301 | replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_client_id); | 301 | replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key); |
302 | } | 302 | } |
303 | 303 | ||
304 | } | 304 | } |
@@ -310,7 +310,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id) | |||
310 | if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) | 310 | if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) |
311 | { | 311 | { |
312 | //if we can't replace bad nodes we try replacing good ones | 312 | //if we can't replace bad nodes we try replacing good ones |
313 | replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, self_client_id); | 313 | replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, self_public_key); |
314 | } | 314 | } |
315 | } | 315 | } |
316 | } | 316 | } |
@@ -324,7 +324,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id) | |||
324 | //if we are already, return 1 | 324 | //if we are already, return 1 |
325 | //else return 0 | 325 | //else return 0 |
326 | //TODO: Maybe optimize this | 326 | //TODO: Maybe optimize this |
327 | int is_pinging(IP_Port ip_port, uint32_t ping_id) | 327 | int is_pinging(IP_Port ip_port, uint64_t ping_id) |
328 | { | 328 | { |
329 | uint32_t i; | 329 | uint32_t i; |
330 | uint8_t pinging; | 330 | uint8_t pinging; |
@@ -364,7 +364,7 @@ int is_pinging(IP_Port ip_port, uint32_t ping_id) | |||
364 | 364 | ||
365 | 365 | ||
366 | //Same as last function but for get_node requests. | 366 | //Same as last function but for get_node requests. |
367 | int is_gettingnodes(IP_Port ip_port, uint32_t ping_id) | 367 | int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) |
368 | { | 368 | { |
369 | uint32_t i; | 369 | uint32_t i; |
370 | uint8_t pinging; | 370 | uint8_t pinging; |
@@ -407,10 +407,10 @@ int is_gettingnodes(IP_Port ip_port, uint32_t ping_id) | |||
407 | //returns the ping_id to put in the ping request | 407 | //returns the ping_id to put in the ping request |
408 | //returns 0 if problem. | 408 | //returns 0 if problem. |
409 | //TODO: Maybe optimize this | 409 | //TODO: Maybe optimize this |
410 | int add_pinging(IP_Port ip_port) | 410 | uint64_t add_pinging(IP_Port ip_port) |
411 | { | 411 | { |
412 | uint32_t i, j; | 412 | uint32_t i, j; |
413 | int ping_id = rand(); | 413 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
414 | uint32_t temp_time = unix_time(); | 414 | uint32_t temp_time = unix_time(); |
415 | 415 | ||
416 | for(i = 0; i < PING_TIMEOUT; i++ ) | 416 | for(i = 0; i < PING_TIMEOUT; i++ ) |
@@ -431,10 +431,10 @@ int add_pinging(IP_Port ip_port) | |||
431 | } | 431 | } |
432 | 432 | ||
433 | //Same but for get node requests | 433 | //Same but for get node requests |
434 | int add_gettingnodes(IP_Port ip_port) | 434 | uint64_t add_gettingnodes(IP_Port ip_port) |
435 | { | 435 | { |
436 | uint32_t i, j; | 436 | uint32_t i, j; |
437 | int ping_id = rand(); | 437 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
438 | uint32_t temp_time = unix_time(); | 438 | uint32_t temp_time = unix_time(); |
439 | 439 | ||
440 | for(i = 0; i < PING_TIMEOUT; i++ ) | 440 | for(i = 0; i < PING_TIMEOUT; i++ ) |
@@ -458,23 +458,38 @@ int add_gettingnodes(IP_Port ip_port) | |||
458 | 458 | ||
459 | //send a ping request | 459 | //send a ping request |
460 | //Ping request only works if none has been sent to that ip/port in the last 5 seconds. | 460 | //Ping request only works if none has been sent to that ip/port in the last 5 seconds. |
461 | int pingreq(IP_Port ip_port) | 461 | static int pingreq(IP_Port ip_port, uint8_t * public_key) |
462 | { | 462 | { |
463 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself | ||
464 | { | ||
465 | return 1; | ||
466 | } | ||
467 | |||
463 | if(is_pinging(ip_port, 0)) | 468 | if(is_pinging(ip_port, 0)) |
464 | { | 469 | { |
465 | return 1; | 470 | return 1; |
466 | } | 471 | } |
467 | 472 | ||
468 | int ping_id = add_pinging(ip_port); | 473 | uint64_t ping_id = add_pinging(ip_port); |
469 | if(ping_id == 0) | 474 | if(ping_id == 0) |
470 | { | 475 | { |
471 | return 1; | 476 | return 1; |
472 | } | 477 | } |
473 | 478 | ||
474 | uint8_t data[5 + CLIENT_ID_SIZE]; | 479 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; |
480 | uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; | ||
481 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
482 | random_nonce(nonce); | ||
483 | |||
484 | int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); | ||
485 | if(len != sizeof(ping_id) + ENCRYPTION_PADDING) | ||
486 | { | ||
487 | return -1; | ||
488 | } | ||
475 | data[0] = 0; | 489 | data[0] = 0; |
476 | memcpy(data + 1, &ping_id, 4); | 490 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); |
477 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); | 491 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
492 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | ||
478 | 493 | ||
479 | return sendpacket(ip_port, data, sizeof(data)); | 494 | return sendpacket(ip_port, data, sizeof(data)); |
480 | 495 | ||
@@ -482,65 +497,117 @@ int pingreq(IP_Port ip_port) | |||
482 | 497 | ||
483 | 498 | ||
484 | //send a ping response | 499 | //send a ping response |
485 | int pingres(IP_Port ip_port, uint32_t ping_id) | 500 | static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) |
486 | { | 501 | { |
487 | uint8_t data[5 + CLIENT_ID_SIZE]; | 502 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself |
488 | data[0] = 1; | 503 | { |
504 | return 1; | ||
505 | } | ||
489 | 506 | ||
490 | memcpy(data + 1, &ping_id, 4); | 507 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; |
491 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); | 508 | uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; |
509 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
510 | random_nonce(nonce); | ||
511 | |||
512 | int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); | ||
513 | if(len != sizeof(ping_id) + ENCRYPTION_PADDING) | ||
514 | { | ||
515 | return -1; | ||
516 | } | ||
517 | data[0] = 1; | ||
518 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | ||
519 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | ||
520 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | ||
492 | 521 | ||
493 | return sendpacket(ip_port, data, sizeof(data)); | 522 | return sendpacket(ip_port, data, sizeof(data)); |
494 | 523 | ||
495 | } | 524 | } |
496 | 525 | ||
497 | //send a getnodes request | 526 | //send a getnodes request |
498 | int getnodes(IP_Port ip_port, uint8_t * client_id) | 527 | static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) |
499 | { | 528 | { |
529 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself | ||
530 | { | ||
531 | return 1; | ||
532 | } | ||
533 | |||
500 | if(is_gettingnodes(ip_port, 0)) | 534 | if(is_gettingnodes(ip_port, 0)) |
501 | { | 535 | { |
502 | return 1; | 536 | return 1; |
503 | } | 537 | } |
504 | 538 | ||
505 | int ping_id = add_gettingnodes(ip_port); | 539 | uint64_t ping_id = add_gettingnodes(ip_port); |
506 | 540 | ||
507 | if(ping_id == 0) | 541 | if(ping_id == 0) |
508 | { | 542 | { |
509 | return 1; | 543 | return 1; |
510 | } | 544 | } |
511 | 545 | ||
512 | uint8_t data[5 + CLIENT_ID_SIZE*2]; | 546 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; |
513 | data[0] = 2; | 547 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; |
548 | uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; | ||
549 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
550 | random_nonce(nonce); | ||
514 | 551 | ||
515 | memcpy(data + 1, &ping_id, 4); | 552 | memcpy(plain, &ping_id, sizeof(ping_id)); |
516 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); | 553 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); |
517 | memcpy(data + 5 + CLIENT_ID_SIZE, client_id, CLIENT_ID_SIZE); | 554 | |
518 | 555 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); | |
556 | |||
557 | if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) | ||
558 | { | ||
559 | return -1; | ||
560 | } | ||
561 | data[0] = 2; | ||
562 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | ||
563 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | ||
564 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | ||
519 | return sendpacket(ip_port, data, sizeof(data)); | 565 | return sendpacket(ip_port, data, sizeof(data)); |
520 | 566 | ||
521 | } | 567 | } |
522 | 568 | ||
523 | 569 | ||
524 | //send a send nodes response | 570 | //send a send nodes response |
525 | int sendnodes(IP_Port ip_port, uint8_t * client_id, uint32_t ping_id) | 571 | static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) |
526 | { | 572 | { |
527 | uint8_t data[5 + CLIENT_ID_SIZE + (CLIENT_ID_SIZE + sizeof(IP_Port))*MAX_SENT_NODES]; | 573 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself |
574 | { | ||
575 | return 1; | ||
576 | } | ||
577 | |||
578 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | ||
579 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | ||
580 | |||
528 | Node_format nodes_list[MAX_SENT_NODES]; | 581 | Node_format nodes_list[MAX_SENT_NODES]; |
529 | |||
530 | int num_nodes = get_close_nodes(client_id, nodes_list); | 582 | int num_nodes = get_close_nodes(client_id, nodes_list); |
531 | 583 | ||
532 | if(num_nodes == 0) | 584 | if(num_nodes == 0) |
533 | { | 585 | { |
534 | return 0; | 586 | return 0; |
535 | } | 587 | } |
536 | 588 | ||
589 | uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; | ||
590 | uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | ||
591 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
592 | random_nonce(nonce); | ||
593 | |||
594 | memcpy(plain, &ping_id, sizeof(ping_id)); | ||
595 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); | ||
596 | |||
597 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, | ||
598 | sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); | ||
599 | |||
600 | if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) | ||
601 | { | ||
602 | return -1; | ||
603 | } | ||
604 | |||
537 | data[0] = 3; | 605 | data[0] = 3; |
538 | 606 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | |
539 | memcpy(data + 1, &ping_id, 4); | 607 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
540 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); | 608 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
541 | memcpy(data + 5 + CLIENT_ID_SIZE, nodes_list, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port))); | 609 | |
542 | 610 | return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | |
543 | return sendpacket(ip_port, data, 5 + CLIENT_ID_SIZE + num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port))); | ||
544 | 611 | ||
545 | } | 612 | } |
546 | 613 | ||
@@ -550,26 +617,32 @@ int sendnodes(IP_Port ip_port, uint8_t * client_id, uint32_t ping_id) | |||
550 | //Packet handling functions | 617 | //Packet handling functions |
551 | //One to handle each types of packets we receive | 618 | //One to handle each types of packets we receive |
552 | //return 0 if handled correctly, 1 if packet is bad. | 619 | //return 0 if handled correctly, 1 if packet is bad. |
553 | int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)//tested | 620 | int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) |
554 | { | 621 | { |
555 | if(length != 5 + CLIENT_ID_SIZE) | 622 | uint64_t ping_id; |
623 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) | ||
624 | { | ||
625 | return 1; | ||
626 | } | ||
627 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is from ourself. | ||
556 | { | 628 | { |
557 | return 1; | 629 | return 1; |
558 | } | 630 | } |
559 | 631 | ||
560 | uint32_t ping_id; | ||
561 | 632 | ||
562 | memcpy(&ping_id, packet + 1, 4); | ||
563 | IP_Port bad_ip = {{{0}}, 0}; | ||
564 | 633 | ||
565 | if(is_pinging(bad_ip, ping_id))//check if packet is from ourself. | 634 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
635 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
636 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); | ||
637 | if(len != sizeof(ping_id)) | ||
566 | { | 638 | { |
567 | return 1; | 639 | return 1; |
568 | } | 640 | } |
641 | |||
569 | 642 | ||
570 | pingres(source, ping_id); | 643 | pingres(source, packet + 1, ping_id); |
571 | 644 | ||
572 | pingreq(source); | 645 | pingreq(source, packet + 1);//TODO: make this smarter? |
573 | 646 | ||
574 | return 0; | 647 | return 0; |
575 | 648 | ||
@@ -577,16 +650,29 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)//tested | |||
577 | 650 | ||
578 | int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) | 651 | int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) |
579 | { | 652 | { |
580 | if(length != (5 + CLIENT_ID_SIZE)) | 653 | uint64_t ping_id; |
654 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) | ||
655 | { | ||
656 | return 1; | ||
657 | } | ||
658 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is from ourself. | ||
659 | { | ||
660 | return 1; | ||
661 | } | ||
662 | |||
663 | |||
664 | |||
665 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | ||
666 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
667 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); | ||
668 | if(len != sizeof(ping_id)) | ||
581 | { | 669 | { |
582 | return 1; | 670 | return 1; |
583 | } | 671 | } |
584 | uint32_t ping_id; | ||
585 | 672 | ||
586 | memcpy(&ping_id, packet + 1, 4); | ||
587 | if(is_pinging(source, ping_id)) | 673 | if(is_pinging(source, ping_id)) |
588 | { | 674 | { |
589 | addto_lists(source, packet + 5); | 675 | addto_lists(source, packet + 1); |
590 | return 0; | 676 | return 0; |
591 | } | 677 | } |
592 | return 1; | 678 | return 1; |
@@ -595,53 +681,80 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) | |||
595 | 681 | ||
596 | int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) | 682 | int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) |
597 | { | 683 | { |
598 | if(length != (5 + CLIENT_ID_SIZE*2)) | 684 | uint64_t ping_id; |
685 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) | ||
599 | { | 686 | { |
600 | return 1; | 687 | return 1; |
601 | } | 688 | } |
602 | uint32_t ping_id; | 689 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is from ourself. |
603 | memcpy(&ping_id, packet + 1, 4); | 690 | { |
604 | sendnodes(source, packet + 5 + CLIENT_ID_SIZE, ping_id); | 691 | return 1; |
692 | } | ||
693 | |||
694 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; | ||
605 | 695 | ||
606 | IP_Port bad_ip = {{{0}}, 0}; | 696 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
697 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
698 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); | ||
607 | 699 | ||
608 | if(is_gettingnodes(bad_ip, ping_id))//check if packet is from ourself. | 700 | if(len != sizeof(ping_id) + CLIENT_ID_SIZE) |
609 | { | 701 | { |
610 | return 1; | 702 | return 1; |
611 | } | 703 | } |
612 | 704 | ||
613 | pingreq(source); | 705 | |
706 | memcpy(&ping_id, plain, sizeof(ping_id)); | ||
707 | sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); | ||
708 | |||
709 | pingreq(source, packet + 1);//TODO: make this smarter? | ||
614 | 710 | ||
615 | return 0; | 711 | return 0; |
616 | 712 | ||
617 | } | 713 | } |
618 | 714 | ||
619 | int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)//tested | 715 | int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) |
620 | { | 716 | { |
621 | if(length > (5 + CLIENT_ID_SIZE + MAX_SENT_NODES * (CLIENT_ID_SIZE + sizeof(IP_Port))) || | 717 | uint64_t ping_id; |
622 | (length - 5 - CLIENT_ID_SIZE) % (CLIENT_ID_SIZE + sizeof(IP_Port)) != 0) | 718 | if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
719 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) || | ||
720 | (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | ||
721 | + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || | ||
722 | length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | ||
723 | + sizeof(Node_format) + ENCRYPTION_PADDING) | ||
623 | { | 724 | { |
624 | return 1; | 725 | return 1; |
625 | } | 726 | } |
626 | uint32_t num_nodes = (length - 5 - CLIENT_ID_SIZE) / (CLIENT_ID_SIZE + sizeof(IP_Port)); | 727 | uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES |
627 | uint32_t i; | 728 | + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format); |
628 | uint32_t ping_id; | 729 | |
730 | uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; | ||
731 | |||
732 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | ||
733 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
734 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); | ||
629 | 735 | ||
630 | memcpy(&ping_id, packet + 1, 4); | 736 | |
737 | if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) | ||
738 | { | ||
739 | return 1; | ||
740 | } | ||
741 | |||
742 | memcpy(&ping_id, plain, sizeof(ping_id)); | ||
631 | if(!is_gettingnodes(source, ping_id)) | 743 | if(!is_gettingnodes(source, ping_id)) |
632 | { | 744 | { |
633 | return 1; | 745 | return 1; |
634 | } | 746 | } |
635 | 747 | ||
636 | Node_format nodes_list[MAX_SENT_NODES]; | 748 | Node_format nodes_list[MAX_SENT_NODES]; |
637 | memcpy(nodes_list, packet + 5 + CLIENT_ID_SIZE, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port))); | 749 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); |
638 | 750 | ||
751 | uint32_t i; | ||
639 | for(i = 0; i < num_nodes; i++) | 752 | for(i = 0; i < num_nodes; i++) |
640 | { | 753 | { |
641 | pingreq(nodes_list[i].ip_port); | 754 | pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); |
642 | } | 755 | } |
643 | 756 | ||
644 | addto_lists(source, packet + 5); | 757 | addto_lists(source, packet + 1); |
645 | return 0; | 758 | return 0; |
646 | 759 | ||
647 | } | 760 | } |
@@ -772,7 +885,7 @@ void doDHTFriends() | |||
772 | { | 885 | { |
773 | if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) | 886 | if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) |
774 | { | 887 | { |
775 | pingreq(friends_list[i].client_list[j].ip_port); | 888 | pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); |
776 | friends_list[i].client_list[j].last_pinged = temp_time; | 889 | friends_list[i].client_list[j].last_pinged = temp_time; |
777 | } | 890 | } |
778 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. | 891 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. |
@@ -786,7 +899,8 @@ void doDHTFriends() | |||
786 | { | 899 | { |
787 | rand_node = rand() % num_nodes; | 900 | rand_node = rand() % num_nodes; |
788 | getnodes(friends_list[i].client_list[index[rand_node]].ip_port, | 901 | getnodes(friends_list[i].client_list[index[rand_node]].ip_port, |
789 | friends_list[i].client_list[index[rand_node]].client_id); | 902 | friends_list[i].client_list[index[rand_node]].client_id, |
903 | friends_list[i].client_id); | ||
790 | friend_lastgetnode[i] = temp_time; | 904 | friend_lastgetnode[i] = temp_time; |
791 | } | 905 | } |
792 | } | 906 | } |
@@ -810,7 +924,7 @@ void doClose()//tested | |||
810 | { | 924 | { |
811 | if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) | 925 | if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) |
812 | { | 926 | { |
813 | pingreq(close_clientlist[i].ip_port); | 927 | pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); |
814 | close_clientlist[i].last_pinged = temp_time; | 928 | close_clientlist[i].last_pinged = temp_time; |
815 | } | 929 | } |
816 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. | 930 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. |
@@ -825,7 +939,8 @@ void doClose()//tested | |||
825 | { | 939 | { |
826 | rand_node = rand() % num_nodes; | 940 | rand_node = rand() % num_nodes; |
827 | getnodes(close_clientlist[index[rand_node]].ip_port, | 941 | getnodes(close_clientlist[index[rand_node]].ip_port, |
828 | close_clientlist[index[rand_node]].client_id); | 942 | close_clientlist[index[rand_node]].client_id, |
943 | self_public_key); | ||
829 | close_lastgetnodes = temp_time; | 944 | close_lastgetnodes = temp_time; |
830 | } | 945 | } |
831 | 946 | ||
@@ -842,10 +957,10 @@ void doDHT() | |||
842 | 957 | ||
843 | 958 | ||
844 | 959 | ||
845 | void DHT_bootstrap(IP_Port ip_port) | 960 | void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) |
846 | { | 961 | { |
847 | 962 | ||
848 | getnodes(ip_port, self_client_id); | 963 | getnodes(ip_port, public_key, self_public_key); |
849 | 964 | ||
850 | } | 965 | } |
851 | 966 | ||