Framework for trail rejection and threshold on links
[oweals/gnunet.git] / src / dht / gnunet-service-xdht_neighbours.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009-2013 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file dht/gnunet-service-xdht_neighbours.c
23  * @brief GNUnet DHT service's finger and friend table management code
24  * @author Supriti Singh
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_block_lib.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_constants.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_nse_service.h"
34 #include "gnunet_ats_service.h"
35 #include "gnunet_core_service.h"
36 #include "gnunet_datacache_lib.h"
37 #include "gnunet_transport_service.h"
38 #include "gnunet_hello_lib.h"
39 #include "gnunet_dht_service.h"
40 #include "gnunet_statistics_service.h"
41 #include "gnunet-service-xdht.h"
42 #include "gnunet-service-xdht_clients.h"
43 #include "gnunet-service-xdht_datacache.h"
44 #include "gnunet-service-xdht_hello.h"
45 #include "gnunet-service-xdht_neighbours.h"
46 #include "gnunet-service-xdht_nse.h"
47 #include "gnunet-service-xdht_routing.h"
48 #include <fenv.h>
49 #include "dht.h"
50
51 /* TODO:
52  * 1. when should we use const struct and replace wherever needed. 
53  * 2. use assert for each function where you need to check the return value.
54  1. Use a global array of all known peers in find_successor, Only when 
55  a new peer is added in finger or friend peer map, then re calculate
56  the array. Or else use the old one.
57  2. Should we be using const in all the handle for the message we received 
58  * and then copy the fields and make changes to the fields instead of sending
59  * them as they come.
60  * 3. Everywhere you are storing yourself as the first element in the trail.
61  * It is obviously taking too much space. Try to remove it and think of something
62  * better.
63  4. Choose the correct interval to send finger and verify message.
64  5. Do we need expiration time for trail setup and all other messages? TTL
65  6. In case of trail setup after TTL, we should again send the request but 
66  * through a different route. How do we remeber each time which friend we
67  * chose last time for the trail setup. We will need a data structure where we
68  * add entry in finger table add and when setup is done remove it.
69  * 7. I have not added any authentication on messages exachanged between peers.
70  * Only when basic put/get is correct I will add it. */
71
72 /**
73  * Maximum possible fingers of a peer.
74  */
75 #define MAX_FINGERS 64
76
77 /**
78  * Maximum allowed number of pending messages per friend peer.
79  */
80 #define MAXIMUM_PENDING_PER_FRIEND 64
81
82 /**
83  * How long at least to wait before sending another find finger trail request.
84  */
85 #define DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
86
87 /**
88  * How long at most to wait before sending another find finger trail request.
89  */
90 #define DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 10)
91
92 /**
93  * How long at most to wait for transmission of a GET request to another peer?
94  */
95 #define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
96
97 /**
98  * Maximum number of trails allowed to go through a friend.
99  */
100 #define LINK_THRESHOLD 64
101
102
103 GNUNET_NETWORK_STRUCT_BEGIN
104   
105 /**
106  * P2P PUT message
107  */
108 struct PeerPutMessage
109 {
110   /**
111    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
112    */
113   struct GNUNET_MessageHeader header;
114
115   /**
116    * Processing options
117    */
118   uint32_t options GNUNET_PACKED;
119
120   /**
121    * Content type.
122    */
123   uint32_t block_type GNUNET_PACKED;
124
125   /**
126    * Hop count
127    */
128   uint32_t hop_count GNUNET_PACKED;
129
130   /**
131    * Replication level for this message
132    */
133   uint32_t desired_replication_level GNUNET_PACKED;
134
135   /**
136    * Length of the PUT path that follows (if tracked).
137    */
138   uint32_t put_path_length GNUNET_PACKED;
139   
140   /** 
141    * Current destination to which this message is forwarded.
142    */
143   struct GNUNET_PeerIdentity current_destination;
144   
145   /**
146    * Peer whose finger is current_destination. 
147    */
148   struct GNUNET_PeerIdentity current_source;
149   
150   /** 
151    * current_destination type.
152    */
153   enum current_destination_type current_destination_type;
154
155   /**
156    * When does the content expire?
157    */
158   struct GNUNET_TIME_AbsoluteNBO expiration_time;
159   
160   /**
161    * The key to store the value under.
162    */
163   struct GNUNET_HashCode key GNUNET_PACKED;
164  
165
166   /* put path (if tracked) */
167
168   /* Payload */
169  
170 };
171
172
173 /**
174  * P2P Result message
175  */
176 struct PeerGetResultMessage
177 {
178   /**
179    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT
180    */
181   struct GNUNET_MessageHeader header;
182
183   /**
184    * The type for the data.
185    */
186   uint32_t type GNUNET_PACKED;
187   
188   /**
189    * Peer which is sending get result message.
190    */
191   struct GNUNET_PeerIdentity source_peer;
192   
193   /**
194    * Peer which will receive the get result message. 
195    */
196   struct GNUNET_PeerIdentity destination_peer;
197
198   /**
199    * Current index in get path. 
200    */
201   unsigned int current_path_index;
202   /**
203    * Number of peers recorded in the outgoing path from source to the
204    * storgage location of this message.
205    */
206   uint32_t put_path_length GNUNET_PACKED;
207   
208   /**
209    * When does this entry expire?
210    */
211   struct GNUNET_TIME_AbsoluteNBO expiration;
212   
213   /**
214    * Length of the GET path that follows (if tracked).
215    */
216   uint32_t get_path_length GNUNET_PACKED;
217
218   /**
219    * When does the content expire?
220    */
221   struct GNUNET_TIME_AbsoluteNBO expiration_time;
222
223   /**
224    * The key of the corresponding GET request.
225    */
226   struct GNUNET_HashCode key;
227  
228   /* put path (if tracked) */
229
230   /* get path (if tracked) */
231
232   /* Payload */
233
234 };
235
236
237 /**
238  * P2P GET message
239  */
240 struct PeerGetMessage
241 {
242   /**
243    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET
244    */
245   struct GNUNET_MessageHeader header;
246   
247   /**
248    * Processing options
249    */
250   uint32_t options GNUNET_PACKED;
251
252   /**
253    * Desired content type.
254    */
255   uint32_t block_type GNUNET_PACKED;
256   
257   /**
258    * Hop count
259    */
260   uint32_t hop_count GNUNET_PACKED;
261  
262   /**
263    * Desired replication level for this request.
264    */
265   uint32_t desired_replication_level GNUNET_PACKED;
266   
267   /**
268    * Total number of peers in get path. 
269    */
270   unsigned int get_path_length;
271   
272   /**
273    * Peer which is an intermediate destination. 
274    */
275   struct GNUNET_PeerIdentity current_destination;
276   
277   /**
278    * Source for which current_destination is the finger. 
279    */
280   struct GNUNET_PeerIdentity current_source;
281   
282   /**
283    * Type of current destination
284    */
285   enum current_destination_type current_dest_type;  
286   
287   /**
288    * The key we are looking for.
289    */
290   struct GNUNET_HashCode key;
291   
292   /* Get path. */
293
294 };
295
296
297 /**
298  * P2P Trail setup message
299  */
300 struct PeerTrailSetupMessage
301 {
302   
303   /**
304    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
305    */
306   struct GNUNET_MessageHeader header;
307
308   /**
309    * Source peer which wants to setup the trail to one of its finger. 
310    */
311   struct GNUNET_PeerIdentity source_peer;
312
313   /**
314    * Successor of this finger value will be our finger peer.
315    */
316   uint64_t destination_finger;
317   
318   /**
319    * Peer which gets this message can be either an intermediate finger or friend. 
320    */
321   enum current_destination_type current_destination_type;
322   
323   /**
324    * Peer to which this packet is forwarded.
325    */
326   struct GNUNET_PeerIdentity current_destination;
327   
328   /**
329    * In case the packet is forwarded to an intermediate finger, then 
330    * current_source contains the peer id whose finger is the intermediate
331    * finger. In case the packet is forwarded to a friend, then it is NULL.
332    */
333   struct GNUNET_PeerIdentity current_source;
334   
335   /**
336    * Index into finger peer map. 
337    */
338   unsigned int finger_map_index;
339   
340   /**
341    * Number of entries in trail list.
342    */
343   uint32_t trail_length GNUNET_PACKED;
344   
345 };
346
347
348 /**
349  * P2P Trail Setup Result message
350  */
351 struct PeerTrailSetupResultMessage
352 {
353   
354   /**
355    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT
356    */
357   struct GNUNET_MessageHeader header;
358   
359   /**
360    * Finger to which we have found the path. 
361    */
362   struct GNUNET_PeerIdentity finger_identity;
363
364   /**
365    * Peer which was looking for the trail to finger. 
366    */
367   struct GNUNET_PeerIdentity destination_peer;
368
369   /**
370    * Trail index which points to next destination to send this message.
371    */
372   unsigned int current_index;
373   
374   /**
375    * Index into finger peer map
376    */
377   unsigned int finger_map_index;
378   
379   /**
380    * Number of entries in trail list.
381    */
382   uint32_t trail_length GNUNET_PACKED;
383   
384 };
385
386 /**
387  *
388  */
389 struct PeerTrailRejectionMessage
390 {
391   /**
392    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION
393    */
394   struct GNUNET_MessageHeader header;
395   
396   /**
397    * Source peer which wants to set up the trail. 
398    */
399   struct GNUNET_PeerIdentity source_peer;
400   
401   /**
402    * Finger identity value. 
403    */
404   uint64_t finger_identity;
405   
406   /**
407    * Peer which sent trail rejection message. 
408    */
409   struct GNUNET_PeerIdentity congested_peer;
410   
411   /**
412    * Index in finger peer map of source peer.
413    */
414   unsigned int finger_map_index;
415   
416   /**
417    * Total number of peers in the trail.
418    */
419   unsigned int trail_length;
420   
421   /* trail_list */
422 };
423
424
425 /**
426  * P2P Verify Successor message. 
427  */
428 struct PeerVerifySuccessorMessage
429 {
430   
431   /**
432    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR
433    */
434   struct GNUNET_MessageHeader header;
435   
436   /**
437    * Source peer which wants to verify its successor. 
438    */
439   struct GNUNET_PeerIdentity source_peer;
440   
441   /**
442    * My current successor.
443    */
444   struct GNUNET_PeerIdentity successor;
445   
446   /**
447    * Total number of peers in trail to current successor.
448    */
449   unsigned int trail_length;
450   
451   /**
452    * Trail index which points to next destination to send this message.
453    */
454   unsigned int current_trail_index;
455   
456 };
457
458
459 /**
460  * P2P Verify Successor Result message. 
461  */
462 struct PeerVerifySuccessorResultMessage
463 {
464   
465   /**
466    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT
467    */
468   struct GNUNET_MessageHeader header;
469   
470   /**
471    * Destination peer which sent the request to verify its successor. 
472    */
473   struct GNUNET_PeerIdentity destination_peer;
474   
475   /**
476    * Successor to which PeerVerifySuccessorMessage was sent.
477    */
478   struct GNUNET_PeerIdentity source_successor;
479   
480   /**
481    * source_successor's predecessor
482    */
483   struct GNUNET_PeerIdentity my_predecessor;
484   
485   /**
486    * Total number of peers in trail.
487    * If source_successor is not destination peer, then trail is from destination_peer
488    * to my_predecessor.
489    * If source_successor is destination peer, then trail is from destination_peer
490    * to source_successor.
491    */
492   unsigned int trail_length;
493   
494   /**
495    * Trail index which points to next destination to send this message.
496    */
497   unsigned int current_index;
498   
499 };
500
501 /**
502  * P2P Notify New Successor message.
503  */
504 struct PeerNotifyNewSuccessorMessage
505 {
506   /**
507    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR
508    */
509   struct GNUNET_MessageHeader header;
510   
511   /**
512    * Source peer which wants to notify its new successor. 
513    */
514   struct GNUNET_PeerIdentity source_peer;
515   
516   /**
517    * New successor identity.
518    */
519   struct GNUNET_PeerIdentity destination_peer;
520   
521   /**
522    * Number of peers in trail from source_peer to new successor.
523    */
524   unsigned int trail_length;
525   
526   /**
527    * Trail index which points to next destination to send this message.
528    */
529   unsigned int current_index;
530   
531 };
532
533
534 GNUNET_NETWORK_STRUCT_END
535
536
537 /**
538  * Linked list of messages to send to a particular other peer.
539  */
540 struct P2PPendingMessage
541 {
542   /**
543    * Pointer to next item in the list
544    */
545   struct P2PPendingMessage *next;
546
547   /**
548    * Pointer to previous item in the list
549    */
550   struct P2PPendingMessage *prev;
551
552   /**
553    * When does this message time out?
554    */
555   struct GNUNET_TIME_Absolute timeout;
556
557    /**
558    * Message importance level.  FIXME: used? useful?
559    */
560   unsigned int importance;
561
562   /**
563    * Actual message to be sent, allocated at the end of the struct:
564    * // msg = (cast) &pm[1];
565    * // memcpy (&pm[1], data, len);
566    */
567   const struct GNUNET_MessageHeader *msg;
568
569 };
570
571
572 /**
573  * Linked List of peers which are part of trail to reach a particular Finger.
574  */
575 struct TrailPeerList
576 {
577    /**
578     * Pointer to next item in the list
579     */
580    struct TrailPeerList *next;
581
582    /**
583     * Pointer to previous item in the list
584     */
585    struct TrailPeerList *prev;
586    
587    /**
588     * An element in this trail list
589     */
590    struct GNUNET_PeerIdentity peer;
591   
592 };
593
594
595 /** 
596  *  Entry in friend_peermap.
597  */
598 struct FriendInfo
599 {
600   /**
601    * Friend Identity 
602    */
603   struct GNUNET_PeerIdentity id;
604
605   /**
606    * Number of trail of which this friend is the first hop.
607    */
608   unsigned int trail_links;
609   
610   /**
611    * Count of outstanding messages for this friend.
612    */
613   unsigned int pending_count;
614   
615   /**
616    * Head of pending messages to be sent to this friend.
617    */
618   struct P2PPendingMessage *head;
619
620   /**
621    * Tail of pending messages to be sent to this friend.
622    */
623   struct P2PPendingMessage *tail;
624  
625   /**
626    * Core handle for sending messages to this friend.
627    */
628   struct GNUNET_CORE_TransmitHandle *th;
629
630 };
631
632
633 /**
634  * Entry in finger_peermap.
635  */
636 struct FingerInfo
637 {
638   /**
639    * Finger identity.
640    */
641   struct GNUNET_PeerIdentity finger_identity;
642   
643   /**
644    * Index in finger peer map
645    */
646   unsigned int finger_map_index;
647   
648   /**
649    * Total number of entries in trail from (me,finger] 
650    */
651   unsigned int trail_length;
652   
653   /**
654    * Head of trail to reach this finger.
655    */
656   struct TrailPeerList *head;
657   
658   /**
659    * Tail of trail to reach this finger.
660    */
661   struct TrailPeerList *tail;
662   
663 };
664
665
666 /**
667  * FIXME: Think of a better name. 
668  * Data structure passed to sorting algorithm in find_successor.
669  */
670 struct Sorting_List
671 {
672   /**
673    * 64 bit value of peer identity
674    */
675   uint64_t peer_id;
676   
677   /**
678    * Type : MY_ID, FINGER, FINGER, Value 
679    */
680   enum current_destination_type type;
681   
682   /**
683    * Pointer to original data structure linked to peer id.
684    */
685   void *data;
686 };
687
688
689 /**
690  * FIXME: Think of better comments.
691  * An entry in Failed_Trail_List
692  */
693 struct FailedTrail
694 {
695   /**
696    * Source peer which was trying to setup up the trail to @a destination_finger_value
697    */
698   struct GNUNET_PeerIdentity source_peer;
699   
700   /**
701    * Value to which we were trying to find the closest successor.
702    */
703   uint64_t destination_finger_value;
704   
705   /**
706    * Peer which has crossed the threshold limit on its routing table size.
707    */
708   struct GNUNET_PeerIdentity congested_peer;
709   
710 };
711
712
713 /**
714  * Task that sends FIND FINGER TRAIL requests.
715  */
716 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
717
718 /**
719  * 
720  * Task that periodically verifies my successor. 
721  */
722 static GNUNET_SCHEDULER_TaskIdentifier verify_successor;
723
724 /**
725  * Identity of this peer.
726  */
727 static struct GNUNET_PeerIdentity my_identity;
728
729 /**
730  * Hash map of all the friends of a peer
731  */
732 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
733
734 /**
735  * Hash map of all the fingers of a peer
736  */
737 static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap;
738
739 /**
740  * Hash maps of all the trail which failed due to a congested peer. 
741  */
742 static struct GNUNET_CONTAINER_MultiPeerMap *failed_trail_list;
743
744 /**
745  * Handle to CORE.
746  */
747 static struct GNUNET_CORE_Handle *core_api;
748
749 /**
750  * FIXME: Is it safe to assume its initialized to 0 by default.
751  * The current finger index that we have found trail to.
752  */
753 static unsigned int current_finger_index;
754
755
756 /**
757  * Called when core is ready to send a message we asked for
758  * out to the destination.
759  *
760  * @param cls the 'struct FriendInfo' of the target friend
761  * @param size number of bytes available in buf
762  * @param buf where the callee should write the message
763  * @return number of bytes written to buf
764  */
765 static size_t
766 core_transmit_notify (void *cls, size_t size, void *buf)
767 {
768   struct FriendInfo *peer = cls;
769   char *cbuf = buf;
770   struct P2PPendingMessage *pending;
771   size_t off;
772   size_t msize;
773   
774   peer->th = NULL;
775   while ((NULL != (pending = peer->head)) &&
776          (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
777   {
778     peer->pending_count--;
779     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);  
780     GNUNET_free (pending);
781   }
782   if (NULL == pending)
783   {
784     /* no messages pending */
785     return 0;
786   }
787   if (NULL == buf)
788   {
789     peer->th =
790         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
791                                            GNUNET_CORE_PRIO_BEST_EFFORT,
792                                            GNUNET_TIME_absolute_get_remaining
793                                            (pending->timeout), &peer->id,
794                                            ntohs (pending->msg->size),
795                                            &core_transmit_notify, peer);
796     GNUNET_break (NULL != peer->th);
797     return 0;
798   }
799   off = 0;
800   while ((NULL != (pending = peer->head)) &&
801          (size - off >= (msize = ntohs (pending->msg->size))))
802   {
803     GNUNET_STATISTICS_update (GDS_stats,
804                               gettext_noop
805                               ("# Bytes transmitted to other peers"), msize,
806                               GNUNET_NO);
807     memcpy (&cbuf[off], pending->msg, msize);
808     off += msize;
809     peer->pending_count--;
810     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
811     GNUNET_free (pending);
812   }
813   if (peer->head != NULL)
814   {
815     peer->th =
816         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
817                                            GNUNET_CORE_PRIO_BEST_EFFORT,
818                                            GNUNET_TIME_absolute_get_remaining
819                                            (pending->timeout), &peer->id, msize,
820                                            &core_transmit_notify, peer);
821     GNUNET_break (NULL != peer->th);
822   }
823   return off;
824 }
825
826
827 /**
828  * Transmit all messages in the friend's message queue.
829  *
830  * @param peer message queue to process
831  */
832 static void
833 process_friend_queue (struct FriendInfo *peer)
834 {
835   struct P2PPendingMessage *pending;
836   
837   if (NULL == (pending = peer->head))
838     return;
839   if (NULL != peer->th)
840     return;
841   
842   GNUNET_STATISTICS_update (GDS_stats,
843                             gettext_noop
844                             ("# Bytes of bandwidth requested from core"),
845                             ntohs (pending->msg->size), GNUNET_NO);
846   
847   /* FIXME: Are we correctly initializing importance and pending. */
848   peer->th =
849       GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
850                                          pending->importance,
851                                          GNUNET_TIME_absolute_get_remaining
852                                          (pending->timeout), &peer->id,
853                                          ntohs (pending->msg->size),
854                                          &core_transmit_notify, peer);
855   GNUNET_break (NULL != peer->th);
856 }
857
858
859 /**FIXME: add better comment for current_source which shows its relation
860  * with current_destination. 
861  * Construct a trail message and forward it to a friend. 
862  * @param source_peer Peer which wants to set up the trail to one of its finger.
863  * @param destination_finger Value whose successor we are searching the network.
864  * @param current_destination Peer which gets this message. 
865  * @param current_source Peer for which current_destination is its finger.
866  * @param target_friend Current friend to which this message should be forwarded.
867  * @param trail_length Numbers of peers in the trail.
868  * @param trail_peer_list peers this request has traversed so far  
869  * @param finger_map_index Index in finger peer map
870  * @param type Type of current destination can be either FRIEND or FINGER
871  */
872 void
873 GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity *source_peer,
874                                  uint64_t destination_finger,
875                                  struct GNUNET_PeerIdentity *current_destination,
876                                  struct GNUNET_PeerIdentity *current_source,
877                                  struct FriendInfo *target_friend,
878                                  unsigned int trail_length,
879                                  struct GNUNET_PeerIdentity *trail_peer_list,
880                                  unsigned int finger_map_index,
881                                  enum current_destination_type type)
882 {
883   struct P2PPendingMessage *pending;
884   struct PeerTrailSetupMessage *tsm;
885   struct GNUNET_PeerIdentity *peer_list;
886   size_t msize;
887   
888   msize = sizeof (struct PeerTrailSetupMessage) + 
889           (trail_length * sizeof (struct GNUNET_PeerIdentity));
890   
891   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
892   {
893     GNUNET_break (0);
894     return;
895   }
896   
897   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
898   {  
899     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
900                                 1, GNUNET_NO);
901   }
902   
903   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
904   pending->importance = 0;    /* FIXME */
905   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
906   tsm = (struct PeerTrailSetupMessage *) &pending[1]; 
907   pending->msg = &tsm->header;
908   tsm->header.size = htons (msize);
909   tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
910   memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t));
911   memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
912   memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
913   /* FIXME: Is it correct to use NULL here for comparison? */
914   if (current_source != NULL)
915     memcpy (&(tsm->current_source), current_source, sizeof (struct GNUNET_PeerIdentity));
916   tsm->current_destination_type = htonl (type); 
917   tsm->trail_length = htonl (trail_length); 
918   tsm->finger_map_index = htonl (finger_map_index);
919   
920   if (trail_peer_list != NULL)
921   {
922     peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
923     memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
924   }
925
926   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
927   target_friend->pending_count++;
928   process_friend_queue (target_friend);
929   
930 }
931
932
933 /**
934  * Construct a trail setup result message and forward it to a friend. 
935  * @param destination_peer Peer which will get the trail to one of its finger.
936  * @param source_finger Peer to which the trail has been setup to.
937  * @param target_friend Friend to which this message should be forwarded.
938  * @param trail_length Numbers of peers in the trail.
939  * @param trail_peer_list Peers which are part of the trail from source to destination.
940  * @param current_trail_index Index at which sender of this message is located.  
941  * @param finger_map_index Index in finger peer map 
942  */
943 void
944 GDS_NEIGHBOURS_send_trail_setup_result (struct GNUNET_PeerIdentity *destination_peer,
945                                         struct GNUNET_PeerIdentity *source_finger,
946                                         struct FriendInfo *target_friend,
947                                         unsigned int trail_length,
948                                         struct GNUNET_PeerIdentity *trail_peer_list,
949                                         unsigned int current_trail_index,
950                                         unsigned int finger_map_index)
951 {
952   struct P2PPendingMessage *pending;
953   struct PeerTrailSetupResultMessage *tsrm;
954   struct GNUNET_PeerIdentity *peer_list;
955   size_t msize;
956   
957   msize = sizeof (struct PeerTrailSetupResultMessage) + 
958           (trail_length * sizeof (struct GNUNET_PeerIdentity));
959   
960   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
961   {
962     GNUNET_break (0);
963     return;
964   }
965   
966   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
967   {  
968     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
969                                 1, GNUNET_NO);
970   }
971
972   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
973   pending->importance = 0;    
974   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
975   tsrm = (struct PeerTrailSetupResultMessage *) &pending[1]; 
976   pending->msg = &tsrm->header;
977   tsrm->header.size = htons (msize);
978   tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT);
979   memcpy (&(tsrm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
980   memcpy (&(tsrm->finger_identity), source_finger, sizeof (struct GNUNET_PeerIdentity));
981   tsrm->trail_length = htonl (trail_length);
982   tsrm->current_index = htonl (current_trail_index);
983   tsrm->finger_map_index = htonl (finger_map_index);
984   peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
985   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
986   
987   /* Send the message to chosen friend. */
988   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
989   target_friend->pending_count++;
990   process_friend_queue (target_friend);
991 }
992
993
994 /**
995  * Construct a PeerVerifySuccessor message and send it to friend.
996  * @param source_peer Peer which wants to verify its successor
997  * @param successor Peer which is our current successor
998  * @param target_friend Friend to which this message should be forwarded.
999  * @param trail_peer_list Peer which are part of trail from source to destination
1000  * @param trail_length Number of peers in the trail list.
1001  * @param current_trail_index Index in the trial list at which receiving peer should
1002  *                            read the next element.
1003  */
1004 void GDS_NEIGHBOURS_send_verify_successor(struct GNUNET_PeerIdentity *source_peer,
1005                                           struct GNUNET_PeerIdentity *successor,
1006                                           struct FriendInfo *target_friend,
1007                                           struct GNUNET_PeerIdentity *trail_peer_list,
1008                                           unsigned int trail_length,
1009                                           unsigned int current_trail_index)
1010 {
1011   struct PeerVerifySuccessorMessage *vsm;
1012   struct P2PPendingMessage *pending;
1013   struct GNUNET_PeerIdentity *peer_list;
1014   size_t msize;
1015   
1016   msize = sizeof (struct PeerVerifySuccessorMessage) + 
1017           (trail_length * sizeof (struct GNUNET_PeerIdentity));
1018   
1019   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1020   {
1021     GNUNET_break (0);
1022     return;
1023   }
1024  
1025   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1026   {  
1027     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1028                                 1, GNUNET_NO);
1029   }
1030   
1031   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1032   pending->importance = 0;    /* FIXME */
1033   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1034   vsm = (struct PeerVerifySuccessorMessage *) &pending[1];
1035   pending->msg = &vsm->header;
1036   vsm->header.size = htons (msize);
1037   vsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR);
1038   memcpy (&(vsm->successor), successor, sizeof (struct GNUNET_PeerIdentity));
1039   memcpy (&(vsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1040   vsm->trail_length = htonl (trail_length);
1041   vsm->current_trail_index = htonl (current_trail_index);
1042   peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
1043   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1044   
1045   /* Send the message to chosen friend. */
1046   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1047   target_friend->pending_count++;
1048   process_friend_queue (target_friend);
1049   
1050 }
1051
1052
1053 /**
1054  * Construct a PeerVerifySuccessorResult message and send it to friend.
1055  * @param destination_peer Peer which sent verify successor message
1056  * @param source_successor Peer to which verify successor message was sent.
1057  * @param my_predecessor source_successor's predecessor.
1058  * @param target_friend Friend to which this message should be forwarded.
1059  * @param trail_peer_list Peers which are part of trail from source to destination
1060  * @param trail_length Number of peers in the trail list.
1061  * @param current_trail_index Index in the trial list at which receiving peer should
1062  *                            get the next element.
1063  */
1064 void GDS_NEIGHBOURS_send_verify_successor_result (struct GNUNET_PeerIdentity *destination_peer,
1065                                                   struct GNUNET_PeerIdentity *source_successor,
1066                                                   struct GNUNET_PeerIdentity *my_predecessor,
1067                                                   struct FriendInfo *target_friend,
1068                                                   struct GNUNET_PeerIdentity *trail_peer_list,
1069                                                   unsigned int trail_length,
1070                                                   unsigned int current_trail_index)
1071 {
1072   struct PeerVerifySuccessorResultMessage *vsmr;
1073   struct P2PPendingMessage *pending;
1074   struct GNUNET_PeerIdentity *peer_list;
1075   size_t msize;
1076   
1077   msize = sizeof (struct PeerVerifySuccessorResultMessage) + 
1078           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1079   
1080   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1081   {
1082     GNUNET_break (0);
1083     return;
1084   }
1085   
1086   
1087   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1088   {  
1089     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1090                                 1, GNUNET_NO);
1091   }
1092
1093   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1094   pending->importance = 0;    /* FIXME */
1095   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1096   vsmr = (struct PeerVerifySuccessorResultMessage *) &pending[1];
1097   pending->msg = &vsmr->header;
1098   vsmr->header.size = htons (msize);
1099   vsmr->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT);
1100   memcpy (&(vsmr->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1101   memcpy (&(vsmr->source_successor), source_successor, sizeof (struct GNUNET_PeerIdentity));
1102   memcpy (&(vsmr->my_predecessor), my_predecessor, sizeof (struct GNUNET_PeerIdentity));
1103   vsmr->trail_length = htonl (trail_length);
1104   vsmr->current_index = htonl (current_trail_index);
1105   
1106   peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
1107   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1108   
1109    /* Send the message to chosen friend. */
1110   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1111   target_friend->pending_count++;
1112   process_friend_queue (target_friend);
1113 }
1114
1115
1116 /**
1117  * Construct a PeerNotifyNewSuccessor message and send it to friend.
1118  * @param source_peer Peer which is sending notify message to its new successor.
1119  * @param destination_peer Peer which is the new destination.
1120  * @param target_friend Next friend to pass this message to. 
1121  * @param peer_list List of peers in the trail to reach to destination_peer.
1122  * @param current_trail_index Index of peer_list for next target friend position. 
1123  * @param trail_length Total number of peers in peer list 
1124  */
1125 void 
1126 GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity *source_peer,
1127                                           struct GNUNET_PeerIdentity *destination_peer,
1128                                           struct FriendInfo *target_friend,
1129                                           struct GNUNET_PeerIdentity *trail_peer_list,
1130                                           unsigned int trail_length,
1131                                           unsigned int current_trail_index)
1132 {
1133   struct PeerNotifyNewSuccessorMessage *nsm;
1134   struct P2PPendingMessage *pending;
1135   struct GNUNET_PeerIdentity *peer_list;
1136   size_t msize;
1137   
1138   msize = sizeof (struct PeerNotifyNewSuccessorMessage) + 
1139           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1140   
1141   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1142   {
1143     GNUNET_break (0);
1144     return;
1145   }
1146   
1147   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1148   {  
1149     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1150                                 1, GNUNET_NO);
1151   }
1152   
1153   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1154   pending->importance = 0;    /* FIXME */
1155   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1156   nsm = (struct PeerNotifyNewSuccessorMessage *) &pending[1];
1157   pending->msg = &nsm->header;
1158   nsm->header.size = htons (msize);
1159   nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR);
1160   memcpy (&(nsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1161   memcpy (&(nsm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1162   nsm->trail_length = htonl (trail_length);
1163   nsm->current_index = htonl (current_trail_index);
1164   
1165   peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
1166   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1167   
1168    /* Send the message to chosen friend. */
1169   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1170   target_friend->pending_count++;
1171   process_friend_queue (target_friend);
1172 }
1173
1174
1175 /** 
1176  * FIXME: Optimizaiton Once the basic code is running. Add the optimization
1177  * where you check if the threshold on number of links that should go through
1178  * a particular friend has crossed. If yes then again choose a different
1179  * friend. Important that the new friend chosen should be different. How to 
1180  * ensure this? This is an important optimization as without this one x-vine
1181  * is actually not a sybil tolerant DHT.
1182  * Randomly choose one of your friends from the friends_peer map
1183  * @return Friend
1184  */
1185 static struct FriendInfo *
1186 select_random_friend (struct GNUNET_PeerIdentity *congested_peer)
1187 {  
1188   unsigned int current_size;
1189   unsigned int *index; 
1190   unsigned int j = 0;
1191   struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1192   struct GNUNET_PeerIdentity key_ret;
1193   struct FriendInfo *friend;
1194   
1195   current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
1196   index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1197   iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1198  
1199   while(j < (*index))
1200   {
1201     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
1202     {
1203       j++;
1204     }
1205     else 
1206       return NULL;
1207   }  
1208
1209   if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1210   {
1211     /* TODO: Here you have chosen a random friend. Now you should check the size
1212      of its routing table size, and if its more than threshold, then check which
1213      of the entries has trail length greater than trail length threshold. we
1214      should without checking the routing table size also we should check the
1215      trail with trail length greater than threshold. then 
1216      you should try to find a new route through this new node that has joined in
1217      only for those finger entries whose trail length is greater than threshold. 
1218      But I don't want the new node to wait for this process to get over. so
1219      should i declare a function which will be called after some interval.*/
1220     return friend;
1221   }
1222   else
1223     return NULL;
1224 }
1225
1226
1227 /**
1228  * Compute finger_identity to which we want to setup the trail
1229  * @return finger_identity 
1230  */
1231 static uint64_t *
1232 compute_finger_identity()
1233 {
1234   uint64_t my_id64 ;
1235   uint64_t *finger_identity64;
1236   
1237   finger_identity64 = GNUNET_malloc (sizeof (uint64_t));
1238   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1239   /*FIXME: Do we need a mod finger = ((my_id + pow(2, finger_index)) mod (pow (2, MAX_FINGERS))*/
1240   *finger_identity64 = (my_id64 + (unsigned long) pow (2,current_finger_index));
1241   
1242   return finger_identity64;
1243 }
1244
1245
1246 /**
1247  * Compute immediate predecessor identity in the network.
1248  * @return peer identity of immediate predecessor.
1249  */
1250 static uint64_t *
1251 compute_predecessor_identity()
1252 {
1253   uint64_t my_id ;
1254   uint64_t *predecessor;
1255
1256   predecessor = GNUNET_malloc (sizeof (uint64_t));
1257   memcpy (&my_id, &my_identity, sizeof (uint64_t));
1258   /* FIXME: Do we need to use mod pow(2, MAX_FINGERS) here? */
1259   *predecessor = (my_id -1);
1260           
1261   return predecessor;
1262 }
1263
1264
1265 /**
1266  * Periodically ping your successor to ask its current predecessor
1267  * 
1268  * @param cls closure for this task
1269  * @param tc the context under which the task is running
1270  */
1271 static void
1272 send_verify_successor_message (void *cls,
1273                                const struct GNUNET_SCHEDULER_TaskContext *tc )
1274 {
1275   struct GNUNET_TIME_Relative next_send_time;
1276   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1277   struct GNUNET_PeerIdentity key_ret;
1278   struct FriendInfo *target_friend;
1279   struct GNUNET_PeerIdentity *next_hop;
1280   struct GNUNET_PeerIdentity *peer_list;
1281   unsigned int finger_trail_current_index;
1282   struct FingerInfo *finger;
1283   unsigned int finger_index;
1284   unsigned int i;
1285   int flag = 0;
1286   
1287   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
1288   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1289   {
1290     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1291                                                                  (const void **)&finger)) 
1292     {
1293       if (0 == finger->finger_map_index)
1294       {
1295         flag = 1;
1296         break;
1297       }
1298     }
1299   }
1300   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1301   
1302   if( flag == 0)
1303     goto send_new_request;
1304   
1305   peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->trail_length);
1306  
1307   struct TrailPeerList *iterate;
1308   iterate = finger->head;
1309   i = 0;
1310   while ( i < (finger->trail_length))
1311   {
1312     memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity));
1313     iterate = iterate->next;
1314     i++;
1315   }
1316  
1317   next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1318   memcpy (next_hop, &peer_list[0], sizeof (struct GNUNET_PeerIdentity));
1319   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1320   finger_trail_current_index = 0; 
1321   
1322   
1323   GDS_NEIGHBOURS_send_verify_successor (&my_identity,
1324                                         &(finger->finger_identity),
1325                                         target_friend,
1326                                         peer_list,
1327                                         finger->trail_length,
1328                                         finger_trail_current_index);
1329   
1330   
1331   /* FIXME: Use a random value so that this message is send not at the same
1332    interval as send_find_finger_trail_message. */
1333   send_new_request:
1334   next_send_time.rel_value_us =
1335       DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1336       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1337                                 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us /
1338                                 (current_finger_index + 50));
1339  
1340   verify_successor =
1341       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_verify_successor_message,
1342                                     NULL);
1343 }
1344
1345
1346 /**
1347  * Task to send a find finger trail message. We attempt to find trail
1348  * to our fingers, successor and predecessor in the network.
1349  *
1350  * @param cls closure for this task
1351  * @param tc the context under which the task is running
1352  */
1353 static void
1354 send_find_finger_trail_message (void *cls,
1355                                 const struct GNUNET_SCHEDULER_TaskContext *tc)
1356 {
1357   struct FriendInfo *target_friend;
1358   struct GNUNET_TIME_Relative next_send_time;
1359   uint64_t *finger_identity;
1360   unsigned int finger_map_index;
1361   
1362   if (1 == current_finger_index)
1363   {
1364     finger_identity = compute_predecessor_identity();  
1365     goto select_friend;
1366   }
1367   else
1368   {
1369     finger_identity = compute_finger_identity();
1370   }
1371   
1372   select_friend:
1373   target_friend = select_random_friend (NULL);
1374   
1375   finger_map_index = current_finger_index;
1376   current_finger_index = ( current_finger_index + 1) % MAX_FINGERS;
1377   
1378   if(NULL != target_friend)
1379   { 
1380     /* FIXME: Here I am passing NULL for current source, is it correct? 
1381      also, we set the current source only if current_destination_type
1382      is finger. */
1383     GDS_NEIGHBOURS_send_trail_setup (&my_identity, *finger_identity, &(target_friend->id),
1384                                      NULL, target_friend, 0, NULL, finger_map_index, FRIEND);
1385   }
1386   
1387   /* FIXME: How to decide the correct interval? */
1388   next_send_time.rel_value_us =
1389       DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1390       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1391                                 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us /
1392                                 (current_finger_index + 10));
1393  
1394   find_finger_trail_task =
1395       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1396                                     NULL);
1397 }
1398
1399
1400 /**
1401  * Method called whenever a peer connects.
1402  *
1403  * @param cls closure
1404  * @param peer_identity peer identity this notification is about
1405  */
1406 static void
1407 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
1408 {
1409   struct FriendInfo *friend;
1410
1411   /* Check for connect to self message */
1412   if (0 == memcmp (&my_identity, peer_identity, sizeof (struct GNUNET_PeerIdentity)))
1413     return;
1414   
1415   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to %s\n", GNUNET_i2s (peer_identity));
1416   
1417   /* If peer already exists in our friend_peermap, then exit. */
1418   if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap, peer_identity))
1419   {
1420     GNUNET_break (0);
1421     return;
1422   }
1423
1424   GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
1425                             GNUNET_NO);
1426
1427   friend = GNUNET_new (struct FriendInfo);
1428   friend->id = *peer_identity;
1429   
1430   GNUNET_assert (GNUNET_OK ==
1431                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
1432                                                     peer_identity, friend,
1433                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1434
1435   /* got a first connection, good time to start with FIND FINGER TRAIL requests... */
1436   if (1 == GNUNET_CONTAINER_multipeermap_size (friend_peermap))
1437     find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
1438 }
1439
1440
1441 /**
1442  * Method called whenever a peer disconnects.
1443  *
1444  * @param cls closure
1445  * @param peer peer identity this notification is about
1446  */
1447 static void
1448 handle_core_disconnect (void *cls,
1449                         const struct GNUNET_PeerIdentity *peer)
1450 {
1451   struct FriendInfo *remove_friend;
1452   struct FingerInfo *remove_finger;
1453   struct GNUNET_PeerIdentity key_ret;
1454   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1455   struct TrailPeerList *iterator;
1456   struct GNUNET_PeerIdentity *finger_identity;
1457   int finger_index;
1458   
1459   /* Check for self message. */
1460   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
1461     return;
1462   
1463    /* Search for peer to remove in your friend_peermap. */
1464   remove_friend =
1465       GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
1466   
1467   if (NULL == remove_friend)
1468   {
1469     GNUNET_break (0);
1470     return;
1471   }
1472   
1473   iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
1474   finger_identity = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1475   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
1476   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1477   {
1478     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1479                                                                  (const void **)&remove_finger)) 
1480     {
1481       iterator = remove_finger->head->next;
1482       if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(iterator->peer), &(remove_friend->id)))
1483       {
1484         memcpy (finger_identity, &(remove_finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
1485         GNUNET_assert (GNUNET_YES ==
1486                        GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
1487                                                              finger_identity,
1488                                                              remove_finger));
1489       }
1490     }
1491   }
1492   
1493   /* Remove the friend from friend_peermap. */
1494   GNUNET_assert (GNUNET_YES ==
1495                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
1496                                                        peer,
1497                                                        remove_friend));
1498 }
1499
1500
1501 /**
1502  * To be called on core init/fail.
1503  *
1504  * @param cls service closure
1505  * @param identity the public identity of this peer
1506  */
1507 static void
1508 core_init (void *cls,
1509            const struct GNUNET_PeerIdentity *identity)
1510 {
1511   my_identity = *identity;
1512   
1513   /* SUPU TEST CODE */
1514   struct GNUNET_PeerIdentity *print_peer;
1515   print_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1516   memcpy (print_peer, &my_identity, sizeof (struct GNUNET_PeerIdentity));
1517   FPRINTF (stderr,_("\nSUPU %s, %s, %d,my_identity = %s"),
1518   __FILE__, __func__,__LINE__, GNUNET_i2s (print_peer));
1519   /* SUPU TEST CODE ENDS */
1520
1521 }
1522
1523
1524 /**
1525  * 
1526  * @param destination_peer
1527  * @param existing_trail
1528  * @param trail_length
1529  * @return 
1530  */
1531 static struct GNUNET_PeerIdentity *
1532 invert_trail_list (struct GNUNET_PeerIdentity *destination_peer,
1533                    struct GNUNET_PeerIdentity *existing_trail, 
1534                    unsigned int trail_length)
1535 {
1536   int i;
1537   int j;
1538   struct GNUNET_PeerIdentity *new_trail;
1539   
1540   j = 0;
1541   new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
1542   
1543   if (trail_length > 1)
1544   {
1545     i = trail_length - 2;
1546     while (i >= 0 )
1547     {
1548       memcpy( &new_trail[j], &existing_trail[i], sizeof (struct GNUNET_PeerIdentity));
1549       i--;
1550       j++;
1551     }
1552   }
1553   memcpy (&new_trail[j], destination_peer, sizeof(struct GNUNET_PeerIdentity));
1554  
1555   return new_trail;
1556 }
1557
1558
1559 /**
1560  * 
1561  * @param existing_finger
1562  * @param new_finger
1563  * @return 
1564  */
1565 static int
1566 compare_finger_identity (struct GNUNET_PeerIdentity *existing_finger,
1567                          struct GNUNET_PeerIdentity *new_finger)
1568 {
1569   int ret;
1570   ret = (existing_finger > new_finger) ? 1 : 
1571           (existing_finger == new_finger) ? 0 : -1;
1572   return ret;
1573 }
1574
1575
1576 /**
1577  * FIXME: Not sure of the logic to find the correct predecessor
1578  * I think logic of this code is wrong everything else seems to be correct. 
1579  * Given two finger identities, find the closest predecessor. 
1580  * @param existing_predecessor
1581  * @param new_predecessor
1582  * @return 
1583  */
1584 static int
1585 compare_predecessor(struct GNUNET_PeerIdentity *existing_predecessor,
1586                     struct GNUNET_PeerIdentity *new_predecessor)
1587 {
1588   int ret;
1589   ret = (existing_predecessor < new_predecessor) ? 1 : 
1590           (existing_predecessor == new_predecessor) ? 0 : -1;
1591   return ret;
1592 }
1593
1594
1595
1596 /*
1597  * Add an entry in finger table. 
1598  * @param finger_identity Peer identity of finger
1599  * @param finger_trail Trail to reach the finger
1600  * @param trail_length Number of peers in the trail. 
1601  * @param finger_map_index Index in finger peer map.
1602  */
1603 static
1604 void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1605                        struct GNUNET_PeerIdentity *finger_trail,
1606                        unsigned int trail_length,
1607                        unsigned int finger_map_index)
1608 {
1609   struct FingerInfo *new_finger_entry;
1610   struct GNUNET_PeerIdentity key_ret;
1611   int i;
1612   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1613   struct FingerInfo *existing_finger;
1614   int finger_index;
1615
1616   /* SUPU Here we trying to check if we already have an entry. If yes then we
1617    can keep two trails for redundant routing. if they are different then we
1618    need to choose the closest one. and remove the other one. */
1619   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 
1620
1621   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1622   {
1623     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1624                                                                  (const void **)&existing_finger)) 
1625     {
1626       if ((finger_map_index == existing_finger->finger_map_index))
1627       {
1628         if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),finger_identity))
1629         {
1630           FPRINTF (stderr,_("\nSUPU Entries are same. %s, %s, %d"),    __FILE__, __func__,__LINE__);
1631           /* FIXME: Here you should check if the trail is same. If yes then don't add the entry. it
1632            seems to be very suboptimal. */
1633           if ((existing_finger->trail_length) == trail_length)
1634           {
1635             struct TrailPeerList *iterate;
1636             iterate = existing_finger->head;
1637             int k;
1638             k = 0;
1639             while (k < trail_length)
1640             {
1641               if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(iterate->peer), &finger_trail[k]))
1642               {
1643                 k++;
1644                 iterate = iterate->next;
1645               }
1646             }
1647             if (k == trail_length)
1648               return;
1649             else
1650               goto add_new_entry;
1651           }
1652           goto add_new_entry;
1653         }
1654         else
1655         {
1656           int ret;
1657           if (finger_map_index == 1)
1658           {
1659             FPRINTF (stderr,_("\nSUPUP Predecessor are different %s, %s, %d"),    __FILE__, __func__,__LINE__);
1660             ret = compare_predecessor (&(existing_finger->finger_identity),
1661                                        finger_identity);
1662             goto add_new_entry;
1663           }
1664           else
1665           {
1666             FPRINTF (stderr,_("\nSUPU %s, %s, %d"),    __FILE__, __func__,__LINE__);
1667             ret = compare_finger_identity (&(existing_finger->finger_identity),
1668                                           finger_identity);
1669           }
1670           if (ret > 0)
1671           {
1672             FPRINTF (stderr,_("\nSUPU Adding the new one and removing the old one %s, %s, %d"),    __FILE__, __func__,__LINE__);
1673             GNUNET_assert (GNUNET_YES ==
1674                        GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
1675                                                              &(existing_finger->finger_identity),
1676                                                              existing_finger));
1677             goto add_new_entry;
1678           }
1679           else
1680           {
1681             FPRINTF (stderr,_("\nSUPU Nothing to do return %s, %s, %d"),    __FILE__, __func__,__LINE__);
1682             return;
1683           }
1684         }
1685       }
1686     }
1687   }
1688
1689   add_new_entry:
1690   new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
1691   memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity));
1692   new_finger_entry->finger_map_index = finger_map_index;
1693   
1694   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity))
1695   {
1696     /* I am the finger */
1697     new_finger_entry->trail_length = 0;
1698   }
1699   else
1700   {
1701     i = 0;
1702     while (i < trail_length)
1703     {
1704       struct TrailPeerList *element;
1705       element = GNUNET_malloc (sizeof (struct TrailPeerList));
1706       element->next = NULL;
1707       element->prev = NULL;
1708     
1709       memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity));
1710       GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->head, new_finger_entry->tail, element);
1711       i++;
1712     }
1713     new_finger_entry->trail_length = trail_length;
1714   }
1715   
1716   /* FIXME: Here we are keeping multiple hashmap option so that there are
1717    multiple routes to reach to same finger, redundant routing.
1718    * Also same peers could be our fingers for different finger map index
1719    * Should we handle the case where we have same fingers at the different
1720    * finger index but with different trail to reach.  */
1721   GNUNET_assert (GNUNET_OK ==
1722                  GNUNET_CONTAINER_multipeermap_put (finger_peermap,
1723                                                     &(new_finger_entry->finger_identity),
1724                                                     new_finger_entry,
1725                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); /* Fixme: change to multiple */
1726   /* SUPU TEST CODE */
1727   /* Here I want to iterate over finger peer map, print its id and the trail
1728    to reach to the finger. */
1729   int test_index;
1730   struct GNUNET_CONTAINER_MultiPeerMapIterator *test_iter;
1731   struct FingerInfo *test_finger;
1732   test_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 
1733   FPRINTF (stderr,_("\nSUPU #### %s, %s, %d, size = %d####"),__FILE__, __func__,__LINE__,GNUNET_CONTAINER_multipeermap_size (finger_peermap));
1734   for (test_index = 0; test_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); test_index++)
1735   {
1736     FPRINTF (stderr,_("\nSUPU *********%s, %s, %d, %d entry*********"),__FILE__, __func__,__LINE__,test_index);
1737     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (test_iter, &key_ret,
1738                                                                  (const void **)&test_finger)) 
1739     {
1740       FPRINTF (stderr,_("\nSUPU %s, %s, %d "),__FILE__, __func__,__LINE__);
1741       struct GNUNET_PeerIdentity *print_peer;
1742       struct TrailPeerList *iterator;
1743       int z;
1744       iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
1745       print_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1746       memcpy (print_peer, &(test_finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
1747       FPRINTF (stderr,_("\nSUPU %s, %s, %d, finger_index = %d"),    __FILE__, __func__,__LINE__,test_finger->finger_map_index);
1748       FPRINTF (stderr,_("\nSUPU %s, %s, %d, finger_identity = %s"),  
1749               __FILE__, __func__,__LINE__, GNUNET_i2s (print_peer));
1750       iterator = test_finger->head;
1751       z = 0;
1752       while (z < test_finger->trail_length)
1753       {
1754         memcpy (print_peer, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
1755         FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail[%d] = %s"),__FILE__, __func__,__LINE__,z,GNUNET_i2s (print_peer));
1756         z++;
1757         iterator = iterator->next;
1758       }
1759     }
1760   }
1761   FPRINTF (stderr,_("\nSUPU End of loop%s, %s, %d"),__FILE__, __func__,__LINE__);
1762   /* SUPU TEST CODE ENDS */
1763
1764   
1765   if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap)
1766       && (new_finger_entry->finger_map_index!= 1))
1767   {
1768     verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL);
1769   }
1770 }
1771   
1772
1773 /**
1774  * Compare two peer identities.
1775  * @param p1 Peer identity
1776  * @param p2 Peer identity
1777  * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2. 
1778  */
1779   static int
1780 compare_peer_id (const void *p1, const void *p2)
1781 {
1782   struct Sorting_List *p11;
1783   struct Sorting_List *p22;
1784   int ret;
1785   p11 = GNUNET_malloc (sizeof (struct Sorting_List));
1786   p22 = GNUNET_malloc (sizeof (struct Sorting_List));
1787   p11 = (struct Sorting_List *)p1;
1788   p22 = (struct Sorting_List *)p2;
1789   ret = ( (p11->peer_id) > (p22->peer_id) ) ? 1 : 
1790           ( (p11->peer_id) == (p22->peer_id) ) ? 0 : -1;
1791   return ret;
1792 }
1793
1794   
1795 /**
1796  * Return the successor of value in all_known_peers.
1797  * @param all_known_peers list of all the peers
1798  * @param value value we have to search in the all_known_peers.
1799  * @return 
1800  */
1801 static struct Sorting_List *
1802 find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value,
1803                        unsigned int size)
1804 {
1805   int first;
1806   int last;
1807   int middle;
1808   
1809   first = 0;
1810   last = size - 1;
1811   middle = (first + last)/2;
1812   
1813   while(first <= last)
1814   {
1815     if(all_known_peers[middle].peer_id < value)
1816     {
1817       first = middle + 1; 
1818     }
1819     else if(all_known_peers[middle].peer_id == value)
1820     {
1821       if(middle == (size -1))
1822       {
1823         return &all_known_peers[0];
1824       }
1825       else
1826       {
1827         return &all_known_peers[middle+1];
1828       }
1829     }
1830     else
1831     {
1832        last = middle - 1;
1833     }
1834   
1835     middle = (first + last)/2;  
1836   }
1837   return NULL;
1838 }
1839
1840
1841 /**
1842  * Find closest successor for the value.
1843  * @param value Value for which we are looking for successor
1844  * @param current_destination NULL if my_identity is successor else finger/friend 
1845  *                            identity 
1846  * @param type Next destination type
1847  * @return Peer identity of next destination i.e. successor of value. 
1848  */
1849 static struct GNUNET_PeerIdentity *
1850 find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1851                enum current_destination_type *type)
1852 {
1853   struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
1854   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1855   struct GNUNET_PeerIdentity key_ret;
1856   struct FriendInfo *friend;
1857   struct FingerInfo *finger;
1858   unsigned int finger_index;
1859   unsigned int friend_index;
1860   struct Sorting_List *successor;
1861   unsigned int size;
1862   int j;
1863   
1864   /* 2 is added in size for my_identity and value which will part of all_known_peers. */
1865   size = GNUNET_CONTAINER_multipeermap_size (friend_peermap)+
1866          GNUNET_CONTAINER_multipeermap_size (finger_peermap)+
1867          2;
1868   
1869   struct Sorting_List all_known_peers[size];
1870   
1871   int k;
1872   for (k = 0; k < size; k++)
1873     all_known_peers[k].peer_id = 0;
1874   
1875   /* Copy your identity at 0th index in all_known_peers. */
1876   j = 0;
1877   memcpy (&(all_known_peers[j].peer_id), &my_identity, sizeof (uint64_t));
1878   all_known_peers[j].type = MY_ID;
1879   all_known_peers[j].data = 0;
1880   j++;
1881   
1882   /* Copy value */
1883   all_known_peers[j].peer_id = value;
1884   all_known_peers[j].type = VALUE;
1885   all_known_peers[j].data = 0;
1886   j++;
1887   
1888   /* Iterate over friend peer map and copy all the elements into array. */
1889   friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); 
1890   for (friend_index = 0; friend_index < GNUNET_CONTAINER_multipeermap_size (friend_peermap); friend_index++)
1891   {
1892     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(friend_iter,&key_ret,(const void **)&friend)) 
1893     {
1894       memcpy (&(all_known_peers[j].peer_id), &(friend->id), sizeof (uint64_t));
1895       all_known_peers[j].type = FRIEND;
1896       all_known_peers[j].data = friend;
1897       j++;
1898     }
1899   }
1900   
1901   /* Iterate over finger map and copy all the entries into all_known_peers array. */
1902   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
1903   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1904   {
1905     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(finger_iter,&key_ret,(const void **)&finger)) 
1906     {
1907       memcpy (&(all_known_peers[j].peer_id), &(finger->finger_identity), sizeof (uint64_t));
1908       all_known_peers[j].type = FINGER;
1909       all_known_peers[j].data = finger;
1910       j++;
1911     }
1912   }
1913   
1914   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1915   GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter);   
1916   
1917   qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id);
1918   
1919   /* search value in all_known_peers array. */
1920   successor = find_closest_successor (all_known_peers, value, size);
1921   
1922   if (successor->type == MY_ID)
1923   {
1924     *type = MY_ID;
1925     return NULL;
1926   }
1927   else if (successor->type == FRIEND)
1928   {
1929     *type = FRIEND;
1930     struct FriendInfo *target_friend;
1931     target_friend = (struct FriendInfo *)successor->data;
1932     memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
1933     return current_destination;
1934   }
1935   else if (successor->type == FINGER)
1936   {
1937     *type = FINGER;
1938     struct GNUNET_PeerIdentity *next_hop;
1939     struct FingerInfo *finger;
1940     struct TrailPeerList *iterator;
1941     iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
1942     finger = successor->data;
1943     iterator = finger->head;
1944     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1945     memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
1946     memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
1947     return next_hop;
1948   }
1949   else
1950   {
1951    type = NULL;
1952    return NULL;
1953   }
1954 }
1955
1956
1957 /**
1958  * Send a get message to selected target friend. If target friend in NULL,
1959  * then search for a target friend. 
1960  * @param block_type type of the block
1961  * @param options routing options
1962  * @param desired_replication_level desired replication count
1963  * @param hop_count how many hops did this request traverse so far?
1964  * @param get_peer_path Peer list to reach to final destination which contains the data.
1965  * @param get_path_length Total numbers of peer in get_path
1966  * @param key Key key for the content
1967  * @param target_peer Next peer to forward the message to.
1968  * @param current_destination Peer which will get this message. 
1969  * @param current_dest_type Type of current destination can be either FRIEND or FINGER
1970  */
1971 void
1972 GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type block_type,
1973                            enum GNUNET_DHT_RouteOption options,
1974                            uint32_t desired_replication_level,
1975                            uint32_t hop_count,
1976                            struct GNUNET_PeerIdentity *get_peer_path,
1977                            unsigned int get_path_length,
1978                            struct GNUNET_HashCode *key,
1979                            struct GNUNET_PeerIdentity *target_peer,
1980                            struct GNUNET_PeerIdentity *current_destination,
1981                            struct GNUNET_PeerIdentity *current_source,
1982                            enum current_destination_type *current_dest_type)
1983 {
1984   struct PeerGetMessage *get_request;
1985   struct P2PPendingMessage *pending;
1986   struct GNUNET_PeerIdentity *get_path;
1987   struct FriendInfo *target_friend;
1988   uint64_t key_value;
1989   size_t msize;
1990   
1991   msize = sizeof (struct PeerGetMessage) + 
1992           (get_path_length * sizeof (struct GNUNET_PeerIdentity));
1993   
1994   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1995   {
1996     GNUNET_break (0);
1997     return;
1998   }
1999   
2000   memcpy (&key_value, key, sizeof (uint64_t));
2001   
2002   /* FIXME: Is this correct comparison? */
2003   if (NULL == target_peer)
2004   {
2005     /* We have received the request from the client file and we don't know
2006      to which peer should we forward the message to. */
2007     struct GNUNET_PeerIdentity *next_hop;  
2008     next_hop = find_successor (key_value, current_destination, current_dest_type);
2009     
2010     if (*current_dest_type == MY_ID)
2011     {
2012       get_path = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2013       memcpy (get_path, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2014       get_path_length = 1;
2015       /* FIXME: At the moment I am just passing null,0 for values which I don't
2016        have. Also, handle return type. Modify this function and pass get path
2017        and get path length and then in datacache_handle. here in this case
2018        you can diretly call gds_client_handle_reply. */
2019 #if 0
2020       GDS_DATACACHE_handle_get (&(get_request->key),(get_request->block_type), 
2021                                 get_path, get_path_length,get_path_length - 1,NULL);
2022 #endif
2023       return;
2024     }
2025     else 
2026     {
2027       if (*current_dest_type == FINGER)
2028       {
2029         memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2030       }
2031       
2032       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2033     }
2034   }
2035   else
2036     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, target_peer);
2037   
2038   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2039   pending->importance = 0;    /* FIXME */
2040   get_request = (struct PeerGetMessage *) &pending[1];
2041   pending->msg = &get_request->header;
2042   get_request->header.size = htons (msize);
2043   get_request->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET);
2044   get_request->get_path_length = htonl (get_path_length);
2045   get_request->key = *key;
2046   memcpy (&(get_request->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
2047   /* FIXME: Is this comparison correct? */
2048   if (current_source != NULL)
2049     memcpy (&(get_request->current_source), current_source, sizeof (struct GNUNET_PeerIdentity));
2050   get_request->current_dest_type = htonl (*current_dest_type);
2051   get_path = (struct GNUNET_PeerIdentity *) &get_request[1];
2052   memcpy (get_path, get_peer_path, get_path_length * sizeof (struct GNUNET_PeerIdentity));
2053   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2054   target_friend->pending_count++;
2055   process_friend_queue (target_friend);
2056   
2057 }
2058
2059
2060 /**
2061  * FIXME: Here you should update the fields of struct PeerGetResultMessage.
2062  * At the end of this message you should add the data and get path and send 
2063  * to the original requesting client. and there you should call GDS_CLIENT_handle_reply
2064  * with correct parameter. 
2065  * @param expiration
2066  * @param key
2067  * @param get_path_length
2068  * @param get_path
2069  * @param put_path_length
2070  * @param put_path
2071  * @param type
2072  * @param data_size
2073  * @param data
2074  */
2075 void 
2076 GDS_NEIGHBOURS_datacache_get (struct GNUNET_TIME_Absolute expiration,
2077                               const struct GNUNET_HashCode *key,
2078                               unsigned int get_path_length,
2079                               const struct GNUNET_PeerIdentity *get_path,
2080                               unsigned int put_path_length,
2081                               const struct GNUNET_PeerIdentity *put_path,
2082                               enum GNUNET_BLOCK_Type type, size_t data_size,
2083                               const void *data)
2084 {
2085   /* Here you don't have the get path and get path length. you should call
2086    some function get those values and update the message and send them. */
2087 }
2088
2089
2090 /** 
2091  * TODO: In case of put, you add the peer in the peer list in handle_dht_p2p_put.
2092  * Verify that the addition is correct and we are adding peers correctly and incrementing
2093  * the trail length correctly. 
2094  * Handle a put request from client file. If I am the final destination,
2095  * do a put else forward the message to next peer.
2096  * @param block_type type of the block
2097  * @param options routing options
2098  * @param desired_replication_level desired replication count, 0 for current
2099  *        implementation of X-Vine.
2100  * @param expiration_time when does the content expire
2101  * @param hop_count how many hops has this message traversed so far
2102  * @param key key for the content
2103  * @param put_path_length number of entries in @a put_path
2104  * @param put_path peers this request has traversed so far (if tracked)
2105  * @param data payload to store
2106  * @param data_size number of bytes in @a data
2107  * @param current_destination intermediate destination of the packet.
2108  * @param current_source source for which @a current_destination is destination.
2109  * @param dest_type type of @a current_destination.
2110  * @param target_peer_id Next peer to forward the message to.
2111  */
2112 void
2113 GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type block_type,
2114                            enum GNUNET_DHT_RouteOption options,
2115                            uint32_t desired_replication_level,
2116                            struct GNUNET_TIME_Absolute expiration_time,
2117                            uint32_t hop_count,
2118                            const struct GNUNET_HashCode *key,
2119                            unsigned int put_path_length,
2120                            struct GNUNET_PeerIdentity *put_path,
2121                            const void *data, size_t data_size,
2122                            struct GNUNET_PeerIdentity *current_destination,
2123                            struct GNUNET_PeerIdentity *current_source,
2124                            enum current_destination_type dest_type,
2125                            struct GNUNET_PeerIdentity *target_peer)
2126 {
2127   struct PeerPutMessage *ppm;
2128   struct P2PPendingMessage *pending;
2129   struct FriendInfo *target_friend;
2130   struct GNUNET_PeerIdentity *pp;
2131   size_t msize;
2132   uint64_t key_value;
2133   
2134   msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
2135           sizeof (struct PeerPutMessage);
2136   
2137   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2138   {
2139     put_path_length = 0;
2140     msize = data_size + sizeof (struct PeerPutMessage);
2141   }
2142   
2143   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2144   {
2145     GNUNET_break (0);
2146     return;
2147   }
2148   
2149   memcpy (&key_value, key, sizeof (uint64_t)); 
2150   struct GNUNET_PeerIdentity *current_dest;
2151   current_dest = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2152   if (target_peer == NULL)
2153   {
2154      /* This is the first time the call has been made from handle_dht_local_put.
2155      So, you need to search for the next peer to send this message to. */
2156     struct GNUNET_PeerIdentity *next_hop;  
2157    
2158     next_hop = find_successor (key_value, current_dest, &dest_type);  
2159     if (dest_type == MY_ID)
2160     {
2161       /* FIXME: Choose one place to do datacache_put. I am doing put only if its
2162          destination so I will do no put operation
2163        in the client file.*/
2164       GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path,
2165                                 block_type, data_size, data);
2166       return;
2167     }
2168     else
2169     {
2170       /* Find the friend corresponding to next_hop */
2171       if (dest_type == FINGER)
2172       {
2173         memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2174       }
2175       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2176     }
2177   }
2178   else
2179     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, target_peer);
2180   
2181   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2182   pending->importance = 0;    /* FIXME */
2183   pending->timeout = expiration_time;
2184   ppm = (struct PeerPutMessage *) &pending[1];
2185   pending->msg = &ppm->header;
2186   ppm->header.size = htons (msize);
2187   ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
2188   ppm->options = htonl (options);
2189   ppm->block_type = htonl (block_type);
2190   ppm->hop_count = htonl (hop_count + 1);
2191   ppm->desired_replication_level = htonl (desired_replication_level);
2192   ppm->put_path_length = htonl (put_path_length);
2193   ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
2194   /* FIXME: Here I am checking if we have a value in current_source then only copy.
2195    I am not sure if this checking is correct or not. */
2196   if (current_source != NULL)
2197     memcpy (&(ppm->current_source), current_source, sizeof (struct GNUNET_PeerIdentity));
2198   
2199   /* FIXME: here current_destination is the parameter, current_dest is what you
2200    get when you call find_successor. names don't do justice to the function.
2201    Please change it*/
2202   if (current_destination != NULL)
2203     memcpy (&(ppm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
2204   else
2205     memcpy (&(ppm->current_destination), current_dest, sizeof (struct GNUNET_PeerIdentity));
2206   ppm->current_destination_type = htonl (dest_type);
2207   ppm->key = *key;
2208   
2209   pp = (struct GNUNET_PeerIdentity *) &ppm[1];
2210   /* FIXME: Is this comparison correct? Do we need this comparison. What happens
2211    in the case put_path_length is 0 and put_path is NULL, then at run time
2212    memcpy will fail. And I am not sure if comparing NULL is correct or not. */
2213   if (put_path_length != 0)
2214   {
2215     memcpy (pp, put_path,
2216             sizeof (struct GNUNET_PeerIdentity) * put_path_length);
2217   }
2218   memcpy (&pp[put_path_length], data, data_size);
2219   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2220   target_friend->pending_count++;
2221   process_friend_queue (target_friend);
2222 }
2223
2224
2225 /**
2226  * FIXME: I am removing source peer as the first element in the trail
2227  * is source identity.
2228  * If I am adding myself when I am source then I don't need destination 
2229  * peer in get but if I am not adding then I need it. At the moment I am removing
2230  * it but will check later if its wrong. 
2231  * Send get result back to requesting client. 
2232  * @param expiration when will the reply expire
2233  * @param key the query this reply is for
2234  * @param get_path_length number of peers in @a get_path
2235  * @param get_path path the reply took on get
2236  * @param put_path_length number of peers in @a put_path
2237  * @param put_path path the reply took on put
2238  * @param type type of the reply
2239  * @param data_size number of bytes in @a data
2240  * @param data application payload data
2241  * @param get_path
2242  * @param get_path_length
2243  */
2244 void 
2245 GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration,
2246                                 const struct GNUNET_HashCode *key,
2247                                 unsigned int put_path_length,
2248                                 const struct GNUNET_PeerIdentity *put_path,
2249                                 enum GNUNET_BLOCK_Type type, size_t data_size,
2250                                 const void *data,
2251                                 struct GNUNET_PeerIdentity *get_path,
2252                                 unsigned int get_path_length,
2253                                 unsigned int current_path_index,
2254                                 struct GNUNET_PeerIdentity *next_hop)
2255 {
2256   struct PeerGetResultMessage *get_result;
2257   struct GNUNET_PeerIdentity *get_result_path;
2258   struct P2PPendingMessage *pending;
2259   struct FriendInfo *target_friend;
2260   size_t msize;
2261   
2262   msize = get_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
2263           sizeof (struct PeerPutMessage);
2264  
2265   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2266   {
2267     GNUNET_break (0);
2268     return;
2269   }
2270   /* GET_REULT should have all the things which we want to pass in client_handle_reply
2271    put path put path length get path get length data data_size. and rest things
2272    are required to reach to the correct peer. */
2273   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2274   pending->importance = 0;    /* FIXME */
2275   /* FIXME: Should we add an expiration time like in put message. */
2276   get_result = (struct PeerGetResultMessage *)&pending[1];
2277   pending->msg = &get_result->header;
2278   get_result->header.size = htons (msize);
2279   get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT);
2280   get_result->current_path_index = current_path_index;
2281   get_result->key = *key;
2282   
2283   get_result_path = (struct GNUNET_PeerIdentity *)&get_result[1];
2284   memcpy (get_result_path, get_path,
2285            sizeof (struct GNUNET_PeerIdentity) * get_path_length);
2286   memcpy (&get_result_path[get_path_length], data, data_size);
2287   
2288   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2289   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2290   target_friend->pending_count++;
2291   process_friend_queue (target_friend);
2292 }
2293
2294
2295 /**
2296  * 
2297  * @param cls
2298  * @param peer
2299  * @param message
2300  * @return 
2301  */
2302 static int
2303 handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2304                            const struct GNUNET_MessageHeader *message)
2305 {
2306   /* If you are the source, go back to the client file and there search for
2307    the requesting client and send back the result. */
2308   struct PeerGetResultMessage *get_result;
2309   struct GNUNET_PeerIdentity *get_path;
2310   //void *payload;
2311   //size_t payload_size;
2312   size_t msize;
2313   unsigned int getlen;
2314   int current_path_index;
2315   
2316   msize = ntohs (message->size);
2317   if (msize < sizeof (struct PeerGetResultMessage))
2318   {
2319     GNUNET_break_op (0);
2320     return GNUNET_YES;
2321   }
2322   
2323   get_result = (struct PeerGetResultMessage *)message;
2324   getlen = ntohl (get_result->get_path_length);
2325   
2326   if ((msize <
2327        sizeof (struct PeerGetResultMessage) +
2328        getlen * sizeof (struct GNUNET_PeerIdentity)) ||
2329       (getlen >
2330        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2331   {
2332     GNUNET_break_op (0);
2333     return GNUNET_YES;
2334   }
2335   
2336   /* FIXME: Get the put_path */
2337   get_path = (struct GNUNET_PeerIdentity *) &get_result[1];
2338   //payload = &get_path[getlen];
2339   /* payload_size = msize - (sizeof (struct PeerGetResultMessage) + 
2340                           getlen * sizeof (struct GNUNET_PeerIdentity));*/
2341   current_path_index = ntohl (get_result->current_path_index);
2342   
2343   /* Here you just have to check if you are the destination or not if not 
2344    then read the next peer and send the message. */
2345   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(get_result->destination_peer))))
2346   {
2347     /* I am the destination. Call the function in client file.
2348      * FIXME: Here I don't know how I communicate the result back to client
2349        file.  */
2350     //GDS_CLIENTS_process_get_result();
2351     return GNUNET_YES;
2352   }
2353   else
2354   {
2355     /* Read the element from the get path at trail index. set the trail index 
2356      and call gds_neighbours_send_get_result.*/
2357     struct GNUNET_PeerIdentity *next_hop;
2358     
2359     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2360     memcpy (next_hop, &get_path[current_path_index], sizeof (struct GNUNET_PeerIdentity));
2361  
2362     
2363     if (current_path_index != 0)
2364       current_path_index--;
2365 #if 0
2366     GDS_NEIGHBOURS_send_get_result ((get_result->expiration), get_result->key,
2367                                      get_result->put_path_length, put_path,
2368                                      get_result->type, payload, payload_size
2369                                      get_path, getlen,current_path_index,
2370                                      next_hop);
2371 #endif
2372     return GNUNET_YES;
2373   }  
2374   return GNUNET_SYSERR;
2375 }
2376
2377
2378 /**
2379  * Core handler for p2p put requests.
2380  *
2381  * @param cls closure
2382  * @param peer sender of the request
2383  * @param message message
2384  * @param peer peer identity this notification is about
2385  * @return #GNUNET_OK to keep the connection open,
2386  *         #GNUNET_SYSERR to close it (signal serious error)
2387  */
2388 static int
2389 handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2390                     const struct GNUNET_MessageHeader *message)
2391 {
2392   struct PeerPutMessage *put;
2393   struct GNUNET_PeerIdentity *put_path;
2394   enum GNUNET_DHT_RouteOption options;
2395   enum current_destination_type current_dst_type;
2396   struct GNUNET_PeerIdentity *current_destination;
2397   struct GNUNET_PeerIdentity *next_hop;
2398   struct GNUNET_HashCode test_key;
2399   uint64_t key_value;
2400   void *payload;
2401   size_t payload_size;
2402   size_t msize;
2403   uint32_t putlen;
2404   
2405   put = (struct PeerPutMessage *) message;
2406   putlen = ntohl (put->put_path_length);
2407   msize = ntohs (message->size);
2408    
2409   if ((msize <
2410        sizeof (struct PeerPutMessage) +
2411        putlen * sizeof (struct GNUNET_PeerIdentity)) ||
2412       (putlen >
2413        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2414   {
2415     GNUNET_break_op (0);
2416     return GNUNET_YES;
2417   }
2418   
2419   put_path = (struct GNUNET_PeerIdentity *) &put[1];
2420   payload = &put_path[putlen];
2421   options = ntohl (put->options);
2422   payload_size = msize - (sizeof (struct PeerPutMessage) + 
2423                           putlen * sizeof (struct GNUNET_PeerIdentity));
2424   
2425   switch (GNUNET_BLOCK_get_key (GDS_block_context, ntohl (put->block_type),
2426                                 payload, payload_size, &test_key))
2427   {
2428     case GNUNET_YES:
2429       if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode)))
2430       {
2431         char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
2432         GNUNET_break_op (0);
2433         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2434                     "PUT with key `%s' for block with key %s\n",
2435                      put_s, GNUNET_h2s_full (&test_key));
2436         GNUNET_free (put_s);
2437         return GNUNET_YES;
2438       }
2439     break;
2440     case GNUNET_NO:
2441       GNUNET_break_op (0);
2442       return GNUNET_YES;
2443     case GNUNET_SYSERR:
2444       /* cannot verify, good luck */
2445       break;
2446   }
2447   
2448   if (ntohl (put->block_type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
2449   {
2450     switch (GNUNET_BLOCK_evaluate (GDS_block_context,
2451                                    ntohl (put->block_type),
2452                                    NULL,    /* query */
2453                                    NULL, 0, /* bloom filer */
2454                                    NULL, 0, /* xquery */
2455                                    payload, payload_size))
2456     {
2457     case GNUNET_BLOCK_EVALUATION_OK_MORE:
2458     case GNUNET_BLOCK_EVALUATION_OK_LAST:
2459       break;
2460
2461     case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
2462     case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
2463     case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
2464     case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
2465     case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
2466     case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
2467     default:
2468       GNUNET_break_op (0);
2469       return GNUNET_OK;
2470     }
2471   }
2472   
2473   struct GNUNET_PeerIdentity pp[putlen + 1];
2474
2475   /* extend 'put path' by sender */
2476   if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
2477   {
2478     memcpy (pp, put_path, putlen * sizeof (struct GNUNET_PeerIdentity));
2479     pp[putlen] = *peer;
2480     putlen++;
2481   }
2482   else
2483     putlen = 0;
2484   
2485    current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2486    memcpy (current_destination, &(put->current_destination), sizeof (struct GNUNET_PeerIdentity));
2487    current_dst_type = ntohl (put->current_destination_type);
2488    memcpy (&key_value, &(put->key), sizeof (uint64_t));
2489    
2490    if (current_dst_type == FRIEND)
2491    {
2492      next_hop = find_successor (key_value, current_destination, &current_dst_type);
2493    }
2494    else if (current_dst_type == FINGER)
2495    {
2496      if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, current_destination))
2497      {
2498        next_hop = find_successor (key_value, current_destination, &current_dst_type);
2499      } 
2500      else
2501      {
2502        next_hop = GDS_ROUTING_search (&(put->current_source), current_destination, peer);
2503        current_dst_type = FRIEND;
2504      }
2505    }
2506   
2507    if (current_dst_type == MY_ID) 
2508    {
2509      GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
2510                               &(put->key),putlen, pp, ntohl (put->block_type), 
2511                               payload_size, payload);
2512      return GNUNET_YES;
2513    }
2514    else
2515    {
2516      struct GNUNET_PeerIdentity *current_source;
2517      if (current_dst_type == FINGER)
2518      {
2519        current_source = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2520        memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2521      }
2522      else
2523        current_source = NULL;
2524      
2525      GDS_CLIENTS_process_put (options,
2526                               ntohl (put->block_type),
2527                               ntohl (put->hop_count),
2528                               ntohl (put->desired_replication_level),
2529                               putlen, pp,
2530                               GNUNET_TIME_absolute_ntoh (put->expiration_time),
2531                               &put->key,
2532                               payload,
2533                               payload_size);
2534     
2535      GDS_NEIGHBOURS_handle_put (ntohl (put->block_type),ntohl (put->options),
2536                                 ntohl (put->desired_replication_level),
2537                                 GNUNET_TIME_absolute_ntoh (put->expiration_time),
2538                                 ntohl (put->hop_count),&put->key, putlen,
2539                                 pp, payload, payload_size,
2540                                 current_destination, current_source,current_dst_type, next_hop);
2541      return GNUNET_YES;
2542    }
2543   return GNUNET_SYSERR;
2544 }
2545
2546
2547 /**
2548  * FIXME
2549  * 1. I don't do block evalute as it uses xquery and bf for evaluation.Is
2550  * it okay if I just pass NULL. I am anyways going to pass NULL in case of 
2551  * datacache_get? 
2552  * Core handler for p2p get requests.
2553  *
2554  * @param cls closure
2555  * @param peer sender of the request
2556  * @param message message
2557  * @return #GNUNET_OK to keep the connection open,
2558  *         #GNUNET_SYSERR to close it (signal serious error)
2559  */
2560 static int
2561 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2562                     const struct GNUNET_MessageHeader *message)
2563 {
2564   struct PeerGetMessage *get;
2565   struct GNUNET_PeerIdentity *current_destination;
2566   uint64_t key_value;
2567   enum current_destination_type current_dest_type;
2568   struct GNUNET_PeerIdentity *next_hop;
2569   struct GNUNET_PeerIdentity *get_path;
2570   enum GNUNET_BLOCK_Type block_type;
2571   enum GNUNET_DHT_RouteOption options;
2572   size_t msize;
2573   unsigned int get_length;
2574   
2575   msize = ntohs (message->size);
2576   if (msize < sizeof (struct PeerGetMessage))
2577   {
2578     GNUNET_break_op (0);
2579     return GNUNET_YES;
2580   }
2581   
2582   get = (struct PeerGetMessage *)message;
2583   get_length = ntohl (get->get_path_length);
2584   get_path = (struct GNUNET_PeerIdentity *)&get[1];
2585   
2586   if ((msize <
2587        sizeof (struct PeerGetMessage) +
2588        get_length * sizeof (struct GNUNET_PeerIdentity)) ||
2589        (get_length >
2590         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2591   {
2592     GNUNET_break_op (0);
2593     return GNUNET_YES; 
2594   }
2595   
2596   current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2597   memcpy (current_destination, &(get->current_destination), sizeof (struct GNUNET_PeerIdentity));
2598   memcpy (&key_value, &(get->key), sizeof (uint64_t));
2599   current_dest_type = ntohl (get->current_dest_type);
2600   block_type = ntohl (get->block_type);
2601   options = ntohl (get->options);
2602  
2603   if (current_dest_type == FRIEND)
2604   {
2605     next_hop = find_successor (key_value, current_destination, &current_dest_type);
2606   }
2607   else if (current_dest_type == FINGER)
2608   {
2609      if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, current_destination))
2610      {
2611        next_hop = find_successor (key_value, current_destination, &current_dest_type);
2612      } 
2613      else
2614      {
2615        next_hop = GDS_ROUTING_search (&(get->current_source), current_destination, peer);
2616        current_dest_type = FRIEND;
2617      }
2618   }
2619   
2620   /* Add sender to get path */
2621   struct GNUNET_PeerIdentity gp[get_length + 1];
2622   memcpy (gp, get_path, get_length * sizeof (struct GNUNET_PeerIdentity));
2623   gp[get_length + 1] = *peer;
2624   get_length = get_length + 1;
2625   
2626   if (current_dest_type == MY_ID)
2627   {
2628     struct GNUNET_PeerIdentity final_get_path[get_length+1];
2629     memcpy (final_get_path, get_path, get_length * sizeof (struct GNUNET_PeerIdentity));
2630     memcpy (final_get_path, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2631     get_length = get_length + 1;
2632     struct GNUNET_PeerIdentity *next_hop;
2633     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2634     /* FIXME: Check if we need to have a check on get length. */
2635     memcpy (next_hop, &final_get_path[get_length-2], sizeof (struct GNUNET_PeerIdentity));
2636 #if 0
2637     GDS_DATACACHE_handle_get (&(get->key),(get->block_type),
2638                              final_get_path, get_length,get_length - 1,next_hop);
2639 #endif
2640     return GNUNET_YES;
2641   }
2642   else
2643   {
2644     struct GNUNET_PeerIdentity *current_source;
2645     current_source = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2646     if (current_dest_type == FINGER)
2647     {
2648       memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2649     }
2650     else
2651       /* FIXME: Is this correct? */
2652     {
2653       /* how to handle the case when we don't have any value for current source.*/
2654     }
2655     
2656     GDS_NEIGHBOURS_handle_get (block_type, options, get->desired_replication_level,
2657                                get->hop_count, gp,
2658                                get_length, &(get->key),next_hop,
2659                                current_destination, &(get->current_source),&current_dest_type);
2660     
2661     return GNUNET_YES;
2662   }
2663   return GNUNET_SYSERR;
2664 }
2665
2666
2667
2668 /**
2669  * Send tral rejection message
2670  * @param source_peer Source peer which wants to set up the trail.
2671  * @param finger_identity Finger identity to which it want to setup the trail.
2672  * @param congested_peer Peer which has send trail rejection message
2673  * @param next_hop Peer to which this message should be forwarded.
2674  * @param finger_map_index
2675  * @param trail_peer_list
2676  * @param trail_length
2677  */
2678 void
2679 GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_peer,
2680                                             uint64_t finger_identity,
2681                                             struct GNUNET_PeerIdentity *congested_peer,
2682                                             const struct GNUNET_PeerIdentity *next_hop,
2683                                             unsigned int finger_map_index,
2684                                             struct GNUNET_PeerIdentity *trail_peer_list,
2685                                             unsigned int trail_length)
2686 {
2687   struct PeerTrailRejectionMessage *trail_rejection;
2688   struct GNUNET_PeerIdentity *trail_list;
2689   struct P2PPendingMessage *pending;
2690   struct FriendInfo *target_friend;
2691   size_t msize;
2692   
2693   msize =  sizeof (struct PeerTrailRejectionMessage);
2694   
2695   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
2696   pending->importance = 0;    /* FIXME */
2697   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
2698   trail_rejection = (struct PeerTrailRejectionMessage *) &pending[1]; 
2699   pending->msg = &trail_rejection->header;
2700   trail_rejection->header.size = htons (msize);
2701   trail_rejection->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
2702   memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2703   memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity));
2704   memcpy (&(trail_rejection->finger_identity), &finger_identity, sizeof (uint64_t));
2705   trail_rejection->finger_map_index = htonl(finger_map_index);
2706   trail_rejection->trail_length = htonl (trail_length);
2707   
2708   trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
2709   memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2710   
2711   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2712   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2713   target_friend->pending_count++;
2714   process_friend_queue (target_friend);
2715 }
2716
2717
2718 /** 
2719  * Handle a PeerTrailSetupMessage. 
2720  * @param cls closure
2721  * @param message message
2722  * @param peer peer identity this notification is about
2723  * @return GNUNET_OK on success, GNUNET_SYSERR on error
2724  */
2725 static int
2726 handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2727                            const struct GNUNET_MessageHeader *message)
2728 {
2729   struct PeerTrailSetupMessage *trail_setup; 
2730   struct GNUNET_PeerIdentity *next_hop; 
2731   struct FriendInfo *target_friend;
2732   struct GNUNET_PeerIdentity *current_destination;
2733   struct GNUNET_PeerIdentity *trail_peer_list;
2734   enum current_destination_type current_dest_type;
2735   struct GNUNET_PeerIdentity *next_peer;
2736   unsigned int trail_length;
2737   uint32_t current_trail_index;
2738   unsigned int finger_map_index;
2739   uint64_t destination_finger_value;
2740   size_t msize;
2741   
2742   msize = ntohs (message->size);
2743   if (msize < sizeof (struct PeerTrailSetupMessage))
2744   {
2745     GNUNET_break_op (0);
2746     return GNUNET_YES;
2747   }
2748   
2749   trail_setup = (struct PeerTrailSetupMessage *) message; 
2750   trail_length = ntohl (trail_setup->trail_length); 
2751   
2752   if ((msize < sizeof (struct PeerTrailSetupMessage) +
2753        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2754        (trail_length >
2755         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2756   {
2757     GNUNET_break_op (0);
2758     return GNUNET_YES; 
2759   }
2760   
2761   current_dest_type = ntohl (trail_setup->current_destination_type);
2762   finger_map_index = ntohl (trail_setup->finger_map_index);
2763   trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_setup[1];
2764   destination_finger_value = trail_setup->destination_finger;
2765   current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2766   memcpy (current_destination, &(trail_setup->current_destination), sizeof (struct GNUNET_PeerIdentity));
2767   
2768   /* TODO:
2769    each peer maintains a list of trail fail list. there it stores an entry with
2770    source, finger identity it was trying, hop which rejected. it again call
2771    select_random_friend but does not consider me. and starts trail setup 
2772    again. */
2773   if (GDS_ROUTING_size() > 1)
2774   {
2775     /* Setup the trail rejection message and send the message to peer. */
2776     /* FIXME: you need to pass the trail, trail length and finger map index. */
2777     GDS_NEIGHBOURS_send_trail_rejection_message (&(trail_setup->source_peer),
2778                                                  trail_setup->destination_finger,
2779                                                  &my_identity, peer, finger_map_index,
2780                                                  trail_peer_list, trail_length);
2781   }
2782   /* Find the next hop to send the packet to. */
2783   if (current_dest_type == FRIEND)
2784   {
2785     if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination),
2786                                                &my_identity)))
2787     {
2788       next_hop = find_successor (destination_finger_value, current_destination, &(current_dest_type));
2789     }
2790     else
2791       return GNUNET_SYSERR; 
2792   }
2793   else if (current_dest_type == FINGER)
2794   {
2795     if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination),
2796                                                &my_identity)))
2797     {
2798       next_hop = GDS_ROUTING_search (&(trail_setup->current_source),
2799                                      &(trail_setup->current_destination), peer);
2800       /* As an optimization, find the successor from the find successor and
2801        compare both the ids to find the closest peer. */
2802     } 
2803     else
2804     {
2805       next_hop = find_successor (destination_finger_value, current_destination, &(current_dest_type)); 
2806     }
2807   }
2808  
2809   /* Add yourself to the trail list and increment the trail length. */
2810   struct GNUNET_PeerIdentity *peer_list;
2811   peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length + 1));
2812   if ( trail_length > 0)
2813   {
2814     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2815   }
2816   memcpy (&peer_list[trail_length], &my_identity, sizeof (struct GNUNET_PeerIdentity));
2817   trail_length++;
2818   
2819   if (current_dest_type == MY_ID || 
2820      (0 == GNUNET_CRYPTO_cmp_peer_identity(next_hop, &(trail_setup->source_peer))))
2821   {
2822     struct GNUNET_PeerIdentity *source_peer;
2823     source_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2824     memcpy (source_peer, &(trail_setup->source_peer), sizeof (struct GNUNET_PeerIdentity));
2825     
2826     current_trail_index = trail_length - 1; 
2827     next_peer=  GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2828     if (current_trail_index == 0)
2829     {
2830       memcpy (next_peer, &(trail_setup->source_peer), sizeof (struct GNUNET_PeerIdentity));
2831     }
2832     else
2833     {
2834       memcpy (next_peer, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity));
2835     }
2836      
2837     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer);
2838     GNUNET_free (next_peer);
2839     
2840     if (0 == trail_setup->finger_map_index)
2841     {
2842       struct GNUNET_PeerIdentity *new_trail_list;
2843       new_trail_list = invert_trail_list (source_peer, peer_list, trail_length);
2844       finger_table_add (source_peer, new_trail_list, trail_length, 1);
2845     }
2846     
2847     GDS_NEIGHBOURS_send_trail_setup_result (&(trail_setup->source_peer),
2848                                             &(my_identity),
2849                                             target_friend, trail_length,
2850                                             peer_list, current_trail_index,
2851                                             finger_map_index);
2852   
2853     return GNUNET_YES;
2854   }
2855   else 
2856   {
2857     struct GNUNET_PeerIdentity *current_source;
2858     current_source = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2859     if (current_dest_type == FINGER)
2860     {
2861       memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2862     }
2863     else
2864       current_source = NULL;
2865     
2866     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2867    /* FiXME: Is it correct to use null value for current source. */
2868     GDS_NEIGHBOURS_send_trail_setup (&(trail_setup->source_peer),
2869                                      trail_setup->destination_finger,
2870                                      current_destination,current_source,
2871                                      target_friend, trail_length, peer_list, 
2872                                      finger_map_index, current_dest_type);
2873
2874   return GNUNET_YES;
2875   }
2876  
2877   return GNUNET_SYSERR;
2878 }
2879
2880
2881 /**
2882  * Core handle for p2p trail construction result messages.
2883  * @param cls closure
2884  * @param message message
2885  * @param peer peer identity this notification is about
2886  * @return GNUNET_OK on success, GNUNET_SYSERR on error
2887  */
2888 static int
2889 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2890                                   const struct GNUNET_MessageHeader *message)
2891 {
2892   struct PeerTrailSetupResultMessage *trail_result;
2893   struct GNUNET_PeerIdentity *trail_peer_list;
2894   struct GNUNET_PeerIdentity *next_hop;
2895   struct FriendInfo *target_friend;
2896   unsigned int current_trail_index;
2897   unsigned int finger_map_index;
2898   unsigned int trail_length;
2899   size_t msize;
2900   
2901   msize = ntohs (message->size);
2902   if (msize < sizeof (struct PeerTrailSetupResultMessage))
2903   {
2904     GNUNET_break_op (0);
2905     return GNUNET_YES;
2906   }
2907   
2908   trail_result = (struct PeerTrailSetupResultMessage *) message; 
2909   trail_length = ntohl (trail_result->trail_length); 
2910   
2911   if ((msize <
2912        sizeof (struct PeerTrailSetupResultMessage) +
2913        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2914        (trail_length >
2915         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2916   {
2917     GNUNET_break_op (0);
2918     return GNUNET_YES;
2919   }
2920   
2921   current_trail_index = ntohl (trail_result->current_index);
2922   finger_map_index = ntohl (trail_result->finger_map_index);
2923
2924   trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
2925   
2926   if ( 0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
2927                                               &my_identity)))
2928   {
2929       finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length, 
2930                        finger_map_index);
2931      
2932       return GNUNET_YES;
2933
2934   }
2935   else
2936   {
2937     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2938     
2939     current_trail_index = current_trail_index - 1; 
2940     if (current_trail_index == 0)
2941     {
2942       memcpy (next_hop, &(trail_result->destination_peer),sizeof (struct GNUNET_PeerIdentity));
2943     }
2944     else
2945     {   
2946       memcpy (next_hop, &(trail_peer_list[current_trail_index-1]),sizeof (struct GNUNET_PeerIdentity));
2947     }
2948     
2949     
2950     /* If trail length  = 2, it means that destination and source peer are friends
2951      Then don't add an entry. */
2952     if (trail_length != 2)
2953       GDS_ROUTING_add (&(trail_result->destination_peer), &(trail_result->finger_identity),
2954                      peer, next_hop);   
2955     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2956     GNUNET_free (next_hop);
2957       
2958     GDS_NEIGHBOURS_send_trail_setup_result (&(trail_result->destination_peer),
2959                                             &(trail_result->finger_identity),
2960                                             target_friend, trail_length,
2961                                             trail_peer_list,current_trail_index,
2962                                             finger_map_index);
2963       return GNUNET_YES;
2964     }
2965   
2966   return GNUNET_SYSERR;
2967 }
2968
2969
2970 /**
2971  * FIXME: Use flag in the case finger peer map does not contain predcessor
2972  * then its NULL. Ideally it should never happen. 
2973  * Get my current predecessor from the finger peer map
2974  * @return Current predecessor.
2975  */
2976 static struct FingerInfo *
2977 get_predecessor()
2978 {
2979   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2980   struct GNUNET_PeerIdentity key_ret;
2981   unsigned int finger_index;
2982   struct FingerInfo *my_predecessor;
2983  
2984   /* Iterate over finger peer map and extract your predecessor. */
2985   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
2986   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
2987   {
2988     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next 
2989                        (finger_iter,&key_ret,(const void **)&my_predecessor)) 
2990     {
2991       if(1 == my_predecessor->finger_map_index)
2992       {
2993         break;
2994       }
2995     }
2996   }
2997   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2998   return my_predecessor;
2999 }
3000
3001
3002 /**
3003  * Core handle for p2p verify successor messages.
3004  * @param cls closure
3005  * @param message message
3006  * @param peer peer identity this notification is about
3007  * @return GNUNET_OK on success, GNUNET_SYSERR on error
3008  */
3009 static int
3010 handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
3011                                 const struct GNUNET_MessageHeader *message)
3012 {
3013   struct PeerVerifySuccessorMessage *vsm;
3014   struct GNUNET_PeerIdentity *trail_peer_list;
3015   struct FriendInfo *target_friend;
3016   struct GNUNET_PeerIdentity *next_hop;
3017   struct GNUNET_PeerIdentity *source_peer;
3018   unsigned int trail_length;
3019   unsigned int current_trail_index;
3020   size_t msize;
3021   
3022   msize = ntohs (message->size);
3023   if (msize < sizeof (struct PeerVerifySuccessorMessage))
3024   {
3025     GNUNET_break_op (0);
3026     return GNUNET_YES;
3027   }
3028   
3029   vsm = (struct PeerVerifySuccessorMessage *) message;
3030   trail_length = ntohl (vsm->trail_length);
3031   
3032   if ((msize < sizeof (struct PeerVerifySuccessorMessage) +
3033                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3034      (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3035   {
3036     GNUNET_break_op (0);
3037     return GNUNET_YES;
3038   }
3039   
3040   current_trail_index = ntohl (vsm->current_trail_index);       
3041   trail_peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
3042   source_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
3043   memcpy (source_peer, &(vsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
3044   
3045   next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
3046   
3047   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity)))
3048   {
3049     struct FingerInfo *my_predecessor;
3050     current_trail_index = trail_length - 1; 
3051     if (current_trail_index == 0)
3052       memcpy (next_hop, source_peer, sizeof (struct GNUNET_PeerIdentity));
3053     else
3054       memcpy (next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity));
3055     
3056     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3057     GNUNET_free (next_hop);
3058     
3059     my_predecessor = get_predecessor();
3060     if (0 == (GNUNET_CRYPTO_cmp_peer_identity (source_peer,
3061                                                &(my_predecessor->finger_identity))))
3062     {
3063       GDS_NEIGHBOURS_send_verify_successor_result (source_peer,
3064                                                    &(my_identity),
3065                                                    &(my_predecessor->finger_identity),
3066                                                    target_friend,
3067                                                    trail_peer_list,
3068                                                    trail_length,
3069                                                    current_trail_index);
3070     }
3071     else
3072     {
3073       struct GNUNET_PeerIdentity *new_successor_trail;
3074       int new_trail_length;
3075       int i;
3076       
3077       new_trail_length = trail_length + my_predecessor->trail_length;
3078       new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length);
3079       memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity));
3080       struct TrailPeerList *iterator;
3081       iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
3082       iterator = my_predecessor->head; 
3083       i = trail_length;
3084       while (i < new_trail_length)
3085       {
3086         memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
3087         iterator = iterator->next;
3088         i++;
3089       }
3090  
3091       GDS_NEIGHBOURS_send_verify_successor_result (source_peer,
3092                                                    &(my_identity),
3093                                                    &(my_predecessor->finger_identity),
3094                                                    target_friend,
3095                                                    new_successor_trail,
3096                                                    new_trail_length,
3097                                                    current_trail_index); 
3098     }      
3099    
3100   }
3101   else
3102   {
3103     current_trail_index = current_trail_index + 1;
3104     memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
3105     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3106     GNUNET_free (next_hop);
3107         
3108     GDS_NEIGHBOURS_send_verify_successor (source_peer, &(vsm->successor),target_friend,
3109                                           trail_peer_list, trail_length, current_trail_index); 
3110   }
3111   return GNUNET_YES;
3112 }
3113
3114
3115 /**
3116  * Core handle for p2p notify new successor messages.
3117  * @param cls closure
3118  * @param message message
3119  * @param peer peer identity this notification is about
3120  * @return GNUNET_OK on success, GNUNET_SYSERR on error
3121  */
3122 static int
3123 handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
3124                                     const struct GNUNET_MessageHeader *message)
3125 {
3126   struct PeerNotifyNewSuccessorMessage *nsm;
3127   struct GNUNET_PeerIdentity *trail_peer_list;
3128   unsigned int current_trail_index;
3129   size_t msize;
3130   unsigned int trail_length;
3131   
3132   msize = ntohs (message->size);
3133   if (msize < sizeof (struct PeerNotifyNewSuccessorMessage))
3134   {
3135     GNUNET_break_op (0);
3136     return GNUNET_YES;
3137   }
3138   
3139   nsm = (struct PeerNotifyNewSuccessorMessage *) message;
3140   trail_length = ntohl (nsm->trail_length);
3141   
3142   if ((msize < sizeof (struct PeerNotifyNewSuccessorMessage) +
3143                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3144       (trail_length >
3145        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3146   {
3147     GNUNET_break_op (0);
3148     return GNUNET_YES;
3149   }
3150   
3151   current_trail_index = ntohl (nsm->current_index);
3152   trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
3153   
3154   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity)))
3155   {
3156     struct GNUNET_PeerIdentity *new_trail;
3157     new_trail = invert_trail_list (&(nsm->source_peer), trail_peer_list, trail_length);
3158     finger_table_add (&(nsm->source_peer), new_trail, trail_length, 1); 
3159     return GNUNET_YES;
3160   }
3161   else
3162   {
3163     struct FriendInfo *target_friend;
3164     struct GNUNET_PeerIdentity *next_hop;
3165     
3166     target_friend = GNUNET_malloc (sizeof (struct FriendInfo));
3167     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
3168     
3169     current_trail_index = current_trail_index + 1;
3170     memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
3171     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3172     GNUNET_free (next_hop);
3173     
3174     GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), 
3175                                               &(nsm->destination_peer),
3176                                               target_friend, trail_peer_list,
3177                                               trail_length, current_trail_index);
3178   }
3179   return GNUNET_YES;
3180 }
3181
3182
3183 /**
3184  * Core handle for p2p verify successor result messages.
3185  * @param cls closure
3186  * @param message message
3187  * @param peer peer identity this notification is about
3188  * @return GNUNET_OK on success, GNUNET_SYSERR on error
3189  */
3190 static int
3191 handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdentity *peer,
3192                                        const struct GNUNET_MessageHeader *message)
3193 {
3194   struct PeerVerifySuccessorResultMessage *vsrm;
3195   struct FriendInfo *target_friend;
3196   struct GNUNET_PeerIdentity *trail_peer_list;
3197   struct GNUNET_PeerIdentity *next_hop;
3198   unsigned int trail_length;
3199   unsigned int current_trail_index;
3200   size_t msize;
3201   
3202   msize = ntohs (message->size);
3203   if (msize < sizeof (struct PeerVerifySuccessorResultMessage))
3204   {
3205     GNUNET_break_op (0);
3206     return GNUNET_YES;
3207   }
3208   
3209   vsrm = (struct PeerVerifySuccessorResultMessage *) message;
3210   trail_length = ntohl (vsrm->trail_length); 
3211   
3212   if ((msize <
3213        sizeof (struct PeerVerifySuccessorResultMessage) +
3214        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3215        (trail_length >
3216        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3217   {
3218     GNUNET_break_op (0);
3219     return GNUNET_YES;
3220   }
3221   
3222   current_trail_index = ntohl (vsrm->current_index);
3223   trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1];
3224
3225   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity))))
3226   {
3227     if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor), &(my_identity))))
3228     {
3229       finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0);
3230       next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
3231       memcpy (next_hop, &trail_peer_list[0], sizeof (struct GNUNET_PeerIdentity));
3232       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3233       current_trail_index = 0;
3234       GNUNET_free (next_hop);
3235       
3236       GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor),
3237                                                 target_friend, trail_peer_list,
3238                                                 trail_length, current_trail_index);
3239     }
3240   }
3241   else
3242   {
3243     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
3244     current_trail_index = current_trail_index - 1;
3245     if (current_trail_index == 0)
3246       memcpy (next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3247     else
3248       memcpy (next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity));
3249     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3250     GNUNET_free (next_hop);
3251     
3252     GDS_NEIGHBOURS_send_verify_successor_result (&(vsrm->destination_peer),
3253                                                  &(vsrm->source_successor),
3254                                                  &(vsrm->my_predecessor),
3255                                                  target_friend,
3256                                                  trail_peer_list,
3257                                                  trail_length,
3258                                                  current_trail_index); 
3259   }
3260   return GNUNET_YES;
3261 }
3262
3263
3264 /**
3265  * FIXME: Does it matter if the packet was going to a finger or friend?
3266  * Core handle for p2p trail rejection messages.
3267  * @param cls closure
3268  * @param message message
3269  * @param peer peer identity this notification is about
3270  * @return GNUNET_OK on success, GNUNET_SYSERR on error
3271  */
3272 static
3273 int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer,
3274                                    const struct GNUNET_MessageHeader *message)
3275 {
3276   struct PeerTrailRejectionMessage *trail_rejection;
3277   struct FailedTrail *trail_fail;
3278   struct FriendInfo *target_friend;
3279   struct GNUNET_PeerIdentity *trail_peer_list;
3280   unsigned int finger_map_index;
3281   size_t msize;
3282   
3283   msize = ntohs (message->size);
3284   if (msize < sizeof (struct PeerTrailRejectionMessage))
3285   {
3286     GNUNET_break_op (0);
3287     return GNUNET_YES;
3288   }
3289   
3290   trail_rejection = (struct PeerTrailRejectionMessage *) message;
3291   trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
3292   finger_map_index = ntohl (trail_rejection->finger_map_index);
3293   trail_fail = GNUNET_malloc (sizeof (struct FailedTrail));
3294   memcpy (&(trail_fail->source_peer), &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
3295   memcpy (&(trail_fail->congested_peer), &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity));
3296   memcpy (&(trail_fail->destination_finger_value), &(trail_rejection->finger_identity), sizeof (uint64_t));
3297   
3298   GNUNET_assert (GNUNET_OK ==
3299   GNUNET_CONTAINER_multipeermap_put (failed_trail_list, &(trail_fail->source_peer),
3300                                      trail_fail, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
3301    
3302   /* FIXME: Is it okay if I pass the struct as parameter. */
3303   target_friend = select_random_friend (&(trail_fail->congested_peer));
3304   
3305   if(NULL != target_friend)
3306   { 
3307     /* FIXME: Here I am passing NULL for current source, is it correct? 
3308      also, we set the current source only if current_destination_type
3309      is finger. */
3310     GDS_NEIGHBOURS_send_trail_setup (&(trail_fail->source_peer), 
3311                                      trail_fail->destination_finger_value,
3312                                      &(target_friend->id),
3313                                      NULL, target_friend, ntohl (trail_rejection->trail_length),
3314                                      trail_peer_list, 
3315                                      finger_map_index, FRIEND);
3316     return GNUNET_YES;
3317   }
3318   return GNUNET_SYSERR;
3319 }
3320
3321
3322 /**
3323  * Initialize neighbours subsystem.
3324  * @return GNUNET_OK on success, GNUNET_SYSERR on error
3325  */
3326 int
3327 GDS_NEIGHBOURS_init()
3328 {
3329   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
3330     {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
3331     {&handle_dht_p2p_get_result, GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT, 0},
3332     {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
3333     {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
3334     {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
3335     {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
3336     {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
3337     {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
3338     {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0},
3339     {NULL, 0, 0}
3340   };
3341   
3342   core_api =
3343     GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
3344                          &handle_core_disconnect, NULL, GNUNET_NO, NULL,
3345                          GNUNET_NO, core_handlers);
3346   if (NULL == core_api)
3347     return GNUNET_SYSERR;
3348
3349   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
3350   finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS, GNUNET_NO);
3351   /* FIXME: Not sure if this value is correct for this data structure. */
3352   failed_trail_list = GNUNET_CONTAINER_multipeermap_create (LINK_THRESHOLD, GNUNET_NO);
3353   return GNUNET_OK;
3354 }
3355
3356
3357 /**
3358  * Shutdown neighbours subsystem.
3359  */
3360 void
3361 GDS_NEIGHBOURS_done ()
3362 {
3363   if (NULL == core_api)
3364     return;
3365   
3366   GNUNET_CORE_disconnect (core_api);
3367   core_api = NULL;
3368   
3369   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
3370   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
3371   friend_peermap = NULL;
3372   
3373   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (finger_peermap));
3374   GNUNET_CONTAINER_multipeermap_destroy (finger_peermap);
3375   finger_peermap = NULL;
3376
3377   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
3378   {
3379     GNUNET_SCHEDULER_cancel (find_finger_trail_task);
3380     find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
3381   }
3382   
3383   if (GNUNET_SCHEDULER_NO_TASK != verify_successor)
3384   {
3385     GNUNET_SCHEDULER_cancel (verify_successor);
3386     verify_successor = GNUNET_SCHEDULER_NO_TASK;
3387   }
3388   
3389 }
3390
3391
3392 /**
3393  * Get the ID of the local node.
3394  *
3395  * @return identity of the local node
3396  */
3397 struct GNUNET_PeerIdentity *
3398 GDS_NEIGHBOURS_get_id ()
3399 {
3400   return &my_identity;
3401 }
3402
3403
3404 /* end of gnunet-service-xdht_neighbours.c */