From patchwork Fri Mar 10 05:08:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiko Hund X-Patchwork-Id: 3120 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7300:2310:b0:9f:bfa4:120f with SMTP id r16csp874449dye; Thu, 9 Mar 2023 21:09:06 -0800 (PST) X-Google-Smtp-Source: AK7set97cAj9xP19ql7LNH74PPa35OezqIKXaGAeYL2u7kAVg44+EEdmAx8cHTzmHZ9TJCZ47bmJ X-Received: by 2002:a05:6a20:9388:b0:cd:9974:5d8b with SMTP id x8-20020a056a20938800b000cd99745d8bmr28890965pzh.29.1678424946234; Thu, 09 Mar 2023 21:09:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1678424946; cv=none; d=google.com; s=arc-20160816; b=aDcGMVTDlhghSsYfCZWhsVg5AXEscNcojGt8gAWj3CLPI2sV+PJHrDbiLcabbKuQGg H9nstbZNP8VGryUHPkvFlM+YHBG1FdoaDG8VCc0mXBnYO1reCfpGIgx/ijCF/6PWrsvP cVfrcOmozuPid1BmCSXBdXfEu6BpN9SDhs60QBNK21lQHqhFTv40b2Te7AFOB+10N3yJ SPotBoV4Un9qWvVwehXs0Zyt68NWAqDnCTH27k9Sei21KqflXdeH2+/BAaUoFz1Oj5mI Upa8BT6/3CS8F9x2zsO7VWf6kvrPqukmcZgd5EJBoZ0ZGzeW1eNVfxd8xiu3ct2fE8dJ xqkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:message-id:date:to:from:dkim-signature:dkim-signature; bh=d315DWDV8AK77xNR9lE8RhDJQqQESVcY43/2O2YemEs=; b=xs7YOM/MMEbgLtTHdlFw+0oUumcXGwH4nmED9Gboce2xvUMHi3SJ1BiBdC2vZDinHf wxL3UGwEZSFFEAJ2l794nmwveUsOuxa+ryMrz/VTkdqKv2CPS0lctZHLuu7no7ifCbjy aHz08fbuqCO6a3hho7VD/D1Nlwsr8XErgLgjRTUViftyuSpVN+ENn5duFbfxGEqPm/gd Ghu9pMXAKusowmbwdpPRN+il13Ouo8By8ApXGZ5Oyz0hCfWQTKVfOBotuoQQTjPJykAC q1Le018IKtS5cj1xMIVF+b+Xt6txZeskhi9Ww5fk01ItGnaPHFUCC/0xKwqbMg2tf4Y3 gdzw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=QCIr5FLI; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=gbCr3DhM; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id z15-20020a63e54f000000b00502d8ca5383si1035624pgj.820.2023.03.09.21.09.05 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Mar 2023 21:09:06 -0800 (PST) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=QCIr5FLI; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=gbCr3DhM; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1paUzf-0006hl-0N; Fri, 10 Mar 2023 05:08:39 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1paUzc-0006hZ-CU for openvpn-devel@lists.sourceforge.net; Fri, 10 Mar 2023 05:08:36 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:Message-Id: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=cHRNG0/NMBVN9eG5+4PONo53576TJMWx6K0YMRVymMk=; b=QCIr5FLIZZVoaqMreoDYe6I96y QwpL/6jcSZ2aMI9B44tXFXyJhzUTCB5I0W1JXWFMM5qbeRuUonmcDz3PmNljnNJNGngdt/zaJGLM5 HyI4WlHF9Iu8qIAAEEM22scZ5hmIwfnk+gO3ns6sIDTnuvl7BxJGkxpXV4DQGetaw/1I=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject:To:From: Sender:Reply-To:Cc:Content-Type:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=cHRNG0/NMBVN9eG5+4PONo53576TJMWx6K0YMRVymMk=; b=g bCr3DhMXv0JTF154CiRCKG9AKyQmqXktIFQ9iG4eQjec8qeYlmX3ZEKIBDEf6UY2hcJr4BaNumd06 UuzKQ+MB4sp3/GkXcx1zmccrrxXjYDQSce5hKa8aELyh53k0fwssK2JWfiaJgJp0YFRCsXQMAMT/z DkmvH/Fkwi0q0dWg=; Received: from exit0.net ([85.25.119.185]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1paUzY-0039vy-EL for openvpn-devel@lists.sourceforge.net; Fri, 10 Mar 2023 05:08:36 +0000 Received: from coruscant.fritz.box (i577BF783.versanet.de [87.123.247.131]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by exit0.net (Postfix) with ESMTPSA id 500E9648024C for ; Fri, 10 Mar 2023 06:08:19 +0100 (CET) From: Heiko Hund To: openvpn-devel@lists.sourceforge.net Date: Fri, 10 Mar 2023 06:08:12 +0100 Message-Id: <20230310050814.67246-1-heiko@ist.eigentlich.net> X-Mailer: git-send-email 2.37.2 MIME-Version: 1.0 X-Spam-Score: 0.2 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: This change allows configuration of more than one address per family for a DNS server. This way you can specify backup addresses in case a server is not reachable. During closer inspection of the vari [...] Content analysis details: (0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-Headers-End: 1paUzY-0039vy-EL Subject: [Openvpn-devel] [PATCH 1/3] dns option: allow up to eight addresses per server X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1759956116384797403?= X-GMAIL-MSGID: =?utf-8?q?1759956116384797403?= This change allows configuration of more than one address per family for a DNS server. This way you can specify backup addresses in case a server is not reachable. During closer inspection of the various DNS backend in supported operation systems it turned out that our previous idea to have more than one DNS server applied in order of priority does not work in most cases. Thus it became important to be able to specify backup addresses. So instead of doing dns server 1 address 1.2.3.4 2001::1 dns server 2 address 5.6.7.8 2001::2 to specify a backup addresses, this is now done like so: dns server 1 address 1.2.3.4 2001::1 dns server 1 address 5.6.7.8 2001::2 or you can have all the addresses on one line if you like: dns server 1 address 1.2.3.4 2001::1 2001::2 5.6.7.8 This also saves some repeated options when (backup) servers share the same settings like "resolve-domains" compared to the originally intended way. The order in which addresses are given is retained for backends that support this sort of cross address family ordering. Change-Id: I9bd3d6d05da4e61a5fa05c0e455fc770b1fe186a Signed-off-by: Heiko Hund Acked-By: Arne Schwabe --- doc/man-sections/client-options.rst | 9 ++-- doc/man-sections/script-options.rst | 6 +-- src/openvpn/dns.c | 83 +++++++++++++++-------------- src/openvpn/dns.h | 18 ++++--- src/openvpn/options.c | 76 ++++++++++++++------------ 5 files changed, 103 insertions(+), 89 deletions(-) diff --git a/doc/man-sections/client-options.rst b/doc/man-sections/client-options.rst index 974cc992..fe9ffa6a 100644 --- a/doc/man-sections/client-options.rst +++ b/doc/man-sections/client-options.rst @@ -168,7 +168,7 @@ configuration. :: dns search-domains domain [domain ...] - dns server n address addr[:port] [addr[:port]] + dns server n address addr[:port] [addr[:port] ...] dns server n resolve-domains|exclude-domains domain [domain ...] dns server n dnssec yes|optional|no dns server n transport DoH|DoT|plain @@ -186,9 +186,10 @@ configuration. lower numbers come first. DNS servers being pushed to a client replace already configured DNS servers with the same server id. - The ``address`` option configures the IPv4 and / or IPv6 address of - the DNS server. Optionally a port can be appended after a colon. IPv6 - addresses need to be enclosed in brackets if a port is appended. + The ``address`` option configures the IPv4 and / or IPv6 address(es) of + the DNS server. Up to eight addresses can be specified per DNS server. + Optionally a port can be appended after a colon. IPv6 addresses need to + be enclosed in brackets if a port is appended. The ``resolve-domains`` and ``exclude-domains`` options take one or more DNS domains which are explicitly resolved or explicitly not resolved diff --git a/doc/man-sections/script-options.rst b/doc/man-sections/script-options.rst index 3d2c7445..d73231ed 100644 --- a/doc/man-sections/script-options.rst +++ b/doc/man-sections/script-options.rst @@ -660,10 +660,8 @@ instances. :: dns_search_domain_{n} - dns_server_{n}_address4 - dns_server_{n}_port4 - dns_server_{n}_address6 - dns_server_{n}_port6 + dns_server_{n}_address_{m} + dns_server_{n}_port_{m} dns_server_{n}_resolve_domain_{m} dns_server_{n}_exclude_domain_{m} dns_server_{n}_dnssec diff --git a/src/openvpn/dns.c b/src/openvpn/dns.c index 9f2a7d5e..b7808db1 100644 --- a/src/openvpn/dns.c +++ b/src/openvpn/dns.c @@ -64,7 +64,7 @@ dns_server_addr_parse(struct dns_server *server, const char *addr) char addrcopy[INET6_ADDRSTRLEN] = {0}; size_t copylen = 0; in_port_t port = 0; - int af; + sa_family_t af; char *first_colon = strchr(addr, ':'); char *last_colon = strrchr(addr, ':'); @@ -115,21 +115,26 @@ dns_server_addr_parse(struct dns_server *server, const char *addr) return false; } + if (server->addr_count >= SIZE(server->addr)) + { + return false; + } + if (ai->ai_family == AF_INET) { struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr; - server->addr4_defined = true; - server->addr4.s_addr = ntohl(sin->sin_addr.s_addr); - server->port4 = port; + server->addr[server->addr_count].in.a4.s_addr = ntohl(sin->sin_addr.s_addr); } else { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr; - server->addr6_defined = true; - server->addr6 = sin6->sin6_addr; - server->port6 = port; + server->addr[server->addr_count].in.a6 = sin6->sin6_addr; } + server->addr[server->addr_count].family = af; + server->addr[server->addr_count].port = port; + server->addr_count += 1; + freeaddrinfo(ai); return true; } @@ -197,7 +202,7 @@ dns_options_verify(int msglevel, const struct dns_options *o) o->servers ? o->servers : o->servers_prepull; while (server) { - if (!server->addr4_defined && !server->addr6_defined) + if (server->addr_count == 0) { msg(msglevel, "ERROR: dns server %ld does not have an address assigned", server->priority); return false; @@ -376,26 +381,23 @@ setenv_dns_options(const struct dns_options *o, struct env_set *es) for (i = 1, s = o->servers; s != NULL; i++, s = s->next) { - if (s->addr4_defined) - { - setenv_dns_option(es, "dns_server_%d_address4", i, -1, - print_in_addr_t(s->addr4.s_addr, 0, &gc)); - } - if (s->port4) - { - setenv_dns_option(es, "dns_server_%d_port4", i, -1, - print_in_port_t(s->port4, &gc)); - } - - if (s->addr6_defined) - { - setenv_dns_option(es, "dns_server_%d_address6", i, -1, - print_in6_addr(s->addr6, 0, &gc)); - } - if (s->port6) + for (j = 0; j < s->addr_count; ++j) { - setenv_dns_option(es, "dns_server_%d_port6", i, -1, - print_in_port_t(s->port6, &gc)); + if (s->addr[j].family == AF_INET) + { + setenv_dns_option(es, "dns_server_%d_address_%d", i, j + 1, + print_in_addr_t(s->addr[j].in.a4.s_addr, 0, &gc)); + } + else + { + setenv_dns_option(es, "dns_server_%d_address_%d", i, j + 1, + print_in6_addr(s->addr[j].in.a6, 0, &gc)); + } + if (s->addr[j].port) + { + setenv_dns_option(es, "dns_server_%d_port_%d", i, j + 1, + print_in_port_t(s->addr[j].port, &gc)); + } } if (s->domains) @@ -439,30 +441,29 @@ show_dns_options(const struct dns_options *o) { msg(D_SHOW_PARMS, " DNS server #%d:", i++); - if (server->addr4_defined) + for (int j = 0; j < server->addr_count; ++j) { - const char *addr = print_in_addr_t(server->addr4.s_addr, 0, &gc); - if (server->port4) + const char *addr; + const char *fmt_port; + if (server->addr[j].family == AF_INET) { - const char *port = print_in_port_t(server->port4, &gc); - msg(D_SHOW_PARMS, " address4 = %s:%s", addr, port); + addr = print_in_addr_t(server->addr[j].in.a4.s_addr, 0, &gc); + fmt_port = " address = %s:%s"; } else { - msg(D_SHOW_PARMS, " address4 = %s", addr); + addr = print_in6_addr(server->addr[j].in.a6, 0, &gc); + fmt_port = " address = [%s]:%s"; } - } - if (server->addr6_defined) - { - const char *addr = print_in6_addr(server->addr6, 0, &gc); - if (server->port6) + + if (server->addr[j].port) { - const char *port = print_in_port_t(server->port6, &gc); - msg(D_SHOW_PARMS, " address6 = [%s]:%s", addr, port); + const char *port = print_in_port_t(server->addr[j].port, &gc); + msg(D_SHOW_PARMS, fmt_port, addr, port); } else { - msg(D_SHOW_PARMS, " address6 = %s", addr); + msg(D_SHOW_PARMS, " address = %s", addr); } } diff --git a/src/openvpn/dns.h b/src/openvpn/dns.h index 03a894f2..162dec12 100644 --- a/src/openvpn/dns.h +++ b/src/openvpn/dns.h @@ -52,15 +52,21 @@ struct dns_domain { const char *name; }; +struct dns_server_addr +{ + union { + struct in_addr a4; + struct in6_addr a6; + } in; + sa_family_t family; + in_port_t port; +}; + struct dns_server { struct dns_server *next; long priority; - bool addr4_defined; - bool addr6_defined; - struct in_addr addr4; - struct in6_addr addr6; - in_port_t port4; - in_port_t port6; + size_t addr_count; + struct dns_server_addr addr[8]; struct dns_domain *domains; enum dns_domain_type domain_type; enum dns_security dnssec; diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 9105449c..17ce2b05 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -512,7 +512,7 @@ static const char usage_message[] = " each filter is applied in the order of appearance.\n" "--dns server