aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-16 19:31:31 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-16 19:31:40 +0100
commite66a9b07d76995c00dab4c62ef22c73d2a3d7aaf (patch)
tree669832e718b17f957c596b9fb0ccfc6e232ef7d1 /src
parent64ae3fa79fb69de77eee7497922af2f79cbf7de4 (diff)
downloadgnunet-e66a9b07d76995c00dab4c62ef22c73d2a3d7aaf.tar.gz
gnunet-e66a9b07d76995c00dab4c62ef22c73d2a3d7aaf.zip
finish logic to maintain paths
Diffstat (limited to 'src')
-rw-r--r--src/cadet/gnunet-service-cadet-new_dht.c27
-rw-r--r--src/cadet/gnunet-service-cadet-new_dht.h19
-rw-r--r--src/cadet/gnunet-service-cadet-new_paths.c240
-rw-r--r--src/cadet/gnunet-service-cadet-new_paths.h40
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.c73
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.h38
6 files changed, 282 insertions, 155 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_dht.c b/src/cadet/gnunet-service-cadet-new_dht.c
index 8cd3a648e..3cf3f0301 100644
--- a/src/cadet/gnunet-service-cadet-new_dht.c
+++ b/src/cadet/gnunet-service-cadet-new_dht.c
@@ -47,16 +47,6 @@ struct GCD_search_handle
47 */ 47 */
48 struct GNUNET_DHT_GetHandle *dhtget; 48 struct GNUNET_DHT_GetHandle *dhtget;
49 49
50 /**
51 * Provided callback to call when a path is found.
52 */
53 GCD_search_callback callback;
54
55 /**
56 * Provided closure.
57 */
58 void *cls;
59
60}; 50};
61 51
62 52
@@ -86,7 +76,6 @@ static struct GNUNET_SCHEDULER_Task *announce_id_task;
86static struct GNUNET_TIME_Relative announce_delay; 76static struct GNUNET_TIME_Relative announce_delay;
87 77
88 78
89
90/** 79/**
91 * Function to process paths received for a new peer addition. The recorded 80 * Function to process paths received for a new peer addition. The recorded
92 * paths form the initial tunnel, which can be optimized later. 81 * paths form the initial tunnel, which can be optimized later.
@@ -114,19 +103,13 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
114 size_t size, 103 size_t size,
115 const void *data) 104 const void *data)
116{ 105{
117 struct GCD_search_handle *h = cls;
118 const struct GNUNET_HELLO_Message *hello = data; 106 const struct GNUNET_HELLO_Message *hello = data;
119 struct CadetPeerPath *p;
120 struct CadetPeer *peer; 107 struct CadetPeer *peer;
121 108
122 p = GCPP_path_from_dht (get_path, 109 GCPP_try_path_from_dht (get_path,
123 get_path_length, 110 get_path_length,
124 put_path, 111 put_path,
125 put_path_length); 112 put_path_length);
126 h->callback (h->cls,
127 p);
128 GCPP_path_destroy (p);
129
130 if ( (size >= sizeof (struct GNUNET_HELLO_Message)) && 113 if ( (size >= sizeof (struct GNUNET_HELLO_Message)) &&
131 (ntohs (hello->header.size) == size) && 114 (ntohs (hello->header.size) == size) &&
132 (size == GNUNET_HELLO_size (hello)) ) 115 (size == GNUNET_HELLO_size (hello)) )
@@ -280,14 +263,10 @@ GCD_shutdown (void)
280 * Search DHT for paths to @a peeR_id 263 * Search DHT for paths to @a peeR_id
281 * 264 *
282 * @param peer_id peer to search for 265 * @param peer_id peer to search for
283 * @param callback function to call with results
284 * @param callback_cls closure for @a callback
285 * @return handle to abort search 266 * @return handle to abort search
286 */ 267 */
287struct GCD_search_handle * 268struct GCD_search_handle *
288GCD_search (const struct GNUNET_PeerIdentity *peer_id, 269GCD_search (const struct GNUNET_PeerIdentity *peer_id)
289 GCD_search_callback callback,
290 void *callback_cls)
291{ 270{
292 struct GNUNET_HashCode phash; 271 struct GNUNET_HashCode phash;
293 struct GCD_search_handle *h; 272 struct GCD_search_handle *h;
@@ -307,8 +286,6 @@ GCD_search (const struct GNUNET_PeerIdentity *peer_id,
307 sizeof (*peer_id)); 286 sizeof (*peer_id));
308 287
309 h = GNUNET_new (struct GCD_search_handle); 288 h = GNUNET_new (struct GCD_search_handle);
310 h->callback = callback;
311 h->cls = callback_cls;
312 h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */ 289 h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
313 GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */ 290 GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */
314 &phash, /* key to search */ 291 &phash, /* key to search */
diff --git a/src/cadet/gnunet-service-cadet-new_dht.h b/src/cadet/gnunet-service-cadet-new_dht.h
index ff3923790..81f16ae99 100644
--- a/src/cadet/gnunet-service-cadet-new_dht.h
+++ b/src/cadet/gnunet-service-cadet-new_dht.h
@@ -47,18 +47,6 @@ struct GCD_search_handle;
47 47
48 48
49/** 49/**
50 * Callback called on each path found over the DHT.
51 *
52 * @param cls Closure.
53 * @param path An unchecked, unoptimized path to the target node.
54 * After callback will no longer be valid, unless #GCPP_acquire() is called!
55 */
56typedef void
57(*GCD_search_callback) (void *cls,
58 struct CadetPeerPath *path);
59
60
61/**
62 * Initialize the DHT subsystem. 50 * Initialize the DHT subsystem.
63 * 51 *
64 * @param c Configuration. 52 * @param c Configuration.
@@ -66,6 +54,7 @@ typedef void
66void 54void
67GCD_init (const struct GNUNET_CONFIGURATION_Handle *c); 55GCD_init (const struct GNUNET_CONFIGURATION_Handle *c);
68 56
57
69/** 58/**
70 * Shut down the DHT subsystem. 59 * Shut down the DHT subsystem.
71 */ 60 */
@@ -77,14 +66,10 @@ GCD_shutdown (void);
77 * Search DHT for paths to @a peeR_id 66 * Search DHT for paths to @a peeR_id
78 * 67 *
79 * @param peer_id peer to search for 68 * @param peer_id peer to search for
80 * @param callback function to call with results
81 * @param callback_cls closure for @a callback
82 * @return handle to abort search 69 * @return handle to abort search
83 */ 70 */
84struct GCD_search_handle * 71struct GCD_search_handle *
85GCD_search (const struct GNUNET_PeerIdentity *peer_id, 72GCD_search (const struct GNUNET_PeerIdentity *peer_id);
86 GCD_search_callback callback,
87 void *callback_cls);
88 73
89 74
90/** 75/**
diff --git a/src/cadet/gnunet-service-cadet-new_paths.c b/src/cadet/gnunet-service-cadet-new_paths.c
index 005d8e807..96f32a87b 100644
--- a/src/cadet/gnunet-service-cadet-new_paths.c
+++ b/src/cadet/gnunet-service-cadet-new_paths.c
@@ -24,6 +24,10 @@
24 * @brief Information we track per path. 24 * @brief Information we track per path.
25 * @author Bartlomiej Polot 25 * @author Bartlomiej Polot
26 * @author Christian Grothoff 26 * @author Christian Grothoff
27 *
28 * TODO:
29 * - path desirability score calculations are not done
30 * (and will be tricky to have during path changes)
27 */ 31 */
28#include "platform.h" 32#include "platform.h"
29#include "gnunet-service-cadet-new_peer.h" 33#include "gnunet-service-cadet-new_peer.h"
@@ -69,7 +73,6 @@ struct CadetPeerPath
69}; 73};
70 74
71 75
72
73/** 76/**
74 * Return how much we like keeping the path. This is an aggregate 77 * Return how much we like keeping the path. This is an aggregate
75 * score based on various factors, including the age of the path 78 * score based on various factors, including the age of the path
@@ -86,27 +89,7 @@ struct CadetPeerPath
86GNUNET_CONTAINER_HeapCostType 89GNUNET_CONTAINER_HeapCostType
87GCPP_get_desirability (const struct CadetPeerPath *path) 90GCPP_get_desirability (const struct CadetPeerPath *path)
88{ 91{
89 GNUNET_break (0); 92 return path->desirability;
90 return 0;
91}
92
93
94/**
95 * The given peer @a cp used to own this @a path. However, it is no
96 * longer interested in maintaining it, so the path should be
97 * discarded or shortened (in case a previous peer on the path finds
98 * the path desirable).
99 *
100 * @param path the path that is being released
101 * @param node entry in the heap of @a cp where this path is anchored
102 * should be used for updates to the desirability of this path
103 */
104void
105GCPP_acquire (struct CadetPeerPath *path,
106 struct GNUNET_CONTAINER_HeapNode *node)
107{
108 GNUNET_assert (NULL == path->hn);
109 path->hn = node;
110} 93}
111 94
112 95
@@ -226,7 +209,8 @@ GCPP_release (struct CadetPeerPath *path)
226 /* see if new peer at the end likes this path any better */ 209 /* see if new peer at the end likes this path any better */
227 entry = &path->entries[path->entries_length - 1]; 210 entry = &path->entries[path->entries_length - 1];
228 path->hn = GCP_attach_path (entry->peer, 211 path->hn = GCP_attach_path (entry->peer,
229 path); 212 path,
213 path->entries_length);
230 if (NULL != path->hn) 214 if (NULL != path->hn)
231 return; /* yep, got attached, we are done. */ 215 return; /* yep, got attached, we are done. */
232 } 216 }
@@ -275,17 +259,109 @@ GCPP_update_score (struct CadetPeerPath *path,
275 259
276 260
277/** 261/**
278 * Create a peer path based on the result of a DHT lookup. 262 * Closure for #find_peer_at() and #check_match().
279 * If we already know this path, or one that is longer, 263 */
280 * simply return NULL. 264struct CheckMatchContext
265{
266
267 /**
268 * Set to a matching path, if any.
269 */
270 struct CadetPeerPath *match;
271
272 /**
273 * Array the combined paths.
274 */
275 struct CadetPeer **cpath;
276
277};
278
279
280/**
281 * Check if the given path is identical on all of the
282 * hops until @a off, and not longer than @a off. If the
283 * @a path matches, store it in `match`.
281 * 284 *
282 * FIXME: change API completely! 285 * @param cls the `struct CheckMatchContext` to check against
283 * Should in here create path transiently, then call 286 * @param path the path to check
284 * callback, and then do path destroy (if applicable) 287 * @param off offset to check at
285 * without returning in the middle. 288 * @return #GNUNET_YES (continue to iterate), or if found #GNUNET_NO
289 */
290static int
291check_match (void *cls,
292 struct CadetPeerPath *path,
293 unsigned int off)
294{
295 struct CheckMatchContext *cm_ctx = cls;
296
297 if (path->entries_length > off)
298 return GNUNET_YES; /* too long, cannot be useful */
299 for (unsigned int i=0;i<off;i++)
300 if (cm_ctx->cpath[i] !=
301 GCPP_get_peer_at_offset (path,
302 i))
303 return GNUNET_YES; /* missmatch, ignore */
304 cm_ctx->match = path;
305 return GNUNET_NO; /* match, we are done! */
306}
307
308
309/**
310 * Extend path @a path by the @a num_peers from the @a peers
311 * array, assuming the owners past the current owner want it.
286 * 312 *
287 * FIXME: also need to nicely handle case that this path 313 * @param path path to extend
288 * extends (lengthens!) an existing path. 314 * @param peers list of peers beyond the end of @a path
315 * @param num_peers length of the @a peers array
316 */
317static void
318extend_path (struct CadetPeerPath *path,
319 struct CadetPeer **peers,
320 unsigned int num_peers)
321{
322 unsigned int old_len = path->entries_length;
323 struct GNUNET_CONTAINER_HeapNode *hn;
324 int i;
325
326 /* If we extend an existing path, detach it from the
327 old owner and re-attach to the new one */
328 hn = NULL;
329 for (i=num_peers-1;i>=0;i--)
330 {
331 /* FIXME: note that path->desirability is used, but not yet updated here! */
332 hn = GCP_attach_path (peers[i],
333 path,
334 old_len + (unsigned int) i);
335 if (NULL != hn)
336 break;
337 }
338 if (NULL == hn)
339 return; /* none of the peers is interested in this path */
340 GCP_detach_path (path->entries[old_len-1].peer,
341 path,
342 path->hn);
343 path->hn = hn;
344 GNUNET_array_grow (path->entries,
345 path->entries_length,
346 old_len + i);
347 for (;i >= 0;i--)
348 {
349 struct CadetPeerPathEntry *entry = &path->entries[old_len + i];
350
351 entry->peer = peers[i];
352 entry->path = path;
353 GCP_path_entry_add (entry->peer,
354 entry,
355 old_len + i);
356 }
357}
358
359
360/**
361 * Create a peer path based on the result of a DHT lookup. If we
362 * already know this path, or one that is longer, simply return NULL.
363 * Otherwise, we try to extend an existing path, or create a new one
364 * if applicable.
289 * 365 *
290 * @param get_path path of the get request 366 * @param get_path path of the get request
291 * @param get_path_length lenght of @a get_path 367 * @param get_path_length lenght of @a get_path
@@ -293,47 +369,93 @@ GCPP_update_score (struct CadetPeerPath *path,
293 * @param put_path_length length of the @a put_path 369 * @param put_path_length length of the @a put_path
294 * @return a path through the network 370 * @return a path through the network
295 */ 371 */
296struct CadetPeerPath * 372void
297GCPP_path_from_dht (const struct GNUNET_PeerIdentity *get_path, 373GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path,
298 unsigned int get_path_length, 374 unsigned int get_path_length,
299 const struct GNUNET_PeerIdentity *put_path, 375 const struct GNUNET_PeerIdentity *put_path,
300 unsigned int put_path_length) 376 unsigned int put_path_length)
301{ 377{
378 struct CheckMatchContext cm_ctx;
379 struct CadetPeer *cpath[get_path_length + put_path_length];
302 struct CadetPeerPath *path; 380 struct CadetPeerPath *path;
381 struct GNUNET_CONTAINER_HeapNode *hn;
382 int i;
383
384 /* precompute 'cpath' so we can avoid doing the lookups lots of times */
385 for (unsigned int off=0;off<get_path_length + put_path_length;off++)
386 {
387 const struct GNUNET_PeerIdentity *pid;
388
389 pid = (off < get_path_length)
390 ? &get_path[get_path_length - off]
391 : &put_path[get_path_length + put_path_length - off];
392 cpath[off] = GCP_get (pid,
393 GNUNET_YES);
394 }
303 395
396 /* First figure out if this path is a subset of an existing path, an
397 extension of an existing path, or a new path. */
398 cm_ctx.cpath = cpath;
399 cm_ctx.match = NULL;
400 for (i=get_path_length + put_path_length-1;i>=0;i--)
401 {
402 GCP_iterate_paths_at (cpath[i],
403 (unsigned int) i,
404 &check_match,
405 &cm_ctx);
406 if (NULL != cm_ctx.match)
407 {
408 if (i == get_path_length + put_path_length - 1)
409 {
410 /* Existing path includes this one, nothing to do! */
411 return;
412 }
413 if (cm_ctx.match->entries_length == i + 1)
414 {
415 /* Existing path ends in the middle of new path, extend it! */
416 extend_path (cm_ctx.match,
417 &cpath[i],
418 get_path_length + put_path_length - i);
419 return;
420 }
421 }
422 }
423
424 /* No match at all, create completely new path */
304 path = GNUNET_new (struct CadetPeerPath); 425 path = GNUNET_new (struct CadetPeerPath);
305 path->entries_length = get_path_length + put_path_length; 426
427 /* First, try to attach it */
428 hn = NULL;
429 for (i=get_path_length + put_path_length-1;i>=0;i--)
430 {
431 path->entries_length = i;
432 /* FIXME: note that path->desirability is used, but not yet initialized here! */
433 hn = GCP_attach_path (cpath[i],
434 path,
435 (unsigned int) i);
436 if (NULL != hn)
437 break;
438 }
439 if (NULL == hn)
440 {
441 /* None of the peers on the path care about it. */
442 GNUNET_free (path);
443 return;
444 }
445 path->hn = hn;
446 path->entries_length = i;
306 path->entries = GNUNET_new_array (path->entries_length, 447 path->entries = GNUNET_new_array (path->entries_length,
307 struct CadetPeerPathEntry); 448 struct CadetPeerPathEntry);
308 for (unsigned int i=0;i<get_path_length + put_path_length;i++) 449 for (;i>=0;i--)
309 { 450 {
310 struct CadetPeerPathEntry *entry = &path->entries[i]; 451 struct CadetPeerPathEntry *entry = &path->entries[i];
311 const struct GNUNET_PeerIdentity *pid;
312 452
313 pid = (i < get_path_length) ? &get_path[get_path_length - i] : &put_path[path->entries_length - i]; 453 entry->peer = cpath[i];
314 entry->peer = GCP_get (pid,
315 GNUNET_YES);
316 entry->path = path; 454 entry->path = path;
317 GCP_path_entry_add (entry->peer, 455 GCP_path_entry_add (entry->peer,
318 entry, 456 entry,
319 i); 457 i);
320 } 458 }
321 GNUNET_break (0);
322 return NULL;
323}
324
325
326/**
327 * Destroy a path, we no longer need it.
328 *
329 * @param p path to destroy.
330 */
331void
332GCPP_path_destroy (struct CadetPeerPath *path)
333{
334 if (NULL != path->hn)
335 return; /* path was attached, to be kept! */
336 path_destroy (path);
337} 459}
338 460
339 461
diff --git a/src/cadet/gnunet-service-cadet-new_paths.h b/src/cadet/gnunet-service-cadet-new_paths.h
index 4b47784a0..f08d4a705 100644
--- a/src/cadet/gnunet-service-cadet-new_paths.h
+++ b/src/cadet/gnunet-service-cadet-new_paths.h
@@ -32,30 +32,21 @@
32#include "gnunet-service-cadet-new.h" 32#include "gnunet-service-cadet-new.h"
33 33
34/** 34/**
35 * Create a peer path based on the result of a DHT lookup. 35 * Create a peer path based on the result of a DHT lookup. If we
36 * If we already know this path, or one that is longer, 36 * already know this path, or one that is longer, simply return NULL.
37 * simply return NULL. 37 * Otherwise, we try to extend an existing path, or create a new one
38 * if applicable.
38 * 39 *
39 * @param get_path path of the get request 40 * @param get_path path of the get request
40 * @param get_path_length lenght of @a get_path 41 * @param get_path_length lenght of @a get_path
41 * @param put_path path of the put request 42 * @param put_path path of the put request
42 * @param put_path_length length of the @a put_path 43 * @param put_path_length length of the @a put_path
43 * @return a path through the network
44 */
45struct CadetPeerPath *
46GCPP_path_from_dht (const struct GNUNET_PeerIdentity *get_path,
47 unsigned int get_path_length,
48 const struct GNUNET_PeerIdentity *put_path,
49 unsigned int put_path_length);
50
51
52/**
53 * Destroy a path, we no longer need it.
54 *
55 * @param path path to destroy.
56 */ 44 */
57void 45void
58GCPP_path_destroy (struct CadetPeerPath *path); 46GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path,
47 unsigned int get_path_length,
48 const struct GNUNET_PeerIdentity *put_path,
49 unsigned int put_path_length);
59 50
60 51
61/** 52/**
@@ -149,21 +140,6 @@ GCPP_get_desirability (const struct CadetPeerPath *path);
149 * the path desirable). 140 * the path desirable).
150 * 141 *
151 * @param path the path that is being released 142 * @param path the path that is being released
152 * @param node entry in the heap of @a cp where this path is anchored
153 * should be used for updates to the desirability of this path
154 */
155void
156GCPP_acquire (struct CadetPeerPath *path,
157 struct GNUNET_CONTAINER_HeapNode *node);
158
159
160/**
161 * The given peer @a cp used to own this @a path. However, it is no
162 * longer interested in maintaining it, so the path should be
163 * discarded or shortened (in case a previous peer on the path finds
164 * the path desirable).
165 *
166 * @param path the path that is being released
167 */ 143 */
168void 144void
169GCPP_release (struct CadetPeerPath *path); 145GCPP_release (struct CadetPeerPath *path);
diff --git a/src/cadet/gnunet-service-cadet-new_peer.c b/src/cadet/gnunet-service-cadet-new_peer.c
index 8c8b23820..9878c540e 100644
--- a/src/cadet/gnunet-service-cadet-new_peer.c
+++ b/src/cadet/gnunet-service-cadet-new_peer.c
@@ -385,19 +385,22 @@ GCP_path_entry_remove (struct CadetPeer *cp,
385 * has plenty of paths, return NULL. 385 * has plenty of paths, return NULL.
386 * 386 *
387 * @param cp peer to which the @a path leads to 387 * @param cp peer to which the @a path leads to
388 * @param path a path looking for an owner 388 * @param path a path looking for an owner; may not be fully initialized yet!
389 * @param off offset of @a cp in @a path
389 * @return NULL if this peer does not care to become a new owner, 390 * @return NULL if this peer does not care to become a new owner,
390 * otherwise the node in the peer's path heap for the @a path. 391 * otherwise the node in the peer's path heap for the @a path.
391 */ 392 */
392struct GNUNET_CONTAINER_HeapNode * 393struct GNUNET_CONTAINER_HeapNode *
393GCP_attach_path (struct CadetPeer *cp, 394GCP_attach_path (struct CadetPeer *cp,
394 struct CadetPeerPath *path) 395 struct CadetPeerPath *path,
396 unsigned int off)
395{ 397{
396 GNUNET_CONTAINER_HeapCostType desirability; 398 GNUNET_CONTAINER_HeapCostType desirability;
397 struct CadetPeerPath *root; 399 struct CadetPeerPath *root;
398 GNUNET_CONTAINER_HeapCostType root_desirability; 400 GNUNET_CONTAINER_HeapCostType root_desirability;
399 struct GNUNET_CONTAINER_HeapNode *hn; 401 struct GNUNET_CONTAINER_HeapNode *hn;
400 402
403 /* FIXME: desirability is not yet initialized; tricky! */
401 desirability = GCPP_get_desirability (path); 404 desirability = GCPP_get_desirability (path);
402 if (GNUNET_NO == 405 if (GNUNET_NO ==
403 GNUNET_CONTAINER_heap_peek2 (cp->path_heap, 406 GNUNET_CONTAINER_heap_peek2 (cp->path_heap,
@@ -443,24 +446,21 @@ GCP_attach_path (struct CadetPeer *cp,
443 446
444 447
445/** 448/**
446 * Function called when the DHT finds a @a path to the peer (@a cls). 449 * This peer can no longer own @a path as the path
450 * has been extended and a peer further down the line
451 * is now the new owner.
447 * 452 *
448 * @param cls the `struct CadetPeer` 453 * @param cp old owner of the @a path
449 * @param path the path that was found 454 * @param path path where the ownership is lost
455 * @param hn note in @a cp's path heap that must be deleted
450 */ 456 */
451static void 457void
452dht_result_cb (void *cls, 458GCP_detach_path (struct CadetPeer *cp,
453 struct CadetPeerPath *path) 459 struct CadetPeerPath *path,
460 struct GNUNET_CONTAINER_HeapNode *hn)
454{ 461{
455 struct CadetPeer *cp = cls; 462 GNUNET_assert (path ==
456 struct GNUNET_CONTAINER_HeapNode *hn; 463 GNUNET_CONTAINER_heap_remove_node (hn));
457
458 hn = GCP_attach_path (cp,
459 path);
460 if (NULL == hn)
461 return;
462 GCPP_acquire (path,
463 hn);
464} 464}
465 465
466 466
@@ -502,9 +502,7 @@ consider_peer_activate (struct CadetPeer *cp)
502 if ( (NULL == cp->search_h) && 502 if ( (NULL == cp->search_h) &&
503 (DESIRED_CONNECTIONS_PER_TUNNEL < cp->num_paths) ) 503 (DESIRED_CONNECTIONS_PER_TUNNEL < cp->num_paths) )
504 cp->search_h 504 cp->search_h
505 = GCD_search (&cp->pid, 505 = GCD_search (&cp->pid);
506 &dht_result_cb,
507 cp);
508 } 506 }
509 else 507 else
510 { 508 {
@@ -640,6 +638,41 @@ GCP_iterate_paths (struct CadetPeer *peer,
640 638
641 639
642/** 640/**
641 * Iterate over the paths to @a peer where
642 * @a peer is at distance @a dist from us.
643 *
644 * @param peer Peer to get path info.
645 * @param dist desired distance of @a peer to us on the path
646 * @param callback Function to call for every path.
647 * @param callback_cls Closure for @a callback.
648 * @return Number of iterated paths.
649 */
650unsigned int
651GCP_iterate_paths_at (struct CadetPeer *peer,
652 unsigned int dist,
653 GCP_PathIterator callback,
654 void *callback_cls)
655{
656 unsigned int ret = 0;
657
658 if (dist<peer->path_dll_length)
659 return 0;
660 for (struct CadetPeerPathEntry *pe = peer->path_heads[dist];
661 NULL != pe;
662 pe = pe->next)
663 {
664 if (GNUNET_NO ==
665 callback (callback_cls,
666 pe->path,
667 dist))
668 return ret;
669 ret++;
670 }
671 return ret;
672}
673
674
675/**
643 * Get the tunnel towards a peer. 676 * Get the tunnel towards a peer.
644 * 677 *
645 * @param peer Peer to get from. 678 * @param peer Peer to get from.
diff --git a/src/cadet/gnunet-service-cadet-new_peer.h b/src/cadet/gnunet-service-cadet-new_peer.h
index e1c8476d1..780640674 100644
--- a/src/cadet/gnunet-service-cadet-new_peer.h
+++ b/src/cadet/gnunet-service-cadet-new_peer.h
@@ -120,6 +120,23 @@ GCP_iterate_paths (struct CadetPeer *cp,
120 120
121 121
122/** 122/**
123 * Iterate over the paths to @a peer where
124 * @a peer is at distance @a dist from us.
125 *
126 * @param peer Peer to get path info.
127 * @param dist desired distance of @a peer to us on the path
128 * @param callback Function to call for every path.
129 * @param callback_cls Closure for @a callback.
130 * @return Number of iterated paths.
131 */
132unsigned int
133GCP_iterate_paths_at (struct CadetPeer *peer,
134 unsigned int dist,
135 GCP_PathIterator callback,
136 void *callback_cls);
137
138
139/**
123 * Remove an entry from the DLL of all of the paths that this peer is on. 140 * Remove an entry from the DLL of all of the paths that this peer is on.
124 * 141 *
125 * @param cp peer to modify 142 * @param cp peer to modify
@@ -174,13 +191,30 @@ GCP_drop_tunnel (struct CadetPeer *cp,
174 * has plenty of paths, return NULL. 191 * has plenty of paths, return NULL.
175 * 192 *
176 * @param cp peer to which the @a path leads to 193 * @param cp peer to which the @a path leads to
177 * @param path a path looking for an owner 194 * @param path a path looking for an owner; may not be fully initialized yet!
195 * @param off offset of @a cp in @a path
178 * @return NULL if this peer does not care to become a new owner, 196 * @return NULL if this peer does not care to become a new owner,
179 * otherwise the node in the peer's path heap for the @a path. 197 * otherwise the node in the peer's path heap for the @a path.
180 */ 198 */
181struct GNUNET_CONTAINER_HeapNode * 199struct GNUNET_CONTAINER_HeapNode *
182GCP_attach_path (struct CadetPeer *cp, 200GCP_attach_path (struct CadetPeer *cp,
183 struct CadetPeerPath *path); 201 struct CadetPeerPath *path,
202 unsigned int off);
203
204
205/**
206 * This peer can no longer own @a path as the path
207 * has been extended and a peer further down the line
208 * is now the new owner.
209 *
210 * @param cp old owner of the @a path
211 * @param path path where the ownership is lost
212 * @param hn note in @a cp's path heap that must be deleted
213 */
214void
215GCP_detach_path (struct CadetPeer *cp,
216 struct CadetPeerPath *path,
217 struct GNUNET_CONTAINER_HeapNode *hn);
184 218
185 219
186/** 220/**