aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-02-24 14:11:53 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-02-24 14:11:53 +0000
commit7ff606c7821c3beec90d4d5511162f33688138bc (patch)
treefe5356aa557e6f09443d8b348d0c0488a94c3173 /src/dht
parent2300e9b9fa809d20bd407248a5a83b764122de71 (diff)
downloadgnunet-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.c394
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 */
254enum 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 */
619void 650void
620GDS_NEIGHBOURS_handle_trail_setup(struct GNUNET_PeerIdentity *finger_id, 651GDS_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 */
673void 715void
674GDS_NEIGHBOURS_handle_trail_setup_result(struct PeerTrailSetupMessage *tsm) 716GDS_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 */
869static 912static
@@ -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
997handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer) 1033handle_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 */
1147static struct GNUNET_PeerIdentity * 1188static struct GNUNET_PeerIdentity *
1148find_successor(struct GNUNET_PeerIdentity *destination, struct GNUNET_PeerIdentity *current_destination,int *flag) 1189find_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. */ 1397return 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 */
1370static 1408static
1371void finger_table_add(struct PeerTrailSetupResultMessage *result) 1409void 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 */
1388static int 1429static int
1389handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer, 1430handle_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);