[Openvpn-devel,1/2] tun.c: reorder IPv6 ifconfig on Windows

Message ID 20200310094822.588-1-simon@rozman.si
State Accepted
Headers show
Series [Openvpn-devel,1/2] tun.c: reorder IPv6 ifconfig on Windows | expand

Commit Message

Simon Rozman March 9, 2020, 10:48 p.m. UTC
The IPv6 interface network route should be setup as soon as possible
after the interface address is set. Actually, all routes should be added
before DNS servers are configured. This would allow Windows to validate
DNS servers properly instead of shutting the validation off.

The cleanup order has been changed to match reverse order of ifconfig.
An additional check was added to skip the cleanup when --ip-win32 is set
to manual.

Signed-off-by: Simon Rozman <simon@rozman.si>
---
 src/openvpn/tun.c | 51 +++++++++++++++++++++++++----------------------
 1 file changed, 27 insertions(+), 24 deletions(-)

Comments

Lev Stipakov March 11, 2020, 9:02 p.m. UTC | #1
Hi,

Explanation makes sense and code does what is says -
adds address/route/dns and removes in reverse direction.

Compiled and smoke-tested with MSVC.

Acked-by: Lev Stipakov <lstipakov@gmail.com>
Gert Doering March 14, 2020, 1:43 a.m. UTC | #2
Your patch has been applied to the master branch.

I did a cursory review and the changes look good (the ACK is Lev's, 
though :-) ).  Test compiled on Ubuntu 16.04/MinGW for good measure.

commit f3ef6ced23b659855ac8b957e147fa8b58578098
Author: Simon Rozman
Date:   Tue Mar 10 10:48:21 2020 +0100

     tun.c: reorder IPv6 ifconfig on Windows

     Signed-off-by: Simon Rozman <simon@rozman.si>
     Acked-by: Lev Stipakov <lstipakov@gmail.com>
     Message-Id: <20200310094822.588-1-simon@rozman.si>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg19541.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index 1f848d24..42193d97 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -1016,6 +1016,7 @@  do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
     else if (tt->options.msg_channel)
     {
         do_address_service(true, AF_INET6, tt);
+        add_route_connected_v6_net(tt, es);
         do_dns_service(true, AF_INET6, tt);
     }
     else
@@ -1031,15 +1032,10 @@  do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
                     get_win_sys_path(), NETSH_PATH_SUFFIX, iface,
                     ifconfig_ipv6_local);
         netsh_command(&argv, 4, M_FATAL);
+        add_route_connected_v6_net(tt, es);
         /* set ipv6 dns servers if any are specified */
         netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, ifname);
     }
-
-    /* explicit route needed */
-    if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
-    {
-        add_route_connected_v6_net(tt, es);
-    }
 #else /* platforms we have no IPv6 code for */
     msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
 #endif /* outer "if defined(TARGET_xxx)" conditional */
@@ -6467,6 +6463,24 @@  netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc
     const char *ifconfig_ip_local;
     struct argv argv = argv_new();
 
+    /* delete ipvX dns servers if any were set */
+    int len = ipv6 ? tt->options.dns6_len : tt->options.dns_len;
+    if (len > 0)
+    {
+        argv_printf(&argv,
+                    "%s%s interface %s delete dns %s all",
+                    get_win_sys_path(),
+                    NETSH_PATH_SUFFIX,
+                    ipv6 ? "ipv6" : "ipv4",
+                    tt->actual_name);
+        netsh_command(&argv, 1, M_WARN);
+    }
+
+    if (ipv6)
+    {
+        delete_route_connected_v6_net(tt, NULL);
+    }
+
     /* "store=active" is needed in Windows 8(.1) to delete the
      * address we added (pointed out by Cedric Tabary).
      */
@@ -6487,21 +6501,8 @@  netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc
                 ipv6 ? "ipv6" : "ipv4",
                 tt->actual_name,
                 ifconfig_ip_local);
-
     netsh_command(&argv, 1, M_WARN);
 
-    /* delete ipvX dns servers if any were set */
-    int len = ipv6 ? tt->options.dns6_len : tt->options.dns_len;
-    if (len > 0)
-    {
-        argv_printf(&argv,
-                    "%s%s interface %s delete dns %s all",
-                    get_win_sys_path(),
-                    NETSH_PATH_SUFFIX,
-                    ipv6 ? "ipv6" : "ipv4",
-                    tt->actual_name);
-        netsh_command(&argv, 1, M_WARN);
-    }
     argv_free(&argv);
 }
 
@@ -6514,16 +6515,18 @@  close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
 
     if (tt->did_ifconfig_ipv6_setup)
     {
-        /* remove route pointing to interface */
-        delete_route_connected_v6_net(tt, NULL);
-
-        if (tt->options.msg_channel)
+        if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
+        {
+            /* We didn't do ifconfig. */
+        }
+        else if (tt->options.msg_channel)
         {
-            do_address_service(false, AF_INET6, tt);
             if (tt->options.dns6_len > 0)
             {
                 do_dns_service(false, AF_INET6, tt);
             }
+            delete_route_connected_v6_net(tt, NULL);
+            do_address_service(false, AF_INET6, tt);
         }
         else
         {