From 326a86ef927e1f161a6742edfca041a945c7a547 Mon Sep 17 00:00:00 2001 From: Aaron Krebs Date: Sat, 9 Aug 2014 22:05:34 +0200 Subject: [PATCH] Implemented API function to capture mesh edges. --- src/meshlink.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/meshlink.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/src/meshlink.c b/src/meshlink.c index b8f3c969..6396163d 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1836,6 +1836,56 @@ void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const // @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(); } diff --git a/src/meshlink.h b/src/meshlink.h index 6858b5bc..8bc8c706 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -48,6 +48,9 @@ typedef struct meshlink_handle meshlink_handle_t; /// A handle for a MeshLink node. typedef struct meshlink_node meshlink_node_t; +/// A handle for a MeshLink edge. +typedef struct meshlink_edge meshlink_edge_t; + /// A handle for a MeshLink channel. typedef struct meshlink_channel meshlink_channel_t; @@ -97,6 +100,15 @@ struct meshlink_channel { #endif // MESHLINK_INTERNAL_H +// TODO documentation +struct meshlink_edge { + struct meshlink_node *from; + struct meshlink_node *to; + struct sockaddr_storage address; + uint32_t options; + int weight; +}; + /// Get the text for the given MeshLink error code. /** This function returns a pointer to the string containing the description of the given error code. * @@ -608,6 +620,25 @@ extern ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t */ extern void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const struct sockaddr *addr); +/// Get a list of edges. +/** This function returns an array with copies of all known bidirectional edges. + * The edges are copied to capture the mesh state at call time, since edges + * mutate frequently. The nodes pointed to within the meshlink_edge_t type + * are not copies; these are the same pointers that one would get from a call + * to meshlink_get_all_nodes(). + * + * @param mesh A handle which represents an instance of MeshLink. + * @param nmemb A pointer to a variable that will be filled with the number + * of edges in the returned array. + * + * @return A pointer to an array containing pointers to all known + * edges, or NULL in case of an error. + * The caller must call free() on each element of this + * array (but not the contents of said elements), + * as well as the array itself when it is finished. + */ +extern meshlink_edge_t **meshlink_get_all_edges_state(meshlink_handle_t *mesh, size_t *nmemb); + #ifdef __cplusplus } #endif -- 2.39.2