From 6cf2bd7b4a69a1b173d52d059aae092343b4c4ed Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Tue, 26 Jan 2021 22:55:21 +0100 Subject: [PATCH] Add meshlink_hint_network_change(). This is intended to be used when there is no way for MeshLink to get notifications of local network changes. It forces MeshLink to scan all network interfaces for changes in up/down status and new/removed addresses, and will immediately check if all connections to other nodes are still alive. --- src/discovery.c | 29 ++++++++++++++++++++++++++--- src/discovery.h | 3 ++- src/meshlink++.h | 9 +++++++++ src/meshlink.c | 24 +++++++++++++++++++++++- src/meshlink.h | 12 +++++++++++- src/meshlink.sym | 1 + 6 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/discovery.c b/src/discovery.c index 65c19740..18919745 100644 --- a/src/discovery.c +++ b/src/discovery.c @@ -1,3 +1,22 @@ +/* + discovery.c -- local network discovery + Copyright (C) 2014-2021 Guus Sliepen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + #define __APPLE_USE_RFC_3542 #include "system.h" @@ -413,8 +432,8 @@ static void addr_del(meshlink_handle_t *mesh, const discovery_address_t *addr) { memmove(p, p + 1, (mesh->discovery.addresses + --mesh->discovery.address_count - p) * sizeof(*p)); } -#if !defined(__linux) && (defined(RTM_NEWADDR) || defined(__APPLE__)) -static void scan_ifaddrs(meshlink_handle_t *mesh) { +void scan_ifaddrs(meshlink_handle_t *mesh) { +#ifdef HAVE_GETIFADDRS struct ifaddrs *ifa = NULL; if(getifaddrs(&ifa) == -1) { @@ -512,8 +531,10 @@ static void scan_ifaddrs(meshlink_handle_t *mesh) { } freeifaddrs(ifa); -} +#else + (void)mesh; #endif +} #if defined(__linux) static void netlink_getlink(int fd) { @@ -932,9 +953,11 @@ bool discovery_start(meshlink_handle_t *mesh) { netlink_getlink(sock); } else { logger(mesh, MESHLINK_WARNING, "Could not bind AF_NETLINK socket: %s", strerror(errno)); + scan_ifaddrs(mesh); } } else { logger(mesh, MESHLINK_WARNING, "Could not open AF_NETLINK socket: %s", strerror(errno)); + scan_ifaddrs(mesh); } #elif defined(__APPLE__) diff --git a/src/discovery.h b/src/discovery.h index d3b8e004..03c43120 100644 --- a/src/discovery.h +++ b/src/discovery.h @@ -3,7 +3,7 @@ /* discovery.h -- header for discovery.c - Copyright (C) 2014, 2017 Guus Sliepen + Copyright (C) 2014-2021 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,5 +25,6 @@ bool discovery_start(meshlink_handle_t *mesh); void discovery_stop(meshlink_handle_t *mesh); void discovery_refresh(meshlink_handle_t *mesh); +void scan_ifaddrs(meshlink_handle_t *mesh); #endif diff --git a/src/meshlink++.h b/src/meshlink++.h index 551913d4..10370e26 100644 --- a/src/meshlink++.h +++ b/src/meshlink++.h @@ -1100,6 +1100,15 @@ public: meshlink_enable_discovery(handle, enable); } + /// Inform MeshLink that the local network configuration might have changed + /** This is intended to be used when there is no way for MeshLink to get notifications of local network changes. + * It forces MeshLink to scan all network interfaces for changes in up/down status and new/removed addresses, + * and will immediately check if all connections to other nodes are still alive. + */ + void hint_network_change() { + meshlink_hint_network_change(handle); + } + /// Set device class timeouts /** This sets the ping interval and timeout for a given device class. * diff --git a/src/meshlink.c b/src/meshlink.c index 1b7b03cf..4577c550 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1,6 +1,6 @@ /* meshlink.c -- Implementation of the MeshLink API. - Copyright (C) 2014-2018 Guus Sliepen + Copyright (C) 2014-2021 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -4491,6 +4491,28 @@ end: pthread_mutex_unlock(&mesh->mutex); } +void meshlink_hint_network_change(struct meshlink_handle *mesh) { + if(!mesh) { + meshlink_errno = MESHLINK_EINVAL; + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + if(mesh->discovery.enabled) { + scan_ifaddrs(mesh); + } + + if(mesh->loop.now.tv_sec > mesh->discovery.last_update + 5) { + mesh->discovery.last_update = mesh->loop.now.tv_sec; + handle_network_change(mesh, 1); + } + + pthread_mutex_unlock(&mesh->mutex); +} + void meshlink_set_dev_class_timeouts(meshlink_handle_t *mesh, dev_class_t devclass, int pinginterval, int pingtimeout) { if(!mesh || devclass < 0 || devclass >= DEV_CLASS_COUNT) { meshlink_errno = EINVAL; diff --git a/src/meshlink.h b/src/meshlink.h index 1acd99b0..82f8653c 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -3,7 +3,7 @@ /* meshlink.h -- MeshLink API - Copyright (C) 2014-2019 Guus Sliepen + Copyright (C) 2014-2021 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1654,6 +1654,16 @@ void meshlink_hint_address(struct meshlink_handle *mesh, struct meshlink_node *n */ void meshlink_enable_discovery(struct meshlink_handle *mesh, bool enable); +/// Inform MeshLink that the local network configuration might have changed +/** This is intended to be used when there is no way for MeshLink to get notifications of local network changes. + * It forces MeshLink to scan all network interfaces for changes in up/down status and new/removed addresses, + * and will immediately check if all connections to other nodes are still alive. + * + * \memberof meshlink_handle + * @param mesh A handle which represents an instance of MeshLink. + */ +void meshlink_hint_network_change(struct meshlink_handle *mesh); + /// Performs key rotation for an encrypted storage /** This rotates the (master) key for an encrypted storage and discards the old key * if the call succeeded. This is an atomic call. diff --git a/src/meshlink.sym b/src/meshlink.sym index 51511ee9..e427b9d3 100644 --- a/src/meshlink.sym +++ b/src/meshlink.sym @@ -54,6 +54,7 @@ meshlink_get_port meshlink_get_self meshlink_get_submesh meshlink_hint_address +meshlink_hint_network_change meshlink_import meshlink_invite meshlink_invite_ex -- 2.39.5