]> 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>
Tue, 26 Jan 2021 21:55:21 +0000 (22:55 +0100)
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 551913d4ba2a94ceb4df51852dd8595ce563a28d..10370e269f8ed139067ff4fc80d02973db975992 100644 (file)
@@ -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.
         *
index 1b7b03cf05868ad545bd6f51fa227be9776cbf83..4577c550410aeb6fddb4fc5cb08ce50caa390533 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
@@ -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;
index 1acd99b0663bd021ba6fc70a4e0ecfcb48ff319a..82f8653caa8e315488e2522f1582a2f2be5ff921 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
@@ -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.
index 51511ee9e1d5ed9a1eb8680306ac09f386657160..e427b9d3efb19265cb9127b3f801405e20c79ad4 100644 (file)
@@ -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