aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-03-06 14:48:21 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-03-06 14:48:21 +0000
commitc3e0eb9e5cbc2a3212fb22e39c8fa4749fdee396 (patch)
treefef9237043d8fa55f72a7aa35e69865f6062ada2 /src/dht
parent478edf9bbe5c1a82a410ff8302c892d6d585d2e6 (diff)
downloadgnunet-c3e0eb9e5cbc2a3212fb22e39c8fa4749fdee396.tar.gz
gnunet-c3e0eb9e5cbc2a3212fb22e39c8fa4749fdee396.zip
- Modified find_successor
- added a new field successor flag to identify successor in finger table.
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c438
1 files changed, 282 insertions, 156 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index e0f9ff665..cb1af96c3 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -50,20 +50,14 @@
50 50
51 51
52/* FIXME: 52/* FIXME:
53 *SUPU: Lets assume that while adding entries in the multipeermap
54 we are adding it in sorted way.
55 1. Add content and route replication later. 53 1. Add content and route replication later.
56 *2. Algorithm to shorten the trail length - one possible solution could be 54 *2. Algorithm to shorten the trail length - one possible solution could be
57 * when we are in trail seutp result part. each peer in the trail check if any of 55 * when we are in trail seutp result part. each peer in the trail check if any of
58 * the corresponding peers is its friend list. Then it can shortcut the path. 56 * the corresponding peers is its friend list. Then it can shortcut the path.
59 * But this will have O(n) run time at each peer, where n = trail_length.\ 57 * But this will have O(n) run time at each peer, where n = trail_length.\
60 * or rather O(n)+O(n-1)+..O(1) =O(n). 58 * or rather O(n)+O(n-1)+..O(1) =O(n).
61 * 3. Add a new field finger index to keep track of which finger respongs to which
62 * entry.
63 * 4. As we start looking for finger from i = 0, using this parameter to 59 * 4. As we start looking for finger from i = 0, using this parameter to
64 * generate random value does not look smart in send_find_finger_trail_message. 60 * generate random value does not look smart in send_find_finger_trail_message.
65 * 5. Need to store the interval in finger and friend table which will be used
66 * to find the correct successor.
67 * 6. Need to add a new task, fix fingers. For node join/leave, we need to 61 * 6. Need to add a new task, fix fingers. For node join/leave, we need to
68 * upgrade our finger table periodically. So, we should call fix_fingers 62 * upgrade our finger table periodically. So, we should call fix_fingers
69 * and change our finger table. 63 * and change our finger table.
@@ -306,6 +300,11 @@ struct PeerTrailSetupMessage
306 uint64_t destination_finger; 300 uint64_t destination_finger;
307 301
308 /** 302 /**
303 * If set to 1, then we are looking for trail to our immediate successor.
304 */
305 unsigned int successor_flag;
306
307 /**
309 * If the message is forwarded to finger or friend. 308 * If the message is forwarded to finger or friend.
310 */ 309 */
311 enum current_destination_type current_destination_type; 310 enum current_destination_type current_destination_type;
@@ -328,8 +327,31 @@ struct PeerTrailSetupMessage
328 327
329}; 328};
330 329
330/**
331 *
332 */
333struct PeerVerifySuccessor
334{
335
336};
337
338
339/**
340 *
341 */
342struct PeerVerifySuccessorResult
343{
344
345};
331 346
332/** 347/**
348 *
349 */
350struct PeerNotifyNewSuccessor
351{
352
353};
354/**
333 * P2P Trail setup Result message 355 * P2P Trail setup Result message
334 */ 356 */
335struct PeerTrailSetupResultMessage 357struct PeerTrailSetupResultMessage
@@ -361,6 +383,11 @@ struct PeerTrailSetupResultMessage
361 unsigned int current_index; 383 unsigned int current_index;
362 384
363 /** 385 /**
386 * If set to 1, then this trail is the trail to succcessor of our finger.
387 */
388 unsigned int successor_flag;
389
390 /**
364 * Number of entries in trail list. 391 * Number of entries in trail list.
365 * FIXME: Is this data type correct? 392 * FIXME: Is this data type correct?
366 * FIXME: Is usage of GNUNET_PACKED correct? 393 * FIXME: Is usage of GNUNET_PACKED correct?
@@ -444,16 +471,6 @@ struct FriendInfo
444 * Count of outstanding messages for peer. 471 * Count of outstanding messages for peer.
445 */ 472 */
446 unsigned int pending_count; 473 unsigned int pending_count;
447
448 /**
449 * Start of interval friend[i].start
450 */
451 uint64_t interval_start;
452
453 /**
454 * Start of interval friend[i+1].start
455 */
456 uint64_t interval_end;
457 474
458 /** 475 /**
459 * Successor of this finger. 476 * Successor of this finger.
@@ -485,6 +502,9 @@ struct FriendInfo
485 502
486 503
487/** 504/**
505 * FIXME: As in chord , where we store the actual finger identity we were looking
506 * for and the real id which we got as successor. If we want to store like that
507 * then we will need to add a new field and search actual peer id.
488 * FIXME: Should we use another PeerIdentity which is smaller 508 * FIXME: Should we use another PeerIdentity which is smaller
489 * than 256 bits while storing. 509 * than 256 bits while storing.
490 * SUPU 510 * SUPU
@@ -499,35 +519,14 @@ struct FriendInfo
499struct FingerInfo 519struct FingerInfo
500{ 520{
501 /** 521 /**
502 * Index in finger_peermap.
503 */
504 unsigned int index;
505
506 /**
507 * Finger identity. 522 * Finger identity.
508 */ 523 */
509 struct GNUNET_PeerIdentity finger_identity; 524 struct GNUNET_PeerIdentity finger_identity;
510 525
511 /** 526 /**
512 * Start of interval finger[i].start 527 * If 1, then this finger entry is first finger /successor of the peer.
513 */ 528 */
514 uint64_t interval_start; 529 unsigned int successor;
515
516 /**
517 * Start of interval finger[i+1].start
518 */
519 uint64_t interval_end;
520
521 /**
522 * Successor of this finger.
523 */
524 struct GNUNET_PeerIdentity successor_identity;
525
526 /**
527 * Predecessor of this finger.
528 */
529 struct GNUNET_PeerIdentity predecessor_identity;
530
531 /** 530 /**
532 * List of peers in the trail. 531 * List of peers in the trail.
533 */ 532 */
@@ -549,7 +548,7 @@ static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
549 * 548 *
550 * Task that periodically checks for the immediate successor. 549 * Task that periodically checks for the immediate successor.
551 */ 550 */
552static GNUNET_SCHEDULER_TaskIdentifier verify_immediate_successor; 551static GNUNET_SCHEDULER_TaskIdentifier verify_successor;
553 552
554/** 553/**
555 * Identity of this peer. 554 * Identity of this peer.
@@ -703,14 +702,16 @@ process_friend_queue (struct FriendInfo *peer)
703 * @param destination_finger Peer to which we want to set up the trail to. 702 * @param destination_finger Peer to which we want to set up the trail to.
704 * @param current_destination Current peer to which this message should be forwarded. 703 * @param current_destination Current peer to which this message should be forwarded.
705 * @param trail_length Numbers of peers in the trail. 704 * @param trail_length Numbers of peers in the trail.
706 * @param trail_peer_list peers this request has traversed so far 705 * @param trail_peer_list peers this request has traversed so far
706 * @param successor_flag If 1 then we are looking for trail to our successor.
707 */ 707 */
708void 708void
709GDS_NEIGHBOURS_handle_trail_setup(struct GNUNET_PeerIdentity *source_peer, 709GDS_NEIGHBOURS_handle_trail_setup(struct GNUNET_PeerIdentity *source_peer,
710 uint64_t *destination_finger, 710 uint64_t *destination_finger,
711 struct FriendInfo *current_destination, 711 struct FriendInfo *current_destination,
712 unsigned int trail_length, 712 unsigned int trail_length,
713 struct GNUNET_PeerIdentity *trail_peer_list) 713 struct GNUNET_PeerIdentity *trail_peer_list,
714 unsigned int successor_flag)
714{ 715{
715 struct P2PPendingMessage *pending; 716 struct P2PPendingMessage *pending;
716 struct PeerTrailSetupMessage *tsm; 717 struct PeerTrailSetupMessage *tsm;
@@ -744,6 +745,8 @@ GDS_NEIGHBOURS_handle_trail_setup(struct GNUNET_PeerIdentity *source_peer,
744 memcpy(&(tsm->current_destination),&(current_destination->id), sizeof (struct GNUNET_PeerIdentity)); 745 memcpy(&(tsm->current_destination),&(current_destination->id), sizeof (struct GNUNET_PeerIdentity));
745 tsm->current_destination_type = htonl(FRIEND); 746 tsm->current_destination_type = htonl(FRIEND);
746 tsm->trail_length = htonl(trail_length); 747 tsm->trail_length = htonl(trail_length);
748 if(successor_flag == 1)
749 tsm->successor_flag = 1;
747 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length); 750 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
748 peer_list = (struct GNUNET_PeerIdentity *) &tsm[1]; 751 peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
749 memcpy(peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity)); 752 memcpy(peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
@@ -769,7 +772,8 @@ GDS_NEIGHBOURS_handle_trail_setup_result(struct GNUNET_PeerIdentity *destination
769 struct FriendInfo *current_destination, 772 struct FriendInfo *current_destination,
770 unsigned int trail_length, 773 unsigned int trail_length,
771 const struct GNUNET_PeerIdentity *trail_peer_list, 774 const struct GNUNET_PeerIdentity *trail_peer_list,
772 unsigned int current_trial_index) 775 unsigned int current_trial_index,
776 unsigned int successor_flag)
773{ 777{
774 struct P2PPendingMessage *pending; 778 struct P2PPendingMessage *pending;
775 struct PeerTrailSetupResultMessage *tsrm; 779 struct PeerTrailSetupResultMessage *tsrm;
@@ -803,6 +807,7 @@ GDS_NEIGHBOURS_handle_trail_setup_result(struct GNUNET_PeerIdentity *destination
803 memcpy(&(tsrm->finger), source_finger, sizeof(struct GNUNET_PeerIdentity)); 807 memcpy(&(tsrm->finger), source_finger, sizeof(struct GNUNET_PeerIdentity));
804 tsrm->trail_length = htonl(trail_length); 808 tsrm->trail_length = htonl(trail_length);
805 tsrm->current_index = htonl(current_trial_index); 809 tsrm->current_index = htonl(current_trial_index);
810 tsrm->successor_flag = htonl(successor_flag);
806 peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1]; 811 peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
807 memcpy(peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity)); 812 memcpy(peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
808 813
@@ -813,6 +818,46 @@ GDS_NEIGHBOURS_handle_trail_setup_result(struct GNUNET_PeerIdentity *destination
813} 818}
814 819
815 820
821/**
822 * This function is called from send_verify_successor_message funciton
823 * and handle_dht_p2p_verify_successor.
824 * Construct a PeerVerifySuccessor message and send it to friend.
825 */
826void GDS_NEIGUBOURS_handle_verify_successor()
827{
828 /* In this funciton, you receive
829 1. successor
830 2. trial to reach that successor
831 3. trail_length.
832 4. current trail index --> this gives the next_hop on whose pending queue you should
833 add the message. */
834}
835
836
837/**
838 * this function will be called by destination successor.
839 * Construct a PeerVerifySuccessorResult message and send it to friend.
840 */
841void GDS_NEIGHBOURS_handle_verify_successor_result()
842{
843 /* In this funciton, you receive
844 1. successor
845 2. trial to reach that successor
846 3. trail_length.
847 4. current trail index --> this gives the next_hop on whose pending queue you should
848 add the message. */
849}
850
851
852/**
853 * Construct a PeerNotifyNewSuccessor message and send it to friend.
854 */
855void GDS_NEIGHBOURS_handle_notify_new_successor()
856{
857
858}
859
860
816/**FIXME: Old implementation just to remove error 861/**FIXME: Old implementation just to remove error
817 * TODO: Modify this function to handle our get request. 862 * TODO: Modify this function to handle our get request.
818 * Perform a GET operation. Forwards the given request to other 863 * Perform a GET operation. Forwards the given request to other
@@ -895,6 +940,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
895 940
896 941
897/** 942/**
943 * FIXME: Check if this function actually iterates or not.
898 * Randomly choose one of your friends from the friends_peer map 944 * Randomly choose one of your friends from the friends_peer map
899 * @return Friend 945 * @return Friend
900 */ 946 */
@@ -920,7 +966,11 @@ select_random_friend()
920 while(j < (*index)) 966 while(j < (*index))
921 { 967 {
922 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(iter,NULL,NULL)) 968 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(iter,NULL,NULL))
969 {
970 /* FIXME: I don't think we are actually incrementing iter. iter is always
971 pointing to the same element. */
923 j++; 972 j++;
973 }
924 else 974 else
925 return NULL; 975 return NULL;
926 } 976 }
@@ -953,7 +1003,6 @@ compute_finger_identity()
953 1003
954 memcpy(my_id64, &(my_identity.public_key.q_y), sizeof (uint64_t)); 1004 memcpy(my_id64, &(my_identity.public_key.q_y), sizeof (uint64_t));
955 *finger_identity64 = fmod ((*my_id64 + pow (2,current_finger_index)),( (pow (2,MAX_FINGERS)))); 1005 *finger_identity64 = fmod ((*my_id64 + pow (2,current_finger_index)),( (pow (2,MAX_FINGERS))));
956 current_finger_index = current_finger_index + 1;
957 1006
958 return finger_identity64; 1007 return finger_identity64;
959} 1008}
@@ -991,7 +1040,7 @@ find_immediate_predecessor()
991 * @param tc the context under which the task is running 1040 * @param tc the context under which the task is running
992 */ 1041 */
993static void 1042static void
994stabilize(void *cls, 1043send_verify_successor_message(void *cls,
995 const struct GNUNET_SCHEDULER_TaskContext *tc ) 1044 const struct GNUNET_SCHEDULER_TaskContext *tc )
996{ 1045{
997 /* 1046 /*
@@ -1006,16 +1055,32 @@ stabilize(void *cls,
1006 3. If not then update the new successor and your successor 1055 3. If not then update the new successor and your successor
1007 and notify the new successor that you are its new predecessor. 1056 and notify the new successor that you are its new predecessor.
1008 */ 1057 */
1058
1059 /* okay so you first need to construct a messsage that you want to send
1060 to your "successor". but here you should just call another function which
1061 will construct the message and send it to first friend in the trial to
1062 reach our successor. */
1009 struct GNUNET_TIME_Relative next_send_time; 1063 struct GNUNET_TIME_Relative next_send_time;
1010 1064 //struct GNUNET_PeerIdentity *successor;
1065 //struct FingerInfo *finger;
1066
1067 /* Iterate over your finger peermap to find the element with successor field set.
1068 That field is your successor. */
1069
1070 /* In this function you should send your successor id, trail to reach that successor,
1071 trail_length, current_trial_index. */
1072 GDS_NEIGUBOURS_handle_verify_successor();
1073
1074 /* FIXME: Use a random value so that this message is send not at the same
1075 interval as send_find_finger_trail_message. */
1011 next_send_time.rel_value_us = 1076 next_send_time.rel_value_us =
1012 DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + 1077 DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1013 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 1078 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1014 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us / 1079 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us /
1015 (current_finger_index + 1)); 1080 (current_finger_index + 1));
1016 1081
1017 verify_immediate_successor = 1082 verify_successor =
1018 GNUNET_SCHEDULER_add_delayed (next_send_time, &stabilize, 1083 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_verify_successor_message,
1019 NULL); 1084 NULL);
1020} 1085}
1021 1086
@@ -1035,7 +1100,9 @@ send_find_finger_trail_message (void *cls,
1035 struct GNUNET_TIME_Relative next_send_time; 1100 struct GNUNET_TIME_Relative next_send_time;
1036 uint64_t *finger_identity; /* FIXME: Better variable name */ 1101 uint64_t *finger_identity; /* FIXME: Better variable name */
1037 struct GNUNET_PeerIdentity *peer_list; 1102 struct GNUNET_PeerIdentity *peer_list;
1038 1103 unsigned int successor_flag; /* set to 1 if we are looking for first finger/
1104 our succcessor, else 0. */
1105
1039 /* We already have found trail to each of our possible fingers in the network. */ 1106 /* We already have found trail to each of our possible fingers in the network. */
1040 if (GNUNET_CONTAINER_multipeermap_size (finger_peermap) == MAX_FINGERS) 1107 if (GNUNET_CONTAINER_multipeermap_size (finger_peermap) == MAX_FINGERS)
1041 { 1108 {
@@ -1057,26 +1124,30 @@ send_find_finger_trail_message (void *cls,
1057 else 1124 else
1058 { 1125 {
1059 finger_identity = compute_finger_identity(); 1126 finger_identity = compute_finger_identity();
1060 1127
1061 if(finger_identity == NULL) 1128 if(finger_identity == NULL)
1062 { 1129 {
1063 goto new_find_finger_trail_request; 1130 goto new_find_finger_trail_request;
1064 } 1131 }
1065 } 1132 }
1066 1133
1134 if(0 == current_finger_index)
1135 {
1136 /* We are searching for our successor in the network. */
1137 successor_flag = 1;
1138 }
1067 friend = GNUNET_malloc (sizeof (struct FriendInfo)); 1139 friend = GNUNET_malloc (sizeof (struct FriendInfo));
1068 friend = select_random_friend(); 1140 friend = select_random_friend();
1069 1141
1070 /* We found a friend.*/ 1142 /* We found a friend.*/
1071 if(NULL != friend) 1143 if(NULL != friend)
1072 { 1144 {
1073 /* SUPU: Verify if its correct or not. */
1074 unsigned int trail_length = 2; 1145 unsigned int trail_length = 2;
1075 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length); 1146 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
1076 memcpy(&peer_list[0], &(my_identity), sizeof (struct GNUNET_PeerIdentity)); 1147 memcpy(&peer_list[0], &(my_identity), sizeof (struct GNUNET_PeerIdentity));
1077 memcpy(&peer_list[1], &(friend->id), sizeof (struct GNUNET_PeerIdentity)); 1148 memcpy(&peer_list[1], &(friend->id), sizeof (struct GNUNET_PeerIdentity));
1078 GDS_NEIGHBOURS_handle_trail_setup(&my_identity, finger_identity, 1149 GDS_NEIGHBOURS_handle_trail_setup(&my_identity, finger_identity,
1079 friend, trail_length, peer_list); 1150 friend, trail_length, peer_list,successor_flag);
1080 } 1151 }
1081 1152
1082 /* FIXME: Should we be using current_finger_index to generate random interval.*/ 1153 /* FIXME: Should we be using current_finger_index to generate random interval.*/
@@ -1124,12 +1195,9 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
1124 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1, 1195 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
1125 GNUNET_NO); 1196 GNUNET_NO);
1126 1197
1127 /* FIXME: Whenever you add an entry into your finger peermap, 1198
1128 first add everything in sorted way and interval field should also
1129 be updated. */
1130 ret = GNUNET_new (struct FriendInfo); 1199 ret = GNUNET_new (struct FriendInfo);
1131 ret->id = *peer; 1200 ret->id = *peer;
1132
1133 1201
1134 GNUNET_assert (GNUNET_OK == 1202 GNUNET_assert (GNUNET_OK ==
1135 GNUNET_CONTAINER_multipeermap_put (friend_peermap, 1203 GNUNET_CONTAINER_multipeermap_put (friend_peermap,
@@ -1182,6 +1250,7 @@ core_init (void *cls,
1182 GNUNET_CRYPTO_hash (identity, 1250 GNUNET_CRYPTO_hash (identity,
1183 sizeof (struct GNUNET_PeerIdentity), 1251 sizeof (struct GNUNET_PeerIdentity),
1184 &my_identity_hash); 1252 &my_identity_hash);
1253
1185} 1254}
1186 1255
1187 1256
@@ -1238,117 +1307,177 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
1238 return 0; 1307 return 0;
1239} 1308}
1240 1309
1310/**
1311 * Compare two peer identities. Used with qsort or bsearch.
1312 *
1313 * @param p1 Some peer identity.
1314 * @param p2 Some peer identity.
1315 * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2.
1316 */
1317static int
1318peer_id_cmp (const void *p1, const void *p2)
1319{
1320 return memcmp (p1, p2, sizeof (uint64_t));
1321}
1241 1322
1242/** 1323/**
1243 * FIXME: Use some optimal way to do the operations. 1324 * Returns the previous element of value in all_known_peers.
1244 * FIXME: Check if this function can be used as such for put/get 1325 * @param all_known_peers list of all the peers
1245 * 1.assumption that when ever we insert a value into friend or 1326 * @param value value we have to search in the all_known_peers.
1246 * finger map, we sort it and also update the interval correctly,
1247 * 2. all the comparison are done on 64 bit values. so in last part when
1248 * you compare finger , friend and your own identity then also you need to
1249 * have the values in 64 bit format and get the correct successor.
1250 * At this point the algorithm does not look very smart.
1251 * Finds successor of the identifier
1252 * @param id Identifier for which we are trying to find the successor
1253 * @return 1327 * @return
1254 */ 1328 */
1255static struct GNUNET_PeerIdentity * 1329static struct GNUNET_PeerIdentity *
1256find_successor(uint64_t id, 1330binary_search(struct GNUNET_PeerIdentity *all_known_peers, uint64_t *value,
1257 struct GNUNET_PeerIdentity *current_destination, 1331 unsigned int size)
1332{
1333 unsigned int first;
1334 unsigned int last;
1335 unsigned int middle;
1336 struct GNUNET_PeerIdentity *successor;
1337 successor = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1338
1339 first = 0;
1340 last = size - 1;
1341 middle = (first + last)/2;
1342
1343 while(first <= last)
1344 {
1345 /* all_known_peers[middle] > value*/
1346 if(0 > peer_id_cmp(&all_known_peers[middle], &value))
1347 {
1348 first = middle + 1;
1349 }
1350 else if(0 == peer_id_cmp(&all_known_peers[middle], &value))
1351 {
1352 if(middle == 0)
1353 {
1354 successor = &(all_known_peers[size - 1]);
1355 }
1356 else
1357 successor = &(all_known_peers[middle-1]);
1358 }
1359 else
1360 {
1361 last = middle - 1;
1362 }
1363
1364 middle = (first + last)/2;
1365 }
1366 return successor;
1367}
1368
1369
1370
1371/**
1372 * Find closest successor for the value.
1373 * @param value Value for which we are looking for successor
1374 * @param current_destination NULL if my_identity is successor else finger/friend
1375 * identity
1376 * @param type Next destination type
1377 * @return Peer identity of next destination i.e. successor of value.
1378 */
1379static struct GNUNET_PeerIdentity *
1380find_successor(uint64_t *value, struct GNUNET_PeerIdentity *current_destination,
1258 enum current_destination_type *type) 1381 enum current_destination_type *type)
1259{ 1382{
1260 /* 1. Iterate over friend map and find the closest peer. 1383 /* 1. Create an array and copy all the peer identites from finger_peermap,
1261 2. Iterate over finger map and find the closest peer. 1384 friend_peermap, your own identity and value you are searching.
1262 3. Sort my_identity, friend successor and finger successor. 1385 2. Sort the array.
1263 4. Choose the closest peer among the three. 1386 3. Do a binary search on array to find the location of your value.
1264 */ 1387 4. previous element of the value is your successor.
1388 5. search for the successor in friend/finger/my_identity .
1389 6. if my_identity, then return NULL and set type to my_identity
1390 7. if friend, then return friend->id and set type to friend.
1391 8. if finger, then set current_destination = finger and return the first
1392 element from the trail list of finger as next_hop. */
1265 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter; 1393 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
1266 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; 1394 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1395 struct GNUNET_PeerIdentity key_ret;
1267 struct FriendInfo *friend; 1396 struct FriendInfo *friend;
1268 struct FingerInfo *finger; 1397 struct FingerInfo *finger;
1269 struct GNUNET_PeerIdentity key_ret;
1270 unsigned int finger_index; 1398 unsigned int finger_index;
1271 unsigned int friend_index; 1399 unsigned int friend_index;
1272 struct FriendInfo *successor_friend; 1400 struct GNUNET_PeerIdentity *all_known_peers;
1273 struct FingerInfo *successor_finger; 1401 struct GNUNET_PeerIdentity *successor;
1274 uint64_t friend_id; 1402 unsigned int size;
1275 uint64_t finger_id; 1403 unsigned int j;
1276 uint64_t my_id; 1404 /* SUPU: 2 is added for my_identity and value. */
1277 1405 size = GNUNET_CONTAINER_multipeermap_size (friend_peermap)+
1278 successor_friend = GNUNET_malloc (sizeof (struct FriendInfo )); 1406 GNUNET_CONTAINER_multipeermap_size (finger_peermap)+
1279 successor_finger = GNUNET_malloc (sizeof (struct FingerInfo )); 1407 2;
1280 1408
1281 /* Iterate over friend map. */ 1409 all_known_peers = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * size);
1410
1411 j = 0;
1412 memcpy(&all_known_peers[j], &(my_identity), sizeof (struct GNUNET_PeerIdentity));
1413 j++;
1414 memcpy(&all_known_peers[j], value, sizeof(struct GNUNET_PeerIdentity));
1415
1416 /* Iterate over friend peermap and copy all the elements into array. */
1282 friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); 1417 friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1283 for (friend_index = 0; friend_index < GNUNET_CONTAINER_multipeermap_size (friend_peermap); friend_index++) 1418 for (friend_index = 0; friend_index < GNUNET_CONTAINER_multipeermap_size (friend_peermap); friend_index++)
1284 { 1419 {
1285 /* SUPU: check if you are using iterator_next correctly */ 1420 /* FIXME: I don't think we are actually iterating.
1421 Read about how to iterate over the multipeermap. */
1286 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(friend_iter,&key_ret,(const void **)&friend)) 1422 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(friend_iter,&key_ret,(const void **)&friend))
1287 { 1423 {
1288 if(((friend->interval_start <= id) && (id < friend->interval_end)) 1424 memcpy(&all_known_peers[j], &(friend->id), sizeof (struct GNUNET_PeerIdentity));
1289 || (((friend->interval_start) > (friend->interval_end)) 1425 j++;
1290 && ((friend->interval_start <= id) && (id < friend->interval_end))))
1291 {
1292 /* SUPU: Here I am copying friend into successor_friend as when among
1293 three ids i.e. friend, finger and my_id, one is chosen then I should
1294 be able to identify which one was chosen. */
1295 memcpy(successor_friend, friend, sizeof (struct FriendInfo));
1296 break; /*FIXME: Will it come out of outer for loop */
1297 }
1298 } 1426 }
1299 } 1427 }
1300 1428
1429 /* Iterate over finger map and copy all the entries into all_known_peers array. */
1301 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 1430 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1302 /* iterate over finger map till you reach a peer id such that destination <= peer id */
1303 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++) 1431 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1304 { 1432 {
1433 /* FIXME: I don't think we are actually iterating.
1434 Read about how to iterate over the multi peer map. */
1305 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(finger_iter,&key_ret,(const void **)&finger)) 1435 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(finger_iter,&key_ret,(const void **)&finger))
1306 { 1436 {
1307 if(((finger->interval_start <= id) && (id < finger->interval_end)) 1437 memcpy(&all_known_peers[j], &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
1308 || (((finger->interval_start) > (finger->interval_end)) 1438 j++;
1309 && ((finger->interval_start <= id) && (id < finger->interval_end))))
1310 {
1311 memcpy(successor_finger, finger, sizeof (struct FingerInfo));
1312 break; /*FIXME: Will it come out of outer for loop */
1313 }
1314 } 1439 }
1315 } 1440 }
1316 1441
1317 /* Here you have two values from friend and finger map. 1442 qsort(all_known_peers, size, sizeof (struct GNUNET_PeerIdentity), &peer_id_cmp);
1318 Now sort the my_identity, friend and finger and 1443
1319 choose the closest peer. Also update the closest successor type 1444 /* search value in all_known_peers array. */
1320 correctly to finger/friend/me. and update the current_destination value. */ 1445 successor = binary_search(all_known_peers, value, size);
1321 memcpy (&my_id, &(my_identity.public_key.q_y), sizeof (uint64_t)); 1446
1322 memcpy (&friend_id, (successor_friend->id.public_key.q_y), sizeof (uint64_t)); 1447 /* compare successor with my_identity, finger and friend */
1323 memcpy (&finger_id, (successor_finger->finger_identity.public_key.q_y), sizeof (uint64_t)); 1448 if(0 == GNUNET_CRYPTO_cmp_peer_identity(&(my_identity), successor))
1324 1449 {
1325 /* if finger_id is selected, then set type = FINGER, current_destination = finger 1450 *type = MY_ID;
1326 and next_hop = first peer in trail list. 1451 return NULL;
1327 if friend id is selected, then set type = FRIEND, current_destination = friend 1452 }
1328 and return friend. */ 1453 else if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap,
1329 /* You need some function to compare which three of them is successor to 1454 successor))
1330 id that we are looking for. 1455 {
1331 1. Sort three of them. 1456 *type = FRIEND;
1332 2. Set up the new interval. 1457 memcpy(current_destination, successor, sizeof (struct GNUNET_PeerIdentity));
1333 3. Check in which interval id lies. 1458 return successor;
1334 * You should set the type proprly. Need to add a new type to handle 1459 }
1335 * my_idenity. 1460 else if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (finger_peermap,
1336 This is very suboptimal. 1461 successor))
1337 Once you found the correct successor you should just return the 1462 {
1338 correct PeerIdentity. 1463 *type = FINGER;
1339 so basic logic is: 1464 memcpy(current_destination, successor, sizeof (struct GNUNET_PeerIdentity));
1340 lets say that 1465 /* get the corresponding finger for succcesor and read the first element from
1341 my_id = 3 [3,5) 1466 the trail list and return that element. */
1342 friend_id = 5 [5,7) 1467 struct FingerInfo *successor_finger;
1343 finger_id = 7 [7,3) 1468 struct GNUNET_PeerIdentity *next_hop;
1344 and we are looking for 1. */ 1469 next_hop = GNUNET_malloc(sizeof (struct GNUNET_PeerIdentity));
1345 return &(successor_friend->id); /* FIXME: remove this, added just to remove 1470 successor_finger = GNUNET_malloc (sizeof (struct FingerInfo));
1346 * warning */ 1471 successor_finger = GNUNET_CONTAINER_multipeermap_get (finger_peermap, successor);
1472 memcpy(next_hop, &(successor_finger->trail_peer_list[0]), sizeof (struct GNUNET_PeerIdentity));
1473 return next_hop;
1474 }
1475 return NULL;
1347} 1476}
1348 1477
1349 1478
1350/** 1479/**
1351 * Handle a P2PTrailSetupMessage. 1480 * Handle a PeerTrailSetupMessage.
1352 * @param cls closure 1481 * @param cls closure
1353 * @param message message 1482 * @param message message
1354 * @param peer peer identity this notification is about 1483 * @param peer peer identity this notification is about
@@ -1404,7 +1533,7 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1404 { 1533 {
1405 if(0 == (GNUNET_CRYPTO_cmp_peer_identity(&(trail_setup->current_destination),&my_identity))) 1534 if(0 == (GNUNET_CRYPTO_cmp_peer_identity(&(trail_setup->current_destination),&my_identity)))
1406 { 1535 {
1407 next_hop = find_successor((trail_setup->destination_finger),&(trail_setup->current_destination),&(peer_type)); 1536 next_hop = find_successor(&(trail_setup->destination_finger),&(trail_setup->current_destination),&(peer_type));
1408 } 1537 }
1409 else 1538 else
1410 return GNUNET_SYSERR; /*TODO: Should we handle this case differently? */ 1539 return GNUNET_SYSERR; /*TODO: Should we handle this case differently? */
@@ -1429,7 +1558,7 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1429 In this case, is it safe to assume current_Destination = my_identity. 1558 In this case, is it safe to assume current_Destination = my_identity.
1430 I guess we are sending current_destination so that we update it with new 1559 I guess we are sending current_destination so that we update it with new
1431 current_destination, if could either me, friend or finger.*/ 1560 current_destination, if could either me, friend or finger.*/
1432 next_hop = find_successor((trail_setup->destination_finger),&(trail_setup->current_destination),&(peer_type)); 1561 next_hop = find_successor(&(trail_setup->destination_finger),&(trail_setup->current_destination),&(peer_type));
1433 } 1562 }
1434 } 1563 }
1435 1564
@@ -1457,7 +1586,8 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1457 GDS_NEIGHBOURS_handle_trail_setup_result(&(trail_setup->source_peer), 1586 GDS_NEIGHBOURS_handle_trail_setup_result(&(trail_setup->source_peer),
1458 &(my_identity), 1587 &(my_identity),
1459 target_friend, trail_length, 1588 target_friend, trail_length,
1460 peer_list,current_trail_index); 1589 peer_list,current_trail_index,
1590 trail_setup->successor_flag);
1461 1591
1462 return GNUNET_YES; 1592 return GNUNET_YES;
1463 } 1593 }
@@ -1481,7 +1611,7 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1481 &(trail_setup->destination_finger), 1611 &(trail_setup->destination_finger),
1482 target_friend, 1612 target_friend,
1483 trail_setup->trail_length, 1613 trail_setup->trail_length,
1484 peer_list); 1614 peer_list,trail_setup->successor_flag);
1485return GNUNET_YES; 1615return GNUNET_YES;
1486} 1616}
1487 1617
@@ -1499,24 +1629,19 @@ return GNUNET_YES;
1499static 1629static
1500void finger_table_add(struct GNUNET_PeerIdentity *finger, 1630void finger_table_add(struct GNUNET_PeerIdentity *finger,
1501 const struct GNUNET_PeerIdentity *peer_list, 1631 const struct GNUNET_PeerIdentity *peer_list,
1502 unsigned int trail_length) 1632 unsigned int trail_length,
1633 unsigned int successor_flag)
1503{ 1634{
1635 /*FIXME: okay so there are two fields. one we should remember what finger
1636 identity we were looking for and what successor id we got. */
1504 struct FingerInfo *finger_entry; 1637 struct FingerInfo *finger_entry;
1505 finger_entry = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); 1638 finger_entry = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
1506 memcpy(&(finger_entry->finger_identity), finger, sizeof(struct GNUNET_PeerIdentity)); 1639 memcpy(&(finger_entry->finger_identity), finger, sizeof(struct GNUNET_PeerIdentity));
1507 memcpy(&(finger_entry->trail_peer_list), peer_list, sizeof(struct GNUNET_PeerIdentity) 1640 memcpy(&(finger_entry->trail_peer_list), peer_list, sizeof(struct GNUNET_PeerIdentity)
1508 * trail_length); 1641 * trail_length);
1509 /*FIXME: When you add an entry into your finger table, then 1642 finger_entry->successor = successor_flag;
1510 you should add it in sorted way. Also, once sorted update the finger table
1511 entry. As we will be using sorting and updating the interval in finger and friend
1512 table and also in find_successor, we need this functionality see if you can
1513 define a common function which can be used in all the three functions.
1514 Also, you should then insert that entry into your finger_peermap.
1515 It seems to be too much of complexity but I need a working copy but i will
1516 ask bart first. */
1517
1518 if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap)) 1643 if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap))
1519 verify_immediate_successor = GNUNET_SCHEDULER_add_now (&stabilize, NULL); 1644 verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL);
1520} 1645}
1521 1646
1522 1647
@@ -1566,7 +1691,7 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
1566 /* Am I the destination? */ 1691 /* Am I the destination? */
1567 if( 0 == (GNUNET_CRYPTO_cmp_peer_identity(&(trail_result->destination_peer), &my_identity))) 1692 if( 0 == (GNUNET_CRYPTO_cmp_peer_identity(&(trail_result->destination_peer), &my_identity)))
1568 { 1693 {
1569 finger_table_add(&(trail_result->finger), trail_peer_list,trail_length); 1694 finger_table_add(&(trail_result->finger), trail_peer_list,trail_length,trail_result->successor_flag);
1570 return GNUNET_YES; 1695 return GNUNET_YES;
1571 } 1696 }
1572 else 1697 else
@@ -1579,7 +1704,8 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
1579 GDS_NEIGHBOURS_handle_trail_setup_result(&(trail_result->destination_peer), 1704 GDS_NEIGHBOURS_handle_trail_setup_result(&(trail_result->destination_peer),
1580 &(trail_result->finger), 1705 &(trail_result->finger),
1581 target_friend, trail_length, 1706 target_friend, trail_length,
1582 trail_peer_list,current_trail_index); 1707 trail_peer_list,current_trail_index,
1708 trail_result->successor_flag);
1583 return GNUNET_YES; 1709 return GNUNET_YES;
1584 } 1710 }
1585 } 1711 }
@@ -1612,7 +1738,7 @@ handle_dht_p2p_verify_successor()
1612 * @return GNUNET_OK on success, GNUNET_SYSERR on error 1738 * @return GNUNET_OK on success, GNUNET_SYSERR on error
1613 */ 1739 */
1614static int 1740static int
1615handle_dht_p2p_notify_successor() 1741handle_dht_p2p_notify_new_successor()
1616{ 1742{
1617 /* 1743 /*
1618 * So, if you are the destination you should update your 1744 * So, if you are the destination you should update your
@@ -1656,7 +1782,7 @@ GDS_NEIGHBOURS_init()
1656 {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0}, 1782 {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
1657 {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0}, 1783 {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
1658 {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0}, 1784 {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
1659 {&handle_dht_p2p_notify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_SUCCESSOR, 0}, 1785 {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
1660 {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0}, 1786 {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
1661 {NULL, 0, 0} 1787 {NULL, 0, 0}
1662 }; 1788 };
@@ -1709,10 +1835,10 @@ GDS_NEIGHBOURS_done ()
1709 1835
1710 /* FIXME: fix_fingers will also be a task like this. 1836 /* FIXME: fix_fingers will also be a task like this.
1711 Add it later. */ 1837 Add it later. */
1712 if (GNUNET_SCHEDULER_NO_TASK != verify_immediate_successor) 1838 if (GNUNET_SCHEDULER_NO_TASK != verify_successor)
1713 { 1839 {
1714 GNUNET_SCHEDULER_cancel (verify_immediate_successor); 1840 GNUNET_SCHEDULER_cancel (verify_successor);
1715 verify_immediate_successor = GNUNET_SCHEDULER_NO_TASK; 1841 verify_successor = GNUNET_SCHEDULER_NO_TASK;
1716 } 1842 }
1717 1843
1718} 1844}