summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-11-10 14:32:46 -0500
committerirungentoo <irungentoo@gmail.com>2013-11-10 14:32:46 -0500
commit57763f2737b6920d09e4f3fec5792a2c59ad2b21 (patch)
tree39950688279346bf80940af61bb1dc91f140755b /toxcore/DHT.c
parent91c9dc2464b76217b2ac907861c4347c08cc7d80 (diff)
parent572fb60392f2bdbea0b738ab9cc4eca2aefe6585 (diff)
Merge branch 'master' into harden
Conflicts: toxcore/DHT.c
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c123
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. */
815static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes); 815static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes);
816 816
817static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 817static 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
861static 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
879static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) 898static 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}