Skip to content

Commit 3f90ff3

Browse files
committed
libpod: bind both IPv4 and IPv6 addresses with dual-stack wildcard
Currently podman only binds IPv4 wildcard address. But since golang net.Listen("tcp",) listens on all IPv4 and IPv6 addresses, we (intentionally) handle both 4 and 6 here. But the downside was that you could still explicitly request an IPv6 (::) wildcard along with a dual-stack("") wildcard causing netavark to leak nftable rules. This change handles both IPv4(0.0.0.0) and IPv6(::) when no address is passed, and throws EADDRINUSE if an explicit IPv4 or IPv6 is requested on top of dual-stack wildcard. Signed-off-by: Danish Prakash <[email protected]>
1 parent 7fecff5 commit 3f90ff3

File tree

1 file changed

+29
-14
lines changed

1 file changed

+29
-14
lines changed

libpod/oci_util.go

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,39 @@ func bindPorts(ports []types.PortMapping) ([]*os.File, error) {
3232
var files []*os.File
3333
sctpWarning := true
3434
for _, port := range ports {
35-
isV6 := net.ParseIP(port.HostIP).To4() == nil
36-
if port.HostIP == "" {
37-
isV6 = false
38-
}
3935
protocols := strings.SplitSeq(port.Protocol, ",")
4036
for protocol := range protocols {
4137
for i := uint16(0); i < port.Range; i++ {
42-
f, err := bindPort(protocol, port.HostIP, port.HostPort+i, isV6, &sctpWarning)
43-
if err != nil {
44-
// close all open ports in case of early error so we do not
45-
// rely garbage collector to close them
46-
for _, f := range files {
47-
f.Close()
38+
if port.HostIP == "" {
39+
f4, err := bindPort(protocol, "", port.HostPort+i, false, &sctpWarning)
40+
if err != nil {
41+
for _, f := range files {
42+
f.Close()
43+
}
44+
return nil, fmt.Errorf("failed to bind IPv4 port: %w", err)
45+
}
46+
if f4 != nil {
47+
files = append(files, f4)
48+
}
49+
50+
f6, err := bindPort(protocol, "", port.HostPort+i, true, &sctpWarning)
51+
if err != nil {
52+
logrus.Warnf("Failed to bind IPv6 for port %d, continuing with IPv4 only: %v", port.HostPort+i, err)
53+
} else if f6 != nil {
54+
files = append(files, f6)
55+
}
56+
} else {
57+
isV6 := net.ParseIP(port.HostIP).To4() == nil
58+
f, err := bindPort(protocol, port.HostIP, port.HostPort+i, isV6, &sctpWarning)
59+
if err != nil {
60+
for _, f := range files {
61+
f.Close()
62+
}
63+
return nil, err
64+
}
65+
if f != nil {
66+
files = append(files, f)
4867
}
49-
return nil, err
50-
}
51-
if f != nil {
52-
files = append(files, f)
5368
}
5469
}
5570
}

0 commit comments

Comments
 (0)