diff options
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/DHT.c | 109 |
1 files changed, 105 insertions, 4 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 661ac98a..60e8b88f 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -765,7 +765,8 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32 | |||
765 | { | 765 | { |
766 | DHT *dht = object; | 766 | DHT *dht = object; |
767 | 767 | ||
768 | if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES )) | 768 | if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + |
769 | crypto_box_MACBYTES )) | ||
769 | return 1; | 770 | return 1; |
770 | 771 | ||
771 | /* Check if packet is from ourself. */ | 772 | /* Check if packet is from ourself. */ |
@@ -785,7 +786,8 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32 | |||
785 | return 1; | 786 | return 1; |
786 | 787 | ||
787 | sendnodes(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE); | 788 | sendnodes(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE); |
788 | sendnodes_ipv6(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE); /* TODO: prevent possible amplification attacks */ | 789 | sendnodes_ipv6(dht, source, packet + 1, plain, |
790 | plain + CLIENT_ID_SIZE); /* TODO: prevent possible amplification attacks */ | ||
789 | 791 | ||
790 | add_toping(dht->ping, packet + 1, source); | 792 | add_toping(dht->ping, packet + 1, source); |
791 | //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ | 793 | //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ |
@@ -804,13 +806,17 @@ static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_i | |||
804 | NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES, | 806 | NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES, |
805 | plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2) | 807 | plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2) |
806 | return 0; | 808 | return 0; |
809 | |||
807 | uint64_t comp_time; | 810 | uint64_t comp_time; |
808 | memcpy(&comp_time, plain_message, sizeof(uint64_t)); | 811 | memcpy(&comp_time, plain_message, sizeof(uint64_t)); |
809 | uint64_t temp_time = unix_time(); | 812 | uint64_t temp_time = unix_time(); |
813 | |||
810 | if (comp_time + PING_TIMEOUT < temp_time || temp_time < comp_time) | 814 | if (comp_time + PING_TIMEOUT < temp_time || temp_time < comp_time) |
811 | return 0; | 815 | return 0; |
816 | |||
812 | Node_format test; | 817 | Node_format test; |
813 | memcpy(&test, plain_message + sizeof(uint64_t), sizeof(Node_format)); | 818 | memcpy(&test, plain_message + sizeof(uint64_t), sizeof(Node_format)); |
819 | |||
814 | if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.client_id, client_id, CLIENT_ID_SIZE) != 0) | 820 | if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.client_id, client_id, CLIENT_ID_SIZE) != 0) |
815 | return 0; | 821 | return 0; |
816 | 822 | ||
@@ -818,6 +824,9 @@ static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_i | |||
818 | return 1; | 824 | return 1; |
819 | } | 825 | } |
820 | 826 | ||
827 | /* Function is needed in following functions. */ | ||
828 | static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes); | ||
829 | |||
821 | static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 830 | static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
822 | { | 831 | { |
823 | DHT *dht = object; | 832 | DHT *dht = object; |
@@ -845,6 +854,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 | |||
845 | return 1; | 854 | return 1; |
846 | 855 | ||
847 | Node_format sendback_node; | 856 | Node_format sendback_node; |
857 | |||
848 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node4_format_size, &sendback_node)) | 858 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node4_format_size, &sendback_node)) |
849 | return 1; | 859 | return 1; |
850 | 860 | ||
@@ -868,6 +878,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 | |||
868 | num_nodes = num_nodes_ok; | 878 | num_nodes = num_nodes_ok; |
869 | } | 879 | } |
870 | 880 | ||
881 | send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes); | ||
871 | addto_lists(dht, source, packet + 1); | 882 | addto_lists(dht, source, packet + 1); |
872 | 883 | ||
873 | for (i = 0; i < num_nodes; ++i) { | 884 | for (i = 0; i < num_nodes; ++i) { |
@@ -905,6 +916,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, | |||
905 | return 1; | 916 | return 1; |
906 | 917 | ||
907 | Node_format sendback_node; | 918 | Node_format sendback_node; |
919 | |||
908 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node_format_size, &sendback_node)) | 920 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node_format_size, &sendback_node)) |
909 | return 1; | 921 | return 1; |
910 | 922 | ||
@@ -912,6 +924,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, | |||
912 | Node_format nodes_list[MAX_SENT_NODES]; | 924 | Node_format nodes_list[MAX_SENT_NODES]; |
913 | memcpy(nodes_list, plain, num_nodes * sizeof(Node_format)); | 925 | memcpy(nodes_list, plain, num_nodes * sizeof(Node_format)); |
914 | 926 | ||
927 | send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes); | ||
915 | addto_lists(dht, source, packet + 1); | 928 | addto_lists(dht, source, packet + 1); |
916 | 929 | ||
917 | for (i = 0; i < num_nodes; ++i) { | 930 | for (i = 0; i < num_nodes; ++i) { |
@@ -1552,12 +1565,100 @@ static void do_NAT(DHT *dht) | |||
1552 | /*----------------------------------------------------------------------------------*/ | 1565 | /*----------------------------------------------------------------------------------*/ |
1553 | /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ | 1566 | /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ |
1554 | 1567 | ||
1568 | #define HARDREQ_DATA_SIZE 768 /* Attempt to prevent amplification/other attacks*/ | ||
1555 | 1569 | ||
1556 | /* Handle a received ping request for. */ | 1570 | #define CHECK_TYPE_GETNODE_REQ 0 |
1571 | #define CHECK_TYPE_GETNODE_RES 1 | ||
1572 | |||
1573 | static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8_t *contents, uint16_t length) | ||
1574 | { | ||
1575 | if (length > HARDREQ_DATA_SIZE - 1) | ||
1576 | return -1; | ||
1577 | |||
1578 | uint8_t packet[MAX_DATA_SIZE]; | ||
1579 | uint8_t data[HARDREQ_DATA_SIZE] = {0}; | ||
1580 | data[0] = type; | ||
1581 | memcpy(data + 1, contents, length); | ||
1582 | int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data, | ||
1583 | sizeof(data), CRYPTO_PACKET_HARDENING); | ||
1584 | |||
1585 | if (len == -1) | ||
1586 | return -1; | ||
1587 | |||
1588 | return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len); | ||
1589 | } | ||
1590 | |||
1591 | /* Send a get node hardening request */ | ||
1592 | static int send_hardening_getnode_req(DHT *dht, Node_format *dest, Node_format *node_totest, uint8_t *search_id) | ||
1593 | { | ||
1594 | uint8_t data[sizeof(Node_format) + CLIENT_ID_SIZE]; | ||
1595 | memcpy(data, node_totest, sizeof(Node_format)); | ||
1596 | memcpy(data + sizeof(Node_format), search_id, CLIENT_ID_SIZE); | ||
1597 | return send_hardening_req(dht, dest, CHECK_TYPE_GETNODE_REQ, data, sizeof(Node_format) + CLIENT_ID_SIZE); | ||
1598 | } | ||
1599 | |||
1600 | /* Send a get node hardening response */ | ||
1601 | static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes) | ||
1602 | { | ||
1603 | if (!ip_isset(&sendto->ip_port.ip)) | ||
1604 | return -1; | ||
1605 | |||
1606 | uint8_t packet[MAX_DATA_SIZE]; | ||
1607 | uint8_t data[1 + num_nodes * sizeof(Node_format)]; | ||
1608 | data[0] = CHECK_TYPE_GETNODE_RES; | ||
1609 | memcpy(data + 1, list, num_nodes * sizeof(Node_format)); | ||
1610 | int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data, | ||
1611 | sizeof(data), CRYPTO_PACKET_HARDENING); | ||
1612 | |||
1613 | if (len == -1) | ||
1614 | return -1; | ||
1615 | |||
1616 | return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len); | ||
1617 | } | ||
1618 | |||
1619 | /* Handle a received hardening packet */ | ||
1557 | static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) | 1620 | static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) |
1558 | { | 1621 | { |
1559 | DHT *dht = object; | 1622 | DHT *dht = object; |
1560 | return 0;/* success*/ | 1623 | |
1624 | if (length < 2) { | ||
1625 | return 1; | ||
1626 | } | ||
1627 | |||
1628 | switch (packet[0]) { | ||
1629 | case CHECK_TYPE_GETNODE_REQ: { | ||
1630 | if (length != HARDREQ_DATA_SIZE) | ||
1631 | return 1; | ||
1632 | |||
1633 | Node_format node, tocheck_node; | ||
1634 | node.ip_port = source; | ||
1635 | memcpy(node.client_id, source_pubkey, CLIENT_ID_SIZE); | ||
1636 | memcpy(&tocheck_node, packet + 1, sizeof(Node_format)); | ||
1637 | |||
1638 | if (getnodes(dht, tocheck_node.ip_port, tocheck_node.client_id, packet + 1 + sizeof(Node_format), &node) == -1) | ||
1639 | return 1; | ||
1640 | |||
1641 | return 0; | ||
1642 | } | ||
1643 | |||
1644 | case CHECK_TYPE_GETNODE_RES: { | ||
1645 | if ((length - 1) % sizeof(Node_format) != 0) | ||
1646 | return 1; | ||
1647 | |||
1648 | uint16_t num = (length - 1) / sizeof(Node_format); | ||
1649 | |||
1650 | if (num > MAX_SENT_NODES || num == 0) | ||
1651 | return 1; | ||
1652 | |||
1653 | Node_format nodes[num]; | ||
1654 | memcpy(nodes, packet + 1, sizeof(Node_format)*num); | ||
1655 | /* If Nodes look good and the request checks out */ | ||
1656 | //TODO | ||
1657 | return 0;/* success*/ | ||
1658 | } | ||
1659 | } | ||
1660 | |||
1661 | return 1; | ||
1561 | } | 1662 | } |
1562 | 1663 | ||
1563 | /*----------------------------------------------------------------------------------*/ | 1664 | /*----------------------------------------------------------------------------------*/ |