X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=e84aafcac9e3a7d3197e278eb186c510b0c5a232;hb=b9eb3647186bf697e4bdc8f60fd05cc15a99c18b;hp=acb4b0fb1802d10c9bbf556bdedbd5591770371b;hpb=49b8d045d498574b51913be05ea1e9a41609b6e1;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index acb4b0fb..e84aafca 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,72 @@ 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, meshlink_edge_t **edges, size_t *nmemb) { + if(!mesh || !nmemb || (*nmemb && !edges)) { + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + pthread_mutex_lock(&(mesh->mesh_mutex)); + + meshlink_edge_t **result = NULL; + meshlink_edge_t *copy = NULL; + int result_size = 0; + + result_size = mesh->edges->count; + + // if result is smaller than edges, we have to dealloc all the excess meshlink_edge_t + if(result_size > *nmemb) { + result = realloc(edges, result_size * sizeof (meshlink_edge_t*)); + } else { + result = edges; + } + + if(result) { + meshlink_edge_t **p = result; + int n = 0; + 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)) { + result_size--; + continue; + } + n++; + // the first *nmemb members of result can be re-used + if(n > *nmemb) { + copy = xzalloc(sizeof *copy); + } + else { + copy = *p; + } + copy->from = (meshlink_node_t*)e->from; + copy->to = (meshlink_node_t*)e->to; + copy->address = e->address.storage; + copy->options = e->options; + copy->weight = e->weight; + *p++ = copy; + } + // shrink result to the actual amount of memory used + for(int i = *nmemb; i > result_size; i--) { + free(result[i - 1]); + } + result = realloc(result, result_size * sizeof (meshlink_edge_t*)); + *nmemb = result_size; + } else { + *nmemb = 0; + free(result); + meshlink_errno = MESHLINK_ENOMEM; + } + + pthread_mutex_unlock(&(mesh->mesh_mutex)); + + return result; +} + static void __attribute__((constructor)) meshlink_init(void) { crypto_init(); }