[Openvpn-devel,v4] openvpnserv: keep IPv6 name servers in NRPT exclude rules

Message ID 20261112181513.27212-1-gert@greenie.muc.de
State New
Headers
Series [Openvpn-devel,v4] openvpnserv: keep IPv6 name servers in NRPT exclude rules |

Commit Message

Gert Doering Nov. 12, 2026, 6:15 p.m. UTC
  From: Razvan Cojocaru <razvanc@mailbox.org>

GetNrptExcludeData() stored the IPv6 name servers after the IPv4 list,
but the IPv4 size includes the terminating NUL. With both present, the
string ended at the IPv4 list and the IPv6 servers never made it into
GenericDNSServers. Join the lists by replacing that NUL with a
delimiter.

Both readers now start from an empty string: RegGetValueA() leaves the
buffer untouched when the value is missing, and a slot is reused after
an interface is skipped, so an interface without name servers could
inherit those of the skipped one. They also return the length of the
list without trailing delimiters, instead of the registry value size,
which can include NUL padding.

Broken since 0f3b7d17 ("win: implement --dns option support with
NRPT").

Change-Id: Ic602b125d857f1beed4af8661f522d339bc9e972
Signed-off-by: Razvan Cojocaru <razvanc@mailbox.org>
Acked-by: Heiko Hund <heiko@ist.eigentlich.net>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/2162
---

This change was reviewed on Gerrit and approved by at least one
developer. I request to merge it to master.

Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/2162
This mail reflects revision 4 of this Change.

Acked-by according to Gerrit (reflected above):
Heiko Hund <heiko@ist.eigentlich.net>
  

Patch

diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c
index 81205d6..1b76003 100644
--- a/src/openvpnserv/interactive.c
+++ b/src/openvpnserv/interactive.c
@@ -2128,6 +2128,24 @@ 
 }
 
 /**
+ * Remove trailing delimiters from a name server list
+ *
+ * @param  addrs      NUL-terminated list of addresses
+ *
+ * @return the size of the list in bytes, including the terminating NUL
+ */
+static DWORD
+TrimNameServers(PSTR addrs)
+{
+    size_t len = strlen(addrs);
+    while (len && (addrs[len - 1] == ',' || addrs[len - 1] == ' '))
+    {
+        addrs[--len] = '\0';
+    }
+    return (DWORD)len + 1;
+}
+
+/**
  * Get DNS server IPv4 addresses of an interface
  *
  * @param  itf_key    registry key of the IPv4 interface data
@@ -2140,6 +2158,7 @@ 
 static LSTATUS
 GetItfDnsServersV4(HKEY itf_key, PSTR addrs, PDWORD size)
 {
+    addrs[0] = '\0';
     addrs[*size - 1] = '\0';
 
     LSTATUS err;
@@ -2165,7 +2184,7 @@ 
 
     if (strchr(addrs, '.'))
     {
-        *size = s;
+        *size = TrimNameServers(addrs);
         return NO_ERROR;
     }
 
@@ -2178,13 +2197,15 @@ 
  *
  * @param  itf_key    registry key of the IPv6 interface data
  * @param  addrs      pointer to the buffer addresses are returned in
- * @param  size       pointer to the size of the buffer
+ * @param  size       pointer to the size of the buffer, contains the
+ *                    size of the addresses on return
  *
  * @return LSTATUS NO_ERROR on success, a Windows error code otherwise
  */
 static LSTATUS
 GetItfDnsServersV6(HKEY itf_key, PSTR addrs, PDWORD size)
 {
+    addrs[0] = '\0';
     addrs[*size - 1] = '\0';
 
     LSTATUS err;
@@ -2231,12 +2252,11 @@ 
             pos += addr_len;
             s -= (DWORD)addr_len;
         }
-        s = (DWORD)strlen(addrs) + 1;
     }
 
     if (strchr(addrs, ':'))
     {
-        *size = s;
+        *size = TrimNameServers(addrs);
         return NO_ERROR;
     }
 
@@ -2563,6 +2583,11 @@ 
                               __func__, itf_guid, err);
                 goto next_itf;
             }
+            if (v4_addrs_size && v6_addrs_size)
+            {
+                /* Join the lists: replace the v4 terminating NUL with a delimiter */
+                data[i].addresses[v4_addrs_size - 1] = ',';
+            }
         }
 
         if (v4_addrs_size || v6_addrs_size)