X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=6396163dc4d6938a230f2039132cd8ce2dbc044a;hb=326a86ef927e1f161a6742edfca041a945c7a547;hp=acb4b0fb1802d10c9bbf556bdedbd5591770371b;hpb=49b8d045d498574b51913be05ea1e9a41609b6e1;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index acb4b0fb..6396163d 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1814,7 +1814,7 @@ void meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) { /* Hint that a hostname may be found at an address * See header file for detailed comment. */ -extern void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const struct sockaddr *addr) { +void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const struct sockaddr *addr) { if(!mesh || !node || !addr) return; @@ -1836,6 +1836,56 @@ extern void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node // @TODO do we want to fire off a connection attempt right away? } +/* Return an array of edges in the current network graph. + * Data captures the current state and will not be updated. + * Caller must deallocate data when done. + */ +meshlink_edge_t **meshlink_get_all_edges_state(meshlink_handle_t *mesh, size_t *nmemb) { + if(!mesh || !nmemb) { + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + pthread_mutex_lock(&(mesh->mesh_mutex)); + + meshlink_edge_t **result = NULL; + meshlink_edge_t *copy = NULL; + + // mesh->edges->count is the max size + *nmemb = mesh->edges->count; + + result = xzalloc(*nmemb * sizeof (meshlink_edge_t*)); + + if(result) { + meshlink_edge_t **p = result; + for splay_each(edge_t, e, mesh->edges) { + // skip edges that do not represent a two-directional connection + if((!e->reverse) || (e->reverse->to != e->from)) { + *nmemb--; + continue; + } + // copy the edge so it can't be mutated + copy = xzalloc(sizeof *copy); + copy->from = (meshlink_node_t*)e->from; + copy->to = (meshlink_node_t*)e->to; + //TODO fix conversion from sockaddr_t to sockaddr_storage + //copy->address = e->address.ss; + copy->options = e->options; + copy->weight = e->weight; + *p++ = copy; + } + // shrink result to the actual amount of memory used + result = realloc(result, *nmemb * sizeof (meshlink_edge_t*)); + } else { + *nmemb = 0; + meshlink_errno = MESHLINK_ENOMEM; + } + + pthread_mutex_unlock(&(mesh->mesh_mutex)); + + return result; +} + static void __attribute__((constructor)) meshlink_init(void) { crypto_init(); }