From: Thomas Lamprecht Date: Tue, 2 May 2017 09:51:19 +0000 (+0200) Subject: Network: add helpers to resolve hostnames to IPs X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=commitdiff_plain;h=87aa00de73e579ebc10a49a04c7d633953a48510 Network: add helpers to resolve hostnames to IPs Add addr_to_ip and get_ip_from_hostname helpers to PVE::Network The first helper, addr_to_ip, is based on Wolfgangs version of this [0] I just moved it from PVE::Tools to PVE::Network, as it seems a more fitting place. It uses getnameinfo to extract information from the paddr parameter, which is sockaddr struct It gets used in the second helper and in a bug fix series from Wolfgang [1] The second helper, get_ip_from_hostname, resolves an hostname to an IP and checks if it isn't one from the for loopback reserved 127/8 subnet. It will be used in get_remote_nodeip from PVE::CLuster and for a bugfix in pvecm. [0]: http://pve.proxmox.com/pipermail/pve-devel/2017-April/026099.html [1]: http://pve.proxmox.com/pipermail/pve-devel/2017-April/026098.html Signed-off-by: Thomas Lamprecht --- diff --git a/src/PVE/Network.pm b/src/PVE/Network.pm index c8bd8ab..babc204 100644 --- a/src/PVE/Network.pm +++ b/src/PVE/Network.pm @@ -7,6 +7,7 @@ use PVE::ProcFSTools; use PVE::INotify; use File::Basename; use IO::Socket::IP; +use Socket qw(NI_NUMERICHOST NI_NUMERICSERV); use POSIX qw(ECONNREFUSED); use Net::IP; @@ -575,6 +576,37 @@ sub get_local_ip_from_cidr { return $IPs; } +sub addr_to_ip { + my ($addr) = @_; + my ($err, $host, $port) = Socket::getnameinfo($addr, NI_NUMERICHOST | NI_NUMERICSERV); + die "failed to get numerical host address: $err\n" if $err; + return ($host, $port) if wantarray; + return $host; +} + +sub get_ip_from_hostname { + my ($hostname, $noerr) = @_; + + my ($family, $ip); + + eval { + my @res = PVE::Tools::getaddrinfo_all($hostname); + $family = $res[0]->{family}; + $ip = addr_to_ip($res[0]->{addr}) + }; + if ($@) { + die "hostname lookup failed:\n$@" if !$noerr; + return undef; + } + + if ($ip =~ m/^127\.|^::1$/) { + die "hostname lookup failed - got local IP address ($hostname = $ip)\n" if !$noerr; + return undef; + } + + return wantarray ? ($ip, $family) : $ip; +} + sub lock_network { my ($code, @param) = @_; my $res = lock_file('/var/lock/pve-network.lck', 10, $code, @param);