aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-04-28 15:28:19 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-04-28 15:28:19 +0000
commit49a2ed15bd67052f98813644eb3967dcb2e0f4f5 (patch)
tree16bb8eba4c75fab2900342d7022dc8dd3f710715 /src/dht
parenta8504a84ee0161e36180811b1d44fd1dc3ab9b17 (diff)
downloadgnunet-49a2ed15bd67052f98813644eb3967dcb2e0f4f5.tar.gz
gnunet-49a2ed15bd67052f98813644eb3967dcb2e0f4f5.zip
Handling trail rejection message, not using a failed trial list.
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c1271
-rw-r--r--src/dht/gnunet-service-xdht_routing.c22
-rw-r--r--src/dht/gnunet-service-xdht_routing.h14
3 files changed, 896 insertions, 411 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index e12afccf8..46247f9dd 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -47,12 +47,25 @@
47/* TODO: 47/* TODO:
48 1. Use a global array of all known peers in find_successor, Only when 48 1. Use a global array of all known peers in find_successor, Only when
49 a new peer is added in finger or friend peer map, then re calculate 49 a new peer is added in finger or friend peer map, then re calculate
50 the array. Or else use the old one.*/ 50 the array. Or else use the old one. The benefit of having this list is something
51 * I am not sure. only when the code is complete and working I will do this part.
52 2. Structure alignment.
53 3. In case of trail setup, you can see the comment on top of finger map index,
54 * trial length --> in NBO. Check how do we keep it in NBO, and make sure its
55 * same everywhere. When i send any message across the network i use htonl, so that
56 * converts it into network byte order.
57 4.THAT IN ROUTING TABLE SOURCE PEER IS INDEED THE SOURCE PEER.
58 should trail contain last element as finger or just the last element.? if
59 you can get some value then you should not keep at different places.
60 remove finger as last element in the trail.
61 5. I have removed the last element in the trail which was finger identity as we
62 * are already sending finger identity in the message. handle the case in case
63 * of notify new successor and verify the successor. */
51 64
52/** 65/**
53 * Maximum possible fingers of a peer. 66 * Maximum possible fingers of a peer.
54 */ 67 */
55#define MAX_FINGERS 63 68#define MAX_FINGERS 65
56 69
57/** 70/**
58 * Maximum allowed number of pending messages per friend peer. 71 * Maximum allowed number of pending messages per friend peer.
@@ -60,13 +73,12 @@
60#define MAXIMUM_PENDING_PER_FRIEND 64 73#define MAXIMUM_PENDING_PER_FRIEND 64
61 74
62/** 75/**
63 * How long at least to wait before sending another find finger trail request, 76 * How long to wait before sending another find finger trail request
64 * at most we wait twice this long.
65 */ 77 */
66#define DHT_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) 78#define DHT_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
67 79
68/** 80/**
69 * How long at most to wait for transmission of a GET request to another peer? 81 * How long at most to wait for transmission of a request to another peer?
70 */ 82 */
71#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) 83#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
72 84
@@ -75,7 +87,7 @@
75 * FIXME: Random value at the moment, need to be adjusted to maintain a balance 87 * FIXME: Random value at the moment, need to be adjusted to maintain a balance
76 * between performance and Sybil tolerance. 88 * between performance and Sybil tolerance.
77 */ 89 */
78#define LINK_THRESHOLD 64 90#define TRAIL_THROUGH_FRIEND_THRESHOLD 64.
79 91
80 92
81GNUNET_NETWORK_STRUCT_BEGIN 93GNUNET_NETWORK_STRUCT_BEGIN
@@ -107,6 +119,7 @@ struct PeerPutMessage
107 119
108 /** 120 /**
109 * Replication level for this message 121 * Replication level for this message
122 * In the current implementation, this value is not used.
110 */ 123 */
111 uint32_t desired_replication_level GNUNET_PACKED; 124 uint32_t desired_replication_level GNUNET_PACKED;
112 125
@@ -219,6 +232,7 @@ struct PeerGetMessage
219 232
220 /** 233 /**
221 * Desired replication level for this request. 234 * Desired replication level for this request.
235 * In the current implementation, this value is not used.
222 */ 236 */
223 uint32_t desired_replication_level GNUNET_PACKED; 237 uint32_t desired_replication_level GNUNET_PACKED;
224 238
@@ -248,7 +262,6 @@ struct PeerGetMessage
248 262
249 263
250/** 264/**
251 * FIXME: Check the alignment in all the struct
252 * P2P Trail setup message 265 * P2P Trail setup message
253 */ 266 */
254struct PeerTrailSetupMessage 267struct PeerTrailSetupMessage
@@ -278,19 +291,21 @@ struct PeerTrailSetupMessage
278 * In case the packet is forwarded to an intermediate finger, then 291 * In case the packet is forwarded to an intermediate finger, then
279 * current_source contains the peer id whose finger is the intermediate 292 * current_source contains the peer id whose finger is the intermediate
280 * finger. In case the packet is forwarded to a friend, then it is NULL. 293 * finger. In case the packet is forwarded to a friend, then it is NULL.
294 * FIXME: check the usage of current_source and fix this comment.
281 */ 295 */
282 struct GNUNET_PeerIdentity current_source; 296 struct GNUNET_PeerIdentity current_source;
283 297
284 /** 298 /**
285 * Index into finger peer map, in NBO. 299 * Index into finger peer map, in Network Byte Order.
286 */ 300 */
287 uint32_t finger_map_index; 301 uint32_t finger_map_index;
288 302
289 /** 303 /**
290 * Number of entries in trail list, in NBO. 304 * Number of entries in trail list, in Network Byte Order.
291 */ 305 */
292 uint32_t trail_length GNUNET_PACKED; 306 uint32_t trail_length GNUNET_PACKED;
293 307
308 /* Trail formed in the process. */
294}; 309};
295 310
296 311
@@ -316,19 +331,22 @@ struct PeerTrailSetupResultMessage
316 struct GNUNET_PeerIdentity destination_peer; 331 struct GNUNET_PeerIdentity destination_peer;
317 332
318 /** 333 /**
319 * Index into finger peer map 334 * Index into finger peer map in NBO.
320 */ 335 */
321 uint32_t finger_map_index; 336 uint32_t finger_map_index;
322 337
323 /** 338 /**
324 * Number of entries in trail list. 339 * Number of entries in trail list in NBO.
325 */ 340 */
326 uint32_t trail_length GNUNET_PACKED; 341 uint32_t trail_length GNUNET_PACKED;
327 342
343 /* Trail from destination_peer to finger_identity */
344
328}; 345};
329 346
347
330/** 348/**
331 * 349 * P2P Trail Rejection Message.
332 */ 350 */
333struct PeerTrailRejectionMessage 351struct PeerTrailRejectionMessage
334{ 352{
@@ -348,9 +366,10 @@ struct PeerTrailRejectionMessage
348 struct GNUNET_PeerIdentity congested_peer; 366 struct GNUNET_PeerIdentity congested_peer;
349 367
350 /** 368 /**
351 * Finger identity value. 369 * Peer identity which will be successor to this value will be finger of
370 * source_peer.
352 */ 371 */
353 uint64_t finger_identity; 372 uint64_t finger_identity_value;
354 373
355 /** 374 /**
356 * Index in finger peer map of source peer. 375 * Index in finger peer map of source peer.
@@ -362,7 +381,8 @@ struct PeerTrailRejectionMessage
362 */ 381 */
363 uint32_t trail_length; 382 uint32_t trail_length;
364 383
365 /* trail_list */ 384 /* Trail_list from source_peer to peer which sent the message for trail setup
385 * to congested peer.*/
366}; 386};
367 387
368 388
@@ -391,6 +411,8 @@ struct PeerVerifySuccessorMessage
391 * Total number of peers in trail to current successor. 411 * Total number of peers in trail to current successor.
392 */ 412 */
393 uint32_t trail_length; 413 uint32_t trail_length;
414
415 /* Trail to reach to from source_peer to successor. */
394}; 416};
395 417
396 418
@@ -422,14 +444,17 @@ struct PeerVerifySuccessorResultMessage
422 444
423 /** 445 /**
424 * Total number of peers in trail. 446 * Total number of peers in trail.
447 */
448 uint32_t trail_length;
449
450 /* Trail to reach from destination_peer to its correct successor.
425 * If source_successor is not destination peer, then trail is from destination_peer 451 * If source_successor is not destination peer, then trail is from destination_peer
426 * to my_predecessor. 452 * to my_predecessor.
427 * If source_successor is destination peer, then trail is from destination_peer 453 * If source_successor is destination peer, then trail is from destination_peer
428 * to source_successor. 454 * to source_successor. */
429 */
430 uint32_t trail_length;
431}; 455};
432 456
457
433/** 458/**
434 * P2P Notify New Successor message. 459 * P2P Notify New Successor message.
435 */ 460 */
@@ -454,8 +479,34 @@ struct PeerNotifyNewSuccessorMessage
454 * Number of peers in trail from source_peer to new successor. 479 * Number of peers in trail from source_peer to new successor.
455 */ 480 */
456 uint32_t trail_length; 481 uint32_t trail_length;
482
483 /* Trail to from source_peer to destination_peer. */
457}; 484};
458 485
486struct PeerTrailTearDownMessage
487{
488 /**
489 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN
490 */
491 struct GNUNET_MessageHeader header;
492
493 /**
494 * Source peer which wants to notify its new successor.
495 */
496 struct GNUNET_PeerIdentity source_peer;
497
498 /**
499 * New successor identity.
500 */
501 struct GNUNET_PeerIdentity destination_peer;
502
503 /**
504 * Number of peers in trail from source_peer to new successor.
505 */
506 uint32_t trail_length;
507
508 /* Trail to from source_peer to destination_peer. */
509};
459 510
460GNUNET_NETWORK_STRUCT_END 511GNUNET_NETWORK_STRUCT_END
461 512
@@ -529,9 +580,24 @@ struct FriendInfo
529 struct GNUNET_PeerIdentity id; 580 struct GNUNET_PeerIdentity id;
530 581
531 /** 582 /**
583 * 1. used in select_random_friend(), in case the friend has trails_count > TRAILS_THROUGH_FRIEND,
584 * then choose another friend.
585 * 2. in case of find_successor(), if the number of trails going through the friend
586 * has already crossed, then choose another friend.
587 * 3. in case of find_successor(), if we choose a finger, and if friend through
588 * which we reach this finger has crossed the limit then choose another finger/friend.
589 * 4. One way to implement in case of find_successor, is 1) you can have a global
590 * array of the entries and only when an entry is added in finger table, friend table,
591 * then you re calculate the array. In array while adding the element you check
592 * the threshold of the friend in case its friend, and in case of finger check
593 * the threshold of the first friend in the trail. If crossed then don't add the
594 * entries in the array. When the count goes down, then again set a flag and
595 * recalculte the array. Store a field in Finger table also, which will be
596 * equal to number of trails going through the first friend.
532 * Number of trail of which this friend is the first hop. 597 * Number of trail of which this friend is the first hop.
598 * 5.FIXME: understand where you need to use memcpy or direct assignment.
533 */ 599 */
534 unsigned int trail_links; 600 unsigned int trails_count;
535 601
536 /** 602 /**
537 * Count of outstanding messages for this friend. 603 * Count of outstanding messages for this friend.
@@ -577,6 +643,12 @@ struct FingerInfo
577 unsigned int trail_length; 643 unsigned int trail_length;
578 644
579 /** 645 /**
646 * Number of trail of which the first element to reach to this finger is
647 * part of.
648 */
649 unsigned int first_friend_trails_count;
650
651 /**
580 * Head of trail to reach this finger. 652 * Head of trail to reach this finger.
581 */ 653 */
582 struct TrailPeerList *head; 654 struct TrailPeerList *head;
@@ -588,6 +660,11 @@ struct FingerInfo
588 660
589}; 661};
590 662
663
664/**
665 * FIXME: The name is not correct.
666 * Used to specify the kind of value stored in the array all_known_peers.
667 */
591enum current_destination_type 668enum current_destination_type
592{ 669{
593 FRIEND, 670 FRIEND,
@@ -596,9 +673,9 @@ enum current_destination_type
596 MY_ID 673 MY_ID
597}; 674};
598 675
676
599/** 677/**
600 * FIXME: Think of a better name. 678 * Data structure passed to sorting algorithm in find_successor().
601 * Data structure passed to sorting algorithm in find_successor.
602 */ 679 */
603struct Sorting_List 680struct Sorting_List
604{ 681{
@@ -608,6 +685,7 @@ struct Sorting_List
608 uint64_t peer_id; 685 uint64_t peer_id;
609 686
610 /** 687 /**
688 * FIXME: think of a better name for both the struct and destination_type
611 * Type : MY_ID, FINGER, FINGER, Value 689 * Type : MY_ID, FINGER, FINGER, Value
612 */ 690 */
613 enum current_destination_type type; 691 enum current_destination_type type;
@@ -620,7 +698,7 @@ struct Sorting_List
620 698
621 699
622/** 700/**
623 * FIXME: Think of better comments. 701 * FIXME: Not sure if we really need any such data structure.
624 * An entry in Failed_Trail_List 702 * An entry in Failed_Trail_List
625 */ 703 */
626struct FailedTrail 704struct FailedTrail
@@ -644,13 +722,14 @@ struct FailedTrail
644 722
645 723
646/** 724/**
647 * Task that sends FIND FINGER TRAIL requests. 725 * Task that sends FIND FINGER TRAIL requests. This task is started when we have
726 * get our first friend.
648 */ 727 */
649static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task; 728static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
650 729
651/** 730/**
652 * 731 * Task that periodically verifies my successor. This task is started when we
653 * Task that periodically verifies my successor. 732 * have found our successor.
654 */ 733 */
655static GNUNET_SCHEDULER_TaskIdentifier verify_successor; 734static GNUNET_SCHEDULER_TaskIdentifier verify_successor;
656 735
@@ -670,11 +749,6 @@ static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
670static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap; 749static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap;
671 750
672/** 751/**
673 * Hash maps of all the trail which failed due to a congested peer.
674 */
675static struct GNUNET_CONTAINER_MultiPeerMap *failed_trail_list;
676
677/**
678 * Handle to CORE. 752 * Handle to CORE.
679 */ 753 */
680static struct GNUNET_CORE_Handle *core_api; 754static struct GNUNET_CORE_Handle *core_api;
@@ -684,22 +758,81 @@ static struct GNUNET_CORE_Handle *core_api;
684 */ 758 */
685#define PREDECESSOR_FINGER_ID 64 759#define PREDECESSOR_FINGER_ID 64
686 760
761unsigned int all_friends_trail_threshold;
687/** 762/**
688 * The current finger index that we have found trail to. 763 * FIXME: The problem with incrementing this value in find_finger_trail_task
764 * is that it may happen that we started with a request to look for a finger
765 * with current_finger_index = x, and its not yet complete but we are again back
766 * in send_find_finger_trail message and we again start looking for current_finger_index = x.
767 * and only when we get the entry for x, we make it x-1. I am not sure if this is
768 * correct.
769 * The current finger index that we have want to find trail to.
689 */ 770 */
690static unsigned int current_finger_index; 771static unsigned int current_finger_index;
691 772
773
692/** 774/**
693 * Iterate over trail and search your index location in the array. 775 * Iterate over trail and search your index location in the array.
694 * @param trail Trail which contains list of peers. 776 * @param trail Trail which contains list of peers.
777 * @param trail_length Number of peers in the trail.
695 * @return Index in the array. 778 * @return Index in the array.
779 * #GNUNET_SYSERR, in case there is no entry which should not be the case ideally.
696 */ 780 */
697static int 781static int
698search_my_index (const struct GNUNET_PeerIdentity *trail) 782search_my_index (const struct GNUNET_PeerIdentity *trail,
783 int trail_length)
784{
785 int i = 0;
786
787 while (i < trail_length)
788 {
789 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &trail[i]))
790 {
791 return i;
792 }
793 i++;
794 }
795 return GNUNET_SYSERR;
796}
797
798
799/**
800 * Invert the trail list.
801 * @param destination_peer Destination of the inverted trail.Trail is always
802 * (me, destination]. I am not part of trail that starts
803 * from me.
804 * @param existing_trail Trail
805 * @param trail_length Number of peers in the existing trail.
806 * @return
807 */
808static struct GNUNET_PeerIdentity *
809invert_trail_list (struct GNUNET_PeerIdentity *destination_peer,
810 struct GNUNET_PeerIdentity *existing_trail,
811 unsigned int trail_length)
699{ 812{
700 return 0; 813 int i;
814 int j;
815 struct GNUNET_PeerIdentity *new_trail;
816
817 j = 0;
818 new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
819
820 if (trail_length > 1)
821 {
822 i = trail_length - 2;
823 while (i >= 0 )
824 {
825 memcpy( &new_trail[j], &existing_trail[i], sizeof (struct GNUNET_PeerIdentity));
826 i--;
827 j++;
828 }
829 }
830 memcpy (&new_trail[j], destination_peer, sizeof(struct GNUNET_PeerIdentity));
831
832 return new_trail;
701} 833}
702 834
835
703/** 836/**
704 * Called when core is ready to send a message we asked for 837 * Called when core is ready to send a message we asked for
705 * out to the destination. 838 * out to the destination.
@@ -804,12 +937,6 @@ process_friend_queue (struct FriendInfo *peer)
804 937
805 938
806/** 939/**
807 * FIXME: In this function using const, does it affect only here right? not in
808 * the struct P2PTrailSetupMessage as their fields are not defined as const.
809 * Also, I changed current_destination and current_source from const to not,
810 * because when we make a call from handle_dht_p2p_trail_setup, then we are
811 * passing struct for current_destination and not current_source, as we are writing
812 * to these variables and we can not decalre them as const.
813 * Construct a trail message and forward it to a friend. 940 * Construct a trail message and forward it to a friend.
814 * @param source_peer Peer which wants to set up the trail to one of its finger. 941 * @param source_peer Peer which wants to set up the trail to one of its finger.
815 * @param destination_finger Peer identity closest to this value will be 942 * @param destination_finger Peer identity closest to this value will be
@@ -849,8 +976,6 @@ GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer,
849 976
850 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND) 977 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
851 { 978 {
852 /* SUPU: Its important to have such statistics as you need to keep track of
853 the packets lost due to full queue. */
854 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), 979 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
855 1, GNUNET_NO); 980 1, GNUNET_NO);
856 } 981 }
@@ -861,7 +986,6 @@ GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer,
861 pending->msg = &tsm->header; 986 pending->msg = &tsm->header;
862 tsm->header.size = htons (msize); 987 tsm->header.size = htons (msize);
863 tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP); 988 tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
864 /* FIXME: understand where you need to use memcpy or direct assignment. */
865 memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t)); 989 memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t));
866 memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); 990 memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
867 memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity)); 991 memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
@@ -869,9 +993,6 @@ GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer,
869 tsm->trail_length = htonl (trail_length); 993 tsm->trail_length = htonl (trail_length);
870 tsm->finger_map_index = htonl (finger_map_index); 994 tsm->finger_map_index = htonl (finger_map_index);
871 995
872 /* SUPU: here i guess its okay to have it as NULL as it is added at the end of
873 the struct but in case of current_destination and current_source, it is part
874 of the struct. thats why the confusion. */
875 if (trail_peer_list != NULL) 996 if (trail_peer_list != NULL)
876 { 997 {
877 peer_list = (struct GNUNET_PeerIdentity *) &tsm[1]; 998 peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
@@ -1111,6 +1232,61 @@ GDS_NEIGHBOURS_send_notify_new_successor (const struct GNUNET_PeerIdentity *sour
1111 process_friend_queue (target_friend); 1232 process_friend_queue (target_friend);
1112} 1233}
1113 1234
1235/**
1236 * Send a trail tear down message
1237 * @param source_peer Source of the trail.
1238 * @param destination_peer Destination of the trail.
1239 * @param trail_list Peers in the trail from @a source_peer to @a destination_peer
1240 * @param trail_length Total number of peers in trail_list.
1241 * @pararm target_peer Next peer to forward this message to.
1242 */
1243void
1244GDS_NEIGHBOURS_send_trail_teardown (struct GNUNET_PeerIdentity *source_peer,
1245 const struct GNUNET_PeerIdentity *destination_peer,
1246 struct GNUNET_PeerIdentity *trail_peer_list,
1247 unsigned int trail_length,
1248 struct FriendInfo *target_friend)
1249{
1250 struct P2PPendingMessage *pending;
1251 struct PeerTrailTearDownMessage *ttdm;
1252 struct GNUNET_PeerIdentity *peer_list;
1253 size_t msize;
1254
1255 msize = sizeof (struct PeerTrailTearDownMessage) +
1256 (trail_length * sizeof(struct GNUNET_PeerIdentity));
1257
1258 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1259 {
1260 GNUNET_break (0);
1261 return;
1262 }
1263
1264 if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1265 {
1266 GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1267 1, GNUNET_NO);
1268 }
1269
1270 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1271 pending->importance = 0; /* FIXME */
1272 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1273 ttdm = (struct PeerTrailTearDownMessage *) &pending[1];
1274 pending->msg = &ttdm->header;
1275 ttdm->header.size = htons (msize);
1276 ttdm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN);
1277 memcpy (&(ttdm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1278 memcpy (&(ttdm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1279 ttdm->trail_length = htonl (trail_length);
1280
1281 peer_list = (struct GNUNET_PeerIdentity *) &ttdm[1];
1282 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1283
1284 /* Send the message to chosen friend. */
1285 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1286 target_friend->pending_count++;
1287 process_friend_queue (target_friend);
1288}
1289
1114 1290
1115/** 1291/**
1116 * FIXME: Optimizaiton Once the basic code is running. Add the optimization 1292 * FIXME: Optimizaiton Once the basic code is running. Add the optimization
@@ -1136,13 +1312,6 @@ select_random_friend (struct GNUNET_PeerIdentity *congested_peer)
1136 index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size); 1312 index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1137 iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); 1313 iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1138 1314
1139 if (GNUNET_CONTAINER_multipeermap_size (friend_peermap) == 0)
1140 {
1141 /* FIXME: It may happen that there is not friend in friend peermap but
1142 as this task has already been started it failed.*/
1143 GNUNET_break(0);
1144 return NULL;
1145 }
1146 while(j < (*index)) 1315 while(j < (*index))
1147 { 1316 {
1148 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL)) 1317 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
@@ -1155,7 +1324,11 @@ select_random_friend (struct GNUNET_PeerIdentity *congested_peer)
1155 1324
1156 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend)) 1325 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1157 { 1326 {
1158 /* TODO: Here you have chosen a random friend. Now you should check the size 1327 /* TODO: UPDATE: Also, I think I am always looking for better trails, and always
1328 * choosing friends randomly so this solves the problem automatically. I don't
1329 * think I should call this algorithm here. Will read
1330 * the paper again and check if its right or not. Here you have
1331 * chosen a random friend. Now you should check the size
1159 of its routing table size, and if its more than threshold, then check which 1332 of its routing table size, and if its more than threshold, then check which
1160 of the entries has trail length greater than trail length threshold. we 1333 of the entries has trail length greater than trail length threshold. we
1161 should without checking the routing table size also we should check the 1334 should without checking the routing table size also we should check the
@@ -1164,6 +1337,23 @@ select_random_friend (struct GNUNET_PeerIdentity *congested_peer)
1164 only for those finger entries whose trail length is greater than threshold. 1337 only for those finger entries whose trail length is greater than threshold.
1165 But I don't want the new node to wait for this process to get over. so 1338 But I don't want the new node to wait for this process to get over. so
1166 should i declare a function which will be called after some interval.*/ 1339 should i declare a function which will be called after some interval.*/
1340 /* here we are checking the value only set by us. but the friend may have its
1341 routing table full. we don't have the access to the value. in trail setup
1342 it will fail. so in case of put/get if we don't have the trail already then
1343 how does the intermediate peer stores the information in routing table.
1344 because in put we don't do the put result. hence, intermediate peers don't
1345 add the path in their routing table. then in get is it problem. */
1346 /* Possible number of trails that can go through this friend has been reached. */
1347 if (friend->trails_count > TRAIL_THROUGH_FRIEND_THRESHOLD)
1348 {
1349 /* FIXME: What should I do now, should I call this same function again and
1350 remember the index, j so that call random function without j and find
1351 a new friend. Also, I need some way to make sure that if number of times
1352 I have called the function is equal to number of entries in friend peermap.
1353 then I should return NULL. but its much better to have a function which
1354 just eliminates looking at the entries with threshold crossed. URGENT: Whats
1355 the best way to handle this case? */
1356 }
1167 return friend; 1357 return friend;
1168 } 1358 }
1169 else 1359 else
@@ -1172,7 +1362,6 @@ select_random_friend (struct GNUNET_PeerIdentity *congested_peer)
1172 1362
1173 1363
1174/** 1364/**
1175 * FIMXE: pass current_finger_index as argument.
1176 * Compute finger_identity to which we want to setup the trail 1365 * Compute finger_identity to which we want to setup the trail
1177 * @return finger_identity 1366 * @return finger_identity
1178 */ 1367 */
@@ -1183,7 +1372,6 @@ compute_finger_identity()
1183 1372
1184 memcpy (&my_id64, &my_identity, sizeof (uint64_t)); 1373 memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1185 my_id64 = GNUNET_ntohll (my_id64); 1374 my_id64 = GNUNET_ntohll (my_id64);
1186 /*FIXME: Do we need a mod finger = ((my_id + pow(2, finger_index)) mod (pow (2, MAX_FINGERS))*/
1187 return (my_id64 + (unsigned long) pow (2, current_finger_index)); 1375 return (my_id64 + (unsigned long) pow (2, current_finger_index));
1188} 1376}
1189 1377
@@ -1224,6 +1412,7 @@ send_verify_successor_message (void *cls,
1224 unsigned int i; 1412 unsigned int i;
1225 int flag = 0; 1413 int flag = 0;
1226 1414
1415 /* Find the successor from the finger peermap.*/
1227 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 1416 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1228 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++) 1417 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1229 { 1418 {
@@ -1279,17 +1468,6 @@ send_verify_successor_message (void *cls,
1279 1468
1280 1469
1281/** 1470/**
1282 * FIXME - the main logic of handling the finger map index has changed.
1283 * first we start with finger index = 64, that index is reserved for the
1284 * predecessor always. Then we start going backwards, finger_index = 63 to 0
1285 * and once its 0 we again go back to 64. now, when you start looking for the finger
1286 * then your successor is always the finger with lowest finger index. in finger_table_add
1287 * whenever you do an entry you check for predecessor , if the new finger identity
1288 * is greater than existing one, then that should be your predecessor. In case of
1289 * other fingers also, if the new entry is smaller than existing one. If yes
1290 * then that is correct finger for that finger index. Also, the lowest finger index and
1291 * its corresponding finger identity is your successor.
1292 *
1293 * Choose a random friend and start looking for the trail to reach to 1471 * Choose a random friend and start looking for the trail to reach to
1294 * finger identity through this random friend. 1472 * finger identity through this random friend.
1295 * 1473 *
@@ -1305,36 +1483,49 @@ send_find_finger_trail_message (void *cls,
1305 uint64_t finger_identity; 1483 uint64_t finger_identity;
1306 unsigned int finger_map_index; 1484 unsigned int finger_map_index;
1307 1485
1308 /* FIXME: understand how does this scheduling of processes take place? */
1309 next_send_time.rel_value_us = 1486 next_send_time.rel_value_us =
1310 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + 1487 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1311 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 1488 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1312 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us); 1489 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
1313 /* FIXME: here we are just adding the process to the scheduling list. only 1490
1314 when this function is executed, it may get scheduled. */ 1491 /* FIXME; if all the friend have reached their threshold, then don't schedule
1492 the task till the all_friends_trail_threshold gets reset. It will be
1493 scheduled from there. So, in finger table when we remove an entry and the new
1494 * entry does not have the same friend as the first hop, then decrement the
1495 * threshold limit. and schedule this task.
1496 IMPORTANT: reset the value some where. Better name */
1497 if (GNUNET_YES == all_friends_trail_threshold)
1498 {
1499 return;
1500 }
1501
1315 find_finger_trail_task = 1502 find_finger_trail_task =
1316 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message, 1503 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1317 NULL); 1504 NULL);
1505
1506 /* Friend peermap is empty but this task has already been started it failed.*/
1507 if (GNUNET_CONTAINER_multipeermap_size (friend_peermap) == 0)
1508 {
1509 GNUNET_break(0);
1510 return;
1511 }
1512
1318 target_friend = select_random_friend (NULL); 1513 target_friend = select_random_friend (NULL);
1319 1514
1320 if (NULL == target_friend) 1515 if (NULL == target_friend)
1321 { 1516 {
1322 /* SUPU: Here we can get NULL in the case there is no friend in the peer map 1517 /* FIXME URGENT: Here we can get NULL all of the friends have reached their threshold.
1323 or all of the friends have reached their threshold. The first case should ideally 1518 * At the moment, the code for select_random_friend, is not handling it. In such a
1324 never happen because in handle_core_disconnect we have already canceled the task 1519 * case I think we can set a flag, and only when any value for any friend gets
1325 but it may happen if we already started the process and we reached here and 1520 * decremented,(which can happen only in finger table, when we remove an entry
1326 we cancelled the next task. So, it can return NULL in that case also. Should 1521 * from our finger table, and we are not part of the trail to reach to that
1327 we handle both cases in same way or not? */ 1522 * finger any more, t then reset the flag and schedule the code from there. */
1523 all_friends_trail_threshold = GNUNET_YES;
1328 return; 1524 return;
1329 } 1525 }
1330 1526
1331 /* FIXME: start with current_finger_index = 64, */
1332 if (PREDECESSOR_FINGER_ID == current_finger_index) 1527 if (PREDECESSOR_FINGER_ID == current_finger_index)
1333 { 1528 {
1334 /* FIXME: Where do we set the value back to PREDECESSR_FINGER_ID? Only
1335 when current_finger_index = 0, do we set it back to PREDECESSOR_FINGER_ID,
1336 in finger_table_add? Or is there any other possible condition, where we
1337 may need to set it to PREDECESSOR_FINGER_ID*/
1338 finger_identity = compute_predecessor_identity(); 1529 finger_identity = compute_predecessor_identity();
1339 } 1530 }
1340 else 1531 else
@@ -1344,69 +1535,15 @@ send_find_finger_trail_message (void *cls,
1344 1535
1345 finger_map_index = current_finger_index; 1536 finger_map_index = current_finger_index;
1346 1537
1347 /* FIXME: verify if its correct to set current_destination and current_source 1538 /* URGENT :FIXME: In case the packet is not sent to a finger, then current_source is the
1348 as my identity. Check what should be the best value to set for current_dest 1539 * peer which sent the packet and current_destination which recevied it. Now
1349 * and current_source. */ 1540 * these fields are not always used. Think of some way to remove these variables. */
1350 GDS_NEIGHBOURS_send_trail_setup (&my_identity, finger_identity, &(target_friend->id), 1541 GDS_NEIGHBOURS_send_trail_setup (&my_identity, finger_identity, &(target_friend->id),
1351 &(target_friend->id), target_friend, 0, NULL, finger_map_index); 1542 &my_identity, target_friend, 0, NULL, finger_map_index);
1352} 1543}
1353 1544
1354 1545
1355/** 1546/**
1356 * Invert the trail list.
1357 * @param destination_peer
1358 * @param existing_trail
1359 * @param trail_length
1360 * @return
1361 */
1362static struct GNUNET_PeerIdentity *
1363invert_trail_list (struct GNUNET_PeerIdentity *destination_peer,
1364 struct GNUNET_PeerIdentity *existing_trail,
1365 unsigned int trail_length)
1366{
1367 int i;
1368 int j;
1369 struct GNUNET_PeerIdentity *new_trail;
1370
1371 j = 0;
1372 new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
1373
1374 if (trail_length > 1)
1375 {
1376 i = trail_length - 2;
1377 while (i >= 0 )
1378 {
1379 memcpy( &new_trail[j], &existing_trail[i], sizeof (struct GNUNET_PeerIdentity));
1380 i--;
1381 j++;
1382 }
1383 }
1384 memcpy (&new_trail[j], destination_peer, sizeof(struct GNUNET_PeerIdentity));
1385
1386 return new_trail;
1387}
1388
1389
1390#if 0
1391/**
1392 *
1393 * @param existing_finger
1394 * @param new_finger
1395 * @return
1396 */
1397static int
1398compare_finger_identity (struct GNUNET_PeerIdentity *existing_finger,
1399 struct GNUNET_PeerIdentity *new_finger)
1400{
1401 int ret;
1402 ret = (existing_finger > new_finger) ? 1 :
1403 (existing_finger == new_finger) ? 0 : -1;
1404 return ret;
1405}
1406#endif
1407
1408
1409/**
1410 * Check if there is a predecessor in our finger peer map or not. 1547 * Check if there is a predecessor in our finger peer map or not.
1411 * If no, then return GNUNET_YES 1548 * If no, then return GNUNET_YES
1412 * else compare existing predecessor and peer, and find the correct 1549 * else compare existing predecessor and peer, and find the correct
@@ -1425,6 +1562,41 @@ compare_predecessor(struct GNUNET_PeerIdentity *peer)
1425 return GNUNET_YES; 1562 return GNUNET_YES;
1426} 1563}
1427 1564
1565#if 0
1566static int
1567update_predecessor (struct GNUNET_PeerIdentity *peer, struct GNUNET_PeerIdentity *trail_peer_list)
1568{
1569 /* In this function, we check if there is an entry or not for predecessor.
1570 if not then just add the peer, if no then compare the closest one, and add it
1571 . and remove the older one. There can still be multiple paths to reach to
1572 predecessor so in case both are same then make sure the paths are disjoint
1573 and then do multiple routing options. Also, invert the trail. and then add.
1574 Do all the things here. */
1575 return GNUNET_NO;
1576}
1577#endif
1578
1579/**
1580 * FIXME: free_finger(remove_finger); Call this function at finger_table_add,
1581 when you replace an existing entry
1582 * Free finger and its trail.
1583 * @param remove_finger Finger to be freed.
1584 */
1585static void
1586free_finger (struct FingerInfo *finger)
1587{
1588 struct TrailPeerList *peer;
1589
1590 while (NULL != (peer = finger->head))
1591 {
1592 GNUNET_CONTAINER_DLL_remove (finger->head, finger->tail, peer);
1593 GNUNET_free (peer);
1594 }
1595
1596 GNUNET_free (finger);
1597}
1598
1599
1428/** 1600/**
1429 * 1601 *
1430 * @return 1602 * @return
@@ -1434,52 +1606,146 @@ check_for_successor ()
1434{ 1606{
1435 return NULL; 1607 return NULL;
1436} 1608}
1609
1610
1437/** 1611/**
1438 * Scan the trail, check if there is a friend in the trail, then shortcut 1612 * FIXME: How do I send back the updated trail.
1439 * the trail and return the new trail and trail length. 1613 * Scan the trail to check if any on my own friend is part of trail. If yes
1440 * FIXME: How to send the trail length? Should I create a new array and copy into 1614 * the shortcut the trail and update the finger_trail and trail_length.
1441 * it or modify the existing trail. also, how can it be done optimally?
1442 * @param finger_trail 1615 * @param finger_trail
1616 * @param trail_length
1443 * @return 1617 * @return
1444 */ 1618 */
1445#if 0
1446static struct GNUNET_PeerIdentity * 1619static struct GNUNET_PeerIdentity *
1447scan_trail (struct GNUNET_PeerIdentity *finger_trail) 1620scan_trail (struct GNUNET_PeerIdentity *finger_trail, unsigned int trail_length,
1448{ 1621 const struct GNUNET_PeerIdentity *finger)
1449 return NULL;
1450}
1451#endif
1452
1453/* @param cls closure
1454 * @param key current public key
1455 * @param value value in the hash map
1456 * @return #GNUNET_YES if we should continue to
1457 * iterate,
1458 * #GNUNET_NO if not.
1459 */
1460static int
1461get_existing_finger (void *cls,
1462 const struct GNUNET_PeerIdentity *key,
1463 void *value)
1464{ 1622{
1465 struct FingerInfo *existing_finger = value; 1623 /* start from the second element as first element will always be your friend.
1466 uint32_t finger_map_index = (uint32_t) cls; 1624 In case trail_length = 2, and the last element is also your friend then you
1625 should delete the first element. In other cases go through the list and check
1626 if the trail */
1627 int i = trail_length - 1;
1467 1628
1468 if (existing_finger->finger_map_index == finger_map_index) 1629 while (i > 1)
1469 { 1630 {
1470 /* SUPU: How do I communicate this finger to the calling function. */ 1631 if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[i]))
1632 {
1633 /* This element of trail is not my friend. */
1634 i--;
1635 }
1636 else
1637 {
1638 /* If for any i>1 we found a friend, then we can use this friend as the
1639 first link and forget about all the peers behind it. But we need to first
1640 copy the peers behind it. send a trail tear down message along
1641 that line. */
1642 struct GNUNET_PeerIdentity *discarded_trail;
1643 struct FriendInfo *target_friend;
1644 /* FIXME: Create a new trail. to send back*/
1645 int discarded_trail_length = trail_length - i;
1646 int j = 0;
1647 discarded_trail = GNUNET_malloc (discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1648
1649 while (j < (discarded_trail_length + 1))
1650 {
1651 memcpy (&discarded_trail[j], &finger_trail[j], sizeof (struct GNUNET_PeerIdentity));
1652 j++;
1653 }
1654
1655 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[0]);
1656 /* FIXME: THAT IN ROUTING TABLE SOURCE PEER IS INDEED THE SOURCE PEER.
1657 * should trail contain last element as finger or just the last element.? if
1658 * you can get some value then you should not keep at different places.
1659 * remove finger as last element in the trail. */
1660 GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, discarded_trail,
1661 discarded_trail_length, target_friend);
1662
1663 /* fixme: CHANGE IT TO NEW TRAIL */
1664 return NULL;
1665 }
1471 } 1666 }
1472 return GNUNET_NO; 1667 return NULL;
1473} 1668}
1474 1669
1475/** 1670
1476 * TODO: 1671/**TOD0.
1477 * If you remove an entry from finger table, and if the finger is not your friend 1672 * 1.* If you remove an entry from finger table, and if the finger is not your friend
1478 * and the trail length > 1 for the finger that you removed, then you should send 1673 * and the trail length > 1 for the finger that you removed, then you should send
1479 * a trail_teardown message along the trail. so that the peers which have an 1674 * a trail_teardown message along the trail. so that the peers which have an
1480 * entry in their routing table for this trail can remove it from their routing 1675 * entry in their routing table for this trail can remove it from their routing
1481 * table. 1676 * table.
1482 * 2. how to handle the case in which same finger identity is stored for different 1677 * 2.
1678 * Choose the closest successor from existing_finger and new_finger. In case new_finger
1679 * is choosen, then send a tear down message along the trail to reach existing_finger.
1680 * @param existing_finger Existing entry in finger peer map
1681 * @param new_finger New finger
1682 * @param trail Trail to reach to the new finger from me.
1683 * @param trail_length Number of peers in the @a trail
1684 * @param finger_map_index If finger_map_index == PREDECESSOR_FINGER_INDEX,
1685 * then we use a different logic to find the closest
1686 * predecessor.
1687 * @return #GNUNET_YES In case we want to store the new entry.
1688 * #GNUNET_NO In case we want the existing entry.
1689 * #GNUNET_SYSERR Error.
1690 */
1691static
1692int select_correct_entry (struct FingerInfo *existing_finger,
1693 const struct GNUNET_PeerIdentity *new_finger,
1694 struct GNUNET_PeerIdentity *trail,
1695 unsigned int trail_length)
1696{
1697 int val = GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger);
1698 if (0 == val)
1699 {
1700 /* FIXME: if the new entry = old entry, then compare the trails, and see if the trails
1701 are disjoint, then send GNUNET_YES, but don't free old finger. But first you
1702 * should collapse the trail and then do comparison. Also, if you are collapsing
1703 * for one case then you should do it for all the cases where you are sending
1704 * GNUNET_YES. */
1705 /* Scan the trail for a friend and shorten if possible. */
1706 scan_trail (trail, trail_length, new_finger);
1707 return GNUNET_YES;
1708 }
1709 else if (val > 0)
1710 {
1711 /* If the new entry is closest one, then free the old entry, send a trail_teardown message.*/
1712 struct GNUNET_PeerIdentity *peer_list;
1713 struct FriendInfo *friend;
1714 struct TrailPeerList *finger_trail;
1715 int existing_finger_trail_length = existing_finger->trail_length;
1716 int i = 0;
1717
1718 finger_trail = existing_finger->head;
1719 friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer));
1720 peer_list = GNUNET_malloc ( existing_finger_trail_length * sizeof (struct GNUNET_PeerIdentity));
1721 while (i < existing_finger->trail_length)
1722 {
1723 memcpy (&peer_list[i], &(finger_trail->peer), sizeof (struct GNUNET_PeerIdentity));
1724 finger_trail = finger_trail->next;
1725 i++;
1726 }
1727
1728 GDS_NEIGHBOURS_send_trail_teardown (&my_identity, &(existing_finger->finger_identity),
1729 peer_list, existing_finger_trail_length, friend);
1730
1731 free_finger (existing_finger);
1732 scan_trail (trail, trail_length, new_finger);
1733 return GNUNET_YES;
1734 }
1735 else
1736 {
1737 /* If the old entry is closest then just return GNUNET_NO.*/
1738 return GNUNET_NO;
1739 }
1740 return GNUNET_SYSERR;
1741}
1742
1743
1744/**
1745 * SUPU: now the finger trail does not contain finger identity as the last element.
1746 * TODO:
1747 * 1. handle predecessor case differently.
1748 * how to handle the case in which same finger identity is stored for different
1483 * finger map index. because this will just increase the size of finger map and 1749 * finger map index. because this will just increase the size of finger map and
1484 * also size of the array we use in find_successor. 1750 * also size of the array we use in find_successor.
1485 * Add an entry in finger table. Before adding, check if there is already an 1751 * Add an entry in finger table. Before adding, check if there is already an
@@ -1498,41 +1764,44 @@ get_existing_finger (void *cls,
1498 */ 1764 */
1499static 1765static
1500void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, 1766void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
1501 const struct GNUNET_PeerIdentity *finger_trail, 1767 struct GNUNET_PeerIdentity *finger_trail,
1502 uint32_t finger_trail_length, 1768 uint32_t finger_trail_length,
1503 uint32_t finger_map_index) 1769 uint32_t finger_map_index)
1504{ 1770{
1505 struct FingerInfo new_finger_entry; 1771 struct FingerInfo new_finger_entry;
1772 struct FingerInfo *existing_finger;
1773 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1506 int i; 1774 int i;
1507 1775
1508 /* If I am my own finger, then return. */ 1776 /* If I am my own finger, then return. */
1509 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity)) 1777 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity))
1510 { 1778 {
1511 GNUNET_break (0); /* SUPU: Its here because I need to see when it happens. */ 1779 GNUNET_break (0);
1780 /* FIXME:Is there any point in keeping my own identity as finger?
1781 * Also, send a trail tear down message to all the peers which
1782 are in the finger trail, so that they can remove the entries from routing
1783 table. */
1512 return; 1784 return;
1513 } 1785 }
1514 1786
1515 if (finger_map_index == PREDECESSOR_FINGER_ID) 1787 /* Check if there is already an entry for the finger map index in the finger peer map. */
1516 goto add_new_entry; 1788 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1517 1789 for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++)
1518 /* For rest of current_finger_index, choose the correct finger and correct trail. */ 1790 {
1519 /* SUPU: Here I want to iterate over all the entries and see if there is already 1791 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL,
1520 an entry for the finger map index. if yes then check if finger identity are same 1792 (const void **)&existing_finger))
1521 if yes then check the trail. if I use gnuent_container_multipeermap_iterate, 1793 {
1522 i should stop after I found the finger map index, and just return the 1794 /* If existing_finger is the closest, then don't add any entry. */
1523 struct finger info. then I should call another function which takes care of 1795 if ( GNUNET_NO == select_correct_entry (existing_finger, finger_identity,
1524 finding the closest peer */ 1796 finger_trail, finger_trail_length))
1525 GNUNET_CONTAINER_multipeermap_iterate (finger_peermap, &get_existing_finger, 1797 goto increment_finger_index;
1526 (void *)finger_map_index); 1798 }
1799 }
1527 1800
1528 add_new_entry: 1801 /* Add the new entry. */
1529 memcpy (&(new_finger_entry.finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity)); 1802 memcpy (&(new_finger_entry.finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity));
1530 new_finger_entry.finger_map_index = finger_map_index; 1803 new_finger_entry.finger_map_index = finger_map_index;
1531 /* FIXME: How do I get the length as well as the trail.
1532 * scan_trail (finger_trail);
1533 */
1534 new_finger_entry.trail_length = finger_trail_length; 1804 new_finger_entry.trail_length = finger_trail_length;
1535
1536 i = 0; 1805 i = 0;
1537 while (i < finger_trail_length) 1806 while (i < finger_trail_length)
1538 { 1807 {
@@ -1554,11 +1823,11 @@ void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
1554 1823
1555 /* FIXME: after adding an entry, I want to check if there is a successor, if yes 1824 /* FIXME: after adding an entry, I want to check if there is a successor, if yes
1556 then this function will return it and then we should schedule a verify successor 1825 then this function will return it and then we should schedule a verify successor
1557 task */ 1826 task Will the successor always be at index 0 */
1827 increment_finger_index:
1558 if (NULL != check_for_successor()) 1828 if (NULL != check_for_successor())
1559 { 1829 {
1560 verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL); 1830 verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL);
1561 /* FIXME: Is it safe to set the finger index to predecessor_finger_id here? */
1562 current_finger_index = PREDECESSOR_FINGER_ID; 1831 current_finger_index = PREDECESSOR_FINGER_ID;
1563 return; 1832 return;
1564 } 1833 }
@@ -1788,22 +2057,19 @@ find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value,
1788 2057
1789 2058
1790/** 2059/**
1791 * here you should set the current source instead of destination type.
1792 * so current_source is actual source till we don't find another current_source
1793 * but is it good. why are we wasting space in case current_Destination is just us.
1794 * also in many case current_destination is just me. so again it does not seem
1795 * so smart.
1796 * Find closest successor for the value. 2060 * Find closest successor for the value.
1797 * @param value Value for which we are looking for successor 2061 * @param value Value for which we are looking for successor
1798 * FIXME: pass the correct value for current_destination
1799 * @param[out] current_destination set to the end of the finger to traverse next 2062 * @param[out] current_destination set to the end of the finger to traverse next
1800 * @param type Next destination type 2063 * @param[out] current_source set to my_identity.
2064 * @param congested_peer Peer not to be considered when looking for
2065 * successor. FIXME: IMPLEMENT IT.
1801 * @return Peer identity of next hop, NULL if we are the 2066 * @return Peer identity of next hop, NULL if we are the
1802 * ultimate destination 2067 * ultimate destination
1803 */ 2068 */
1804static struct GNUNET_PeerIdentity * 2069static struct GNUNET_PeerIdentity *
1805find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, 2070find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1806 struct GNUNET_PeerIdentity *current_source) 2071 struct GNUNET_PeerIdentity *current_source,
2072 struct GNUNET_PeerIdentity *congested_peer)
1807{ 2073{
1808 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter; 2074 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
1809 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; 2075 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
@@ -1883,6 +2149,7 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1883 struct FriendInfo *target_friend; 2149 struct FriendInfo *target_friend;
1884 target_friend = (struct FriendInfo *)successor->data; 2150 target_friend = (struct FriendInfo *)successor->data;
1885 memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity)); 2151 memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
2152 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
1886 return current_destination; 2153 return current_destination;
1887 } 2154 }
1888 else if (successor->type == FINGER) 2155 else if (successor->type == FINGER)
@@ -1972,7 +2239,7 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
1972 struct GNUNET_PeerIdentity curr_src; 2239 struct GNUNET_PeerIdentity curr_src;
1973 memcpy (&curr_dest, &current_destination, sizeof (struct GNUNET_PeerIdentity)); 2240 memcpy (&curr_dest, &current_destination, sizeof (struct GNUNET_PeerIdentity));
1974 memcpy (&curr_src, &current_source, sizeof (struct GNUNET_PeerIdentity)); 2241 memcpy (&curr_src, &current_source, sizeof (struct GNUNET_PeerIdentity));
1975 next_hop = find_successor (key_value, &curr_dest, &curr_src); 2242 next_hop = find_successor (key_value, &curr_dest, &curr_src, NULL);
1976 /* FIXME: I am copying back current_destination and current_source. but I am not 2243 /* FIXME: I am copying back current_destination and current_source. but I am not
1977 sure, if its correct. I am doing so just to remove the code from client file.*/ 2244 sure, if its correct. I am doing so just to remove the code from client file.*/
1978 memcpy (&current_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity)); 2245 memcpy (&current_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity));
@@ -2071,7 +2338,7 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
2071 memcpy (&curr_dest, &current_destination, sizeof (struct GNUNET_PeerIdentity)); 2338 memcpy (&curr_dest, &current_destination, sizeof (struct GNUNET_PeerIdentity));
2072 memcpy (&curr_src, &current_source, sizeof (struct GNUNET_PeerIdentity)); 2339 memcpy (&curr_src, &current_source, sizeof (struct GNUNET_PeerIdentity));
2073 memcpy (&key_value, key, sizeof (struct GNUNET_PeerIdentity)); 2340 memcpy (&key_value, key, sizeof (struct GNUNET_PeerIdentity));
2074 next_hop = find_successor (key_value, &curr_dest, &curr_src); 2341 next_hop = find_successor (key_value, &curr_dest, &curr_src, NULL);
2075 /* FIXME: Again I am copying back value of current_destination, current_source, 2342 /* FIXME: Again I am copying back value of current_destination, current_source,
2076 Think of a better solution. */ 2343 Think of a better solution. */
2077 memcpy (&current_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity)); 2344 memcpy (&current_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity));
@@ -2151,10 +2418,10 @@ GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration,
2151 return; 2418 return;
2152 } 2419 }
2153 2420
2154 current_path_index = search_my_index(get_path); 2421 current_path_index = search_my_index(get_path, get_path_length);
2422 /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/
2155 if (0 == current_path_index) 2423 if (0 == current_path_index)
2156 { 2424 {
2157 FPRINTF (stderr,_("\nSUPU %s, %s, %d"),__FILE__, __func__,__LINE__);
2158 GDS_CLIENTS_handle_reply (expiration, key, get_path_length, get_path, put_path_length, 2425 GDS_CLIENTS_handle_reply (expiration, key, get_path_length, get_path, put_path_length,
2159 put_path, type, data_size, data); 2426 put_path, type, data_size, data);
2160 return; 2427 return;
@@ -2185,23 +2452,25 @@ GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration,
2185 2452
2186 2453
2187/** 2454/**
2188 * Send tral rejection message 2455 * Send tral rejection message to the peer which sent me a trail setup message.
2189 * @param source_peer Source peer which wants to set up the trail. 2456 * @param source_peer Source peer which wants to set up the trail.
2190 * @param finger_identity Finger identity to which it want to setup the trail. 2457 * @param finger_identity Value whose successor will be the finger of @a source_peer.
2191 * @param congested_peer Peer which has send trail rejection message 2458 * @param congested_peer Peer which has send trail rejection message.
2192 * @param next_hop Peer to which this message should be forwarded. 2459 * @param next_hop Peer to which this message should be forwarded.
2193 * @param finger_map_index 2460 * @param finger_map_index Index in @a source_peer finger peermap.
2194 * @param trail_peer_list 2461 * @param trail_peer_list Trail followed to reach from @a source_peer to next_hop,
2195 * @param trail_length 2462 * NULL, in case the @a congested_peer was the first peer
2463 * to which trail setup message was forwarded.
2464 * @param trail_length Number of peers in trail_peer_list.
2196 */ 2465 */
2197void 2466void
2198GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_peer, 2467GDS_NEIGHBOURS_send_trail_rejection (struct GNUNET_PeerIdentity *source_peer,
2199 uint64_t finger_identity, 2468 uint64_t finger_identity,
2200 struct GNUNET_PeerIdentity *congested_peer, 2469 struct GNUNET_PeerIdentity *congested_peer,
2201 const struct GNUNET_PeerIdentity *next_hop, 2470 const struct GNUNET_PeerIdentity *next_hop,
2202 unsigned int finger_map_index, 2471 unsigned int finger_map_index,
2203 struct GNUNET_PeerIdentity *trail_peer_list, 2472 struct GNUNET_PeerIdentity *trail_peer_list,
2204 unsigned int trail_length) 2473 unsigned int trail_length)
2205{ 2474{
2206 struct PeerTrailRejectionMessage *trail_rejection; 2475 struct PeerTrailRejectionMessage *trail_rejection;
2207 struct GNUNET_PeerIdentity *trail_list; 2476 struct GNUNET_PeerIdentity *trail_list;
@@ -2209,10 +2478,17 @@ GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_p
2209 struct FriendInfo *target_friend; 2478 struct FriendInfo *target_friend;
2210 size_t msize; 2479 size_t msize;
2211 2480
2212 msize = sizeof (struct PeerTrailRejectionMessage); 2481 msize = trail_length * sizeof(struct GNUNET_PeerIdentity) +
2482 sizeof (struct PeerTrailRejectionMessage);
2483
2484 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2485 {
2486 GNUNET_break (0);
2487 return;
2488 }
2213 2489
2214 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 2490 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2215 pending->importance = 0; /* FIXME */ 2491 pending->importance = 0;
2216 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT); 2492 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
2217 trail_rejection = (struct PeerTrailRejectionMessage *) &pending[1]; 2493 trail_rejection = (struct PeerTrailRejectionMessage *) &pending[1];
2218 pending->msg = &trail_rejection->header; 2494 pending->msg = &trail_rejection->header;
@@ -2220,12 +2496,13 @@ GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_p
2220 trail_rejection->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP); 2496 trail_rejection->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
2221 memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); 2497 memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2222 memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity)); 2498 memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity));
2223 memcpy (&(trail_rejection->finger_identity), &finger_identity, sizeof (uint64_t)); 2499 memcpy (&(trail_rejection->finger_identity_value), &finger_identity, sizeof (uint64_t));
2224 trail_rejection->finger_map_index = htonl(finger_map_index); 2500 trail_rejection->finger_map_index = htonl(finger_map_index);
2225 trail_rejection->trail_length = htonl (trail_length); 2501 trail_rejection->trail_length = htonl (trail_length);
2226 2502
2227 trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; 2503 trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
2228 memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); 2504 if (trail_length != 0)
2505 memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2229 2506
2230 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2507 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2231 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); 2508 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
@@ -2235,11 +2512,12 @@ GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_p
2235 2512
2236 2513
2237/** 2514/**
2238 * 2515 * Core handler for P2P put messages.
2239 * @param cls 2516 * @param cls closure
2240 * @param peer 2517 * @param peer sender of the request
2241 * @param message 2518 * @param message message
2242 * @return 2519 * @return #GNUNET_OK to keep the connection open,
2520 * #GNUNET_SYSERR to close it (signal serious error)
2243 */ 2521 */
2244static int 2522static int
2245handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, 2523handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
@@ -2357,7 +2635,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2357 } 2635 }
2358 else 2636 else
2359 { 2637 {
2360 next_hop = find_successor (key_value, &current_destination, &current_source); 2638 next_hop = find_successor (key_value, &current_destination, &current_source, NULL);
2361 } 2639 }
2362 2640
2363 if (NULL == next_hop) /* I am the final destination */ 2641 if (NULL == next_hop) /* I am the final destination */
@@ -2454,7 +2732,7 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2454 } 2732 }
2455 else 2733 else
2456 { 2734 {
2457 next_hop = find_successor (key_value, &current_destination, &current_source); 2735 next_hop = find_successor (key_value, &current_destination, &current_source, NULL);
2458 } 2736 }
2459 2737
2460 if (NULL == next_hop) 2738 if (NULL == next_hop)
@@ -2555,7 +2833,8 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2555 { 2833 {
2556 struct GNUNET_PeerIdentity *next_hop; 2834 struct GNUNET_PeerIdentity *next_hop;
2557 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2835 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2558 current_path_index = search_my_index (get_path); 2836 /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/
2837 current_path_index = search_my_index (get_path, getlen);
2559 /* FIXME: First check if you are adding yourself to the get path or not. 2838 /* FIXME: First check if you are adding yourself to the get path or not.
2560 if yes then don't check if current_path_index == 0, if not then check 2839 if yes then don't check if current_path_index == 0, if not then check
2561 and next_hop == source_peer. */ 2840 and next_hop == source_peer. */
@@ -2573,7 +2852,7 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2573 2852
2574 2853
2575/** 2854/**
2576 * Handle a PeerTrailSetupMessage. 2855 * Core handle for PeerTrailSetupMessage.
2577 * @param cls closure 2856 * @param cls closure
2578 * @param message message 2857 * @param message message
2579 * @param peer peer identity this notification is about 2858 * @param peer peer identity this notification is about
@@ -2583,7 +2862,7 @@ static int
2583handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer, 2862handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2584 const struct GNUNET_MessageHeader *message) 2863 const struct GNUNET_MessageHeader *message)
2585{ 2864{
2586 const struct PeerTrailSetupMessage *trail_setup; 2865 const struct PeerTrailSetupMessage *trail_setup;
2587 struct GNUNET_PeerIdentity current_destination; 2866 struct GNUNET_PeerIdentity current_destination;
2588 struct GNUNET_PeerIdentity current_source; 2867 struct GNUNET_PeerIdentity current_source;
2589 struct GNUNET_PeerIdentity source; 2868 struct GNUNET_PeerIdentity source;
@@ -2622,61 +2901,79 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2622 finger_map_index = ntohl (trail_setup->finger_map_index); 2901 finger_map_index = ntohl (trail_setup->finger_map_index);
2623 destination_finger_value = ntohl (trail_setup->destination_finger); 2902 destination_finger_value = ntohl (trail_setup->destination_finger);
2624 2903
2625 /* Check if you are part of the trail or current destination, and accordingly 2904 /* My routing state size has crossed the threshold, I can not be part of any more
2626 * find the next peer to send the message to. */ 2905 * trails. */
2906 if(GDS_ROUTING_check_threshold())
2907 {
2908 /* No more trails possible through me. send a trail rejection message. */
2909 GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity,
2910 peer,finger_map_index, trail_peer_list,trail_length);
2911 return GNUNET_YES;
2912 }
2913
2914 /* Check if you are current_destination or not. */
2627 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity))) 2915 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
2628 { 2916 {
2917 /* You are not current_destination, you are part of trail to reach to
2918 current_destination. */
2629 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer); 2919 next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer);
2630 /* ADDNOW: OPTIMIZATION: do find_successor also and get a better path if possible. */ 2920 /* ADDNOW: OPTIMIZATION: do find_successor also and get a better path if possible. */
2631 2921
2632 if (next_hop == NULL) 2922 if (next_hop == NULL)
2633 { 2923 {
2634 /* FIXME next_hop to NULL, 1. statistics update, drop the message. 2924 /* FIXME:
2925 * next_hop is NULL, in a case when next_hop was a friend which got disconnected
2926 * and we removed the trail from our routing trail. So, I can send the message
2927 * to other peer or can drop the message. VERIFY which will be the correct
2928 * thing to do.
2929 * next_hop to NULL, 1. statistics update, drop the message.
2635 2. complain to sender with new message: trail lost */ 2930 2. complain to sender with new message: trail lost */
2636 return GNUNET_OK; 2931 return GNUNET_OK;
2637 } 2932 }
2638 } 2933 }
2639 else 2934 else
2640 { 2935 {
2641 next_hop = find_successor (destination_finger_value, &current_destination, &current_source); 2936 next_hop = find_successor (destination_finger_value, &current_destination, &current_source, NULL);
2642 } 2937 }
2643 2938
2644 /* Now add yourself to the trail. */ 2939
2645 struct GNUNET_PeerIdentity peer_list[trail_length + 1];
2646 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2647 peer_list[trail_length] = my_identity;
2648 trail_length++;
2649
2650 /* Check next_hop type and make the judgment what to do next. */
2651 if (NULL == next_hop) /* This means I am the final destination */ 2940 if (NULL == next_hop) /* This means I am the final destination */
2652 { 2941 {
2653 if (trail_length == 1) 2942 /* SUPU: trail length is 0, when I am the friend of the srouce peer. */
2943 if (trail_length == 0)
2654 { 2944 {
2655 memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity)); 2945 memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity));
2656 } 2946 }
2657 else 2947 else
2658 { 2948 {
2659 memcpy (&next_peer, &trail_peer_list[trail_length-2], sizeof (struct GNUNET_PeerIdentity)); 2949 memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
2660 } 2950 }
2661 2951
2662 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); 2952 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
2663 /* FIXME: URGENT change it to handle the change in current_finger_index. 2953
2664 compare to your own predecessor */
2665 if (compare_predecessor (&source) /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */) 2954 if (compare_predecessor (&source) /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */)
2666 { 2955 {
2956 /* FIXME: In case we have different function update_predecessor then
2957 remove the lines below. */
2667 struct GNUNET_PeerIdentity *new_trail_list; 2958 struct GNUNET_PeerIdentity *new_trail_list;
2668 new_trail_list = invert_trail_list (&source, peer_list, trail_length); 2959 new_trail_list = invert_trail_list (&source, trail_peer_list, trail_length);
2669 finger_table_add (&source, new_trail_list, trail_length, PREDECESSOR_FINGER_ID); 2960 finger_table_add (&source, new_trail_list, trail_length, PREDECESSOR_FINGER_ID);
2670 } 2961 }
2671 GDS_NEIGHBOURS_send_trail_setup_result (&source, 2962 GDS_NEIGHBOURS_send_trail_setup_result (&source,
2672 &(my_identity), 2963 &(my_identity),
2673 target_friend, trail_length, 2964 target_friend, trail_length,
2674 peer_list, 2965 trail_peer_list,
2675 finger_map_index); 2966 finger_map_index);
2676 return GNUNET_OK; 2967 return GNUNET_OK;
2677 } 2968 }
2678 else 2969 else
2679 { 2970 {
2971 /* Now add yourself to the trail. */
2972 struct GNUNET_PeerIdentity peer_list[trail_length + 1];
2973 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2974 peer_list[trail_length] = my_identity;
2975 trail_length++;
2976
2680 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2977 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2681 GDS_NEIGHBOURS_send_trail_setup (&source, 2978 GDS_NEIGHBOURS_send_trail_setup (&source,
2682 destination_finger_value, 2979 destination_finger_value,
@@ -2701,7 +2998,7 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
2701 const struct GNUNET_MessageHeader *message) 2998 const struct GNUNET_MessageHeader *message)
2702{ 2999{
2703 const struct PeerTrailSetupResultMessage *trail_result; 3000 const struct PeerTrailSetupResultMessage *trail_result;
2704 const struct GNUNET_PeerIdentity *trail_peer_list; 3001 struct GNUNET_PeerIdentity *trail_peer_list;
2705 uint32_t trail_length; 3002 uint32_t trail_length;
2706 uint32_t finger_map_index; 3003 uint32_t finger_map_index;
2707 size_t msize; 3004 size_t msize;
@@ -2727,7 +3024,7 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
2727 } 3024 }
2728 3025
2729 finger_map_index = htonl (trail_result->finger_map_index); 3026 finger_map_index = htonl (trail_result->finger_map_index);
2730 trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1]; 3027 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
2731 3028
2732 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer), 3029 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
2733 &my_identity))) 3030 &my_identity)))
@@ -2742,7 +3039,9 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
2742 struct FriendInfo *target_friend; 3039 struct FriendInfo *target_friend;
2743 int my_index; 3040 int my_index;
2744 3041
2745 my_index = search_my_index (trail_peer_list); 3042 /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/
3043 /* FIXME: Make sure you are passing the current length */
3044 my_index = search_my_index (trail_peer_list, trail_length);
2746 if (my_index == 0) 3045 if (my_index == 0)
2747 { 3046 {
2748 next_hop = trail_result->destination_peer; 3047 next_hop = trail_result->destination_peer;
@@ -2770,10 +3069,12 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
2770 return GNUNET_SYSERR; 3069 return GNUNET_SYSERR;
2771} 3070}
2772 3071
2773#if 0 3072
2774/** 3073/**
2775 * FIXME: Use flag in the case finger peer map does not contain predcessor 3074 * FIXME: Use flag in the case finger peer map does not contain predcessor
2776 * then its NULL. Ideally it should never happen. 3075 * then its NULL. Ideally it should never happen. Some one sent you are verify
3076 * successor and you don't have any predecessor, then ideally you should
3077 * GNUNET_break_op(0).
2777 * Get my current predecessor from the finger peer map 3078 * Get my current predecessor from the finger peer map
2778 * @return Current predecessor. 3079 * @return Current predecessor.
2779 */ 3080 */
@@ -2801,86 +3102,27 @@ get_predecessor()
2801 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); 3102 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2802 return my_predecessor; 3103 return my_predecessor;
2803} 3104}
2804#endif
2805 3105
2806/**
2807 * Core handle for p2p verify successor messages.
2808 * @param cls closure
2809 * @param message message
2810 * @param peer peer identity this notification is about
2811 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2812 */
2813static int
2814handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2815 const struct GNUNET_MessageHeader *message)
2816{
2817 const struct PeerVerifySuccessorMessage *vsm;
2818 const struct GNUNET_PeerIdentity *trail_peer_list;
2819 struct GNUNET_PeerIdentity next_hop;
2820 struct FriendInfo *target_friend;
2821 size_t msize;
2822 uint32_t trail_length;
2823
2824 msize = ntohs (message->size);
2825 if (msize < sizeof (struct PeerVerifySuccessorMessage))
2826 {
2827 GNUNET_break_op (0);
2828 return GNUNET_YES;
2829 }
2830
2831 vsm = (struct PeerVerifySuccessorMessage *) message;
2832 trail_length = ntohl (vsm->trail_length);
2833
2834 if ((msize < sizeof (struct PeerVerifySuccessorMessage) +
2835 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2836 (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2837 {
2838 GNUNET_break_op (0);
2839 return GNUNET_YES;
2840 }
2841
2842 trail_peer_list = (const struct GNUNET_PeerIdentity *)&vsm[1];
2843 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity)))
2844 {
2845 /*FIXME:URGENT:IMPLEMENT Here you are the successor, here you should check your predecessor
2846 and if there is no predecessor then just add this peer and send result
2847 if there is some other predecessor, then construct a new trial and then
2848 send back the list to requesting peer. */
2849 }
2850 else
2851 {
2852 int my_index;
2853
2854 my_index = search_my_index (trail_peer_list);
2855 memcpy (&next_hop, &trail_peer_list[my_index], sizeof (struct GNUNET_PeerIdentity));
2856 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
2857
2858 GDS_NEIGHBOURS_send_verify_successor (&(vsm->source_peer), &(vsm->successor),target_friend,
2859 trail_peer_list, trail_length);
2860 }
2861 return GNUNET_SYSERR;
2862}
2863 3106
2864#if 0
2865/** 3107/**
2866 * Core handle for p2p verify successor messages. 3108 * Core handle for p2p verify successor messages.
2867 * @param cls closure 3109 * @param cls closure
2868 * @param message message 3110 * @param message message
2869 * @param peer peer identity this notification is about 3111 * @param peer peer identity this notification is about
2870 * @return GNUNET_OK on success, GNUNET_SYSERR on error 3112 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2871 */ 3113 */
2872static int 3114static int
2873handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer, 3115handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2874 const struct GNUNET_MessageHeader *message) 3116 const struct GNUNET_MessageHeader *message)
2875{ 3117{
2876 struct PeerVerifySuccessorMessage *vsm; 3118 const struct PeerVerifySuccessorMessage *vsm;
2877 struct GNUNET_PeerIdentity *trail_peer_list; 3119 const struct GNUNET_PeerIdentity *trail_peer_list;
3120 struct GNUNET_PeerIdentity source_peer;
3121 struct GNUNET_PeerIdentity next_hop;
2878 struct FriendInfo *target_friend; 3122 struct FriendInfo *target_friend;
2879 struct GNUNET_PeerIdentity *next_hop;
2880 struct GNUNET_PeerIdentity *source_peer;
2881 unsigned int trail_length;
2882 size_t msize; 3123 size_t msize;
2883 3124 uint32_t trail_length;
3125
2884 msize = ntohs (message->size); 3126 msize = ntohs (message->size);
2885 if (msize < sizeof (struct PeerVerifySuccessorMessage)) 3127 if (msize < sizeof (struct PeerVerifySuccessorMessage))
2886 { 3128 {
@@ -2893,37 +3135,34 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
2893 3135
2894 if ((msize < sizeof (struct PeerVerifySuccessorMessage) + 3136 if ((msize < sizeof (struct PeerVerifySuccessorMessage) +
2895 trail_length * sizeof (struct GNUNET_PeerIdentity)) || 3137 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2896 (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) 3138 (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2897 { 3139 {
2898 GNUNET_break_op (0); 3140 GNUNET_break_op (0);
2899 return GNUNET_YES; 3141 return GNUNET_YES;
2900 } 3142 }
2901 3143
2902 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsm[1]; 3144 trail_peer_list = (const struct GNUNET_PeerIdentity *)&vsm[1];
2903 source_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 3145 memcpy (&source_peer, &(vsm->source_peer), sizeof(struct GNUNET_PeerIdentity));
2904 memcpy (source_peer, &(vsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
2905
2906 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2907
2908 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity))) 3146 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity)))
2909 { 3147 {
2910 struct FingerInfo *my_predecessor; 3148 struct FingerInfo *my_predecessor;
2911 if (trail_length == 1) 3149
2912 memcpy (next_hop, source_peer, sizeof (struct GNUNET_PeerIdentity)); 3150 if (trail_length == 0)
3151 memcpy (&next_hop, &source_peer, sizeof (struct GNUNET_PeerIdentity));
2913 else 3152 else
2914 { 3153 {
2915 int current_trail_index; 3154 int current_trail_index;
2916 current_trail_index = search_my_index (trail_peer_list); 3155 current_trail_index = search_my_index (trail_peer_list, trail_length);
2917 memcpy (next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity)); 3156 memcpy (&next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity));
2918 } 3157 }
2919 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 3158 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
2920 GNUNET_free (next_hop);
2921 3159
2922 my_predecessor = get_predecessor(); 3160 my_predecessor = get_predecessor();
2923 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (source_peer, 3161 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
2924 &(my_predecessor->finger_identity)))) 3162 &(my_predecessor->finger_identity))))
2925 { 3163 {
2926 GDS_NEIGHBOURS_send_verify_successor_result (source_peer, 3164
3165 GDS_NEIGHBOURS_send_verify_successor_result (&source_peer,
2927 &(my_identity), 3166 &(my_identity),
2928 &(my_predecessor->finger_identity), 3167 &(my_predecessor->finger_identity),
2929 target_friend, 3168 target_friend,
@@ -2933,16 +3172,18 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
2933 else 3172 else
2934 { 3173 {
2935 struct GNUNET_PeerIdentity *new_successor_trail; 3174 struct GNUNET_PeerIdentity *new_successor_trail;
3175 struct TrailPeerList *iterator;
2936 int new_trail_length; 3176 int new_trail_length;
2937 int i; 3177 int i;
2938 3178
2939 new_trail_length = trail_length + my_predecessor->trail_length; 3179 new_trail_length = trail_length + my_predecessor->trail_length + 1;
2940 new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length); 3180 new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length);
2941 memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity)); 3181 memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity));
2942 struct TrailPeerList *iterator; 3182 memcpy (&new_successor_trail[trail_length], &my_identity, sizeof (struct GNUNET_PeerIdentity));
3183
2943 iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); 3184 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
2944 iterator = my_predecessor->head; 3185 iterator = my_predecessor->head;
2945 i = trail_length; 3186 i = trail_length + 1;
2946 while (i < new_trail_length) 3187 while (i < new_trail_length)
2947 { 3188 {
2948 memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity)); 3189 memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
@@ -2950,29 +3191,30 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
2950 i++; 3191 i++;
2951 } 3192 }
2952 3193
2953 GDS_NEIGHBOURS_send_verify_successor_result (source_peer, 3194 GDS_NEIGHBOURS_send_verify_successor_result (&source_peer,
2954 &(my_identity), 3195 &(my_identity),
2955 &(my_predecessor->finger_identity), 3196 &(my_predecessor->finger_identity),
2956 target_friend, 3197 target_friend,
2957 new_successor_trail, 3198 new_successor_trail,
2958 new_trail_length); 3199 new_trail_length);
2959 } 3200 }
2960 3201
2961 } 3202 }
2962 else 3203 else
2963 { 3204 {
2964 unsigned int current_trail_index; 3205 int my_index;
2965 current_trail_index = search_my_index (trail_peer_list); 3206 /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/
2966 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity)); 3207 /* FIXME: make sure you are passing the correct trail length */
2967 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 3208 my_index = search_my_index (trail_peer_list, trail_length);
2968 GNUNET_free (next_hop); 3209 memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity));
2969 3210 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
2970 GDS_NEIGHBOURS_send_verify_successor (source_peer, &(vsm->successor),target_friend, 3211
3212 GDS_NEIGHBOURS_send_verify_successor (&(vsm->source_peer), &(vsm->successor),target_friend,
2971 trail_peer_list, trail_length); 3213 trail_peer_list, trail_length);
2972 } 3214 }
2973 return GNUNET_YES; 3215 return GNUNET_SYSERR;
2974} 3216}
2975#endif 3217
2976 3218
2977/** 3219/**
2978 * Core handle for p2p verify successor result messages. 3220 * Core handle for p2p verify successor result messages.
@@ -2986,7 +3228,7 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti
2986 const struct GNUNET_MessageHeader *message) 3228 const struct GNUNET_MessageHeader *message)
2987{ 3229{
2988 const struct PeerVerifySuccessorResultMessage *vsrm; 3230 const struct PeerVerifySuccessorResultMessage *vsrm;
2989 const struct GNUNET_PeerIdentity *trail_peer_list; 3231 struct GNUNET_PeerIdentity *trail_peer_list;
2990 struct GNUNET_PeerIdentity next_hop; 3232 struct GNUNET_PeerIdentity next_hop;
2991 struct FriendInfo *target_friend; 3233 struct FriendInfo *target_friend;
2992 size_t msize; 3234 size_t msize;
@@ -3012,7 +3254,7 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti
3012 return GNUNET_YES; 3254 return GNUNET_YES;
3013 } 3255 }
3014 3256
3015 trail_peer_list = (const struct GNUNET_PeerIdentity *) &vsrm[1]; 3257 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1];
3016 3258
3017 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity)))) 3259 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity))))
3018 { 3260 {
@@ -3030,8 +3272,9 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti
3030 else 3272 else
3031 { 3273 {
3032 int my_index; 3274 int my_index;
3033 3275 /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/
3034 my_index = search_my_index (trail_peer_list); 3276 /* FIXME: make sure you are passing the correct trail length */
3277 my_index = search_my_index (trail_peer_list, trail_length);
3035 if (my_index == 1) 3278 if (my_index == 1)
3036 memcpy (&next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity)); 3279 memcpy (&next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3037 else 3280 else
@@ -3050,28 +3293,6 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti
3050 3293
3051 3294
3052/** 3295/**
3053 * Check if there is already an entry in finger_peermap for predecessor,
3054 * If not then add peer as your predecessor.
3055 * Else compare existing entry and peer, and choose the closest one as predecessor.
3056 * @param peer Peer identity
3057 * @param trail_peer_list Trail to reach from @a peer to me.
3058 */
3059static void
3060update_predecessor (const struct GNUNET_PeerIdentity *peer,
3061 const struct GNUNET_PeerIdentity *trail_peer_list)
3062{
3063 /*FIXME: URGENT: Here you should first check if there is already an entry for predecessor
3064 field or not. if not then add peer. else compare existing entry and peer,
3065 and choose the closest one as predecessor. I am confused should I call a
3066 function which just checks if this peer can be predecessor or not, and then
3067 call another function to add it. Or call a single function which checks
3068 it all and add the entry. we are never going to communicate with the peer
3069 if it is my predecessor or not. so, we don't care about the result. */
3070
3071}
3072
3073
3074/**
3075 * Core handle for p2p notify new successor messages. 3296 * Core handle for p2p notify new successor messages.
3076 * @param cls closure 3297 * @param cls closure
3077 * @param message message 3298 * @param message message
@@ -3083,7 +3304,7 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
3083 const struct GNUNET_MessageHeader *message) 3304 const struct GNUNET_MessageHeader *message)
3084{ 3305{
3085 const struct PeerNotifyNewSuccessorMessage *nsm; 3306 const struct PeerNotifyNewSuccessorMessage *nsm;
3086 const struct GNUNET_PeerIdentity *trail_peer_list; 3307 struct GNUNET_PeerIdentity *trail_peer_list;
3087 size_t msize; 3308 size_t msize;
3088 uint32_t trail_length; 3309 uint32_t trail_length;
3089 3310
@@ -3106,11 +3327,11 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
3106 return GNUNET_YES; 3327 return GNUNET_YES;
3107 } 3328 }
3108 3329
3109 trail_peer_list = (const struct GNUNET_PeerIdentity *) &nsm[1]; 3330 trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
3110 3331
3111 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity))) 3332 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity)))
3112 { 3333 {
3113 update_predecessor (&(nsm->destination_peer), trail_peer_list); 3334 //update_predecessor (&(nsm->destination_peer), trail_peer_list);
3114 return GNUNET_OK; 3335 return GNUNET_OK;
3115 } 3336 }
3116 else 3337 else
@@ -3119,7 +3340,9 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
3119 struct GNUNET_PeerIdentity next_hop; 3340 struct GNUNET_PeerIdentity next_hop;
3120 int my_index; 3341 int my_index;
3121 3342
3122 my_index = search_my_index (trail_peer_list); 3343 /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/
3344 /* FIXME: check that trail length is correct. */
3345 my_index = search_my_index (trail_peer_list, trail_length);
3123 memcpy (&next_hop, &trail_peer_list[my_index+1], sizeof (struct GNUNET_PeerIdentity)); 3346 memcpy (&next_hop, &trail_peer_list[my_index+1], sizeof (struct GNUNET_PeerIdentity));
3124 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 3347 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3125 GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), 3348 GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer),
@@ -3133,8 +3356,183 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
3133 3356
3134 3357
3135/** 3358/**
3136 * FIXME: I am not sure if this is correct or not. once I am done with 3359 * Core handler for P2P trail rejection message
3137 * basic implementation then will handle threshold limits. 3360 * @param cls closure
3361 * @param message message
3362 * @param peer peer identity this notification is about
3363 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3364 */
3365static
3366int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer,
3367 const struct GNUNET_MessageHeader *message)
3368{
3369 /* Here you have recevied the message it means that the peer next to you have
3370 failed to setup the trail to the finger identity value. now you should call
3371 find_successor and make sure that you don't choose the peer as next hop
3372 in order to do so, you need to pass a new parameter to find successor,
3373 congested peer - a peer which you should ignore. once you have found this
3374 peer then just send a trail setup message to that peer. In case you are
3375 also congested then remove yourself from the trail as this message
3376 reached to as you are part of the trail. and then send the message to
3377 element before you. Ideally you should be the last element in the trail as
3378 all the the elements before you have rejected you. In case you are source,
3379 then you should call select_random_Friend(congested_peer). in case you don't
3380 find any peer because congested peer then set flag that all friends are busy
3381 and leave. */
3382 const struct PeerTrailRejectionMessage *trail_rejection;
3383 struct GNUNET_PeerIdentity *trail_peer_list;
3384 struct GNUNET_PeerIdentity source_peer;
3385 struct GNUNET_PeerIdentity congested_peer;
3386 struct FriendInfo *target_friend;
3387 struct GNUNET_PeerIdentity next_peer;
3388 struct GNUNET_PeerIdentity *next_hop;
3389 struct GNUNET_PeerIdentity current_source;
3390 struct GNUNET_PeerIdentity current_destination;
3391 size_t msize;
3392 uint32_t trail_length;
3393 uint32_t finger_map_index;
3394 uint64_t destination_finger_value;
3395
3396 msize = ntohs (message->size);
3397 if (msize < sizeof (struct PeerTrailRejectionMessage))
3398 {
3399 GNUNET_break_op (0);
3400 return GNUNET_YES;
3401 }
3402
3403 trail_rejection = (struct PeerTrailRejectionMessage *) message;
3404 trail_length = ntohl (trail_rejection->trail_length);
3405
3406 if ((msize < sizeof (struct PeerTrailRejectionMessage) +
3407 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3408 (trail_length >
3409 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3410 {
3411 GNUNET_break_op (0);
3412 return GNUNET_YES;
3413 }
3414 trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
3415 finger_map_index = ntohl (trail_rejection->finger_map_index);
3416 memcpy (&source_peer, &(trail_rejection->source_peer), sizeof(struct GNUNET_PeerIdentity));
3417 memcpy (&destination_finger_value, &(trail_rejection->finger_identity_value), sizeof (uint64_t));
3418 memcpy (&congested_peer, &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity));
3419
3420 /* If I am the source of the original trail setup message, then again select
3421 a random friend and send a new trail setup message to this finger identity
3422 value. */
3423 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &source_peer)))
3424 {
3425 /* If friend peer map is empty, or all the friends trail threshold has been crossed,
3426 * then return. */
3427 if ((GNUNET_CONTAINER_multipeermap_size (friend_peermap) == 0) ||
3428 (all_friends_trail_threshold == GNUNET_YES))
3429 {
3430 GNUNET_break(0);
3431 return GNUNET_SYSERR;
3432 }
3433
3434 /* Select any random friend except congested peer. */
3435 target_friend = select_random_friend (&congested_peer);
3436
3437 if (NULL == target_friend)
3438 {
3439 all_friends_trail_threshold = GNUNET_YES;
3440 return GNUNET_SYSERR;
3441 }
3442
3443 GDS_NEIGHBOURS_send_trail_setup (&my_identity, destination_finger_value, &(target_friend->id),
3444 &my_identity, target_friend, 0, NULL, finger_map_index);
3445 return GNUNET_YES;
3446 }
3447
3448 /* My routing state size has crossed the threshold, I can not be part of any more
3449 * trails. */
3450 if(GDS_ROUTING_check_threshold())
3451 {
3452 struct GNUNET_PeerIdentity *new_trail;
3453
3454 if (trail_length == 1)
3455 {
3456 memcpy (&next_peer, &source_peer, sizeof (struct GNUNET_PeerIdentity));
3457 }
3458 else
3459 {
3460 memcpy (&next_peer, &trail_peer_list[trail_length - 2], sizeof (struct GNUNET_PeerIdentity));
3461 }
3462
3463 /* Remove myself from the trail. */
3464 new_trail = GNUNET_malloc ((trail_length -1) * sizeof (struct GNUNET_PeerIdentity));
3465 memcpy (new_trail, trail_peer_list, (trail_length -1) * sizeof (struct GNUNET_PeerIdentity));
3466
3467 /* No more trails possible through me. send a trail rejection message to next hop. */
3468 GDS_NEIGHBOURS_send_trail_rejection (&source_peer, destination_finger_value, &my_identity,
3469 &next_peer,finger_map_index, new_trail,trail_length - 1);
3470 return GNUNET_YES;
3471 }
3472
3473 /* FIXME: In this case I have just written my_identity as current_destination
3474 and current source need ot think more of better values anad if needed or not.
3475 Also, i am adding a new parameter to funciton find_successor so that this peer
3476 is not considered as next hop congested_peer is not being used. FIXME. */
3477 memcpy (&current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity));
3478 memcpy (&current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
3479 next_hop = find_successor (destination_finger_value, &current_destination, &current_source, &congested_peer);
3480
3481 /* FIXME: WE NEED ANOTHER CASE as it may happend that congested peer is the only
3482 friend, and find_successor finds nothig, so check something else
3483 here like if current_destination is me, it means that i am destination
3484 or if current_destination = NULL, then it means found nothing. URGENT. */
3485 if (NULL == next_hop) /* This means I am the final destination */
3486 {
3487 /* SUPU: trail length is 1, when I am the friend of the srouce peer. */
3488 if (trail_length == 1)
3489 {
3490 memcpy (&next_peer, &source_peer, sizeof (struct GNUNET_PeerIdentity));
3491 }
3492 else
3493 {
3494 memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
3495 }
3496
3497 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
3498
3499 if (compare_predecessor (&source_peer) /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */)
3500 {
3501 /* FIXME: In case we have different function update_predecessor then
3502 remove the lines below. */
3503 struct GNUNET_PeerIdentity *new_trail_list;
3504 new_trail_list = invert_trail_list (&source_peer, trail_peer_list, trail_length);
3505 finger_table_add (&source_peer, new_trail_list, trail_length, PREDECESSOR_FINGER_ID);
3506 }
3507 GDS_NEIGHBOURS_send_trail_setup_result (&source_peer,
3508 &(my_identity),
3509 target_friend, trail_length,
3510 trail_peer_list,
3511 finger_map_index);
3512 return GNUNET_OK;
3513 }
3514 else
3515 {
3516 /* Now add yourself to the trail. */
3517 struct GNUNET_PeerIdentity peer_list[trail_length + 1];
3518 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
3519 peer_list[trail_length] = my_identity;
3520 trail_length++;
3521
3522 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3523 GDS_NEIGHBOURS_send_trail_setup (&source_peer,
3524 destination_finger_value,
3525 &current_destination, &current_source,
3526 target_friend, trail_length, peer_list,
3527 finger_map_index);
3528 return GNUNET_OK;
3529 }
3530 return GNUNET_SYSERR;
3531}
3532
3533#if 0
3534/**
3535 * FIXME:
3138 * Does it matter if the packet was going to a finger or friend? 3536 * Does it matter if the packet was going to a finger or friend?
3139 * Core handle for p2p trail rejection messages. 3537 * Core handle for p2p trail rejection messages.
3140 * @param cls closure 3538 * @param cls closure
@@ -3147,10 +3545,10 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *
3147 const struct GNUNET_MessageHeader *message) 3545 const struct GNUNET_MessageHeader *message)
3148{ 3546{
3149 struct PeerTrailRejectionMessage *trail_rejection; 3547 struct PeerTrailRejectionMessage *trail_rejection;
3150 struct FailedTrail *trail_fail;
3151 struct FriendInfo *target_friend; 3548 struct FriendInfo *target_friend;
3152 struct GNUNET_PeerIdentity *trail_peer_list; 3549 struct GNUNET_PeerIdentity *trail_peer_list;
3153 unsigned int finger_map_index; 3550 unsigned int finger_map_index;
3551 uint32_t trail_length;
3154 size_t msize; 3552 size_t msize;
3155 3553
3156 msize = ntohs (message->size); 3554 msize = ntohs (message->size);
@@ -3161,8 +3559,23 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *
3161 } 3559 }
3162 3560
3163 trail_rejection = (struct PeerTrailRejectionMessage *) message; 3561 trail_rejection = (struct PeerTrailRejectionMessage *) message;
3562 trail_length = ntohl (trail_rejection->trail_length);
3563
3564 if ((msize < sizeof (struct PeerTrailRejectionMessage) +
3565 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3566 (trail_length >
3567 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3568 {
3569 GNUNET_break_op (0);
3570 return GNUNET_YES;
3571 }
3164 trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; 3572 trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
3165 finger_map_index = ntohl (trail_rejection->finger_map_index); 3573 finger_map_index = ntohl (trail_rejection->finger_map_index);
3574
3575 /* FIXME: I don't think we need failed trail list. will remove it once sure.
3576 * only case where I think we can need it in if in case of finger. where
3577 * we would like to send back the message to current source and leave it
3578 * to the current source to find the closest peer.
3166 trail_fail = GNUNET_malloc (sizeof (struct FailedTrail)); 3579 trail_fail = GNUNET_malloc (sizeof (struct FailedTrail));
3167 memcpy (&(trail_fail->source_peer), &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity)); 3580 memcpy (&(trail_fail->source_peer), &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
3168 memcpy (&(trail_fail->congested_peer), &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity)); 3581 memcpy (&(trail_fail->congested_peer), &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity));
@@ -3171,14 +3584,15 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *
3171 GNUNET_assert (GNUNET_OK == 3584 GNUNET_assert (GNUNET_OK ==
3172 GNUNET_CONTAINER_multipeermap_put (failed_trail_list, &(trail_fail->source_peer), 3585 GNUNET_CONTAINER_multipeermap_put (failed_trail_list, &(trail_fail->source_peer),
3173 trail_fail, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 3586 trail_fail, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
3174 3587 */
3588
3175 /* FIXME: Is it okay if I pass the struct as parameter. */ 3589 /* FIXME: Is it okay if I pass the struct as parameter. */
3176 target_friend = select_random_friend (&(trail_fail->congested_peer)); 3590 target_friend = select_random_friend (&(trail_rejection->congested_peer));
3177 3591
3178 if(NULL != target_friend) 3592 if(NULL != target_friend)
3179 { 3593 {
3180 GDS_NEIGHBOURS_send_trail_setup (&(trail_fail->source_peer), 3594 GDS_NEIGHBOURS_send_trail_setup (&(trail_rejection->source_peer),
3181 trail_fail->destination_finger_value, 3595 trail_rejection->finger_identity,
3182 &(target_friend->id), 3596 &(target_friend->id),
3183 NULL, target_friend, ntohl (trail_rejection->trail_length), 3597 NULL, target_friend, ntohl (trail_rejection->trail_length),
3184 trail_peer_list, 3598 trail_peer_list,
@@ -3187,6 +3601,7 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *
3187 } 3601 }
3188 return GNUNET_SYSERR; 3602 return GNUNET_SYSERR;
3189} 3603}
3604#endif
3190 3605
3191/** 3606/**
3192 * Core handle for p2p trail tear down messages. 3607 * Core handle for p2p trail tear down messages.
@@ -3203,31 +3618,66 @@ int handle_dht_p2p_trail_treadown (void *cls, const struct GNUNET_PeerIdentity *
3203 finger entry and it need to inform the peers which are part of the trail to remove 3618 finger entry and it need to inform the peers which are part of the trail to remove
3204 the trail from their routing table. So, this peer should first 3619 the trail from their routing table. So, this peer should first
3205 get the next hop and then delete the entry. */ 3620 get the next hop and then delete the entry. */
3206 return GNUNET_YES; 3621 struct PeerTrailTearDownMessage *trail_teardown;
3207} 3622 struct GNUNET_PeerIdentity *trail_peer_list;
3208 3623 struct GNUNET_PeerIdentity next_hop;
3209 3624 struct FriendInfo *target_friend;
3210/** 3625 uint32_t trail_length;
3211 * FIXME: free_finger(remove_finger); Call this function at finger_table_add, 3626 size_t msize;
3212 when you replace an existing entry 3627 int my_index;
3213 * Free finger and its trail.
3214 * @param remove_finger Finger to be freed.
3215 */
3216static void
3217free_finger (struct FingerInfo *finger)
3218{
3219 struct TrailPeerList *peer;
3220 3628
3221 while (NULL != (peer = finger->head)) 3629 msize = ntohs (message->size);
3630 if (msize < sizeof (struct PeerTrailTearDownMessage))
3222 { 3631 {
3223 GNUNET_CONTAINER_DLL_remove (finger->head, finger->tail, peer); 3632 GNUNET_break_op (0);
3224 GNUNET_free (peer); 3633 return GNUNET_YES;
3225 } 3634 }
3226 3635
3227 GNUNET_free (finger); 3636 trail_teardown = (struct PeerTrailTearDownMessage *) message;
3637 trail_length = ntohl (trail_teardown->trail_length);
3638
3639 if ((msize < sizeof (struct PeerTrailTearDownMessage) +
3640 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3641 (trail_length >
3642 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3643 {
3644 GNUNET_break_op (0);
3645 return GNUNET_YES;
3646 }
3647
3648 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_teardown[1];
3649
3650 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->destination_peer), &my_identity)))
3651 {
3652 /* We have reached destination then just return. May be if the peer before this
3653 destination, does not forward the packet to destination. So, this case should never
3654 occur. */
3655 GNUNET_break (0);
3656 return GNUNET_YES;
3657 }
3658
3659 my_index = search_my_index (trail_peer_list, trail_length);
3660 if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer),
3661 &(trail_teardown->destination_peer),peer))
3662 {
3663 /* Here we get GNUNET_NO, only if there is no matching entry found in routing
3664 table. */
3665 GNUNET_break (0);
3666 return GNUNET_YES;
3667 }
3668
3669 if (my_index == (trail_length - 2))
3670 return GNUNET_SYSERR;
3671
3672 memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity));
3673 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3674
3675 GDS_NEIGHBOURS_send_trail_teardown (&(trail_teardown->source_peer),
3676 &(trail_teardown->destination_peer),
3677 trail_peer_list, trail_length, target_friend);
3678 return GNUNET_YES;
3228} 3679}
3229 3680
3230
3231/** 3681/**
3232 * Iterate over finger_peermap, and remove entries with peer as the first element 3682 * Iterate over finger_peermap, and remove entries with peer as the first element
3233 * of their trail. 3683 * of their trail.
@@ -3399,15 +3849,16 @@ GDS_NEIGHBOURS_init (void)
3399 if (NULL == core_api) 3849 if (NULL == core_api)
3400 return GNUNET_SYSERR; 3850 return GNUNET_SYSERR;
3401 3851
3402 /* Initialize the current index in the finger map. */
3403 current_finger_index = PREDECESSOR_FINGER_ID;
3404
3405 friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); 3852 friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
3406 finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO); 3853 finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO);
3854
3407 /* FIXME: Not sure if this value is correct for this data structure. also 3855 /* FIXME: Not sure if this value is correct for this data structure. also
3408 * not sure if we actually need any such data structure. Once done with other functions, 3856 * not sure if we actually need any such data structure. Once done with other functions,
3409 * will revisit this part. */ 3857 * will revisit this part.
3410 failed_trail_list = GNUNET_CONTAINER_multipeermap_create (LINK_THRESHOLD * 4/3, GNUNET_NO); 3858 failed_trail_list = GNUNET_CONTAINER_multipeermap_create (LINK_THRESHOLD * 4/3, GNUNET_NO);*/
3859 /* This global variable is set to GNUNET_YES, in case all the friends have their
3860 links threshold set. */
3861 all_friends_trail_threshold = GNUNET_NO;
3411 return GNUNET_OK; 3862 return GNUNET_OK;
3412} 3863}
3413 3864
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c
index 59df8ed40..ac27370a9 100644
--- a/src/dht/gnunet-service-xdht_routing.c
+++ b/src/dht/gnunet-service-xdht_routing.c
@@ -28,6 +28,10 @@
28#include "gnunet-service-xdht_routing.h" 28#include "gnunet-service-xdht_routing.h"
29#include "gnunet-service-xdht.h" 29#include "gnunet-service-xdht.h"
30 30
31/* TODO
32 1. to understand if we really need all the four fields.
33 2. if we can merge remove_peer and remove_trail
34 3. do we need next_hop to uniquely identify a trail in remove_trail. */
31 35
32/** 36/**
33 * Number of requests we track at most (for routing replies). 37 * Number of requests we track at most (for routing replies).
@@ -178,6 +182,22 @@ GDS_ROUTING_remove_entry (const struct GNUNET_PeerIdentity *peer)
178} 182}
179 183
180 184
185/** FIXME:TODO URGNET Need to understand if we need next hop to uniquely identify an entry
186 * in routing table or not.
187 * Remove the trail as result of trail tear down message.
188 * @param source_peer Source of the trail.
189 * @param destination_peer Destination of the trail.
190 * @param next_hop Next hop
191 * @param prev_hop Previous hop.
192 */
193int
194GDS_ROUTING_remove_trail (struct GNUNET_PeerIdentity *source_peer,
195 struct GNUNET_PeerIdentity *destination_peer,
196 const struct GNUNET_PeerIdentity *prev_hop)
197{
198 return GNUNET_NO;
199}
200
181/** 201/**
182 * Find the next hop to send packet to. 202 * Find the next hop to send packet to.
183 * @param source_peer Source of the trail. 203 * @param source_peer Source of the trail.
@@ -213,7 +233,7 @@ int
213GDS_ROUTING_check_threshold () 233GDS_ROUTING_check_threshold ()
214{ 234{
215 int ret; 235 int ret;
216 ret = (GNUNET_CONTAINER_multipeermap_size(routing_table) > ROUTING_TABLE_THRESHOLD) ? 0:1; 236 ret = (GNUNET_CONTAINER_multipeermap_size(routing_table) > ROUTING_TABLE_THRESHOLD) ? 1:0;
217 return ret; 237 return ret;
218} 238}
219 239
diff --git a/src/dht/gnunet-service-xdht_routing.h b/src/dht/gnunet-service-xdht_routing.h
index 70bacebf5..efda58a94 100644
--- a/src/dht/gnunet-service-xdht_routing.h
+++ b/src/dht/gnunet-service-xdht_routing.h
@@ -64,6 +64,20 @@ GDS_ROUTING_search(struct GNUNET_PeerIdentity *source_peer,
64 struct GNUNET_PeerIdentity *destination_peer, 64 struct GNUNET_PeerIdentity *destination_peer,
65 const struct GNUNET_PeerIdentity *prev_hop); 65 const struct GNUNET_PeerIdentity *prev_hop);
66 66
67/**
68 * Remove the trail as result of trail tear down message.
69 * @param source_peer Source of the trail.
70 * @param destination_peer Destination of the trail.
71 * @param next_hop Next hop
72 * @param prev_hop Previous hop.
73 * @return #GNUNET_YES if successful
74 * #GNUNET_NO if not successful.
75 */
76int
77GDS_ROUTING_remove_trail (struct GNUNET_PeerIdentity *source_peer,
78 struct GNUNET_PeerIdentity *destination_peer,
79 const struct GNUNET_PeerIdentity *prev_hop);
80
67 81
68/** 82/**
69 * Check if size of routing table is greater than threshold or not. 83 * Check if size of routing table is greater than threshold or not.