]> git.proxmox.com Git - pve-common.git/commitdiff
tools: unused ports: optional address parameter
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Tue, 30 May 2017 13:30:09 +0000 (15:30 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 31 May 2017 05:32:17 +0000 (07:32 +0200)
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

index dd9cd0f8e5f0e4d0aed19ba3bb52a2cce4c2c723..30322b2888246a8b6ae1c139f370582de936db7e 100644 (file)
@@ -758,7 +758,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.
@@ -786,16 +786,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);
@@ -824,18 +826,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