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