github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/libnetwork/portmapper/mapper_linux_test.go (about)

     1  package portmapper
     2  
     3  import (
     4  	"net"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/docker/docker/libnetwork/iptables"
     9  )
    10  
    11  func init() {
    12  	// override this func to mock out the proxy server
    13  	newProxy = newMockProxyCommand
    14  }
    15  
    16  func TestSetIptablesChain(t *testing.T) {
    17  	pm := New("")
    18  
    19  	c := &iptables.ChainInfo{
    20  		Name: "TEST",
    21  	}
    22  
    23  	if pm.chain != nil {
    24  		t.Fatal("chain should be nil at init")
    25  	}
    26  
    27  	pm.SetIptablesChain(c, "lo")
    28  	if pm.chain == nil {
    29  		t.Fatal("chain should not be nil after set")
    30  	}
    31  }
    32  
    33  func TestMapTCPPorts(t *testing.T) {
    34  	pm := New("")
    35  	dstIP1 := net.ParseIP("192.168.0.1")
    36  	dstIP2 := net.ParseIP("192.168.0.2")
    37  	dstAddr1 := &net.TCPAddr{IP: dstIP1, Port: 80}
    38  	dstAddr2 := &net.TCPAddr{IP: dstIP2, Port: 80}
    39  
    40  	srcAddr1 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")}
    41  	srcAddr2 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.2")}
    42  
    43  	addrEqual := func(addr1, addr2 net.Addr) bool {
    44  		return (addr1.Network() == addr2.Network()) && (addr1.String() == addr2.String())
    45  	}
    46  
    47  	if host, err := pm.Map(srcAddr1, dstIP1, 80, true); err != nil {
    48  		t.Fatalf("Failed to allocate port: %s", err)
    49  	} else if !addrEqual(dstAddr1, host) {
    50  		t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s",
    51  			dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network())
    52  	}
    53  
    54  	if _, err := pm.Map(srcAddr1, dstIP1, 80, true); err == nil {
    55  		t.Fatalf("Port is in use - mapping should have failed")
    56  	}
    57  
    58  	if _, err := pm.Map(srcAddr2, dstIP1, 80, true); err == nil {
    59  		t.Fatalf("Port is in use - mapping should have failed")
    60  	}
    61  
    62  	if _, err := pm.Map(srcAddr2, dstIP2, 80, true); err != nil {
    63  		t.Fatalf("Failed to allocate port: %s", err)
    64  	}
    65  
    66  	if pm.Unmap(dstAddr1) != nil {
    67  		t.Fatalf("Failed to release port")
    68  	}
    69  
    70  	if pm.Unmap(dstAddr2) != nil {
    71  		t.Fatalf("Failed to release port")
    72  	}
    73  
    74  	if pm.Unmap(dstAddr2) == nil {
    75  		t.Fatalf("Port already released, but no error reported")
    76  	}
    77  }
    78  
    79  func TestGetUDPKey(t *testing.T) {
    80  	addr := &net.UDPAddr{IP: net.ParseIP("192.168.1.5"), Port: 53}
    81  
    82  	key := getKey(addr)
    83  
    84  	if expected := "192.168.1.5:53/udp"; key != expected {
    85  		t.Fatalf("expected key %s got %s", expected, key)
    86  	}
    87  }
    88  
    89  func TestGetTCPKey(t *testing.T) {
    90  	addr := &net.TCPAddr{IP: net.ParseIP("192.168.1.5"), Port: 80}
    91  
    92  	key := getKey(addr)
    93  
    94  	if expected := "192.168.1.5:80/tcp"; key != expected {
    95  		t.Fatalf("expected key %s got %s", expected, key)
    96  	}
    97  }
    98  
    99  func TestGetUDPIPAndPort(t *testing.T) {
   100  	addr := &net.UDPAddr{IP: net.ParseIP("192.168.1.5"), Port: 53}
   101  
   102  	ip, port := getIPAndPort(addr)
   103  	if expected := "192.168.1.5"; ip.String() != expected {
   104  		t.Fatalf("expected ip %s got %s", expected, ip)
   105  	}
   106  
   107  	if ep := 53; port != ep {
   108  		t.Fatalf("expected port %d got %d", ep, port)
   109  	}
   110  }
   111  
   112  func TestMapUDPPorts(t *testing.T) {
   113  	pm := New("")
   114  	dstIP1 := net.ParseIP("192.168.0.1")
   115  	dstIP2 := net.ParseIP("192.168.0.2")
   116  	dstAddr1 := &net.UDPAddr{IP: dstIP1, Port: 80}
   117  	dstAddr2 := &net.UDPAddr{IP: dstIP2, Port: 80}
   118  
   119  	srcAddr1 := &net.UDPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")}
   120  	srcAddr2 := &net.UDPAddr{Port: 1080, IP: net.ParseIP("172.16.0.2")}
   121  
   122  	addrEqual := func(addr1, addr2 net.Addr) bool {
   123  		return (addr1.Network() == addr2.Network()) && (addr1.String() == addr2.String())
   124  	}
   125  
   126  	if host, err := pm.Map(srcAddr1, dstIP1, 80, true); err != nil {
   127  		t.Fatalf("Failed to allocate port: %s", err)
   128  	} else if !addrEqual(dstAddr1, host) {
   129  		t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s",
   130  			dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network())
   131  	}
   132  
   133  	if _, err := pm.Map(srcAddr1, dstIP1, 80, true); err == nil {
   134  		t.Fatalf("Port is in use - mapping should have failed")
   135  	}
   136  
   137  	if _, err := pm.Map(srcAddr2, dstIP1, 80, true); err == nil {
   138  		t.Fatalf("Port is in use - mapping should have failed")
   139  	}
   140  
   141  	if _, err := pm.Map(srcAddr2, dstIP2, 80, true); err != nil {
   142  		t.Fatalf("Failed to allocate port: %s", err)
   143  	}
   144  
   145  	if pm.Unmap(dstAddr1) != nil {
   146  		t.Fatalf("Failed to release port")
   147  	}
   148  
   149  	if pm.Unmap(dstAddr2) != nil {
   150  		t.Fatalf("Failed to release port")
   151  	}
   152  
   153  	if pm.Unmap(dstAddr2) == nil {
   154  		t.Fatalf("Port already released, but no error reported")
   155  	}
   156  }
   157  
   158  func TestMapAllPortsSingleInterface(t *testing.T) {
   159  	pm := New("")
   160  	dstIP1 := net.ParseIP("0.0.0.0")
   161  	srcAddr1 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")}
   162  
   163  	hosts := []net.Addr{}
   164  	var host net.Addr
   165  	var err error
   166  
   167  	defer func() {
   168  		for _, val := range hosts {
   169  			pm.Unmap(val)
   170  		}
   171  	}()
   172  
   173  	for i := 0; i < 10; i++ {
   174  		start, end := pm.Allocator.Begin, pm.Allocator.End
   175  		for i := start; i < end; i++ {
   176  			if host, err = pm.Map(srcAddr1, dstIP1, 0, true); err != nil {
   177  				t.Fatal(err)
   178  			}
   179  
   180  			hosts = append(hosts, host)
   181  		}
   182  
   183  		if _, err := pm.Map(srcAddr1, dstIP1, start, true); err == nil {
   184  			t.Fatalf("Port %d should be bound but is not", start)
   185  		}
   186  
   187  		for _, val := range hosts {
   188  			if err := pm.Unmap(val); err != nil {
   189  				t.Fatal(err)
   190  			}
   191  		}
   192  
   193  		hosts = []net.Addr{}
   194  	}
   195  }
   196  
   197  func TestMapTCPDummyListen(t *testing.T) {
   198  	pm := New("")
   199  	dstIP := net.ParseIP("0.0.0.0")
   200  	dstAddr := &net.TCPAddr{IP: dstIP, Port: 80}
   201  
   202  	// no-op for dummy
   203  	srcAddr := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")}
   204  
   205  	addrEqual := func(addr1, addr2 net.Addr) bool {
   206  		return (addr1.Network() == addr2.Network()) && (addr1.String() == addr2.String())
   207  	}
   208  
   209  	if host, err := pm.Map(srcAddr, dstIP, 80, false); err != nil {
   210  		t.Fatalf("Failed to allocate port: %s", err)
   211  	} else if !addrEqual(dstAddr, host) {
   212  		t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s",
   213  			dstAddr.String(), dstAddr.Network(), host.String(), host.Network())
   214  	}
   215  	if _, err := net.Listen("tcp", "0.0.0.0:80"); err == nil {
   216  		t.Fatal("Listen on mapped port without proxy should fail")
   217  	} else {
   218  		if !strings.Contains(err.Error(), "address already in use") {
   219  			t.Fatalf("Error should be about address already in use, got %v", err)
   220  		}
   221  	}
   222  	if _, err := net.Listen("tcp", "0.0.0.0:81"); err != nil {
   223  		t.Fatal(err)
   224  	}
   225  	if host, err := pm.Map(srcAddr, dstIP, 81, false); err == nil {
   226  		t.Fatalf("Bound port shouldn't be allocated, but it was on: %v", host)
   227  	} else {
   228  		if !strings.Contains(err.Error(), "address already in use") {
   229  			t.Fatalf("Error should be about address already in use, got %v", err)
   230  		}
   231  	}
   232  }
   233  
   234  func TestMapUDPDummyListen(t *testing.T) {
   235  	pm := New("")
   236  	dstIP := net.ParseIP("0.0.0.0")
   237  	dstAddr := &net.UDPAddr{IP: dstIP, Port: 80}
   238  
   239  	// no-op for dummy
   240  	srcAddr := &net.UDPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")}
   241  
   242  	addrEqual := func(addr1, addr2 net.Addr) bool {
   243  		return (addr1.Network() == addr2.Network()) && (addr1.String() == addr2.String())
   244  	}
   245  
   246  	if host, err := pm.Map(srcAddr, dstIP, 80, false); err != nil {
   247  		t.Fatalf("Failed to allocate port: %s", err)
   248  	} else if !addrEqual(dstAddr, host) {
   249  		t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s",
   250  			dstAddr.String(), dstAddr.Network(), host.String(), host.Network())
   251  	}
   252  	if _, err := net.ListenUDP("udp", &net.UDPAddr{IP: dstIP, Port: 80}); err == nil {
   253  		t.Fatal("Listen on mapped port without proxy should fail")
   254  	} else {
   255  		if !strings.Contains(err.Error(), "address already in use") {
   256  			t.Fatalf("Error should be about address already in use, got %v", err)
   257  		}
   258  	}
   259  	if _, err := net.ListenUDP("udp", &net.UDPAddr{IP: dstIP, Port: 81}); err != nil {
   260  		t.Fatal(err)
   261  	}
   262  	if host, err := pm.Map(srcAddr, dstIP, 81, false); err == nil {
   263  		t.Fatalf("Bound port shouldn't be allocated, but it was on: %v", host)
   264  	} else {
   265  		if !strings.Contains(err.Error(), "address already in use") {
   266  			t.Fatalf("Error should be about address already in use, got %v", err)
   267  		}
   268  	}
   269  }