diff options
-rw-r--r-- | toxcore/DHT.c | 119 |
1 files changed, 112 insertions, 7 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index a4734747..7663b1cc 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -137,19 +137,23 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id | |||
137 | uint32_t i; | 137 | uint32_t i; |
138 | uint64_t temp_time = unix_time(); | 138 | uint64_t temp_time = unix_time(); |
139 | 139 | ||
140 | for (i = 0; i < length; ++i) { | 140 | /* if client_id is in list, find it and maybe overwrite ip_port */ |
141 | /* If ip_port is assigned to a different client_id replace it */ | 141 | for (i = 0; i < length; ++i) |
142 | if (ipport_equal(&list[i].ip_port, &ip_port)) { | 142 | if (id_equal(list[i].client_id, client_id)) { |
143 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 143 | /* Refresh the client timestamp. */ |
144 | list[i].timestamp = temp_time; | ||
145 | list[i].ip_port = ip_port; | ||
146 | return 1; | ||
144 | } | 147 | } |
145 | 148 | ||
146 | if (id_equal(list[i].client_id, client_id)) { | 149 | /* client_id not in list yet: find ip_port to overwrite */ |
150 | for (i = 0; i < length; ++i) | ||
151 | if (ipport_equal(&list[i].ip_port, &ip_port)) { | ||
147 | /* Refresh the client timestamp. */ | 152 | /* Refresh the client timestamp. */ |
148 | list[i].timestamp = temp_time; | 153 | list[i].timestamp = temp_time; |
149 | ipport_copy(&list[i].ip_port, &ip_port); | 154 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
150 | return 1; | 155 | return 1; |
151 | } | 156 | } |
152 | } | ||
153 | 157 | ||
154 | return 0; | 158 | return 0; |
155 | } | 159 | } |
@@ -610,6 +614,54 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl | |||
610 | return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | 614 | return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); |
611 | } | 615 | } |
612 | 616 | ||
617 | #ifdef TOX_ENABLE_IPV6 | ||
618 | /* Send a send nodes response: message for IPv6 nodes */ | ||
619 | static int sendnodes_ex(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) | ||
620 | { | ||
621 | /* Check if packet is going to be sent to ourself. */ | ||
622 | if (id_equal(public_key, dht->c->self_public_key)) | ||
623 | return -1; | ||
624 | |||
625 | size_t Node_format_size = sizeof(Node_format); | ||
626 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | ||
627 | + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; | ||
628 | |||
629 | Node_format nodes_list[MAX_SENT_NODES]; | ||
630 | int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET6); | ||
631 | |||
632 | if (num_nodes == 0) | ||
633 | return 0; | ||
634 | |||
635 | uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; | ||
636 | uint8_t encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; | ||
637 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
638 | random_nonce(nonce); | ||
639 | |||
640 | memcpy(plain, &ping_id, sizeof(ping_id)); | ||
641 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size); | ||
642 | |||
643 | int len = encrypt_data( public_key, | ||
644 | dht->c->self_secret_key, | ||
645 | nonce, | ||
646 | plain, | ||
647 | sizeof(ping_id) + num_nodes * Node_format_size, | ||
648 | encrypt ); | ||
649 | |||
650 | if (len == -1) | ||
651 | return -1; | ||
652 | |||
653 | if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size + ENCRYPTION_PADDING) | ||
654 | return -1; | ||
655 | |||
656 | data[0] = NET_PACKET_SEND_NODES_EX; | ||
657 | memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); | ||
658 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | ||
659 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | ||
660 | |||
661 | return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | ||
662 | } | ||
663 | #endif | ||
664 | |||
613 | static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 665 | static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
614 | { | 666 | { |
615 | DHT *dht = object; | 667 | DHT *dht = object; |
@@ -637,6 +689,9 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32 | |||
637 | 689 | ||
638 | memcpy(&ping_id, plain, sizeof(ping_id)); | 690 | memcpy(&ping_id, plain, sizeof(ping_id)); |
639 | sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); | 691 | sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); |
692 | #ifdef TOX_ENABLE_IPV6 | ||
693 | sendnodes_ex(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); | ||
694 | #endif | ||
640 | 695 | ||
641 | //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ | 696 | //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ |
642 | 697 | ||
@@ -709,6 +764,53 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 | |||
709 | return 0; | 764 | return 0; |
710 | } | 765 | } |
711 | 766 | ||
767 | #ifdef TOX_ENABLE_IPV6 | ||
768 | static int handle_sendnodes_ex(void *object, IP_Port source, uint8_t *packet, uint32_t length) | ||
769 | { | ||
770 | DHT *dht = object; | ||
771 | uint64_t ping_id; | ||
772 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; | ||
773 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; | ||
774 | |||
775 | size_t Node_format_size = sizeof(Node4_format); | ||
776 | if (length > (cid_size + Node_format_size * MAX_SENT_NODES) || | ||
777 | ((length - cid_size) % Node_format_size) != 0 || | ||
778 | (length < cid_size + Node_format_size)) | ||
779 | return 1; | ||
780 | |||
781 | uint32_t num_nodes = (length - cid_size) / Node_format_size; | ||
782 | uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; | ||
783 | |||
784 | int len = decrypt_data( | ||
785 | packet + 1, | ||
786 | dht->c->self_secret_key, | ||
787 | packet + 1 + CLIENT_ID_SIZE, | ||
788 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
789 | sizeof(ping_id) + num_nodes * Node_format_size + ENCRYPTION_PADDING, plain ); | ||
790 | |||
791 | if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size) | ||
792 | return 1; | ||
793 | |||
794 | memcpy(&ping_id, plain, sizeof(ping_id)); | ||
795 | |||
796 | if (!is_gettingnodes(dht, source, ping_id)) | ||
797 | return 1; | ||
798 | |||
799 | uint32_t i; | ||
800 | Node_format nodes_list[MAX_SENT_NODES]; | ||
801 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); | ||
802 | |||
803 | addto_lists(dht, source, packet + 1); | ||
804 | |||
805 | for (i = 0; i < num_nodes; ++i) { | ||
806 | send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id); | ||
807 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | ||
808 | } | ||
809 | |||
810 | return 0; | ||
811 | } | ||
812 | #endif | ||
813 | |||
712 | /*----------------------------------------------------------------------------------*/ | 814 | /*----------------------------------------------------------------------------------*/ |
713 | /*------------------------END of packet handling functions--------------------------*/ | 815 | /*------------------------END of packet handling functions--------------------------*/ |
714 | 816 | ||
@@ -1293,6 +1395,9 @@ DHT *new_DHT(Net_Crypto *c) | |||
1293 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, temp); | 1395 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, temp); |
1294 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, temp); | 1396 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, temp); |
1295 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, temp); | 1397 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, temp); |
1398 | #ifdef TOX_ENABLE_IPV6 | ||
1399 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_EX, &handle_sendnodes_ex, temp); | ||
1400 | #endif | ||
1296 | init_cryptopackets(temp); | 1401 | init_cryptopackets(temp); |
1297 | cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, temp); | 1402 | cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, temp); |
1298 | return temp; | 1403 | return temp; |