diff --git a/daemon/libnetwork/service_linux.go b/daemon/libnetwork/service_linux.go index 0058552169..b167502a23 100644 --- a/daemon/libnetwork/service_linux.go +++ b/daemon/libnetwork/service_linux.go @@ -552,6 +552,7 @@ func plumbIngressPortsProxy(ingressPorts []*PortConfig) { if err != nil { log.G(context.TODO()).Warnf("failed to create proxy for port %s: %v", iPort, err) + continue } ingressProxyTbl[portSpec] = l diff --git a/daemon/libnetwork/service_linux_test.go b/daemon/libnetwork/service_linux_test.go new file mode 100644 index 0000000000..09561538fb --- /dev/null +++ b/daemon/libnetwork/service_linux_test.go @@ -0,0 +1,43 @@ +//go:build linux + +package libnetwork + +import ( + "fmt" + "io" + "net" + "strings" + "testing" + + "gotest.tools/v3/assert" +) + +func TestCloseIngressPortsProxyAfterBindFailure(t *testing.T) { + ingressMu.Lock() + defer ingressMu.Unlock() + + origTbl := ingressProxyTbl + t.Cleanup(func() { + ingressProxyTbl = origTbl + }) + ingressProxyTbl = make(map[string]io.Closer) + + blocker, err := net.ListenUDP("udp", &net.UDPAddr{Port: 0}) + assert.NilError(t, err) + defer blocker.Close() + + port := uint32(blocker.LocalAddr().(*net.UDPAddr).Port) + ingressPort := &PortConfig{ + Protocol: ProtocolUDP, + PublishedPort: port, + } + + plumbIngressPortsProxy([]*PortConfig{ingressPort}) + + portSpec := fmt.Sprintf("%d/%s", ingressPort.PublishedPort, strings.ToLower(ingressPort.Protocol.String())) + if _, ok := ingressProxyTbl[portSpec]; ok { + t.Fatal("bind failure must not store a listener in ingressProxyTbl") + } + + closeIngressPortsProxy([]*PortConfig{ingressPort}) +}