diff options
Diffstat (limited to 'pkg/tcpip/transport/udp/udp_test.go')
-rw-r--r-- | pkg/tcpip/transport/udp/udp_test.go | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index c1c099900..4700193c2 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -112,7 +112,7 @@ func (c *testContext) cleanup() { } } -func (c *testContext) createV6Endpoint(v4only bool) { +func (c *testContext) createV6Endpoint(v6only bool) { var err *tcpip.Error c.ep, err = c.s.NewEndpoint(udp.ProtocolNumber, ipv6.ProtocolNumber, &c.wq) if err != nil { @@ -120,7 +120,7 @@ func (c *testContext) createV6Endpoint(v4only bool) { } var v tcpip.V6OnlyOption - if v4only { + if v6only { v = 1 } if err := c.ep.SetSockOpt(v); err != nil { @@ -296,6 +296,76 @@ func testV4Read(c *testContext) { } } +func TestBindEphemeralPort(t *testing.T) { + c := newDualTestContext(t, defaultMTU) + defer c.cleanup() + + c.createV6Endpoint(false) + + if err := c.ep.Bind(tcpip.FullAddress{}, nil); err != nil { + t.Fatalf("ep.Bind(...) failed: %v", err) + } +} + +func TestBindReservedPort(t *testing.T) { + c := newDualTestContext(t, defaultMTU) + defer c.cleanup() + + c.createV6Endpoint(false) + + if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil { + c.t.Fatalf("Connect failed: %v", err) + } + + addr, err := c.ep.GetLocalAddress() + if err != nil { + t.Fatalf("GetLocalAddress failed: %v", err) + } + + // We can't bind the address reserved by the connected endpoint above. + { + ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv6.ProtocolNumber, &c.wq) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + defer ep.Close() + if got, want := ep.Bind(addr, nil), tcpip.ErrPortInUse; got != want { + t.Fatalf("got ep.Bind(...) = %v, want = %v", got, want) + } + } + + func() { + ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &c.wq) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + defer ep.Close() + // We can't bind ipv4-any on the port reserved by the connected endpoint + // above, since the endpoint is dual-stack. + if got, want := ep.Bind(tcpip.FullAddress{Port: addr.Port}, nil), tcpip.ErrPortInUse; got != want { + t.Fatalf("got ep.Bind(...) = %v, want = %v", got, want) + } + // We can bind an ipv4 address on this port, though. + if err := ep.Bind(tcpip.FullAddress{Addr: stackAddr, Port: addr.Port}, nil); err != nil { + t.Fatalf("ep.Bind(...) failed: %v", err) + } + }() + + // Once the connected endpoint releases its port reservation, we are able to + // bind ipv4-any once again. + c.ep.Close() + func() { + ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &c.wq) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + defer ep.Close() + if err := ep.Bind(tcpip.FullAddress{Port: addr.Port}, nil); err != nil { + t.Fatalf("ep.Bind(...) failed: %v", err) + } + }() +} + func TestV4ReadOnV6(t *testing.T) { c := newDualTestContext(t, defaultMTU) defer c.cleanup() |