summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toxcore/DHT.c119
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 */
619static 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
613static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 665static 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
768static 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;