From: Guus Sliepen Date: Wed, 22 Jul 2020 18:29:22 +0000 (+0200) Subject: Add devtool_set_meta_status_cb(). X-Git-Url: https://git.meshlink.io/?a=commitdiff_plain;h=b2d1ccdaf1554f2f34e8acb86f89190cb93b6634;p=meshlink Add devtool_set_meta_status_cb(). This function is similar to meshlink_set_node_status_cb(), except that this callback will only be called when a meta-connection to a node is activated or terminated. This is mainly useful for the test suite. --- diff --git a/src/devtools.c b/src/devtools.c index 22a0818b..2a98e595 100644 --- a/src/devtools.c +++ b/src/devtools.c @@ -367,3 +367,17 @@ void devtool_force_sptps_renewal(meshlink_handle_t *mesh, meshlink_node_t *node) c->last_key_renewal = -3600; } } + +void devtool_set_meta_status_cb(meshlink_handle_t *mesh, meshlink_node_status_cb_t cb) { + if(!mesh) { + meshlink_errno = MESHLINK_EINVAL; + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + mesh->meta_status_cb = cb; + pthread_mutex_unlock(&mesh->mutex); +} diff --git a/src/devtools.h b/src/devtools.h index 44965c37..786e2900 100644 --- a/src/devtools.h +++ b/src/devtools.h @@ -195,4 +195,18 @@ void devtool_force_sptps_renewal(meshlink_handle_t *mesh, meshlink_node_t *node) */ extern void (*devtool_set_inviter_commits_first)(bool inviter_commited_first); +/// Set the meta-connection status callback. +/** This functions sets the callback that is called whenever a meta-connection is made or closed. + * The callback is run in MeshLink's own thread. + * It is therefore important that the callback uses apprioriate methods (queues, pipes, locking, etc.) + * to hand the data over to the application's thread. + * The callback should also not block itself and return as quickly as possible. + * + * \memberof meshlink_handle + * @param mesh A handle which represents an instance of MeshLink. + * @param cb A pointer to the function which will be called when a node's meta-connection status changes. + * If a NULL pointer is given, the callback will be disabled. + */ +void devtool_set_meta_status_cb(struct meshlink_handle *mesh, meshlink_node_status_cb_t cb); + #endif diff --git a/src/meshlink.sym b/src/meshlink.sym index 6be514ae..00f8fa38 100644 --- a/src/meshlink.sym +++ b/src/meshlink.sym @@ -5,6 +5,7 @@ devtool_get_all_submeshes devtool_get_node_status devtool_keyrotate_probe devtool_open_in_netns +devtool_set_meta_status_cb devtool_set_inviter_commits_first devtool_trybind_probe meshlink_add_address diff --git a/src/meshlink_internal.h b/src/meshlink_internal.h index c75e6957..588c630a 100644 --- a/src/meshlink_internal.h +++ b/src/meshlink_internal.h @@ -135,6 +135,7 @@ struct meshlink_handle { // Infrequently used callbacks meshlink_node_status_cb_t node_status_cb; + meshlink_node_status_cb_t meta_status_cb; meshlink_node_pmtu_cb_t node_pmtu_cb; meshlink_channel_accept_cb_t channel_accept_cb; meshlink_node_duplicate_cb_t node_duplicate_cb; diff --git a/src/net.c b/src/net.c index 6fd90e19..9dc9598a 100644 --- a/src/net.c +++ b/src/net.c @@ -54,12 +54,16 @@ static const int default_interval = 60; void terminate_connection(meshlink_handle_t *mesh, connection_t *c, bool report) { logger(mesh, MESHLINK_INFO, "Closing connection with %s", c->name); - c->status.active = false; - if(c->node && c->node->connection == c) { + if(c->status.active && mesh->meta_status_cb) { + mesh->meta_status_cb(mesh, (meshlink_node_t *)c->node, false); + } + c->node->connection = NULL; } + c->status.active = false; + if(c->edge) { if(report) { send_del_edge(mesh, mesh->everyone, c->edge, 0); diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 201cac9f..2154faae 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -370,6 +370,10 @@ bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { logger(mesh, MESHLINK_INFO, "Connection with %s activated", c->name); + if(mesh->meta_status_cb) { + mesh->meta_status_cb(mesh, (meshlink_node_t *)n, true); + } + /* Send him everything we know */ send_everything(mesh, c);