]> git.meshlink.io Git - meshlink/commitdiff
Add a callback for PMTU changes.
authorGuus Sliepen <guus@meshlink.io>
Mon, 23 Sep 2019 18:54:16 +0000 (20:54 +0200)
committerGuus Sliepen <guus@meshlink.io>
Mon, 23 Sep 2019 18:54:16 +0000 (20:54 +0200)
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
src/meshlink.h
src/meshlink_internal.h
src/net_packet.c

index 1b33e88d47d3e3a9801c907f44be42d1a617f306..d619f544a7971c364a8e774f7a7fbb27561425cd 100644 (file)
@@ -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) {
index 40ed38f50d7f1eece92883e4231353b0b6f68050..65d019f2f30555e18366e6849ab32e79faef16fd 100644 (file)
@@ -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.
index 4e459b4e847bd5861047ebccca89caeeca8bc33a..3b7e66cdf93e374afed0f333faed4988de673d3e 100644 (file)
@@ -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);
index 0bef53433030d0606e49151ca6de2a8d34d0a67c..c816532711e8a685f597d6e4ddba1c9085bce457 100644 (file)
@@ -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);
                }
        }
 }