2 This file is part of GNUnet.
3 (C) 2009-2013 Christian Grothoff (and other contributing authors)
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.
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.
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.
22 * @file dht/gnunet-service-xdht_neighbours.c
23 * @brief GNUnet DHT service's finger and friend table management code
24 * @author Supriti Singh
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_nse_service.h"
34 #include "gnunet_ats_service.h"
35 #include "gnunet_core_service.h"
36 #include "gnunet_datacache_lib.h"
37 #include "gnunet_transport_service.h"
38 #include "gnunet_hello_lib.h"
39 #include "gnunet_dht_service.h"
40 #include "gnunet_statistics_service.h"
41 #include "gnunet-service-xdht.h"
42 #include "gnunet-service-xdht_clients.h"
43 #include "gnunet-service-xdht_datacache.h"
44 #include "gnunet-service-xdht_hello.h"
45 #include "gnunet-service-xdht_neighbours.h"
46 #include "gnunet-service-xdht_nse.h"
47 #include "gnunet-service-xdht_routing.h"
52 1. Use a global array of all known peers in find_successor, Only when
53 a new peer is added in finger or friend peer map, then re calculate
54 the array. Or else use the old one. */
57 * Maximum possible fingers of a peer.
59 #define MAX_FINGERS 64
62 * Maximum allowed number of pending messages per friend peer.
64 #define MAXIMUM_PENDING_PER_FRIEND 64
67 * How long at least to wait before sending another find finger trail request.
69 #define DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
72 * How long at most to wait before sending another find finger trail request.
74 #define DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 10)
77 * How long at most to wait for transmission of a GET request to another peer?
79 #define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
82 GNUNET_NETWORK_STRUCT_BEGIN
90 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
92 struct GNUNET_MessageHeader header;
97 uint32_t options GNUNET_PACKED;
102 uint32_t type GNUNET_PACKED;
107 uint32_t hop_count GNUNET_PACKED;
110 * Replication level for this message
112 uint32_t desired_replication_level GNUNET_PACKED;
115 * Length of the PUT path that follows (if tracked).
117 uint32_t put_path_length GNUNET_PACKED;
120 * When does the content expire?
122 struct GNUNET_TIME_AbsoluteNBO expiration_time;
125 * Bloomfilter (for peer identities) to stop circular routes
127 char bloomfilter[DHT_BLOOM_SIZE];
130 * The key we are storing under.
132 struct GNUNET_HashCode key;
134 /* put path (if tracked) */
144 struct PeerResultMessage
147 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT
149 struct GNUNET_MessageHeader header;
154 uint32_t type GNUNET_PACKED;
157 * Length of the PUT path that follows (if tracked).
159 uint32_t put_path_length GNUNET_PACKED;
162 * Length of the GET path that follows (if tracked).
164 uint32_t get_path_length GNUNET_PACKED;
167 * When does the content expire?
169 struct GNUNET_TIME_AbsoluteNBO expiration_time;
172 * The key of the corresponding GET request.
174 struct GNUNET_HashCode key;
176 /* put path (if tracked) */
178 /* get path (if tracked) */
188 struct PeerGetMessage
191 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET
193 struct GNUNET_MessageHeader header;
198 uint32_t options GNUNET_PACKED;
201 * Desired content type.
203 uint32_t type GNUNET_PACKED;
208 uint32_t hop_count GNUNET_PACKED;
211 * Desired replication level for this request.
213 uint32_t desired_replication_level GNUNET_PACKED;
216 * Size of the extended query.
218 uint32_t xquery_size;
221 * Bloomfilter mutator.
226 * Bloomfilter (for peer identities) to stop circular routes
228 char bloomfilter[DHT_BLOOM_SIZE];
231 * The key we are looking for.
233 struct GNUNET_HashCode key;
239 * FIXME: Change the comment to explain about usage of this in find successor.
240 * Field in trail setup message to understand if the message is sent to an
241 * intermediate finger, friend or me.
243 enum current_destination_type
253 * P2P Trail setup message
255 struct PeerTrailSetupMessage
259 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
261 struct GNUNET_MessageHeader header;
264 * Source peer which wants to setup the trail to one of its finger.
266 struct GNUNET_PeerIdentity source_peer;
269 * Successor of this finger value will be our finger peer.
271 uint64_t destination_finger;
274 * Peer which gets this message can be either an intermediate finger or friend.
276 enum current_destination_type current_destination_type;
279 * Peer to which this packet is forwarded.
281 struct GNUNET_PeerIdentity current_destination;
284 * Index into finger peer map.
286 unsigned int finger_map_index;
289 * Number of entries in trail list.
291 uint32_t trail_length GNUNET_PACKED;
297 * P2P Trail Setup Result message
299 struct PeerTrailSetupResultMessage
303 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_RESULT_SETUP
305 struct GNUNET_MessageHeader header;
308 * Finger to which we have found the path.
310 struct GNUNET_PeerIdentity finger_identity;
313 * Peer which was looking for the trail to finger.
315 struct GNUNET_PeerIdentity destination_peer;
318 * Trail index which points to next destination to send this message.
320 unsigned int current_index;
323 * Index into finger peer map
325 unsigned int finger_map_index;
328 * Number of entries in trail list.
330 uint32_t trail_length GNUNET_PACKED;
336 * P2P Verify Successor message.
338 struct PeerVerifySuccessorMessage
342 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR
344 struct GNUNET_MessageHeader header;
347 * Source peer which wants to verify its successor.
349 struct GNUNET_PeerIdentity source_peer;
352 * My current successor.
354 struct GNUNET_PeerIdentity successor;
357 * Total number of peers in trail to current successor.
359 unsigned int trail_length;
362 * Trail index which points to next destination to send this message.
364 unsigned int current_trail_index;
370 * P2P Verify Successor Result message.
372 struct PeerVerifySuccessorResultMessage
376 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT
378 struct GNUNET_MessageHeader header;
381 * Destination peer which sent the request to verify its successor.
383 struct GNUNET_PeerIdentity destination_peer;
386 * Successor to which PeerVerifySuccessorMessage was sent.
388 struct GNUNET_PeerIdentity source_successor;
391 * source_successor's predecessor
393 struct GNUNET_PeerIdentity my_predecessor;
396 * Total number of peers in trail.
397 * If source_successor is not destination peer, then trail is from destination_peer
399 * If source_successor is destination peer, then trail is from destination_peer
400 * to source_successor.
402 unsigned int trail_length;
405 * Trail index which points to next destination to send this message.
407 unsigned int current_index;
412 * P2P Notify New Successor message.
414 struct PeerNotifyNewSuccessorMessage
417 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR
419 struct GNUNET_MessageHeader header;
422 * Source peer which wants to notify its new successor.
424 struct GNUNET_PeerIdentity source_peer;
427 * New successor identity.
429 struct GNUNET_PeerIdentity destination_peer;
432 * Number of peers in trail from source_peer to new successor.
434 unsigned int trail_length;
437 * Trail index which points to next destination to send this message.
439 unsigned int current_index;
444 GNUNET_NETWORK_STRUCT_END
448 * Linked list of messages to send to a particular other peer.
450 struct P2PPendingMessage
453 * Pointer to next item in the list
455 struct P2PPendingMessage *next;
458 * Pointer to previous item in the list
460 struct P2PPendingMessage *prev;
463 * When does this message time out?
465 struct GNUNET_TIME_Absolute timeout;
468 * Message importance level. FIXME: used? useful?
470 unsigned int importance;
473 * Actual message to be sent, allocated at the end of the struct:
474 * // msg = (cast) &pm[1];
475 * // memcpy (&pm[1], data, len);
477 const struct GNUNET_MessageHeader *msg;
483 * Linked List of peers which are part of trail to reach a particular Finger.
488 * Pointer to next item in the list
490 struct TrailPeerList *next;
493 * Pointer to previous item in the list
495 struct TrailPeerList *prev;
498 * An element in this trail list
500 struct GNUNET_PeerIdentity peer;
506 * Entry in friend_peermap.
513 struct GNUNET_PeerIdentity id;
516 * Count of outstanding messages for this friend.
518 unsigned int pending_count;
521 * Head of pending messages to be sent to this friend.
523 struct P2PPendingMessage *head;
526 * Tail of pending messages to be sent to this friend.
528 struct P2PPendingMessage *tail;
531 * Core handle for sending messages to this friend.
533 struct GNUNET_CORE_TransmitHandle *th;
539 * Entry in finger_peermap.
546 struct GNUNET_PeerIdentity finger_identity;
549 * Index in finger peer map
551 unsigned int finger_map_index;
554 * Total number of entries in trail from [me,finger]
556 unsigned int trail_length;
559 * Head of trail to reach this finger.
561 struct TrailPeerList *head;
564 * Tail of trail to reach this finger.
566 struct TrailPeerList *tail;
572 * FIXME: Think of a better name.
573 * Data structure passed to sorting algorithm in find_successor.
578 * 64 bit value of peer identity
583 * Type : MY_ID, FINGER, FINGER, Value
585 enum current_destination_type type;
588 * Pointer to original data structure linked to peer id.
595 * Task that sends FIND FINGER TRAIL requests.
597 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
601 * Task that periodically verifies my successor.
603 static GNUNET_SCHEDULER_TaskIdentifier verify_successor;
606 * Identity of this peer.
608 static struct GNUNET_PeerIdentity my_identity;
611 * Hash map of all the friends of a peer
613 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
616 * Hash map of all the fingers of a peer
618 static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap;
623 static struct GNUNET_ATS_PerformanceHandle *atsAPI;
628 static struct GNUNET_CORE_Handle *core_api;
631 * FIXME: Is it safe to assume its initialized to 0 by default.
632 * The current finger index that we have found trail to.
634 static unsigned int current_finger_index;
638 * Called when core is ready to send a message we asked for
639 * out to the destination.
641 * @param cls the 'struct FriendInfo' of the target friend
642 * @param size number of bytes available in buf
643 * @param buf where the callee should write the message
644 * @return number of bytes written to buf
647 core_transmit_notify (void *cls, size_t size, void *buf)
649 struct FriendInfo *peer = cls;
651 struct P2PPendingMessage *pending;
656 while ((NULL != (pending = peer->head)) &&
657 (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
659 peer->pending_count--;
660 GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
661 GNUNET_free (pending);
665 /* no messages pending */
671 GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
672 GNUNET_CORE_PRIO_BEST_EFFORT,
673 GNUNET_TIME_absolute_get_remaining
674 (pending->timeout), &peer->id,
675 ntohs (pending->msg->size),
676 &core_transmit_notify, peer);
677 GNUNET_break (NULL != peer->th);
681 while ((NULL != (pending = peer->head)) &&
682 (size - off >= (msize = ntohs (pending->msg->size))))
684 GNUNET_STATISTICS_update (GDS_stats,
686 ("# Bytes transmitted to other peers"), msize,
688 memcpy (&cbuf[off], pending->msg, msize);
690 peer->pending_count--;
691 GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
692 GNUNET_free (pending);
694 if (peer->head != NULL)
697 GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
698 GNUNET_CORE_PRIO_BEST_EFFORT,
699 GNUNET_TIME_absolute_get_remaining
700 (pending->timeout), &peer->id, msize,
701 &core_transmit_notify, peer);
702 GNUNET_break (NULL != peer->th);
709 * Transmit all messages in the friend's message queue.
711 * @param peer message queue to process
714 process_friend_queue (struct FriendInfo *peer)
716 struct P2PPendingMessage *pending;
718 if (NULL == (pending = peer->head))
720 if (NULL != peer->th)
723 GNUNET_STATISTICS_update (GDS_stats,
725 ("# Bytes of bandwidth requested from core"),
726 ntohs (pending->msg->size), GNUNET_NO);
728 /* FIXME: Are we correctly initializing importance and pending. */
730 GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
732 GNUNET_TIME_absolute_get_remaining
733 (pending->timeout), &peer->id,
734 ntohs (pending->msg->size),
735 &core_transmit_notify, peer);
736 GNUNET_break (NULL != peer->th);
741 * Construct a trail message and forward it to a friend.
742 * @param source_peer Peer which wants to set up the trail to one of its finger.
743 * @param destination_finger Value whose successor we are searching the network.
744 * @param current_destination Peer which gets this message.
745 * @param target_friend Current friend to which this message should be forwarded.
746 * @param trail_length Numbers of peers in the trail.
747 * @param trail_peer_list peers this request has traversed so far
748 * @param finger_map_index Index in finger peer map
749 * @param type Type of current destination can be either FRIEND or FINGER
752 GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity *source_peer,
753 uint64_t destination_finger,
754 struct GNUNET_PeerIdentity *current_destination,
755 struct FriendInfo *target_friend,
756 unsigned int trail_length,
757 struct GNUNET_PeerIdentity *trail_peer_list,
758 unsigned int finger_map_index,
759 enum current_destination_type type)
761 struct P2PPendingMessage *pending;
762 struct PeerTrailSetupMessage *tsm;
763 struct GNUNET_PeerIdentity *peer_list;
766 msize = sizeof (struct PeerTrailSetupMessage) +
767 (trail_length * sizeof (struct GNUNET_PeerIdentity));
769 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
775 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
777 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
781 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
782 pending->importance = 0; /* FIXME */
783 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
784 tsm = (struct PeerTrailSetupMessage *) &pending[1];
785 pending->msg = &tsm->header;
786 tsm->header.size = htons (msize);
787 tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
788 memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t));
789 memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
790 memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
791 tsm->current_destination_type = htonl (type);
792 tsm->trail_length = htonl (trail_length);
793 tsm->finger_map_index = htonl (finger_map_index);
795 peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
796 memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
797 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
798 target_friend->pending_count++;
799 process_friend_queue (target_friend);
805 * Construct a trail setup result message and forward it to a friend.
806 * @param destination_peer Peer which will get the trail to one of its finger.
807 * @param source_finger Peer to which the trail has been setup to.
808 * @param target_friend Friend to which this message should be forwarded.
809 * @param trail_length Numbers of peers in the trail.
810 * @param trail_peer_list Peers which are part of the trail from source to destination.
811 * @param current_trail_index Index in the trial list at which receiving peer should
812 * read the next element.
813 * @param finger_map_index Index in finger peer map
816 GDS_NEIGHBOURS_send_trail_setup_result (struct GNUNET_PeerIdentity *destination_peer,
817 struct GNUNET_PeerIdentity *source_finger,
818 struct FriendInfo *target_friend,
819 unsigned int trail_length,
820 struct GNUNET_PeerIdentity *trail_peer_list,
821 unsigned int current_trail_index,
822 unsigned int finger_map_index)
824 struct P2PPendingMessage *pending;
825 struct PeerTrailSetupResultMessage *tsrm;
826 struct GNUNET_PeerIdentity *peer_list;
829 msize = sizeof (struct PeerTrailSetupResultMessage) +
830 (trail_length * sizeof (struct GNUNET_PeerIdentity));
832 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
838 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
840 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
844 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
845 pending->importance = 0;
846 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
847 tsrm = (struct PeerTrailSetupResultMessage *) &pending[1];
848 pending->msg = &tsrm->header;
849 tsrm->header.size = htons (msize);
850 tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT);
851 memcpy (&(tsrm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
852 memcpy (&(tsrm->finger_identity), source_finger, sizeof (struct GNUNET_PeerIdentity));
853 tsrm->trail_length = htonl (trail_length);
854 tsrm->current_index = htonl (current_trail_index);
855 tsrm->finger_map_index = htonl (finger_map_index);
856 peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
857 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
859 /* Send the message to chosen friend. */
860 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
861 target_friend->pending_count++;
862 process_friend_queue (target_friend);
867 * Construct a PeerVerifySuccessor message and send it to friend.
868 * @param source_peer Peer which wants to verify its successor
869 * @param successor Peer which is our current successor
870 * @param target_friend Friend to which this message should be forwarded.
871 * @param trail_peer_list Peer which are part of trail from source to destination
872 * @param trail_length Number of peers in the trail list.
873 * @param current_trail_index Index in the trial list at which receiving peer should
874 * read the next element.
876 void GDS_NEIGHBOURS_send_verify_successor(struct GNUNET_PeerIdentity *source_peer,
877 struct GNUNET_PeerIdentity *successor,
878 struct FriendInfo *target_friend,
879 struct GNUNET_PeerIdentity *trail_peer_list,
880 unsigned int trail_length,
881 unsigned int current_trail_index)
883 struct PeerVerifySuccessorMessage *vsm;
884 struct P2PPendingMessage *pending;
885 struct GNUNET_PeerIdentity *peer_list;
888 msize = sizeof (struct PeerVerifySuccessorMessage) +
889 (trail_length * sizeof (struct GNUNET_PeerIdentity));
891 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
897 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
899 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
903 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
904 pending->importance = 0; /* FIXME */
905 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
906 vsm = (struct PeerVerifySuccessorMessage *) &pending[1];
907 pending->msg = &vsm->header;
908 vsm->header.size = htons (msize);
909 vsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR);
910 memcpy (&(vsm->successor), successor, sizeof (struct GNUNET_PeerIdentity));
911 memcpy (&(vsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
912 vsm->trail_length = htonl (trail_length);
913 vsm->current_trail_index = htonl (current_trail_index);
914 peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
915 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
917 /* Send the message to chosen friend. */
918 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
919 target_friend->pending_count++;
920 process_friend_queue (target_friend);
926 * Construct a PeerVerifySuccessorResult message and send it to friend.
927 * @param destination_peer Peer which sent verify successor message
928 * @param source_successor Peer to which verify successor message was sent.
929 * @param my_predecessor source_successor's predecessor.
930 * @param target_friend Friend to which this message should be forwarded.
931 * @param trail_peer_list Peers which are part of trail from source to destination
932 * @param trail_length Number of peers in the trail list.
933 * @param current_trail_index Index in the trial list at which receiving peer should
934 * get the next element.
936 void GDS_NEIGHBOURS_send_verify_successor_result (struct GNUNET_PeerIdentity *destination_peer,
937 struct GNUNET_PeerIdentity *source_successor,
938 struct GNUNET_PeerIdentity *my_predecessor,
939 struct FriendInfo *target_friend,
940 struct GNUNET_PeerIdentity *trail_peer_list,
941 unsigned int trail_length,
942 unsigned int current_trail_index)
944 struct PeerVerifySuccessorResultMessage *vsmr;
945 struct P2PPendingMessage *pending;
946 struct GNUNET_PeerIdentity *peer_list;
949 msize = sizeof (struct PeerVerifySuccessorResultMessage) +
950 (trail_length * sizeof(struct GNUNET_PeerIdentity));
952 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
959 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
961 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
965 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
966 pending->importance = 0; /* FIXME */
967 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
968 vsmr = (struct PeerVerifySuccessorResultMessage *) &pending[1];
969 pending->msg = &vsmr->header;
970 vsmr->header.size = htons (msize);
971 vsmr->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT);
972 memcpy (&(vsmr->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
973 memcpy (&(vsmr->source_successor), source_successor, sizeof (struct GNUNET_PeerIdentity));
974 memcpy (&(vsmr->my_predecessor), my_predecessor, sizeof (struct GNUNET_PeerIdentity));
975 vsmr->trail_length = htonl (trail_length);
976 vsmr->current_index = htonl (current_trail_index);
978 peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
979 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
981 /* Send the message to chosen friend. */
982 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
983 target_friend->pending_count++;
984 process_friend_queue (target_friend);
989 * Construct a PeerNotifyNewSuccessor message and send it to friend.
990 * @param source_peer Peer which is sending notify message to its new successor.
991 * @param destination_peer Peer which is the new destination.
992 * @param target_friend Next friend to pass this message to.
993 * @param peer_list List of peers in the trail to reach to destination_peer.
994 * @param current_trail_index Index of peer_list for next target friend position.
995 * @param trail_length Total number of peers in peer list
998 GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity *source_peer,
999 struct GNUNET_PeerIdentity *destination_peer,
1000 struct FriendInfo *target_friend,
1001 struct GNUNET_PeerIdentity *trail_peer_list,
1002 unsigned int trail_length,
1003 unsigned int current_trail_index)
1005 struct PeerNotifyNewSuccessorMessage *nsm;
1006 struct P2PPendingMessage *pending;
1007 struct GNUNET_PeerIdentity *peer_list;
1010 msize = sizeof (struct PeerNotifyNewSuccessorMessage) +
1011 (trail_length * sizeof(struct GNUNET_PeerIdentity));
1013 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1019 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1021 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1025 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1026 pending->importance = 0; /* FIXME */
1027 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1028 nsm = (struct PeerNotifyNewSuccessorMessage *) &pending[1];
1029 pending->msg = &nsm->header;
1030 nsm->header.size = htons (msize);
1031 nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR);
1032 memcpy (&(nsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1033 memcpy (&(nsm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1034 nsm->trail_length = htonl (trail_length);
1035 nsm->current_index = htonl (current_trail_index);
1037 peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
1038 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1040 /* Send the message to chosen friend. */
1041 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1042 target_friend->pending_count++;
1043 process_friend_queue (target_friend);
1047 /**FIXME: Old implementation just to remove error
1048 * TODO: Modify this function to handle our get request.
1049 * Perform a GET operation. Forwards the given request to other
1050 * peers. Does not lookup the key locally. May do nothing if this is
1051 * the only peer in the network (or if we are the closest peer in the
1054 * @param type type of the block
1055 * @param options routing options
1056 * @param desired_replication_level desired replication count
1057 * @param hop_count how many hops did this request traverse so far?
1058 * @param key key for the content
1059 * @param xquery extended query
1060 * @param xquery_size number of bytes in @a xquery
1061 * @param reply_bf bloomfilter to filter duplicates
1062 * @param reply_bf_mutator mutator for @a reply_bf
1063 * @param peer_bf filter for peers not to select (again)
1066 GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
1067 enum GNUNET_DHT_RouteOption options,
1068 uint32_t desired_replication_level,
1069 uint32_t hop_count, const struct GNUNET_HashCode * key,
1070 const void *xquery, size_t xquery_size,
1071 const struct GNUNET_CONTAINER_BloomFilter *reply_bf,
1072 uint32_t reply_bf_mutator,
1073 struct GNUNET_CONTAINER_BloomFilter *peer_bf)
1077 1. take the key, get the 64 bit value of the key.
1078 2. call find_successor to get the successor of the key.
1079 3. successor can be either a friend or finger.
1080 4. update the field in get message to reflect if its a friend or finger table
1081 5. add the put message to pending message and send it.
1086 /**FIXME: Old implementation just to remove error.
1087 * TODO: Modify this function to handle our put request.
1088 * Perform a PUT operation. Forwards the given request to other
1089 * peers. Does not store the data locally. Does not give the
1090 * data to local clients. May do nothing if this is the only
1091 * peer in the network (or if we are the closest peer in the
1094 * @param type type of the block
1095 * @param options routing options
1096 * @param desired_replication_level desired replication count
1097 * @param expiration_time when does the content expire
1098 * @param hop_count how many hops has this message traversed so far
1099 * @param bf Bloom filter of peers this PUT has already traversed
1100 * @param key key for the content
1101 * @param put_path_length number of entries in @a put_path
1102 * @param put_path peers this request has traversed so far (if tracked)
1103 * @param data payload to store
1104 * @param data_size number of bytes in @a data
1107 GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1108 enum GNUNET_DHT_RouteOption options,
1109 uint32_t desired_replication_level,
1110 struct GNUNET_TIME_Absolute expiration_time,
1112 struct GNUNET_CONTAINER_BloomFilter *bf,
1113 const struct GNUNET_HashCode *key,
1114 unsigned int put_path_length,
1115 struct GNUNET_PeerIdentity *put_path,
1116 const void *data, size_t data_size)
1120 1. take the key, get the 64 bit value of the key.
1121 2. call find_successor to get the successor of the key.
1122 3. successor can be either a friend or finger.
1123 4. update the field in put message to reflect if its a friend or finger table
1124 5. add the put message to pending message and send it.
1126 /* SUPU: Call is made to this function from client. It does not seem to be
1127 waiting for a confirmation So, once we got the request, we use the key and
1128 try to find the closest successor, but in this case when we reach to the
1129 closest successor in handle_dht_p2p_put, then just do datacache_put. As the calling
1130 function does not need any confirmation, we don't need the result back. */
1135 * Randomly choose one of your friends from the friends_peer map
1138 static struct FriendInfo *
1139 select_random_friend()
1141 unsigned int current_size;
1142 unsigned int *index;
1144 struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1145 struct GNUNET_PeerIdentity key_ret;
1146 struct FriendInfo *friend;
1148 current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
1150 /* Element stored at this index in friend_peermap should be selected friend. */
1151 index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1153 /* Create an iterator for friend_peermap. */
1154 iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1156 /* Set the position of iterator to index. */
1159 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
1168 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1178 * Compute finger_identity to which we want to setup the trail
1179 * @return finger_identity
1182 compute_finger_identity()
1185 uint64_t *finger_identity64;
1187 finger_identity64 = GNUNET_malloc (sizeof (uint64_t));
1189 memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1191 /*FIXME: Do we need a mod finger = ((my_id + pow(2, finger_index)) mod (pow (2, MAX_FINGERS))*/
1192 *finger_identity64 = (my_id64 + (unsigned long) pow (2,current_finger_index));
1194 return finger_identity64;
1199 * Compute immediate predecessor identity in the network.
1200 * @return peer identity of immediate predecessor.
1203 compute_predecessor_identity()
1206 uint64_t *predecessor;
1208 predecessor = GNUNET_malloc (sizeof (uint64_t));
1209 memcpy (&my_id, &my_identity, sizeof (uint64_t));
1210 /* FIXME: Do we need to use mod pow(2, MAX_FINGERS) here? */
1211 *predecessor = (my_id -1);
1218 * Periodically ping your successor to ask its current predecessor
1220 * @param cls closure for this task
1221 * @param tc the context under which the task is running
1224 send_verify_successor_message (void *cls,
1225 const struct GNUNET_SCHEDULER_TaskContext *tc )
1227 struct GNUNET_TIME_Relative next_send_time;
1228 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1229 struct GNUNET_PeerIdentity key_ret;
1230 struct FriendInfo *target_friend;
1231 struct GNUNET_PeerIdentity *next_hop;
1232 struct GNUNET_PeerIdentity *peer_list;
1233 unsigned int finger_trail_current_index;
1234 struct FingerInfo *finger;
1235 unsigned int finger_index;
1238 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1239 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1241 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1242 (const void **)&finger))
1244 if (0 == finger->finger_map_index)
1251 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1254 goto send_new_request;
1256 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->trail_length);
1258 struct TrailPeerList *iterate;
1259 iterate = finger->head;
1261 while ( i < (finger->trail_length))
1263 memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity));
1264 iterate = iterate->next;
1268 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1269 memcpy (next_hop, &peer_list[1], sizeof (struct GNUNET_PeerIdentity));
1270 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1271 finger_trail_current_index = 2;
1273 GDS_NEIGHBOURS_send_verify_successor (&my_identity,
1274 &(finger->finger_identity),
1277 finger->trail_length,
1278 finger_trail_current_index);
1281 /* FIXME: Use a random value so that this message is send not at the same
1282 interval as send_find_finger_trail_message. */
1284 next_send_time.rel_value_us =
1285 DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1286 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1287 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us /
1288 (current_finger_index + 50));
1291 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_verify_successor_message,
1297 * Task to send a find finger trail message. We attempt to find trail
1298 * to our fingers, successor and predecessor in the network.
1300 * @param cls closure for this task
1301 * @param tc the context under which the task is running
1304 send_find_finger_trail_message (void *cls,
1305 const struct GNUNET_SCHEDULER_TaskContext *tc)
1307 struct FriendInfo *target_friend;
1308 struct GNUNET_TIME_Relative next_send_time;
1309 struct GNUNET_PeerIdentity *peer_list;
1310 uint64_t *finger_identity;
1311 unsigned int finger_map_index;
1313 if (1 == current_finger_index)
1315 /* We have started the process to find the successor. We should search
1316 for our predecessor. */
1317 finger_identity = compute_predecessor_identity();
1322 finger_identity = compute_finger_identity();
1326 target_friend = select_random_friend();
1329 finger_map_index = current_finger_index;
1330 current_finger_index = ( current_finger_index + 1) % MAX_FINGERS;
1332 /* We found a friend.*/
1333 if(NULL != target_friend)
1335 /* Add yourself and selected friend in the trail list. */
1336 unsigned int trail_length = 2;
1337 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
1338 memcpy (&peer_list[0], &(my_identity), sizeof (struct GNUNET_PeerIdentity));
1339 memcpy (&peer_list[1], &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
1341 GDS_NEIGHBOURS_send_trail_setup (&my_identity, *finger_identity, &(target_friend->id),
1342 target_friend, trail_length, peer_list,
1343 finger_map_index, FRIEND);
1346 /* FIXME: Should we be using current_finger_index to generate random interval.*/
1347 next_send_time.rel_value_us =
1348 DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1349 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1350 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us /
1351 (current_finger_index + 10));
1353 find_finger_trail_task =
1354 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1360 * Method called whenever a peer connects.
1362 * @param cls closure
1363 * @param peer_identity peer identity this notification is about
1366 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
1368 struct FriendInfo *friend;
1370 /* Check for connect to self message */
1371 if (0 == memcmp (&my_identity, peer_identity, sizeof (struct GNUNET_PeerIdentity)))
1374 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to %s\n", GNUNET_i2s (peer_identity));
1376 /* If peer already exists in our friend_peermap, then exit. */
1377 if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap, peer_identity))
1383 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
1386 friend = GNUNET_new (struct FriendInfo);
1387 friend->id = *peer_identity;
1389 GNUNET_assert (GNUNET_OK ==
1390 GNUNET_CONTAINER_multipeermap_put (friend_peermap,
1391 peer_identity, friend,
1392 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1394 /* got a first connection, good time to start with FIND FINGER TRAIL requests... */
1395 if (1 == GNUNET_CONTAINER_multipeermap_size (friend_peermap))
1396 find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
1401 * Method called whenever a peer disconnects.
1403 * @param cls closure
1404 * @param peer peer identity this notification is about
1407 handle_core_disconnect (void *cls,
1408 const struct GNUNET_PeerIdentity *peer)
1410 struct FriendInfo *remove_friend;
1411 struct FingerInfo *remove_finger;
1412 struct GNUNET_PeerIdentity key_ret;
1413 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1414 struct TrailPeerList *iterator;
1415 struct GNUNET_PeerIdentity *finger_identity;
1418 /* Check for self message. */
1419 if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
1422 /* Search for peer to remove in your friend_peermap. */
1424 GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
1426 if (NULL == remove_friend)
1432 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
1433 finger_identity = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1434 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1435 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1437 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1438 (const void **)&remove_finger))
1440 iterator = remove_finger->head->next;
1441 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(iterator->peer), &(remove_friend->id)))
1443 memcpy (finger_identity, &(remove_finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
1444 GNUNET_assert (GNUNET_YES ==
1445 GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
1452 /* Remove the friend from friend_peermap. */
1453 GNUNET_assert (GNUNET_YES ==
1454 GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
1461 * To be called on core init/fail.
1463 * @param cls service closure
1464 * @param identity the public identity of this peer
1467 core_init (void *cls,
1468 const struct GNUNET_PeerIdentity *identity)
1470 my_identity = *identity;
1476 * Core handler for p2p put requests.
1478 * @param cls closure
1479 * @param peer sender of the request
1480 * @param message message
1481 * @param peer peer identity this notification is about
1482 * @return #GNUNET_OK to keep the connection open,
1483 * #GNUNET_SYSERR to close it (signal serious error)
1486 handle_dht_p2p_put (void *cls,
1487 const struct GNUNET_PeerIdentity *peer,
1488 const struct GNUNET_MessageHeader *message)
1491 1. Check if destination is friend or finger.
1492 2. If finger then get the next hop from routing table and
1493 * call GDS_NEGIHBOURS_handle_get.
1494 3. If friend then call find_successor to get the next hop and again
1495 * call GDS_NEIGHBOURS_handle_get to send to chosen hop.
1496 4. If you are the destination then do datacache_store.
1503 * Core handler for p2p get requests.
1505 * @param cls closure
1506 * @param peer sender of the request
1507 * @param message message
1508 * @return #GNUNET_OK to keep the connection open,
1509 * #GNUNET_SYSERR to close it (signal serious error)
1512 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
1513 const struct GNUNET_MessageHeader *message)
1516 1. Check if destination is friend or finger.
1517 2. If finger then get the next hop from routing table and
1518 * call GDS_NEGIHBOURS_handle_get.
1519 3. If friend then call find_successor to get the next hop and again
1520 * call GDS_NEIGHBOURS_handle_get to send to chosen hop.
1521 4. If you are the destination then send the data back to source peer
1522 * Assuming we have trail setup we can
1523 * either store the whole trail or again do the search process..
1530 * FIXME: When we add a successor or predecessor should we check the entry in
1531 * finger map index. If we don't replace the old entry then should we notify
1532 * peer which think it is our predecessor or successor. Or will send verify
1533 * successor message will handle this case on its own.
1534 * * FIXME: For redundant routing, we may start looking for different
1535 * paths to reach to same finger. So, in send_find_finger, we are starting
1536 * the search for trail to a finger, even if we already have found trail to
1537 * reach to it. There are several reasons for doing so
1538 * 1. We may reach to a closer successor than we have at the moment. So, we
1539 * should keep looking for the successor.
1540 * 2. We may reach to the same successor but through a shorter path.
1541 * 3. As I don't know how keys are distributed and how put/get will react
1542 * because of this, I have to think further before implementing it.
1543 * Add an entry in finger table.
1544 * Add an entry into finger table
1545 * @param finger_identity Peer identity of finger
1546 * @param finger_trail Trail to reach the finger
1547 * @param trail_length Number of peers in the trail.
1548 * @param finger_map_index Index in finger peer map.
1551 void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1552 struct GNUNET_PeerIdentity *finger_trail,
1553 unsigned int trail_length,
1554 unsigned int finger_map_index)
1556 struct FingerInfo *new_finger_entry;
1557 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1558 struct GNUNET_PeerIdentity key_ret;
1559 struct FingerInfo *existing_finger;
1563 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1565 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1567 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1568 (const void **)&existing_finger))
1570 /* If we already have an entry at the finger map index. */
1571 if ((finger_map_index == existing_finger->finger_map_index))
1573 /* Check if the finger entry are same. */
1574 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),finger_identity))
1576 /* Compare the trail length. */
1577 if ((trail_length == existing_finger->trail_length)||
1578 (trail_length > existing_finger->trail_length))
1582 else if (trail_length < existing_finger->trail_length)
1584 /* FIXME: As an optimization, when you add limit on trail length
1585 going through a particular friend, then check if the friend to
1586 reach the two trails are same or not. If not then choose one
1587 whose threshold value has not yet reached. Also, think about
1588 redundant routing, where you want to keep multiple paths
1589 to reach to the same finger. In that case you should allow multiple
1590 entries with same finger identity. */
1591 if ( GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
1592 &(existing_finger->finger_identity),
1601 /* FIXME: Here you are if you got different finger identity then one
1602 you already have at that index. Then you should choose the
1603 one which is closest. */
1610 new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
1611 memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity));
1614 while (i < trail_length)
1616 struct TrailPeerList *element;
1617 element = GNUNET_malloc (sizeof (struct TrailPeerList));
1618 element->next = NULL;
1619 element->prev = NULL;
1621 memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity));
1622 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->head, new_finger_entry->tail, element);
1626 new_finger_entry->finger_map_index = finger_map_index;
1627 new_finger_entry->trail_length = trail_length;
1629 /* FIXME: Here we are keeping multiple hashmap option so that there are
1630 multiple routes to reach to same finger, redundant routing. */
1631 GNUNET_assert (GNUNET_OK ==
1632 GNUNET_CONTAINER_multipeermap_put (finger_peermap,
1633 &(new_finger_entry->finger_identity),
1635 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1637 if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap)
1638 && (new_finger_entry->finger_map_index!= 1))
1640 verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL);
1646 * Compare two peer identities.
1647 * @param p1 Peer identity
1648 * @param p2 Peer identity
1649 * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2.
1652 compare_peer_id (const void *p1, const void *p2)
1654 struct Sorting_List *p11;
1655 struct Sorting_List *p22;
1657 p11 = GNUNET_malloc (sizeof (struct Sorting_List));
1658 p22 = GNUNET_malloc (sizeof (struct Sorting_List));
1659 p11 = (struct Sorting_List *)p1;
1660 p22 = (struct Sorting_List *)p2;
1661 ret = ( (p11->peer_id) > (p22->peer_id) ) ? 1 :
1662 ( (p11->peer_id) == (p22->peer_id) ) ? 0 : -1;
1668 * Return the previous element of value in all_known_peers.
1669 * @param all_known_peers list of all the peers
1670 * @param value value we have to search in the all_known_peers.
1673 static struct Sorting_List *
1674 find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value,
1683 middle = (first + last)/2;
1685 while(first <= last)
1687 if(all_known_peers[middle].peer_id < value)
1691 else if(all_known_peers[middle].peer_id == value)
1693 if(middle == (size -1))
1695 return &all_known_peers[0];
1699 return &all_known_peers[middle+1];
1707 middle = (first + last)/2;
1714 * Find closest successor for the value.
1715 * @param value Value for which we are looking for successor
1716 * @param current_destination NULL if my_identity is successor else finger/friend
1718 * @param type Next destination type
1719 * @return Peer identity of next destination i.e. successor of value.
1721 static struct GNUNET_PeerIdentity *
1722 find_successor(uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1723 enum current_destination_type *type)
1725 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
1726 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1727 struct GNUNET_PeerIdentity key_ret;
1728 struct FriendInfo *friend;
1729 struct FingerInfo *finger;
1730 unsigned int finger_index;
1731 unsigned int friend_index;
1732 struct Sorting_List *successor;
1736 /* 2 is added in size for my_identity and value which will part of all_known_peers. */
1737 size = GNUNET_CONTAINER_multipeermap_size (friend_peermap)+
1738 GNUNET_CONTAINER_multipeermap_size (finger_peermap)+
1741 struct Sorting_List all_known_peers[size];
1744 for (k = 0; k < size; k++)
1745 all_known_peers[k].peer_id = 0;
1747 /* Copy your identity at 0th index in all_known_peers. */
1749 memcpy (&(all_known_peers[j].peer_id), &my_identity, sizeof (uint64_t));
1750 all_known_peers[j].type = MY_ID;
1751 all_known_peers[j].data = 0;
1755 all_known_peers[j].peer_id = value;
1756 all_known_peers[j].type = VALUE;
1757 all_known_peers[j].data = 0;
1760 /* Iterate over friend peer map and copy all the elements into array. */
1761 friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1762 for (friend_index = 0; friend_index < GNUNET_CONTAINER_multipeermap_size (friend_peermap); friend_index++)
1764 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(friend_iter,&key_ret,(const void **)&friend))
1766 memcpy (&(all_known_peers[j].peer_id), &(friend->id), sizeof (uint64_t));
1767 all_known_peers[j].type = FRIEND;
1768 all_known_peers[j].data = friend;
1773 /* Iterate over finger map and copy all the entries into all_known_peers array. */
1774 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1775 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1777 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(finger_iter,&key_ret,(const void **)&finger))
1779 memcpy (&(all_known_peers[j].peer_id), &(finger->finger_identity), sizeof (uint64_t));
1780 all_known_peers[j].type = FINGER;
1781 all_known_peers[j].data = finger;
1786 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1787 GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter);
1789 qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id);
1791 /* search value in all_known_peers array. */
1792 successor = find_closest_successor (all_known_peers, value, size);
1794 if (successor->type == MY_ID)
1799 else if (successor->type == FRIEND)
1802 struct FriendInfo *target_friend;
1803 target_friend = (struct FriendInfo *)successor->data;
1804 memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
1805 return current_destination;
1807 else if (successor->type == FINGER)
1810 struct GNUNET_PeerIdentity *next_hop;
1811 struct FingerInfo *finger;
1812 struct TrailPeerList *iterator;
1813 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
1814 finger = successor->data;
1815 iterator = finger->head->next;
1816 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1817 memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
1818 memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
1830 * Handle a PeerTrailSetupMessage.
1831 * @param cls closure
1832 * @param message message
1833 * @param peer peer identity this notification is about
1834 * @return GNUNET_OK on success, GNUNET_SYSERR on error
1837 handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1838 const struct GNUNET_MessageHeader *message)
1840 struct PeerTrailSetupMessage *trail_setup;
1841 struct GNUNET_PeerIdentity *next_hop;
1842 struct FriendInfo *target_friend;
1843 struct GNUNET_PeerIdentity *current_destination;
1844 struct GNUNET_PeerIdentity *next_peer;
1845 struct GNUNET_PeerIdentity *trail_peer_list;
1846 enum current_destination_type peer_type;
1847 unsigned int trail_length;
1848 uint32_t current_trail_index;
1849 unsigned int finger_map_index;
1850 uint64_t finger_value;
1853 /* parse and validate message. */
1854 msize = ntohs (message->size);
1855 if (msize < sizeof (struct PeerTrailSetupMessage))
1857 GNUNET_break_op (0);
1861 trail_setup = (struct PeerTrailSetupMessage *) message;
1862 trail_length = ntohl (trail_setup->trail_length);
1865 sizeof (struct PeerTrailSetupMessage) +
1866 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
1868 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
1870 GNUNET_break_op (0);
1874 peer_type = ntohl (trail_setup->current_destination_type);
1875 finger_map_index = ntohl (trail_setup->finger_map_index);
1876 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_setup[1];
1877 finger_value = trail_setup->destination_finger;
1878 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1879 memcpy (current_destination, &(trail_setup->current_destination), sizeof (struct GNUNET_PeerIdentity));
1881 if (peer_type == FRIEND)
1883 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination),
1886 next_hop = find_successor (finger_value, current_destination, &(peer_type));
1889 return GNUNET_SYSERR;
1891 else if (peer_type == FINGER)
1893 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination),
1896 next_hop = GDS_ROUTING_search (&(trail_setup->source_peer),
1897 &(trail_setup->current_destination));
1900 /* This is an optimization. Uncomment when basic code is running first. */
1901 /* I am part of trail.*/
1902 struct GNUNET_PeerIdentity *next_peer_routing_table;
1903 next_peer_routing_table = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1904 next_peer_routing_table = GDS_ROUTING_search (&(trail_setup->source_peer),
1905 &(trail_setup->current_destination));
1907 struct GNUNET_PeerIdentity *next_peer_find_successor;
1908 next_peer_find_successor = find_successor (&(trail_setup->destination_finger),
1909 &(trail_setup->current_destination),
1912 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1913 next_hop = find_closest_destination (next_peer_routing_table,
1914 next_peer_find_successor,
1915 &(trail_setup->destination_finger) );
1920 /* I am the current_destination finger */
1921 next_hop = find_successor (finger_value, current_destination, &(peer_type));
1925 /* If you are the next hop, then you are the final destination */
1926 if (peer_type == MY_ID)
1928 struct GNUNET_PeerIdentity *source;
1929 source = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1930 memcpy (source, &(trail_setup->source_peer), sizeof (struct GNUNET_PeerIdentity));
1931 current_trail_index = trail_length - 2;
1932 next_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1933 memcpy (next_peer, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
1934 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer);
1935 GNUNET_free (next_peer);
1937 if(current_trail_index != 0)
1938 current_trail_index = current_trail_index - 1;
1940 if (0 == trail_setup->finger_map_index)
1942 struct GNUNET_PeerIdentity *new_trail;
1946 i = trail_length - 1;
1948 new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) *
1952 memcpy( &new_trail[j], &trail_peer_list[i], sizeof (struct GNUNET_PeerIdentity));
1956 memcpy (&new_trail[j], &trail_peer_list[i], sizeof(struct GNUNET_PeerIdentity));
1957 finger_table_add (source, new_trail, trail_length, 1);
1960 GDS_NEIGHBOURS_send_trail_setup_result (&(trail_setup->source_peer),
1962 target_friend, trail_length,
1963 trail_peer_list, current_trail_index,
1969 /* Add next hop to list of peers. */
1970 struct GNUNET_PeerIdentity *peer_list;
1971 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length + 1));
1972 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1973 memcpy (&peer_list[trail_length], next_hop, sizeof (struct GNUNET_PeerIdentity));
1976 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1978 if(peer_type == FINGER)
1980 GDS_ROUTING_add (&(trail_setup->source_peer),
1981 &(trail_setup->current_destination),
1985 GDS_NEIGHBOURS_send_trail_setup (&(trail_setup->source_peer),
1986 trail_setup->destination_finger,
1987 current_destination, target_friend, trail_length,
1988 peer_list, finger_map_index, peer_type);
1995 * Core handle for p2p trail construction result messages.
1996 * @param cls closure
1997 * @param message message
1998 * @param peer peer identity this notification is about
1999 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2002 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2003 const struct GNUNET_MessageHeader *message)
2005 struct PeerTrailSetupResultMessage *trail_result;
2006 struct GNUNET_PeerIdentity *trail_peer_list;
2007 struct GNUNET_PeerIdentity *next_peer;
2008 struct FriendInfo *target_friend;
2009 unsigned int current_trail_index;
2010 unsigned int finger_map_index;
2011 unsigned int trail_length;
2014 msize = ntohs (message->size);
2015 if (msize < sizeof (struct PeerTrailSetupResultMessage))
2017 GNUNET_break_op (0);
2021 trail_result = (struct PeerTrailSetupResultMessage *) message;
2022 trail_length = ntohl (trail_result->trail_length);
2025 sizeof (struct PeerTrailSetupResultMessage) +
2026 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2028 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2030 GNUNET_break_op (0);
2034 current_trail_index = ntohl (trail_result->current_index);
2035 finger_map_index = ntohl (trail_result->finger_map_index);
2037 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
2039 if ( 0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
2043 /* SUPU: Here I have removed myself from the trail before storing it in
2044 th finger table - to save space, but in case of verify successor result
2045 the result trail does not contain me, and I will never get the message back.
2046 So, keeping myself in the trail list. Think of better solution.*/
2047 struct GNUNET_PeerIdentity *finger_trail;
2048 finger_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length - 1));
2050 /* Copy the whole trail_peer_list except the first element into trail */
2052 i = trail_length - 1;
2055 memcpy (&finger_trail[i], &trail_peer_list[i], sizeof (struct GNUNET_PeerIdentity));
2058 trail_length = trail_length -1 ; SUPU: As you removed yourself from the trail.*/
2061 finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length,
2068 next_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2069 memcpy (next_peer, &(trail_peer_list[current_trail_index]),
2070 sizeof (struct GNUNET_PeerIdentity));
2071 /* SUPU: here current trail index will always be greater than 0.
2072 so no need for this check here. trail index = 0, contains the final
2073 destination, and if we are in this loop we have not yet reached the
2074 final destination. */
2075 current_trail_index = current_trail_index - 1;
2077 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer);
2078 GNUNET_free (next_peer);
2080 GDS_NEIGHBOURS_send_trail_setup_result (&(trail_result->destination_peer),
2081 &(trail_result->finger_identity),
2082 target_friend, trail_length,
2083 trail_peer_list,current_trail_index,
2088 return GNUNET_SYSERR;
2093 * Core handle for p2p verify successor messages.
2094 * @param cls closure
2095 * @param message message
2096 * @param peer peer identity this notification is about
2097 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2100 handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2101 const struct GNUNET_MessageHeader *message)
2103 struct PeerVerifySuccessorMessage *vsm;
2104 struct GNUNET_PeerIdentity *trail_peer_list;
2105 struct FriendInfo *target_friend;
2106 struct GNUNET_PeerIdentity *next_hop;
2107 struct GNUNET_PeerIdentity *source_peer;
2108 unsigned int trail_length;
2109 unsigned int current_trail_index;
2112 msize = ntohs (message->size);
2113 if (msize < sizeof (struct PeerVerifySuccessorMessage))
2115 GNUNET_break_op (0);
2119 vsm = (struct PeerVerifySuccessorMessage *) message;
2120 trail_length = ntohl (vsm->trail_length);
2123 sizeof (struct PeerVerifySuccessorMessage) +
2124 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2126 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2128 GNUNET_break_op (0);
2132 current_trail_index = ntohl (vsm->current_trail_index);
2133 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
2134 source_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2135 memcpy (source_peer, &(vsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
2137 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2139 /* SUPU: If I am the destination. */
2140 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),
2143 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2144 struct GNUNET_PeerIdentity key_ret;
2145 unsigned int finger_index;
2146 struct FingerInfo *my_predecessor;
2147 struct GNUNET_PeerIdentity *destination_peer;
2149 /* Iterate over finger peer map and extract your predecessor. */
2150 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
2151 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
2153 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next
2154 (finger_iter,&key_ret,(const void **)&my_predecessor))
2156 if(1 == my_predecessor->finger_map_index)
2162 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2164 destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2165 memcpy (destination_peer, source_peer, sizeof (struct GNUNET_PeerIdentity));
2166 current_trail_index = trail_length - 2;
2167 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2168 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2169 GNUNET_free (next_hop);
2171 if (current_trail_index != 0)
2172 current_trail_index = current_trail_index - 1;
2174 /*SUPU: Remove this later*/
2175 struct GNUNET_PeerIdentity *predecessor;
2176 predecessor = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2177 if (NULL == my_predecessor)
2179 /* FIXME: Ideally my_predecessor should not be NULL. If some one sent
2180 me a request to verify it I am the successor or not, then I would have
2181 added that peer to my_predecessor list. Check trail setup and see if
2182 you are adding predecessor when you get the request for successor. */
2184 update_predecessor (source_peer, trail_peer_list, trail_length);
2186 GDS_NEIGHBOURS_send_verify_successor_result (destination_peer,
2192 current_trail_index);
2197 /* FIXME: some times my_predecssor->finger_identity has no valid value.
2199 memcpy (predecessor, &(my_predecessor->finger_identity), sizeof (struct GNUNET_PeerIdentity));
2202 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (source_peer,
2203 &(my_predecessor->finger_identity))))
2205 /* SUPU: If source peer is my predecessor .*/
2206 GDS_NEIGHBOURS_send_verify_successor_result (destination_peer,
2208 &(my_predecessor->finger_identity),
2212 current_trail_index);
2216 struct GNUNET_PeerIdentity *new_successor_trail;
2217 int new_trail_length;
2220 new_trail_length = trail_length + my_predecessor->trail_length - 1;
2221 new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)
2222 * new_trail_length);
2224 /* Copy the trail from source peer to me. */
2225 memcpy (new_successor_trail, trail_peer_list,
2226 (trail_length) * sizeof (struct GNUNET_PeerIdentity));
2228 /* Copy the trail from me to my predecessor excluding me. */
2229 struct TrailPeerList *iterator;
2230 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
2231 iterator = my_predecessor->head->next;
2233 while (i < new_trail_length)
2235 memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
2236 iterator = iterator->next;
2240 GDS_NEIGHBOURS_send_verify_successor_result (destination_peer,
2242 &(my_predecessor->finger_identity),
2244 new_successor_trail,
2246 current_trail_index);
2252 /* If I am not the destination. */
2253 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2254 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2255 GNUNET_free (next_hop);
2257 current_trail_index = current_trail_index + 1;
2259 GDS_NEIGHBOURS_send_verify_successor(source_peer, &(vsm->successor),target_friend,
2260 trail_peer_list, trail_length, current_trail_index);
2267 * Core handle for p2p notify new successor messages.
2268 * @param cls closure
2269 * @param message message
2270 * @param peer peer identity this notification is about
2271 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2274 handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2275 const struct GNUNET_MessageHeader *message)
2277 struct PeerNotifyNewSuccessorMessage *nsm;
2278 struct GNUNET_PeerIdentity *trail_peer_list;
2279 unsigned int current_trail_index;
2281 unsigned int trail_length;
2283 msize = ntohs (message->size);
2284 if (msize < sizeof (struct PeerNotifyNewSuccessorMessage))
2286 GNUNET_break_op (0);
2290 nsm = (struct PeerNotifyNewSuccessorMessage *) message;
2291 trail_length = ntohl (nsm->trail_length);
2294 sizeof (struct PeerNotifyNewSuccessorMessage) +
2295 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2297 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2299 GNUNET_break_op (0);
2303 current_trail_index = ntohl (nsm->current_index);
2304 trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
2306 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer),
2309 struct GNUNET_PeerIdentity *new_trail;
2313 i = trail_length - 1;
2315 new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) *
2319 memcpy( &new_trail[j], &trail_peer_list[i], sizeof (struct GNUNET_PeerIdentity));
2323 memcpy (&new_trail[j], &trail_peer_list[i], sizeof(struct GNUNET_PeerIdentity));
2324 finger_table_add (&(nsm->source_peer), new_trail, trail_length, 1);
2330 struct FriendInfo *target_friend;
2331 target_friend = GNUNET_malloc (sizeof (struct FriendInfo));
2332 struct GNUNET_PeerIdentity *next_hop;
2333 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2334 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2335 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2336 GNUNET_free (next_hop);
2337 current_trail_index = current_trail_index + 1;
2339 GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer),
2340 &(nsm->destination_peer),
2341 target_friend, trail_peer_list,
2342 trail_length, current_trail_index);
2349 * Core handle for p2p verify successor result messages.
2350 * @param cls closure
2351 * @param message message
2352 * @param peer peer identity this notification is about
2353 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2356 handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2357 const struct GNUNET_MessageHeader *message)
2359 struct PeerVerifySuccessorResultMessage *vsrm;
2360 struct FriendInfo *target_friend;
2361 struct GNUNET_PeerIdentity *trail_peer_list;
2362 struct GNUNET_PeerIdentity *next_hop;
2363 unsigned int trail_length;
2364 unsigned int current_trail_index;
2367 msize = ntohs (message->size);
2368 if (msize < sizeof (struct PeerVerifySuccessorResultMessage))
2370 GNUNET_break_op (0);
2374 vsrm = (struct PeerVerifySuccessorResultMessage *) message;
2375 trail_length = ntohl (vsrm->trail_length);
2378 sizeof (struct PeerVerifySuccessorResultMessage) +
2379 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2381 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2383 GNUNET_break_op (0);
2387 current_trail_index = ntohl (vsrm->current_index);
2388 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1];
2390 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer),
2393 if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor),
2396 finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0);
2397 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2398 memcpy (next_hop, &trail_peer_list[1], sizeof (struct GNUNET_PeerIdentity));
2399 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2400 current_trail_index = 2;
2401 GNUNET_free (next_hop);
2403 GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor),
2404 target_friend, trail_peer_list,
2405 trail_length, current_trail_index);
2410 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2411 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2412 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2413 GNUNET_free (next_hop);
2414 current_trail_index = current_trail_index - 1;
2416 GDS_NEIGHBOURS_send_verify_successor_result (&(vsrm->destination_peer),
2417 &(vsrm->source_successor),
2418 &(vsrm->my_predecessor),
2422 current_trail_index);
2429 * Initialize neighbours subsystem.
2430 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2433 GDS_NEIGHBOURS_init()
2435 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
2436 {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
2437 {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
2438 {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
2439 {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
2440 {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
2441 {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
2442 {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
2447 /*TODO: What is ATS? Why do we need it? */
2448 atsAPI = GNUNET_ATS_performance_init (GDS_cfg, NULL, NULL);
2450 GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
2451 &handle_core_disconnect, NULL, GNUNET_NO, NULL,
2452 GNUNET_NO, core_handlers);
2453 if (NULL == core_api)
2454 return GNUNET_SYSERR;
2456 friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
2457 finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS, GNUNET_NO);
2464 * Shutdown neighbours subsystem.
2467 GDS_NEIGHBOURS_done ()
2469 if (NULL == core_api)
2472 GNUNET_CORE_disconnect (core_api);
2474 GNUNET_ATS_performance_done (atsAPI);
2477 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
2478 GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
2479 friend_peermap = NULL;
2482 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (finger_peermap));
2483 GNUNET_CONTAINER_multipeermap_destroy (finger_peermap);
2484 finger_peermap = NULL;
2486 if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
2488 GNUNET_SCHEDULER_cancel (find_finger_trail_task);
2489 find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
2493 if (GNUNET_SCHEDULER_NO_TASK != verify_successor)
2495 GNUNET_SCHEDULER_cancel (verify_successor);
2496 verify_successor = GNUNET_SCHEDULER_NO_TASK;
2503 * Get the ID of the local node.
2505 * @return identity of the local node
2507 struct GNUNET_PeerIdentity *
2508 GDS_NEIGHBOURS_get_id ()
2510 return &my_identity;
2514 /* end of gnunet-service-xdht_neighbours.c */