aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-xdht_neighbours.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-xdht_neighbours.c')
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c188
1 files changed, 76 insertions, 112 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