GNUnet 0.26.2-113-ged4734898
 
Loading...
Searching...
No Matches
gnunet-service-cadet_paths.h File Reference
Include dependency graph for gnunet-service-cadet_paths.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

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.
 
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.
 
unsigned int GCPP_find_peer (struct CadetPeerPath *path, struct CadetPeer *cp)
 Find peer's offset on path.
 
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability (const struct CadetPeerPath *path)
 Return how much we like keeping the path.
 
void GCPP_release (struct CadetPeerPath *path)
 The given peer cp used to own this 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 *p)
 Convert a path to a human-readable string.
 

Function Documentation

◆ 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

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.
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
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.
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...
#define LOG(level,...)
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.
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.
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
Entry in a peer path.
struct CadetPeer * peer
The peer at this offset of the path.
struct CadetPeerPath * path
Path this entry belongs to.
Information regarding a possible path to reach a peer.
unsigned int entries_length
Length of the entries array.
struct CadetPeerPathEntry ** entries
Array of all the peers on the path.
struct GNUNET_CONTAINER_HeapNode * hn
Node of this path in the owner's heap.
Struct containing all information regarding a given peer.
Closure for #find_peer_at() and check_match().
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}
static void recalculate_path_desirability(struct CadetPeerPath *path)
Calculate the path's desirability score.
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.
#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_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}
struct CadetConnection * cc
Connection using this path, or NULL for none.

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.

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:

◆ 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}
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.

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_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}
GNUNET_CONTAINER_HeapCostType desirability
Desirability of the path.

References CadetPeerPath::desirability.

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

Here is the caller graph for this function:

◆ GCPP_release()

void GCPP_release ( struct CadetPeerPath path)

The given peer cp used to own this path.

However, it 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).

Parameters
paththe path that is being released

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}
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.

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_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, statically allocated
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: