summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-06-25 09:19:01 -0400
committerirungentoo <irungentoo@gmail.com>2013-06-25 09:19:01 -0400
commitc93858110bb17ce35143bae7ba9aa68fac93f46b (patch)
treecf2df0b4b2af4d829e3583fedc1fe7e30f666a57 /core
parentb9563fd9e27261ef3d48cb82decfa198e61cca86 (diff)
DHT almost done, started testing. Fixed ADDR compiling problem. No more warnings with GCC and clang.
Diffstat (limited to 'core')
-rw-r--r--core/DHT.c157
-rw-r--r--core/DHT.h1
2 files changed, 119 insertions, 39 deletions
diff --git a/core/DHT.c b/core/DHT.c
index fd34db71..37f8b323 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -7,8 +7,7 @@
7//Function to send packet(data) of length length to ip_port 7//Function to send packet(data) of length length to ip_port
8int sendpacket(IP_Port ip_port, char * data, uint32_t length) 8int sendpacket(IP_Port ip_port, char * data, uint32_t length)
9{ 9{
10 ADDR addr = {.family = AF_INET, .ip = ip_port.ip, .port = ip_port.port}; 10 ADDR addr = {AF_INET, ip_port.port, ip_port.ip};
11
12 return sendto(sock, data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); 11 return sendto(sock, data, length, 0, (struct sockaddr *)&addr, sizeof(addr));
13} 12}
14 13
@@ -71,7 +70,7 @@ int client_in_list(Client_data * list, uint32_t length, char * client_id)
71 break; 70 break;
72 } 71 }
73 } 72 }
74 if((j - 1) == CLIENT_ID_SIZE) 73 if(j == CLIENT_ID_SIZE)
75 { 74 {
76 //Refresh the client timestamp. 75 //Refresh the client timestamp.
77 list[i].timestamp = unix_time(); 76 list[i].timestamp = unix_time();
@@ -81,7 +80,7 @@ int client_in_list(Client_data * list, uint32_t length, char * client_id)
81 return 0; 80 return 0;
82} 81}
83 82
84//check if client with client_id is already in knode format list of length length. 83//check if client with client_id is already in node format list of length length.
85//return True(1) or False(0) 84//return True(1) or False(0)
86int client_in_nodelist(Node_format * list, uint32_t length, char * client_id) 85int client_in_nodelist(Node_format * list, uint32_t length, char * client_id)
87{ 86{
@@ -96,7 +95,7 @@ int client_in_nodelist(Node_format * list, uint32_t length, char * client_id)
96 break; 95 break;
97 } 96 }
98 } 97 }
99 if((j - 1) == CLIENT_ID_SIZE) 98 if(j == CLIENT_ID_SIZE)
100 { 99 {
101 100
102 return 1; 101 return 1;
@@ -161,19 +160,18 @@ int get_close_nodes(char * client_id, Node_format * nodes_list)
161 } 160 }
162 else for(k = 0; k < MAX_SENT_NODES; k++) 161 else for(k = 0; k < MAX_SENT_NODES; k++)
163 { 162 {
164 if(id_closest(client_id, nodes_list[j].client_id, friends_list[i].client_list[j].client_id) == 2) 163 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2)
165 { 164 {
166 memcpy(nodes_list[j].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); 165 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
167 nodes_list[j].ip_port = friends_list[i].client_list[j].ip_port; 166 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
168 break; 167 break;
169 } 168 }
170 } 169 }
171 } 170 }
172
173 } 171 }
174
175 } 172 }
176 173
174 return num_nodes;
177} 175}
178 176
179 177
@@ -216,7 +214,7 @@ int replace_good(Client_data * list, uint32_t length, char * client_id, IP_Port
216} 214}
217 215
218//Attempt to add client with ip_port and client_id to the friends client list and close_clientlist 216//Attempt to add client with ip_port and client_id to the friends client list and close_clientlist
219int addto_lists(IP_Port ip_port, char * client_id) 217void addto_lists(IP_Port ip_port, char * client_id)
220{ 218{
221 uint32_t i; 219 uint32_t i;
222 220
@@ -295,6 +293,7 @@ int is_gettingnodes(IP_Port ip_port)
295 293
296//Add a new ping request to the list of ping requests 294//Add a new ping request to the list of ping requests
297//returns the ping_id to put in the ping request 295//returns the ping_id to put in the ping request
296//returns 0 if problem.
298//TODO: Maybe optimize this 297//TODO: Maybe optimize this
299int add_pinging(IP_Port ip_port) 298int add_pinging(IP_Port ip_port)
300{ 299{
@@ -313,6 +312,7 @@ int add_pinging(IP_Port ip_port)
313 } 312 }
314 } 313 }
315 } 314 }
315 return 0;
316} 316}
317 317
318//Same but for get node requests 318//Same but for get node requests
@@ -333,10 +333,12 @@ int add_gettingnodes(IP_Port ip_port)
333 } 333 }
334 } 334 }
335 } 335 }
336 return 0;
336} 337}
337 338
338 339
339//send a ping request 340//send a ping request
341//Ping request only works if there is none hos been sent to that ip/port in the last 5 seconds.
340int pingreq(IP_Port ip_port) 342int pingreq(IP_Port ip_port)
341{ 343{
342 if(is_pinging(ip_port)) 344 if(is_pinging(ip_port))
@@ -345,6 +347,10 @@ int pingreq(IP_Port ip_port)
345 } 347 }
346 348
347 int ping_id = add_pinging(ip_port); 349 int ping_id = add_pinging(ip_port);
350 if(ping_id == 0)
351 {
352 return 1;
353 }
348 354
349 char data[5 + CLIENT_ID_SIZE]; 355 char data[5 + CLIENT_ID_SIZE];
350 data[0] = 0; 356 data[0] = 0;
@@ -377,7 +383,12 @@ int getnodes(IP_Port ip_port, char * client_id)
377 return 1; 383 return 1;
378 } 384 }
379 385
380 int ping_id = add_pinging(ip_port); 386 int ping_id = add_gettingnodes(ip_port);
387
388 if(ping_id == 0)
389 {
390 return 1;
391 }
381 392
382 char data[5 + CLIENT_ID_SIZE*2]; 393 char data[5 + CLIENT_ID_SIZE*2];
383 data[0] = 2; 394 data[0] = 2;
@@ -392,15 +403,20 @@ int getnodes(IP_Port ip_port, char * client_id)
392 403
393//send a send nodes response 404//send a send nodes response
394//Currently incomplete: missing bunch of stuff 405//Currently incomplete: missing bunch of stuff
395int sendnodes(IP_Port ip_port, char * client_id) 406int sendnodes(IP_Port ip_port, char * client_id, uint32_t ping_id)
396{ 407{
397 char data[5 + (CLIENT_ID_SIZE + sizeof(IP_Port))*MAX_SENT_NODES]; 408 char data[5 + (CLIENT_ID_SIZE + sizeof(IP_Port))*MAX_SENT_NODES];
409 Node_format nodes_list[MAX_SENT_NODES];
410
411 int num_nodes = get_close_nodes(client_id, nodes_list);
412
398 data[0] = 3; 413 data[0] = 3;
399 414
415 memcpy(data + 1, &ping_id, 4);
400 memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); 416 memcpy(data + 5, self_client_id, CLIENT_ID_SIZE);
401 memcpy(data + 5 + CLIENT_ID_SIZE, client_id, CLIENT_ID_SIZE); 417 memcpy(data + 5 + CLIENT_ID_SIZE, nodes_list, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port)));
402 418
403 sendpacket(ip_port, data, sizeof(data)); 419 return sendpacket(ip_port, data, sizeof(data));
404} 420}
405 421
406 422
@@ -420,6 +436,8 @@ int handle_pingreq(char * packet, uint32_t length, IP_Port source)
420 436
421 memcpy(&ping_id, packet + 1, 4); 437 memcpy(&ping_id, packet + 1, 4);
422 pingres(source, ping_id); 438 pingres(source, ping_id);
439
440 pingreq(source);
423 441
424 return 0; 442 return 0;
425} 443}
@@ -432,6 +450,7 @@ int handle_pingres(char * packet, uint32_t length, IP_Port source)
432 } 450 }
433 451
434 addto_lists(source, packet + 5); 452 addto_lists(source, packet + 5);
453 return 0;
435} 454}
436 455
437int handle_getnodes(char * packet, uint32_t length, IP_Port source) 456int handle_getnodes(char * packet, uint32_t length, IP_Port source)
@@ -440,9 +459,9 @@ int handle_getnodes(char * packet, uint32_t length, IP_Port source)
440 { 459 {
441 return 1; 460 return 1;
442 } 461 }
443 //sendnodes(IP_Port ip_port, char * client_id) 462 uint32_t ping_id;
444 463 memcpy(&ping_id, packet + 1, 4);
445 464 sendnodes(source, packet + 5 + CLIENT_ID_SIZE, ping_id);
446 465
447 return 0; 466 return 0;
448} 467}
@@ -454,8 +473,19 @@ int handle_sendnodes(char * packet, uint32_t length, IP_Port source)
454 { 473 {
455 return 1; 474 return 1;
456 } 475 }
457 addto_lists(source, packet + 5); 476 int num_nodes = (length - 5) / (CLIENT_ID_SIZE + sizeof(IP_Port));
477 uint32_t i;
478
479 Node_format nodes_list[MAX_SENT_NODES];
480 memcpy(nodes_list, packet + 5, num_nodes);
458 481
482 for(i = 0; i < num_nodes; i++)
483 {
484 pingreq(nodes_list[i].ip_port);
485 }
486
487 addto_lists(source, packet + 5);
488 return 0;
459} 489}
460 490
461//END of packet handling functions 491//END of packet handling functions
@@ -492,14 +522,33 @@ char delfriend(char * client_id)
492 522
493 523
494 524
495 525//TODO: Optimize this.
496IP_Port getfriendip(char * client_id) 526IP_Port getfriendip(char * client_id)
497{ 527{
528 uint32_t i, j;
529 IP_Port empty = {{{0}}, 0};
498 530
531 for(i = 0; i < num_friends; i++)
532 {
533 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)//Equal
534 {
535 for(j = 0; j < MAX_FRIEND_CLIENTS; j++)
536 {
537 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0)
538 {
539 return friends_list[i].client_list[j].ip_port;
540 }
541
542 }
543
544 return empty;
545 }
546 }
547 empty.ip.i = 1;
548 return empty;
549}
499 550
500 551
501}
502
503 552
504 553
505 554
@@ -507,17 +556,17 @@ int DHT_recvpacket(char * packet, uint32_t length, IP_Port source)
507{ 556{
508 switch (packet[0]) { 557 switch (packet[0]) {
509 case 0: 558 case 0:
510 handle_pingreq(packet, length, source); 559 return handle_pingreq(packet, length, source);
511 break; 560
512 case 1: 561 case 1:
513 handle_pingres(packet, length, source); 562 return handle_pingres(packet, length, source);
514 break; 563
515 case 2: 564 case 2:
516 handle_getnodes(packet, length, source); 565 return handle_getnodes(packet, length, source);
517 break; 566
518 case 3: 567 case 3:
519 handle_sendnodes(packet, length, source); 568 return handle_sendnodes(packet, length, source);
520 break; 569
521 default: 570 default:
522 return 1; 571 return 1;
523 572
@@ -526,30 +575,60 @@ int DHT_recvpacket(char * packet, uint32_t length, IP_Port source)
526return 0; 575return 0;
527} 576}
528 577
578//The timeout after which a node is discarded completely.
579#define Kill_NODE_TIMEOUT 300
580
581//ping interval in seconds for each node in our lists.
582#define PING_INTERVAL 60
583
529//Ping each client in the "friends" list every 60 seconds. 584//Ping each client in the "friends" list every 60 seconds.
530//Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. 585//Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list.
531void doFriends() 586void doFriends()
532{ 587{
533 588 uint32_t i, j;
534 589 uint32_t temp_time = unix_time();
535 590 for(i = 0; i < num_friends; i++)
591 {
592 for(j = 0; j < MAX_FRIEND_CLIENTS; j++)
593 {
594 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time)//if node is not dead.
595 {
596 //TODO: Make this better, it only works if the function is called more than once per second.
597 if((temp_time - friends_list[i].client_list[j].timestamp) % PING_INTERVAL == 0)
598 {
599 pingreq(friends_list[i].client_list[j].ip_port);
600 }
601 //TODO: Send getnodes requests
602 }
603 }
604 }
536} 605}
537 606
538 607
539void doClose() 608void doClose()
540{ 609{
541 610 uint32_t i;
542 611 uint32_t temp_time = unix_time();
543 612 for(i = 0; i < MAX_FRIEND_CLIENTS; i++)
613 {
614 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time)//if node is not dead.
615 {
616 //TODO: Make this better, it only works if the function is called more than once per second.
617 if((temp_time - close_clientlist[i].timestamp) % PING_INTERVAL == 0)
618 {
619 pingreq(close_clientlist[i].ip_port);
620 }
621 //TODO: Send getnodes requests
622 }
623 }
544} 624}
545 625
546 626
547 627
548void doDHT() 628void doDHT()
549{ 629{
550 630 doClose();
551 631 doFriends();
552
553} 632}
554 633
555 634
diff --git a/core/DHT.h b/core/DHT.h
index 82a16cb7..4a8640e6 100644
--- a/core/DHT.h
+++ b/core/DHT.h
@@ -106,6 +106,7 @@ char delfriend(char * client_id);
106//port must be 2 bytes long. 106//port must be 2 bytes long.
107//returns ip if success 107//returns ip if success
108//returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) 108//returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.)
109//returns ip of 1 if friend is not in list.
109IP_Port getfriendip(char * client_id); 110IP_Port getfriendip(char * client_id);
110 111
111 112