aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-05-16 10:40:30 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-05-16 10:40:30 +0000
commita523a1d723acb1544bf2066dbe63fe5e2a07f71b (patch)
tree473f70a706b3ba981b29ea608a5e163b4c48ab47 /src/dht
parent4932af68493bdb0f8ea88703c838a9c3d653d467 (diff)
downloadgnunet-a523a1d723acb1544bf2066dbe63fe5e2a07f71b.tar.gz
gnunet-a523a1d723acb1544bf2066dbe63fe5e2a07f71b.zip
Bug fix
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-xdht_clients.c2
-rw-r--r--src/dht/gnunet-service-xdht_datacache.c9
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c313
-rw-r--r--src/dht/gnunet-service-xdht_routing.c2
-rw-r--r--src/dht/gnunet-service-xdht_routing.h22
5 files changed, 234 insertions, 114 deletions
diff --git a/src/dht/gnunet-service-xdht_clients.c b/src/dht/gnunet-service-xdht_clients.c
index 3da483ae7..566e19ae4 100644
--- a/src/dht/gnunet-service-xdht_clients.c
+++ b/src/dht/gnunet-service-xdht_clients.c
@@ -1018,7 +1018,7 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client,
1018 "Received GET request for %s from local client %p, xq: %.*s\n", 1018 "Received GET request for %s from local client %p, xq: %.*s\n",
1019 GNUNET_h2s (&get->key), client, xquery_size, xquery); 1019 GNUNET_h2s (&get->key), client, xquery_size, xquery);
1020 1020
1021 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "R5N CLIENT-GET %s\n", 1021 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "X-VINE CLIENT-GET %s\n",
1022 GNUNET_h2s_full (&get->key)); 1022 GNUNET_h2s_full (&get->key));
1023 1023
1024 1024
diff --git a/src/dht/gnunet-service-xdht_datacache.c b/src/dht/gnunet-service-xdht_datacache.c
index b679f28a6..a63f7efba 100644
--- a/src/dht/gnunet-service-xdht_datacache.c
+++ b/src/dht/gnunet-service-xdht_datacache.c
@@ -188,9 +188,9 @@ static int
188datacache_get_iterator (void *cls, 188datacache_get_iterator (void *cls,
189 const struct GNUNET_HashCode * key, size_t size, 189 const struct GNUNET_HashCode * key, size_t size,
190 const char *data, enum GNUNET_BLOCK_Type type, 190 const char *data, enum GNUNET_BLOCK_Type type,
191 struct GNUNET_TIME_Absolute exp, 191 struct GNUNET_TIME_Absolute exp,
192 unsigned int put_path_length, 192 unsigned int put_path_length,
193 const struct GNUNET_PeerIdentity *put_path) 193 const struct GNUNET_PeerIdentity *put_path)
194{ 194{
195 struct GetRequestContext *ctx = cls; 195 struct GetRequestContext *ctx = cls;
196 enum GNUNET_BLOCK_EvaluationResult eval; 196 enum GNUNET_BLOCK_EvaluationResult eval;
@@ -310,6 +310,7 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key,
310 310
311 /* FIXME: add the get path into ctx and then call gds_neighbours_handle_get*/ 311 /* FIXME: add the get path into ctx and then call gds_neighbours_handle_get*/
312 int i = 0; 312 int i = 0;
313
313 if(get_path != NULL) 314 if(get_path != NULL)
314 { 315 {
315 while (i < get_path_length) 316 while (i < get_path_length)
@@ -320,7 +321,7 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key,
320 element->prev = NULL; 321 element->prev = NULL;
321 322
322 memcpy (&(element->peer), &get_path[i], sizeof(struct GNUNET_PeerIdentity)); 323 memcpy (&(element->peer), &get_path[i], sizeof(struct GNUNET_PeerIdentity));
323 GNUNET_CONTAINER_DLL_insert_tail(ctx.head, ctx.tail, element); 324 GNUNET_CONTAINER_DLL_insert_tail (ctx.head, ctx.tail, element); /* FIXME: changed from insert_tail to insert. */
324 i++; 325 i++;
325 } 326 }
326 } 327 }
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index f56abf093..4b3abd7d2 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -558,6 +558,7 @@ struct TrailPeerList
558 558
559 559
560/** 560/**
561 * FIXME: for congested peer just define a relative time as #define.
561 * Entry in friend_peermap. 562 * Entry in friend_peermap.
562 */ 563 */
563struct FriendInfo 564struct FriendInfo
@@ -568,22 +569,7 @@ struct FriendInfo
568 struct GNUNET_PeerIdentity id; 569 struct GNUNET_PeerIdentity id;
569 570
570 /** 571 /**
571 * 1. used in select_random_friend(), in case the friend has trails_count > TRAILS_THROUGH_FRIEND, 572 * Number of trails for which this friend is the first hop.
572 * then choose another friend.
573 * 2. in case of find_successor(), if the number of trails going through the friend
574 * has already crossed, then choose another friend.
575 * 3. in case of find_successor(), if we choose a finger, and if friend through
576 * which we reach this finger has crossed the limit then choose another finger/friend.
577 * 4. One way to implement in case of find_successor, is 1) you can have a global
578 * array of the entries and only when an entry is added in finger table, friend table,
579 * then you re calculate the array. In array while adding the element you check
580 * the threshold of the friend in case its friend, and in case of finger check
581 * the threshold of the first friend in the trail. If crossed then don't add the
582 * entries in the array. When the count goes down, then again set a flag and
583 * recalculte the array. Store a field in Finger table also, which will be
584 * equal to number of trails going through the first friend.
585 * Number of trail of which this friend is the first hop.
586 * 5.FIXME: understand where you need to use memcpy or direct assignment.
587 */ 573 */
588 unsigned int trails_count; 574 unsigned int trails_count;
589 575
@@ -602,6 +588,7 @@ struct FriendInfo
602 * struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get(); 588 * struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();
603 * struct GNUNET_TIME_Relative congestion_timeout = 589 * struct GNUNET_TIME_Relative congestion_timeout =
604 * congestion_duration = GNUNET_TIME_absolute_add (start,congestion_timeout); 590 * congestion_duration = GNUNET_TIME_absolute_add (start,congestion_timeout);
591 * in select_random_friend, GNUNET_TIME_absolute_get_remaning()
605 */ 592 */
606 struct GNUNET_TIME_Absolute congestion_duration; 593 struct GNUNET_TIME_Absolute congestion_duration;
607 594
@@ -624,6 +611,8 @@ struct FriendInfo
624 611
625 612
626/** 613/**
614 * FIXME: make an array of trails. #define number of entries in the array =
615 * number of trails we want to keep. Remove head, tail of trails.
627 * Entry in finger_peermap. 616 * Entry in finger_peermap.
628 */ 617 */
629struct FingerInfo 618struct FingerInfo
@@ -763,13 +752,6 @@ static struct GNUNET_CORE_Handle *core_api;
763#define TRAIL_COUNT 2 752#define TRAIL_COUNT 2
764 753
765/** 754/**
766 * FIXME: better name.
767 * Set to GNUNET_YES, when the number of trails going through all my friends
768 * have reached the TRAIL_THROUGH_FRIEND_THRESHOLD.
769 */
770static unsigned int all_friends_trail_threshold;
771
772/**
773 * The current finger index that we have want to find trail to. 755 * The current finger index that we have want to find trail to.
774 */ 756 */
775static unsigned int current_search_finger_index; 757static unsigned int current_search_finger_index;
@@ -1020,14 +1002,13 @@ process_friend_queue (struct FriendInfo *peer)
1020 1002
1021 1003
1022/** 1004/**
1023 * Construct a trail message and forward it to a friend. 1005 * Construct a trail setup message and forward it to a friend.
1024 * @param source_peer Peer which wants to set up the trail to one of its finger. 1006 * @param source_peer Peer which wants to set up the trail to one of its finger.
1025 * @param destination_finger Peer identity closest to this value will be 1007 * @param destination_finger Peer identity closest to this value will be
1026 * @a source_peer's finger. 1008 * @a source_peer's finger.
1027 * @param current_destination Finger of the @a current_source, for which among 1009 * @param current_destination next destination corresponding to @a current_source,
1028 * its friends, its own identity and all fingers, this 1010 * can be either a finger or a friend of @a current_source.
1029 * finger is the closest to the @a destination_finger 1011 * @param current_source Peer for which @a current_destination is its finger/friend.
1030 * @param current_source Peer for which @a current_destination is its finger.
1031 * @param target_friend Friend to which this message should be forwarded. 1012 * @param target_friend Friend to which this message should be forwarded.
1032 * @param trail_length Numbers of peers in the trail found so far. 1013 * @param trail_length Numbers of peers in the trail found so far.
1033 * @param trail_peer_list Peers this request has traversed so far 1014 * @param trail_peer_list Peers this request has traversed so far
@@ -1085,7 +1066,6 @@ GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer,
1085 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); 1066 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1086 target_friend->pending_count++; 1067 target_friend->pending_count++;
1087 process_friend_queue (target_friend); 1068 process_friend_queue (target_friend);
1088
1089} 1069}
1090 1070
1091 1071
@@ -1386,13 +1366,64 @@ GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_PeerIdentity *source_pee
1386} 1366}
1387 1367
1388 1368
1369/**
1370 * FIXME: call GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1371 * In case the friend chosen in select_random_friend() is congested or
1372 * has crossed trail_threshold, then get next friend which is not congested or
1373 * has not crossed trail threshold from friend peermap.
1374 * @param current_index Index in finger peermap chosen randomly
1375 * @param friend_peermap_size Total number of entries in friend peermap.
1376 * @param count Total number of time this function has been called, in case
1377 * count == sizeof(friend_peermap) - 1, it means none of the friends are free.
1378 * @return Friend Friend found.
1379 * NULL in case all the friends are congested or have crossed trail threshold.
1380 */
1381static struct FriendInfo *
1382get_next_friend (unsigned int current_index,
1383 unsigned int friend_peermap_size,
1384 unsigned int count)
1385{
1386 struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1387 struct GNUNET_PeerIdentity key_ret;
1388 struct FriendInfo *friend;
1389 int j = 0;
1390
1391 current_index = (current_index + 1) % friend_peermap_size;
1392 iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1393 while(j < (current_index))
1394 {
1395 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
1396 {
1397 j++;
1398 }
1399 else
1400 return NULL;
1401 }
1402
1403 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1404 {
1405 if ((friend->trails_count > TRAIL_THROUGH_FRIEND_THRESHOLD) ||
1406 (0 != GNUNET_TIME_absolute_get_remaining (friend->congestion_duration).rel_value_us))
1407 {
1408 count++;
1409 if (count == (friend_peermap_size -1))
1410 return NULL;
1411 else
1412 return get_next_friend (j,friend_peermap_size,count);
1413 }
1414 return friend;
1415 }
1416 else
1417 return NULL;
1418}
1419
1420
1389/** 1421/**
1390 * FIMXE: Change the return value, to handle the case where all friends 1422 * FIXME: call GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1391 * are congested.
1392 * FIXME: Handle congested peer - don't choose this friend, also don't choose
1393 * the friend if the link threshold has crossed. Not implemented yet.
1394 * Randomly choose one of your friends from the friends_peer map 1423 * Randomly choose one of your friends from the friends_peer map
1395 * @return Friend 1424 * @return Friend Randomly chosen friend.
1425 * NULL in case friend peermap is empty, or all the friends are either
1426 * congested or have crossed trail threshold.
1396 */ 1427 */
1397static struct FriendInfo * 1428static struct FriendInfo *
1398select_random_friend () 1429select_random_friend ()
@@ -1405,6 +1436,9 @@ select_random_friend ()
1405 struct FriendInfo *friend; 1436 struct FriendInfo *friend;
1406 1437
1407 current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap); 1438 current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
1439 if (0 == current_size)
1440 return NULL;
1441
1408 index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size); 1442 index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1409 iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); 1443 iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1410 1444
@@ -1415,22 +1449,18 @@ select_random_friend ()
1415 j++; 1449 j++;
1416 } 1450 }
1417 else 1451 else
1452 {
1418 return NULL; 1453 return NULL;
1454 }
1419 } 1455 }
1420 1456
1421 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend)) 1457 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1422 { 1458 {
1423 /* Possible number of trails that can go through this friend has been reached. */ 1459 if ((TRAIL_THROUGH_FRIEND_THRESHOLD == friend->trails_count) ||
1424 if (friend->trails_count > TRAIL_THROUGH_FRIEND_THRESHOLD) 1460 (0 != GNUNET_TIME_absolute_get_remaining (friend->congestion_duration).rel_value_us))
1425 { 1461 {
1426 /* FIXME: What should I do now, should I call this same function again and 1462 return get_next_friend (*index, current_size, 1);
1427 remember the index, j so that call random function without j and find 1463 }
1428 a new friend. Also, I need some way to make sure that if number of times
1429 I have called the function is equal to number of entries in friend peermap.
1430 then I should return NULL. but its much better to have a function which
1431 just eliminates looking at the entries with threshold crossed. URGENT: Whats
1432 the best way to handle this case? */
1433 }
1434 return friend; 1464 return friend;
1435 } 1465 }
1436 else 1466 else
@@ -1513,10 +1543,10 @@ send_verify_successor_message()
1513 int i = 0; 1543 int i = 0;
1514 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->first_trail_length); 1544 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->first_trail_length);
1515 iterate = finger->first_trail_head; 1545 iterate = finger->first_trail_head;
1516 1546
1547 /* FIXME: SEGMENTATION FAULT. */
1517 while ( i < (finger->first_trail_length)) 1548 while ( i < (finger->first_trail_length))
1518 { 1549 {
1519
1520 memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity)); 1550 memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity));
1521 iterate = iterate->next; 1551 iterate = iterate->next;
1522 i++; 1552 i++;
@@ -1541,11 +1571,6 @@ send_verify_successor_message()
1541 1571
1542 1572
1543/** 1573/**
1544 * FIXME:
1545 * 1. Need to handle the case where all friends are either congested or
1546 * have reached their threshold.
1547 * 2. If we need all_friends_trail_threshold
1548 * 3. do we need to check if friend peermap is empty or not.
1549 * Choose a random friend and start looking for the trail to reach to 1574 * Choose a random friend and start looking for the trail to reach to
1550 * finger identity through this random friend. 1575 * finger identity through this random friend.
1551 * 1576 *
@@ -1569,17 +1594,9 @@ send_find_finger_trail_message (void *cls,
1569 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message, 1594 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1570 NULL); 1595 NULL);
1571 1596
1572 if (GNUNET_YES == all_friends_trail_threshold)
1573 {
1574 /* All friends in friend peer map, have reached their trail threshold. No
1575 more new trail can be created. */
1576 return;
1577 }
1578
1579 target_friend = select_random_friend (); 1597 target_friend = select_random_friend ();
1580 if (NULL == target_friend) 1598 if (NULL == target_friend) /* Either all the friends are congested or reached trail threshold. */
1581 { 1599 {
1582 all_friends_trail_threshold = GNUNET_YES;
1583 return; 1600 return;
1584 } 1601 }
1585 1602
@@ -1637,6 +1654,7 @@ scan_and_compress_trail (struct GNUNET_PeerIdentity *trail,
1637 } 1654 }
1638 1655
1639 i = *trail_length - 1; 1656 i = *trail_length - 1;
1657
1640 while (i > 1) 1658 while (i > 1)
1641 { 1659 {
1642 if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[i])) 1660 if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[i]))
@@ -1656,7 +1674,7 @@ scan_and_compress_trail (struct GNUNET_PeerIdentity *trail,
1656 struct FriendInfo *target_friend; 1674 struct FriendInfo *target_friend;
1657 int discarded_trail_length; 1675 int discarded_trail_length;
1658 int j = 0; 1676 int j = 0;
1659 1677
1660 discarded_trail_length = i - 1; 1678 discarded_trail_length = i - 1;
1661 discarded_trail = GNUNET_malloc (discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)); 1679 discarded_trail = GNUNET_malloc (discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1662 memcpy (discarded_trail, trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)); 1680 memcpy (discarded_trail, trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
@@ -1731,6 +1749,7 @@ void send_trail_teardown (struct FingerInfo *removed_finger)
1731 1749
1732 if (removed_finger->first_trail_length == 0) 1750 if (removed_finger->first_trail_length == 0)
1733 return; 1751 return;
1752
1734 finger_trail = removed_finger->first_trail_head; 1753 finger_trail = removed_finger->first_trail_head;
1735 friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer)); 1754 friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer));
1736 peer_list = GNUNET_malloc ( removed_finger_trail_length * sizeof (struct GNUNET_PeerIdentity)); 1755 peer_list = GNUNET_malloc ( removed_finger_trail_length * sizeof (struct GNUNET_PeerIdentity));
@@ -2126,7 +2145,10 @@ compare_and_update_predecessor (const struct GNUNET_PeerIdentity *peer,
2126 } 2145 }
2127 } 2146 }
2128 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); 2147 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2129 if(GNUNET_NO == old_entry_found) 2148
2149 /* FIXME: in case predecessor is my friend what ? */
2150 if((GNUNET_NO == old_entry_found)
2151 && (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity,peer)))
2130 { 2152 {
2131 trail_length = 0; 2153 trail_length = 0;
2132 trail = NULL; 2154 trail = NULL;
@@ -2137,25 +2159,9 @@ compare_and_update_predecessor (const struct GNUNET_PeerIdentity *peer,
2137 new_finger_entry->finger_map_index = PREDECESSOR_FINGER_ID; 2159 new_finger_entry->finger_map_index = PREDECESSOR_FINGER_ID;
2138 new_finger_entry->first_trail_length = trail_length; 2160 new_finger_entry->first_trail_length = trail_length;
2139 new_finger_entry->trail_count = 1; 2161 new_finger_entry->trail_count = 1;
2140 2162
2141 if (0 != GNUNET_CRYPTO_cmp_peer_identity(&my_identity,peer)) /* finger_trail is NULL in case I am my own finger identity. */ 2163 if (0 != GNUNET_CRYPTO_cmp_peer_identity(&my_identity,peer)) /* finger_trail is NULL in case I am my own finger identity. */
2142 { 2164 {
2143 /* FIXME: Currently we are not handling the second trail. In that case, finger
2144 trail count = min (first_friend, second_friend) trail count. */
2145 /* Incrementing the friend trails count. */
2146 if (trail_length > 0)
2147 {
2148 first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[0]);
2149 first_friend_trail->trails_count++;
2150 }
2151 else
2152 {
2153 /* It means the finger is my friend. */
2154 first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
2155 first_friend_trail->trails_count++;
2156 }
2157 new_finger_entry->first_friend_trails_count = first_friend_trail->trails_count;
2158
2159 /* Invert the trail and then add. */ 2165 /* Invert the trail and then add. */
2160 if (trail_length != 0) 2166 if (trail_length != 0)
2161 { 2167 {
@@ -2177,6 +2183,22 @@ compare_and_update_predecessor (const struct GNUNET_PeerIdentity *peer,
2177 element->prev = NULL; 2183 element->prev = NULL;
2178 memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity)); 2184 memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
2179 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->first_trail_head, new_finger_entry->first_trail_tail, element); 2185 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->first_trail_head, new_finger_entry->first_trail_tail, element);
2186
2187 /* FIXME: Currently we are not handling the second trail. In that case, finger
2188 trail count = min (first_friend, second_friend) trail count. */
2189 /* Incrementing the friend trails count. */
2190 if (trail_length > 0)
2191 {
2192 first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[0]);
2193 first_friend_trail->trails_count++;
2194 }
2195 else
2196 {
2197 /* It means the finger is my friend. */
2198 first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
2199 first_friend_trail->trails_count++;
2200 }
2201 new_finger_entry->first_friend_trails_count = first_friend_trail->trails_count;
2180 } 2202 }
2181 } 2203 }
2182 GNUNET_assert (GNUNET_OK == 2204 GNUNET_assert (GNUNET_OK ==
@@ -2392,7 +2414,62 @@ int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2392 2414
2393 return new_entry_added; 2415 return new_entry_added;
2394} 2416}
2395 2417
2418
2419/**
2420 *
2421 * @param all_known_peers
2422 * @param array_size
2423 * @param friend
2424 * @param key_value
2425 * @return
2426 */
2427static struct Sorting_List *
2428get_next_successor (struct Sorting_List *all_known_peers,
2429 unsigned int array_size,
2430 struct FriendInfo *friend,
2431 uint64_t key_value)
2432{
2433 /* 1. search friend in all_known_peers.
2434 2. get the next peer. if peer == my_identity or peer == value, then go to
2435 next element.
2436 3. if friend then again check if threshold crossed or not . If not then return
2437 or else again increment. remember starting index of friend in all_known_peers
2438 and when you reach to it again then return NULL as it means all the friend
2439 are congested or threshold reached.
2440 */
2441 return NULL;
2442}
2443
2444
2445/**
2446 * Check if the friend is congested or has crossed TRAIL_THRESHOLD. If yes
2447 * then choose the peer next to it in the array. In case number of times this
2448 * function is called is equal to total number of entries in the array then it
2449 * means that none of the friends are busy. But remember in this array you also
2450 * have your own identity, value that you were searching, You should skip those
2451 * and also keep the count = size -2. But if we call in this order is our get/put
2452 * not getting wrong.
2453 * @param all_known_peers
2454 * @param array_size
2455 * @param friend Friend to be checked if
2456 * @param key_value To be ignored
2457 * @return #GNUNET_YES
2458 * #GNUNET_NO
2459 */
2460static int
2461check_friend_threshold_and_congestion (struct Sorting_List *all_known_peers,
2462 unsigned int array_size,
2463 struct FriendInfo *friend,
2464 uint64_t key_value)
2465{
2466 if (friend->trails_count == TRAIL_THROUGH_FRIEND_THRESHOLD)
2467 {
2468 return GNUNET_YES;
2469 }
2470 return GNUNET_NO;
2471}
2472
2396 2473
2397/** 2474/**
2398 * FIXME: In case a friend is either congested or has crossed its trail threshold, 2475 * FIXME: In case a friend is either congested or has crossed its trail threshold,
@@ -2494,6 +2571,10 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2494 { 2571 {
2495 struct FriendInfo *target_friend; 2572 struct FriendInfo *target_friend;
2496 target_friend = (struct FriendInfo *)successor->data; 2573 target_friend = (struct FriendInfo *)successor->data;
2574 if( GNUNET_YES == check_friend_threshold_and_congestion (all_known_peers, size, target_friend, value))
2575 {
2576 get_next_successor (all_known_peers, size, friend, value);
2577 }
2497 memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity)); 2578 memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
2498 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity)); 2579 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2499 return current_destination; 2580 return current_destination;
@@ -2587,8 +2668,7 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
2587 2668
2588 memcpy (&key_value, key, sizeof (uint64_t)); 2669 memcpy (&key_value, key, sizeof (uint64_t));
2589 next_hop = find_successor (key_value, &current_destination, &current_source); 2670 next_hop = find_successor (key_value, &current_destination, &current_source);
2590 2671 if (0 == GNUNET_CRYPTO_cmp_peer_identity(next_hop, &my_identity)) /* I am the destination do datacache_put */
2591 if (0 == GNUNET_CRYPTO_cmp_peer_identity(next_hop, &current_destination)) /* I am the destination do datacache_put */
2592 { 2672 {
2593 GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path, 2673 GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path,
2594 block_type, data_size, data); 2674 block_type, data_size, data);
@@ -2678,7 +2758,6 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
2678 memcpy (&key_value, key, sizeof (uint64_t)); 2758 memcpy (&key_value, key, sizeof (uint64_t));
2679 // FIXME: endianess of key_value!? 2759 // FIXME: endianess of key_value!?
2680 next_hop = find_successor (key_value, &current_destination, &current_source); 2760 next_hop = find_successor (key_value, &current_destination, &current_source);
2681
2682 if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity,next_hop)) /* I am the destination do datacache_put */ 2761 if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity,next_hop)) /* I am the destination do datacache_put */
2683 { 2762 {
2684 GDS_DATACACHE_handle_get (key,block_type, NULL, 0, 2763 GDS_DATACACHE_handle_get (key,block_type, NULL, 0,
@@ -2757,11 +2836,15 @@ GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration,
2757 return; 2836 return;
2758 } 2837 }
2759 2838
2760 current_path_index = search_my_index(get_path, get_path_length); 2839 if(get_path_length > 0)
2761 if (GNUNET_SYSERR == current_path_index)
2762 { 2840 {
2763 GNUNET_break (0); 2841 current_path_index = search_my_index(get_path, get_path_length);
2764 return; 2842 if (GNUNET_SYSERR == current_path_index)
2843 {
2844 /* FIXME: This assertion always fails. FIX IT. */
2845 GNUNET_break (0);
2846 return;
2847 }
2765 } 2848 }
2766 if (0 == current_path_index) 2849 if (0 == current_path_index)
2767 { 2850 {
@@ -3009,7 +3092,6 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
3009 &put->key, 3092 &put->key,
3010 payload, 3093 payload,
3011 payload_size); 3094 payload_size);
3012
3013 GDS_NEIGHBOURS_send_put (&put->key, payload, payload_size, 3095 GDS_NEIGHBOURS_send_put (&put->key, payload, payload_size,
3014 ntohl (put->block_type),ntohl (put->options), 3096 ntohl (put->block_type),ntohl (put->options),
3015 ntohl (put->desired_replication_level), 3097 ntohl (put->desired_replication_level),
@@ -3099,7 +3181,6 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
3099 memcpy (&final_get_path[get_length+1], &my_identity, sizeof (struct GNUNET_PeerIdentity)); 3181 memcpy (&final_get_path[get_length+1], &my_identity, sizeof (struct GNUNET_PeerIdentity));
3100 get_length = get_length + 1; 3182 get_length = get_length + 1;
3101 memcpy (&next_hop, &final_get_path[get_length-2], sizeof (struct GNUNET_PeerIdentity)); 3183 memcpy (&next_hop, &final_get_path[get_length-2], sizeof (struct GNUNET_PeerIdentity));
3102
3103 GDS_DATACACHE_handle_get (&(get->key),(get->block_type), NULL, 0, NULL, 0, 3184 GDS_DATACACHE_handle_get (&(get->key),(get->block_type), NULL, 0, NULL, 0,
3104 get_length, final_get_path,&next_hop, &my_identity); 3185 get_length, final_get_path,&next_hop, &my_identity);
3105 3186
@@ -3178,7 +3259,6 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
3178 3259
3179 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(get_path[0])))) 3260 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(get_path[0]))))
3180 { 3261 {
3181 //GDS_CLIENTS_process_get_result();
3182 GDS_CLIENTS_handle_reply (get_result->expiration_time, &(get_result->key), 3262 GDS_CLIENTS_handle_reply (get_result->expiration_time, &(get_result->key),
3183 getlen, get_path, putlen, 3263 getlen, get_path, putlen,
3184 put_path, get_result->type, payload_size, payload); 3264 put_path, get_result->type, payload_size, payload);
@@ -3757,15 +3837,18 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
3757 GNUNET_break_op (0); 3837 GNUNET_break_op (0);
3758 return GNUNET_YES; 3838 return GNUNET_YES;
3759 } 3839 }
3760 3840 if( trail_length > 1)
3761 trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1]; 3841 {
3842 trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
3843 }
3762 3844
3763 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity))) 3845 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity)))
3764 { 3846 {
3765 /* I am the new successor. */ 3847 /* I am the new successor. */
3766 struct GNUNET_PeerIdentity new_predecessor; 3848 struct GNUNET_PeerIdentity *new_predecessor;
3767 memcpy (&new_predecessor, &(nsm->source_peer), sizeof (struct GNUNET_PeerIdentity)); 3849 new_predecessor = GNUNET_new (struct GNUNET_PeerIdentity);
3768 if (GNUNET_NO == compare_and_update_predecessor (&new_predecessor, trail_peer_list, 3850 memcpy (new_predecessor, &(nsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
3851 if (GNUNET_NO == compare_and_update_predecessor (new_predecessor, trail_peer_list,
3769 trail_length)) 3852 trail_length))
3770 { 3853 {
3771 /* Someone claims to be my predecessor but its not closest predecessor 3854 /* Someone claims to be my predecessor but its not closest predecessor
@@ -3781,9 +3864,13 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
3781 struct GNUNET_PeerIdentity next_hop; 3864 struct GNUNET_PeerIdentity next_hop;
3782 int my_index; 3865 int my_index;
3783 3866
3867 if (trail_length == 0)
3868 return GNUNET_SYSERR;
3869
3784 my_index = search_my_index (trail_peer_list, trail_length); 3870 my_index = search_my_index (trail_peer_list, trail_length);
3785 if (GNUNET_SYSERR == my_index) 3871 if (GNUNET_SYSERR == my_index)
3786 { 3872 {
3873 /* FIXME: happend once */
3787 GNUNET_break(0); 3874 GNUNET_break(0);
3788 return GNUNET_SYSERR; 3875 return GNUNET_SYSERR;
3789 } 3876 }
@@ -4036,14 +4123,24 @@ int handle_dht_p2p_trail_teardown(void *cls, const struct GNUNET_PeerIdentity *p
4036 /* FIXME: 4123 /* FIXME:
4037 * I am the new first hop in the trail to reach from source to destination. 4124 * I am the new first hop in the trail to reach from source to destination.
4038 Update the trail in routing table with prev_hop == source peer. */ 4125 Update the trail in routing table with prev_hop == source peer. */
4126 return GDS_ROUTING_trail_update (&(trail_teardown->source_peer),
4127 &(trail_teardown->destination_peer), peer);
4039 } 4128 }
4040 } 4129 }
4041 else 4130 else
4042 { 4131 {
4043 my_index = search_my_index (discarded_trail, discarded_trail_length); 4132 /* This should always be the case. */
4044 if(GNUNET_SYSERR == my_index) 4133 if (discarded_trail_length > 0)
4134 {
4135 my_index = search_my_index (discarded_trail, discarded_trail_length);
4136 if(GNUNET_SYSERR == my_index)
4137 return GNUNET_SYSERR;
4138 }
4139 else
4140 {
4141 GNUNET_break (0);
4045 return GNUNET_SYSERR; 4142 return GNUNET_SYSERR;
4046 4143 }
4047 GDS_ROUTING_print(); 4144 GDS_ROUTING_print();
4048 if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer), 4145 if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer),
4049 &(trail_teardown->destination_peer),peer)) 4146 &(trail_teardown->destination_peer),peer))
@@ -4054,8 +4151,14 @@ int handle_dht_p2p_trail_teardown(void *cls, const struct GNUNET_PeerIdentity *p
4054 return GNUNET_YES; 4151 return GNUNET_YES;
4055 } 4152 }
4056 4153
4057 memcpy (&next_hop, &discarded_trail[my_index + 1], sizeof (struct GNUNET_PeerIdentity)); 4154 /* In case we got this message when we removed an entry from finger table,
4155 then we need to send the message to destination. */
4156 if (my_index != (discarded_trail_length - 1))
4157 memcpy (&next_hop, &discarded_trail[my_index + 1], sizeof (struct GNUNET_PeerIdentity));
4158 else
4159 memcpy (&next_hop, &(trail_teardown->destination_peer), sizeof (struct GNUNET_PeerIdentity));
4058 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 4160 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4161
4059 GDS_NEIGHBOURS_send_trail_teardown (&(trail_teardown->source_peer), 4162 GDS_NEIGHBOURS_send_trail_teardown (&(trail_teardown->source_peer),
4060 &(trail_teardown->destination_peer), 4163 &(trail_teardown->destination_peer),
4061 discarded_trail, discarded_trail_length, 4164 discarded_trail, discarded_trail_length,
@@ -4067,6 +4170,7 @@ int handle_dht_p2p_trail_teardown(void *cls, const struct GNUNET_PeerIdentity *p
4067 4170
4068 4171
4069/** 4172/**
4173 * FIXME: always gives segmentation fault.
4070 * Iterate over finger_peermap, and remove entries with peer as the first element 4174 * Iterate over finger_peermap, and remove entries with peer as the first element
4071 * of their trail. 4175 * of their trail.
4072 * @param cls closure 4176 * @param cls closure
@@ -4241,8 +4345,7 @@ GDS_NEIGHBOURS_init (void)
4241 4345
4242 friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); 4346 friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
4243 finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO); 4347 finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO);
4244 all_friends_trail_threshold = GNUNET_NO; 4348
4245
4246 return GNUNET_OK; 4349 return GNUNET_OK;
4247} 4350}
4248 4351
@@ -4267,12 +4370,6 @@ GDS_NEIGHBOURS_done (void)
4267 GNUNET_CONTAINER_multipeermap_destroy (finger_peermap); 4370 GNUNET_CONTAINER_multipeermap_destroy (finger_peermap);
4268 finger_peermap = NULL; 4371 finger_peermap = NULL;
4269 4372
4270 /* FIXME: Here I have added GNUNET_break(0) as ideally if friend_peermap
4271 is already zero, then we really don't need to cancel it again. If this
4272 condition happens it mean we might have missed some corner case. But we
4273 cancel the task only in handle_core_disconnect. it may happen that this
4274 function is called but not handle_core_disconnect, In that case GNUNET_break(0)
4275 is not needed. */
4276 if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task) 4373 if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
4277 { 4374 {
4278 GNUNET_break (0); 4375 GNUNET_break (0);
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c
index 7bf96e9d0..a78e73937 100644
--- a/src/dht/gnunet-service-xdht_routing.c
+++ b/src/dht/gnunet-service-xdht_routing.c
@@ -119,7 +119,7 @@ get_next_hop (struct RoutingTrail *trail,
119int 119int
120GDS_ROUTING_trail_update (struct GNUNET_PeerIdentity *source_peer, 120GDS_ROUTING_trail_update (struct GNUNET_PeerIdentity *source_peer,
121 struct GNUNET_PeerIdentity *destination_peer, 121 struct GNUNET_PeerIdentity *destination_peer,
122 struct GNUNET_PeerIdentity *prev_hop) 122 const struct GNUNET_PeerIdentity *prev_hop)
123{ 123{
124 /* 1. find the trail corresponding to these values. 124 /* 1. find the trail corresponding to these values.
125 2. update the prev hop to source peer. */ 125 2. update the prev hop to source peer. */
diff --git a/src/dht/gnunet-service-xdht_routing.h b/src/dht/gnunet-service-xdht_routing.h
index 0b0c80862..1dc2871e8 100644
--- a/src/dht/gnunet-service-xdht_routing.h
+++ b/src/dht/gnunet-service-xdht_routing.h
@@ -65,6 +65,28 @@ GDS_ROUTING_search(struct GNUNET_PeerIdentity *source_peer,
65 const struct GNUNET_PeerIdentity *prev_hop); 65 const struct GNUNET_PeerIdentity *prev_hop);
66 66
67/** 67/**
68 * FIXME: How to ensure that with only 3 fields also we have a unique trail.
69 * in case of redundant routes we can have different next hop.
70 * in that case we have to call this function on each entry of routing table
71 * and from multiple next hop we return one. Here also we are going to return one.
72 * URGENT.
73 * Assumption - there can be only on one trail with all these fields. But if
74 * we consider only 3 fields then it is possible that next hop is differet.
75 * Update prev_hop field to source_peer. Trail from source peer to destination
76 * peer is compressed such that I am the first friend in the trail.
77 * @param source_peer Source of the trail.
78 * @param destination_peer Destination of the trail.
79 * @param prev_hop Peer before me in the trail.
80 * @return #GNUNET_YES trail is updated.
81 * #GNUNET_NO, trail not found.
82 */
83int
84GDS_ROUTING_trail_update (struct GNUNET_PeerIdentity *source_peer,
85 struct GNUNET_PeerIdentity *destination_peer,
86 const struct GNUNET_PeerIdentity *prev_hop);
87
88
89/**
68 * Remove the trail as result of trail tear down message. 90 * Remove the trail as result of trail tear down message.
69 * @param source_peer Source of the trail. 91 * @param source_peer Source of the trail.
70 * @param destination_peer Destination of the trail. 92 * @param destination_peer Destination of the trail.