diff options
author | irungentoo <irungentoo@gmail.com> | 2013-06-25 09:19:01 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2013-06-25 09:19:01 -0400 |
commit | c93858110bb17ce35143bae7ba9aa68fac93f46b (patch) | |
tree | cf2df0b4b2af4d829e3583fedc1fe7e30f666a57 /core | |
parent | b9563fd9e27261ef3d48cb82decfa198e61cca86 (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.c | 157 | ||||
-rw-r--r-- | core/DHT.h | 1 |
2 files changed, 119 insertions, 39 deletions
@@ -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 |
8 | int sendpacket(IP_Port ip_port, char * data, uint32_t length) | 8 | int 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) |
86 | int client_in_nodelist(Node_format * list, uint32_t length, char * client_id) | 85 | int 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 |
219 | int addto_lists(IP_Port ip_port, char * client_id) | 217 | void 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 |
299 | int add_pinging(IP_Port ip_port) | 298 | int 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. | ||
340 | int pingreq(IP_Port ip_port) | 342 | int 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 |
395 | int sendnodes(IP_Port ip_port, char * client_id) | 406 | int 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 | ||
437 | int handle_getnodes(char * packet, uint32_t length, IP_Port source) | 456 | int 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. | |
496 | IP_Port getfriendip(char * client_id) | 526 | IP_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) | |||
526 | return 0; | 575 | return 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. |
531 | void doFriends() | 586 | void 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 | ||
539 | void doClose() | 608 | void 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 | ||
548 | void doDHT() | 628 | void doDHT() |
549 | { | 629 | { |
550 | 630 | doClose(); | |
551 | 631 | doFriends(); | |
552 | |||
553 | } | 632 | } |
554 | 633 | ||
555 | 634 | ||
@@ -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. | ||
109 | IP_Port getfriendip(char * client_id); | 110 | IP_Port getfriendip(char * client_id); |
110 | 111 | ||
111 | 112 | ||