summaryrefslogtreecommitdiff
path: root/core/DHT.c
diff options
context:
space:
mode:
authorcharmlesscoin <charmlesscoin@gmail.com>2013-08-06 20:58:42 -0400
committercharmlesscoin <charmlesscoin@gmail.com>2013-08-06 20:58:42 -0400
commitc644ccd28782e9d74f5962a97a0973551fb7afe2 (patch)
tree42f892aea55a6394d5d6ff0dbace2214675cbd71 /core/DHT.c
parent95a3f69580749b8fcabf92cc2ace757d61fa34de (diff)
parentd04f2d0e51931db5fbd8c672c44bb1e59fc58b79 (diff)
Merge branch 'master' of git://github.com/irungentoo/ProjectTox-Core
Diffstat (limited to 'core/DHT.c')
-rw-r--r--core/DHT.c142
1 files changed, 11 insertions, 131 deletions
diff --git a/core/DHT.c b/core/DHT.c
index f0b32df5..b5224b8f 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -24,6 +24,7 @@
24/*----------------------------------------------------------------------------------*/ 24/*----------------------------------------------------------------------------------*/
25 25
26#include "DHT.h" 26#include "DHT.h"
27#include "packets.h"
27#include "ping.h" 28#include "ping.h"
28 29
29/* maximum number of clients stored per friend. */ 30/* maximum number of clients stored per friend. */
@@ -351,7 +352,7 @@ static int replace_good( Client_data * list,
351/* Attempt to add client with ip_port and client_id to the friends client list 352/* Attempt to add client with ip_port and client_id to the friends client list
352 * and close_clientlist 353 * and close_clientlist
353 */ 354 */
354static void addto_lists(IP_Port ip_port, uint8_t * client_id) 355void addto_lists(IP_Port ip_port, uint8_t * client_id)
355{ 356{
356 uint32_t i; 357 uint32_t i;
357 358
@@ -472,71 +473,6 @@ static uint64_t add_gettingnodes(IP_Port ip_port)
472 return 0; 473 return 0;
473} 474}
474 475
475/* send a ping request, only works if none has been sent to that ip/port
476 * in the last 5 seconds.
477 */
478static int pingreq(IP_Port ip_port, uint8_t * public_key)
479{
480 /* check if packet is gonna be sent to ourself */
481 if(id_equal(public_key, self_public_key) || is_pinging(ip_port, 0))
482 return 1;
483
484 uint64_t ping_id = add_ping(ip_port);
485 if(ping_id == 0)
486 return 1;
487
488 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING];
489 uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING];
490 uint8_t nonce[crypto_box_NONCEBYTES];
491 random_nonce(nonce);
492
493 int len = encrypt_data( public_key,
494 self_secret_key,
495 nonce,
496 (uint8_t *)&ping_id,
497 sizeof(ping_id),
498 encrypt );
499
500 if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
501 return -1;
502
503 data[0] = 0;
504 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
505 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
506 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
507
508 return sendpacket(ip_port, data, sizeof(data));
509}
510
511/* send a ping response */
512static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
513{
514 /* check if packet is gonna be sent to ourself */
515 if(id_equal(public_key, self_public_key))
516 return 1;
517
518 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING];
519 uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING];
520 uint8_t nonce[crypto_box_NONCEBYTES];
521 random_nonce(nonce);
522
523 int len = encrypt_data( public_key,
524 self_secret_key, nonce,
525 (uint8_t *)&ping_id,
526 sizeof(ping_id),
527 encrypt );
528
529 if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
530 return -1;
531
532 data[0] = 1;
533 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
534 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
535 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
536
537 return sendpacket(ip_port, data, sizeof(data));
538}
539
540/* send a getnodes request */ 476/* send a getnodes request */
541static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) 477static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
542{ 478{
@@ -618,62 +554,6 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
618 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 554 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
619} 555}
620 556
621/* Packet handling functions, one to handle each types of packets we receive
622 * Returns 0 if handled correctly, 1 if packet is bad.
623 */
624static int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
625{
626 uint64_t ping_id;
627 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
628 return 1;
629
630 /* check if packet is from ourself. */
631 if(id_equal(packet + 1, self_public_key))
632 return 1;
633
634 int len = decrypt_data( packet + 1,
635 self_secret_key,
636 packet + 1 + CLIENT_ID_SIZE,
637 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
638 sizeof(ping_id) + ENCRYPTION_PADDING,
639 (uint8_t *)&ping_id );
640
641 if(len != sizeof(ping_id))
642 return 1;
643
644 pingres(source, packet + 1, ping_id);
645 pingreq(source, packet + 1); /* TODO: make this smarter? */
646
647 return 0;
648}
649
650static int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
651{
652 uint64_t ping_id;
653 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
654 return 1;
655
656 /* check if packet is from ourself. */
657 if(id_equal(packet + 1, self_public_key))
658 return 1;
659
660 int len = decrypt_data( packet + 1,
661 self_secret_key,
662 packet + 1 + CLIENT_ID_SIZE,
663 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
664 sizeof(ping_id) + ENCRYPTION_PADDING,
665 (uint8_t *)&ping_id );
666
667 if(len != sizeof(ping_id))
668 return 1;
669
670 if(is_pinging(source, ping_id)) {
671 addto_lists(source, packet + 1);
672 return 0;
673 }
674 return 1;
675}
676
677static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) 557static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
678{ 558{
679 uint64_t ping_id; 559 uint64_t ping_id;
@@ -701,7 +581,7 @@ static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
701 memcpy(&ping_id, plain, sizeof(ping_id)); 581 memcpy(&ping_id, plain, sizeof(ping_id));
702 sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); 582 sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id);
703 583
704 pingreq(source, packet + 1); /* TODO: make this smarter? */ 584 send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */
705 585
706 return 0; 586 return 0;
707} 587}
@@ -741,7 +621,7 @@ static int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
741 621
742 uint32_t i; 622 uint32_t i;
743 for(i = 0; i < num_nodes; ++i) { 623 for(i = 0; i < num_nodes; ++i) {
744 pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); 624 send_ping_request(nodes_list[i].ip_port, (clientid_t*) &nodes_list[i].client_id);
745 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 625 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
746 } 626 }
747 627
@@ -831,8 +711,8 @@ static void doDHTFriends(void)
831 /* if node is not dead. */ 711 /* if node is not dead. */
832 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { 712 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) {
833 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 713 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
834 pingreq( friends_list[i].client_list[j].ip_port, 714 send_ping_request( friends_list[i].client_list[j].ip_port,
835 friends_list[i].client_list[j].client_id ); 715 (clientid_t*) &friends_list[i].client_list[j].client_id );
836 friends_list[i].client_list[j].last_pinged = temp_time; 716 friends_list[i].client_list[j].last_pinged = temp_time;
837 } 717 }
838 /* if node is good. */ 718 /* if node is good. */
@@ -869,8 +749,8 @@ static void doClose(void)
869 /* if node is not dead. */ 749 /* if node is not dead. */
870 if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { 750 if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) {
871 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { 751 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
872 pingreq( close_clientlist[i].ip_port, 752 send_ping_request( close_clientlist[i].ip_port,
873 close_clientlist[i].client_id ); 753 (clientid_t*) &close_clientlist[i].client_id );
874 close_clientlist[i].last_pinged = temp_time; 754 close_clientlist[i].last_pinged = temp_time;
875 } 755 }
876 /* if node is good. */ 756 /* if node is good. */
@@ -1151,7 +1031,7 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t
1151 /*TODO: improve port guessing algorithm*/ 1031 /*TODO: improve port guessing algorithm*/
1152 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); 1032 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1);
1153 IP_Port pinging = {ip, htons(port)}; 1033 IP_Port pinging = {ip, htons(port)};
1154 pingreq(pinging, friends_list[friend_num].client_id); 1034 send_ping_request(pinging, (clientid_t*) &friends_list[friend_num].client_id);
1155 } 1035 }
1156 friends_list[friend_num].punching_index = i; 1036 friends_list[friend_num].punching_index = i;
1157} 1037}
@@ -1198,10 +1078,10 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
1198{ 1078{
1199 switch (packet[0]) { 1079 switch (packet[0]) {
1200 case 0: 1080 case 0:
1201 return handle_pingreq(packet, length, source); 1081 return handle_ping_request(packet, length, source);
1202 1082
1203 case 1: 1083 case 1:
1204 return handle_pingres(packet, length, source); 1084 return handle_ping_response(packet, length, source);
1205 1085
1206 case 2: 1086 case 2:
1207 return handle_getnodes(packet, length, source); 1087 return handle_getnodes(packet, length, source);