summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/DHT.c148
1 files changed, 117 insertions, 31 deletions
diff --git a/core/DHT.c b/core/DHT.c
index 53c740a7..547520d2 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -60,11 +60,20 @@ int id_closest(char * client_id, char * client_id1, char * client_id2)//tested
60//check if client with client_id is already in list of length length. 60//check if client with client_id is already in list of length length.
61//if it is set it's corresponding timestamp to current time. 61//if it is set it's corresponding timestamp to current time.
62//return True(1) or False(0) 62//return True(1) or False(0)
63int client_in_list(Client_data * list, uint32_t length, char * client_id) 63//TODO: maybe optimize this.
64int client_in_list(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port)
64{ 65{
65 uint32_t i, j; 66 uint32_t i, j;
67 uint32_t temp_time = unix_time();
68
66 for(i = 0; i < length; i++) 69 for(i = 0; i < length; i++)
67 { 70 {
71 //If the id for an ip/port changes, replace it.
72 if(list[i].ip_port.ip.i == ip_port.ip.i &&
73 list[i].ip_port.port == ip_port.port)
74 {
75 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
76 }
68 for(j = 0; j < CLIENT_ID_SIZE; j++) 77 for(j = 0; j < CLIENT_ID_SIZE; j++)
69 { 78 {
70 79
@@ -76,7 +85,7 @@ int client_in_list(Client_data * list, uint32_t length, char * client_id)
76 if(j == CLIENT_ID_SIZE) 85 if(j == CLIENT_ID_SIZE)
77 { 86 {
78 //Refresh the client timestamp. 87 //Refresh the client timestamp.
79 list[i].timestamp = unix_time(); 88 list[i].timestamp = temp_time;
80 return 1; 89 return 1;
81 } 90 }
82 } 91 }
@@ -207,13 +216,15 @@ int replace_bad(Client_data * list, uint32_t length, char * client_id, IP_Port i
207int replace_good(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port, char * comp_client_id) 216int replace_good(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port, char * comp_client_id)
208{ 217{
209 uint32_t i; 218 uint32_t i;
219 uint32_t temp_time = unix_time();
220
210 for(i = 0; i < length; i++) 221 for(i = 0; i < length; i++)
211 { 222 {
212 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) 223 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2)
213 { 224 {
214 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 225 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
215 list[i].ip_port = ip_port; 226 list[i].ip_port = ip_port;
216 list[i].timestamp = unix_time(); 227 list[i].timestamp = temp_time;
217 return 0; 228 return 0;
218 } 229 }
219 } 230 }
@@ -227,7 +238,7 @@ void addto_lists(IP_Port ip_port, char * client_id)
227 uint32_t i; 238 uint32_t i;
228 239
229 //NOTE: current behaviour if there are two clients with the same id is to only keep one (the first one) 240 //NOTE: current behaviour if there are two clients with the same id is to only keep one (the first one)
230 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id)) 241 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port))
231 { 242 {
232 243
233 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 244 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port))
@@ -239,7 +250,7 @@ void addto_lists(IP_Port ip_port, char * client_id)
239 } 250 }
240 for(i = 0; i < num_friends; i++) 251 for(i = 0; i < num_friends; i++)
241 { 252 {
242 if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id)) 253 if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port))
243 { 254 {
244 255
245 if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) 256 if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port))
@@ -254,21 +265,43 @@ void addto_lists(IP_Port ip_port, char * client_id)
254 265
255//ping timeout in seconds 266//ping timeout in seconds
256#define PING_TIMEOUT 10 267#define PING_TIMEOUT 10
257//check if we are currently pinging an ip_port 268//check if we are currently pinging an ip_port and/or a ping_id
269//Variables with values of zero will not be checked.
258//if we are already, return 1 270//if we are already, return 1
259//else return 0 271//else return 0
260//TODO: Maybe optimize this 272//TODO: Maybe optimize this
261int is_pinging(IP_Port ip_port) 273int is_pinging(IP_Port ip_port, uint32_t ping_id)
262{ 274{
263 uint32_t i; 275 uint32_t i;
264 276 uint8_t pinging;
277 uint32_t temp_time = unix_time();
278
265 for(i = 0; i < LPING_ARRAY; i++ ) 279 for(i = 0; i < LPING_ARRAY; i++ )
266 { 280 {
267 if((pings[i].timestamp + PING_TIMEOUT) > unix_time() && 281 if((pings[i].timestamp + PING_TIMEOUT) > temp_time)
268 pings[i].ip_port.ip.i == ip_port.ip.i &&
269 pings[i].ip_port.port == ip_port.port)
270 { 282 {
271 return 1; 283 if(ip_port.ip.i != 0)
284 {
285 pinging = 0;
286 if(pings[i].ip_port.ip.i == ip_port.ip.i &&
287 pings[i].ip_port.port == ip_port.port)
288 {
289 pinging = 1;
290 }
291 }
292 if(ping_id != 0)
293 {
294 pinging = 0;
295 if(pings[i].ping_id == ping_id)
296 {
297 pinging = 1;
298 }
299 }
300 if(pinging == 1)
301 {
302 return 1;
303 }
304
272 } 305 }
273 } 306 }
274 307
@@ -278,17 +311,38 @@ int is_pinging(IP_Port ip_port)
278 311
279 312
280//Same as last function but for get_node requests. 313//Same as last function but for get_node requests.
281int is_gettingnodes(IP_Port ip_port) 314int is_gettingnodes(IP_Port ip_port, uint32_t ping_id)
282{ 315{
283 uint32_t i; 316 uint32_t i;
284 317 uint8_t pinging;
285 for(i = 0; i < LSEND_NODES_ARRAY; i++ ) 318 uint32_t temp_time = unix_time();
319
320 for(i = 0; i < LPING_ARRAY; i++ )
286 { 321 {
287 if((send_nodes[i].timestamp + PING_TIMEOUT) > unix_time() && 322 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time)
288 send_nodes[i].ip_port.ip.i == ip_port.ip.i &&
289 send_nodes[i].ip_port.port == ip_port.port)
290 { 323 {
291 return 1; 324 if(ip_port.ip.i != 0)
325 {
326 pinging = 0;
327 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i &&
328 send_nodes[i].ip_port.port == ip_port.port)
329 {
330 pinging = 1;
331 }
332 }
333 if(ping_id != 0)
334 {
335 pinging = 0;
336 if(send_nodes[i].ping_id == ping_id)
337 {
338 pinging = 1;
339 }
340 }
341 if(pinging == 1)
342 {
343 return 1;
344 }
345
292 } 346 }
293 } 347 }
294 348
@@ -296,6 +350,7 @@ int is_gettingnodes(IP_Port ip_port)
296 350
297} 351}
298 352
353
299//Add a new ping request to the list of ping requests 354//Add a new ping request to the list of ping requests
300//returns the ping_id to put in the ping request 355//returns the ping_id to put in the ping request
301//returns 0 if problem. 356//returns 0 if problem.
@@ -304,13 +359,15 @@ int add_pinging(IP_Port ip_port)
304{ 359{
305 uint32_t i, j; 360 uint32_t i, j;
306 int ping_id = rand(); 361 int ping_id = rand();
362 uint32_t temp_time = unix_time();
363
307 for(i = 0; i < PING_TIMEOUT; i++ ) 364 for(i = 0; i < PING_TIMEOUT; i++ )
308 { 365 {
309 for(j = 0; j < LPING_ARRAY; j++ ) 366 for(j = 0; j < LPING_ARRAY; j++ )
310 { 367 {
311 if((pings[j].timestamp + PING_TIMEOUT - i) < unix_time()) 368 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time)
312 { 369 {
313 pings[j].timestamp = unix_time(); 370 pings[j].timestamp = temp_time;
314 pings[j].ip_port = ip_port; 371 pings[j].ip_port = ip_port;
315 pings[j].ping_id = ping_id; 372 pings[j].ping_id = ping_id;
316 return ping_id; 373 return ping_id;
@@ -326,13 +383,15 @@ int add_gettingnodes(IP_Port ip_port)
326{ 383{
327 uint32_t i, j; 384 uint32_t i, j;
328 int ping_id = rand(); 385 int ping_id = rand();
386 uint32_t temp_time = unix_time();
387
329 for(i = 0; i < PING_TIMEOUT; i++ ) 388 for(i = 0; i < PING_TIMEOUT; i++ )
330 { 389 {
331 for(j = 0; j < LSEND_NODES_ARRAY; j++ ) 390 for(j = 0; j < LSEND_NODES_ARRAY; j++ )
332 { 391 {
333 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < unix_time()) 392 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time)
334 { 393 {
335 send_nodes[j].timestamp = unix_time(); 394 send_nodes[j].timestamp = temp_time;
336 send_nodes[j].ip_port = ip_port; 395 send_nodes[j].ip_port = ip_port;
337 send_nodes[j].ping_id = ping_id; 396 send_nodes[j].ping_id = ping_id;
338 return ping_id; 397 return ping_id;
@@ -344,11 +403,12 @@ int add_gettingnodes(IP_Port ip_port)
344} 403}
345 404
346 405
406
347//send a ping request 407//send a ping request
348//Ping request only works if there is none hos been sent to that ip/port in the last 5 seconds. 408//Ping request only works if there is none hos been sent to that ip/port in the last 5 seconds.
349int pingreq(IP_Port ip_port) 409int pingreq(IP_Port ip_port)
350{ 410{
351 if(is_pinging(ip_port)) 411 if(is_pinging(ip_port, 0))
352 { 412 {
353 return 1; 413 return 1;
354 } 414 }
@@ -385,7 +445,7 @@ int pingres(IP_Port ip_port, uint32_t ping_id)
385//send a getnodes request 445//send a getnodes request
386int getnodes(IP_Port ip_port, char * client_id) 446int getnodes(IP_Port ip_port, char * client_id)
387{ 447{
388 if(is_gettingnodes(ip_port)) 448 if(is_gettingnodes(ip_port, 0))
389 { 449 {
390 return 1; 450 return 1;
391 } 451 }
@@ -448,6 +508,13 @@ int handle_pingreq(char * packet, uint32_t length, IP_Port source)//tested
448 uint32_t ping_id; 508 uint32_t ping_id;
449 509
450 memcpy(&ping_id, packet + 1, 4); 510 memcpy(&ping_id, packet + 1, 4);
511 IP_Port bad_ip = {{{0}}, 0};
512
513 if(is_pinging(bad_ip, ping_id))//check if packet is from ourself.
514 {
515 return 1;
516 }
517
451 pingres(source, ping_id); 518 pingres(source, ping_id);
452 519
453 pingreq(source); 520 pingreq(source);
@@ -456,15 +523,21 @@ int handle_pingreq(char * packet, uint32_t length, IP_Port source)//tested
456 523
457} 524}
458 525
459int handle_pingres(char * packet, uint32_t length, IP_Port source)//tested 526int handle_pingres(char * packet, uint32_t length, IP_Port source)
460{ 527{
461 if(length != (5 + CLIENT_ID_SIZE)) 528 if(length != (5 + CLIENT_ID_SIZE))
462 { 529 {
463 return 1; 530 return 1;
464 } 531 }
532 uint32_t ping_id;
465 533
466 addto_lists(source, packet + 5); 534 memcpy(&ping_id, packet + 1, 4);
467 return 0; 535 if(is_pinging(source, ping_id))
536 {
537 addto_lists(source, packet + 5);
538 return 0;
539 }
540 return 1;
468 541
469} 542}
470 543
@@ -478,6 +551,13 @@ int handle_getnodes(char * packet, uint32_t length, IP_Port source)
478 memcpy(&ping_id, packet + 1, 4); 551 memcpy(&ping_id, packet + 1, 4);
479 sendnodes(source, packet + 5 + CLIENT_ID_SIZE, ping_id); 552 sendnodes(source, packet + 5 + CLIENT_ID_SIZE, ping_id);
480 553
554 IP_Port bad_ip = {{{0}}, 0};
555
556 if(is_gettingnodes(bad_ip, ping_id))//check if packet is from ourself.
557 {
558 return 1;
559 }
560
481 pingreq(source); 561 pingreq(source);
482 562
483 return 0; 563 return 0;
@@ -493,6 +573,13 @@ int handle_sendnodes(char * packet, uint32_t length, IP_Port source)//tested
493 } 573 }
494 int num_nodes = (length - 5 - CLIENT_ID_SIZE) / (CLIENT_ID_SIZE + sizeof(IP_Port)); 574 int num_nodes = (length - 5 - CLIENT_ID_SIZE) / (CLIENT_ID_SIZE + sizeof(IP_Port));
495 uint32_t i; 575 uint32_t i;
576 uint32_t ping_id;
577
578 memcpy(&ping_id, packet + 1, 4);
579 if(!is_gettingnodes(source, ping_id))
580 {
581 return 1;
582 }
496 583
497 Node_format nodes_list[MAX_SENT_NODES]; 584 Node_format nodes_list[MAX_SENT_NODES];
498 memcpy(nodes_list, packet + 5 + CLIENT_ID_SIZE, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port))); 585 memcpy(nodes_list, packet + 5 + CLIENT_ID_SIZE, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port)));
@@ -513,7 +600,7 @@ int handle_sendnodes(char * packet, uint32_t length, IP_Port source)//tested
513 600
514int addfriend(char * client_id) 601int addfriend(char * client_id)
515{ 602{
516 //TODO:Maybe make the array of friends dynamic instead of a static array with 256 603 //TODO:Maybe make the array of friends dynamic instead of a static array with MAX_FRIENDS
517 if(MAX_FRIENDS > num_friends) 604 if(MAX_FRIENDS > num_friends)
518 { 605 {
519 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); 606 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE);
@@ -609,7 +696,7 @@ int DHT_recvpacket(char * packet, uint32_t length, IP_Port source)
609#define PING_INTERVAL 60 696#define PING_INTERVAL 60
610 697
611//ping interval in seconds for each random sending of a get nodes request. 698//ping interval in seconds for each random sending of a get nodes request.
612#define GET_NODE_INTERVAL 20 699#define GET_NODE_INTERVAL 10
613 700
614//Ping each client in the "friends" list every 60 seconds. 701//Ping each client in the "friends" list every 60 seconds.
615//Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. 702//Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list.
@@ -679,7 +766,6 @@ void doClose()//tested
679 index[num_nodes] = i; 766 index[num_nodes] = i;
680 num_nodes++; 767 num_nodes++;
681 } 768 }
682 //TODO: Send getnodes requests
683 } 769 }
684 } 770 }
685 771