From da55b444c063c510f37e4f8527982eb86f01c7b3 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Wed, 24 Jun 2020 22:22:01 +0200 Subject: [PATCH] Make the maximum outgoing connection timeout runtime configurable. This moves maxtimeout to the dev_class_traits, and adds a function to change it, similar to how we handle other configurable timeouts. --- src/meshlink++.h | 10 ++++++++++ src/meshlink.c | 24 ++++++++++++++++++++---- src/meshlink.h | 10 ++++++++++ src/meshlink_internal.h | 2 +- src/net_setup.c | 6 ------ src/net_socket.c | 4 ++-- 6 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/meshlink++.h b/src/meshlink++.h index bca39fd3..eeb1cd02 100644 --- a/src/meshlink++.h +++ b/src/meshlink++.h @@ -1049,6 +1049,16 @@ public: meshlink_set_dev_class_fast_retry_period(handle, devclass, fast_retry_period); } + /// Set device class maximum timeout + /** This sets the maximum timeout for outgoing connection retries for a given device class. + * + * @param devclass The device class to update + * @param maxtimeout The maximum timeout between reconnection attempts, in seconds. The default is 900. + */ + void set_dev_class_maxtimeout(dev_class_t devclass, int maxtimeout) { + meshlink_set_dev_class_maxtimeout(handle, devclass, maxtimeout); + } + /// Set which order invitations are committed /** This determines in which order configuration files are written to disk during an invitation. * By default, the invitee saves the configuration to disk first, then the inviter. diff --git a/src/meshlink.c b/src/meshlink.c index d0b8bef5..57ada124 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1296,10 +1296,10 @@ void meshlink_open_params_free(meshlink_open_params_t *params) { /// Device class traits static const dev_class_traits_t default_class_traits[DEV_CLASS_COUNT] = { - { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 10000, .edge_weight = 1 }, // DEV_CLASS_BACKBONE - { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 100, .edge_weight = 3 }, // DEV_CLASS_STATIONARY - { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 3, .edge_weight = 6 }, // DEV_CLASS_PORTABLE - { .pingtimeout = 5, .pinginterval = 60, .min_connects = 1, .max_connects = 1, .edge_weight = 9 }, // DEV_CLASS_UNKNOWN + { .pingtimeout = 5, .pinginterval = 60, .maxtimeout = 900, .min_connects = 3, .max_connects = 10000, .edge_weight = 1 }, // DEV_CLASS_BACKBONE + { .pingtimeout = 5, .pinginterval = 60, .maxtimeout = 900, .min_connects = 3, .max_connects = 100, .edge_weight = 3 }, // DEV_CLASS_STATIONARY + { .pingtimeout = 5, .pinginterval = 60, .maxtimeout = 900, .min_connects = 3, .max_connects = 3, .edge_weight = 6 }, // DEV_CLASS_PORTABLE + { .pingtimeout = 5, .pinginterval = 60, .maxtimeout = 900, .min_connects = 1, .max_connects = 1, .edge_weight = 9 }, // DEV_CLASS_UNKNOWN }; meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char *appname, dev_class_t devclass) { @@ -4260,6 +4260,22 @@ void meshlink_set_dev_class_fast_retry_period(meshlink_handle_t *mesh, dev_class assert(pthread_mutex_unlock(&mesh->mutex) == 0); } +void meshlink_set_dev_class_maxtimeout(struct meshlink_handle *mesh, dev_class_t devclass, int maxtimeout) { + if(!mesh || devclass < 0 || devclass >= DEV_CLASS_COUNT) { + meshlink_errno = EINVAL; + return; + } + + if(maxtimeout < 0) { + meshlink_errno = EINVAL; + return; + } + + assert(pthread_mutex_lock(&mesh->mutex) == 0); + mesh->dev_class_traits[devclass].maxtimeout = maxtimeout; + assert(pthread_mutex_unlock(&mesh->mutex) == 0); +} + extern void meshlink_set_inviter_commits_first(struct meshlink_handle *mesh, bool inviter_commits_first) { if(!mesh) { meshlink_errno = EINVAL; diff --git a/src/meshlink.h b/src/meshlink.h index 25a52d19..e0164b7f 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -1589,6 +1589,16 @@ void meshlink_set_dev_class_timeouts(struct meshlink_handle *mesh, dev_class_t d */ void meshlink_set_dev_class_fast_retry_period(struct meshlink_handle *mesh, dev_class_t devclass, int fast_retry_period); +/// Set device class maximum timeout +/** This sets the maximum timeout for outgoing connection retries for a given device class. + * + * \memberof meshlink_handle + * @param mesh A handle which represents an instance of MeshLink. + * @param devclass The device class to update + * @param maxtimeout The maximum timeout between reconnection attempts, in seconds. The default is 900. + */ +void meshlink_set_dev_class_maxtimeout(struct meshlink_handle *mesh, dev_class_t devclass, int maxtimeout); + /// Set which order invitations are committed /** This determines in which order configuration files are written to disk during an invitation. * By default, the invitee saves the configuration to disk first, then the inviter. diff --git a/src/meshlink_internal.h b/src/meshlink_internal.h index d6dc87d0..c75e6957 100644 --- a/src/meshlink_internal.h +++ b/src/meshlink_internal.h @@ -74,6 +74,7 @@ typedef struct { int pinginterval; int pingtimeout; int fast_retry_period; + int maxtimeout; unsigned int min_connects; unsigned int max_connects; int edge_weight; @@ -150,7 +151,6 @@ struct meshlink_handle { dev_class_t devclass; int invitation_timeout; - int maxtimeout; int udp_choice; dev_class_traits_t dev_class_traits[DEV_CLASS_COUNT]; diff --git a/src/net_setup.c b/src/net_setup.c index af49ea09..a82d5d97 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -522,12 +522,6 @@ static bool add_listen_sockets(meshlink_handle_t *mesh) { Configure node_t mesh->self and set up the local sockets (listen only) */ static bool setup_myself(meshlink_handle_t *mesh) { - /* Set some defaults */ - - mesh->maxtimeout = 900; - - /* Done */ - mesh->self->nexthop = mesh->self; node_add(mesh, mesh->self); diff --git a/src/net_socket.c b/src/net_socket.c index 5464b95f..6af4f738 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -93,8 +93,8 @@ void retry_outgoing(meshlink_handle_t *mesh, outgoing_t *outgoing) { outgoing->timeout += 5; } - if(outgoing->timeout > mesh->maxtimeout) { - outgoing->timeout = mesh->maxtimeout; + if(outgoing->timeout > mesh->dev_class_traits[mesh->devclass].maxtimeout) { + outgoing->timeout = mesh->dev_class_traits[mesh->devclass].maxtimeout; } timeout_add(&mesh->loop, &outgoing->ev, retry_outgoing_handler, outgoing, &(struct timespec) { -- 2.39.5