diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 5232deed..3a1b9cf0 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -1545,8 +1545,12 @@ static void do_NAT(DHT *dht) #define HARDREQ_DATA_SIZE 768 /* Attempt to prevent amplification/other attacks*/ -#define CHECK_TYPE_GETNODE_REQ 0 -#define CHECK_TYPE_GETNODE_RES 1 +#define CHECK_TYPE_ROUTE_REQ 0 +#define CHECK_TYPE_ROUTE_RES 1 +#define CHECK_TYPE_GETNODE_REQ 2 +#define CHECK_TYPE_GETNODE_RES 3 +#define CHECK_TYPE_TEST_REQ 4 +#define CHECK_TYPE_TEST_RES 5 static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8_t *contents, uint16_t length) { @@ -1639,6 +1643,80 @@ static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey return 1; } +/* Return a random node from all the nodes we are connected to. + * TODO: improve this function. + */ +Node_format random_node(DHT *dht, sa_family_t sa_family) +{ + uint8_t id[CLIENT_ID_SIZE]; + uint32_t i; + + for (i = 0; i < CLIENT_ID_SIZE / 4; ++i) { /* populate the id with pseudorandom bytes.*/ + uint32_t t = rand(); + memcpy(id + i * sizeof(t), &t, sizeof(t)); + } + + Node_format nodes_list[MAX_SENT_NODES]; + memset(nodes_list, 0, sizeof(nodes_list)); + int num_nodes = get_close_nodes(dht, id, nodes_list, sa_family, 1); + + if (num_nodes < 1) + return nodes_list[0]; + else + return nodes_list[rand() % num_nodes]; +} + +/* Interval in seconds between checks */ +#define HARDENING_INTERVAL 5 +#define HARDEN_TIMEOUT 500 + +void do_hardening(DHT *dht) +{ + uint32_t i; + + for (i = 0; i < LCLIENT_LIST * 2; ++i) { + IPPTsPng *cur_iptspng; + sa_family_t sa_family; + uint8_t *client_id = dht->close_clientlist[i / 2].client_id; + + if (i % 2 == 0) { + cur_iptspng = &dht->close_clientlist[i / 2].assoc4; + sa_family = AF_INET; + } else { + cur_iptspng = &dht->close_clientlist[i / 2].assoc6; + sa_family = AF_INET6; + } + + if (is_timeout(cur_iptspng->timestamp, BAD_NODE_TIMEOUT)) + continue; + + if (cur_iptspng->hardening.send_nodes_ok == 0) { + if (is_timeout(cur_iptspng->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) { + Node_format rand_node = random_node(dht, sa_family); + + if (!ipport_isset(&rand_node.ip_port)) + continue; + + Node_format to_test; + to_test.ip_port = cur_iptspng->ip_port; + memcpy(to_test.client_id, client_id, CLIENT_ID_SIZE); + + //TODO: The search id should maybe not be ours? + if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->c->self_public_key) != -1) { + memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.client_id, CLIENT_ID_SIZE); + cur_iptspng->hardening.send_nodes_timestamp = unix_time(); + } + } + } else { + if (is_timeout(cur_iptspng->hardening.send_nodes_timestamp, HARDEN_TIMEOUT)) { + cur_iptspng->hardening.send_nodes_ok = 0; + } + } + + //TODO: add the 2 other testers. + } +} + /*----------------------------------------------------------------------------------*/ DHT *new_DHT(Net_Crypto *c) diff --git a/toxcore/DHT.h b/toxcore/DHT.h index ac02710f..ec62442e 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -38,11 +38,30 @@ /* Maximum newly announced nodes to ping per TIME_TOPING seconds. */ #define MAX_TOPING 16 +typedef struct { + /* Node routes request correctly (true (1) or false/didn't check (0)) */ + uint8_t routes_requests_ok; + /* Time which we last checked this.*/ + uint64_t routes_requests_timestamp; + uint8_t routes_requests_pingedid[CLIENT_ID_SIZE]; + /* Node sends correct send_node (true (1) or false/didn't check (0)) */ + uint8_t send_nodes_ok; + /* Time which we last checked this.*/ + uint64_t send_nodes_timestamp; + uint8_t send_nodes_pingedid[CLIENT_ID_SIZE]; + /* Node can be used to test other nodes (true (1) or false/didn't check (0)) */ + uint8_t testing_requests; + /* Time which we last checked this.*/ + uint64_t testing_timestamp; + uint8_t testing_pingedid[CLIENT_ID_SIZE]; +} Hardening; + typedef struct { IP_Port ip_port; uint64_t timestamp; uint64_t last_pinged; - + + Hardening hardening; /* Returned by this node. Either our friend or us. */ IP_Port ret_ip_port; uint64_t ret_timestamp; @@ -66,21 +85,6 @@ typedef struct { uint64_t NATping_timestamp; } NAT; -typedef struct { - /* Node routes request correctly (true (1) or false/didn't check (0)) */ - uint8_t routes_requests_ok; - /* Time which we last checked this.*/ - uint64_t routes_requests_timestamp; - /* Node sends correct send_node (true (1) or false/didn't check (0)) */ - uint8_t send_nodes_ok; - /* Time which we last checked this.*/ - uint64_t send_nodes_timestamp; - /* Node can be used to test other nodes (true (1) or false/didn't check (0)) */ - uint8_t testing_requests; - /* Time which we last checked this.*/ - uint64_t testing_timestamp; -} Hardening; - typedef struct { uint8_t client_id[CLIENT_ID_SIZE]; Client_data client_list[MAX_FRIEND_CLIENTS]; @@ -88,7 +92,6 @@ typedef struct { /* Time at which the last get_nodes request was sent. */ uint64_t lastgetnode; - Hardening hardening; /* Symetric NAT hole punching stuff. */ NAT nat; } DHT_Friend; diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index fdf6e834..5831e7d4 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -531,7 +531,7 @@ void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat, Group_Chat *new_groupchat(Networking_Core *net) { unix_time_update(); - + if (net == 0) return 0; diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index d58f4c27..8be1059e 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -800,7 +800,7 @@ static void receive_crypto(Net_Crypto *c) Net_Crypto *new_net_crypto(Networking_Core *net) { unix_time_update(); - + if (net == NULL) return NULL; diff --git a/toxcore/network.c b/toxcore/network.c index d163c0eb..5cbc4695 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -278,7 +278,7 @@ void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handl void networking_poll(Networking_Core *net) { unix_time_update(); - + IP_Port ip_port; uint8_t data[MAX_UDP_PACKET_SIZE]; uint32_t length;