aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-08-28 20:09:30 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-08-28 20:09:30 +0000
commit6c20cb042f548dbd98a89ed457c82212090ea7b0 (patch)
tree36cf658d4b43376b7ee2a4e52ff73507c6641647 /src
parent19d2226cb1957fbe7e5f825b87849b6028615a19 (diff)
downloadgnunet-6c20cb042f548dbd98a89ed457c82212090ea7b0.tar.gz
gnunet-6c20cb042f548dbd98a89ed457c82212090ea7b0.zip
Readding trail compression to check if it can reduce trail length
Diffstat (limited to 'src')
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c306
-rw-r--r--src/include/gnunet_protocols.h7
2 files changed, 293 insertions, 20 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index 91e96d8a8..c328a6734 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -118,7 +118,7 @@
118/** 118/**
119 * Maximum number of trails stored per finger. 119 * Maximum number of trails stored per finger.
120 */ 120 */
121#define MAXIMUM_TRAILS_PER_FINGER 1 121#define MAXIMUM_TRAILS_PER_FINGER 2
122 122
123/** 123/**
124 * Finger map index for predecessor entry in finger table. 124 * Finger map index for predecessor entry in finger table.
@@ -630,6 +630,34 @@ struct PeerAddTrailMessage
630 */ 630 */
631}; 631};
632 632
633/**
634 * P2P Trail Compression Message.
635 */
636struct PeerTrailCompressionMessage
637{
638 /**
639 * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_COMPRESSION
640 */
641 struct GNUNET_MessageHeader header;
642
643 /**
644 * Source peer of this trail.
645 */
646 struct GNUNET_PeerIdentity source_peer;
647
648 /**
649 * Trail from source_peer to destination_peer compressed such that
650 * new_first_friend is the first hop in the trail from source to
651 * destination.
652 */
653 struct GNUNET_PeerIdentity new_first_friend;
654
655 /**
656 * Unique identifier of trail.
657 */
658 struct GNUNET_HashCode trail_id;
659};
660
633GNUNET_NETWORK_STRUCT_END 661GNUNET_NETWORK_STRUCT_END
634 662
635/** 663/**
@@ -1452,6 +1480,55 @@ GDS_NEIGHBOURS_send_trail_teardown (struct GNUNET_HashCode trail_id,
1452 process_friend_queue (target_friend); 1480 process_friend_queue (target_friend);
1453} 1481}
1454 1482
1483/**
1484 * Construct a trail compression message and send it to target_friend.
1485 * @param source_peer Source of the trail.
1486 * @param trail_id Unique identifier of trail.
1487 * @param first_friend First hop in compressed trail to reach from source to finger
1488 * @param target_friend Next friend to get this message.
1489 */
1490void
1491GDS_NEIGHBOURS_send_trail_compression (struct GNUNET_PeerIdentity source_peer,
1492 struct GNUNET_HashCode trail_id,
1493 struct GNUNET_PeerIdentity first_friend,
1494 struct FriendInfo *target_friend)
1495{
1496 struct P2PPendingMessage *pending;
1497 struct PeerTrailCompressionMessage *tcm;
1498 size_t msize;
1499
1500 msize = sizeof (struct PeerTrailCompressionMessage);
1501
1502 if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1503 {
1504 GNUNET_break (0);
1505 return;
1506 }
1507
1508 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1509 {
1510 GNUNET_STATISTICS_update (GDS_stats,
1511 gettext_noop ("# P2P messages dropped due to full queue"),
1512 1, GNUNET_NO);
1513 }
1514
1515 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1516 pending->importance = 0; /* FIXME */
1517 pending->timeout = GNUNET_TIME_relative_to_absolute (PENDING_MESSAGE_TIMEOUT);
1518 tcm = (struct PeerTrailCompressionMessage *) &pending[1];
1519 pending->msg = &tcm->header;
1520 tcm->header.size = htons (msize);
1521 tcm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_COMPRESSION);
1522 tcm->source_peer = source_peer;
1523 tcm->new_first_friend = first_friend;
1524 tcm->trail_id = trail_id;
1525
1526 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1527 target_friend->pending_count++;
1528 process_friend_queue (target_friend);
1529
1530}
1531
1455 1532
1456/** 1533/**
1457 * Construct a verify successor result message and send it to target_friend 1534 * Construct a verify successor result message and send it to target_friend
@@ -3451,6 +3528,187 @@ remove_existing_finger (struct FingerInfo *existing_finger,
3451 return; 3528 return;
3452} 3529}
3453 3530
3531/*
3532 * Core handle for p2p trail tear compression messages.
3533 * @param cls closure
3534 * @param message message
3535 * @param peer peer identity this notification is about
3536 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3537 */
3538static int
3539handle_dht_p2p_trail_compression (void *cls, const struct GNUNET_PeerIdentity *peer,
3540 const struct GNUNET_MessageHeader *message)
3541{
3542 const struct PeerTrailCompressionMessage *trail_compression;
3543 struct GNUNET_PeerIdentity *next_hop;
3544 struct FriendInfo *target_friend;
3545 struct GNUNET_HashCode trail_id;
3546 size_t msize;
3547
3548 msize = ntohs (message->size);
3549
3550 if (msize != sizeof (struct PeerTrailCompressionMessage))
3551 {
3552 GNUNET_break_op (0);
3553 return GNUNET_OK;
3554 }
3555
3556 GNUNET_STATISTICS_update (GDS_stats,
3557 gettext_noop
3558 ("# Bytes received from other peers"), msize,
3559 GNUNET_NO);
3560
3561 trail_compression = (const struct PeerTrailCompressionMessage *) message;
3562 trail_id = trail_compression->trail_id;
3563
3564 /* Am I the new first friend to reach to finger of this trail. */
3565 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&trail_compression->new_first_friend,
3566 &my_identity)))
3567 {
3568 if (NULL ==
3569 (GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3570 &trail_compression->source_peer)))
3571 {
3572 GNUNET_break_op(0);
3573 return GNUNET_OK;
3574 }
3575
3576 /* Update your prev hop to source of this message. */
3577 if(GNUNET_SYSERR ==
3578 (GDS_ROUTING_update_trail_prev_hop (trail_id,
3579 trail_compression->source_peer)))
3580 {
3581 GNUNET_break(0);
3582 return GNUNET_OK;
3583 }
3584 return GNUNET_OK;
3585 }
3586
3587 /* Pass the message to next hop to finally reach to new_first_friend. */
3588 next_hop = GDS_ROUTING_get_next_hop (trail_id, GDS_ROUTING_SRC_TO_DEST);
3589
3590 if (NULL == next_hop)
3591 {
3592 GNUNET_break (0);
3593 return GNUNET_OK;
3594 }
3595
3596 if( NULL == (target_friend =
3597 GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop)))
3598 {
3599 GNUNET_break_op(0);
3600 return GNUNET_OK;
3601 }
3602
3603 GDS_ROUTING_remove_trail (trail_id);
3604
3605 GDS_NEIGHBOURS_send_trail_compression (trail_compression->source_peer,
3606 trail_id,
3607 trail_compression->new_first_friend,
3608 target_friend);
3609 return GNUNET_OK;
3610}
3611
3612
3613/**
3614 * Scan the trail to check if there is any other friend in the trail other than
3615 * first hop. If yes then shortcut the trail, send trail compression message to
3616 * peers which are no longer part of trail and send back the updated trail
3617 * and trail_length to calling function.
3618 * @param finger_identity Finger whose trail we will scan.
3619 * @param finger_trail [in, out] Trail to reach from source to finger,
3620 * @param finger_trail_length Total number of peers in original finger_trail.
3621 * @param finger_trail_id Unique identifier of the finger trail.
3622 * @return updated trail length in case we shortcut the trail, else original
3623 * trail length.
3624 */
3625static struct GNUNET_PeerIdentity *
3626scan_and_compress_trail (struct GNUNET_PeerIdentity finger_identity,
3627 const struct GNUNET_PeerIdentity *trail,
3628 unsigned int trail_length,
3629 struct GNUNET_HashCode trail_id,
3630 int *new_trail_length)
3631{
3632 struct FriendInfo *target_friend;
3633 struct GNUNET_PeerIdentity *new_trail;
3634 unsigned int i;
3635
3636 /* I am my own finger. */
3637 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &finger_identity))
3638 {
3639 *new_trail_length = 0;
3640 return NULL;
3641 }
3642
3643 if (0 == trail_length)
3644 {
3645 *new_trail_length = 0;
3646 return NULL;
3647 }
3648
3649 /* If finger identity is a friend. */
3650 if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_identity))
3651 {
3652 *new_trail_length = 0;
3653
3654 /* If there is trail to reach this finger/friend */
3655 if (trail_length > 0)
3656 {
3657 /* Finger is your first friend. */
3658 GDS_ROUTING_update_trail_next_hop (trail_id, finger_identity);
3659 GNUNET_assert (NULL !=
3660 (target_friend =
3661 GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3662 &trail[0])));
3663
3664
3665 GDS_NEIGHBOURS_send_trail_compression (my_identity,
3666 trail_id, finger_identity,
3667 target_friend);
3668 }
3669 return NULL;
3670 }
3671
3672 /* For other cases, when its neither a friend nor my own identity.*/
3673 for (i = trail_length - 1; i > 0; i--)
3674 {
3675 /* If the element at this index in trail is a friend. */
3676 if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[i]))
3677 {
3678 struct FriendInfo *target_friend;
3679 int j = 0;
3680
3681 GNUNET_assert (NULL !=
3682 (target_friend =
3683 GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3684 &trail[0])));
3685 GDS_ROUTING_update_trail_next_hop (trail_id, trail[i]);
3686 GDS_NEIGHBOURS_send_trail_compression (my_identity,
3687 trail_id, trail[i],
3688 target_friend);
3689
3690
3691 /* Copy the trail from index i to index (trail_length -1) into a new trail
3692 * and update new trail length */
3693 *new_trail_length = trail_length - i;
3694 new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (*new_trail_length));
3695 while (i < trail_length)
3696 {
3697 memcpy (&new_trail[j], &trail[i], sizeof(struct GNUNET_PeerIdentity));
3698 j++;
3699 i++;
3700 }
3701 return new_trail;
3702 }
3703 }
3704
3705 /* If we did not compress the trail, return the original trail back.*/
3706 *new_trail_length = trail_length;
3707 new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
3708 memcpy (new_trail, trail, trail_length * sizeof (struct GNUNET_PeerIdentity));
3709 return new_trail;
3710}
3711
3454 3712
3455/** 3713/**
3456 * Check if there is already an entry in finger_table at finger_table_index. 3714 * Check if there is already an entry in finger_table at finger_table_index.
@@ -3485,6 +3743,8 @@ finger_table_add (struct GNUNET_PeerIdentity finger_identity,
3485 struct GNUNET_PeerIdentity closest_peer; 3743 struct GNUNET_PeerIdentity closest_peer;
3486 struct FingerInfo *successor; 3744 struct FingerInfo *successor;
3487 unsigned int finger_table_index; 3745 unsigned int finger_table_index;
3746 struct GNUNET_PeerIdentity *updated_trail;
3747 int updated_finger_trail_length;
3488 3748
3489 /* Get the finger_table_index corresponding to finger_value we got from network.*/ 3749 /* Get the finger_table_index corresponding to finger_value we got from network.*/
3490 finger_table_index = get_finger_table_index (finger_value, is_predecessor); 3750 finger_table_index = get_finger_table_index (finger_value, is_predecessor);
@@ -3509,8 +3769,6 @@ finger_table_add (struct GNUNET_PeerIdentity finger_identity,
3509 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, 3769 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity,
3510 &successor->finger_identity)) 3770 &successor->finger_identity))
3511 { 3771 {
3512// find_finger_trail_task_next_send_time =
3513// GNUNET_TIME_STD_BACKOFF(find_finger_trail_task_next_send_time);
3514 if (0 == fingers_round_count) 3772 if (0 == fingers_round_count)
3515 { 3773 {
3516 find_finger_trail_task_next_send_time = 3774 find_finger_trail_task_next_send_time =
@@ -3543,8 +3801,14 @@ finger_table_add (struct GNUNET_PeerIdentity finger_identity,
3543 /* No entry present in finger_table for given finger map index. */ 3801 /* No entry present in finger_table for given finger map index. */
3544 if (GNUNET_NO == existing_finger->is_present) 3802 if (GNUNET_NO == existing_finger->is_present)
3545 { 3803 {
3546 add_new_finger (finger_identity, finger_trail, 3804 /* Shorten the trail if possible. */
3547 finger_trail_length, 3805 updated_finger_trail_length = finger_trail_length;
3806 updated_trail = scan_and_compress_trail (finger_identity, finger_trail,
3807 finger_trail_length,
3808 finger_trail_id,
3809 &updated_finger_trail_length);
3810 add_new_finger (finger_identity, updated_trail,
3811 updated_finger_trail_length,
3548 finger_trail_id, finger_table_index); 3812 finger_trail_id, finger_table_index);
3549 update_current_search_finger_index (finger_table_index); 3813 update_current_search_finger_index (finger_table_index);
3550 return; 3814 return;
@@ -3558,20 +3822,18 @@ finger_table_add (struct GNUNET_PeerIdentity finger_identity,
3558 &finger_identity, 3822 &finger_identity,
3559 finger_value, 3823 finger_value,
3560 is_predecessor); 3824 is_predecessor);
3561 3825
3562 /* If the new finger is the closest peer. */ 3826 /* If the new finger is the closest peer. */
3563 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, &closest_peer)) 3827 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, &closest_peer))
3564 { 3828 {
3829 updated_finger_trail_length = finger_trail_length;
3830 updated_trail = scan_and_compress_trail (finger_identity, finger_trail,
3831 updated_finger_trail_length,
3832 finger_trail_id,
3833 &updated_finger_trail_length);
3565 remove_existing_finger (existing_finger, finger_table_index); 3834 remove_existing_finger (existing_finger, finger_table_index);
3566 add_new_finger (finger_identity, finger_trail, finger_trail_length, 3835 add_new_finger (finger_identity, updated_trail, updated_finger_trail_length,
3567 finger_trail_id, finger_table_index); 3836 finger_trail_id, finger_table_index);
3568// if ((0 == finger_table_index) && (1 == waiting_for_notify_confirmation))
3569// {
3570// /* SUPUS: We have removed our successor, but we are still waiting for a
3571// * confirmation. As we have removed successor, then it does not make
3572// sense to wait for the new successor. */
3573// waiting_for_notify_confirmation = 0;
3574// }
3575 } 3837 }
3576 else 3838 else
3577 { 3839 {
@@ -3598,14 +3860,18 @@ finger_table_add (struct GNUNET_PeerIdentity finger_identity,
3598 { 3860 {
3599 return; 3861 return;
3600 } 3862 }
3601 3863 updated_finger_trail_length = finger_trail_length;
3864 updated_trail = scan_and_compress_trail (finger_identity, finger_trail,
3865 finger_trail_length,
3866 finger_trail_id,
3867 &updated_finger_trail_length);
3602 /* If there is space to store more trails. */ 3868 /* If there is space to store more trails. */
3603 if (existing_finger->trails_count < MAXIMUM_TRAILS_PER_FINGER) 3869 if (existing_finger->trails_count < MAXIMUM_TRAILS_PER_FINGER)
3604 add_new_trail (existing_finger, finger_trail, 3870 add_new_trail (existing_finger, updated_trail,
3605 finger_trail_length, finger_trail_id); 3871 updated_finger_trail_length, finger_trail_id);
3606 else 3872 else
3607 select_and_replace_trail (existing_finger, finger_trail, 3873 select_and_replace_trail (existing_finger, updated_trail,
3608 finger_trail_length, finger_trail_id); 3874 updated_finger_trail_length, finger_trail_id);
3609 } 3875 }
3610 update_current_search_finger_index (finger_table_index); 3876 update_current_search_finger_index (finger_table_index);
3611 return; 3877 return;
@@ -6070,6 +6336,8 @@ GDS_NEIGHBOURS_init (void)
6070 {&handle_dht_p2p_trail_setup_rejection, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION, 0}, 6336 {&handle_dht_p2p_trail_setup_rejection, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION, 0},
6071 {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN, 6337 {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN,
6072 sizeof (struct PeerTrailTearDownMessage)}, 6338 sizeof (struct PeerTrailTearDownMessage)},
6339 {&handle_dht_p2p_trail_compression, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_COMPRESSION,
6340 sizeof (struct PeerTrailCompressionMessage)},
6073 {&handle_dht_p2p_add_trail, GNUNET_MESSAGE_TYPE_XDHT_P2P_ADD_TRAIL, 0}, 6341 {&handle_dht_p2p_add_trail, GNUNET_MESSAGE_TYPE_XDHT_P2P_ADD_TRAIL, 0},
6074 {&handle_dht_p2p_notify_succ_confirmation, GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_SUCCESSOR_CONFIRMATION, 6342 {&handle_dht_p2p_notify_succ_confirmation, GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_SUCCESSOR_CONFIRMATION,
6075 sizeof (struct PeerNotifyConfirmationMessage)}, 6343 sizeof (struct PeerNotifyConfirmationMessage)},
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 16dc9ae9a..29ddf1c04 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2605,10 +2605,15 @@ extern "C"
2605 * that you got the notify successor message. 2605 * that you got the notify successor message.
2606 */ 2606 */
2607#define GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_SUCCESSOR_CONFIRMATION 893 2607#define GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_SUCCESSOR_CONFIRMATION 893
2608
2609/**
2610 * Trail Compression
2611 */
2612#define GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_COMPRESSION 894
2608/*******************************************************************************/ 2613/*******************************************************************************/
2609 2614
2610/** 2615/**
2611 * Next available: 903 2616 * Next available: 904
2612 */ 2617 */
2613 2618
2614/** 2619/**