2 This file is part of GNUnet.
3 (C) 2009-2014 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. when should we use const struct and replace wherever needed.
53 * 2. use assert for each function where you need to check the return value.
54 1. Use a global array of all known peers in find_successor, Only when
55 a new peer is added in finger or friend peer map, then re calculate
56 the array. Or else use the old one.
57 2. Should we be using const in all the handle for the message we received
58 * and then copy the fields and make changes to the fields instead of sending
60 * 3. Everywhere you are storing yourself as the first element in the trail.
61 * It is obviously taking too much space. Try to remove it and think of something
63 4. Choose the correct interval to send finger and verify message.
64 5. Do we need expiration time for trail setup and all other messages? TTL
65 6. In case of trail setup after TTL, we should again send the request but
66 * through a different route. How do we remeber each time which friend we
67 * chose last time for the trail setup. We will need a data structure where we
68 * add entry in finger table add and when setup is done remove it.
69 * 7. I have not added any authentication on messages exachanged between peers.
70 * Only when basic put/get is correct I will add it. */
73 * Maximum possible fingers of a peer.
75 #define MAX_FINGERS 64
78 * Maximum allowed number of pending messages per friend peer.
80 #define MAXIMUM_PENDING_PER_FRIEND 64
83 * How long at least to wait before sending another find finger trail request,
84 * at most we wait twice this long.
86 #define DHT_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
89 * How long at most to wait for transmission of a GET request to another peer?
91 #define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
94 * Maximum number of trails allowed to go through a friend.
96 #define LINK_THRESHOLD 64
99 GNUNET_NETWORK_STRUCT_BEGIN
104 struct PeerPutMessage
107 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
109 struct GNUNET_MessageHeader header;
114 uint32_t options GNUNET_PACKED;
119 uint32_t block_type GNUNET_PACKED;
124 uint32_t hop_count GNUNET_PACKED;
127 * Replication level for this message
129 uint32_t desired_replication_level GNUNET_PACKED;
132 * Length of the PUT path that follows (if tracked).
134 uint32_t put_path_length GNUNET_PACKED;
137 * Current destination to which this message is forwarded.
139 struct GNUNET_PeerIdentity current_destination;
142 * Peer whose finger is current_destination.
144 struct GNUNET_PeerIdentity current_source;
147 * When does the content expire?
149 struct GNUNET_TIME_AbsoluteNBO expiration_time;
152 * The key to store the value under.
154 struct GNUNET_HashCode key GNUNET_PACKED;
157 /* put path (if tracked) */
167 struct PeerGetResultMessage
170 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT
172 struct GNUNET_MessageHeader header;
175 * The type for the data.
177 uint32_t type GNUNET_PACKED;
180 * Peer which will receive the get result message.
182 struct GNUNET_PeerIdentity source_peer;
185 * Number of peers recorded in the outgoing path from source to the
186 * stored location of this message.
188 uint32_t put_path_length GNUNET_PACKED;
191 * Length of the GET path that follows (if tracked).
193 uint32_t get_path_length GNUNET_PACKED;
196 * When does the content expire?
198 struct GNUNET_TIME_Absolute expiration_time;
201 * The key of the corresponding GET request.
203 struct GNUNET_HashCode key;
205 /* put path (if tracked) */
207 /* get path (if tracked) */
217 struct PeerGetMessage
220 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET
222 struct GNUNET_MessageHeader header;
227 uint32_t options GNUNET_PACKED;
230 * Desired content type.
232 uint32_t block_type GNUNET_PACKED;
237 uint32_t hop_count GNUNET_PACKED;
240 * Desired replication level for this request.
242 uint32_t desired_replication_level GNUNET_PACKED;
245 * Total number of peers in get path.
247 unsigned int get_path_length;
250 * Peer which is an intermediate destination.
252 struct GNUNET_PeerIdentity current_destination;
255 * Source for which current_destination is the finger.
257 struct GNUNET_PeerIdentity current_source;
260 * The key we are looking for.
262 struct GNUNET_HashCode key;
270 * FIXME: Check the alignment in all the struct
271 * P2P Trail setup message
273 struct PeerTrailSetupMessage
277 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
279 struct GNUNET_MessageHeader header;
282 * Successor of this finger value will be our finger peer.
284 uint64_t destination_finger;
287 * Source peer which wants to setup the trail to one of its finger.
289 struct GNUNET_PeerIdentity source_peer;
292 * Peer to which this packet is forwarded.
294 struct GNUNET_PeerIdentity current_destination;
297 * In case the packet is forwarded to an intermediate finger, then
298 * current_source contains the peer id whose finger is the intermediate
299 * finger. In case the packet is forwarded to a friend, then it is NULL.
301 struct GNUNET_PeerIdentity current_source;
304 * Index into finger peer map, in NBO.
306 uint32_t finger_map_index;
309 * Number of entries in trail list, in NBO.
311 uint32_t trail_length GNUNET_PACKED;
317 * P2P Trail Setup Result message
319 struct PeerTrailSetupResultMessage
323 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT
325 struct GNUNET_MessageHeader header;
328 * Finger to which we have found the path.
330 struct GNUNET_PeerIdentity finger_identity;
333 * Peer which was looking for the trail to finger.
335 struct GNUNET_PeerIdentity destination_peer;
338 * Index into finger peer map
340 uint32_t finger_map_index;
343 * Number of entries in trail list.
345 uint32_t trail_length GNUNET_PACKED;
352 struct PeerTrailRejectionMessage
355 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION
357 struct GNUNET_MessageHeader header;
360 * Source peer which wants to set up the trail.
362 struct GNUNET_PeerIdentity source_peer;
365 * Finger identity value.
367 uint64_t finger_identity;
370 * Peer which sent trail rejection message.
372 struct GNUNET_PeerIdentity congested_peer;
375 * Index in finger peer map of source peer.
377 unsigned int finger_map_index;
380 * Total number of peers in the trail.
382 unsigned int trail_length;
389 * P2P Verify Successor message.
391 struct PeerVerifySuccessorMessage
395 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR
397 struct GNUNET_MessageHeader header;
400 * Source peer which wants to verify its successor.
402 struct GNUNET_PeerIdentity source_peer;
405 * My current successor.
407 struct GNUNET_PeerIdentity successor;
410 * Total number of peers in trail to current successor.
412 unsigned int trail_length;
417 * P2P Verify Successor Result message.
419 struct PeerVerifySuccessorResultMessage
423 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT
425 struct GNUNET_MessageHeader header;
428 * Destination peer which sent the request to verify its successor.
430 struct GNUNET_PeerIdentity destination_peer;
433 * Successor to which PeerVerifySuccessorMessage was sent.
435 struct GNUNET_PeerIdentity source_successor;
438 * source_successor's predecessor
440 struct GNUNET_PeerIdentity my_predecessor;
443 * Total number of peers in trail.
444 * If source_successor is not destination peer, then trail is from destination_peer
446 * If source_successor is destination peer, then trail is from destination_peer
447 * to source_successor.
449 unsigned int trail_length;
453 * P2P Notify New Successor message.
455 struct PeerNotifyNewSuccessorMessage
458 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR
460 struct GNUNET_MessageHeader header;
463 * Source peer which wants to notify its new successor.
465 struct GNUNET_PeerIdentity source_peer;
468 * New successor identity.
470 struct GNUNET_PeerIdentity destination_peer;
473 * Number of peers in trail from source_peer to new successor.
475 unsigned int trail_length;
479 GNUNET_NETWORK_STRUCT_END
483 * Linked list of messages to send to a particular other peer.
485 struct P2PPendingMessage
488 * Pointer to next item in the list
490 struct P2PPendingMessage *next;
493 * Pointer to previous item in the list
495 struct P2PPendingMessage *prev;
498 * When does this message time out?
500 struct GNUNET_TIME_Absolute timeout;
503 * Message importance level. FIXME: used? useful?
505 unsigned int importance;
508 * Actual message to be sent, allocated at the end of the struct:
509 * // msg = (cast) &pm[1];
510 * // memcpy (&pm[1], data, len);
512 const struct GNUNET_MessageHeader *msg;
518 * Linked List of peers which are part of trail to reach a particular Finger.
523 * Pointer to next item in the list
525 struct TrailPeerList *next;
528 * Pointer to previous item in the list
530 struct TrailPeerList *prev;
533 * An element in this trail list
535 struct GNUNET_PeerIdentity peer;
541 * Entry in friend_peermap.
548 struct GNUNET_PeerIdentity id;
551 * Number of trail of which this friend is the first hop.
553 unsigned int trail_links;
556 * Count of outstanding messages for this friend.
558 unsigned int pending_count;
561 * Head of pending messages to be sent to this friend.
563 struct P2PPendingMessage *head;
566 * Tail of pending messages to be sent to this friend.
568 struct P2PPendingMessage *tail;
571 * Core handle for sending messages to this friend.
573 struct GNUNET_CORE_TransmitHandle *th;
579 * Entry in finger_peermap.
586 struct GNUNET_PeerIdentity finger_identity;
589 * Index in finger peer map
591 unsigned int finger_map_index;
594 * Total number of entries in trail from (me,finger]
596 unsigned int trail_length;
599 * Head of trail to reach this finger.
601 struct TrailPeerList *head;
604 * Tail of trail to reach this finger.
606 struct TrailPeerList *tail;
610 enum current_destination_type
619 * FIXME: Think of a better name.
620 * Data structure passed to sorting algorithm in find_successor.
625 * 64 bit value of peer identity
630 * Type : MY_ID, FINGER, FINGER, Value
632 enum current_destination_type type;
635 * Pointer to original data structure linked to peer id.
642 * FIXME: Think of better comments.
643 * An entry in Failed_Trail_List
648 * Source peer which was trying to setup up the trail to @a destination_finger_value
650 struct GNUNET_PeerIdentity source_peer;
653 * Value to which we were trying to find the closest successor.
655 uint64_t destination_finger_value;
658 * Peer which has crossed the threshold limit on its routing table size.
660 struct GNUNET_PeerIdentity congested_peer;
666 * Task that sends FIND FINGER TRAIL requests.
668 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
672 * Task that periodically verifies my successor.
674 static GNUNET_SCHEDULER_TaskIdentifier verify_successor;
677 * Identity of this peer.
679 static struct GNUNET_PeerIdentity my_identity;
682 * Hash map of all the friends of a peer
684 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
687 * Hash map of all the fingers of a peer
689 static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap;
692 * Hash maps of all the trail which failed due to a congested peer.
694 static struct GNUNET_CONTAINER_MultiPeerMap *failed_trail_list;
699 static struct GNUNET_CORE_Handle *core_api;
702 * Finger map index for predecessor entry in finger peermap.
704 #define PREDECESSOR_FINGER_ID 64
707 * The current finger index that we have found trail to.
709 static unsigned int current_finger_index;
712 * Iterate over trail and search your index location in the array.
713 * @param trail Trail which contains list of peers.
714 * @return Index in the array.
717 search_my_location (struct GNUNET_PeerIdentity *trail)
723 * Called when core is ready to send a message we asked for
724 * out to the destination.
726 * @param cls the 'struct FriendInfo' of the target friend
727 * @param size number of bytes available in buf
728 * @param buf where the callee should write the message
729 * @return number of bytes written to buf
732 core_transmit_notify (void *cls, size_t size, void *buf)
734 struct FriendInfo *peer = cls;
736 struct P2PPendingMessage *pending;
741 while ((NULL != (pending = peer->head)) &&
742 (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
744 peer->pending_count--;
745 GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
746 GNUNET_free (pending);
750 /* no messages pending */
756 GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
757 GNUNET_CORE_PRIO_BEST_EFFORT,
758 GNUNET_TIME_absolute_get_remaining
759 (pending->timeout), &peer->id,
760 ntohs (pending->msg->size),
761 &core_transmit_notify, peer);
762 GNUNET_break (NULL != peer->th);
766 while ((NULL != (pending = peer->head)) &&
767 (size - off >= (msize = ntohs (pending->msg->size))))
769 GNUNET_STATISTICS_update (GDS_stats,
771 ("# Bytes transmitted to other peers"), msize,
773 memcpy (&cbuf[off], pending->msg, msize);
775 peer->pending_count--;
776 GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
777 GNUNET_free (pending);
779 if (peer->head != NULL)
782 GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
783 GNUNET_CORE_PRIO_BEST_EFFORT,
784 GNUNET_TIME_absolute_get_remaining
785 (pending->timeout), &peer->id, msize,
786 &core_transmit_notify, peer);
787 GNUNET_break (NULL != peer->th);
794 * Transmit all messages in the friend's message queue.
796 * @param peer message queue to process
799 process_friend_queue (struct FriendInfo *peer)
801 struct P2PPendingMessage *pending;
803 if (NULL == (pending = peer->head))
805 if (NULL != peer->th)
808 GNUNET_STATISTICS_update (GDS_stats,
810 ("# Bytes of bandwidth requested from core"),
811 ntohs (pending->msg->size), GNUNET_NO);
813 /* FIXME: Are we correctly initializing importance and pending. */
815 GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
817 GNUNET_TIME_absolute_get_remaining
818 (pending->timeout), &peer->id,
819 ntohs (pending->msg->size),
820 &core_transmit_notify, peer);
821 GNUNET_break (NULL != peer->th);
826 * FIXME: In this function using const, does it affect only here right? not in
827 * the struct P2PTrailSetupMessage as their fields are not defined as const.
828 * Also, I changed current_destination and current_source from const to not,
829 * because when we make a call from handle_dht_p2p_trail_setup, then we are
830 * passing struct for current_destination and not current_source, as we are writing
831 * to these variables and we can not decalre them as const.
832 * Construct a trail message and forward it to a friend.
833 * @param source_peer Peer which wants to set up the trail to one of its finger.
834 * @param destination_finger Peer identity closest to this value will be
835 * @a source_peer's finger.
836 * @param current_destination Finger of the @a current_source, for which among
837 * its friends, its own identity and all fingers, this
838 * finger is the closest to the @a destination_finger
839 * @param current_source Peer for which @a current_destination is its finger.
840 * @param target_friend Friend to which this message should be forwarded.
841 * @param trail_length Numbers of peers in the trail found so far.
842 * @param trail_peer_list Peers this request has traversed so far
843 * @param finger_map_index Index in finger peer map
846 GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer,
847 uint64_t destination_finger,
848 struct GNUNET_PeerIdentity *current_destination,
849 struct GNUNET_PeerIdentity *current_source,
850 struct FriendInfo *target_friend,
851 unsigned int trail_length,
852 const struct GNUNET_PeerIdentity *trail_peer_list,
853 unsigned int finger_map_index)
855 struct P2PPendingMessage *pending;
856 struct PeerTrailSetupMessage *tsm;
857 struct GNUNET_PeerIdentity *peer_list;
860 msize = sizeof (struct PeerTrailSetupMessage) +
861 (trail_length * sizeof (struct GNUNET_PeerIdentity));
863 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
869 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
871 /* SUPU: Its important to have such statistics as you need to keep track of
872 the packets lost due to full queue. */
873 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
877 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
878 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
879 tsm = (struct PeerTrailSetupMessage *) &pending[1];
880 pending->msg = &tsm->header;
881 tsm->header.size = htons (msize);
882 tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
883 /* FIXME: understand where you need to use memcpy or direct assignment. */
884 memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t));
885 memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
886 memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
887 memcpy (&(tsm->current_source), current_source, sizeof (struct GNUNET_PeerIdentity));
888 tsm->trail_length = htonl (trail_length);
889 tsm->finger_map_index = htonl (finger_map_index);
891 /* SUPU: here i guess its okay to have it as NULL as it is added at the end of
892 the struct but in case of current_destination and current_source, it is part
893 of the struct. thats why the confusion. */
894 if (trail_peer_list != NULL)
896 peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
897 memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
900 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
901 target_friend->pending_count++;
902 process_friend_queue (target_friend);
908 * Construct a trail setup result message and forward it to a friend.
909 * @param destination_peer Peer which will get the trail to one of its finger.
910 * @param source_finger Peer to which the trail has been setup to.
911 * @param target_friend Friend to which this message should be forwarded.
912 * @param trail_length Numbers of peers in the trail.
913 * @param trail_peer_list Peers which are part of the trail from source to destination.
914 * @param finger_map_index Index in finger peer map
917 GDS_NEIGHBOURS_send_trail_setup_result (struct GNUNET_PeerIdentity *destination_peer,
918 struct GNUNET_PeerIdentity *source_finger,
919 struct FriendInfo *target_friend,
920 unsigned int trail_length,
921 struct GNUNET_PeerIdentity *trail_peer_list,
922 unsigned int finger_map_index)
924 struct P2PPendingMessage *pending;
925 struct PeerTrailSetupResultMessage *tsrm;
926 struct GNUNET_PeerIdentity *peer_list;
929 msize = sizeof (struct PeerTrailSetupResultMessage) +
930 (trail_length * sizeof (struct GNUNET_PeerIdentity));
932 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
938 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
940 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
944 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
945 pending->importance = 0;
946 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
947 tsrm = (struct PeerTrailSetupResultMessage *) &pending[1];
948 pending->msg = &tsrm->header;
949 tsrm->header.size = htons (msize);
950 tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT);
951 memcpy (&(tsrm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
952 memcpy (&(tsrm->finger_identity), source_finger, sizeof (struct GNUNET_PeerIdentity));
953 tsrm->trail_length = htonl (trail_length);
954 tsrm->finger_map_index = htonl (finger_map_index);
955 peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
956 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
958 /* Send the message to chosen friend. */
959 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
960 target_friend->pending_count++;
961 process_friend_queue (target_friend);
966 * Construct a PeerVerifySuccessor message and send it to friend.
967 * @param source_peer Peer which wants to verify its successor
968 * @param successor Peer which is our current successor
969 * @param target_friend Friend to which this message should be forwarded.
970 * @param trail_peer_list Peer which are part of trail from source to destination
971 * @param trail_length Number of peers in the trail list.
973 void GDS_NEIGHBOURS_send_verify_successor(struct GNUNET_PeerIdentity *source_peer,
974 struct GNUNET_PeerIdentity *successor,
975 struct FriendInfo *target_friend,
976 struct GNUNET_PeerIdentity *trail_peer_list,
977 unsigned int trail_length)
979 struct PeerVerifySuccessorMessage *vsm;
980 struct P2PPendingMessage *pending;
981 struct GNUNET_PeerIdentity *peer_list;
984 msize = sizeof (struct PeerVerifySuccessorMessage) +
985 (trail_length * sizeof (struct GNUNET_PeerIdentity));
987 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
993 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
995 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
999 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1000 pending->importance = 0; /* FIXME */
1001 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1002 vsm = (struct PeerVerifySuccessorMessage *) &pending[1];
1003 pending->msg = &vsm->header;
1004 vsm->header.size = htons (msize);
1005 vsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR);
1006 memcpy (&(vsm->successor), successor, sizeof (struct GNUNET_PeerIdentity));
1007 memcpy (&(vsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1008 vsm->trail_length = htonl (trail_length);
1009 peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
1010 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1012 /* Send the message to chosen friend. */
1013 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1014 target_friend->pending_count++;
1015 process_friend_queue (target_friend);
1021 * Construct a PeerVerifySuccessorResult message and send it to friend.
1022 * @param destination_peer Peer which sent verify successor message
1023 * @param source_successor Peer to which verify successor message was sent.
1024 * @param my_predecessor source_successor's predecessor.
1025 * @param target_friend Friend to which this message should be forwarded.
1026 * @param trail_peer_list Peers which are part of trail from source to destination
1027 * @param trail_length Number of peers in the trail list.
1029 void GDS_NEIGHBOURS_send_verify_successor_result (struct GNUNET_PeerIdentity *destination_peer,
1030 struct GNUNET_PeerIdentity *source_successor,
1031 struct GNUNET_PeerIdentity *my_predecessor,
1032 struct FriendInfo *target_friend,
1033 struct GNUNET_PeerIdentity *trail_peer_list,
1034 unsigned int trail_length)
1036 struct PeerVerifySuccessorResultMessage *vsmr;
1037 struct P2PPendingMessage *pending;
1038 struct GNUNET_PeerIdentity *peer_list;
1041 msize = sizeof (struct PeerVerifySuccessorResultMessage) +
1042 (trail_length * sizeof(struct GNUNET_PeerIdentity));
1044 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1051 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1053 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1057 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1058 pending->importance = 0; /* FIXME */
1059 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1060 vsmr = (struct PeerVerifySuccessorResultMessage *) &pending[1];
1061 pending->msg = &vsmr->header;
1062 vsmr->header.size = htons (msize);
1063 vsmr->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT);
1064 memcpy (&(vsmr->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1065 memcpy (&(vsmr->source_successor), source_successor, sizeof (struct GNUNET_PeerIdentity));
1066 memcpy (&(vsmr->my_predecessor), my_predecessor, sizeof (struct GNUNET_PeerIdentity));
1067 vsmr->trail_length = htonl (trail_length);
1068 peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
1069 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1071 /* Send the message to chosen friend. */
1072 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1073 target_friend->pending_count++;
1074 process_friend_queue (target_friend);
1079 * Construct a PeerNotifyNewSuccessor message and send it to friend.
1080 * @param source_peer Peer which is sending notify message to its new successor.
1081 * @param destination_peer Peer which is the new destination.
1082 * @param target_friend Next friend to pass this message to.
1083 * @param peer_list List of peers in the trail to reach to destination_peer.
1084 * @param trail_length Total number of peers in peer list
1087 GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity *source_peer,
1088 struct GNUNET_PeerIdentity *destination_peer,
1089 struct FriendInfo *target_friend,
1090 struct GNUNET_PeerIdentity *trail_peer_list,
1091 unsigned int trail_length)
1093 struct PeerNotifyNewSuccessorMessage *nsm;
1094 struct P2PPendingMessage *pending;
1095 struct GNUNET_PeerIdentity *peer_list;
1098 msize = sizeof (struct PeerNotifyNewSuccessorMessage) +
1099 (trail_length * sizeof(struct GNUNET_PeerIdentity));
1101 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1107 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1109 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1113 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1114 pending->importance = 0; /* FIXME */
1115 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1116 nsm = (struct PeerNotifyNewSuccessorMessage *) &pending[1];
1117 pending->msg = &nsm->header;
1118 nsm->header.size = htons (msize);
1119 nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR);
1120 memcpy (&(nsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1121 memcpy (&(nsm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1122 nsm->trail_length = htonl (trail_length);
1124 peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
1125 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1127 /* Send the message to chosen friend. */
1128 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1129 target_friend->pending_count++;
1130 process_friend_queue (target_friend);
1135 * FIXME: Optimizaiton Once the basic code is running. Add the optimization
1136 * where you check if the threshold on number of links that should go through
1137 * a particular friend has crossed. If yes then again choose a different
1138 * friend. Important that the new friend chosen should be different. How to
1139 * ensure this? This is an important optimization as without this one x-vine
1140 * is actually not a sybil tolerant DHT.
1141 * Randomly choose one of your friends from the friends_peer map
1144 static struct FriendInfo *
1145 select_random_friend (struct GNUNET_PeerIdentity *congested_peer)
1147 unsigned int current_size;
1148 unsigned int *index;
1150 struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1151 struct GNUNET_PeerIdentity key_ret;
1152 struct FriendInfo *friend;
1154 current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
1155 index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1156 iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1158 if (GNUNET_CONTAINER_multipeermap_size (friend_peermap) == 0)
1160 /* FIXME: It may happen that there is not friend in friend peermap but
1161 as this task has already been started it failed.*/
1167 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
1175 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1177 /* TODO: Here you have chosen a random friend. Now you should check the size
1178 of its routing table size, and if its more than threshold, then check which
1179 of the entries has trail length greater than trail length threshold. we
1180 should without checking the routing table size also we should check the
1181 trail with trail length greater than threshold. then
1182 you should try to find a new route through this new node that has joined in
1183 only for those finger entries whose trail length is greater than threshold.
1184 But I don't want the new node to wait for this process to get over. so
1185 should i declare a function which will be called after some interval.*/
1194 * FIMXE: pass current_finger_index as argument.
1195 * Compute finger_identity to which we want to setup the trail
1196 * @return finger_identity
1199 compute_finger_identity()
1203 memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1204 my_id64 = GNUNET_ntohll (my_id64);
1205 /*FIXME: Do we need a mod finger = ((my_id + pow(2, finger_index)) mod (pow (2, MAX_FINGERS))*/
1206 return (my_id64 + (unsigned long) pow (2, current_finger_index));
1211 * Compute immediate predecessor identity in the network.
1212 * @return peer identity of immediate predecessor.
1215 compute_predecessor_identity()
1219 memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1220 my_id64 = GNUNET_ntohll (my_id64);
1221 return (my_id64 -1);
1226 * Periodically ping your successor to ask its current predecessor
1228 * @param cls closure for this task
1229 * @param tc the context under which the task is running
1232 send_verify_successor_message (void *cls,
1233 const struct GNUNET_SCHEDULER_TaskContext *tc )
1235 struct GNUNET_TIME_Relative next_send_time;
1236 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1237 struct GNUNET_PeerIdentity key_ret;
1238 struct FriendInfo *target_friend;
1239 struct GNUNET_PeerIdentity *next_hop;
1240 struct GNUNET_PeerIdentity *peer_list;
1241 struct FingerInfo *finger;
1242 unsigned int finger_index;
1246 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1247 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1249 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1250 (const void **)&finger))
1252 if (0 == finger->finger_map_index)
1259 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1262 goto send_new_request;
1264 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->trail_length);
1266 struct TrailPeerList *iterate;
1267 iterate = finger->head;
1269 while ( i < (finger->trail_length))
1271 memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity));
1272 iterate = iterate->next;
1276 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1277 memcpy (next_hop, &peer_list[0], sizeof (struct GNUNET_PeerIdentity));
1278 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1280 GDS_NEIGHBOURS_send_verify_successor (&my_identity,
1281 &(finger->finger_identity),
1284 finger->trail_length);
1287 /* FIXME: Understand what this function is actually doing here. */
1289 next_send_time.rel_value_us =
1290 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1291 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1292 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
1295 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_verify_successor_message,
1301 * FIXME - the main logic of handling the finger map index has changed.
1302 * first we start with finger index = 64, that index is reserved for the
1303 * predecessor always. Then we start going backwards, finger_index = 63 to 0
1304 * and once its 0 we again go back to 64. now, when you start looking for the finger
1305 * then your successor is always the finger with lowest finger index. in finger_table_add
1306 * whenever you do an entry you check for predecessor , if the new finger identity
1307 * is greater than existing one, then that should be your predecessor. In case of
1308 * other fingers also, if the new entry is smaller than existing one. If yes
1309 * then that is correct finger for that finger index. Also, the lowest finger index and
1310 * its corresponding finger identity is your successor.
1312 * Choose a random friend and start looking for the trail to reach to
1313 * finger identity through this random friend.
1315 * @param cls closure for this task
1316 * @param tc the context under which the task is running
1319 send_find_finger_trail_message (void *cls,
1320 const struct GNUNET_SCHEDULER_TaskContext *tc)
1322 struct FriendInfo *target_friend;
1323 struct GNUNET_TIME_Relative next_send_time;
1324 uint64_t finger_identity;
1325 unsigned int finger_map_index;
1327 /* FIXME: understand how does this scheduling of processes take place? */
1328 next_send_time.rel_value_us =
1329 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1330 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1331 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
1332 /* FIXME: here we are just adding the process to the scheduling list. only
1333 when this function is executed, it may get scheduled. */
1334 find_finger_trail_task =
1335 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1337 target_friend = select_random_friend (NULL);
1339 if (NULL == target_friend)
1341 /* SUPU: Here we can get NULL in the case there is no friend in the peer map
1342 or all of the friends have reached their threshold. The first case should ideally
1343 never happen because in handle_core_disconnect we have already canceled the task
1344 but it may happen if we already started the process and we reached here and
1345 we cancelled the next task. So, it can return NULL in that case also. Should
1346 we handle both cases in same way or not? */
1350 /* FIXME: start with current_finger_index = 64, */
1351 if (PREDECESSOR_FINGER_ID == current_finger_index)
1353 /* FIXME: Where do we set the value back to PREDECESSR_FINGER_ID? Only
1354 when current_finger_index = 0, do we set it back to PREDECESSOR_FINGER_ID,
1355 in finger_table_add? Or is there any other possible condition, where we
1356 may need to set it to PREDECESSOR_FINGER_ID*/
1357 finger_identity = compute_predecessor_identity();
1361 finger_identity = compute_finger_identity();
1363 finger_map_index = current_finger_index;
1365 /* FIXME: verify if its correct to set current_destination and current_source
1367 GDS_NEIGHBOURS_send_trail_setup (&my_identity, finger_identity, &(target_friend->id),
1368 &(target_friend->id), target_friend, 0, NULL, finger_map_index);
1374 * @param destination_peer
1375 * @param existing_trail
1376 * @param trail_length
1379 static struct GNUNET_PeerIdentity *
1380 invert_trail_list (struct GNUNET_PeerIdentity *destination_peer,
1381 struct GNUNET_PeerIdentity *existing_trail,
1382 unsigned int trail_length)
1386 struct GNUNET_PeerIdentity *new_trail;
1389 new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
1391 if (trail_length > 1)
1393 i = trail_length - 2;
1396 memcpy( &new_trail[j], &existing_trail[i], sizeof (struct GNUNET_PeerIdentity));
1401 memcpy (&new_trail[j], destination_peer, sizeof(struct GNUNET_PeerIdentity));
1410 * @param existing_finger
1415 compare_finger_identity (struct GNUNET_PeerIdentity *existing_finger,
1416 struct GNUNET_PeerIdentity *new_finger)
1419 ret = (existing_finger > new_finger) ? 1 :
1420 (existing_finger == new_finger) ? 0 : -1;
1426 * FIXME: Not sure of the logic to find the correct predecessor
1427 * I think logic of this code is wrong everything else seems to be correct.
1428 * Given two finger identities, find the closest predecessor.
1429 * @param existing_predecessor
1430 * @param new_predecessor
1434 compare_predecessor(struct GNUNET_PeerIdentity *peer)
1436 /* FIXME: here you should first check if you already have an entry in the
1437 finger peer map for finger index = 64, if yes then compare it with peer
1438 if not then just add the peer. */
1443 /*FIXME: Here you need to set the correct value of finger_map_index,
1444 * in case it is 0, then you set it back to 64, and in case it is x,
1445 * then you set it back to x-1. current_finger_index = ( current_finger_index - 1) % MAX_FINGERS
1446 * Add an entry in finger table.
1447 * @param finger_identity Peer identity of finger
1448 * @param finger_trail Trail to reach the finger
1449 * @param trail_length Number of peers in the trail.
1450 * @param finger_map_index Index in finger peer map.
1453 void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1454 struct GNUNET_PeerIdentity *finger_trail,
1455 unsigned int trail_length,
1456 unsigned int finger_map_index)
1458 struct FingerInfo *new_finger_entry;
1459 //struct GNUNET_PeerIdentity key_ret;
1461 //struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1462 //struct FingerInfo *existing_finger;
1465 /* SUPU Here we trying to check if we already have an entry. If yes then we
1466 can keep two trails for redundant routing. if they are different then we
1467 need to choose the closest one. and remove the other one. */
1469 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1471 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1473 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1474 (const void **)&existing_finger))
1476 if ((finger_map_index == existing_finger->finger_map_index))
1478 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),finger_identity))
1480 /* FIXME: Here you should check if the trail is same. If yes then don't add the entry. it
1481 seems to be very suboptimal. */
1482 if ((existing_finger->trail_length) == trail_length)
1484 struct TrailPeerList *iterate;
1485 iterate = existing_finger->head;
1488 while (k < trail_length)
1490 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(iterate->peer), &finger_trail[k]))
1493 iterate = iterate->next;
1496 if (k == trail_length)
1506 if (finger_map_index == 1)
1508 ret = compare_predecessor (&(existing_finger->finger_identity),
1514 ret = compare_finger_identity (&(existing_finger->finger_identity),
1519 GNUNET_assert (GNUNET_YES ==
1520 GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
1521 &(existing_finger->finger_identity),
1536 new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
1537 memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity));
1538 new_finger_entry->finger_map_index = finger_map_index;
1540 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity))
1542 /* I am the finger */
1543 new_finger_entry->trail_length = 0;
1548 while (i < trail_length)
1550 struct TrailPeerList *element;
1551 element = GNUNET_malloc (sizeof (struct TrailPeerList));
1552 element->next = NULL;
1553 element->prev = NULL;
1555 memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity));
1556 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->head, new_finger_entry->tail, element);
1559 new_finger_entry->trail_length = trail_length;
1562 /* FIXME: Here we are keeping multiple hashmap option so that there are
1563 multiple routes to reach to same finger, redundant routing.
1564 * Also same peers could be our fingers for different finger map index
1565 * Should we handle the case where we have same fingers at the different
1566 * finger index but with different trail to reach. */
1567 GNUNET_assert (GNUNET_OK ==
1568 GNUNET_CONTAINER_multipeermap_put (finger_peermap,
1569 &(new_finger_entry->finger_identity),
1571 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1573 if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap)
1574 && (new_finger_entry->finger_map_index!= 1))
1576 verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL);
1582 * Compare two peer identities.
1583 * @param p1 Peer identity
1584 * @param p2 Peer identity
1585 * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2.
1588 compare_peer_id (const void *p1, const void *p2)
1590 struct Sorting_List *p11;
1591 struct Sorting_List *p22;
1593 p11 = GNUNET_malloc (sizeof (struct Sorting_List));
1594 p22 = GNUNET_malloc (sizeof (struct Sorting_List));
1595 p11 = (struct Sorting_List *)p1;
1596 p22 = (struct Sorting_List *)p2;
1597 ret = ( (p11->peer_id) > (p22->peer_id) ) ? 1 :
1598 ( (p11->peer_id) == (p22->peer_id) ) ? 0 : -1;
1604 * Return the successor of value in all_known_peers.
1605 * @param all_known_peers list of all the peers
1606 * @param value value we have to search in the all_known_peers.
1609 static struct Sorting_List *
1610 find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value,
1619 middle = (first + last)/2;
1621 while(first <= last)
1623 if(all_known_peers[middle].peer_id < value)
1627 else if(all_known_peers[middle].peer_id == value)
1629 if(middle == (size -1))
1631 return &all_known_peers[0];
1635 return &all_known_peers[middle+1];
1643 middle = (first + last)/2;
1650 * here you should set the current source instead of destination type.
1651 * Find closest successor for the value.
1652 * @param value Value for which we are looking for successor
1653 * FIXME: pass the correct value for current_destination
1654 * @param[out] current_destination set to the end of the finger to traverse next
1655 * @param type Next destination type
1656 * @return Peer identity of next hop, NULL if we are the
1657 * ultimate destination
1659 static struct GNUNET_PeerIdentity *
1660 find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1661 struct GNUNET_PeerIdentity *current_source)
1663 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
1664 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1665 struct GNUNET_PeerIdentity key_ret;
1666 struct FriendInfo *friend;
1667 struct FingerInfo *finger;
1668 unsigned int finger_index;
1669 unsigned int friend_index;
1670 struct Sorting_List *successor;
1674 /* 2 is added in size for my_identity and value which will part of all_known_peers. */
1675 size = GNUNET_CONTAINER_multipeermap_size (friend_peermap)+
1676 GNUNET_CONTAINER_multipeermap_size (finger_peermap)+
1679 struct Sorting_List all_known_peers[size];
1682 for (k = 0; k < size; k++)
1683 all_known_peers[k].peer_id = 0;
1685 /* Copy your identity at 0th index in all_known_peers. */
1687 memcpy (&(all_known_peers[j].peer_id), &my_identity, sizeof (uint64_t));
1688 all_known_peers[j].type = MY_ID;
1689 all_known_peers[j].data = 0;
1693 all_known_peers[j].peer_id = value;
1694 all_known_peers[j].type = VALUE;
1695 all_known_peers[j].data = 0;
1698 /* Iterate over friend peer map and copy all the elements into array. */
1699 friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1700 for (friend_index = 0; friend_index < GNUNET_CONTAINER_multipeermap_size (friend_peermap); friend_index++)
1702 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(friend_iter,&key_ret,(const void **)&friend))
1704 memcpy (&(all_known_peers[j].peer_id), &(friend->id), sizeof (uint64_t));
1705 all_known_peers[j].type = FRIEND;
1706 all_known_peers[j].data = friend;
1711 /* Iterate over finger map and copy all the entries into all_known_peers array. */
1712 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1713 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1715 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(finger_iter,&key_ret,(const void **)&finger))
1717 memcpy (&(all_known_peers[j].peer_id), &(finger->finger_identity), sizeof (uint64_t));
1718 all_known_peers[j].type = FINGER;
1719 all_known_peers[j].data = finger;
1724 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1725 GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter);
1727 qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id);
1729 /* search value in all_known_peers array. */
1730 successor = find_closest_successor (all_known_peers, value, size);
1732 if (successor->type == MY_ID)
1736 else if (successor->type == FRIEND)
1738 struct FriendInfo *target_friend;
1739 target_friend = (struct FriendInfo *)successor->data;
1740 memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
1741 return current_destination;
1743 else if (successor->type == FINGER)
1745 struct GNUNET_PeerIdentity *next_hop;
1746 struct FingerInfo *finger;
1747 struct TrailPeerList *iterator;
1748 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
1749 finger = successor->data;
1750 iterator = finger->head;
1751 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1752 memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
1753 memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
1754 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
1765 /** FIXME: by default I keep current_source, and destination as my own id.
1766 * in case we find a finger then we update current_source in the
1767 * find_successor message.
1768 * Construct a Put message and send it to target_peer.
1769 * @param key Key for the content
1770 * @param data Content to store
1771 * @param data_size Size of content @a data in bytes
1772 * @param block_type Type of the block
1773 * @param options Routing options
1774 * @param desired_replication_level Desired replication count
1775 * @param expiration_time When does the content expire
1776 * @param current_destination
1777 * @param current_source
1778 * @param target_peer Peer to which this message will be forwarded.
1779 * @param hop_count Number of hops traversed so far.
1780 * @param put_path_length Total number of peers in @a put_path
1781 * @param put_path Number of peers traversed so far
1784 GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
1785 const void *data, size_t data_size,
1786 enum GNUNET_BLOCK_Type block_type,
1787 enum GNUNET_DHT_RouteOption options,
1788 uint32_t desired_replication_level,
1789 struct GNUNET_TIME_Absolute expiration_time,
1790 struct GNUNET_PeerIdentity *current_destination,
1791 struct GNUNET_PeerIdentity *current_source,
1792 struct GNUNET_PeerIdentity *target_peer,
1794 uint32_t put_path_length,
1795 struct GNUNET_PeerIdentity *put_path)
1797 struct PeerPutMessage *ppm;
1798 struct P2PPendingMessage *pending;
1799 struct FriendInfo *target_friend;
1800 struct GNUNET_PeerIdentity *pp;
1803 msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
1804 sizeof (struct PeerPutMessage);
1806 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1808 put_path_length = 0;
1809 msize = data_size + sizeof (struct PeerPutMessage);
1812 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1818 /* This is the first call made from clients file. So, we should search for the
1820 if (NULL == target_peer)
1823 struct GNUNET_PeerIdentity *next_hop;
1825 memcpy (&key_value, key, sizeof (uint64_t));
1826 next_hop = find_successor (key_value, current_destination, current_source);
1827 if (NULL == next_hop) /* I am the destination do datacache_put */
1829 GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path,
1830 block_type, data_size, data);
1834 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1837 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1838 pending->timeout = expiration_time;
1839 ppm = (struct PeerPutMessage *) &pending[1];
1840 pending->msg = &ppm->header;
1841 ppm->header.size = htons (msize);
1842 ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
1843 ppm->options = htonl (options);
1844 ppm->block_type = htonl (block_type);
1845 ppm->hop_count = htonl (hop_count + 1);
1846 ppm->desired_replication_level = htonl (desired_replication_level);
1847 ppm->put_path_length = htonl (put_path_length);
1848 ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
1850 ppm->current_destination = *current_destination;
1851 ppm->current_source = *current_source;
1853 pp = (struct GNUNET_PeerIdentity *) &ppm[1];
1854 if (put_path_length != 0)
1856 memcpy (pp, put_path,
1857 sizeof (struct GNUNET_PeerIdentity) * put_path_length);
1859 memcpy (&pp[put_path_length], data, data_size);
1860 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1861 target_friend->pending_count++;
1862 process_friend_queue (target_friend);
1867 /** FIXME: by default I keep current_source, and destination as my own id.
1868 * in case we find a finger then we update current_source in the
1869 * find_successor message.
1870 * Construct a Get message and send it to target_peer.
1871 * @param key Key for the content
1872 * @param block_type Type of the block
1873 * @param options Routing options
1874 * @param desired_replication_level Desired replication count
1875 * @param expiration_time When does the content expire
1876 * @param current_destination
1877 * @param current_source
1878 * @param target_peer Peer to which this message will be forwarded.
1879 * @param hop_count Number of hops traversed so far.
1880 * @param put_path_length Total number of peers in @a put_path
1881 * @param put_path Number of peers traversed so far
1884 GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
1885 enum GNUNET_BLOCK_Type block_type,
1886 enum GNUNET_DHT_RouteOption options,
1887 uint32_t desired_replication_level,
1888 struct GNUNET_PeerIdentity *current_destination,
1889 struct GNUNET_PeerIdentity *current_source,
1890 struct GNUNET_PeerIdentity *target_peer,
1892 uint32_t get_path_length,
1893 struct GNUNET_PeerIdentity *get_path)
1895 struct PeerGetMessage *pgm;
1896 struct P2PPendingMessage *pending;
1897 struct FriendInfo *target_friend;
1898 struct GNUNET_PeerIdentity *gp;
1901 msize = sizeof (struct PeerGetMessage) +
1902 (get_path_length * sizeof (struct GNUNET_PeerIdentity));
1904 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1910 if (NULL == target_peer)
1912 /* This is the first call from client file, we need to search for next_hop*/
1913 struct GNUNET_PeerIdentity *next_hop;
1916 memcpy (&key_value, key, sizeof (struct GNUNET_PeerIdentity));
1917 next_hop = find_successor (key_value, current_destination, current_source);
1918 if (NULL == next_hop) /* I am the destination do datacache_put */
1920 GDS_DATACACHE_handle_get (key,block_type, NULL, 0,
1921 NULL, 0, 1, &my_identity, NULL,&my_identity);
1925 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1929 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1930 pending->importance = 0; /* FIXME */
1931 pgm = (struct PeerGetMessage *) &pending[1];
1932 pending->msg = &pgm->header;
1933 pgm->header.size = htons (msize);
1934 pgm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET);
1935 pgm->get_path_length = htonl (get_path_length);
1937 pgm->current_destination = *current_destination;
1938 pgm->current_source = *current_source;
1939 pgm->hop_count = htonl (hop_count + 1);
1941 gp = (struct GNUNET_PeerIdentity *) &pgm[1];
1942 memcpy (gp, get_path, get_path_length * sizeof (struct GNUNET_PeerIdentity));
1943 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1944 target_friend->pending_count++;
1945 process_friend_queue (target_friend);
1950 * Send the get result to requesting client.
1951 * @param expiration When will this result expire?
1952 * @param key Key of the requested data.
1953 * @param put_path_length Number of peers in @a put_path
1954 * @param put_path Path taken to put the data at its stored location.
1955 * @param type Block type
1956 * @param data_size Size of the @a data
1957 * @param data Payload to store
1958 * @param get_path Path taken to reach to the location of the key.
1959 * @param get_path_length Number of peers in @a get_path
1960 * @param next_hop Next peer to forward the message to.
1961 * @param source_peer Peer which has the data for the key.
1964 GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration,
1965 const struct GNUNET_HashCode *key,
1966 unsigned int put_path_length,
1967 const struct GNUNET_PeerIdentity *put_path,
1968 enum GNUNET_BLOCK_Type type, size_t data_size,
1970 struct GNUNET_PeerIdentity *get_path,
1971 unsigned int get_path_length,
1972 struct GNUNET_PeerIdentity *next_hop,
1973 struct GNUNET_PeerIdentity *source_peer)
1975 struct PeerGetResultMessage *get_result;
1976 struct GNUNET_PeerIdentity *get_result_path;
1977 struct GNUNET_PeerIdentity *pp;
1978 struct P2PPendingMessage *pending;
1979 struct FriendInfo *target_friend;
1980 int current_path_index;
1983 msize = get_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
1984 sizeof (struct PeerPutMessage);
1986 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1992 current_path_index = search_my_location(get_path);
1993 if (0 == current_path_index)
1995 FPRINTF (stderr,_("\nSUPU %s, %s, %d"),__FILE__, __func__,__LINE__);
1996 GDS_CLIENTS_handle_reply (expiration, key, get_path_length, get_path, put_path_length,
1997 put_path, type, data_size, data);
2000 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2001 pending->importance = 0;
2002 get_result = (struct PeerGetResultMessage *)&pending[1];
2003 pending->msg = &get_result->header;
2004 get_result->header.size = htons (msize);
2005 get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT);
2006 get_result->key = *key;
2007 memcpy (&(get_result->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2008 get_result->expiration_time = expiration;
2010 get_result_path = (struct GNUNET_PeerIdentity *)&get_result[1];
2011 memcpy (get_result_path, get_path,
2012 sizeof (struct GNUNET_PeerIdentity) * get_path_length);
2013 memcpy (&get_result_path[get_path_length], data, data_size);
2014 /* FIXME: Is this correct? */
2015 pp = (struct GNUNET_PeerIdentity *)&get_result_path[1];
2016 memcpy (pp, put_path,sizeof (struct GNUNET_PeerIdentity) * put_path_length);
2018 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2019 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2020 target_friend->pending_count++;
2021 process_friend_queue (target_friend);
2026 * Send tral rejection message
2027 * @param source_peer Source peer which wants to set up the trail.
2028 * @param finger_identity Finger identity to which it want to setup the trail.
2029 * @param congested_peer Peer which has send trail rejection message
2030 * @param next_hop Peer to which this message should be forwarded.
2031 * @param finger_map_index
2032 * @param trail_peer_list
2033 * @param trail_length
2036 GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_peer,
2037 uint64_t finger_identity,
2038 struct GNUNET_PeerIdentity *congested_peer,
2039 const struct GNUNET_PeerIdentity *next_hop,
2040 unsigned int finger_map_index,
2041 struct GNUNET_PeerIdentity *trail_peer_list,
2042 unsigned int trail_length)
2044 struct PeerTrailRejectionMessage *trail_rejection;
2045 struct GNUNET_PeerIdentity *trail_list;
2046 struct P2PPendingMessage *pending;
2047 struct FriendInfo *target_friend;
2050 msize = sizeof (struct PeerTrailRejectionMessage);
2052 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2053 pending->importance = 0; /* FIXME */
2054 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
2055 trail_rejection = (struct PeerTrailRejectionMessage *) &pending[1];
2056 pending->msg = &trail_rejection->header;
2057 trail_rejection->header.size = htons (msize);
2058 trail_rejection->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
2059 memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2060 memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity));
2061 memcpy (&(trail_rejection->finger_identity), &finger_identity, sizeof (uint64_t));
2062 trail_rejection->finger_map_index = htonl(finger_map_index);
2063 trail_rejection->trail_length = htonl (trail_length);
2065 trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
2066 memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2068 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2069 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2070 target_friend->pending_count++;
2071 process_friend_queue (target_friend);
2083 handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2084 const struct GNUNET_MessageHeader *message)
2086 struct PeerPutMessage *put;
2087 struct GNUNET_PeerIdentity *put_path;
2088 struct GNUNET_HashCode test_key;
2089 enum GNUNET_DHT_RouteOption options;
2090 struct GNUNET_PeerIdentity current_destination;
2091 struct GNUNET_PeerIdentity current_source;
2092 struct GNUNET_PeerIdentity *next_hop;
2096 size_t payload_size;
2099 msize = ntohs (message->size);
2100 if (msize < sizeof (struct PeerPutMessage))
2102 GNUNET_break_op (0);
2106 put = (struct PeerPutMessage *) message;
2107 putlen = ntohl (put->put_path_length);
2110 sizeof (struct PeerPutMessage) +
2111 putlen * sizeof (struct GNUNET_PeerIdentity)) ||
2113 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2115 GNUNET_break_op (0);
2119 current_destination = put->current_destination;
2120 current_source = put->current_source;
2121 put_path = (struct GNUNET_PeerIdentity *) &put[1];
2122 payload = &put_path[putlen];
2123 options = ntohl (put->options);
2124 payload_size = msize - (sizeof (struct PeerPutMessage) +
2125 putlen * sizeof (struct GNUNET_PeerIdentity));
2127 switch (GNUNET_BLOCK_get_key (GDS_block_context, ntohl (put->block_type),
2128 payload, payload_size, &test_key))
2131 if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode)))
2133 char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
2134 GNUNET_break_op (0);
2135 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2136 "PUT with key `%s' for block with key %s\n",
2137 put_s, GNUNET_h2s_full (&test_key));
2138 GNUNET_free (put_s);
2143 GNUNET_break_op (0);
2146 /* cannot verify, good luck */
2150 if (ntohl (put->block_type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
2152 switch (GNUNET_BLOCK_evaluate (GDS_block_context,
2153 ntohl (put->block_type),
2155 NULL, 0, /* bloom filer */
2156 NULL, 0, /* xquery */
2157 payload, payload_size))
2159 case GNUNET_BLOCK_EVALUATION_OK_MORE:
2160 case GNUNET_BLOCK_EVALUATION_OK_LAST:
2163 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
2164 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
2165 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
2166 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
2167 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
2168 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
2170 GNUNET_break_op (0);
2175 struct GNUNET_PeerIdentity pp[putlen + 1];
2176 /* extend 'put path' by sender */
2177 /* FIXME: Check what are we doing here? */
2178 if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
2180 memcpy (pp, put_path, putlen * sizeof (struct GNUNET_PeerIdentity));
2187 memcpy (&key_value, &(put->key), sizeof (uint64_t));
2188 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_destination, &my_identity)))
2190 next_hop = GDS_ROUTING_search (¤t_source, ¤t_destination, peer);
2191 if (next_hop == NULL)
2193 /* refer to handle_dht_p2p_trail_setup. */
2198 next_hop = find_successor (key_value, ¤t_destination, ¤t_source);
2201 if (NULL == next_hop) /* I am the final destination */
2203 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
2204 &(put->key),putlen, pp, ntohl (put->block_type),
2205 payload_size, payload);
2210 GDS_CLIENTS_process_put (options,
2211 ntohl (put->block_type),
2212 ntohl (put->hop_count),
2213 ntohl (put->desired_replication_level),
2215 GNUNET_TIME_absolute_ntoh (put->expiration_time),
2220 GDS_NEIGHBOURS_send_put (&put->key, payload, payload_size,
2221 ntohl (put->block_type),ntohl (put->options),
2222 ntohl (put->desired_replication_level),
2223 GNUNET_TIME_absolute_ntoh (put->expiration_time),
2224 ¤t_destination, ¤t_source, next_hop,
2225 ntohl (put->hop_count), putlen, pp);
2229 return GNUNET_SYSERR;
2234 * Core handler for p2p get requests.
2236 * @param cls closure
2237 * @param peer sender of the request
2238 * @param message message
2239 * @return #GNUNET_OK to keep the connection open,
2240 * #GNUNET_SYSERR to close it (signal serious error)
2243 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2244 const struct GNUNET_MessageHeader *message)
2246 struct PeerGetMessage *get;
2247 struct GNUNET_PeerIdentity *get_path;
2248 struct GNUNET_PeerIdentity current_destination;
2249 struct GNUNET_PeerIdentity current_source;
2250 struct GNUNET_PeerIdentity *next_hop;
2251 uint32_t get_length;
2255 msize = ntohs (message->size);
2256 if (msize < sizeof (struct PeerGetMessage))
2258 GNUNET_break_op (0);
2262 get = (struct PeerGetMessage *)message;
2263 get_length = ntohl (get->get_path_length);
2264 get_path = (struct GNUNET_PeerIdentity *)&get[1];
2265 current_destination = get->current_destination;
2266 current_source = get->current_source;
2269 sizeof (struct PeerGetMessage) +
2270 get_length * sizeof (struct GNUNET_PeerIdentity)) ||
2272 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2274 GNUNET_break_op (0);
2278 /* Add sender to get path */
2279 struct GNUNET_PeerIdentity gp[get_length + 1];
2280 memcpy (gp, get_path, get_length * sizeof (struct GNUNET_PeerIdentity));
2281 gp[get_length + 1] = *peer;
2282 get_length = get_length + 1;
2284 memcpy (&key_value, &(get->key), sizeof (uint64_t));
2285 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_destination, &my_identity)))
2287 next_hop = GDS_ROUTING_search (¤t_source, ¤t_destination, peer);
2288 if (next_hop == NULL)
2290 /* refer to handle_dht_p2p_trail_setup. */
2295 next_hop = find_successor (key_value, ¤t_destination, ¤t_source);
2298 if (NULL == next_hop)
2300 /* FIXME: Try to make this code also short and remove useless variables. */
2301 struct GNUNET_PeerIdentity final_get_path[get_length+1];
2302 memcpy (final_get_path, gp, get_length * sizeof (struct GNUNET_PeerIdentity));
2303 memcpy (&final_get_path[get_length+1], &my_identity, sizeof (struct GNUNET_PeerIdentity));
2304 get_length = get_length + 1;
2305 struct GNUNET_PeerIdentity *next_hop;
2306 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2307 memcpy (next_hop, &final_get_path[get_length-2], sizeof (struct GNUNET_PeerIdentity));
2308 GDS_DATACACHE_handle_get (&(get->key),(get->block_type), NULL, 0, NULL, 0,
2309 get_length, final_get_path,next_hop, &my_identity);
2315 GDS_NEIGHBOURS_send_get (&(get->key), get->block_type, get->options,
2316 get->desired_replication_level,¤t_destination,
2317 ¤t_source, next_hop, 0,
2320 return GNUNET_SYSERR;
2326 * Core handler for get result
2327 * @param cls closure
2328 * @param peer sender of the request
2329 * @param message message
2330 * @return #GNUNET_OK to keep the connection open,
2331 * #GNUNET_SYSERR to close it (signal serious error)
2334 handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2335 const struct GNUNET_MessageHeader *message)
2337 /* If you are the source, go back to the client file and there search for
2338 the requesting client and send back the result. */
2339 struct PeerGetResultMessage *get_result;
2340 struct GNUNET_PeerIdentity *get_path;
2341 struct GNUNET_PeerIdentity *put_path;
2343 size_t payload_size;
2345 unsigned int getlen;
2346 unsigned int putlen;
2347 int current_path_index;
2349 msize = ntohs (message->size);
2350 if (msize < sizeof (struct PeerGetResultMessage))
2352 GNUNET_break_op (0);
2356 get_result = (struct PeerGetResultMessage *)message;
2357 getlen = ntohl (get_result->get_path_length);
2358 putlen = ntohl (get_result->put_path_length);
2361 sizeof (struct PeerGetResultMessage) +
2362 getlen * sizeof (struct GNUNET_PeerIdentity) +
2363 putlen * sizeof (struct GNUNET_PeerIdentity)) ||
2365 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity) ||
2367 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))))
2369 GNUNET_break_op (0);
2373 get_path = (struct GNUNET_PeerIdentity *) &get_result[1];
2374 payload = &get_path[getlen];
2375 payload_size = msize - (sizeof (struct PeerGetResultMessage) +
2376 getlen * sizeof (struct GNUNET_PeerIdentity));
2377 /* FIXME: Check if its correct or not. */
2379 put_path = &get_path[1];
2381 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(get_path[0]))))
2383 //GDS_CLIENTS_process_get_result();
2384 GDS_CLIENTS_handle_reply (get_result->expiration_time, &(get_result->key),
2385 getlen, get_path, putlen,
2386 put_path, get_result->type, payload_size, payload);
2391 struct GNUNET_PeerIdentity *next_hop;
2392 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2393 current_path_index = search_my_location (get_path);
2394 /* FIXME: First check if you are adding yourself to the get path or not.
2395 if yes then don't check if current_path_index == 0, if not then check
2396 and next_hop == source_peer. */
2397 memcpy (next_hop, &get_path[current_path_index - 1], sizeof (struct GNUNET_PeerIdentity));
2399 GDS_NEIGHBOURS_send_get_result (get_result->expiration_time, &(get_result->key),
2401 get_result->type, payload_size,payload,
2403 next_hop, &(get_result->source_peer));
2406 return GNUNET_SYSERR;
2411 * Handle a PeerTrailSetupMessage.
2412 * @param cls closure
2413 * @param message message
2414 * @param peer peer identity this notification is about
2415 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2418 handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2419 const struct GNUNET_MessageHeader *message)
2421 const struct PeerTrailSetupMessage *trail_setup;
2422 struct GNUNET_PeerIdentity current_destination;
2423 struct GNUNET_PeerIdentity current_source;
2424 struct GNUNET_PeerIdentity source;
2425 struct GNUNET_PeerIdentity *next_hop;
2426 struct GNUNET_PeerIdentity next_peer;
2427 struct GNUNET_PeerIdentity *trail_peer_list;
2428 struct FriendInfo *target_friend;
2429 uint64_t destination_finger_value;
2430 uint32_t trail_length;
2431 uint32_t finger_map_index;
2434 msize = ntohs (message->size);
2435 if (msize < sizeof (struct PeerTrailSetupMessage))
2437 GNUNET_break_op (0);
2441 trail_setup = (const struct PeerTrailSetupMessage *) message;
2442 trail_length = ntohl (trail_setup->trail_length);
2444 if ((msize < sizeof (struct PeerTrailSetupMessage) +
2445 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2447 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2449 GNUNET_break_op (0);
2453 trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_setup[1];
2454 current_destination = trail_setup->current_destination;
2455 current_source = trail_setup->current_source;
2456 source = trail_setup->source_peer;
2457 finger_map_index = ntohl (trail_setup->finger_map_index);
2458 destination_finger_value = ntohl (trail_setup->destination_finger);
2460 /* Check if you are part of the trail or current destination, and accordingly
2461 * find the next peer to send the message to. */
2462 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_destination, &my_identity)))
2464 next_hop = GDS_ROUTING_search (¤t_source, ¤t_destination, peer);
2465 /* OPTIMIZATION: do find_successor also and get a better path if possible. */
2466 if (next_hop == NULL)
2468 /* FIXME next_hop to NULL,
2469 * 1. statistics update, drop the message.
2470 2. complain to sender with new message: trail lost */
2476 next_hop = find_successor (destination_finger_value, ¤t_destination, ¤t_source);
2479 /* Now add yourself to the trail. */
2480 struct GNUNET_PeerIdentity peer_list[trail_length + 1];
2481 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2482 peer_list[trail_length] = my_identity;
2485 /* Check next_hop type and make the judgment what to do next. */
2486 if (NULL == next_hop) /* This means I am the final destination */
2488 if (trail_length == 1)
2490 memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity));
2494 memcpy (&next_peer, &trail_peer_list[trail_length-2], sizeof (struct GNUNET_PeerIdentity));
2497 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
2499 /* FIXME: URGENT change it to handle the change in current_finger_index.
2500 compare to your own predecessor */
2501 if (compare_predecessor (&source) /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */)
2503 struct GNUNET_PeerIdentity *new_trail_list;
2504 new_trail_list = invert_trail_list (&source, peer_list, trail_length);
2505 finger_table_add (&source, new_trail_list, trail_length, PREDECESSOR_FINGER_ID);
2508 GDS_NEIGHBOURS_send_trail_setup_result (&source,
2510 target_friend, trail_length,
2518 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2519 GDS_NEIGHBOURS_send_trail_setup (&source,
2520 destination_finger_value,
2521 ¤t_destination, ¤t_source,
2522 target_friend, trail_length, peer_list,
2526 return GNUNET_SYSERR;
2531 * Core handle for p2p trail construction result messages.
2532 * @param cls closure
2533 * @param message message
2534 * @param peer peer identity this notification is about
2535 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2538 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2539 const struct GNUNET_MessageHeader *message)
2541 struct PeerTrailSetupResultMessage *trail_result;
2542 struct GNUNET_PeerIdentity *trail_peer_list;
2543 struct GNUNET_PeerIdentity *next_hop;
2544 struct FriendInfo *target_friend;
2545 unsigned int current_trail_index;
2546 unsigned int finger_map_index;
2547 unsigned int trail_length;
2550 msize = ntohs (message->size);
2551 if (msize < sizeof (struct PeerTrailSetupResultMessage))
2553 GNUNET_break_op (0);
2557 trail_result = (struct PeerTrailSetupResultMessage *) message;
2558 trail_length = ntohl (trail_result->trail_length);
2561 sizeof (struct PeerTrailSetupResultMessage) +
2562 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2564 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2566 GNUNET_break_op (0);
2570 finger_map_index = ntohl (trail_result->finger_map_index);
2572 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
2574 if ( 0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
2577 finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length,
2585 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2586 current_trail_index = search_my_location (trail_peer_list);
2587 current_trail_index = current_trail_index - 1;
2588 if (current_trail_index == 0)
2590 memcpy (next_hop, &(trail_result->destination_peer),sizeof (struct GNUNET_PeerIdentity));
2594 memcpy (next_hop, &(trail_peer_list[current_trail_index-1]),sizeof (struct GNUNET_PeerIdentity));
2597 /* If trail length = 2, it means that destination and source peer are friends
2598 Then don't add an entry. */
2599 if (trail_length != 2)
2600 GDS_ROUTING_add (&(trail_result->destination_peer), &(trail_result->finger_identity),
2602 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2603 GNUNET_free (next_hop);
2605 GDS_NEIGHBOURS_send_trail_setup_result (&(trail_result->destination_peer),
2606 &(trail_result->finger_identity),
2607 target_friend, trail_length,
2613 return GNUNET_SYSERR;
2618 * FIXME: Use flag in the case finger peer map does not contain predcessor
2619 * then its NULL. Ideally it should never happen.
2620 * Get my current predecessor from the finger peer map
2621 * @return Current predecessor.
2623 static struct FingerInfo *
2626 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2627 struct GNUNET_PeerIdentity key_ret;
2628 unsigned int finger_index;
2629 struct FingerInfo *my_predecessor;
2631 /* Iterate over finger peer map and extract your predecessor. */
2632 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
2633 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
2635 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next
2636 (finger_iter,&key_ret,(const void **)&my_predecessor))
2638 if(1 == my_predecessor->finger_map_index)
2644 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2645 return my_predecessor;
2650 * Core handle for p2p verify successor messages.
2651 * @param cls closure
2652 * @param message message
2653 * @param peer peer identity this notification is about
2654 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2657 handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2658 const struct GNUNET_MessageHeader *message)
2660 struct PeerVerifySuccessorMessage *vsm;
2661 struct GNUNET_PeerIdentity *trail_peer_list;
2662 struct FriendInfo *target_friend;
2663 struct GNUNET_PeerIdentity *next_hop;
2664 struct GNUNET_PeerIdentity *source_peer;
2665 unsigned int trail_length;
2668 msize = ntohs (message->size);
2669 if (msize < sizeof (struct PeerVerifySuccessorMessage))
2671 GNUNET_break_op (0);
2675 vsm = (struct PeerVerifySuccessorMessage *) message;
2676 trail_length = ntohl (vsm->trail_length);
2678 if ((msize < sizeof (struct PeerVerifySuccessorMessage) +
2679 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2680 (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2682 GNUNET_break_op (0);
2686 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
2687 source_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2688 memcpy (source_peer, &(vsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
2690 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2692 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity)))
2694 struct FingerInfo *my_predecessor;
2695 if (trail_length == 1)
2696 memcpy (next_hop, source_peer, sizeof (struct GNUNET_PeerIdentity));
2699 int current_trail_index;
2700 current_trail_index = search_my_location (trail_peer_list);
2701 memcpy (next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity));
2703 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2704 GNUNET_free (next_hop);
2706 my_predecessor = get_predecessor();
2707 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (source_peer,
2708 &(my_predecessor->finger_identity))))
2710 GDS_NEIGHBOURS_send_verify_successor_result (source_peer,
2712 &(my_predecessor->finger_identity),
2719 struct GNUNET_PeerIdentity *new_successor_trail;
2720 int new_trail_length;
2723 new_trail_length = trail_length + my_predecessor->trail_length;
2724 new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length);
2725 memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity));
2726 struct TrailPeerList *iterator;
2727 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
2728 iterator = my_predecessor->head;
2730 while (i < new_trail_length)
2732 memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
2733 iterator = iterator->next;
2737 GDS_NEIGHBOURS_send_verify_successor_result (source_peer,
2739 &(my_predecessor->finger_identity),
2741 new_successor_trail,
2748 unsigned int current_trail_index;
2749 current_trail_index = search_my_location (trail_peer_list);
2750 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2751 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2752 GNUNET_free (next_hop);
2754 GDS_NEIGHBOURS_send_verify_successor (source_peer, &(vsm->successor),target_friend,
2755 trail_peer_list, trail_length);
2762 * Core handle for p2p verify successor result messages.
2763 * @param cls closure
2764 * @param message message
2765 * @param peer peer identity this notification is about
2766 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2769 handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2770 const struct GNUNET_MessageHeader *message)
2772 struct PeerVerifySuccessorResultMessage *vsrm;
2773 struct FriendInfo *target_friend;
2774 struct GNUNET_PeerIdentity *trail_peer_list;
2775 struct GNUNET_PeerIdentity *next_hop;
2776 unsigned int trail_length;
2777 unsigned int current_trail_index;
2780 msize = ntohs (message->size);
2781 if (msize < sizeof (struct PeerVerifySuccessorResultMessage))
2783 GNUNET_break_op (0);
2787 vsrm = (struct PeerVerifySuccessorResultMessage *) message;
2788 trail_length = ntohl (vsrm->trail_length);
2791 sizeof (struct PeerVerifySuccessorResultMessage) +
2792 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2794 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2796 GNUNET_break_op (0);
2800 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1];
2802 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity))))
2804 if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor), &(my_identity))))
2806 finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0);
2807 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2808 memcpy (next_hop, &trail_peer_list[0], sizeof (struct GNUNET_PeerIdentity));
2809 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2810 GNUNET_free (next_hop);
2812 GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor),
2813 target_friend, trail_peer_list,
2819 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2820 current_trail_index = search_my_location (trail_peer_list);
2821 if (current_trail_index == 1)
2822 memcpy (next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity));
2824 memcpy (next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity));
2825 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2826 GNUNET_free (next_hop);
2828 GDS_NEIGHBOURS_send_verify_successor_result (&(vsrm->destination_peer),
2829 &(vsrm->source_successor),
2830 &(vsrm->my_predecessor),
2840 * Core handle for p2p notify new successor messages.
2841 * @param cls closure
2842 * @param message message
2843 * @param peer peer identity this notification is about
2844 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2847 handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2848 const struct GNUNET_MessageHeader *message)
2850 struct PeerNotifyNewSuccessorMessage *nsm;
2851 struct GNUNET_PeerIdentity *trail_peer_list;
2852 unsigned int current_trail_index;
2854 unsigned int trail_length;
2856 msize = ntohs (message->size);
2857 if (msize < sizeof (struct PeerNotifyNewSuccessorMessage))
2859 GNUNET_break_op (0);
2863 nsm = (struct PeerNotifyNewSuccessorMessage *) message;
2864 trail_length = ntohl (nsm->trail_length);
2866 if ((msize < sizeof (struct PeerNotifyNewSuccessorMessage) +
2867 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2869 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2871 GNUNET_break_op (0);
2875 trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
2877 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity)))
2879 struct GNUNET_PeerIdentity *new_trail;
2880 new_trail = invert_trail_list (&(nsm->source_peer), trail_peer_list, trail_length);
2881 finger_table_add (&(nsm->source_peer), new_trail, trail_length, 1);
2886 struct FriendInfo *target_friend;
2887 struct GNUNET_PeerIdentity *next_hop;
2889 target_friend = GNUNET_malloc (sizeof (struct FriendInfo));
2890 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2892 current_trail_index = search_my_location (trail_peer_list);
2893 memcpy (next_hop, &trail_peer_list[current_trail_index+1], sizeof (struct GNUNET_PeerIdentity));
2894 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2895 GNUNET_free (next_hop);
2897 GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer),
2898 &(nsm->destination_peer),
2899 target_friend, trail_peer_list,
2907 * FIXME: Does it matter if the packet was going to a finger or friend?
2908 * Core handle for p2p trail rejection messages.
2909 * @param cls closure
2910 * @param message message
2911 * @param peer peer identity this notification is about
2912 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2915 int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer,
2916 const struct GNUNET_MessageHeader *message)
2918 struct PeerTrailRejectionMessage *trail_rejection;
2919 struct FailedTrail *trail_fail;
2920 struct FriendInfo *target_friend;
2921 struct GNUNET_PeerIdentity *trail_peer_list;
2922 unsigned int finger_map_index;
2925 msize = ntohs (message->size);
2926 if (msize < sizeof (struct PeerTrailRejectionMessage))
2928 GNUNET_break_op (0);
2932 trail_rejection = (struct PeerTrailRejectionMessage *) message;
2933 trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
2934 finger_map_index = ntohl (trail_rejection->finger_map_index);
2935 trail_fail = GNUNET_malloc (sizeof (struct FailedTrail));
2936 memcpy (&(trail_fail->source_peer), &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
2937 memcpy (&(trail_fail->congested_peer), &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity));
2938 memcpy (&(trail_fail->destination_finger_value), &(trail_rejection->finger_identity), sizeof (uint64_t));
2940 GNUNET_assert (GNUNET_OK ==
2941 GNUNET_CONTAINER_multipeermap_put (failed_trail_list, &(trail_fail->source_peer),
2942 trail_fail, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
2944 /* FIXME: Is it okay if I pass the struct as parameter. */
2945 target_friend = select_random_friend (&(trail_fail->congested_peer));
2947 if(NULL != target_friend)
2949 GDS_NEIGHBOURS_send_trail_setup (&(trail_fail->source_peer),
2950 trail_fail->destination_finger_value,
2951 &(target_friend->id),
2952 NULL, target_friend, ntohl (trail_rejection->trail_length),
2957 return GNUNET_SYSERR;
2969 remove_matching_finger (void *cls,
2970 const struct GNUNET_PeerIdentity *key,
2973 struct FingerInfo *remove_finger = value;
2974 const struct GNUNET_PeerIdentity *disconnected_peer = cls;
2976 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->head->peer, disconnected_peer))
2978 GNUNET_assert (GNUNET_YES ==
2979 GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
2982 /* FIXME: free_finger(remove_finger); Call this function at finger_table_add,
2983 *when you replace an existing entry */
2990 * Method called whenever a peer disconnects.
2992 * @param cls closure
2993 * @param peer peer identity this notification is about
2996 handle_core_disconnect (void *cls,
2997 const struct GNUNET_PeerIdentity *peer)
3000 struct FriendInfo *remove_friend;
3001 //struct FingerInfo *remove_finger;
3002 // struct GNUNET_PeerIdentity key_ret;
3003 //struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
3004 //struct TrailPeerList *iterator;
3005 //struct GNUNET_PeerIdentity *finger_identity;
3008 /* Check for self message. */
3009 if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
3012 /* Search for peer to remove in your friend_peermap. */
3014 GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
3016 if (NULL == remove_friend)
3021 //FPRINTF (stderr,_("\nSUPU %s, %s, %d"),__FILE__, __func__,__LINE__);
3023 GNUNET_CONTAINER_multipeermap_iterate (finger_peermap,
3024 &remove_matching_finger, peer);
3025 /* Remove the friend from friend_peermap. */
3026 GNUNET_assert (GNUNET_YES ==
3027 GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
3031 if (0 != GNUNET_CONTAINER_multipeermap_size (friend_peermap))
3034 if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
3036 GNUNET_SCHEDULER_cancel (find_finger_trail_task);
3037 find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
3042 if (GNUNET_SCHEDULER_NO_TASK != verify_successor)
3044 GNUNET_SCHEDULER_cancel (verify_successor);
3045 verify_successor = GNUNET_SCHEDULER_NO_TASK;
3047 /* FIXME: garbage collect routing table, and notify the failed trails about
3055 * Method called whenever a peer connects.
3057 * @param cls closure
3058 * @param peer_identity peer identity this notification is about
3061 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
3063 struct FriendInfo *friend;
3065 /* Check for connect to self message */
3066 if (0 == memcmp (&my_identity, peer_identity, sizeof (struct GNUNET_PeerIdentity)))
3069 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to %s\n", GNUNET_i2s (peer_identity));
3071 /* If peer already exists in our friend_peermap, then exit. */
3072 if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap, peer_identity))
3077 /* FIXME: Use statistics at places where you think such a conditions are very
3078 rare. Then use statistics to make sure that it is indeed rare but if not
3079 rare then hanlde it differently.*/
3080 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
3083 friend = GNUNET_new (struct FriendInfo);
3084 friend->id = *peer_identity;
3086 GNUNET_assert (GNUNET_OK ==
3087 GNUNET_CONTAINER_multipeermap_put (friend_peermap,
3088 peer_identity, friend,
3089 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3091 /* got a first connection, good time to start with FIND FINGER TRAIL requests... */
3092 if (GNUNET_SCHEDULER_NO_TASK == find_finger_trail_task)
3093 find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
3098 * To be called on core init/fail.
3100 * @param cls service closure
3101 * @param identity the public identity of this peer
3104 core_init (void *cls,
3105 const struct GNUNET_PeerIdentity *identity)
3107 my_identity = *identity;
3109 /* SUPU TEST CODE */
3110 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3111 _("\nSUPU %s, %s, %d,my_identity = %s"),
3112 __FILE__, __func__, __LINE__, GNUNET_i2s (&my_identity));
3113 /* SUPU TEST CODE ENDS */
3119 * Initialize neighbours subsystem.
3120 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3123 GDS_NEIGHBOURS_init()
3125 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
3126 {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
3127 {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
3128 {&handle_dht_p2p_get_result, GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT, 0},
3129 {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
3130 {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
3131 {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
3132 {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
3133 {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
3134 {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0},
3139 GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
3140 &handle_core_disconnect, NULL, GNUNET_NO, NULL,
3141 GNUNET_NO, core_handlers);
3142 if (NULL == core_api)
3143 return GNUNET_SYSERR;
3145 /* Initialize the current index in the finger map. */
3146 current_finger_index = PREDECESSOR_FINGER_ID;
3148 friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
3149 finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO);
3150 /* FIXME: Not sure if this value is correct for this data structure. also
3151 * not sure if we actually need any such data structure. Once done with other functions,
3152 * will revisit this part. */
3153 failed_trail_list = GNUNET_CONTAINER_multipeermap_create (LINK_THRESHOLD * 4/3, GNUNET_NO);
3159 * Shutdown neighbours subsystem.
3162 GDS_NEIGHBOURS_done ()
3164 if (NULL == core_api)
3167 GNUNET_CORE_disconnect (core_api);
3170 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
3171 GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
3172 friend_peermap = NULL;
3174 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (finger_peermap));
3175 GNUNET_CONTAINER_multipeermap_destroy (finger_peermap);
3176 finger_peermap = NULL;
3178 /* FIXME: Here I have added GNUNET_break(0) as ideally if friend_peermap
3179 is already zero, then we really don't need to cancel it again. If this
3180 condition happens it mean we might have missed some corner case. */
3181 if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
3184 GNUNET_SCHEDULER_cancel (find_finger_trail_task);
3185 find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
3188 /* FIXME: when do you cancel verify successor irrespective of this part
3189 of code. If no where else, then there should not be GNUNET_break (0) as it
3190 is right to call it here. Also, leave it here for time being and in case
3191 you always encounter this break, it means it is nor required. remove it then. */
3192 if (GNUNET_SCHEDULER_NO_TASK != verify_successor)
3195 GNUNET_SCHEDULER_cancel (verify_successor);
3196 verify_successor = GNUNET_SCHEDULER_NO_TASK;
3202 * FIXME: I want to remove const but at the moment its giving error
3206 * @return my identity
3208 struct GNUNET_PeerIdentity *
3209 GDS_NEIGHBOURS_get_my_id (void)
3211 return &my_identity;
3215 /* end of gnunet-service-xdht_neighbours.c */