gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r33541 - gnunet/src/dht


From: gnunet
Subject: [GNUnet-SVN] r33541 - gnunet/src/dht
Date: Thu, 5 Jun 2014 17:24:26 +0200

Author: supriti
Date: 2014-06-05 17:24:26 +0200 (Thu, 05 Jun 2014)
New Revision: 33541

Modified:
   gnunet/src/dht/
   gnunet/src/dht/gnunet-service-xdht_clients.c
   gnunet/src/dht/gnunet-service-xdht_neighbours.c
   gnunet/src/dht/gnunet-service-xdht_neighbours.h
Log:
Not passing finger_map_index in trail setup message.
Not passing trail length in any message.


Index: gnunet/src/dht
===================================================================
--- gnunet/src/dht      2014-06-05 13:46:59 UTC (rev 33540)
+++ gnunet/src/dht      2014-06-05 15:24:26 UTC (rev 33541)

Property changes on: gnunet/src/dht
___________________________________________________________________
Modified: svn:ignore
## -24,3 +24,6 ##
 gnunet-dht-get
 .deps
 .logfile.swo
+.gnunet-service-xdht_clients.c.kate-swp
+.gnunet-service-xdht_neighbours.c.kate-swp
+.gnunet-service-xdht_neighbours_new.c.kate-swp
Modified: gnunet/src/dht/gnunet-service-xdht_clients.c
===================================================================
--- gnunet/src/dht/gnunet-service-xdht_clients.c        2014-06-05 13:46:59 UTC 
(rev 33540)
+++ gnunet/src/dht/gnunet-service-xdht_clients.c        2014-06-05 15:24:26 UTC 
(rev 33541)
@@ -844,10 +844,8 @@
        cqr->replication,
        cqr->seen_replies_count);
 
-  struct GNUNET_PeerIdentity my_identity;
-  my_identity = GDS_NEIGHBOURS_get_my_id ();
   GDS_NEIGHBOURS_send_get (&cqr->key, cqr->type, cqr->msg_options, 
-                           cqr->replication, my_identity, my_identity, NULL,
+                           cqr->replication, NULL, NULL , NULL,
                            0, 0, NULL);
   
   /* exponential back-off for retries.
@@ -947,12 +945,12 @@
   struct GNUNET_PeerIdentity my_identity =  GDS_NEIGHBOURS_get_my_id();
   GDS_NEIGHBOURS_send_put (&put_msg->key, 
                            ntohl (put_msg->type), ntohl (put_msg->options),
-                           ntohl (put_msg->desired_replication_level),         
                 
-                           my_identity, my_identity, NULL, 0, 0, NULL,
+                           ntohl (put_msg->desired_replication_level), NULL,
+                           NULL, NULL, 0, 0, NULL,
                            GNUNET_TIME_absolute_ntoh (put_msg->expiration),
                            &put_msg[1],
                            size - sizeof (struct GNUNET_DHT_ClientPutMessage));
-                           
+  
 
   GDS_CLIENTS_process_put (ntohl (put_msg->options),
                            ntohl (put_msg->type),

Modified: gnunet/src/dht/gnunet-service-xdht_neighbours.c
===================================================================
--- gnunet/src/dht/gnunet-service-xdht_neighbours.c     2014-06-05 13:46:59 UTC 
(rev 33540)
+++ gnunet/src/dht/gnunet-service-xdht_neighbours.c     2014-06-05 15:24:26 UTC 
(rev 33541)
@@ -45,7 +45,7 @@
 #include "dht.h"
 
 /**
- * Maximum possible fingers of a peer.
+ * Maximum possible fingers (including predecessor) of a peer 
  */
 #define MAX_FINGERS 65
 
@@ -65,92 +65,261 @@
 #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
 
 /**
- * How long will I remain congested?
+ * Duration for which I may remain congested. 
+ * Note: Its a static value. In future, a peer may do some analysis and 
calculate 
+ * congestion_timeout based on 'some' parameters. 
  */
 #define CONGESTION_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MINUTES, 2)
 
 /**
+ * Maximum number of trails allowed to go through a friend.
+ */
+#define TRAILS_THROUGH_FRIEND_THRESHOLD 64
+
+/**
  * Maximum number of trails stored per finger.
  */
 #define MAXIMUM_TRAILS_PER_FINGER 2
 
 /**
- * Used to distinguish put/get request use of find_successor() from others
+ * Finger map index for predecessor entry in finger peermap.
  */
-#define PUT_GET_REQUEST 65
+#define PREDECESSOR_FINGER_ID 64
 
 /**
- * Maximum number of trails that can go through a friend.
+ * Wrap around in peer identity circle. 
+ * FIXME: not used anywhere, should be used in
+ * find_successor() while comparing two peers.
  */
-#define TRAIL_THROUGH_FRIEND_THRESHOLD 64
+#define PEER_IDENTITES_WRAP_AROUND pow(2, 64) - 1
 
 /**
- * Finger map index for predecessor entry in finger peermap.
+ * To check if a finger is predecessor or not. 
  */
-#define PREDECESSOR_FINGER_ID 64
+enum GDS_NEIGHBOURS_finger_type
+{
+  GDS_FINGER_TYPE_PREDECESSOR = 0,
+  GDS_FINGER_TYPE_NON_PREDECESSOR = 1
+};
 
+GNUNET_NETWORK_STRUCT_BEGIN
+
 /**
- * Maximum number of trails allowed to go through a friend.
+ * P2P PUT message
  */
-#define TRAILS_THROUGH_FRIEND_THRESHOLD 64
+struct PeerPutMessage
+{
+  /**
+   * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
+   */
+  struct GNUNET_MessageHeader header;
 
+  /**
+   * Processing options
+   */
+  uint32_t options GNUNET_PACKED;
+
+  /**
+   * Content type.
+   */
+  uint32_t block_type GNUNET_PACKED;
+
+  /**
+   * Hop count
+   */
+  uint32_t hop_count GNUNET_PACKED;
+
+  /**
+   * Replication level for this message
+   * In the current implementation, this value is not used. 
+   */
+  uint32_t desired_replication_level GNUNET_PACKED;
+
+  /**
+   * Length of the PUT path that follows (if tracked).
+   */
+  uint32_t put_path_length GNUNET_PACKED;
+  
+  /** 
+   * Best known destination (could be my friend or finger) which should
+   * get this message next. 
+   */
+  struct GNUNET_PeerIdentity best_known_destination;
+  
+  /**
+   * In case best_known_destination is a finger, then trail to reach
+   * to that finger. Else its default value is 0. 
+   */
+  struct GNUNET_HashCode intermediate_trail_id;
+  
+  /**
+   * When does the content expire?
+   */
+  struct GNUNET_TIME_AbsoluteNBO expiration_time;
+  
+  /**
+   * The key to store the value under.
+   */
+  struct GNUNET_HashCode key GNUNET_PACKED;
+
+  /* put path (if tracked) */
+
+  /* Payload */
+ 
+};
+
 /**
- * Wrap around in peer identity circle. 
+ * P2P GET message
  */
-#define PEER_IDENTITES_WRAP_AROUND pow(2, 256) - 1
+struct PeerGetMessage
+{
+  /**
+   * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET
+   */
+  struct GNUNET_MessageHeader header;
+  
+  /**
+   * Processing options
+   */
+  uint32_t options GNUNET_PACKED;
 
-GNUNET_NETWORK_STRUCT_BEGIN
+  /**
+   * Desired content type.
+   */
+  uint32_t block_type GNUNET_PACKED;
+  
+  /**
+   * Hop count
+   */
+  uint32_t hop_count GNUNET_PACKED;
+ 
+  /**
+   * Desired replication level for this request.
+   * In the current implementation, this value is not used. 
+   */
+  uint32_t desired_replication_level GNUNET_PACKED;
+  
+  /**
+   * Total number of peers in get path. 
+   */
+  unsigned int get_path_length;
+  
+  /**
+   * Best known destination (could be my friend or finger) which should
+   * get this message next. 
+   */
+  struct GNUNET_PeerIdentity best_known_destination;
+  
+  /**
+   * In case best_known_destination is a finger, then trail to reach
+   * to that finger. Else its default value is 0. 
+   */
+  struct GNUNET_HashCode intermediate_trail_id;
+ 
+  /**
+   * The key we are looking for.
+   */
+  struct GNUNET_HashCode key;
+  
+  /* Get path. */
 
+};
+
 /**
- * P2P Trail setup message
+ * P2P Result message
  */
-struct PeerTrailSetupMessage
+struct PeerGetResultMessage
 {
   /**
-   * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
+   * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT
    */
   struct GNUNET_MessageHeader header;
 
-  /* Bitmask of options, 1 = IS_PREDECESSOR */
-  // int32_t options;
-
   /**
-   * Peer closest to this value will be our finger.
+   * The type for the data.
    */
-  uint64_t ultimate_destination_finger;
+  uint32_t type GNUNET_PACKED;
+  
+  /**
+   * Number of peers recorded in the outgoing path from source to the
+   * stored location of this message.
+   */
+  uint32_t put_path_length GNUNET_PACKED;
+  
+  /**
+   * Length of the GET path that follows (if tracked).
+   */
+  uint32_t get_path_length GNUNET_PACKED;
+  
+  /**
+   * Peer which queried for get and should get the result. 
+   */
+  struct GNUNET_PeerIdentity querying_peer;
+  
+  /**
+   * When does the content expire?
+   */
+  struct GNUNET_TIME_Absolute expiration_time;
 
   /**
-   * Source peer which wants to setup the trail to one of its finger.
+   * The key of the corresponding GET request.
    */
-  struct GNUNET_PeerIdentity source_peer;
+  struct GNUNET_HashCode key;
+ 
+  /* put path (if tracked) */
 
+  /* get path (if tracked) */
+
+  /* Payload */
+
+};
+
+/**
+ * P2P Trail setup message
+ */
+struct PeerTrailSetupMessage
+{
   /**
-   * Peer to which this packet is forwarded.
+   * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
    */
-  struct GNUNET_PeerIdentity next_destination; // rename "best_known_dest"
+  struct GNUNET_MessageHeader header;
+  
+  /**
+   * Is source_peer trying to setup the trail to any finger or predecessor.
+   */
+  uint32_t is_predecessor; 
+  
+  /**
+   * Peer closest to this value will be our finger.
+   */
+  uint64_t ultimate_destination_finger_value;
 
   /**
-   * Index into finger peer map, in Network Byte Order.
+   * Source peer which wants to setup the trail to one of its finger.
    */
-  uint32_t finger_map_index; // remove this, include 
ultimate_destination_finger in response, calculate index from it
+  struct GNUNET_PeerIdentity source_peer;
 
   /**
-   * Number of entries in trail_list, in Network Byte Order.
+   * Best known destination (could be my friend or finger) which should
+   * get this message next. 
    */
-  uint32_t trail_length GNUNET_PACKED; // remove this, calculte length from 
message size
+  struct GNUNET_PeerIdentity best_known_destination; 
 
   /**
    * Trail id of any intermediate trail we may encounter while doing trail 
setup.
    */
   struct GNUNET_HashCode intermediate_trail_id;
-
+  
   /**
    * Trail id for trail which we are trying to setup.
    */
-  struct GNUNET_HashCode new_trail_id; // rename to "trail_id"
+  struct GNUNET_HashCode trail_id; 
 
-  /* Trail formed in the process. */
-  /* GNUNET_PeerIdentity trail_list[] */
+  /* List of peers which are part of trail setup so far.
+   * Trail does NOT include source_peer and peer which will be closest to
+   * ultimate_destination_finger_value.
+   * struct GNUNET_PeerIdentity trail_list[]
+   */
 };
 
 /**
@@ -170,27 +339,30 @@
   struct GNUNET_PeerIdentity finger_identity;
 
   /**
-   * Peer which was looking for the trail to finger.
+   * Peer which started trail_setup to find trail to finger_identity
    */
-  struct GNUNET_PeerIdentity destination_peer; // querying_peer
+  struct GNUNET_PeerIdentity querying_peer; 
 
   /**
-   * Index into finger peer map in NBO.
+   * Is the trail setup to querying_peer's predecessor or finger?
    */
-  uint32_t finger_map_index; // flag/option with IS_PREDECESSOR
+  uint32_t is_predecessor; 
 
   /**
-   * Number of entries in trail list in NBO.
+   * Value to which finger_identity is the closest peer. 
    */
-  uint32_t trail_length GNUNET_PACKED; // remove, calculate
-
+  uint64_t ulitmate_destination_finger_value;
+  
   /**
-   * Identifier of the trail.
+   * Identifier of the trail from querying peer to finger_identity, NOT
+   * including both endpoints. 
    */
   struct GNUNET_HashCode trail_id;
 
-  /* Trail from "destination_peer" to finger_identity, NOT including both */
-  /* struct GNUNET_PeerIdentity trail[] */
+  /* List of peers which are part of the trail from querying peer to 
+   * finger_identity, NOT including both endpoints.
+   * struct GNUNET_PeerIdentity trail[] 
+   */
 };
 
 /**
@@ -204,12 +376,12 @@
   struct GNUNET_MessageHeader header;
 
   /**
-   * Source peer which wants to verify its successor.
+   * Peer which wants to verify its successor.
    */
   struct GNUNET_PeerIdentity source_peer;
 
   /**
-   * My current successor.
+   * Source Peer's current successor.
    */
   struct GNUNET_PeerIdentity successor;
 
@@ -218,15 +390,17 @@
    */
   struct GNUNET_HashCode trail_id;
 
-  /**
-   * Total number of peers to reach from source to successor.
+  /* List of the peers which are part of trail to reach  from source_peer 
+   * to successor, NOT including them
+   * struct GNUNET_PeerIdentity trail[] 
    */
-  unsigned int trail_length;
-
-  /* Trail. */
 };
 
 /**
+ * FIXME: In case you append the trail it may contain the same peer twice.
+ * So, when you call search_my_index it can return error. Solution is while
+ * appending the entry first check for duplicate entries or may be don't
+ * send the current_predecessor at all. 
  * P2P Verify Successor Result Message
  */
 struct PeerVerifySuccessorResultMessage
@@ -237,9 +411,9 @@
   struct GNUNET_MessageHeader header;
 
   /**
-   * Destination peer which sent the request to verify its successor.
+   * Peer which sent the request to verify its successor.
    */
-  struct GNUNET_PeerIdentity destination_peer;
+  struct GNUNET_PeerIdentity querying_peer;
 
   /**
    * Successor to which PeerVerifySuccessorMessage was sent.
@@ -247,28 +421,25 @@
   struct GNUNET_PeerIdentity source_successor;
 
   /**
-   * source_successor's predecessor
+   * Current Predecessor of source_successor. It can be same as querying peer
+   * or different.
    */
-  struct GNUNET_PeerIdentity my_predecessor;
+  struct GNUNET_PeerIdentity current_predecessor;
 
   /**
-   * Trail identifier of trail from my_predecessor to source_successor.
+   * Trail identifier of trail from querying_peer to source_successor.
    */
   struct GNUNET_HashCode trail_id;
 
   /**
    * Direction in which we are looking at the trail.
    */
-  enum GDS_ROUTING_trail_direction trail_direction;
+  uint32_t trail_direction;
 
-  /**
-   * Total number of peers in trail from source_successor to my_predecessor
-   * if my_predecessor is not same as destination_peer.
+  /* In case current_predecessor != querying_peer, then trail to reach from
+   * querying_peer to current_predecessor, NOT including end points.
+   * struct GNUNET_PeerIdentity trail[]
    */
-  uint32_t trail_length;
-
-  /* Trail from source_successor to my_predecessor where
-   * my_predecessor != destination_peer*/
 };
 
 /**
@@ -282,29 +453,31 @@
   struct GNUNET_MessageHeader header;
 
   /**
-   * Source peer which wants to notify its new successor.
+   * Peer which wants to notify its new successor.
    */
   struct GNUNET_PeerIdentity source_peer;
 
   /**
-   * New successor identity.
+   * New successor of source_peer.
    */
-  struct GNUNET_PeerIdentity destination_peer;
+  struct GNUNET_PeerIdentity new_successor;
 
   /**
-   * Total number of peers in trail from source_peer to destination_peer
+   * Unique identifier of the trail from source_peer to new_successor,
+   * NOT including the endpoints.
    */
-  unsigned int trail_length;
+  struct GNUNET_HashCode trail_id;
 
-  /**
-   * Unique identifier of the trail.
+  /* List of peers in trail from source_peer to new_successor, 
+   * NOT including the endpoints. 
+   * struct GNUNET_PeerIdentity trail[]
    */
-  struct GNUNET_HashCode trail_id;
-
-  /* Trail. */
 };
 
 /**
+ * FIXME: Check if you can merge trail compression and trail teardown
+ * by modifying routing table structure a little bit. PRIORITY: at the end
+ * less code. 
  * P2P Trail Compression Message.
  */
 struct PeerTrailCompressionMessage
@@ -366,7 +539,7 @@
   /**
    * Direction of trail.
    */
-  enum GDS_ROUTING_trail_direction trail_direction;
+  uint32_t trail_direction;
 };
 
 
@@ -381,42 +554,39 @@
   struct GNUNET_MessageHeader header;
 
   /**
-   * Source peer which wants to set up the trail.
+   * Peer which wants to set up the trail.
    */
   struct GNUNET_PeerIdentity source_peer;
 
   /**
-   * Peer which sent trail rejection message.
+   * Peer which sent trail rejection message as it it congested. 
    */
   struct GNUNET_PeerIdentity congested_peer;
 
   /**
-   * Peer identity which will be successor to this value will be finger of
+   * Peer identity closest to this value will be finger of
    * source_peer.
    */
-  uint64_t ultimate_destination_finger_identity_value;
+  uint64_t ultimate_destination_finger_value;
 
   /**
-   * Index in finger peer map of source peer.
+   * Is source_peer trying to setup the trail to its predecessor or finger.
    */
-  uint32_t finger_map_index;
+  uint32_t is_predecessor;
 
   /**
-   * Total number of peers in the trail.
+   * Identifier for the trail that source peer is trying to setup.
    */
-  uint32_t trail_length;
-
-  /**
-   * Identifier for the trail source peer is trying to setup.
-   */
   struct GNUNET_HashCode trail_id;
+  
   /**
    * Relative time for which congested_peer will remain congested.
    */
   struct GNUNET_TIME_Relative congestion_time;
 
   /* Trail_list from source_peer to peer which sent the message for trail setup
-   * to congested peer.*/
+   * to congested peer. This trail does NOT include source_peer.
+   struct GNUNET_PeerIdnetity trail[]*/
 };
 
 /**
@@ -430,26 +600,24 @@
   struct GNUNET_MessageHeader header;
 
   /**
-   * Source peer of the routing trail.
+   * Source of the routing trail.
    */
   struct GNUNET_PeerIdentity source_peer;
 
   /**
-   * Destination peer of the routing trail.
+   * Destination of the routing trail.
    */
   struct GNUNET_PeerIdentity destination_peer;
 
   /**
-   * Total number of peers from source peer to destination peer.
+   * Unique identifier of the trail from source_peer to destination_peer,
+   * NOT including the endpoints.
    */
-  unsigned int trail_length;
+  struct GNUNET_HashCode trail_id;
 
-  /**
-   * Unique identifier of the trail.
+  /* Trail from source peer to destination peer, NOT including them.
+   * struct GNUNET_PeerIdentity trail[]
    */
-  struct GNUNET_HashCode trail_id;
-
-  /* Trail from source peer to destination peer. */
 };
 
 GNUNET_NETWORK_STRUCT_END
@@ -500,7 +668,8 @@
   struct GNUNET_PeerIdentity id;
 
   /**
-   * Number of trails for which this friend is the first hop.
+   * Number of trails for which this friend is the first hop or if the friend
+   * is finger. 
    */
   unsigned int trails_count;
 
@@ -532,19 +701,19 @@
 };
 
 /**
- * An individual trail to reach to a finger.
+ * An individual element of the trail to reach to a finger.
  */
-struct Trail // "node" "element" "relay"
+struct Trail_Element 
 {
   /**
     * Pointer to next item in the list
     */
-  struct Trail *next;
+  struct Trail_Element *next;
 
   /**
     * Pointer to prev item in the list
     */
-  struct Trail *prev;
+  struct Trail_Element *prev;
 
   /**
    * An element in this trail.
@@ -553,19 +722,22 @@
 };
 
 /**
- * List of all trails to reach a particular finger.
+ * FIXME: removed first_friend_trails_count, need to write a function
+ * to calculate each time we need it. Else, keep a pointer to first
+ * friend of in the trail. 
+ * Information about an individual trail. 
  */
-struct TrailList // "trail": list of "elements"
+struct Trail 
 {
   /**
    * Head of trail.
    */
-  struct Trail *trail_head;
+  struct Trail_Element *trail_head;
 
   /**
    * Tail of trail.
    */
-  struct Trail *trail_tail;
+  struct Trail_Element *trail_tail;
 
   /**
    * Unique identifier of this trail.
@@ -576,12 +748,6 @@
    * Length of trail pointed
    */
   unsigned int trail_length;
-
-  /**
-   * Number of trails that the first friend of this trail is a part of.
-   */
-  unsigned int first_friend_trail_count; // remove this, duplicate variable!
-                                         // include a pointer to Friend or 
function that calculates it
 };
 
 /**
@@ -601,16 +767,18 @@
 
   /**
    * Number of trails setup so far for this finger.
+   * Should not cross MAXIMUM_TRAILS_PER_FINGER.
    */
   uint32_t trails_count;
 
   /**
-   * Array of trails.
+   * Array of trails to reach to this finger.
    */
-  struct TrailList trail_list[MAXIMUM_TRAILS_PER_FINGER]; // OK!
+  struct Trail trail_list[MAXIMUM_TRAILS_PER_FINGER]; 
 };
 
 /**
+ * FIXME: Need to check if we need all the fields or not. 
  * Data structure to keep track of closest peer seen so far in find_successor()
  */
 struct Closest_Peer
@@ -626,7 +794,7 @@
   struct GNUNET_HashCode trail_id;
 
   /**
-   * First hop, NULL in case of friend and my_identity
+   * FIXME: see the usage of this field and write comment. 
    */
   struct GNUNET_PeerIdentity next_hop;
 
@@ -634,13 +802,15 @@
    * Next destination. In case of friend and my_identity , it is same as 
next_hop
    * In case of finger it is finger identity.
    */
-  struct GNUNET_PeerIdentity next_destination;
+  struct GNUNET_PeerIdentity best_known_destination;
 };
 
 /**
+ * FIXME: now I have removed the first_friend_trail_count,
+ * Need to update the code to find the count.
  * Data structure to store the trail chosen to reach to finger.
  */
-struct Correct_Trail
+struct Selected_Finger_Trail
 {
   /**
    * First friend in the trail to reach finger.
@@ -680,13 +850,19 @@
 static struct GNUNET_CONTAINER_MultiHashMap32 *finger_hashmap;
 
 /**
+ * FIXME: Check if you can replace finger_hashmap by an array of fingers. 
+ * Array of all the fingers. 
+ *
+static struct FingerInfo finger_table [MAX_FINGERS];*/
+
+/**
  * Handle to CORE.
  */
 static struct GNUNET_CORE_Handle *core_api;
 
 /**
  * The current finger index that we have want to find trail to. We start the
- * search with value = 0, i.e. successor peer and then go to 
PREDCESSOR_FINGER_ID
+ * search with value = 0, i.e. successor  and then go to PREDCESSOR_FINGER_ID
  * and decrement it. For any index 63 <= index < 0, if finger is same as 
successor,
  * we reset this index to 0.
  */
@@ -766,7 +942,6 @@
 
 
 /**
- * FIXME: assertion fails at the end of this function. also in core_api.c at 
1299.
  * Transmit all messages in the friend's message queue.
  *
  * @param peer message queue to process
@@ -799,29 +974,29 @@
 
 /**
  * Construct a trail setup message and forward it to target_friend
- * @param source_peer Source peer which wants to setup the trail
- * @param ultimate_destination_finger Peer identity closest to this value will
- *                                    be finger to @a source_peer
- * @param next_destination Peer which should get the packet. I can be same as
- *                         target_friend or different.
+ * @param source_peer Peer which wants to setup the trail
+ * @param ultimate_destination_finger_value Peer identity closest to this 
value 
+ *                                          will be finger to @a source_peer
+ * @param best_known_destination Best known destination (could be finger or 
friend)
+ *                               which should get this message.
  * @param target_friend Friend to which message is forwarded now.
  * @param trail_length Total number of peers in trail setup so far.
  * @param trail_peer_list Trail setup so far
- * @param finger_map_index Index in finger map for which we are looking for 
finger.
+ * @param is_predecessor Is source_peer looking for trail to a predecessor or 
not.
  * @param trail_id Unique identifier for the trail we are trying to setup.
- * @param intermediate_trail_id Trail id of any intermediate trail we may have 
to
- *                              traverse during trail setup. If not used then 
set to
- *                              0.
+ * @param intermediate_trail_id Trail id of intermediate trail to reach to 
+ *                              best_known_destination when its a finger. If 
not 
+ *                              used then set to 0.
  */
 void
-GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity source_peer,
-                                 uint64_t ultimate_destination_finger,
-                                 struct GNUNET_PeerIdentity next_destination,
+GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity source_peer,
+                                 uint64_t ultimate_destination_finger_value,
+                                 struct GNUNET_PeerIdentity 
best_known_destination,
                                  struct FriendInfo *target_friend,
                                  unsigned int trail_length,
                                  const struct GNUNET_PeerIdentity 
*trail_peer_list,
-                                 unsigned int finger_map_index,
-                                 struct GNUNET_HashCode new_trail_id,
+                                 unsigned int is_predecessor,
+                                 struct GNUNET_HashCode trail_id,
                                  struct GNUNET_HashCode *intermediate_trail_id)
 {
   struct P2PPendingMessage *pending;
@@ -850,16 +1025,17 @@
   pending->msg = &tsm->header;
   tsm->header.size = htons (msize);
   tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
-  tsm->ultimate_destination_finger = GNUNET_htonll 
(ultimate_destination_finger);
+  tsm->ultimate_destination_finger_value = GNUNET_htonll 
(ultimate_destination_finger_value);
   tsm->source_peer = source_peer;
-  tsm->next_destination = next_destination;
-  tsm->trail_length = htonl (trail_length);
-  tsm->finger_map_index = htonl (finger_map_index);
-  tsm->new_trail_id = new_trail_id;
+  tsm->best_known_destination = best_known_destination;
+  tsm->is_predecessor = htonl (is_predecessor);
+  tsm->trail_id = trail_id;
+  
   if (NULL == intermediate_trail_id)
     memset (&tsm->intermediate_trail_id, 0, sizeof 
(tsm->intermediate_trail_id));
   else
     tsm->intermediate_trail_id = *intermediate_trail_id;
+  
   if (trail_length > 0)
   {
     peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
@@ -874,21 +1050,26 @@
 
 /**
  * Construct a trail setup result message and forward it to target friend.
- * @param destination_peer Peer which will get the trail to one of its finger.
- * @param source_finger Peer to which the trail has been setup to.
+ * @param querying_peer Peer which sent the trail setup request and should get
+ *                      the result back. 
+ * @param Finger Peer to which the trail has been setup to.
  * @param target_friend Friend to which this message should be forwarded.
  * @param trail_length Numbers of peers in the trail.
- * @param trail_peer_list Peers which are part of the trail from source to 
destination.
- * @param finger_map_index Index in finger peer map
+ * @param trail_peer_list Peers which are part of the trail from q
+ *                        querying_peer to Finger, NOT including them. 
+ * @param is_predecessor Is @a Finger predecessor to @a querying_peer
+ * @param ultimate_destination_finger_value Value to which @a finger is the 
closest
+ *                                          peer. 
  * @param trail_id Unique identifier of the trail.
  */
 void
-GDS_NEIGHBOURS_send_trail_setup_result (struct GNUNET_PeerIdentity 
destination_peer,
-                                        struct GNUNET_PeerIdentity 
source_finger,
+GDS_NEIGHBOURS_send_trail_setup_result (struct GNUNET_PeerIdentity 
querying_peer,
+                                        struct GNUNET_PeerIdentity finger,
                                         struct FriendInfo *target_friend,
                                         unsigned int trail_length,
                                         const struct GNUNET_PeerIdentity 
*trail_peer_list,
-                                        unsigned int finger_map_index,
+                                        unsigned int is_predecessor,
+                                        uint64_t 
ultimate_destination_finger_value,
                                         struct GNUNET_HashCode trail_id)
 {
   struct P2PPendingMessage *pending;
@@ -918,12 +1099,12 @@
   pending->msg = &tsrm->header;
   tsrm->header.size = htons (msize);
   tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT);
-  tsrm->destination_peer = destination_peer;
-  tsrm->finger_identity = source_finger;
-  tsrm->trail_length = htonl (trail_length);
-  tsrm->finger_map_index = htonl (finger_map_index);
+  tsrm->querying_peer = querying_peer;
+  tsrm->finger_identity = finger;
+  tsrm->is_predecessor = htonl (is_predecessor);
   tsrm->trail_id = trail_id;
-
+  tsrm->ulitmate_destination_finger_value = 
+          GNUNET_htonll (ultimate_destination_finger_value);
   peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
   if (trail_length > 0)
   {
@@ -938,24 +1119,25 @@
 
 /**
  * Send trail rejection message to next_hop
- * @param source_peer Source peer which is trying to setup the trail.
- * @param finger_identity Peer closest to this value will be @a source_peer's 
finger
+ * @param source_peer Peer which is trying to setup the trail.
+ * @param ultimate_destination_finger_value Peer closest to this value will be 
+ *                                          @a source_peer's finger
  * @param congested_peer Peer which sent this message as it is congested.
- * @param next_hop Peer to which we are forwarding this message.
- * @param finger_map_index Index in finger peermap for which we are searching 
for finger.
+ * @param is_predecessor Is source_peer looking for trail to a predecessor or 
not.
  * @param trail_peer_list Trails seen so far in trail setup before getting 
rejected
- *                        by congested_peer
- * @param trail_length Total number of peers in trail_peer_list
+ *                        by congested_peer. This does not include @a 
source_peer
+ * @param trail_length Total number of peers in trail_peer_list, not including
+ *                     @a source_peer
  * @param trail_id Unique identifier of this trail.
  * @param congestion_timeout Duration given by congested peer as an estimate of
  *                           how long it may remain congested.
  */
 void
 GDS_NEIGHBOURS_send_trail_rejection (struct GNUNET_PeerIdentity source_peer,
-                                     uint64_t finger_identity,
+                                     uint64_t 
ultimate_destination_finger_value,
                                      struct GNUNET_PeerIdentity congested_peer,
-                                     unsigned int finger_map_index,
-                                     struct GNUNET_PeerIdentity 
*trail_peer_list,
+                                     unsigned int is_predecessor,
+                                     const struct GNUNET_PeerIdentity 
*trail_peer_list,
                                      unsigned int trail_length,
                                      struct GNUNET_HashCode trail_id,
                                      struct FriendInfo *target_friend,
@@ -991,14 +1173,16 @@
   trm->source_peer = source_peer;
   trm->congested_peer = congested_peer;
   trm->congestion_time = congestion_timeout;
-  trm->finger_map_index = htonl (finger_map_index);
+  trm->is_predecessor = htonl (is_predecessor);
   trm->trail_id = trail_id;
+  trm->ultimate_destination_finger_value = GNUNET_htonll 
(ultimate_destination_finger_value);
 
   peer_list = (struct GNUNET_PeerIdentity *) &trm[1];
   if (trail_length > 0)
   {
     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct 
GNUNET_PeerIdentity));
   }
+  
   /* Send the message to chosen friend. */
   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, 
pending);
   target_friend->pending_count++;
@@ -1010,10 +1194,12 @@
  * Construct a verify successor message and forward it to target_friend.
  * @param source_peer Peer which wants to verify its successor.
  * @param successor Peer which is @a source_peer's current successor.
- * @param trail_id Identifier of trail to reach successor.
- * @param trail Trail to reach from source_peer to successor
+ * @param trail_id Unique Identifier of trail from @a source_peer to @a 
successor,
+ *                 NOT including them. 
+ * @param trail List of peers which are part of trail to reach from @a 
source_peer
+ *              to @a successor, NOT including them. 
  * @param trail_length Total number of peers in @a trail.
- * @param target_friend Message send to this friend.
+ * @param target_friend Next friend to get this message. 
  */
 void
 GDS_NEIGHBOURS_send_verify_successor_message (struct GNUNET_PeerIdentity 
source_peer,
@@ -1051,8 +1237,7 @@
   vsm->source_peer = source_peer;
   vsm->successor = successor;
   vsm->trail_id = trail_id;
-  vsm->trail_length = htonl (trail_length);
-
+  
   if (trail_length > 0)
   {
     peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
@@ -1067,6 +1252,7 @@
 
 
 /**
+ * FIXME: check if we can merge send_trail_teardown and trail_compression
  * Construct a trail teardown message and send it to target_friend
  * @param source_peer Source of the trail.
  * @param destination_peer Destination of the trail.
@@ -1119,19 +1305,24 @@
 
 
 /**
- * Construct a verify successor message and send it to target_friend
- * @param destination_peer
- * @param source_successor
- * @param succ_predecessor
- * @param trail_id
- * @param trail
- * @param trail_length
- * @param target_friend
+ * Construct a verify successor result message and send it to target_friend
+ * @param querying_peer Peer which sent the verify successor message. 
+ * @param source_successor Current_successor of @a querying_peer. 
+ * @param current_predecessor Current predecessor of @a successor. Could be 
same
+ *                            or different from @a querying_peer.
+ * @param trail_id Unique identifier of the trail from @a querying_peer to 
+ *                 @a successor, NOT including them.
+ * @param trail List of peers which are part of trail from @a querying_peer to 
+ *                 @a successor, NOT including them.
+ * @param trail_length Total number of peers in @a trail
+ * @param trail_direction Direction in which we are sending the message. In 
this
+ *                        case we are sending result from @a successor to @a 
querying_peer.
+ * @param target_friend Next friend to get this message. 
  */
 void
-GDS_NEIGHBOURS_send_verify_successor_result (struct GNUNET_PeerIdentity 
destination_peer,
+GDS_NEIGHBOURS_send_verify_successor_result (struct GNUNET_PeerIdentity 
querying_peer,
                                              struct GNUNET_PeerIdentity 
source_successor,
-                                             struct GNUNET_PeerIdentity 
succ_predecessor,
+                                             struct GNUNET_PeerIdentity 
current_predecessor,
                                              struct GNUNET_HashCode trail_id,
                                              const struct GNUNET_PeerIdentity 
*trail,
                                              unsigned int trail_length,
@@ -1165,11 +1356,12 @@
   pending->msg = &vsmr->header;
   vsmr->header.size = htons (msize);
   vsmr->header.type = htons 
(GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT);
-  vsmr->destination_peer = destination_peer;
-  vsmr->my_predecessor = succ_predecessor;
+  vsmr->querying_peer = querying_peer;
   vsmr->source_successor = source_successor;
+  vsmr->current_predecessor = current_predecessor;
   vsmr->trail_direction = htonl (trail_direction);
-
+  vsmr->trail_id = trail_id;
+  
   if (trail_length > 0)
   {
     peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
@@ -1185,18 +1377,22 @@
 
 /**
  * Construct a notify new successor message and send it to target_friend
- * @param source_peer
- * @param new_successor
- * @param new_successor_trail
- * @param new_successor_trail_length
- * @param new_succesor_trail_id
+ * @param source_peer Peer which wants to notify to its new successor that it
+ *                    could be its predecessor. 
+ * @param successor New successor of @a source_peer
+ * @param successor_trail List of peers in Trail to reach from 
+ *                            @a source_peer to @a new_successor, NOT 
including 
+ *                            the endpoints. 
+ * @param successor_trail_length Total number of peers in @a 
new_successor_trail.
+ * @param successor_trail_id Unique identifier of @a new_successor_trail. 
+ * @param target_friend Next friend to get this message. 
  */
 void
 GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity 
source_peer,
-                                          struct GNUNET_PeerIdentity 
new_successor,
-                                          struct GNUNET_PeerIdentity 
*new_successor_trail,
-                                          unsigned int 
new_successor_trail_length,
-                                          struct GNUNET_HashCode 
new_succesor_trail_id,
+                                          struct GNUNET_PeerIdentity successor,
+                                          struct GNUNET_PeerIdentity 
*successor_trail,
+                                          unsigned int successor_trail_length,
+                                          struct GNUNET_HashCode 
succesor_trail_id,
                                           struct FriendInfo *target_friend)
 {
   struct PeerNotifyNewSuccessorMessage *nsm;
@@ -1205,7 +1401,7 @@
   size_t msize;
 
   msize = sizeof (struct PeerNotifyNewSuccessorMessage) +
-          (new_successor_trail_length * sizeof(struct GNUNET_PeerIdentity));
+          (successor_trail_length * sizeof(struct GNUNET_PeerIdentity));
 
   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
   {
@@ -1226,15 +1422,15 @@
   pending->msg = &nsm->header;
   nsm->header.size = htons (msize);
   nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR);
+  nsm->new_successor = successor;
   nsm->source_peer = source_peer;
-  nsm->destination_peer = new_successor;
-  nsm->trail_length = htonl (new_successor_trail_length);
-  nsm->trail_id = new_succesor_trail_id;
-  if (new_successor_trail_length > 0)
+  nsm->trail_id = succesor_trail_id;
+  
+  if (successor_trail_length > 0)
   {
     peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
-    memcpy (peer_list, new_successor_trail,
-            new_successor_trail_length * sizeof (struct GNUNET_PeerIdentity));
+    memcpy (peer_list, successor_trail,
+            successor_trail_length * sizeof (struct GNUNET_PeerIdentity));
   }
 
    /* Send the message to chosen friend. */
@@ -1248,10 +1444,12 @@
  * Construct an add_trail message and send it to target_friend
  * @param source_peer Source of the trail.
  * @param destination_peer Destination of the trail.
- * @param trail_id Unique identifer of the trail
- * @param trail Trail from @a source_peer to @a destination_peer
+ * @param trail_id Unique identifier of the trail from 
+ *                 @a source_peer to @a destination_peer, NOT including the 
endpoints.
+ * @param trail List of peers in Trail from @a source_peer to @a 
destination_peer,
+ *              NOT including the endpoints. 
  * @param trail_length Total number of peers in @a trail.
- * @param target_friend Next peer to get this message.
+ * @param target_friend Next friend to get this message.
  */
 void
 GDS_NEIGHBOURS_send_add_trail (struct GNUNET_PeerIdentity source_peer,
@@ -1290,7 +1488,6 @@
   adm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL);
   adm->source_peer = source_peer;
   adm->destination_peer = destination_peer;
-  adm->trail_length = htonl (trail_length);
   adm->trail_id = trail_id;
 
   if (trail_length > 0)
@@ -1308,7 +1505,7 @@
 
 
 /**
- * Merge into "teardown", add source and "last/new_first" in message struct.
+ * FIXME: Merge into "teardown", add source and "last/new_first" in message 
struct.
  * Construct a trail compression message and send it to target_friend.
  * @param source_peer Source of the trail.
  * @param destination_finger Destination of trail.
@@ -1362,7 +1559,7 @@
 
 
 /**
- * Seach my location in trail.
+ * Search my location in trail.
  * @param trail List of peers
  * @return my_index if found
  *         -1 if no entry found.
@@ -1382,64 +1579,71 @@
   return -1;
 }
 
+/**
+ * Check if the friend is congested or have reached maximum number of trails
+ * it can be part of of. 
+ * @param friend Friend to be chechked.
+ * @return #GNUNET_YES if friend is not congested or have not crossed 
threshold.
+ *         #GNUNET_NO if friend is either congested or have crossed threshold 
+ */
+static int
+is_friend_congested (struct FriendInfo *friend)
+{
+  if ((friend->trails_count == TRAILS_THROUGH_FRIEND_THRESHOLD)||
+      ((0 != GNUNET_TIME_absolute_get_remaining
+             (friend->congestion_timestamp).rel_value_us)))
+    return GNUNET_YES;
+  else
+    return GNUNET_NO;
+}
 
+
 /**
- * Iterate over the list of all the trails to reach Finger. In case the first
- * friend to reach the finger has crossed the trail threshold or is congested,
+ * FIXME: here we should also check if iterator is null or not. It can be NULL
+ * only if we insert randomly at locations. But as we are using trails_count
+ * as the parameter, it should not happen.
+ * Iterate over the list of all the trails of a finger. In case the first
+ * friend to reach the finger has reached trail threshold or is congested,
  * then don't select it. In case there multiple available good trails to reach
  * to Finger, choose the one with shortest trail length.
+ * Note: We use length as parameter. But we can use any other suitable 
parameter
+ * also. 
  * @param finger Finger
- * @return struct Correct_Trail which contains the first friend , trail id
+ * @return struct Selected_Finger_Trail which contains the first friend , 
trail id
  * and trail length. NULL in case none of the trails are free.
  */
-static struct Correct_Trail *
-select_trail_to_finger (struct FingerInfo *finger)
+static struct Selected_Finger_Trail *
+select_finger_trail (struct FingerInfo *finger)
 {
   struct FriendInfo *friend;
-  struct TrailList *iterator;
-  struct Correct_Trail *finger_trail;
-  int i;
+  struct Trail *iterator;
+  struct Selected_Finger_Trail *finger_trail;
+  unsigned int i;
 
-  if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity,
-                                            &my_identity))
-    return NULL;
-
-  finger_trail = GNUNET_new (struct Correct_Trail);
-
+  finger_trail = GNUNET_new (struct Selected_Finger_Trail);
+  
   for (i = 0; i < finger->trails_count; i++)
   {
     iterator = &finger->trail_list[i];
-    if (iterator->trail_length > 0)
+    friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
+                                                &iterator->trail_head->peer);
+    if (GNUNET_YES == is_friend_congested (friend))
+      continue;
+   
+    /* Check if the trail length of this trail is least seen so far. If yes 
then
+     set finger_trail to this trail.*/
+    if (finger_trail->trail_length > iterator->trail_length)
     {
-      friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
-                                                  &iterator->trail_head->peer);
+      finger_trail->friend = *friend;
+      finger_trail->trail_id = iterator->trail_id;
+      finger_trail->trail_length = iterator->trail_length;
     }
-    else
-    {
-      friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
-                                                  &finger->finger_identity);
-    }
-
-    if ((friend->trails_count < TRAILS_THROUGH_FRIEND_THRESHOLD)||
-      ((0 == GNUNET_TIME_absolute_get_remaining 
(friend->congestion_timestamp).rel_value_us)))
-    {
-      if (iterator->trail_length == 0)
-      {
-        finger_trail->friend = *friend;
-        //finger_trail->trail_id = 0;
-        finger_trail->trail_length = 0;
-        return finger_trail;
-      }
-
-      if (finger_trail->trail_length > iterator->trail_length)
-      {
-        finger_trail->friend = *friend;
-        finger_trail->trail_id = iterator->trail_id;
-        finger_trail->trail_length = iterator->trail_length;
-      }
-    }
   }
 
+  /* No trail found. */  
+  if (i == finger->trails_count)
+    finger_trail = NULL;
+  
   return finger_trail;
 }
 
@@ -1546,91 +1750,104 @@
  * @param finger_map_index Index in finger peermap for which we are
  *                         looking for a finger, to discern between
  *                         IS_PREDECESSOR or not.
- * @return
+ * @return Closest successor for value. 
  */
 static struct GNUNET_PeerIdentity *
 find_successor (uint64_t destination_finger_value,
-                struct GNUNET_PeerIdentity *next_destination,
+                struct GNUNET_PeerIdentity *best_known_destination,
                 struct GNUNET_HashCode *new_intermediate_trail_id,
                 unsigned int finger_map_index)
 {
-  struct Closest_Peer *successor;
+  struct Closest_Peer *current_successor;
   struct GNUNET_PeerIdentity *next_hop;
   struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
   struct GNUNET_CONTAINER_MultiHashMap32Iterator *finger_iter;
-  struct GNUNET_PeerIdentity *closest_peer;
-  struct Correct_Trail *finger_trail;
+  struct Selected_Finger_Trail *finger_trail;
   struct FriendInfo *friend;
   struct FingerInfo *finger;
   int i;
-
-  successor = GNUNET_new (struct Closest_Peer);
-  memcpy (&successor->value, &my_identity, sizeof (uint64_t));
-  //successor->trail_id = 0; /* FIXME:Default value for trail id */
-  successor->next_hop = my_identity;
-  successor->next_destination = my_identity;
-
+  
+  /* Initialize current_successor to my_identity. */
+  current_successor = GNUNET_new (struct Closest_Peer);
+  memcpy (&current_successor->value, &my_identity, sizeof (uint64_t));
+  memset (&current_successor->trail_id, 0, sizeof 
(current_successor->trail_id)); 
+  current_successor->next_hop = my_identity;
+  current_successor->best_known_destination = my_identity;
+  
+  /* Iterate over friend_peermap and compare each friend with 
current_successor.*/
   friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
   for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (friend_peermap); i++)
   {
     GNUNET_assert (GNUNET_YES ==
       GNUNET_CONTAINER_multipeermap_iterator_next (friend_iter, NULL,
                                                   (const void **)&friend));
-    if ((friend->trails_count > TRAILS_THROUGH_FRIEND_THRESHOLD)||
-        (0 != GNUNET_TIME_absolute_get_remaining 
(friend->congestion_timestamp).rel_value_us))
+    
+    if (GNUNET_YES == is_friend_congested (friend))
       continue;
-
-    closest_peer = select_closest_peer (&my_identity, &friend->id,
-                                        destination_finger_value,
-                                        finger_map_index);
-    if (0 == GNUNET_CRYPTO_cmp_peer_identity (closest_peer, &friend->id))
-    {
-      memcpy (&successor->value, &friend->id, sizeof (uint64_t));
-      //successor->trail_id = 0;
-      successor->next_hop = friend->id;
-      successor->next_destination = friend->id;
-    }
+    
+    /* FIXME: select closest peer w.r.t. value. [friend_id, 
current_successor->id)
+     and [current_successor->id, friend_id). Check in which range value lies.
+     Also, check for wrap around. Set the value of current_successor 
accordingly.*/
   }
-
+  
+  /* Iterate over finger_hashmap and compare each finger with 
current_successor.*/
   finger_iter = GNUNET_CONTAINER_multihashmap32_iterator_create 
(finger_hashmap);
   for (i = 0; i < GNUNET_CONTAINER_multihashmap32_size (finger_hashmap); i++)
   {
     GNUNET_assert (GNUNET_YES ==
       GNUNET_CONTAINER_multihashmap32_iterator_next (finger_iter, NULL,
                                                      (void *)&finger));
-   finger_trail = select_trail_to_finger (finger);
-   if (NULL == finger_trail)
-     continue;
-
-   closest_peer = select_closest_peer (&my_identity,
-                                       &finger->finger_identity,
-                                       destination_finger_value,
-                                       finger_map_index);
-   if (0 == GNUNET_CRYPTO_cmp_peer_identity (closest_peer,
-                                             &finger->finger_identity))
-   {
-      memcpy (&successor->value, &finger->finger_identity, sizeof (uint64_t));
-      successor->trail_id = finger_trail->trail_id;
-      successor->next_hop = finger_trail->friend.id;
-      successor->next_destination = finger->finger_identity;
+    
+    /* If I am my own finger, then ignore this finger. */
+    if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity,
+                                            &my_identity))
+      continue;
+    
+    /* If finger is friend. */
+    if(GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
&finger->finger_identity))
+    {
+      /* If not congested then compare it with current_successor. */
+      if (GNUNET_NO == is_friend_congested (friend))
+      {
+        //compare it with current successor.   
+      }
     }
+    /* Choose one of the trail to reach to finger. */
+    finger_trail = select_finger_trail (finger);
+    
+    /* In case no trail found, ignore this finger. */
+    if (NULL == finger_trail)
+      continue;
+    
+    /* FIXME: select closest peer w.r.t. value. [finger->friend_id, 
current_successor->id)
+     and [current_successor->id, finger->friend_id). Check in which range 
value lies.
+     Also, check for wrap around. But this will give you the immediate 
predecessor
+     For example. if we have 0,1,6 and I am 0 and one of my finger is 6. Then
+     for 1, we will have ranges like [0,6) and [6,0) 1 lies in range from [0,6)
+     but successor is 6 not 0 as 6 is > than 1. If you are the closest one, 
+     then set the values
+     in current_successor. Want to write a generic code so that it is used in 
+     * finger_table_add also while choosing the closest one among new and 
existing
+     * one. */
   }
+  
+  best_known_destination = &current_successor->best_known_destination;
+  new_intermediate_trail_id = &current_successor->trail_id;
+  next_hop = &current_successor->next_hop;
 
-  next_destination = &successor->next_destination;
-  new_intermediate_trail_id = &successor->trail_id;
-  next_hop = &successor->next_hop;
-
   return next_hop;
 }
 
+
 /**
  * Construct a Put message and send it to target_peer.
  * @param key Key for the content
  * @param block_type Type of the block
  * @param options Routing options
  * @param desired_replication_level Desired replication count
- * @param current_destination Next current destination which will get this 
message.
- * @param current_source Source for @a current_destination
+ * @param best_known_dest Peer to which this message should reach eventually,
+ *                        as it is best known destination to me. 
+ * @param intermediate_trail_id Trail id in case 
  * @param target_peer Peer to which this message will be forwarded.
  * @param hop_count Number of hops traversed so far.
  * @param put_path_length Total number of peers in @a put_path
@@ -1642,28 +1859,97 @@
 void
 GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
                          enum GNUNET_BLOCK_Type block_type,
-                         enum GNUNET_DHT_RouteOption options,
-                         uint32_t desired_replication_level,
-                         struct GNUNET_PeerIdentity current_destination,
-                         struct GNUNET_PeerIdentity current_source,
-                         struct GNUNET_PeerIdentity *target_peer,
+                                          enum GNUNET_DHT_RouteOption options,
+                                          uint32_t desired_replication_level,
+                                          struct GNUNET_PeerIdentity 
*best_known_dest,
+                                          struct GNUNET_HashCode 
*intermediate_trail_id,
+                                          struct GNUNET_PeerIdentity 
*target_peer,
                          uint32_t hop_count,
                          uint32_t put_path_length,
                          struct GNUNET_PeerIdentity *put_path,
                          struct GNUNET_TIME_Absolute expiration_time,
                          const void *data, size_t data_size)
 {
+  struct PeerPutMessage *ppm;
+  struct P2PPendingMessage *pending;
+  struct FriendInfo *target_friend;
+  struct GNUNET_PeerIdentity *pp;
+  size_t msize;
 
+  msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
+          sizeof (struct PeerPutMessage);
+  
+  if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+  {
+    put_path_length = 0;
+    msize = data_size + sizeof (struct PeerPutMessage);
+  }
+  
+  if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  
+   /* This is the first call made from clients file. So, we should search for 
the
+     target_friend. */
+  if (NULL == target_peer)
+  {
+    uint64_t key_value;
+    struct GNUNET_PeerIdentity *next_hop;
+   
+    memcpy (&key_value, key, sizeof (uint64_t));
+    next_hop = find_successor (key_value, best_known_dest, 
+                               intermediate_trail_id, 
GDS_FINGER_TYPE_NON_PREDECESSOR);
+    if (0 == GNUNET_CRYPTO_cmp_peer_identity(next_hop, &my_identity)) 
+    {
+      /* I am the destination but we have already done datacache_put in client 
file.  */
+      return;
+    }
+    else
+      target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
next_hop);   
+  }
+  
+  pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
+  pending->timeout = expiration_time;
+  ppm = (struct PeerPutMessage *) &pending[1];
+  pending->msg = &ppm->header;
+  ppm->header.size = htons (msize);
+  ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
+  ppm->options = htonl (options);
+  ppm->block_type = htonl (block_type);
+  ppm->hop_count = htonl (hop_count + 1);
+  ppm->desired_replication_level = htonl (desired_replication_level);
+  ppm->put_path_length = htonl (put_path_length);
+  ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
+  ppm->best_known_destination = *best_known_dest;
+  ppm->key = *key;
+  if (NULL == intermediate_trail_id)
+    memset (&ppm->intermediate_trail_id, 0, sizeof 
(ppm->intermediate_trail_id));
+  else
+    ppm->intermediate_trail_id = *intermediate_trail_id;
+  pp = (struct GNUNET_PeerIdentity *) &ppm[1];
+  if (put_path_length != 0)
+  {
+    memcpy (pp, put_path,
+            sizeof (struct GNUNET_PeerIdentity) * put_path_length);
+  }
+  memcpy (&pp[put_path_length], data, data_size);
+  GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, 
pending);
+  target_friend->pending_count++;
+  process_friend_queue (target_friend);
 }
 
+
+
 /**
  * Construct a Get message and send it to target_peer.
  * @param key Key for the content
  * @param block_type Type of the block
  * @param options Routing options
  * @param desired_replication_level Desired replication count
- * @param current_destination Next current destination which will get this 
message.
- * @param current_source Source for @a current_destination
+ * @param best_known_dest 
+ * @param intermediate_trail_id 
  * @param target_peer Peer to which this message will be forwarded.
  * @param hop_count Number of hops traversed so far.
  * @param data Content to store
@@ -1676,14 +1962,71 @@
                          enum GNUNET_BLOCK_Type block_type,
                          enum GNUNET_DHT_RouteOption options,
                          uint32_t desired_replication_level,
-                         struct GNUNET_PeerIdentity current_destination,
-                         struct GNUNET_PeerIdentity current_source,
+                         struct GNUNET_PeerIdentity *best_known_dest,
+                         struct GNUNET_HashCode *intermediate_trail_id,
                          struct GNUNET_PeerIdentity *target_peer,
                          uint32_t hop_count,
                          uint32_t get_path_length,
                          struct GNUNET_PeerIdentity *get_path)
 {
+  struct PeerGetMessage *pgm;
+  struct P2PPendingMessage *pending;
+  struct FriendInfo *target_friend;
+  struct GNUNET_PeerIdentity *gp;
+  size_t msize;
 
+  msize = sizeof (struct PeerGetMessage) + 
+          (get_path_length * sizeof (struct GNUNET_PeerIdentity));
+  
+  if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  
+  if (NULL == target_peer)
+  {
+    struct GNUNET_PeerIdentity *next_hop;
+    uint64_t key_value;
+    
+    memcpy (&key_value, key, sizeof (uint64_t));
+       // FIXME: endianess of key_value!?
+     /* FIXME: Here you should use enum GDS_NEIGHBOURS_FINGER_TYPE in place of 
0. */
+    next_hop = find_successor (key_value, best_known_dest,
+                               intermediate_trail_id, 
GDS_FINGER_TYPE_NON_PREDECESSOR);
+    
+    if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity,next_hop)) 
+    {
+      GDS_DATACACHE_handle_get (key,block_type, NULL, 0, 
+                                NULL, 0, 1, &my_identity, NULL,&my_identity);
+      return;
+    }
+    else
+    {
+      target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
next_hop);
+    }
+  }
+  
+  pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
+  pending->importance = 0;    /* FIXME */
+  pgm = (struct PeerGetMessage *) &pending[1];
+  pending->msg = &pgm->header;
+  pgm->header.size = htons (msize);
+  pgm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET);
+  pgm->get_path_length = htonl (get_path_length);
+  pgm->key = *key;
+  pgm->best_known_destination = *best_known_dest;
+  pgm->intermediate_trail_id = *intermediate_trail_id;
+  pgm->hop_count = htonl (hop_count + 1);
+  
+  if (get_path != 0)
+  {
+    gp = (struct GNUNET_PeerIdentity *) &pgm[1];
+    memcpy (gp, get_path, get_path_length * sizeof (struct 
GNUNET_PeerIdentity));
+  }
+  GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, 
pending);
+  target_friend->pending_count++;
+  process_friend_queue (target_friend);
 }
 
 
@@ -1713,7 +2056,72 @@
                                 struct GNUNET_TIME_Absolute expiration,
                                 const void *data, size_t data_size)
 {
-
+  struct PeerGetResultMessage *get_result;
+  struct GNUNET_PeerIdentity *get_result_path;
+  struct GNUNET_PeerIdentity *pp;
+  struct P2PPendingMessage *pending;
+  struct FriendInfo *target_friend;
+  int current_path_index;
+  size_t msize;
+  
+  msize = get_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
+          sizeof (struct PeerPutMessage);
+ 
+  if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  
+  if(get_path_length > 0)
+  {
+    current_path_index = search_my_index(get_path, get_path_length);
+    if (GNUNET_SYSERR == current_path_index)
+    {
+      GNUNET_break (0);
+      return;
+    }
+  }
+  if (0 == current_path_index)
+  {
+    GDS_CLIENTS_handle_reply (expiration, key, get_path_length, 
+                              get_path, put_path_length,
+                              put_path, type, data_size, data);
+    return;
+  }
+  
+  pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
+  pending->importance = 0;   
+  get_result = (struct PeerGetResultMessage *)&pending[1];
+  pending->msg = &get_result->header;
+  get_result->header.size = htons (msize);
+  get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT);
+  get_result->key = *key;
+  /* FIXME: check if you are passing the correct querying_peer as described in
+   the get_result documentation. */
+  memcpy (&(get_result->querying_peer), source_peer, sizeof (struct 
GNUNET_PeerIdentity));
+  get_result->expiration_time = expiration;
+  
+  if (get_path_length != 0)
+  {
+    get_result_path = (struct GNUNET_PeerIdentity *)&get_result[1];
+    memcpy (get_result_path, get_path,
+            sizeof (struct GNUNET_PeerIdentity) * get_path_length);
+  }
+  memcpy (&get_result_path[get_path_length], data, data_size);
+  
+  /* FIXME: Is this correct? */
+  if (put_path_length != 0)
+  {
+    pp = (struct GNUNET_PeerIdentity *)&get_result_path[1];
+    memcpy (pp, put_path,sizeof (struct GNUNET_PeerIdentity) * 
put_path_length);
+  }
+  
+  target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
+                                                     
&get_result_path[current_path_index - 1]);
+  GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, 
pending);
+  target_friend->pending_count++;
+  process_friend_queue (target_friend);
 }
 
 
@@ -1759,7 +2167,7 @@
                                                              (const void 
**)&friend));
 
 
-    if ((TRAILS_THROUGH_FRIEND_THRESHOLD > friend->trails_count) &&
+    if ((TRAILS_THROUGH_FRIEND_THRESHOLD == friend->trails_count) &&
         (0 == GNUNET_TIME_absolute_get_remaining 
(friend->congestion_timestamp).rel_value_us))
     {
       break;
@@ -1779,7 +2187,7 @@
  * @return finger_identity
  */
 static uint64_t
-compute_finger_identity()
+compute_finger_identity_value ()
 {
   uint64_t my_id64;
 
@@ -1794,7 +2202,7 @@
  * @return peer identity of immediate predecessor.
  */
 static uint64_t
-compute_predecessor_identity()
+compute_predecessor_identity_value ()
 {
   uint64_t my_id64;
 
@@ -1818,8 +2226,8 @@
   struct FriendInfo *target_friend;
   struct GNUNET_TIME_Relative next_send_time;
   struct GNUNET_HashCode trail_id;
-  unsigned int finger_map_index;
-  uint64_t finger_identity;
+  unsigned int is_predecessor;
+  uint64_t finger_id_value;
 
   next_send_time.rel_value_us =
       DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
@@ -1837,20 +2245,20 @@
 
   if (PREDECESSOR_FINGER_ID == current_search_finger_index)
   {
-    finger_identity = compute_predecessor_identity();
+    finger_id_value = compute_predecessor_identity_value();
+    is_predecessor = 0;
   }
   else
   {
-    finger_identity = compute_finger_identity();
+    finger_id_value = compute_finger_identity_value();
+    is_predecessor = 1;
   }
 
-  finger_map_index = current_search_finger_index;
-
   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
                               &trail_id, sizeof (trail_id));
-  GDS_NEIGHBOURS_send_trail_setup (my_identity, finger_identity,
+  GDS_NEIGHBOURS_send_trail_setup (my_identity, finger_id_value,
                                    target_friend->id, target_friend, 0, NULL,
-                                   finger_map_index, trail_id, NULL);
+                                   is_predecessor, trail_id, NULL);
 }
 
 
@@ -1873,14 +2281,14 @@
  */
 static void
 select_and_replace_trail (struct FingerInfo *existing_finger,
-                          struct GNUNET_PeerIdentity *new_trail,
+                          const struct GNUNET_PeerIdentity *new_trail,
                           unsigned int new_trail_length,
                           struct GNUNET_HashCode new_trail_id)
 {
-  struct TrailList *trail_list_iterator;
+  struct Trail *trail_list_iterator;
   unsigned int largest_trail_length;
   unsigned int largest_trail_index;
-  struct Trail *trail_element;
+  struct Trail_Element *trail_element;
   unsigned int i;
 
   largest_trail_length = new_trail_length;
@@ -1905,7 +2313,7 @@
   }
 
   /* Send trail teardown message across the replaced trail. */
-  struct TrailList *replace_trail = 
&existing_finger->trail_list[largest_trail_index];
+  struct Trail *replace_trail = 
&existing_finger->trail_list[largest_trail_index];
   struct FriendInfo *target_friend =
       GNUNET_CONTAINER_multipeermap_get (friend_peermap,
                                          &replace_trail->trail_head->peer);
@@ -1926,7 +2334,7 @@
   i = 0;
   while (i < new_trail_length)
   {
-    struct Trail *element = GNUNET_new (struct Trail);
+    struct Trail_Element *element = GNUNET_new (struct Trail_Element);
     element->peer = new_trail[i];
 
     GNUNET_CONTAINER_DLL_insert_tail (replace_trail->trail_head,
@@ -1947,11 +2355,11 @@
  */
 static int
 is_new_trail_unique (struct FingerInfo *existing_finger,
-                     struct GNUNET_PeerIdentity *new_trail,
+                     const struct GNUNET_PeerIdentity *new_trail,
                      unsigned int trail_length)
 {
-  struct TrailList *trail_list_iterator;
-  struct Trail *trail_element;
+  struct Trail *trail_list_iterator;
+  struct Trail_Element *trail_element;
   int i;
   int j;
   int trail_unique = GNUNET_NO;
@@ -1985,11 +2393,11 @@
  */
 static void
 add_new_trail (struct FingerInfo *existing_finger,
-               struct GNUNET_PeerIdentity *new_trail,
+               const struct GNUNET_PeerIdentity *new_trail,
                unsigned int new_trail_length,
                struct GNUNET_HashCode new_trail_id)
 {
-  struct TrailList *trail_list_iterator;
+  struct Trail *trail_list_iterator;
   struct FriendInfo *first_friend;
   int i;
 
@@ -2012,13 +2420,14 @@
     first_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
                                                       
&(existing_finger->finger_identity));
   first_friend->trails_count++;
-  trail_list_iterator->first_friend_trail_count = first_friend->trails_count;
+  /* FIXME; we removed this field but read fixme. */
+  //trail_list_iterator->first_friend_trail_count = first_friend->trails_count;
   trail_list_iterator->trail_length = new_trail_length;
 
   for (i = 0; i < new_trail_length; i++)
   {
-    struct Trail *element;
-    element = GNUNET_new (struct Trail);
+    struct Trail_Element *element;
+    element = GNUNET_new (struct Trail_Element);
 
     element->peer = new_trail[i];
     GNUNET_CONTAINER_DLL_insert_tail (trail_list_iterator->trail_head,
@@ -2036,7 +2445,7 @@
 static void
 send_trail_teardown (struct FingerInfo *finger)
 {
-  struct TrailList *trail_list_iterator;
+  struct Trail *trail_list_iterator;
   struct FriendInfo *target_friend;
   int i;
 
@@ -2071,7 +2480,7 @@
 static void
 decrement_friend_trail_count (struct FingerInfo *finger)
 {
-  struct TrailList *trail_list_iterator;
+  struct Trail *trail_list_iterator;
   struct FriendInfo *target_friend;
   int i = 0;
 
@@ -2092,8 +2501,9 @@
                                                  &finger->finger_identity);
 
     // check target_friend for NULL
-    target_friend->trails_count--;
-    trail_list_iterator->first_friend_trail_count--;
+    /* FIXME: we have removed first_friend_trail_count field. */
+   target_friend->trails_count--;
+    //trail_list_iterator->first_friend_trail_count--;
   }
   return;
 }
@@ -2106,8 +2516,8 @@
 static void
 free_finger (struct FingerInfo *finger)
 {
-  struct TrailList *trail_list_iterator;
-  struct Trail *trail_element;
+  struct Trail *trail_list_iterator;
+  struct Trail_Element *trail_element;
   unsigned int i;
 
   for (i = 0; i < finger->trails_count; i++)
@@ -2126,85 +2536,6 @@
 
 
 /**
- * FIXME: merge into finger_table_add
- * FIXME: leave as simple a check
- * Check if new finger is closer than existing_finger. If both new finger and
- * existing finger are same then we may add a new trail (if there is space)
- * or choose the best trail among existing trails and new trails.
- * @param existing_finger Finger present in finger_peermap at @a 
finger_map_index
- *                        or NULL if none
- * @param new_finger_identity Peer identity of new finger.
- * FIXME: all the following params *should* not be necessary
- * @param new_finger_trail Trail to reach from source to new_finger.
- * @param new_finger_trail_length Total number of peers in @a new_finger_trail.
- * @param trail_id Unique identifier of trail.
- * @param finger_map_index Index in finger map.
- * @return #GNUNET_YES if the new finger is closest.
- *         #GNUNET_NO either new_finger and existing_finger are same, or
- *                    existing_finger is closest.
- */
-static int
-is_new_finger_closest (struct FingerInfo *existing_finger,
-                       struct GNUNET_PeerIdentity new_finger_identity,
-                       struct GNUNET_PeerIdentity *new_finger_trail,
-                       unsigned int new_finger_trail_length,
-                       struct GNUNET_HashCode new_finger_trail_id,
-                       unsigned int finger_map_index)
-{
-  struct GNUNET_PeerIdentity *closest_peer;
-  uint64_t finger_identity_value;
-  uint64_t my_id64;
-
-  if (NULL == existing_finger)
-    return GNUNET_YES;
-
-  memcpy (&my_id64, &my_identity, sizeof (uint64_t));
-  if (0 != GNUNET_CRYPTO_cmp_peer_identity 
(&(existing_finger->finger_identity),
-                                            &new_finger_identity))
-  {
-    if (PREDECESSOR_FINGER_ID == finger_map_index)
-      finger_identity_value = my_id64 - 1;
-    else
-      finger_identity_value = my_id64 + (unsigned long) pow (2, 
finger_map_index);
-    closest_peer = select_closest_peer (&existing_finger->finger_identity,
-                                        &new_finger_identity,
-                                        finger_identity_value, 
finger_map_index);
-
-    if (0 == GNUNET_CRYPTO_cmp_peer_identity (&new_finger_identity, 
closest_peer))
-    {
-      GNUNET_assert (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
-                                                           
&new_finger_identity));
-
-      send_trail_teardown (existing_finger);
-      decrement_friend_trail_count (existing_finger);
-      free_finger (existing_finger);
-      return GNUNET_YES;
-    }
-  }
-  else
-  {
-    if (0 == GNUNET_CRYPTO_cmp_peer_identity 
(&(existing_finger->finger_identity),
-                                              &my_identity))
-    {
-      return GNUNET_NO;
-    }
-    if (NULL ==
-        GNUNET_CONTAINER_multipeermap_get (friend_peermap,
-                                            
&(existing_finger->finger_identity)))
-    {
-      if (existing_finger->trails_count < MAXIMUM_TRAILS_PER_FINGER)
-        add_new_trail (existing_finger, new_finger_trail,
-                        new_finger_trail_length, new_finger_trail_id);
-      else
-        select_and_replace_trail (existing_finger, new_finger_trail,
-                                  new_finger_trail_length, 
new_finger_trail_id);
-    }
-  }
-  return GNUNET_NO;
-}
-
-
-/**
  * Add a new entry in finger hashmap at finger_map_index
  * @param finger_identity Peer Identity of new finger
  * @param finger_trail Trail to reach from me to finger (excluding both end 
points).
@@ -2217,14 +2548,14 @@
  */
 static int
 add_new_entry (struct GNUNET_PeerIdentity finger_identity,
-               struct GNUNET_PeerIdentity *finger_trail,
+               const struct GNUNET_PeerIdentity *finger_trail,
                unsigned int finger_trail_length,
                struct GNUNET_HashCode trail_id,
                unsigned int finger_map_index)
 {
   struct FingerInfo *new_entry;
   struct FriendInfo *first_trail_hop;
-  struct TrailList *first_trail;
+  struct Trail *first_trail;
   int i = 0;
 
   new_entry = GNUNET_new (struct FingerInfo);
@@ -2247,11 +2578,12 @@
 
     first_trail_hop->trails_count++;
     first_trail = &new_entry->trail_list[0];
-    first_trail->first_friend_trail_count = first_trail_hop->trails_count;
+    /* FIXME: We have removed this field. */
+    //first_trail->first_friend_trail_count = first_trail_hop->trails_count;
 
     while (i < finger_trail_length)
     {
-      struct Trail *element = GNUNET_new (struct Trail);
+      struct Trail_Element *element = GNUNET_new (struct Trail_Element);
 
       element->next = NULL;
       element->prev = NULL;
@@ -2282,18 +2614,21 @@
  * @return updated trail length in case we shortcut the trail, else original
  *         trail length.
  */
-static int
+static struct GNUNET_PeerIdentity *
 scan_and_compress_trail (struct GNUNET_PeerIdentity finger_identity,
-                         struct GNUNET_PeerIdentity *trail,
+                         const struct GNUNET_PeerIdentity *trail,
                          unsigned int trail_length,
-                         struct GNUNET_HashCode trail_id)
+                         struct GNUNET_HashCode trail_id,
+                         int *new_trail_length)
 {
   struct FriendInfo *target_friend;
+  struct GNUNET_PeerIdentity *new_trail;
   int i;
-
+  
   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &finger_identity))
   {
-    return 0;
+    *new_trail_length = 0;
+    return NULL;
   }
 
   if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
&finger_identity))
@@ -2303,11 +2638,11 @@
       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
                                                        &trail[0]);
       GDS_NEIGHBOURS_send_trail_compression (my_identity, finger_identity,
-                                           trail_id, finger_identity,
-                                           target_friend);
-      trail = NULL;
+                                             trail_id, finger_identity,
+                                             target_friend);
+      *new_trail_length = 0;
     }
-    return 0;
+    return NULL;
   }
 
   for (i = trail_length - 1; i > 0; i--)
@@ -2323,26 +2658,30 @@
                                              trail_id, trail[i],
                                              target_friend);
 
-      // FIXME WARNING WARNING WARNING rewrite!!! consider directly creating a
-      // struct TrailList (current) // struct Trial (after renaming).
-
+    
       /* Copy the trail from index i to index trail_length -1 and change
        trail length and return */
+      new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * i);
       while (i < trail_length)
       {
-        memcpy (&trail[j], &trail[i], sizeof(struct GNUNET_PeerIdentity));
+        memcpy (&new_trail[j], &trail[i], sizeof(struct GNUNET_PeerIdentity));
         j++;
         i++;
       }
-      trail_length = j+1;
+      *new_trail_length = j+1;
       break;
+      return new_trail;
     }
   }
-  return trail_length;
+  *new_trail_length = trail_length;
+  memcpy (new_trail, new_trail, trail_length * sizeof (struct 
GNUNET_PeerIdentity));
+  return new_trail;
 }
 
 
 /**
+ * FIXME: Ensure that we add trail in succession in the trail list.
+ * There are no free spots within the trail list. 
  * Send verify successor message to your successor on all trails to reach
  * the successor.
  * @param successor My current successor
@@ -2350,7 +2689,7 @@
 static void
 send_verify_successor_message (struct FingerInfo *successor)
 {
-  struct TrailList *trail_list_iterator;
+  struct Trail *trail_list_iterator;
   struct GNUNET_HashCode trail_id;
   struct GNUNET_PeerIdentity next_hop;
   struct FriendInfo *target_friend;
@@ -2359,17 +2698,14 @@
   int i;
   int j;
 
-  for (i = 0; i < MAXIMUM_TRAILS_PER_FINGER; i++)
+  for (i = 0; i < successor->trails_count; i++)
   {
     trail_list_iterator = &successor->trail_list[i];
+    GNUNET_assert (NULL != trail_list_iterator->trail_head);
 
-//      FIXME check if this entry in the trail list is valid!
-//     if (NULL == trail_list_iterator->SOMETHING)
-//       continue;
-
     if (trail_list_iterator->trail_length > 0)
     {
-      struct Trail *element;
+      struct Trail_Element *element;
 
       trail_length = trail_list_iterator->trail_length;
       trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)
@@ -2386,8 +2722,9 @@
       next_hop = successor->finger_identity;
     }
     trail_id = trail_list_iterator->trail_id;
-    target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
&next_hop);
-    // check friend for NULL
+    GNUNET_assert (NULL != (target_friend = 
+                           GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
&next_hop)));
+    
     GDS_NEIGHBOURS_send_verify_successor_message (my_identity,
                                                   successor->finger_identity,
                                                   trail_id, trail, 
trail_length,
@@ -2398,6 +2735,73 @@
 
 
 /**
+ * FIXME: Is it safe to assume that current_search_finger_index == 
finger_map_index?
+ * Update the current search finger index. 
+ */
+static void
+update_current_search_finger_index (struct GNUNET_PeerIdentity 
new_finger_identity)
+{
+  struct FingerInfo *successor;
+  
+  successor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap, 0);
+  
+  if (0 == current_search_finger_index)
+  {
+    current_search_finger_index = PREDECESSOR_FINGER_ID;
+
+    if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, 
&new_finger_identity))
+    {
+        send_verify_successor_message (successor);
+    }
+  }
+  else if (0 == GNUNET_CRYPTO_cmp_peer_identity (&new_finger_identity,
+                                                  
&(successor->finger_identity)))
+  {
+     current_search_finger_index = 0;
+  }
+  else
+     current_search_finger_index = current_search_finger_index - 1;
+}
+
+/**
+ * FIXME: Is it sage to assume that finger_map_index == 
current_search_finger_index
+ * Calculate finger_map_index from initial value that we send in trail setup
+ * message. 
+ * @param ultimate_destination_finger_value Value that we calculated from our
+ * identity and finger_map_index.
+ * @param is_predecessor Is the entry for predecessor or not. 
+ * @return finger_map_index which is a value between 0 <= finger_map_index <= 
64
+ *         -1, if no valid finger_map_index is found. 
+ */
+static int
+get_finger_map_index (uint64_t ultimate_destination_finger_value,
+                      unsigned int is_predecessor)
+{
+  uint64_t my_id64;
+  unsigned int finger_map_index;
+  
+  finger_map_index = -1;
+  memcpy (&my_id64, &my_identity, sizeof (uint64_t));
+  
+  if (is_predecessor)
+  {
+    if(1 == (my_id64 - ultimate_destination_finger_value))
+      finger_map_index = PREDECESSOR_FINGER_ID;
+  }
+  else
+  {
+    finger_map_index = log (ultimate_destination_finger_value - my_id64);
+  }
+  
+  if ((finger_map_index > PREDECESSOR_FINGER_ID) ||
+      (finger_map_index == current_search_finger_index))
+    finger_map_index = -1;
+  
+  return finger_map_index;
+}
+
+
+/**
  * Check if there is already an entry in finger peermap for given finger map 
index.
  * If yes, then select the closest finger. If new and existing finger are same,
  * the check if you can store more trails. If yes then add trail, else keep 
the best
@@ -2406,76 +2810,102 @@
  * @param new_finger_identity Peer Identity of new finger
  * @param new_finger_trail Trail to reach the new finger
  * @param new_finger_length Total number of peers in @a new_finger_trail.
- * @param finger_map_index Index in finger peermap.
+ * @param is_predecessor Is this entry for predecessor in finger_peermap. 
  * @param new_finger_trail_id Unique identifier of @new_finger_trail.
  * @return #GNUNET_YES if the new entry is added
  *         #GNUNET_NO if new entry is not added, either it was discarded or
  *                    it was same as existing finger at finger map index.
  */
 static int
-finger_table_add (struct GNUNET_PeerIdentity new_finger_identity, // 
"finger_id"
-                  struct GNUNET_PeerIdentity *new_finger_trail, // "trail"
-                  unsigned int new_finger_trail_length,
-                  unsigned int finger_map_index,
-                  struct GNUNET_HashCode new_finger_trail_id)
+finger_table_add (struct GNUNET_PeerIdentity finger_identity, 
+                  const struct GNUNET_PeerIdentity *finger_trail, 
+                  unsigned int finger_trail_length,
+                  unsigned int is_predecessor,
+                  uint64_t finger_value,
+                  struct GNUNET_HashCode finger_trail_id)
 {
   struct FingerInfo *existing_finger;
-  struct FingerInfo *successor;
-  unsigned int new_entry_added = GNUNET_NO;
-  int new_finger_updated_trail_length; // new_finger_trail_length
-
-  new_finger_updated_trail_length =
-       scan_and_compress_trail (new_finger_identity, new_finger_trail,
-                                new_finger_trail_length, new_finger_trail_id);
-
+  struct GNUNET_PeerIdentity *closest_peer;
+  int updated_finger_trail_length; 
+  struct GNUNET_PeerIdentity *updated_trail;
+  unsigned int finger_map_index;
+  unsigned int new_entry_added;
+  
+  new_entry_added = GNUNET_NO;
+  
+  finger_map_index = get_finger_map_index (finger_value,
+                                           is_predecessor);
+  
+  if (-1 == finger_map_index)
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  
+  updated_trail =
+       scan_and_compress_trail (finger_identity, finger_trail,
+                                finger_trail_length, finger_trail_id, 
+                                &updated_finger_trail_length);
+  
   existing_finger = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
                                                          finger_map_index);
-
-  if  (GNUNET_YES == is_new_finger_closest (existing_finger,
-                                            new_finger_identity,
-                                            new_finger_trail,
-                                            new_finger_updated_trail_length,
-                                            new_finger_trail_id, 
finger_map_index))
+  
+  /* No entry present in finger hashmap for given finger map index. */
+  if (NULL == existing_finger)
   {
-    // send_destroy_existing_finger ...
-    // free_exisiting_finger ...
-    GNUNET_assert (GNUNET_YES == add_new_entry (new_finger_identity,
-                                                new_finger_trail,
-                                                
new_finger_updated_trail_length,
-                                                new_finger_trail_id,
-                                                finger_map_index));
-    new_entry_added = GNUNET_YES;
+    add_new_entry (finger_identity, updated_trail, updated_finger_trail_length,
+                   finger_trail_id, finger_map_index);
+    update_current_search_finger_index (finger_identity);
+    return GNUNET_YES;
   }
-//   else if if_new_finger_equal () {
-//
-//   }
-//   else // existing finger is closest
-//   {
-//
-//   }
-
-  // FIXME move block to "update_succesor"
+  
+  /* If existing entry and finger identity are not same. */
+  if (0 != GNUNET_CRYPTO_cmp_peer_identity 
(&(existing_finger->finger_identity),
+                                            &finger_identity))
   {
-    successor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap, 0);
-    // WARNING FIXME check that current_search_finger_index does not go out of 
bounds
-    if (0 == finger_map_index)
+    closest_peer = select_closest_peer (&existing_finger->finger_identity,
+                                        &finger_identity,
+                                        finger_value, finger_map_index);
+    
+    /* If the new finger is the closest peer. */
+    if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, closest_peer))
     {
-      current_search_finger_index = PREDECESSOR_FINGER_ID;
+      GNUNET_assert (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
+                                                           &finger_identity));
 
-      if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, 
&new_finger_identity))
-      {
-        send_verify_successor_message (successor);
-      }
+      send_trail_teardown (existing_finger);
+      decrement_friend_trail_count (existing_finger);
+      free_finger (existing_finger);
+      add_new_entry (finger_identity, updated_trail, 
updated_finger_trail_length,
+                     finger_trail_id, finger_map_index);
+      new_entry_added = GNUNET_YES;
     }
-    else if (0 == GNUNET_CRYPTO_cmp_peer_identity (&new_finger_identity,
-                                                  
&(successor->finger_identity)))
+  }
+  else
+  {
+    /* If both new and existing entry are same as my_identity, then do 
nothing. */
+    if (0 == GNUNET_CRYPTO_cmp_peer_identity 
(&(existing_finger->finger_identity),
+                                              &my_identity))
     {
-      current_search_finger_index = 0;
+      return GNUNET_NO;
     }
-    else
-      current_search_finger_index = current_search_finger_index - 1;
+    
+    /* If the existing finger is not a friend. */
+    if (NULL ==
+        GNUNET_CONTAINER_multipeermap_get (friend_peermap,
+                                            
&(existing_finger->finger_identity)))
+    {
+      if (existing_finger->trails_count < MAXIMUM_TRAILS_PER_FINGER)
+        add_new_trail (existing_finger, updated_trail,
+                       finger_trail_length, finger_trail_id);
+      else
+        select_and_replace_trail (existing_finger, updated_trail,
+                                  finger_trail_length, finger_trail_id);
+    }
+    new_entry_added = GNUNET_NO;
   }
-
+  
+  update_current_search_finger_index (finger_identity);
   return new_entry_added;
 }
 
@@ -2492,7 +2922,159 @@
 handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
                     const struct GNUNET_MessageHeader *message)
 {
-  return GNUNET_OK;
+   struct PeerPutMessage *put;
+  struct GNUNET_PeerIdentity *put_path;
+  struct GNUNET_HashCode test_key;
+  enum GNUNET_DHT_RouteOption options;
+  struct GNUNET_PeerIdentity best_known_dest;
+  struct GNUNET_HashCode intermediate_trail_id;
+  struct GNUNET_PeerIdentity *next_hop;
+  void *payload;
+  size_t msize;
+  uint32_t putlen;
+  size_t payload_size;
+  uint64_t key_value;
+  
+  msize = ntohs (message->size);
+  if (msize < sizeof (struct PeerPutMessage))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_YES;
+  }
+  
+  put = (struct PeerPutMessage *) message;
+  putlen = ntohl (put->put_path_length);
+   
+  if ((msize <
+       sizeof (struct PeerPutMessage) +
+       putlen * sizeof (struct GNUNET_PeerIdentity)) ||
+      (putlen >
+       GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_YES;
+  }
+
+  best_known_dest = put->best_known_destination;
+  put_path = (struct GNUNET_PeerIdentity *) &put[1];
+  payload = &put_path[putlen];
+  options = ntohl (put->options);
+  intermediate_trail_id = put->intermediate_trail_id;
+  
+  payload_size = msize - (sizeof (struct PeerPutMessage) + 
+                          putlen * sizeof (struct GNUNET_PeerIdentity));
+  
+  switch (GNUNET_BLOCK_get_key (GDS_block_context, ntohl (put->block_type),
+                                payload, payload_size, &test_key))
+  {
+    case GNUNET_YES:
+      if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode)))
+      {
+        char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
+        GNUNET_break_op (0);
+        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                    "PUT with key `%s' for block with key %s\n",
+                     put_s, GNUNET_h2s_full (&test_key));
+        GNUNET_free (put_s);
+        return GNUNET_YES;
+      }
+    break;
+    case GNUNET_NO:
+      GNUNET_break_op (0);
+      return GNUNET_YES;
+    case GNUNET_SYSERR:
+      /* cannot verify, good luck */
+      break;
+  }
+  
+   if (ntohl (put->block_type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for 
all tpyes */
+  {
+    switch (GNUNET_BLOCK_evaluate (GDS_block_context,
+                                   ntohl (put->block_type),
+                                   NULL,    /* query */
+                                   NULL, 0, /* bloom filer */
+                                   NULL, 0, /* xquery */
+                                   payload, payload_size))
+    {
+    case GNUNET_BLOCK_EVALUATION_OK_MORE:
+    case GNUNET_BLOCK_EVALUATION_OK_LAST:
+      break;
+
+    case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
+    case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
+    case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
+    case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
+    case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
+    case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
+    default:
+      GNUNET_break_op (0);
+      return GNUNET_OK;
+    }
+  }
+  
+  /* extend 'put path' by sender */
+  struct GNUNET_PeerIdentity pp[putlen + 1];
+  if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
+  {
+    memcpy (pp, put_path, putlen * sizeof (struct GNUNET_PeerIdentity));
+    pp[putlen] = *peer;
+    putlen++;
+  }
+  else
+    putlen = 0;
+  
+  memcpy (&key_value, &(put->key), sizeof (uint64_t));
+  if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&best_known_dest, &my_identity)))
+  {
+    next_hop = GDS_ROUTING_get_next_hop (intermediate_trail_id, 
+                                         GDS_ROUTING_SRC_TO_DEST);
+  }
+  else
+  {
+     /*FIXME: Here you should use enum GDS_NEIGHBOURS_FINGER_TYPE in place of 
0. */
+    next_hop = find_successor (key_value, &best_known_dest, 
+                               &intermediate_trail_id, 
GDS_FINGER_TYPE_NON_PREDECESSOR); 
+  }
+  
+  if (NULL == next_hop)
+  {
+    GNUNET_STATISTICS_update (GDS_stats,
+                              gettext_noop ("# Next hop to forward the packet 
not found "
+                              "trail setup request, packet dropped."),
+                              1, GNUNET_NO);
+    return GNUNET_SYSERR;
+  }
+  
+  GDS_CLIENTS_process_put (options,
+                           ntohl (put->block_type),
+                           ntohl (put->hop_count),
+                           ntohl (put->desired_replication_level),
+                           putlen, pp,
+                           GNUNET_TIME_absolute_ntoh (put->expiration_time),
+                           &put->key,
+                           payload,
+                           payload_size);
+  
+  if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, next_hop)) /* I am 
the final destination */
+  {
+    GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
+                              &(put->key),putlen, pp, ntohl (put->block_type), 
+                              payload_size, payload);
+    return GNUNET_YES;
+  }
+  else
+  {
+    GDS_NEIGHBOURS_send_put (&put->key,  
+                             ntohl (put->block_type),ntohl (put->options),
+                             ntohl (put->desired_replication_level),
+                             &best_known_dest, &intermediate_trail_id, 
next_hop,
+                             ntohl (put->hop_count), putlen, pp,
+                             GNUNET_TIME_absolute_ntoh (put->expiration_time),
+                             payload, payload_size);
+ 
+     return GNUNET_YES;
+  }
+  return GNUNET_SYSERR;
 }
 
 
@@ -2509,7 +3091,89 @@
 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
                     const struct GNUNET_MessageHeader *message)
 {
-  return GNUNET_OK;
+  struct PeerGetMessage *get;
+  struct GNUNET_PeerIdentity *get_path;
+  struct GNUNET_PeerIdentity best_known_dest;
+  struct GNUNET_HashCode intermediate_trail_id;
+  struct GNUNET_PeerIdentity *next_hop;
+  uint32_t get_length;
+  uint64_t key_value;
+  size_t msize;
+  
+  msize = ntohs (message->size);
+  if (msize < sizeof (struct PeerGetMessage))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_YES;
+  }
+  
+  get = (struct PeerGetMessage *)message;
+  get_length = ntohl (get->get_path_length);
+  best_known_dest = get->best_known_destination;
+  intermediate_trail_id = get->intermediate_trail_id;
+  if (get_length > 0)
+    get_path = (struct GNUNET_PeerIdentity *)&get[1];
+  
+  if ((msize <
+       sizeof (struct PeerGetMessage) +
+       get_length * sizeof (struct GNUNET_PeerIdentity)) ||
+       (get_length >
+        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_YES; 
+  }
+
+  /* Add sender to get path */
+  struct GNUNET_PeerIdentity gp[get_length + 1];
+  memcpy (gp, get_path, get_length * sizeof (struct GNUNET_PeerIdentity));
+  gp[get_length + 1] = *peer;
+  get_length = get_length + 1;
+  
+  memcpy (&key_value, &(get->key), sizeof (uint64_t));
+  if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&best_known_dest, &my_identity)))
+  {
+    next_hop = GDS_ROUTING_get_next_hop (intermediate_trail_id, 
+                                         GDS_ROUTING_SRC_TO_DEST);
+  }
+  else
+  {
+     /*FIXME: Here you should use enum GDS_NEIGHBOURS_FINGER_TYPE in place of 
0. */
+    next_hop = find_successor (key_value, &best_known_dest, 
+                               &intermediate_trail_id, 
GDS_FINGER_TYPE_NON_PREDECESSOR);  
+  }
+  
+  if (NULL == next_hop)
+  {
+    GNUNET_STATISTICS_update (GDS_stats,
+                              gettext_noop ("# Next hop to forward the packet 
not found "
+                              "trail setup request, packet dropped."),
+                              1, GNUNET_NO);
+    return GNUNET_SYSERR;
+  }
+  if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, next_hop))
+  {
+    /* I am the destination.*/
+    struct GNUNET_PeerIdentity final_get_path[get_length+1];
+    struct GNUNET_PeerIdentity next_hop;
+
+    memcpy (final_get_path, gp, get_length * sizeof (struct 
GNUNET_PeerIdentity));
+    memcpy (&final_get_path[get_length+1], &my_identity, sizeof (struct 
GNUNET_PeerIdentity));
+    get_length = get_length + 1;
+    memcpy (&next_hop, &final_get_path[get_length-2], sizeof (struct 
GNUNET_PeerIdentity));
+    GDS_DATACACHE_handle_get (&(get->key),(get->block_type), NULL, 0, NULL, 0,
+                              get_length, final_get_path,&next_hop, 
&my_identity);
+    
+    return GNUNET_YES;
+  }
+  else
+  {
+    GDS_NEIGHBOURS_send_get (&(get->key), get->block_type, get->options, 
+                             get->desired_replication_level, &best_known_dest,
+                             &intermediate_trail_id, next_hop, 0,
+                             get_length, gp);  
+  }
+  return GNUNET_SYSERR;
 }
 
 
@@ -2525,7 +3189,74 @@
 handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
                            const struct GNUNET_MessageHeader *message)
 {
-  return GNUNET_OK;
+  struct PeerGetResultMessage *get_result;
+  struct GNUNET_PeerIdentity *get_path;
+  struct GNUNET_PeerIdentity *put_path;
+  void *payload;
+  size_t payload_size;
+  size_t msize;
+  unsigned int getlen;
+  unsigned int putlen;
+  int current_path_index;
+  
+  msize = ntohs (message->size);
+  if (msize < sizeof (struct PeerGetResultMessage))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_YES;
+  }
+  
+  get_result = (struct PeerGetResultMessage *)message;
+  getlen = ntohl (get_result->get_path_length);
+  putlen = ntohl (get_result->put_path_length);
+  
+  if ((msize <
+       sizeof (struct PeerGetResultMessage) +
+       getlen * sizeof (struct GNUNET_PeerIdentity) + 
+       putlen * sizeof (struct GNUNET_PeerIdentity)) ||
+      (getlen >
+       GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity) ||
+      (putlen >
+         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct 
GNUNET_PeerIdentity))))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_YES;
+  }
+  
+  if (getlen > 0)
+   get_path = (struct GNUNET_PeerIdentity *) &get_result[1];
+  payload = &get_path[getlen];
+  payload_size = msize - (sizeof (struct PeerGetResultMessage) + 
+                          getlen * sizeof (struct GNUNET_PeerIdentity));
+  
+  if (putlen > 0)
+    put_path = &get_path[1];
+  else
+    put_path = NULL;
+  
+  if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(get_path[0]))))
+  {
+    GDS_CLIENTS_handle_reply (get_result->expiration_time, &(get_result->key), 
+                              getlen, get_path, putlen,
+                              put_path, get_result->type, payload_size, 
payload);
+    return GNUNET_YES;
+  }
+  else
+  {
+    current_path_index = search_my_index (get_path, getlen);
+    if (GNUNET_SYSERR == current_path_index )
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    GDS_NEIGHBOURS_send_get_result (&(get_result->key), get_result->type,
+                                    &get_path[current_path_index - 1],
+                                    &(get_result->querying_peer), putlen, 
put_path,
+                                    getlen, get_path, 
get_result->expiration_time,
+                                    payload, payload_size);
+    return GNUNET_YES;
+  }  
+  return GNUNET_SYSERR;
 }
 
 
@@ -2539,19 +3270,19 @@
 handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
                             const struct GNUNET_MessageHeader *message)
 {
-  struct PeerTrailSetupMessage *trail_setup;
-  struct GNUNET_PeerIdentity *trail_peer_list;
-  struct GNUNET_PeerIdentity next_destination; // 
"local_best_known_destination"
-  struct GNUNET_PeerIdentity *current_destination;
+  const struct PeerTrailSetupMessage *trail_setup;
+  const struct GNUNET_PeerIdentity *trail_peer_list;
+  struct GNUNET_PeerIdentity local_best_known_destination; 
+  struct GNUNET_PeerIdentity current_destination;
   struct GNUNET_PeerIdentity *next_hop;
   struct GNUNET_PeerIdentity next_peer;
   struct FriendInfo *target_friend;
   struct GNUNET_PeerIdentity source;
   uint64_t ultimate_destination_finger_value;
   struct GNUNET_HashCode new_intermediate_trail_id;
-  //struct GNUNET_HashCode *intermediate_trail_id;
-  struct GNUNET_HashCode new_trail_id;
-  unsigned int finger_map_index;
+  struct GNUNET_HashCode intermediate_trail_id;
+  struct GNUNET_HashCode trail_id;
+  unsigned int is_predecessor;
   uint32_t trail_length;
   size_t msize;
 
@@ -2563,67 +3294,71 @@
     return GNUNET_YES;
   }
 
-  trail_setup = (struct PeerTrailSetupMessage *) message;
-  trail_length = ntohl (trail_setup->trail_length); // (msize - sizeof (msg)) 
/ sizeof(PI)
-  // if ((msize - sizeof (msg)) % sizeof(PI) != 0)
-  if ((msize != sizeof (struct PeerTrailSetupMessage) +
-       trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
-       (trail_length >
-        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
+  trail_setup = (const struct PeerTrailSetupMessage *) message;
+  trail_length = (msize - sizeof (struct PeerTrailSetupMessage))/
+                  sizeof (struct GNUNET_PeerIdentity);
+  if ((msize - sizeof (struct PeerTrailSetupMessage)) % 
+      sizeof (struct GNUNET_PeerIdentity) != 0)
   {
     GNUNET_break_op (0);
-    return GNUNET_OK;
-  }
-
-  trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_setup[1];
-  current_destination = &trail_setup->next_destination;
-  new_trail_id = trail_setup->new_trail_id;
-  ultimate_destination_finger_value = GNUNET_ntohll 
(trail_setup->ultimate_destination_finger);
+    return GNUNET_OK;      
+  }           
+  
+  trail_peer_list = (const struct GNUNET_PeerIdentity *)&trail_setup[1];
+  current_destination = trail_setup->best_known_destination;
+  trail_id = trail_setup->trail_id;
+  ultimate_destination_finger_value = 
+          GNUNET_ntohll (trail_setup->ultimate_destination_finger_value);
   source = trail_setup->source_peer;
-  finger_map_index = ntohl (trail_setup->finger_map_index);
-  //intermediate_trail_id = &trail_setup->intermediate_trail_id;
+  is_predecessor = ntohl (trail_setup->is_predecessor);
+  intermediate_trail_id = trail_setup->intermediate_trail_id;
   
   if (GNUNET_YES == GDS_ROUTING_threshold_reached())
   {
     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
     GDS_NEIGHBOURS_send_trail_rejection (source, 
ultimate_destination_finger_value,
-                                         my_identity, finger_map_index,
+                                         my_identity, is_predecessor,
                                          trail_peer_list, trail_length,
-                                         new_trail_id, target_friend,
+                                         trail_id, target_friend,
                                          CONGESTION_TIMEOUT);
     return GNUNET_OK;
   }
 
-  next_hop = find_successor (ultimate_destination_finger_value, 
&next_destination,
-                             &new_intermediate_trail_id, finger_map_index);
+  
+  next_hop = find_successor (ultimate_destination_finger_value,
+                             &local_best_known_destination,
+                             &new_intermediate_trail_id, is_predecessor);
 
-  /* Are we just a part of a trail towards a finger? */
-  if (0 != (GNUNET_CRYPTO_cmp_peer_identity(&my_identity, 
current_destination)))
+  /* Are we just a part of a trail towards a finger (current_destination)? */
+  if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, 
&current_destination)))
   {
-//    struct GNUNET_PeerIdentity *closest_peer;
-//     struct GNUNET_PeerIdentity *peer1 =
-//         GDS_ROUTING_get_next_hop (intermediate_trail_id,
-//                                   GDS_ROUTING_SRC_TO_DEST);
-    /* Is next_destination better than the original best_known_dest? */
-    // BIG FIXME START
-//     if (0 != GNUNET_CRYPTO_cmp_peer_identity (next_destination,
-//                                               current_destination))
-//     {
-//        closest_peer = select_closest_peer (peer1, next_hop,
-//                                            
ultimate_destination_finger_value,
-//                                            finger_map_index);
-//     }
-//     if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer1, closest_peer) ||
-//         (0 == GNUNET_CRYPTO_cmp_peer_identity (peer1, next_hop)))
-//     {
-//       next_hop = peer1;
-//       next_destination = *current_destination;
-//       new_intermediate_trail_id = intermediate_trail_id;
-//     }
-    // BIG FIXME END
+    struct GNUNET_PeerIdentity *closest_peer;
+    
+    /* Select best successor among one found locally and current_destination.*/
+    closest_peer = select_closest_peer (&local_best_known_destination,
+                                        &current_destination,
+                                        ultimate_destination_finger_value,
+                                        is_predecessor);
+    if (0 == GNUNET_CRYPTO_cmp_peer_identity (&current_destination, 
+                                              closest_peer))
+    {
+      next_hop = GDS_ROUTING_get_next_hop (intermediate_trail_id,
+                                           GDS_ROUTING_SRC_TO_DEST);
+      if (NULL == next_hop) /* FIXME: Here we found next_hop NULL from routing 
table,
+                             * but we still have a next_hop from 
find_successor.
+                             * Should we not break and choose that next_hop. */
+      {
+        GNUNET_break_op (0);
+        return GNUNET_SYSERR;
+      }
+      
+      local_best_known_destination =  current_destination;
+      new_intermediate_trail_id = intermediate_trail_id;
+    }
   }
-
+  
   GNUNET_assert (NULL != next_hop);
+  
   /* Am I the final destination? */
   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)))
   {
@@ -2637,7 +3372,8 @@
                                             my_identity,
                                             target_friend, trail_length,
                                             trail_peer_list,
-                                            finger_map_index, new_trail_id);
+                                            ultimate_destination_finger_value,
+                                            is_predecessor, trail_id);
   }
   else
   {
@@ -2648,33 +3384,103 @@
     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
next_hop);
     GDS_NEIGHBOURS_send_trail_setup (source,
                                      ultimate_destination_finger_value,
-                                     next_destination,
+                                     local_best_known_destination,
                                      target_friend, trail_length + 1, 
peer_list,
-                                     finger_map_index, new_trail_id,
+                                     is_predecessor, trail_id,
                                      &new_intermediate_trail_id);
   }
   return GNUNET_OK;
 }
 
 
+/* FIXME: here we are calculating my_index and comparing also in this function.
+   And we are doing it again here in this function. Re factor the code. */
 /**
- * Core handle for p2p trail construction result messages.
+ * Check if sender_peer and peer from which we should receive the message are
+ * same or different.
+ * @param trail_peer_list List of peers in trail
+ * @param trail_length Total number of peers in @a trail_peer_list
+ * @param sender_peer Peer from which we got the message. 
+ * @param finger_identity Finger to which trail is setup. It is not part of 
trail.
+ * @return #GNUNET_YES if sender_peer and peer from which we should receive the
+ *                    message are different.
+ *         #GNUNET_NO if sender_peer and peer from which we should receive the
+ *                    message are different. 
+ */
+static int
+is_sender_peer_correct (const struct GNUNET_PeerIdentity *trail_peer_list,
+                        unsigned int trail_length,
+                        const struct GNUNET_PeerIdentity *sender_peer,
+                        struct GNUNET_PeerIdentity finger_identity,
+                        struct GNUNET_PeerIdentity source_peer)
+{
+  int my_index;
+  
+  if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
+                                             &my_identity)))
+  {
+    if (trail_length > 0)
+    {
+      // source, then trail_length > 0, trail_peer_list[0] != peer
+      if (0 != GNUNET_CRYPTO_cmp_peer_identity (&trail_peer_list[0],
+                                                sender_peer))
+        return GNUNET_NO;
+    }
+    else
+    {
+      // source, trail_length == 0, finger != peer
+      if (0 != GNUNET_CRYPTO_cmp_peer_identity (sender_peer,
+                                                &finger_identity))
+        return GNUNET_NO;
+    }
+  }
+  else
+  {
+    my_index = search_my_index (trail_peer_list, trail_length);
+    if (-1 == my_index)
+      return GNUNET_NO;
+    
+    // my_index == trail_length -1, finger != peer
+    if ((trail_length - 1) == my_index)
+    {
+      if (0 != GNUNET_CRYPTO_cmp_peer_identity (sender_peer,
+                                                &finger_identity))
+        return GNUNET_NO;
+    }
+    else
+    {
+      // FIXME: if trail_peer_list[my_index + 1] != peer
+      if (0 != GNUNET_CRYPTO_cmp_peer_identity (sender_peer,
+                                                &trail_peer_list[my_index + 
1]))
+        return GNUNET_NO;
+    }
+  }
+  return GNUNET_YES;
+}
+
+
+/**
+ * Core handle for p2p trail setup result messages.
  * @param closure
  * @param message message
- * @param peer peer identity this notification is about
+ * @param peer sender of this message. 
  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  */
 static int
 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity 
*peer,
                                   const struct GNUNET_MessageHeader *message)
 {
-  struct PeerTrailSetupResultMessage *trail_result;
-  struct GNUNET_PeerIdentity *trail_peer_list;
-  struct GNUNET_PeerIdentity destination_peer;
+  const struct PeerTrailSetupResultMessage *trail_result;
+  const struct GNUNET_PeerIdentity *trail_peer_list;
+  struct GNUNET_PeerIdentity next_hop;
+  struct FriendInfo *target_friend;
+  struct GNUNET_PeerIdentity querying_peer;
   struct GNUNET_PeerIdentity finger_identity;
   uint32_t trail_length;
-  uint32_t finger_map_index;
+  uint64_t ulitmate_destination_finger_value;
+  uint32_t is_predecessor;
   struct GNUNET_HashCode trail_id;
+  int my_index;
   size_t msize;
 
   msize = ntohs (message->size);
@@ -2684,66 +3490,71 @@
     return GNUNET_YES;
   }
 
-  trail_result = (struct PeerTrailSetupResultMessage *) message;
-
-  // calculate trail_length with message size, check for % 0
-  trail_length = ntohl (trail_result->trail_length);
-  if ((msize !=
-       sizeof (struct PeerTrailSetupResultMessage) +
-       trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
-       (trail_length >
-        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
+  trail_result = (const struct PeerTrailSetupResultMessage *) message;
+  trail_length = (msize - sizeof (struct PeerTrailSetupResultMessage))/
+                  sizeof (struct GNUNET_PeerIdentity);
+  if ((msize - sizeof (struct PeerTrailSetupResultMessage)) % 
+      sizeof (struct GNUNET_PeerIdentity) != 0)
   {
     GNUNET_break_op (0);
-    return GNUNET_YES;
-  }
-
-  finger_map_index = htonl (trail_result->finger_map_index);
-  destination_peer = trail_result->destination_peer;
+    return GNUNET_OK;      
+  }       
+  
+  is_predecessor = htonl (trail_result->is_predecessor);
+  querying_peer = trail_result->querying_peer;
   finger_identity = trail_result->finger_identity;
   trail_id = trail_result->trail_id;
-  trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
-
-  // FIXME: check that trail_peer_list[my_index + 1] == peer or
-  // my_index == trail_length - 1 AND finger_identity == peer
-
+  trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1];
+  ulitmate_destination_finger_value = 
+          GNUNET_ntohll (trail_result->ulitmate_destination_finger_value);
+  /* FIXME: here we are calculating my_index and comparing also in this 
function.
+   And we are doing it again here in this function. Re factor the code. */
+  /* Ensure that sender peer is the peer from which we were expecting the 
message. */
+  if (GNUNET_NO == is_sender_peer_correct (trail_peer_list,
+                                           trail_length,
+                                           peer, finger_identity, 
querying_peer))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  
   /* Am I the one who initiated the query? */
-  if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&destination_peer,
+  if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&querying_peer,
                                              &my_identity)))
   {
     finger_table_add (finger_identity, trail_peer_list,
-                      trail_length,
-                      finger_map_index, trail_id);
+                      trail_length, ulitmate_destination_finger_value,
+                      is_predecessor, trail_id);
     return GNUNET_YES;
   }
-
-  struct GNUNET_PeerIdentity next_hop;
-  struct FriendInfo *target_friend;
-  int my_index;
-
+  
   my_index = search_my_index(trail_peer_list, trail_length);
   if (-1 == my_index)
   {
     GNUNET_break_op(0);
     return GNUNET_SYSERR;
   }
-
-
+  
   if (my_index == 0)
-    next_hop = trail_result->destination_peer;
+    next_hop = trail_result->querying_peer;
   else
     next_hop = trail_peer_list[my_index - 1];
 
-  if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
-                                               
&(trail_result->finger_identity))))
+  /* If the querying_peer is its own finger, then don't add an entry in routing
+   * table as querying peer will discard the trail.
+   */
+  if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->querying_peer),
+                                             
&(trail_result->finger_identity))))
   {
     GDS_ROUTING_add (trail_id, next_hop, *peer);
   }
 
   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
&next_hop);
-  GDS_NEIGHBOURS_send_trail_setup_result (destination_peer, finger_identity,
+  GDS_NEIGHBOURS_send_trail_setup_result (querying_peer, finger_identity,
                                           target_friend, trail_length, 
trail_peer_list,
-                                          finger_map_index, trail_id);
+                                          is_predecessor, 
+                                          ulitmate_destination_finger_value,
+                                          trail_id);
   return GNUNET_OK;
 }
 
@@ -2755,7 +3566,7 @@
  * @return Updated trail
  */
 static struct GNUNET_PeerIdentity *
-invert_trail (struct GNUNET_PeerIdentity *trail,
+invert_trail (const struct GNUNET_PeerIdentity *trail,
               unsigned int trail_length)
 {
   int i;
@@ -2777,37 +3588,10 @@
 
 
 /**
- * Check if the new finger can be our predecessor. If yes then update 
predecessor
- *
- * @param new_finger
- * @param new_finger_trail
- * @param new_finger_trail_length
- * @return
- */
-static int
-is_new_entry_correct_predecessor (struct FingerInfo *my_predecessor,
-                                struct GNUNET_PeerIdentity new_finger,
-                                struct GNUNET_PeerIdentity *new_finger_trail,
-                                unsigned int new_finger_trail_length)
-{
-  struct GNUNET_PeerIdentity *updated_trail;
-  struct GNUNET_HashCode new_trail_id;
-
-  updated_trail =  invert_trail (new_finger_trail, new_finger_trail_length);
-  if (GNUNET_YES == is_new_finger_closest (my_predecessor, new_finger,
-                                           new_finger_trail,
-                                           new_finger_trail_length,
-                                           new_trail_id, 
PREDECESSOR_FINGER_ID))
-  {
-    add_new_entry (new_finger, updated_trail, new_finger_trail_length,
-                   new_trail_id, PREDECESSOR_FINGER_ID);
-    /* FIXME: check where you send add trail message */
-    return GNUNET_YES;
-  }
-  return GNUNET_NO;
-}
-
-/**
+ * FIXME: 
+ * my_current_predecessor != source_peer. get the trail to reach to 
+ * my_current_predecessor and append it to the trail from source to me.
+ * It can contain duplicate elements. Need to get the correct one. 
  * In case the source peer of verify successor message is not my successor,
  * then construct a trail from source peer to my current predecessor.
  * @param my_predecessor my current predecessor.
@@ -2817,18 +3601,21 @@
  * @return Updated trail from source peer to my_predecessor.
  */
 static struct GNUNET_PeerIdentity *
-trail_source_to_my_predecessor (struct FingerInfo *my_predecessor,
-                                struct GNUNET_PeerIdentity *current_trail,
+trail_source_to_my_predecessor (const struct GNUNET_PeerIdentity 
*current_trail,
                                 unsigned int current_trail_length,
                                 unsigned int *new_trail_length)
 {
   struct GNUNET_PeerIdentity *new_trail;
-  struct TrailList *trail_list_iterator;
-  struct Trail *trail_iterator;
+  struct Trail *trail_list_iterator;
+  struct Trail_Element *trail_iterator;
+  struct FingerInfo *my_predecessor;
   unsigned int i;
   unsigned int j;
   unsigned int shortest_trail_length = 0;
   unsigned int trail_index = 0;
+ 
+  my_predecessor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
+                                                        PREDECESSOR_FINGER_ID);
 
   for (i = 0; i < my_predecessor->trails_count; i++)
   {
@@ -2864,6 +3651,96 @@
 
 
 /**
+ * FIMXE: IF you update your predecessor with new finger identity or added
+ * a new trail, then you should send add_trail message or else the peers
+ * which are part of the trail to reach to your new predecessor will not 
+ * know its existence.
+ * Check if we already have an entry for predecessor in our finger hashmap.
+ * If no, then add new predecessor.
+ * If yes, then compare new and existing entry. If both are same, and there is
+ * place to store more trail, then add entry. If both are different then choose
+ * the closest one. 
+ * @param finger Peer which claims to be our predecessor.
+ * @param trail Trail to reach from @a predecessor to me, NOT including both 
endpoints
+ * @param trail_length Total number of peers in @a trail.
+ * @return #GNUNET_YES if we added the new entry.
+ *         #GNUNET_NO, if new entry is not the closest predecessor or both new
+ *                     and existing entry are same. 
+ */
+static struct GNUNET_PeerIdentity 
+compare_and_update_predecessor (struct GNUNET_PeerIdentity finger_identity,
+                                const struct GNUNET_PeerIdentity *trail,
+                                unsigned int trail_length)
+{
+  struct FingerInfo *current_predecessor;
+  struct GNUNET_PeerIdentity *closest_peer;
+  struct GNUNET_PeerIdentity *inverted_trail;
+  struct GNUNET_HashCode trail_id;
+  uint64_t finger_value;
+  
+  current_predecessor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
+                                                             
PREDECESSOR_FINGER_ID);
+  inverted_trail = invert_trail (trail, trail_length);
+  
+  /* No predecessor in finger table. Add the new predecessor. */
+  if (NULL == current_predecessor)
+  {
+    add_new_entry (finger_identity, inverted_trail, trail_length,
+                   trail_id, PREDECESSOR_FINGER_ID);
+    return finger_identity;
+  }
+  
+  /* If the new predecessor and current predecessor are not same, then choose
+   the closest one. */
+  if (0 != GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, 
+                                            
&current_predecessor->finger_identity))
+  {
+    finger_value = compute_predecessor_identity_value();
+    closest_peer = select_closest_peer (&current_predecessor->finger_identity,
+                                        &finger_identity,
+                                        finger_value, PREDECESSOR_FINGER_ID);
+    
+    /* If the finger is the closest predecessor, then add it in finger table
+     * and free resources of current_predecessor. */
+    if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, closest_peer))
+    {
+      GNUNET_assert (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
+                                                           &finger_identity));
+
+      send_trail_teardown (current_predecessor);
+      decrement_friend_trail_count (current_predecessor);
+      free_finger (current_predecessor);
+      add_new_entry (finger_identity, inverted_trail, trail_length,
+                     trail_id, PREDECESSOR_FINGER_ID);
+      return finger_identity;
+    }
+  }
+  
+  /* If both finger and current_predecessor are same as my_identity, then do 
nothing. */
+  if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, &my_identity))
+      return current_predecessor->finger_identity;
+    
+  /* If the current_predecessor is not a friend. */
+  if (NULL ==
+        GNUNET_CONTAINER_multipeermap_get (friend_peermap,
+                                           
&current_predecessor->finger_identity))
+  {
+    if (current_predecessor->trails_count < MAXIMUM_TRAILS_PER_FINGER)
+      add_new_trail (current_predecessor, inverted_trail, 
+                     trail_length, trail_id);
+    //FIXME: here you should send add a new trail as you don't have this trail
+    // in the routing table. 
+    else
+      select_and_replace_trail (current_predecessor, inverted_trail,
+                                trail_length, trail_id);
+     //FIXME: here you should send add a new trail as you don't have this trail
+    // in the routing table. 
+  }
+  return current_predecessor->finger_identity;
+}
+
+
+/**
  * Core handle for p2p verify successor messages.
  * @param cls closure
  * @param message message
@@ -2880,7 +3757,7 @@
   struct GNUNET_PeerIdentity *next_hop;
   struct FriendInfo *target_friend;
   struct GNUNET_HashCode trail_id;
-  struct FingerInfo *my_predecessor;
+  struct GNUNET_PeerIdentity current_predecessor;
   struct GNUNET_PeerIdentity *trail;
   struct GNUNET_PeerIdentity *new_trail;
   unsigned int trail_length;
@@ -2895,19 +3772,22 @@
   }
 
   vsm = (struct PeerVerifySuccessorMessage *) message;
-  trail_length = ntohl (vsm->trail_length);
-  if ((msize != sizeof (struct PeerVerifySuccessorMessage) +
-               trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
-      (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct 
GNUNET_PeerIdentity)))
+  trail_length = (msize - sizeof (struct PeerVerifySuccessorMessage))/
+                  sizeof (struct GNUNET_PeerIdentity);
+  if ((msize - sizeof (struct PeerVerifySuccessorMessage)) % 
+      sizeof (struct GNUNET_PeerIdentity) != 0)
   {
     GNUNET_break_op (0);
-    return GNUNET_YES;
-  }
+    return GNUNET_OK;      
+  }           
+  
   trail = (struct GNUNET_PeerIdentity *)&vsm[1];
   source_peer = vsm->source_peer;
   successor = vsm->successor;
   trail_id = vsm->trail_id;
 
+  /* I am not the successor of source_peer. Pass the message to next_hop on
+   * the trail. */
   if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&successor, &my_identity)))
   {
     next_hop = GDS_ROUTING_get_next_hop (trail_id, GDS_ROUTING_SRC_TO_DEST);
@@ -2922,39 +3802,26 @@
                                                   target_friend);
     return GNUNET_OK;
   }
-
-  my_predecessor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
-                                                        PREDECESSOR_FINGER_ID);
+  
   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
-  if (GNUNET_NO == is_new_entry_correct_predecessor (my_predecessor, 
source_peer,
-                                                     trail, trail_length))
+  current_predecessor = compare_and_update_predecessor (source_peer, 
+                                                        trail, trail_length);
+  /* source_peer is my current_predecessor. */
+  if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&current_predecessor, 
&source_peer)))
   {
-    if (0 != GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
-                                              
&my_predecessor->finger_identity))
-    {
-      new_trail = trail_source_to_my_predecessor (my_predecessor, trail,
-                                                  trail_length, 
&new_trail_length);
-    }
+    /* Here we don't need to pass the trail as it is of new use. We can pass
+     NULL and trail length = 0. */
+    new_trail = NULL;
+    new_trail_length = 0;
   }
   else
-  {
-    my_predecessor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
-                                                          
PREDECESSOR_FINGER_ID);
-    GDS_NEIGHBOURS_send_add_trail (my_predecessor->finger_identity,
-                                   source_peer, trail_id,
-                                   trail, trail_length,
-                                   target_friend);
-    new_trail_length = trail_length;
-    new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) *
-                               new_trail_length);
-    memcpy (new_trail, trail, sizeof (struct GNUNET_PeerIdentity) *
-                              trail_length);
+  { 
+    new_trail = trail_source_to_my_predecessor (trail, trail_length, 
+                                                &new_trail_length);
   }
-
   GDS_NEIGHBOURS_send_verify_successor_result (source_peer, my_identity,
-                                               my_predecessor->finger_identity,
-                                               trail_id, new_trail,
-                                               new_trail_length,
+                                               current_predecessor, trail_id,
+                                               new_trail, new_trail_length,
                                                GDS_ROUTING_DEST_TO_SRC,
                                                target_friend);
   return GNUNET_OK;
@@ -2962,6 +3829,9 @@
 
 
 /**
+ * Here you may or may not be the predecessor. If you are then also while 
adding
+ * you have to check and if not then notify new successor. But again the trail
+ * may be a problem here. 
  * FIXME: I will keep the logic to remove the old trail to reach from me to
  * my old successor here and move adding a new trail from me to new successor 
to notify
  * new successor. And in case if the new successor also take it as predecessor
@@ -2981,9 +3851,9 @@
   struct GNUNET_HashCode trail_id;
   unsigned int new_trail_length;
   struct GNUNET_PeerIdentity *new_trail;
-  struct GNUNET_PeerIdentity destination_peer;
-  struct GNUNET_PeerIdentity my_new_successor;
-  struct GNUNET_PeerIdentity old_successor;
+  struct GNUNET_PeerIdentity querying_peer;
+  struct GNUNET_PeerIdentity current_predecessor;
+  //struct GNUNET_PeerIdentity old_successor;
   struct GNUNET_PeerIdentity *next_hop;
   struct FriendInfo *target_friend;
   size_t msize;
@@ -2995,28 +3865,29 @@
     return GNUNET_YES;
   }
   vsrm = (struct PeerVerifySuccessorResultMessage *) message;
-  new_trail_length = ntohl (vsrm->trail_length);
+  new_trail_length = (msize - sizeof (struct PeerTrailSetupMessage))/
+                      sizeof (struct GNUNET_PeerIdentity);
+  if ((msize - sizeof (struct PeerTrailSetupMessage)) % 
+      sizeof (struct GNUNET_PeerIdentity) != 0)
+  {
+    GNUNET_break_op (0);
+    return GNUNET_OK;      
+  }           
   trail_direction = ntohl (vsrm->trail_direction);
   trail_id = vsrm->trail_id;
 
-  if ((msize !=
-       sizeof (struct PeerVerifySuccessorResultMessage) +
-       new_trail_length *
-       sizeof (struct GNUNET_PeerIdentity)) ||
-       (new_trail_length >
-       GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
-  {
-    GNUNET_break_op (0);
-    return GNUNET_YES;
-  }
-
   new_trail = (struct GNUNET_PeerIdentity *) &vsrm[1];
-  destination_peer = vsrm->destination_peer;
-  my_new_successor = vsrm->my_predecessor;
-  old_successor = vsrm->source_successor;
+  querying_peer = vsrm->querying_peer;
+  current_predecessor = vsrm->current_predecessor;
+  //old_successor = vsrm->source_successor;
 
-  if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&destination_peer, &my_identity)))
+  if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&querying_peer, &my_identity)))
   {
+#if 0
+    //Here I am the final quering peer and its verify successor result.
+    // now I know it is for successor and now I don't have any finger_map_index
+    // as parameter in finger_table_add. 
+    // BIG FIX HOW TO ADAPT IT FOR change in finger_table_add
     struct GNUNET_HashCode new_finger_trail_id;
     /* FIXME: generate a new trail id. */
     if (GNUNET_YES == finger_table_add (my_new_successor,
@@ -3037,15 +3908,16 @@
                                                 new_trail_length,
                                                 new_finger_trail_id, 
target_friend);
     }
+#endif
     return GNUNET_OK;
   }
 
   GNUNET_assert (NULL != (next_hop =
                          GDS_ROUTING_get_next_hop (trail_id, 
trail_direction)));
   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
-  GDS_NEIGHBOURS_send_verify_successor_result (destination_peer,
+  GDS_NEIGHBOURS_send_verify_successor_result (querying_peer,
                                                vsrm->source_successor,
-                                               my_new_successor, trail_id,
+                                               current_predecessor, trail_id,
                                                new_trail,
                                                new_trail_length,
                                                trail_direction, target_friend);
@@ -3054,6 +3926,8 @@
 
 
 /*
+ * FIXME: here before adding the peer you again have to call to check 
+ * if its correct predecessor or not.
  * Core handle for p2p notify new successor messages.
  * @param cls closure
  * @param message message
@@ -3067,8 +3941,9 @@
   struct PeerNotifyNewSuccessorMessage *nsm;
   struct GNUNET_PeerIdentity *trail;
   struct GNUNET_PeerIdentity source;
-  struct GNUNET_PeerIdentity destination;
+  struct GNUNET_PeerIdentity new_successor;
   struct FriendInfo *target_friend;
+  struct GNUNET_PeerIdentity closest_successor;
   struct GNUNET_HashCode trail_id;
   unsigned int my_index;
   struct GNUNET_PeerIdentity next_hop;
@@ -3083,7 +3958,14 @@
   }
 
   nsm = (struct PeerNotifyNewSuccessorMessage *) message;
-  trail_length = ntohl (nsm->trail_length);
+  trail_length = (msize - sizeof (struct PeerNotifyNewSuccessorMessage))/
+                  sizeof (struct GNUNET_PeerIdentity);
+  if ((msize - sizeof (struct PeerTrailRejectionMessage)) % 
+      sizeof (struct GNUNET_PeerIdentity) != 0)
+  {
+    GNUNET_break_op (0);
+    return GNUNET_OK;      
+  }  
 
   if ((msize < sizeof (struct PeerNotifyNewSuccessorMessage) +
                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
@@ -3096,45 +3978,42 @@
 
   trail = (struct GNUNET_PeerIdentity *) &nsm[1];
   source  = nsm->source_peer;
-  destination = nsm->destination_peer;
+  new_successor = nsm->new_successor;
   trail_id = nsm->trail_id;
 
-  if ( 0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &destination))
+  /* I am the new_successor to source_peer. */
+  if ( 0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &new_successor))
   {
-    struct GNUNET_HashCode new_trail_id;
-    struct FingerInfo *my_predecessor;
-
-    my_predecessor =
-            GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
-                                                 PREDECESSOR_FINGER_ID);
-    /* FIXME: get new_trail_id*/
-
-    if (GNUNET_YES == is_new_entry_correct_predecessor (my_predecessor,
-                                                        source, trail,
-                                                        trail_length))
+    closest_successor = compare_and_update_predecessor (source, trail, 
trail_length);
+    /* If the source peer is my new predecessor, then add trail in the
+     routing table of all the peers which are part of the trail to reach from 
+     me to source, NOT including endpoints. 
+     FIXME: In case we have same predecessor but we added just a new trail, 
then
+     we are not sending add a new trail message. Need to update this. */
+    if (0 == GNUNET_CRYPTO_cmp_peer_identity (&closest_successor, &source))
     {
-
+      struct GNUNET_HashCode new_trail_id;
       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
                                                          peer);
       GDS_NEIGHBOURS_send_add_trail (my_identity, source, new_trail_id,
                                      trail, trail_length, target_friend);
-      return GNUNET_OK;
     }
+    return GNUNET_OK;
   }
 
   my_index = search_my_index (trail, trail_length);
-  if (GNUNET_SYSERR == my_index)
+  if (-1 == my_index)
   {
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
   if (trail_length == my_index)
-    next_hop = destination;
+    next_hop = new_successor;
   else
     next_hop = trail[my_index + 1];
   GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (trail_id, *peer, next_hop));
   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
&next_hop);
-  GDS_NEIGHBOURS_send_notify_new_successor (source, destination, trail,
+  GDS_NEIGHBOURS_send_notify_new_successor (source, new_successor, trail,
                                             trail_length,
                                             trail_id, target_friend);
   return GNUNET_OK;
@@ -3165,7 +4044,7 @@
   struct GNUNET_PeerIdentity source;
   struct GNUNET_PeerIdentity *next_hop;
   uint64_t ultimate_destination_finger_value;
-  unsigned int finger_map_index;
+  unsigned int is_predecessor;
   size_t msize;
 
   msize = ntohs (message->size);
@@ -3176,24 +4055,22 @@
   }
 
   trail_rejection = (struct PeerTrailRejectionMessage *) message;
-  trail_length = ntohl (trail_rejection->trail_length);
-
-  if ((msize != sizeof (struct PeerTrailRejectionMessage) +
-               trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
-      (trail_length >
-       GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
+  trail_length = (msize - sizeof (struct PeerTrailRejectionMessage))/
+                  sizeof (struct GNUNET_PeerIdentity);
+  if ((msize - sizeof (struct PeerTrailRejectionMessage)) % 
+      sizeof (struct GNUNET_PeerIdentity) != 0)
   {
     GNUNET_break_op (0);
-    return GNUNET_YES;
-  }
+    return GNUNET_OK;      
+  }           
 
   trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
-  finger_map_index = ntohl (trail_rejection->finger_map_index);
+  is_predecessor = ntohl (trail_rejection->is_predecessor);
   congestion_timeout = trail_rejection->congestion_time;
   source = trail_rejection->source_peer;
   trail_id = trail_rejection->trail_id;
-  ultimate_destination_finger_value =
-  trail_rejection->ultimate_destination_finger_identity_value;
+  ultimate_destination_finger_value = 
+          trail_rejection->ultimate_destination_finger_value;
 
   /* First set the congestion time of the friend that sent you this message. */
   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
@@ -3229,7 +4106,7 @@
     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
next_hop);
     GDS_NEIGHBOURS_send_trail_rejection (source,
                                          ultimate_destination_finger_value,
-                                         my_identity, finger_map_index,
+                                         my_identity, is_predecessor,
                                          new_trail,new_trail_length,trail_id,
                                          target_friend, CONGESTION_TIMEOUT);
     return GNUNET_YES;
@@ -3239,7 +4116,7 @@
   next_hop = find_successor (ultimate_destination_finger_value,
                              &next_destination,
                              &new_intermediate_trail_id,
-                             finger_map_index);
+                             is_predecessor);
 
   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)))/* This 
means I am the final destination */
   {
@@ -3253,7 +4130,9 @@
                                             my_identity,
                                             target_friend, trail_length,
                                             trail_peer_list,
-                                            finger_map_index, trail_id);
+                                            is_predecessor, 
+                                            ultimate_destination_finger_value,
+                                            trail_id);
   }
   else
   {
@@ -3267,7 +4146,7 @@
                                      ultimate_destination_finger_value,
                                      next_destination,
                                      target_friend, trail_length + 1, 
peer_list,
-                                     finger_map_index, trail_id,
+                                     is_predecessor, trail_id,
                                      &new_intermediate_trail_id);
   }
   return GNUNET_OK;
@@ -3415,7 +4294,14 @@
   }
 
   add_trail = (struct PeerAddTrailMessage *) message;
-  trail_length = ntohl (add_trail->trail_length);
+  trail_length = (msize - sizeof (struct PeerAddTrailMessage))/
+                  sizeof (struct GNUNET_PeerIdentity);
+  if ((msize - sizeof (struct PeerAddTrailMessage)) % 
+      sizeof (struct GNUNET_PeerIdentity) != 0)
+  {
+    GNUNET_break_op (0);
+    return GNUNET_OK;      
+  }           
 
   if ((msize < sizeof (struct PeerAddTrailMessage) +
                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
@@ -3480,7 +4366,7 @@
 {
   struct FingerInfo *remove_finger = value;
   const struct GNUNET_PeerIdentity *disconnected_peer = cls;
-  struct TrailList *trail_list;
+  struct Trail *trail_list;
   int i;
 
   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->finger_identity,

Modified: gnunet/src/dht/gnunet-service-xdht_neighbours.h
===================================================================
--- gnunet/src/dht/gnunet-service-xdht_neighbours.h     2014-06-05 13:46:59 UTC 
(rev 33540)
+++ gnunet/src/dht/gnunet-service-xdht_neighbours.h     2014-06-05 15:24:26 UTC 
(rev 33541)
@@ -32,18 +32,19 @@
 #include "gnunet_dht_service.h"
 
 
-/**  
- * Construct a Put message and send it to target_peer. 
- * @param key Key for the content  
+/**
+ * Construct a Put message and send it to target_peer.
+ * @param key Key for the content
  * @param block_type Type of the block
  * @param options Routing options
  * @param desired_replication_level Desired replication count
- * @param current_destination Next current destination which will get this 
message.
- * @param current_source Source for @a current_destination
+ * @param best_known_dest Peer to which this message should reach eventually,
+ *                        as it is best known destination to me. 
+ * @param intermediate_trail_id Trail id in case 
  * @param target_peer Peer to which this message will be forwarded.
  * @param hop_count Number of hops traversed so far.
  * @param put_path_length Total number of peers in @a put_path
- * @param put_path Number of peers traversed so far 
+ * @param put_path Number of peers traversed so far
  * @param expiration_time When does the content expire
  * @param data Content to store
  * @param data_size Size of content @a data in bytes
@@ -51,11 +52,11 @@
 void
 GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
                          enum GNUNET_BLOCK_Type block_type,
-                         enum GNUNET_DHT_RouteOption options,
-                         uint32_t desired_replication_level,
-                         struct GNUNET_PeerIdentity current_destination,
-                         struct GNUNET_PeerIdentity current_source,
-                         struct GNUNET_PeerIdentity *target_peer,
+                        enum GNUNET_DHT_RouteOption options,
+                        uint32_t desired_replication_level,
+                        struct GNUNET_PeerIdentity *best_known_dest,
+                        struct GNUNET_HashCode *intermediate_trail_id,
+                        struct GNUNET_PeerIdentity *target_peer,
                          uint32_t hop_count,
                          uint32_t put_path_length,
                          struct GNUNET_PeerIdentity *put_path,
@@ -63,14 +64,14 @@
                          const void *data, size_t data_size);
 
 
-/** 
- * Construct a Get message and send it to target_peer. 
- * @param key Key for the content  
+/**
+ * Construct a Get message and send it to target_peer.
+ * @param key Key for the content
  * @param block_type Type of the block
  * @param options Routing options
  * @param desired_replication_level Desired replication count
- * @param current_destination Next current destination which will get this 
message.
- * @param current_source Source for @a current_destination
+ * @param best_known_dest 
+ * @param intermediate_trail_id 
  * @param target_peer Peer to which this message will be forwarded.
  * @param hop_count Number of hops traversed so far.
  * @param data Content to store
@@ -83,8 +84,8 @@
                          enum GNUNET_BLOCK_Type block_type,
                          enum GNUNET_DHT_RouteOption options,
                          uint32_t desired_replication_level,
-                         struct GNUNET_PeerIdentity current_destination,
-                         struct GNUNET_PeerIdentity current_source,
+                         struct GNUNET_PeerIdentity *best_known_dest,
+                         struct GNUNET_HashCode *intermediate_trail_id,
                          struct GNUNET_PeerIdentity *target_peer,
                          uint32_t hop_count,
                          uint32_t get_path_length,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]