aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-04-29 15:16:04 +0000
committerChristian Grothoff <christian@grothoff.org>2015-04-29 15:16:04 +0000
commit0b48745c1c6ec80a8e99bcdb9514e028b8656fe0 (patch)
tree6d25cad8fc17af082b1481a48b8d4643a75fdc51 /src/dht
parentd97cb7e3039c0c3d560a1e43761afe9a3b0d1cb6 (diff)
downloadgnunet-0b48745c1c6ec80a8e99bcdb9514e028b8656fe0.tar.gz
gnunet-0b48745c1c6ec80a8e99bcdb9514e028b8656fe0.zip
-major wdht hacking / refactoring -- still not finished
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-wdht_neighbours.c620
1 files changed, 387 insertions, 233 deletions
diff --git a/src/dht/gnunet-service-wdht_neighbours.c b/src/dht/gnunet-service-wdht_neighbours.c
index 0818e21a4..3ce65978d 100644
--- a/src/dht/gnunet-service-wdht_neighbours.c
+++ b/src/dht/gnunet-service-wdht_neighbours.c
@@ -38,6 +38,7 @@
38#include "gnunet-service-wdht_clients.h" 38#include "gnunet-service-wdht_clients.h"
39#include "gnunet-service-wdht_datacache.h" 39#include "gnunet-service-wdht_datacache.h"
40#include "gnunet-service-wdht_neighbours.h" 40#include "gnunet-service-wdht_neighbours.h"
41#include "gnunet-service-wdht_nse.h"
41#include <fenv.h> 42#include <fenv.h>
42#include <stdlib.h> 43#include <stdlib.h>
43#include <string.h> 44#include <string.h>
@@ -47,9 +48,14 @@
47 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) 48 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
48 49
49/** 50/**
50 * FIXME 51 * Trail timeout. After what time do trails always die?
51 */ 52 */
52#define FOO_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) 53#define TRAIL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 42)
54
55/**
56 * Random walk delay. How often do we walk the overlay?
57 */
58#define RANDOM_WALK_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 42)
53 59
54/** 60/**
55 * The number of layered ID to use. 61 * The number of layered ID to use.
@@ -66,7 +72,7 @@
66/******************* The db structure and related functions *******************/ 72/******************* The db structure and related functions *******************/
67 73
68/** 74/**
69 * Entry in friend_peermap. 75 * Entry in #friends_peermap.
70 */ 76 */
71struct FriendInfo; 77struct FriendInfo;
72 78
@@ -127,11 +133,17 @@ struct Trail
127 */ 133 */
128 struct GNUNET_CONTAINER_HeapNode *hn; 134 struct GNUNET_CONTAINER_HeapNode *hn;
129 135
136 /**
137 * If this peer started the to create a Finger (and thus @e pred is
138 * NULL), this is the Finger we are trying to intialize.
139 */
140 struct Finger **finger;
141
130}; 142};
131 143
132 144
133/** 145/**
134 * Entry in friend_peermap. 146 * Entry in #friends_peermap.
135 */ 147 */
136struct FriendInfo 148struct FriendInfo
137{ 149{
@@ -156,22 +168,56 @@ struct FriendInfo
156}; 168};
157 169
158 170
159struct db_cell 171struct FingerTable;
172
173
174struct Finger
175{
176 struct Trail *trail;
177
178 struct FingerTable *ft;
179
180 struct GNUNET_HashCode destination;
181
182 /**
183 * #GNUNET_YES if a response has been received. Otherwise #GNUNET_NO.
184 */
185 int valid;
186};
187
188
189struct FingerTable
160{ 190{
161 /** 191 /**
162 * The identity of the peer. 192 * Array of our fingers, unsorted.
163 */ 193 */
164 struct GNUNET_PeerIdentity peer_id; 194 struct Finger **fingers;
165 195
166 /** 196 /**
167 * The trail to use to reach the peer. 197 * Array of sorted fingers (sorted by destination, valid fingers first).
168 */ 198 */
169 struct Trail *trail; 199 struct Finger **sorted_fingers;
170 200
171 /** 201 /**
172 * #GNUNET_YES if a response has been received. Otherwise #GNUNET_NO. 202 * Size of the finger array.
173 */ 203 */
174 int valid; 204 unsigned int finger_array_size;
205
206 /**
207 * Number of valid entries in @e sorted_fingers (contiguous from offset 0)
208 */
209 unsigned int number_valid_fingers;
210
211 /**
212 * Which offset in @e fingers will we redo next.
213 */
214 unsigned int walk_offset;
215
216 /**
217 * Is the finger array sorted?
218 */
219 int is_sorted;
220
175}; 221};
176 222
177 223
@@ -183,10 +229,10 @@ GNUNET_NETWORK_STRUCT_BEGIN
183/** 229/**
184 * Setup a finger using the underlay topology ("social network"). 230 * Setup a finger using the underlay topology ("social network").
185 */ 231 */
186struct FingerSetupMessage 232struct RandomWalkMessage
187{ 233{
188 /** 234 /**
189 * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP 235 * Type: #GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK
190 */ 236 */
191 struct GNUNET_MessageHeader header; 237 struct GNUNET_MessageHeader header;
192 238
@@ -203,20 +249,19 @@ struct FingerSetupMessage
203 249
204 /** 250 /**
205 * Unique (random) identifier this peer will use to 251 * Unique (random) identifier this peer will use to
206 * identify the finger (in future messages). 252 * identify the trail (in future messages).
207 */ 253 */
208 struct GNUNET_HashCode finger_id; 254 struct GNUNET_HashCode trail_id;
209 255
210}; 256};
211 257
212
213/** 258/**
214 * Response to a `struct FingerSetupMessage`. 259 * Response to a `struct RandomWalkMessage`.
215 */ 260 */
216struct FingerSetupResponseMessage 261struct RandomWalkResponseMessage
217{ 262{
218 /** 263 /**
219 * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP_RESPONSE 264 * Type: #GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK_RESPONSE
220 */ 265 */
221 struct GNUNET_MessageHeader header; 266 struct GNUNET_MessageHeader header;
222 267
@@ -226,10 +271,10 @@ struct FingerSetupResponseMessage
226 uint32_t reserved GNUNET_PACKED; 271 uint32_t reserved GNUNET_PACKED;
227 272
228 /** 273 /**
229 * Unique (random) identifier this peer will use to 274 * Unique (random) identifier from the
230 * identify the finger (in future messages). 275 * `struct RandomWalkMessage`.
231 */ 276 */
232 struct GNUNET_HashCode finger_id; 277 struct GNUNET_HashCode trail_id;
233 278
234 /** 279 /**
235 * Random location in the respective layer where the 280 * Random location in the respective layer where the
@@ -239,14 +284,37 @@ struct FingerSetupResponseMessage
239 284
240}; 285};
241 286
287/**
288 * Response to an event that causes a trail to die.
289 */
290struct TrailDestroyMessage
291{
292 /**
293 * Type: #GNUNET_MESSAGE_TYPE_WDHT_TRAIL_DESTROY
294 */
295 struct GNUNET_MessageHeader header;
296
297 /**
298 * Zero, for alignment.
299 */
300 uint32_t reserved GNUNET_PACKED;
301
302 /**
303 * Unique (random) identifier this peer will use to
304 * identify the finger (in future messages).
305 */
306 struct GNUNET_HashCode trail_id;
307
308};
309
242 310
243/** 311/**
244 * Response to an event that causes a finger to die. 312 * Send a message along a trail.
245 */ 313 */
246struct FingerDestroyMessage 314struct FindSuccessorMessage
247{ 315{
248 /** 316 /**
249 * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_DESTROY 317 * Type: #GNUNET_MESSAGE_TYPE_WDHT_FIND_SUCCESSOR
250 */ 318 */
251 struct GNUNET_MessageHeader header; 319 struct GNUNET_MessageHeader header;
252 320
@@ -259,18 +327,24 @@ struct FingerDestroyMessage
259 * Unique (random) identifier this peer will use to 327 * Unique (random) identifier this peer will use to
260 * identify the finger (in future messages). 328 * identify the finger (in future messages).
261 */ 329 */
262 struct GNUNET_HashCode finger_id; 330 struct GNUNET_HashCode trail_id;
331
332 /**
333 * Key for which we would like close values returned.
334 * identify the finger (in future messages).
335 */
336 struct GNUNET_HashCode key;
263 337
264}; 338};
265 339
266 340
267/** 341/**
268 * Send a message along a finger. 342 * Send a message along a trail.
269 */ 343 */
270struct FingerRouteMessage 344struct TrailRouteMessage
271{ 345{
272 /** 346 /**
273 * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_ROUTE 347 * Type: #GNUNET_MESSAGE_TYPE_WDHT_TRAIL_ROUTE
274 */ 348 */
275 struct GNUNET_MessageHeader header; 349 struct GNUNET_MessageHeader header;
276 350
@@ -283,9 +357,9 @@ struct FingerRouteMessage
283 * Unique (random) identifier this peer will use to 357 * Unique (random) identifier this peer will use to
284 * identify the finger (in future messages). 358 * identify the finger (in future messages).
285 */ 359 */
286 struct GNUNET_HashCode finger_id; 360 struct GNUNET_HashCode trail_id;
287 361
288 /* followed by payload to send along the finger */ 362 /* followed by payload to send along the trail */
289}; 363};
290 364
291 365
@@ -438,15 +512,6 @@ struct PeerGetResultMessage
438 512
439GNUNET_NETWORK_STRUCT_END 513GNUNET_NETWORK_STRUCT_END
440 514
441/**
442 * The number of cells stored in the db structure.
443 */
444static unsigned int number_cell;
445
446/**
447 * If sorted_db array is sorted #GNUNET_YES. Otherwise #GNUNET_NO.
448 */
449static int is_sorted;
450 515
451/** 516/**
452 * Contains all the layered IDs of this peer. 517 * Contains all the layered IDs of this peer.
@@ -454,17 +519,6 @@ static int is_sorted;
454struct GNUNET_PeerIdentity layered_id[NUMBER_LAYERED_ID]; 519struct GNUNET_PeerIdentity layered_id[NUMBER_LAYERED_ID];
455 520
456/** 521/**
457 * Unsorted database, here we manage the entries.
458 */
459static struct db_cell *unsorted_db[NUMBER_RANDOM_WALK * NUMBER_LAYERED_ID];
460
461/**
462 * Sorted database by peer identity, needs to be re-sorted if
463 * #is_sorted is #GNUNET_NO.
464 */
465static struct db_cell **sorted_db[NUMBER_RANDOM_WALK * NUMBER_LAYERED_ID];
466
467/**
468 * Task to timeout trails that have expired. 522 * Task to timeout trails that have expired.
469 */ 523 */
470static struct GNUNET_SCHEDULER_Task *trail_timeout_task; 524static struct GNUNET_SCHEDULER_Task *trail_timeout_task;
@@ -480,14 +534,14 @@ static struct GNUNET_SCHEDULER_Task *random_walk_task;
480static struct GNUNET_PeerIdentity my_identity; 534static struct GNUNET_PeerIdentity my_identity;
481 535
482/** 536/**
483 * Peer map of all the fingers of a peer 537 * Peer map of all the friends of a peer
484 */ 538 */
485static struct GNUNET_CONTAINER_MultiPeerMap *fingers_peermap; 539static struct GNUNET_CONTAINER_MultiPeerMap *friends_peermap;
486 540
487/** 541/**
488 * Peer map of all the successors of a peer 542 * Fingers per layer.
489 */ 543 */
490static struct GNUNET_CONTAINER_MultiPeerMap *successors_peermap; 544static struct FingerTable fingers[NUMBER_LAYERED_ID];
491 545
492/** 546/**
493 * Tail map, mapping tail identifiers to `struct Trail`s 547 * Tail map, mapping tail identifiers to `struct Trail`s
@@ -506,49 +560,6 @@ static struct GNUNET_CORE_Handle *core_api;
506 560
507 561
508/** 562/**
509 * Initialize the db structure with default values.
510 */
511static void
512init_db_structure ()
513{
514 unsigned int i;
515
516 for (i = 0; i < NUMBER_RANDOM_WALK; i++)
517 {
518 unsorted_db[i] = NULL;
519 sorted_db[i] = &unsorted_db[i];
520 }
521}
522
523
524/**
525 * Destroy the db_structure. Basically, free every db_cell.
526 */
527static void
528destroy_db_structure ()
529{
530 unsigned int i;
531
532 for (i = 0; i < NUMBER_RANDOM_WALK; i++)
533 {
534 // what about 'unsorted_db[i]->trail?
535 GNUNET_free_non_null (unsorted_db[i]);
536 }
537}
538
539
540/**
541 * Add a new db_cell in the db structure.
542 */
543static void
544add_new_cell (struct db_cell *bd_cell)
545{
546 unsorted_db[number_cell] = bd_cell;
547 is_sorted = GNUNET_NO;
548}
549
550
551/**
552 * Handle the put request from the client. 563 * Handle the put request from the client.
553 * 564 *
554 * @param key Key for the content 565 * @param key Key for the content
@@ -567,6 +578,12 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key,
567 struct GNUNET_TIME_Absolute expiration_time, 578 struct GNUNET_TIME_Absolute expiration_time,
568 const void *data, size_t data_size) 579 const void *data, size_t data_size)
569{ 580{
581 GDS_DATACACHE_handle_put (expiration_time,
582 key,
583 0, NULL,
584 block_type,
585 data_size,
586 data);
570} 587}
571 588
572 589
@@ -586,9 +603,26 @@ GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key,
586 enum GNUNET_DHT_RouteOption options, 603 enum GNUNET_DHT_RouteOption options,
587 uint32_t desired_replication_level) 604 uint32_t desired_replication_level)
588{ 605{
606 // find closest finger(s) on all layers
607 // use TrailRoute with PeerGetMessage embedded to contact peer
589} 608}
590 609
591 610
611/**
612 * Delete a trail, it died (timeout, link failure, etc.).
613 *
614 * @param trail trail to delete from all data structures
615 * @param inform_pred should we notify the predecessor?
616 * @param inform_succ should we inform the successor?
617 */
618static void
619delete_trail (struct Trail *trail,
620 int inform_pred,
621 int inform_succ)
622{
623 // ... FIXME
624}
625
592 626
593/** 627/**
594 * Send the get result to requesting client. 628 * Send the get result to requesting client.
@@ -617,6 +651,8 @@ GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
617 struct GNUNET_TIME_Absolute expiration, 651 struct GNUNET_TIME_Absolute expiration,
618 const void *data, size_t data_size) 652 const void *data, size_t data_size)
619{ 653{
654 // TRICKY: need to introduce some context to remember trail from
655 // the lookup...
620} 656}
621 657
622 658
@@ -631,6 +667,7 @@ handle_core_disconnect (void *cls,
631 const struct GNUNET_PeerIdentity *peer) 667 const struct GNUNET_PeerIdentity *peer)
632{ 668{
633 struct FriendInfo *remove_friend; 669 struct FriendInfo *remove_friend;
670 struct Trail *t;
634 671
635 /* If disconnected to own identity, then return. */ 672 /* If disconnected to own identity, then return. */
636 if (0 == memcmp (&my_identity, 673 if (0 == memcmp (&my_identity,
@@ -639,7 +676,7 @@ handle_core_disconnect (void *cls,
639 return; 676 return;
640 677
641 if (NULL == (remove_friend = 678 if (NULL == (remove_friend =
642 GNUNET_CONTAINER_multipeermap_get (fingers_peermap, 679 GNUNET_CONTAINER_multipeermap_get (friends_peermap,
643 peer))) 680 peer)))
644 { 681 {
645 GNUNET_break (0); 682 GNUNET_break (0);
@@ -647,14 +684,21 @@ handle_core_disconnect (void *cls,
647 } 684 }
648 685
649 GNUNET_assert (GNUNET_YES == 686 GNUNET_assert (GNUNET_YES ==
650 GNUNET_CONTAINER_multipeermap_remove (fingers_peermap, 687 GNUNET_CONTAINER_multipeermap_remove (friends_peermap,
651 peer, 688 peer,
652 remove_friend)); 689 remove_friend));
653 /* FIXME: do stuff */ 690 while (NULL != (t = remove_friend->succ_head))
691 delete_trail (t,
692 GNUNET_YES,
693 GNUNET_NO);
694 while (NULL != (t = remove_friend->pred_head))
695 delete_trail (t,
696 GNUNET_NO,
697 GNUNET_YES);
654 GNUNET_MQ_destroy (remove_friend->mq); 698 GNUNET_MQ_destroy (remove_friend->mq);
655 GNUNET_free (remove_friend); 699 GNUNET_free (remove_friend);
656 if (0 == 700 if (0 ==
657 GNUNET_CONTAINER_multipeermap_size (fingers_peermap)) 701 GNUNET_CONTAINER_multipeermap_size (friends_peermap))
658 { 702 {
659 GNUNET_SCHEDULER_cancel (random_walk_task); 703 GNUNET_SCHEDULER_cancel (random_walk_task);
660 random_walk_task = NULL; 704 random_walk_task = NULL;
@@ -663,6 +707,18 @@ handle_core_disconnect (void *cls,
663 707
664 708
665/** 709/**
710 * Pick random friend from friends for random walk.
711 */
712static struct FriendInfo *
713pick_random_friend ()
714{
715 // TODO: need to extend peermap API to return random entry...
716 // (Note: same extension exists for hashmap API).
717 return NULL; // FIXME...
718}
719
720
721/**
666 * Initiate a random walk. 722 * Initiate a random walk.
667 * 723 *
668 * @param cls NULL 724 * @param cls NULL
@@ -672,34 +728,71 @@ static void
672do_random_walk (void *cls, 728do_random_walk (void *cls,
673 const struct GNUNET_SCHEDULER_TaskContext *tc) 729 const struct GNUNET_SCHEDULER_TaskContext *tc)
674{ 730{
731 static unsigned int walk_layer;
675 struct FriendInfo *friend; 732 struct FriendInfo *friend;
676 struct GNUNET_MQ_Envelope *env; 733 struct GNUNET_MQ_Envelope *env;
677 struct FingerSetupMessage *fsm; 734 struct RandomWalkMessage *rwm;
678 struct db_cell *friend_cell; 735 struct FingerTable *ft;
736 struct Finger *finger;
679 struct Trail *trail; 737 struct Trail *trail;
680 738
681 friend = NULL; // FIXME: pick at random... 739 random_walk_task = NULL;
682 740 friend = pick_random_friend ();
683 friend_cell = GNUNET_new (struct db_cell);
684 friend_cell->peer_id = friend->id;
685 741
686 trail = GNUNET_new (struct Trail); 742 trail = GNUNET_new (struct Trail);
687
688 /* We create the random walk so, no predecessor */ 743 /* We create the random walk so, no predecessor */
689 trail->succ = friend; 744 trail->succ = friend;
690 745 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
746 &trail->succ_id);
747 if (GNUNET_OK !=
748 GNUNET_CONTAINER_multihashmap_put (trail_map,
749 &trail->succ_id,
750 trail,
751 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
752 {
753 GNUNET_break (0);
754 GNUNET_free (trail);
755 return;
756 }
691 GNUNET_CONTAINER_MDLL_insert (succ, 757 GNUNET_CONTAINER_MDLL_insert (succ,
692 friend->succ_head, 758 friend->succ_head,
693 friend->succ_tail, 759 friend->succ_tail,
694 trail); 760 trail);
695 env = GNUNET_MQ_msg (fsm, 761 env = GNUNET_MQ_msg (rwm,
696 GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP); 762 GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK);
697 fsm->hops_taken = htons (0); 763 rwm->hops_taken = htonl (0);
698 fsm->layer = htons (0); // FIXME: not always 0... 764 rwm->trail_id = trail->succ_id;
699 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
700 &fsm->finger_id);
701 GNUNET_MQ_send (friend->mq, 765 GNUNET_MQ_send (friend->mq,
702 env); 766 env);
767 /* clean up 'old' entry (implicitly via trail cleanup) */
768 ft = &fingers[walk_layer];
769
770 if ( (NULL != ft->fingers) &&
771 (NULL != (finger = ft->fingers[ft->walk_offset])) )
772 delete_trail (finger->trail,
773 GNUNET_NO,
774 GNUNET_YES);
775 if (ft->finger_array_size < 42)
776 {
777 // FIXME: must have finger array of the right size here,
778 // FIXME: growing / shrinking are tricy -- with pointers
779 // from Trails!!!
780 }
781
782 GNUNET_assert (NULL == ft->fingers[ft->walk_offset]);
783
784 finger = GNUNET_new (struct Finger);
785 finger->trail = trail;
786 trail->finger = &ft->fingers[ft->walk_offset];
787 finger->ft = ft;
788 ft->fingers[ft->walk_offset] = finger;
789 ft->is_sorted = GNUNET_NO;
790 ft->walk_offset = (ft->walk_offset + 1) % ft->finger_array_size;
791
792 walk_layer = (walk_layer + 1) % NUMBER_LAYERED_ID;
793 random_walk_task = GNUNET_SCHEDULER_add_delayed (RANDOM_WALK_DELAY,
794 &do_random_walk,
795 NULL);
703} 796}
704 797
705 798
@@ -723,7 +816,7 @@ handle_core_connect (void *cls,
723 816
724 /* If peer already exists in our friend_peermap, then exit. */ 817 /* If peer already exists in our friend_peermap, then exit. */
725 if (GNUNET_YES == 818 if (GNUNET_YES ==
726 GNUNET_CONTAINER_multipeermap_contains (fingers_peermap, 819 GNUNET_CONTAINER_multipeermap_contains (friends_peermap,
727 peer_identity)) 820 peer_identity))
728 { 821 {
729 GNUNET_break (0); 822 GNUNET_break (0);
@@ -735,16 +828,15 @@ handle_core_connect (void *cls,
735 friend->mq = GNUNET_CORE_mq_create (core_api, 828 friend->mq = GNUNET_CORE_mq_create (core_api,
736 peer_identity); 829 peer_identity);
737 GNUNET_assert (GNUNET_OK == 830 GNUNET_assert (GNUNET_OK ==
738 GNUNET_CONTAINER_multipeermap_put (fingers_peermap, 831 GNUNET_CONTAINER_multipeermap_put (friends_peermap,
739 peer_identity, 832 peer_identity,
740 friend, 833 friend,
741 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 834 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
742 /* do work? */
743
744 if (NULL == random_walk_task) 835 if (NULL == random_walk_task)
745 { 836 {
746 random_walk_task = GNUNET_SCHEDULER_add_now (&do_random_walk, 837 /* random walk needs to be started -- we have a first connection */
747 NULL); 838 random_walk_task = GNUNET_SCHEDULER_add_now (&do_random_walk,
839 NULL);
748 } 840 }
749} 841}
750 842
@@ -764,8 +856,8 @@ core_init (void *cls,
764 856
765 857
766/** 858/**
767 * Handle a `struct FingerSetupMessage` from a GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP 859 * Handle a `struct RandomWalkMessage` from a
768 * message. 860 * #GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK message.
769 * 861 *
770 * @param cls closure (NULL) 862 * @param cls closure (NULL)
771 * @param peer sender identity 863 * @param peer sender identity
@@ -773,27 +865,120 @@ core_init (void *cls,
773 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 865 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
774 */ 866 */
775static int 867static int
776handle_dht_p2p_finger_setup (void *cls, 868handle_dht_p2p_random_walk (void *cls,
777 const struct GNUNET_PeerIdentity *peer, 869 const struct GNUNET_PeerIdentity *peer,
778 const struct GNUNET_MessageHeader *message) 870 const struct GNUNET_MessageHeader *message)
779{ 871{
780 const struct FingerSetupMessage *fsm; 872 const struct RandomWalkMessage *m;
781 873 struct Trail *t;
782 fsm = (const struct FingerSetupMessage *) message; 874 struct FriendInfo *pred;
783
784 /*
785 * Steps :
786 * 1 check if the hops_taken is < to log(honest node)
787 * 1.a.1 if true : increments the hops_taken
788 * 1.a.2 send the same structure
789 * 1.b if false : drop the message
790 */
791 875
876 m = (const struct RandomWalkMessage *) message;
877 pred = GNUNET_CONTAINER_multipeermap_get (friends_peermap,
878 peer);
879 t = GNUNET_new (struct Trail);
880 t->pred_id = m->trail_id;
881 t->pred = pred;
882 t->expiration_time = GNUNET_TIME_relative_to_absolute (TRAIL_TIMEOUT);
883 if (GNUNET_OK !=
884 GNUNET_CONTAINER_multihashmap_put (trail_map,
885 &t->pred_id,
886 t,
887 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
888 {
889 GNUNET_break_op (0);
890 GNUNET_free (t);
891 return GNUNET_SYSERR;
892 }
893 GNUNET_CONTAINER_MDLL_insert (pred,
894 pred->pred_head,
895 pred->pred_tail,
896 t);
897 if (ntohl (m->hops_taken) > GDS_NSE_get ())
898 {
899 /* We are the last hop, generate response */
900 struct GNUNET_MQ_Envelope *env;
901 struct RandomWalkResponseMessage *rwrm;
902 uint16_t layer;
903
904 env = GNUNET_MQ_msg (rwrm,
905 GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK_RESPONSE);
906 rwrm->reserved = htonl (0);
907 rwrm->trail_id = m->trail_id;
908 layer = ntohs (m->layer);
909 if (0 == layer)
910 (void) GDS_DATACACHE_get_random_key (&rwrm->location);
911 else
912 {
913 struct FingerTable *ft;
914
915 if (layer > NUMBER_LAYERED_ID)
916 {
917 GNUNET_break_op (0);
918 // FIXME: clean up 't'...
919 return GNUNET_SYSERR;
920 }
921 ft = &fingers[layer-1];
922 if (0 == ft->number_valid_fingers)
923 {
924 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
925 &rwrm->location);
926 }
927 else
928 {
929 struct Finger *f;
930
931 f = ft->fingers[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
932 ft->number_valid_fingers)];
933 rwrm->location = f->destination;
934 }
935 }
936 GNUNET_MQ_send (pred->mq,
937 env);
938 }
939 else
940 {
941 struct GNUNET_MQ_Envelope *env;
942 struct RandomWalkMessage *rwm;
943 struct FriendInfo *succ;
944
945 /* extend the trail by another random hop */
946 succ = pick_random_friend ();
947 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
948 &t->succ_id);
949 t->succ = succ;
950 if (GNUNET_OK !=
951 GNUNET_CONTAINER_multihashmap_put (trail_map,
952 &t->succ_id,
953 t,
954 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
955 {
956 GNUNET_break (0);
957 GNUNET_CONTAINER_MDLL_remove (pred,
958 pred->pred_head,
959 pred->pred_tail,
960 t);
961 GNUNET_free (t);
962 return GNUNET_OK;
963 }
964 GNUNET_CONTAINER_MDLL_insert (succ,
965 succ->succ_head,
966 succ->succ_tail,
967 t);
968 env = GNUNET_MQ_msg (rwm,
969 GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK);
970 rwm->hops_taken = htons (1 + ntohs (m->hops_taken));
971 rwm->layer = m->layer;
972 rwm->trail_id = t->succ_id;
973 GNUNET_MQ_send (succ->mq,
974 env);
975 }
792 return GNUNET_OK; 976 return GNUNET_OK;
793} 977}
794 978
979
795/** 980/**
796 * Handle a `struct FingerSetupResponseMessage` from a GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP_RESPONSE 981 * Handle a `struct RandomWalkResponseMessage` from a GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK_RESPONSE
797 * message. 982 * message.
798 * 983 *
799 * @param cls closure (NULL) 984 * @param cls closure (NULL)
@@ -802,14 +987,14 @@ handle_dht_p2p_finger_setup (void *cls,
802 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 987 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
803 */ 988 */
804static int 989static int
805handle_dht_p2p_finger_setup_response (void *cls, 990handle_dht_p2p_random_walk_response (void *cls,
806 const struct GNUNET_PeerIdentity *peer, 991 const struct GNUNET_PeerIdentity *peer,
807 const struct GNUNET_MessageHeader *message) 992 const struct GNUNET_MessageHeader *message)
808{ 993{
809 const struct FingerSetupResponseMessage *fsrm; 994 const struct RandomWalkResponseMessage *rwrm;
810
811 fsrm = (const struct FingerSetupResponseMessage *) message;
812 995
996 rwrm = (const struct RandomWalkResponseMessage *) message;
997 // 1) lookup trail => find Finger entry => fill in 'destination' and mark valid, move to end of sorted array, mark unsorted, update links from 'trails'
813 /* 998 /*
814 * Steps : 999 * Steps :
815 * 1 check if we are the correct layer 1000 * 1 check if we are the correct layer
@@ -823,7 +1008,7 @@ handle_dht_p2p_finger_setup_response (void *cls,
823 1008
824 1009
825/** 1010/**
826 * Handle a `struct FingerDestroyMessage`. 1011 * Handle a `struct TrailDestroyMessage`.
827 * 1012 *
828 * @param cls closure (NULL) 1013 * @param cls closure (NULL)
829 * @param peer sender identity 1014 * @param peer sender identity
@@ -831,17 +1016,17 @@ handle_dht_p2p_finger_setup_response (void *cls,
831 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 1016 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
832 */ 1017 */
833static int 1018static int
834handle_dht_p2p_finger_destroy (void *cls, 1019handle_dht_p2p_trail_destroy (void *cls,
835 const struct GNUNET_PeerIdentity *peer, 1020 const struct GNUNET_PeerIdentity *peer,
836 const struct GNUNET_MessageHeader *message) 1021 const struct GNUNET_MessageHeader *message)
837{ 1022{
838 const struct FingerDestroyMessage *fdm; 1023 const struct TrailDestroyMessage *tdm;
839 1024
840 fdm = (const struct FingerDestroyMessage *) message; 1025 tdm = (const struct TrailDestroyMessage *) message;
841 1026
842 /* 1027 /*
843 * Steps : 1028 * Steps :
844 * 1 check if message comme from a trail 1029 * 1 check if message comme from a trail (that we still remember...)
845 * 1.a.1 if true: send the destroy message to the rest trail 1030 * 1.a.1 if true: send the destroy message to the rest trail
846 * 1.a.2 clean the trail structure 1031 * 1.a.2 clean the trail structure
847 * 1.a.3 did i have to remove the trail and ID from the db structure? 1032 * 1.a.3 did i have to remove the trail and ID from the db structure?
@@ -851,37 +1036,37 @@ handle_dht_p2p_finger_destroy (void *cls,
851 return GNUNET_OK; 1036 return GNUNET_OK;
852} 1037}
853 1038
1039
854/** 1040/**
855 * Handle a `struct FingerRouteMessage`. 1041 * Handle a `struct TrailRouteMessage`.
856 * 1042 *
857 * @param cls closure (NULL) 1043 * @param cls closure (NULL)
858 * @param peer sender identity 1044 * @param peer sender identity
859 * @param message the finger route message 1045 * @param message the finger destroy message
860 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 1046 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
861 */ 1047 */
862static int 1048static int
863handle_dht_p2p_finger_route (void *cls, 1049handle_dht_p2p_trail_route (void *cls,
864 const struct GNUNET_PeerIdentity *peer, 1050 const struct GNUNET_PeerIdentity *peer,
865 const struct GNUNET_MessageHeader *message) 1051 const struct GNUNET_MessageHeader *message)
866{ 1052{
867 const struct FingerRouteMessage *frm; 1053 const struct TrailRouteMessage *trm;
868 1054
869 frm = (const struct FingerRouteMessage *) message; 1055 trm = (const struct TrailRouteMessage *) message;
870 /* FIXME: check the size of the message */
871 1056
872 /* 1057 /*
873 * steps : 1058 * Steps :
874 * 1 find the good trail 1059 * 1 check if message comme from a trail
875 * 2 check the message inside 1060 * 1.a.1 if trail not finished with us, continue to forward
876 * 2.a if the message is a finger setup message : increments ce hops_takeb 1061 * 1.a.2 otherwise handle body message embedded in trail
877 * 3 send the finger route message
878 */ 1062 */
879 1063
880 return GNUNET_OK; 1064 return GNUNET_OK;
881} 1065}
882 1066
1067
883/** 1068/**
884 * Handle a `struct FingerSetupMessage` from a GNUNET_MESSAGE_TYPE_WDHT_NEIGHBOUR_FIND 1069 * Handle a `struct FindSuccessorMessage` from a #GNUNET_MESSAGE_TYPE_WDHT_SUCCESSOR_FIND
885 * message. 1070 * message.
886 * 1071 *
887 * @param cls closure (NULL) 1072 * @param cls closure (NULL)
@@ -890,37 +1075,20 @@ handle_dht_p2p_finger_route (void *cls,
890 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 1075 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
891 */ 1076 */
892static int 1077static int
893handle_dht_p2p_neighbour_find (void *cls, 1078handle_dht_p2p_successor_find (void *cls,
894 const struct GNUNET_PeerIdentity *peer, 1079 const struct GNUNET_PeerIdentity *peer,
895 const struct GNUNET_MessageHeader *message) 1080 const struct GNUNET_MessageHeader *message)
896{ 1081{
897 const struct FingerSetupMessage *fsm; 1082 const struct FindSuccessorMessage *fsm;
898 1083
899 fsm = (const struct FingerSetupMessage *) message; 1084 fsm = (const struct FindSuccessorMessage *) message;
1085 // locate trail (for sending reply), if not exists, fail nicely.
1086 // otherwise, go to datacache and return 'top k' elements closest to 'key'
1087 // as "PUT" messages via the trail (need to extend DB API!)
900 1088
901 return GNUNET_OK; 1089 return GNUNET_OK;
902} 1090}
903 1091
904/**
905 * Handle a `struct FingerSetupResponseMessage` from a GNUNET_MESSAGE_TYPE_WDHT_NEIGHBOUR_FIND
906 * message.
907 *
908 * @param cls closure (NULL)
909 * @param peer sender identity
910 * @param message the finger setup response message
911 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
912 */
913static int
914handle_dht_p2p_neighbour_found (void *cls,
915 const struct GNUNET_PeerIdentity *peer,
916 const struct GNUNET_MessageHeader *message)
917{
918 const struct FingerSetupResponseMessage *fsrm;
919
920 fsrm = (const struct FingerSetupResponseMessage *) message;
921
922 return GNUNET_OK;
923}
924 1092
925/** 1093/**
926 * Handle a `struct PeerGetMessage`. 1094 * Handle a `struct PeerGetMessage`.
@@ -932,13 +1100,14 @@ handle_dht_p2p_neighbour_found (void *cls,
932 */ 1100 */
933static int 1101static int
934handle_dht_p2p_peer_get (void *cls, 1102handle_dht_p2p_peer_get (void *cls,
935 const struct GNUNET_PeerIdentity *peer, 1103 const struct GNUNET_PeerIdentity *peer,
936 const struct GNUNET_MessageHeader *message) 1104 const struct GNUNET_MessageHeader *message)
937{ 1105{
938 const struct PeerGetMessage *pgm; 1106 const struct PeerGetMessage *pgm;
939 1107
1108 // FIXME: note: never called like this, message embedded with trail route!
940 pgm = (const struct PeerGetMessage *) message; 1109 pgm = (const struct PeerGetMessage *) message;
941 1110 // -> lookup in datacache (figure out way to remember trail!)
942 /* 1111 /*
943 * steps : 1112 * steps :
944 * 1 extract the result 1113 * 1 extract the result
@@ -951,6 +1120,7 @@ handle_dht_p2p_peer_get (void *cls,
951 return GNUNET_OK; 1120 return GNUNET_OK;
952} 1121}
953 1122
1123
954/** 1124/**
955 * Handle a `struct PeerGetResultMessage`. 1125 * Handle a `struct PeerGetResultMessage`.
956 * 1126 *
@@ -967,15 +1137,7 @@ handle_dht_p2p_peer_get_result (void *cls,
967 const struct PeerGetResultMessage *pgrm; 1137 const struct PeerGetResultMessage *pgrm;
968 1138
969 pgrm = (const struct PeerGetResultMessage *) message; 1139 pgrm = (const struct PeerGetResultMessage *) message;
970 1140 // pretty much: parse, & pass to client (there is some call for that...)
971 /*
972 * steps :
973 * 1 extract the result
974 * 2 create a peerGetResult struct
975 * 3 send it using the good trail
976 *
977 * What do i do when i don't have the key/value?
978 */
979 1141
980 return GNUNET_OK; 1142 return GNUNET_OK;
981} 1143}
@@ -997,7 +1159,7 @@ handle_dht_p2p_peer_put (void *cls,
997 const struct PeerGetResultMessage *pgrm; 1159 const struct PeerGetResultMessage *pgrm;
998 1160
999 pgrm = (const struct PeerGetResultMessage *) message; 1161 pgrm = (const struct PeerGetResultMessage *) message;
1000 1162 // parse & store in datacache, this is in response to us asking for successors.
1001 /* 1163 /*
1002 * steps : 1164 * steps :
1003 * 1 check the size of the message 1165 * 1 check the size of the message
@@ -1016,24 +1178,21 @@ int
1016GDS_NEIGHBOURS_init (void) 1178GDS_NEIGHBOURS_init (void)
1017{ 1179{
1018 static const struct GNUNET_CORE_MessageHandler core_handlers[] = { 1180 static const struct GNUNET_CORE_MessageHandler core_handlers[] = {
1019 { &handle_dht_p2p_finger_setup, 1181 { &handle_dht_p2p_random_walk,
1020 GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP, 1182 GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK,
1021 sizeof (struct FingerSetupMessage) }, 1183 sizeof (struct RandomWalkMessage) },
1022 { &handle_dht_p2p_finger_setup_response, 1184 { &handle_dht_p2p_random_walk_response,
1023 GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP_RESPONSE, 1185 GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK_RESPONSE,
1024 sizeof (struct FingerSetupResponseMessage) }, 1186 sizeof (struct RandomWalkResponseMessage) },
1025 { &handle_dht_p2p_finger_destroy, 1187 { &handle_dht_p2p_trail_destroy,
1026 GNUNET_MESSAGE_TYPE_WDHT_FINGER_DESTROY, 1188 GNUNET_MESSAGE_TYPE_WDHT_TRAIL_DESTROY,
1027 sizeof (struct FingerDestroyMessage) }, 1189 sizeof (struct TrailDestroyMessage) },
1028 { &handle_dht_p2p_finger_route, 1190 { &handle_dht_p2p_trail_route,
1029 GNUNET_MESSAGE_TYPE_WDHT_FINGER_ROUTE, 1191 GNUNET_MESSAGE_TYPE_WDHT_TRAIL_ROUTE,
1030 0}, 1192 0},
1031 { &handle_dht_p2p_neighbour_find, 1193 { &handle_dht_p2p_successor_find,
1032 GNUNET_MESSAGE_TYPE_WDHT_NEIGHBOUR_FIND, 1194 GNUNET_MESSAGE_TYPE_WDHT_SUCCESSOR_FIND,
1033 sizeof (struct FingerSetupMessage) }, 1195 sizeof (struct FindSuccessorMessage) },
1034 { &handle_dht_p2p_neighbour_found,
1035 GNUNET_MESSAGE_TYPE_WDHT_NEIGHBOUR_FOUND,
1036 sizeof (struct FingerSetupResponseMessage) },
1037 { &handle_dht_p2p_peer_get, 1196 { &handle_dht_p2p_peer_get,
1038 GNUNET_MESSAGE_TYPE_WDHT_GET, 1197 GNUNET_MESSAGE_TYPE_WDHT_GET,
1039 sizeof (struct PeerGetMessage) }, 1198 sizeof (struct PeerGetMessage) },
@@ -1057,15 +1216,9 @@ GDS_NEIGHBOURS_init (void)
1057 1216
1058 if (NULL == core_api) 1217 if (NULL == core_api)
1059 return GNUNET_SYSERR; 1218 return GNUNET_SYSERR;
1060 1219 friends_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
1061 fingers_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); 1220 trail_map = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_YES);
1062 successors_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); 1221 trail_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1063
1064 init_db_structure();
1065
1066
1067
1068
1069 return GNUNET_OK; 1222 return GNUNET_OK;
1070} 1223}
1071 1224
@@ -1080,13 +1233,14 @@ GDS_NEIGHBOURS_done (void)
1080 return; 1233 return;
1081 GNUNET_CORE_disconnect (core_api); 1234 GNUNET_CORE_disconnect (core_api);
1082 core_api = NULL; 1235 core_api = NULL;
1083 1236 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friends_peermap));
1084 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (fingers_peermap)); 1237 GNUNET_CONTAINER_multipeermap_destroy (friends_peermap);
1085 GNUNET_CONTAINER_multipeermap_destroy (fingers_peermap); 1238 friends_peermap = NULL;
1086 GNUNET_CONTAINER_multipeermap_destroy (successors_peermap); 1239 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (trail_map));
1087 destroy_db_structure(); 1240 GNUNET_CONTAINER_multihashmap_destroy (trail_map);
1088 1241 trail_map = NULL;
1089 fingers_peermap = NULL; 1242 GNUNET_CONTAINER_heap_destroy (trail_heap);
1243 trail_heap = NULL;
1090} 1244}
1091 1245
1092 1246