aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-05-19 16:58:57 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-05-19 16:58:57 +0000
commit90981ab5c69a3264b02fef933bcc871022fa3190 (patch)
tree10ec1d00da78889c7ae0fa331610e0df60557c13 /src/dht
parent5dd4ccb857a2f1639bd9de918f1fcb8cb78b1b5a (diff)
downloadgnunet-90981ab5c69a3264b02fef933bcc871022fa3190.tar.gz
gnunet-90981ab5c69a3264b02fef933bcc871022fa3190.zip
- Adding a new message type,GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL
- removing compare_and_update_predecessor() - refactoring trail rejection.
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-xdht_datacache.c2
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c1004
-rw-r--r--src/dht/gnunet-service-xdht_routing.c9
-rw-r--r--src/dht/gnunet-service-xdht_routing.h2
4 files changed, 566 insertions, 451 deletions
diff --git a/src/dht/gnunet-service-xdht_datacache.c b/src/dht/gnunet-service-xdht_datacache.c
index a63f7efba..34b3f2b9c 100644
--- a/src/dht/gnunet-service-xdht_datacache.c
+++ b/src/dht/gnunet-service-xdht_datacache.c
@@ -321,7 +321,7 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key,
321 element->prev = NULL; 321 element->prev = NULL;
322 322
323 memcpy (&(element->peer), &get_path[i], sizeof(struct GNUNET_PeerIdentity)); 323 memcpy (&(element->peer), &get_path[i], sizeof(struct GNUNET_PeerIdentity));
324 GNUNET_CONTAINER_DLL_insert_tail (ctx.head, ctx.tail, element); /* FIXME: changed from insert_tail to insert. */ 324 GNUNET_CONTAINER_DLL_insert (ctx.head, ctx.tail, element);
325 i++; 325 i++;
326 } 326 }
327 } 327 }
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index 4b3abd7d2..733d3daa3 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -47,9 +47,15 @@
47/* TODO: 47/* TODO:
48 1. to randomly choose one of the routes in case there are multiple 48 1. to randomly choose one of the routes in case there are multiple
49 routes to reach to the finger. 49 routes to reach to the finger.
50 3. Structure alignment. 50 2. Structure alignment.
51 5. In put, we don't have anything like put result. so we are not adding anything 51 3. In put, we don't have anything like put result. so we are not adding anything
52 in the routing table. 52 in the routing table.
53 4. Maintain a list of trails --> struct Trail *all_trails_head
54 * struct Trail *all_trails_tail. How do I keep it as an array and not as a list??
55 * First will complete the logic everywhere and then make this change.
56 5. At some places you use memcpy and at some places =, use uniformly.
57 6. I have removed compare_and_update_predecessor from handle_dht_p2p_Trail_setup
58 * (refer to google docs for reason).
53*/ 59*/
54 60
55/** 61/**
@@ -72,6 +78,16 @@
72 */ 78 */
73#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) 79#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
74 80
81/**
82 * Maximum number of trails stored per finger.
83 */
84#define TRAILS_COUNT 2
85
86/**
87 * Used to distinguish put/get request use of find_successor() from others
88 */
89#define PUT_GET_REQUEST 68
90
75GNUNET_NETWORK_STRUCT_BEGIN 91GNUNET_NETWORK_STRUCT_BEGIN
76 92
77/** 93/**
@@ -452,6 +468,11 @@ struct PeerNotifyNewSuccessorMessage
452 */ 468 */
453 struct GNUNET_PeerIdentity source_peer; 469 struct GNUNET_PeerIdentity source_peer;
454 470
471 /**
472 * Old successor of source peer.
473 */
474 struct GNUNET_PeerIdentity old_successor;
475
455 /** 476 /**
456 * New successor identity. 477 * New successor identity.
457 */ 478 */
@@ -493,7 +514,34 @@ struct PeerTrailTearDownMessage
493 */ 514 */
494 uint32_t trail_length; 515 uint32_t trail_length;
495 516
496 /* Trail to from source_peer to new first friend. */ 517 /* Trail from source_peer to new first friend. */
518};
519
520
521struct PeerAddTrailMessage
522{
523 /**
524 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL
525 */
526 struct GNUNET_MessageHeader header;
527
528 /**
529 * Source peer of the routing trail.
530 */
531 struct GNUNET_PeerIdentity source_peer;
532
533 /**
534 * Destination peer of the routing trail.
535 */
536 struct GNUNET_PeerIdentity destination_peer;
537
538 /**
539 * Total number of peers from source peer to destination peer.
540 */
541 unsigned int trail_length;
542
543 /* Trail from source peer to destination peer. */
544
497}; 545};
498 546
499GNUNET_NETWORK_STRUCT_END 547GNUNET_NETWORK_STRUCT_END
@@ -1261,6 +1309,7 @@ void GDS_NEIGHBOURS_send_verify_successor_result (const struct GNUNET_PeerIdenti
1261void 1309void
1262GDS_NEIGHBOURS_send_notify_new_successor (const struct GNUNET_PeerIdentity *source_peer, 1310GDS_NEIGHBOURS_send_notify_new_successor (const struct GNUNET_PeerIdentity *source_peer,
1263 const struct GNUNET_PeerIdentity *destination_peer, 1311 const struct GNUNET_PeerIdentity *destination_peer,
1312 const struct GNUNET_PeerIdentity *old_successor,
1264 struct FriendInfo *target_friend, 1313 struct FriendInfo *target_friend,
1265 const struct GNUNET_PeerIdentity *trail_peer_list, 1314 const struct GNUNET_PeerIdentity *trail_peer_list,
1266 unsigned int trail_length) 1315 unsigned int trail_length)
@@ -1294,12 +1343,14 @@ GDS_NEIGHBOURS_send_notify_new_successor (const struct GNUNET_PeerIdentity *sour
1294 nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR); 1343 nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR);
1295 memcpy (&(nsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); 1344 memcpy (&(nsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1296 memcpy (&(nsm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity)); 1345 memcpy (&(nsm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1346 memcpy (&(nsm->old_successor), old_successor, sizeof (struct GNUNET_PeerIdentity));
1297 nsm->trail_length = htonl (trail_length); 1347 nsm->trail_length = htonl (trail_length);
1298 /* FIXME: Here I am not checking the trail length, as I am assuming that for new 1348
1299 successor our old successor is a part of trail, so trail length > 1. */ 1349 if (trail_length > 0)
1300 peer_list = (struct GNUNET_PeerIdentity *) &nsm[1]; 1350 {
1301 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); 1351 peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
1302 1352 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1353 }
1303 /* Send the message to chosen friend. */ 1354 /* Send the message to chosen friend. */
1304 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); 1355 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1305 target_friend->pending_count++; 1356 target_friend->pending_count++;
@@ -1356,9 +1407,11 @@ GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_PeerIdentity *source_pee
1356 memcpy (&(ttdm->new_first_friend),new_first_friend, sizeof (struct GNUNET_PeerIdentity)); 1407 memcpy (&(ttdm->new_first_friend),new_first_friend, sizeof (struct GNUNET_PeerIdentity));
1357 ttdm->trail_length = htonl (discarded_trail_length); 1408 ttdm->trail_length = htonl (discarded_trail_length);
1358 1409
1359 peer_list = (struct GNUNET_PeerIdentity *) &ttdm[1]; 1410 if (discarded_trail_length > 0)
1360 memcpy (peer_list, discarded_trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)); 1411 {
1361 1412 peer_list = (struct GNUNET_PeerIdentity *) &ttdm[1];
1413 memcpy (peer_list, discarded_trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1414 }
1362 /* Send the message to chosen friend. */ 1415 /* Send the message to chosen friend. */
1363 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); 1416 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1364 target_friend->pending_count++; 1417 target_friend->pending_count++;
@@ -1367,6 +1420,66 @@ GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_PeerIdentity *source_pee
1367 1420
1368 1421
1369/** 1422/**
1423 *
1424 * @param source_peer
1425 * @param destination_peer
1426 * @param trail
1427 * @param trail_length
1428 * @param target_friend
1429 */
1430void
1431GDS_NEIGHBOURS_send_add_trail_message (struct GNUNET_PeerIdentity *source_peer,
1432 struct GNUNET_PeerIdentity *destination_peer,
1433 struct GNUNET_PeerIdentity *trail,
1434 unsigned int trail_length,
1435 struct FriendInfo *target_friend)
1436{
1437 struct P2PPendingMessage *pending;
1438 struct PeerAddTrailMessage *adm;
1439 struct GNUNET_PeerIdentity *peer_list;
1440 size_t msize;
1441
1442 msize = sizeof (struct PeerAddTrailMessage) +
1443 (trail_length * sizeof(struct GNUNET_PeerIdentity));
1444
1445 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1446 {
1447 GNUNET_break (0);
1448 return;
1449 }
1450
1451 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1452 {
1453 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1454 1, GNUNET_NO);
1455 }
1456
1457 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1458 pending->importance = 0; /* FIXME */
1459 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1460 adm = (struct PeerAddTrailMessage *) &pending[1];
1461 pending->msg = &adm->header;
1462 adm->header.size = htons (msize);
1463 adm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL);
1464 memcpy (&(adm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1465 memcpy (&(adm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1466 adm->trail_length = htonl (trail_length);
1467
1468 if (trail_length > 0)
1469 {
1470 peer_list = (struct GNUNET_PeerIdentity *)&adm[1];
1471 memcpy (peer_list, trail, sizeof (struct GNUNET_PeerIdentity) * trail_length);
1472 }
1473
1474 /* Send the message to chosen friend. */
1475 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1476 target_friend->pending_count++;
1477 process_friend_queue (target_friend);
1478}
1479
1480
1481/**
1482 * FIXME: CONGESTION: check the code once basic code is all correct. s
1370 * FIXME: call GNUNET_CONTAINER_multipeermap_iterator_destroy (iter); 1483 * FIXME: call GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1371 * In case the friend chosen in select_random_friend() is congested or 1484 * 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 1485 * has crossed trail_threshold, then get next friend which is not congested or
@@ -1419,6 +1532,7 @@ get_next_friend (unsigned int current_index,
1419 1532
1420 1533
1421/** 1534/**
1535 * FIXME: CONGESTION: check the code once basic code is all correct.
1422 * FIXME: call GNUNET_CONTAINER_multipeermap_iterator_destroy (iter); 1536 * FIXME: call GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1423 * Randomly choose one of your friends from the friends_peer map 1537 * Randomly choose one of your friends from the friends_peer map
1424 * @return Friend Randomly chosen friend. 1538 * @return Friend Randomly chosen friend.
@@ -1544,7 +1658,6 @@ send_verify_successor_message()
1544 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->first_trail_length); 1658 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->first_trail_length);
1545 iterate = finger->first_trail_head; 1659 iterate = finger->first_trail_head;
1546 1660
1547 /* FIXME: SEGMENTATION FAULT. */
1548 while ( i < (finger->first_trail_length)) 1661 while ( i < (finger->first_trail_length))
1549 { 1662 {
1550 memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity)); 1663 memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity));
@@ -1595,7 +1708,7 @@ send_find_finger_trail_message (void *cls,
1595 NULL); 1708 NULL);
1596 1709
1597 target_friend = select_random_friend (); 1710 target_friend = select_random_friend ();
1598 if (NULL == target_friend) /* Either all the friends are congested or reached trail threshold. */ 1711 if (NULL == target_friend)
1599 { 1712 {
1600 return; 1713 return;
1601 } 1714 }
@@ -1616,9 +1729,6 @@ send_find_finger_trail_message (void *cls,
1616 1729
1617 1730
1618/** 1731/**
1619 * FIXME: You need to handle the case of predecessor in case you don't get
1620 * the call from finger table add then you should not send a trail teardown message
1621 * because no one has added that in their trail.
1622 * Scan the trail to check if any of my own friend is part of trail. If yes 1732 * Scan the trail to check if any of my own friend is part of trail. If yes
1623 * then shortcut the trail, send a trail teardown for the discarded trail, 1733 * then shortcut the trail, send a trail teardown for the discarded trail,
1624 * update trail list and trail_length. 1734 * update trail list and trail_length.
@@ -1638,6 +1748,8 @@ scan_and_compress_trail (struct GNUNET_PeerIdentity *trail,
1638 1748
1639 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,finger)) 1749 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,finger))
1640 { 1750 {
1751 /* Here you don't send a trail teardown as no one added this in their
1752 routing table. */
1641 *trail_length = 0; 1753 *trail_length = 0;
1642 trail = NULL; 1754 trail = NULL;
1643 return; 1755 return;
@@ -1699,9 +1811,8 @@ scan_and_compress_trail (struct GNUNET_PeerIdentity *trail,
1699} 1811}
1700 1812
1701 1813
1702/** 1814/**
1703 * FIXME: Is this correct? Here I am using dll_remove and its documentation 1815 * FIXME: Adapt the code for List of trails.
1704 * reads something else. Verify. Urgent.
1705 * Free finger and its trail. 1816 * Free finger and its trail.
1706 * @param finger Finger to be freed. 1817 * @param finger Finger to be freed.
1707 */ 1818 */
@@ -1959,6 +2070,7 @@ decrement_friend_trail_count (struct FingerInfo *finger)
1959 2070
1960 2071
1961/** 2072/**
2073 * FIXME: create a different data structure for storing the peer ids here.
1962 * Select the closest finger. Used for both predecessor and other fingers.. 2074 * Select the closest finger. Used for both predecessor and other fingers..
1963 * But internally calls different functions for predecessor and other fingers. 2075 * But internally calls different functions for predecessor and other fingers.
1964 * @param existing_finger Finger in finger peermap. 2076 * @param existing_finger Finger in finger peermap.
@@ -1997,7 +2109,6 @@ int select_finger (struct FingerInfo *existing_finger,
1997 peers[2].data = NULL; 2109 peers[2].data = NULL;
1998 2110
1999 memcpy (&value, &my_identity, sizeof (uint64_t)); 2111 memcpy (&value, &my_identity, sizeof (uint64_t));
2000
2001 qsort (&peers, 3, sizeof (struct Sorting_List), &compare_peer_id); 2112 qsort (&peers, 3, sizeof (struct Sorting_List), &compare_peer_id);
2002 2113
2003 if (PREDECESSOR_FINGER_ID == finger_map_index) 2114 if (PREDECESSOR_FINGER_ID == finger_map_index)
@@ -2021,197 +2132,6 @@ int select_finger (struct FingerInfo *existing_finger,
2021 2132
2022 2133
2023/** 2134/**
2024 * FIXME: Do we need to reinsert the existing finger into finger peermap
2025 * in case we add a new trail?
2026 * Choose the closest finger between existing finger and new finger.
2027 * If the new finger is closest and finger_map_index != PREDECESSOR_FINGER_ID,
2028 * then send a trail_teardown message along existing_finger's trail.
2029 * In case both the id's are same, and there is a place to keep more trails, then
2030 * store both of them. In case there is no space to store any more trail, then
2031 * choose the best trail (best - depends on length in current_implementation) and
2032 * discard the others.
2033 * @param existing_finger Existing entry in finger peer map
2034 * @param new_finger New finger
2035 * @param trail Trail to reach to the new finger from me.
2036 * @param trail_length Number of peers in the @a trail
2037 * @param finger_map_index If finger_map_index == PREDECESSOR_FINGER_INDEX,
2038 * then we use a different logic to find the closest
2039 * predecessor.
2040 * @return #GNUNET_YES In case we want to store the new entry.
2041 * #GNUNET_NO In case we want the existing entry.
2042 * #GNUNET_SYSERR Error.
2043 */
2044static
2045int select_closest_finger (struct FingerInfo *existing_finger,
2046 const struct GNUNET_PeerIdentity *new_finger,
2047 struct GNUNET_PeerIdentity *trail,
2048 unsigned int trail_length,
2049 unsigned int finger_map_index)
2050{
2051 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger))
2052 {
2053 /* Both the new entry and existing entry are same. */
2054 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), &my_identity))
2055 {
2056 /* If existing_finger is my_identity then trail_length = 0, trail = NULL. In
2057 this case you don't need to check the trails. Exit. */
2058 return GNUNET_NO;
2059 }
2060 if (trail_length > 0)
2061 {
2062 scan_and_compress_trail (trail, &trail_length, new_finger);
2063 }
2064 if (existing_finger->trail_count < TRAIL_COUNT)
2065 {
2066 add_new_trail (existing_finger, trail, trail_length);
2067 return GNUNET_NO;
2068 }
2069 else
2070 {
2071 select_and_replace_trail (existing_finger, trail, trail_length);
2072 return GNUNET_NO;
2073 }
2074 }
2075 else if (GNUNET_YES == select_finger (existing_finger, new_finger, finger_map_index))
2076 {
2077 /* new_finger is the correct finger. */
2078 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, new_finger))
2079 {
2080 /* FIXME: Here in case the new finger is my_identity and old entry is not,
2081 should we keep the old entry even if the old entry is not the closest? */
2082 return GNUNET_NO;
2083 }
2084
2085 /* Clear all things associated with existing_finger (only if its not a
2086 predecessor) */
2087 if (PREDECESSOR_FINGER_ID != finger_map_index)
2088 send_trail_teardown (existing_finger);
2089 decrement_friend_trail_count (existing_finger);
2090 free_finger (existing_finger);
2091
2092 if (trail_length > 0)
2093 {
2094 scan_and_compress_trail (trail, &trail_length, new_finger);
2095 }
2096 return GNUNET_YES;
2097 }
2098 else if (GNUNET_NO == select_finger (existing_finger, new_finger,finger_map_index))
2099 {
2100 /* existing_finger is the correct finger. */
2101 return GNUNET_NO;
2102 }
2103 return GNUNET_SYSERR;
2104}
2105
2106
2107/**
2108 * Check if there is a predecessor in our finger peer map or not.
2109 * If no, then return GNUNET_YES
2110 * else compare existing predecessor and peer, and find the correct
2111 * predecessor.
2112 * @param existing_predecessor
2113 * @param new_predecessor
2114 * @return #GNUNET_YES if new peer is predecessor
2115 * #GNUNET_NO if new peer is not the predecessor.
2116 */
2117static int
2118compare_and_update_predecessor (const struct GNUNET_PeerIdentity *peer,
2119 struct GNUNET_PeerIdentity *trail,
2120 unsigned int trail_length)
2121{
2122 /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */
2123 struct FingerInfo *existing_finger;
2124 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2125 struct FingerInfo *new_finger_entry;
2126 struct FriendInfo *first_friend_trail;
2127 int i;
2128 int old_entry_found = GNUNET_NO;
2129
2130 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
2131 for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++)
2132 {
2133 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL,
2134 (const void **)&existing_finger))
2135 {
2136 if (PREDECESSOR_FINGER_ID == existing_finger->finger_map_index)
2137 {
2138 old_entry_found = GNUNET_YES;
2139 if( GNUNET_NO == select_closest_finger (existing_finger, peer, trail,
2140 trail_length,PREDECESSOR_FINGER_ID))
2141 return GNUNET_NO;
2142 else
2143 break;
2144 }
2145 }
2146 }
2147 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
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)))
2152 {
2153 trail_length = 0;
2154 trail = NULL;
2155 }
2156
2157 new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
2158 memcpy (&(new_finger_entry->finger_identity), peer, sizeof (struct GNUNET_PeerIdentity));
2159 new_finger_entry->finger_map_index = PREDECESSOR_FINGER_ID;
2160 new_finger_entry->first_trail_length = trail_length;
2161 new_finger_entry->trail_count = 1;
2162
2163 if (0 != GNUNET_CRYPTO_cmp_peer_identity(&my_identity,peer)) /* finger_trail is NULL in case I am my own finger identity. */
2164 {
2165 /* Invert the trail and then add. */
2166 if (trail_length != 0)
2167 {
2168 i = trail_length - 1;
2169 while (i > 0)
2170 {
2171 struct TrailPeerList *element;
2172 element = GNUNET_malloc (sizeof (struct TrailPeerList));
2173 element->next = NULL;
2174 element->prev = NULL;
2175
2176 memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
2177 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->first_trail_head, new_finger_entry->first_trail_tail, element);
2178 i--;
2179 }
2180 struct TrailPeerList *element;
2181 element = GNUNET_malloc (sizeof (struct TrailPeerList));
2182 element->next = NULL;
2183 element->prev = NULL;
2184 memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
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;
2202 }
2203 }
2204 GNUNET_assert (GNUNET_OK ==
2205 GNUNET_CONTAINER_multipeermap_put (finger_peermap,
2206 &(new_finger_entry->finger_identity),
2207 new_finger_entry,
2208 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
2209
2210 return GNUNET_YES;
2211}
2212
2213
2214/**
2215 * FIXME: Better name, and make the code more cleaner. 2135 * FIXME: Better name, and make the code more cleaner.
2216 * Compare the new finger entry added and our successor. 2136 * Compare the new finger entry added and our successor.
2217 * @return #GNUNET_YES if same. 2137 * @return #GNUNET_YES if same.
@@ -2315,31 +2235,99 @@ add_new_entry (const struct GNUNET_PeerIdentity *finger_identity,
2315 } 2235 }
2316 } 2236 }
2317 2237
2318 return GNUNET_CONTAINER_multipeermap_put (finger_peermap, 2238 return GNUNET_CONTAINER_multipeermap_put (finger_peermap,
2319 &(new_finger_entry->finger_identity), 2239 &(new_finger_entry->finger_identity),
2320 new_finger_entry, 2240 new_finger_entry,
2321 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 2241 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2322} 2242}
2323 2243
2324 2244
2325/**1. Should we check if there is already an entry for same finger id in the finger 2245/**
2326 * peermap as we are checking for index. I think its too much of code and the use 2246 * Choose the closest finger between existing finger and new finger.
2327 * of having unique identifier in finger map is only in case of find_successor 2247 * If the new finger is closest, then send a trail_teardown message along
2328 * but anyways we will find the correct successor. 2248 * existing_finger's trail. In case both the id's are same, and there is a place
2329 * 2. you don't handle the second trail here as in new entry you will have only 2249 * to add more trails, then store both of them. In case there is no space to
2330 * one trail to reach to the finger. 2250 * store any more trail, then choose the best trail (best - depends on length in
2331 * Add an entry in the finger table. If there is already an existing entry in 2251 * current_implementation) and discard the others.
2332 * the finger peermap for given finger map index, then choose the closest one. 2252 * @param existing_finger
2333 * In case both the new entry and old entry are same, store both of them. (Redundant 2253 * @param new_finger Existing finger in finger_peermap for @a finger_map_index
2334 * routing). 2254 * @param trail Trail to reach from me to @a new_finger
2335 * @param finger_identity 2255 * @param trail_length Total number of peers in @a trail.
2336 * @param finger_trail 2256 * @param finger_map_index Index in finger peermap.
2337 * @param finger_trail_length 2257 * @return #GNUNET_YES In case we want to store the new entry.
2338 * @param finger_map_index 2258 * #GNUNET_NO In case we want the existing entry.
2259 * #GNUNET_SYSERR Error.
2260 */
2261static
2262int select_closest_finger (struct FingerInfo *existing_finger,
2263 const struct GNUNET_PeerIdentity *new_finger,
2264 struct GNUNET_PeerIdentity *trail,
2265 unsigned int trail_length,
2266 unsigned int finger_map_index)
2267{
2268 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger))
2269 {
2270 /* New entry and existing entry are same. */
2271 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), &my_identity))
2272 {
2273 /* If existing_finger is my_identity then trail_length = 0, trail = NULL. In
2274 this case you don't need to check the trails. Exit. */
2275 return GNUNET_NO;
2276 }
2277 if (trail_length > 0)
2278 {
2279 scan_and_compress_trail (trail, &trail_length, new_finger);
2280 }
2281 if (existing_finger->trail_count < TRAIL_COUNT)
2282 {
2283 add_new_trail (existing_finger, trail, trail_length);
2284 return GNUNET_NO;
2285 }
2286 else
2287 {
2288 select_and_replace_trail (existing_finger, trail, trail_length);
2289 return GNUNET_NO;
2290 }
2291 }
2292 else if (GNUNET_YES == select_finger (existing_finger, new_finger, finger_map_index))
2293 {
2294 /* New finger is the closest finger. */
2295 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, new_finger))
2296 {
2297 /* FIXME: Here in case the new finger is my_identity and old entry is not,
2298 should we keep the old entry even if the old entry is not the closest? */
2299 return GNUNET_NO;
2300 }
2301 send_trail_teardown (existing_finger);
2302 decrement_friend_trail_count (existing_finger);
2303 free_finger (existing_finger);
2304
2305 if (trail_length > 0)
2306 {
2307 scan_and_compress_trail (trail, &trail_length, new_finger);
2308 }
2309 return GNUNET_YES;
2310 }
2311 else if (GNUNET_NO == select_finger (existing_finger, new_finger,finger_map_index))
2312 {
2313 /* existing_finger is the closest finger. */
2314 return GNUNET_NO;
2315 }
2316 return GNUNET_SYSERR;
2317}
2318
2319
2320/**
2321 * Check if there is already an entry for finger map index in finger table.
2322 * If yes then choose the closest finger.
2323 * @param finger_identity Peer Identity of finger.
2324 * @param finger_trail Trail to reach from me to @a finger_identity
2325 * @param finger_trail_length Total number of peers in finger_trail.
2326 * @param finger_map_index Index in finger_peermap.
2339 * @return #GNUNET_YES if the new entry is added. 2327 * @return #GNUNET_YES if the new entry is added.
2340 * #GNUNET_NO if the new entry is discarded. 2328 * #GNUNET_NO if the new entry is discarded.
2341 */ 2329 */
2342static 2330static
2343int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, 2331int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2344 struct GNUNET_PeerIdentity *finger_trail, 2332 struct GNUNET_PeerIdentity *finger_trail,
2345 uint32_t finger_trail_length, 2333 uint32_t finger_trail_length,
@@ -2349,17 +2337,7 @@ int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2349 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; 2337 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2350 int i; 2338 int i;
2351 int old_entry_found = GNUNET_NO; 2339 int old_entry_found = GNUNET_NO;
2352 int new_entry_added = GNUNET_NO; 2340 int new_entry_added = GNUNET_NO;
2353
2354 if (PREDECESSOR_FINGER_ID == finger_map_index)
2355 {
2356 /* FIXME: Here GNUNET_NO, means that we did not update predecessor . But it
2357 we also need to handle the case that insertion failed in peer map after we decided to add
2358 the entry. */
2359 if( GNUNET_YES == compare_and_update_predecessor (finger_identity, finger_trail, finger_trail_length))
2360 new_entry_added = GNUNET_YES;
2361 goto update_current_search_finger_index;
2362 }
2363 2341
2364 /* Check if there is already an entry for the finger map index in the finger peer map. */ 2342 /* Check if there is already an entry for the finger map index in the finger peer map. */
2365 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 2343 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
@@ -2389,8 +2367,8 @@ int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2389 scan_and_compress_trail (finger_trail, &finger_trail_length, finger_identity); 2367 scan_and_compress_trail (finger_trail, &finger_trail_length, finger_identity);
2390 } 2368 }
2391 } 2369 }
2392 /* SUPU: in this case you get GNUNET_NO, only when insertion fails in the peer map. 2370
2393 so its an error as we already have decided to add the entry into finger peer map. */ 2371 /* FIXME: handle the case when addition in peer map failed. */
2394 if(GNUNET_OK == add_new_entry (finger_identity,finger_trail,finger_trail_length, finger_map_index)) 2372 if(GNUNET_OK == add_new_entry (finger_identity,finger_trail,finger_trail_length, finger_map_index))
2395 new_entry_added = GNUNET_YES; 2373 new_entry_added = GNUNET_YES;
2396 else 2374 else
@@ -2472,7 +2450,9 @@ check_friend_threshold_and_congestion (struct Sorting_List *all_known_peers,
2472 2450
2473 2451
2474/** 2452/**
2475 * FIXME: In case a friend is either congested or has crossed its trail threshold, 2453 * FIXME: Complete the code for checking the threshold and getting the next
2454 * peer, add the case in finger.
2455 * In case a friend is either congested or has crossed its trail threshold,
2476 * then don't consider it as next successor, In case of finger if its first 2456 * then don't consider it as next successor, In case of finger if its first
2477 * friend has crossed the threshold then don't consider it. In case no finger 2457 * friend has crossed the threshold then don't consider it. In case no finger
2478 * or friend is found, then return NULL. 2458 * or friend is found, then return NULL.
@@ -2483,13 +2463,14 @@ check_friend_threshold_and_congestion (struct Sorting_List *all_known_peers,
2483 * set to first friend to reach to finger, in case finger 2463 * set to first friend to reach to finger, in case finger
2484 * is final destination. 2464 * is final destination.
2485 * @param[out] current_source set to my_identity. 2465 * @param[out] current_source set to my_identity.
2466 * @param finger_map_index Index in finger peer map.
2486 * @return Peer identity of next hop to send trail setup message to, 2467 * @return Peer identity of next hop to send trail setup message to,
2487 * NULL in case all the friends are either congested or have crossed 2468 * NULL in case all the friends are either congested or have crossed
2488 * their trail threshold. 2469 * their trail threshold.
2489 */ 2470 */
2490static struct GNUNET_PeerIdentity * 2471static struct GNUNET_PeerIdentity *
2491find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, 2472find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2492 struct GNUNET_PeerIdentity *current_source) 2473 struct GNUNET_PeerIdentity *current_source, unsigned int finger_map_index)
2493{ 2474{
2494 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter; 2475 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
2495 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; 2476 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
@@ -2560,7 +2541,10 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2560 qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id); 2541 qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id);
2561 2542
2562 /* search value in all_known_peers array. */ 2543 /* search value in all_known_peers array. */
2563 successor = find_closest_successor (all_known_peers, value, size); 2544 if (PREDECESSOR_FINGER_ID == finger_map_index)
2545 successor = find_closest_predecessor (all_known_peers, value, size);
2546 else
2547 successor = find_closest_successor (all_known_peers, value, size);
2564 2548
2565 if (successor->type == MY_ID) 2549 if (successor->type == MY_ID)
2566 { 2550 {
@@ -2667,7 +2651,7 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
2667 struct GNUNET_PeerIdentity *next_hop; 2651 struct GNUNET_PeerIdentity *next_hop;
2668 2652
2669 memcpy (&key_value, key, sizeof (uint64_t)); 2653 memcpy (&key_value, key, sizeof (uint64_t));
2670 next_hop = find_successor (key_value, &current_destination, &current_source); 2654 next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST);
2671 if (0 == GNUNET_CRYPTO_cmp_peer_identity(next_hop, &my_identity)) /* I am the destination do datacache_put */ 2655 if (0 == GNUNET_CRYPTO_cmp_peer_identity(next_hop, &my_identity)) /* I am the destination do datacache_put */
2672 { 2656 {
2673 GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path, 2657 GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path,
@@ -2757,7 +2741,7 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
2757 2741
2758 memcpy (&key_value, key, sizeof (uint64_t)); 2742 memcpy (&key_value, key, sizeof (uint64_t));
2759 // FIXME: endianess of key_value!? 2743 // FIXME: endianess of key_value!?
2760 next_hop = find_successor (key_value, &current_destination, &current_source); 2744 next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST);
2761 if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity,next_hop)) /* I am the destination do datacache_put */ 2745 if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity,next_hop)) /* I am the destination do datacache_put */
2762 { 2746 {
2763 GDS_DATACACHE_handle_get (key,block_type, NULL, 0, 2747 GDS_DATACACHE_handle_get (key,block_type, NULL, 0,
@@ -2897,9 +2881,9 @@ GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration,
2897 * @param trail_length Number of peers in trail_peer_list. 2881 * @param trail_length Number of peers in trail_peer_list.
2898 */ 2882 */
2899void 2883void
2900GDS_NEIGHBOURS_send_trail_rejection (struct GNUNET_PeerIdentity *source_peer, 2884GDS_NEIGHBOURS_send_trail_rejection (const struct GNUNET_PeerIdentity *source_peer,
2901 uint64_t finger_identity, 2885 uint64_t finger_identity,
2902 struct GNUNET_PeerIdentity *congested_peer, 2886 const struct GNUNET_PeerIdentity *congested_peer,
2903 const struct GNUNET_PeerIdentity *next_hop, 2887 const struct GNUNET_PeerIdentity *next_hop,
2904 unsigned int finger_map_index, 2888 unsigned int finger_map_index,
2905 struct GNUNET_PeerIdentity *trail_peer_list, 2889 struct GNUNET_PeerIdentity *trail_peer_list,
@@ -2930,7 +2914,7 @@ GDS_NEIGHBOURS_send_trail_rejection (struct GNUNET_PeerIdentity *source_peer,
2930 memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); 2914 memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2931 memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity)); 2915 memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity));
2932 memcpy (&(trail_rejection->finger_identity_value), &finger_identity, sizeof (uint64_t)); 2916 memcpy (&(trail_rejection->finger_identity_value), &finger_identity, sizeof (uint64_t));
2933 trail_rejection->finger_map_index = htonl(finger_map_index); 2917 trail_rejection->finger_map_index = htonl (finger_map_index);
2934 trail_rejection->trail_length = htonl (trail_length); 2918 trail_rejection->trail_length = htonl (trail_length);
2935 2919
2936 if (trail_length != 0) 2920 if (trail_length != 0)
@@ -3071,7 +3055,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
3071 } 3055 }
3072 else 3056 else
3073 { 3057 {
3074 next_hop = find_successor (key_value, &current_destination, &current_source); 3058 next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST);
3075 } 3059 }
3076 3060
3077 if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, next_hop)) /* I am the final destination */ 3061 if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, next_hop)) /* I am the final destination */
@@ -3168,7 +3152,7 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
3168 } 3152 }
3169 else 3153 else
3170 { 3154 {
3171 next_hop = find_successor (key_value, &current_destination, &current_source); 3155 next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST);
3172 } 3156 }
3173 3157
3174 if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, next_hop)) 3158 if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, next_hop))
@@ -3286,8 +3270,98 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
3286} 3270}
3287 3271
3288 3272
3273/**
3274 * FIXME: URGENT: refactor it.
3275 * FIXME; now we can make a new ds to store 2 peers and one value as we are
3276 * using it at two places. Will complete the logic and then add a new ds.
3277 * In case finger map index is 64 do we need to call find_closest_predecessor?
3278 * Select the closest peer.
3279 * @param prev_hop
3280 * @param current_destination
3281 * @param current_source
3282 * @param value
3283 * @para finger_map_index
3284 * @return Peer which is closest, in case of error NULL.
3285 */
3286struct GNUNET_PeerIdentity *
3287select_closest_peer (const struct GNUNET_PeerIdentity *prev_hop,
3288 struct GNUNET_PeerIdentity *current_destination,
3289 struct GNUNET_PeerIdentity *current_source,
3290 uint64_t value,
3291 unsigned int finger_map_index)
3292{
3293 struct GNUNET_PeerIdentity *peer1;
3294 struct GNUNET_PeerIdentity *peer2;
3295 struct Sorting_List peers[3];
3296 struct Sorting_List *closest_finger;
3297
3298 peer1 = GDS_ROUTING_search (current_source, current_destination, prev_hop);
3299 peer2 = find_successor (value, current_destination, current_source,finger_map_index);
3300
3301 /* SUPU TEST CODE */
3302 struct GNUNET_PeerIdentity print_peer;
3303 memcpy (&print_peer, &peer1, sizeof (struct GNUNET_PeerIdentity));
3304 FPRINTF (stderr,_("\nSUPU %s, %s, %d,routing_peer = %s"), __FILE__, __func__,__LINE__,GNUNET_i2s(&print_peer));
3305 memcpy (&print_peer, &peer2, sizeof (struct GNUNET_PeerIdentity));
3306 FPRINTF (stderr,_("\nSUPU %s, %s, %d,find_successor_peer = %s"), __FILE__, __func__,__LINE__,GNUNET_i2s(&print_peer));
3307 /* SUPU TEST CODE ENDS*/
3308 if( (peer1 != NULL) && (peer2 != NULL))
3309 {
3310 /* Add peer 1 to the list. */
3311 memcpy (&peers[0], &peer1, sizeof (uint64_t));
3312 peers[0].type = FINGER;
3313 peers[0].data = NULL;
3314
3315 /* Add peer 2 to the list. */
3316 memcpy (&peers[1], &peer1, sizeof (uint64_t));
3317 peers[0].type = FRIEND;
3318 peers[0].data = NULL;
3319
3320 /* Add value to the list. */
3321 memcpy (&peers[2], &peer1, sizeof (uint64_t));
3322 peers[0].type = VALUE;
3323 peers[0].data = NULL;
3324
3325 qsort (&peers, 3, sizeof (struct Sorting_List), &compare_peer_id);
3326 if (PREDECESSOR_FINGER_ID == finger_map_index)
3327 closest_finger = find_closest_predecessor (peers, value, 3);
3328 else
3329 closest_finger = find_closest_successor (peers, value, 3);
3330
3331 /* SUPU TEST CODE*/
3332 if (closest_finger->type == FINGER)
3333 {
3334 FPRINTF (stderr,_("\nSUPU %s, %s, %d"), __FILE__, __func__,__LINE__);
3335 return peer2;
3336 }
3337 else if (closest_finger->type == VALUE)
3338 {
3339 return NULL;
3340 }
3341 else if (closest_finger->type == FRIEND);
3342 {
3343 /* If we are returning peer2 then find_successor has already taken care
3344 of setting up current_destination and current_source. */
3345 return peer1;
3346 }
3347 }
3348 else if ((peer1 == NULL) && (peer2 == NULL))
3349 {
3350 return NULL;
3351 }
3352 else if (peer1 == NULL)
3353 {
3354 return peer2;
3355 }
3356 else if (peer2 == NULL)
3357 {
3358 return peer1;
3359 }
3360 return NULL;
3361}
3362
3363
3289/** 3364/**
3290 * FIXME: Is all trails threshold and routing table has some link.
3291 * Core handle for PeerTrailSetupMessage. 3365 * Core handle for PeerTrailSetupMessage.
3292 * @param cls closure 3366 * @param cls closure
3293 * @param message message 3367 * @param message message
@@ -3338,51 +3412,32 @@ handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
3338 finger_map_index = ntohl (trail_setup->finger_map_index); 3412 finger_map_index = ntohl (trail_setup->finger_map_index);
3339 destination_finger_value = ntohl (trail_setup->destination_finger); 3413 destination_finger_value = ntohl (trail_setup->destination_finger);
3340 3414
3341#if 0 3415 /* Check your routing table size, and if you can handle any more trails through you. */
3342 /* FIXME: Here we need to check 3 things 3416 if (GNUNET_YES == GDS_ROUTING_check_threshold())
3343 * 1. if my routing table is all full 3417 {
3344 * 2. if all my friends are congested
3345 * 3. if trail threshold of my friends have crossed.
3346 * In all these cases we need to send back trail rejection message. */
3347 if ( (GNUNET_YES == all_friends_trail_threshold)
3348 || (GNUNET_YES == GDS_ROUTING_check_threshold()))
3349 {
3350 /* If all the friends have reached their trail threshold or if there is no
3351 more space in routing table to store more trails, then reject. */
3352 GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity, 3418 GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity,
3353 peer,finger_map_index, trail_peer_list,trail_length); 3419 peer, finger_map_index, trail_peer_list, trail_length);
3354 return GNUNET_OK; 3420 return GNUNET_OK;
3355 } 3421 }
3356#endif
3357
3358 3422
3359 /* Check if you are current_destination or not. */ 3423 /* Check if you are current_destination or not. */
3360 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity))) 3424 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
3361 { 3425 {
3362 GDS_ROUTING_print(); 3426 next_hop = select_closest_peer (peer, &current_destination, &current_source,
3363 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer); 3427 destination_finger_value, finger_map_index);
3364 /* OPTIMIZATION: Choose a peer from find_successor and choose the closest one.
3365 In case the closest one is from routing table and it is NULL, then update
3366 statistics. */
3367 if (next_hop == NULL)
3368 {
3369 /* FIXME: Should we inform the peer before us. If not then it may continue
3370 to send us request. But in case we want to inform we need to have a
3371 different kind of message. */
3372 GNUNET_STATISTICS_update (GDS_stats,
3373 gettext_noop ("# Trail not found in routing table during"
3374 "trail setup request, packet dropped."),
3375 1, GNUNET_NO);
3376 return GNUNET_OK;
3377 }
3378 } 3428 }
3379 else 3429 else
3380 { 3430 {
3381 next_hop = find_successor (destination_finger_value, &current_destination, &current_source); 3431 next_hop = find_successor (destination_finger_value, &current_destination,
3432 &current_source,finger_map_index);
3382 } 3433 }
3383 3434
3384 if (NULL == next_hop) 3435 if (NULL == next_hop)
3385 { 3436 {
3437 GNUNET_STATISTICS_update (GDS_stats,
3438 gettext_noop ("# Trail not found in routing table during"
3439 "trail setup request, packet dropped."),
3440 1, GNUNET_NO);
3386 return GNUNET_SYSERR; 3441 return GNUNET_SYSERR;
3387 } 3442 }
3388 else if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)))/* This means I am the final destination */ 3443 else if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)))/* This means I am the final destination */
@@ -3397,13 +3452,6 @@ handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
3397 } 3452 }
3398 3453
3399 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); 3454 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
3400 /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */
3401 if (PREDECESSOR_FINGER_ID != finger_map_index)
3402 {
3403 /* FIXME: Is this correct assumption? A peer which think I am its predecessor,
3404 then I am not its predecessor. */
3405 compare_and_update_predecessor (&source, trail_peer_list, trail_length );
3406 }
3407 GDS_NEIGHBOURS_send_trail_setup_result (&source, 3455 GDS_NEIGHBOURS_send_trail_setup_result (&source,
3408 &(my_identity), 3456 &(my_identity),
3409 target_friend, trail_length, 3457 target_friend, trail_length,
@@ -3443,6 +3491,8 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
3443{ 3491{
3444 const struct PeerTrailSetupResultMessage *trail_result; 3492 const struct PeerTrailSetupResultMessage *trail_result;
3445 struct GNUNET_PeerIdentity *trail_peer_list; 3493 struct GNUNET_PeerIdentity *trail_peer_list;
3494 struct GNUNET_PeerIdentity destination_peer;
3495 struct GNUNET_PeerIdentity finger_identity;
3446 uint32_t trail_length; 3496 uint32_t trail_length;
3447 uint32_t finger_map_index; 3497 uint32_t finger_map_index;
3448 size_t msize; 3498 size_t msize;
@@ -3468,7 +3518,12 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
3468 } 3518 }
3469 3519
3470 finger_map_index = htonl (trail_result->finger_map_index); 3520 finger_map_index = htonl (trail_result->finger_map_index);
3471 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1]; 3521 memcpy (&destination_peer, &(trail_result->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3522 memcpy (&finger_identity, &(trail_result->finger_identity), sizeof (struct GNUNET_PeerIdentity));
3523
3524 if (trail_length > 0)
3525 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
3526
3472 3527
3473 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer), 3528 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
3474 &my_identity))) 3529 &my_identity)))
@@ -3494,17 +3549,19 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
3494 else 3549 else
3495 next_hop = trail_peer_list[my_index - 1]; 3550 next_hop = trail_peer_list[my_index - 1];
3496 3551
3497 /* Finger table of destination peer will not contain any trail for the case
3498 * where destination peer is its own finger identity.*/
3499 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer), 3552 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
3500 &(trail_result->finger_identity)))) 3553 &(trail_result->finger_identity))))
3501 { 3554 {
3502 /* FIXME: First call GDS_ROUTING_search, only if it returns NULL, call 3555 struct GNUNET_PeerIdentity *routing_next_hop;
3503 GDS_ROUTING_add. But in case we have same 3 fields but 1 different next hop 3556
3504 then we should add the entry but in current implementation of GDS_ROUTNG_search 3557 routing_next_hop = GDS_ROUTING_search (&destination_peer,&finger_identity,
3505 we don't handle it. */ 3558 peer);
3506 GDS_ROUTING_add (&(trail_result->destination_peer), &(trail_result->finger_identity), 3559 if ((NULL == routing_next_hop) ||
3507 peer, &next_hop); 3560 (0 != GNUNET_CRYPTO_cmp_peer_identity(routing_next_hop, &next_hop)))
3561 {
3562 GDS_ROUTING_add (&(trail_result->destination_peer), &(trail_result->finger_identity),
3563 peer, &next_hop);
3564 }
3508 GDS_ROUTING_print(); 3565 GDS_ROUTING_print();
3509 } 3566 }
3510 3567
@@ -3601,13 +3658,10 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
3601 struct FingerInfo *my_predecessor; 3658 struct FingerInfo *my_predecessor;
3602 if (trail_length == 0) 3659 if (trail_length == 0)
3603 { 3660 {
3604 /* SUPU: If I am friend of source_peer, then trail_length == 0. */
3605 memcpy (&next_hop, &source_peer, sizeof (struct GNUNET_PeerIdentity)); 3661 memcpy (&next_hop, &source_peer, sizeof (struct GNUNET_PeerIdentity));
3606 } 3662 }
3607 else 3663 else
3608 { 3664 {
3609 /* SUPU: Here I am the final destination successor, and trail does not contain
3610 destination. So, the next hop is the last element in the trail. */
3611 memcpy (&next_hop, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity)); 3665 memcpy (&next_hop, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
3612 } 3666 }
3613 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 3667 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
@@ -3615,8 +3669,8 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
3615 my_predecessor = get_predecessor(); 3669 my_predecessor = get_predecessor();
3616 if (NULL == my_predecessor) 3670 if (NULL == my_predecessor)
3617 { 3671 {
3618 GNUNET_break(0); 3672 /* FIXME: should we just return. */
3619 return GNUNET_SYSERR; 3673 return GNUNET_OK;
3620 } 3674 }
3621 3675
3622 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer, 3676 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
@@ -3698,11 +3752,7 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
3698} 3752}
3699 3753
3700 3754
3701/**FIXME: in case we have a new successor do we need to update the entries in 3755/**
3702 * routing table to change the destination of the message from old successor
3703 * to new successor or when the old successor sends the message the I am not
3704 * your successor then it sends a trail teardown message across the old trail.
3705 * Need to decide on a strategy.
3706 * Core handle for p2p verify successor result messages. 3756 * Core handle for p2p verify successor result messages.
3707 * @param cls closure 3757 * @param cls closure
3708 * @param message message 3758 * @param message message
@@ -3738,35 +3788,28 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti
3738 GNUNET_break_op (0); 3788 GNUNET_break_op (0);
3739 return GNUNET_YES; 3789 return GNUNET_YES;
3740 } 3790 }
3741 /* FIXME: URGENT: What happens when trail length = 0. */
3742 3791
3743 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1]; 3792 if (trail_length > 0)
3793 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1];
3744 3794
3745 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity)))) 3795 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity))))
3746 { 3796 {
3747 if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor), &(my_identity)))) 3797 if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor), &(my_identity))))
3748 { 3798 {
3749 /* FIXME: Here we have got a new successor. But it may happen that our logic
3750 * says that this is not correct successor. so in finger table add it
3751 * failed to update the successor and we are still sending a notify
3752 * new successor. Here trail_length will be atleast 1, in case we have a new
3753 * successor because in that case our old successor is part of trail.
3754 * Could it be possible that our identity and my_predecessor is same. Check it. */
3755 if (GNUNET_YES == finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0)) 3799 if (GNUNET_YES == finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0))
3756 { 3800 {
3757 memcpy (&next_hop, &trail_peer_list[0], sizeof (struct GNUNET_PeerIdentity)); 3801 memcpy (&next_hop, &trail_peer_list[0], sizeof (struct GNUNET_PeerIdentity));
3758 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 3802 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3803 /* FIXME: first call scan_and_compress_trail and then call the notify new
3804 successor with new trail. */
3759 GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor), 3805 GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor),
3806 &(vsrm->source_successor),
3760 target_friend, trail_peer_list, 3807 target_friend, trail_peer_list,
3761 trail_length); 3808 trail_length);
3762 return GNUNET_OK; 3809 return GNUNET_OK;
3763 } 3810 }
3764 /*else 3811 else
3765 { 3812 return GNUNET_OK;
3766
3767 GNUNET_break (0);
3768 return GNUNET_SYSERR;
3769 }*/
3770 } 3813 }
3771 } 3814 }
3772 else 3815 else
@@ -3782,8 +3825,6 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti
3782 3825
3783 if (my_index == 0) 3826 if (my_index == 0)
3784 { 3827 {
3785 /* Source is not part of trail, so if I am the last one then my index
3786 should be 0. */
3787 memcpy (&next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity)); 3828 memcpy (&next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3788 } 3829 }
3789 else 3830 else
@@ -3817,6 +3858,9 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
3817{ 3858{
3818 const struct PeerNotifyNewSuccessorMessage *nsm; 3859 const struct PeerNotifyNewSuccessorMessage *nsm;
3819 struct GNUNET_PeerIdentity *trail_peer_list; 3860 struct GNUNET_PeerIdentity *trail_peer_list;
3861 struct GNUNET_PeerIdentity source_peer;
3862 struct GNUNET_PeerIdentity old_successor;
3863 struct GNUNET_PeerIdentity new_successor;
3820 size_t msize; 3864 size_t msize;
3821 uint32_t trail_length; 3865 uint32_t trail_length;
3822 3866
@@ -3837,26 +3881,27 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
3837 GNUNET_break_op (0); 3881 GNUNET_break_op (0);
3838 return GNUNET_YES; 3882 return GNUNET_YES;
3839 } 3883 }
3840 if( trail_length > 1) 3884
3841 { 3885 if( trail_length > 0)
3842 trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1]; 3886 trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
3843 } 3887 memcpy (&source_peer, &(nsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
3888 memcpy (&old_successor, &(nsm->old_successor), sizeof (struct GNUNET_PeerIdentity));
3889 memcpy (&new_successor, &(nsm->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3844 3890
3845 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity))) 3891 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&new_successor, &my_identity)))
3846 { 3892 {
3847 /* I am the new successor. */ 3893 /* I am the new successor. */
3848 struct GNUNET_PeerIdentity *new_predecessor; 3894 struct GNUNET_PeerIdentity *new_predecessor;
3849 new_predecessor = GNUNET_new (struct GNUNET_PeerIdentity); 3895 new_predecessor = GNUNET_new (struct GNUNET_PeerIdentity);
3850 memcpy (new_predecessor, &(nsm->source_peer), sizeof (struct GNUNET_PeerIdentity)); 3896 memcpy (new_predecessor, &(nsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
3851 if (GNUNET_NO == compare_and_update_predecessor (new_predecessor, trail_peer_list, 3897 if (GNUNET_YES == finger_table_add (new_predecessor, trail_peer_list, trail_length, PREDECESSOR_FINGER_ID))
3852 trail_length))
3853 { 3898 {
3854 /* Someone claims to be my predecessor but its not closest predecessor 3899 /* You are adding a new predecessor in your finger table. but the intermediate
3855 the break. */ 3900 peers don't have an entry in their routing table. So, you need to check the
3856 GNUNET_break (0); 3901 return value of finger_table_Add and if its successful then you should send
3857 return GNUNET_SYSERR; 3902 routing_add_message. */
3858 } 3903 }
3859 return GNUNET_OK; 3904 return GNUNET_OK;
3860 } 3905 }
3861 else 3906 else
3862 { 3907 {
@@ -3884,9 +3929,12 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
3884 memcpy (&next_hop, &trail_peer_list[my_index+1], sizeof (struct GNUNET_PeerIdentity)); 3929 memcpy (&next_hop, &trail_peer_list[my_index+1], sizeof (struct GNUNET_PeerIdentity));
3885 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 3930 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3886 } 3931 }
3887 /* FIXME: Should we update the entries in routing table? */ 3932
3933 GDS_ROUTING_remove_trail (&source_peer, &old_successor, peer);
3934 GDS_ROUTING_add (&(nsm->source_peer), &(nsm->destination_peer), &next_hop, peer);
3888 GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), 3935 GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer),
3889 &(nsm->destination_peer), 3936 &(nsm->destination_peer),
3937 &(nsm->old_successor),
3890 target_friend, trail_peer_list, 3938 target_friend, trail_peer_list,
3891 trail_length); 3939 trail_length);
3892 return GNUNET_OK; 3940 return GNUNET_OK;
@@ -3894,14 +3942,11 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
3894 return GNUNET_SYSERR; 3942 return GNUNET_SYSERR;
3895} 3943}
3896 3944
3897
3898/** 3945/**
3899 * FIXME; Should we call select_random_friend from here in case I am the source 3946 * FIXME: pass congestion time in struct PeerTrailRejectionMessage,
3900 * of the message or should I just return and in next iteration by default 3947 * we are calling exact same thing here as in handle_dht_p2p_trail_seutp.set
3901 * we will call select random friend from send_find_finger_trail. But in that 3948 * that value here.
3902 * case we should maintain a list of congested peer which failed to setup the 3949 * if we make it a function then we can it here.
3903 * trail. and then in select random friend we should ignore them. this list
3904 * should have an expiration time and we should garbage collect it periodically.
3905 * Core handler for P2P trail rejection message 3950 * Core handler for P2P trail rejection message
3906 * @param cls closure 3951 * @param cls closure
3907 * @param message message 3952 * @param message message
@@ -3912,32 +3957,18 @@ static
3912int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer, 3957int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer,
3913 const struct GNUNET_MessageHeader *message) 3958 const struct GNUNET_MessageHeader *message)
3914{ 3959{
3915 /* Here you have recevied the message it means that the peer next to you have
3916 failed to setup the trail to the finger identity value. now you should call
3917 find_successor and make sure that you don't choose the peer as next hop
3918 in order to do so, you need to pass a new parameter to find successor,
3919 congested peer - a peer which you should ignore. once you have found this
3920 peer then just send a trail setup message to that peer. In case you are
3921 also congested then remove yourself from the trail as this message
3922 reached to as you are part of the trail. and then send the message to
3923 element before you. Ideally you should be the last element in the trail as
3924 all the the elements before you have rejected you. In case you are source,
3925 then you should call select_random_Friend(congested_peer). in case you don't
3926 find any peer because congested peer then set flag that all friends are busy
3927 and leave. */
3928 const struct PeerTrailRejectionMessage *trail_rejection; 3960 const struct PeerTrailRejectionMessage *trail_rejection;
3929 struct GNUNET_PeerIdentity *trail_peer_list; 3961 struct GNUNET_PeerIdentity *trail_peer_list;
3930 struct GNUNET_PeerIdentity source_peer;
3931 struct GNUNET_PeerIdentity congested_peer;
3932 struct FriendInfo *target_friend; 3962 struct FriendInfo *target_friend;
3933 struct GNUNET_PeerIdentity next_peer; 3963 struct GNUNET_PeerIdentity next_hop;
3934 struct GNUNET_PeerIdentity *next_hop; 3964 struct GNUNET_PeerIdentity *next_peer;
3935 struct GNUNET_PeerIdentity current_source; 3965 struct GNUNET_PeerIdentity source;
3936 struct GNUNET_PeerIdentity current_destination; 3966 struct GNUNET_PeerIdentity current_destination;
3937 size_t msize; 3967 struct GNUNET_PeerIdentity current_source;
3938 uint32_t trail_length; 3968 uint32_t trail_length;
3939 uint32_t finger_map_index; 3969 uint32_t finger_map_index;
3940 uint64_t destination_finger_value; 3970 uint64_t destination_finger_value;
3971 size_t msize;
3941 3972
3942 msize = ntohs (message->size); 3973 msize = ntohs (message->size);
3943 if (msize < sizeof (struct PeerTrailRejectionMessage)) 3974 if (msize < sizeof (struct PeerTrailRejectionMessage))
@@ -3958,127 +3989,109 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *
3958 return GNUNET_YES; 3989 return GNUNET_YES;
3959 } 3990 }
3960 3991
3961 trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; 3992 if (trail_length > 0)
3993 trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
3962 finger_map_index = ntohl (trail_rejection->finger_map_index); 3994 finger_map_index = ntohl (trail_rejection->finger_map_index);
3963 memcpy (&source_peer, &(trail_rejection->source_peer), sizeof(struct GNUNET_PeerIdentity));
3964 memcpy (&destination_finger_value, &(trail_rejection->finger_identity_value), sizeof (uint64_t)); 3995 memcpy (&destination_finger_value, &(trail_rejection->finger_identity_value), sizeof (uint64_t));
3965 memcpy (&congested_peer, &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity)); 3996 memcpy (&source, &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
3997
3998 /* First set the congestion time of the friend that sent you this message. */
3999 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
4000 //FIXME: target_friend->congestion_time ==?
3966 4001
3967 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &source_peer))) 4002 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(trail_rejection->source_peer))))
3968 { 4003 {
3969 /* I am the source of original trail setup message. Do nothing and exit. */ 4004 return GNUNET_OK;
3970 /* In current implementation, when we don't get the result of a trail setup,
3971 then no entry is added to finger table and hence, by default a trail setup for
3972 the same finger map index is sent. so we don't need to send it here. */
3973 return GNUNET_YES;
3974 } 4005 }
3975 4006
3976 if(GDS_ROUTING_check_threshold()) 4007 if(GNUNET_YES == GDS_ROUTING_check_threshold())
3977 { 4008 {
3978 /* My routing state size has crossed the threshold, I can not be part of any more
3979 * trails. */
3980 struct GNUNET_PeerIdentity *new_trail; 4009 struct GNUNET_PeerIdentity *new_trail;
3981 4010 unsigned int new_trail_length;
4011
3982 if (trail_length == 1) 4012 if (trail_length == 1)
3983 { 4013 {
3984 memcpy (&next_peer, &source_peer, sizeof (struct GNUNET_PeerIdentity)); 4014 new_trail = NULL;
4015 new_trail_length = 0;
4016 memcpy (&next_hop, &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
3985 } 4017 }
3986 else 4018 else
3987 { 4019 {
3988 /* FIXME: Here if I got the trail rejection message then I am the last element 4020 memcpy (&next_hop, &trail_peer_list[trail_length - 2], sizeof (struct GNUNET_PeerIdentity));
3989 in the trail. So, I should choose trail_length-2.*/ 4021 /* Remove myself from the trail. */
3990 memcpy (&next_peer, &trail_peer_list[trail_length - 2], sizeof (struct GNUNET_PeerIdentity)); 4022 new_trail_length = trail_length -1;
4023 new_trail = GNUNET_malloc (new_trail_length * sizeof (struct GNUNET_PeerIdentity));
4024 memcpy (new_trail, trail_peer_list, new_trail_length * sizeof (struct GNUNET_PeerIdentity));
3991 } 4025 }
3992 4026 GDS_NEIGHBOURS_send_trail_rejection (&(trail_rejection->source_peer),
3993 /* Remove myself from the trail. */ 4027 destination_finger_value,
3994 new_trail = GNUNET_malloc ((trail_length -1) * sizeof (struct GNUNET_PeerIdentity)); 4028 &my_identity, &next_hop,finger_map_index,
3995 memcpy (new_trail, trail_peer_list, (trail_length -1) * sizeof (struct GNUNET_PeerIdentity)); 4029 new_trail,new_trail_length);
3996
3997 /* No more trails possible through me. send a trail rejection message to next hop. */
3998 GDS_NEIGHBOURS_send_trail_rejection (&source_peer, destination_finger_value, &my_identity,
3999 &next_peer,finger_map_index, new_trail,trail_length - 1);
4000 return GNUNET_YES; 4030 return GNUNET_YES;
4001 } 4031 }
4002 4032
4033 {
4003 memcpy (&current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity)); 4034 memcpy (&current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity));
4004 memcpy (&current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity)); 4035 memcpy (&current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
4005 /* FIXME: After adding a new field in struct FriendInfo congested, then call 4036 next_peer = find_successor (destination_finger_value,&current_destination,
4006 find successor then it will never consider that friend by default. */ 4037 &current_source, finger_map_index);
4007 next_hop = find_successor (destination_finger_value, &current_destination, &current_source); 4038 if (NULL == next_peer)
4008
4009 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &current_destination))) /* This means I am the final destination */
4010 { 4039 {
4011 if (trail_length == 1) 4040 GNUNET_STATISTICS_update (GDS_stats,
4041 gettext_noop ("# Trail not found in routing table during"
4042 "trail setup request, packet dropped."),
4043 1, GNUNET_NO);
4044 return GNUNET_SYSERR;
4045 }
4046 else if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_peer, &my_identity)))/* This means I am the final destination */
4047 {
4048 if (trail_length == 0)
4012 { 4049 {
4013 memcpy (&next_peer, &source_peer, sizeof (struct GNUNET_PeerIdentity)); 4050 memcpy (&next_hop, &source, sizeof (struct GNUNET_PeerIdentity));
4014 } 4051 }
4015 else 4052 else
4016 { 4053 {
4017 memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity)); 4054 memcpy (&next_hop, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
4018 } 4055 }
4019 4056 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4020 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); 4057 GDS_NEIGHBOURS_send_trail_setup_result (&source,
4021 compare_and_update_predecessor (&source_peer, trail_peer_list, trail_length);
4022
4023 GDS_NEIGHBOURS_send_trail_setup_result (&source_peer,
4024 &(my_identity), 4058 &(my_identity),
4025 target_friend, trail_length, 4059 target_friend, trail_length,
4026 trail_peer_list, 4060 trail_peer_list,
4027 finger_map_index); 4061 finger_map_index);
4028 return GNUNET_OK; 4062 return GNUNET_OK;
4029 } 4063 }
4030 else if (NULL == next_hop)
4031 {
4032 /* No peer found. Send a trail rejection message to previous peer in the trail. */
4033
4034 struct GNUNET_PeerIdentity *new_trail;
4035
4036 if (trail_length == 1)
4037 {
4038 memcpy (&next_peer, &source_peer, sizeof (struct GNUNET_PeerIdentity));
4039 }
4040 else
4041 {
4042 memcpy (&next_peer, &trail_peer_list[trail_length - 2], sizeof (struct GNUNET_PeerIdentity));
4043 }
4044
4045 /* Remove myself from the trail. */
4046 new_trail = GNUNET_malloc ((trail_length -1) * sizeof (struct GNUNET_PeerIdentity));
4047 memcpy (new_trail, trail_peer_list, (trail_length -1) * sizeof (struct GNUNET_PeerIdentity));
4048
4049 /* No more trails possible through me. send a trail rejection message to next hop. */
4050 GDS_NEIGHBOURS_send_trail_rejection (&source_peer, destination_finger_value, &my_identity,
4051 &next_peer,finger_map_index, new_trail,trail_length - 1);
4052 return GNUNET_YES;
4053 }
4054 else 4064 else
4055 { 4065 {
4056 /* Now add yourself to the trail. */ 4066 /* Now add yourself to the trail. */
4057 struct GNUNET_PeerIdentity peer_list[trail_length + 1]; 4067 struct GNUNET_PeerIdentity peer_list[trail_length + 1];
4058 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); 4068 if (trail_length != 0)
4069 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
4059 peer_list[trail_length] = my_identity; 4070 peer_list[trail_length] = my_identity;
4060 trail_length++; 4071 trail_length++;
4061 4072 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4062 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 4073 GDS_NEIGHBOURS_send_trail_setup (&source,
4063 GDS_NEIGHBOURS_send_trail_setup (&source_peer,
4064 destination_finger_value, 4074 destination_finger_value,
4065 &current_destination, &current_source, 4075 &current_destination, &current_source,
4066 target_friend, trail_length, peer_list, 4076 target_friend, trail_length, peer_list,
4067 finger_map_index); 4077 finger_map_index);
4068 return GNUNET_OK; 4078 return GNUNET_OK;
4069 } 4079 }
4070 return GNUNET_SYSERR; 4080 }
4081
4071} 4082}
4072 4083
4073 4084
4074/* Core handle for p2p trail tear down messages. 4085/* FIXME: there is a loop between in call from notify new successor to this function
4086 * check why and fix it.
4087 * Core handle for p2p trail tear down messages.
4075 * @param cls closure 4088 * @param cls closure
4076 * @param message message 4089 * @param message message
4077 * @param peer peer identity this notification is about 4090 * @param peer peer identity this notification is about
4078 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 4091 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4079 */ 4092 */
4080static 4093static
4081int handle_dht_p2p_trail_teardown(void *cls, const struct GNUNET_PeerIdentity *peer, 4094int handle_dht_p2p_trail_teardown (void *cls, const struct GNUNET_PeerIdentity *peer,
4082 const struct GNUNET_MessageHeader *message) 4095 const struct GNUNET_MessageHeader *message)
4083{ 4096{
4084 struct PeerTrailTearDownMessage *trail_teardown; 4097 struct PeerTrailTearDownMessage *trail_teardown;
@@ -4108,8 +4121,20 @@ int handle_dht_p2p_trail_teardown(void *cls, const struct GNUNET_PeerIdentity *p
4108 return GNUNET_OK; 4121 return GNUNET_OK;
4109 } 4122 }
4110 4123
4124 if (discarded_trail_length > 0)
4111 discarded_trail = (struct GNUNET_PeerIdentity *) &trail_teardown[1]; 4125 discarded_trail = (struct GNUNET_PeerIdentity *) &trail_teardown[1];
4112 4126
4127 /* SUPU TEST CODE */
4128 struct GNUNET_PeerIdentity print_peer;
4129 int k = 0;
4130 while ( k < discarded_trail_length)
4131 {
4132 memcpy (&print_peer, &discarded_trail[k], sizeof (struct GNUNET_PeerIdentity));
4133 FPRINTF (stderr,_("\nSUPU %s, %s, %d,discarded_trail[%d]=%s"),
4134 __FILE__, __func__,__LINE__,k,GNUNET_i2s(&print_peer));
4135 k++;
4136 }
4137 /* SUPU TEST CODE ENDS*/
4113 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->new_first_friend), 4138 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->new_first_friend),
4114 &my_identity))) 4139 &my_identity)))
4115 { 4140 {
@@ -4168,9 +4193,86 @@ int handle_dht_p2p_trail_teardown(void *cls, const struct GNUNET_PeerIdentity *p
4168 return GNUNET_SYSERR; 4193 return GNUNET_SYSERR;
4169} 4194}
4170 4195
4196/**
4197 * Core handle for p2p routing table add messages.
4198 * @param cls closure
4199 * @param message message
4200 * @param peer peer identity this notification is about
4201 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4202 */
4203static int
4204handle_dht_p2p_add_trail (void *cls, const struct GNUNET_PeerIdentity *peer,
4205 const struct GNUNET_MessageHeader *message)
4206{
4207 /* This function is called in case when we update our predecessor as a new peer
4208 claims to be our successor. In that case as we did not do a trail setup,
4209 intermediate nodes don't know about this trail. our predecessor has added
4210 that trail but not we. So, we need to add it. Its only in case of predecessor
4211 and succcessor that we have a symmetric relation. */
4212 struct PeerAddTrailMessage *add_trail;
4213 struct GNUNET_PeerIdentity *trail;
4214 struct GNUNET_PeerIdentity next_hop;
4215 struct FriendInfo *target_friend;
4216 size_t msize;
4217 uint32_t trail_length;
4218 int my_index;
4219
4220 msize = ntohs (message->size);
4221 if (msize < sizeof (struct PeerAddTrailMessage))
4222 {
4223 GNUNET_break_op (0);
4224 return GNUNET_OK;
4225 }
4226
4227 add_trail = (struct PeerAddTrailMessage *) message;
4228 trail_length = ntohl (add_trail->trail_length);
4229
4230 if ((msize < sizeof (struct PeerAddTrailMessage) +
4231 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
4232 (trail_length >
4233 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
4234 {
4235 GNUNET_break_op (0);
4236 return GNUNET_OK;
4237 }
4238
4239 if (trail_length > 0)
4240 trail = (struct GNUNET_PeerIdentity *)&add_trail[1];
4241
4242 my_index = search_my_index (trail, trail_length);
4243 if (GNUNET_SYSERR == my_index)
4244 {
4245 GNUNET_break (0);
4246 return GNUNET_SYSERR;
4247 }
4248 if (my_index == 0)
4249 memcpy(&next_hop, &(add_trail->source_peer), sizeof (struct GNUNET_PeerIdentity));
4250 else
4251 memcpy (&next_hop, &trail[my_index - 1], sizeof (struct GNUNET_PeerIdentity));
4252
4253 if (GNUNET_YES == GDS_ROUTING_add (&(add_trail->source_peer), &(add_trail->destination_peer),
4254 peer,&next_hop))
4255 {
4256 if (my_index != 0)
4257 {
4258 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4259 GDS_NEIGHBOURS_send_add_trail_message (&(add_trail->source_peer),
4260 &(add_trail->destination_peer),
4261 trail, trail_length,target_friend);
4262 }
4263 return GNUNET_OK;
4264 }
4265 else
4266 {
4267 /* FIXME: there is not space in routing table to add the trail. What should
4268 be done. */
4269 return GNUNET_SYSERR;
4270 }
4271}
4272
4171 4273
4172/** 4274/**
4173 * FIXME: always gives segmentation fault. 4275 * FIXME: Adapt the code for List of trails.
4174 * Iterate over finger_peermap, and remove entries with peer as the first element 4276 * Iterate over finger_peermap, and remove entries with peer as the first element
4175 * of their trail. 4277 * of their trail.
4176 * @param cls closure 4278 * @param cls closure
@@ -4188,8 +4290,19 @@ remove_matching_finger (void *cls,
4188 struct FingerInfo *remove_finger = value; 4290 struct FingerInfo *remove_finger = value;
4189 const struct GNUNET_PeerIdentity *disconnected_peer = cls; 4291 const struct GNUNET_PeerIdentity *disconnected_peer = cls;
4190 4292
4191 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->first_trail_head->peer, disconnected_peer) 4293 if (remove_finger->first_trail_length > 0)
4192 || (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_finger->finger_identity), disconnected_peer))) 4294 {
4295 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->first_trail_head->peer, disconnected_peer))
4296 {
4297 GNUNET_assert (GNUNET_YES ==
4298 GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
4299 key,
4300 remove_finger));
4301 free_finger (remove_finger);
4302 }
4303 }
4304 else if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_finger->finger_identity),
4305 disconnected_peer))
4193 { 4306 {
4194 GNUNET_assert (GNUNET_YES == 4307 GNUNET_assert (GNUNET_YES ==
4195 GNUNET_CONTAINER_multipeermap_remove (finger_peermap, 4308 GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
@@ -4232,12 +4345,6 @@ handle_core_disconnect (void *cls,
4232 * the friend is a finger. */ 4345 * the friend is a finger. */
4233 GNUNET_CONTAINER_multipeermap_iterate (finger_peermap, 4346 GNUNET_CONTAINER_multipeermap_iterate (finger_peermap,
4234 &remove_matching_finger, (void *)peer); 4347 &remove_matching_finger, (void *)peer);
4235
4236 /* Remove routing trails of which this peer is a part.
4237 * FIXME: Here do we only remove the entry from our own routing table
4238 * or do we also inform other peers which are part of trail. It seems to be
4239 * too much of messages exchanged. */
4240 GDS_ROUTING_print();
4241 GDS_ROUTING_remove_entry (peer); 4348 GDS_ROUTING_remove_entry (peer);
4242 4349
4243 /* Remove the peer from friend_peermap. */ 4350 /* Remove the peer from friend_peermap. */
@@ -4332,7 +4439,8 @@ GDS_NEIGHBOURS_init (void)
4332 {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0}, 4439 {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
4333 {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0}, 4440 {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
4334 {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0}, 4441 {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0},
4335 {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN, 0}, 4442 {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN, 0},
4443 {&handle_dht_p2p_add_trail, GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL, 0},
4336 {NULL, 0, 0} 4444 {NULL, 0, 0}
4337 }; 4445 };
4338 4446
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c
index a78e73937..2101a8ada 100644
--- a/src/dht/gnunet-service-xdht_routing.c
+++ b/src/dht/gnunet-service-xdht_routing.c
@@ -148,11 +148,16 @@ GDS_ROUTING_trail_update (struct GNUNET_PeerIdentity *source_peer,
148 148
149 149
150/** 150/**
151 * It can happen that a particular peer removed the entry because one of the peers
152 * (source, destination, next , prev) was friend which got disconnected. So,
153 * no matching trail is found. In this case we return NULL. Its on calling function
154 * to handle the return value.
151 * Find the next hop to send packet to. 155 * Find the next hop to send packet to.
152 * @param source_peer Source of the trail. 156 * @param source_peer Source of the trail.
153 * @param destination_peer Destination of the trail. 157 * @param destination_peer Destination of the trail.
154 * @param prev_hop Previous hop in the trail. 158 * @param prev_hop Previous hop in the trail.
155 * @return Next hop in the trail from source to destination. 159 * @return Next hop in the trail from source to destination.
160 * NULL in case no matching trail found in routing table.
156 */ 161 */
157struct GNUNET_PeerIdentity * 162struct GNUNET_PeerIdentity *
158GDS_ROUTING_search (struct GNUNET_PeerIdentity *source_peer, 163GDS_ROUTING_search (struct GNUNET_PeerIdentity *source_peer,
@@ -184,6 +189,8 @@ GDS_ROUTING_search (struct GNUNET_PeerIdentity *source_peer,
184 189
185 190
186/** 191/**
192 * FIXME: first search in routing table and if same entry found then don't add
193 * it.
187 * Add a new entry to our routing table. 194 * Add a new entry to our routing table.
188 * @param source peer Source of the trail. 195 * @param source peer Source of the trail.
189 * @param destintation Destination of the trail. 196 * @param destintation Destination of the trail.
@@ -195,7 +202,7 @@ int
195GDS_ROUTING_add (const struct GNUNET_PeerIdentity *source, 202GDS_ROUTING_add (const struct GNUNET_PeerIdentity *source,
196 const struct GNUNET_PeerIdentity *dest, 203 const struct GNUNET_PeerIdentity *dest,
197 const struct GNUNET_PeerIdentity *next_hop, 204 const struct GNUNET_PeerIdentity *next_hop,
198 struct GNUNET_PeerIdentity *prev_hop) 205 const struct GNUNET_PeerIdentity *prev_hop)
199{ 206{
200 struct RoutingTrail *new_routing_entry; 207 struct RoutingTrail *new_routing_entry;
201 208
diff --git a/src/dht/gnunet-service-xdht_routing.h b/src/dht/gnunet-service-xdht_routing.h
index 1dc2871e8..a79ba68a3 100644
--- a/src/dht/gnunet-service-xdht_routing.h
+++ b/src/dht/gnunet-service-xdht_routing.h
@@ -43,7 +43,7 @@ int
43GDS_ROUTING_add (const struct GNUNET_PeerIdentity *source, 43GDS_ROUTING_add (const struct GNUNET_PeerIdentity *source,
44 const struct GNUNET_PeerIdentity *dest, 44 const struct GNUNET_PeerIdentity *dest,
45 const struct GNUNET_PeerIdentity *next_hop, 45 const struct GNUNET_PeerIdentity *next_hop,
46 struct GNUNET_PeerIdentity *prev_hop); 46 const struct GNUNET_PeerIdentity *prev_hop);
47 47
48 48
49/** 49/**