Some DHT hardening done.

See comments of added functions for details.
This commit is contained in:
irungentoo 2013-08-16 11:04:28 -04:00
parent b15230583c
commit 095b3c4913
3 changed files with 70 additions and 2 deletions

View File

@ -61,6 +61,10 @@
/*Interval in seconds between punching attempts*/
#define PUNCH_INTERVAL 10
/*Maximum newly announced nodes to ping per TIME_TOPING seconds*/
#define MAX_TOPING 16
#define TIME_TOPING 5
/*----------------------------------------------------------------------------------*/
typedef struct {
@ -101,6 +105,8 @@ static Client_data close_clientlist[LCLIENT_LIST];
static Friend * friends_list;
static uint16_t num_friends;
static Pinged send_nodes[LSEND_NODES_ARRAY];
static Node_format toping[MAX_TOPING];
static uint64_t last_toping;
/*----------------------------------------------------------------------------------*/
@ -599,7 +605,7 @@ static int handle_getnodes(IP_Port source, uint8_t * packet, uint32_t length)
memcpy(&ping_id, plain, sizeof(ping_id));
sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id);
send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */
//send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */
return 0;
}
@ -1075,6 +1081,57 @@ static void doNAT(void)
/*----------------------------------------------------------------------------------*/
/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/
/* Add nodes to the toping list
all nodes in this list are pinged every TIME_TOPING seconds
and are then removed from the list.
if the list is full the nodes farthest from our client_id are replaced
the purpose of this list is to enable quick integration of new nodes into the
network while preventing amplification attacks.
return 0 if node was added
return -1 if node was not added */
int add_toping(uint8_t *client_id, IP_Port ip_port)
{
if (ip_port.ip.i == 0)
return -1;
uint32_t i;
for (i = 0; i < MAX_TOPING; ++i) {
if (toping[i].ip_port.ip.i == 0) {
memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE);
toping[i].ip_port.ip.i = ip_port.ip.i;
toping[i].ip_port.port = ip_port.port;
return 0;
}
}
for (i = 0; i < MAX_TOPING; ++i) {
if (id_closest(self_public_key, toping[i].client_id, client_id) == 2) {
memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE);
toping[i].ip_port.ip.i = ip_port.ip.i;
toping[i].ip_port.port = ip_port.port;
return 0;
}
}
return -1;
}
/*Ping all the valid nodes in the toping list every TIME_TOPING seconds
this function must be run at least once every TIME_TOPING seconds*/
static void do_toping()
{
uint64_t temp_time = unix_time();
if (!is_timeout(temp_time, last_toping, TIME_TOPING))
return;
last_toping = temp_time;
uint32_t i;
for (i = 0; i < MAX_TOPING; ++i) {
if (toping[i].ip_port.ip.i == 0)
return;
send_ping_request(toping[i].ip_port, (clientid_t *) toping[i].client_id);
toping[i].ip_port.ip.i = 0;
}
}
void DHT_init(void)
{
networking_registerhandler(0, &handle_ping_request);
@ -1089,6 +1146,7 @@ void doDHT(void)
doClose();
doDHTFriends();
doNAT();
do_toping();
}
/* get the size of the DHT (for saving) */

View File

@ -75,6 +75,16 @@ void doDHT(void);
Sends a get nodes request to the given node with ip port and public_key */
void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key);
/* Add nodes to the toping list
all nodes in this list are pinged every TIME_TOPING seconds
and are then removed from the list.
if the list is full the nodes farthest from our client_id are replaced
the purpose of this list is to enable quick integration of new nodes into the
network while preventing amplification attacks.
return 0 if node was added
return -1 if node was not added */
int add_toping(uint8_t *client_id, IP_Port ip_port);
/* ROUTING FUNCTIONS */
/* send the given packet to node with client_id

View File

@ -185,7 +185,7 @@ int handle_ping_request(IP_Port source, uint8_t* packet, uint32_t length)
// Send response
send_ping_response(source, &p->client_id, ping_id);
send_ping_request(source, &p->client_id); // Make this smarter?
add_toping((uint8_t*) &p->client_id, source);
return 0;
}