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