aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-05-20 11:15:15 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-05-20 11:15:15 +0000
commit658c986e1ff9a95369f8ada3ae2be16cd2c1d170 (patch)
treea1b77a7ce2ef1d2781928da64694eb5e82a73d08 /src/dht
parent8d5da67b9a88e45c184eb679505afd9ea15eda42 (diff)
downloadgnunet-658c986e1ff9a95369f8ada3ae2be16cd2c1d170.tar.gz
gnunet-658c986e1ff9a95369f8ada3ae2be16cd2c1d170.zip
- Adding code to check for congestion and threshold in find_successor()
- Updating trail rejection to get congestion time from congested peer.
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c295
1 files changed, 247 insertions, 48 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index 733d3daa3..29efc4c57 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -56,6 +56,9 @@
56 5. At some places you use memcpy and at some places =, use uniformly. 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 57 6. I have removed compare_and_update_predecessor from handle_dht_p2p_Trail_setup
58 * (refer to google docs for reason). 58 * (refer to google docs for reason).
59 7. when to use GNUNET_ntohll and when to use ntohl.
60 8. everywhere check if you should use GNUNET_htonll for key value which is 64 bit
61 * right now you are doing memcpy which does not seem correct.
59*/ 62*/
60 63
61/** 64/**
@@ -79,6 +82,12 @@
79#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) 82#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
80 83
81/** 84/**
85 * How long will I remain congested?
86 */
87#define CONGESTION_TIMEOUT GNUNET_TIME_relative_get_minute_()
88
89
90/**
82 * Maximum number of trails stored per finger. 91 * Maximum number of trails stored per finger.
83 */ 92 */
84#define TRAILS_COUNT 2 93#define TRAILS_COUNT 2
@@ -379,6 +388,11 @@ struct PeerTrailRejectionMessage
379 */ 388 */
380 uint32_t trail_length; 389 uint32_t trail_length;
381 390
391 /**
392 * Relative time for which congested_peer will remain congested.
393 */
394 struct GNUNET_TIME_Relative congestion_time;
395
382 /* Trail_list from source_peer to peer which sent the message for trail setup 396 /* Trail_list from source_peer to peer which sent the message for trail setup
383 * to congested peer.*/ 397 * to congested peer.*/
384}; 398};
@@ -627,16 +641,7 @@ struct FriendInfo
627 unsigned int pending_count; 641 unsigned int pending_count;
628 642
629 /** 643 /**
630 * FIXME: Refer to time.c and gnunet_time_lib.h for correct functions. 644
631 * in handle_dht_p2p_trail_rejection, you should update these values
632 * and whenever you are selecting a friend in select_random_friend()
633 * and find_successor(), you should check congestion_duration = 0,
634 * then proceed else if congestion_duration < your current time then also
635 * proceed.
636 * struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();
637 * struct GNUNET_TIME_Relative congestion_timeout =
638 * congestion_duration = GNUNET_TIME_absolute_add (start,congestion_timeout);
639 * in select_random_friend, GNUNET_TIME_absolute_get_remaning()
640 */ 645 */
641 struct GNUNET_TIME_Absolute congestion_duration; 646 struct GNUNET_TIME_Absolute congestion_duration;
642 647
@@ -2395,6 +2400,45 @@ int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2395 2400
2396 2401
2397/** 2402/**
2403 * Check if the successor chosen is congested or has crossed trail threshold.
2404 * @param successor Successor to be checked.
2405 * @return #GNUNET_YES in case its is either congested or has crossed trail threshold.
2406 * #GNUNET_NO if its good to go.
2407 */
2408static int
2409check_friend_threshold_and_congestion (struct Sorting_List *successor)
2410{
2411 struct FriendInfo *friend;
2412
2413 if (successor->type == FRIEND)
2414 {
2415 friend = successor->data;
2416 }
2417 else if (successor->type == FINGER)
2418 {
2419 struct FingerInfo *finger = successor->data;
2420 if (finger->first_trail_length > 0)
2421 {
2422 friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2423 &(finger->first_trail_head->peer));
2424 }
2425 else
2426 {
2427 friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger->finger_identity));
2428 }
2429 }
2430
2431 if ((friend->trails_count == TRAIL_THROUGH_FRIEND_THRESHOLD)||
2432 ((0 != GNUNET_TIME_absolute_get_remaining (friend->congestion_duration).rel_value_us)))
2433 {
2434 return GNUNET_YES;
2435 }
2436 else
2437 return GNUNET_NO;
2438}
2439
2440
2441/**
2398 * 2442 *
2399 * @param all_known_peers 2443 * @param all_known_peers
2400 * @param array_size 2444 * @param array_size
@@ -2404,52 +2448,201 @@ int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2404 */ 2448 */
2405static struct Sorting_List * 2449static struct Sorting_List *
2406get_next_successor (struct Sorting_List *all_known_peers, 2450get_next_successor (struct Sorting_List *all_known_peers,
2407 unsigned int array_size, 2451 unsigned int array_size, int start_index,
2408 struct FriendInfo *friend, 2452 int search_index, int count)
2409 uint64_t key_value)
2410{ 2453{
2411 /* 1. search friend in all_known_peers. 2454 struct Sorting_List *next_peer;
2412 2. get the next peer. if peer == my_identity or peer == value, then go to 2455
2413 next element. 2456 if (search_index == start_index)
2414 3. if friend then again check if threshold crossed or not . If not then return 2457 return NULL;
2415 or else again increment. remember starting index of friend in all_known_peers 2458 next_peer = GNUNET_malloc (sizeof (struct Sorting_List));
2416 and when you reach to it again then return NULL as it means all the friend 2459 memcpy (next_peer, &all_known_peers[search_index], sizeof (struct Sorting_List));
2417 are congested or threshold reached. 2460
2418 */ 2461 if ((next_peer->type == VALUE) ||
2419 return NULL; 2462 (GNUNET_YES == check_friend_threshold_and_congestion (next_peer)))
2463 {
2464 search_index = (search_index + 1) % array_size;
2465 count++;
2466 return get_next_successor (all_known_peers, array_size, start_index, search_index, count);
2467 }
2468 else
2469 return next_peer;
2420} 2470}
2421 2471
2422 2472
2423/** 2473/**
2424 * Check if the friend is congested or has crossed TRAIL_THRESHOLD. If yes 2474 *
2425 * then choose the peer next to it in the array. In case number of times this
2426 * function is called is equal to total number of entries in the array then it
2427 * means that none of the friends are busy. But remember in this array you also
2428 * have your own identity, value that you were searching, You should skip those
2429 * and also keep the count = size -2. But if we call in this order is our get/put
2430 * not getting wrong.
2431 * @param all_known_peers 2475 * @param all_known_peers
2432 * @param array_size 2476 * @param array_size
2433 * @param friend Friend to be checked if 2477 * @param search_value
2434 * @param key_value To be ignored 2478 * @return
2435 * @return #GNUNET_YES
2436 * #GNUNET_NO
2437 */ 2479 */
2438static int 2480static int
2439check_friend_threshold_and_congestion (struct Sorting_List *all_known_peers, 2481get_friend_location (struct Sorting_List *all_known_peers, size_t array_size,
2440 unsigned int array_size, 2482 uint64_t search_value)
2441 struct FriendInfo *friend, 2483{
2442 uint64_t key_value) 2484 int k;
2443{ 2485
2444 if (friend->trails_count == TRAIL_THROUGH_FRIEND_THRESHOLD) 2486 while (0 != memcmp (&all_known_peers[k], &search_value, sizeof (uint64_t)))
2445 { 2487 {
2446 return GNUNET_YES; 2488 k++;
2447 } 2489 }
2448 return GNUNET_NO; 2490 if (k == array_size)
2491 return GNUNET_SYSERR;
2492 else
2493 return k;
2449} 2494}
2450 2495
2451 2496
2452/** 2497/**
2498 * Initialize all_known_peers with my_id, value, friends and fingers.
2499 * @param all_known_peers Empty all_known_peers
2500 * @param size Total number of elements in all_known_peers
2501 */
2502static void
2503init_all_known_peers (struct Sorting_List *all_known_peers, int size, uint64_t value)
2504{
2505 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
2506 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2507 struct GNUNET_PeerIdentity key_ret;
2508 struct FriendInfo *friend;
2509 struct FingerInfo *finger;
2510 unsigned int finger_index;
2511 unsigned int friend_index;
2512 int k;
2513 int j;
2514
2515 for (k = 0; k < size; k++)
2516 all_known_peers[k].peer_id = 0;
2517
2518 /* Copy your identity at 0th index in all_known_peers. */
2519 j = 0;
2520 memcpy (&(all_known_peers[j].peer_id), &my_identity, sizeof (uint64_t));
2521 all_known_peers[j].type = MY_ID;
2522 all_known_peers[j].data = 0;
2523 j++;
2524
2525 /* Copy value */
2526 all_known_peers[j].peer_id = value;
2527 all_known_peers[j].type = VALUE;
2528 all_known_peers[j].data = 0;
2529 j++;
2530
2531 /* Iterate over friend peer map and copy all the elements into array. */
2532 friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
2533 for (friend_index = 0; friend_index < GNUNET_CONTAINER_multipeermap_size (friend_peermap); friend_index++)
2534 {
2535 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(friend_iter,&key_ret,(const void **)&friend))
2536 {
2537 memcpy (&(all_known_peers[j].peer_id), &(friend->id), sizeof (uint64_t));
2538 all_known_peers[j].type = FRIEND;
2539 all_known_peers[j].data = friend;
2540 j++;
2541 }
2542 }
2543
2544
2545 /* Iterate over finger map and copy all the entries into all_known_peers array. */
2546 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
2547 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
2548 {
2549 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(finger_iter,&key_ret,(const void **)&finger))
2550 {
2551 memcpy (&(all_known_peers[j].peer_id), &(finger->finger_identity), sizeof (uint64_t));
2552 all_known_peers[j].type = FINGER;
2553 all_known_peers[j].data = finger;
2554 j++;
2555 }
2556 }
2557
2558 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2559 GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter);
2560}
2561
2562/** Find closest successor for the value.
2563 * @param value Value for which we are looking for successor
2564 * @param[out] current_destination set to my_identity in case I am the final destination,
2565 * set to friend identity in case friend is final destination,
2566 * set to first friend to reach to finger, in case finger
2567 * is final destination.
2568 * @param[out] current_source set to my_identity.
2569 * @param finger_map_index Index in finger peer map.
2570 * @return Peer identity of next hop to send trail setup message to,
2571 * NULL in case all the friends are either congested or have crossed
2572 * their trail threshold.
2573 */
2574static struct GNUNET_PeerIdentity *
2575find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2576 struct GNUNET_PeerIdentity *current_source, unsigned int finger_map_index)
2577{
2578 struct Sorting_List *successor;
2579 unsigned int size;
2580
2581 size = GNUNET_CONTAINER_multipeermap_size (friend_peermap)+
2582 GNUNET_CONTAINER_multipeermap_size (finger_peermap)+
2583 2;
2584
2585 struct Sorting_List all_known_peers[size];
2586 init_all_known_peers (all_known_peers, size, value);
2587 qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id);
2588
2589 if (PREDECESSOR_FINGER_ID == finger_map_index)
2590 successor = find_closest_predecessor (all_known_peers, value, size);
2591 else
2592 successor = find_closest_successor (all_known_peers, value, size);
2593
2594 if ((successor->type != MY_ID) && (successor->type != VALUE))
2595 {
2596 if (GNUNET_YES == check_friend_threshold_and_congestion (successor))
2597 {
2598 int search_index = get_friend_location (all_known_peers, size, successor->peer_id);
2599 successor = get_next_successor (all_known_peers, size, search_index, search_index + 1, 0);
2600 }
2601 }
2602
2603 if (successor->type == MY_ID)
2604 {
2605 memcpy (current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2606 return &my_identity;
2607 }
2608 else if (successor->type == FRIEND)
2609 {
2610 struct FriendInfo *target_friend = successor->data;
2611 memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
2612 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2613 return current_destination;
2614 }
2615 else if (successor->type == FINGER)
2616 {
2617 struct GNUNET_PeerIdentity *next_hop;
2618 struct FingerInfo *finger;
2619 finger = successor->data;
2620 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2621
2622 if (finger->first_trail_length > 0)
2623 {
2624 struct TrailPeerList *iterator;
2625 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
2626 iterator = finger->first_trail_head;
2627 memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
2628 }
2629 else /* This means finger is our friend. */
2630 memcpy (next_hop, &(finger->finger_identity), sizeof(struct GNUNET_PeerIdentity));
2631
2632 memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
2633 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2634 return next_hop;
2635 }
2636 else
2637 {
2638 /* It means all the peers known to me are either congested or has crossed
2639 trial threshold. */
2640 return NULL;
2641 }
2642}
2643
2644#if 0
2645/**
2453 * FIXME: Complete the code for checking the threshold and getting the next 2646 * FIXME: Complete the code for checking the threshold and getting the next
2454 * peer, add the case in finger. 2647 * peer, add the case in finger.
2455 * In case a friend is either congested or has crossed its trail threshold, 2648 * In case a friend is either congested or has crossed its trail threshold,
@@ -2536,7 +2729,6 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2536 2729
2537 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); 2730 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2538 GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter); 2731 GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter);
2539
2540 2732
2541 qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id); 2733 qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id);
2542 2734
@@ -2557,7 +2749,8 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2557 target_friend = (struct FriendInfo *)successor->data; 2749 target_friend = (struct FriendInfo *)successor->data;
2558 if( GNUNET_YES == check_friend_threshold_and_congestion (all_known_peers, size, target_friend, value)) 2750 if( GNUNET_YES == check_friend_threshold_and_congestion (all_known_peers, size, target_friend, value))
2559 { 2751 {
2560 get_next_successor (all_known_peers, size, friend, value); 2752 int search_index = get_friend_location (all_known_peers);
2753 get_next_successor (all_known_peers, size, search_index, search_index + 1, 0);
2561 } 2754 }
2562 memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity)); 2755 memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
2563 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity)); 2756 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
@@ -2590,7 +2783,7 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2590 return NULL; 2783 return NULL;
2591 } 2784 }
2592} 2785}
2593 2786#endif
2594 2787
2595/** 2788/**
2596 * Construct a Put message and send it to target_peer. 2789 * Construct a Put message and send it to target_peer.
@@ -2887,7 +3080,8 @@ GDS_NEIGHBOURS_send_trail_rejection (const struct GNUNET_PeerIdentity *source_pe
2887 const struct GNUNET_PeerIdentity *next_hop, 3080 const struct GNUNET_PeerIdentity *next_hop,
2888 unsigned int finger_map_index, 3081 unsigned int finger_map_index,
2889 struct GNUNET_PeerIdentity *trail_peer_list, 3082 struct GNUNET_PeerIdentity *trail_peer_list,
2890 unsigned int trail_length) 3083 unsigned int trail_length,
3084 struct GNUNET_TIME_Relative congestion_timeout)
2891{ 3085{
2892 struct PeerTrailRejectionMessage *trail_rejection; 3086 struct PeerTrailRejectionMessage *trail_rejection;
2893 struct GNUNET_PeerIdentity *trail_list; 3087 struct GNUNET_PeerIdentity *trail_list;
@@ -2916,6 +3110,7 @@ GDS_NEIGHBOURS_send_trail_rejection (const struct GNUNET_PeerIdentity *source_pe
2916 memcpy (&(trail_rejection->finger_identity_value), &finger_identity, sizeof (uint64_t)); 3110 memcpy (&(trail_rejection->finger_identity_value), &finger_identity, sizeof (uint64_t));
2917 trail_rejection->finger_map_index = htonl (finger_map_index); 3111 trail_rejection->finger_map_index = htonl (finger_map_index);
2918 trail_rejection->trail_length = htonl (trail_length); 3112 trail_rejection->trail_length = htonl (trail_length);
3113 trail_rejection->congestion_time = congestion_timeout;
2919 3114
2920 if (trail_length != 0) 3115 if (trail_length != 0)
2921 { 3116 {
@@ -3416,7 +3611,8 @@ handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
3416 if (GNUNET_YES == GDS_ROUTING_check_threshold()) 3611 if (GNUNET_YES == GDS_ROUTING_check_threshold())
3417 { 3612 {
3418 GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity, 3613 GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity,
3419 peer, finger_map_index, trail_peer_list, trail_length); 3614 peer, finger_map_index, trail_peer_list, trail_length,
3615 CONGESTION_TIMEOUT);
3420 return GNUNET_OK; 3616 return GNUNET_OK;
3421 } 3617 }
3422 3618
@@ -3968,6 +4164,7 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *
3968 uint32_t trail_length; 4164 uint32_t trail_length;
3969 uint32_t finger_map_index; 4165 uint32_t finger_map_index;
3970 uint64_t destination_finger_value; 4166 uint64_t destination_finger_value;
4167 struct GNUNET_TIME_Relative congestion_timeout;
3971 size_t msize; 4168 size_t msize;
3972 4169
3973 msize = ntohs (message->size); 4170 msize = ntohs (message->size);
@@ -3994,10 +4191,12 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *
3994 finger_map_index = ntohl (trail_rejection->finger_map_index); 4191 finger_map_index = ntohl (trail_rejection->finger_map_index);
3995 memcpy (&destination_finger_value, &(trail_rejection->finger_identity_value), sizeof (uint64_t)); 4192 memcpy (&destination_finger_value, &(trail_rejection->finger_identity_value), sizeof (uint64_t));
3996 memcpy (&source, &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity)); 4193 memcpy (&source, &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
4194 congestion_timeout = trail_rejection->congestion_time;
3997 4195
3998 /* First set the congestion time of the friend that sent you this message. */ 4196 /* First set the congestion time of the friend that sent you this message. */
3999 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer); 4197 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
4000 //FIXME: target_friend->congestion_time ==? 4198 target_friend->congestion_duration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
4199 congestion_timeout);
4001 4200
4002 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(trail_rejection->source_peer)))) 4201 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(trail_rejection->source_peer))))
4003 { 4202 {
@@ -4026,7 +4225,7 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *
4026 GDS_NEIGHBOURS_send_trail_rejection (&(trail_rejection->source_peer), 4225 GDS_NEIGHBOURS_send_trail_rejection (&(trail_rejection->source_peer),
4027 destination_finger_value, 4226 destination_finger_value,
4028 &my_identity, &next_hop,finger_map_index, 4227 &my_identity, &next_hop,finger_map_index,
4029 new_trail,new_trail_length); 4228 new_trail,new_trail_length, CONGESTION_TIMEOUT);
4030 return GNUNET_YES; 4229 return GNUNET_YES;
4031 } 4230 }
4032 4231