]> git.meshlink.io Git - meshlink/commitdiff
Add meshlink_hint_network_change().
authorGuus Sliepen <guus@meshlink.io>
Tue, 26 Jan 2021 21:55:21 +0000 (22:55 +0100)
committerGuus Sliepen <guus@meshlink.io>
Thu, 15 Apr 2021 18:30:51 +0000 (20:30 +0200)
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
src/discovery.h
src/meshlink++.h
src/meshlink.c
src/meshlink.h
src/meshlink.sym

index 65c197409808acbc65469f6139dc164b4fdba735..18919745c2e01d783bf452e5f638c56cf6779e0a 100644 (file)
@@ -1,3 +1,22 @@
+/*
+  discovery.c -- local network discovery
+  Copyright (C) 2014-2021 Guus Sliepen <guus@meshlink.io>
+
+  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__)
index d3b8e0047b9f730ed9faaab7e4d344f27375eefd..03c431207a1569996e44f04fa4b4724f48ba5b6b 100644 (file)
@@ -3,7 +3,7 @@
 
 /*
     discovery.h -- header for discovery.c
-    Copyright (C) 2014, 2017 Guus Sliepen <guus@meshlink.io>
+    Copyright (C) 2014-2021 Guus Sliepen <guus@meshlink.io>
 
     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
index 1f109849b6408e5cd7487f4365c92b3493a32185..baf08ae1ef15405aa238360bfbb69a1f2309c5a0 100644 (file)
@@ -1150,6 +1150,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.
         *
index 1b65e40c3efc6c59d6e1bb2e6347096c6e7b1741..f6b12bd89d0e26e87e796290b3e9305263db573c 100644 (file)
@@ -1,6 +1,6 @@
 /*
     meshlink.c -- Implementation of the MeshLink API.
-    Copyright (C) 2014-2018 Guus Sliepen <guus@meshlink.io>
+    Copyright (C) 2014-2021 Guus Sliepen <guus@meshlink.io>
 
     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
@@ -4570,6 +4570,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;
index ead75205809f5f3f2e10fa7363ea629cfd0d68ff..cc18bec037841b54bcc253c0ce0c873749c98595 100644 (file)
@@ -3,7 +3,7 @@
 
 /*
     meshlink.h -- MeshLink API
-    Copyright (C) 2014-2019 Guus Sliepen <guus@meshlink.io>
+    Copyright (C) 2014-2021 Guus Sliepen <guus@meshlink.io>
 
     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
@@ -1735,6 +1735,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.
index 4ecd23e99df950061f8738d090bc8f3d2cc206be..ce78f112003715982d95e30036f1ff7511345cf0 100644 (file)
@@ -55,6 +55,7 @@ meshlink_get_port
 meshlink_get_self
 meshlink_get_submesh
 meshlink_hint_address
+meshlink_hint_network_change
 meshlink_import
 meshlink_invite
 meshlink_invite_ex