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