aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-05-05 11:03:22 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-05-05 11:03:22 +0000
commit2f166164c80ef5065d8899e0f9f123a148b742b6 (patch)
tree7b938c530efa7e38c0869b807ce8f2c7dd30e09c /src
parenta8137a9f38342180c3bf93ed52f4f022dfb9c369 (diff)
downloadgnunet-2f166164c80ef5065d8899e0f9f123a148b742b6.tar.gz
gnunet-2f166164c80ef5065d8899e0f9f123a148b742b6.zip
Handling all the cases while adding a new entry in finger table.
Modifying struct FingerInfo to store two trails to reach to same finger. Adding code to handle threshold on number of trails through a friend.
Diffstat (limited to 'src')
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c995
1 files changed, 516 insertions, 479 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index 46247f9dd..2338407f3 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -82,14 +82,6 @@
82 */ 82 */
83#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) 83#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
84 84
85/**
86 * Maximum number of trails allowed to go through a friend.
87 * FIXME: Random value at the moment, need to be adjusted to maintain a balance
88 * between performance and Sybil tolerance.
89 */
90#define TRAIL_THROUGH_FRIEND_THRESHOLD 64.
91
92
93GNUNET_NETWORK_STRUCT_BEGIN 85GNUNET_NETWORK_STRUCT_BEGIN
94 86
95/** 87/**
@@ -638,9 +630,20 @@ struct FingerInfo
638 unsigned int finger_map_index; 630 unsigned int finger_map_index;
639 631
640 /** 632 /**
641 * Total number of entries in trail from (me,finger] 633 * Number of trails to reach to this finger.
642 */ 634 */
643 unsigned int trail_length; 635 unsigned int trail_count;
636
637 /**
638 * Total number of entries in first trail from (me,finger)
639 */
640 unsigned int first_trail_length;
641
642 /**
643 * Total number of entries in second trail from (me,finger)
644 */
645 unsigned int second_trail_length;
646
644 647
645 /** 648 /**
646 * Number of trail of which the first element to reach to this finger is 649 * Number of trail of which the first element to reach to this finger is
@@ -649,14 +652,24 @@ struct FingerInfo
649 unsigned int first_friend_trails_count; 652 unsigned int first_friend_trails_count;
650 653
651 /** 654 /**
652 * Head of trail to reach this finger. 655 * Head of first trail to reach this finger.
653 */ 656 */
654 struct TrailPeerList *head; 657 struct TrailPeerList *first_trail_head;
655 658
656 /** 659 /**
657 * Tail of trail to reach this finger. 660 * Tail of first trail to reach this finger.
658 */ 661 */
659 struct TrailPeerList *tail; 662 struct TrailPeerList *first_trail_tail;
663
664 /**
665 * Head of second trail to reach this finger.
666 */
667 struct TrailPeerList *second_trail_head;
668
669 /**
670 * Tail of second trail to reach this finger.
671 */
672 struct TrailPeerList *second_trail_tail;
660 673
661}; 674};
662 675
@@ -698,30 +711,6 @@ struct Sorting_List
698 711
699 712
700/** 713/**
701 * FIXME: Not sure if we really need any such data structure.
702 * An entry in Failed_Trail_List
703 */
704struct FailedTrail
705{
706 /**
707 * Source peer which was trying to setup up the trail to @a destination_finger_value
708 */
709 struct GNUNET_PeerIdentity source_peer;
710
711 /**
712 * Value to which we were trying to find the closest successor.
713 */
714 uint64_t destination_finger_value;
715
716 /**
717 * Peer which has crossed the threshold limit on its routing table size.
718 */
719 struct GNUNET_PeerIdentity congested_peer;
720
721};
722
723
724/**
725 * Task that sends FIND FINGER TRAIL requests. This task is started when we have 714 * Task that sends FIND FINGER TRAIL requests. This task is started when we have
726 * get our first friend. 715 * get our first friend.
727 */ 716 */
@@ -758,17 +747,29 @@ static struct GNUNET_CORE_Handle *core_api;
758 */ 747 */
759#define PREDECESSOR_FINGER_ID 64 748#define PREDECESSOR_FINGER_ID 64
760 749
761unsigned int all_friends_trail_threshold;
762/** 750/**
763 * FIXME: The problem with incrementing this value in find_finger_trail_task 751 * Maximum number of trails allowed to go through a friend.
764 * is that it may happen that we started with a request to look for a finger 752 * FIXME: Better name, Random value at the moment, need to be adjusted to maintain a balance
765 * with current_finger_index = x, and its not yet complete but we are again back 753 * between performance and Sybil tolerance.
766 * in send_find_finger_trail message and we again start looking for current_finger_index = x. 754 */
767 * and only when we get the entry for x, we make it x-1. I am not sure if this is 755#define TRAIL_THROUGH_FRIEND_THRESHOLD 64
768 * correct. 756
757/**
758 * Possible number of different trails to reach to a finger. (Redundant routing)
759 */
760#define TRAIL_COUNT 2
761
762/**
763 * FIXME: better name.
764 * Set to GNUNET_YES, when the number of trails going through all my friends
765 * have reached the TRAIL_THROUGH_FRIEND_THRESHOLD.
766 */
767static unsigned int all_friends_trail_threshold;
768
769/**
769 * The current finger index that we have want to find trail to. 770 * The current finger index that we have want to find trail to.
770 */ 771 */
771static unsigned int current_finger_index; 772static unsigned int current_search_finger_index;
772 773
773 774
774/** 775/**
@@ -798,16 +799,12 @@ search_my_index (const struct GNUNET_PeerIdentity *trail,
798 799
799/** 800/**
800 * Invert the trail list. 801 * Invert the trail list.
801 * @param destination_peer Destination of the inverted trail.Trail is always
802 * (me, destination]. I am not part of trail that starts
803 * from me.
804 * @param existing_trail Trail 802 * @param existing_trail Trail
805 * @param trail_length Number of peers in the existing trail. 803 * @param trail_length Number of peers in the existing trail.
806 * @return 804 * @return
807 */ 805 */
808static struct GNUNET_PeerIdentity * 806static struct GNUNET_PeerIdentity *
809invert_trail_list (struct GNUNET_PeerIdentity *destination_peer, 807invert_trail_list (struct GNUNET_PeerIdentity *existing_trail,
810 struct GNUNET_PeerIdentity *existing_trail,
811 unsigned int trail_length) 808 unsigned int trail_length)
812{ 809{
813 int i; 810 int i;
@@ -827,8 +824,6 @@ invert_trail_list (struct GNUNET_PeerIdentity *destination_peer,
827 j++; 824 j++;
828 } 825 }
829 } 826 }
830 memcpy (&new_trail[j], destination_peer, sizeof(struct GNUNET_PeerIdentity));
831
832 return new_trail; 827 return new_trail;
833} 828}
834 829
@@ -900,6 +895,7 @@ core_transmit_notify (void *cls, size_t size, void *buf)
900 &core_transmit_notify, peer); 895 &core_transmit_notify, peer);
901 GNUNET_break (NULL != peer->th); 896 GNUNET_break (NULL != peer->th);
902 } 897 }
898
903 return off; 899 return off;
904} 900}
905 901
@@ -1042,7 +1038,7 @@ GDS_NEIGHBOURS_send_trail_setup_result (const struct GNUNET_PeerIdentity *destin
1042 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), 1038 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1043 1, GNUNET_NO); 1039 1, GNUNET_NO);
1044 } 1040 }
1045 1041
1046 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 1042 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1047 pending->importance = 0; 1043 pending->importance = 0;
1048 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT); 1044 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
@@ -1054,8 +1050,10 @@ GDS_NEIGHBOURS_send_trail_setup_result (const struct GNUNET_PeerIdentity *destin
1054 memcpy (&(tsrm->finger_identity), source_finger, sizeof (struct GNUNET_PeerIdentity)); 1050 memcpy (&(tsrm->finger_identity), source_finger, sizeof (struct GNUNET_PeerIdentity));
1055 tsrm->trail_length = htonl (trail_length); 1051 tsrm->trail_length = htonl (trail_length);
1056 tsrm->finger_map_index = htonl (finger_map_index); 1052 tsrm->finger_map_index = htonl (finger_map_index);
1053
1057 peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1]; 1054 peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
1058 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); 1055 if (trail_length > 0)
1056 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1059 1057
1060 /* Send the message to chosen friend. */ 1058 /* Send the message to chosen friend. */
1061 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); 1059 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
@@ -1289,12 +1287,8 @@ GDS_NEIGHBOURS_send_trail_teardown (struct GNUNET_PeerIdentity *source_peer,
1289 1287
1290 1288
1291/** 1289/**
1292 * FIXME: Optimizaiton Once the basic code is running. Add the optimization 1290 * FIXME: Handle congested peer - don't choose this friend, also don't choose
1293 * where you check if the threshold on number of links that should go through 1291 * the friend if the link threshold has crossed. Not implemented yet.
1294 * a particular friend has crossed. If yes then again choose a different
1295 * friend. Important that the new friend chosen should be different. How to
1296 * ensure this? This is an important optimization as without this one x-vine
1297 * is actually not a sybil tolerant DHT.
1298 * Randomly choose one of your friends from the friends_peer map 1292 * Randomly choose one of your friends from the friends_peer map
1299 * @return Friend 1293 * @return Friend
1300 */ 1294 */
@@ -1324,25 +1318,6 @@ select_random_friend (struct GNUNET_PeerIdentity *congested_peer)
1324 1318
1325 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend)) 1319 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1326 { 1320 {
1327 /* TODO: UPDATE: Also, I think I am always looking for better trails, and always
1328 * choosing friends randomly so this solves the problem automatically. I don't
1329 * think I should call this algorithm here. Will read
1330 * the paper again and check if its right or not. Here you have
1331 * chosen a random friend. Now you should check the size
1332 of its routing table size, and if its more than threshold, then check which
1333 of the entries has trail length greater than trail length threshold. we
1334 should without checking the routing table size also we should check the
1335 trail with trail length greater than threshold. then
1336 you should try to find a new route through this new node that has joined in
1337 only for those finger entries whose trail length is greater than threshold.
1338 But I don't want the new node to wait for this process to get over. so
1339 should i declare a function which will be called after some interval.*/
1340 /* here we are checking the value only set by us. but the friend may have its
1341 routing table full. we don't have the access to the value. in trail setup
1342 it will fail. so in case of put/get if we don't have the trail already then
1343 how does the intermediate peer stores the information in routing table.
1344 because in put we don't do the put result. hence, intermediate peers don't
1345 add the path in their routing table. then in get is it problem. */
1346 /* Possible number of trails that can go through this friend has been reached. */ 1321 /* Possible number of trails that can go through this friend has been reached. */
1347 if (friend->trails_count > TRAIL_THROUGH_FRIEND_THRESHOLD) 1322 if (friend->trails_count > TRAIL_THROUGH_FRIEND_THRESHOLD)
1348 { 1323 {
@@ -1372,7 +1347,7 @@ compute_finger_identity()
1372 1347
1373 memcpy (&my_id64, &my_identity, sizeof (uint64_t)); 1348 memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1374 my_id64 = GNUNET_ntohll (my_id64); 1349 my_id64 = GNUNET_ntohll (my_id64);
1375 return (my_id64 + (unsigned long) pow (2, current_finger_index)); 1350 return (my_id64 + (unsigned long) pow (2, current_search_finger_index));
1376} 1351}
1377 1352
1378 1353
@@ -1431,12 +1406,12 @@ send_verify_successor_message (void *cls,
1431 if( flag == 0) 1406 if( flag == 0)
1432 goto send_new_request; 1407 goto send_new_request;
1433 1408
1434 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->trail_length); 1409 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->first_trail_length);
1435 1410
1436 struct TrailPeerList *iterate; 1411 struct TrailPeerList *iterate;
1437 iterate = finger->head; 1412 iterate = finger->first_trail_head;
1438 i = 0; 1413 i = 0;
1439 while ( i < (finger->trail_length)) 1414 while ( i < (finger->first_trail_length))
1440 { 1415 {
1441 memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity)); 1416 memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity));
1442 iterate = iterate->next; 1417 iterate = iterate->next;
@@ -1451,7 +1426,7 @@ send_verify_successor_message (void *cls,
1451 &(finger->finger_identity), 1426 &(finger->finger_identity),
1452 target_friend, 1427 target_friend,
1453 peer_list, 1428 peer_list,
1454 finger->trail_length); 1429 finger->first_trail_length);
1455 1430
1456 1431
1457 /* FIXME: Understand what this function is actually doing here. */ 1432 /* FIXME: Understand what this function is actually doing here. */
@@ -1489,8 +1464,8 @@ send_find_finger_trail_message (void *cls,
1489 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us); 1464 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
1490 1465
1491 /* FIXME; if all the friend have reached their threshold, then don't schedule 1466 /* FIXME; if all the friend have reached their threshold, then don't schedule
1492 the task till the all_friends_trail_threshold gets reset. It will be 1467 * the task till the all_friends_trail_threshold gets reset. It will be
1493 scheduled from there. So, in finger table when we remove an entry and the new 1468 * scheduled from there. So, in finger table when we remove an entry and the new
1494 * entry does not have the same friend as the first hop, then decrement the 1469 * entry does not have the same friend as the first hop, then decrement the
1495 * threshold limit. and schedule this task. 1470 * threshold limit. and schedule this task.
1496 IMPORTANT: reset the value some where. Better name */ 1471 IMPORTANT: reset the value some where. Better name */
@@ -1524,7 +1499,7 @@ send_find_finger_trail_message (void *cls,
1524 return; 1499 return;
1525 } 1500 }
1526 1501
1527 if (PREDECESSOR_FINGER_ID == current_finger_index) 1502 if (PREDECESSOR_FINGER_ID == current_search_finger_index)
1528 { 1503 {
1529 finger_identity = compute_predecessor_identity(); 1504 finger_identity = compute_predecessor_identity();
1530 } 1505 }
@@ -1533,7 +1508,7 @@ send_find_finger_trail_message (void *cls,
1533 finger_identity = compute_finger_identity(); 1508 finger_identity = compute_finger_identity();
1534 } 1509 }
1535 1510
1536 finger_map_index = current_finger_index; 1511 finger_map_index = current_search_finger_index;
1537 1512
1538 /* URGENT :FIXME: In case the packet is not sent to a finger, then current_source is the 1513 /* URGENT :FIXME: In case the packet is not sent to a finger, then current_source is the
1539 * peer which sent the packet and current_destination which recevied it. Now 1514 * peer which sent the packet and current_destination which recevied it. Now
@@ -1544,71 +1519,6 @@ send_find_finger_trail_message (void *cls,
1544 1519
1545 1520
1546/** 1521/**
1547 * Check if there is a predecessor in our finger peer map or not.
1548 * If no, then return GNUNET_YES
1549 * else compare existing predecessor and peer, and find the correct
1550 * predecessor.
1551 * @param existing_predecessor
1552 * @param new_predecessor
1553 * @return #GNUNET_YES if new peer is predecessor
1554 * #GNUNET_NO if new peer is not the predecessor.
1555 */
1556static int
1557compare_predecessor(struct GNUNET_PeerIdentity *peer)
1558{
1559 /* FIXME: here you should first check if you already have an entry in the
1560 finger peer map for finger index = 64, if yes then compare it with peer
1561 if not then just add the peer. */
1562 return GNUNET_YES;
1563}
1564
1565#if 0
1566static int
1567update_predecessor (struct GNUNET_PeerIdentity *peer, struct GNUNET_PeerIdentity *trail_peer_list)
1568{
1569 /* In this function, we check if there is an entry or not for predecessor.
1570 if not then just add the peer, if no then compare the closest one, and add it
1571 . and remove the older one. There can still be multiple paths to reach to
1572 predecessor so in case both are same then make sure the paths are disjoint
1573 and then do multiple routing options. Also, invert the trail. and then add.
1574 Do all the things here. */
1575 return GNUNET_NO;
1576}
1577#endif
1578
1579/**
1580 * FIXME: free_finger(remove_finger); Call this function at finger_table_add,
1581 when you replace an existing entry
1582 * Free finger and its trail.
1583 * @param remove_finger Finger to be freed.
1584 */
1585static void
1586free_finger (struct FingerInfo *finger)
1587{
1588 struct TrailPeerList *peer;
1589
1590 while (NULL != (peer = finger->head))
1591 {
1592 GNUNET_CONTAINER_DLL_remove (finger->head, finger->tail, peer);
1593 GNUNET_free (peer);
1594 }
1595
1596 GNUNET_free (finger);
1597}
1598
1599
1600/**
1601 *
1602 * @return
1603 */
1604static struct GNUNET_PeerIdentity *
1605check_for_successor ()
1606{
1607 return NULL;
1608}
1609
1610
1611/**
1612 * FIXME: How do I send back the updated trail. 1522 * FIXME: How do I send back the updated trail.
1613 * Scan the trail to check if any on my own friend is part of trail. If yes 1523 * Scan the trail to check if any on my own friend is part of trail. If yes
1614 * the shortcut the trail and update the finger_trail and trail_length. 1524 * the shortcut the trail and update the finger_trail and trail_length.
@@ -1617,7 +1527,7 @@ check_for_successor ()
1617 * @return 1527 * @return
1618 */ 1528 */
1619static struct GNUNET_PeerIdentity * 1529static struct GNUNET_PeerIdentity *
1620scan_trail (struct GNUNET_PeerIdentity *finger_trail, unsigned int trail_length, 1530scan_and_compress_trail (struct GNUNET_PeerIdentity *finger_trail, unsigned int trail_length,
1621 const struct GNUNET_PeerIdentity *finger) 1531 const struct GNUNET_PeerIdentity *finger)
1622{ 1532{
1623 /* start from the second element as first element will always be your friend. 1533 /* start from the second element as first element will always be your friend.
@@ -1668,31 +1578,62 @@ scan_trail (struct GNUNET_PeerIdentity *finger_trail, unsigned int trail_length,
1668} 1578}
1669 1579
1670 1580
1671/**TOD0. 1581/**
1672 * 1.* If you remove an entry from finger table, and if the finger is not your friend 1582 * TODO:
1673 * and the trail length > 1 for the finger that you removed, then you should send 1583 * To see the logic better, I guess it better that function calling
1674 * a trail_teardown message along the trail. so that the peers which have an 1584 * free_finger, decrement the count of the trail going through them
1675 * entry in their routing table for this trail can remove it from their routing 1585 * reset all_friends_trail_threshold. In case you are removing an entry from
1676 * table. 1586 * finger table, and the new entry has the first friend different from the old
1677 * 2. 1587 * entry, then reset this all_friends_trail_threshold, if it is set to GNUNET_YES.
1678 * Choose the closest successor from existing_finger and new_finger. In case new_finger 1588 * and also schedule send_find_finger_trail_message.
1679 * is choosen, then send a tear down message along the trail to reach existing_finger. 1589 * Free finger and its trail.
1680 * @param existing_finger Existing entry in finger peer map 1590 * @param remove_finger Finger to be freed.
1681 * @param new_finger New finger
1682 * @param trail Trail to reach to the new finger from me.
1683 * @param trail_length Number of peers in the @a trail
1684 * @param finger_map_index If finger_map_index == PREDECESSOR_FINGER_INDEX,
1685 * then we use a different logic to find the closest
1686 * predecessor.
1687 * @return #GNUNET_YES In case we want to store the new entry.
1688 * #GNUNET_NO In case we want the existing entry.
1689 * #GNUNET_SYSERR Error.
1690 */ 1591 */
1691static 1592static void
1692int select_correct_entry (struct FingerInfo *existing_finger, 1593free_finger (struct FingerInfo *finger)
1693 const struct GNUNET_PeerIdentity *new_finger, 1594{
1694 struct GNUNET_PeerIdentity *trail, 1595 struct TrailPeerList *peer;
1695 unsigned int trail_length) 1596 struct FriendInfo *first_trail_friend;
1597 struct FriendInfo *second_trail_friend;
1598
1599 first_trail_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1600 &(finger->first_trail_head->peer));
1601 second_trail_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1602 &(finger->second_trail_head->peer));
1603
1604 first_trail_friend->trails_count--;
1605 second_trail_friend->trails_count--;
1606
1607 /* FIXME: Here we should reset the all_peers_trail_count to GNUNET_NO, and
1608 send_find_finger_trail_message. */
1609 while (NULL != (peer = finger->first_trail_head))
1610 {
1611 GNUNET_CONTAINER_DLL_remove (finger->first_trail_head, finger->first_trail_tail, peer);
1612 GNUNET_free (peer);
1613 }
1614
1615 while (NULL != (peer = finger->second_trail_head))
1616 {
1617 GNUNET_CONTAINER_DLL_remove (finger->second_trail_head, finger->second_trail_tail, peer);
1618 GNUNET_free (peer);
1619 }
1620 GNUNET_free (finger);
1621}
1622
1623
1624/**
1625 * FIMXE: Change the function, here you need to invert the trail.
1626 * @param existing_finger
1627 * @param new_finger
1628 * @param trail
1629 * @param trail_length
1630 * @return
1631 */
1632static
1633int select_correct_predecessor (struct FingerInfo *existing_finger,
1634 const struct GNUNET_PeerIdentity *new_finger,
1635 struct GNUNET_PeerIdentity *trail,
1636 unsigned int trail_length)
1696{ 1637{
1697 int val = GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger); 1638 int val = GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger);
1698 if (0 == val) 1639 if (0 == val)
@@ -1703,22 +1644,22 @@ int select_correct_entry (struct FingerInfo *existing_finger,
1703 * for one case then you should do it for all the cases where you are sending 1644 * for one case then you should do it for all the cases where you are sending
1704 * GNUNET_YES. */ 1645 * GNUNET_YES. */
1705 /* Scan the trail for a friend and shorten if possible. */ 1646 /* Scan the trail for a friend and shorten if possible. */
1706 scan_trail (trail, trail_length, new_finger); 1647 scan_and_compress_trail (trail, trail_length, new_finger);
1707 return GNUNET_YES; 1648 return GNUNET_YES;
1708 } 1649 }
1709 else if (val > 0) 1650 else if (val < 0)
1710 { 1651 {
1711 /* If the new entry is closest one, then free the old entry, send a trail_teardown message.*/ 1652 /* If the new entry is closest one, then free the old entry, send a trail_teardown message.*/
1712 struct GNUNET_PeerIdentity *peer_list; 1653 struct GNUNET_PeerIdentity *peer_list;
1713 struct FriendInfo *friend; 1654 struct FriendInfo *friend;
1714 struct TrailPeerList *finger_trail; 1655 struct TrailPeerList *finger_trail;
1715 int existing_finger_trail_length = existing_finger->trail_length; 1656 int existing_finger_trail_length = existing_finger->first_trail_length;
1716 int i = 0; 1657 int i = 0;
1717 1658
1718 finger_trail = existing_finger->head; 1659 finger_trail = existing_finger->first_trail_head;
1719 friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer)); 1660 friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer));
1720 peer_list = GNUNET_malloc ( existing_finger_trail_length * sizeof (struct GNUNET_PeerIdentity)); 1661 peer_list = GNUNET_malloc ( existing_finger_trail_length * sizeof (struct GNUNET_PeerIdentity));
1721 while (i < existing_finger->trail_length) 1662 while (i < existing_finger->first_trail_length)
1722 { 1663 {
1723 memcpy (&peer_list[i], &(finger_trail->peer), sizeof (struct GNUNET_PeerIdentity)); 1664 memcpy (&peer_list[i], &(finger_trail->peer), sizeof (struct GNUNET_PeerIdentity));
1724 finger_trail = finger_trail->next; 1665 finger_trail = finger_trail->next;
@@ -1729,7 +1670,7 @@ int select_correct_entry (struct FingerInfo *existing_finger,
1729 peer_list, existing_finger_trail_length, friend); 1670 peer_list, existing_finger_trail_length, friend);
1730 1671
1731 free_finger (existing_finger); 1672 free_finger (existing_finger);
1732 scan_trail (trail, trail_length, new_finger); 1673 scan_and_compress_trail (trail, trail_length, new_finger);
1733 return GNUNET_YES; 1674 return GNUNET_YES;
1734 } 1675 }
1735 else 1676 else
@@ -1742,251 +1683,436 @@ int select_correct_entry (struct FingerInfo *existing_finger,
1742 1683
1743 1684
1744/** 1685/**
1745 * SUPU: now the finger trail does not contain finger identity as the last element. 1686 * Check if there is a predecessor in our finger peer map or not.
1746 * TODO: 1687 * If no, then return GNUNET_YES
1747 * 1. handle predecessor case differently. 1688 * else compare existing predecessor and peer, and find the correct
1748 * how to handle the case in which same finger identity is stored for different 1689 * predecessor.
1749 * finger map index. because this will just increase the size of finger map and 1690 * @param existing_predecessor
1750 * also size of the array we use in find_successor. 1691 * @param new_predecessor
1751 * Add an entry in finger table. Before adding, check if there is already an 1692 * @return #GNUNET_YES if new peer is predecessor
1752 * entry in finger peermap for the same index, if yes then choose the closest one. 1693 * #GNUNET_NO if new peer is not the predecessor.
1753 * In case both the existing identity and new identity are same, keep both the trail
1754 * only if the trails are different (Redundant routing). Also, a peer stored at index,i
1755 * if its same as peer stored index, i+1, and 'i' is the lowest finger map index
1756 * seen so far, then that peer is the successor. In case finger_map_index is PREDECESSOR_INDEX,
1757 * then simply add it as handle rest of the cases for it in a different function.
1758 * Also while adding an entry check the trail, scan the trail and check if there
1759 * is a friend in between, then shortcut the path.
1760 * @param finger_identity
1761 * @param finger_trail
1762 * @param finger_trail_length
1763 * @param finger_map_index
1764 */ 1694 */
1765static 1695static void
1766void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, 1696compare_and_update_predecessor (struct GNUNET_PeerIdentity *peer,
1767 struct GNUNET_PeerIdentity *finger_trail, 1697 struct GNUNET_PeerIdentity *trail,
1768 uint32_t finger_trail_length, 1698 unsigned int trail_length)
1769 uint32_t finger_map_index)
1770{ 1699{
1771 struct FingerInfo new_finger_entry; 1700 /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */
1772 struct FingerInfo *existing_finger; 1701 struct FingerInfo *existing_finger;
1773 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; 1702 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1703 struct FingerInfo *new_finger_entry;
1774 int i; 1704 int i;
1705 int predecessor_flag = 0;
1775 1706
1776 /* If I am my own finger, then return. */
1777 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity))
1778 {
1779 GNUNET_break (0);
1780 /* FIXME:Is there any point in keeping my own identity as finger?
1781 * Also, send a trail tear down message to all the peers which
1782 are in the finger trail, so that they can remove the entries from routing
1783 table. */
1784 return;
1785 }
1786
1787 /* Check if there is already an entry for the finger map index in the finger peer map. */
1788 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 1707 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1789 for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++) 1708 for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++)
1790 { 1709 {
1791 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL, 1710 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL,
1792 (const void **)&existing_finger)) 1711 (const void **)&existing_finger))
1793 { 1712 {
1794 /* If existing_finger is the closest, then don't add any entry. */ 1713 if (existing_finger->finger_map_index == PREDECESSOR_FINGER_ID)
1795 if ( GNUNET_NO == select_correct_entry (existing_finger, finger_identity, 1714 {
1796 finger_trail, finger_trail_length)) 1715 predecessor_flag = 1;
1797 goto increment_finger_index; 1716 break;
1717 }
1798 } 1718 }
1799 } 1719 }
1800 1720
1801 /* Add the new entry. */ 1721 if (predecessor_flag != 0)
1802 memcpy (&(new_finger_entry.finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity)); 1722 {
1803 new_finger_entry.finger_map_index = finger_map_index; 1723 /* There is a predecessor entry. Now we need to find out which one is
1804 new_finger_entry.trail_length = finger_trail_length; 1724 * the closest one. If both are same then how to handle. */
1725 if(select_correct_predecessor (existing_finger, peer, trail, trail_length) == GNUNET_NO)
1726 return;
1727 }
1728 else
1729 {
1730 scan_and_compress_trail (trail, trail_length, peer);
1731 invert_trail_list (trail, trail_length);
1732 }
1733 FPRINTF (stderr,_("\nSUPU %s, %s, %d"),__FILE__, __func__,__LINE__);
1734 memcpy (&(new_finger_entry->finger_identity), peer, sizeof (struct GNUNET_PeerIdentity));
1735 new_finger_entry->finger_map_index = PREDECESSOR_FINGER_ID;
1736 new_finger_entry->first_trail_length = trail_length;
1805 i = 0; 1737 i = 0;
1806 while (i < finger_trail_length) 1738 while (i < trail_length)
1807 { 1739 {
1808 struct TrailPeerList *element; 1740 struct TrailPeerList *element;
1809 element = GNUNET_malloc (sizeof (struct TrailPeerList)); 1741 element = GNUNET_malloc (sizeof (struct TrailPeerList));
1810 element->next = NULL; 1742 element->next = NULL;
1811 element->prev = NULL; 1743 element->prev = NULL;
1812 1744
1813 memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity)); 1745 memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
1814 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry.head, new_finger_entry.tail, element); 1746 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->first_trail_head, new_finger_entry->first_trail_tail, element);
1815 i++; 1747 i++;
1816 } 1748 }
1817 1749
1818 GNUNET_assert (GNUNET_OK == 1750 GNUNET_assert (GNUNET_OK ==
1819 GNUNET_CONTAINER_multipeermap_put (finger_peermap, 1751 GNUNET_CONTAINER_multipeermap_put (finger_peermap,
1820 &(new_finger_entry.finger_identity), 1752 &(new_finger_entry->finger_identity),
1821 &new_finger_entry, 1753 &new_finger_entry,
1822 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 1754 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1823 1755
1824 /* FIXME: after adding an entry, I want to check if there is a successor, if yes 1756 return;
1825 then this function will return it and then we should schedule a verify successor 1757}
1826 task Will the successor always be at index 0 */ 1758
1827 increment_finger_index: 1759
1828 if (NULL != check_for_successor()) 1760/**
1761 * FIXME: In this case first you should check which of the trail is longest and
1762 * the just discard it. Right now you are not checking it.
1763 * In case there are already maximum number of possible trail to reach to a finger,
1764 * then check if the new trail can replace an existing one. If yes then replace.
1765 * @param existing_finger
1766 * @param trail
1767 * @param trail_length
1768 * @return #GNUNET_YES
1769 * #GNUNET_NO
1770 */
1771static
1772void select_and_replace_trail (struct FingerInfo *existing_finger,
1773 struct GNUNET_PeerIdentity *trail,
1774 unsigned int trail_length)
1775{
1776 if (trail_length < existing_finger->first_trail_length)
1829 { 1777 {
1830 verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL); 1778 struct TrailPeerList *peer;
1831 current_finger_index = PREDECESSOR_FINGER_ID; 1779 int i = 0;
1832 return; 1780
1781 while (NULL != (peer = existing_finger->first_trail_head))
1782 {
1783 GNUNET_CONTAINER_DLL_remove (existing_finger->first_trail_head, existing_finger->first_trail_tail, peer);
1784 GNUNET_free (peer);
1785 }
1786
1787 while (i < trail_length)
1788 {
1789 struct TrailPeerList *element;
1790 element = GNUNET_malloc (sizeof (struct TrailPeerList));
1791 element->next = NULL;
1792 element->prev = NULL;
1793
1794 memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
1795 GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
1796 i++;
1797 }
1798 }
1799 else if (trail_length < existing_finger->second_trail_length)
1800 {
1801 struct TrailPeerList *peer;
1802 int i = 0;
1803
1804 while (NULL != (peer = existing_finger->second_trail_head))
1805 {
1806 GNUNET_CONTAINER_DLL_remove (existing_finger->second_trail_head, existing_finger->second_trail_tail, peer);
1807 GNUNET_free (peer);
1808 }
1809
1810 while (i < trail_length)
1811 {
1812 struct TrailPeerList *element;
1813 element = GNUNET_malloc (sizeof (struct TrailPeerList));
1814 element->next = NULL;
1815 element->prev = NULL;
1816
1817 memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
1818 GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
1819 i++;
1820 }
1821 }
1822}
1823
1824
1825/**
1826 * Add a new trail to reach an existing finger in finger peermap.
1827 * @param existing_finger
1828 * @param trail
1829 * @param trail_length
1830 */
1831static
1832void add_new_trail (struct FingerInfo *existing_finger,
1833 struct GNUNET_PeerIdentity *trail,
1834 unsigned int trail_length)
1835{
1836 int i;
1837 i = 0;
1838
1839 if (existing_finger->second_trail_head != NULL)
1840 {
1841 while (i < trail_length)
1842 {
1843 struct TrailPeerList *element;
1844 element = GNUNET_malloc (sizeof (struct TrailPeerList));
1845 element->next = NULL;
1846 element->prev = NULL;
1847
1848 memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
1849 GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
1850 i++;
1851 }
1852 }
1853 else if (existing_finger->second_trail_head != NULL)
1854 {
1855 while (i < trail_length)
1856 {
1857 struct TrailPeerList *element;
1858 element = GNUNET_malloc (sizeof (struct TrailPeerList));
1859 element->next = NULL;
1860 element->prev = NULL;
1861
1862 memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
1863 GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
1864 i++;
1865 }
1866 }
1867}
1868
1869
1870/**
1871 * * 1.* If you remove an entry from finger table, and if the finger is not your friend
1872 * and the trail length > 1 for the finger that you removed, then you should send
1873 * a trail_teardown message along the trail. so that the peers which have an
1874 * entry in their routing table for this trail can remove it from their routing
1875 * table.
1876 * Better name
1877 * TODO: First check if both the trails are present if yes then send it
1878 * for both of them.
1879 * @param existing_finger
1880 */
1881static
1882void send_trail_teardown (struct FingerInfo *existing_finger)
1883{
1884 struct GNUNET_PeerIdentity *peer_list;
1885 struct FriendInfo *friend;
1886 struct TrailPeerList *finger_trail;
1887 int existing_finger_trail_length = existing_finger->first_trail_length;
1888 int i = 0;
1889
1890
1891 finger_trail = existing_finger->first_trail_head;
1892 friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer));
1893 peer_list = GNUNET_malloc ( existing_finger_trail_length * sizeof (struct GNUNET_PeerIdentity));
1894 while (i < existing_finger->first_trail_length)
1895 {
1896 memcpy (&peer_list[i], &(finger_trail->peer), sizeof (struct GNUNET_PeerIdentity));
1897 finger_trail = finger_trail->next;
1898 i++;
1899 }
1900
1901 GDS_NEIGHBOURS_send_trail_teardown (&my_identity, &(existing_finger->finger_identity),
1902 peer_list, existing_finger_trail_length, friend);
1903}
1904
1905
1906/**TOD0.
1907 * Choose the closest successor from existing_finger and new_finger. In case new_finger
1908 * is choosen, then send a tear down message along the trail to reach existing_finger.
1909 * @param existing_finger Existing entry in finger peer map
1910 * @param new_finger New finger
1911 * @param trail Trail to reach to the new finger from me.
1912 * @param trail_length Number of peers in the @a trail
1913 * @param finger_map_index If finger_map_index == PREDECESSOR_FINGER_INDEX,
1914 * then we use a different logic to find the closest
1915 * predecessor.
1916 * @return #GNUNET_YES In case we want to store the new entry.
1917 * #GNUNET_NO In case we want the existing entry.
1918 * #GNUNET_SYSERR Error.
1919 */
1920static
1921int select_closest_finger (struct FingerInfo *existing_finger,
1922 const struct GNUNET_PeerIdentity *new_finger,
1923 struct GNUNET_PeerIdentity *trail,
1924 unsigned int trail_length)
1925{
1926 int val = GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger);
1927
1928 if (0 == val)
1929 {
1930 /*FIXME: Check if this returns the compressed trail in the trail sent as parameter.
1931 Scan the trail for a friend and shorten if possible. */
1932 scan_and_compress_trail (trail, trail_length, new_finger);
1933
1934 if (existing_finger->trail_count < TRAIL_COUNT)
1935 {
1936 add_new_trail (existing_finger, trail, trail_length);
1937 return GNUNET_NO;
1938 }
1939 else
1940 {
1941 /* If not then first check if this new trail is shorter than other trails,
1942 if yes then remove the old trail, and add this new trail. and send GNUNET_YES. */
1943 select_and_replace_trail (existing_finger, trail, trail_length);
1944 return GNUNET_NO;
1945 }
1946 }
1947 else if (val > 0)
1948 {
1949 /* If the new entry is closest one, then free the old entry, send a trail_teardown message.*/
1950
1951 send_trail_teardown (existing_finger);
1952 free_finger (existing_finger);
1953 scan_and_compress_trail (trail, trail_length, new_finger);
1954 return GNUNET_YES;
1955 }
1956 else
1957 {
1958 /* If the old entry is closest then just return GNUNET_NO.*/
1959 return GNUNET_NO;
1960 }
1961 return GNUNET_SYSERR;
1962}
1963
1964
1965/**
1966 * FIXME: Better name, and make the code more cleaner.
1967 * Compare the new finger entry added and our successor.
1968 * @return #GNUNET_YES if same.
1969 * #GNUNET_NO if not.
1970 */
1971static int
1972compare_new_entry_successor (const struct GNUNET_PeerIdentity *new_finger)
1973{
1974 int successor_flag = 0;
1975 struct FingerInfo *successor_finger;
1976 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1977 int i;
1978
1979 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1980 for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++)
1981 {
1982 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL,
1983 (const void **)&successor_finger))
1984 {
1985 if (successor_finger->finger_map_index == 0)
1986 {
1987 successor_flag = 1;
1988 break;
1989 }
1990 }
1991 }
1992 /* Ideally we should never reach here. */
1993 if (successor_flag == 0)
1994 {
1995 GNUNET_break (0);
1996 return GNUNET_NO;
1833 } 1997 }
1834 1998
1835 /* FIXME: Not sure if this is the correct place to set the values. Look into 1999 if (0 == GNUNET_CRYPTO_cmp_peer_identity (new_finger, &(successor_finger->finger_identity)))
1836 send_find_finger_trail_message and check. */ 2000 return GNUNET_YES;
1837 if(current_finger_index == 0)
1838 current_finger_index = PREDECESSOR_FINGER_ID;
1839 else 2001 else
1840 current_finger_index = current_finger_index - 1; 2002 return GNUNET_NO;
1841} 2003}
1842 2004
1843 2005
1844#if 0 2006/**
1845/*FIXME: Here you need to set the correct value of finger_map_index, 2007 * Add an entry in the finger table. If there is already an existing entry in
1846 * in case it is 0, then you set it back to 64, and in case it is x, 2008 * the finger peermap for given finger map index, then choose the closest one.
1847 * then you set it back to x-1. current_finger_index = ( current_finger_index - 1) % MAX_FINGERS 2009 * In case both the new entry and old entry are same, store both of them. (Redundant
1848 * we also need to change the logic of starting the process to look for a successor. 2010 * routing).
1849 * when you add an entry then go through whole trail and check if there is an entry 2011 * @param finger_identity
1850 * which is your friend, if yes then just collapse the trail. if you are not doing it 2012 * @param finger_trail
1851 * here then you need to do it in handle_core_disconnect where you will have to search 2013 * @param finger_trail_length
1852 * through whole trail find peer and then delete the finger. 2014 * @param finger_map_index
1853 * Add an entry in finger table.
1854 * @param finger_identity Peer identity of finger
1855 * @param finger_trail Trail to reach the finger
1856 * @param trail_length Number of peers in the trail.
1857 * @param finger_map_index Index in finger peer map.
1858 */ 2015 */
1859static 2016static
1860void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, 2017void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
1861 const struct GNUNET_PeerIdentity *finger_trail, 2018 struct GNUNET_PeerIdentity *finger_trail,
1862 unsigned int trail_length, 2019 uint32_t finger_trail_length,
1863 const unsigned int finger_map_index) 2020 uint32_t finger_map_index)
1864{ 2021{
1865 struct FingerInfo *new_finger_entry; 2022 struct FingerInfo new_finger_entry;
1866 //struct GNUNET_PeerIdentity key_ret; 2023 struct FingerInfo *existing_finger;
2024 struct FriendInfo *first_friend_trail;
2025 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1867 int i; 2026 int i;
1868 //struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; 2027
1869 //struct FingerInfo *existing_finger; 2028 /* If you are your own finger, then exit. */
1870 //int finger_index; 2029 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity))
1871 2030 {
1872 /* SUPU Here we trying to check if we already have an entry. If yes then we 2031 /* SUPU: We don't store this trail in case of trail_setup_result, if
1873 can keep two trails for redundant routing. if they are different then we 2032 source and destination of the message are same. */
1874 need to choose the closest one. and remove the other one. */ 2033 return;
1875#if 0 2034 }
2035
2036 /* Check if there is already an entry for the finger map index in the finger peer map. */
1876 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 2037 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1877 2038 for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++)
1878 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1879 { 2039 {
1880 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret, 2040 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL,
1881 (const void **)&existing_finger)) 2041 (const void **)&existing_finger))
1882 { 2042 {
1883 if ((finger_map_index == existing_finger->finger_map_index)) 2043 if (existing_finger->finger_map_index == finger_map_index)
1884 { 2044 {
1885 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),finger_identity)) 2045 /* If existing finger is closest or both the new finger and existing finger
1886 { 2046 are same, then just update current_search_finger_index. We are not
1887 /* FIXME: Here you should check if the trail is same. If yes then don't add the entry. it 2047 adding a new entry just updating the existing entry or doing nothing. */
1888 seems to be very suboptimal. */ 2048 if ( GNUNET_NO == select_closest_finger (existing_finger, finger_identity,
1889 if ((existing_finger->trail_length) == trail_length) 2049 finger_trail, finger_trail_length))
1890 { 2050 goto update_current_search_finger_index;
1891 struct TrailPeerList *iterate;
1892 iterate = existing_finger->head;
1893 int k;
1894 k = 0;
1895 while (k < trail_length)
1896 {
1897 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(iterate->peer), &finger_trail[k]))
1898 {
1899 k++;
1900 iterate = iterate->next;
1901 }
1902 }
1903 if (k == trail_length)
1904 return;
1905 else
1906 goto add_new_entry;
1907 }
1908 goto add_new_entry;
1909 }
1910 else 2051 else
1911 { 2052 break;
1912 int ret;
1913 if (finger_map_index == 1)
1914 {
1915 ret = compare_predecessor (&(existing_finger->finger_identity),
1916 finger_identity);
1917 goto add_new_entry;
1918 }
1919 else
1920 {
1921 ret = compare_finger_identity (&(existing_finger->finger_identity),
1922 finger_identity);
1923 }
1924 if (ret > 0)
1925 {
1926 GNUNET_assert (GNUNET_YES ==
1927 GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
1928 &(existing_finger->finger_identity),
1929 existing_finger));
1930 goto add_new_entry;
1931 }
1932 else
1933 {
1934 return;
1935 }
1936 }
1937 } 2053 }
1938 } 2054 }
1939 } 2055 }
1940
1941 add_new_entry:
1942#endif
1943 new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
1944 memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity));
1945 new_finger_entry->finger_map_index = finger_map_index;
1946 2056
1947 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity)) 2057 /* Add the new entry. */
2058 memcpy (&(new_finger_entry.finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity));
2059 new_finger_entry.finger_map_index = finger_map_index;
2060 new_finger_entry.first_trail_length = finger_trail_length;
2061
2062 if (finger_trail_length > 0)
1948 { 2063 {
1949 /* I am the finger */ 2064 first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[0]);
1950 new_finger_entry->trail_length = 0; 2065 first_friend_trail->trails_count++;
1951 /* FIXME: If I am the finger then why do we even do an entry. don't add any
1952 * field because it is of no use. you may just send a message to yourself
1953 * when another peer send you a trail setup or put request. */
1954 } 2066 }
1955 else 2067 else
1956 { 2068 {
1957 i = 0; 2069 /* It means the finger is my friend. */
1958 while (i < trail_length) 2070 first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, finger_identity);
1959 { 2071 first_friend_trail->trails_count++;
1960 struct TrailPeerList *element; 2072 }
1961 element = GNUNET_malloc (sizeof (struct TrailPeerList)); 2073
1962 element->next = NULL; 2074
1963 element->prev = NULL; 2075 new_finger_entry.first_friend_trails_count = first_friend_trail->trails_count;
2076 i = 0;
2077 while (i < finger_trail_length)
2078 {
2079 struct TrailPeerList *element;
2080 element = GNUNET_malloc (sizeof (struct TrailPeerList));
2081 element->next = NULL;
2082 element->prev = NULL;
1964 2083
1965 memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity)); 2084 memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity));
1966 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->head, new_finger_entry->tail, element); 2085 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry.first_trail_head, new_finger_entry.first_trail_tail, element);
1967 i++; 2086 i++;
1968 }
1969 new_finger_entry->trail_length = trail_length;
1970 } 2087 }
1971 2088
1972 /* FIXME: Here we are keeping multiple hashmap option so that there are
1973 multiple routes to reach to same finger, redundant routing.
1974 * Also same peers could be our fingers for different finger map index
1975 * Should we handle the case where we have same fingers at the different
1976 * finger index but with different trail to reach. */
1977 GNUNET_assert (GNUNET_OK == 2089 GNUNET_assert (GNUNET_OK ==
1978 GNUNET_CONTAINER_multipeermap_put (finger_peermap, 2090 GNUNET_CONTAINER_multipeermap_put (finger_peermap,
1979 &(new_finger_entry->finger_identity), 2091 &(new_finger_entry.finger_identity),
1980 new_finger_entry, 2092 &new_finger_entry,
1981 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 2093 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1982 2094
1983 if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap) 2095 /* Set the value of current_search_finger_index. */
1984 && (new_finger_entry->finger_map_index!= 1)) 2096 update_current_search_finger_index:
2097 if (0 == finger_map_index)
1985 { 2098 {
1986 verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL); 2099 verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL);
2100 current_search_finger_index = PREDECESSOR_FINGER_ID;
2101 return;
2102 }
2103 else if (GNUNET_YES == compare_new_entry_successor (finger_identity))
2104 {
2105 /* If the new entry is same as our successor, then reset the current_search_finger_index to 0*/
2106 current_search_finger_index = 0;
2107 return;
2108 }
2109 else
2110 {
2111 current_search_finger_index = current_search_finger_index - 1;
2112 return;
1987 } 2113 }
1988} 2114}
1989#endif 2115
1990 2116
1991/** 2117/**
1992 * Compare two peer identities. 2118 * Compare two peer identities.
@@ -1994,7 +2120,7 @@ void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
1994 * @param p2 Peer identity 2120 * @param p2 Peer identity
1995 * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2. 2121 * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2.
1996 */ 2122 */
1997 static int 2123static int
1998compare_peer_id (const void *p1, const void *p2) 2124compare_peer_id (const void *p1, const void *p2)
1999{ 2125{
2000 struct Sorting_List *p11; 2126 struct Sorting_List *p11;
@@ -2142,6 +2268,9 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2142 2268
2143 if (successor->type == MY_ID) 2269 if (successor->type == MY_ID)
2144 { 2270 {
2271 /* FIXME: make sure everywhere you are using current_destination to check if
2272 I am the final destination. */
2273 memcpy (current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2145 return NULL; 2274 return NULL;
2146 } 2275 }
2147 else if (successor->type == FRIEND) 2276 else if (successor->type == FRIEND)
@@ -2159,7 +2288,7 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2159 struct TrailPeerList *iterator; 2288 struct TrailPeerList *iterator;
2160 iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); 2289 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
2161 finger = successor->data; 2290 finger = successor->data;
2162 iterator = finger->head; 2291 iterator = finger->first_trail_head;
2163 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2292 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2164 memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity)); 2293 memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
2165 memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity)); 2294 memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
@@ -2168,6 +2297,8 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2168 } 2297 }
2169 else 2298 else
2170 { 2299 {
2300 /* FIXME: This is returned when congested peer is the only peer or the only
2301 finger that we have is reachable through this congested peer. */
2171 GNUNET_assert (0); 2302 GNUNET_assert (0);
2172 return NULL; 2303 return NULL;
2173 } 2304 }
@@ -2859,8 +2990,8 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2859 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 2990 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2860 */ 2991 */
2861static int 2992static int
2862handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer, 2993handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
2863 const struct GNUNET_MessageHeader *message) 2994 const struct GNUNET_MessageHeader *message)
2864{ 2995{
2865 const struct PeerTrailSetupMessage *trail_setup; 2996 const struct PeerTrailSetupMessage *trail_setup;
2866 struct GNUNET_PeerIdentity current_destination; 2997 struct GNUNET_PeerIdentity current_destination;
@@ -2908,27 +3039,23 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2908 /* No more trails possible through me. send a trail rejection message. */ 3039 /* No more trails possible through me. send a trail rejection message. */
2909 GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity, 3040 GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity,
2910 peer,finger_map_index, trail_peer_list,trail_length); 3041 peer,finger_map_index, trail_peer_list,trail_length);
2911 return GNUNET_YES; 3042 return GNUNET_OK;
2912 } 3043 }
2913 3044
2914 /* Check if you are current_destination or not. */ 3045 /* Check if you are current_destination or not. */
2915 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity))) 3046 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
2916 { 3047 {
2917 /* You are not current_destination, you are part of trail to reach to
2918 current_destination. */
2919 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer); 3048 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer);
2920 /* ADDNOW: OPTIMIZATION: do find_successor also and get a better path if possible. */ 3049 /* ADDNOW: OPTIMIZATION: do find_successor also and get a better path if possible. */
2921 3050
2922 if (next_hop == NULL) 3051 if (next_hop == NULL)
2923 { 3052 {
2924 /* FIXME: 3053 /* FIXME next_hop is NULL, in a case when next_hop was a friend which got disconnected
2925 * next_hop is NULL, in a case when next_hop was a friend which got disconnected
2926 * and we removed the trail from our routing trail. So, I can send the message 3054 * and we removed the trail from our routing trail. So, I can send the message
2927 * to other peer or can drop the message. VERIFY which will be the correct 3055 * to other peer or can drop the message. VERIFY which will be the correct
2928 * thing to do. 3056 * thing to do. next_hop to NULL, 1. statistics update, drop the message.
2929 * next_hop to NULL, 1. statistics update, drop the message. 3057 * 2. complain to sender with new message: trail lost */
2930 2. complain to sender with new message: trail lost */ 3058 return GNUNET_OK;
2931 return GNUNET_OK;
2932 } 3059 }
2933 } 3060 }
2934 else 3061 else
@@ -2936,10 +3063,9 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2936 next_hop = find_successor (destination_finger_value, &current_destination, &current_source, NULL); 3063 next_hop = find_successor (destination_finger_value, &current_destination, &current_source, NULL);
2937 } 3064 }
2938 3065
2939 3066 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity))) /* This means I am the final destination */
2940 if (NULL == next_hop) /* This means I am the final destination */
2941 { 3067 {
2942 /* SUPU: trail length is 0, when I am the friend of the srouce peer. */ 3068 /* SUPU: trail length is 0, when I am the friend of the source peer. */
2943 if (trail_length == 0) 3069 if (trail_length == 0)
2944 { 3070 {
2945 memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity)); 3071 memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity));
@@ -2950,15 +3076,9 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2950 } 3076 }
2951 3077
2952 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); 3078 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
3079 /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */
3080 compare_and_update_predecessor (&source, trail_peer_list, trail_length );
2953 3081
2954 if (compare_predecessor (&source) /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */)
2955 {
2956 /* FIXME: In case we have different function update_predecessor then
2957 remove the lines below. */
2958 struct GNUNET_PeerIdentity *new_trail_list;
2959 new_trail_list = invert_trail_list (&source, trail_peer_list, trail_length);
2960 finger_table_add (&source, new_trail_list, trail_length, PREDECESSOR_FINGER_ID);
2961 }
2962 GDS_NEIGHBOURS_send_trail_setup_result (&source, 3082 GDS_NEIGHBOURS_send_trail_setup_result (&source,
2963 &(my_identity), 3083 &(my_identity),
2964 target_friend, trail_length, 3084 target_friend, trail_length,
@@ -3176,13 +3296,13 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
3176 int new_trail_length; 3296 int new_trail_length;
3177 int i; 3297 int i;
3178 3298
3179 new_trail_length = trail_length + my_predecessor->trail_length + 1; 3299 new_trail_length = trail_length + my_predecessor->first_trail_length + 1;
3180 new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length); 3300 new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length);
3181 memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity)); 3301 memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity));
3182 memcpy (&new_successor_trail[trail_length], &my_identity, sizeof (struct GNUNET_PeerIdentity)); 3302 memcpy (&new_successor_trail[trail_length], &my_identity, sizeof (struct GNUNET_PeerIdentity));
3183 3303
3184 iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); 3304 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
3185 iterator = my_predecessor->head; 3305 iterator = my_predecessor->first_trail_head;
3186 i = trail_length + 1; 3306 i = trail_length + 1;
3187 while (i < new_trail_length) 3307 while (i < new_trail_length)
3188 { 3308 {
@@ -3495,15 +3615,8 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *
3495 } 3615 }
3496 3616
3497 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); 3617 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
3618 compare_and_update_predecessor (&source_peer, trail_peer_list, trail_length);
3498 3619
3499 if (compare_predecessor (&source_peer) /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */)
3500 {
3501 /* FIXME: In case we have different function update_predecessor then
3502 remove the lines below. */
3503 struct GNUNET_PeerIdentity *new_trail_list;
3504 new_trail_list = invert_trail_list (&source_peer, trail_peer_list, trail_length);
3505 finger_table_add (&source_peer, new_trail_list, trail_length, PREDECESSOR_FINGER_ID);
3506 }
3507 GDS_NEIGHBOURS_send_trail_setup_result (&source_peer, 3620 GDS_NEIGHBOURS_send_trail_setup_result (&source_peer,
3508 &(my_identity), 3621 &(my_identity),
3509 target_friend, trail_length, 3622 target_friend, trail_length,
@@ -3530,78 +3643,6 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *
3530 return GNUNET_SYSERR; 3643 return GNUNET_SYSERR;
3531} 3644}
3532 3645
3533#if 0
3534/**
3535 * FIXME:
3536 * Does it matter if the packet was going to a finger or friend?
3537 * Core handle for p2p trail rejection messages.
3538 * @param cls closure
3539 * @param message message
3540 * @param peer peer identity this notification is about
3541 * @return GNUNET_OK on success, GNUNET_SYSERR on error
3542 */
3543static
3544int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer,
3545 const struct GNUNET_MessageHeader *message)
3546{
3547 struct PeerTrailRejectionMessage *trail_rejection;
3548 struct FriendInfo *target_friend;
3549 struct GNUNET_PeerIdentity *trail_peer_list;
3550 unsigned int finger_map_index;
3551 uint32_t trail_length;
3552 size_t msize;
3553
3554 msize = ntohs (message->size);
3555 if (msize < sizeof (struct PeerTrailRejectionMessage))
3556 {
3557 GNUNET_break_op (0);
3558 return GNUNET_YES;
3559 }
3560
3561 trail_rejection = (struct PeerTrailRejectionMessage *) message;
3562 trail_length = ntohl (trail_rejection->trail_length);
3563
3564 if ((msize < sizeof (struct PeerTrailRejectionMessage) +
3565 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3566 (trail_length >
3567 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3568 {
3569 GNUNET_break_op (0);
3570 return GNUNET_YES;
3571 }
3572 trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
3573 finger_map_index = ntohl (trail_rejection->finger_map_index);
3574
3575 /* FIXME: I don't think we need failed trail list. will remove it once sure.
3576 * only case where I think we can need it in if in case of finger. where
3577 * we would like to send back the message to current source and leave it
3578 * to the current source to find the closest peer.
3579 trail_fail = GNUNET_malloc (sizeof (struct FailedTrail));
3580 memcpy (&(trail_fail->source_peer), &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
3581 memcpy (&(trail_fail->congested_peer), &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity));
3582 memcpy (&(trail_fail->destination_finger_value), &(trail_rejection->finger_identity), sizeof (uint64_t));
3583
3584 GNUNET_assert (GNUNET_OK ==
3585 GNUNET_CONTAINER_multipeermap_put (failed_trail_list, &(trail_fail->source_peer),
3586 trail_fail, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
3587 */
3588
3589 /* FIXME: Is it okay if I pass the struct as parameter. */
3590 target_friend = select_random_friend (&(trail_rejection->congested_peer));
3591
3592 if(NULL != target_friend)
3593 {
3594 GDS_NEIGHBOURS_send_trail_setup (&(trail_rejection->source_peer),
3595 trail_rejection->finger_identity,
3596 &(target_friend->id),
3597 NULL, target_friend, ntohl (trail_rejection->trail_length),
3598 trail_peer_list,
3599 finger_map_index);
3600 return GNUNET_YES;
3601 }
3602 return GNUNET_SYSERR;
3603}
3604#endif
3605 3646
3606/** 3647/**
3607 * Core handle for p2p trail tear down messages. 3648 * Core handle for p2p trail tear down messages.
@@ -3696,7 +3737,7 @@ remove_matching_finger (void *cls,
3696 struct FingerInfo *remove_finger = value; 3737 struct FingerInfo *remove_finger = value;
3697 const struct GNUNET_PeerIdentity *disconnected_peer = cls; 3738 const struct GNUNET_PeerIdentity *disconnected_peer = cls;
3698 3739
3699 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->head->peer, disconnected_peer)) 3740 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->first_trail_head->peer, disconnected_peer))
3700 { 3741 {
3701 GNUNET_assert (GNUNET_YES == 3742 GNUNET_assert (GNUNET_YES ==
3702 GNUNET_CONTAINER_multipeermap_remove (finger_peermap, 3743 GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
@@ -3795,6 +3836,7 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
3795 3836
3796 friend = GNUNET_new (struct FriendInfo); 3837 friend = GNUNET_new (struct FriendInfo);
3797 friend->id = *peer_identity; 3838 friend->id = *peer_identity;
3839 friend->trails_count = 0;
3798 3840
3799 GNUNET_assert (GNUNET_OK == 3841 GNUNET_assert (GNUNET_OK ==
3800 GNUNET_CONTAINER_multipeermap_put (friend_peermap, 3842 GNUNET_CONTAINER_multipeermap_put (friend_peermap,
@@ -3852,13 +3894,8 @@ GDS_NEIGHBOURS_init (void)
3852 friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); 3894 friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
3853 finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO); 3895 finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO);
3854 3896
3855 /* FIXME: Not sure if this value is correct for this data structure. also
3856 * not sure if we actually need any such data structure. Once done with other functions,
3857 * will revisit this part.
3858 failed_trail_list = GNUNET_CONTAINER_multipeermap_create (LINK_THRESHOLD * 4/3, GNUNET_NO);*/
3859 /* This global variable is set to GNUNET_YES, in case all the friends have their
3860 links threshold set. */
3861 all_friends_trail_threshold = GNUNET_NO; 3897 all_friends_trail_threshold = GNUNET_NO;
3898
3862 return GNUNET_OK; 3899 return GNUNET_OK;
3863} 3900}
3864 3901