Refactoring
[oweals/gnunet.git] / src / dht / gnunet-service-xdht_neighbours.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009-2014 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_ats_service.h"
34 #include "gnunet_core_service.h"
35 #include "gnunet_datacache_lib.h"
36 #include "gnunet_transport_service.h"
37 #include "gnunet_dht_service.h"
38 #include "gnunet_statistics_service.h"
39 #include "gnunet-service-xdht.h"
40 #include "gnunet-service-xdht_clients.h"
41 #include "gnunet-service-xdht_datacache.h"
42 #include "gnunet-service-xdht_neighbours.h"
43 #include "gnunet-service-xdht_routing.h"
44 #include <fenv.h>
45 #include "dht.h"
46
47
48 /**
49  * Maximum possible fingers of a peer.
50  */
51 #define MAX_FINGERS 65
52
53 /**
54  * Maximum allowed number of pending messages per friend peer.
55  */
56 #define MAXIMUM_PENDING_PER_FRIEND 64
57
58 /**
59  * How long to wait before sending another find finger trail request
60  */
61 #define DHT_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
62
63 /**
64  * How long at most to wait for transmission of a request to another peer?
65  */
66 #define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
67
68 /**
69  * How long will I remain congested?
70  */
71 #define CONGESTION_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
72
73 /**
74  * Maximum number of trails stored per finger.
75  */
76 #define TRAILS_COUNT 2
77
78 /**
79  * Used to distinguish put/get request use of find_successor() from others 
80  */
81 #define PUT_GET_REQUEST 65
82
83
84 GNUNET_NETWORK_STRUCT_BEGIN
85   
86 /**
87  * P2P PUT message
88  */
89 struct PeerPutMessage
90 {
91   /**
92    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
93    */
94   struct GNUNET_MessageHeader header;
95
96   /**
97    * Processing options
98    */
99   uint32_t options GNUNET_PACKED;
100
101   /**
102    * Content type.
103    */
104   uint32_t block_type GNUNET_PACKED;
105
106   /**
107    * Hop count
108    */
109   uint32_t hop_count GNUNET_PACKED;
110
111   /**
112    * Replication level for this message
113    * In the current implementation, this value is not used. 
114    */
115   uint32_t desired_replication_level GNUNET_PACKED;
116
117   /**
118    * Length of the PUT path that follows (if tracked).
119    */
120   uint32_t put_path_length GNUNET_PACKED;
121   
122   /** 
123    * Current destination to which this message is forwarded.
124    */
125   struct GNUNET_PeerIdentity current_destination;
126   
127   /**
128    * Peer whose finger is current_destination. 
129    */
130   struct GNUNET_PeerIdentity current_source;
131   
132   /**
133    * When does the content expire?
134    */
135   struct GNUNET_TIME_AbsoluteNBO expiration_time;
136   
137   /**
138    * The key to store the value under.
139    */
140   struct GNUNET_HashCode key GNUNET_PACKED;
141
142   /* put path (if tracked) */
143
144   /* Payload */
145  
146 };
147
148
149 /**
150  * P2P Result message
151  */
152 struct PeerGetResultMessage
153 {
154   /**
155    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT
156    */
157   struct GNUNET_MessageHeader header;
158
159   /**
160    * The type for the data.
161    */
162   uint32_t type GNUNET_PACKED;
163   
164   /**
165    * Number of peers recorded in the outgoing path from source to the
166    * stored location of this message.
167    */
168   uint32_t put_path_length GNUNET_PACKED;
169   
170   /**
171    * Length of the GET path that follows (if tracked).
172    */
173   uint32_t get_path_length GNUNET_PACKED;
174   
175   /**
176    * Peer which will receive the get result message. 
177    */
178   struct GNUNET_PeerIdentity source_peer;
179   
180   /**
181    * When does the content expire?
182    */
183   struct GNUNET_TIME_Absolute expiration_time;
184
185   /**
186    * The key of the corresponding GET request.
187    */
188   struct GNUNET_HashCode key;
189  
190   /* put path (if tracked) */
191
192   /* get path (if tracked) */
193
194   /* Payload */
195
196 };
197
198
199 /**
200  * P2P GET message
201  */
202 struct PeerGetMessage
203 {
204   /**
205    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET
206    */
207   struct GNUNET_MessageHeader header;
208   
209   /**
210    * Processing options
211    */
212   uint32_t options GNUNET_PACKED;
213
214   /**
215    * Desired content type.
216    */
217   uint32_t block_type GNUNET_PACKED;
218   
219   /**
220    * Hop count
221    */
222   uint32_t hop_count GNUNET_PACKED;
223  
224   /**
225    * Desired replication level for this request.
226    * In the current implementation, this value is not used. 
227    */
228   uint32_t desired_replication_level GNUNET_PACKED;
229   
230   /**
231    * Total number of peers in get path. 
232    */
233   unsigned int get_path_length;
234   
235   /**
236    * Peer which is an intermediate destination. 
237    */
238   struct GNUNET_PeerIdentity current_destination;
239   
240   /**
241    * Source for which current_destination is the finger. 
242    */
243   struct GNUNET_PeerIdentity current_source;
244  
245   /**
246    * The key we are looking for.
247    */
248   struct GNUNET_HashCode key;
249   
250   /* Get path. */
251
252 };
253
254
255 /**
256  * P2P Trail setup message
257  */
258 struct PeerTrailSetupMessage
259 {
260   
261   /**
262    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
263    */
264   struct GNUNET_MessageHeader header;
265   
266   /**
267    * Peer closest to this value will be our finger. 
268    */
269   uint64_t destination_finger;
270
271   /**
272    * Source peer which wants to setup the trail to one of its finger. 
273    */
274   struct GNUNET_PeerIdentity source_peer;
275   
276   /**
277    * Peer to which this packet is forwarded.
278    */
279   struct GNUNET_PeerIdentity current_destination;
280   
281   /**
282    * In case the packet is forwarded to an intermediate finger, then 
283    * current_source contains the peer id whose finger is the intermediate
284    * finger. In case the packet is forwarded to a friend, then it is NULL.
285    * FIXME: check the usage of current_source and fix this comment. 
286    */
287   struct GNUNET_PeerIdentity current_source;
288   
289   /**
290    * Index into finger peer map, in Network Byte Order. 
291    */
292   uint32_t finger_map_index;
293   
294   /**
295    * Number of entries in trail list, in Network Byte Order.
296    */
297   uint32_t trail_length GNUNET_PACKED;
298   
299   /* Trail formed in the process. */
300 };
301
302
303 /**
304  * P2P Trail Setup Result message
305  */
306 struct PeerTrailSetupResultMessage
307 {
308   
309   /**
310    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT
311    */
312   struct GNUNET_MessageHeader header;
313   
314   /**
315    * Finger to which we have found the path. 
316    */
317   struct GNUNET_PeerIdentity finger_identity;
318
319   /**
320    * Peer which was looking for the trail to finger. 
321    */
322   struct GNUNET_PeerIdentity destination_peer;
323   
324   /**
325    * Index into finger peer map in NBO.
326    */
327   uint32_t finger_map_index;
328   
329   /**
330    * Number of entries in trail list in NBO.
331    */
332   uint32_t trail_length GNUNET_PACKED;
333   
334   /* Trail from destination_peer to finger_identity */
335   
336 };
337
338
339 /**
340  * P2P Trail Rejection Message. 
341  */
342 struct PeerTrailRejectionMessage
343 {
344   /**
345    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION
346    */
347   struct GNUNET_MessageHeader header;
348   
349   /**
350    * Source peer which wants to set up the trail. 
351    */
352   struct GNUNET_PeerIdentity source_peer;
353   
354   /**
355    * Peer which sent trail rejection message. 
356    */
357   struct GNUNET_PeerIdentity congested_peer;
358   
359   /**
360    * Peer identity which will be successor to this value will be finger of
361    * source_peer. 
362    */
363   uint64_t finger_identity_value;
364   
365   /**
366    * Index in finger peer map of source peer.
367    */
368   uint32_t finger_map_index;
369   
370   /**
371    * Total number of peers in the trail.
372    */
373   uint32_t trail_length;
374   
375   /**
376    * Relative time for which congested_peer will remain congested. 
377    */
378   struct GNUNET_TIME_Relative congestion_time;
379   
380   /* Trail_list from source_peer to peer which sent the message for trail setup
381    * to congested peer.*/
382 };
383
384
385 /**
386  * P2P Verify Successor message. 
387  */
388 struct PeerVerifySuccessorMessage
389 {
390   
391   /**
392    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR
393    */
394   struct GNUNET_MessageHeader header;
395   
396   /**
397    * Source peer which wants to verify its successor. 
398    */
399   struct GNUNET_PeerIdentity source_peer;
400   
401   /**
402    * My current successor.
403    */
404   struct GNUNET_PeerIdentity successor;
405   
406   /**
407    * Total number of peers in trail to current successor.
408    */
409   uint32_t trail_length;
410   
411   /* Trail to reach to from source_peer to successor. */
412 };
413
414
415 /**
416  * P2P Verify Successor Result message. 
417  */
418 struct PeerVerifySuccessorResultMessage
419 {
420   
421   /**
422    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT
423    */
424   struct GNUNET_MessageHeader header;
425   
426   /**
427    * Destination peer which sent the request to verify its successor. 
428    */
429   struct GNUNET_PeerIdentity destination_peer;
430   
431   /**
432    * Successor to which PeerVerifySuccessorMessage was sent.
433    */
434   struct GNUNET_PeerIdentity source_successor;
435   
436   /**
437    * source_successor's predecessor
438    */
439   struct GNUNET_PeerIdentity my_predecessor;
440   
441   /**
442    * Total number of peers in trail.
443    */
444   uint32_t trail_length; 
445   
446   /* Trail to reach from destination_peer to its correct successor.
447    * If source_successor is not destination peer, then trail is from destination_peer
448    * to my_predecessor.
449    * If source_successor is destination peer, then trail is from destination_peer
450    * to source_successor. */
451 };
452
453
454 /**
455  * P2P Notify New Successor message.
456  */
457 struct PeerNotifyNewSuccessorMessage
458 {
459   /**
460    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR
461    */
462   struct GNUNET_MessageHeader header;
463   
464   /**
465    * Source peer which wants to notify its new successor. 
466    */
467   struct GNUNET_PeerIdentity source_peer;
468   
469   /** 
470    * Old successor of source peer. 
471    */
472   struct GNUNET_PeerIdentity old_successor;
473   
474   /**
475    * New successor identity.
476    */
477   struct GNUNET_PeerIdentity destination_peer;
478   
479   /**
480    * Number of peers in trail from source_peer to new successor.
481    */
482   uint32_t trail_length;
483   
484   /* Trail to from source_peer to destination_peer. */
485 };
486
487 struct PeerTrailTearDownMessage
488 {
489   /**
490    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN
491    */
492   struct GNUNET_MessageHeader header;
493   
494   /**
495    * Source peer of this trail.  
496    */
497   struct GNUNET_PeerIdentity source_peer;
498   
499   /**
500    * Destination peer of this trail. 
501    */
502   struct GNUNET_PeerIdentity destination_peer;
503   
504   /**
505    * Trail from source_peer to destination_peer compressed such that 
506    * new_first_friend is the first hop in the trail from source to 
507    * destination. 
508    */
509   struct GNUNET_PeerIdentity new_first_friend;
510   /**
511    * Number of peers in trail from source_peer to new first friend.
512    */
513   uint32_t trail_length;
514   
515   /* Trail from source_peer to new first friend. */
516 };
517
518
519 struct PeerAddTrailMessage
520 {
521   /**
522    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL
523    */
524   struct GNUNET_MessageHeader header;
525   
526   /**
527    * Source peer of the routing trail. 
528    */
529   struct GNUNET_PeerIdentity source_peer;
530   
531   /**
532    * Destination peer of the routing trail. 
533    */
534   struct GNUNET_PeerIdentity destination_peer;
535   
536   /**
537    * Total number of peers from source peer to destination peer. 
538    */
539   unsigned int trail_length;
540   
541   /* Trail from source peer to destination peer. */
542   
543 };
544
545 GNUNET_NETWORK_STRUCT_END
546
547
548 /**
549  * Linked list of messages to send to a particular other peer.
550  */
551 struct P2PPendingMessage
552 {
553   /**
554    * Pointer to next item in the list
555    */
556   struct P2PPendingMessage *next;
557
558   /**
559    * Pointer to previous item in the list
560    */
561   struct P2PPendingMessage *prev;
562
563   /**
564    * Message importance level.  FIXME: used? useful?
565    */
566   unsigned int importance;
567   
568   /**
569    * When does this message time out?
570    */
571   struct GNUNET_TIME_Absolute timeout;
572   
573   /**
574    * Actual message to be sent, allocated at the end of the struct:
575    * // msg = (cast) &pm[1];
576    * // memcpy (&pm[1], data, len);
577    */
578   const struct GNUNET_MessageHeader *msg;
579
580 };
581
582
583 /**
584  * Linked List of peers which are part of trail to reach a particular Finger.
585  */
586 struct TrailPeerList
587 {
588    /**
589     * Pointer to next item in the list
590     */
591    struct TrailPeerList *next;
592
593    /**
594     * Pointer to previous item in the list
595     */
596    struct TrailPeerList *prev;
597    
598    /**
599     * An element in this trail list
600     */
601    struct GNUNET_PeerIdentity peer;
602   
603 };
604
605
606 /** 
607  * FIXME: for congested peer just define a relative time as #define.
608  *  Entry in friend_peermap.
609  */
610 struct FriendInfo
611 {
612   /**
613    * Friend Identity 
614    */
615   struct GNUNET_PeerIdentity id;
616
617   /**
618    * Number of trails for which this friend is the first hop. 
619    */
620   unsigned int trails_count;
621   
622   /**
623    * Count of outstanding messages for this friend.
624    */
625   unsigned int pending_count;
626   
627   /**
628    * In case not 0, then amount of time for which this friend is congested. 
629    */
630   struct GNUNET_TIME_Absolute congestion_duration;
631   
632   /**
633    * Head of pending messages to be sent to this friend.
634    */
635   struct P2PPendingMessage *head;
636
637   /**
638    * Tail of pending messages to be sent to this friend.
639    */
640   struct P2PPendingMessage *tail;
641  
642   /**
643    * Core handle for sending messages to this friend.
644    */
645   struct GNUNET_CORE_TransmitHandle *th;
646
647 };
648
649
650 /**
651  * Entry in finger_peermap.
652  */
653 struct FingerInfo
654 {
655   /**
656    * Finger identity.
657    */
658   struct GNUNET_PeerIdentity finger_identity;
659   
660   /**
661    * Index in finger peer map
662    */
663   unsigned int finger_map_index;
664   
665   /**
666    * Number of trails to reach to this finger.
667    */
668   unsigned int trail_count;
669   
670   /**
671    * Total number of entries in first trail from (me,finger)
672    */
673   unsigned int first_trail_length;
674   
675   /**
676    * Total number of entries in second trail from (me,finger)
677    */
678   unsigned int second_trail_length;
679   
680   
681   /**
682    * Number of trail of which the first element to reach to this finger is
683    * part of. 
684    */
685   unsigned int first_friend_trails_count;
686   
687   /**
688    * Head of first trail to reach this finger.
689    */
690   struct TrailPeerList *first_trail_head;
691   
692   /**
693    * Tail of first trail to reach this finger.
694    */
695   struct TrailPeerList *first_trail_tail;
696   
697   /**
698    * Head of second trail to reach this finger.
699    */
700   struct TrailPeerList *second_trail_head;
701   
702   /**
703    * Tail of second trail to reach this finger.
704    */
705   struct TrailPeerList *second_trail_tail;
706   
707 };
708
709
710 /**
711  * FIXME: The name is not correct. 
712  * Used to specify the kind of value stored in the array all_known_peers. 
713  */
714 enum current_destination_type
715 {
716   FRIEND,
717   FINGER,
718   VALUE,
719   MY_ID
720 };
721
722
723 /**
724  * Data structure passed to sorting algorithm in find_successor().
725  */
726 struct Sorting_List
727 {
728   /**
729    * 64 bit value of peer identity
730    */
731   uint64_t peer_id;
732   
733   /**
734    * FIXME: think of a better name for both the struct and destination_type
735    * Type : MY_ID, FINGER, FINGER, Value 
736    */
737   enum current_destination_type type;
738   
739   /**
740    * Pointer to original data structure linked to peer id.
741    */
742   void *data;
743 };
744
745
746 /**
747  * Task that sends FIND FINGER TRAIL requests. This task is started when we have
748  * get our first friend. 
749  */
750 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
751
752 /**
753  * Identity of this peer.
754  */
755 static struct GNUNET_PeerIdentity my_identity;
756
757 /**
758  * Hash map of all the friends of a peer
759  */
760 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
761
762 /**
763  * Hash map of all the fingers of a peer
764  */
765 static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap;
766
767 /**
768  * Handle to CORE.
769  */
770 static struct GNUNET_CORE_Handle *core_api;
771
772 /**
773  * Finger map index for predecessor entry in finger peermap. 
774  */
775 #define PREDECESSOR_FINGER_ID 64
776
777 /**
778  * Maximum number of trails allowed to go through a friend.
779  * FIXME: Better name, Random value at the moment, need to be adjusted to maintain a balance
780  * between performance and Sybil tolerance. 
781  */
782 #define TRAIL_THROUGH_FRIEND_THRESHOLD 64
783
784 /**
785  * Possible number of different trails to reach to a finger. (Redundant routing) 
786  */
787 #define TRAIL_COUNT 2
788
789 /**
790  * The current finger index that we have want to find trail to.
791  */
792 static unsigned int current_search_finger_index;
793
794
795 /**
796  * Iterate over trail and search your index location in the array. 
797  * @param trail Trail which contains list of peers.
798  * @param trail_length Number of peers in the trail.
799  * @return Index in the array.
800  *         #GNUNET_SYSERR, in case there is no entry which should not be the case ideally. 
801  */
802 static int
803 search_my_index (const struct GNUNET_PeerIdentity *trail,
804                 int trail_length)
805 {
806   int i = 0;
807   
808   while (i < trail_length)
809   {
810     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &trail[i]))
811     {
812       return i;
813     }
814     i++;
815   }
816   return GNUNET_SYSERR;
817 }
818
819
820 /**
821  * Compare two peer identities.
822  * @param p1 Peer identity
823  * @param p2 Peer identity
824  * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2. 
825  */
826 static int
827 compare_peer_id (const void *p1, const void *p2)
828 {
829   struct Sorting_List *p11;
830   struct Sorting_List *p22;
831   int ret;
832   p11 = GNUNET_malloc (sizeof (struct Sorting_List));
833   p22 = GNUNET_malloc (sizeof (struct Sorting_List));
834   p11 = (struct Sorting_List *)p1;
835   p22 = (struct Sorting_List *)p2;
836   ret = ( (p11->peer_id) > (p22->peer_id) ) ? 1 : 
837           ( (p11->peer_id) == (p22->peer_id) ) ? 0 : -1;
838   return ret;
839 }
840
841
842 /**
843  * Return the predecessor of value in all_known_peers.
844  * @param all_known_peers list of all the peers
845  * @param value value we have to search in the all_known_peers.
846  * @param size Total numbers of elements
847  * @return Predecessor
848  */
849 static struct Sorting_List *
850 find_closest_predecessor(struct Sorting_List *all_known_peers, uint64_t value,
851                          unsigned int size)
852 {
853   int first;
854   int last;
855   int middle;
856   
857   first = 0;
858   last = size - 1;
859   middle = (first + last)/2;
860   
861   while(first <= last)
862   {
863     if(all_known_peers[middle].peer_id < value)
864     {
865       first = middle + 1; 
866     }
867     else if(all_known_peers[middle].peer_id == value)
868     {
869       if(middle == 0)
870       {
871         return &all_known_peers[size - 1];
872       }
873       else
874       {
875         return &all_known_peers[middle - 1];
876       }
877     }
878     else
879     {
880        last = middle - 1;
881     }
882   
883     middle = (first + last)/2;  
884   }
885   return NULL;
886 }
887
888
889 /**
890  * Return the successor of value in all_known_peers.
891  * @param all_known_peers list of all the peers
892  * @param value value we have to search in the all_known_peers.
893  * @param size Total numbers of elements
894  * @return Successor
895  */
896 static struct Sorting_List *
897 find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value,
898                        unsigned int size)
899 {
900   int first;
901   int last;
902   int middle;
903   
904   first = 0;
905   last = size - 1;
906   middle = (first + last)/2;
907   
908   while(first <= last)
909   {
910     if(all_known_peers[middle].peer_id < value)
911     {
912       first = middle + 1; 
913     }
914     else if(all_known_peers[middle].peer_id == value)
915     {
916       if(middle == (size -1))
917       {
918         return &all_known_peers[0];
919       }
920       else
921       {
922         return &all_known_peers[middle+1];
923       }
924     }
925     else
926     {
927        last = middle - 1;
928     }
929   
930     middle = (first + last)/2;  
931   }
932   return NULL;
933 }
934
935
936 /**
937  * Called when core is ready to send a message we asked for
938  * out to the destination.
939  *
940  * @param cls the 'struct FriendInfo' of the target friend
941  * @param size number of bytes available in buf
942  * @param buf where the callee should write the message
943  * @return number of bytes written to buf
944  */
945 static size_t
946 core_transmit_notify (void *cls, size_t size, void *buf)
947 {
948   struct FriendInfo *peer = cls;
949   char *cbuf = buf;
950   struct P2PPendingMessage *pending;
951   size_t off;
952   size_t msize;
953   
954   peer->th = NULL;
955   while ((NULL != (pending = peer->head)) &&
956          (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
957   {
958     peer->pending_count--;
959     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);  
960     GNUNET_free (pending);
961   }
962   if (NULL == pending)
963   {
964     /* no messages pending */
965     return 0;
966   }
967   if (NULL == buf)
968   {
969     peer->th =
970         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
971                                            GNUNET_CORE_PRIO_BEST_EFFORT,
972                                            GNUNET_TIME_absolute_get_remaining
973                                            (pending->timeout), &peer->id,
974                                            ntohs (pending->msg->size),
975                                            &core_transmit_notify, peer);
976     GNUNET_break (NULL != peer->th);
977     return 0;
978   }
979   off = 0;
980   while ((NULL != (pending = peer->head)) &&
981          (size - off >= (msize = ntohs (pending->msg->size))))
982   {
983     GNUNET_STATISTICS_update (GDS_stats,
984                               gettext_noop
985                               ("# Bytes transmitted to other peers"), msize,
986                               GNUNET_NO);
987     memcpy (&cbuf[off], pending->msg, msize);
988     off += msize;
989     peer->pending_count--;
990     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
991     GNUNET_free (pending);
992   }
993   if (peer->head != NULL)
994   {
995     peer->th =
996         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
997                                            GNUNET_CORE_PRIO_BEST_EFFORT,
998                                            GNUNET_TIME_absolute_get_remaining
999                                            (pending->timeout), &peer->id, msize,
1000                                            &core_transmit_notify, peer);
1001     GNUNET_break (NULL != peer->th);
1002   }
1003  
1004   return off;
1005 }
1006
1007
1008 /**
1009  * FIXME: assertion fails at the end of this function. also in core_api.c at 1299.
1010  * Transmit all messages in the friend's message queue.
1011  *
1012  * @param peer message queue to process
1013  */
1014 static void
1015 process_friend_queue (struct FriendInfo *peer)
1016 {
1017   struct P2PPendingMessage *pending;
1018   
1019   if (NULL == (pending = peer->head))
1020     return;
1021   if (NULL != peer->th)
1022     return;
1023   
1024   GNUNET_STATISTICS_update (GDS_stats,
1025                             gettext_noop
1026                             ("# Bytes of bandwidth requested from core"),
1027                             ntohs (pending->msg->size), GNUNET_NO);
1028   
1029   peer->th =
1030       GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
1031                                          pending->importance,
1032                                          GNUNET_TIME_absolute_get_remaining
1033                                          (pending->timeout), &peer->id,
1034                                          ntohs (pending->msg->size),
1035                                          &core_transmit_notify, peer);
1036   GNUNET_break (NULL != peer->th);
1037 }
1038
1039
1040 /**
1041  * Construct a trail setup message and forward it to a friend. 
1042  * @param source_peer Peer which wants to set up the trail to one of its finger.
1043  * @param destination_finger Peer identity closest to this value will be 
1044  *                           @a source_peer's finger.
1045  * @param current_destination next destination corresponding to @a current_source,
1046  *                            can be either a finger or a friend of @a current_source. 
1047  * @param current_source Peer for which @a current_destination is its finger/friend.
1048  * @param target_friend Friend to which this message should be forwarded.
1049  * @param trail_length Numbers of peers in the trail found so far.
1050  * @param trail_peer_list Peers this request has traversed so far  
1051  * @param finger_map_index Index in finger peer map
1052  */
1053 void
1054 GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer,
1055                                  uint64_t destination_finger,
1056                                  struct GNUNET_PeerIdentity *current_destination,
1057                                  struct GNUNET_PeerIdentity *current_source,
1058                                  struct FriendInfo *target_friend,
1059                                  unsigned int trail_length,
1060                                  const struct GNUNET_PeerIdentity *trail_peer_list,
1061                                  unsigned int finger_map_index)
1062 {
1063   struct P2PPendingMessage *pending;
1064   struct PeerTrailSetupMessage *tsm;
1065   struct GNUNET_PeerIdentity *peer_list;
1066   size_t msize;
1067   
1068   msize = sizeof (struct PeerTrailSetupMessage) + 
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   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1078   {  
1079     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1080                                 1, GNUNET_NO);
1081   }
1082   
1083   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1084   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1085   tsm = (struct PeerTrailSetupMessage *) &pending[1]; 
1086   pending->msg = &tsm->header;
1087   tsm->header.size = htons (msize);
1088   tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
1089   memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t));
1090   memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1091   memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
1092   memcpy (&(tsm->current_source), current_source, sizeof (struct GNUNET_PeerIdentity));
1093   tsm->trail_length = htonl (trail_length); 
1094   tsm->finger_map_index = htonl (finger_map_index);
1095   
1096   if (trail_length > 0)
1097   {
1098     peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
1099     memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
1100   }
1101
1102   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1103   target_friend->pending_count++;
1104   process_friend_queue (target_friend);
1105 }
1106
1107
1108 /**
1109  * Construct a trail setup result message and forward it to a friend. 
1110  * @param destination_peer Peer which will get the trail to one of its finger.
1111  * @param source_finger Peer to which the trail has been setup to.
1112  * @param target_friend Friend to which this message should be forwarded.
1113  * @param trail_length Numbers of peers in the trail.
1114  * @param trail_peer_list Peers which are part of the trail from source to destination.
1115  * @param finger_map_index Index in finger peer map 
1116  */
1117 void
1118 GDS_NEIGHBOURS_send_trail_setup_result (const struct GNUNET_PeerIdentity *destination_peer,
1119                                         const struct GNUNET_PeerIdentity *source_finger,
1120                                         struct FriendInfo *target_friend,
1121                                         unsigned int trail_length,
1122                                         const struct GNUNET_PeerIdentity *trail_peer_list,
1123                                         unsigned int finger_map_index)
1124 {
1125   struct P2PPendingMessage *pending;
1126   struct PeerTrailSetupResultMessage *tsrm;
1127   struct GNUNET_PeerIdentity *peer_list;
1128   size_t msize;
1129   
1130   msize = sizeof (struct PeerTrailSetupResultMessage) + 
1131           (trail_length * sizeof (struct GNUNET_PeerIdentity));
1132   
1133   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1134   {
1135     GNUNET_break (0);
1136     return;
1137   }
1138   
1139   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1140   {  
1141     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1142                                 1, GNUNET_NO);
1143   }
1144   
1145   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1146   pending->importance = 0;    
1147   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1148   tsrm = (struct PeerTrailSetupResultMessage *) &pending[1]; 
1149   pending->msg = &tsrm->header;
1150   tsrm->header.size = htons (msize);
1151   tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT);
1152   memcpy (&(tsrm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1153   memcpy (&(tsrm->finger_identity), source_finger, sizeof (struct GNUNET_PeerIdentity));
1154   tsrm->trail_length = htonl (trail_length);
1155   tsrm->finger_map_index = htonl (finger_map_index);
1156  
1157   peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
1158   if (trail_length > 0)
1159   {
1160     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1161   }
1162   /* Send the message to chosen friend. */
1163   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1164   target_friend->pending_count++;
1165   process_friend_queue (target_friend);
1166 }
1167
1168
1169 /**
1170  * Construct a PeerVerifySuccessor message and send it to friend.
1171  * @param source_peer Peer which wants to verify its successor
1172  * @param successor Peer which is our current successor
1173  * @param target_friend Friend to which this message should be forwarded.
1174  * @param trail_peer_list Peer which are part of trail from source to destination
1175  * @param trail_length Number of peers in the trail list.
1176  */
1177 void GDS_NEIGHBOURS_send_verify_successor(const struct GNUNET_PeerIdentity *source_peer,
1178                                           const struct GNUNET_PeerIdentity *successor,
1179                                           struct FriendInfo *target_friend,
1180                                           const struct GNUNET_PeerIdentity *trail_peer_list,
1181                                           unsigned int trail_length)
1182 {
1183   struct PeerVerifySuccessorMessage *vsm;
1184   struct P2PPendingMessage *pending;
1185   struct GNUNET_PeerIdentity *peer_list;
1186   size_t msize;
1187   
1188   msize = sizeof (struct PeerVerifySuccessorMessage) + 
1189           (trail_length * sizeof (struct GNUNET_PeerIdentity));
1190   
1191   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1192   {
1193     GNUNET_break (0);
1194     return;
1195   }
1196  
1197   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1198   {  
1199     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1200                                 1, GNUNET_NO);
1201   }
1202   
1203   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1204   pending->importance = 0;    /* FIXME */
1205   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1206   vsm = (struct PeerVerifySuccessorMessage *) &pending[1];
1207   pending->msg = &vsm->header;
1208   vsm->header.size = htons (msize);
1209   vsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR);
1210   memcpy (&(vsm->successor), successor, sizeof (struct GNUNET_PeerIdentity));
1211   memcpy (&(vsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1212   vsm->trail_length = htonl (trail_length);
1213   
1214   if (trail_length > 0)
1215   {
1216     peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
1217     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1218   }
1219   
1220   /* Send the message to chosen friend. */
1221   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1222   target_friend->pending_count++;
1223   process_friend_queue (target_friend);
1224   
1225 }
1226
1227
1228 /**
1229  * Construct a PeerVerifySuccessorResult message and send it to friend.
1230  * @param destination_peer Peer which sent verify successor message
1231  * @param source_successor Peer to which verify successor message was sent.
1232  * @param my_predecessor source_successor's predecessor.
1233  * @param target_friend Friend to which this message should be forwarded.
1234  * @param trail_peer_list Peers which are part of trail from source to destination
1235  * @param trail_length Number of peers in the trail list.
1236  */
1237 void GDS_NEIGHBOURS_send_verify_successor_result (const struct GNUNET_PeerIdentity *destination_peer,
1238                                                   const struct GNUNET_PeerIdentity *source_successor,
1239                                                   const struct GNUNET_PeerIdentity *my_predecessor,
1240                                                   struct FriendInfo *target_friend,
1241                                                   const struct GNUNET_PeerIdentity *trail_peer_list,
1242                                                   unsigned int trail_length)
1243 {
1244   struct PeerVerifySuccessorResultMessage *vsmr;
1245   struct P2PPendingMessage *pending;
1246   struct GNUNET_PeerIdentity *peer_list;
1247   size_t msize;
1248   
1249   msize = sizeof (struct PeerVerifySuccessorResultMessage) + 
1250           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1251   
1252   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1253   {
1254     GNUNET_break (0);
1255     return;
1256   }
1257   
1258   
1259   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1260   {  
1261     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1262                                 1, GNUNET_NO);
1263   }
1264
1265   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1266   pending->importance = 0;    /* FIXME */
1267   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1268   vsmr = (struct PeerVerifySuccessorResultMessage *) &pending[1];
1269   pending->msg = &vsmr->header;
1270   vsmr->header.size = htons (msize);
1271   vsmr->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT);
1272   memcpy (&(vsmr->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1273   memcpy (&(vsmr->source_successor), source_successor, sizeof (struct GNUNET_PeerIdentity));
1274   memcpy (&(vsmr->my_predecessor), my_predecessor, sizeof (struct GNUNET_PeerIdentity));
1275   vsmr->trail_length = htonl (trail_length);  
1276   if (trail_length > 0)
1277   {
1278     peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
1279     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1280   }
1281   
1282    /* Send the message to chosen friend. */
1283   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1284   target_friend->pending_count++;
1285   process_friend_queue (target_friend);
1286 }
1287
1288
1289 /**
1290  * Construct a PeerNotifyNewSuccessor message and send it to friend.
1291  * @param source_peer Peer which is sending notify message to its new successor.
1292  * @param destination_peer Peer which is the new destination.
1293  * @param target_friend Next friend to pass this message to. 
1294  * @param peer_list List of peers in the trail to reach to destination_peer.
1295  * @param trail_length Total number of peers in peer list 
1296  */
1297 void 
1298 GDS_NEIGHBOURS_send_notify_new_successor (const struct GNUNET_PeerIdentity *source_peer,
1299                                           const struct GNUNET_PeerIdentity *destination_peer,
1300                                           const struct GNUNET_PeerIdentity *old_successor,
1301                                           struct FriendInfo *target_friend,
1302                                           const struct GNUNET_PeerIdentity *trail_peer_list,
1303                                           unsigned int trail_length)
1304 {
1305   struct PeerNotifyNewSuccessorMessage *nsm;
1306   struct P2PPendingMessage *pending;
1307   struct GNUNET_PeerIdentity *peer_list;
1308   size_t msize;
1309   
1310   msize = sizeof (struct PeerNotifyNewSuccessorMessage) + 
1311           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1312   
1313   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1314   {
1315     GNUNET_break (0);
1316     return;
1317   }
1318   
1319   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1320   {  
1321     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1322                                 1, GNUNET_NO);
1323   }
1324   
1325   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1326   pending->importance = 0;    /* FIXME */
1327   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1328   nsm = (struct PeerNotifyNewSuccessorMessage *) &pending[1];
1329   pending->msg = &nsm->header;
1330   nsm->header.size = htons (msize);
1331   nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR);
1332   memcpy (&(nsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1333   memcpy (&(nsm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1334   memcpy (&(nsm->old_successor), old_successor, sizeof (struct GNUNET_PeerIdentity));
1335   nsm->trail_length = htonl (trail_length);
1336
1337   if (trail_length > 0)
1338   {
1339     peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
1340     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1341   }
1342    /* Send the message to chosen friend. */
1343   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1344   target_friend->pending_count++;
1345   process_friend_queue (target_friend);
1346 }
1347
1348
1349 /**
1350  * Send a trail tear down message
1351  * @param source_peer Source of the trail.
1352  * @param destination_peer Destination of the trail. 
1353  * @param discarded_trail Discarded trail from source to destination. 
1354  * @param discarded_trail_length Total number of peers in trail_list. 
1355  * @pararm target_peer Next peer to forward this message to. 
1356  * @param new_first_friend The new first hop in the new trail from source to destination
1357  *                         peer.
1358  */
1359 void
1360 GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_PeerIdentity *source_peer,
1361                                     const struct GNUNET_PeerIdentity *destination_peer,
1362                                     const struct GNUNET_PeerIdentity *discarded_trail,
1363                                     unsigned int discarded_trail_length,
1364                                     struct FriendInfo *target_friend,
1365                                     const struct GNUNET_PeerIdentity *new_first_friend)
1366 {
1367   struct P2PPendingMessage *pending;
1368   struct PeerTrailTearDownMessage *ttdm;
1369   struct GNUNET_PeerIdentity *peer_list;
1370   size_t msize;
1371   
1372   msize = sizeof (struct PeerTrailTearDownMessage) + 
1373           (discarded_trail_length * sizeof(struct GNUNET_PeerIdentity));
1374   
1375   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1376   {
1377     GNUNET_break (0);
1378     return;
1379   }
1380   
1381   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1382   {  
1383     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1384                                 1, GNUNET_NO);
1385   }
1386   
1387   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1388   pending->importance = 0;    /* FIXME */
1389   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1390   ttdm = (struct PeerTrailTearDownMessage *) &pending[1];
1391   pending->msg = &ttdm->header;
1392   ttdm->header.size = htons (msize);
1393   ttdm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN);
1394   memcpy (&(ttdm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1395   memcpy (&(ttdm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1396   memcpy (&(ttdm->new_first_friend),new_first_friend, sizeof (struct GNUNET_PeerIdentity));
1397   ttdm->trail_length = htonl (discarded_trail_length);
1398   
1399   if (discarded_trail_length > 0)
1400   {
1401     peer_list = (struct GNUNET_PeerIdentity *) &ttdm[1];
1402     memcpy (peer_list, discarded_trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1403   }
1404    /* Send the message to chosen friend. */
1405   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1406   target_friend->pending_count++;
1407   process_friend_queue (target_friend);
1408 }
1409
1410
1411 /**
1412  * Construct an add_trail_message and send it to target_friend
1413  * @param source_peer Source of the trail to be added
1414  * @param destination_peer Destination of the trail to be added
1415  * @param trail Trail from source to destination
1416  * @param trail_length Total number of peers in the trail
1417  * @param target_friend Friend to forward this message. 
1418  */
1419 void
1420 GDS_NEIGHBOURS_send_add_trail_message (struct GNUNET_PeerIdentity *source_peer,
1421                                        struct GNUNET_PeerIdentity *destination_peer,
1422                                        struct GNUNET_PeerIdentity *trail,
1423                                        unsigned int trail_length,
1424                                        struct FriendInfo *target_friend)
1425 {
1426   struct P2PPendingMessage *pending;
1427   struct PeerAddTrailMessage *adm;
1428   struct GNUNET_PeerIdentity *peer_list;
1429   size_t msize;
1430   
1431   msize = sizeof (struct PeerAddTrailMessage) + 
1432           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1433   
1434   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1435   {
1436     GNUNET_break (0);
1437     return;
1438   }
1439   
1440   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1441   {  
1442     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1443                                 1, GNUNET_NO);
1444   }
1445   
1446   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1447   pending->importance = 0;    /* FIXME */
1448   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1449   adm = (struct PeerAddTrailMessage *) &pending[1];
1450   pending->msg = &adm->header;
1451   adm->header.size = htons (msize);
1452   adm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL);
1453   memcpy (&(adm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1454   memcpy (&(adm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1455   adm->trail_length = htonl (trail_length);
1456   
1457   if (trail_length > 0)
1458   {
1459     peer_list = (struct GNUNET_PeerIdentity *)&adm[1];
1460     memcpy (peer_list, trail, sizeof (struct GNUNET_PeerIdentity) * trail_length);
1461   }
1462   
1463   /* Send the message to chosen friend. */
1464   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1465   target_friend->pending_count++;
1466   process_friend_queue (target_friend);
1467 }
1468
1469
1470 /**
1471  * FIXME: CONGESTION: check the code once basic code is all correct. s
1472  * FIXME: call GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1473  * In case the friend chosen in select_random_friend() is congested or
1474  * has crossed trail_threshold, then get next friend which is not congested or 
1475  * has not crossed trail threshold from friend peermap. 
1476  * @param current_index Index in finger peermap chosen randomly
1477  * @param friend_peermap_size Total number of entries in friend peermap.
1478  * @param count Total number of time this function has been called, in case
1479  *              count == sizeof(friend_peermap) - 1, it means none of the friends are free. 
1480  * @return Friend Friend found.
1481  *         NULL in case all the friends are congested or have crossed trail threshold.
1482  */
1483 static struct FriendInfo *
1484 get_next_friend (unsigned int current_index, 
1485                  unsigned int friend_peermap_size,
1486                  unsigned int count)
1487 {
1488   struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1489   struct GNUNET_PeerIdentity key_ret;
1490   struct FriendInfo *friend;
1491   int j = 0;
1492   
1493   current_index = (current_index + 1) % friend_peermap_size;
1494   iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1495   while(j < (current_index))
1496   {
1497     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
1498     {
1499       j++;
1500     }
1501     else 
1502       return NULL;
1503   }  
1504
1505   if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1506   {
1507     if ((friend->trails_count > TRAIL_THROUGH_FRIEND_THRESHOLD) ||
1508         (0 != GNUNET_TIME_absolute_get_remaining (friend->congestion_duration).rel_value_us))
1509     {
1510       count++;
1511       if (count == (friend_peermap_size -1))
1512         return NULL;
1513       else
1514         return get_next_friend (j,friend_peermap_size,count);
1515     }
1516     return friend;
1517   }
1518   else
1519     return NULL;
1520 }
1521
1522
1523 /** 
1524  * FIXME: CONGESTION: check the code once basic code is all correct. 
1525  * FIXME: call GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1526  * Randomly choose one of your friends from the friends_peer map
1527  * @return Friend Randomly chosen friend. 
1528  *         NULL in case friend peermap is empty, or all the friends are either
1529  *              congested or have crossed trail threshold. 
1530  */
1531 static struct FriendInfo *
1532 select_random_friend ()
1533 {  
1534   unsigned int current_size;
1535   unsigned int *index; 
1536   unsigned int j = 0;
1537   struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1538   struct GNUNET_PeerIdentity key_ret;
1539   struct FriendInfo *friend;
1540   
1541   current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
1542   if (0 == current_size)
1543     return NULL;
1544   
1545   index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1546   iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1547  
1548   while(j < (*index))
1549   {
1550     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
1551     {
1552       j++;
1553     }
1554     else 
1555     {
1556       return NULL;
1557     }
1558   }  
1559
1560   if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1561   {
1562     if ((TRAIL_THROUGH_FRIEND_THRESHOLD == friend->trails_count) ||
1563         (0 != GNUNET_TIME_absolute_get_remaining (friend->congestion_duration).rel_value_us))
1564     {
1565       return get_next_friend (*index, current_size, 1);
1566     } 
1567     return friend;
1568   }
1569   else
1570     return NULL;
1571 }
1572
1573
1574 /**
1575  * Compute finger_identity to which we want to setup the trail
1576  * @return finger_identity 
1577  */
1578 static uint64_t 
1579 compute_finger_identity()
1580 {
1581   uint64_t my_id64 ;
1582
1583   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1584   my_id64 = GNUNET_ntohll (my_id64);
1585   return (my_id64 + (unsigned long) pow (2, current_search_finger_index));
1586 }
1587
1588
1589 /**
1590  * Compute immediate predecessor identity in the network.
1591  * @return peer identity of immediate predecessor.
1592  */
1593 static uint64_t 
1594 compute_predecessor_identity()
1595 {
1596   uint64_t my_id64;
1597
1598   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1599   my_id64 = GNUNET_ntohll (my_id64);
1600   return (my_id64 -1);
1601 }
1602
1603
1604 /**
1605  * Ping your successor to verify if it is still your successor or not. 
1606  */
1607 static void
1608 send_verify_successor_message()
1609 {
1610   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1611   struct GNUNET_PeerIdentity key_ret;
1612   struct FriendInfo *target_friend;
1613   struct GNUNET_PeerIdentity next_hop;
1614   struct GNUNET_PeerIdentity *peer_list;
1615   struct FingerInfo *finger;
1616   unsigned int finger_index;
1617   int flag = 0;
1618   
1619   /* Find the successor from the finger peermap.*/
1620   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
1621   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1622   {
1623     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1624                                                                  (const void **)&finger)) 
1625     {
1626       if (0 == finger->finger_map_index)
1627       {
1628         flag = 1;
1629         break;
1630       }
1631     }
1632   }
1633   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1634   
1635   /* Either you don't have a successor or you are your own successor, then don't
1636    send a successor message. */
1637   if(( flag == 0) ||
1638     (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, &(finger->finger_identity))))
1639   {
1640     return;
1641   }
1642
1643   if (finger->first_trail_length > 0)
1644   {
1645     struct TrailPeerList *iterate;
1646     int i = 0;
1647     peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->first_trail_length);
1648     iterate = finger->first_trail_head;
1649     
1650     while ( i < (finger->first_trail_length))
1651     {     
1652       memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity));
1653       iterate = iterate->next;
1654       i++;
1655     }
1656     memcpy (&next_hop, &peer_list[0], sizeof (struct GNUNET_PeerIdentity));
1657     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
1658   }
1659   else
1660   {
1661     /* If trail length = 0, then our successor is our friend. */
1662     peer_list = NULL;
1663     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1664                                                       &(finger->finger_identity));
1665   }
1666    
1667   GDS_NEIGHBOURS_send_verify_successor (&my_identity,
1668                                         &(finger->finger_identity),
1669                                         target_friend,
1670                                         peer_list,
1671                                         finger->first_trail_length);  
1672 }
1673
1674
1675 /**
1676  * Choose a random friend and start looking for the trail to reach to 
1677  * finger identity through this random friend. 
1678  *
1679  * @param cls closure for this task
1680  * @param tc the context under which the task is running
1681  */
1682 static void
1683 send_find_finger_trail_message (void *cls,
1684                                 const struct GNUNET_SCHEDULER_TaskContext *tc)
1685 {
1686   struct FriendInfo *target_friend;
1687   struct GNUNET_TIME_Relative next_send_time;
1688   uint64_t finger_identity;
1689   unsigned int finger_map_index;
1690   
1691   next_send_time.rel_value_us =
1692       DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1693       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1694                                 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
1695   find_finger_trail_task =
1696       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1697                                     NULL);
1698   
1699   target_friend = select_random_friend (); 
1700   if (NULL == target_friend) 
1701   {
1702     return;
1703   }
1704   
1705   if (PREDECESSOR_FINGER_ID == current_search_finger_index)
1706   {
1707     finger_identity = compute_predecessor_identity();  
1708   }
1709   else
1710   {
1711     finger_identity = compute_finger_identity();
1712   }
1713     
1714   finger_map_index = current_search_finger_index;
1715   GDS_NEIGHBOURS_send_trail_setup (&my_identity, finger_identity, &(target_friend->id),
1716                                    &my_identity, target_friend, 0, NULL, finger_map_index);
1717 }
1718
1719
1720 /**
1721  * FIXME: TRAIL_LIST URGENT. Send trail teardown message along each of the trail. 
1722  * Scan the trail to check if any of my own friend is part of trail. If yes
1723  * then shortcut the trail, send a trail teardown for the discarded trail,
1724  * update trail list and trail_length. 
1725  * @param trail[Out] Current trail to reach to @a finger, will be updated
1726  *                          in case we compress the trail. 
1727  * @param trail_length[Out] Number of peers in @a finger_trail, will be updated
1728  *                          in case we compress the trail. 
1729  * @param finger Finger identity 
1730  */
1731 static void
1732 scan_and_compress_trail (struct GNUNET_PeerIdentity *trail,
1733                          unsigned int *trail_length,
1734                          const struct GNUNET_PeerIdentity *finger)
1735 {
1736   int i;
1737   struct FriendInfo *target_friend;
1738    
1739   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,finger))
1740   {
1741     /* Here you don't send a trail teardown as no one added this in their
1742      routing table. */
1743     *trail_length = 0;
1744     trail = NULL;
1745     return;    
1746   }
1747   if (GNUNET_CONTAINER_multipeermap_get (friend_peermap, finger))
1748   {
1749     int discarded_trail_length = *trail_length;
1750     target_friend = GNUNET_CONTAINER_multipeermap_get(friend_peermap, &trail[0]);
1751     GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, trail,
1752                                         discarded_trail_length, target_friend, finger);
1753     *trail_length = 0;
1754     trail = NULL;
1755     return;
1756   }
1757  
1758   i = *trail_length - 1;
1759
1760   while (i > 1)
1761   {
1762     if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[i]))
1763     {
1764       /* This element of trail is not my friend. */
1765       i--;
1766     }
1767     else
1768     {
1769       /* A --> B(friend 1) --> C(friend 2)--> D ---> E, then we can rewrite the trail as
1770        * C --> D --> E,
1771        * Now, we should remove the entry from A's routing table, B's routing table
1772        * and update the entry in C's routing table. Rest everything will be same.
1773        * C's routing table should have source peer as the prev.hop. 
1774        */
1775       struct GNUNET_PeerIdentity *discarded_trail;
1776       struct FriendInfo *target_friend;
1777       int discarded_trail_length;
1778       int j = 0;
1779
1780       discarded_trail_length = i - 1;
1781       discarded_trail = GNUNET_malloc (discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1782       memcpy (discarded_trail, trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1783       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[0]);
1784       GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, discarded_trail,
1785                                          discarded_trail_length, target_friend,
1786                                          &trail[i]);
1787      
1788       /* Copy the trail from index i to index trail_length -1 and change
1789        trail length and return */
1790       while (i < *trail_length)
1791       {
1792         memcpy (&trail[j], &trail[i], sizeof(struct GNUNET_PeerIdentity));
1793         j++;
1794         i++;
1795       }
1796       *trail_length = j+1;
1797       return;
1798     }
1799   }
1800   return;
1801 }
1802
1803
1804 /** 
1805  * FIXME: URGENT:Adapt the code for List of trails. 
1806  * Free finger and its trail.  
1807  * @param finger Finger to be freed.
1808  */
1809 static void
1810 free_finger (struct FingerInfo *finger)
1811 {
1812   struct TrailPeerList *peer;
1813
1814   if(finger->first_trail_head != NULL)
1815   {
1816     while (NULL != (peer = finger->first_trail_head))
1817     {
1818       GNUNET_CONTAINER_DLL_remove (finger->first_trail_head, finger->first_trail_tail, peer);
1819       GNUNET_free (peer);
1820     }
1821   }
1822   
1823   if (finger->second_trail_head != NULL)
1824   {
1825     while (NULL != (peer = finger->second_trail_head))
1826     {
1827       GNUNET_CONTAINER_DLL_remove (finger->second_trail_head, finger->second_trail_tail, peer);
1828       GNUNET_free (peer);
1829     }
1830     GNUNET_free (finger);
1831   }
1832 }
1833
1834
1835 /**
1836  * FIXME: URGENT: TRAIL_LIST First check if both the trails are present if yes 
1837  * then send it for both of them. Currently sending it only for one trail.
1838  * Send a trail teardown message for the trail of removed finger from the finger
1839  * peermap. 
1840  * @param existing_finger Finger to removed from the finger peermap.
1841  */
1842 static
1843 void send_trail_teardown (struct FingerInfo *removed_finger)
1844 {
1845  struct GNUNET_PeerIdentity *peer_list; 
1846  struct FriendInfo *friend; 
1847  struct TrailPeerList *finger_trail;
1848  int removed_finger_trail_length = removed_finger->first_trail_length;
1849  int i = 0;
1850
1851  if (removed_finger->first_trail_length == 0)
1852     return;
1853  
1854  finger_trail = removed_finger->first_trail_head;
1855  friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer)); 
1856  peer_list = GNUNET_malloc ( removed_finger_trail_length * sizeof (struct GNUNET_PeerIdentity));
1857  while (i < removed_finger->first_trail_length)
1858  {
1859    memcpy (&peer_list[i], &(finger_trail->peer), sizeof (struct GNUNET_PeerIdentity));
1860    finger_trail = finger_trail->next;
1861    i++;
1862  }
1863
1864  GDS_NEIGHBOURS_send_trail_teardown (&my_identity, &(removed_finger->finger_identity),
1865                                      peer_list, removed_finger_trail_length, friend,
1866                                      &(removed_finger->finger_identity)); 
1867 }
1868
1869
1870 /**
1871  * FIXME: URGENT Adapt it to trail list. 
1872  * Add a new trail to reach an existing finger in finger peermap and increment
1873  * the count of number of trails to reach to this finger. 
1874  * @param existing_finger Finger 
1875  * @param trail New trail to be added
1876  * @param trail_length Total number of peers in the trail. 
1877  */
1878 static
1879 void add_new_trail (struct FingerInfo *existing_finger, 
1880                     struct GNUNET_PeerIdentity *trail,
1881                     unsigned int trail_length)
1882 {
1883   int i;
1884   i = 0;
1885   /* FIXME: Here you need to understand which trail is there and which not. 
1886    In case first_trail_head != NULL, then that trail is present 
1887    so you should add the second one. Need to verify this logic. */    
1888   if (existing_finger->first_trail_head != NULL)
1889   {
1890     while (i < trail_length)
1891     {
1892       struct TrailPeerList *element;
1893       element = GNUNET_malloc (sizeof (struct TrailPeerList));
1894       element->next = NULL;
1895       element->prev = NULL;
1896     
1897       memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
1898       GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
1899       i++;
1900     }
1901   }
1902   else if (existing_finger->second_trail_head != NULL)
1903   {
1904     while (i < trail_length)
1905     {
1906       struct TrailPeerList *element;
1907       element = GNUNET_malloc (sizeof (struct TrailPeerList));
1908       element->next = NULL;
1909       element->prev = NULL;
1910     
1911       memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
1912       GNUNET_CONTAINER_DLL_insert_tail(existing_finger->first_trail_head, existing_finger->first_trail_tail, element);
1913       i++;
1914     }
1915   }  
1916   existing_finger->trail_count++;
1917 }
1918
1919
1920 /**
1921  * FIXME: URGENT: adapt it to TRAIL LIST. 
1922  * In case there are already maximum number of possible trail to reach to a finger,
1923  * then check if the new trail's length is lesser than any of the existing trails.
1924  * If yes then replace that old trail by new trail.
1925  * Note: Here we are taking length as a parameter to choose the best possible trail,
1926  * but there could be other parameters also like - 1. duration of existence of a
1927  * trail - older the better. 2. if the new trail is completely disjoint than the 
1928  * other trails, then may be choosing it is better. 
1929  * @param existing_finger
1930  * @param trail
1931  * @param trail_length
1932  * @return #GNUNET_YES 
1933  *         #GNUNET_NO
1934  */
1935 static 
1936 void select_and_replace_trail (struct FingerInfo *existing_finger, 
1937                                struct GNUNET_PeerIdentity *new_trail,
1938                                unsigned int new_trail_length)
1939 {
1940   if (existing_finger->first_trail_length == existing_finger->second_trail_length)
1941   {
1942     if (new_trail_length < existing_finger->first_trail_length)
1943     {
1944       /* Randomly choose one of the trail. FIXME:currently I am just replacing the
1945        first trail.*/
1946       struct TrailPeerList *peer;
1947       int i = 0;
1948         
1949       while (NULL != (peer = existing_finger->first_trail_head))
1950       {
1951         GNUNET_CONTAINER_DLL_remove (existing_finger->first_trail_head, existing_finger->first_trail_tail, peer);
1952         GNUNET_free (peer);
1953       } 
1954         
1955       while (i < new_trail_length)
1956       {
1957         struct TrailPeerList *element;
1958         element = GNUNET_malloc (sizeof (struct TrailPeerList));
1959         element->next = NULL;
1960         element->prev = NULL;
1961     
1962         memcpy (&(element->peer), &new_trail[i], sizeof(struct GNUNET_PeerIdentity));
1963         GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
1964         i++;
1965       }
1966     }
1967   }
1968   else if ((new_trail_length < existing_finger->second_trail_length) && 
1969           (existing_finger->second_trail_length < existing_finger->first_trail_length))
1970   {
1971     /* Replace the first trail by the new trail. */
1972     struct TrailPeerList *peer;
1973     int i = 0;
1974         
1975     while (NULL != (peer = existing_finger->first_trail_head))
1976     {
1977       GNUNET_CONTAINER_DLL_remove (existing_finger->first_trail_head, existing_finger->first_trail_tail, peer);
1978       GNUNET_free (peer);
1979     } 
1980         
1981     while (i < new_trail_length)
1982     {
1983       struct TrailPeerList *element;
1984       element = GNUNET_malloc (sizeof (struct TrailPeerList));
1985       element->next = NULL;
1986       element->prev = NULL;
1987     
1988       memcpy (&(element->peer), &new_trail[i], sizeof(struct GNUNET_PeerIdentity));
1989       GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
1990       i++;
1991     }
1992   }
1993   else if ( (new_trail_length < existing_finger->first_trail_length) &&
1994            (existing_finger->first_trail_length < existing_finger->second_trail_length))
1995   {
1996     /* Replace the second trail by the new trail. */
1997     struct TrailPeerList *peer;
1998     int i = 0;
1999         
2000     while (NULL != (peer = existing_finger->second_trail_head))
2001     {
2002       GNUNET_CONTAINER_DLL_remove (existing_finger->second_trail_head, existing_finger->second_trail_tail, peer);
2003       GNUNET_free (peer);
2004     }
2005         
2006     while (i < new_trail_length)
2007     {
2008       struct TrailPeerList *element;
2009       element = GNUNET_malloc (sizeof (struct TrailPeerList));
2010       element->next = NULL;
2011       element->prev = NULL;
2012     
2013       memcpy (&(element->peer), &new_trail[i], sizeof(struct GNUNET_PeerIdentity));
2014       GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
2015       i++;
2016      }
2017   } 
2018 }
2019
2020
2021 /**
2022  * FIXME: URGENT: Adapat it for trail list. 
2023  * FIXME: If we remove a finger which is our friend, then how should we handle it. 
2024  * Ideally only in case if the trail_length > 0,we increment the trail count
2025  * of the first friend in the trail to reach to the finger. in case finger is
2026  * our friend then trail length = 0, and hence, we have never incremented the
2027  * trail count associated with that friend. 
2028  * Decrement the trail count for the first friend to reach to the finger. 
2029  * @param finger
2030  */
2031 static void
2032 decrement_friend_trail_count (struct FingerInfo *finger)
2033 {
2034   struct FriendInfo *first_trail_friend;
2035   struct FriendInfo *second_trail_friend;
2036   
2037   if(finger->first_trail_head != NULL)
2038   {
2039     first_trail_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
2040                                                             &(finger->first_trail_head->peer));
2041     first_trail_friend->trails_count--;
2042   }
2043     
2044   if(finger->second_trail_head != NULL)
2045   {
2046     second_trail_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
2047                                                            &(finger->second_trail_head->peer));
2048     second_trail_friend->trails_count--;
2049   }
2050   
2051 #if 0
2052   /* We will not need this variable any more, all_friends_trail_threshold,
2053    FIXME: REMOVE IT. */
2054   if (GNUNET_YES == all_friends_trail_threshold)
2055   {
2056     all_friends_trail_threshold = GNUNET_NO;
2057     /* FIXME; Here you should reschedule the send_find_finger_task here. or
2058      make a call.*/
2059   }
2060 #endif
2061 }
2062
2063
2064 /**
2065  * FIXME: create a different data structure for storing the peer ids here. 
2066  * Select the closest finger. Used for both predecessor and other fingers..
2067  * But internally calls different functions for predecessor and other fingers.
2068  * @param existing_finger Finger in finger peermap. 
2069  * @param new_finger New finger identity
2070  * @param finger_map_index Index in finger peermap where @a existing_finger is stored.
2071  * @return #GNUNET_YES if the new finger is closest.
2072  *         #GNUNET_NO if the old finger is closest.
2073  *         #GNUNET_SYSERR in case our own identity is closest (should never happen).
2074  */
2075 static 
2076 int select_finger (struct FingerInfo *existing_finger,
2077                    const struct GNUNET_PeerIdentity *new_finger,
2078                    unsigned int finger_map_index)
2079 {
2080   struct Sorting_List peers[3]; /* 3 for existing_finger, new_finger, my_identity */
2081   struct Sorting_List *closest_finger; 
2082   uint64_t value;
2083   int k;
2084   
2085   for (k = 0; k < 3; k++)
2086     peers[k].data = 0;
2087   
2088   /* Add your entry to peers. */
2089   memcpy (&peers[0], &my_identity, sizeof (uint64_t));
2090   peers[0].type = MY_ID;
2091   peers[0].data = NULL;
2092   
2093   /* Add existing_finger identity to the peers. */
2094   memcpy (&peers[1], &(existing_finger->finger_identity), sizeof (uint64_t));
2095   peers[1].type = FINGER;
2096   peers[1].data = existing_finger;
2097   
2098   /* Add new_finger identity to the peers. s*/
2099   memcpy (&peers[2], &new_finger, sizeof (uint64_t));
2100   peers[2].type = VALUE;
2101   peers[2].data = NULL;
2102   
2103   memcpy (&value, &my_identity, sizeof (uint64_t));
2104   qsort (&peers, 3, sizeof (struct Sorting_List), &compare_peer_id);
2105   
2106   if (PREDECESSOR_FINGER_ID == finger_map_index)
2107     closest_finger = find_closest_predecessor (peers, value, 3);
2108   else
2109     closest_finger = find_closest_successor (peers, value, 3);
2110   
2111   if (closest_finger->type  == FINGER)
2112   {
2113     return GNUNET_NO;
2114   }
2115   else if (closest_finger->type == VALUE)
2116   {
2117     return GNUNET_YES;
2118   }
2119   else if (closest_finger->type == MY_ID);
2120   {
2121     return GNUNET_SYSERR;  
2122   }
2123 }
2124
2125
2126 /**
2127  * FIXME: Better name, and make the code more cleaner.
2128  * Compare the new finger entry added and our successor. 
2129  * @return #GNUNET_YES if same.
2130  *         #GNUNET_NO if not. 
2131  */
2132 static int
2133 compare_new_entry_and_successor (const struct GNUNET_PeerIdentity *new_finger,
2134                                  int finger_map_index)
2135 {
2136   int successor_flag = 0;
2137   struct FingerInfo *successor_finger;
2138   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2139   int i;
2140
2141   if (PREDECESSOR_FINGER_ID == finger_map_index)
2142     return GNUNET_NO;
2143   
2144   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 
2145   for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++)
2146   {
2147     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL,
2148                                                                  (const void **)&successor_finger)) 
2149     {
2150       if (successor_finger->finger_map_index == 0)
2151       {
2152         successor_flag = 1;
2153         break;
2154       }
2155     }
2156   }
2157   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2158   
2159   /* Ideally we should never reach here. */
2160   if (successor_flag == 0)
2161   {
2162     GNUNET_break (0);
2163     return GNUNET_NO;
2164   }
2165   
2166   if (0 == GNUNET_CRYPTO_cmp_peer_identity (new_finger, &(successor_finger->finger_identity)))
2167     return GNUNET_YES;
2168   else
2169     return GNUNET_NO;
2170 }
2171
2172
2173 /**
2174  * FIXME: URGENT: Adapat it for trail list. 
2175  * Add a new entry in finger table. 
2176  * @param finger_identity PeerIdentity of the new finger
2177  * @param finger_trail Trail to reach to the finger, can be NULL in case I am my own
2178  *                     finger.
2179  * @param finger_trail_length Number of peers in the trail, can be 0 in case finger
2180  *                            is a friend or I am my own finger.
2181  * @param finger_map_index Index in finger map. 
2182  */
2183 static int
2184 add_new_entry (const struct GNUNET_PeerIdentity *finger_identity,
2185                struct GNUNET_PeerIdentity *finger_trail,
2186                uint32_t finger_trail_length,
2187                uint32_t finger_map_index)
2188 {
2189   struct FriendInfo *first_friend_trail;
2190   struct FingerInfo *new_finger_entry;
2191   int i;
2192   
2193   /* Add a new entry. */
2194   new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
2195   memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity));
2196   new_finger_entry->finger_map_index = finger_map_index;
2197   new_finger_entry->first_trail_length = finger_trail_length;
2198   new_finger_entry->trail_count = 1;
2199   
2200   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,finger_identity)) /* finger_trail is NULL in case I am my own finger identity. */
2201   {
2202     /* Incrementing the friend trails count. */
2203     if (finger_trail_length > 0)   
2204     {
2205       first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[0]);
2206       first_friend_trail->trails_count++;
2207     }
2208     else
2209     {
2210       /* It means the finger is my friend. */
2211       first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, finger_identity);
2212       first_friend_trail->trails_count++;
2213     }
2214     new_finger_entry->first_friend_trails_count = first_friend_trail->trails_count; 
2215     
2216     /* Copy the trail. */
2217     i = 0;
2218     while (i < finger_trail_length)
2219     {
2220       struct TrailPeerList *element;
2221       element = GNUNET_malloc (sizeof (struct TrailPeerList));
2222       element->next = NULL;
2223       element->prev = NULL;
2224     
2225       memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity));
2226       GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->first_trail_head, new_finger_entry->first_trail_tail, element);
2227       i++;
2228     }
2229   }
2230  
2231   return GNUNET_CONTAINER_multipeermap_put (finger_peermap,
2232                                             &(new_finger_entry->finger_identity),
2233                                             new_finger_entry,
2234                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);    
2235 }
2236
2237
2238 /**
2239  * Choose the closest finger between existing finger and new finger.
2240  * If the new finger is closest, then send a trail_teardown message along 
2241  * existing_finger's trail. In case both the id's are same, and there is a place
2242  * to add more trails, then store both of them. In case there is no space to 
2243  * store any more trail, then choose the best trail (best - depends on length in
2244  * current_implementation) and discard the others. 
2245  * @param existing_finger
2246  * @param new_finger Existing finger in finger_peermap for @a finger_map_index
2247  * @param trail Trail to reach from me to @a new_finger
2248  * @param trail_length Total number of peers in @a trail.
2249  * @param finger_map_index Index in finger peermap. 
2250  * @return #GNUNET_YES In case we want to store the new entry.
2251  *         #GNUNET_NO In case we want the existing entry.
2252  *         #GNUNET_SYSERR Error. 
2253  */
2254 static 
2255 int select_closest_finger (struct FingerInfo *existing_finger,
2256                            const struct GNUNET_PeerIdentity *new_finger,
2257                            struct GNUNET_PeerIdentity *trail,
2258                            unsigned int trail_length,
2259                            unsigned int finger_map_index)
2260 {
2261   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger))
2262   {
2263     /* New entry and existing entry are same. */
2264     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), &my_identity))
2265     {
2266       /* If existing_finger is my_identity then trail_length = 0, trail = NULL. In
2267        this case you don't need to check the trails. Exit. */
2268       return GNUNET_NO;
2269     }
2270     if (trail_length > 0)
2271     {
2272       scan_and_compress_trail (trail, &trail_length, new_finger);
2273     }
2274     if (existing_finger->trail_count < TRAIL_COUNT)
2275     {
2276       add_new_trail (existing_finger, trail, trail_length);
2277       return GNUNET_NO;
2278     }
2279     else
2280     {
2281       select_and_replace_trail (existing_finger, trail, trail_length);
2282       return GNUNET_NO;
2283     }  
2284   }
2285   else if (GNUNET_YES == select_finger (existing_finger, new_finger, finger_map_index))
2286   {
2287     /* New finger is the closest finger. */
2288     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, new_finger))
2289     {
2290       /* FIXME: Here in case the new finger is my_identity and old entry is not,
2291        should we keep the old entry even if the old entry is not the closest? */
2292       return GNUNET_NO;    
2293     }
2294     send_trail_teardown (existing_finger);
2295     decrement_friend_trail_count (existing_finger);
2296     free_finger (existing_finger);
2297     
2298     if (trail_length > 0)
2299     {
2300       scan_and_compress_trail (trail, &trail_length, new_finger);
2301     }
2302     return GNUNET_YES;
2303   }
2304   else if (GNUNET_NO == select_finger (existing_finger, new_finger,finger_map_index))
2305   {
2306     /* existing_finger is the closest finger. */
2307     return GNUNET_NO;
2308   }
2309   return GNUNET_SYSERR;
2310 }
2311
2312
2313 /**
2314  * FIXME: TRAIL LIST urgent. 
2315  * Check if there is already an entry for finger map index in finger table.
2316  * If yes then choose the closest finger. 
2317  * @param finger_identity Peer Identity of finger. 
2318  * @param finger_trail Trail to reach from me to @a finger_identity
2319  * @param finger_trail_length Total number of peers in finger_trail.
2320  * @param finger_map_index Index in finger_peermap.
2321  * @return #GNUNET_YES if the new entry is added.
2322  *         #GNUNET_NO if the new entry is discarded.
2323  */
2324 static 
2325 int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2326                       struct GNUNET_PeerIdentity *finger_trail,
2327                       uint32_t finger_trail_length,
2328                       uint32_t finger_map_index)
2329 {
2330   struct FingerInfo *existing_finger;
2331   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2332   int i;
2333   int old_entry_found = GNUNET_NO;
2334   int new_entry_added = GNUNET_NO;  
2335   
2336   /* Check if there is already an entry for the finger map index in the finger peer map. */
2337   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 
2338   for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++)
2339   {
2340     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL,
2341                                                                  (const void **)&existing_finger)) 
2342     {
2343       if (existing_finger->finger_map_index == finger_map_index)
2344       {
2345         old_entry_found = GNUNET_YES;
2346         if ( GNUNET_NO == select_closest_finger (existing_finger, finger_identity, 
2347                                                  finger_trail, finger_trail_length,
2348                                                  finger_map_index)) 
2349           goto update_current_search_finger_index;
2350         else
2351           break;
2352       }
2353     } 
2354   }
2355   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2356   
2357   if (GNUNET_NO == old_entry_found)
2358   {
2359     if (finger_trail_length > 0)
2360     {
2361       scan_and_compress_trail (finger_trail, &finger_trail_length, finger_identity);
2362     }
2363   }
2364   
2365   /* FIXME: handle the case when addition in peer map failed. */
2366   if(GNUNET_OK == add_new_entry (finger_identity,finger_trail,finger_trail_length, finger_map_index))
2367     new_entry_added = GNUNET_YES;
2368   else
2369     return GNUNET_NO;
2370   
2371   update_current_search_finger_index:
2372   if (0 == finger_map_index)
2373   {
2374     current_search_finger_index = PREDECESSOR_FINGER_ID;
2375     if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,finger_identity))
2376       send_verify_successor_message();
2377   }
2378   else if (GNUNET_YES == compare_new_entry_and_successor (finger_identity,finger_map_index))
2379   {
2380     current_search_finger_index = 0;
2381   }
2382   else 
2383   {
2384     current_search_finger_index = current_search_finger_index - 1;
2385   }
2386   
2387   return new_entry_added;
2388 }
2389
2390
2391 /**
2392  * FIXME: URGNET: adapt it for trail list. 
2393  * Check if the successor chosen is congested or has crossed trail threshold. 
2394  * @param successor Successor to be checked.
2395  * @return #GNUNET_YES in case its is either congested or has crossed trail threshold.
2396  *         #GNUNET_NO if its good to go. 
2397  */
2398 static int
2399 check_friend_threshold_and_congestion (struct Sorting_List *successor)
2400 {  
2401   struct FriendInfo *friend;
2402   
2403   if (successor->type == FRIEND)
2404   {
2405     friend = successor->data;
2406   }
2407   else if (successor->type == FINGER)
2408   {
2409     struct FingerInfo *finger = successor->data;
2410     if (finger->first_trail_length > 0)
2411     {
2412       friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
2413                                                   &(finger->first_trail_head->peer));
2414     }
2415     else
2416     {
2417       if (0 != GNUNET_CRYPTO_cmp_peer_identity(&my_identity, &finger->finger_identity))
2418        friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger->finger_identity));
2419       else
2420         return GNUNET_YES;
2421     }
2422   }
2423   
2424   if ((friend->trails_count == TRAIL_THROUGH_FRIEND_THRESHOLD)||
2425       ((0 != GNUNET_TIME_absolute_get_remaining (friend->congestion_duration).rel_value_us)))
2426   {
2427     return GNUNET_YES;
2428   }
2429   else
2430     return GNUNET_NO;
2431 }
2432
2433
2434 /**
2435  * Find the next successor for key_value as the earlier selected successor is either
2436  * congested or have crossed trail threshold. 
2437  * @param all_known_peers Array that contains my_identity, value, friends and fingers.
2438  * @param array_size Total number of entries in @a all_known_peers.
2439  * @param start_index Index at which original successor is located. 
2440  * @param search_index Index at which our possible current successor is located.
2441  * @param count Number of times this function has been called. 
2442  * @return successor, in case found.
2443  *         NULL, in case of error.  
2444  */
2445 static struct Sorting_List *
2446 get_next_successor (struct Sorting_List *all_known_peers,
2447                     unsigned int array_size, int start_index,
2448                     int search_index, int count)
2449 {
2450   struct Sorting_List *next_peer;
2451   
2452   if (search_index == start_index)
2453     return NULL;
2454   next_peer = GNUNET_malloc (sizeof (struct Sorting_List));
2455   memcpy (next_peer, &all_known_peers[search_index], sizeof (struct Sorting_List));
2456   
2457   if (next_peer->type == MY_ID)
2458     return next_peer;
2459   
2460   if ((next_peer->type == VALUE) || 
2461      (GNUNET_YES == check_friend_threshold_and_congestion (next_peer)))
2462   {
2463     search_index = (search_index + 1) % array_size;
2464     count++;
2465     return get_next_successor (all_known_peers, array_size, start_index, search_index, count);
2466   }
2467   else 
2468     return next_peer;
2469 }
2470
2471
2472 /**
2473  * Search the current location of successor in all_known_peers array.
2474  * @param all_known_peers Array which contains my_id, key value, friends and fingers.
2475  * @param array_size Total number of entries in @a all_known_peers
2476  * @param search_value 64 bit value of successor. 
2477  * @return Index of array at which value is stored,
2478  *         #GNUNET_SYSERR in case of error.
2479  */
2480 static int
2481 get_successor_location (struct Sorting_List *all_known_peers, size_t array_size,
2482                      uint64_t search_value)
2483 {
2484   int k;
2485   
2486   while (0 != memcmp (&all_known_peers[k].data, &search_value, sizeof (uint64_t)))
2487   {
2488     k++;
2489   }
2490   if (k == array_size)
2491     return GNUNET_SYSERR;
2492   else 
2493     return k;
2494 }
2495
2496
2497 /**
2498  * Initialize all_known_peers with my_id, value, friends and fingers. 
2499  * @param all_known_peers Empty all_known_peers
2500  * @param size Total number of elements in all_known_peers
2501  */
2502 static void
2503 init_all_known_peers (struct Sorting_List *all_known_peers, int size, uint64_t value)
2504 {
2505   struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
2506   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2507   struct GNUNET_PeerIdentity key_ret;
2508   struct FriendInfo *friend;
2509   struct FingerInfo *finger;
2510   unsigned int finger_index;
2511   unsigned int friend_index;
2512   int k;
2513   int j; 
2514   
2515   for (k = 0; k < size; k++)
2516     all_known_peers[k].peer_id = 0;
2517   
2518   /* Copy your identity at 0th index in all_known_peers. */
2519   j = 0;
2520   memcpy (&(all_known_peers[j].peer_id), &my_identity, sizeof (uint64_t));
2521   all_known_peers[j].type = MY_ID;
2522   all_known_peers[j].data = 0;
2523   j++;
2524   
2525   /* Copy value */
2526   all_known_peers[j].peer_id = value;
2527   all_known_peers[j].type = VALUE;
2528   all_known_peers[j].data = 0;
2529   j++;
2530   
2531   /* Iterate over friend peer map and copy all the elements into array. */
2532   friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); 
2533   for (friend_index = 0; friend_index < GNUNET_CONTAINER_multipeermap_size (friend_peermap); friend_index++)
2534   {
2535     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(friend_iter,&key_ret,(const void **)&friend)) 
2536     {
2537       memcpy (&(all_known_peers[j].peer_id), &(friend->id), sizeof (uint64_t));
2538       all_known_peers[j].type = FRIEND;
2539       all_known_peers[j].data = friend;
2540       j++;
2541     }
2542   }
2543   
2544  
2545   /* Iterate over finger map and copy all the entries into all_known_peers array. */
2546   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
2547   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
2548   {
2549     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(finger_iter,&key_ret,(const void **)&finger)) 
2550     {
2551       memcpy (&(all_known_peers[j].peer_id), &(finger->finger_identity), sizeof (uint64_t));
2552       all_known_peers[j].type = FINGER;
2553       all_known_peers[j].data = finger;
2554       j++;
2555     }
2556   }
2557   
2558   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2559   GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter); 
2560 }
2561
2562
2563 /** 
2564  * FIXME: 1. In case all the peers are congested/threshold then by default my_id is
2565  * chosen. There is no limit on number of peers which can keep me as their finger.
2566  * Should there be limit? If yes then we need to keep a counter of number of peers
2567  * that keep me as fingers. This counter may/may not give the correct value as
2568  * that peer may have found a better finger. So should reset the limit at some
2569  * interval. 
2570  * 2. Change the finger code, TRAIL_LIST. URGENT
2571  * Find closest successor for the value.
2572  * @param value Value for which we are looking for successor
2573  * @param[out] current_destination set to my_identity in case I am the final destination,
2574  *                                 set to friend identity in case friend is final destination,
2575  *                                 set to first friend to reach to finger, in case finger
2576  *                                 is final destination. 
2577  * @param[out] current_source set to my_identity.
2578  * @param finger_map_index Index in finger peer map. 
2579  * @return Peer identity of next hop to send trail setup message to 
2580  */
2581 static struct GNUNET_PeerIdentity *
2582 find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2583                struct GNUNET_PeerIdentity *current_source, unsigned int finger_map_index)
2584 {
2585   struct Sorting_List *successor;
2586   unsigned int size;
2587   
2588   size = GNUNET_CONTAINER_multipeermap_size (friend_peermap)+
2589          GNUNET_CONTAINER_multipeermap_size (finger_peermap)+
2590          2;
2591   
2592   struct Sorting_List all_known_peers[size];
2593   init_all_known_peers (all_known_peers, size, value);
2594   qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id);
2595   
2596   if (PREDECESSOR_FINGER_ID == finger_map_index)
2597     successor = find_closest_predecessor (all_known_peers, value, size);
2598   else
2599     successor = find_closest_successor (all_known_peers, value, size);
2600   
2601   if ((successor->type != MY_ID) && (successor->type != VALUE))
2602   {
2603     if (GNUNET_YES == check_friend_threshold_and_congestion (successor))
2604     {
2605       int search_index = get_successor_location (all_known_peers, size, successor->peer_id);
2606       successor = get_next_successor (all_known_peers, size, search_index, search_index + 1, 0);
2607     }
2608   }
2609   
2610   if (successor->type == MY_ID)
2611   {
2612     memcpy (current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2613     return &my_identity;
2614   }
2615   else if (successor->type == FRIEND)
2616   {
2617     struct FriendInfo *target_friend = successor->data;
2618     memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
2619     memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2620     return current_destination;
2621   }
2622   else if (successor->type == FINGER)
2623   {
2624     struct GNUNET_PeerIdentity *next_hop;
2625     struct FingerInfo *finger;
2626     finger = successor->data;
2627     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2628     
2629     if (finger->first_trail_length > 0)
2630     {
2631       struct TrailPeerList *iterator;
2632       iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
2633       iterator = finger->first_trail_head;
2634       memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
2635     }
2636     else /* This means finger is our friend. */
2637       memcpy (next_hop, &(finger->finger_identity), sizeof(struct GNUNET_PeerIdentity));
2638     
2639     memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
2640     memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2641     return next_hop;
2642   }
2643   else 
2644   {
2645     return NULL;
2646   }
2647 }
2648
2649
2650 /**  
2651  * Construct a Put message and send it to target_peer. 
2652  * @param key Key for the content  
2653  * @param block_type Type of the block
2654  * @param options Routing options
2655  * @param desired_replication_level Desired replication count
2656  * @param current_destination Next current destination which will get this message.
2657  * @param current_source Source for @a current_destination
2658  * @param target_peer Peer to which this message will be forwarded.
2659  * @param hop_count Number of hops traversed so far.
2660  * @param put_path_length Total number of peers in @a put_path
2661  * @param put_path Number of peers traversed so far 
2662  * @param expiration_time When does the content expire
2663  * @param data Content to store
2664  * @param data_size Size of content @a data in bytes
2665  */
2666 void
2667 GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
2668                          enum GNUNET_BLOCK_Type block_type,
2669                          enum GNUNET_DHT_RouteOption options,
2670                          uint32_t desired_replication_level,
2671                          struct GNUNET_PeerIdentity current_destination,
2672                          struct GNUNET_PeerIdentity current_source,
2673                          struct GNUNET_PeerIdentity *target_peer,
2674                          uint32_t hop_count,
2675                          uint32_t put_path_length,
2676                          struct GNUNET_PeerIdentity *put_path,
2677                          struct GNUNET_TIME_Absolute expiration_time,
2678                          const void *data, size_t data_size)
2679 {
2680   struct PeerPutMessage *ppm;
2681   struct P2PPendingMessage *pending;
2682   struct FriendInfo *target_friend;
2683   struct GNUNET_PeerIdentity *pp;
2684   size_t msize;
2685
2686   msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
2687           sizeof (struct PeerPutMessage);
2688   
2689   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2690   {
2691     put_path_length = 0;
2692     msize = data_size + sizeof (struct PeerPutMessage);
2693   }
2694   
2695   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2696   {
2697     GNUNET_break (0);
2698     return;
2699   }
2700   
2701   /* This is the first call made from clients file. So, we should search for the
2702      target_friend. */
2703   if (NULL == target_peer)
2704   {
2705     uint64_t key_value;
2706     struct GNUNET_PeerIdentity *next_hop;
2707    
2708     memcpy (&key_value, key, sizeof (uint64_t));
2709     next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST);
2710     if (0 == GNUNET_CRYPTO_cmp_peer_identity(next_hop, &my_identity)) 
2711     {
2712       /* I am the destination but we have already done datacache_put in client file.  */
2713       return;
2714     }
2715     else
2716       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);   
2717   }
2718   
2719   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2720   pending->timeout = expiration_time;
2721   ppm = (struct PeerPutMessage *) &pending[1];
2722   pending->msg = &ppm->header;
2723   ppm->header.size = htons (msize);
2724   ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
2725   ppm->options = htonl (options);
2726   ppm->block_type = htonl (block_type);
2727   ppm->hop_count = htonl (hop_count + 1);
2728   ppm->desired_replication_level = htonl (desired_replication_level);
2729   ppm->put_path_length = htonl (put_path_length);
2730   ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
2731   ppm->key = *key;
2732   ppm->current_destination = current_destination;
2733   ppm->current_source = current_source;
2734  
2735   pp = (struct GNUNET_PeerIdentity *) &ppm[1];
2736   if (put_path_length != 0)
2737   {
2738     memcpy (pp, put_path,
2739             sizeof (struct GNUNET_PeerIdentity) * put_path_length);
2740   }
2741   memcpy (&pp[put_path_length], data, data_size);
2742   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2743   target_friend->pending_count++;
2744   process_friend_queue (target_friend);
2745 }
2746
2747
2748 /** 
2749  * Construct a Get message and send it to target_peer. 
2750  * @param key Key for the content  
2751  * @param block_type Type of the block
2752  * @param options Routing options
2753  * @param desired_replication_level Desired replication count
2754  * @param current_destination Next current destination which will get this message.
2755  * @param current_source Source for @a current_destination
2756  * @param target_peer Peer to which this message will be forwarded.
2757  * @param hop_count Number of hops traversed so far.
2758  * @param data Content to store
2759  * @param data_size Size of content @a data in bytes
2760  * @param get_path_length Total number of peers in @a get_path
2761  * @param get_path Number of peers traversed so far
2762  */
2763 void
2764 GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
2765                          enum GNUNET_BLOCK_Type block_type,
2766                          enum GNUNET_DHT_RouteOption options,
2767                          uint32_t desired_replication_level,
2768                          struct GNUNET_PeerIdentity current_destination,
2769                          struct GNUNET_PeerIdentity current_source,
2770                          struct GNUNET_PeerIdentity *target_peer,
2771                          uint32_t hop_count,
2772                          uint32_t get_path_length,
2773                          struct GNUNET_PeerIdentity *get_path)
2774 {
2775   struct PeerGetMessage *pgm;
2776   struct P2PPendingMessage *pending;
2777   struct FriendInfo *target_friend;
2778   struct GNUNET_PeerIdentity *gp;
2779   size_t msize;
2780
2781   msize = sizeof (struct PeerGetMessage) + 
2782           (get_path_length * sizeof (struct GNUNET_PeerIdentity));
2783   
2784   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2785   {
2786     GNUNET_break (0);
2787     return;
2788   }
2789   
2790   if (NULL == target_peer)
2791   {
2792     struct GNUNET_PeerIdentity *next_hop;
2793     uint64_t key_value;
2794     
2795     memcpy (&key_value, key, sizeof (uint64_t));
2796         // FIXME: endianess of key_value!?
2797     next_hop = find_successor (key_value, &current_destination, &current_source, PUT_GET_REQUEST);
2798     if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity,next_hop)) 
2799     {
2800       GDS_DATACACHE_handle_get (key,block_type, NULL, 0, 
2801                                 NULL, 0, 1, &my_identity, NULL,&my_identity);
2802       return;
2803     }
2804     else
2805     {
2806       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2807     }
2808   }
2809   
2810   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2811   pending->importance = 0;    /* FIXME */
2812   pgm = (struct PeerGetMessage *) &pending[1];
2813   pending->msg = &pgm->header;
2814   pgm->header.size = htons (msize);
2815   pgm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET);
2816   pgm->get_path_length = htonl (get_path_length);
2817   pgm->key = *key;
2818   pgm->current_destination = current_destination;
2819   pgm->current_source = current_source;
2820   pgm->hop_count = htonl (hop_count + 1);
2821   
2822   if (get_path != 0)
2823   {
2824     gp = (struct GNUNET_PeerIdentity *) &pgm[1];
2825     memcpy (gp, get_path, get_path_length * sizeof (struct GNUNET_PeerIdentity));
2826   }
2827   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2828   target_friend->pending_count++;
2829   process_friend_queue (target_friend);
2830 }
2831
2832
2833 /**
2834  * Send the get result to requesting client.
2835  * @param key Key of the requested data.
2836  * @param type Block type
2837  * @param target_peer Next peer to forward the message to. 
2838  * @param source_peer Peer which has the data for the key.
2839  * @param put_path_length Number of peers in @a put_path
2840  * @param put_path Path taken to put the data at its stored location.
2841  * @param get_path_length Number of peers in @a get_path
2842  * @param get_path Path taken to reach to the location of the key.
2843  * @param expiration When will this result expire?
2844  * @param data Payload to store
2845  * @param data_size Size of the @a data 
2846  */
2847 void 
2848 GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
2849                                 enum GNUNET_BLOCK_Type type,
2850                                 struct GNUNET_PeerIdentity *next_hop,
2851                                 struct GNUNET_PeerIdentity *source_peer,
2852                                 unsigned int put_path_length,
2853                                 const struct GNUNET_PeerIdentity *put_path,
2854                                 unsigned int get_path_length,
2855                                 struct GNUNET_PeerIdentity *get_path,
2856                                 struct GNUNET_TIME_Absolute expiration,
2857                                 const void *data, size_t data_size)
2858 {
2859   struct PeerGetResultMessage *get_result;
2860   struct GNUNET_PeerIdentity *get_result_path;
2861   struct GNUNET_PeerIdentity *pp;
2862   struct P2PPendingMessage *pending;
2863   struct FriendInfo *target_friend;
2864   int current_path_index;
2865   size_t msize;
2866   
2867   msize = get_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
2868           sizeof (struct PeerPutMessage);
2869  
2870   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2871   {
2872     GNUNET_break (0);
2873     return;
2874   }
2875   
2876   if(get_path_length > 0)
2877   {
2878     current_path_index = search_my_index(get_path, get_path_length);
2879     if (GNUNET_SYSERR == current_path_index)
2880     {
2881       GNUNET_break (0);
2882       return;
2883     }
2884   }
2885   if (0 == current_path_index)
2886   {
2887     GDS_CLIENTS_handle_reply (expiration, key, get_path_length, get_path, put_path_length,
2888                               put_path, type, data_size, data);
2889     return;
2890   }
2891   
2892   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2893   pending->importance = 0;   
2894   get_result = (struct PeerGetResultMessage *)&pending[1];
2895   pending->msg = &get_result->header;
2896   get_result->header.size = htons (msize);
2897   get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT);
2898   get_result->key = *key;
2899   memcpy (&(get_result->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2900   get_result->expiration_time = expiration;
2901   
2902   if (get_path_length != 0)
2903   {
2904     get_result_path = (struct GNUNET_PeerIdentity *)&get_result[1];
2905     memcpy (get_result_path, get_path,
2906             sizeof (struct GNUNET_PeerIdentity) * get_path_length);
2907   }
2908   memcpy (&get_result_path[get_path_length], data, data_size);
2909   
2910   /* FIXME: Is this correct? */
2911   if (put_path_length != 0)
2912   {
2913     pp = (struct GNUNET_PeerIdentity *)&get_result_path[1];
2914     memcpy (pp, put_path,sizeof (struct GNUNET_PeerIdentity) * put_path_length);
2915   }
2916   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2917   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2918   target_friend->pending_count++;
2919   process_friend_queue (target_friend);
2920 }
2921
2922
2923 /**
2924  * Send trail rejection message to the peer which sent me a trail setup message. 
2925  * @param source_peer Source peer which wants to set up the trail.
2926  * @param finger_identity Value whose successor will be the finger of @a source_peer.
2927  * @param congested_peer Peer which has send trail rejection message.
2928  * @param next_hop Peer to which this message should be forwarded.
2929  * @param finger_map_index Index in @a source_peer finger peermap.
2930  * @param trail_peer_list Trail followed to reach from @a source_peer to next_hop,
2931  *                        NULL, in case the @a congested_peer was the first peer 
2932  *                        to which trail setup message was forwarded.
2933  * @param trail_length Number of peers in trail_peer_list. 
2934  * @param congestion_timeout Time duration for which @a congested peer will be
2935  *                           congested. 
2936  */
2937 void
2938 GDS_NEIGHBOURS_send_trail_rejection (const struct GNUNET_PeerIdentity *source_peer,
2939                                      uint64_t finger_identity,
2940                                      const struct GNUNET_PeerIdentity *congested_peer,
2941                                      const struct GNUNET_PeerIdentity *next_hop,
2942                                      unsigned int finger_map_index,
2943                                      struct GNUNET_PeerIdentity *trail_peer_list,
2944                                      unsigned int trail_length,
2945                                      struct GNUNET_TIME_Relative congestion_timeout)
2946 {
2947   struct PeerTrailRejectionMessage *trail_rejection;
2948   struct GNUNET_PeerIdentity *trail_list;
2949   struct P2PPendingMessage *pending;
2950   struct FriendInfo *target_friend;
2951   size_t msize;
2952   
2953   msize = trail_length * sizeof(struct GNUNET_PeerIdentity) +
2954           sizeof (struct PeerTrailRejectionMessage);
2955   
2956   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2957   {
2958     GNUNET_break (0);
2959     return;
2960   }
2961   
2962   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
2963   pending->importance = 0;    
2964   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
2965   trail_rejection = (struct PeerTrailRejectionMessage *) &pending[1]; 
2966   pending->msg = &trail_rejection->header;
2967   trail_rejection->header.size = htons (msize);
2968   trail_rejection->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
2969   memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2970   memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity));
2971   memcpy (&(trail_rejection->finger_identity_value), &finger_identity, sizeof (uint64_t));
2972   trail_rejection->finger_map_index = htonl (finger_map_index);
2973   trail_rejection->trail_length = htonl (trail_length);
2974   trail_rejection->congestion_time = congestion_timeout;
2975   
2976   if (trail_length != 0)
2977   {
2978     trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
2979     memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2980   }
2981   
2982   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2983   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2984   target_friend->pending_count++;
2985   process_friend_queue (target_friend);
2986 }
2987
2988
2989 /**
2990  * Core handler for P2P put messages. 
2991  * @param cls closure
2992  * @param peer sender of the request
2993  * @param message message
2994  * @return #GNUNET_OK to keep the connection open,
2995  *         #GNUNET_SYSERR to close it (signal serious error)
2996  */
2997 static int 
2998 handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2999                     const struct GNUNET_MessageHeader *message)
3000 {
3001   struct PeerPutMessage *put;
3002   struct GNUNET_PeerIdentity *put_path;
3003   struct GNUNET_HashCode test_key;
3004   enum GNUNET_DHT_RouteOption options;
3005   struct GNUNET_PeerIdentity current_destination;
3006   struct GNUNET_PeerIdentity current_source;
3007   struct GNUNET_PeerIdentity *next_hop;
3008   void *payload;
3009   size_t msize;
3010   uint32_t putlen;
3011   size_t payload_size;
3012   uint64_t key_value;
3013   
3014   msize = ntohs (message->size);
3015   if (msize < sizeof (struct PeerPutMessage))
3016   {
3017     GNUNET_break_op (0);
3018     return GNUNET_YES;
3019   }
3020   
3021   put = (struct PeerPutMessage *) message;
3022   putlen = ntohl (put->put_path_length);
3023    
3024   if ((msize <
3025        sizeof (struct PeerPutMessage) +
3026        putlen * sizeof (struct GNUNET_PeerIdentity)) ||
3027       (putlen >
3028        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3029   {
3030     GNUNET_break_op (0);
3031     return GNUNET_YES;
3032   }
3033
3034   current_destination = put->current_destination;
3035   current_source = put->current_source;
3036   put_path = (struct GNUNET_PeerIdentity *) &put[1];
3037   payload = &put_path[putlen];
3038   options = ntohl (put->options);
3039   payload_size = msize - (sizeof (struct PeerPutMessage) + 
3040                           putlen * sizeof (struct GNUNET_PeerIdentity));
3041   
3042   switch (GNUNET_BLOCK_get_key (GDS_block_context, ntohl (put->block_type),
3043                                 payload, payload_size, &test_key))
3044   {
3045     case GNUNET_YES:
3046       if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode)))
3047       {
3048         char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
3049         GNUNET_break_op (0);
3050         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3051                     "PUT with key `%s' for block with key %s\n",
3052                      put_s, GNUNET_h2s_full (&test_key));
3053         GNUNET_free (put_s);
3054         return GNUNET_YES;
3055       }
3056     break;
3057     case GNUNET_NO:
3058       GNUNET_break_op (0);
3059       return GNUNET_YES;
3060     case GNUNET_SYSERR:
3061       /* cannot verify, good luck */
3062       break;
3063   }
3064   
3065    if (ntohl (put->block_type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
3066   {
3067     switch (GNUNET_BLOCK_evaluate (GDS_block_context,
3068                                    ntohl (put->block_type),
3069                                    NULL,    /* query */
3070                                    NULL, 0, /* bloom filer */
3071                                    NULL, 0, /* xquery */
3072                                    payload, payload_size))
3073     {
3074     case GNUNET_BLOCK_EVALUATION_OK_MORE:
3075     case GNUNET_BLOCK_EVALUATION_OK_LAST:
3076       break;
3077
3078     case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
3079     case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
3080     case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
3081     case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
3082     case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
3083     case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
3084     default:
3085       GNUNET_break_op (0);
3086       return GNUNET_OK;
3087     }
3088   }
3089   
3090   /* extend 'put path' by sender */
3091   struct GNUNET_PeerIdentity pp[putlen + 1];
3092   if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
3093   {
3094     memcpy (pp, put_path, putlen * sizeof (struct GNUNET_PeerIdentity));
3095     pp[putlen] = *peer;
3096     putlen++;
3097   }
3098   else
3099     putlen = 0;
3100   
3101   memcpy (&key_value, &(put->key), sizeof (uint64_t));
3102   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
3103   {
3104     next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer);
3105   }
3106   else
3107   {
3108     next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST); 
3109   }
3110   
3111   if (NULL == next_hop)
3112   {
3113     GNUNET_STATISTICS_update (GDS_stats,
3114                               gettext_noop ("# Next hop to forward the packet not found "
3115                               "trail setup request, packet dropped."),
3116                               1, GNUNET_NO);
3117     return GNUNET_SYSERR;
3118   }
3119   
3120   GDS_CLIENTS_process_put (options,
3121                            ntohl (put->block_type),
3122                            ntohl (put->hop_count),
3123                            ntohl (put->desired_replication_level),
3124                            putlen, pp,
3125                            GNUNET_TIME_absolute_ntoh (put->expiration_time),
3126                            &put->key,
3127                            payload,
3128                            payload_size);
3129   
3130   if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, next_hop)) /* I am the final destination */
3131   {
3132     GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
3133                               &(put->key),putlen, pp, ntohl (put->block_type), 
3134                               payload_size, payload);
3135     return GNUNET_YES;
3136   }
3137   else
3138   {
3139     GDS_NEIGHBOURS_send_put (&put->key,  
3140                              ntohl (put->block_type),ntohl (put->options),
3141                              ntohl (put->desired_replication_level),
3142                              current_destination, current_source, next_hop,
3143                              ntohl (put->hop_count), putlen, pp,
3144                              GNUNET_TIME_absolute_ntoh (put->expiration_time),
3145                              payload, payload_size);
3146  
3147      return GNUNET_YES;
3148   }
3149   return GNUNET_SYSERR;
3150 }
3151
3152
3153 /**
3154  * Core handler for p2p get requests.
3155  *
3156  * @param cls closure
3157  * @param peer sender of the request
3158  * @param message message
3159  * @return #GNUNET_OK to keep the connection open,
3160  *         #GNUNET_SYSERR to close it (signal serious error)
3161  */
3162 static int
3163 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
3164                     const struct GNUNET_MessageHeader *message)
3165 {
3166   struct PeerGetMessage *get;
3167   struct GNUNET_PeerIdentity *get_path;
3168   struct GNUNET_PeerIdentity current_destination;
3169   struct GNUNET_PeerIdentity current_source;
3170   struct GNUNET_PeerIdentity *next_hop;
3171   uint32_t get_length;
3172   uint64_t key_value;
3173   size_t msize;
3174   
3175   msize = ntohs (message->size);
3176   if (msize < sizeof (struct PeerGetMessage))
3177   {
3178     GNUNET_break_op (0);
3179     return GNUNET_YES;
3180   }
3181   
3182   get = (struct PeerGetMessage *)message;
3183   get_length = ntohl (get->get_path_length);
3184   current_destination = get->current_destination;
3185   current_source = get->current_source;
3186   if (get_length > 0)
3187     get_path = (struct GNUNET_PeerIdentity *)&get[1];
3188   
3189   if ((msize <
3190        sizeof (struct PeerGetMessage) +
3191        get_length * sizeof (struct GNUNET_PeerIdentity)) ||
3192        (get_length >
3193         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3194   {
3195     GNUNET_break_op (0);
3196     return GNUNET_YES; 
3197   }
3198
3199   /* Add sender to get path */
3200   struct GNUNET_PeerIdentity gp[get_length + 1];
3201   memcpy (gp, get_path, get_length * sizeof (struct GNUNET_PeerIdentity));
3202   gp[get_length + 1] = *peer;
3203   get_length = get_length + 1;
3204   
3205   memcpy (&key_value, &(get->key), sizeof (uint64_t));
3206   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
3207   {
3208     next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer);
3209   }
3210   else
3211   {
3212     next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST);  
3213   }
3214   
3215   if (NULL == next_hop)
3216   {
3217     GNUNET_STATISTICS_update (GDS_stats,
3218                               gettext_noop ("# Next hop to forward the packet not found "
3219                               "trail setup request, packet dropped."),
3220                               1, GNUNET_NO);
3221     return GNUNET_SYSERR;
3222   }
3223   if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, next_hop))
3224   {
3225     /* I am the destination.*/
3226     struct GNUNET_PeerIdentity final_get_path[get_length+1];
3227     struct GNUNET_PeerIdentity next_hop;
3228
3229     memcpy (final_get_path, gp, get_length * sizeof (struct GNUNET_PeerIdentity));
3230     memcpy (&final_get_path[get_length+1], &my_identity, sizeof (struct GNUNET_PeerIdentity));
3231     get_length = get_length + 1;
3232     memcpy (&next_hop, &final_get_path[get_length-2], sizeof (struct GNUNET_PeerIdentity));
3233     GDS_DATACACHE_handle_get (&(get->key),(get->block_type), NULL, 0, NULL, 0,
3234                               get_length, final_get_path,&next_hop, &my_identity);
3235     
3236     return GNUNET_YES;
3237   }
3238   else
3239   {
3240     GDS_NEIGHBOURS_send_get (&(get->key), get->block_type, get->options, 
3241                              get->desired_replication_level,current_destination,
3242                              current_source, next_hop, 0,
3243                              get_length, gp);  
3244   }
3245   return GNUNET_SYSERR;
3246 }
3247
3248
3249 /**
3250  * Core handler for get result
3251  * @param cls closure
3252  * @param peer sender of the request
3253  * @param message message
3254  * @return #GNUNET_OK to keep the connection open,
3255  *         #GNUNET_SYSERR to close it (signal serious error)
3256  */
3257 static int
3258 handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
3259                            const struct GNUNET_MessageHeader *message)
3260 {
3261   struct PeerGetResultMessage *get_result;
3262   struct GNUNET_PeerIdentity *get_path;
3263   struct GNUNET_PeerIdentity *put_path;
3264   void *payload;
3265   size_t payload_size;
3266   size_t msize;
3267   unsigned int getlen;
3268   unsigned int putlen;
3269   int current_path_index;
3270   
3271   msize = ntohs (message->size);
3272   if (msize < sizeof (struct PeerGetResultMessage))
3273   {
3274     GNUNET_break_op (0);
3275     return GNUNET_YES;
3276   }
3277   
3278   get_result = (struct PeerGetResultMessage *)message;
3279   getlen = ntohl (get_result->get_path_length);
3280   putlen = ntohl (get_result->put_path_length);
3281   
3282   if ((msize <
3283        sizeof (struct PeerGetResultMessage) +
3284        getlen * sizeof (struct GNUNET_PeerIdentity) + 
3285        putlen * sizeof (struct GNUNET_PeerIdentity)) ||
3286       (getlen >
3287        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity) ||
3288       (putlen >
3289          GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))))
3290   {
3291     GNUNET_break_op (0);
3292     return GNUNET_YES;
3293   }
3294   
3295   if (getlen > 0)
3296    get_path = (struct GNUNET_PeerIdentity *) &get_result[1];
3297   payload = &get_path[getlen];
3298   payload_size = msize - (sizeof (struct PeerGetResultMessage) + 
3299                           getlen * sizeof (struct GNUNET_PeerIdentity));
3300   
3301   if (putlen > 0)
3302     put_path = &get_path[1];
3303   else
3304     put_path = NULL;
3305   
3306   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(get_path[0]))))
3307   {
3308     GDS_CLIENTS_handle_reply (get_result->expiration_time, &(get_result->key), 
3309                               getlen, get_path, putlen,
3310                               put_path, get_result->type, payload_size, payload);
3311     return GNUNET_YES;
3312   }
3313   else
3314   {
3315     current_path_index = search_my_index (get_path, getlen);
3316     if (GNUNET_SYSERR == current_path_index )
3317     {
3318       GNUNET_break (0);
3319       return GNUNET_SYSERR;
3320     }
3321     GDS_NEIGHBOURS_send_get_result (&(get_result->key), get_result->type,
3322                                     &get_path[current_path_index - 1],
3323                                     &(get_result->source_peer), putlen, put_path,
3324                                     getlen, get_path, get_result->expiration_time,
3325                                     payload, payload_size);
3326     return GNUNET_YES;
3327   }  
3328   return GNUNET_SYSERR;
3329 }
3330  
3331
3332 /**
3333  * Select the closest peer between peer returned from routing table and from
3334  * find_successor()
3335  * @param prev_hop Peer which sent the trail setup message.
3336  * @param current_destination[out] Next peer which will receive this message.
3337  * @param current_source[out] Source of the @a current_destination. 
3338  * @param value Key value to which the peer should be closest.
3339  * @para finger_map_index Index in finger map. 
3340  * @return Peer which is closest, in case of error NULL.
3341  */
3342 struct GNUNET_PeerIdentity *
3343 select_closest_peer (const struct GNUNET_PeerIdentity *prev_hop,
3344                      struct GNUNET_PeerIdentity *current_destination,
3345                      struct GNUNET_PeerIdentity *current_source,
3346                      uint64_t value,
3347                      unsigned int finger_map_index)
3348 {
3349   struct GNUNET_PeerIdentity *peer1;
3350   struct GNUNET_PeerIdentity *peer2;
3351   struct Sorting_List peers[3];
3352   struct Sorting_List *closest_finger;
3353   struct GNUNET_PeerIdentity current_dest;
3354   struct GNUNET_PeerIdentity current_src;
3355   
3356   peer1 = GDS_ROUTING_search (current_source, current_destination, prev_hop);
3357   peer2 = find_successor (value, &current_dest, &current_src,finger_map_index);
3358
3359   if( (peer1 != NULL) && (peer2 != NULL))
3360   {
3361     memcpy (&peers[0], &peer1, sizeof (uint64_t));
3362     peers[0].type = FRIEND;
3363     peers[0].data = NULL;
3364     
3365     memcpy (&peers[1], &value, sizeof (uint64_t));
3366     peers[1].type = VALUE;
3367     peers[1].data = NULL;
3368     
3369     memcpy (&peers[2], &peer2, sizeof (uint64_t));
3370     peers[2].type = FINGER;
3371     peers[1].data = NULL;
3372   
3373     qsort (&peers, 3, sizeof (struct Sorting_List), &compare_peer_id);
3374     if (PREDECESSOR_FINGER_ID == finger_map_index)
3375       closest_finger = find_closest_predecessor (peers, value, 3);
3376     else
3377       closest_finger = find_closest_successor (peers, value, 3);
3378
3379     if (closest_finger->type == FINGER)
3380     {
3381       memcpy (current_destination, &current_dest, sizeof (struct GNUNET_PeerIdentity));
3382       memcpy (current_source, &current_src, sizeof (struct GNUNET_PeerIdentity));
3383       return peer2;
3384     }
3385     else if (closest_finger->type == VALUE)
3386     { 
3387       return NULL;
3388     }
3389     else if (closest_finger->type == FRIEND);
3390     {
3391       return peer1;  
3392     }
3393   }
3394   else if ((peer1 == NULL) && (peer2 == NULL))
3395   {
3396     return NULL;
3397   }
3398   else if (peer1 == NULL)
3399   {
3400     return peer2;
3401   }
3402   else if (peer2 == NULL)
3403   {
3404     return peer1;
3405   }
3406   return NULL;
3407 }
3408
3409
3410 /** 
3411  * Core handle for PeerTrailSetupMessage. 
3412  * @param cls closure
3413  * @param message message
3414  * @param peer peer identity this notification is about
3415  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3416  */
3417 static int
3418 handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
3419                             const struct GNUNET_MessageHeader *message)
3420 {
3421   const struct PeerTrailSetupMessage *trail_setup; 
3422   struct GNUNET_PeerIdentity current_destination;
3423   struct GNUNET_PeerIdentity current_source;
3424   struct GNUNET_PeerIdentity source;
3425   struct GNUNET_PeerIdentity *next_hop;
3426   struct GNUNET_PeerIdentity next_peer;
3427   struct GNUNET_PeerIdentity *trail_peer_list;
3428   struct FriendInfo *target_friend;
3429   uint64_t destination_finger_value;
3430   uint32_t trail_length;
3431   uint32_t finger_map_index;
3432   size_t msize;
3433
3434   msize = ntohs (message->size);
3435   if (msize < sizeof (struct PeerTrailSetupMessage))
3436   {
3437     GNUNET_break_op (0);
3438     return GNUNET_YES;
3439   }
3440   
3441   trail_setup = (const struct PeerTrailSetupMessage *) message; 
3442   trail_length = ntohl (trail_setup->trail_length); 
3443  
3444   if ((msize < sizeof (struct PeerTrailSetupMessage) +
3445        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3446        (trail_length >
3447         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3448   {
3449     GNUNET_break_op (0);
3450     return GNUNET_OK; 
3451   }
3452   
3453   if (trail_length > 0)
3454     trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_setup[1];
3455   memcpy (&current_destination, &(trail_setup->current_destination), sizeof (struct GNUNET_PeerIdentity));
3456   memcpy (&current_source,&(trail_setup->current_source), sizeof (struct GNUNET_PeerIdentity));
3457   memcpy (&source, &(trail_setup->source_peer), sizeof (struct GNUNET_PeerIdentity));
3458   finger_map_index = ntohl (trail_setup->finger_map_index);
3459   destination_finger_value = ntohl (trail_setup->destination_finger);
3460   
3461   /* Check your routing table size, and if you can handle any more trails through you. */
3462   if (GNUNET_YES == GDS_ROUTING_check_threshold())
3463   {
3464     GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity,
3465                                          peer, finger_map_index, trail_peer_list, trail_length,
3466                                          CONGESTION_TIMEOUT);
3467     return GNUNET_OK;
3468   }
3469   
3470    /* Check if you are current_destination or not. */
3471   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
3472   {
3473     next_hop = select_closest_peer (peer, &current_destination, &current_source,
3474                                     destination_finger_value, finger_map_index);
3475   }
3476   else
3477   {
3478     next_hop = find_successor (destination_finger_value, &current_destination, 
3479                                &current_source,finger_map_index); 
3480   } 
3481   
3482   if (NULL == next_hop)
3483   {
3484     GNUNET_STATISTICS_update (GDS_stats,
3485                                 gettext_noop ("# Next hop to forward the packet not found "
3486                                 "trail setup request, packet dropped."),
3487                                 1, GNUNET_NO);
3488     return GNUNET_SYSERR;
3489   }
3490   else if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)))/* This means I am the final destination */
3491   {
3492     if (trail_length == 0)
3493     {
3494       memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity));
3495     }
3496     else
3497     {
3498       memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
3499     }
3500     
3501     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
3502     GDS_NEIGHBOURS_send_trail_setup_result (&source,
3503                                             &(my_identity),
3504                                             target_friend, trail_length,
3505                                             trail_peer_list,
3506                                             finger_map_index);
3507     return GNUNET_OK;
3508   }
3509   else
3510   {
3511     /* Now add yourself to the trail. */
3512     struct GNUNET_PeerIdentity peer_list[trail_length + 1];
3513     if (trail_length != 0)
3514       memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
3515     peer_list[trail_length] = my_identity;
3516     trail_length++;
3517     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3518     GDS_NEIGHBOURS_send_trail_setup (&source,
3519                                      destination_finger_value,
3520                                      &current_destination, &current_source,
3521                                      target_friend, trail_length, peer_list, 
3522                                      finger_map_index);
3523      return GNUNET_OK;
3524   }
3525 }
3526
3527
3528 /**
3529  * Core handle for p2p trail construction result messages.
3530  * @param closure
3531  * @param message message
3532  * @param peer peer identity this notification is about
3533  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3534  */
3535 static int
3536 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
3537                                   const struct GNUNET_MessageHeader *message)
3538 {
3539   const struct PeerTrailSetupResultMessage *trail_result;
3540   struct GNUNET_PeerIdentity *trail_peer_list;
3541   struct GNUNET_PeerIdentity destination_peer;
3542   struct GNUNET_PeerIdentity finger_identity;    
3543   uint32_t trail_length;
3544   uint32_t finger_map_index;
3545   size_t msize;
3546   
3547   msize = ntohs (message->size);
3548   if (msize < sizeof (struct PeerTrailSetupResultMessage))
3549   {
3550     GNUNET_break_op (0);
3551     return GNUNET_YES;
3552   }
3553   
3554   trail_result = (const struct PeerTrailSetupResultMessage *) message; 
3555   trail_length = ntohl (trail_result->trail_length); 
3556   
3557   if ((msize <
3558        sizeof (struct PeerTrailSetupResultMessage) +
3559        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3560        (trail_length >
3561         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3562   {
3563     GNUNET_break_op (0);
3564     return GNUNET_YES;
3565   }
3566   
3567   finger_map_index = htonl (trail_result->finger_map_index);
3568   memcpy (&destination_peer, &(trail_result->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3569   memcpy (&finger_identity, &(trail_result->finger_identity), sizeof (struct GNUNET_PeerIdentity));
3570   
3571   if (trail_length > 0)
3572     trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
3573   
3574   
3575   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
3576                                              &my_identity)))
3577   {
3578     finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length, 
3579                       finger_map_index);
3580     return GNUNET_YES;
3581   }
3582   else
3583   {
3584     struct GNUNET_PeerIdentity next_hop;
3585     struct FriendInfo *target_friend;
3586     int my_index;
3587     
3588     my_index =  search_my_index (trail_peer_list, trail_length);
3589     if (my_index == GNUNET_SYSERR)
3590       return GNUNET_SYSERR;
3591     
3592     if (my_index == 0)
3593       next_hop = trail_result->destination_peer;
3594     else
3595       next_hop = trail_peer_list[my_index - 1];
3596   
3597     if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
3598                                                &(trail_result->finger_identity))))
3599     {
3600       struct GNUNET_PeerIdentity *routing_next_hop;
3601
3602       routing_next_hop = GDS_ROUTING_search (&destination_peer,&finger_identity,
3603                                              peer);
3604       if ((NULL == routing_next_hop) || 
3605           (0 != GNUNET_CRYPTO_cmp_peer_identity(routing_next_hop, &next_hop)))
3606       {
3607         GDS_ROUTING_add (&(trail_result->destination_peer), &(trail_result->finger_identity),
3608                          peer, &next_hop);
3609       }
3610     }
3611     
3612     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3613     GDS_NEIGHBOURS_send_trail_setup_result (&(trail_result->destination_peer),
3614                                             &(trail_result->finger_identity),
3615                                             target_friend, trail_length,
3616                                             trail_peer_list,
3617                                             finger_map_index);
3618     return GNUNET_YES;
3619   }
3620   return GNUNET_SYSERR;
3621 }
3622
3623
3624 /**
3625  * Get my current predecessor from the finger peer map
3626  * @return Current predecessor.
3627  */
3628 static struct FingerInfo *
3629 get_predecessor()
3630 {
3631   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
3632   struct GNUNET_PeerIdentity key_ret;
3633   unsigned int finger_index;
3634   struct FingerInfo *my_predecessor;
3635   int flag = 0;
3636  
3637   /* Iterate over finger peer map and extract your predecessor. */
3638   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
3639   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
3640   {
3641     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next 
3642                        (finger_iter,&key_ret,(const void **)&my_predecessor)) 
3643     {
3644       if(PREDECESSOR_FINGER_ID == my_predecessor->finger_map_index)
3645       {
3646         flag = 1;
3647         break;
3648       }
3649     }
3650   }
3651   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
3652   
3653   if (0 == flag)
3654     return NULL;
3655   else
3656     return my_predecessor;
3657 }
3658
3659
3660 /**
3661  * Core handle for p2p verify successor messages.
3662  * @param cls closure
3663  * @param message message
3664  * @param peer peer identity this notification is about
3665  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3666  */
3667 static int
3668 handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
3669                                 const struct GNUNET_MessageHeader *message)
3670 {
3671   const struct PeerVerifySuccessorMessage *vsm;
3672   const struct GNUNET_PeerIdentity *trail_peer_list;
3673   struct GNUNET_PeerIdentity source_peer;
3674   struct GNUNET_PeerIdentity next_hop;
3675   struct FriendInfo *target_friend;
3676   size_t msize;
3677   uint32_t trail_length;
3678    
3679   msize = ntohs (message->size);
3680   if (msize < sizeof (struct PeerVerifySuccessorMessage))
3681   {
3682     GNUNET_break_op (0);
3683     return GNUNET_YES;
3684   }
3685   
3686   vsm = (struct PeerVerifySuccessorMessage *) message;
3687   trail_length = ntohl (vsm->trail_length);
3688   
3689   if ((msize < sizeof (struct PeerVerifySuccessorMessage) +
3690                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3691       (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3692   {
3693     GNUNET_break_op (0);
3694     return GNUNET_YES;
3695   }
3696   if (trail_length > 0)
3697     trail_peer_list = (const struct GNUNET_PeerIdentity *)&vsm[1];
3698   memcpy (&source_peer, &(vsm->source_peer), sizeof(struct GNUNET_PeerIdentity));
3699   
3700   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity)))
3701   {
3702     struct FingerInfo *my_predecessor;
3703     
3704     my_predecessor = get_predecessor();
3705     if (NULL == my_predecessor)
3706     {
3707       /* FIXME: should we just return. */
3708       return GNUNET_OK;
3709     }
3710     
3711     if (trail_length == 0)
3712     {
3713       memcpy (&next_hop, &source_peer, sizeof (struct GNUNET_PeerIdentity));
3714     }
3715     else
3716     {
3717       memcpy (&next_hop, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
3718     }
3719     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3720     
3721     if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
3722                                                &(my_predecessor->finger_identity))))
3723     {
3724       /* Source peer and my predecessor, both are same. */
3725       
3726       GDS_NEIGHBOURS_send_verify_successor_result (&source_peer,
3727                                                    &(my_identity),
3728                                                    &(my_predecessor->finger_identity),
3729                                                    target_friend,
3730                                                    trail_peer_list,
3731                                                    trail_length);
3732     }
3733     else
3734     {
3735       struct GNUNET_PeerIdentity *new_successor_trail;
3736       struct TrailPeerList *iterator;
3737       int new_trail_length;
3738       int i;
3739
3740       new_trail_length = trail_length + my_predecessor->first_trail_length + 1;
3741       new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length);
3742       if (trail_length > 0)
3743         memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity));
3744       
3745       memcpy (&new_successor_trail[trail_length], &my_identity, sizeof (struct GNUNET_PeerIdentity));
3746      
3747       if (my_predecessor->first_trail_length)
3748       {
3749         iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
3750         iterator = my_predecessor->first_trail_head; 
3751         i = trail_length + 1;
3752         while (i < new_trail_length)
3753         {
3754           memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
3755           iterator = iterator->next;
3756           i++;
3757         }
3758       }
3759       GDS_NEIGHBOURS_send_verify_successor_result (&source_peer,
3760                                                    &(my_identity),
3761                                                    &(my_predecessor->finger_identity),
3762                                                    target_friend,
3763                                                    new_successor_trail,
3764                                                    new_trail_length); 
3765     }      
3766     
3767   }
3768   else
3769   {
3770    int my_index;
3771    
3772    my_index = search_my_index (trail_peer_list, trail_length);
3773    if (my_index == GNUNET_SYSERR)
3774    {
3775      GNUNET_break (0);
3776      return GNUNET_SYSERR;
3777    }
3778    if (my_index == (trail_length - 1))
3779    {
3780       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(vsm->successor));
3781    }
3782    else
3783    {
3784      memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity));
3785      target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3786    }   
3787
3788    GDS_NEIGHBOURS_send_verify_successor (&(vsm->source_peer), &(vsm->successor),target_friend,
3789                                           trail_peer_list, trail_length); 
3790   }
3791   return GNUNET_SYSERR;
3792 }
3793
3794
3795 /**
3796  * Core handle for p2p verify successor result messages.
3797  * @param cls closure
3798  * @param message message
3799  * @param peer peer identity this notification is about
3800  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3801  */
3802 static int
3803 handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdentity *peer,
3804                                        const struct GNUNET_MessageHeader *message)
3805 {
3806   const struct PeerVerifySuccessorResultMessage *vsrm;
3807   struct GNUNET_PeerIdentity *trail_peer_list;
3808   struct GNUNET_PeerIdentity next_hop;
3809   struct FriendInfo *target_friend;
3810   size_t msize;
3811   uint32_t trail_length;
3812   
3813   msize = ntohs (message->size);
3814   if (msize < sizeof (struct PeerVerifySuccessorResultMessage))
3815   {
3816     GNUNET_break_op (0);
3817     return GNUNET_YES;
3818   }
3819   vsrm = (const struct PeerVerifySuccessorResultMessage *) message;
3820   trail_length = ntohl (vsrm->trail_length); 
3821   
3822   if ((msize <
3823        sizeof (struct PeerVerifySuccessorResultMessage) +
3824        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3825        (trail_length >
3826        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3827   {
3828     GNUNET_break_op (0);
3829     return GNUNET_YES;
3830   }
3831   
3832   if (trail_length > 0)
3833     trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1];
3834   
3835   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity))))
3836   {
3837     if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor), &(my_identity))))
3838     {
3839       if (GNUNET_YES == finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0))
3840       {
3841         memcpy (&next_hop, &trail_peer_list[0], sizeof (struct GNUNET_PeerIdentity));
3842         target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3843         scan_and_compress_trail (trail_peer_list, &trail_length, &(vsrm->my_predecessor));
3844         GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor),
3845                                                   &(vsrm->source_successor),
3846                                                   target_friend, trail_peer_list,
3847                                                   trail_length);
3848       }
3849       return GNUNET_OK;
3850     }
3851   }
3852   else
3853   {
3854     int my_index;
3855     
3856     my_index = search_my_index (trail_peer_list, trail_length);
3857     if (GNUNET_SYSERR == my_index)
3858     {
3859       GNUNET_break (0);
3860       return GNUNET_SYSERR;
3861     }
3862     if (my_index == 0)
3863     {
3864       memcpy (&next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3865     }
3866     else
3867     {
3868       memcpy (&next_hop, &trail_peer_list[my_index-1], sizeof (struct GNUNET_PeerIdentity));
3869     }
3870     
3871     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 
3872     GDS_NEIGHBOURS_send_verify_successor_result (&(vsrm->destination_peer),
3873                                                  &(vsrm->source_successor),
3874                                                  &(vsrm->my_predecessor),
3875                                                  target_friend,
3876                                                  trail_peer_list,
3877                                                  trail_length); 
3878     return GNUNET_OK;
3879   }
3880   return GNUNET_SYSERR;
3881 }
3882
3883
3884 /**
3885  * Core handle for p2p notify new successor messages.
3886  * @param cls closure
3887  * @param message message
3888  * @param peer peer identity this notification is about
3889  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3890  */
3891 static int
3892 handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
3893                                     const struct GNUNET_MessageHeader *message)
3894 {
3895   const struct PeerNotifyNewSuccessorMessage *nsm;
3896   struct GNUNET_PeerIdentity *trail_peer_list;
3897   struct GNUNET_PeerIdentity source_peer;
3898   struct GNUNET_PeerIdentity old_successor;
3899   struct GNUNET_PeerIdentity new_successor;
3900   struct FriendInfo *target_friend;
3901   size_t msize;
3902   uint32_t trail_length;
3903   
3904   msize = ntohs (message->size);
3905   if (msize < sizeof (struct PeerNotifyNewSuccessorMessage))
3906   {
3907     GNUNET_break_op (0);
3908     return GNUNET_YES;
3909   }
3910   nsm = (const struct PeerNotifyNewSuccessorMessage *) message;
3911   trail_length = ntohl (nsm->trail_length);
3912   
3913   if ((msize < sizeof (struct PeerNotifyNewSuccessorMessage) +
3914                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3915       (trail_length >
3916        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3917   {
3918     GNUNET_break_op (0);
3919     return GNUNET_YES;
3920   }
3921   
3922   if( trail_length > 0)
3923     trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
3924   memcpy (&source_peer, &(nsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
3925   memcpy (&old_successor, &(nsm->old_successor), sizeof (struct GNUNET_PeerIdentity));
3926   memcpy (&new_successor, &(nsm->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3927   
3928   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&new_successor, &my_identity)))
3929   {
3930     /* I am the new successor. */
3931     struct GNUNET_PeerIdentity *new_predecessor;
3932    
3933     new_predecessor = GNUNET_new (struct GNUNET_PeerIdentity);
3934     memcpy (new_predecessor, &(nsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
3935     if (GNUNET_YES == finger_table_add (new_predecessor, trail_peer_list, trail_length, PREDECESSOR_FINGER_ID))
3936     {
3937       if (trail_length > 0)
3938        target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(trail_peer_list[trail_length - 1]));
3939       else 
3940         target_friend = NULL;
3941       GDS_NEIGHBOURS_send_add_trail_message (&my_identity, new_predecessor, 
3942                                              trail_peer_list, trail_length, target_friend);  
3943     }
3944     return GNUNET_OK;
3945   }
3946   else
3947   {
3948     struct GNUNET_PeerIdentity next_hop;
3949     int my_index;
3950     
3951     my_index = search_my_index (trail_peer_list, trail_length);
3952     if (GNUNET_SYSERR == my_index)
3953     {
3954       GNUNET_break(0);
3955       return GNUNET_SYSERR;
3956     }
3957     
3958     if (my_index == (trail_length - 1))
3959     {
3960       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(nsm->destination_peer));
3961     }
3962     else
3963     {
3964       memcpy (&next_hop, &trail_peer_list[my_index+1], sizeof (struct GNUNET_PeerIdentity));
3965       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3966     }
3967     GDS_ROUTING_remove_trail (&source_peer, &old_successor, peer);
3968     GDS_ROUTING_add (&(nsm->source_peer), &(nsm->destination_peer), &next_hop, peer);
3969     GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), 
3970                                               &(nsm->destination_peer),
3971                                               &(nsm->old_successor),
3972                                               target_friend, trail_peer_list,
3973                                               trail_length);
3974     return GNUNET_OK;
3975   }
3976   return GNUNET_SYSERR;
3977 }
3978
3979
3980 /**
3981  * Core handler for P2P trail rejection message 
3982  * @param cls closure
3983  * @param message message
3984  * @param peer peer identity this notification is about
3985  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3986  */
3987 static
3988 int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer,
3989                                    const struct GNUNET_MessageHeader *message)
3990 {
3991   const struct PeerTrailRejectionMessage *trail_rejection;
3992   struct GNUNET_PeerIdentity *trail_peer_list;
3993   struct FriendInfo *target_friend;
3994   struct GNUNET_PeerIdentity next_hop;
3995   struct GNUNET_PeerIdentity *next_peer;
3996   struct GNUNET_PeerIdentity source;
3997   struct GNUNET_PeerIdentity current_destination;
3998   struct GNUNET_PeerIdentity current_source;
3999   uint32_t trail_length;
4000   uint32_t finger_map_index;
4001   uint64_t destination_finger_value;
4002   struct GNUNET_TIME_Relative congestion_timeout;
4003   size_t msize;
4004   
4005   msize = ntohs (message->size);
4006   if (msize < sizeof (struct PeerTrailRejectionMessage))
4007   {
4008     GNUNET_break_op (0);
4009     return GNUNET_YES;
4010   }
4011   
4012   trail_rejection = (struct PeerTrailRejectionMessage *) message;
4013   trail_length = ntohl (trail_rejection->trail_length);
4014   
4015   if ((msize < sizeof (struct PeerTrailRejectionMessage) +
4016                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
4017       (trail_length >
4018        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
4019   {
4020     GNUNET_break_op (0);
4021     return GNUNET_YES;
4022   }
4023   
4024   if (trail_length > 0)
4025     trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
4026   finger_map_index = ntohl (trail_rejection->finger_map_index);
4027   memcpy (&destination_finger_value, &(trail_rejection->finger_identity_value), sizeof (uint64_t));
4028   memcpy (&source, &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
4029   congestion_timeout = trail_rejection->congestion_time;
4030   
4031   /* First set the congestion time of the friend that sent you this message. */
4032   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
4033   target_friend->congestion_duration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
4034                                                                  congestion_timeout);
4035   
4036   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(trail_rejection->source_peer))))
4037   {
4038     return GNUNET_OK;
4039   }
4040   
4041   if(GNUNET_YES == GDS_ROUTING_check_threshold())
4042   {
4043     struct GNUNET_PeerIdentity *new_trail;
4044     unsigned int new_trail_length;
4045     
4046     if (trail_length == 1)
4047     {
4048       new_trail = NULL;
4049       new_trail_length = 0;
4050       memcpy (&next_hop, &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
4051     }
4052     else 
4053     {
4054       memcpy (&next_hop, &trail_peer_list[trail_length - 2], sizeof (struct GNUNET_PeerIdentity));
4055       /* Remove myself from the trail. */
4056       new_trail_length = trail_length -1;
4057       new_trail = GNUNET_malloc (new_trail_length * sizeof (struct GNUNET_PeerIdentity));
4058       memcpy (new_trail, trail_peer_list, new_trail_length * sizeof (struct GNUNET_PeerIdentity));
4059     }
4060     GDS_NEIGHBOURS_send_trail_rejection (&(trail_rejection->source_peer), 
4061                                          destination_finger_value,
4062                                          &my_identity, &next_hop,finger_map_index,
4063                                          new_trail,new_trail_length, CONGESTION_TIMEOUT);
4064     return GNUNET_YES;
4065   }
4066   
4067   {
4068   memcpy (&current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity));
4069   memcpy (&current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
4070   next_peer = find_successor (destination_finger_value,&current_destination,
4071                              &current_source, finger_map_index);
4072   if (NULL == next_peer)
4073   {
4074     GNUNET_STATISTICS_update (GDS_stats,
4075                                 gettext_noop ("# Next hop not found"
4076                                 "trail setup request, packet dropped."),
4077                                 1, GNUNET_NO);
4078     return GNUNET_SYSERR;
4079   }
4080   else if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_peer, &my_identity)))/* This means I am the final destination */
4081   {
4082     memcpy (&next_hop, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
4083     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4084     GDS_NEIGHBOURS_send_trail_setup_result (&source,
4085                                             &(my_identity),
4086                                             target_friend, trail_length,
4087                                             trail_peer_list,
4088                                             finger_map_index);
4089     return GNUNET_OK;
4090   }
4091   else
4092   {
4093     /* Now add yourself to the trail. */
4094     struct GNUNET_PeerIdentity peer_list[trail_length + 1];
4095     if (trail_length != 0)
4096       memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
4097     peer_list[trail_length] = my_identity;
4098     trail_length++;
4099     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4100     GDS_NEIGHBOURS_send_trail_setup (&source,
4101                                      destination_finger_value,
4102                                      &current_destination, &current_source,
4103                                      target_friend, trail_length, peer_list, 
4104                                      finger_map_index);
4105      return GNUNET_OK;
4106   }
4107   }
4108   
4109 }
4110
4111
4112 /*
4113  * Core handle for p2p trail tear down messages.
4114  * @param cls closure
4115  * @param message message
4116  * @param peer peer identity this notification is about
4117  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4118  */
4119 static
4120 int handle_dht_p2p_trail_teardown (void *cls, const struct GNUNET_PeerIdentity *peer,
4121                                    const struct GNUNET_MessageHeader *message)
4122 {
4123   struct PeerTrailTearDownMessage *trail_teardown;
4124   struct GNUNET_PeerIdentity *discarded_trail;
4125   struct GNUNET_PeerIdentity next_hop;
4126   struct FriendInfo *target_friend;
4127   uint32_t discarded_trail_length;
4128   size_t msize;
4129   int my_index;
4130   
4131   msize = ntohs (message->size);
4132   if (msize < sizeof (struct PeerTrailTearDownMessage))
4133   {
4134     GNUNET_break_op (0);
4135     return GNUNET_OK;
4136   }
4137   
4138   trail_teardown = (struct PeerTrailTearDownMessage *) message;
4139   discarded_trail_length = ntohl (trail_teardown->trail_length);
4140   
4141   if ((msize < sizeof (struct PeerTrailTearDownMessage) +
4142                discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
4143       (discarded_trail_length >
4144        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
4145   {
4146     GNUNET_break_op (0);
4147     return GNUNET_OK;
4148   }
4149   
4150   if (discarded_trail_length > 0)
4151     discarded_trail = (struct GNUNET_PeerIdentity *) &trail_teardown[1];
4152   
4153   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->new_first_friend),
4154                                              &my_identity)))
4155   {
4156      if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->destination_peer), 
4157                                                &my_identity)))
4158      {
4159        return GNUNET_OK;
4160      }
4161      else
4162      {
4163        return GDS_ROUTING_trail_update (&(trail_teardown->source_peer),
4164                                         &(trail_teardown->destination_peer), peer);
4165      }
4166   }
4167   else
4168   {
4169     my_index = search_my_index (discarded_trail, discarded_trail_length);
4170     if(GNUNET_SYSERR == my_index)
4171         return GNUNET_SYSERR;
4172     
4173     if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer),
4174                                                &(trail_teardown->destination_peer),peer))
4175     { 
4176       GNUNET_break (0); /* no matching entry found. Should not happen */
4177       return GNUNET_SYSERR;
4178     }  
4179     
4180     if (my_index == (discarded_trail_length - 1))
4181       return GNUNET_OK;
4182     
4183     memcpy (&next_hop, &discarded_trail[my_index + 1], sizeof (struct GNUNET_PeerIdentity));
4184     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 
4185     GDS_NEIGHBOURS_send_trail_teardown (&(trail_teardown->source_peer), 
4186                                         &(trail_teardown->destination_peer),
4187                                         discarded_trail, discarded_trail_length, 
4188                                         target_friend, &(trail_teardown->new_first_friend));
4189     return GNUNET_YES;
4190   }
4191   return GNUNET_SYSERR;
4192 }
4193
4194
4195 /**
4196  * Core handle for p2p add trail message. 
4197  * @param cls closure
4198  * @param message message
4199  * @param peer peer identity this notification is about
4200  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4201  */
4202 static int 
4203 handle_dht_p2p_add_trail (void *cls, const struct GNUNET_PeerIdentity *peer,
4204                           const struct GNUNET_MessageHeader *message)
4205 {
4206   struct PeerAddTrailMessage *add_trail;
4207   struct GNUNET_PeerIdentity *trail;
4208   struct GNUNET_PeerIdentity next_hop;
4209   struct FriendInfo *target_friend;
4210   size_t msize;
4211   uint32_t trail_length;
4212   int my_index;
4213   
4214   msize = ntohs (message->size);
4215   if (msize < sizeof (struct PeerAddTrailMessage))
4216   {
4217     GNUNET_break_op (0);
4218     return GNUNET_OK;
4219   }
4220   
4221   add_trail = (struct PeerAddTrailMessage *) message;
4222   trail_length = ntohl (add_trail->trail_length);
4223   
4224   if ((msize < sizeof (struct PeerAddTrailMessage) +
4225                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
4226       (trail_length >
4227        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
4228   {
4229     GNUNET_break_op (0);
4230     return GNUNET_OK;
4231   }
4232   
4233   if (trail_length > 0)
4234     trail = (struct GNUNET_PeerIdentity *)&add_trail[1];
4235   
4236   my_index = search_my_index (trail, trail_length);
4237   if (GNUNET_SYSERR == my_index)
4238   {
4239     GNUNET_break (0);
4240     return GNUNET_SYSERR;
4241   }
4242   
4243   if (GNUNET_YES == GDS_ROUTING_add (&(add_trail->source_peer), &(add_trail->destination_peer),
4244                                      peer,&next_hop))
4245   {
4246     if (my_index != 0)
4247     {
4248       memcpy (&next_hop, &trail[my_index - 1], sizeof (struct GNUNET_PeerIdentity));  
4249       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 
4250       GDS_NEIGHBOURS_send_add_trail_message (&(add_trail->source_peer), 
4251                                              &(add_trail->destination_peer),
4252                                              trail, trail_length,target_friend);
4253     }
4254     return GNUNET_OK;
4255   }
4256   else
4257   {
4258     /* No space left in my routing table. How should we handle this case? */
4259     return GNUNET_SYSERR;
4260   }
4261 }
4262
4263
4264 /**
4265  * FIXME: Adapt the code for List of trails. 
4266  * Iterate over finger_peermap, and remove entries with peer as the first element
4267  * of their trail.  
4268  * @param cls closure
4269  * @param key current public key
4270  * @param value value in the hash map
4271  * @return #GNUNET_YES if we should continue to
4272  *         iterate,
4273  *         #GNUNET_NO if not.
4274  */
4275 static int
4276 remove_matching_finger (void *cls,
4277                         const struct GNUNET_PeerIdentity *key,
4278                         void *value)
4279 {
4280   struct FingerInfo *remove_finger = value;
4281   const struct GNUNET_PeerIdentity *disconnected_peer = cls;
4282   
4283   if (remove_finger->first_trail_length > 0)
4284   {
4285     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->first_trail_head->peer, disconnected_peer))
4286     {
4287       GNUNET_assert (GNUNET_YES ==
4288                    GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
4289                                                          key, 
4290                                                          remove_finger));
4291       free_finger (remove_finger);
4292     }
4293   }
4294   else if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_finger->finger_identity), 
4295                                                  disconnected_peer))
4296   {
4297     GNUNET_assert (GNUNET_YES ==
4298                    GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
4299                                                          key, 
4300                                                          remove_finger));
4301     free_finger (remove_finger);
4302   }
4303   
4304   return GNUNET_YES;
4305 }
4306
4307
4308 /**
4309  * Method called whenever a peer disconnects.
4310  *
4311  * @param cls closure
4312  * @param peer peer identity this notification is about
4313  */
4314 static void
4315 handle_core_disconnect (void *cls,
4316                                           const struct GNUNET_PeerIdentity *peer)
4317 {
4318   struct FriendInfo *remove_friend;
4319   
4320   /* Check for self message. */
4321   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
4322     return;
4323   
4324   /* Search for peer to remove in your friend_peermap. */
4325   remove_friend =
4326       GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
4327   
4328   if (NULL == remove_friend)
4329   {
4330     GNUNET_break (0);
4331     return;
4332   }
4333
4334   /* Remove fingers for which this peer is the first element in the trail or if
4335    * the friend is a finger.  */
4336   GNUNET_CONTAINER_multipeermap_iterate (finger_peermap,
4337                                          &remove_matching_finger, (void *)peer);
4338   GDS_ROUTING_remove_entry (peer);
4339   
4340   /* Remove the peer from friend_peermap. */
4341   GNUNET_assert (GNUNET_YES ==
4342                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
4343                                                        peer,
4344                                                        remove_friend));
4345   
4346   if (0 != GNUNET_CONTAINER_multipeermap_size (friend_peermap))
4347     return;
4348   
4349   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
4350   {
4351       GNUNET_SCHEDULER_cancel (find_finger_trail_task);
4352       find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
4353   }
4354   else
4355     GNUNET_break (0);
4356 }
4357
4358
4359 /**
4360  * Method called whenever a peer connects.
4361  *
4362  * @param cls closure
4363  * @param peer_identity peer identity this notification is about
4364  */
4365 static void
4366 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
4367 {
4368   struct FriendInfo *friend;
4369
4370   /* Check for connect to self message */
4371   if (0 == memcmp (&my_identity, peer_identity, sizeof (struct GNUNET_PeerIdentity)))
4372     return;
4373   
4374   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to %s\n", GNUNET_i2s (peer_identity));
4375   
4376   /* If peer already exists in our friend_peermap, then exit. */
4377   if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap, peer_identity))
4378   {
4379     GNUNET_break (0);
4380     return;
4381   }
4382   
4383   GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
4384                             GNUNET_NO);
4385
4386   friend = GNUNET_new (struct FriendInfo);
4387   friend->id = *peer_identity;
4388   friend->trails_count = 0;
4389   
4390   GNUNET_assert (GNUNET_OK ==
4391                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
4392                                                     peer_identity, friend,
4393                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
4394
4395   /* got a first connection, good time to start with FIND FINGER TRAIL requests... */
4396   if (GNUNET_SCHEDULER_NO_TASK == find_finger_trail_task)
4397     find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
4398 }
4399
4400
4401 /**
4402  * To be called on core init/fail.
4403  *
4404  * @param cls service closure
4405  * @param identity the public identity of this peer
4406  */
4407 static void
4408 core_init (void *cls,
4409            const struct GNUNET_PeerIdentity *identity)
4410 {
4411   my_identity = *identity;
4412 }
4413
4414
4415 /**
4416  * Initialize neighbours subsystem.
4417  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4418  */
4419 int
4420 GDS_NEIGHBOURS_init (void)
4421 {
4422   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
4423     {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
4424     {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
4425     {&handle_dht_p2p_get_result, GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT, 0},   
4426     {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
4427     {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
4428     {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
4429     {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
4430     {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
4431     {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0},
4432     {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN, 0},
4433     {&handle_dht_p2p_add_trail, GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL, 0},
4434     {NULL, 0, 0}
4435   };
4436   
4437   core_api =
4438     GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
4439                          &handle_core_disconnect, NULL, GNUNET_NO, NULL,
4440                          GNUNET_NO, core_handlers);
4441   if (NULL == core_api)
4442     return GNUNET_SYSERR;
4443   
4444   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
4445   finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO);
4446   
4447   return GNUNET_OK;
4448 }
4449
4450
4451 /**
4452  * Shutdown neighbours subsystem.
4453  */
4454 void
4455 GDS_NEIGHBOURS_done (void)
4456 {
4457   if (NULL == core_api)
4458     return;
4459   
4460   GNUNET_CORE_disconnect (core_api);
4461   core_api = NULL;
4462   
4463   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
4464   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
4465   friend_peermap = NULL;
4466   
4467   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (finger_peermap));
4468   GNUNET_CONTAINER_multipeermap_destroy (finger_peermap);
4469   finger_peermap = NULL;
4470
4471   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
4472   {
4473     GNUNET_break (0);
4474     GNUNET_SCHEDULER_cancel (find_finger_trail_task);
4475     find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
4476   }
4477 }
4478
4479
4480 /**
4481  * Get my identity
4482  *
4483  * @return my identity
4484  */
4485 struct GNUNET_PeerIdentity 
4486 GDS_NEIGHBOURS_get_my_id (void)
4487 {
4488   return my_identity;
4489 }
4490
4491
4492 /* end of gnunet-service-xdht_neighbours.c */