aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-05-14 14:06:29 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-05-14 14:06:29 +0000
commitcb67c0bb1e6f2a5bae0295a75bc1f4b1b9f9f765 (patch)
treed598edc55a3f81eb829337aa51d6cbf2a393a021 /src/dht
parent3f7071b9e18b3013d4fe68fb9e9f5530d4174f73 (diff)
downloadgnunet-cb67c0bb1e6f2a5bae0295a75bc1f4b1b9f9f765.tar.gz
gnunet-cb67c0bb1e6f2a5bae0295a75bc1f4b1b9f9f765.zip
- Fixes in routing table functions
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c188
-rw-r--r--src/dht/gnunet-service-xdht_routing.c268
-rw-r--r--src/dht/gnunet-service-xdht_routing.h5
3 files changed, 269 insertions, 192 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index 00b4580c7..f56abf093 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -47,12 +47,7 @@
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 2. Use a global array of all known peers in find_successor, Only when
51 a new peer is added in finger or friend peer map, then re calculate
52 the array. Or else use the old one. The benefit of having this list is something
53 I am not sure. only when the code is complete and working I will do this part.
54 3. Structure alignment. 50 3. Structure alignment.
55 4. Check where do you set all_friends_trail_threshold? In select_random_friend?
56 5. In put, we don't have anything like put result. so we are not adding anything 51 5. In put, we don't have anything like put result. so we are not adding anything
57 in the routing table. 52 in the routing table.
58*/ 53*/
@@ -598,6 +593,19 @@ struct FriendInfo
598 unsigned int pending_count; 593 unsigned int pending_count;
599 594
600 /** 595 /**
596 * FIXME: Refer to time.c and gnunet_time_lib.h for correct functions.
597 * in handle_dht_p2p_trail_rejection, you should update these values
598 * and whenever you are selecting a friend in select_random_friend()
599 * and find_successor(), you should check congestion_duration = 0,
600 * then proceed else if congestion_duration < your current time then also
601 * proceed.
602 * struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();
603 * struct GNUNET_TIME_Relative congestion_timeout =
604 * congestion_duration = GNUNET_TIME_absolute_add (start,congestion_timeout);
605 */
606 struct GNUNET_TIME_Absolute congestion_duration;
607
608 /**
601 * Head of pending messages to be sent to this friend. 609 * Head of pending messages to be sent to this friend.
602 */ 610 */
603 struct P2PPendingMessage *head; 611 struct P2PPendingMessage *head;
@@ -1591,6 +1599,9 @@ send_find_finger_trail_message (void *cls,
1591 1599
1592 1600
1593/** 1601/**
1602 * FIXME: You need to handle the case of predecessor in case you don't get
1603 * the call from finger table add then you should not send a trail teardown message
1604 * because no one has added that in their trail.
1594 * Scan the trail to check if any of my own friend is part of trail. If yes 1605 * Scan the trail to check if any of my own friend is part of trail. If yes
1595 * then shortcut the trail, send a trail teardown for the discarded trail, 1606 * then shortcut the trail, send a trail teardown for the discarded trail,
1596 * update trail list and trail_length. 1607 * update trail list and trail_length.
@@ -1607,20 +1618,24 @@ scan_and_compress_trail (struct GNUNET_PeerIdentity *trail,
1607{ 1618{
1608 int i; 1619 int i;
1609 struct FriendInfo *target_friend; 1620 struct FriendInfo *target_friend;
1610 1621
1611 /* If finger is my friend, then send a trail teardown message and then set 1622 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,finger))
1612 * trail_length = 0; */ 1623 {
1624 *trail_length = 0;
1625 trail = NULL;
1626 return;
1627 }
1613 if (GNUNET_CONTAINER_multipeermap_get (friend_peermap, finger)) 1628 if (GNUNET_CONTAINER_multipeermap_get (friend_peermap, finger))
1614 { 1629 {
1615 int discarded_trail_length = *trail_length; 1630 int discarded_trail_length = *trail_length;
1616 target_friend = GNUNET_CONTAINER_multipeermap_get(friend_peermap, &trail[0]); 1631 target_friend = GNUNET_CONTAINER_multipeermap_get(friend_peermap, &trail[0]);
1617 GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, trail, 1632 GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, trail,
1618 discarded_trail_length, target_friend, finger); 1633 discarded_trail_length, target_friend, finger);
1619 trail_length = 0; 1634 *trail_length = 0;
1620 trail = NULL; 1635 trail = NULL;
1621 return; 1636 return;
1622 } 1637 }
1623 1638
1624 i = *trail_length - 1; 1639 i = *trail_length - 1;
1625 while (i > 1) 1640 while (i > 1)
1626 { 1641 {
@@ -1646,7 +1661,6 @@ scan_and_compress_trail (struct GNUNET_PeerIdentity *trail,
1646 discarded_trail = GNUNET_malloc (discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)); 1661 discarded_trail = GNUNET_malloc (discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1647 memcpy (discarded_trail, trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)); 1662 memcpy (discarded_trail, trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1648 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[0]); 1663 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[0]);
1649
1650 GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, discarded_trail, 1664 GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, discarded_trail,
1651 discarded_trail_length, target_friend, 1665 discarded_trail_length, target_friend,
1652 &trail[i]); 1666 &trail[i]);
@@ -1726,7 +1740,7 @@ void send_trail_teardown (struct FingerInfo *removed_finger)
1726 finger_trail = finger_trail->next; 1740 finger_trail = finger_trail->next;
1727 i++; 1741 i++;
1728 } 1742 }
1729 1743
1730 GDS_NEIGHBOURS_send_trail_teardown (&my_identity, &(removed_finger->finger_identity), 1744 GDS_NEIGHBOURS_send_trail_teardown (&my_identity, &(removed_finger->finger_identity),
1731 peer_list, removed_finger_trail_length, friend, 1745 peer_list, removed_finger_trail_length, friend,
1732 &(removed_finger->finger_identity)); 1746 &(removed_finger->finger_identity));
@@ -2024,7 +2038,7 @@ int select_closest_finger (struct FingerInfo *existing_finger,
2024 this case you don't need to check the trails. Exit. */ 2038 this case you don't need to check the trails. Exit. */
2025 return GNUNET_NO; 2039 return GNUNET_NO;
2026 } 2040 }
2027 if (trail_length > 1) 2041 if (trail_length > 0)
2028 { 2042 {
2029 scan_and_compress_trail (trail, &trail_length, new_finger); 2043 scan_and_compress_trail (trail, &trail_length, new_finger);
2030 } 2044 }
@@ -2056,8 +2070,10 @@ int select_closest_finger (struct FingerInfo *existing_finger,
2056 decrement_friend_trail_count (existing_finger); 2070 decrement_friend_trail_count (existing_finger);
2057 free_finger (existing_finger); 2071 free_finger (existing_finger);
2058 2072
2059 if (trail_length > 1) 2073 if (trail_length > 0)
2074 {
2060 scan_and_compress_trail (trail, &trail_length, new_finger); 2075 scan_and_compress_trail (trail, &trail_length, new_finger);
2076 }
2061 return GNUNET_YES; 2077 return GNUNET_YES;
2062 } 2078 }
2063 else if (GNUNET_NO == select_finger (existing_finger, new_finger,finger_map_index)) 2079 else if (GNUNET_NO == select_finger (existing_finger, new_finger,finger_map_index))
@@ -2090,6 +2106,7 @@ compare_and_update_predecessor (const struct GNUNET_PeerIdentity *peer,
2090 struct FingerInfo *new_finger_entry; 2106 struct FingerInfo *new_finger_entry;
2091 struct FriendInfo *first_friend_trail; 2107 struct FriendInfo *first_friend_trail;
2092 int i; 2108 int i;
2109 int old_entry_found = GNUNET_NO;
2093 2110
2094 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 2111 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
2095 for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++) 2112 for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++)
@@ -2099,6 +2116,7 @@ compare_and_update_predecessor (const struct GNUNET_PeerIdentity *peer,
2099 { 2116 {
2100 if (PREDECESSOR_FINGER_ID == existing_finger->finger_map_index) 2117 if (PREDECESSOR_FINGER_ID == existing_finger->finger_map_index)
2101 { 2118 {
2119 old_entry_found = GNUNET_YES;
2102 if( GNUNET_NO == select_closest_finger (existing_finger, peer, trail, 2120 if( GNUNET_NO == select_closest_finger (existing_finger, peer, trail,
2103 trail_length,PREDECESSOR_FINGER_ID)) 2121 trail_length,PREDECESSOR_FINGER_ID))
2104 return GNUNET_NO; 2122 return GNUNET_NO;
@@ -2108,6 +2126,11 @@ compare_and_update_predecessor (const struct GNUNET_PeerIdentity *peer,
2108 } 2126 }
2109 } 2127 }
2110 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); 2128 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2129 if(GNUNET_NO == old_entry_found)
2130 {
2131 trail_length = 0;
2132 trail = NULL;
2133 }
2111 2134
2112 new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo)); 2135 new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
2113 memcpy (&(new_finger_entry->finger_identity), peer, sizeof (struct GNUNET_PeerIdentity)); 2136 memcpy (&(new_finger_entry->finger_identity), peer, sizeof (struct GNUNET_PeerIdentity));
@@ -2115,7 +2138,7 @@ compare_and_update_predecessor (const struct GNUNET_PeerIdentity *peer,
2115 new_finger_entry->first_trail_length = trail_length; 2138 new_finger_entry->first_trail_length = trail_length;
2116 new_finger_entry->trail_count = 1; 2139 new_finger_entry->trail_count = 1;
2117 2140
2118 if (trail != NULL) /* finger_trail is NULL in case I am my own finger identity. */ 2141 if (0 != GNUNET_CRYPTO_cmp_peer_identity(&my_identity,peer)) /* finger_trail is NULL in case I am my own finger identity. */
2119 { 2142 {
2120 /* FIXME: Currently we are not handling the second trail. In that case, finger 2143 /* FIXME: Currently we are not handling the second trail. In that case, finger
2121 trail count = min (first_friend, second_friend) trail count. */ 2144 trail count = min (first_friend, second_friend) trail count. */
@@ -2239,7 +2262,7 @@ add_new_entry (const struct GNUNET_PeerIdentity *finger_identity,
2239 new_finger_entry->first_trail_length = finger_trail_length; 2262 new_finger_entry->first_trail_length = finger_trail_length;
2240 new_finger_entry->trail_count = 1; 2263 new_finger_entry->trail_count = 1;
2241 2264
2242 if (finger_trail != NULL) /* finger_trail is NULL in case I am my own finger identity. */ 2265 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,finger_identity)) /* finger_trail is NULL in case I am my own finger identity. */
2243 { 2266 {
2244 /* Incrementing the friend trails count. */ 2267 /* Incrementing the friend trails count. */
2245 if (finger_trail_length > 0) 2268 if (finger_trail_length > 0)
@@ -2303,6 +2326,7 @@ int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2303 struct FingerInfo *existing_finger; 2326 struct FingerInfo *existing_finger;
2304 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; 2327 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2305 int i; 2328 int i;
2329 int old_entry_found = GNUNET_NO;
2306 int new_entry_added = GNUNET_NO; 2330 int new_entry_added = GNUNET_NO;
2307 2331
2308 if (PREDECESSOR_FINGER_ID == finger_map_index) 2332 if (PREDECESSOR_FINGER_ID == finger_map_index)
@@ -2324,6 +2348,7 @@ int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2324 { 2348 {
2325 if (existing_finger->finger_map_index == finger_map_index) 2349 if (existing_finger->finger_map_index == finger_map_index)
2326 { 2350 {
2351 old_entry_found = GNUNET_YES;
2327 if ( GNUNET_NO == select_closest_finger (existing_finger, finger_identity, 2352 if ( GNUNET_NO == select_closest_finger (existing_finger, finger_identity,
2328 finger_trail, finger_trail_length, 2353 finger_trail, finger_trail_length,
2329 finger_map_index)) 2354 finger_map_index))
@@ -2334,6 +2359,14 @@ int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2334 } 2359 }
2335 } 2360 }
2336 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); 2361 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2362
2363 if (GNUNET_NO == old_entry_found)
2364 {
2365 if (finger_trail_length > 0)
2366 {
2367 scan_and_compress_trail (finger_trail, &finger_trail_length, finger_identity);
2368 }
2369 }
2337 /* SUPU: in this case you get GNUNET_NO, only when insertion fails in the peer map. 2370 /* SUPU: in this case you get GNUNET_NO, only when insertion fails in the peer map.
2338 so its an error as we already have decided to add the entry into finger peer map. */ 2371 so its an error as we already have decided to add the entry into finger peer map. */
2339 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))
@@ -2357,7 +2390,6 @@ int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2357 current_search_finger_index = current_search_finger_index - 1; 2390 current_search_finger_index = current_search_finger_index - 1;
2358 } 2391 }
2359 2392
2360
2361 return new_entry_added; 2393 return new_entry_added;
2362} 2394}
2363 2395
@@ -2947,11 +2979,12 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2947 memcpy (&key_value, &(put->key), sizeof (uint64_t)); 2979 memcpy (&key_value, &(put->key), sizeof (uint64_t));
2948 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity))) 2980 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
2949 { 2981 {
2950 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer); 2982 GDS_ROUTING_print();
2951 if (next_hop == NULL) 2983 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer);
2952 { 2984 if (next_hop == NULL)
2985 {
2953 /* refer to handle_dht_p2p_trail_setup. */ 2986 /* refer to handle_dht_p2p_trail_setup. */
2954 } 2987 }
2955 } 2988 }
2956 else 2989 else
2957 { 2990 {
@@ -3044,11 +3077,12 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
3044 memcpy (&key_value, &(get->key), sizeof (uint64_t)); 3077 memcpy (&key_value, &(get->key), sizeof (uint64_t));
3045 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity))) 3078 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
3046 { 3079 {
3047 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer); 3080 GDS_ROUTING_print();
3048 if (next_hop == NULL) 3081 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer);
3049 { 3082 if (next_hop == NULL)
3083 {
3050 /* refer to handle_dht_p2p_trail_setup. */ 3084 /* refer to handle_dht_p2p_trail_setup. */
3051 } 3085 }
3052 } 3086 }
3053 else 3087 else
3054 { 3088 {
@@ -3245,6 +3279,7 @@ handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
3245 /* Check if you are current_destination or not. */ 3279 /* Check if you are current_destination or not. */
3246 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity))) 3280 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
3247 { 3281 {
3282 GDS_ROUTING_print();
3248 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer); 3283 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer);
3249 /* OPTIMIZATION: Choose a peer from find_successor and choose the closest one. 3284 /* OPTIMIZATION: Choose a peer from find_successor and choose the closest one.
3250 In case the closest one is from routing table and it is NULL, then update 3285 In case the closest one is from routing table and it is NULL, then update
@@ -3282,7 +3317,6 @@ handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
3282 } 3317 }
3283 3318
3284 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); 3319 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
3285
3286 /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */ 3320 /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */
3287 if (PREDECESSOR_FINGER_ID != finger_map_index) 3321 if (PREDECESSOR_FINGER_ID != finger_map_index)
3288 { 3322 {
@@ -3305,7 +3339,6 @@ handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
3305 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); 3339 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
3306 peer_list[trail_length] = my_identity; 3340 peer_list[trail_length] = my_identity;
3307 trail_length++; 3341 trail_length++;
3308
3309 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 3342 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3310 GDS_NEIGHBOURS_send_trail_setup (&source, 3343 GDS_NEIGHBOURS_send_trail_setup (&source,
3311 destination_finger_value, 3344 destination_finger_value,
@@ -3386,8 +3419,13 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
3386 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer), 3419 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
3387 &(trail_result->finger_identity)))) 3420 &(trail_result->finger_identity))))
3388 { 3421 {
3422 /* FIXME: First call GDS_ROUTING_search, only if it returns NULL, call
3423 GDS_ROUTING_add. But in case we have same 3 fields but 1 different next hop
3424 then we should add the entry but in current implementation of GDS_ROUTNG_search
3425 we don't handle it. */
3389 GDS_ROUTING_add (&(trail_result->destination_peer), &(trail_result->finger_identity), 3426 GDS_ROUTING_add (&(trail_result->destination_peer), &(trail_result->finger_identity),
3390 peer, &next_hop); 3427 peer, &next_hop);
3428 GDS_ROUTING_print();
3391 } 3429 }
3392 3430
3393 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 3431 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
@@ -3551,6 +3589,12 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
3551 { 3589 {
3552 int my_index; 3590 int my_index;
3553 3591
3592 if (trail_length == 0)
3593 {
3594 GNUNET_break (0);
3595 return GNUNET_SYSERR;
3596 }
3597
3554 my_index = search_my_index (trail_peer_list, trail_length); 3598 my_index = search_my_index (trail_peer_list, trail_length);
3555 if (my_index == GNUNET_SYSERR) 3599 if (my_index == GNUNET_SYSERR)
3556 { 3600 {
@@ -3999,9 +4043,10 @@ int handle_dht_p2p_trail_teardown(void *cls, const struct GNUNET_PeerIdentity *p
3999 my_index = search_my_index (discarded_trail, discarded_trail_length); 4043 my_index = search_my_index (discarded_trail, discarded_trail_length);
4000 if(GNUNET_SYSERR == my_index) 4044 if(GNUNET_SYSERR == my_index)
4001 return GNUNET_SYSERR; 4045 return GNUNET_SYSERR;
4002 4046
4047 GDS_ROUTING_print();
4003 if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer), 4048 if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer),
4004 &(trail_teardown->destination_peer),peer)) 4049 &(trail_teardown->destination_peer),peer))
4005 { 4050 {
4006 /* Here we get GNUNET_NO, only if there is no matching entry found in routing 4051 /* Here we get GNUNET_NO, only if there is no matching entry found in routing
4007 table. */ 4052 table. */
@@ -4011,7 +4056,6 @@ int handle_dht_p2p_trail_teardown(void *cls, const struct GNUNET_PeerIdentity *p
4011 4056
4012 memcpy (&next_hop, &discarded_trail[my_index + 1], sizeof (struct GNUNET_PeerIdentity)); 4057 memcpy (&next_hop, &discarded_trail[my_index + 1], sizeof (struct GNUNET_PeerIdentity));
4013 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 4058 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4014
4015 GDS_NEIGHBOURS_send_trail_teardown (&(trail_teardown->source_peer), 4059 GDS_NEIGHBOURS_send_trail_teardown (&(trail_teardown->source_peer),
4016 &(trail_teardown->destination_peer), 4060 &(trail_teardown->destination_peer),
4017 discarded_trail, discarded_trail_length, 4061 discarded_trail, discarded_trail_length,
@@ -4022,87 +4066,6 @@ int handle_dht_p2p_trail_teardown(void *cls, const struct GNUNET_PeerIdentity *p
4022} 4066}
4023 4067
4024 4068
4025#if 0
4026/**
4027 * FIXME: we don't send trail teardown to finger for which the trail was setup.
4028 * Trail teardown only aim is to remove entries from the routing table. Destination
4029 * finger does not have any entry in its routing table. So, it does not need
4030 * a trail teardown.
4031 * Core handle for p2p trail tear down messages.
4032 * @param cls closure
4033 * @param message message
4034 * @param peer peer identity this notification is about
4035 * @return GNUNET_OK on success, GNUNET_SYSERR on error
4036 */
4037static
4038int handle_dht_p2p_trail_teardown (void *cls, const struct GNUNET_PeerIdentity *peer,
4039 const struct GNUNET_MessageHeader *message)
4040{
4041 struct PeerTrailTearDownMessage *trail_teardown;
4042 struct GNUNET_PeerIdentity *trail_peer_list;
4043 struct GNUNET_PeerIdentity next_hop;
4044 struct FriendInfo *target_friend;
4045 uint32_t trail_length;
4046 size_t msize;
4047 int my_index;
4048
4049 msize = ntohs (message->size);
4050 if (msize < sizeof (struct PeerTrailTearDownMessage))
4051 {
4052 GNUNET_break_op (0);
4053 return GNUNET_YES;
4054 }
4055
4056 trail_teardown = (struct PeerTrailTearDownMessage *) message;
4057 trail_length = ntohl (trail_teardown->trail_length);
4058
4059 if ((msize < sizeof (struct PeerTrailTearDownMessage) +
4060 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
4061 (trail_length >
4062 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
4063 {
4064 GNUNET_break_op (0);
4065 return GNUNET_YES;
4066 }
4067
4068 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_teardown[1];
4069
4070 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->destination_peer), &my_identity)))
4071 {
4072 /* I am the destination of the trail, but I am not part of trail. I don't
4073 need to remove any entry from my routing table. So, I should not get this
4074 message. */
4075 GNUNET_break (0);
4076 return GNUNET_YES;
4077 }
4078
4079 my_index = search_my_index (trail_peer_list, trail_length);
4080 if(GNUNET_SYSERR == my_index)
4081 return GNUNET_SYSERR;
4082
4083 if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer),
4084 &(trail_teardown->destination_peer),peer))
4085 {
4086 /* Here we get GNUNET_NO, only if there is no matching entry found in routing
4087 table. */
4088 GNUNET_break (0);
4089 return GNUNET_YES;
4090 }
4091
4092 /* I am the last element of the trail. */
4093 if(my_index == trail_length - 1)
4094 return GNUNET_YES;
4095
4096 memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity));
4097 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4098 /* FIXME:add a new field new_first_friend. */
4099 GDS_NEIGHBOURS_send_trail_teardown (&(trail_teardown->source_peer),
4100 &(trail_teardown->destination_peer),
4101 trail_peer_list, trail_length, target_friend);
4102 return GNUNET_YES;
4103}
4104#endif
4105
4106/** 4069/**
4107 * Iterate over finger_peermap, and remove entries with peer as the first element 4070 * Iterate over finger_peermap, and remove entries with peer as the first element
4108 * of their trail. 4071 * of their trail.
@@ -4170,6 +4133,7 @@ handle_core_disconnect (void *cls,
4170 * FIXME: Here do we only remove the entry from our own routing table 4133 * FIXME: Here do we only remove the entry from our own routing table
4171 * or do we also inform other peers which are part of trail. It seems to be 4134 * or do we also inform other peers which are part of trail. It seems to be
4172 * too much of messages exchanged. */ 4135 * too much of messages exchanged. */
4136 GDS_ROUTING_print();
4173 GDS_ROUTING_remove_entry (peer); 4137 GDS_ROUTING_remove_entry (peer);
4174 4138
4175 /* Remove the peer from friend_peermap. */ 4139 /* Remove the peer from friend_peermap. */
@@ -4330,4 +4294,4 @@ GDS_NEIGHBOURS_get_my_id (void)
4330} 4294}
4331 4295
4332 4296
4333/* end of gnunet-service-xdht_neighbours.c */ 4297/* end of gnunet-service-xdht_neighbours.c */ \ No newline at end of file
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c
index 3601a4186..7bf96e9d0 100644
--- a/src/dht/gnunet-service-xdht_routing.c
+++ b/src/dht/gnunet-service-xdht_routing.c
@@ -34,11 +34,6 @@
34 3. do we need next_hop to uniquely identify a trail in remove_trail. */ 34 3. do we need next_hop to uniquely identify a trail in remove_trail. */
35 35
36/** 36/**
37 * Number of requests we track at most (for routing replies).
38 */
39#define DHT_MAX_RECENT (1024 * 16)
40
41/**
42 * Maximum number of entries in routing table. 37 * Maximum number of entries in routing table.
43 */ 38 */
44#define ROUTING_TABLE_THRESHOLD 64 39#define ROUTING_TABLE_THRESHOLD 64
@@ -76,59 +71,76 @@ struct RoutingTrail
76 */ 71 */
77static struct GNUNET_CONTAINER_MultiPeerMap *routing_table; 72static struct GNUNET_CONTAINER_MultiPeerMap *routing_table;
78 73
74
79/** 75/**
80 * Iterate over routing table and remove entries for which peer is a part. 76 * Get next hop from the trail with source peer, destination peer and next hop
81 * @param cls closure 77 * same as the argument to this function.
82 * @param key current public key 78 * @param source_peer Source peer of the trail.
83 * @param value value in the hash map 79 * @param destination_peer Destination peer of the trail.
84 * @return #GNUNET_YES if we should continue to 80 * @param prev_hop Previous hop of the trail.
85 * iterate, 81 * @return #GNUNET_YES if we found the matching trail.
86 * #GNUNET_NO if not. 82 * #GNUNET_NO if we found no matching trail.
87 */ 83 */
88static int 84static int
89remove_routing_entry (void *cls, 85get_next_hop (struct RoutingTrail *trail,
90 const struct GNUNET_PeerIdentity *key, 86 struct GNUNET_PeerIdentity *source_peer,
91 void *value) 87 struct GNUNET_PeerIdentity *destination_peer,
88 const struct GNUNET_PeerIdentity *prev_hop)
92{ 89{
93 struct RoutingTrail *remove_entry = value; 90 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(trail->source),source_peer))
94 const struct GNUNET_PeerIdentity *disconnected_peer = cls;
95
96 if ((0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_entry->source), disconnected_peer)) ||
97 (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_entry->destination), disconnected_peer)) ||
98 (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_entry->next_hop), disconnected_peer)) ||
99 (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_entry->prev_hop), disconnected_peer)))
100 { 91 {
101 GNUNET_assert (GNUNET_YES == 92 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(trail->prev_hop),prev_hop))
102 GNUNET_CONTAINER_multipeermap_remove (routing_table, 93 {
103 key, 94 return GNUNET_YES;
104 remove_entry)); 95 }
96 else
97 return GNUNET_NO;
105 } 98 }
106 return GNUNET_YES; 99 return GNUNET_NO;
107} 100}
108 101
109 102
110/** 103/**
111 * Iterate over multiple entries for same destination value and get 104 * FIXME: How to ensure that with only 3 fields also we have a unique trail.
112 * the correct next hop. 105 * in case of redundant routes we can have different next hop.
113 * @param cls struct RoutingTrail 106 * in that case we have to call this function on each entry of routing table
114 * @param key Destination identity 107 * and from multiple next hop we return one. Here also we are going to return one.
115 * @param value struct RoutingTrail 108 * URGENT.
116 * @return #GNUNET_YES to continue looking, #GNUNET_NO if we found the next hop 109 * Assumption - there can be only on one trail with all these fields. But if
110 * we consider only 3 fields then it is possible that next hop is differet.
111 * Update prev_hop field to source_peer. Trail from source peer to destination
112 * peer is compressed such that I am the first friend in the trail.
113 * @param source_peer Source of the trail.
114 * @param destination_peer Destination of the trail.
115 * @param prev_hop Peer before me in the trail.
116 * @return #GNUNET_YES trail is updated.
117 * #GNUNET_NO, trail not found.
117 */ 118 */
118int 119int
119get_next_hop (void *cls, const struct GNUNET_PeerIdentity *key, void *value) 120GDS_ROUTING_trail_update (struct GNUNET_PeerIdentity *source_peer,
121 struct GNUNET_PeerIdentity *destination_peer,
122 struct GNUNET_PeerIdentity *prev_hop)
120{ 123{
121 /* Here you should match if source, prev hop matches if yes then send 124 /* 1. find the trail corresponding to these values.
122 GNUNET_NO as you don't need to check more entries. */ 125 2. update the prev hop to source peer. */
123 struct RoutingTrail *request = cls; 126 struct RoutingTrail *trail;
124 struct RoutingTrail *existing_entry = (struct RoutingTrail *)value; 127 struct GNUNET_CONTAINER_MultiPeerMapIterator *iterator;
128 int i;
125 129
126 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(request->source), &(existing_entry->source))) 130 iterator = GNUNET_CONTAINER_multipeermap_iterator_create (routing_table);
131 for (i = 0; i< GNUNET_CONTAINER_multipeermap_size(routing_table); i++)
127 { 132 {
128 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(request->prev_hop), &(existing_entry->prev_hop))) 133 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iterator, NULL,
134 (const void **)&trail))
129 { 135 {
130 memcpy (&(request->next_hop), &(existing_entry->next_hop), sizeof (struct GNUNET_PeerIdentity)); 136 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(trail->destination), destination_peer))
131 return GNUNET_YES; 137 {
138 if (GNUNET_YES == get_next_hop (trail, source_peer, destination_peer, prev_hop))
139 {
140 memcpy (&(trail->prev_hop), source_peer, sizeof (struct GNUNET_PeerIdentity));
141 return GNUNET_YES;
142 }
143 }
132 } 144 }
133 } 145 }
134 return GNUNET_NO; 146 return GNUNET_NO;
@@ -136,6 +148,42 @@ get_next_hop (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
136 148
137 149
138/** 150/**
151 * Find the next hop to send packet to.
152 * @param source_peer Source of the trail.
153 * @param destination_peer Destination of the trail.
154 * @param prev_hop Previous hop in the trail.
155 * @return Next hop in the trail from source to destination.
156 */
157struct GNUNET_PeerIdentity *
158GDS_ROUTING_search (struct GNUNET_PeerIdentity *source_peer,
159 struct GNUNET_PeerIdentity *destination_peer,
160 const struct GNUNET_PeerIdentity *prev_hop)
161{
162 struct RoutingTrail *trail;
163 struct GNUNET_CONTAINER_MultiPeerMapIterator *iterator;
164 int i;
165
166 iterator = GNUNET_CONTAINER_multipeermap_iterator_create (routing_table);
167 for (i = 0; i< GNUNET_CONTAINER_multipeermap_size(routing_table); i++)
168 {
169 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iterator, NULL,
170 (const void **)&trail))
171 {
172 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(trail->destination), destination_peer))
173 {
174 if (GNUNET_YES == get_next_hop (trail, source_peer, destination_peer, prev_hop))
175 {
176 return &(trail->next_hop);
177 }
178 }
179 }
180 }
181 GNUNET_CONTAINER_multipeermap_iterator_destroy (iterator);
182 return NULL;
183}
184
185
186/**
139 * Add a new entry to our routing table. 187 * Add a new entry to our routing table.
140 * @param source peer Source of the trail. 188 * @param source peer Source of the trail.
141 * @param destintation Destination of the trail. 189 * @param destintation Destination of the trail.
@@ -171,71 +219,100 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *source,
171 219
172/** 220/**
173 * Iterate over routing table and remove entries for which peer is a part. 221 * Iterate over routing table and remove entries for which peer is a part.
174 * @param peer 222 * @param cls closure
175 * @return 223 * @param key current public key
224 * @param value value in the hash map
225 * @return #GNUNET_YES if we should continue to
226 * iterate,
227 * #GNUNET_NO if not.
228 */
229static int
230remove_routing_entry (void *cls,
231 const struct GNUNET_PeerIdentity *key,
232 void *value)
233{
234 struct RoutingTrail *remove_entry = value;
235 const struct GNUNET_PeerIdentity *disconnected_peer = cls;
236
237 if ((0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_entry->source), disconnected_peer)) ||
238 (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_entry->destination), disconnected_peer)) ||
239 (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_entry->next_hop), disconnected_peer)) ||
240 (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_entry->prev_hop), disconnected_peer)))
241 {
242 GNUNET_assert (GNUNET_YES ==
243 GNUNET_CONTAINER_multipeermap_remove (routing_table,
244 key,
245 remove_entry));
246 }
247 return GNUNET_YES;
248}
249
250
251/**
252 * FIXME: add a return value.
253 * Iterate over routing table and remove all entries for which peer is a part.
254 * @param peer Peer to be searched for in the trail to remove that trail.
176 */ 255 */
177void 256void
178GDS_ROUTING_remove_entry (const struct GNUNET_PeerIdentity *peer) 257GDS_ROUTING_remove_entry (const struct GNUNET_PeerIdentity *peer)
179{ 258{
180 GNUNET_CONTAINER_multipeermap_iterate (routing_table, &remove_routing_entry, 259 GNUNET_CONTAINER_multipeermap_iterate (routing_table, &remove_routing_entry,
181 (void *)peer); 260 (void *)peer);
182} 261}
183 262
184 263
185/** FIXME:TODO URGNET Need to understand if we need next hop to uniquely identify an entry 264/**
186 * in routing table or not. 265 * In response to trail teardown message, remove the trail with source peer,
187 * Remove the trail as result of trail tear down message. 266 * destination peer and next hop same as the argument to this function.
267 * Assumption - there can be only one possible trail with these 4 values.
188 * @param source_peer Source of the trail. 268 * @param source_peer Source of the trail.
189 * @param destination_peer Destination of the trail. 269 * @param destination_peer Destination of the trail.
190 * @param next_hop Next hop 270 * @param next_hop Next hop
191 * @param prev_hop Previous hop. 271 * @param prev_hop Previous hop.
272 * @return #GNUNET_YES Matching trail deleted from routing table.
273 * #GNUNET_NO No matching trail found.
274 *
192 */ 275 */
193int 276int
194GDS_ROUTING_remove_trail (struct GNUNET_PeerIdentity *source_peer, 277GDS_ROUTING_remove_trail (struct GNUNET_PeerIdentity *source_peer,
195 struct GNUNET_PeerIdentity *destination_peer, 278 struct GNUNET_PeerIdentity *destination_peer,
196 const struct GNUNET_PeerIdentity *prev_hop) 279 const struct GNUNET_PeerIdentity *prev_hop)
197{ 280{
281 struct RoutingTrail *trail;
282 struct GNUNET_CONTAINER_MultiPeerMapIterator *iterator;
283 int i;
284
285 iterator = GNUNET_CONTAINER_multipeermap_iterator_create (routing_table);
286 for (i = 0; i< GNUNET_CONTAINER_multipeermap_size(routing_table); i++)
287 {
288 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iterator, NULL,
289 (const void **)&trail))
290 {
291 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(trail->destination), destination_peer))
292 {
293 GNUNET_assert (GNUNET_YES ==
294 GNUNET_CONTAINER_multipeermap_remove (routing_table,
295 &(trail->destination),
296 trail));
297 return GNUNET_YES;
298 }
299 }
300 }
301 GNUNET_CONTAINER_multipeermap_iterator_destroy (iterator);
198 return GNUNET_NO; 302 return GNUNET_NO;
199} 303}
200 304
201/**
202 * Find the next hop to send packet to.
203 * @param source_peer Source of the trail.
204 * @param destination_peer Destination of the trail.
205 * @param prev_hop Previous hop in the trail.
206 * @return Next hop in the trail from source to destination.
207 */
208struct GNUNET_PeerIdentity *
209GDS_ROUTING_search(struct GNUNET_PeerIdentity *source_peer,
210 struct GNUNET_PeerIdentity *destination_peer,
211 const struct GNUNET_PeerIdentity *prev_hop)
212{
213 struct RoutingTrail *trail;
214 trail = GNUNET_malloc (sizeof (struct RoutingTrail));
215 memcpy (&(trail->destination), destination_peer, sizeof (struct GNUNET_PeerIdentity));
216 memcpy (&(trail->source), source_peer, sizeof (struct GNUNET_PeerIdentity));
217 memcpy (&(trail->prev_hop), prev_hop, sizeof (struct GNUNET_PeerIdentity));
218
219 GNUNET_CONTAINER_multipeermap_get_multiple (routing_table, destination_peer,
220 get_next_hop, trail);
221 if(trail != NULL)
222 return &(trail->next_hop);
223 else
224 return NULL;
225}
226 305
227 306
228/** 307/**
229 * FIXME:URGENT:Better name.
230 * Check if the size of routing table has crossed threshold. 308 * Check if the size of routing table has crossed threshold.
231 * @return #GNUNET_YES, if threshold crossed else #GNUNET_NO. 309 * @return #GNUNET_YES, if threshold crossed else #GNUNET_NO.
232 */ 310 */
233int 311int
234GDS_ROUTING_check_threshold () 312GDS_ROUTING_check_threshold ()
235{ 313{
236 int ret; 314 return (GNUNET_CONTAINER_multipeermap_size(routing_table) > ROUTING_TABLE_THRESHOLD) ?
237 ret = (GNUNET_CONTAINER_multipeermap_size(routing_table) > ROUTING_TABLE_THRESHOLD) ? GNUNET_YES:GNUNET_NO; 315 GNUNET_YES:GNUNET_NO;
238 return ret;
239} 316}
240 317
241 318
@@ -245,11 +322,42 @@ GDS_ROUTING_check_threshold ()
245void 322void
246GDS_ROUTING_init (void) 323GDS_ROUTING_init (void)
247{ 324{
248 routing_table = GNUNET_CONTAINER_multipeermap_create (DHT_MAX_RECENT * 4 / 3, GNUNET_NO); 325 routing_table = GNUNET_CONTAINER_multipeermap_create (ROUTING_TABLE_THRESHOLD * 4 / 3,
326 GNUNET_NO);
249} 327}
250 328
251
252/** 329/**
330 * ONLY FOR TESTING.
331 */
332void
333GDS_ROUTING_print (void)
334{
335 struct RoutingTrail *trail;
336 struct GNUNET_CONTAINER_MultiPeerMapIterator *iterator;
337 int i;
338
339 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing table entries \n");
340 iterator = GNUNET_CONTAINER_multipeermap_iterator_create (routing_table);
341 for (i = 0; i< GNUNET_CONTAINER_multipeermap_size(routing_table); i++)
342 {
343 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iterator, NULL,
344 (const void **)&trail))
345 {
346 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing trail source \n", GNUNET_i2s (&(trail->source)));
347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing trail source \n", GNUNET_i2s (&(trail->destination)));
348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing trail source \n", GNUNET_i2s (&(trail->next_hop)));
349 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing trail source \n", GNUNET_i2s (&(trail->prev_hop)));
350 }
351 }
352
353}
354/**
355 * FIXME: here you can have routing table with size 0, only when you delete
356 * the entries correctly. Possible scenarios where we delete the entries are
357 * 1. when one of my friend gets disconnected then I remove any trail (does not
358 * matter if that friend is source, destination, next hop or previous hop).
359 * 2. if I get a trail teardown message then I remove the entry.
360 * Is there any other case that I may have missed?
253 * Shutdown routing subsystem. 361 * Shutdown routing subsystem.
254 */ 362 */
255void 363void
diff --git a/src/dht/gnunet-service-xdht_routing.h b/src/dht/gnunet-service-xdht_routing.h
index 63007c7e4..0b0c80862 100644
--- a/src/dht/gnunet-service-xdht_routing.h
+++ b/src/dht/gnunet-service-xdht_routing.h
@@ -78,6 +78,11 @@ GDS_ROUTING_remove_trail (struct GNUNET_PeerIdentity *source_peer,
78 struct GNUNET_PeerIdentity *destination_peer, 78 struct GNUNET_PeerIdentity *destination_peer,
79 const struct GNUNET_PeerIdentity *prev_hop); 79 const struct GNUNET_PeerIdentity *prev_hop);
80 80
81/**
82 * FOR TESTING.
83 */
84void
85GDS_ROUTING_print (void);
81 86
82/** 87/**
83 * Check if size of routing table is greater than threshold or not. 88 * Check if size of routing table is greater than threshold or not.