Browse code

Deallocate port before trying to delete iptables chain

Fixes #7954
Signed-off-by: Alexandr Morozov <lk4d4math@gmail.com>

Alexandr Morozov authored on 2014/09/09 21:47:25
Showing 2 changed files
... ...
@@ -4,11 +4,11 @@ import (
4 4
 	"errors"
5 5
 	"fmt"
6 6
 	"net"
7
-	"strings"
8 7
 	"sync"
9 8
 
10 9
 	"github.com/docker/docker/daemon/networkdriver/portallocator"
11 10
 	"github.com/docker/docker/pkg/iptables"
11
+	"github.com/docker/docker/pkg/log"
12 12
 )
13 13
 
14 14
 type mapping struct {
... ...
@@ -127,10 +127,7 @@ func Unmap(host net.Addr) error {
127 127
 	containerIP, containerPort := getIPAndPort(data.container)
128 128
 	hostIP, hostPort := getIPAndPort(data.host)
129 129
 	if err := forward(iptables.Delete, data.proto, hostIP, hostPort, containerIP.String(), containerPort); err != nil {
130
-		// skip "no chain" errors because we can safely release port in this case
131
-		if !strings.Contains(err.Error(), "No chain/target/match by that name") {
132
-			return err
133
-		}
130
+		log.Errorf("Error on iptables delete: %s", err)
134 131
 	}
135 132
 
136 133
 	switch a := host.(type) {
... ...
@@ -139,7 +136,6 @@ func Unmap(host net.Addr) error {
139 139
 	case *net.UDPAddr:
140 140
 		return portallocator.ReleasePort(a.IP, "udp", a.Port)
141 141
 	}
142
-
143 142
 	return nil
144 143
 }
145 144
 
... ...
@@ -1846,3 +1846,32 @@ func TestRunNetworkNotInitializedNoneMode(t *testing.T) {
1846 1846
 	deleteAllContainers()
1847 1847
 	logDone("run - network must not be initialized in 'none' mode")
1848 1848
 }
1849
+
1850
+func TestRunDeallocatePortOnMissingIptablesRule(t *testing.T) {
1851
+	cmd := exec.Command(dockerBinary, "run", "-d", "-p", "23:23", "busybox", "top")
1852
+	out, _, err := runCommandWithOutput(cmd)
1853
+	if err != nil {
1854
+		t.Fatal(err)
1855
+	}
1856
+	id := strings.TrimSpace(out)
1857
+	ip, err := inspectField(id, "NetworkSettings.IPAddress")
1858
+	if err != nil {
1859
+		t.Fatal(err)
1860
+	}
1861
+	iptCmd := exec.Command("iptables", "-D", "FORWARD", "-d", fmt.Sprintf("%s/32", ip),
1862
+		"!", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-m", "tcp", "--dport", "23", "-j", "ACCEPT")
1863
+	out, _, err = runCommandWithOutput(iptCmd)
1864
+	if err != nil {
1865
+		t.Fatal(err, out)
1866
+	}
1867
+	if err := deleteContainer(id); err != nil {
1868
+		t.Fatal(err)
1869
+	}
1870
+	cmd = exec.Command(dockerBinary, "run", "-d", "-p", "23:23", "busybox", "top")
1871
+	out, _, err = runCommandWithOutput(cmd)
1872
+	if err != nil {
1873
+		t.Fatal(err, out)
1874
+	}
1875
+	deleteAllContainers()
1876
+	logDone("run - port should be deallocated even on iptables error")
1877
+}