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