From d01fc8a3280da739fbc83ca8fac61b5deb5e1c78 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Tue, 30 May 2017 15:30:09 +0200 Subject: [PATCH] tools: unused ports: optional address parameter While it should be impossible to bind to a wildcard address when the port is in use by any other address there's one case where this is allowed, and that's when the port is in use by an ipv6 address while trying to bind to an ipv4 wildcard. This currently happens when qemu finds ::1 for the 'localhost' we pass to qemu's spice address while we're resolving the local nodename via IPv4. --- src/PVE/Tools.pm | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm index 04f7469..675580e 100644 --- a/src/PVE/Tools.pm +++ b/src/PVE/Tools.pm @@ -757,7 +757,7 @@ sub wait_for_vnc_port { } sub next_unused_port { - my ($range_start, $range_end, $family) = @_; + my ($range_start, $range_end, $family, $address) = @_; # We use a file to register allocated ports. # Those registrations expires after $expiretime. @@ -785,16 +785,18 @@ sub next_unused_port { } my $newport; + my %sockargs = (Listen => 5, + ReuseAddr => 1, + Family => $family, + Proto => 0, + GetAddrInfoFlags => 0); + $sockargs{LocalAddr} = $address if defined($address); for (my $p = $range_start; $p < $range_end; $p++) { next if $ports->{$p}; # reserved - my $sock = IO::Socket::IP->new(Listen => 5, - LocalPort => $p, - ReuseAddr => 1, - Family => $family, - Proto => 0, - GetAddrInfoFlags => 0); + $sockargs{LocalPort} = $p; + my $sock = IO::Socket::IP->new(%sockargs); if ($sock) { close($sock); @@ -823,18 +825,18 @@ sub next_unused_port { } sub next_migrate_port { - my ($family) = @_; - return next_unused_port(60000, 60050, $family); + my ($family, $address) = @_; + return next_unused_port(60000, 60050, $family, $address); } sub next_vnc_port { - my ($family) = @_; - return next_unused_port(5900, 6000, $family); + my ($family, $address) = @_; + return next_unused_port(5900, 6000, $family, $address); } sub next_spice_port { - my ($family) = @_; - return next_unused_port(61000, 61099, $family); + my ($family, $address) = @_; + return next_unused_port(61000, 61099, $family, $address); } # NOTE: NFS syscall can't be interrupted, so alarm does