github.com/FlowerWrong/netstack@v0.0.0-20191009141956-e5848263af28/tcpip/transport/udp/udp_test.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package udp_test
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"math/rand"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/FlowerWrong/netstack/tcpip"
    25  	"github.com/FlowerWrong/netstack/tcpip/buffer"
    26  	"github.com/FlowerWrong/netstack/tcpip/checker"
    27  	"github.com/FlowerWrong/netstack/tcpip/header"
    28  	"github.com/FlowerWrong/netstack/tcpip/link/channel"
    29  	"github.com/FlowerWrong/netstack/tcpip/link/loopback"
    30  	"github.com/FlowerWrong/netstack/tcpip/link/sniffer"
    31  	"github.com/FlowerWrong/netstack/tcpip/network/ipv4"
    32  	"github.com/FlowerWrong/netstack/tcpip/network/ipv6"
    33  	"github.com/FlowerWrong/netstack/tcpip/stack"
    34  	"github.com/FlowerWrong/netstack/tcpip/transport/udp"
    35  	"github.com/FlowerWrong/netstack/waiter"
    36  )
    37  
    38  // Addresses and ports used for testing. It is recommended that tests stick to
    39  // using these addresses as it allows using the testFlow helper.
    40  // Naming rules: 'stack*'' denotes local addresses and ports, while 'test*'
    41  // represents the remote endpoint.
    42  const (
    43  	v4MappedAddrPrefix    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff"
    44  	stackV6Addr           = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
    45  	testV6Addr            = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
    46  	stackV4MappedAddr     = v4MappedAddrPrefix + stackAddr
    47  	testV4MappedAddr      = v4MappedAddrPrefix + testAddr
    48  	multicastV4MappedAddr = v4MappedAddrPrefix + multicastAddr
    49  	broadcastV4MappedAddr = v4MappedAddrPrefix + broadcastAddr
    50  	v4MappedWildcardAddr  = v4MappedAddrPrefix + "\x00\x00\x00\x00"
    51  
    52  	stackAddr       = "\x0a\x00\x00\x01"
    53  	stackPort       = 1234
    54  	testAddr        = "\x0a\x00\x00\x02"
    55  	testPort        = 4096
    56  	multicastAddr   = "\xe8\x2b\xd3\xea"
    57  	multicastV6Addr = "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    58  	broadcastAddr   = header.IPv4Broadcast
    59  
    60  	// defaultMTU is the MTU, in bytes, used throughout the tests, except
    61  	// where another value is explicitly used. It is chosen to match the MTU
    62  	// of loopback interfaces on linux systems.
    63  	defaultMTU = 65536
    64  )
    65  
    66  // header4Tuple stores the 4-tuple {src-IP, src-port, dst-IP, dst-port} used in
    67  // a packet header. These values are used to populate a header or verify one.
    68  // Note that because they are used in packet headers, the addresses are never in
    69  // a V4-mapped format.
    70  type header4Tuple struct {
    71  	srcAddr tcpip.FullAddress
    72  	dstAddr tcpip.FullAddress
    73  }
    74  
    75  // testFlow implements a helper type used for sending and receiving test
    76  // packets. A given test flow value defines 1) the socket endpoint used for the
    77  // test and 2) the type of packet send or received on the endpoint. E.g., a
    78  // multicastV6Only flow is a V6 multicast packet passing through a V6-only
    79  // endpoint. The type provides helper methods to characterize the flow (e.g.,
    80  // isV4) as well as return a proper header4Tuple for it.
    81  type testFlow int
    82  
    83  const (
    84  	unicastV4       testFlow = iota // V4 unicast on a V4 socket
    85  	unicastV4in6                    // V4-mapped unicast on a V6-dual socket
    86  	unicastV6                       // V6 unicast on a V6 socket
    87  	unicastV6Only                   // V6 unicast on a V6-only socket
    88  	multicastV4                     // V4 multicast on a V4 socket
    89  	multicastV4in6                  // V4-mapped multicast on a V6-dual socket
    90  	multicastV6                     // V6 multicast on a V6 socket
    91  	multicastV6Only                 // V6 multicast on a V6-only socket
    92  	broadcast                       // V4 broadcast on a V4 socket
    93  	broadcastIn6                    // V4-mapped broadcast on a V6-dual socket
    94  )
    95  
    96  func (flow testFlow) String() string {
    97  	switch flow {
    98  	case unicastV4:
    99  		return "unicastV4"
   100  	case unicastV6:
   101  		return "unicastV6"
   102  	case unicastV6Only:
   103  		return "unicastV6Only"
   104  	case unicastV4in6:
   105  		return "unicastV4in6"
   106  	case multicastV4:
   107  		return "multicastV4"
   108  	case multicastV6:
   109  		return "multicastV6"
   110  	case multicastV6Only:
   111  		return "multicastV6Only"
   112  	case multicastV4in6:
   113  		return "multicastV4in6"
   114  	case broadcast:
   115  		return "broadcast"
   116  	case broadcastIn6:
   117  		return "broadcastIn6"
   118  	default:
   119  		return "unknown"
   120  	}
   121  }
   122  
   123  // packetDirection explains if a flow is incoming (read) or outgoing (write).
   124  type packetDirection int
   125  
   126  const (
   127  	incoming packetDirection = iota
   128  	outgoing
   129  )
   130  
   131  // header4Tuple returns the header4Tuple for the given flow and direction. Note
   132  // that the tuple contains no mapped addresses as those only exist at the socket
   133  // level but not at the packet header level.
   134  func (flow testFlow) header4Tuple(d packetDirection) header4Tuple {
   135  	var h header4Tuple
   136  	if flow.isV4() {
   137  		if d == outgoing {
   138  			h = header4Tuple{
   139  				srcAddr: tcpip.FullAddress{Addr: stackAddr, Port: stackPort},
   140  				dstAddr: tcpip.FullAddress{Addr: testAddr, Port: testPort},
   141  			}
   142  		} else {
   143  			h = header4Tuple{
   144  				srcAddr: tcpip.FullAddress{Addr: testAddr, Port: testPort},
   145  				dstAddr: tcpip.FullAddress{Addr: stackAddr, Port: stackPort},
   146  			}
   147  		}
   148  		if flow.isMulticast() {
   149  			h.dstAddr.Addr = multicastAddr
   150  		} else if flow.isBroadcast() {
   151  			h.dstAddr.Addr = broadcastAddr
   152  		}
   153  	} else { // IPv6
   154  		if d == outgoing {
   155  			h = header4Tuple{
   156  				srcAddr: tcpip.FullAddress{Addr: stackV6Addr, Port: stackPort},
   157  				dstAddr: tcpip.FullAddress{Addr: testV6Addr, Port: testPort},
   158  			}
   159  		} else {
   160  			h = header4Tuple{
   161  				srcAddr: tcpip.FullAddress{Addr: testV6Addr, Port: testPort},
   162  				dstAddr: tcpip.FullAddress{Addr: stackV6Addr, Port: stackPort},
   163  			}
   164  		}
   165  		if flow.isMulticast() {
   166  			h.dstAddr.Addr = multicastV6Addr
   167  		}
   168  	}
   169  	return h
   170  }
   171  
   172  func (flow testFlow) getMcastAddr() tcpip.Address {
   173  	if flow.isV4() {
   174  		return multicastAddr
   175  	}
   176  	return multicastV6Addr
   177  }
   178  
   179  // mapAddrIfApplicable converts the given V4 address into its V4-mapped version
   180  // if it is applicable to the flow.
   181  func (flow testFlow) mapAddrIfApplicable(v4Addr tcpip.Address) tcpip.Address {
   182  	if flow.isMapped() {
   183  		return v4MappedAddrPrefix + v4Addr
   184  	}
   185  	return v4Addr
   186  }
   187  
   188  // netProto returns the protocol number used for the network packet.
   189  func (flow testFlow) netProto() tcpip.NetworkProtocolNumber {
   190  	if flow.isV4() {
   191  		return ipv4.ProtocolNumber
   192  	}
   193  	return ipv6.ProtocolNumber
   194  }
   195  
   196  // sockProto returns the protocol number used when creating the socket
   197  // endpoint for this flow.
   198  func (flow testFlow) sockProto() tcpip.NetworkProtocolNumber {
   199  	switch flow {
   200  	case unicastV4in6, unicastV6, unicastV6Only, multicastV4in6, multicastV6, multicastV6Only, broadcastIn6:
   201  		return ipv6.ProtocolNumber
   202  	case unicastV4, multicastV4, broadcast:
   203  		return ipv4.ProtocolNumber
   204  	default:
   205  		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
   206  	}
   207  }
   208  
   209  func (flow testFlow) checkerFn() func(*testing.T, []byte, ...checker.NetworkChecker) {
   210  	if flow.isV4() {
   211  		return checker.IPv4
   212  	}
   213  	return checker.IPv6
   214  }
   215  
   216  func (flow testFlow) isV6() bool { return !flow.isV4() }
   217  func (flow testFlow) isV4() bool {
   218  	return flow.sockProto() == ipv4.ProtocolNumber || flow.isMapped()
   219  }
   220  
   221  func (flow testFlow) isV6Only() bool {
   222  	switch flow {
   223  	case unicastV6Only, multicastV6Only:
   224  		return true
   225  	case unicastV4, unicastV4in6, unicastV6, multicastV4, multicastV4in6, multicastV6, broadcast, broadcastIn6:
   226  		return false
   227  	default:
   228  		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
   229  	}
   230  }
   231  
   232  func (flow testFlow) isMulticast() bool {
   233  	switch flow {
   234  	case multicastV4, multicastV4in6, multicastV6, multicastV6Only:
   235  		return true
   236  	case unicastV4, unicastV4in6, unicastV6, unicastV6Only, broadcast, broadcastIn6:
   237  		return false
   238  	default:
   239  		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
   240  	}
   241  }
   242  
   243  func (flow testFlow) isBroadcast() bool {
   244  	switch flow {
   245  	case broadcast, broadcastIn6:
   246  		return true
   247  	case unicastV4, unicastV4in6, unicastV6, unicastV6Only, multicastV4, multicastV4in6, multicastV6, multicastV6Only:
   248  		return false
   249  	default:
   250  		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
   251  	}
   252  }
   253  
   254  func (flow testFlow) isMapped() bool {
   255  	switch flow {
   256  	case unicastV4in6, multicastV4in6, broadcastIn6:
   257  		return true
   258  	case unicastV4, unicastV6, unicastV6Only, multicastV4, multicastV6, multicastV6Only, broadcast:
   259  		return false
   260  	default:
   261  		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
   262  	}
   263  }
   264  
   265  type testContext struct {
   266  	t      *testing.T
   267  	linkEP *channel.Endpoint
   268  	s      *stack.Stack
   269  
   270  	ep tcpip.Endpoint
   271  	wq waiter.Queue
   272  }
   273  
   274  func newDualTestContext(t *testing.T, mtu uint32) *testContext {
   275  	t.Helper()
   276  
   277  	s := stack.New(stack.Options{
   278  		NetworkProtocols:   []stack.NetworkProtocol{ipv4.NewProtocol(), ipv6.NewProtocol()},
   279  		TransportProtocols: []stack.TransportProtocol{udp.NewProtocol()},
   280  	})
   281  	ep := channel.New(256, mtu, "")
   282  	wep := stack.LinkEndpoint(ep)
   283  
   284  	if testing.Verbose() {
   285  		wep = sniffer.New(ep)
   286  	}
   287  	if err := s.CreateNIC(1, wep); err != nil {
   288  		t.Fatalf("CreateNIC failed: %v", err)
   289  	}
   290  
   291  	if err := s.AddAddress(1, ipv4.ProtocolNumber, stackAddr); err != nil {
   292  		t.Fatalf("AddAddress failed: %v", err)
   293  	}
   294  
   295  	if err := s.AddAddress(1, ipv6.ProtocolNumber, stackV6Addr); err != nil {
   296  		t.Fatalf("AddAddress failed: %v", err)
   297  	}
   298  
   299  	s.SetRouteTable([]tcpip.Route{
   300  		{
   301  			Destination: header.IPv4EmptySubnet,
   302  			NIC:         1,
   303  		},
   304  		{
   305  			Destination: header.IPv6EmptySubnet,
   306  			NIC:         1,
   307  		},
   308  	})
   309  
   310  	return &testContext{
   311  		t:      t,
   312  		s:      s,
   313  		linkEP: ep,
   314  	}
   315  }
   316  
   317  func (c *testContext) cleanup() {
   318  	if c.ep != nil {
   319  		c.ep.Close()
   320  	}
   321  }
   322  
   323  func (c *testContext) createEndpoint(proto tcpip.NetworkProtocolNumber) {
   324  	c.t.Helper()
   325  
   326  	var err *tcpip.Error
   327  	c.ep, err = c.s.NewEndpoint(udp.ProtocolNumber, proto, &c.wq)
   328  	if err != nil {
   329  		c.t.Fatal("NewEndpoint failed: ", err)
   330  	}
   331  }
   332  
   333  func (c *testContext) createEndpointForFlow(flow testFlow) {
   334  	c.t.Helper()
   335  
   336  	c.createEndpoint(flow.sockProto())
   337  	if flow.isV6Only() {
   338  		if err := c.ep.SetSockOpt(tcpip.V6OnlyOption(1)); err != nil {
   339  			c.t.Fatalf("SetSockOpt failed: %v", err)
   340  		}
   341  	} else if flow.isBroadcast() {
   342  		if err := c.ep.SetSockOpt(tcpip.BroadcastOption(1)); err != nil {
   343  			c.t.Fatal("SetSockOpt failed:", err)
   344  		}
   345  	}
   346  }
   347  
   348  // getPacketAndVerify reads a packet from the link endpoint and verifies the
   349  // header against expected values from the given test flow. In addition, it
   350  // calls any extra checker functions provided.
   351  func (c *testContext) getPacketAndVerify(flow testFlow, checkers ...checker.NetworkChecker) []byte {
   352  	c.t.Helper()
   353  
   354  	select {
   355  	case p := <-c.linkEP.C:
   356  		if p.Proto != flow.netProto() {
   357  			c.t.Fatalf("Bad network protocol: got %v, wanted %v", p.Proto, flow.netProto())
   358  		}
   359  		b := make([]byte, len(p.Header)+len(p.Payload))
   360  		copy(b, p.Header)
   361  		copy(b[len(p.Header):], p.Payload)
   362  
   363  		h := flow.header4Tuple(outgoing)
   364  		checkers := append(
   365  			checkers,
   366  			checker.SrcAddr(h.srcAddr.Addr),
   367  			checker.DstAddr(h.dstAddr.Addr),
   368  			checker.UDP(checker.DstPort(h.dstAddr.Port)),
   369  		)
   370  		flow.checkerFn()(c.t, b, checkers...)
   371  		return b
   372  
   373  	case <-time.After(2 * time.Second):
   374  		c.t.Fatalf("Packet wasn't written out")
   375  	}
   376  
   377  	return nil
   378  }
   379  
   380  // injectPacket creates a packet of the given flow and with the given payload,
   381  // and injects it into the link endpoint.
   382  func (c *testContext) injectPacket(flow testFlow, payload []byte) {
   383  	c.t.Helper()
   384  
   385  	h := flow.header4Tuple(incoming)
   386  	if flow.isV4() {
   387  		c.injectV4Packet(payload, &h)
   388  	} else {
   389  		c.injectV6Packet(payload, &h)
   390  	}
   391  }
   392  
   393  // injectV6Packet creates a V6 test packet with the given payload and header
   394  // values, and injects it into the link endpoint.
   395  func (c *testContext) injectV6Packet(payload []byte, h *header4Tuple) {
   396  	// Allocate a buffer for data and headers.
   397  	buf := buffer.NewView(header.UDPMinimumSize + header.IPv6MinimumSize + len(payload))
   398  	copy(buf[len(buf)-len(payload):], payload)
   399  
   400  	// Initialize the IP header.
   401  	ip := header.IPv6(buf)
   402  	ip.Encode(&header.IPv6Fields{
   403  		PayloadLength: uint16(header.UDPMinimumSize + len(payload)),
   404  		NextHeader:    uint8(udp.ProtocolNumber),
   405  		HopLimit:      65,
   406  		SrcAddr:       h.srcAddr.Addr,
   407  		DstAddr:       h.dstAddr.Addr,
   408  	})
   409  
   410  	// Initialize the UDP header.
   411  	u := header.UDP(buf[header.IPv6MinimumSize:])
   412  	u.Encode(&header.UDPFields{
   413  		SrcPort: h.srcAddr.Port,
   414  		DstPort: h.dstAddr.Port,
   415  		Length:  uint16(header.UDPMinimumSize + len(payload)),
   416  	})
   417  
   418  	// Calculate the UDP pseudo-header checksum.
   419  	xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, h.srcAddr.Addr, h.dstAddr.Addr, uint16(len(u)))
   420  
   421  	// Calculate the UDP checksum and set it.
   422  	xsum = header.Checksum(payload, xsum)
   423  	u.SetChecksum(^u.CalculateChecksum(xsum))
   424  
   425  	// Inject packet.
   426  	c.linkEP.Inject(ipv6.ProtocolNumber, buf.ToVectorisedView())
   427  }
   428  
   429  // injectV6Packet creates a V4 test packet with the given payload and header
   430  // values, and injects it into the link endpoint.
   431  func (c *testContext) injectV4Packet(payload []byte, h *header4Tuple) {
   432  	// Allocate a buffer for data and headers.
   433  	buf := buffer.NewView(header.UDPMinimumSize + header.IPv4MinimumSize + len(payload))
   434  	copy(buf[len(buf)-len(payload):], payload)
   435  
   436  	// Initialize the IP header.
   437  	ip := header.IPv4(buf)
   438  	ip.Encode(&header.IPv4Fields{
   439  		IHL:         header.IPv4MinimumSize,
   440  		TotalLength: uint16(len(buf)),
   441  		TTL:         65,
   442  		Protocol:    uint8(udp.ProtocolNumber),
   443  		SrcAddr:     h.srcAddr.Addr,
   444  		DstAddr:     h.dstAddr.Addr,
   445  	})
   446  	ip.SetChecksum(^ip.CalculateChecksum())
   447  
   448  	// Initialize the UDP header.
   449  	u := header.UDP(buf[header.IPv4MinimumSize:])
   450  	u.Encode(&header.UDPFields{
   451  		SrcPort: h.srcAddr.Port,
   452  		DstPort: h.dstAddr.Port,
   453  		Length:  uint16(header.UDPMinimumSize + len(payload)),
   454  	})
   455  
   456  	// Calculate the UDP pseudo-header checksum.
   457  	xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, h.srcAddr.Addr, h.dstAddr.Addr, uint16(len(u)))
   458  
   459  	// Calculate the UDP checksum and set it.
   460  	xsum = header.Checksum(payload, xsum)
   461  	u.SetChecksum(^u.CalculateChecksum(xsum))
   462  
   463  	// Inject packet.
   464  	c.linkEP.Inject(ipv4.ProtocolNumber, buf.ToVectorisedView())
   465  }
   466  
   467  func newPayload() []byte {
   468  	return newMinPayload(30)
   469  }
   470  
   471  func newMinPayload(minSize int) []byte {
   472  	b := make([]byte, minSize+rand.Intn(100))
   473  	for i := range b {
   474  		b[i] = byte(rand.Intn(256))
   475  	}
   476  	return b
   477  }
   478  
   479  func TestBindToDeviceOption(t *testing.T) {
   480  	s := stack.New(stack.Options{
   481  		NetworkProtocols:   []stack.NetworkProtocol{ipv4.NewProtocol()},
   482  		TransportProtocols: []stack.TransportProtocol{udp.NewProtocol()}})
   483  
   484  	ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
   485  	if err != nil {
   486  		t.Fatalf("NewEndpoint failed; %v", err)
   487  	}
   488  	defer ep.Close()
   489  
   490  	if err := s.CreateNamedNIC(321, "my_device", loopback.New()); err != nil {
   491  		t.Errorf("CreateNamedNIC failed: %v", err)
   492  	}
   493  
   494  	// Make an nameless NIC.
   495  	if err := s.CreateNIC(54321, loopback.New()); err != nil {
   496  		t.Errorf("CreateNIC failed: %v", err)
   497  	}
   498  
   499  	// strPtr is used instead of taking the address of string literals, which is
   500  	// a compiler error.
   501  	strPtr := func(s string) *string {
   502  		return &s
   503  	}
   504  
   505  	testActions := []struct {
   506  		name                 string
   507  		setBindToDevice      *string
   508  		setBindToDeviceError *tcpip.Error
   509  		getBindToDevice      tcpip.BindToDeviceOption
   510  	}{
   511  		{"GetDefaultValue", nil, nil, ""},
   512  		{"BindToNonExistent", strPtr("non_existent_device"), tcpip.ErrUnknownDevice, ""},
   513  		{"BindToExistent", strPtr("my_device"), nil, "my_device"},
   514  		{"UnbindToDevice", strPtr(""), nil, ""},
   515  	}
   516  	for _, testAction := range testActions {
   517  		t.Run(testAction.name, func(t *testing.T) {
   518  			if testAction.setBindToDevice != nil {
   519  				bindToDevice := tcpip.BindToDeviceOption(*testAction.setBindToDevice)
   520  				if got, want := ep.SetSockOpt(bindToDevice), testAction.setBindToDeviceError; got != want {
   521  					t.Errorf("SetSockOpt(%v) got %v, want %v", bindToDevice, got, want)
   522  				}
   523  			}
   524  			bindToDevice := tcpip.BindToDeviceOption("to be modified by GetSockOpt")
   525  			if ep.GetSockOpt(&bindToDevice) != nil {
   526  				t.Errorf("GetSockOpt got %v, want %v", ep.GetSockOpt(&bindToDevice), nil)
   527  			}
   528  			if got, want := bindToDevice, testAction.getBindToDevice; got != want {
   529  				t.Errorf("bindToDevice got %q, want %q", got, want)
   530  			}
   531  		})
   532  	}
   533  }
   534  
   535  // testReadInternal sends a packet of the given test flow into the stack by
   536  // injecting it into the link endpoint. It then attempts to read it from the
   537  // UDP endpoint and depending on if this was expected to succeed verifies its
   538  // correctness.
   539  func testReadInternal(c *testContext, flow testFlow, packetShouldBeDropped bool) {
   540  	c.t.Helper()
   541  
   542  	payload := newPayload()
   543  	c.injectPacket(flow, payload)
   544  
   545  	// Try to receive the data.
   546  	we, ch := waiter.NewChannelEntry(nil)
   547  	c.wq.EventRegister(&we, waiter.EventIn)
   548  	defer c.wq.EventUnregister(&we)
   549  
   550  	var addr tcpip.FullAddress
   551  	v, _, err := c.ep.Read(&addr)
   552  	if err == tcpip.ErrWouldBlock {
   553  		// Wait for data to become available.
   554  		select {
   555  		case <-ch:
   556  			v, _, err = c.ep.Read(&addr)
   557  
   558  		case <-time.After(300 * time.Millisecond):
   559  			if packetShouldBeDropped {
   560  				return // expected to time out
   561  			}
   562  			c.t.Fatal("timed out waiting for data")
   563  		}
   564  	}
   565  
   566  	if err != nil {
   567  		c.t.Fatal("Read failed:", err)
   568  	}
   569  
   570  	if packetShouldBeDropped {
   571  		c.t.Fatalf("Read unexpectedly received data from %s", addr.Addr)
   572  	}
   573  
   574  	// Check the peer address.
   575  	h := flow.header4Tuple(incoming)
   576  	if addr.Addr != h.srcAddr.Addr {
   577  		c.t.Fatalf("unexpected remote address: got %s, want %s", addr.Addr, h.srcAddr)
   578  	}
   579  
   580  	// Check the payload.
   581  	if !bytes.Equal(payload, v) {
   582  		c.t.Fatalf("bad payload: got %x, want %x", v, payload)
   583  	}
   584  }
   585  
   586  // testRead sends a packet of the given test flow into the stack by injecting it
   587  // into the link endpoint. It then reads it from the UDP endpoint and verifies
   588  // its correctness.
   589  func testRead(c *testContext, flow testFlow) {
   590  	c.t.Helper()
   591  	testReadInternal(c, flow, false /* packetShouldBeDropped */)
   592  }
   593  
   594  // testFailingRead sends a packet of the given test flow into the stack by
   595  // injecting it into the link endpoint. It then tries to read it from the UDP
   596  // endpoint and expects this to fail.
   597  func testFailingRead(c *testContext, flow testFlow) {
   598  	c.t.Helper()
   599  	testReadInternal(c, flow, true /* packetShouldBeDropped */)
   600  }
   601  
   602  func TestBindEphemeralPort(t *testing.T) {
   603  	c := newDualTestContext(t, defaultMTU)
   604  	defer c.cleanup()
   605  
   606  	c.createEndpoint(ipv6.ProtocolNumber)
   607  
   608  	if err := c.ep.Bind(tcpip.FullAddress{}); err != nil {
   609  		t.Fatalf("ep.Bind(...) failed: %v", err)
   610  	}
   611  }
   612  
   613  func TestBindReservedPort(t *testing.T) {
   614  	c := newDualTestContext(t, defaultMTU)
   615  	defer c.cleanup()
   616  
   617  	c.createEndpoint(ipv6.ProtocolNumber)
   618  
   619  	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
   620  		c.t.Fatalf("Connect failed: %v", err)
   621  	}
   622  
   623  	addr, err := c.ep.GetLocalAddress()
   624  	if err != nil {
   625  		t.Fatalf("GetLocalAddress failed: %v", err)
   626  	}
   627  
   628  	// We can't bind the address reserved by the connected endpoint above.
   629  	{
   630  		ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv6.ProtocolNumber, &c.wq)
   631  		if err != nil {
   632  			t.Fatalf("NewEndpoint failed: %v", err)
   633  		}
   634  		defer ep.Close()
   635  		if got, want := ep.Bind(addr), tcpip.ErrPortInUse; got != want {
   636  			t.Fatalf("got ep.Bind(...) = %v, want = %v", got, want)
   637  		}
   638  	}
   639  
   640  	func() {
   641  		ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &c.wq)
   642  		if err != nil {
   643  			t.Fatalf("NewEndpoint failed: %v", err)
   644  		}
   645  		defer ep.Close()
   646  		// We can't bind ipv4-any on the port reserved by the connected endpoint
   647  		// above, since the endpoint is dual-stack.
   648  		if got, want := ep.Bind(tcpip.FullAddress{Port: addr.Port}), tcpip.ErrPortInUse; got != want {
   649  			t.Fatalf("got ep.Bind(...) = %v, want = %v", got, want)
   650  		}
   651  		// We can bind an ipv4 address on this port, though.
   652  		if err := ep.Bind(tcpip.FullAddress{Addr: stackAddr, Port: addr.Port}); err != nil {
   653  			t.Fatalf("ep.Bind(...) failed: %v", err)
   654  		}
   655  	}()
   656  
   657  	// Once the connected endpoint releases its port reservation, we are able to
   658  	// bind ipv4-any once again.
   659  	c.ep.Close()
   660  	func() {
   661  		ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &c.wq)
   662  		if err != nil {
   663  			t.Fatalf("NewEndpoint failed: %v", err)
   664  		}
   665  		defer ep.Close()
   666  		if err := ep.Bind(tcpip.FullAddress{Port: addr.Port}); err != nil {
   667  			t.Fatalf("ep.Bind(...) failed: %v", err)
   668  		}
   669  	}()
   670  }
   671  
   672  func TestV4ReadOnV6(t *testing.T) {
   673  	c := newDualTestContext(t, defaultMTU)
   674  	defer c.cleanup()
   675  
   676  	c.createEndpointForFlow(unicastV4in6)
   677  
   678  	// Bind to wildcard.
   679  	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
   680  		c.t.Fatalf("Bind failed: %v", err)
   681  	}
   682  
   683  	// Test acceptance.
   684  	testRead(c, unicastV4in6)
   685  }
   686  
   687  func TestV4ReadOnBoundToV4MappedWildcard(t *testing.T) {
   688  	c := newDualTestContext(t, defaultMTU)
   689  	defer c.cleanup()
   690  
   691  	c.createEndpointForFlow(unicastV4in6)
   692  
   693  	// Bind to v4 mapped wildcard.
   694  	if err := c.ep.Bind(tcpip.FullAddress{Addr: v4MappedWildcardAddr, Port: stackPort}); err != nil {
   695  		c.t.Fatalf("Bind failed: %v", err)
   696  	}
   697  
   698  	// Test acceptance.
   699  	testRead(c, unicastV4in6)
   700  }
   701  
   702  func TestV4ReadOnBoundToV4Mapped(t *testing.T) {
   703  	c := newDualTestContext(t, defaultMTU)
   704  	defer c.cleanup()
   705  
   706  	c.createEndpointForFlow(unicastV4in6)
   707  
   708  	// Bind to local address.
   709  	if err := c.ep.Bind(tcpip.FullAddress{Addr: stackV4MappedAddr, Port: stackPort}); err != nil {
   710  		c.t.Fatalf("Bind failed: %v", err)
   711  	}
   712  
   713  	// Test acceptance.
   714  	testRead(c, unicastV4in6)
   715  }
   716  
   717  func TestV6ReadOnV6(t *testing.T) {
   718  	c := newDualTestContext(t, defaultMTU)
   719  	defer c.cleanup()
   720  
   721  	c.createEndpointForFlow(unicastV6)
   722  
   723  	// Bind to wildcard.
   724  	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
   725  		c.t.Fatalf("Bind failed: %v", err)
   726  	}
   727  
   728  	// Test acceptance.
   729  	testRead(c, unicastV6)
   730  }
   731  
   732  func TestV4ReadOnV4(t *testing.T) {
   733  	c := newDualTestContext(t, defaultMTU)
   734  	defer c.cleanup()
   735  
   736  	c.createEndpointForFlow(unicastV4)
   737  
   738  	// Bind to wildcard.
   739  	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
   740  		c.t.Fatalf("Bind failed: %v", err)
   741  	}
   742  
   743  	// Test acceptance.
   744  	testRead(c, unicastV4)
   745  }
   746  
   747  // TestReadOnBoundToMulticast checks that an endpoint can bind to a multicast
   748  // address and receive data sent to that address.
   749  func TestReadOnBoundToMulticast(t *testing.T) {
   750  	// FIXME(b/128189410): multicastV4in6 currently doesn't work as
   751  	// AddMembershipOption doesn't handle V4in6 addresses.
   752  	for _, flow := range []testFlow{multicastV4, multicastV6, multicastV6Only} {
   753  		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
   754  			c := newDualTestContext(t, defaultMTU)
   755  			defer c.cleanup()
   756  
   757  			c.createEndpointForFlow(flow)
   758  
   759  			// Bind to multicast address.
   760  			mcastAddr := flow.mapAddrIfApplicable(flow.getMcastAddr())
   761  			if err := c.ep.Bind(tcpip.FullAddress{Addr: mcastAddr, Port: stackPort}); err != nil {
   762  				c.t.Fatal("Bind failed:", err)
   763  			}
   764  
   765  			// Join multicast group.
   766  			ifoptSet := tcpip.AddMembershipOption{NIC: 1, MulticastAddr: mcastAddr}
   767  			if err := c.ep.SetSockOpt(ifoptSet); err != nil {
   768  				c.t.Fatal("SetSockOpt failed:", err)
   769  			}
   770  
   771  			// Check that we receive multicast packets but not unicast or broadcast
   772  			// ones.
   773  			testRead(c, flow)
   774  			testFailingRead(c, broadcast)
   775  			testFailingRead(c, unicastV4)
   776  		})
   777  	}
   778  }
   779  
   780  // TestV4ReadOnBoundToBroadcast checks that an endpoint can bind to a broadcast
   781  // address and can receive only broadcast data.
   782  func TestV4ReadOnBoundToBroadcast(t *testing.T) {
   783  	for _, flow := range []testFlow{broadcast, broadcastIn6} {
   784  		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
   785  			c := newDualTestContext(t, defaultMTU)
   786  			defer c.cleanup()
   787  
   788  			c.createEndpointForFlow(flow)
   789  
   790  			// Bind to broadcast address.
   791  			bcastAddr := flow.mapAddrIfApplicable(broadcastAddr)
   792  			if err := c.ep.Bind(tcpip.FullAddress{Addr: bcastAddr, Port: stackPort}); err != nil {
   793  				c.t.Fatalf("Bind failed: %s", err)
   794  			}
   795  
   796  			// Check that we receive broadcast packets but not unicast ones.
   797  			testRead(c, flow)
   798  			testFailingRead(c, unicastV4)
   799  		})
   800  	}
   801  }
   802  
   803  // TestV4ReadBroadcastOnBoundToWildcard checks that an endpoint can bind to ANY
   804  // and receive broadcast and unicast data.
   805  func TestV4ReadBroadcastOnBoundToWildcard(t *testing.T) {
   806  	for _, flow := range []testFlow{broadcast, broadcastIn6} {
   807  		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
   808  			c := newDualTestContext(t, defaultMTU)
   809  			defer c.cleanup()
   810  
   811  			c.createEndpointForFlow(flow)
   812  
   813  			// Bind to wildcard.
   814  			if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
   815  				c.t.Fatalf("Bind failed: %s (", err)
   816  			}
   817  
   818  			// Check that we receive both broadcast and unicast packets.
   819  			testRead(c, flow)
   820  			testRead(c, unicastV4)
   821  		})
   822  	}
   823  }
   824  
   825  // testFailingWrite sends a packet of the given test flow into the UDP endpoint
   826  // and verifies it fails with the provided error code.
   827  func testFailingWrite(c *testContext, flow testFlow, wantErr *tcpip.Error) {
   828  	c.t.Helper()
   829  
   830  	h := flow.header4Tuple(outgoing)
   831  	writeDstAddr := flow.mapAddrIfApplicable(h.dstAddr.Addr)
   832  
   833  	payload := buffer.View(newPayload())
   834  	_, _, gotErr := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{
   835  		To: &tcpip.FullAddress{Addr: writeDstAddr, Port: h.dstAddr.Port},
   836  	})
   837  	if gotErr != wantErr {
   838  		c.t.Fatalf("Write returned unexpected error: got %v, want %v", gotErr, wantErr)
   839  	}
   840  }
   841  
   842  // testWrite sends a packet of the given test flow from the UDP endpoint to the
   843  // flow's destination address:port. It then receives it from the link endpoint
   844  // and verifies its correctness including any additional checker functions
   845  // provided.
   846  func testWrite(c *testContext, flow testFlow, checkers ...checker.NetworkChecker) uint16 {
   847  	c.t.Helper()
   848  	return testWriteInternal(c, flow, true, checkers...)
   849  }
   850  
   851  // testWriteWithoutDestination sends a packet of the given test flow from the
   852  // UDP endpoint without giving a destination address:port. It then receives it
   853  // from the link endpoint and verifies its correctness including any additional
   854  // checker functions provided.
   855  func testWriteWithoutDestination(c *testContext, flow testFlow, checkers ...checker.NetworkChecker) uint16 {
   856  	c.t.Helper()
   857  	return testWriteInternal(c, flow, false, checkers...)
   858  }
   859  
   860  func testWriteInternal(c *testContext, flow testFlow, setDest bool, checkers ...checker.NetworkChecker) uint16 {
   861  	c.t.Helper()
   862  
   863  	writeOpts := tcpip.WriteOptions{}
   864  	if setDest {
   865  		h := flow.header4Tuple(outgoing)
   866  		writeDstAddr := flow.mapAddrIfApplicable(h.dstAddr.Addr)
   867  		writeOpts = tcpip.WriteOptions{
   868  			To: &tcpip.FullAddress{Addr: writeDstAddr, Port: h.dstAddr.Port},
   869  		}
   870  	}
   871  	payload := buffer.View(newPayload())
   872  	n, _, err := c.ep.Write(tcpip.SlicePayload(payload), writeOpts)
   873  	if err != nil {
   874  		c.t.Fatalf("Write failed: %v", err)
   875  	}
   876  	if n != int64(len(payload)) {
   877  		c.t.Fatalf("Bad number of bytes written: got %v, want %v", n, len(payload))
   878  	}
   879  
   880  	// Received the packet and check the payload.
   881  	b := c.getPacketAndVerify(flow, checkers...)
   882  	var udp header.UDP
   883  	if flow.isV4() {
   884  		udp = header.UDP(header.IPv4(b).Payload())
   885  	} else {
   886  		udp = header.UDP(header.IPv6(b).Payload())
   887  	}
   888  	if !bytes.Equal(payload, udp.Payload()) {
   889  		c.t.Fatalf("Bad payload: got %x, want %x", udp.Payload(), payload)
   890  	}
   891  
   892  	return udp.SourcePort()
   893  }
   894  
   895  func testDualWrite(c *testContext) uint16 {
   896  	c.t.Helper()
   897  
   898  	v4Port := testWrite(c, unicastV4in6)
   899  	v6Port := testWrite(c, unicastV6)
   900  	if v4Port != v6Port {
   901  		c.t.Fatalf("expected v4 and v6 ports to be equal: got v4Port = %d, v6Port = %d", v4Port, v6Port)
   902  	}
   903  
   904  	return v4Port
   905  }
   906  
   907  func TestDualWriteUnbound(t *testing.T) {
   908  	c := newDualTestContext(t, defaultMTU)
   909  	defer c.cleanup()
   910  
   911  	c.createEndpoint(ipv6.ProtocolNumber)
   912  
   913  	testDualWrite(c)
   914  }
   915  
   916  func TestDualWriteBoundToWildcard(t *testing.T) {
   917  	c := newDualTestContext(t, defaultMTU)
   918  	defer c.cleanup()
   919  
   920  	c.createEndpoint(ipv6.ProtocolNumber)
   921  
   922  	// Bind to wildcard.
   923  	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
   924  		c.t.Fatalf("Bind failed: %v", err)
   925  	}
   926  
   927  	p := testDualWrite(c)
   928  	if p != stackPort {
   929  		c.t.Fatalf("Bad port: got %v, want %v", p, stackPort)
   930  	}
   931  }
   932  
   933  func TestDualWriteConnectedToV6(t *testing.T) {
   934  	c := newDualTestContext(t, defaultMTU)
   935  	defer c.cleanup()
   936  
   937  	c.createEndpoint(ipv6.ProtocolNumber)
   938  
   939  	// Connect to v6 address.
   940  	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
   941  		c.t.Fatalf("Bind failed: %v", err)
   942  	}
   943  
   944  	testWrite(c, unicastV6)
   945  
   946  	// Write to V4 mapped address.
   947  	testFailingWrite(c, unicastV4in6, tcpip.ErrNetworkUnreachable)
   948  }
   949  
   950  func TestDualWriteConnectedToV4Mapped(t *testing.T) {
   951  	c := newDualTestContext(t, defaultMTU)
   952  	defer c.cleanup()
   953  
   954  	c.createEndpoint(ipv6.ProtocolNumber)
   955  
   956  	// Connect to v4 mapped address.
   957  	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}); err != nil {
   958  		c.t.Fatalf("Bind failed: %v", err)
   959  	}
   960  
   961  	testWrite(c, unicastV4in6)
   962  
   963  	// Write to v6 address.
   964  	testFailingWrite(c, unicastV6, tcpip.ErrInvalidEndpointState)
   965  }
   966  
   967  func TestV4WriteOnV6Only(t *testing.T) {
   968  	c := newDualTestContext(t, defaultMTU)
   969  	defer c.cleanup()
   970  
   971  	c.createEndpointForFlow(unicastV6Only)
   972  
   973  	// Write to V4 mapped address.
   974  	testFailingWrite(c, unicastV4in6, tcpip.ErrNoRoute)
   975  }
   976  
   977  func TestV6WriteOnBoundToV4Mapped(t *testing.T) {
   978  	c := newDualTestContext(t, defaultMTU)
   979  	defer c.cleanup()
   980  
   981  	c.createEndpoint(ipv6.ProtocolNumber)
   982  
   983  	// Bind to v4 mapped address.
   984  	if err := c.ep.Bind(tcpip.FullAddress{Addr: stackV4MappedAddr, Port: stackPort}); err != nil {
   985  		c.t.Fatalf("Bind failed: %v", err)
   986  	}
   987  
   988  	// Write to v6 address.
   989  	testFailingWrite(c, unicastV6, tcpip.ErrInvalidEndpointState)
   990  }
   991  
   992  func TestV6WriteOnConnected(t *testing.T) {
   993  	c := newDualTestContext(t, defaultMTU)
   994  	defer c.cleanup()
   995  
   996  	c.createEndpoint(ipv6.ProtocolNumber)
   997  
   998  	// Connect to v6 address.
   999  	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
  1000  		c.t.Fatalf("Connect failed: %v", err)
  1001  	}
  1002  
  1003  	testWriteWithoutDestination(c, unicastV6)
  1004  }
  1005  
  1006  func TestV4WriteOnConnected(t *testing.T) {
  1007  	c := newDualTestContext(t, defaultMTU)
  1008  	defer c.cleanup()
  1009  
  1010  	c.createEndpoint(ipv6.ProtocolNumber)
  1011  
  1012  	// Connect to v4 mapped address.
  1013  	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}); err != nil {
  1014  		c.t.Fatalf("Connect failed: %v", err)
  1015  	}
  1016  
  1017  	testWriteWithoutDestination(c, unicastV4)
  1018  }
  1019  
  1020  // TestWriteOnBoundToV4Multicast checks that we can send packets out of a socket
  1021  // that is bound to a V4 multicast address.
  1022  func TestWriteOnBoundToV4Multicast(t *testing.T) {
  1023  	for _, flow := range []testFlow{unicastV4, multicastV4, broadcast} {
  1024  		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
  1025  			c := newDualTestContext(t, defaultMTU)
  1026  			defer c.cleanup()
  1027  
  1028  			c.createEndpointForFlow(flow)
  1029  
  1030  			// Bind to V4 mcast address.
  1031  			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastAddr, Port: stackPort}); err != nil {
  1032  				c.t.Fatal("Bind failed:", err)
  1033  			}
  1034  
  1035  			testWrite(c, flow)
  1036  		})
  1037  	}
  1038  }
  1039  
  1040  // TestWriteOnBoundToV4MappedMulticast checks that we can send packets out of a
  1041  // socket that is bound to a V4-mapped multicast address.
  1042  func TestWriteOnBoundToV4MappedMulticast(t *testing.T) {
  1043  	for _, flow := range []testFlow{unicastV4in6, multicastV4in6, broadcastIn6} {
  1044  		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
  1045  			c := newDualTestContext(t, defaultMTU)
  1046  			defer c.cleanup()
  1047  
  1048  			c.createEndpointForFlow(flow)
  1049  
  1050  			// Bind to V4Mapped mcast address.
  1051  			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastV4MappedAddr, Port: stackPort}); err != nil {
  1052  				c.t.Fatalf("Bind failed: %s", err)
  1053  			}
  1054  
  1055  			testWrite(c, flow)
  1056  		})
  1057  	}
  1058  }
  1059  
  1060  // TestWriteOnBoundToV6Multicast checks that we can send packets out of a
  1061  // socket that is bound to a V6 multicast address.
  1062  func TestWriteOnBoundToV6Multicast(t *testing.T) {
  1063  	for _, flow := range []testFlow{unicastV6, multicastV6} {
  1064  		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
  1065  			c := newDualTestContext(t, defaultMTU)
  1066  			defer c.cleanup()
  1067  
  1068  			c.createEndpointForFlow(flow)
  1069  
  1070  			// Bind to V6 mcast address.
  1071  			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastV6Addr, Port: stackPort}); err != nil {
  1072  				c.t.Fatalf("Bind failed: %s", err)
  1073  			}
  1074  
  1075  			testWrite(c, flow)
  1076  		})
  1077  	}
  1078  }
  1079  
  1080  // TestWriteOnBoundToV6Multicast checks that we can send packets out of a
  1081  // V6-only socket that is bound to a V6 multicast address.
  1082  func TestWriteOnBoundToV6OnlyMulticast(t *testing.T) {
  1083  	for _, flow := range []testFlow{unicastV6Only, multicastV6Only} {
  1084  		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
  1085  			c := newDualTestContext(t, defaultMTU)
  1086  			defer c.cleanup()
  1087  
  1088  			c.createEndpointForFlow(flow)
  1089  
  1090  			// Bind to V6 mcast address.
  1091  			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastV6Addr, Port: stackPort}); err != nil {
  1092  				c.t.Fatalf("Bind failed: %s", err)
  1093  			}
  1094  
  1095  			testWrite(c, flow)
  1096  		})
  1097  	}
  1098  }
  1099  
  1100  // TestWriteOnBoundToBroadcast checks that we can send packets out of a
  1101  // socket that is bound to the broadcast address.
  1102  func TestWriteOnBoundToBroadcast(t *testing.T) {
  1103  	for _, flow := range []testFlow{unicastV4, multicastV4, broadcast} {
  1104  		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
  1105  			c := newDualTestContext(t, defaultMTU)
  1106  			defer c.cleanup()
  1107  
  1108  			c.createEndpointForFlow(flow)
  1109  
  1110  			// Bind to V4 broadcast address.
  1111  			if err := c.ep.Bind(tcpip.FullAddress{Addr: broadcastAddr, Port: stackPort}); err != nil {
  1112  				c.t.Fatal("Bind failed:", err)
  1113  			}
  1114  
  1115  			testWrite(c, flow)
  1116  		})
  1117  	}
  1118  }
  1119  
  1120  // TestWriteOnBoundToV4MappedBroadcast checks that we can send packets out of a
  1121  // socket that is bound to the V4-mapped broadcast address.
  1122  func TestWriteOnBoundToV4MappedBroadcast(t *testing.T) {
  1123  	for _, flow := range []testFlow{unicastV4in6, multicastV4in6, broadcastIn6} {
  1124  		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
  1125  			c := newDualTestContext(t, defaultMTU)
  1126  			defer c.cleanup()
  1127  
  1128  			c.createEndpointForFlow(flow)
  1129  
  1130  			// Bind to V4Mapped mcast address.
  1131  			if err := c.ep.Bind(tcpip.FullAddress{Addr: broadcastV4MappedAddr, Port: stackPort}); err != nil {
  1132  				c.t.Fatalf("Bind failed: %s", err)
  1133  			}
  1134  
  1135  			testWrite(c, flow)
  1136  		})
  1137  	}
  1138  }
  1139  
  1140  func TestReadIncrementsPacketsReceived(t *testing.T) {
  1141  	c := newDualTestContext(t, defaultMTU)
  1142  	defer c.cleanup()
  1143  
  1144  	// Create IPv4 UDP endpoint
  1145  	c.createEndpoint(ipv6.ProtocolNumber)
  1146  
  1147  	// Bind to wildcard.
  1148  	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
  1149  		c.t.Fatalf("Bind failed: %v", err)
  1150  	}
  1151  
  1152  	testRead(c, unicastV4)
  1153  
  1154  	var want uint64 = 1
  1155  	if got := c.s.Stats().UDP.PacketsReceived.Value(); got != want {
  1156  		c.t.Fatalf("Read did not increment PacketsReceived: got %v, want %v", got, want)
  1157  	}
  1158  }
  1159  
  1160  func TestWriteIncrementsPacketsSent(t *testing.T) {
  1161  	c := newDualTestContext(t, defaultMTU)
  1162  	defer c.cleanup()
  1163  
  1164  	c.createEndpoint(ipv6.ProtocolNumber)
  1165  
  1166  	testDualWrite(c)
  1167  
  1168  	var want uint64 = 2
  1169  	if got := c.s.Stats().UDP.PacketsSent.Value(); got != want {
  1170  		c.t.Fatalf("Write did not increment PacketsSent: got %v, want %v", got, want)
  1171  	}
  1172  }
  1173  
  1174  func TestTTL(t *testing.T) {
  1175  	for _, flow := range []testFlow{unicastV4, unicastV4in6, unicastV6, unicastV6Only, multicastV4, multicastV4in6, multicastV6, broadcast, broadcastIn6} {
  1176  		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
  1177  			c := newDualTestContext(t, defaultMTU)
  1178  			defer c.cleanup()
  1179  
  1180  			c.createEndpointForFlow(flow)
  1181  
  1182  			const multicastTTL = 42
  1183  			if err := c.ep.SetSockOpt(tcpip.MulticastTTLOption(multicastTTL)); err != nil {
  1184  				c.t.Fatalf("SetSockOpt failed: %v", err)
  1185  			}
  1186  
  1187  			var wantTTL uint8
  1188  			if flow.isMulticast() {
  1189  				wantTTL = multicastTTL
  1190  			} else {
  1191  				var p stack.NetworkProtocol
  1192  				if flow.isV4() {
  1193  					p = ipv4.NewProtocol()
  1194  				} else {
  1195  					p = ipv6.NewProtocol()
  1196  				}
  1197  				ep, err := p.NewEndpoint(0, tcpip.AddressWithPrefix{}, nil, nil, nil)
  1198  				if err != nil {
  1199  					t.Fatal(err)
  1200  				}
  1201  				wantTTL = ep.DefaultTTL()
  1202  				ep.Close()
  1203  			}
  1204  
  1205  			testWrite(c, flow, checker.TTL(wantTTL))
  1206  		})
  1207  	}
  1208  }
  1209  
  1210  func TestSetTTL(t *testing.T) {
  1211  	for _, flow := range []testFlow{unicastV4, unicastV4in6, unicastV6, unicastV6Only, broadcast, broadcastIn6} {
  1212  		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
  1213  			for _, wantTTL := range []uint8{1, 2, 50, 64, 128, 254, 255} {
  1214  				t.Run(fmt.Sprintf("TTL:%d", wantTTL), func(t *testing.T) {
  1215  					c := newDualTestContext(t, defaultMTU)
  1216  					defer c.cleanup()
  1217  
  1218  					c.createEndpointForFlow(flow)
  1219  
  1220  					if err := c.ep.SetSockOpt(tcpip.TTLOption(wantTTL)); err != nil {
  1221  						c.t.Fatalf("SetSockOpt failed: %v", err)
  1222  					}
  1223  
  1224  					var p stack.NetworkProtocol
  1225  					if flow.isV4() {
  1226  						p = ipv4.NewProtocol()
  1227  					} else {
  1228  						p = ipv6.NewProtocol()
  1229  					}
  1230  					ep, err := p.NewEndpoint(0, tcpip.AddressWithPrefix{}, nil, nil, nil)
  1231  					if err != nil {
  1232  						t.Fatal(err)
  1233  					}
  1234  					ep.Close()
  1235  
  1236  					testWrite(c, flow, checker.TTL(wantTTL))
  1237  				})
  1238  			}
  1239  		})
  1240  	}
  1241  }
  1242  
  1243  func TestMulticastInterfaceOption(t *testing.T) {
  1244  	for _, flow := range []testFlow{multicastV4, multicastV4in6, multicastV6, multicastV6Only} {
  1245  		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
  1246  			for _, bindTyp := range []string{"bound", "unbound"} {
  1247  				t.Run(bindTyp, func(t *testing.T) {
  1248  					for _, optTyp := range []string{"use local-addr", "use NICID", "use local-addr and NIC"} {
  1249  						t.Run(optTyp, func(t *testing.T) {
  1250  							h := flow.header4Tuple(outgoing)
  1251  							mcastAddr := h.dstAddr.Addr
  1252  							localIfAddr := h.srcAddr.Addr
  1253  
  1254  							var ifoptSet tcpip.MulticastInterfaceOption
  1255  							switch optTyp {
  1256  							case "use local-addr":
  1257  								ifoptSet.InterfaceAddr = localIfAddr
  1258  							case "use NICID":
  1259  								ifoptSet.NIC = 1
  1260  							case "use local-addr and NIC":
  1261  								ifoptSet.InterfaceAddr = localIfAddr
  1262  								ifoptSet.NIC = 1
  1263  							default:
  1264  								t.Fatal("unknown test variant")
  1265  							}
  1266  
  1267  							c := newDualTestContext(t, defaultMTU)
  1268  							defer c.cleanup()
  1269  
  1270  							c.createEndpoint(flow.sockProto())
  1271  
  1272  							if bindTyp == "bound" {
  1273  								// Bind the socket by connecting to the multicast address.
  1274  								// This may have an influence on how the multicast interface
  1275  								// is set.
  1276  								addr := tcpip.FullAddress{
  1277  									Addr: flow.mapAddrIfApplicable(mcastAddr),
  1278  									Port: stackPort,
  1279  								}
  1280  								if err := c.ep.Connect(addr); err != nil {
  1281  									c.t.Fatalf("Connect failed: %v", err)
  1282  								}
  1283  							}
  1284  
  1285  							if err := c.ep.SetSockOpt(ifoptSet); err != nil {
  1286  								c.t.Fatalf("SetSockOpt failed: %v", err)
  1287  							}
  1288  
  1289  							// Verify multicast interface addr and NIC were set correctly.
  1290  							// Note that NIC must be 1 since this is our outgoing interface.
  1291  							ifoptWant := tcpip.MulticastInterfaceOption{NIC: 1, InterfaceAddr: ifoptSet.InterfaceAddr}
  1292  							var ifoptGot tcpip.MulticastInterfaceOption
  1293  							if err := c.ep.GetSockOpt(&ifoptGot); err != nil {
  1294  								c.t.Fatalf("GetSockOpt failed: %v", err)
  1295  							}
  1296  							if ifoptGot != ifoptWant {
  1297  								c.t.Errorf("got GetSockOpt() = %#v, want = %#v", ifoptGot, ifoptWant)
  1298  							}
  1299  						})
  1300  					}
  1301  				})
  1302  			}
  1303  		})
  1304  	}
  1305  }
  1306  
  1307  // TestV4UnknownDestination verifies that we generate an ICMPv4 Destination
  1308  // Unreachable message when a udp datagram is received on ports for which there
  1309  // is no bound udp socket.
  1310  func TestV4UnknownDestination(t *testing.T) {
  1311  	c := newDualTestContext(t, defaultMTU)
  1312  	defer c.cleanup()
  1313  
  1314  	testCases := []struct {
  1315  		flow         testFlow
  1316  		icmpRequired bool
  1317  		// largePayload if true, will result in a payload large enough
  1318  		// so that the final generated IPv4 packet is larger than
  1319  		// header.IPv4MinimumProcessableDatagramSize.
  1320  		largePayload bool
  1321  	}{
  1322  		{unicastV4, true, false},
  1323  		{unicastV4, true, true},
  1324  		{multicastV4, false, false},
  1325  		{multicastV4, false, true},
  1326  		{broadcast, false, false},
  1327  		{broadcast, false, true},
  1328  	}
  1329  	for _, tc := range testCases {
  1330  		t.Run(fmt.Sprintf("flow:%s icmpRequired:%t largePayload:%t", tc.flow, tc.icmpRequired, tc.largePayload), func(t *testing.T) {
  1331  			payload := newPayload()
  1332  			if tc.largePayload {
  1333  				payload = newMinPayload(576)
  1334  			}
  1335  			c.injectPacket(tc.flow, payload)
  1336  			if !tc.icmpRequired {
  1337  				select {
  1338  				case p := <-c.linkEP.C:
  1339  					t.Fatalf("unexpected packet received: %+v", p)
  1340  				case <-time.After(1 * time.Second):
  1341  					return
  1342  				}
  1343  			}
  1344  
  1345  			select {
  1346  			case p := <-c.linkEP.C:
  1347  				var pkt []byte
  1348  				pkt = append(pkt, p.Header...)
  1349  				pkt = append(pkt, p.Payload...)
  1350  				if got, want := len(pkt), header.IPv4MinimumProcessableDatagramSize; got > want {
  1351  					t.Fatalf("got an ICMP packet of size: %d, want: sz <= %d", got, want)
  1352  				}
  1353  
  1354  				hdr := header.IPv4(pkt)
  1355  				checker.IPv4(t, hdr, checker.ICMPv4(
  1356  					checker.ICMPv4Type(header.ICMPv4DstUnreachable),
  1357  					checker.ICMPv4Code(header.ICMPv4PortUnreachable)))
  1358  
  1359  				icmpPkt := header.ICMPv4(hdr.Payload())
  1360  				payloadIPHeader := header.IPv4(icmpPkt.Payload())
  1361  				wantLen := len(payload)
  1362  				if tc.largePayload {
  1363  					wantLen = header.IPv4MinimumProcessableDatagramSize - header.IPv4MinimumSize*2 - header.ICMPv4MinimumSize - header.UDPMinimumSize
  1364  				}
  1365  
  1366  				// In case of large payloads the IP packet may be truncated. Update
  1367  				// the length field before retrieving the udp datagram payload.
  1368  				payloadIPHeader.SetTotalLength(uint16(wantLen + header.UDPMinimumSize + header.IPv4MinimumSize))
  1369  
  1370  				origDgram := header.UDP(payloadIPHeader.Payload())
  1371  				if got, want := len(origDgram.Payload()), wantLen; got != want {
  1372  					t.Fatalf("unexpected payload length got: %d, want: %d", got, want)
  1373  				}
  1374  				if got, want := origDgram.Payload(), payload[:wantLen]; !bytes.Equal(got, want) {
  1375  					t.Fatalf("unexpected payload got: %d, want: %d", got, want)
  1376  				}
  1377  			case <-time.After(1 * time.Second):
  1378  				t.Fatalf("packet wasn't written out")
  1379  			}
  1380  		})
  1381  	}
  1382  }
  1383  
  1384  // TestV6UnknownDestination verifies that we generate an ICMPv6 Destination
  1385  // Unreachable message when a udp datagram is received on ports for which there
  1386  // is no bound udp socket.
  1387  func TestV6UnknownDestination(t *testing.T) {
  1388  	c := newDualTestContext(t, defaultMTU)
  1389  	defer c.cleanup()
  1390  
  1391  	testCases := []struct {
  1392  		flow         testFlow
  1393  		icmpRequired bool
  1394  		// largePayload if true will result in a payload large enough to
  1395  		// create an IPv6 packet > header.IPv6MinimumMTU bytes.
  1396  		largePayload bool
  1397  	}{
  1398  		{unicastV6, true, false},
  1399  		{unicastV6, true, true},
  1400  		{multicastV6, false, false},
  1401  		{multicastV6, false, true},
  1402  	}
  1403  	for _, tc := range testCases {
  1404  		t.Run(fmt.Sprintf("flow:%s icmpRequired:%t largePayload:%t", tc.flow, tc.icmpRequired, tc.largePayload), func(t *testing.T) {
  1405  			payload := newPayload()
  1406  			if tc.largePayload {
  1407  				payload = newMinPayload(1280)
  1408  			}
  1409  			c.injectPacket(tc.flow, payload)
  1410  			if !tc.icmpRequired {
  1411  				select {
  1412  				case p := <-c.linkEP.C:
  1413  					t.Fatalf("unexpected packet received: %+v", p)
  1414  				case <-time.After(1 * time.Second):
  1415  					return
  1416  				}
  1417  			}
  1418  
  1419  			select {
  1420  			case p := <-c.linkEP.C:
  1421  				var pkt []byte
  1422  				pkt = append(pkt, p.Header...)
  1423  				pkt = append(pkt, p.Payload...)
  1424  				if got, want := len(pkt), header.IPv6MinimumMTU; got > want {
  1425  					t.Fatalf("got an ICMP packet of size: %d, want: sz <= %d", got, want)
  1426  				}
  1427  
  1428  				hdr := header.IPv6(pkt)
  1429  				checker.IPv6(t, hdr, checker.ICMPv6(
  1430  					checker.ICMPv6Type(header.ICMPv6DstUnreachable),
  1431  					checker.ICMPv6Code(header.ICMPv6PortUnreachable)))
  1432  
  1433  				icmpPkt := header.ICMPv6(hdr.Payload())
  1434  				payloadIPHeader := header.IPv6(icmpPkt.Payload())
  1435  				wantLen := len(payload)
  1436  				if tc.largePayload {
  1437  					wantLen = header.IPv6MinimumMTU - header.IPv6MinimumSize*2 - header.ICMPv6MinimumSize - header.UDPMinimumSize
  1438  				}
  1439  				// In case of large payloads the IP packet may be truncated. Update
  1440  				// the length field before retrieving the udp datagram payload.
  1441  				payloadIPHeader.SetPayloadLength(uint16(wantLen + header.UDPMinimumSize))
  1442  
  1443  				origDgram := header.UDP(payloadIPHeader.Payload())
  1444  				if got, want := len(origDgram.Payload()), wantLen; got != want {
  1445  					t.Fatalf("unexpected payload length got: %d, want: %d", got, want)
  1446  				}
  1447  				if got, want := origDgram.Payload(), payload[:wantLen]; !bytes.Equal(got, want) {
  1448  					t.Fatalf("unexpected payload got: %v, want: %v", got, want)
  1449  				}
  1450  			case <-time.After(1 * time.Second):
  1451  				t.Fatalf("packet wasn't written out")
  1452  			}
  1453  		})
  1454  	}
  1455  }