diff options
author | Supriti Singh <supritisingh08@gmail.com> | 2014-02-24 14:11:53 +0000 |
---|---|---|
committer | Supriti Singh <supritisingh08@gmail.com> | 2014-02-24 14:11:53 +0000 |
commit | 7ff606c7821c3beec90d4d5511162f33688138bc (patch) | |
tree | fe5356aa557e6f09443d8b348d0c0488a94c3173 /src/dht | |
parent | 2300e9b9fa809d20bd407248a5a83b764122de71 (diff) | |
download | gnunet-7ff606c7821c3beec90d4d5511162f33688138bc.tar.gz gnunet-7ff606c7821c3beec90d4d5511162f33688138bc.zip |
1. Refactored the code for trail setup and trail setup result.
2. Adding an entry into finger table.
Diffstat (limited to 'src/dht')
-rw-r--r-- | src/dht/gnunet-service-xdht_neighbours.c | 394 |
1 files changed, 230 insertions, 164 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c index aa52591bb..4d4997d6e 100644 --- a/src/dht/gnunet-service-xdht_neighbours.c +++ b/src/dht/gnunet-service-xdht_neighbours.c | |||
@@ -50,7 +50,12 @@ | |||
50 | 50 | ||
51 | 51 | ||
52 | /* FIXME: | 52 | /* FIXME: |
53 | 1. You are not using mod when searching for the closest successor of a finger. | 53 | 1. Add content and route replication later. |
54 | * 3. Algorithm to shorten the trail length - one possible solution could be | ||
55 | * when we are in trail seutp result part. each peer in the trail check if any of | ||
56 | * the corresponding peers is its friend list. Then it can shortcut the path. | ||
57 | * But this will have O(n) run time at each peer, where n = trail_length.\ | ||
58 | * or rather O(n)+O(n-1)+..O(1) =O(n). | ||
54 | */ | 59 | */ |
55 | 60 | ||
56 | 61 | ||
@@ -244,6 +249,19 @@ struct PeerGetMessage | |||
244 | 249 | ||
245 | 250 | ||
246 | /** | 251 | /** |
252 | * A destination can be either a friend or finger. | ||
253 | */ | ||
254 | enum current_destination_type | ||
255 | { | ||
256 | /* Friend */ | ||
257 | FRIEND , | ||
258 | |||
259 | /* Finger */ | ||
260 | FINGER | ||
261 | |||
262 | }; | ||
263 | |||
264 | /** | ||
247 | * P2P Trail setup message | 265 | * P2P Trail setup message |
248 | * TODO: Take reference from put_path and get_path to understand how to use size of trail list. | 266 | * TODO: Take reference from put_path and get_path to understand how to use size of trail list. |
249 | */ | 267 | */ |
@@ -267,7 +285,10 @@ struct PeerTrailSetupMessage | |||
267 | /* FIXME: Temporary field to handle current_destination properly. | 285 | /* FIXME: Temporary field to handle current_destination properly. |
268 | If flag = 0, then this message's current_destination is a friend. | 286 | If flag = 0, then this message's current_destination is a friend. |
269 | If flag = 1, then the message's current destination is a finger. */ | 287 | If flag = 1, then the message's current destination is a finger. */ |
270 | int flag; | 288 | //int flag; |
289 | |||
290 | enum current_destination_type current_destination_type; | ||
291 | |||
271 | /** | 292 | /** |
272 | * This field contains the peer to which this packet is forwarded. | 293 | * This field contains the peer to which this packet is forwarded. |
273 | */ | 294 | */ |
@@ -280,8 +301,9 @@ struct PeerTrailSetupMessage | |||
280 | */ | 301 | */ |
281 | uint32_t trail_length GNUNET_PACKED; | 302 | uint32_t trail_length GNUNET_PACKED; |
282 | 303 | ||
283 | /* The finger index in finger map. */ | 304 | /* FIXME: Add this field later. |
284 | unsigned int finger_index; | 305 | * The finger index in finger map. |
306 | unsigned int finger_index;*/ | ||
285 | 307 | ||
286 | }; | 308 | }; |
287 | 309 | ||
@@ -322,7 +344,7 @@ struct PeerTrailSetupResultMessage | |||
322 | * FIXME: Is this data type correct? | 344 | * FIXME: Is this data type correct? |
323 | * FIXME: Is usage of GNUNET_PACKED correct? | 345 | * FIXME: Is usage of GNUNET_PACKED correct? |
324 | */ | 346 | */ |
325 | uint32_t list_size GNUNET_PACKED; | 347 | uint32_t trail_length GNUNET_PACKED; |
326 | 348 | ||
327 | }; | 349 | }; |
328 | 350 | ||
@@ -403,6 +425,12 @@ struct FriendInfo | |||
403 | unsigned int pending_count; | 425 | unsigned int pending_count; |
404 | 426 | ||
405 | /** | 427 | /** |
428 | * FIXME: | ||
429 | * 1. We need some mechanism to check the interval of values for which | ||
430 | * a peer is responsible. If we can somehow maintain the peer id of | ||
431 | * next peer in the friend map, then we will be able to check. Or else | ||
432 | * we iterate over friend map twice will results in O(n^2) complexity. | ||
433 | * So, the tradeoff is between space and run time complexity. | ||
406 | * Peer id of next friend in friend peermap in 64 bit format. | 434 | * Peer id of next friend in friend peermap in 64 bit format. |
407 | */ | 435 | */ |
408 | uint64_t interval_end; | 436 | uint64_t interval_end; |
@@ -447,14 +475,9 @@ struct FingerInfo | |||
447 | unsigned int interval_end; | 475 | unsigned int interval_end; |
448 | 476 | ||
449 | /** | 477 | /** |
450 | * Head of trail list. | 478 | * List of peers in the trail. |
451 | */ | 479 | */ |
452 | struct TrailPeerList *head; | 480 | const struct GNUNET_PeerIdentity *trail_peer_list; |
453 | |||
454 | /** | ||
455 | * Tail of trail list. | ||
456 | */ | ||
457 | struct TrailPeerList *tail; | ||
458 | 481 | ||
459 | /** | 482 | /** |
460 | * Finger index. | 483 | * Finger index. |
@@ -523,7 +546,7 @@ core_transmit_notify (void *cls, size_t size, void *buf) | |||
523 | struct P2PPendingMessage *pending; | 546 | struct P2PPendingMessage *pending; |
524 | size_t off; | 547 | size_t off; |
525 | size_t msize; | 548 | size_t msize; |
526 | 549 | ||
527 | peer->th = NULL; | 550 | peer->th = NULL; |
528 | while ((NULL != (pending = peer->head)) && | 551 | while ((NULL != (pending = peer->head)) && |
529 | (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us)) | 552 | (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us)) |
@@ -610,33 +633,42 @@ process_friend_queue (struct FriendInfo *peer) | |||
610 | 633 | ||
611 | 634 | ||
612 | /** | 635 | /** |
613 | * FIXME: Do we need to use some block type in this function? | 636 | * SUPU: |
614 | * Set up the trial message and forwards this message to friend. | 637 | * 1. trail_length is already incremented in the calling function |
615 | * | 638 | * i.e. in send_find_finger_trail, we send trail_length = 1, and then we |
616 | * @param Finger id to which we want to setup the trail. | 639 | * add the peer. |
617 | * @param Friend id through which we will try to setup the trail. | 640 | * 2. in handle_dht_p2p_trail_setup, we send trail_length = trail_length+1; |
641 | * and we already have added the id of current_destination in our peer_list so | ||
642 | * we need not to do anything else. | ||
643 | * Setup the trail message and forward it to a friend. | ||
644 | * @param source_peer Peer which wants to set up the trail to one of its finger. | ||
645 | * @param destination_finger Peer to which we want to set up the trail to. | ||
646 | * @param current_destination Current peer to which this message should be forwarded. | ||
647 | * @param trail_length Numbers of peers in the trail. | ||
648 | * @param trail_peer_list peers this request has traversed so far | ||
618 | */ | 649 | */ |
619 | void | 650 | void |
620 | GDS_NEIGHBOURS_handle_trail_setup(struct GNUNET_PeerIdentity *finger_id, | 651 | GDS_NEIGHBOURS_handle_trail_setup(struct GNUNET_PeerIdentity *source_peer, |
621 | struct FriendInfo *target_friend, | 652 | struct GNUNET_PeerIdentity *destination_finger, |
622 | unsigned int finger_index) | 653 | struct FriendInfo *current_destination, |
654 | unsigned int trail_length, | ||
655 | struct GNUNET_PeerIdentity *trail_peer_list) | ||
623 | { | 656 | { |
624 | struct P2PPendingMessage *pending; | 657 | struct P2PPendingMessage *pending; |
625 | struct PeerTrailSetupMessage *tsm; | 658 | struct PeerTrailSetupMessage *tsm; |
626 | struct GNUNET_PeerIdentity *peer_id; | 659 | struct GNUNET_PeerIdentity *peer_list; |
627 | size_t msize; | 660 | size_t msize; |
628 | 661 | ||
629 | /* We will add target_friend to our trail_list. Hence, we add its size to size | 662 | msize = sizeof(struct PeerTrailSetupMessage) + |
630 | of PeerTrailSetupMessage to get msize. */ | 663 | (trail_length * sizeof(struct GNUNET_PeerIdentity)); |
631 | msize = sizeof(struct PeerTrailSetupMessage) + sizeof(struct GNUNET_PeerIdentity); | ||
632 | 664 | ||
633 | if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | 665 | if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
634 | { | 666 | { |
635 | GNUNET_break (0); | 667 | GNUNET_break (0); |
636 | return; | 668 | return; |
637 | } | 669 | } |
638 | 670 | ||
639 | if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND) | 671 | if (current_destination->pending_count >= MAXIMUM_PENDING_PER_FRIEND) |
640 | { | 672 | { |
641 | GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), | 673 | GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), |
642 | 1, GNUNET_NO); | 674 | 1, GNUNET_NO); |
@@ -649,78 +681,85 @@ GDS_NEIGHBOURS_handle_trail_setup(struct GNUNET_PeerIdentity *finger_id, | |||
649 | pending->msg = &tsm->header; | 681 | pending->msg = &tsm->header; |
650 | tsm->header.size = htons (msize); | 682 | tsm->header.size = htons (msize); |
651 | tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP); | 683 | tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP); |
652 | memcpy(&(tsm->destination_finger), finger_id, sizeof (struct GNUNET_PeerIdentity)); | 684 | memcpy(&(tsm->destination_finger), destination_finger, sizeof (struct GNUNET_PeerIdentity)); |
653 | memcpy(&(tsm->source_peer), &my_identity, sizeof (struct GNUNET_PeerIdentity)); | 685 | memcpy(&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); |
654 | memcpy(&(tsm->current_destination),&(target_friend->id), sizeof (struct GNUNET_PeerIdentity)); | 686 | memcpy(&(tsm->current_destination),&(current_destination->id), sizeof (struct GNUNET_PeerIdentity)); |
655 | tsm->flag = 0; /*FIXME: Replace 0 by enum for friend/finger.*/ | 687 | tsm->current_destination_type = htonl(FRIEND); |
656 | tsm->finger_index = finger_index; | 688 | tsm->trail_length = htonl(trail_length); |
657 | tsm->trail_length = 1; | 689 | peer_list = (struct GNUNET_PeerIdentity *) &tsm[1]; |
690 | |||
691 | if(NULL == trail_peer_list) | ||
692 | { | ||
693 | memcpy(peer_list, &(current_destination->id), sizeof(struct GNUNET_PeerIdentity)); | ||
694 | } | ||
695 | else | ||
696 | { | ||
697 | memcpy(peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity)); | ||
698 | } | ||
658 | 699 | ||
659 | peer_id = (struct GNUNET_PeerIdentity *)&tsm[1]; | 700 | GNUNET_CONTAINER_DLL_insert_tail (current_destination->head, current_destination->tail, pending); |
660 | memcpy(peer_id, target_friend, sizeof (struct GNUNET_PeerIdentity)); | 701 | current_destination->pending_count++; |
702 | process_friend_queue (current_destination); | ||
661 | 703 | ||
662 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); | ||
663 | |||
664 | target_friend->pending_count++; | ||
665 | process_friend_queue (target_friend); | ||
666 | } | 704 | } |
667 | 705 | ||
668 | |||
669 | /** | 706 | /** |
670 | * Handle a trail setup result message. | 707 | * Handle a tail setup result message. |
671 | * @tsm PeerTrailSetupMessage | 708 | * @param destination_peer Peer which will get the trail to one of its finger. |
709 | * @param source_finger Peer to which the trail has been setup to. | ||
710 | * @param current_destination Current peer to which this message should be forwarded. | ||
711 | * @param trail_length Numbers of peers in the trail. | ||
712 | * @param trail_peer_list peers this request has traversed so far | ||
713 | * @param current_trail_index Index in trail_peer_list. | ||
672 | */ | 714 | */ |
673 | void | 715 | void |
674 | GDS_NEIGHBOURS_handle_trail_setup_result(struct PeerTrailSetupMessage *tsm) | 716 | GDS_NEIGHBOURS_handle_trail_setup_result(struct GNUNET_PeerIdentity *destination_peer, |
717 | struct GNUNET_PeerIdentity *source_finger, | ||
718 | struct FriendInfo *current_destination, | ||
719 | unsigned int trail_length, | ||
720 | const struct GNUNET_PeerIdentity *trail_peer_list, | ||
721 | unsigned int current_trial_index) | ||
675 | { | 722 | { |
676 | /* In this function, you need to setup the trail result message. */ | ||
677 | struct PeerTrailSetupResultMessage *tsrm; | ||
678 | struct P2PPendingMessage *pending; | 723 | struct P2PPendingMessage *pending; |
679 | struct FriendInfo *friend; | 724 | struct PeerTrailSetupResultMessage *tsrm; |
680 | struct GNUNET_PeerIdentity *peer; | 725 | struct GNUNET_PeerIdentity *peer_list; |
681 | size_t msize; | 726 | size_t msize; |
682 | 727 | ||
683 | /* FIXME: Check if this msize is correct or not. */ | 728 | msize = sizeof(struct PeerTrailSetupMessage) + |
684 | msize = sizeof(struct PeerTrailSetupMessage) + (tsm->trail_length * sizeof(struct GNUNET_PeerIdentity)); | 729 | (trail_length * sizeof(struct GNUNET_PeerIdentity)); |
685 | 730 | ||
686 | if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | 731 | if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
687 | { | 732 | { |
688 | GNUNET_break (0); | 733 | GNUNET_break (0); |
689 | return; | 734 | return; |
690 | } | 735 | } |
691 | 736 | ||
692 | pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); | 737 | if (current_destination->pending_count >= MAXIMUM_PENDING_PER_FRIEND) |
738 | { | ||
739 | GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), | ||
740 | 1, GNUNET_NO); | ||
741 | } | ||
742 | |||
743 | pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); | ||
693 | pending->importance = 0; /* FIXME */ | 744 | pending->importance = 0; /* FIXME */ |
694 | pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT); | 745 | pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT); |
695 | tsrm = (struct PeerTrailSetupResultMessage *) &pending[1]; | 746 | tsrm = (struct PeerTrailSetupResultMessage *) &pending[1]; |
696 | pending->msg = &tsrm->header; | 747 | pending->msg = &tsrm->header; |
697 | tsrm->header.size = htons (msize); | 748 | tsrm->header.size = htons (msize); |
698 | tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT); | 749 | tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT); |
699 | memcpy(&(tsrm->finger), &(tsm->current_destination), sizeof(struct GNUNET_PeerIdentity)); | 750 | memcpy(&(tsrm->current_destination), &(current_destination->id), sizeof(struct GNUNET_PeerIdentity)); |
700 | memcpy(&(tsrm->destination_peer), &(tsm->source_peer), sizeof(struct GNUNET_PeerIdentity)); | 751 | memcpy(&(tsrm->destination_peer), destination_peer, sizeof(struct GNUNET_PeerIdentity)); |
701 | tsrm->list_size = tsm->trail_length; | 752 | memcpy(&(tsrm->finger), source_finger, sizeof(struct GNUNET_PeerIdentity)); |
753 | tsrm->trail_length = htonl(trail_length); | ||
754 | tsrm->current_index = htonl(current_trial_index); | ||
755 | peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1]; | ||
756 | memcpy(peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity)); | ||
702 | 757 | ||
703 | /* TODO: Copy the whole trail list into tsrm. */ | 758 | /* Send the message to chosen friend. */ |
704 | 759 | GNUNET_CONTAINER_DLL_insert_tail (current_destination->head, current_destination->tail, pending); | |
705 | /* Read the elements of trail list backwards to get the target friend to sent | ||
706 | the packet to. Assuming we did not add ourself to the trail list, the last element | ||
707 | will be the element to which we want to send the packet. */ | ||
708 | peer = (struct GNUNET_PeerIdentity *)&tsm[tsm->trail_length]; | ||
709 | |||
710 | /* Get the friend corresponding to this peer. */ | ||
711 | friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer); | ||
712 | |||
713 | if (friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND) | ||
714 | { | ||
715 | GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), | ||
716 | 1, GNUNET_NO); | ||
717 | } | ||
718 | |||
719 | /* call process_friend_queue. */ | ||
720 | GNUNET_CONTAINER_DLL_insert_tail (friend->head, friend->tail, pending); | ||
721 | 760 | ||
722 | friend->pending_count++; | 761 | current_destination->pending_count++; |
723 | process_friend_queue (friend); | 762 | process_friend_queue (current_destination); |
724 | } | 763 | } |
725 | 764 | ||
726 | 765 | ||
@@ -864,6 +903,10 @@ select_random_friend() | |||
864 | 903 | ||
865 | /** | 904 | /** |
866 | * Compute finger_identity to which we want to setup the trail | 905 | * Compute finger_identity to which we want to setup the trail |
906 | * FIXME: If we maintain a index that is value of current_finger_index | ||
907 | * to which a particular entry in finger map corresponds then should we first | ||
908 | * check if there is already an entry for that index. If yes then don't | ||
909 | * search for trail to that finger. | ||
867 | * @return finger_identity | 910 | * @return finger_identity |
868 | */ | 911 | */ |
869 | static | 912 | static |
@@ -875,10 +918,6 @@ compute_finger_identity() | |||
875 | finger_identity = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); | 918 | finger_identity = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); |
876 | finger_identity = GNUNET_CRYPTO_compute_finger_identity(&my_identity,current_finger_index ); | 919 | finger_identity = GNUNET_CRYPTO_compute_finger_identity(&my_identity,current_finger_index ); |
877 | 920 | ||
878 | |||
879 | |||
880 | |||
881 | |||
882 | current_finger_index = (current_finger_index+1) % MAX_FINGERS; | 921 | current_finger_index = (current_finger_index+1) % MAX_FINGERS; |
883 | 922 | ||
884 | /* Check if you already have an entry in finger_peermap for this finger_id. | 923 | /* Check if you already have an entry in finger_peermap for this finger_id. |
@@ -931,12 +970,7 @@ send_find_finger_trail_message (void *cls, | |||
931 | struct GNUNET_PeerIdentity *finger_identity; | 970 | struct GNUNET_PeerIdentity *finger_identity; |
932 | struct FriendInfo *friend; | 971 | struct FriendInfo *friend; |
933 | struct GNUNET_TIME_Relative next_send_time; | 972 | struct GNUNET_TIME_Relative next_send_time; |
934 | unsigned int finger_index; | 973 | |
935 | |||
936 | /* FIXME: How do we use the finger_index in rest of the algorithm | ||
937 | If not use then remove later. */ | ||
938 | finger_index = current_finger_index; | ||
939 | |||
940 | /* We already have found trail to each of our possible fingers in the network. */ | 974 | /* We already have found trail to each of our possible fingers in the network. */ |
941 | if (GNUNET_CONTAINER_multipeermap_size (finger_peermap) == MAX_FINGERS) | 975 | if (GNUNET_CONTAINER_multipeermap_size (finger_peermap) == MAX_FINGERS) |
942 | { | 976 | { |
@@ -968,10 +1002,12 @@ send_find_finger_trail_message (void *cls, | |||
968 | 1002 | ||
969 | friend = GNUNET_malloc (sizeof (struct FriendInfo)); | 1003 | friend = GNUNET_malloc (sizeof (struct FriendInfo)); |
970 | friend = select_random_friend(); | 1004 | friend = select_random_friend(); |
971 | 1005 | ||
972 | /* We found a friend.*/ | 1006 | /* We found a friend.*/ |
973 | if(NULL != friend) | 1007 | if(NULL != friend) |
974 | GDS_NEIGHBOURS_handle_trail_setup(finger_identity, friend, finger_index); | 1008 | { |
1009 | GDS_NEIGHBOURS_handle_trail_setup(&my_identity,finger_identity,friend,1,NULL); | ||
1010 | } | ||
975 | 1011 | ||
976 | /* FIXME: Should we be using current_finger_index to generate random interval.*/ | 1012 | /* FIXME: Should we be using current_finger_index to generate random interval.*/ |
977 | new_find_finger_trail_request: | 1013 | new_find_finger_trail_request: |
@@ -997,7 +1033,7 @@ static void | |||
997 | handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer) | 1033 | handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer) |
998 | { | 1034 | { |
999 | struct FriendInfo *ret; | 1035 | struct FriendInfo *ret; |
1000 | 1036 | ||
1001 | /* Check for connect to self message */ | 1037 | /* Check for connect to self message */ |
1002 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) | 1038 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) |
1003 | return; | 1039 | return; |
@@ -1138,14 +1174,21 @@ handle_dht_p2p_result (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1138 | 1174 | ||
1139 | 1175 | ||
1140 | /** | 1176 | /** |
1141 | * FIXMEl Where do we use mod MAX_FINGERS? | 1177 | * FIXME: |
1178 | * 1. Where do we use mod MAX_FINGERS? | ||
1179 | * 2. You are not using mod when searching for the closest successor of a finger. | ||
1180 | * 3. * 6. When I change the logic for find_successor, then I need to compare the interval | ||
1181 | * of two fingers. for that do I need to maintain a finger index and calculate | ||
1182 | * the interval? | ||
1142 | * @param destination | 1183 | * @param destination |
1143 | * @param flag Set the value of flag to 0, if next_hop = friend/1 if next_hop = finger. | 1184 | * @param flag Set the value of flag to 0, if next_hop = friend/1 if next_hop = finger. |
1144 | * @param current_destination We should set this field to finger id/friend id chosen to be next_hop. | 1185 | * @param current_destination We should set this field to finger id/friend id chosen to be next_hop. |
1145 | * @return | 1186 | * @return |
1146 | */ | 1187 | */ |
1147 | static struct GNUNET_PeerIdentity * | 1188 | static struct GNUNET_PeerIdentity * |
1148 | find_successor(struct GNUNET_PeerIdentity *destination, struct GNUNET_PeerIdentity *current_destination,int *flag) | 1189 | find_successor(struct GNUNET_PeerIdentity *destination, |
1190 | struct GNUNET_PeerIdentity *current_destination, | ||
1191 | enum current_destination_type *type) | ||
1149 | { | 1192 | { |
1150 | /* | 1193 | /* |
1151 | * 1. Compare your identity with destination identity. | 1194 | * 1. Compare your identity with destination identity. |
@@ -1225,12 +1268,12 @@ find_successor(struct GNUNET_PeerIdentity *destination, struct GNUNET_PeerIdenti | |||
1225 | 1268 | ||
1226 | if(successor == finger_peer) | 1269 | if(successor == finger_peer) |
1227 | { | 1270 | { |
1228 | *flag = 1; | 1271 | *type = FINGER; |
1229 | } | 1272 | } |
1230 | else | 1273 | else |
1231 | { | 1274 | { |
1232 | /* The successor is either my_identity or friend. */ | 1275 | /* The successor is either my_identity or friend. */ |
1233 | *flag = 0; | 1276 | *type = FRIEND; |
1234 | } | 1277 | } |
1235 | 1278 | ||
1236 | return current_successor; | 1279 | return current_successor; |
@@ -1238,9 +1281,6 @@ find_successor(struct GNUNET_PeerIdentity *destination, struct GNUNET_PeerIdenti | |||
1238 | 1281 | ||
1239 | 1282 | ||
1240 | /** | 1283 | /** |
1241 | * FIXME: | ||
1242 | * 1. Check if we are correctly adding peer to our message and sending | ||
1243 | * the message correctly to next friend. | ||
1244 | * @param cls closure | 1284 | * @param cls closure |
1245 | * @param message message | 1285 | * @param message message |
1246 | * @param peer peer identity this notification is about | 1286 | * @param peer peer identity this notification is about |
@@ -1252,12 +1292,14 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1252 | { | 1292 | { |
1253 | struct PeerTrailSetupMessage *trail_setup; | 1293 | struct PeerTrailSetupMessage *trail_setup; |
1254 | struct GNUNET_PeerIdentity *next_hop; | 1294 | struct GNUNET_PeerIdentity *next_hop; |
1255 | struct GNUNET_PeerIdentity *peer_identity_trail; | ||
1256 | struct FriendInfo *target_friend; | 1295 | struct FriendInfo *target_friend; |
1257 | struct P2PPendingMessage *pending; | ||
1258 | size_t msize; | 1296 | size_t msize; |
1259 | uint32_t trail_length; | 1297 | uint32_t trail_length; |
1260 | 1298 | enum current_destination_type peer_type; | |
1299 | struct GNUNET_PeerIdentity *trail_peer_list; | ||
1300 | uint32_t current_trail_index; | ||
1301 | struct GNUNET_PeerIdentity *next_peer; | ||
1302 | |||
1261 | /* parse and validate message. */ | 1303 | /* parse and validate message. */ |
1262 | msize = ntohs (message->size); | 1304 | msize = ntohs (message->size); |
1263 | if (msize < sizeof (struct PeerTrailSetupMessage)) | 1305 | if (msize < sizeof (struct PeerTrailSetupMessage)) |
@@ -1266,8 +1308,10 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1266 | return GNUNET_YES; | 1308 | return GNUNET_YES; |
1267 | } | 1309 | } |
1268 | 1310 | ||
1269 | trail_setup = (struct PeerTrailSetupMessage *) message; | 1311 | trail_setup = (struct PeerTrailSetupMessage *) message; |
1270 | trail_length = trail_setup->trail_length; // FIXME: should we use ntohl? | 1312 | trail_length = ntohl (trail_setup->trail_length); |
1313 | peer_type = ntohl (trail_setup->current_destination_type); | ||
1314 | trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_setup[1]; | ||
1271 | 1315 | ||
1272 | if ((msize < | 1316 | if ((msize < |
1273 | sizeof (struct PeerTrailSetupMessage) + | 1317 | sizeof (struct PeerTrailSetupMessage) + |
@@ -1278,7 +1322,8 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1278 | GNUNET_break_op (0); | 1322 | GNUNET_break_op (0); |
1279 | return GNUNET_YES; | 1323 | return GNUNET_YES; |
1280 | } | 1324 | } |
1281 | 1325 | ||
1326 | |||
1282 | GNUNET_STATISTICS_update (GDS_stats, | 1327 | GNUNET_STATISTICS_update (GDS_stats, |
1283 | gettext_noop ("# TRAIL SETUP requests received"), 1, | 1328 | gettext_noop ("# TRAIL SETUP requests received"), 1, |
1284 | GNUNET_NO); | 1329 | GNUNET_NO); |
@@ -1286,94 +1331,91 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1286 | gettext_noop ("# TRAIL SETUP bytes received"), msize, | 1331 | gettext_noop ("# TRAIL SETUP bytes received"), msize, |
1287 | GNUNET_NO); | 1332 | GNUNET_NO); |
1288 | 1333 | ||
1289 | /* FIXME: | 1334 | if(peer_type == FRIEND) |
1290 | * 1. Temporary logic using flag. Think something optmial. | ||
1291 | * 2. Set the value of flag correctly everywhere. */ | ||
1292 | /* flag == 0, so this packet is for a friend. */ | ||
1293 | if(trail_setup->flag == 0) | ||
1294 | { | 1335 | { |
1295 | /* This should always be the case. This packet is sent to me and I have received it. */ | ||
1296 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity(&(trail_setup->current_destination),&my_identity))) | 1336 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity(&(trail_setup->current_destination),&my_identity))) |
1297 | { | 1337 | { |
1298 | next_hop = find_successor(&(trail_setup->destination_finger),&(trail_setup->current_destination),&(trail_setup->flag)); | 1338 | next_hop = find_successor(&(trail_setup->destination_finger),&(trail_setup->current_destination),&(peer_type)); |
1299 | } | 1339 | } |
1300 | else | 1340 | else |
1301 | return GNUNET_SYSERR; | 1341 | return GNUNET_SYSERR; |
1302 | } | 1342 | } |
1303 | else | 1343 | else |
1304 | { | 1344 | { |
1305 | /* The value of flag == 1, so this packet is send to an intermediate finger. | ||
1306 | So, either I am the finger or I am the part of trail. */ | ||
1307 | if(0 != (GNUNET_CRYPTO_cmp_peer_identity(&(trail_setup->current_destination),&my_identity))) | 1345 | if(0 != (GNUNET_CRYPTO_cmp_peer_identity(&(trail_setup->current_destination),&my_identity))) |
1308 | { | 1346 | { |
1309 | /* I am part of trail. | 1347 | /* I am part of trail. */ |
1310 | * FIXME: Do we need to add a field prev_hop in this function call? For same | ||
1311 | * source and destination can we get different paths from different prev_hop. */ | ||
1312 | next_hop = GDS_ROUTING_search(&(trail_setup->source_peer),&(trail_setup->destination_finger)); | 1348 | next_hop = GDS_ROUTING_search(&(trail_setup->source_peer),&(trail_setup->destination_finger)); |
1313 | 1349 | ||
1314 | /*FIXME: Add logic to call find_successor and compare the two peer ids | 1350 | /*TODO: |
1351 | call find_successor and compare the two peer ids | ||
1315 | and choose whichever is closest to the destination finger. */ | 1352 | and choose whichever is closest to the destination finger. */ |
1316 | } | 1353 | } |
1317 | else | 1354 | else |
1318 | { | 1355 | { |
1319 | /* I am the current_destination finger */ | 1356 | /* I am the current_destination finger */ |
1320 | next_hop = find_successor(&(trail_setup->destination_finger),&(trail_setup->current_destination),&(trail_setup->flag)); | 1357 | next_hop = find_successor(&(trail_setup->destination_finger),&(trail_setup->current_destination),&(peer_type)); |
1321 | } | 1358 | } |
1322 | } | 1359 | } |
1323 | 1360 | ||
1361 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); | ||
1362 | |||
1363 | /* Add yourself to list of peers that trail setup message have traversed so far | ||
1364 | and increment trail length. */ | ||
1365 | struct GNUNET_PeerIdentity *peer_list; | ||
1366 | peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length); | ||
1367 | memcpy(peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
1368 | peer_list[trail_length] = *next_hop; | ||
1369 | trail_length++; | ||
1324 | 1370 | ||
1325 | /* At this point, we have found our next hop. */ | 1371 | /* Check if you are next hop, if yes then you have reached the final destination. */ |
1326 | /* Check if your are next hop, if yes then you have reached the final destination. */ | ||
1327 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity(next_hop,&my_identity))) | 1372 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity(next_hop,&my_identity))) |
1328 | { | 1373 | { |
1329 | GDS_NEIGHBOURS_handle_trail_setup_result(trail_setup); | 1374 | /* FIXME: Trail length should be const. */ |
1375 | current_trail_index = trail_length - 1; | ||
1376 | next_peer = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); //FIXME: Do we need to allocate the memory? | ||
1377 | memcpy(next_peer, &peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity)); | ||
1378 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer); | ||
1379 | |||
1380 | GDS_NEIGHBOURS_handle_trail_setup_result(&(trail_setup->source_peer), | ||
1381 | &(trail_setup->destination_finger), | ||
1382 | target_friend, trail_length, | ||
1383 | peer_list,current_trail_index); | ||
1330 | return GNUNET_YES; | 1384 | return GNUNET_YES; |
1331 | } | 1385 | } |
1332 | 1386 | ||
1333 | /* FIXME: Do we need to add an entry if we are just passing the packet to | 1387 | if(peer_type == FINGER) |
1334 | * one of the friend.*/ | ||
1335 | if(trail_setup->flag == 1) | ||
1336 | { | 1388 | { |
1337 | /* This packet is sent to an intermediate finger. Add an entry in routing table. */ | ||
1338 | GDS_ROUTING_add(&(trail_setup->source_peer),&(trail_setup->current_destination),next_hop); | 1389 | GDS_ROUTING_add(&(trail_setup->source_peer),&(trail_setup->current_destination),next_hop); |
1339 | } | 1390 | } |
1340 | 1391 | ||
1341 | /* Add yourself to peer list. */ | 1392 | GDS_NEIGHBOURS_handle_trail_setup(&(trail_setup->source_peer), |
1342 | peer_identity_trail = (struct GNUNET_PeerIdentity *)&trail_setup[1]; | 1393 | &(trail_setup->destination_finger), |
1343 | memcpy(peer_identity_trail, next_hop, sizeof(struct GNUNET_PeerIdentity)); | 1394 | target_friend, |
1344 | 1395 | trail_setup->trail_length, | |
1345 | /* FIXME: Are we correctly incrementing trail_length and msize. | 1396 | peer_list); |
1346 | * Construct the new message to send it to next_hop. */ | 1397 | return GNUNET_YES; |
1347 | trail_setup->trail_length++; | ||
1348 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); | ||
1349 | |||
1350 | pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); | ||
1351 | pending->importance = 0; /* FIXME */ | ||
1352 | pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT); | ||
1353 | trail_setup = (struct PeerTrailSetupMessage *) &pending[1]; | ||
1354 | |||
1355 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); | ||
1356 | |||
1357 | target_friend->pending_count++; | ||
1358 | process_friend_queue(target_friend); | ||
1359 | return GNUNET_YES; | ||
1360 | } | 1398 | } |
1361 | 1399 | ||
1362 | 1400 | ||
1363 | /* Add an entry to finger table. | 1401 | /** |
1364 | FIXME: | 1402 | * FIXME : Add interval field. |
1365 | 1.I have not added logic to find out the interval of keys for which | 1403 | * Add an entry in finger table. |
1366 | a finger is responsible. Possible logic | 1404 | * @param finger Finger to be added to finger table |
1367 | --> finger[i].interval = [finger[i].start,finger[i+1].start) | 1405 | * @param peer_list peers this request has traversed so far |
1368 | * This logic needs to be implemented as we will need it for PUT/GET. | 1406 | * @param trail_length Numbers of peers in the trail. |
1369 | * 2. Also, check the logic again when initializing fields of finger. */ | 1407 | */ |
1370 | static | 1408 | static |
1371 | void finger_table_add(struct PeerTrailSetupResultMessage *result) | 1409 | void finger_table_add(struct GNUNET_PeerIdentity *finger, |
1410 | const struct GNUNET_PeerIdentity *peer_list, | ||
1411 | unsigned int trail_length) | ||
1372 | { | 1412 | { |
1373 | /* 1. create a struct FingerInfo and copy respective members | 1413 | struct FingerInfo *finger_entry; |
1374 | * of result into this struct. | 1414 | |
1375 | * Add the whole trail in your finger table, | 1415 | finger_entry = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); |
1376 | also add interval. */ | 1416 | memcpy(&(finger_entry->id), finger, sizeof(struct GNUNET_PeerIdentity)); |
1417 | memcpy(&(finger_entry->trail_peer_list), peer_list, sizeof(struct GNUNET_PeerIdentity) | ||
1418 | * trail_length); | ||
1377 | } | 1419 | } |
1378 | 1420 | ||
1379 | 1421 | ||
@@ -1382,8 +1424,7 @@ void finger_table_add(struct PeerTrailSetupResultMessage *result) | |||
1382 | * @param cls closure | 1424 | * @param cls closure |
1383 | * @param message message | 1425 | * @param message message |
1384 | * @param peer peer identity this notification is about | 1426 | * @param peer peer identity this notification is about |
1385 | * @return #GNUNET_YES (do not cut p2p connection) | 1427 | * @return #GNUNET_YES |
1386 | * @return | ||
1387 | */ | 1428 | */ |
1388 | static int | 1429 | static int |
1389 | handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer, | 1430 | handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer, |
@@ -1391,29 +1432,53 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p | |||
1391 | { | 1432 | { |
1392 | struct PeerTrailSetupResultMessage *trail_result; | 1433 | struct PeerTrailSetupResultMessage *trail_result; |
1393 | size_t msize; | 1434 | size_t msize; |
1394 | 1435 | uint32_t trail_length; | |
1395 | trail_result = (struct PeerTrailSetupResultMessage *)message; | 1436 | const struct GNUNET_PeerIdentity *trail_peer_list; |
1437 | uint32_t current_trail_index; | ||
1438 | struct GNUNET_PeerIdentity *next_peer; | ||
1439 | struct FriendInfo *target_friend; | ||
1396 | 1440 | ||
1397 | msize = ntohs (message->size); | 1441 | msize = ntohs (message->size); |
1398 | if(msize < sizeof (struct PeerTrailSetupResultMessage)) | 1442 | if (msize < sizeof (struct PeerTrailSetupMessage)) |
1399 | { | 1443 | { |
1400 | GNUNET_break_op(0); | 1444 | GNUNET_break_op (0); |
1401 | return GNUNET_YES; | 1445 | return GNUNET_YES; |
1402 | } | 1446 | } |
1403 | 1447 | ||
1404 | /* This should always be the case. */ | 1448 | trail_result = (struct PeerTrailSetupResultMessage *) message; |
1449 | trail_length = ntohl (trail_result->trail_length); | ||
1450 | current_trail_index = ntohl(trail_result->current_index); | ||
1451 | trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1]; | ||
1452 | |||
1453 | if ((msize < | ||
1454 | sizeof (struct PeerTrailSetupResultMessage) + | ||
1455 | trail_length * sizeof (struct GNUNET_PeerIdentity)) || | ||
1456 | (trail_length > | ||
1457 | GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) | ||
1458 | { | ||
1459 | GNUNET_break_op (0); | ||
1460 | return GNUNET_YES; | ||
1461 | } | ||
1462 | |||
1405 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->current_destination), &my_identity))) | 1463 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->current_destination), &my_identity))) |
1406 | { | 1464 | { |
1407 | /* Am I the destination? */ | 1465 | /* Am I the destination? */ |
1408 | if( 0 == (GNUNET_CRYPTO_cmp_peer_identity(&(trail_result->destination_peer), &my_identity))) | 1466 | if( 0 == (GNUNET_CRYPTO_cmp_peer_identity(&(trail_result->destination_peer), &my_identity))) |
1409 | { | 1467 | { |
1410 | finger_table_add(trail_result); | 1468 | finger_table_add(&(trail_result->finger), trail_peer_list,trail_length); |
1411 | return GNUNET_YES; | 1469 | return GNUNET_YES; |
1412 | } | 1470 | } |
1413 | else | 1471 | else |
1414 | { | 1472 | { |
1415 | /* read the trail list, get the next hop to send the packet to.*/ | 1473 | next_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); |
1416 | /* TODO: Use the current index to access the correct element. */ | 1474 | current_trail_index = current_trail_index - 1; |
1475 | memcpy(next_peer, &(trail_peer_list[trail_length-1]), sizeof (struct GNUNET_PeerIdentity)); | ||
1476 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer); | ||
1477 | |||
1478 | GDS_NEIGHBOURS_handle_trail_setup_result(&(trail_result->destination_peer), | ||
1479 | &(trail_result->finger), | ||
1480 | target_friend, trail_length, | ||
1481 | trail_peer_list,current_trail_index); | ||
1417 | return GNUNET_YES; | 1482 | return GNUNET_YES; |
1418 | } | 1483 | } |
1419 | } | 1484 | } |
@@ -1462,12 +1527,13 @@ GDS_NEIGHBOURS_done () | |||
1462 | { | 1527 | { |
1463 | if (NULL == core_api) | 1528 | if (NULL == core_api) |
1464 | return; | 1529 | return; |
1530 | |||
1465 | GNUNET_CORE_disconnect (core_api); | 1531 | GNUNET_CORE_disconnect (core_api); |
1466 | core_api = NULL; | 1532 | core_api = NULL; |
1467 | GNUNET_ATS_performance_done (atsAPI); | 1533 | GNUNET_ATS_performance_done (atsAPI); |
1468 | atsAPI = NULL; | 1534 | atsAPI = NULL; |
1469 | 1535 | ||
1470 | /* FIXME: Once handle_core_disconnect is implemented, this assertion should not | 1536 | /* FIXME: Once handle_core_disconnect is implemented, both below assertion should not |
1471 | fail. */ | 1537 | fail. */ |
1472 | GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap)); | 1538 | GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap)); |
1473 | GNUNET_CONTAINER_multipeermap_destroy (friend_peermap); | 1539 | GNUNET_CONTAINER_multipeermap_destroy (friend_peermap); |