diff --git a/core/DHT.c b/core/DHT.c index 01abfdd2..fa36d41f 100644 --- a/core/DHT.c +++ b/core/DHT.c @@ -24,6 +24,7 @@ /*----------------------------------------------------------------------------------*/ #include "DHT.h" +#include "packets.h" #include "ping.h" /* maximum number of clients stored per friend. */ @@ -472,71 +473,6 @@ static uint64_t add_gettingnodes(IP_Port ip_port) return 0; } -/* send a ping request, only works if none has been sent to that ip/port - * in the last 5 seconds. - */ -static int pingreq(IP_Port ip_port, uint8_t * public_key) -{ - /* check if packet is gonna be sent to ourself */ - if(id_equal(public_key, self_public_key) || is_pinging(ip_port, 0)) - return 1; - - uint64_t ping_id = add_ping(ip_port); - if(ping_id == 0) - return 1; - - uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t nonce[crypto_box_NONCEBYTES]; - random_nonce(nonce); - - int len = encrypt_data( public_key, - self_secret_key, - nonce, - (uint8_t *)&ping_id, - sizeof(ping_id), - encrypt ); - - if(len != sizeof(ping_id) + ENCRYPTION_PADDING) - return -1; - - data[0] = 0; - memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); - memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); - memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); - - return sendpacket(ip_port, data, sizeof(data)); -} - -/* send a ping response */ -static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) -{ - /* check if packet is gonna be sent to ourself */ - if(id_equal(public_key, self_public_key)) - return 1; - - uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t nonce[crypto_box_NONCEBYTES]; - random_nonce(nonce); - - int len = encrypt_data( public_key, - self_secret_key, nonce, - (uint8_t *)&ping_id, - sizeof(ping_id), - encrypt ); - - if(len != sizeof(ping_id) + ENCRYPTION_PADDING) - return -1; - - data[0] = 1; - memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); - memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); - memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); - - return sendpacket(ip_port, data, sizeof(data)); -} - /* send a getnodes request */ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) { @@ -641,8 +577,8 @@ static int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) if(len != sizeof(ping_id)) return 1; - pingres(source, packet + 1, ping_id); - pingreq(source, packet + 1); /* TODO: make this smarter? */ + send_ping_response(source, (clientid_t*) (packet + 1), ping_id); + send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ return 0; } @@ -701,7 +637,7 @@ static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) memcpy(&ping_id, plain, sizeof(ping_id)); sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); - pingreq(source, packet + 1); /* TODO: make this smarter? */ + send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ return 0; } @@ -741,7 +677,7 @@ static int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) uint32_t i; for(i = 0; i < num_nodes; ++i) { - pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); + send_ping_request(nodes_list[i].ip_port, (clientid_t*) &nodes_list[i].client_id); returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); } @@ -831,8 +767,8 @@ static void doDHTFriends(void) /* if node is not dead. */ if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { - pingreq( friends_list[i].client_list[j].ip_port, - friends_list[i].client_list[j].client_id ); + send_ping_request( friends_list[i].client_list[j].ip_port, + (clientid_t*) &friends_list[i].client_list[j].client_id ); friends_list[i].client_list[j].last_pinged = temp_time; } /* if node is good. */ @@ -869,8 +805,8 @@ static void doClose(void) /* if node is not dead. */ if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { - pingreq( close_clientlist[i].ip_port, - close_clientlist[i].client_id ); + send_ping_request( close_clientlist[i].ip_port, + (clientid_t*) &close_clientlist[i].client_id ); close_clientlist[i].last_pinged = temp_time; } /* if node is good. */ @@ -1151,7 +1087,7 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t /*TODO: improve port guessing algorithm*/ uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); IP_Port pinging = {ip, htons(port)}; - pingreq(pinging, friends_list[friend_num].client_id); + send_ping_request(pinging, (clientid_t*) &friends_list[friend_num].client_id); } friends_list[friend_num].punching_index = i; } diff --git a/core/packets.h b/core/packets.h new file mode 100644 index 00000000..222b1425 --- /dev/null +++ b/core/packets.h @@ -0,0 +1,37 @@ +/* + * packet.h -- Packet structure + * + * This file is donated to the Tox Project. + * Copyright 2013 plutooo + */ + +typedef struct { + uint8_t id[CLIENT_ID_SIZE]; + +} __attribute__((packed)) clientid_t; + +typedef enum { + PACKET_PING_REQ = 0, + PACKET_PING_RES = 1 + +} packetid_t; + +// Ping packet +typedef struct { + uint8_t magic; + clientid_t client_id; + uint8_t nonce[crypto_box_NONCEBYTES]; + uint64_t ping_id; + uint8_t padding[ENCRYPTION_PADDING]; + +} __attribute__((packed)) pingreq_t; + +// Pong packet +typedef struct { + uint8_t magic; + clientid_t client_id; + uint8_t nonce[crypto_box_NONCEBYTES]; + uint64_t ping_id; + uint8_t padding[ENCRYPTION_PADDING]; + +} __attribute__((packed)) pingres_t; diff --git a/core/ping.c b/core/ping.c index 8a7d534f..37f1b7ae 100644 --- a/core/ping.c +++ b/core/ping.c @@ -8,6 +8,9 @@ #include #include +#include "DHT.h" +#include "net_crypto.h" +#include "packets.h" #include "network.h" #include "util.h" @@ -20,76 +23,143 @@ typedef struct { uint64_t timestamp; } pinged_t; -static pinged_t pings[PING_NUM_MAX]; -static size_t num_pings; -static size_t pos_pings; +static pinged_t pings[PING_NUM_MAX]; +static size_t num_pings; +static size_t pos_pings; +static clientid_t* self_id = (clientid_t*) &self_public_key; + +extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c -void init_ping() { - num_pings = 0; - pos_pings = 0; +void init_ping() +{ + num_pings = 0; + pos_pings = 0; } -static bool is_timeout(uint64_t time) { - return (time + PING_TIMEOUT) < now(); +static bool is_timeout(uint64_t time) +{ + return (time + PING_TIMEOUT) < now(); } -static void remove_timeouts() { // O(n) - size_t i, id; - size_t new_pos = pos_pings; - size_t new_num = num_pings; +static void remove_timeouts() // O(n) +{ + size_t i, id; + size_t new_pos = pos_pings; + size_t new_num = num_pings; - // Loop through buffer, oldest first - for(i=0; i #include -#include "network.h" +#include "DHT.h" +#include "packets.h" -uint64_t now() { - return time(NULL); +uint64_t now() +{ + return time(NULL); } -uint64_t random_64b() { - uint64_t r; +uint64_t random_64b() +{ + uint64_t r; - // This is probably not random enough? - r = random_int(); - r <<= 32; - r |= random_int(); + // This is probably not random enough? + r = random_int(); + r <<= 32; + r |= random_int(); - return r; + return r; } -bool ipp_eq(IP_Port a, IP_Port b) { - return (a.ip.i == b.ip.i) && (a.port == b.port); +bool ipp_eq(IP_Port a, IP_Port b) +{ + return (a.ip.i == b.ip.i) && (a.port == b.port); +} + +bool id_eq(clientid_t* dest, clientid_t* src) +{ + return memcmp(dest, src, sizeof(clientid_t)) == 0; +} + +void id_cpy(clientid_t* dest, clientid_t* src) +{ + memcpy(dest, src, sizeof(clientid_t)); } diff --git a/core/util.h b/core/util.h index aab2ead9..a93be08a 100644 --- a/core/util.h +++ b/core/util.h @@ -8,3 +8,6 @@ uint64_t now(); uint64_t random_64b(); bool ipp_eq(IP_Port a, IP_Port b); +bool id_eq(clientid_t* dest, clientid_t* src); +void id_cpy(clientid_t* dest, clientid_t* src); +