diff options
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r-- | toxcore/DHT.c | 123 |
1 files changed, 61 insertions, 62 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index c43382ed..b9ba7e1d 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -814,110 +814,109 @@ static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_i | |||
814 | /* Function is needed in following functions. */ | 814 | /* Function is needed in following functions. */ |
815 | static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes); | 815 | static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes); |
816 | 816 | ||
817 | static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 817 | static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet, uint32_t length, |
818 | size_t node_format_size, uint8_t *plain, uint16_t plain_length, uint32_t *num_nodes_out, Node_format *sendback_node) | ||
818 | { | 819 | { |
820 | if (plain_length != MAX_SENT_NODES * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH) | ||
821 | return 1; | ||
822 | |||
819 | DHT *dht = object; | 823 | DHT *dht = object; |
820 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; | 824 | uint32_t cid_size = 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES; |
821 | cid_size += crypto_box_NONCEBYTES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES; | ||
822 | 825 | ||
823 | size_t Node4_format_size = sizeof(Node4_format); | 826 | if (length <= cid_size) /* too short */ |
827 | return 1; | ||
828 | |||
829 | uint32_t data_size = length - cid_size; | ||
824 | 830 | ||
825 | if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) || | 831 | if ((data_size % node_format_size) != 0) /* invalid length */ |
826 | ((length - cid_size) % Node4_format_size) != 0 || | ||
827 | (length < cid_size + Node4_format_size)) | ||
828 | return 1; | 832 | return 1; |
829 | 833 | ||
830 | uint32_t num_nodes = (length - cid_size) / Node4_format_size; | 834 | uint32_t num_nodes = data_size / node_format_size; |
831 | uint8_t plain[Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; | 835 | |
836 | if (num_nodes > MAX_SENT_NODES) /* too long */ | ||
837 | return 1; | ||
832 | 838 | ||
833 | int len = decrypt_data( | 839 | int len = decrypt_data( |
834 | packet + 1, | 840 | packet + 1, |
835 | dht->c->self_secret_key, | 841 | dht->c->self_secret_key, |
836 | packet + 1 + CLIENT_ID_SIZE, | 842 | packet + 1 + CLIENT_ID_SIZE, |
837 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 843 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
838 | num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, plain ); | 844 | num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, |
845 | plain); | ||
846 | |||
847 | if ((unsigned int)len != num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH) | ||
848 | return 1; | ||
839 | 849 | ||
840 | if ((unsigned int)len != num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH) | 850 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * node_format_size, sendback_node)) |
841 | return 1; | 851 | return 1; |
842 | 852 | ||
853 | /* store the address the *request* was sent to */ | ||
854 | addto_lists(dht, source, packet + 1); | ||
855 | |||
856 | *num_nodes_out = num_nodes; | ||
857 | |||
858 | return 0; | ||
859 | } | ||
860 | |||
861 | static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) | ||
862 | { | ||
863 | DHT *dht = object; | ||
864 | size_t node4_format_size = sizeof(Node4_format); | ||
865 | uint8_t plain[node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; | ||
866 | uint32_t num_nodes; | ||
867 | |||
843 | Node_format sendback_node; | 868 | Node_format sendback_node; |
844 | 869 | ||
845 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node4_format_size, &sendback_node)) | 870 | if (handle_sendnodes_core(object, source, packet, length, node4_format_size, plain, sizeof(plain), &num_nodes, |
871 | &sendback_node)) | ||
846 | return 1; | 872 | return 1; |
847 | 873 | ||
848 | Node4_format *nodes4_list = (Node4_format *)(plain); | 874 | Node4_format *nodes4_list = (Node4_format *)(plain); |
875 | uint32_t i; | ||
876 | |||
877 | IP_Port ipp; | ||
878 | ipp.ip.family = AF_INET; | ||
879 | |||
849 | Node_format nodes_list[MAX_SENT_NODES]; | 880 | Node_format nodes_list[MAX_SENT_NODES]; |
850 | uint32_t i, num_nodes_ok = 0; | ||
851 | 881 | ||
852 | /* blow up from Node4 (IPv4) wire format to Node (IPv4/IPv6) structure */ | ||
853 | for (i = 0; i < num_nodes; i++) | 882 | for (i = 0; i < num_nodes; i++) |
854 | if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != (uint32_t)~0)) { | 883 | if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != (uint32_t)~0)) { |
855 | memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); | 884 | ipp.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32; |
856 | nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET; | 885 | ipp.port = nodes4_list[i].ip_port.port; |
857 | nodes_list[num_nodes_ok].ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32; | ||
858 | nodes_list[num_nodes_ok].ip_port.port = nodes4_list[i].ip_port.port; | ||
859 | 886 | ||
860 | num_nodes_ok++; | 887 | send_ping_request(dht->ping, ipp, nodes4_list[i].client_id); |
861 | } | 888 | returnedip_ports(dht, ipp, nodes4_list[i].client_id, packet + 1); |
862 | 889 | ||
863 | if (num_nodes_ok < num_nodes) { | 890 | memcpy(nodes_list[i].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); |
864 | /* shouldn't happen */ | 891 | ipport_copy(&nodes_list[i].ip_port, &ipp); |
865 | num_nodes = num_nodes_ok; | 892 | } |
866 | } | ||
867 | 893 | ||
868 | send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes); | 894 | send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes); |
869 | addto_lists(dht, source, packet + 1); | ||
870 | |||
871 | for (i = 0; i < num_nodes; ++i) { | ||
872 | send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id); | ||
873 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | ||
874 | } | ||
875 | |||
876 | return 0; | 895 | return 0; |
877 | } | 896 | } |
878 | 897 | ||
879 | static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 898 | static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
880 | { | 899 | { |
881 | DHT *dht = object; | 900 | DHT *dht = object; |
882 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; | 901 | size_t node_format_size = sizeof(Node_format); |
883 | cid_size += crypto_box_NONCEBYTES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES; | 902 | uint8_t plain[node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; |
884 | 903 | uint32_t num_nodes; | |
885 | size_t Node_format_size = sizeof(Node_format); | ||
886 | |||
887 | if (length > (cid_size + Node_format_size * MAX_SENT_NODES) || | ||
888 | ((length - cid_size) % Node_format_size) != 0 || | ||
889 | (length < cid_size + Node_format_size)) | ||
890 | return 1; | ||
891 | |||
892 | uint32_t num_nodes = (length - cid_size) / Node_format_size; | ||
893 | uint8_t plain[Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; | ||
894 | |||
895 | int len = decrypt_data( | ||
896 | packet + 1, | ||
897 | dht->c->self_secret_key, | ||
898 | packet + 1 + CLIENT_ID_SIZE, | ||
899 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
900 | num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, plain ); | ||
901 | |||
902 | if ((unsigned int)len != num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH) | ||
903 | return 1; | ||
904 | 904 | ||
905 | Node_format sendback_node; | 905 | Node_format sendback_node; |
906 | 906 | ||
907 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node_format_size, &sendback_node)) | 907 | if (handle_sendnodes_core(object, source, packet, length, node_format_size, plain, sizeof(plain), &num_nodes, |
908 | &sendback_node)) | ||
908 | return 1; | 909 | return 1; |
909 | 910 | ||
911 | Node_format *nodes_list = (Node_format *)(plain); | ||
910 | uint32_t i; | 912 | uint32_t i; |
911 | Node_format nodes_list[MAX_SENT_NODES]; | ||
912 | memcpy(nodes_list, plain, num_nodes * sizeof(Node_format)); | ||
913 | |||
914 | send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes); | 913 | send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes); |
915 | addto_lists(dht, source, packet + 1); | ||
916 | 914 | ||
917 | for (i = 0; i < num_nodes; ++i) { | 915 | for (i = 0; i < num_nodes; i++) |
918 | send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id); | 916 | if (ipport_isset(&nodes_list[i].ip_port)) { |
919 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | 917 | send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id); |
920 | } | 918 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); |
919 | } | ||
921 | 920 | ||
922 | return 0; | 921 | return 0; |
923 | } | 922 | } |