diff options
author | Supriti Singh <supritisingh08@gmail.com> | 2014-04-28 15:28:19 +0000 |
---|---|---|
committer | Supriti Singh <supritisingh08@gmail.com> | 2014-04-28 15:28:19 +0000 |
commit | 49a2ed15bd67052f98813644eb3967dcb2e0f4f5 (patch) | |
tree | 16bb8eba4c75fab2900342d7022dc8dd3f710715 /src/dht | |
parent | a8504a84ee0161e36180811b1d44fd1dc3ab9b17 (diff) | |
download | gnunet-49a2ed15bd67052f98813644eb3967dcb2e0f4f5.tar.gz gnunet-49a2ed15bd67052f98813644eb3967dcb2e0f4f5.zip |
Handling trail rejection message, not using a failed trial list.
Diffstat (limited to 'src/dht')
-rw-r--r-- | src/dht/gnunet-service-xdht_neighbours.c | 1271 | ||||
-rw-r--r-- | src/dht/gnunet-service-xdht_routing.c | 22 | ||||
-rw-r--r-- | src/dht/gnunet-service-xdht_routing.h | 14 |
3 files changed, 896 insertions, 411 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c index e12afccf8..46247f9dd 100644 --- a/src/dht/gnunet-service-xdht_neighbours.c +++ b/src/dht/gnunet-service-xdht_neighbours.c | |||
@@ -47,12 +47,25 @@ | |||
47 | /* TODO: | 47 | /* TODO: |
48 | 1. Use a global array of all known peers in find_successor, Only when | 48 | 1. Use a global array of all known peers in find_successor, Only when |
49 | a new peer is added in finger or friend peer map, then re calculate | 49 | a new peer is added in finger or friend peer map, then re calculate |
50 | the array. Or else use the old one.*/ | 50 | the array. Or else use the old one. The benefit of having this list is something |
51 | * I am not sure. only when the code is complete and working I will do this part. | ||
52 | 2. Structure alignment. | ||
53 | 3. In case of trail setup, you can see the comment on top of finger map index, | ||
54 | * trial length --> in NBO. Check how do we keep it in NBO, and make sure its | ||
55 | * same everywhere. When i send any message across the network i use htonl, so that | ||
56 | * converts it into network byte order. | ||
57 | 4.THAT IN ROUTING TABLE SOURCE PEER IS INDEED THE SOURCE PEER. | ||
58 | should trail contain last element as finger or just the last element.? if | ||
59 | you can get some value then you should not keep at different places. | ||
60 | remove finger as last element in the trail. | ||
61 | 5. I have removed the last element in the trail which was finger identity as we | ||
62 | * are already sending finger identity in the message. handle the case in case | ||
63 | * of notify new successor and verify the successor. */ | ||
51 | 64 | ||
52 | /** | 65 | /** |
53 | * Maximum possible fingers of a peer. | 66 | * Maximum possible fingers of a peer. |
54 | */ | 67 | */ |
55 | #define MAX_FINGERS 63 | 68 | #define MAX_FINGERS 65 |
56 | 69 | ||
57 | /** | 70 | /** |
58 | * Maximum allowed number of pending messages per friend peer. | 71 | * Maximum allowed number of pending messages per friend peer. |
@@ -60,13 +73,12 @@ | |||
60 | #define MAXIMUM_PENDING_PER_FRIEND 64 | 73 | #define MAXIMUM_PENDING_PER_FRIEND 64 |
61 | 74 | ||
62 | /** | 75 | /** |
63 | * How long at least to wait before sending another find finger trail request, | 76 | * How long to wait before sending another find finger trail request |
64 | * at most we wait twice this long. | ||
65 | */ | 77 | */ |
66 | #define DHT_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) | 78 | #define DHT_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) |
67 | 79 | ||
68 | /** | 80 | /** |
69 | * How long at most to wait for transmission of a GET request to another peer? | 81 | * How long at most to wait for transmission of a request to another peer? |
70 | */ | 82 | */ |
71 | #define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) | 83 | #define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) |
72 | 84 | ||
@@ -75,7 +87,7 @@ | |||
75 | * FIXME: Random value at the moment, need to be adjusted to maintain a balance | 87 | * FIXME: Random value at the moment, need to be adjusted to maintain a balance |
76 | * between performance and Sybil tolerance. | 88 | * between performance and Sybil tolerance. |
77 | */ | 89 | */ |
78 | #define LINK_THRESHOLD 64 | 90 | #define TRAIL_THROUGH_FRIEND_THRESHOLD 64. |
79 | 91 | ||
80 | 92 | ||
81 | GNUNET_NETWORK_STRUCT_BEGIN | 93 | GNUNET_NETWORK_STRUCT_BEGIN |
@@ -107,6 +119,7 @@ struct PeerPutMessage | |||
107 | 119 | ||
108 | /** | 120 | /** |
109 | * Replication level for this message | 121 | * Replication level for this message |
122 | * In the current implementation, this value is not used. | ||
110 | */ | 123 | */ |
111 | uint32_t desired_replication_level GNUNET_PACKED; | 124 | uint32_t desired_replication_level GNUNET_PACKED; |
112 | 125 | ||
@@ -219,6 +232,7 @@ struct PeerGetMessage | |||
219 | 232 | ||
220 | /** | 233 | /** |
221 | * Desired replication level for this request. | 234 | * Desired replication level for this request. |
235 | * In the current implementation, this value is not used. | ||
222 | */ | 236 | */ |
223 | uint32_t desired_replication_level GNUNET_PACKED; | 237 | uint32_t desired_replication_level GNUNET_PACKED; |
224 | 238 | ||
@@ -248,7 +262,6 @@ struct PeerGetMessage | |||
248 | 262 | ||
249 | 263 | ||
250 | /** | 264 | /** |
251 | * FIXME: Check the alignment in all the struct | ||
252 | * P2P Trail setup message | 265 | * P2P Trail setup message |
253 | */ | 266 | */ |
254 | struct PeerTrailSetupMessage | 267 | struct PeerTrailSetupMessage |
@@ -278,19 +291,21 @@ struct PeerTrailSetupMessage | |||
278 | * In case the packet is forwarded to an intermediate finger, then | 291 | * In case the packet is forwarded to an intermediate finger, then |
279 | * current_source contains the peer id whose finger is the intermediate | 292 | * current_source contains the peer id whose finger is the intermediate |
280 | * finger. In case the packet is forwarded to a friend, then it is NULL. | 293 | * finger. In case the packet is forwarded to a friend, then it is NULL. |
294 | * FIXME: check the usage of current_source and fix this comment. | ||
281 | */ | 295 | */ |
282 | struct GNUNET_PeerIdentity current_source; | 296 | struct GNUNET_PeerIdentity current_source; |
283 | 297 | ||
284 | /** | 298 | /** |
285 | * Index into finger peer map, in NBO. | 299 | * Index into finger peer map, in Network Byte Order. |
286 | */ | 300 | */ |
287 | uint32_t finger_map_index; | 301 | uint32_t finger_map_index; |
288 | 302 | ||
289 | /** | 303 | /** |
290 | * Number of entries in trail list, in NBO. | 304 | * Number of entries in trail list, in Network Byte Order. |
291 | */ | 305 | */ |
292 | uint32_t trail_length GNUNET_PACKED; | 306 | uint32_t trail_length GNUNET_PACKED; |
293 | 307 | ||
308 | /* Trail formed in the process. */ | ||
294 | }; | 309 | }; |
295 | 310 | ||
296 | 311 | ||
@@ -316,19 +331,22 @@ struct PeerTrailSetupResultMessage | |||
316 | struct GNUNET_PeerIdentity destination_peer; | 331 | struct GNUNET_PeerIdentity destination_peer; |
317 | 332 | ||
318 | /** | 333 | /** |
319 | * Index into finger peer map | 334 | * Index into finger peer map in NBO. |
320 | */ | 335 | */ |
321 | uint32_t finger_map_index; | 336 | uint32_t finger_map_index; |
322 | 337 | ||
323 | /** | 338 | /** |
324 | * Number of entries in trail list. | 339 | * Number of entries in trail list in NBO. |
325 | */ | 340 | */ |
326 | uint32_t trail_length GNUNET_PACKED; | 341 | uint32_t trail_length GNUNET_PACKED; |
327 | 342 | ||
343 | /* Trail from destination_peer to finger_identity */ | ||
344 | |||
328 | }; | 345 | }; |
329 | 346 | ||
347 | |||
330 | /** | 348 | /** |
331 | * | 349 | * P2P Trail Rejection Message. |
332 | */ | 350 | */ |
333 | struct PeerTrailRejectionMessage | 351 | struct PeerTrailRejectionMessage |
334 | { | 352 | { |
@@ -348,9 +366,10 @@ struct PeerTrailRejectionMessage | |||
348 | struct GNUNET_PeerIdentity congested_peer; | 366 | struct GNUNET_PeerIdentity congested_peer; |
349 | 367 | ||
350 | /** | 368 | /** |
351 | * Finger identity value. | 369 | * Peer identity which will be successor to this value will be finger of |
370 | * source_peer. | ||
352 | */ | 371 | */ |
353 | uint64_t finger_identity; | 372 | uint64_t finger_identity_value; |
354 | 373 | ||
355 | /** | 374 | /** |
356 | * Index in finger peer map of source peer. | 375 | * Index in finger peer map of source peer. |
@@ -362,7 +381,8 @@ struct PeerTrailRejectionMessage | |||
362 | */ | 381 | */ |
363 | uint32_t trail_length; | 382 | uint32_t trail_length; |
364 | 383 | ||
365 | /* trail_list */ | 384 | /* Trail_list from source_peer to peer which sent the message for trail setup |
385 | * to congested peer.*/ | ||
366 | }; | 386 | }; |
367 | 387 | ||
368 | 388 | ||
@@ -391,6 +411,8 @@ struct PeerVerifySuccessorMessage | |||
391 | * Total number of peers in trail to current successor. | 411 | * Total number of peers in trail to current successor. |
392 | */ | 412 | */ |
393 | uint32_t trail_length; | 413 | uint32_t trail_length; |
414 | |||
415 | /* Trail to reach to from source_peer to successor. */ | ||
394 | }; | 416 | }; |
395 | 417 | ||
396 | 418 | ||
@@ -422,14 +444,17 @@ struct PeerVerifySuccessorResultMessage | |||
422 | 444 | ||
423 | /** | 445 | /** |
424 | * Total number of peers in trail. | 446 | * Total number of peers in trail. |
447 | */ | ||
448 | uint32_t trail_length; | ||
449 | |||
450 | /* Trail to reach from destination_peer to its correct successor. | ||
425 | * If source_successor is not destination peer, then trail is from destination_peer | 451 | * If source_successor is not destination peer, then trail is from destination_peer |
426 | * to my_predecessor. | 452 | * to my_predecessor. |
427 | * If source_successor is destination peer, then trail is from destination_peer | 453 | * If source_successor is destination peer, then trail is from destination_peer |
428 | * to source_successor. | 454 | * to source_successor. */ |
429 | */ | ||
430 | uint32_t trail_length; | ||
431 | }; | 455 | }; |
432 | 456 | ||
457 | |||
433 | /** | 458 | /** |
434 | * P2P Notify New Successor message. | 459 | * P2P Notify New Successor message. |
435 | */ | 460 | */ |
@@ -454,8 +479,34 @@ struct PeerNotifyNewSuccessorMessage | |||
454 | * Number of peers in trail from source_peer to new successor. | 479 | * Number of peers in trail from source_peer to new successor. |
455 | */ | 480 | */ |
456 | uint32_t trail_length; | 481 | uint32_t trail_length; |
482 | |||
483 | /* Trail to from source_peer to destination_peer. */ | ||
457 | }; | 484 | }; |
458 | 485 | ||
486 | struct PeerTrailTearDownMessage | ||
487 | { | ||
488 | /** | ||
489 | * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN | ||
490 | */ | ||
491 | struct GNUNET_MessageHeader header; | ||
492 | |||
493 | /** | ||
494 | * Source peer which wants to notify its new successor. | ||
495 | */ | ||
496 | struct GNUNET_PeerIdentity source_peer; | ||
497 | |||
498 | /** | ||
499 | * New successor identity. | ||
500 | */ | ||
501 | struct GNUNET_PeerIdentity destination_peer; | ||
502 | |||
503 | /** | ||
504 | * Number of peers in trail from source_peer to new successor. | ||
505 | */ | ||
506 | uint32_t trail_length; | ||
507 | |||
508 | /* Trail to from source_peer to destination_peer. */ | ||
509 | }; | ||
459 | 510 | ||
460 | GNUNET_NETWORK_STRUCT_END | 511 | GNUNET_NETWORK_STRUCT_END |
461 | 512 | ||
@@ -529,9 +580,24 @@ struct FriendInfo | |||
529 | struct GNUNET_PeerIdentity id; | 580 | struct GNUNET_PeerIdentity id; |
530 | 581 | ||
531 | /** | 582 | /** |
583 | * 1. used in select_random_friend(), in case the friend has trails_count > TRAILS_THROUGH_FRIEND, | ||
584 | * then choose another friend. | ||
585 | * 2. in case of find_successor(), if the number of trails going through the friend | ||
586 | * has already crossed, then choose another friend. | ||
587 | * 3. in case of find_successor(), if we choose a finger, and if friend through | ||
588 | * which we reach this finger has crossed the limit then choose another finger/friend. | ||
589 | * 4. One way to implement in case of find_successor, is 1) you can have a global | ||
590 | * array of the entries and only when an entry is added in finger table, friend table, | ||
591 | * then you re calculate the array. In array while adding the element you check | ||
592 | * the threshold of the friend in case its friend, and in case of finger check | ||
593 | * the threshold of the first friend in the trail. If crossed then don't add the | ||
594 | * entries in the array. When the count goes down, then again set a flag and | ||
595 | * recalculte the array. Store a field in Finger table also, which will be | ||
596 | * equal to number of trails going through the first friend. | ||
532 | * Number of trail of which this friend is the first hop. | 597 | * Number of trail of which this friend is the first hop. |
598 | * 5.FIXME: understand where you need to use memcpy or direct assignment. | ||
533 | */ | 599 | */ |
534 | unsigned int trail_links; | 600 | unsigned int trails_count; |
535 | 601 | ||
536 | /** | 602 | /** |
537 | * Count of outstanding messages for this friend. | 603 | * Count of outstanding messages for this friend. |
@@ -577,6 +643,12 @@ struct FingerInfo | |||
577 | unsigned int trail_length; | 643 | unsigned int trail_length; |
578 | 644 | ||
579 | /** | 645 | /** |
646 | * Number of trail of which the first element to reach to this finger is | ||
647 | * part of. | ||
648 | */ | ||
649 | unsigned int first_friend_trails_count; | ||
650 | |||
651 | /** | ||
580 | * Head of trail to reach this finger. | 652 | * Head of trail to reach this finger. |
581 | */ | 653 | */ |
582 | struct TrailPeerList *head; | 654 | struct TrailPeerList *head; |
@@ -588,6 +660,11 @@ struct FingerInfo | |||
588 | 660 | ||
589 | }; | 661 | }; |
590 | 662 | ||
663 | |||
664 | /** | ||
665 | * FIXME: The name is not correct. | ||
666 | * Used to specify the kind of value stored in the array all_known_peers. | ||
667 | */ | ||
591 | enum current_destination_type | 668 | enum current_destination_type |
592 | { | 669 | { |
593 | FRIEND, | 670 | FRIEND, |
@@ -596,9 +673,9 @@ enum current_destination_type | |||
596 | MY_ID | 673 | MY_ID |
597 | }; | 674 | }; |
598 | 675 | ||
676 | |||
599 | /** | 677 | /** |
600 | * FIXME: Think of a better name. | 678 | * Data structure passed to sorting algorithm in find_successor(). |
601 | * Data structure passed to sorting algorithm in find_successor. | ||
602 | */ | 679 | */ |
603 | struct Sorting_List | 680 | struct Sorting_List |
604 | { | 681 | { |
@@ -608,6 +685,7 @@ struct Sorting_List | |||
608 | uint64_t peer_id; | 685 | uint64_t peer_id; |
609 | 686 | ||
610 | /** | 687 | /** |
688 | * FIXME: think of a better name for both the struct and destination_type | ||
611 | * Type : MY_ID, FINGER, FINGER, Value | 689 | * Type : MY_ID, FINGER, FINGER, Value |
612 | */ | 690 | */ |
613 | enum current_destination_type type; | 691 | enum current_destination_type type; |
@@ -620,7 +698,7 @@ struct Sorting_List | |||
620 | 698 | ||
621 | 699 | ||
622 | /** | 700 | /** |
623 | * FIXME: Think of better comments. | 701 | * FIXME: Not sure if we really need any such data structure. |
624 | * An entry in Failed_Trail_List | 702 | * An entry in Failed_Trail_List |
625 | */ | 703 | */ |
626 | struct FailedTrail | 704 | struct FailedTrail |
@@ -644,13 +722,14 @@ struct FailedTrail | |||
644 | 722 | ||
645 | 723 | ||
646 | /** | 724 | /** |
647 | * Task that sends FIND FINGER TRAIL requests. | 725 | * Task that sends FIND FINGER TRAIL requests. This task is started when we have |
726 | * get our first friend. | ||
648 | */ | 727 | */ |
649 | static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task; | 728 | static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task; |
650 | 729 | ||
651 | /** | 730 | /** |
652 | * | 731 | * Task that periodically verifies my successor. This task is started when we |
653 | * Task that periodically verifies my successor. | 732 | * have found our successor. |
654 | */ | 733 | */ |
655 | static GNUNET_SCHEDULER_TaskIdentifier verify_successor; | 734 | static GNUNET_SCHEDULER_TaskIdentifier verify_successor; |
656 | 735 | ||
@@ -670,11 +749,6 @@ static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap; | |||
670 | static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap; | 749 | static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap; |
671 | 750 | ||
672 | /** | 751 | /** |
673 | * Hash maps of all the trail which failed due to a congested peer. | ||
674 | */ | ||
675 | static struct GNUNET_CONTAINER_MultiPeerMap *failed_trail_list; | ||
676 | |||
677 | /** | ||
678 | * Handle to CORE. | 752 | * Handle to CORE. |
679 | */ | 753 | */ |
680 | static struct GNUNET_CORE_Handle *core_api; | 754 | static struct GNUNET_CORE_Handle *core_api; |
@@ -684,22 +758,81 @@ static struct GNUNET_CORE_Handle *core_api; | |||
684 | */ | 758 | */ |
685 | #define PREDECESSOR_FINGER_ID 64 | 759 | #define PREDECESSOR_FINGER_ID 64 |
686 | 760 | ||
761 | unsigned int all_friends_trail_threshold; | ||
687 | /** | 762 | /** |
688 | * The current finger index that we have found trail to. | 763 | * FIXME: The problem with incrementing this value in find_finger_trail_task |
764 | * is that it may happen that we started with a request to look for a finger | ||
765 | * with current_finger_index = x, and its not yet complete but we are again back | ||
766 | * in send_find_finger_trail message and we again start looking for current_finger_index = x. | ||
767 | * and only when we get the entry for x, we make it x-1. I am not sure if this is | ||
768 | * correct. | ||
769 | * The current finger index that we have want to find trail to. | ||
689 | */ | 770 | */ |
690 | static unsigned int current_finger_index; | 771 | static unsigned int current_finger_index; |
691 | 772 | ||
773 | |||
692 | /** | 774 | /** |
693 | * Iterate over trail and search your index location in the array. | 775 | * Iterate over trail and search your index location in the array. |
694 | * @param trail Trail which contains list of peers. | 776 | * @param trail Trail which contains list of peers. |
777 | * @param trail_length Number of peers in the trail. | ||
695 | * @return Index in the array. | 778 | * @return Index in the array. |
779 | * #GNUNET_SYSERR, in case there is no entry which should not be the case ideally. | ||
696 | */ | 780 | */ |
697 | static int | 781 | static int |
698 | search_my_index (const struct GNUNET_PeerIdentity *trail) | 782 | search_my_index (const struct GNUNET_PeerIdentity *trail, |
783 | int trail_length) | ||
784 | { | ||
785 | int i = 0; | ||
786 | |||
787 | while (i < trail_length) | ||
788 | { | ||
789 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &trail[i])) | ||
790 | { | ||
791 | return i; | ||
792 | } | ||
793 | i++; | ||
794 | } | ||
795 | return GNUNET_SYSERR; | ||
796 | } | ||
797 | |||
798 | |||
799 | /** | ||
800 | * Invert the trail list. | ||
801 | * @param destination_peer Destination of the inverted trail.Trail is always | ||
802 | * (me, destination]. I am not part of trail that starts | ||
803 | * from me. | ||
804 | * @param existing_trail Trail | ||
805 | * @param trail_length Number of peers in the existing trail. | ||
806 | * @return | ||
807 | */ | ||
808 | static struct GNUNET_PeerIdentity * | ||
809 | invert_trail_list (struct GNUNET_PeerIdentity *destination_peer, | ||
810 | struct GNUNET_PeerIdentity *existing_trail, | ||
811 | unsigned int trail_length) | ||
699 | { | 812 | { |
700 | return 0; | 813 | int i; |
814 | int j; | ||
815 | struct GNUNET_PeerIdentity *new_trail; | ||
816 | |||
817 | j = 0; | ||
818 | new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length); | ||
819 | |||
820 | if (trail_length > 1) | ||
821 | { | ||
822 | i = trail_length - 2; | ||
823 | while (i >= 0 ) | ||
824 | { | ||
825 | memcpy( &new_trail[j], &existing_trail[i], sizeof (struct GNUNET_PeerIdentity)); | ||
826 | i--; | ||
827 | j++; | ||
828 | } | ||
829 | } | ||
830 | memcpy (&new_trail[j], destination_peer, sizeof(struct GNUNET_PeerIdentity)); | ||
831 | |||
832 | return new_trail; | ||
701 | } | 833 | } |
702 | 834 | ||
835 | |||
703 | /** | 836 | /** |
704 | * Called when core is ready to send a message we asked for | 837 | * Called when core is ready to send a message we asked for |
705 | * out to the destination. | 838 | * out to the destination. |
@@ -804,12 +937,6 @@ process_friend_queue (struct FriendInfo *peer) | |||
804 | 937 | ||
805 | 938 | ||
806 | /** | 939 | /** |
807 | * FIXME: In this function using const, does it affect only here right? not in | ||
808 | * the struct P2PTrailSetupMessage as their fields are not defined as const. | ||
809 | * Also, I changed current_destination and current_source from const to not, | ||
810 | * because when we make a call from handle_dht_p2p_trail_setup, then we are | ||
811 | * passing struct for current_destination and not current_source, as we are writing | ||
812 | * to these variables and we can not decalre them as const. | ||
813 | * Construct a trail message and forward it to a friend. | 940 | * Construct a trail message and forward it to a friend. |
814 | * @param source_peer Peer which wants to set up the trail to one of its finger. | 941 | * @param source_peer Peer which wants to set up the trail to one of its finger. |
815 | * @param destination_finger Peer identity closest to this value will be | 942 | * @param destination_finger Peer identity closest to this value will be |
@@ -849,8 +976,6 @@ GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer, | |||
849 | 976 | ||
850 | if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND) | 977 | if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND) |
851 | { | 978 | { |
852 | /* SUPU: Its important to have such statistics as you need to keep track of | ||
853 | the packets lost due to full queue. */ | ||
854 | GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), | 979 | GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), |
855 | 1, GNUNET_NO); | 980 | 1, GNUNET_NO); |
856 | } | 981 | } |
@@ -861,7 +986,6 @@ GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer, | |||
861 | pending->msg = &tsm->header; | 986 | pending->msg = &tsm->header; |
862 | tsm->header.size = htons (msize); | 987 | tsm->header.size = htons (msize); |
863 | tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP); | 988 | tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP); |
864 | /* FIXME: understand where you need to use memcpy or direct assignment. */ | ||
865 | memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t)); | 989 | memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t)); |
866 | memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); | 990 | memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); |
867 | memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity)); | 991 | memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity)); |
@@ -869,9 +993,6 @@ GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer, | |||
869 | tsm->trail_length = htonl (trail_length); | 993 | tsm->trail_length = htonl (trail_length); |
870 | tsm->finger_map_index = htonl (finger_map_index); | 994 | tsm->finger_map_index = htonl (finger_map_index); |
871 | 995 | ||
872 | /* SUPU: here i guess its okay to have it as NULL as it is added at the end of | ||
873 | the struct but in case of current_destination and current_source, it is part | ||
874 | of the struct. thats why the confusion. */ | ||
875 | if (trail_peer_list != NULL) | 996 | if (trail_peer_list != NULL) |
876 | { | 997 | { |
877 | peer_list = (struct GNUNET_PeerIdentity *) &tsm[1]; | 998 | peer_list = (struct GNUNET_PeerIdentity *) &tsm[1]; |
@@ -1111,6 +1232,61 @@ GDS_NEIGHBOURS_send_notify_new_successor (const struct GNUNET_PeerIdentity *sour | |||
1111 | process_friend_queue (target_friend); | 1232 | process_friend_queue (target_friend); |
1112 | } | 1233 | } |
1113 | 1234 | ||
1235 | /** | ||
1236 | * Send a trail tear down message | ||
1237 | * @param source_peer Source of the trail. | ||
1238 | * @param destination_peer Destination of the trail. | ||
1239 | * @param trail_list Peers in the trail from @a source_peer to @a destination_peer | ||
1240 | * @param trail_length Total number of peers in trail_list. | ||
1241 | * @pararm target_peer Next peer to forward this message to. | ||
1242 | */ | ||
1243 | void | ||
1244 | GDS_NEIGHBOURS_send_trail_teardown (struct GNUNET_PeerIdentity *source_peer, | ||
1245 | const struct GNUNET_PeerIdentity *destination_peer, | ||
1246 | struct GNUNET_PeerIdentity *trail_peer_list, | ||
1247 | unsigned int trail_length, | ||
1248 | struct FriendInfo *target_friend) | ||
1249 | { | ||
1250 | struct P2PPendingMessage *pending; | ||
1251 | struct PeerTrailTearDownMessage *ttdm; | ||
1252 | struct GNUNET_PeerIdentity *peer_list; | ||
1253 | size_t msize; | ||
1254 | |||
1255 | msize = sizeof (struct PeerTrailTearDownMessage) + | ||
1256 | (trail_length * sizeof(struct GNUNET_PeerIdentity)); | ||
1257 | |||
1258 | if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1259 | { | ||
1260 | GNUNET_break (0); | ||
1261 | return; | ||
1262 | } | ||
1263 | |||
1264 | if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND) | ||
1265 | { | ||
1266 | GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), | ||
1267 | 1, GNUNET_NO); | ||
1268 | } | ||
1269 | |||
1270 | pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); | ||
1271 | pending->importance = 0; /* FIXME */ | ||
1272 | pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT); | ||
1273 | ttdm = (struct PeerTrailTearDownMessage *) &pending[1]; | ||
1274 | pending->msg = &ttdm->header; | ||
1275 | ttdm->header.size = htons (msize); | ||
1276 | ttdm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN); | ||
1277 | memcpy (&(ttdm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); | ||
1278 | memcpy (&(ttdm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity)); | ||
1279 | ttdm->trail_length = htonl (trail_length); | ||
1280 | |||
1281 | peer_list = (struct GNUNET_PeerIdentity *) &ttdm[1]; | ||
1282 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
1283 | |||
1284 | /* Send the message to chosen friend. */ | ||
1285 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); | ||
1286 | target_friend->pending_count++; | ||
1287 | process_friend_queue (target_friend); | ||
1288 | } | ||
1289 | |||
1114 | 1290 | ||
1115 | /** | 1291 | /** |
1116 | * FIXME: Optimizaiton Once the basic code is running. Add the optimization | 1292 | * FIXME: Optimizaiton Once the basic code is running. Add the optimization |
@@ -1136,13 +1312,6 @@ select_random_friend (struct GNUNET_PeerIdentity *congested_peer) | |||
1136 | index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size); | 1312 | index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size); |
1137 | iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); | 1313 | iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); |
1138 | 1314 | ||
1139 | if (GNUNET_CONTAINER_multipeermap_size (friend_peermap) == 0) | ||
1140 | { | ||
1141 | /* FIXME: It may happen that there is not friend in friend peermap but | ||
1142 | as this task has already been started it failed.*/ | ||
1143 | GNUNET_break(0); | ||
1144 | return NULL; | ||
1145 | } | ||
1146 | while(j < (*index)) | 1315 | while(j < (*index)) |
1147 | { | 1316 | { |
1148 | if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL)) | 1317 | if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL)) |
@@ -1155,7 +1324,11 @@ select_random_friend (struct GNUNET_PeerIdentity *congested_peer) | |||
1155 | 1324 | ||
1156 | if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend)) | 1325 | if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend)) |
1157 | { | 1326 | { |
1158 | /* TODO: Here you have chosen a random friend. Now you should check the size | 1327 | /* TODO: UPDATE: Also, I think I am always looking for better trails, and always |
1328 | * choosing friends randomly so this solves the problem automatically. I don't | ||
1329 | * think I should call this algorithm here. Will read | ||
1330 | * the paper again and check if its right or not. Here you have | ||
1331 | * chosen a random friend. Now you should check the size | ||
1159 | of its routing table size, and if its more than threshold, then check which | 1332 | of its routing table size, and if its more than threshold, then check which |
1160 | of the entries has trail length greater than trail length threshold. we | 1333 | of the entries has trail length greater than trail length threshold. we |
1161 | should without checking the routing table size also we should check the | 1334 | should without checking the routing table size also we should check the |
@@ -1164,6 +1337,23 @@ select_random_friend (struct GNUNET_PeerIdentity *congested_peer) | |||
1164 | only for those finger entries whose trail length is greater than threshold. | 1337 | only for those finger entries whose trail length is greater than threshold. |
1165 | But I don't want the new node to wait for this process to get over. so | 1338 | But I don't want the new node to wait for this process to get over. so |
1166 | should i declare a function which will be called after some interval.*/ | 1339 | should i declare a function which will be called after some interval.*/ |
1340 | /* here we are checking the value only set by us. but the friend may have its | ||
1341 | routing table full. we don't have the access to the value. in trail setup | ||
1342 | it will fail. so in case of put/get if we don't have the trail already then | ||
1343 | how does the intermediate peer stores the information in routing table. | ||
1344 | because in put we don't do the put result. hence, intermediate peers don't | ||
1345 | add the path in their routing table. then in get is it problem. */ | ||
1346 | /* Possible number of trails that can go through this friend has been reached. */ | ||
1347 | if (friend->trails_count > TRAIL_THROUGH_FRIEND_THRESHOLD) | ||
1348 | { | ||
1349 | /* FIXME: What should I do now, should I call this same function again and | ||
1350 | remember the index, j so that call random function without j and find | ||
1351 | a new friend. Also, I need some way to make sure that if number of times | ||
1352 | I have called the function is equal to number of entries in friend peermap. | ||
1353 | then I should return NULL. but its much better to have a function which | ||
1354 | just eliminates looking at the entries with threshold crossed. URGENT: Whats | ||
1355 | the best way to handle this case? */ | ||
1356 | } | ||
1167 | return friend; | 1357 | return friend; |
1168 | } | 1358 | } |
1169 | else | 1359 | else |
@@ -1172,7 +1362,6 @@ select_random_friend (struct GNUNET_PeerIdentity *congested_peer) | |||
1172 | 1362 | ||
1173 | 1363 | ||
1174 | /** | 1364 | /** |
1175 | * FIMXE: pass current_finger_index as argument. | ||
1176 | * Compute finger_identity to which we want to setup the trail | 1365 | * Compute finger_identity to which we want to setup the trail |
1177 | * @return finger_identity | 1366 | * @return finger_identity |
1178 | */ | 1367 | */ |
@@ -1183,7 +1372,6 @@ compute_finger_identity() | |||
1183 | 1372 | ||
1184 | memcpy (&my_id64, &my_identity, sizeof (uint64_t)); | 1373 | memcpy (&my_id64, &my_identity, sizeof (uint64_t)); |
1185 | my_id64 = GNUNET_ntohll (my_id64); | 1374 | my_id64 = GNUNET_ntohll (my_id64); |
1186 | /*FIXME: Do we need a mod finger = ((my_id + pow(2, finger_index)) mod (pow (2, MAX_FINGERS))*/ | ||
1187 | return (my_id64 + (unsigned long) pow (2, current_finger_index)); | 1375 | return (my_id64 + (unsigned long) pow (2, current_finger_index)); |
1188 | } | 1376 | } |
1189 | 1377 | ||
@@ -1224,6 +1412,7 @@ send_verify_successor_message (void *cls, | |||
1224 | unsigned int i; | 1412 | unsigned int i; |
1225 | int flag = 0; | 1413 | int flag = 0; |
1226 | 1414 | ||
1415 | /* Find the successor from the finger peermap.*/ | ||
1227 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); | 1416 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); |
1228 | for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++) | 1417 | for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++) |
1229 | { | 1418 | { |
@@ -1279,17 +1468,6 @@ send_verify_successor_message (void *cls, | |||
1279 | 1468 | ||
1280 | 1469 | ||
1281 | /** | 1470 | /** |
1282 | * FIXME - the main logic of handling the finger map index has changed. | ||
1283 | * first we start with finger index = 64, that index is reserved for the | ||
1284 | * predecessor always. Then we start going backwards, finger_index = 63 to 0 | ||
1285 | * and once its 0 we again go back to 64. now, when you start looking for the finger | ||
1286 | * then your successor is always the finger with lowest finger index. in finger_table_add | ||
1287 | * whenever you do an entry you check for predecessor , if the new finger identity | ||
1288 | * is greater than existing one, then that should be your predecessor. In case of | ||
1289 | * other fingers also, if the new entry is smaller than existing one. If yes | ||
1290 | * then that is correct finger for that finger index. Also, the lowest finger index and | ||
1291 | * its corresponding finger identity is your successor. | ||
1292 | * | ||
1293 | * Choose a random friend and start looking for the trail to reach to | 1471 | * Choose a random friend and start looking for the trail to reach to |
1294 | * finger identity through this random friend. | 1472 | * finger identity through this random friend. |
1295 | * | 1473 | * |
@@ -1305,36 +1483,49 @@ send_find_finger_trail_message (void *cls, | |||
1305 | uint64_t finger_identity; | 1483 | uint64_t finger_identity; |
1306 | unsigned int finger_map_index; | 1484 | unsigned int finger_map_index; |
1307 | 1485 | ||
1308 | /* FIXME: understand how does this scheduling of processes take place? */ | ||
1309 | next_send_time.rel_value_us = | 1486 | next_send_time.rel_value_us = |
1310 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + | 1487 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + |
1311 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | 1488 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, |
1312 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us); | 1489 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us); |
1313 | /* FIXME: here we are just adding the process to the scheduling list. only | 1490 | |
1314 | when this function is executed, it may get scheduled. */ | 1491 | /* FIXME; if all the friend have reached their threshold, then don't schedule |
1492 | the task till the all_friends_trail_threshold gets reset. It will be | ||
1493 | scheduled from there. So, in finger table when we remove an entry and the new | ||
1494 | * entry does not have the same friend as the first hop, then decrement the | ||
1495 | * threshold limit. and schedule this task. | ||
1496 | IMPORTANT: reset the value some where. Better name */ | ||
1497 | if (GNUNET_YES == all_friends_trail_threshold) | ||
1498 | { | ||
1499 | return; | ||
1500 | } | ||
1501 | |||
1315 | find_finger_trail_task = | 1502 | find_finger_trail_task = |
1316 | GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message, | 1503 | GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message, |
1317 | NULL); | 1504 | NULL); |
1505 | |||
1506 | /* Friend peermap is empty but this task has already been started it failed.*/ | ||
1507 | if (GNUNET_CONTAINER_multipeermap_size (friend_peermap) == 0) | ||
1508 | { | ||
1509 | GNUNET_break(0); | ||
1510 | return; | ||
1511 | } | ||
1512 | |||
1318 | target_friend = select_random_friend (NULL); | 1513 | target_friend = select_random_friend (NULL); |
1319 | 1514 | ||
1320 | if (NULL == target_friend) | 1515 | if (NULL == target_friend) |
1321 | { | 1516 | { |
1322 | /* SUPU: Here we can get NULL in the case there is no friend in the peer map | 1517 | /* FIXME URGENT: Here we can get NULL all of the friends have reached their threshold. |
1323 | or all of the friends have reached their threshold. The first case should ideally | 1518 | * At the moment, the code for select_random_friend, is not handling it. In such a |
1324 | never happen because in handle_core_disconnect we have already canceled the task | 1519 | * case I think we can set a flag, and only when any value for any friend gets |
1325 | but it may happen if we already started the process and we reached here and | 1520 | * decremented,(which can happen only in finger table, when we remove an entry |
1326 | we cancelled the next task. So, it can return NULL in that case also. Should | 1521 | * from our finger table, and we are not part of the trail to reach to that |
1327 | we handle both cases in same way or not? */ | 1522 | * finger any more, t then reset the flag and schedule the code from there. */ |
1523 | all_friends_trail_threshold = GNUNET_YES; | ||
1328 | return; | 1524 | return; |
1329 | } | 1525 | } |
1330 | 1526 | ||
1331 | /* FIXME: start with current_finger_index = 64, */ | ||
1332 | if (PREDECESSOR_FINGER_ID == current_finger_index) | 1527 | if (PREDECESSOR_FINGER_ID == current_finger_index) |
1333 | { | 1528 | { |
1334 | /* FIXME: Where do we set the value back to PREDECESSR_FINGER_ID? Only | ||
1335 | when current_finger_index = 0, do we set it back to PREDECESSOR_FINGER_ID, | ||
1336 | in finger_table_add? Or is there any other possible condition, where we | ||
1337 | may need to set it to PREDECESSOR_FINGER_ID*/ | ||
1338 | finger_identity = compute_predecessor_identity(); | 1529 | finger_identity = compute_predecessor_identity(); |
1339 | } | 1530 | } |
1340 | else | 1531 | else |
@@ -1344,69 +1535,15 @@ send_find_finger_trail_message (void *cls, | |||
1344 | 1535 | ||
1345 | finger_map_index = current_finger_index; | 1536 | finger_map_index = current_finger_index; |
1346 | 1537 | ||
1347 | /* FIXME: verify if its correct to set current_destination and current_source | 1538 | /* URGENT :FIXME: In case the packet is not sent to a finger, then current_source is the |
1348 | as my identity. Check what should be the best value to set for current_dest | 1539 | * peer which sent the packet and current_destination which recevied it. Now |
1349 | * and current_source. */ | 1540 | * these fields are not always used. Think of some way to remove these variables. */ |
1350 | GDS_NEIGHBOURS_send_trail_setup (&my_identity, finger_identity, &(target_friend->id), | 1541 | GDS_NEIGHBOURS_send_trail_setup (&my_identity, finger_identity, &(target_friend->id), |
1351 | &(target_friend->id), target_friend, 0, NULL, finger_map_index); | 1542 | &my_identity, target_friend, 0, NULL, finger_map_index); |
1352 | } | 1543 | } |
1353 | 1544 | ||
1354 | 1545 | ||
1355 | /** | 1546 | /** |
1356 | * Invert the trail list. | ||
1357 | * @param destination_peer | ||
1358 | * @param existing_trail | ||
1359 | * @param trail_length | ||
1360 | * @return | ||
1361 | */ | ||
1362 | static struct GNUNET_PeerIdentity * | ||
1363 | invert_trail_list (struct GNUNET_PeerIdentity *destination_peer, | ||
1364 | struct GNUNET_PeerIdentity *existing_trail, | ||
1365 | unsigned int trail_length) | ||
1366 | { | ||
1367 | int i; | ||
1368 | int j; | ||
1369 | struct GNUNET_PeerIdentity *new_trail; | ||
1370 | |||
1371 | j = 0; | ||
1372 | new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length); | ||
1373 | |||
1374 | if (trail_length > 1) | ||
1375 | { | ||
1376 | i = trail_length - 2; | ||
1377 | while (i >= 0 ) | ||
1378 | { | ||
1379 | memcpy( &new_trail[j], &existing_trail[i], sizeof (struct GNUNET_PeerIdentity)); | ||
1380 | i--; | ||
1381 | j++; | ||
1382 | } | ||
1383 | } | ||
1384 | memcpy (&new_trail[j], destination_peer, sizeof(struct GNUNET_PeerIdentity)); | ||
1385 | |||
1386 | return new_trail; | ||
1387 | } | ||
1388 | |||
1389 | |||
1390 | #if 0 | ||
1391 | /** | ||
1392 | * | ||
1393 | * @param existing_finger | ||
1394 | * @param new_finger | ||
1395 | * @return | ||
1396 | */ | ||
1397 | static int | ||
1398 | compare_finger_identity (struct GNUNET_PeerIdentity *existing_finger, | ||
1399 | struct GNUNET_PeerIdentity *new_finger) | ||
1400 | { | ||
1401 | int ret; | ||
1402 | ret = (existing_finger > new_finger) ? 1 : | ||
1403 | (existing_finger == new_finger) ? 0 : -1; | ||
1404 | return ret; | ||
1405 | } | ||
1406 | #endif | ||
1407 | |||
1408 | |||
1409 | /** | ||
1410 | * Check if there is a predecessor in our finger peer map or not. | 1547 | * Check if there is a predecessor in our finger peer map or not. |
1411 | * If no, then return GNUNET_YES | 1548 | * If no, then return GNUNET_YES |
1412 | * else compare existing predecessor and peer, and find the correct | 1549 | * else compare existing predecessor and peer, and find the correct |
@@ -1425,6 +1562,41 @@ compare_predecessor(struct GNUNET_PeerIdentity *peer) | |||
1425 | return GNUNET_YES; | 1562 | return GNUNET_YES; |
1426 | } | 1563 | } |
1427 | 1564 | ||
1565 | #if 0 | ||
1566 | static int | ||
1567 | update_predecessor (struct GNUNET_PeerIdentity *peer, struct GNUNET_PeerIdentity *trail_peer_list) | ||
1568 | { | ||
1569 | /* In this function, we check if there is an entry or not for predecessor. | ||
1570 | if not then just add the peer, if no then compare the closest one, and add it | ||
1571 | . and remove the older one. There can still be multiple paths to reach to | ||
1572 | predecessor so in case both are same then make sure the paths are disjoint | ||
1573 | and then do multiple routing options. Also, invert the trail. and then add. | ||
1574 | Do all the things here. */ | ||
1575 | return GNUNET_NO; | ||
1576 | } | ||
1577 | #endif | ||
1578 | |||
1579 | /** | ||
1580 | * FIXME: free_finger(remove_finger); Call this function at finger_table_add, | ||
1581 | when you replace an existing entry | ||
1582 | * Free finger and its trail. | ||
1583 | * @param remove_finger Finger to be freed. | ||
1584 | */ | ||
1585 | static void | ||
1586 | free_finger (struct FingerInfo *finger) | ||
1587 | { | ||
1588 | struct TrailPeerList *peer; | ||
1589 | |||
1590 | while (NULL != (peer = finger->head)) | ||
1591 | { | ||
1592 | GNUNET_CONTAINER_DLL_remove (finger->head, finger->tail, peer); | ||
1593 | GNUNET_free (peer); | ||
1594 | } | ||
1595 | |||
1596 | GNUNET_free (finger); | ||
1597 | } | ||
1598 | |||
1599 | |||
1428 | /** | 1600 | /** |
1429 | * | 1601 | * |
1430 | * @return | 1602 | * @return |
@@ -1434,52 +1606,146 @@ check_for_successor () | |||
1434 | { | 1606 | { |
1435 | return NULL; | 1607 | return NULL; |
1436 | } | 1608 | } |
1609 | |||
1610 | |||
1437 | /** | 1611 | /** |
1438 | * Scan the trail, check if there is a friend in the trail, then shortcut | 1612 | * FIXME: How do I send back the updated trail. |
1439 | * the trail and return the new trail and trail length. | 1613 | * Scan the trail to check if any on my own friend is part of trail. If yes |
1440 | * FIXME: How to send the trail length? Should I create a new array and copy into | 1614 | * the shortcut the trail and update the finger_trail and trail_length. |
1441 | * it or modify the existing trail. also, how can it be done optimally? | ||
1442 | * @param finger_trail | 1615 | * @param finger_trail |
1616 | * @param trail_length | ||
1443 | * @return | 1617 | * @return |
1444 | */ | 1618 | */ |
1445 | #if 0 | ||
1446 | static struct GNUNET_PeerIdentity * | 1619 | static struct GNUNET_PeerIdentity * |
1447 | scan_trail (struct GNUNET_PeerIdentity *finger_trail) | 1620 | scan_trail (struct GNUNET_PeerIdentity *finger_trail, unsigned int trail_length, |
1448 | { | 1621 | const struct GNUNET_PeerIdentity *finger) |
1449 | return NULL; | ||
1450 | } | ||
1451 | #endif | ||
1452 | |||
1453 | /* @param cls closure | ||
1454 | * @param key current public key | ||
1455 | * @param value value in the hash map | ||
1456 | * @return #GNUNET_YES if we should continue to | ||
1457 | * iterate, | ||
1458 | * #GNUNET_NO if not. | ||
1459 | */ | ||
1460 | static int | ||
1461 | get_existing_finger (void *cls, | ||
1462 | const struct GNUNET_PeerIdentity *key, | ||
1463 | void *value) | ||
1464 | { | 1622 | { |
1465 | struct FingerInfo *existing_finger = value; | 1623 | /* start from the second element as first element will always be your friend. |
1466 | uint32_t finger_map_index = (uint32_t) cls; | 1624 | In case trail_length = 2, and the last element is also your friend then you |
1625 | should delete the first element. In other cases go through the list and check | ||
1626 | if the trail */ | ||
1627 | int i = trail_length - 1; | ||
1467 | 1628 | ||
1468 | if (existing_finger->finger_map_index == finger_map_index) | 1629 | while (i > 1) |
1469 | { | 1630 | { |
1470 | /* SUPU: How do I communicate this finger to the calling function. */ | 1631 | if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[i])) |
1632 | { | ||
1633 | /* This element of trail is not my friend. */ | ||
1634 | i--; | ||
1635 | } | ||
1636 | else | ||
1637 | { | ||
1638 | /* If for any i>1 we found a friend, then we can use this friend as the | ||
1639 | first link and forget about all the peers behind it. But we need to first | ||
1640 | copy the peers behind it. send a trail tear down message along | ||
1641 | that line. */ | ||
1642 | struct GNUNET_PeerIdentity *discarded_trail; | ||
1643 | struct FriendInfo *target_friend; | ||
1644 | /* FIXME: Create a new trail. to send back*/ | ||
1645 | int discarded_trail_length = trail_length - i; | ||
1646 | int j = 0; | ||
1647 | discarded_trail = GNUNET_malloc (discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
1648 | |||
1649 | while (j < (discarded_trail_length + 1)) | ||
1650 | { | ||
1651 | memcpy (&discarded_trail[j], &finger_trail[j], sizeof (struct GNUNET_PeerIdentity)); | ||
1652 | j++; | ||
1653 | } | ||
1654 | |||
1655 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[0]); | ||
1656 | /* FIXME: THAT IN ROUTING TABLE SOURCE PEER IS INDEED THE SOURCE PEER. | ||
1657 | * should trail contain last element as finger or just the last element.? if | ||
1658 | * you can get some value then you should not keep at different places. | ||
1659 | * remove finger as last element in the trail. */ | ||
1660 | GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, discarded_trail, | ||
1661 | discarded_trail_length, target_friend); | ||
1662 | |||
1663 | /* fixme: CHANGE IT TO NEW TRAIL */ | ||
1664 | return NULL; | ||
1665 | } | ||
1471 | } | 1666 | } |
1472 | return GNUNET_NO; | 1667 | return NULL; |
1473 | } | 1668 | } |
1474 | 1669 | ||
1475 | /** | 1670 | |
1476 | * TODO: | 1671 | /**TOD0. |
1477 | * If you remove an entry from finger table, and if the finger is not your friend | 1672 | * 1.* If you remove an entry from finger table, and if the finger is not your friend |
1478 | * and the trail length > 1 for the finger that you removed, then you should send | 1673 | * and the trail length > 1 for the finger that you removed, then you should send |
1479 | * a trail_teardown message along the trail. so that the peers which have an | 1674 | * a trail_teardown message along the trail. so that the peers which have an |
1480 | * entry in their routing table for this trail can remove it from their routing | 1675 | * entry in their routing table for this trail can remove it from their routing |
1481 | * table. | 1676 | * table. |
1482 | * 2. how to handle the case in which same finger identity is stored for different | 1677 | * 2. |
1678 | * Choose the closest successor from existing_finger and new_finger. In case new_finger | ||
1679 | * is choosen, then send a tear down message along the trail to reach existing_finger. | ||
1680 | * @param existing_finger Existing entry in finger peer map | ||
1681 | * @param new_finger New finger | ||
1682 | * @param trail Trail to reach to the new finger from me. | ||
1683 | * @param trail_length Number of peers in the @a trail | ||
1684 | * @param finger_map_index If finger_map_index == PREDECESSOR_FINGER_INDEX, | ||
1685 | * then we use a different logic to find the closest | ||
1686 | * predecessor. | ||
1687 | * @return #GNUNET_YES In case we want to store the new entry. | ||
1688 | * #GNUNET_NO In case we want the existing entry. | ||
1689 | * #GNUNET_SYSERR Error. | ||
1690 | */ | ||
1691 | static | ||
1692 | int select_correct_entry (struct FingerInfo *existing_finger, | ||
1693 | const struct GNUNET_PeerIdentity *new_finger, | ||
1694 | struct GNUNET_PeerIdentity *trail, | ||
1695 | unsigned int trail_length) | ||
1696 | { | ||
1697 | int val = GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger); | ||
1698 | if (0 == val) | ||
1699 | { | ||
1700 | /* FIXME: if the new entry = old entry, then compare the trails, and see if the trails | ||
1701 | are disjoint, then send GNUNET_YES, but don't free old finger. But first you | ||
1702 | * should collapse the trail and then do comparison. Also, if you are collapsing | ||
1703 | * for one case then you should do it for all the cases where you are sending | ||
1704 | * GNUNET_YES. */ | ||
1705 | /* Scan the trail for a friend and shorten if possible. */ | ||
1706 | scan_trail (trail, trail_length, new_finger); | ||
1707 | return GNUNET_YES; | ||
1708 | } | ||
1709 | else if (val > 0) | ||
1710 | { | ||
1711 | /* If the new entry is closest one, then free the old entry, send a trail_teardown message.*/ | ||
1712 | struct GNUNET_PeerIdentity *peer_list; | ||
1713 | struct FriendInfo *friend; | ||
1714 | struct TrailPeerList *finger_trail; | ||
1715 | int existing_finger_trail_length = existing_finger->trail_length; | ||
1716 | int i = 0; | ||
1717 | |||
1718 | finger_trail = existing_finger->head; | ||
1719 | friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer)); | ||
1720 | peer_list = GNUNET_malloc ( existing_finger_trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
1721 | while (i < existing_finger->trail_length) | ||
1722 | { | ||
1723 | memcpy (&peer_list[i], &(finger_trail->peer), sizeof (struct GNUNET_PeerIdentity)); | ||
1724 | finger_trail = finger_trail->next; | ||
1725 | i++; | ||
1726 | } | ||
1727 | |||
1728 | GDS_NEIGHBOURS_send_trail_teardown (&my_identity, &(existing_finger->finger_identity), | ||
1729 | peer_list, existing_finger_trail_length, friend); | ||
1730 | |||
1731 | free_finger (existing_finger); | ||
1732 | scan_trail (trail, trail_length, new_finger); | ||
1733 | return GNUNET_YES; | ||
1734 | } | ||
1735 | else | ||
1736 | { | ||
1737 | /* If the old entry is closest then just return GNUNET_NO.*/ | ||
1738 | return GNUNET_NO; | ||
1739 | } | ||
1740 | return GNUNET_SYSERR; | ||
1741 | } | ||
1742 | |||
1743 | |||
1744 | /** | ||
1745 | * SUPU: now the finger trail does not contain finger identity as the last element. | ||
1746 | * TODO: | ||
1747 | * 1. handle predecessor case differently. | ||
1748 | * how to handle the case in which same finger identity is stored for different | ||
1483 | * finger map index. because this will just increase the size of finger map and | 1749 | * finger map index. because this will just increase the size of finger map and |
1484 | * also size of the array we use in find_successor. | 1750 | * also size of the array we use in find_successor. |
1485 | * Add an entry in finger table. Before adding, check if there is already an | 1751 | * Add an entry in finger table. Before adding, check if there is already an |
@@ -1498,41 +1764,44 @@ get_existing_finger (void *cls, | |||
1498 | */ | 1764 | */ |
1499 | static | 1765 | static |
1500 | void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, | 1766 | void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, |
1501 | const struct GNUNET_PeerIdentity *finger_trail, | 1767 | struct GNUNET_PeerIdentity *finger_trail, |
1502 | uint32_t finger_trail_length, | 1768 | uint32_t finger_trail_length, |
1503 | uint32_t finger_map_index) | 1769 | uint32_t finger_map_index) |
1504 | { | 1770 | { |
1505 | struct FingerInfo new_finger_entry; | 1771 | struct FingerInfo new_finger_entry; |
1772 | struct FingerInfo *existing_finger; | ||
1773 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; | ||
1506 | int i; | 1774 | int i; |
1507 | 1775 | ||
1508 | /* If I am my own finger, then return. */ | 1776 | /* If I am my own finger, then return. */ |
1509 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity)) | 1777 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity)) |
1510 | { | 1778 | { |
1511 | GNUNET_break (0); /* SUPU: Its here because I need to see when it happens. */ | 1779 | GNUNET_break (0); |
1780 | /* FIXME:Is there any point in keeping my own identity as finger? | ||
1781 | * Also, send a trail tear down message to all the peers which | ||
1782 | are in the finger trail, so that they can remove the entries from routing | ||
1783 | table. */ | ||
1512 | return; | 1784 | return; |
1513 | } | 1785 | } |
1514 | 1786 | ||
1515 | if (finger_map_index == PREDECESSOR_FINGER_ID) | 1787 | /* Check if there is already an entry for the finger map index in the finger peer map. */ |
1516 | goto add_new_entry; | 1788 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); |
1517 | 1789 | for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++) | |
1518 | /* For rest of current_finger_index, choose the correct finger and correct trail. */ | 1790 | { |
1519 | /* SUPU: Here I want to iterate over all the entries and see if there is already | 1791 | if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL, |
1520 | an entry for the finger map index. if yes then check if finger identity are same | 1792 | (const void **)&existing_finger)) |
1521 | if yes then check the trail. if I use gnuent_container_multipeermap_iterate, | 1793 | { |
1522 | i should stop after I found the finger map index, and just return the | 1794 | /* If existing_finger is the closest, then don't add any entry. */ |
1523 | struct finger info. then I should call another function which takes care of | 1795 | if ( GNUNET_NO == select_correct_entry (existing_finger, finger_identity, |
1524 | finding the closest peer */ | 1796 | finger_trail, finger_trail_length)) |
1525 | GNUNET_CONTAINER_multipeermap_iterate (finger_peermap, &get_existing_finger, | 1797 | goto increment_finger_index; |
1526 | (void *)finger_map_index); | 1798 | } |
1799 | } | ||
1527 | 1800 | ||
1528 | add_new_entry: | 1801 | /* Add the new entry. */ |
1529 | memcpy (&(new_finger_entry.finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity)); | 1802 | memcpy (&(new_finger_entry.finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity)); |
1530 | new_finger_entry.finger_map_index = finger_map_index; | 1803 | new_finger_entry.finger_map_index = finger_map_index; |
1531 | /* FIXME: How do I get the length as well as the trail. | ||
1532 | * scan_trail (finger_trail); | ||
1533 | */ | ||
1534 | new_finger_entry.trail_length = finger_trail_length; | 1804 | new_finger_entry.trail_length = finger_trail_length; |
1535 | |||
1536 | i = 0; | 1805 | i = 0; |
1537 | while (i < finger_trail_length) | 1806 | while (i < finger_trail_length) |
1538 | { | 1807 | { |
@@ -1554,11 +1823,11 @@ void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, | |||
1554 | 1823 | ||
1555 | /* FIXME: after adding an entry, I want to check if there is a successor, if yes | 1824 | /* FIXME: after adding an entry, I want to check if there is a successor, if yes |
1556 | then this function will return it and then we should schedule a verify successor | 1825 | then this function will return it and then we should schedule a verify successor |
1557 | task */ | 1826 | task Will the successor always be at index 0 */ |
1827 | increment_finger_index: | ||
1558 | if (NULL != check_for_successor()) | 1828 | if (NULL != check_for_successor()) |
1559 | { | 1829 | { |
1560 | verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL); | 1830 | verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL); |
1561 | /* FIXME: Is it safe to set the finger index to predecessor_finger_id here? */ | ||
1562 | current_finger_index = PREDECESSOR_FINGER_ID; | 1831 | current_finger_index = PREDECESSOR_FINGER_ID; |
1563 | return; | 1832 | return; |
1564 | } | 1833 | } |
@@ -1788,22 +2057,19 @@ find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value, | |||
1788 | 2057 | ||
1789 | 2058 | ||
1790 | /** | 2059 | /** |
1791 | * here you should set the current source instead of destination type. | ||
1792 | * so current_source is actual source till we don't find another current_source | ||
1793 | * but is it good. why are we wasting space in case current_Destination is just us. | ||
1794 | * also in many case current_destination is just me. so again it does not seem | ||
1795 | * so smart. | ||
1796 | * Find closest successor for the value. | 2060 | * Find closest successor for the value. |
1797 | * @param value Value for which we are looking for successor | 2061 | * @param value Value for which we are looking for successor |
1798 | * FIXME: pass the correct value for current_destination | ||
1799 | * @param[out] current_destination set to the end of the finger to traverse next | 2062 | * @param[out] current_destination set to the end of the finger to traverse next |
1800 | * @param type Next destination type | 2063 | * @param[out] current_source set to my_identity. |
2064 | * @param congested_peer Peer not to be considered when looking for | ||
2065 | * successor. FIXME: IMPLEMENT IT. | ||
1801 | * @return Peer identity of next hop, NULL if we are the | 2066 | * @return Peer identity of next hop, NULL if we are the |
1802 | * ultimate destination | 2067 | * ultimate destination |
1803 | */ | 2068 | */ |
1804 | static struct GNUNET_PeerIdentity * | 2069 | static struct GNUNET_PeerIdentity * |
1805 | find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, | 2070 | find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, |
1806 | struct GNUNET_PeerIdentity *current_source) | 2071 | struct GNUNET_PeerIdentity *current_source, |
2072 | struct GNUNET_PeerIdentity *congested_peer) | ||
1807 | { | 2073 | { |
1808 | struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter; | 2074 | struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter; |
1809 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; | 2075 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; |
@@ -1883,6 +2149,7 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, | |||
1883 | struct FriendInfo *target_friend; | 2149 | struct FriendInfo *target_friend; |
1884 | target_friend = (struct FriendInfo *)successor->data; | 2150 | target_friend = (struct FriendInfo *)successor->data; |
1885 | memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity)); | 2151 | memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity)); |
2152 | memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity)); | ||
1886 | return current_destination; | 2153 | return current_destination; |
1887 | } | 2154 | } |
1888 | else if (successor->type == FINGER) | 2155 | else if (successor->type == FINGER) |
@@ -1972,7 +2239,7 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key, | |||
1972 | struct GNUNET_PeerIdentity curr_src; | 2239 | struct GNUNET_PeerIdentity curr_src; |
1973 | memcpy (&curr_dest, ¤t_destination, sizeof (struct GNUNET_PeerIdentity)); | 2240 | memcpy (&curr_dest, ¤t_destination, sizeof (struct GNUNET_PeerIdentity)); |
1974 | memcpy (&curr_src, ¤t_source, sizeof (struct GNUNET_PeerIdentity)); | 2241 | memcpy (&curr_src, ¤t_source, sizeof (struct GNUNET_PeerIdentity)); |
1975 | next_hop = find_successor (key_value, &curr_dest, &curr_src); | 2242 | next_hop = find_successor (key_value, &curr_dest, &curr_src, NULL); |
1976 | /* FIXME: I am copying back current_destination and current_source. but I am not | 2243 | /* FIXME: I am copying back current_destination and current_source. but I am not |
1977 | sure, if its correct. I am doing so just to remove the code from client file.*/ | 2244 | sure, if its correct. I am doing so just to remove the code from client file.*/ |
1978 | memcpy (¤t_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity)); | 2245 | memcpy (¤t_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity)); |
@@ -2071,7 +2338,7 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key, | |||
2071 | memcpy (&curr_dest, ¤t_destination, sizeof (struct GNUNET_PeerIdentity)); | 2338 | memcpy (&curr_dest, ¤t_destination, sizeof (struct GNUNET_PeerIdentity)); |
2072 | memcpy (&curr_src, ¤t_source, sizeof (struct GNUNET_PeerIdentity)); | 2339 | memcpy (&curr_src, ¤t_source, sizeof (struct GNUNET_PeerIdentity)); |
2073 | memcpy (&key_value, key, sizeof (struct GNUNET_PeerIdentity)); | 2340 | memcpy (&key_value, key, sizeof (struct GNUNET_PeerIdentity)); |
2074 | next_hop = find_successor (key_value, &curr_dest, &curr_src); | 2341 | next_hop = find_successor (key_value, &curr_dest, &curr_src, NULL); |
2075 | /* FIXME: Again I am copying back value of current_destination, current_source, | 2342 | /* FIXME: Again I am copying back value of current_destination, current_source, |
2076 | Think of a better solution. */ | 2343 | Think of a better solution. */ |
2077 | memcpy (¤t_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity)); | 2344 | memcpy (¤t_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity)); |
@@ -2151,10 +2418,10 @@ GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration, | |||
2151 | return; | 2418 | return; |
2152 | } | 2419 | } |
2153 | 2420 | ||
2154 | current_path_index = search_my_index(get_path); | 2421 | current_path_index = search_my_index(get_path, get_path_length); |
2422 | /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/ | ||
2155 | if (0 == current_path_index) | 2423 | if (0 == current_path_index) |
2156 | { | 2424 | { |
2157 | FPRINTF (stderr,_("\nSUPU %s, %s, %d"),__FILE__, __func__,__LINE__); | ||
2158 | GDS_CLIENTS_handle_reply (expiration, key, get_path_length, get_path, put_path_length, | 2425 | GDS_CLIENTS_handle_reply (expiration, key, get_path_length, get_path, put_path_length, |
2159 | put_path, type, data_size, data); | 2426 | put_path, type, data_size, data); |
2160 | return; | 2427 | return; |
@@ -2185,23 +2452,25 @@ GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration, | |||
2185 | 2452 | ||
2186 | 2453 | ||
2187 | /** | 2454 | /** |
2188 | * Send tral rejection message | 2455 | * Send tral rejection message to the peer which sent me a trail setup message. |
2189 | * @param source_peer Source peer which wants to set up the trail. | 2456 | * @param source_peer Source peer which wants to set up the trail. |
2190 | * @param finger_identity Finger identity to which it want to setup the trail. | 2457 | * @param finger_identity Value whose successor will be the finger of @a source_peer. |
2191 | * @param congested_peer Peer which has send trail rejection message | 2458 | * @param congested_peer Peer which has send trail rejection message. |
2192 | * @param next_hop Peer to which this message should be forwarded. | 2459 | * @param next_hop Peer to which this message should be forwarded. |
2193 | * @param finger_map_index | 2460 | * @param finger_map_index Index in @a source_peer finger peermap. |
2194 | * @param trail_peer_list | 2461 | * @param trail_peer_list Trail followed to reach from @a source_peer to next_hop, |
2195 | * @param trail_length | 2462 | * NULL, in case the @a congested_peer was the first peer |
2463 | * to which trail setup message was forwarded. | ||
2464 | * @param trail_length Number of peers in trail_peer_list. | ||
2196 | */ | 2465 | */ |
2197 | void | 2466 | void |
2198 | GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_peer, | 2467 | GDS_NEIGHBOURS_send_trail_rejection (struct GNUNET_PeerIdentity *source_peer, |
2199 | uint64_t finger_identity, | 2468 | uint64_t finger_identity, |
2200 | struct GNUNET_PeerIdentity *congested_peer, | 2469 | struct GNUNET_PeerIdentity *congested_peer, |
2201 | const struct GNUNET_PeerIdentity *next_hop, | 2470 | const struct GNUNET_PeerIdentity *next_hop, |
2202 | unsigned int finger_map_index, | 2471 | unsigned int finger_map_index, |
2203 | struct GNUNET_PeerIdentity *trail_peer_list, | 2472 | struct GNUNET_PeerIdentity *trail_peer_list, |
2204 | unsigned int trail_length) | 2473 | unsigned int trail_length) |
2205 | { | 2474 | { |
2206 | struct PeerTrailRejectionMessage *trail_rejection; | 2475 | struct PeerTrailRejectionMessage *trail_rejection; |
2207 | struct GNUNET_PeerIdentity *trail_list; | 2476 | struct GNUNET_PeerIdentity *trail_list; |
@@ -2209,10 +2478,17 @@ GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_p | |||
2209 | struct FriendInfo *target_friend; | 2478 | struct FriendInfo *target_friend; |
2210 | size_t msize; | 2479 | size_t msize; |
2211 | 2480 | ||
2212 | msize = sizeof (struct PeerTrailRejectionMessage); | 2481 | msize = trail_length * sizeof(struct GNUNET_PeerIdentity) + |
2482 | sizeof (struct PeerTrailRejectionMessage); | ||
2483 | |||
2484 | if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
2485 | { | ||
2486 | GNUNET_break (0); | ||
2487 | return; | ||
2488 | } | ||
2213 | 2489 | ||
2214 | pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); | 2490 | pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); |
2215 | pending->importance = 0; /* FIXME */ | 2491 | pending->importance = 0; |
2216 | pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT); | 2492 | pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT); |
2217 | trail_rejection = (struct PeerTrailRejectionMessage *) &pending[1]; | 2493 | trail_rejection = (struct PeerTrailRejectionMessage *) &pending[1]; |
2218 | pending->msg = &trail_rejection->header; | 2494 | pending->msg = &trail_rejection->header; |
@@ -2220,12 +2496,13 @@ GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_p | |||
2220 | trail_rejection->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP); | 2496 | trail_rejection->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP); |
2221 | memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); | 2497 | memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); |
2222 | memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity)); | 2498 | memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity)); |
2223 | memcpy (&(trail_rejection->finger_identity), &finger_identity, sizeof (uint64_t)); | 2499 | memcpy (&(trail_rejection->finger_identity_value), &finger_identity, sizeof (uint64_t)); |
2224 | trail_rejection->finger_map_index = htonl(finger_map_index); | 2500 | trail_rejection->finger_map_index = htonl(finger_map_index); |
2225 | trail_rejection->trail_length = htonl (trail_length); | 2501 | trail_rejection->trail_length = htonl (trail_length); |
2226 | 2502 | ||
2227 | trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; | 2503 | trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; |
2228 | memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | 2504 | if (trail_length != 0) |
2505 | memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
2229 | 2506 | ||
2230 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); | 2507 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); |
2231 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); | 2508 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); |
@@ -2235,11 +2512,12 @@ GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_p | |||
2235 | 2512 | ||
2236 | 2513 | ||
2237 | /** | 2514 | /** |
2238 | * | 2515 | * Core handler for P2P put messages. |
2239 | * @param cls | 2516 | * @param cls closure |
2240 | * @param peer | 2517 | * @param peer sender of the request |
2241 | * @param message | 2518 | * @param message message |
2242 | * @return | 2519 | * @return #GNUNET_OK to keep the connection open, |
2520 | * #GNUNET_SYSERR to close it (signal serious error) | ||
2243 | */ | 2521 | */ |
2244 | static int | 2522 | static int |
2245 | handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, | 2523 | handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, |
@@ -2357,7 +2635,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2357 | } | 2635 | } |
2358 | else | 2636 | else |
2359 | { | 2637 | { |
2360 | next_hop = find_successor (key_value, ¤t_destination, ¤t_source); | 2638 | next_hop = find_successor (key_value, ¤t_destination, ¤t_source, NULL); |
2361 | } | 2639 | } |
2362 | 2640 | ||
2363 | if (NULL == next_hop) /* I am the final destination */ | 2641 | if (NULL == next_hop) /* I am the final destination */ |
@@ -2454,7 +2732,7 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2454 | } | 2732 | } |
2455 | else | 2733 | else |
2456 | { | 2734 | { |
2457 | next_hop = find_successor (key_value, ¤t_destination, ¤t_source); | 2735 | next_hop = find_successor (key_value, ¤t_destination, ¤t_source, NULL); |
2458 | } | 2736 | } |
2459 | 2737 | ||
2460 | if (NULL == next_hop) | 2738 | if (NULL == next_hop) |
@@ -2555,7 +2833,8 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2555 | { | 2833 | { |
2556 | struct GNUNET_PeerIdentity *next_hop; | 2834 | struct GNUNET_PeerIdentity *next_hop; |
2557 | next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); | 2835 | next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); |
2558 | current_path_index = search_my_index (get_path); | 2836 | /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/ |
2837 | current_path_index = search_my_index (get_path, getlen); | ||
2559 | /* FIXME: First check if you are adding yourself to the get path or not. | 2838 | /* FIXME: First check if you are adding yourself to the get path or not. |
2560 | if yes then don't check if current_path_index == 0, if not then check | 2839 | if yes then don't check if current_path_index == 0, if not then check |
2561 | and next_hop == source_peer. */ | 2840 | and next_hop == source_peer. */ |
@@ -2573,7 +2852,7 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2573 | 2852 | ||
2574 | 2853 | ||
2575 | /** | 2854 | /** |
2576 | * Handle a PeerTrailSetupMessage. | 2855 | * Core handle for PeerTrailSetupMessage. |
2577 | * @param cls closure | 2856 | * @param cls closure |
2578 | * @param message message | 2857 | * @param message message |
2579 | * @param peer peer identity this notification is about | 2858 | * @param peer peer identity this notification is about |
@@ -2583,7 +2862,7 @@ static int | |||
2583 | handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer, | 2862 | handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer, |
2584 | const struct GNUNET_MessageHeader *message) | 2863 | const struct GNUNET_MessageHeader *message) |
2585 | { | 2864 | { |
2586 | const struct PeerTrailSetupMessage *trail_setup; | 2865 | const struct PeerTrailSetupMessage *trail_setup; |
2587 | struct GNUNET_PeerIdentity current_destination; | 2866 | struct GNUNET_PeerIdentity current_destination; |
2588 | struct GNUNET_PeerIdentity current_source; | 2867 | struct GNUNET_PeerIdentity current_source; |
2589 | struct GNUNET_PeerIdentity source; | 2868 | struct GNUNET_PeerIdentity source; |
@@ -2622,61 +2901,79 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2622 | finger_map_index = ntohl (trail_setup->finger_map_index); | 2901 | finger_map_index = ntohl (trail_setup->finger_map_index); |
2623 | destination_finger_value = ntohl (trail_setup->destination_finger); | 2902 | destination_finger_value = ntohl (trail_setup->destination_finger); |
2624 | 2903 | ||
2625 | /* Check if you are part of the trail or current destination, and accordingly | 2904 | /* My routing state size has crossed the threshold, I can not be part of any more |
2626 | * find the next peer to send the message to. */ | 2905 | * trails. */ |
2906 | if(GDS_ROUTING_check_threshold()) | ||
2907 | { | ||
2908 | /* No more trails possible through me. send a trail rejection message. */ | ||
2909 | GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity, | ||
2910 | peer,finger_map_index, trail_peer_list,trail_length); | ||
2911 | return GNUNET_YES; | ||
2912 | } | ||
2913 | |||
2914 | /* Check if you are current_destination or not. */ | ||
2627 | if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_destination, &my_identity))) | 2915 | if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_destination, &my_identity))) |
2628 | { | 2916 | { |
2917 | /* You are not current_destination, you are part of trail to reach to | ||
2918 | current_destination. */ | ||
2629 | next_hop = GDS_ROUTING_search (¤t_source, ¤t_destination, peer); | 2919 | next_hop = GDS_ROUTING_search (¤t_source, ¤t_destination, peer); |
2630 | /* ADDNOW: OPTIMIZATION: do find_successor also and get a better path if possible. */ | 2920 | /* ADDNOW: OPTIMIZATION: do find_successor also and get a better path if possible. */ |
2631 | 2921 | ||
2632 | if (next_hop == NULL) | 2922 | if (next_hop == NULL) |
2633 | { | 2923 | { |
2634 | /* FIXME next_hop to NULL, 1. statistics update, drop the message. | 2924 | /* FIXME: |
2925 | * next_hop is NULL, in a case when next_hop was a friend which got disconnected | ||
2926 | * and we removed the trail from our routing trail. So, I can send the message | ||
2927 | * to other peer or can drop the message. VERIFY which will be the correct | ||
2928 | * thing to do. | ||
2929 | * next_hop to NULL, 1. statistics update, drop the message. | ||
2635 | 2. complain to sender with new message: trail lost */ | 2930 | 2. complain to sender with new message: trail lost */ |
2636 | return GNUNET_OK; | 2931 | return GNUNET_OK; |
2637 | } | 2932 | } |
2638 | } | 2933 | } |
2639 | else | 2934 | else |
2640 | { | 2935 | { |
2641 | next_hop = find_successor (destination_finger_value, ¤t_destination, ¤t_source); | 2936 | next_hop = find_successor (destination_finger_value, ¤t_destination, ¤t_source, NULL); |
2642 | } | 2937 | } |
2643 | 2938 | ||
2644 | /* Now add yourself to the trail. */ | 2939 | |
2645 | struct GNUNET_PeerIdentity peer_list[trail_length + 1]; | ||
2646 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
2647 | peer_list[trail_length] = my_identity; | ||
2648 | trail_length++; | ||
2649 | |||
2650 | /* Check next_hop type and make the judgment what to do next. */ | ||
2651 | if (NULL == next_hop) /* This means I am the final destination */ | 2940 | if (NULL == next_hop) /* This means I am the final destination */ |
2652 | { | 2941 | { |
2653 | if (trail_length == 1) | 2942 | /* SUPU: trail length is 0, when I am the friend of the srouce peer. */ |
2943 | if (trail_length == 0) | ||
2654 | { | 2944 | { |
2655 | memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity)); | 2945 | memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity)); |
2656 | } | 2946 | } |
2657 | else | 2947 | else |
2658 | { | 2948 | { |
2659 | memcpy (&next_peer, &trail_peer_list[trail_length-2], sizeof (struct GNUNET_PeerIdentity)); | 2949 | memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity)); |
2660 | } | 2950 | } |
2661 | 2951 | ||
2662 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); | 2952 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); |
2663 | /* FIXME: URGENT change it to handle the change in current_finger_index. | 2953 | |
2664 | compare to your own predecessor */ | ||
2665 | if (compare_predecessor (&source) /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */) | 2954 | if (compare_predecessor (&source) /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */) |
2666 | { | 2955 | { |
2956 | /* FIXME: In case we have different function update_predecessor then | ||
2957 | remove the lines below. */ | ||
2667 | struct GNUNET_PeerIdentity *new_trail_list; | 2958 | struct GNUNET_PeerIdentity *new_trail_list; |
2668 | new_trail_list = invert_trail_list (&source, peer_list, trail_length); | 2959 | new_trail_list = invert_trail_list (&source, trail_peer_list, trail_length); |
2669 | finger_table_add (&source, new_trail_list, trail_length, PREDECESSOR_FINGER_ID); | 2960 | finger_table_add (&source, new_trail_list, trail_length, PREDECESSOR_FINGER_ID); |
2670 | } | 2961 | } |
2671 | GDS_NEIGHBOURS_send_trail_setup_result (&source, | 2962 | GDS_NEIGHBOURS_send_trail_setup_result (&source, |
2672 | &(my_identity), | 2963 | &(my_identity), |
2673 | target_friend, trail_length, | 2964 | target_friend, trail_length, |
2674 | peer_list, | 2965 | trail_peer_list, |
2675 | finger_map_index); | 2966 | finger_map_index); |
2676 | return GNUNET_OK; | 2967 | return GNUNET_OK; |
2677 | } | 2968 | } |
2678 | else | 2969 | else |
2679 | { | 2970 | { |
2971 | /* Now add yourself to the trail. */ | ||
2972 | struct GNUNET_PeerIdentity peer_list[trail_length + 1]; | ||
2973 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
2974 | peer_list[trail_length] = my_identity; | ||
2975 | trail_length++; | ||
2976 | |||
2680 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); | 2977 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); |
2681 | GDS_NEIGHBOURS_send_trail_setup (&source, | 2978 | GDS_NEIGHBOURS_send_trail_setup (&source, |
2682 | destination_finger_value, | 2979 | destination_finger_value, |
@@ -2701,7 +2998,7 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p | |||
2701 | const struct GNUNET_MessageHeader *message) | 2998 | const struct GNUNET_MessageHeader *message) |
2702 | { | 2999 | { |
2703 | const struct PeerTrailSetupResultMessage *trail_result; | 3000 | const struct PeerTrailSetupResultMessage *trail_result; |
2704 | const struct GNUNET_PeerIdentity *trail_peer_list; | 3001 | struct GNUNET_PeerIdentity *trail_peer_list; |
2705 | uint32_t trail_length; | 3002 | uint32_t trail_length; |
2706 | uint32_t finger_map_index; | 3003 | uint32_t finger_map_index; |
2707 | size_t msize; | 3004 | size_t msize; |
@@ -2727,7 +3024,7 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p | |||
2727 | } | 3024 | } |
2728 | 3025 | ||
2729 | finger_map_index = htonl (trail_result->finger_map_index); | 3026 | finger_map_index = htonl (trail_result->finger_map_index); |
2730 | trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1]; | 3027 | trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1]; |
2731 | 3028 | ||
2732 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer), | 3029 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer), |
2733 | &my_identity))) | 3030 | &my_identity))) |
@@ -2742,7 +3039,9 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p | |||
2742 | struct FriendInfo *target_friend; | 3039 | struct FriendInfo *target_friend; |
2743 | int my_index; | 3040 | int my_index; |
2744 | 3041 | ||
2745 | my_index = search_my_index (trail_peer_list); | 3042 | /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/ |
3043 | /* FIXME: Make sure you are passing the current length */ | ||
3044 | my_index = search_my_index (trail_peer_list, trail_length); | ||
2746 | if (my_index == 0) | 3045 | if (my_index == 0) |
2747 | { | 3046 | { |
2748 | next_hop = trail_result->destination_peer; | 3047 | next_hop = trail_result->destination_peer; |
@@ -2770,10 +3069,12 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p | |||
2770 | return GNUNET_SYSERR; | 3069 | return GNUNET_SYSERR; |
2771 | } | 3070 | } |
2772 | 3071 | ||
2773 | #if 0 | 3072 | |
2774 | /** | 3073 | /** |
2775 | * FIXME: Use flag in the case finger peer map does not contain predcessor | 3074 | * FIXME: Use flag in the case finger peer map does not contain predcessor |
2776 | * then its NULL. Ideally it should never happen. | 3075 | * then its NULL. Ideally it should never happen. Some one sent you are verify |
3076 | * successor and you don't have any predecessor, then ideally you should | ||
3077 | * GNUNET_break_op(0). | ||
2777 | * Get my current predecessor from the finger peer map | 3078 | * Get my current predecessor from the finger peer map |
2778 | * @return Current predecessor. | 3079 | * @return Current predecessor. |
2779 | */ | 3080 | */ |
@@ -2801,86 +3102,27 @@ get_predecessor() | |||
2801 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); | 3102 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); |
2802 | return my_predecessor; | 3103 | return my_predecessor; |
2803 | } | 3104 | } |
2804 | #endif | ||
2805 | 3105 | ||
2806 | /** | ||
2807 | * Core handle for p2p verify successor messages. | ||
2808 | * @param cls closure | ||
2809 | * @param message message | ||
2810 | * @param peer peer identity this notification is about | ||
2811 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
2812 | */ | ||
2813 | static int | ||
2814 | handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer, | ||
2815 | const struct GNUNET_MessageHeader *message) | ||
2816 | { | ||
2817 | const struct PeerVerifySuccessorMessage *vsm; | ||
2818 | const struct GNUNET_PeerIdentity *trail_peer_list; | ||
2819 | struct GNUNET_PeerIdentity next_hop; | ||
2820 | struct FriendInfo *target_friend; | ||
2821 | size_t msize; | ||
2822 | uint32_t trail_length; | ||
2823 | |||
2824 | msize = ntohs (message->size); | ||
2825 | if (msize < sizeof (struct PeerVerifySuccessorMessage)) | ||
2826 | { | ||
2827 | GNUNET_break_op (0); | ||
2828 | return GNUNET_YES; | ||
2829 | } | ||
2830 | |||
2831 | vsm = (struct PeerVerifySuccessorMessage *) message; | ||
2832 | trail_length = ntohl (vsm->trail_length); | ||
2833 | |||
2834 | if ((msize < sizeof (struct PeerVerifySuccessorMessage) + | ||
2835 | trail_length * sizeof (struct GNUNET_PeerIdentity)) || | ||
2836 | (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) | ||
2837 | { | ||
2838 | GNUNET_break_op (0); | ||
2839 | return GNUNET_YES; | ||
2840 | } | ||
2841 | |||
2842 | trail_peer_list = (const struct GNUNET_PeerIdentity *)&vsm[1]; | ||
2843 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity))) | ||
2844 | { | ||
2845 | /*FIXME:URGENT:IMPLEMENT Here you are the successor, here you should check your predecessor | ||
2846 | and if there is no predecessor then just add this peer and send result | ||
2847 | if there is some other predecessor, then construct a new trial and then | ||
2848 | send back the list to requesting peer. */ | ||
2849 | } | ||
2850 | else | ||
2851 | { | ||
2852 | int my_index; | ||
2853 | |||
2854 | my_index = search_my_index (trail_peer_list); | ||
2855 | memcpy (&next_hop, &trail_peer_list[my_index], sizeof (struct GNUNET_PeerIdentity)); | ||
2856 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | ||
2857 | |||
2858 | GDS_NEIGHBOURS_send_verify_successor (&(vsm->source_peer), &(vsm->successor),target_friend, | ||
2859 | trail_peer_list, trail_length); | ||
2860 | } | ||
2861 | return GNUNET_SYSERR; | ||
2862 | } | ||
2863 | 3106 | ||
2864 | #if 0 | ||
2865 | /** | 3107 | /** |
2866 | * Core handle for p2p verify successor messages. | 3108 | * Core handle for p2p verify successor messages. |
2867 | * @param cls closure | 3109 | * @param cls closure |
2868 | * @param message message | 3110 | * @param message message |
2869 | * @param peer peer identity this notification is about | 3111 | * @param peer peer identity this notification is about |
2870 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | 3112 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
2871 | */ | 3113 | */ |
2872 | static int | 3114 | static int |
2873 | handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer, | 3115 | handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer, |
2874 | const struct GNUNET_MessageHeader *message) | 3116 | const struct GNUNET_MessageHeader *message) |
2875 | { | 3117 | { |
2876 | struct PeerVerifySuccessorMessage *vsm; | 3118 | const struct PeerVerifySuccessorMessage *vsm; |
2877 | struct GNUNET_PeerIdentity *trail_peer_list; | 3119 | const struct GNUNET_PeerIdentity *trail_peer_list; |
3120 | struct GNUNET_PeerIdentity source_peer; | ||
3121 | struct GNUNET_PeerIdentity next_hop; | ||
2878 | struct FriendInfo *target_friend; | 3122 | struct FriendInfo *target_friend; |
2879 | struct GNUNET_PeerIdentity *next_hop; | ||
2880 | struct GNUNET_PeerIdentity *source_peer; | ||
2881 | unsigned int trail_length; | ||
2882 | size_t msize; | 3123 | size_t msize; |
2883 | 3124 | uint32_t trail_length; | |
3125 | |||
2884 | msize = ntohs (message->size); | 3126 | msize = ntohs (message->size); |
2885 | if (msize < sizeof (struct PeerVerifySuccessorMessage)) | 3127 | if (msize < sizeof (struct PeerVerifySuccessorMessage)) |
2886 | { | 3128 | { |
@@ -2893,37 +3135,34 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee | |||
2893 | 3135 | ||
2894 | if ((msize < sizeof (struct PeerVerifySuccessorMessage) + | 3136 | if ((msize < sizeof (struct PeerVerifySuccessorMessage) + |
2895 | trail_length * sizeof (struct GNUNET_PeerIdentity)) || | 3137 | trail_length * sizeof (struct GNUNET_PeerIdentity)) || |
2896 | (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) | 3138 | (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) |
2897 | { | 3139 | { |
2898 | GNUNET_break_op (0); | 3140 | GNUNET_break_op (0); |
2899 | return GNUNET_YES; | 3141 | return GNUNET_YES; |
2900 | } | 3142 | } |
2901 | 3143 | ||
2902 | trail_peer_list = (struct GNUNET_PeerIdentity *) &vsm[1]; | 3144 | trail_peer_list = (const struct GNUNET_PeerIdentity *)&vsm[1]; |
2903 | source_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); | 3145 | memcpy (&source_peer, &(vsm->source_peer), sizeof(struct GNUNET_PeerIdentity)); |
2904 | memcpy (source_peer, &(vsm->source_peer), sizeof (struct GNUNET_PeerIdentity)); | ||
2905 | |||
2906 | next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); | ||
2907 | |||
2908 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity))) | 3146 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity))) |
2909 | { | 3147 | { |
2910 | struct FingerInfo *my_predecessor; | 3148 | struct FingerInfo *my_predecessor; |
2911 | if (trail_length == 1) | 3149 | |
2912 | memcpy (next_hop, source_peer, sizeof (struct GNUNET_PeerIdentity)); | 3150 | if (trail_length == 0) |
3151 | memcpy (&next_hop, &source_peer, sizeof (struct GNUNET_PeerIdentity)); | ||
2913 | else | 3152 | else |
2914 | { | 3153 | { |
2915 | int current_trail_index; | 3154 | int current_trail_index; |
2916 | current_trail_index = search_my_index (trail_peer_list); | 3155 | current_trail_index = search_my_index (trail_peer_list, trail_length); |
2917 | memcpy (next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity)); | 3156 | memcpy (&next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity)); |
2918 | } | 3157 | } |
2919 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); | 3158 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); |
2920 | GNUNET_free (next_hop); | ||
2921 | 3159 | ||
2922 | my_predecessor = get_predecessor(); | 3160 | my_predecessor = get_predecessor(); |
2923 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (source_peer, | 3161 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer, |
2924 | &(my_predecessor->finger_identity)))) | 3162 | &(my_predecessor->finger_identity)))) |
2925 | { | 3163 | { |
2926 | GDS_NEIGHBOURS_send_verify_successor_result (source_peer, | 3164 | |
3165 | GDS_NEIGHBOURS_send_verify_successor_result (&source_peer, | ||
2927 | &(my_identity), | 3166 | &(my_identity), |
2928 | &(my_predecessor->finger_identity), | 3167 | &(my_predecessor->finger_identity), |
2929 | target_friend, | 3168 | target_friend, |
@@ -2933,16 +3172,18 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee | |||
2933 | else | 3172 | else |
2934 | { | 3173 | { |
2935 | struct GNUNET_PeerIdentity *new_successor_trail; | 3174 | struct GNUNET_PeerIdentity *new_successor_trail; |
3175 | struct TrailPeerList *iterator; | ||
2936 | int new_trail_length; | 3176 | int new_trail_length; |
2937 | int i; | 3177 | int i; |
2938 | 3178 | ||
2939 | new_trail_length = trail_length + my_predecessor->trail_length; | 3179 | new_trail_length = trail_length + my_predecessor->trail_length + 1; |
2940 | new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length); | 3180 | new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length); |
2941 | memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity)); | 3181 | memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity)); |
2942 | struct TrailPeerList *iterator; | 3182 | memcpy (&new_successor_trail[trail_length], &my_identity, sizeof (struct GNUNET_PeerIdentity)); |
3183 | |||
2943 | iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); | 3184 | iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); |
2944 | iterator = my_predecessor->head; | 3185 | iterator = my_predecessor->head; |
2945 | i = trail_length; | 3186 | i = trail_length + 1; |
2946 | while (i < new_trail_length) | 3187 | while (i < new_trail_length) |
2947 | { | 3188 | { |
2948 | memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity)); | 3189 | memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity)); |
@@ -2950,29 +3191,30 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee | |||
2950 | i++; | 3191 | i++; |
2951 | } | 3192 | } |
2952 | 3193 | ||
2953 | GDS_NEIGHBOURS_send_verify_successor_result (source_peer, | 3194 | GDS_NEIGHBOURS_send_verify_successor_result (&source_peer, |
2954 | &(my_identity), | 3195 | &(my_identity), |
2955 | &(my_predecessor->finger_identity), | 3196 | &(my_predecessor->finger_identity), |
2956 | target_friend, | 3197 | target_friend, |
2957 | new_successor_trail, | 3198 | new_successor_trail, |
2958 | new_trail_length); | 3199 | new_trail_length); |
2959 | } | 3200 | } |
2960 | 3201 | ||
2961 | } | 3202 | } |
2962 | else | 3203 | else |
2963 | { | 3204 | { |
2964 | unsigned int current_trail_index; | 3205 | int my_index; |
2965 | current_trail_index = search_my_index (trail_peer_list); | 3206 | /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/ |
2966 | memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity)); | 3207 | /* FIXME: make sure you are passing the correct trail length */ |
2967 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); | 3208 | my_index = search_my_index (trail_peer_list, trail_length); |
2968 | GNUNET_free (next_hop); | 3209 | memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity)); |
2969 | 3210 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | |
2970 | GDS_NEIGHBOURS_send_verify_successor (source_peer, &(vsm->successor),target_friend, | 3211 | |
3212 | GDS_NEIGHBOURS_send_verify_successor (&(vsm->source_peer), &(vsm->successor),target_friend, | ||
2971 | trail_peer_list, trail_length); | 3213 | trail_peer_list, trail_length); |
2972 | } | 3214 | } |
2973 | return GNUNET_YES; | 3215 | return GNUNET_SYSERR; |
2974 | } | 3216 | } |
2975 | #endif | 3217 | |
2976 | 3218 | ||
2977 | /** | 3219 | /** |
2978 | * Core handle for p2p verify successor result messages. | 3220 | * Core handle for p2p verify successor result messages. |
@@ -2986,7 +3228,7 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti | |||
2986 | const struct GNUNET_MessageHeader *message) | 3228 | const struct GNUNET_MessageHeader *message) |
2987 | { | 3229 | { |
2988 | const struct PeerVerifySuccessorResultMessage *vsrm; | 3230 | const struct PeerVerifySuccessorResultMessage *vsrm; |
2989 | const struct GNUNET_PeerIdentity *trail_peer_list; | 3231 | struct GNUNET_PeerIdentity *trail_peer_list; |
2990 | struct GNUNET_PeerIdentity next_hop; | 3232 | struct GNUNET_PeerIdentity next_hop; |
2991 | struct FriendInfo *target_friend; | 3233 | struct FriendInfo *target_friend; |
2992 | size_t msize; | 3234 | size_t msize; |
@@ -3012,7 +3254,7 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti | |||
3012 | return GNUNET_YES; | 3254 | return GNUNET_YES; |
3013 | } | 3255 | } |
3014 | 3256 | ||
3015 | trail_peer_list = (const struct GNUNET_PeerIdentity *) &vsrm[1]; | 3257 | trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1]; |
3016 | 3258 | ||
3017 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity)))) | 3259 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity)))) |
3018 | { | 3260 | { |
@@ -3030,8 +3272,9 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti | |||
3030 | else | 3272 | else |
3031 | { | 3273 | { |
3032 | int my_index; | 3274 | int my_index; |
3033 | 3275 | /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/ | |
3034 | my_index = search_my_index (trail_peer_list); | 3276 | /* FIXME: make sure you are passing the correct trail length */ |
3277 | my_index = search_my_index (trail_peer_list, trail_length); | ||
3035 | if (my_index == 1) | 3278 | if (my_index == 1) |
3036 | memcpy (&next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity)); | 3279 | memcpy (&next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity)); |
3037 | else | 3280 | else |
@@ -3050,28 +3293,6 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti | |||
3050 | 3293 | ||
3051 | 3294 | ||
3052 | /** | 3295 | /** |
3053 | * Check if there is already an entry in finger_peermap for predecessor, | ||
3054 | * If not then add peer as your predecessor. | ||
3055 | * Else compare existing entry and peer, and choose the closest one as predecessor. | ||
3056 | * @param peer Peer identity | ||
3057 | * @param trail_peer_list Trail to reach from @a peer to me. | ||
3058 | */ | ||
3059 | static void | ||
3060 | update_predecessor (const struct GNUNET_PeerIdentity *peer, | ||
3061 | const struct GNUNET_PeerIdentity *trail_peer_list) | ||
3062 | { | ||
3063 | /*FIXME: URGENT: Here you should first check if there is already an entry for predecessor | ||
3064 | field or not. if not then add peer. else compare existing entry and peer, | ||
3065 | and choose the closest one as predecessor. I am confused should I call a | ||
3066 | function which just checks if this peer can be predecessor or not, and then | ||
3067 | call another function to add it. Or call a single function which checks | ||
3068 | it all and add the entry. we are never going to communicate with the peer | ||
3069 | if it is my predecessor or not. so, we don't care about the result. */ | ||
3070 | |||
3071 | } | ||
3072 | |||
3073 | |||
3074 | /** | ||
3075 | * Core handle for p2p notify new successor messages. | 3296 | * Core handle for p2p notify new successor messages. |
3076 | * @param cls closure | 3297 | * @param cls closure |
3077 | * @param message message | 3298 | * @param message message |
@@ -3083,7 +3304,7 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity | |||
3083 | const struct GNUNET_MessageHeader *message) | 3304 | const struct GNUNET_MessageHeader *message) |
3084 | { | 3305 | { |
3085 | const struct PeerNotifyNewSuccessorMessage *nsm; | 3306 | const struct PeerNotifyNewSuccessorMessage *nsm; |
3086 | const struct GNUNET_PeerIdentity *trail_peer_list; | 3307 | struct GNUNET_PeerIdentity *trail_peer_list; |
3087 | size_t msize; | 3308 | size_t msize; |
3088 | uint32_t trail_length; | 3309 | uint32_t trail_length; |
3089 | 3310 | ||
@@ -3106,11 +3327,11 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity | |||
3106 | return GNUNET_YES; | 3327 | return GNUNET_YES; |
3107 | } | 3328 | } |
3108 | 3329 | ||
3109 | trail_peer_list = (const struct GNUNET_PeerIdentity *) &nsm[1]; | 3330 | trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1]; |
3110 | 3331 | ||
3111 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity))) | 3332 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity))) |
3112 | { | 3333 | { |
3113 | update_predecessor (&(nsm->destination_peer), trail_peer_list); | 3334 | //update_predecessor (&(nsm->destination_peer), trail_peer_list); |
3114 | return GNUNET_OK; | 3335 | return GNUNET_OK; |
3115 | } | 3336 | } |
3116 | else | 3337 | else |
@@ -3119,7 +3340,9 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity | |||
3119 | struct GNUNET_PeerIdentity next_hop; | 3340 | struct GNUNET_PeerIdentity next_hop; |
3120 | int my_index; | 3341 | int my_index; |
3121 | 3342 | ||
3122 | my_index = search_my_index (trail_peer_list); | 3343 | /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/ |
3344 | /* FIXME: check that trail length is correct. */ | ||
3345 | my_index = search_my_index (trail_peer_list, trail_length); | ||
3123 | memcpy (&next_hop, &trail_peer_list[my_index+1], sizeof (struct GNUNET_PeerIdentity)); | 3346 | memcpy (&next_hop, &trail_peer_list[my_index+1], sizeof (struct GNUNET_PeerIdentity)); |
3124 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | 3347 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); |
3125 | GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), | 3348 | GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), |
@@ -3133,8 +3356,183 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity | |||
3133 | 3356 | ||
3134 | 3357 | ||
3135 | /** | 3358 | /** |
3136 | * FIXME: I am not sure if this is correct or not. once I am done with | 3359 | * Core handler for P2P trail rejection message |
3137 | * basic implementation then will handle threshold limits. | 3360 | * @param cls closure |
3361 | * @param message message | ||
3362 | * @param peer peer identity this notification is about | ||
3363 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
3364 | */ | ||
3365 | static | ||
3366 | int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer, | ||
3367 | const struct GNUNET_MessageHeader *message) | ||
3368 | { | ||
3369 | /* Here you have recevied the message it means that the peer next to you have | ||
3370 | failed to setup the trail to the finger identity value. now you should call | ||
3371 | find_successor and make sure that you don't choose the peer as next hop | ||
3372 | in order to do so, you need to pass a new parameter to find successor, | ||
3373 | congested peer - a peer which you should ignore. once you have found this | ||
3374 | peer then just send a trail setup message to that peer. In case you are | ||
3375 | also congested then remove yourself from the trail as this message | ||
3376 | reached to as you are part of the trail. and then send the message to | ||
3377 | element before you. Ideally you should be the last element in the trail as | ||
3378 | all the the elements before you have rejected you. In case you are source, | ||
3379 | then you should call select_random_Friend(congested_peer). in case you don't | ||
3380 | find any peer because congested peer then set flag that all friends are busy | ||
3381 | and leave. */ | ||
3382 | const struct PeerTrailRejectionMessage *trail_rejection; | ||
3383 | struct GNUNET_PeerIdentity *trail_peer_list; | ||
3384 | struct GNUNET_PeerIdentity source_peer; | ||
3385 | struct GNUNET_PeerIdentity congested_peer; | ||
3386 | struct FriendInfo *target_friend; | ||
3387 | struct GNUNET_PeerIdentity next_peer; | ||
3388 | struct GNUNET_PeerIdentity *next_hop; | ||
3389 | struct GNUNET_PeerIdentity current_source; | ||
3390 | struct GNUNET_PeerIdentity current_destination; | ||
3391 | size_t msize; | ||
3392 | uint32_t trail_length; | ||
3393 | uint32_t finger_map_index; | ||
3394 | uint64_t destination_finger_value; | ||
3395 | |||
3396 | msize = ntohs (message->size); | ||
3397 | if (msize < sizeof (struct PeerTrailRejectionMessage)) | ||
3398 | { | ||
3399 | GNUNET_break_op (0); | ||
3400 | return GNUNET_YES; | ||
3401 | } | ||
3402 | |||
3403 | trail_rejection = (struct PeerTrailRejectionMessage *) message; | ||
3404 | trail_length = ntohl (trail_rejection->trail_length); | ||
3405 | |||
3406 | if ((msize < sizeof (struct PeerTrailRejectionMessage) + | ||
3407 | trail_length * sizeof (struct GNUNET_PeerIdentity)) || | ||
3408 | (trail_length > | ||
3409 | GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) | ||
3410 | { | ||
3411 | GNUNET_break_op (0); | ||
3412 | return GNUNET_YES; | ||
3413 | } | ||
3414 | trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; | ||
3415 | finger_map_index = ntohl (trail_rejection->finger_map_index); | ||
3416 | memcpy (&source_peer, &(trail_rejection->source_peer), sizeof(struct GNUNET_PeerIdentity)); | ||
3417 | memcpy (&destination_finger_value, &(trail_rejection->finger_identity_value), sizeof (uint64_t)); | ||
3418 | memcpy (&congested_peer, &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity)); | ||
3419 | |||
3420 | /* If I am the source of the original trail setup message, then again select | ||
3421 | a random friend and send a new trail setup message to this finger identity | ||
3422 | value. */ | ||
3423 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &source_peer))) | ||
3424 | { | ||
3425 | /* If friend peer map is empty, or all the friends trail threshold has been crossed, | ||
3426 | * then return. */ | ||
3427 | if ((GNUNET_CONTAINER_multipeermap_size (friend_peermap) == 0) || | ||
3428 | (all_friends_trail_threshold == GNUNET_YES)) | ||
3429 | { | ||
3430 | GNUNET_break(0); | ||
3431 | return GNUNET_SYSERR; | ||
3432 | } | ||
3433 | |||
3434 | /* Select any random friend except congested peer. */ | ||
3435 | target_friend = select_random_friend (&congested_peer); | ||
3436 | |||
3437 | if (NULL == target_friend) | ||
3438 | { | ||
3439 | all_friends_trail_threshold = GNUNET_YES; | ||
3440 | return GNUNET_SYSERR; | ||
3441 | } | ||
3442 | |||
3443 | GDS_NEIGHBOURS_send_trail_setup (&my_identity, destination_finger_value, &(target_friend->id), | ||
3444 | &my_identity, target_friend, 0, NULL, finger_map_index); | ||
3445 | return GNUNET_YES; | ||
3446 | } | ||
3447 | |||
3448 | /* My routing state size has crossed the threshold, I can not be part of any more | ||
3449 | * trails. */ | ||
3450 | if(GDS_ROUTING_check_threshold()) | ||
3451 | { | ||
3452 | struct GNUNET_PeerIdentity *new_trail; | ||
3453 | |||
3454 | if (trail_length == 1) | ||
3455 | { | ||
3456 | memcpy (&next_peer, &source_peer, sizeof (struct GNUNET_PeerIdentity)); | ||
3457 | } | ||
3458 | else | ||
3459 | { | ||
3460 | memcpy (&next_peer, &trail_peer_list[trail_length - 2], sizeof (struct GNUNET_PeerIdentity)); | ||
3461 | } | ||
3462 | |||
3463 | /* Remove myself from the trail. */ | ||
3464 | new_trail = GNUNET_malloc ((trail_length -1) * sizeof (struct GNUNET_PeerIdentity)); | ||
3465 | memcpy (new_trail, trail_peer_list, (trail_length -1) * sizeof (struct GNUNET_PeerIdentity)); | ||
3466 | |||
3467 | /* No more trails possible through me. send a trail rejection message to next hop. */ | ||
3468 | GDS_NEIGHBOURS_send_trail_rejection (&source_peer, destination_finger_value, &my_identity, | ||
3469 | &next_peer,finger_map_index, new_trail,trail_length - 1); | ||
3470 | return GNUNET_YES; | ||
3471 | } | ||
3472 | |||
3473 | /* FIXME: In this case I have just written my_identity as current_destination | ||
3474 | and current source need ot think more of better values anad if needed or not. | ||
3475 | Also, i am adding a new parameter to funciton find_successor so that this peer | ||
3476 | is not considered as next hop congested_peer is not being used. FIXME. */ | ||
3477 | memcpy (¤t_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity)); | ||
3478 | memcpy (¤t_source, &my_identity, sizeof (struct GNUNET_PeerIdentity)); | ||
3479 | next_hop = find_successor (destination_finger_value, ¤t_destination, ¤t_source, &congested_peer); | ||
3480 | |||
3481 | /* FIXME: WE NEED ANOTHER CASE as it may happend that congested peer is the only | ||
3482 | friend, and find_successor finds nothig, so check something else | ||
3483 | here like if current_destination is me, it means that i am destination | ||
3484 | or if current_destination = NULL, then it means found nothing. URGENT. */ | ||
3485 | if (NULL == next_hop) /* This means I am the final destination */ | ||
3486 | { | ||
3487 | /* SUPU: trail length is 1, when I am the friend of the srouce peer. */ | ||
3488 | if (trail_length == 1) | ||
3489 | { | ||
3490 | memcpy (&next_peer, &source_peer, sizeof (struct GNUNET_PeerIdentity)); | ||
3491 | } | ||
3492 | else | ||
3493 | { | ||
3494 | memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity)); | ||
3495 | } | ||
3496 | |||
3497 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); | ||
3498 | |||
3499 | if (compare_predecessor (&source_peer) /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */) | ||
3500 | { | ||
3501 | /* FIXME: In case we have different function update_predecessor then | ||
3502 | remove the lines below. */ | ||
3503 | struct GNUNET_PeerIdentity *new_trail_list; | ||
3504 | new_trail_list = invert_trail_list (&source_peer, trail_peer_list, trail_length); | ||
3505 | finger_table_add (&source_peer, new_trail_list, trail_length, PREDECESSOR_FINGER_ID); | ||
3506 | } | ||
3507 | GDS_NEIGHBOURS_send_trail_setup_result (&source_peer, | ||
3508 | &(my_identity), | ||
3509 | target_friend, trail_length, | ||
3510 | trail_peer_list, | ||
3511 | finger_map_index); | ||
3512 | return GNUNET_OK; | ||
3513 | } | ||
3514 | else | ||
3515 | { | ||
3516 | /* Now add yourself to the trail. */ | ||
3517 | struct GNUNET_PeerIdentity peer_list[trail_length + 1]; | ||
3518 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
3519 | peer_list[trail_length] = my_identity; | ||
3520 | trail_length++; | ||
3521 | |||
3522 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); | ||
3523 | GDS_NEIGHBOURS_send_trail_setup (&source_peer, | ||
3524 | destination_finger_value, | ||
3525 | ¤t_destination, ¤t_source, | ||
3526 | target_friend, trail_length, peer_list, | ||
3527 | finger_map_index); | ||
3528 | return GNUNET_OK; | ||
3529 | } | ||
3530 | return GNUNET_SYSERR; | ||
3531 | } | ||
3532 | |||
3533 | #if 0 | ||
3534 | /** | ||
3535 | * FIXME: | ||
3138 | * Does it matter if the packet was going to a finger or friend? | 3536 | * Does it matter if the packet was going to a finger or friend? |
3139 | * Core handle for p2p trail rejection messages. | 3537 | * Core handle for p2p trail rejection messages. |
3140 | * @param cls closure | 3538 | * @param cls closure |
@@ -3147,10 +3545,10 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity * | |||
3147 | const struct GNUNET_MessageHeader *message) | 3545 | const struct GNUNET_MessageHeader *message) |
3148 | { | 3546 | { |
3149 | struct PeerTrailRejectionMessage *trail_rejection; | 3547 | struct PeerTrailRejectionMessage *trail_rejection; |
3150 | struct FailedTrail *trail_fail; | ||
3151 | struct FriendInfo *target_friend; | 3548 | struct FriendInfo *target_friend; |
3152 | struct GNUNET_PeerIdentity *trail_peer_list; | 3549 | struct GNUNET_PeerIdentity *trail_peer_list; |
3153 | unsigned int finger_map_index; | 3550 | unsigned int finger_map_index; |
3551 | uint32_t trail_length; | ||
3154 | size_t msize; | 3552 | size_t msize; |
3155 | 3553 | ||
3156 | msize = ntohs (message->size); | 3554 | msize = ntohs (message->size); |
@@ -3161,8 +3559,23 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity * | |||
3161 | } | 3559 | } |
3162 | 3560 | ||
3163 | trail_rejection = (struct PeerTrailRejectionMessage *) message; | 3561 | trail_rejection = (struct PeerTrailRejectionMessage *) message; |
3562 | trail_length = ntohl (trail_rejection->trail_length); | ||
3563 | |||
3564 | if ((msize < sizeof (struct PeerTrailRejectionMessage) + | ||
3565 | trail_length * sizeof (struct GNUNET_PeerIdentity)) || | ||
3566 | (trail_length > | ||
3567 | GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) | ||
3568 | { | ||
3569 | GNUNET_break_op (0); | ||
3570 | return GNUNET_YES; | ||
3571 | } | ||
3164 | trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; | 3572 | trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; |
3165 | finger_map_index = ntohl (trail_rejection->finger_map_index); | 3573 | finger_map_index = ntohl (trail_rejection->finger_map_index); |
3574 | |||
3575 | /* FIXME: I don't think we need failed trail list. will remove it once sure. | ||
3576 | * only case where I think we can need it in if in case of finger. where | ||
3577 | * we would like to send back the message to current source and leave it | ||
3578 | * to the current source to find the closest peer. | ||
3166 | trail_fail = GNUNET_malloc (sizeof (struct FailedTrail)); | 3579 | trail_fail = GNUNET_malloc (sizeof (struct FailedTrail)); |
3167 | memcpy (&(trail_fail->source_peer), &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity)); | 3580 | memcpy (&(trail_fail->source_peer), &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity)); |
3168 | memcpy (&(trail_fail->congested_peer), &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity)); | 3581 | memcpy (&(trail_fail->congested_peer), &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity)); |
@@ -3171,14 +3584,15 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity * | |||
3171 | GNUNET_assert (GNUNET_OK == | 3584 | GNUNET_assert (GNUNET_OK == |
3172 | GNUNET_CONTAINER_multipeermap_put (failed_trail_list, &(trail_fail->source_peer), | 3585 | GNUNET_CONTAINER_multipeermap_put (failed_trail_list, &(trail_fail->source_peer), |
3173 | trail_fail, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); | 3586 | trail_fail, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); |
3174 | 3587 | */ | |
3588 | |||
3175 | /* FIXME: Is it okay if I pass the struct as parameter. */ | 3589 | /* FIXME: Is it okay if I pass the struct as parameter. */ |
3176 | target_friend = select_random_friend (&(trail_fail->congested_peer)); | 3590 | target_friend = select_random_friend (&(trail_rejection->congested_peer)); |
3177 | 3591 | ||
3178 | if(NULL != target_friend) | 3592 | if(NULL != target_friend) |
3179 | { | 3593 | { |
3180 | GDS_NEIGHBOURS_send_trail_setup (&(trail_fail->source_peer), | 3594 | GDS_NEIGHBOURS_send_trail_setup (&(trail_rejection->source_peer), |
3181 | trail_fail->destination_finger_value, | 3595 | trail_rejection->finger_identity, |
3182 | &(target_friend->id), | 3596 | &(target_friend->id), |
3183 | NULL, target_friend, ntohl (trail_rejection->trail_length), | 3597 | NULL, target_friend, ntohl (trail_rejection->trail_length), |
3184 | trail_peer_list, | 3598 | trail_peer_list, |
@@ -3187,6 +3601,7 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity * | |||
3187 | } | 3601 | } |
3188 | return GNUNET_SYSERR; | 3602 | return GNUNET_SYSERR; |
3189 | } | 3603 | } |
3604 | #endif | ||
3190 | 3605 | ||
3191 | /** | 3606 | /** |
3192 | * Core handle for p2p trail tear down messages. | 3607 | * Core handle for p2p trail tear down messages. |
@@ -3203,31 +3618,66 @@ int handle_dht_p2p_trail_treadown (void *cls, const struct GNUNET_PeerIdentity * | |||
3203 | finger entry and it need to inform the peers which are part of the trail to remove | 3618 | finger entry and it need to inform the peers which are part of the trail to remove |
3204 | the trail from their routing table. So, this peer should first | 3619 | the trail from their routing table. So, this peer should first |
3205 | get the next hop and then delete the entry. */ | 3620 | get the next hop and then delete the entry. */ |
3206 | return GNUNET_YES; | 3621 | struct PeerTrailTearDownMessage *trail_teardown; |
3207 | } | 3622 | struct GNUNET_PeerIdentity *trail_peer_list; |
3208 | 3623 | struct GNUNET_PeerIdentity next_hop; | |
3209 | 3624 | struct FriendInfo *target_friend; | |
3210 | /** | 3625 | uint32_t trail_length; |
3211 | * FIXME: free_finger(remove_finger); Call this function at finger_table_add, | 3626 | size_t msize; |
3212 | when you replace an existing entry | 3627 | int my_index; |
3213 | * Free finger and its trail. | ||
3214 | * @param remove_finger Finger to be freed. | ||
3215 | */ | ||
3216 | static void | ||
3217 | free_finger (struct FingerInfo *finger) | ||
3218 | { | ||
3219 | struct TrailPeerList *peer; | ||
3220 | 3628 | ||
3221 | while (NULL != (peer = finger->head)) | 3629 | msize = ntohs (message->size); |
3630 | if (msize < sizeof (struct PeerTrailTearDownMessage)) | ||
3222 | { | 3631 | { |
3223 | GNUNET_CONTAINER_DLL_remove (finger->head, finger->tail, peer); | 3632 | GNUNET_break_op (0); |
3224 | GNUNET_free (peer); | 3633 | return GNUNET_YES; |
3225 | } | 3634 | } |
3226 | 3635 | ||
3227 | GNUNET_free (finger); | 3636 | trail_teardown = (struct PeerTrailTearDownMessage *) message; |
3637 | trail_length = ntohl (trail_teardown->trail_length); | ||
3638 | |||
3639 | if ((msize < sizeof (struct PeerTrailTearDownMessage) + | ||
3640 | trail_length * sizeof (struct GNUNET_PeerIdentity)) || | ||
3641 | (trail_length > | ||
3642 | GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) | ||
3643 | { | ||
3644 | GNUNET_break_op (0); | ||
3645 | return GNUNET_YES; | ||
3646 | } | ||
3647 | |||
3648 | trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_teardown[1]; | ||
3649 | |||
3650 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->destination_peer), &my_identity))) | ||
3651 | { | ||
3652 | /* We have reached destination then just return. May be if the peer before this | ||
3653 | destination, does not forward the packet to destination. So, this case should never | ||
3654 | occur. */ | ||
3655 | GNUNET_break (0); | ||
3656 | return GNUNET_YES; | ||
3657 | } | ||
3658 | |||
3659 | my_index = search_my_index (trail_peer_list, trail_length); | ||
3660 | if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer), | ||
3661 | &(trail_teardown->destination_peer),peer)) | ||
3662 | { | ||
3663 | /* Here we get GNUNET_NO, only if there is no matching entry found in routing | ||
3664 | table. */ | ||
3665 | GNUNET_break (0); | ||
3666 | return GNUNET_YES; | ||
3667 | } | ||
3668 | |||
3669 | if (my_index == (trail_length - 2)) | ||
3670 | return GNUNET_SYSERR; | ||
3671 | |||
3672 | memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity)); | ||
3673 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | ||
3674 | |||
3675 | GDS_NEIGHBOURS_send_trail_teardown (&(trail_teardown->source_peer), | ||
3676 | &(trail_teardown->destination_peer), | ||
3677 | trail_peer_list, trail_length, target_friend); | ||
3678 | return GNUNET_YES; | ||
3228 | } | 3679 | } |
3229 | 3680 | ||
3230 | |||
3231 | /** | 3681 | /** |
3232 | * Iterate over finger_peermap, and remove entries with peer as the first element | 3682 | * Iterate over finger_peermap, and remove entries with peer as the first element |
3233 | * of their trail. | 3683 | * of their trail. |
@@ -3399,15 +3849,16 @@ GDS_NEIGHBOURS_init (void) | |||
3399 | if (NULL == core_api) | 3849 | if (NULL == core_api) |
3400 | return GNUNET_SYSERR; | 3850 | return GNUNET_SYSERR; |
3401 | 3851 | ||
3402 | /* Initialize the current index in the finger map. */ | ||
3403 | current_finger_index = PREDECESSOR_FINGER_ID; | ||
3404 | |||
3405 | friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); | 3852 | friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); |
3406 | finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO); | 3853 | finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO); |
3854 | |||
3407 | /* FIXME: Not sure if this value is correct for this data structure. also | 3855 | /* FIXME: Not sure if this value is correct for this data structure. also |
3408 | * not sure if we actually need any such data structure. Once done with other functions, | 3856 | * not sure if we actually need any such data structure. Once done with other functions, |
3409 | * will revisit this part. */ | 3857 | * will revisit this part. |
3410 | failed_trail_list = GNUNET_CONTAINER_multipeermap_create (LINK_THRESHOLD * 4/3, GNUNET_NO); | 3858 | failed_trail_list = GNUNET_CONTAINER_multipeermap_create (LINK_THRESHOLD * 4/3, GNUNET_NO);*/ |
3859 | /* This global variable is set to GNUNET_YES, in case all the friends have their | ||
3860 | links threshold set. */ | ||
3861 | all_friends_trail_threshold = GNUNET_NO; | ||
3411 | return GNUNET_OK; | 3862 | return GNUNET_OK; |
3412 | } | 3863 | } |
3413 | 3864 | ||
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c index 59df8ed40..ac27370a9 100644 --- a/src/dht/gnunet-service-xdht_routing.c +++ b/src/dht/gnunet-service-xdht_routing.c | |||
@@ -28,6 +28,10 @@ | |||
28 | #include "gnunet-service-xdht_routing.h" | 28 | #include "gnunet-service-xdht_routing.h" |
29 | #include "gnunet-service-xdht.h" | 29 | #include "gnunet-service-xdht.h" |
30 | 30 | ||
31 | /* TODO | ||
32 | 1. to understand if we really need all the four fields. | ||
33 | 2. if we can merge remove_peer and remove_trail | ||
34 | 3. do we need next_hop to uniquely identify a trail in remove_trail. */ | ||
31 | 35 | ||
32 | /** | 36 | /** |
33 | * Number of requests we track at most (for routing replies). | 37 | * Number of requests we track at most (for routing replies). |
@@ -178,6 +182,22 @@ GDS_ROUTING_remove_entry (const struct GNUNET_PeerIdentity *peer) | |||
178 | } | 182 | } |
179 | 183 | ||
180 | 184 | ||
185 | /** FIXME:TODO URGNET Need to understand if we need next hop to uniquely identify an entry | ||
186 | * in routing table or not. | ||
187 | * Remove the trail as result of trail tear down message. | ||
188 | * @param source_peer Source of the trail. | ||
189 | * @param destination_peer Destination of the trail. | ||
190 | * @param next_hop Next hop | ||
191 | * @param prev_hop Previous hop. | ||
192 | */ | ||
193 | int | ||
194 | GDS_ROUTING_remove_trail (struct GNUNET_PeerIdentity *source_peer, | ||
195 | struct GNUNET_PeerIdentity *destination_peer, | ||
196 | const struct GNUNET_PeerIdentity *prev_hop) | ||
197 | { | ||
198 | return GNUNET_NO; | ||
199 | } | ||
200 | |||
181 | /** | 201 | /** |
182 | * Find the next hop to send packet to. | 202 | * Find the next hop to send packet to. |
183 | * @param source_peer Source of the trail. | 203 | * @param source_peer Source of the trail. |
@@ -213,7 +233,7 @@ int | |||
213 | GDS_ROUTING_check_threshold () | 233 | GDS_ROUTING_check_threshold () |
214 | { | 234 | { |
215 | int ret; | 235 | int ret; |
216 | ret = (GNUNET_CONTAINER_multipeermap_size(routing_table) > ROUTING_TABLE_THRESHOLD) ? 0:1; | 236 | ret = (GNUNET_CONTAINER_multipeermap_size(routing_table) > ROUTING_TABLE_THRESHOLD) ? 1:0; |
217 | return ret; | 237 | return ret; |
218 | } | 238 | } |
219 | 239 | ||
diff --git a/src/dht/gnunet-service-xdht_routing.h b/src/dht/gnunet-service-xdht_routing.h index 70bacebf5..efda58a94 100644 --- a/src/dht/gnunet-service-xdht_routing.h +++ b/src/dht/gnunet-service-xdht_routing.h | |||
@@ -64,6 +64,20 @@ GDS_ROUTING_search(struct GNUNET_PeerIdentity *source_peer, | |||
64 | struct GNUNET_PeerIdentity *destination_peer, | 64 | struct GNUNET_PeerIdentity *destination_peer, |
65 | const struct GNUNET_PeerIdentity *prev_hop); | 65 | const struct GNUNET_PeerIdentity *prev_hop); |
66 | 66 | ||
67 | /** | ||
68 | * Remove the trail as result of trail tear down message. | ||
69 | * @param source_peer Source of the trail. | ||
70 | * @param destination_peer Destination of the trail. | ||
71 | * @param next_hop Next hop | ||
72 | * @param prev_hop Previous hop. | ||
73 | * @return #GNUNET_YES if successful | ||
74 | * #GNUNET_NO if not successful. | ||
75 | */ | ||
76 | int | ||
77 | GDS_ROUTING_remove_trail (struct GNUNET_PeerIdentity *source_peer, | ||
78 | struct GNUNET_PeerIdentity *destination_peer, | ||
79 | const struct GNUNET_PeerIdentity *prev_hop); | ||
80 | |||
67 | 81 | ||
68 | /** | 82 | /** |
69 | * Check if size of routing table is greater than threshold or not. | 83 | * Check if size of routing table is greater than threshold or not. |