From cec602155ba9e3e27a7436e360c8934a1599423b Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 23 Sep 2019 20:54:16 +0200 Subject: [PATCH] Add a callback for PMTU changes. This can be used to detect changes in UDP reachability of peers, and allows the application to change the maximum packet size for UDP channels. --- src/meshlink.c | 14 ++++++++++++++ src/meshlink.h | 21 +++++++++++++++++++++ src/meshlink_internal.h | 2 ++ src/net_packet.c | 4 ++++ 4 files changed, 41 insertions(+) diff --git a/src/meshlink.c b/src/meshlink.c index 1b33e88d..d619f544 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -2812,6 +2812,10 @@ void meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) { node_write_config(mesh, n); config_sync(mesh, "current"); + if(n->status.reachable) { + update_node_status(mesh, n); + } + pthread_mutex_unlock(&(mesh->mesh_mutex)); return; } @@ -3379,6 +3383,16 @@ void update_node_status(meshlink_handle_t *mesh, node_t *n) { if(mesh->node_status_cb) { mesh->node_status_cb(mesh, (meshlink_node_t *)n, n->status.reachable && !n->status.blacklisted); } + + if(mesh->node_pmtu_cb) { + mesh->node_pmtu_cb(mesh, (meshlink_node_t *)n, n->minmtu); + } +} + +void update_node_pmtu(meshlink_handle_t *mesh, node_t *n) { + if(mesh->node_pmtu_cb && !n->status.blacklisted) { + mesh->node_pmtu_cb(mesh, (meshlink_node_t *)n, n->minmtu); + } } void handle_duplicate_node(meshlink_handle_t *mesh, node_t *n) { diff --git a/src/meshlink.h b/src/meshlink.h index 40ed38f5..65d019f2 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -418,6 +418,27 @@ typedef void (*meshlink_node_status_cb_t)(meshlink_handle_t *mesh, meshlink_node */ extern void meshlink_set_node_status_cb(meshlink_handle_t *mesh, meshlink_node_status_cb_t cb); +/// A callback reporting node path MTU changes. +/** @param mesh A handle which represents an instance of MeshLink. + * @param node A pointer to a meshlink_node_t describing the node whose status changed. + * This pointer is valid until meshlink_close() is called. + * @param pmtu The current path MTU to the node, or 0 if UDP communication is not (yet) possible. + */ +typedef void (*meshlink_node_pmtu_cb_t)(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t pmtu); + +/// Set the node extended status callback. +/** This functions sets the callback that is called whenever certain connectivity parameters for a node change. + * 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. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param cb A pointer to the function which will be called when another node's extended status changes. + * If a NULL pointer is given, the callback will be disabled. + */ +extern void meshlink_set_node_pmtu_cb(meshlink_handle_t *mesh, meshlink_node_pmtu_cb_t cb); + /// A callback reporting duplicate node detection. /** @param mesh A handle which represents an instance of MeshLink. * @param node A pointer to a meshlink_node_t describing the node which is duplicate. diff --git a/src/meshlink_internal.h b/src/meshlink_internal.h index 4e459b4e..3b7e66cd 100644 --- a/src/meshlink_internal.h +++ b/src/meshlink_internal.h @@ -136,6 +136,7 @@ struct meshlink_handle { // Infrequently used callbacks meshlink_node_status_cb_t node_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; meshlink_connection_try_cb_t connection_try_cb; @@ -248,6 +249,7 @@ typedef struct meshlink_packethdr { extern void meshlink_send_from_queue(event_loop_t *el, meshlink_handle_t *mesh); extern void update_node_status(meshlink_handle_t *mesh, struct node_t *n); +extern void update_node_pmtu(meshlink_handle_t *mesh, struct node_t *n); extern meshlink_log_level_t global_log_level; extern meshlink_log_cb_t global_log_cb; extern int check_port(meshlink_handle_t *mesh); diff --git a/src/net_packet.c b/src/net_packet.c index 0bef5343..c8165327 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -79,6 +79,8 @@ static void send_mtu_probe_handler(event_loop_t *loop, void *data) { n->mtuprobes = 1; n->minmtu = 0; n->maxmtu = MTU; + + update_node_pmtu(mesh, n); } if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) { @@ -89,6 +91,7 @@ static void send_mtu_probe_handler(event_loop_t *loop, void *data) { if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) { if(n->minmtu > n->maxmtu) { n->minmtu = n->maxmtu; + update_node_pmtu(mesh, n); } else { n->maxmtu = n->minmtu; } @@ -198,6 +201,7 @@ static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet if(n->minmtu < len) { n->minmtu = len; + update_node_pmtu(mesh, n); } } } -- 2.39.2