diff options
author | irungentoo <irungentoo@gmail.com> | 2013-10-24 17:39:14 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2013-10-24 17:39:14 -0400 |
commit | f7b90f10602e054544649920832548d8f55d3e48 (patch) | |
tree | 6ffc7638d10e339cd60fdd3711db6158dec97734 /toxcore/DHT.c | |
parent | 2fdc412e364fc67fc54a48b1da816b380117ddd5 (diff) |
Adding encrypted data to send/getnode packets now done.
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r-- | toxcore/DHT.c | 111 |
1 files changed, 83 insertions, 28 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index fc7fd66f..ca78816d 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #define MAX_SENT_NODES 8 | 41 | #define MAX_SENT_NODES 8 |
42 | 42 | ||
43 | /* Ping timeout in seconds */ | 43 | /* Ping timeout in seconds */ |
44 | #define PING_TIMEOUT 5 | 44 | #define PING_TIMEOUT 3 |
45 | 45 | ||
46 | /* The timeout after which a node is discarded completely. */ | 46 | /* The timeout after which a node is discarded completely. */ |
47 | #define KILL_NODE_TIMEOUT 300 | 47 | #define KILL_NODE_TIMEOUT 300 |
@@ -630,10 +630,11 @@ static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port) | |||
630 | return 0; | 630 | return 0; |
631 | } | 631 | } |
632 | 632 | ||
633 | #define NODES_ENCRYPTED_MESSAGE_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(Node_format) + crypto_secretbox_MACBYTES) | 633 | #define NODES_ENCRYPTED_MESSAGE_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint64_t) + sizeof(Node_format) + sizeof(Node_format) + crypto_secretbox_MACBYTES) |
634 | 634 | ||
635 | /* Send a getnodes request. */ | 635 | /* Send a getnodes request. |
636 | static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | 636 | sendback_node is the node that it will send back the response to (set to NULL to disable this) */ |
637 | static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, Node_format *sendback_node) | ||
637 | { | 638 | { |
638 | /* Check if packet is going to be sent to ourself. */ | 639 | /* Check if packet is going to be sent to ourself. */ |
639 | if (id_equal(public_key, dht->c->self_public_key) || is_gettingnodes(dht, ip_port, 0)) | 640 | if (id_equal(public_key, dht->c->self_public_key) || is_gettingnodes(dht, ip_port, 0)) |
@@ -644,23 +645,50 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli | |||
644 | if (ping_id == 0) | 645 | if (ping_id == 0) |
645 | return -1; | 646 | return -1; |
646 | 647 | ||
647 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + crypto_box_MACBYTES]; | 648 | |
648 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; | 649 | uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH] = {0}; |
649 | uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + crypto_box_MACBYTES]; | 650 | uint8_t encrypted_message[NODES_ENCRYPTED_MESSAGE_LENGTH]; |
650 | uint8_t nonce[crypto_box_NONCEBYTES]; | 651 | uint8_t nonce[crypto_box_NONCEBYTES]; |
652 | |||
651 | new_nonce(nonce); | 653 | new_nonce(nonce); |
654 | memcpy(encrypted_message, nonce, crypto_box_NONCEBYTES); | ||
655 | |||
656 | uint64_t temp_time = unix_time(); | ||
657 | memcpy(plain_message, &temp_time, sizeof(temp_time)); | ||
658 | Node_format reciever; | ||
659 | memcpy(reciever.client_id, public_key, CLIENT_ID_SIZE); | ||
660 | reciever.ip_port = ip_port; | ||
661 | memcpy(plain_message + sizeof(temp_time), &reciever, sizeof(reciever)); | ||
662 | |||
663 | if (sendback_node != NULL) | ||
664 | memcpy(plain_message + sizeof(temp_time) + sizeof(reciever), sendback_node, sizeof(Node_format)); | ||
665 | |||
666 | int len_m = encrypt_data_symmetric(dht->secret_symmetric_key, | ||
667 | nonce, | ||
668 | plain_message, | ||
669 | sizeof(temp_time) + sizeof(reciever) + sizeof(Node_format), | ||
670 | encrypted_message + crypto_secretbox_NONCEBYTES); | ||
671 | |||
672 | if (len_m != NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES) | ||
673 | return -1; | ||
674 | |||
675 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; | ||
676 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH]; | ||
677 | uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; | ||
678 | |||
652 | 679 | ||
653 | memcpy(plain, &ping_id, sizeof(ping_id)); | 680 | memcpy(plain, &ping_id, sizeof(ping_id)); |
654 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); | 681 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); |
682 | memcpy(plain + sizeof(ping_id) + CLIENT_ID_SIZE, encrypted_message, NODES_ENCRYPTED_MESSAGE_LENGTH); | ||
655 | 683 | ||
656 | int len = encrypt_data( public_key, | 684 | int len = encrypt_data( public_key, |
657 | dht->c->self_secret_key, | 685 | dht->c->self_secret_key, |
658 | nonce, | 686 | nonce, |
659 | plain, | 687 | plain, |
660 | sizeof(ping_id) + CLIENT_ID_SIZE, | 688 | sizeof(ping_id) + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH, |
661 | encrypt ); | 689 | encrypt ); |
662 | 690 | ||
663 | if (len != sizeof(ping_id) + CLIENT_ID_SIZE + crypto_box_MACBYTES) | 691 | if (len != sizeof(ping_id) + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES) |
664 | return -1; | 692 | return -1; |
665 | 693 | ||
666 | data[0] = NET_PACKET_GET_NODES; | 694 | data[0] = NET_PACKET_GET_NODES; |
@@ -825,13 +853,37 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32 | |||
825 | 853 | ||
826 | return 0; | 854 | return 0; |
827 | } | 855 | } |
856 | /* return 0 if no | ||
857 | return 1 if yes | ||
858 | encrypted_data must be of size NODES_ENCRYPTED_MESSAGE_LENGTH*/ | ||
859 | static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_ip_port, uint8_t *encrypted_data, | ||
860 | Node_format *sendback_node) | ||
861 | { | ||
862 | uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH]; | ||
863 | |||
864 | if (decrypt_data_symmetric(dht->secret_symmetric_key, encrypted_data, encrypted_data + crypto_secretbox_NONCEBYTES, | ||
865 | NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES, | ||
866 | plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2) | ||
867 | return 0; | ||
868 | uint64_t comp_time; | ||
869 | memcpy(&comp_time, plain_message, sizeof(uint64_t)); | ||
870 | if (comp_time + PING_TIMEOUT > unix_time() || unix_time() < comp_time) | ||
871 | return 0; | ||
872 | Node_format test; | ||
873 | memcpy(&test, plain_message + sizeof(uint64_t), sizeof(Node_format)); | ||
874 | if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.client_id, client_id, CLIENT_ID_SIZE) != 0) | ||
875 | return 0; | ||
876 | |||
877 | memcpy(sendback_node, plain_message + sizeof(uint64_t) + sizeof(Node_format), sizeof(Node_format)); | ||
878 | return 1; | ||
879 | } | ||
828 | 880 | ||
829 | static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 881 | static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
830 | { | 882 | { |
831 | DHT *dht = object; | 883 | DHT *dht = object; |
832 | uint64_t ping_id; | 884 | uint64_t ping_id; |
833 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; | 885 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; |
834 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + crypto_box_MACBYTES; | 886 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES; |
835 | 887 | ||
836 | size_t Node4_format_size = sizeof(Node4_format); | 888 | size_t Node4_format_size = sizeof(Node4_format); |
837 | 889 | ||
@@ -841,21 +893,23 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 | |||
841 | return 1; | 893 | return 1; |
842 | 894 | ||
843 | uint32_t num_nodes = (length - cid_size) / Node4_format_size; | 895 | uint32_t num_nodes = (length - cid_size) / Node4_format_size; |
844 | uint8_t plain[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES]; | 896 | uint8_t plain[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; |
845 | 897 | ||
846 | int len = decrypt_data( | 898 | int len = decrypt_data( |
847 | packet + 1, | 899 | packet + 1, |
848 | dht->c->self_secret_key, | 900 | dht->c->self_secret_key, |
849 | packet + 1 + CLIENT_ID_SIZE, | 901 | packet + 1 + CLIENT_ID_SIZE, |
850 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 902 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
851 | sizeof(ping_id) + num_nodes * Node4_format_size + crypto_box_MACBYTES, plain ); | 903 | sizeof(ping_id) + num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, plain ); |
852 | 904 | ||
853 | if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node4_format_size) | 905 | if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH) |
854 | return 1; | 906 | return 1; |
855 | 907 | ||
856 | memcpy(&ping_id, plain, sizeof(ping_id)); | 908 | memcpy(&ping_id, plain, sizeof(ping_id)); |
857 | 909 | ||
858 | if (!is_gettingnodes(dht, source, ping_id)) | 910 | //if (!is_gettingnodes(dht, source, ping_id)) |
911 | Node_format sendback_node; | ||
912 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + sizeof(ping_id) + num_nodes * Node4_format_size, &sendback_node)) | ||
859 | return 1; | 913 | return 1; |
860 | 914 | ||
861 | Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); | 915 | Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); |
@@ -893,7 +947,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, | |||
893 | DHT *dht = object; | 947 | DHT *dht = object; |
894 | uint64_t ping_id; | 948 | uint64_t ping_id; |
895 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; | 949 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; |
896 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + crypto_box_MACBYTES; | 950 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES; |
897 | 951 | ||
898 | size_t Node_format_size = sizeof(Node_format); | 952 | size_t Node_format_size = sizeof(Node_format); |
899 | 953 | ||
@@ -903,21 +957,23 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, | |||
903 | return 1; | 957 | return 1; |
904 | 958 | ||
905 | uint32_t num_nodes = (length - cid_size) / Node_format_size; | 959 | uint32_t num_nodes = (length - cid_size) / Node_format_size; |
906 | uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; | 960 | uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; |
907 | 961 | ||
908 | int len = decrypt_data( | 962 | int len = decrypt_data( |
909 | packet + 1, | 963 | packet + 1, |
910 | dht->c->self_secret_key, | 964 | dht->c->self_secret_key, |
911 | packet + 1 + CLIENT_ID_SIZE, | 965 | packet + 1 + CLIENT_ID_SIZE, |
912 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 966 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
913 | sizeof(ping_id) + num_nodes * Node_format_size + crypto_box_MACBYTES, plain ); | 967 | sizeof(ping_id) + num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, plain ); |
914 | 968 | ||
915 | if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size) | 969 | if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH) |
916 | return 1; | 970 | return 1; |
917 | 971 | ||
918 | memcpy(&ping_id, plain, sizeof(ping_id)); | 972 | memcpy(&ping_id, plain, sizeof(ping_id)); |
919 | 973 | ||
920 | if (!is_gettingnodes(dht, source, ping_id)) | 974 | //if (!is_gettingnodes(dht, source, ping_id)) |
975 | Node_format sendback_node; | ||
976 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + sizeof(ping_id) + num_nodes * Node_format_size, &sendback_node)) | ||
921 | return 1; | 977 | return 1; |
922 | 978 | ||
923 | uint32_t i; | 979 | uint32_t i; |
@@ -952,7 +1008,7 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_ | |||
952 | for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4) | 1008 | for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4) |
953 | if (ipport_isset(&(assoc->ip_port)) && | 1009 | if (ipport_isset(&(assoc->ip_port)) && |
954 | !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { | 1010 | !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { |
955 | getnodes(dht, assoc->ip_port, list[i].client_id, client_id); | 1011 | getnodes(dht, assoc->ip_port, list[i].client_id, client_id, NULL); |
956 | ++num; | 1012 | ++num; |
957 | 1013 | ||
958 | if (num >= max_num) | 1014 | if (num >= max_num) |
@@ -1087,7 +1143,7 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8 | |||
1087 | is_timeout(temp_time, *lastgetnode, GET_NODE_INTERVAL)) { | 1143 | is_timeout(temp_time, *lastgetnode, GET_NODE_INTERVAL)) { |
1088 | uint32_t rand_node = rand() % num_nodes; | 1144 | uint32_t rand_node = rand() % num_nodes; |
1089 | getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id, | 1145 | getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id, |
1090 | client_id); | 1146 | client_id, NULL); |
1091 | *lastgetnode = temp_time; | 1147 | *lastgetnode = temp_time; |
1092 | } | 1148 | } |
1093 | } | 1149 | } |
@@ -1115,7 +1171,7 @@ static void do_Close(DHT *dht) | |||
1115 | 1171 | ||
1116 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) | 1172 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) |
1117 | { | 1173 | { |
1118 | getnodes(dht, ip_port, public_key, dht->c->self_public_key); | 1174 | getnodes(dht, ip_port, public_key, dht->c->self_public_key, NULL); |
1119 | } | 1175 | } |
1120 | int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, | 1176 | int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, |
1121 | uint16_t port, uint8_t *public_key) | 1177 | uint16_t port, uint8_t *public_key) |
@@ -1585,10 +1641,9 @@ DHT *new_DHT(Net_Crypto *c) | |||
1585 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); | 1641 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); |
1586 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht); | 1642 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht); |
1587 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); | 1643 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); |
1588 | |||
1589 | init_cryptopackets(dht); | 1644 | init_cryptopackets(dht); |
1590 | cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); | 1645 | cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); |
1591 | 1646 | new_symmetric_key(dht->secret_symmetric_key); | |
1592 | return dht; | 1647 | return dht; |
1593 | } | 1648 | } |
1594 | 1649 | ||
@@ -1658,7 +1713,7 @@ int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size) | |||
1658 | client = &tempfriends_list[i].client_list[j]; | 1713 | client = &tempfriends_list[i].client_list[j]; |
1659 | 1714 | ||
1660 | if (client->assoc.timestamp != 0) | 1715 | if (client->assoc.timestamp != 0) |
1661 | getnodes(dht, client->assoc.ip_port, client->client_id, tempfriends_list[i].client_id); | 1716 | getnodes(dht, client->assoc.ip_port, client->client_id, tempfriends_list[i].client_id, NULL); |
1662 | } | 1717 | } |
1663 | } | 1718 | } |
1664 | } | 1719 | } |
@@ -1768,7 +1823,7 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length, | |||
1768 | Client_data_old *client = &friend_list[i].client_list[j]; | 1823 | Client_data_old *client = &friend_list[i].client_list[j]; |
1769 | 1824 | ||
1770 | if (client->assoc.timestamp != 0) | 1825 | if (client->assoc.timestamp != 0) |
1771 | getnodes(dht, client->assoc.ip_port, client->client_id, friend_list[i].client_id); | 1826 | getnodes(dht, client->assoc.ip_port, client->client_id, friend_list[i].client_id, NULL); |
1772 | } | 1827 | } |
1773 | } | 1828 | } |
1774 | } /* localize declarations */ | 1829 | } /* localize declarations */ |
@@ -1805,10 +1860,10 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length, | |||
1805 | Client_data *client = &friend_list[i].client_list[j]; | 1860 | Client_data *client = &friend_list[i].client_list[j]; |
1806 | 1861 | ||
1807 | if (client->assoc4.timestamp != 0) | 1862 | if (client->assoc4.timestamp != 0) |
1808 | getnodes(dht, client->assoc4.ip_port, client->client_id, friend_list[i].client_id); | 1863 | getnodes(dht, client->assoc4.ip_port, client->client_id, friend_list[i].client_id, NULL); |
1809 | 1864 | ||
1810 | if (client->assoc6.timestamp != 0) | 1865 | if (client->assoc6.timestamp != 0) |
1811 | getnodes(dht, client->assoc6.ip_port, client->client_id, friend_list[i].client_id); | 1866 | getnodes(dht, client->assoc6.ip_port, client->client_id, friend_list[i].client_id, NULL); |
1812 | } | 1867 | } |
1813 | } | 1868 | } |
1814 | } /* localize declarations */ | 1869 | } /* localize declarations */ |