GNUnet 0.27.0
 
Loading...
Searching...
No Matches
gnunet-service-cadet_paths.c File Reference

Information we track per path. More...

Include dependency graph for gnunet-service-cadet_paths.c:

Go to the source code of this file.

Data Structures

struct  CadetPeerPath
 Information regarding a possible path to reach a peer. More...
 
struct  CheckMatchContext
 Closure for #find_peer_at() and check_match(). More...
 

Macros

#define LOG(level, ...)   GNUNET_log_from (level, "cadet-pat", __VA_ARGS__)
 

Functions

static void recalculate_path_desirability (struct CadetPeerPath *path)
 Calculate the path's desirability score.
 
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability (const struct CadetPeerPath *path)
 Return how much we like keeping the path.
 
struct CadetConnectionGCPP_get_connection (struct CadetPeerPath *path, struct CadetPeer *destination, unsigned int off)
 Return connection to destination using path, or return NULL if no such connection exists.
 
void GCPP_add_connection (struct CadetPeerPath *path, unsigned int off, struct CadetConnection *cc)
 Notify path that it is used for connection cc which ends at the path's offset off.
 
void GCPP_del_connection (struct CadetPeerPath *path, unsigned int off, struct CadetConnection *cc)
 Notify path that it is no longer used for connection cc which ended at the path's offset off.
 
static void attach_path (struct CadetPeerPath *path, unsigned int stop_at)
 Tries to attach path to a peer, working backwards from the end and stopping at stop_at.
 
void GCPP_release (struct CadetPeerPath *path)
 The owning peer of this path is no longer interested in maintaining it, so the path should be discarded or shortened (in case a previous peer on the path finds the path desirable).
 
static void GCPP_update_score (struct CadetPeerPath *path, unsigned int off, int delta)
 Updates the score for an entry on the path based on our experiences with using path.
 
static int check_match (void *cls, struct CadetPeerPath *path, unsigned int off)
 Check if the given path is identical on all of the hops until off, and not longer than off.
 
static void extend_path (struct CadetPeerPath *path, struct CadetPeer **peers_ext, unsigned int num_peers, int force)
 Extend path path by the num_peers from the peers array, assuming the owners past the current owner want it.
 
void GCPP_try_path_from_dht (const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length)
 Create a peer path based on the result of a DHT lookup.
 
struct CadetPeerPathGCPP_get_path_from_route (unsigned int path_length, const struct GNUNET_PeerIdentity *pids)
 We got an incoming connection, obtain the corresponding path.
 
unsigned int GCPP_get_length (struct CadetPeerPath *path)
 Return the length of the path.
 
unsigned int GCPP_find_peer (struct CadetPeerPath *path, struct CadetPeer *cp)
 Find peer's offset on path.
 
struct CadetPeerGCPP_get_peer_at_offset (struct CadetPeerPath *path, unsigned int off)
 Obtain the peer at offset off in path.
 
const char * GCPP_2s (struct CadetPeerPath *path)
 Convert a path to a human-readable string.
 

Detailed Description

Information we track per path.

Author
Bartlomiej Polot
Christian Grothoff

Definition in file gnunet-service-cadet_paths.c.

Macro Definition Documentation

◆ LOG

#define LOG (   level,
  ... 
)    GNUNET_log_from (level, "cadet-pat", __VA_ARGS__)

Definition at line 34 of file gnunet-service-cadet_paths.c.

Function Documentation

◆ recalculate_path_desirability()

static void recalculate_path_desirability ( struct CadetPeerPath path)
static

Calculate the path's desirability score.

Parameters
pathpath to calculate the score for

Definition at line 73 of file gnunet-service-cadet_paths.c.

74{
75 double result = 0.0;
76
77 for (unsigned int i = 0; i < path->entries_length; i++)
78 {
79 struct CadetPeer *cp = path->entries[i]->peer;
80
82 i);
83 }
85}
static int result
Global testing status.
double GCP_get_desirability_of_path(struct CadetPeer *cp, unsigned int off)
Calculate how desirable a path is for cp if cp is at offset off in the path.
uint64_t GNUNET_CONTAINER_HeapCostType
Cost by which elements in a heap can be ordered.
struct CadetPeer * peer
The peer at this offset of the path.
unsigned int entries_length
Length of the entries array.
struct CadetPeerPathEntry ** entries
Array of all the peers on the path.
GNUNET_CONTAINER_HeapCostType desirability
Desirability of the path.
Struct containing all information regarding a given peer.

References CadetPeerPath::desirability, CadetPeerPath::entries, CadetPeerPath::entries_length, GCP_get_desirability_of_path(), CadetPeerPathEntry::peer, and result.

Referenced by attach_path(), GCPP_get_path_from_route(), and GCPP_update_score().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCPP_get_desirability()

GNUNET_CONTAINER_HeapCostType GCPP_get_desirability ( const struct CadetPeerPath path)

Return how much we like keeping the path.

This is an aggregate score based on various factors, including the age of the path (older == better), and the value of this path to all of its adjacent peers. For example, long paths that end at a peer that we have no shorter way to reach are very desirable, while long paths that end at a peer for which we have a shorter way as well are much less desirable. Higher values indicate more valuable paths. The returned value should be used to decide which paths to remember.

Parameters
pathpath to return the length for
Returns
desirability of the path, larger is more desirable

Definition at line 102 of file gnunet-service-cadet_paths.c.

103{
104 return path->desirability;
105}

References CadetPeerPath::desirability.

Referenced by consider_path_cb(), evaluate_connection(), and GCP_attach_path().

Here is the caller graph for this function:

◆ GCPP_get_connection()

struct CadetConnection * GCPP_get_connection ( struct CadetPeerPath path,
struct CadetPeer destination,
unsigned int  off 
)

Return connection to destination using path, or return NULL if no such connection exists.

Parameters
pathpath to traverse
destinationdestination node to get to, must be on path
offoffset of destination on path
Returns
NULL if we have no existing connection otherwise connection from us to destination via path

Definition at line 119 of file gnunet-service-cadet_paths.c.

122{
123 struct CadetPeerPathEntry *entry;
124
125 GNUNET_assert (off < path->entries_length);
126 entry = path->entries[off];
127 GNUNET_assert (entry->peer == destination);
128 return entry->cc;
129}
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Entry in a peer path.
struct CadetConnection * cc
Connection using this path, or NULL for none.
struct CadetPeerPath * path
Path this entry belongs to.

References CadetPeerPathEntry::cc, CadetPeerPath::entries, GNUNET_assert, CadetPeerPathEntry::path, and CadetPeerPathEntry::peer.

Referenced by GCC_create_inbound(), and path_heap_cleanup().

Here is the caller graph for this function:

◆ GCPP_add_connection()

void GCPP_add_connection ( struct CadetPeerPath path,
unsigned int  off,
struct CadetConnection cc 
)

Notify path that it is used for connection cc which ends at the path's offset off.

Parameters
paththe path to remember the cc
offthe offset where the cc ends
ccthe connection to remember

Definition at line 141 of file gnunet-service-cadet_paths.c.

144{
145 struct CadetPeerPathEntry *entry;
146
148 "Adding %s to path %s at offset %u\n",
149 GCC_2s (cc),
150 GCPP_2s (path),
151 off);
152 GNUNET_assert (off < path->entries_length);
153 entry = path->entries[off];
154 GNUNET_assert (NULL == entry->cc);
155 GNUNET_assert (NULL != cc);
156 entry->cc = cc;
157}
const char * GCC_2s(const struct CadetConnection *cc)
Get a (static) string for a connection.
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
#define LOG(level,...)
@ GNUNET_ERROR_TYPE_DEBUG

References CadetPeerPathEntry::cc, CadetPeerPath::entries, GCC_2s(), GCPP_2s(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, LOG, and CadetPeerPathEntry::path.

Referenced by connection_create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCPP_del_connection()

void GCPP_del_connection ( struct CadetPeerPath path,
unsigned int  off,
struct CadetConnection cc 
)

Notify path that it is no longer used for connection cc which ended at the path's offset off.

Parameters
paththe path to forget the cc
offthe offset where the cc ended
ccthe connection to forget

Definition at line 169 of file gnunet-service-cadet_paths.c.

172{
173 struct CadetPeerPathEntry *entry;
174
176 "Removing connection %s to path %s at offset %u\n",
177 GCC_2s (cc),
178 GCPP_2s (path),
179 off);
180 GNUNET_assert (off < path->entries_length);
181 entry = path->entries[off];
182 GNUNET_assert (cc == entry->cc);
183 entry->cc = NULL;
184}

References CadetPeerPathEntry::cc, CadetPeerPath::entries, GCC_2s(), GCPP_2s(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, LOG, and CadetPeerPathEntry::path.

Referenced by GCC_destroy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ attach_path()

static void attach_path ( struct CadetPeerPath path,
unsigned int  stop_at 
)
static

Tries to attach path to a peer, working backwards from the end and stopping at stop_at.

If path->hn is NULL on return then the path was not attached and you can assume that path->entries_length is equal to stop_at.

Parameters
paththe path to attach
stop_atthe path length at which to stop trying

Definition at line 197 of file gnunet-service-cadet_paths.c.

198{
199 GNUNET_assert (NULL == path->hn);
200
201 /* Try to attach this path to a peer, working backwards from the end. */
202 while (path->entries_length > stop_at)
203 {
204 unsigned int end = path->entries_length - 1;
205 struct CadetPeerPathEntry *entry = path->entries[end];
206 int force = GNUNET_NO;
207
209 /* If the entry already has a connection using it, force attach. */
210 if (NULL != entry->cc)
211 force = GNUNET_YES;
212 path->hn = GCP_attach_path (entry->peer,
213 path,
214 end,
215 force);
216 if (NULL != path->hn)
217 break;
218
219 /* Attach failed, trim this entry from the path. */
220 GNUNET_assert (NULL == entry->cc);
222 entry,
223 end);
224 GNUNET_free (entry);
225 path->entries[end] = NULL;
227 }
228
229 /* Shrink array to actual path length. */
233}
static int end
Set if we are to shutdown all services (including ARM).
Definition gnunet-arm.c:33
static void recalculate_path_desirability(struct CadetPeerPath *path)
Calculate the path's desirability score.
void GCP_path_entry_remove(struct CadetPeer *cp, struct CadetPeerPathEntry *entry, unsigned int off)
Remove an entry from the DLL of all of the paths that this peer is on.
struct GNUNET_CONTAINER_HeapNode * GCP_attach_path(struct CadetPeer *cp, struct CadetPeerPath *path, unsigned int off, int force)
Try adding a path to this cp.
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CONTAINER_HeapNode * hn
Node of this path in the owner's heap.

References CadetPeerPathEntry::cc, end, CadetPeerPath::entries, CadetPeerPath::entries_length, GCP_attach_path(), GCP_path_entry_remove(), GNUNET_array_grow, GNUNET_assert, GNUNET_free, GNUNET_NO, GNUNET_YES, CadetPeerPath::hn, CadetPeerPathEntry::path, CadetPeerPathEntry::peer, and recalculate_path_desirability().

Referenced by extend_path(), GCPP_release(), and GCPP_try_path_from_dht().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCPP_release()

void GCPP_release ( struct CadetPeerPath path)

The owning peer of this path is no longer interested in maintaining it, so the path should be discarded or shortened (in case a previous peer on the path finds the path desirable).

The given peer cp used to own this path.

Parameters
paththe path that is being released

Definition at line 244 of file gnunet-service-cadet_paths.c.

245{
246 struct CadetPeerPathEntry *entry;
247
249 "Owner releases path %s\n",
250 GCPP_2s (path));
251 path->hn = NULL;
252 entry = path->entries[path->entries_length - 1];
253 GNUNET_assert (path == entry->path);
254 GNUNET_assert (NULL == entry->cc);
255 /* cut 'off' end of path */
257 entry,
258 path->entries_length - 1);
259 GNUNET_free (entry);
260 path->entries[path->entries_length - 1] = NULL;
262 /* see if new peer at the end likes this path any better */
263 attach_path (path, 0);
264 if (NULL == path->hn)
265 {
266 /* nobody wants us, discard the path */
268 GNUNET_assert (NULL == path->entries);
270 }
271}
static void attach_path(struct CadetPeerPath *path, unsigned int stop_at)
Tries to attach path to a peer, working backwards from the end and stopping at stop_at.

References attach_path(), CadetPeerPathEntry::cc, CadetPeerPath::entries, CadetPeerPath::entries_length, GCP_path_entry_remove(), GCPP_2s(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, CadetPeerPath::hn, LOG, CadetPeerPathEntry::path, and CadetPeerPathEntry::peer.

Referenced by drop_paths(), GCP_drop_owned_paths(), and path_heap_cleanup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCPP_update_score()

static void GCPP_update_score ( struct CadetPeerPath path,
unsigned int  off,
int  delta 
)
static

Updates the score for an entry on the path based on our experiences with using path.

Parameters
paththe path to update
offoffset of the entry to update
deltachange in the score to apply

Definition at line 283 of file gnunet-service-cadet_paths.c.

286{
287 struct CadetPeerPathEntry *entry;
288
289 GNUNET_assert (off < path->entries_length);
290 entry = path->entries[off];
291
292 /* Add delta, with checks for overflows */
293 if (delta >= 0)
294 {
295 if (delta + entry->score < entry->score)
296 entry->score = INT_MAX;
297 else
298 entry->score += delta;
299 }
300 else
301 {
302 if (delta + entry->score > entry->score)
303 entry->score = INT_MIN;
304 else
305 entry->score += delta;
306 }
308}
#define INT_MAX
static struct GNUNET_TIME_Relative delta
Definition speedup.c:36
int score
Path's historic score up to this point.

References delta, CadetPeerPath::entries, GNUNET_assert, INT_MAX, CadetPeerPathEntry::path, recalculate_path_desirability(), and CadetPeerPathEntry::score.

Here is the call graph for this function:

◆ check_match()

static int check_match ( void *  cls,
struct CadetPeerPath path,
unsigned int  off 
)
static

Check if the given path is identical on all of the hops until off, and not longer than off.

If the path matches, store it in match.

Parameters
clsthe struct CheckMatchContext to check against
paththe path to check
offoffset to check at
Returns
GNUNET_YES (continue to iterate), or if found GNUNET_NO

Definition at line 344 of file gnunet-service-cadet_paths.c.

347{
348 struct CheckMatchContext *cm_ctx = cls;
349
350 GNUNET_assert (path->entries_length > off);
351 if ((path->entries_length != off + 1) &&
352 (off + 1 != cm_ctx->cpath_length))
353 {
355 "check_match mismatch because path %s is too long (%u vs. %u vs. %u)\n",
356 GCPP_2s (path),
357 path->entries_length,
358 off + 1,
359 cm_ctx->cpath_length);
360 return GNUNET_YES; /* too long, goes somewhere else already, thus cannot be useful */
361 }
362 for (unsigned int i = 0; i < off; i++)
363 if (cm_ctx->cpath[i] !=
365 i))
366 {
368 "check_match path %s mismatches at offset %u\n",
369 GCPP_2s (path),
370 i);
371 return GNUNET_YES; /* mismatch, ignore */
372 }
374 "check_match found match with path %s\n",
375 GCPP_2s (path));
376 cm_ctx->match = path;
377 return GNUNET_NO; /* match, we are done! */
378}
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
Closure for #find_peer_at() and check_match().
struct CadetPeerPath * match
Set to a matching path, if any.
unsigned int cpath_length
How long is the cpath array?
struct CadetPeer ** cpath
Array the combined paths.

References CheckMatchContext::cpath, CheckMatchContext::cpath_length, CadetPeerPath::entries_length, GCPP_2s(), GCPP_get_peer_at_offset(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_YES, LOG, and CheckMatchContext::match.

Referenced by GCPP_get_path_from_route(), and GCPP_try_path_from_dht().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extend_path()

static void extend_path ( struct CadetPeerPath path,
struct CadetPeer **  peers_ext,
unsigned int  num_peers,
int  force 
)
static

Extend path path by the num_peers from the peers array, assuming the owners past the current owner want it.

Parameters
pathpath to extend
peerslist of peers beyond the end of path
num_peerslength of the peers array
forceforce attachment, even if we have other paths already

Definition at line 392 of file gnunet-service-cadet_paths.c.

396{
397 unsigned int old_len = path->entries_length;
398 int i;
399
400 /* Expand path */
402 path->entries_length,
403 old_len + num_peers);
404 for (i = num_peers - 1; i >= 0; i--)
405 {
406 struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry);
407
408 path->entries[old_len + i] = entry;
409 entry->peer = peers_ext[i];
410 entry->path = path;
411 }
412 for (i = num_peers - 1; i >= 0; i--)
413 {
414 struct CadetPeerPathEntry *entry = path->entries[old_len + i];
415
416 GCP_path_entry_add (entry->peer,
417 entry,
418 old_len + i);
419 }
420
421 /* If we extend an existing path, detach it from the
422 old owner and re-attach to the new one */
423 GCP_detach_path (path->entries[old_len - 1]->peer,
424 path,
425 path->hn);
426 path->hn = NULL;
427 path->entries_length = old_len + num_peers;
428 if (GNUNET_YES == force)
429 {
430 int end = path->entries_length - 1;
431
433 path,
434 end,
435 GNUNET_YES);
436 }
437 else
438 {
439 attach_path (path, old_len);
440 }
441 if (NULL == path->hn)
442 {
443 /* none of the peers is interested in this path;
444 re-attach. */
445 GNUNET_assert (old_len == path->entries_length);
446 path->hn = GCP_attach_path (path->entries[old_len - 1]->peer,
447 path,
448 old_len - 1,
449 GNUNET_YES);
450 GNUNET_assert (NULL != path->hn);
451 return;
452 }
454 "Extended path %s\n",
455 GCPP_2s (path));
456}
void GCP_detach_path(struct CadetPeer *cp, struct CadetPeerPath *path, struct GNUNET_CONTAINER_HeapNode *hn)
This peer can no longer own path as the path has been extended and a peer further down the line is no...
void GCP_path_entry_add(struct CadetPeer *cp, struct CadetPeerPathEntry *entry, unsigned int off)
Add an entry to the DLL of all of the paths that this peer is on.
static unsigned int num_peers
Number of peers.
#define GNUNET_new(type)
Allocate a struct or union of the given type.

References attach_path(), end, CadetPeerPath::entries, CadetPeerPath::entries_length, GCP_attach_path(), GCP_detach_path(), GCP_path_entry_add(), GCPP_2s(), GNUNET_array_grow, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_new, GNUNET_YES, CadetPeerPath::hn, LOG, num_peers, CadetPeerPathEntry::path, and CadetPeerPathEntry::peer.

Referenced by GCPP_get_path_from_route(), and GCPP_try_path_from_dht().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCPP_try_path_from_dht()

void GCPP_try_path_from_dht ( const struct GNUNET_DHT_PathElement get_path,
unsigned int  get_path_length,
const struct GNUNET_DHT_PathElement put_path,
unsigned int  put_path_length 
)

Create a peer path based on the result of a DHT lookup.

If we already know this path, or one that is longer, simply return NULL. Otherwise, we try to extend an existing path, or create a new one if applicable.

Parameters
get_pathpath of the get request
get_path_lengthlength of get_path
put_pathpath of the put request
put_path_lengthlength of the put_path
Returns
a path through the network

Definition at line 472 of file gnunet-service-cadet_paths.c.

476{
477 const struct GNUNET_PeerIdentity *my_identity;
478 struct CadetPeer *cpath[get_path_length + put_path_length];
479 struct CheckMatchContext cm_ctx;
480 struct CadetPeerPath *path;
481 unsigned int skip;
482 unsigned int total_len;
483
485
486 /* precompute 'cpath' so we can avoid doing the lookups lots of times */
487 skip = 0;
488 memset (cpath,
489 0,
490 sizeof(cpath)); /* Just to trigger harder errors later. */
491 total_len = get_path_length + put_path_length;
492 for (unsigned int off = 0; off < total_len; off++)
493 {
494 const struct GNUNET_PeerIdentity *pid;
495
496 pid = (off < get_path_length)
497 ? &get_path[get_path_length - off - 1].pred
498 : &put_path[get_path_length + put_path_length - off - 1].pred;
499 /* Check that I am not in the path */
500 if (0 == GNUNET_memcmp (my_identity, pid))
501 {
502 skip = off + 1;
503 continue;
504 }
505 cpath[off - skip] = GCP_get (pid,
506 GNUNET_YES);
507 /* Check that no peer is twice on the path */
508 for (unsigned int i = 0; i < off - skip; i++)
509 {
510 if (cpath[i] == cpath[off - skip])
511 {
512 skip = off - i;
513 break;
514 }
515 }
516 }
517 if (skip >= total_len)
518 {
520 "Path discovered from DHT is one big cycle?\n");
521 return;
522 }
523 total_len -= skip;
524
525 /* First figure out if this path is a subset of an existing path, an
526 extension of an existing path, or a new path. */
527 cm_ctx.cpath_length = total_len;
528 cm_ctx.cpath = cpath;
529 cm_ctx.match = NULL;
530 for (int i = total_len - 1; i >= 0; i--)
531 {
532 GCP_iterate_paths_at (cpath[i],
533 (unsigned int) i,
535 &cm_ctx);
536 if (NULL != cm_ctx.match)
537 {
538 if (i == total_len - 1)
539 {
540 /* Existing path includes this one, nothing to do! */
542 "Path discovered from DHT is already known\n");
543 return;
544 }
545 if (cm_ctx.match->entries_length == i + 1)
546 {
547 /* Existing path ends in the middle of new path, extend it! */
549 "Trying to extend existing path %s by additional links discovered from DHT\n",
550 GCPP_2s (cm_ctx.match));
551 extend_path (cm_ctx.match,
552 &cpath[i + 1],
553 total_len - i - 1,
554 GNUNET_NO);
555 return;
556 }
557 }
558 }
559
560 /* No match at all, create completely new path */
561 path = GNUNET_new (struct CadetPeerPath);
562 path->entries_length = total_len;
564 struct CadetPeerPathEntry *);
565 for (int i = path->entries_length - 1; i >= 0; i--)
566 {
567 struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry);
568
569 path->entries[i] = entry;
570 entry->peer = cpath[i];
571 entry->path = path;
572 }
573 for (int i = path->entries_length - 1; i >= 0; i--)
574 {
575 struct CadetPeerPathEntry *entry = path->entries[i];
576
577 GCP_path_entry_add (entry->peer,
578 entry,
579 i);
580 }
581
582 /* Finally, try to attach it */
583 attach_path (path, 0);
584 if (NULL == path->hn)
585 {
586 /* None of the peers on the path care about it. */
588 "Path discovered from DHT is not interesting to us\n");
590 GNUNET_assert (NULL == path->entries);
592 return;
593 }
595 "Created new path %s based on information from DHT\n",
596 GCPP_2s (path));
597}
static struct GNUNET_PILS_Handle * pils
Handle to PILS.
Definition gnunet-pils.c:44
static int check_match(void *cls, struct CadetPeerPath *path, unsigned int off)
Check if the given path is identical on all of the hops until off, and not longer than off.
static void extend_path(struct CadetPeerPath *path, struct CadetPeer **peers_ext, unsigned int num_peers, int force)
Extend path path by the num_peers from the peers array, assuming the owners past the current owner wa...
struct CadetPeer * GCP_get(const struct GNUNET_PeerIdentity *peer_id, int create)
Retrieve the CadetPeer structure associated with the peer.
unsigned int GCP_iterate_paths_at(struct CadetPeer *cp, unsigned int dist, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to peer where peer is at distance dist from us.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
Information regarding a possible path to reach a peer.
The identity of the host (wraps the signing key of the peer).

References attach_path(), check_match(), CheckMatchContext::cpath, CheckMatchContext::cpath_length, CadetPeerPath::entries, CadetPeerPath::entries_length, extend_path(), GCP_get(), GCP_iterate_paths_at(), GCP_path_entry_add(), GCPP_2s(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_memcmp, GNUNET_new, GNUNET_new_array, GNUNET_NO, GNUNET_PILS_get_identity(), GNUNET_YES, CadetPeerPath::hn, LOG, CheckMatchContext::match, my_identity, CadetPeerPathEntry::path, CadetPeerPathEntry::peer, pid, pils, and GNUNET_DHT_PathElement::pred.

Referenced by dht_get_id_handler().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCPP_get_path_from_route()

struct CadetPeerPath * GCPP_get_path_from_route ( unsigned int  path_length,
const struct GNUNET_PeerIdentity pids 
)

We got an incoming connection, obtain the corresponding path.

Parameters
path_lengthnumber of segments on the path
pidspath through the network, in reverse order (we are at the end, at index path_length)
Returns
corresponding path object

Definition at line 601 of file gnunet-service-cadet_paths.c.

603{
604 struct CheckMatchContext cm_ctx;
605 struct CadetPeer *cpath[path_length];
606 struct CadetPeerPath *path;
607
608 /* precompute inverted 'cpath' so we can avoid doing the lookups and
609 have the correct order */
610 for (unsigned int off = 0; off < path_length; off++)
611 cpath[off] = GCP_get (&pids[path_length - 1 - off],
612 GNUNET_YES);
613
614 /* First figure out if this path is a subset of an existing path, an
615 extension of an existing path, or a new path. */
616 cm_ctx.cpath = cpath;
617 cm_ctx.cpath_length = path_length;
618 cm_ctx.match = NULL;
619 for (int i = path_length - 1; i >= 0; i--)
620 {
621 GCP_iterate_paths_at (cpath[i],
622 (unsigned int) i,
624 &cm_ctx);
625 if (NULL != cm_ctx.match)
626 {
627 if (i == path_length - 1)
628 {
629 /* Existing path includes this one, return the match! */
631 "Returning existing path %s as inverse for incoming connection\n",
632 GCPP_2s (cm_ctx.match));
633 return cm_ctx.match;
634 }
635 if (cm_ctx.match->entries_length == i + 1)
636 {
637 /* Existing path ends in the middle of new path, extend it! */
639 "Extending existing path %s to create inverse for incoming connection\n",
640 GCPP_2s (cm_ctx.match));
641 extend_path (cm_ctx.match,
642 &cpath[i + 1],
643 path_length - i - 1,
644 GNUNET_YES);
645 /* Check that extension was successful */
646 GNUNET_assert (cm_ctx.match->entries_length == path_length);
647 return cm_ctx.match;
648 }
649 /* Eh, we found a match but couldn't use it? Something is wrong. */
650 GNUNET_break (0);
651 }
652 }
653
654 /* No match at all, create completely new path */
655 path = GNUNET_new (struct CadetPeerPath);
656 path->entries_length = path_length;
658 struct CadetPeerPathEntry *);
659 for (int i = path_length - 1; i >= 0; i--)
660 {
661 struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry);
662
663 path->entries[i] = entry;
664 entry->peer = cpath[i];
665 entry->path = path;
666 }
667 for (int i = path_length - 1; i >= 0; i--)
668 {
669 struct CadetPeerPathEntry *entry = path->entries[i];
670
671 GCP_path_entry_add (entry->peer,
672 entry,
673 i);
674 }
677 "Created new path %s to create inverse for incoming connection\n",
678 GCPP_2s (path));
679 path->hn = GCP_attach_path (cpath[path_length - 1],
680 path,
681 path_length - 1,
682 GNUNET_YES);
683 return path;
684}
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.

References check_match(), CheckMatchContext::cpath, CheckMatchContext::cpath_length, CadetPeerPath::entries, CadetPeerPath::entries_length, extend_path(), GCP_attach_path(), GCP_get(), GCP_iterate_paths_at(), GCP_path_entry_add(), GCPP_2s(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_new, GNUNET_new_array, GNUNET_YES, CadetPeerPath::hn, LOG, CheckMatchContext::match, CadetPeerPathEntry::path, CadetPeerPathEntry::peer, and recalculate_path_desirability().

Referenced by GCP_iterate_paths(), GCP_set_mq(), and handle_connection_create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCPP_get_length()

unsigned int GCPP_get_length ( struct CadetPeerPath path)

Return the length of the path.

Excludes one end of the path, so the loopback path has length 0.

Parameters
pathpath to return the length for
Returns
number of peers on the path

Definition at line 695 of file gnunet-service-cadet_paths.c.

696{
697 return path->entries_length;
698}

References CadetPeerPath::entries_length, and CadetPeerPathEntry::path.

Referenced by consider_path_cb(), evaluate_connection(), GCP_attach_path(), path_heap_cleanup(), and path_info_iterator().

Here is the caller graph for this function:

◆ GCPP_find_peer()

unsigned int GCPP_find_peer ( struct CadetPeerPath path,
struct CadetPeer cp 
)

Find peer's offset on path.

Parameters
pathpath to search
cppeer to look for
Returns
offset of cp on path, or UINT_MAX if not found

Definition at line 709 of file gnunet-service-cadet_paths.c.

711{
712 for (unsigned int off = 0;
713 off < path->entries_length;
714 off++)
715 if (cp == GCPP_get_peer_at_offset (path,
716 off))
717 return off;
718 return UINT_MAX;
719}

References CadetPeerPath::entries_length, GCPP_get_peer_at_offset(), and CadetPeerPathEntry::path.

Referenced by GCC_create_inbound().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCPP_get_peer_at_offset()

struct CadetPeer * GCPP_get_peer_at_offset ( struct CadetPeerPath path,
unsigned int  off 
)

Obtain the peer at offset off in path.

Parameters
pathpeer path to inspect
offoffset to return, must be smaller than path length
Returns
peer at offset off

Definition at line 723 of file gnunet-service-cadet_paths.c.

725{
726 GNUNET_assert (off < path->entries_length);
727 return path->entries[off]->peer;
728}

References CadetPeerPath::entries, GNUNET_assert, and CadetPeerPathEntry::peer.

Referenced by check_match(), connection_create(), consider_path_cb(), cont_send_create(), evaluate_connection(), GCC_destroy(), GCP_attach_path(), GCP_path_entry_add(), GCPP_2s(), GCPP_find_peer(), handle_connection_broken(), handle_connection_create_ack(), handle_connection_destroy(), handle_tunnel_encrypted(), handle_tunnel_kx(), handle_tunnel_kx_auth(), and path_info_iterator().

Here is the caller graph for this function:

◆ GCPP_2s()

const char * GCPP_2s ( struct CadetPeerPath path)

Convert a path to a human-readable string.

Parameters
pathpath to convert
Returns
string, to be freed by caller (unlike other *_2s APIs!)

Definition at line 738 of file gnunet-service-cadet_paths.c.

739{
740 static char buf[2048];
741 size_t off;
742 const unsigned int max_plen = (sizeof(buf) - 16) / 5 - 2; /* 5 characters per entry */
743
744 off = 0;
745 for (unsigned int i = 0;
746 i < path->entries_length;
747 i++)
748 {
749 if ((path->entries_length > max_plen) &&
750 (i == max_plen / 2))
751 off += GNUNET_snprintf (&buf[off],
752 sizeof(buf) - off,
753 "...-");
754 if ((path->entries_length > max_plen) &&
755 (i > max_plen / 2) &&
756 (i < path->entries_length - max_plen / 2))
757 continue;
758 off += GNUNET_snprintf (&buf[off],
759 sizeof(buf) - off,
760 "%s%s",
762 path,
763 i))),
764 (i == path->entries_length - 1) ? "" : "-");
765 }
766 GNUNET_snprintf (&buf[off],
767 sizeof(buf) - off,
768 "(%p)",
769 path);
770 return buf;
771}
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.

References CadetPeerPath::entries_length, GCP_get_id(), GCPP_get_peer_at_offset(), GNUNET_i2s(), and GNUNET_snprintf().

Referenced by check_match(), connection_create(), consider_path_cb(), evaluate_connection(), extend_path(), GCC_create_inbound(), GCC_debug(), GCP_attach_path(), GCP_detach_path(), GCP_path_entry_add(), GCP_path_entry_remove(), GCPP_add_connection(), GCPP_del_connection(), GCPP_get_path_from_route(), GCPP_release(), GCPP_try_path_from_dht(), GCT_consider_path(), and handle_connection_create().

Here is the call graph for this function:
Here is the caller graph for this function: