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