Browse code

Treat dhcp-option DNS6 and DNS identical

OpenVPN3 accepts both IPv4 and IPv6 with option-dhcp DNS but throws
an error for option-dhcp DNS6.

This patch makes OpenVPN2 accept IPv4/IPv6 for both DNS and DNS6

V2: Put IPv6 parsing logic into own function similar as for for IPv4 DNS
V3: more documentation / help message adjustments

Acked-by: Selva Nair <selva.nair@gmail.com>
Message-Id: <1517391662-21325-1-git-send-email-arne@rfc2549.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg16413.html

Signed-off-by: Gert Doering <gert@greenie.muc.de>

Arne Schwabe authored on 2018/01/31 18:41:02
Showing 2 changed files
... ...
@@ -5852,17 +5852,13 @@ across the VPN.
5852 5852
 Set Connection\-specific DNS Suffix.
5853 5853
 
5854 5854
 .B DNS addr \-\-
5855
-Set primary domain name server IPv4 address.  Repeat
5855
+Set primary domain name server IPv4 or IPv6 address.  Repeat
5856 5856
 this option to set secondary DNS server addresses.
5857 5857
 
5858
-.B DNS6 addr \-\-
5859
-Set primary domain name server IPv6 address.  Repeat
5860
-this option to set secondary DNS server IPv6 addresses.
5861
-
5862
-Note: currently this is handled using netsh (the
5863
-existing DHCP code can only do IPv4 DHCP, and that protocol only
5864
-permits IPv4 addresses anywhere).  The option will be put into the
5865
-environment, so an
5858
+Note: DNS IPv6 servers are currently set using netsh (the existing
5859
+DHCP code can only do IPv4 DHCP, and that protocol only permits IPv4
5860
+addresses anywhere).  The option will be put into the environment, so
5861
+an
5866 5862
 .B \-\-up
5867 5863
 script could act upon it if needed.
5868 5864
 
... ...
@@ -703,8 +703,7 @@ static const char usage_message[] =
703 703
     "                    which allow multiple addresses,\n"
704 704
     "                    --dhcp-option must be repeated.\n"
705 705
     "                    DOMAIN name : Set DNS suffix\n"
706
-    "                    DNS addr    : Set domain name server address(es) (IPv4)\n"
707
-    "                    DNS6 addr   : Set domain name server address(es) (IPv6)\n"
706
+    "                    DNS addr    : Set domain name server address(es) (IPv4 and IPv6)\n"
708 707
     "                    NTP         : Set NTP server address(es)\n"
709 708
     "                    NBDD        : Set NBDD server address(es)\n"
710 709
     "                    WINS addr   : Set WINS server address(es)\n"
... ...
@@ -1226,6 +1225,20 @@ show_tuntap_options(const struct tuntap_options *o)
1226 1226
 
1227 1227
 #if defined(_WIN32) || defined(TARGET_ANDROID)
1228 1228
 static void
1229
+dhcp_option_dns6_parse(const char *parm, struct in6_addr *dns6_list, int *len, int msglevel)
1230
+{
1231
+    struct in6_addr addr;
1232
+    if (*len >= N_DHCP_ADDR)
1233
+    {
1234
+        msg(msglevel, "--dhcp-option DNS: maximum of %d IPv6 dns servers can be specified",
1235
+            N_DHCP_ADDR);
1236
+    }
1237
+    else if (get_ipv6_addr(parm, &addr, NULL, msglevel))
1238
+    {
1239
+        dns6_list[(*len)++] = addr;
1240
+    }
1241
+}
1242
+static void
1229 1243
 dhcp_option_address_parse(const char *name, const char *parm, in_addr_t *array, int *len, int msglevel)
1230 1244
 {
1231 1245
     if (*len >= N_DHCP_ADDR)
... ...
@@ -7059,6 +7072,7 @@ add_option(struct options *options,
7059 7059
     {
7060 7060
         struct tuntap_options *o = &options->tuntap_options;
7061 7061
         VERIFY_PERMISSION(OPT_P_IPWIN32);
7062
+        bool ipv6dns = false;
7062 7063
 
7063 7064
         if (streq(p[1], "DOMAIN") && p[2])
7064 7065
         {
... ...
@@ -7079,22 +7093,17 @@ add_option(struct options *options,
7079 7079
             }
7080 7080
             o->netbios_node_type = t;
7081 7081
         }
7082
-        else if (streq(p[1], "DNS") && p[2])
7082
+        else if ((streq(p[1], "DNS") || streq(p[1], "DNS6")) && p[2] && (!strstr(p[2], ":") || ipv6_addr_safe(p[2])))
7083 7083
         {
7084
-            dhcp_option_address_parse("DNS", p[2], o->dns, &o->dns_len, msglevel);
7085
-        }
7086
-        else if (streq(p[1], "DNS6") && p[2] && ipv6_addr_safe(p[2]))
7087
-        {
7088
-            struct in6_addr addr;
7089
-            foreign_option(options, p, 3, es);
7090
-            if (o->dns6_len >= N_DHCP_ADDR)
7084
+            if (strstr(p[2], ":"))
7091 7085
             {
7092
-                msg(msglevel, "--dhcp-option DNS6: maximum of %d dns servers can be specified",
7093
-                    N_DHCP_ADDR);
7086
+                ipv6dns=true;
7087
+                foreign_option(options, p, 3, es);
7088
+                dhcp_option_dns6_parse(p[2], o->dns6, &o->dns6_len, msglevel);
7094 7089
             }
7095
-            else if (get_ipv6_addr(p[2], &addr, NULL, msglevel))
7090
+            else
7096 7091
             {
7097
-                o->dns6[o->dns6_len++] = addr;
7092
+                dhcp_option_address_parse("DNS", p[2], o->dns, &o->dns_len, msglevel);
7098 7093
             }
7099 7094
         }
7100 7095
         else if (streq(p[1], "WINS") && p[2])
... ...
@@ -7122,7 +7131,7 @@ add_option(struct options *options,
7122 7122
         /* flag that we have options to give to the TAP driver's DHCPv4 server
7123 7123
          *  - skipped for "DNS6", as that's not a DHCPv4 option
7124 7124
          */
7125
-        if (!streq(p[1], "DNS6"))
7125
+        if (!ipv6dns)
7126 7126
         {
7127 7127
             o->dhcp_options = true;
7128 7128
         }