]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Add support for requesting the fd again to rebind to the next interface.
authorArne Schwabe <arne@rfc2549.org>
Tue, 15 Sep 2015 09:23:32 +0000 (11:23 +0200)
committerGert Doering <gert@greenie.muc.de>
Tue, 15 Sep 2015 10:47:45 +0000 (12:47 +0200)
This not done via android_control since calling management from management
leads to an infinitive loop

Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1442309019-7586-2-git-send-email-arne@rfc2549.org>
URL: http://article.gmane.org/gmane.network.openvpn.devel/10110

Signed-off-by: Gert Doering <gert@greenie.muc.de>
src/openvpn/init.c
src/openvpn/manage.c
src/openvpn/manage.h

index 4c17905abb026ad2c71afaaf8876bab0af86317f..b6cfecee1fdeab4630b7528689b1f1e4c67904cb 100644 (file)
@@ -3160,6 +3160,37 @@ management_show_net_callback (void *arg, const int msglevel)
 #endif
 }
 
+#ifdef TARGET_ANDROID
+int
+management_callback_network_change (void *arg)
+{
+    /* Check if the client should translate the network change to a SIGUSR1 to
+     reestablish the connection or just reprotect the socket
+
+     At the moment just assume that, for all settings that use pull (not
+     --static) and are not using peer-id reestablishing the connection is
+     required
+
+     The function returns -1 on invalid fd and -2 if the socket cannot be
+     reused. On the -2 return value the man_network_change function triggers
+     a SIGUSR1 to force a reconnect.
+    */
+
+  int socketfd=-1;
+  struct context *c = (struct context *) arg;
+  if (!c->c2.link_socket)
+    return -1;
+  if (c->c2.link_socket->sd == SOCKET_UNDEFINED)
+    return -1;
+
+  socketfd = c->c2.link_socket->sd;
+  if (!c->options.pull || c->c2.tls_multi->use_peer_id)
+    return socketfd;
+  else
+    return -2;
+}
+#endif
+
 #endif
 
 void
@@ -3175,6 +3206,9 @@ init_management_callback_p2p (struct context *c)
       cb.show_net = management_show_net_callback;
       cb.proxy_cmd = management_callback_proxy_cmd;
       cb.remote_cmd = management_callback_remote_cmd;
+#ifdef TARGET_ANDROID
+      cb.network_change = management_callback_network_change;
+#endif
       management_set_callback (management, &cb);
     }
 #endif
index 4f0945ca5c640d481ed7bb53de45925145b777f2..af4aa44f20739fe8935149376d35a5ca4ee8a28e 100644 (file)
@@ -1127,6 +1127,26 @@ man_remote (struct management *man, const char **p)
     }
 }
 
+#ifdef TARGET_ANDROID
+static void
+man_network_change (struct management *man)
+{
+  /* Called to signal the OpenVPN that the network configuration has changed and
+     the client should either float or reconnect.
+
+     The code is currently only used by ics-openvpn
+  */
+  if (man->persist.callback.network_change)
+    {
+      int fd = (*man->persist.callback.network_change)(man->persist.callback.arg);
+      man->connection.fdtosend = fd;
+      msg (M_CLIENT, "PROTECTFD: fd '%d' sent to be protected", fd);
+      if (fd == -2)
+       man_signal (man, "SIGUSR1");
+    }
+}
+#endif
+
 static void
 man_dispatch_command (struct management *man, struct status_output *so, const char **p, const int nparms)
 {
@@ -1170,6 +1190,12 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch
       if (man_need (man, p, 1, 0))
        man_signal (man, p[1]);
     }
+#ifdef TARGET_ANDROID
+  else if (streq (p[0], "network-change"))
+    {
+      man_network_change(man);
+    }
+#endif
   else if (streq (p[0], "load-stats"))
     {
       man_load_stats (man);
index 8d6e87efa061a7613b78807802693692c74dccdf..73183777a77da5a8a1b42c6fab18a22f141bcde8 100644 (file)
@@ -173,6 +173,9 @@ struct management_callback
 #endif
   bool (*proxy_cmd) (void *arg, const char **p);
   bool (*remote_cmd) (void *arg, const char **p);
+#ifdef TARGET_ANDROID
+  int (*network_change) (void *arg);
+#endif
 };
 
 /*