From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 59B6278370 for ; Thu, 29 Apr 2021 15:37:15 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 4E6C11DA66 for ; Thu, 29 Apr 2021 15:37:15 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 4E81F1DA4F for ; Thu, 29 Apr 2021 15:37:14 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 0FE73464BC for ; Thu, 29 Apr 2021 15:37:14 +0200 (CEST) From: Stoiko Ivanov To: pve-devel@lists.proxmox.com Date: Thu, 29 Apr 2021 15:37:01 +0200 Message-Id: <20210429133702.23584-2-s.ivanov@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210429133702.23584-1-s.ivanov@proxmox.com> References: <20210429133702.23584-1-s.ivanov@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.015 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [tools.pm] Subject: [pve-devel] [RFC common 1/1] tools: add get_wildcard_address X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Apr 2021 13:37:15 -0000 the get_wildcard_address sub returns the appropriate wildcard address: * '::' if the hosts has any v6 address (including link-local scoped) configured (i.e. default behavior without any modification to sysctl or kernel commandline) * '0.0.0.0' if ipv6 is disabled via sysctl or kernel commandline This should ensure the best behaviour for listening sockets in dual-stacked environments: * binding to '::' allows to connect via both v6 and v4 addresses (the latter are treated as v4-mapped-v6 addresses (::ffff:192.0.2.1)) * the current unconditional bind to '::' fails if AF_INET6 is not supported via kernel commandline setting [0]. * the previous approach of finding the family based on the node-name getaddrinfo result leads to the service only being available on v4 despite having a working v6 address configured, in case it's /etc/hosts entry points only to the v4 address. [0] on linux passing ipv6.disable=1 on the kernel commandline removes support for AF_INET6 sockets (setting the net.ipv6.conf.*.disable_ipv6 sysctls keeps support) Signed-off-by: Stoiko Ivanov --- src/PVE/Tools.pm | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm index 16ae3d2..fb520ce 100644 --- a/src/PVE/Tools.pm +++ b/src/PVE/Tools.pm @@ -4,8 +4,8 @@ use strict; use warnings; use POSIX qw(EINTR EEXIST EOPNOTSUPP); use IO::Socket::IP; -use Socket qw(AF_INET AF_INET6 AI_ALL AI_V4MAPPED AI_CANONNAME SOCK_DGRAM - IPPROTO_TCP); +use Socket qw(AF_INET AF_INET6 AI_ALL AI_V4MAPPED AI_CANONNAME AI_PASSIVE + AI_ADDRCONFIG NI_NUMERICHOST NI_NUMERICSERV SOCK_DGRAM IPPROTO_TCP); use IO::Select; use File::Basename; use File::Path qw(make_path); @@ -1405,6 +1405,24 @@ sub get_host_address_family { return $res[0]->{family}; } +# returns "::" if the host supports AF_INET6 else "0.0.0.0" +sub get_wildcard_address { + my %hints = ( + flags => AI_PASSIVE|AI_ADDRCONFIG, + ); + my ($err, @res) = Socket::getaddrinfo('', '0', \%hints); + die "failed to get address info for wildcard address: $err\n" if $err; + + my $sockaddr = $res[0]->{addr}; + if (my @v6support = grep {$_->{family} eq AF_INET6} @res) {; + $sockaddr = $v6support[0]->{addr}; + } + my $host; + ($err, $host) = Socket::getnameinfo($sockaddr, NI_NUMERICHOST|NI_NUMERICSERV); + die "failed to get name info for wildcard address: $err\n" if $err; + return $host; +} + # get the fully qualified domain name of a host # same logic as hostname(1): The FQDN is the name getaddrinfo(3) returns, # given a nodename as a parameter -- 2.20.1