]> git.meshlink.io Git - meshlink/commitdiff
Close connections if the local address is no longer valid.
authorGuus Sliepen <guus@meshlink.io>
Fri, 26 Jul 2019 22:44:06 +0000 (00:44 +0200)
committerGuus Sliepen <guus@meshlink.io>
Fri, 26 Jul 2019 22:44:06 +0000 (00:44 +0200)
When we detect that there are changes on the network interfaces, check for
each active connection whether the local side of the connection has an
address that exists on at least one network interface. If not, then
communication via that connection is not possible. Instead of waiting for
a timeout, immediately terminate those connections.

configure.ac
src/have.h
src/net.c

index 48694a700786cb791919f1737908232374d5f49f..4028613f31868e26ea559636126b2dde8c9493f5 100644 (file)
@@ -118,7 +118,7 @@ AM_CONDITIONAL(INSTALL_TESTS, test "$install_tests" = true)
 dnl Checks for header files.
 dnl We do this in multiple stages, because unlike Linux all the other operating systems really suck and don't include their own dependencies.
 
-AC_CHECK_HEADERS([syslog.h sys/file.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h curses.h])
+AC_CHECK_HEADERS([syslog.h sys/file.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h curses.h ifaddrs.h])
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 MeshLink_ATTRIBUTE(__malloc__)
@@ -134,7 +134,7 @@ AC_CHECK_TYPES([struct sockaddr_storage], ,AC_MSG_ERROR([System must support str
 
 dnl Checks for library functions.
 AC_TYPE_SIGNAL
-AC_CHECK_FUNCS([asprintf fchmod fork gettimeofday random select setns strdup usleep],
+AC_CHECK_FUNCS([asprintf fchmod fork gettimeofday random select setns strdup usleep getifaddrs],
   [], [], [#include "$srcdir/src/have.h"]
 )
 
index 536226d5826d54335c71678cb6ccfe6a0073b547..d4c62f4814eebe9debcb9fe53c11dd0a4a893f57 100644 (file)
 #include <arpa/inet.h>
 #endif
 
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
+
 #ifdef HAVE_MINGW
 #define SLASH "\\"
 #else
index a42d933bef822a375fea4c5b4e823d4f6553f683..ddfd2cf09aa828abc5a861742e60172e33b8fddb 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -625,13 +625,61 @@ void retry(meshlink_handle_t *mesh) {
                });
        }
 
-       /* Check for outgoing connections that are in progress, and reset their ping timers */
+#ifdef HAVE_IFADDRS_H
+       struct ifaddrs *ifa = NULL;
+       getifaddrs(&ifa);
+#endif
+
+       /* For active connections, check if their addresses are still valid.
+        * If yes, reset their ping timers, otherwise terminate them. */
        for list_each(connection_t, c, mesh->connections) {
-               if(c->outgoing && !c->node) {
+               if(!c->status.active) {
+                       continue;
+               }
+
+               if(!c->status.pinged) {
                        c->last_ping_time = 0;
                }
+
+#ifdef HAVE_IFADDRS_H
+
+               if(!ifa) {
+                       continue;
+               }
+
+               sockaddr_t sa;
+               socklen_t salen = sizeof(sa);
+
+               if(getsockname(c->socket, &sa.sa, &salen)) {
+                       continue;
+               }
+
+               bool found = false;
+
+               for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) {
+                       if(ifap->ifa_addr && !sockaddrcmp_noport(&sa, (sockaddr_t *)ifap->ifa_addr)) {
+                               found = true;
+                               break;
+                       }
+
+               }
+
+               if(!found) {
+                       logger(mesh, MESHLINK_DEBUG, "Local address for connection to %s no longer valid, terminating", c->name);
+                       terminate_connection(mesh, c, c->status.active);
+               }
+
+#endif
+       }
+
+#ifdef HAVE_IFADDRS_H
+
+       if(ifa) {
+               freeifaddrs(ifa);
        }
 
+#endif
+
        /* Kick the ping timeout handler */
        timeout_set(&mesh->loop, &mesh->pingtimer, &(struct timeval) {
                0, 0