// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package udp_test

import (
	"bytes"
	"context"
	"fmt"
	"io/ioutil"
	"math/rand"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/buffer"
	"gvisor.dev/gvisor/pkg/tcpip/checker"
	"gvisor.dev/gvisor/pkg/tcpip/header"
	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
	"gvisor.dev/gvisor/pkg/tcpip/link/loopback"
	"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
	"gvisor.dev/gvisor/pkg/tcpip/stack"
	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
	"gvisor.dev/gvisor/pkg/waiter"
)

// Addresses and ports used for testing. It is recommended that tests stick to
// using these addresses as it allows using the testFlow helper.
// Naming rules: 'stack*'' denotes local addresses and ports, while 'test*'
// represents the remote endpoint.
const (
	v4MappedAddrPrefix    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff"
	stackV6Addr           = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
	testV6Addr            = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
	stackV4MappedAddr     = v4MappedAddrPrefix + stackAddr
	testV4MappedAddr      = v4MappedAddrPrefix + testAddr
	multicastV4MappedAddr = v4MappedAddrPrefix + multicastAddr
	broadcastV4MappedAddr = v4MappedAddrPrefix + broadcastAddr
	v4MappedWildcardAddr  = v4MappedAddrPrefix + "\x00\x00\x00\x00"

	stackAddr       = "\x0a\x00\x00\x01"
	stackPort       = 1234
	testAddr        = "\x0a\x00\x00\x02"
	testPort        = 4096
	invalidPort     = 8192
	multicastAddr   = "\xe8\x2b\xd3\xea"
	multicastV6Addr = "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
	broadcastAddr   = header.IPv4Broadcast
	testTOS         = 0x80

	// defaultMTU is the MTU, in bytes, used throughout the tests, except
	// where another value is explicitly used. It is chosen to match the MTU
	// of loopback interfaces on linux systems.
	defaultMTU = 65536
)

// header4Tuple stores the 4-tuple {src-IP, src-port, dst-IP, dst-port} used in
// a packet header. These values are used to populate a header or verify one.
// Note that because they are used in packet headers, the addresses are never in
// a V4-mapped format.
type header4Tuple struct {
	srcAddr tcpip.FullAddress
	dstAddr tcpip.FullAddress
}

// testFlow implements a helper type used for sending and receiving test
// packets. A given test flow value defines 1) the socket endpoint used for the
// test and 2) the type of packet send or received on the endpoint. E.g., a
// multicastV6Only flow is a V6 multicast packet passing through a V6-only
// endpoint. The type provides helper methods to characterize the flow (e.g.,
// isV4) as well as return a proper header4Tuple for it.
type testFlow int

const (
	unicastV4         testFlow = iota // V4 unicast on a V4 socket
	unicastV4in6                      // V4-mapped unicast on a V6-dual socket
	unicastV6                         // V6 unicast on a V6 socket
	unicastV6Only                     // V6 unicast on a V6-only socket
	multicastV4                       // V4 multicast on a V4 socket
	multicastV4in6                    // V4-mapped multicast on a V6-dual socket
	multicastV6                       // V6 multicast on a V6 socket
	multicastV6Only                   // V6 multicast on a V6-only socket
	broadcast                         // V4 broadcast on a V4 socket
	broadcastIn6                      // V4-mapped broadcast on a V6-dual socket
	reverseMulticast4                 // V4 multicast src. Must fail.
	reverseMulticast6                 // V6 multicast src. Must fail.
)

func (flow testFlow) String() string {
	switch flow {
	case unicastV4:
		return "unicastV4"
	case unicastV6:
		return "unicastV6"
	case unicastV6Only:
		return "unicastV6Only"
	case unicastV4in6:
		return "unicastV4in6"
	case multicastV4:
		return "multicastV4"
	case multicastV6:
		return "multicastV6"
	case multicastV6Only:
		return "multicastV6Only"
	case multicastV4in6:
		return "multicastV4in6"
	case broadcast:
		return "broadcast"
	case broadcastIn6:
		return "broadcastIn6"
	case reverseMulticast4:
		return "reverseMulticast4"
	case reverseMulticast6:
		return "reverseMulticast6"
	default:
		return "unknown"
	}
}

// packetDirection explains if a flow is incoming (read) or outgoing (write).
type packetDirection int

const (
	incoming packetDirection = iota
	outgoing
)

// header4Tuple returns the header4Tuple for the given flow and direction. Note
// that the tuple contains no mapped addresses as those only exist at the socket
// level but not at the packet header level.
func (flow testFlow) header4Tuple(d packetDirection) header4Tuple {
	var h header4Tuple
	if flow.isV4() {
		if d == outgoing {
			h = header4Tuple{
				srcAddr: tcpip.FullAddress{Addr: stackAddr, Port: stackPort},
				dstAddr: tcpip.FullAddress{Addr: testAddr, Port: testPort},
			}
		} else {
			h = header4Tuple{
				srcAddr: tcpip.FullAddress{Addr: testAddr, Port: testPort},
				dstAddr: tcpip.FullAddress{Addr: stackAddr, Port: stackPort},
			}
		}
		if flow.isMulticast() {
			h.dstAddr.Addr = multicastAddr
		} else if flow.isBroadcast() {
			h.dstAddr.Addr = broadcastAddr
		}
	} else { // IPv6
		if d == outgoing {
			h = header4Tuple{
				srcAddr: tcpip.FullAddress{Addr: stackV6Addr, Port: stackPort},
				dstAddr: tcpip.FullAddress{Addr: testV6Addr, Port: testPort},
			}
		} else {
			h = header4Tuple{
				srcAddr: tcpip.FullAddress{Addr: testV6Addr, Port: testPort},
				dstAddr: tcpip.FullAddress{Addr: stackV6Addr, Port: stackPort},
			}
		}
		if flow.isMulticast() {
			h.dstAddr.Addr = multicastV6Addr
		}
	}
	if flow.isReverseMulticast() {
		h.srcAddr.Addr = flow.getMcastAddr()
	}
	return h
}

func (flow testFlow) getMcastAddr() tcpip.Address {
	if flow.isV4() {
		return multicastAddr
	}
	return multicastV6Addr
}

// mapAddrIfApplicable converts the given V4 address into its V4-mapped version
// if it is applicable to the flow.
func (flow testFlow) mapAddrIfApplicable(v4Addr tcpip.Address) tcpip.Address {
	if flow.isMapped() {
		return v4MappedAddrPrefix + v4Addr
	}
	return v4Addr
}

// netProto returns the protocol number used for the network packet.
func (flow testFlow) netProto() tcpip.NetworkProtocolNumber {
	if flow.isV4() {
		return ipv4.ProtocolNumber
	}
	return ipv6.ProtocolNumber
}

// sockProto returns the protocol number used when creating the socket
// endpoint for this flow.
func (flow testFlow) sockProto() tcpip.NetworkProtocolNumber {
	switch flow {
	case unicastV4in6, unicastV6, unicastV6Only, multicastV4in6, multicastV6, multicastV6Only, broadcastIn6, reverseMulticast6:
		return ipv6.ProtocolNumber
	case unicastV4, multicastV4, broadcast, reverseMulticast4:
		return ipv4.ProtocolNumber
	default:
		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
	}
}

func (flow testFlow) checkerFn() func(*testing.T, []byte, ...checker.NetworkChecker) {
	if flow.isV4() {
		return checker.IPv4
	}
	return checker.IPv6
}

func (flow testFlow) isV6() bool { return !flow.isV4() }
func (flow testFlow) isV4() bool {
	return flow.sockProto() == ipv4.ProtocolNumber || flow.isMapped()
}

func (flow testFlow) isV6Only() bool {
	switch flow {
	case unicastV6Only, multicastV6Only:
		return true
	case unicastV4, unicastV4in6, unicastV6, multicastV4, multicastV4in6, multicastV6, broadcast, broadcastIn6, reverseMulticast4, reverseMulticast6:
		return false
	default:
		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
	}
}

func (flow testFlow) isMulticast() bool {
	switch flow {
	case multicastV4, multicastV4in6, multicastV6, multicastV6Only:
		return true
	case unicastV4, unicastV4in6, unicastV6, unicastV6Only, broadcast, broadcastIn6, reverseMulticast4, reverseMulticast6:
		return false
	default:
		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
	}
}

func (flow testFlow) isBroadcast() bool {
	switch flow {
	case broadcast, broadcastIn6:
		return true
	case unicastV4, unicastV4in6, unicastV6, unicastV6Only, multicastV4, multicastV4in6, multicastV6, multicastV6Only, reverseMulticast4, reverseMulticast6:
		return false
	default:
		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
	}
}

func (flow testFlow) isMapped() bool {
	switch flow {
	case unicastV4in6, multicastV4in6, broadcastIn6:
		return true
	case unicastV4, unicastV6, unicastV6Only, multicastV4, multicastV6, multicastV6Only, broadcast, reverseMulticast4, reverseMulticast6:
		return false
	default:
		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
	}
}

func (flow testFlow) isReverseMulticast() bool {
	switch flow {
	case reverseMulticast4, reverseMulticast6:
		return true
	default:
		return false
	}
}

type testContext struct {
	t      *testing.T
	linkEP *channel.Endpoint
	s      *stack.Stack

	ep tcpip.Endpoint
	wq waiter.Queue
}

func newDualTestContext(t *testing.T, mtu uint32) *testContext {
	t.Helper()
	return newDualTestContextWithOptions(t, mtu, stack.Options{
		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
		TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4},
		HandleLocal:        true,
	})
}

func newDualTestContextWithOptions(t *testing.T, mtu uint32, options stack.Options) *testContext {
	t.Helper()

	s := stack.New(options)
	ep := channel.New(256, mtu, "")
	wep := stack.LinkEndpoint(ep)

	if testing.Verbose() {
		wep = sniffer.New(ep)
	}
	if err := s.CreateNIC(1, wep); err != nil {
		t.Fatalf("CreateNIC failed: %s", err)
	}

	if err := s.AddAddress(1, ipv4.ProtocolNumber, stackAddr); err != nil {
		t.Fatalf("AddAddress failed: %s", err)
	}

	if err := s.AddAddress(1, ipv6.ProtocolNumber, stackV6Addr); err != nil {
		t.Fatalf("AddAddress failed: %s", err)
	}

	s.SetRouteTable([]tcpip.Route{
		{
			Destination: header.IPv4EmptySubnet,
			NIC:         1,
		},
		{
			Destination: header.IPv6EmptySubnet,
			NIC:         1,
		},
	})

	return &testContext{
		t:      t,
		s:      s,
		linkEP: ep,
	}
}

func (c *testContext) cleanup() {
	if c.ep != nil {
		c.ep.Close()
	}
}

func (c *testContext) createEndpoint(proto tcpip.NetworkProtocolNumber) {
	c.t.Helper()

	var err tcpip.Error
	c.ep, err = c.s.NewEndpoint(udp.ProtocolNumber, proto, &c.wq)
	if err != nil {
		c.t.Fatal("NewEndpoint failed: ", err)
	}
}

func (c *testContext) createEndpointForFlow(flow testFlow) {
	c.t.Helper()

	c.createEndpoint(flow.sockProto())
	if flow.isV6Only() {
		c.ep.SocketOptions().SetV6Only(true)
	} else if flow.isBroadcast() {
		c.ep.SocketOptions().SetBroadcast(true)
	}
}

// getPacketAndVerify reads a packet from the link endpoint and verifies the
// header against expected values from the given test flow. In addition, it
// calls any extra checker functions provided.
func (c *testContext) getPacketAndVerify(flow testFlow, checkers ...checker.NetworkChecker) []byte {
	c.t.Helper()

	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()
	p, ok := c.linkEP.ReadContext(ctx)
	if !ok {
		c.t.Fatalf("Packet wasn't written out")
		return nil
	}

	if p.Proto != flow.netProto() {
		c.t.Fatalf("Bad network protocol: got %v, wanted %v", p.Proto, flow.netProto())
	}

	if got, want := p.Pkt.TransportProtocolNumber, header.UDPProtocolNumber; got != want {
		c.t.Errorf("got p.Pkt.TransportProtocolNumber = %d, want = %d", got, want)
	}

	vv := buffer.NewVectorisedView(p.Pkt.Size(), p.Pkt.Views())
	b := vv.ToView()

	h := flow.header4Tuple(outgoing)
	checkers = append(
		checkers,
		checker.SrcAddr(h.srcAddr.Addr),
		checker.DstAddr(h.dstAddr.Addr),
		checker.UDP(checker.DstPort(h.dstAddr.Port)),
	)
	flow.checkerFn()(c.t, b, checkers...)
	return b
}

// injectPacket creates a packet of the given flow and with the given payload,
// and injects it into the link endpoint. If badChecksum is true, the packet has
// a bad checksum in the UDP header.
func (c *testContext) injectPacket(flow testFlow, payload []byte, badChecksum bool) {
	c.t.Helper()

	h := flow.header4Tuple(incoming)
	if flow.isV4() {
		buf := c.buildV4Packet(payload, &h)
		if badChecksum {
			// Invalidate the UDP header checksum field, taking care to avoid
			// overflow to zero, which would disable checksum validation.
			for u := header.UDP(buf[header.IPv4MinimumSize:]); ; {
				u.SetChecksum(u.Checksum() + 1)
				if u.Checksum() != 0 {
					break
				}
			}
		}
		c.linkEP.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
			Data: buf.ToVectorisedView(),
		}))
	} else {
		buf := c.buildV6Packet(payload, &h)
		if badChecksum {
			// Invalidate the UDP header checksum field (Unlike IPv4, zero is
			// a valid checksum value for IPv6 so no need to avoid it).
			u := header.UDP(buf[header.IPv6MinimumSize:])
			u.SetChecksum(u.Checksum() + 1)
		}
		c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
			Data: buf.ToVectorisedView(),
		}))
	}
}

// buildV6Packet creates a V6 test packet with the given payload and header
// values in a buffer.
func (c *testContext) buildV6Packet(payload []byte, h *header4Tuple) buffer.View {
	// Allocate a buffer for data and headers.
	buf := buffer.NewView(header.UDPMinimumSize + header.IPv6MinimumSize + len(payload))
	payloadStart := len(buf) - len(payload)
	copy(buf[payloadStart:], payload)

	// Initialize the IP header.
	ip := header.IPv6(buf)
	ip.Encode(&header.IPv6Fields{
		TrafficClass:      testTOS,
		PayloadLength:     uint16(header.UDPMinimumSize + len(payload)),
		TransportProtocol: udp.ProtocolNumber,
		HopLimit:          65,
		SrcAddr:           h.srcAddr.Addr,
		DstAddr:           h.dstAddr.Addr,
	})

	// Initialize the UDP header.
	u := header.UDP(buf[header.IPv6MinimumSize:])
	u.Encode(&header.UDPFields{
		SrcPort: h.srcAddr.Port,
		DstPort: h.dstAddr.Port,
		Length:  uint16(header.UDPMinimumSize + len(payload)),
	})

	// Calculate the UDP pseudo-header checksum.
	xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, h.srcAddr.Addr, h.dstAddr.Addr, uint16(len(u)))

	// Calculate the UDP checksum and set it.
	xsum = header.Checksum(payload, xsum)
	u.SetChecksum(^u.CalculateChecksum(xsum))

	return buf
}

// buildV4Packet creates a V4 test packet with the given payload and header
// values in a buffer.
func (c *testContext) buildV4Packet(payload []byte, h *header4Tuple) buffer.View {
	// Allocate a buffer for data and headers.
	buf := buffer.NewView(header.UDPMinimumSize + header.IPv4MinimumSize + len(payload))
	payloadStart := len(buf) - len(payload)
	copy(buf[payloadStart:], payload)

	// Initialize the IP header.
	ip := header.IPv4(buf)
	ip.Encode(&header.IPv4Fields{
		TOS:         testTOS,
		TotalLength: uint16(len(buf)),
		TTL:         65,
		Protocol:    uint8(udp.ProtocolNumber),
		SrcAddr:     h.srcAddr.Addr,
		DstAddr:     h.dstAddr.Addr,
	})
	ip.SetChecksum(^ip.CalculateChecksum())

	// Initialize the UDP header.
	u := header.UDP(buf[header.IPv4MinimumSize:])
	u.Encode(&header.UDPFields{
		SrcPort: h.srcAddr.Port,
		DstPort: h.dstAddr.Port,
		Length:  uint16(header.UDPMinimumSize + len(payload)),
	})

	// Calculate the UDP pseudo-header checksum.
	xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, h.srcAddr.Addr, h.dstAddr.Addr, uint16(len(u)))

	// Calculate the UDP checksum and set it.
	xsum = header.Checksum(payload, xsum)
	u.SetChecksum(^u.CalculateChecksum(xsum))

	return buf
}

func newPayload() []byte {
	return newMinPayload(30)
}

func newMinPayload(minSize int) []byte {
	b := make([]byte, minSize+rand.Intn(100))
	for i := range b {
		b[i] = byte(rand.Intn(256))
	}
	return b
}

func TestBindToDeviceOption(t *testing.T) {
	s := stack.New(stack.Options{
		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
		TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}})

	ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
	if err != nil {
		t.Fatalf("NewEndpoint failed; %s", err)
	}
	defer ep.Close()

	opts := stack.NICOptions{Name: "my_device"}
	if err := s.CreateNICWithOptions(321, loopback.New(), opts); err != nil {
		t.Errorf("CreateNICWithOptions(_, _, %+v) failed: %s", opts, err)
	}

	// nicIDPtr is used instead of taking the address of NICID literals, which is
	// a compiler error.
	nicIDPtr := func(s tcpip.NICID) *tcpip.NICID {
		return &s
	}

	testActions := []struct {
		name                 string
		setBindToDevice      *tcpip.NICID
		setBindToDeviceError tcpip.Error
		getBindToDevice      int32
	}{
		{"GetDefaultValue", nil, nil, 0},
		{"BindToNonExistent", nicIDPtr(999), &tcpip.ErrUnknownDevice{}, 0},
		{"BindToExistent", nicIDPtr(321), nil, 321},
		{"UnbindToDevice", nicIDPtr(0), nil, 0},
	}
	for _, testAction := range testActions {
		t.Run(testAction.name, func(t *testing.T) {
			if testAction.setBindToDevice != nil {
				bindToDevice := int32(*testAction.setBindToDevice)
				if gotErr, wantErr := ep.SocketOptions().SetBindToDevice(bindToDevice), testAction.setBindToDeviceError; gotErr != wantErr {
					t.Errorf("got SetSockOpt(&%T(%d)) = %s, want = %s", bindToDevice, bindToDevice, gotErr, wantErr)
				}
			}
			bindToDevice := ep.SocketOptions().GetBindToDevice()
			if bindToDevice != testAction.getBindToDevice {
				t.Errorf("got bindToDevice = %d, want = %d", bindToDevice, testAction.getBindToDevice)
			}
		})
	}
}

// testReadInternal sends a packet of the given test flow into the stack by
// injecting it into the link endpoint. It then attempts to read it from the
// UDP endpoint and depending on if this was expected to succeed verifies its
// correctness including any additional checker functions provided.
func testReadInternal(c *testContext, flow testFlow, packetShouldBeDropped, expectReadError bool, checkers ...checker.ControlMessagesChecker) {
	c.t.Helper()

	payload := newPayload()
	c.injectPacket(flow, payload, false)

	// Try to receive the data.
	we, ch := waiter.NewChannelEntry(nil)
	c.wq.EventRegister(&we, waiter.EventIn)
	defer c.wq.EventUnregister(&we)

	// Take a snapshot of the stats to validate them at the end of the test.
	epstats := c.ep.Stats().(*tcpip.TransportEndpointStats).Clone()

	var buf bytes.Buffer
	res, err := c.ep.Read(&buf, tcpip.ReadOptions{NeedRemoteAddr: true})
	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
		// Wait for data to become available.
		select {
		case <-ch:
			res, err = c.ep.Read(&buf, tcpip.ReadOptions{NeedRemoteAddr: true})

		case <-time.After(300 * time.Millisecond):
			if packetShouldBeDropped {
				return // expected to time out
			}
			c.t.Fatal("timed out waiting for data")
		}
	}

	if expectReadError && err != nil {
		c.checkEndpointReadStats(1, epstats, err)
		return
	}

	if err != nil {
		c.t.Fatal("Read failed:", err)
	}

	if packetShouldBeDropped {
		c.t.Fatalf("Read unexpectedly received data from %s", res.RemoteAddr.Addr)
	}

	// Check the read result.
	h := flow.header4Tuple(incoming)
	if diff := cmp.Diff(tcpip.ReadResult{
		Count:      buf.Len(),
		Total:      buf.Len(),
		RemoteAddr: tcpip.FullAddress{Addr: h.srcAddr.Addr},
	}, res, checker.IgnoreCmpPath(
		"ControlMessages", // ControlMessages will be checked later.
		"RemoteAddr.NIC",
		"RemoteAddr.Port",
	)); diff != "" {
		c.t.Fatalf("Read: unexpected result (-want +got):\n%s", diff)
	}

	// Check the payload.
	v := buf.Bytes()
	if !bytes.Equal(payload, v) {
		c.t.Fatalf("got payload = %x, want = %x", v, payload)
	}

	// Run any checkers against the ControlMessages.
	for _, f := range checkers {
		f(c.t, res.ControlMessages)
	}

	c.checkEndpointReadStats(1, epstats, err)
}

// testRead sends a packet of the given test flow into the stack by injecting it
// into the link endpoint. It then reads it from the UDP endpoint and verifies
// its correctness including any additional checker functions provided.
func testRead(c *testContext, flow testFlow, checkers ...checker.ControlMessagesChecker) {
	c.t.Helper()
	testReadInternal(c, flow, false /* packetShouldBeDropped */, false /* expectReadError */, checkers...)
}

// testFailingRead sends a packet of the given test flow into the stack by
// injecting it into the link endpoint. It then tries to read it from the UDP
// endpoint and expects this to fail.
func testFailingRead(c *testContext, flow testFlow, expectReadError bool) {
	c.t.Helper()
	testReadInternal(c, flow, true /* packetShouldBeDropped */, expectReadError)
}

func TestBindEphemeralPort(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	if err := c.ep.Bind(tcpip.FullAddress{}); err != nil {
		t.Fatalf("ep.Bind(...) failed: %s", err)
	}
}

func TestBindReservedPort(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
		c.t.Fatalf("Connect failed: %s", err)
	}

	addr, err := c.ep.GetLocalAddress()
	if err != nil {
		t.Fatalf("GetLocalAddress failed: %s", 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: %s", err)
		}
		defer ep.Close()
		{
			err := ep.Bind(addr)
			if _, ok := err.(*tcpip.ErrPortInUse); !ok {
				t.Fatalf("got ep.Bind(...) = %s, want = %s", err, &tcpip.ErrPortInUse{})
			}
		}
	}

	func() {
		ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &c.wq)
		if err != nil {
			t.Fatalf("NewEndpoint failed: %s", 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.
		{
			err := ep.Bind(tcpip.FullAddress{Port: addr.Port})
			if _, ok := err.(*tcpip.ErrPortInUse); !ok {
				t.Fatalf("got ep.Bind(...) = %s, want = %s", err, &tcpip.ErrPortInUse{})
			}
		}
		// We can bind an ipv4 address on this port, though.
		if err := ep.Bind(tcpip.FullAddress{Addr: stackAddr, Port: addr.Port}); err != nil {
			t.Fatalf("ep.Bind(...) failed: %s", 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: %s", err)
		}
		defer ep.Close()
		if err := ep.Bind(tcpip.FullAddress{Port: addr.Port}); err != nil {
			t.Fatalf("ep.Bind(...) failed: %s", err)
		}
	}()
}

func TestV4ReadOnV6(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpointForFlow(unicastV4in6)

	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	// Test acceptance.
	testRead(c, unicastV4in6)
}

func TestV4ReadOnBoundToV4MappedWildcard(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpointForFlow(unicastV4in6)

	// Bind to v4 mapped wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Addr: v4MappedWildcardAddr, Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	// Test acceptance.
	testRead(c, unicastV4in6)
}

func TestV4ReadOnBoundToV4Mapped(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpointForFlow(unicastV4in6)

	// Bind to local address.
	if err := c.ep.Bind(tcpip.FullAddress{Addr: stackV4MappedAddr, Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	// Test acceptance.
	testRead(c, unicastV4in6)
}

func TestV6ReadOnV6(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpointForFlow(unicastV6)

	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	// Test acceptance.
	testRead(c, unicastV6)
}

// TestV4ReadSelfSource checks that packets coming from a local IP address are
// correctly dropped when handleLocal is true and not otherwise.
func TestV4ReadSelfSource(t *testing.T) {
	for _, tt := range []struct {
		name              string
		handleLocal       bool
		wantErr           tcpip.Error
		wantInvalidSource uint64
	}{
		{"HandleLocal", false, nil, 0},
		{"NoHandleLocal", true, &tcpip.ErrWouldBlock{}, 1},
	} {
		t.Run(tt.name, func(t *testing.T) {
			c := newDualTestContextWithOptions(t, defaultMTU, stack.Options{
				NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
				HandleLocal:        tt.handleLocal,
			})
			defer c.cleanup()

			c.createEndpointForFlow(unicastV4)

			if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
				t.Fatalf("Bind failed: %s", err)
			}

			payload := newPayload()
			h := unicastV4.header4Tuple(incoming)
			h.srcAddr = h.dstAddr

			buf := c.buildV4Packet(payload, &h)
			c.linkEP.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
				Data: buf.ToVectorisedView(),
			}))

			if got := c.s.Stats().IP.InvalidSourceAddressesReceived.Value(); got != tt.wantInvalidSource {
				t.Errorf("c.s.Stats().IP.InvalidSourceAddressesReceived got %d, want %d", got, tt.wantInvalidSource)
			}

			if _, err := c.ep.Read(ioutil.Discard, tcpip.ReadOptions{}); err != tt.wantErr {
				t.Errorf("got c.ep.Read = %s, want = %s", err, tt.wantErr)
			}
		})
	}
}

func TestV4ReadOnV4(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpointForFlow(unicastV4)

	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	// Test acceptance.
	testRead(c, unicastV4)
}

// TestReadOnBoundToMulticast checks that an endpoint can bind to a multicast
// address and receive data sent to that address.
func TestReadOnBoundToMulticast(t *testing.T) {
	// FIXME(b/128189410): multicastV4in6 currently doesn't work as
	// AddMembershipOption doesn't handle V4in6 addresses.
	for _, flow := range []testFlow{multicastV4, multicastV6, multicastV6Only} {
		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			// Bind to multicast address.
			mcastAddr := flow.mapAddrIfApplicable(flow.getMcastAddr())
			if err := c.ep.Bind(tcpip.FullAddress{Addr: mcastAddr, Port: stackPort}); err != nil {
				c.t.Fatal("Bind failed:", err)
			}

			// Join multicast group.
			ifoptSet := tcpip.AddMembershipOption{NIC: 1, MulticastAddr: mcastAddr}
			if err := c.ep.SetSockOpt(&ifoptSet); err != nil {
				c.t.Fatalf("SetSockOpt(&%#v): %s", ifoptSet, err)
			}

			// Check that we receive multicast packets but not unicast or broadcast
			// ones.
			testRead(c, flow)
			testFailingRead(c, broadcast, false /* expectReadError */)
			testFailingRead(c, unicastV4, false /* expectReadError */)
		})
	}
}

// TestV4ReadOnBoundToBroadcast checks that an endpoint can bind to a broadcast
// address and can receive only broadcast data.
func TestV4ReadOnBoundToBroadcast(t *testing.T) {
	for _, flow := range []testFlow{broadcast, broadcastIn6} {
		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			// Bind to broadcast address.
			bcastAddr := flow.mapAddrIfApplicable(broadcastAddr)
			if err := c.ep.Bind(tcpip.FullAddress{Addr: bcastAddr, Port: stackPort}); err != nil {
				c.t.Fatalf("Bind failed: %s", err)
			}

			// Check that we receive broadcast packets but not unicast ones.
			testRead(c, flow)
			testFailingRead(c, unicastV4, false /* expectReadError */)
		})
	}
}

// TestReadFromMulticast checks that an endpoint will NOT receive a packet
// that was sent with multicast SOURCE address.
func TestReadFromMulticast(t *testing.T) {
	for _, flow := range []testFlow{reverseMulticast4, reverseMulticast6} {
		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
				t.Fatalf("Bind failed: %s", err)
			}
			testFailingRead(c, flow, false /* expectReadError */)
		})
	}
}

// TestV4ReadBroadcastOnBoundToWildcard checks that an endpoint can bind to ANY
// and receive broadcast and unicast data.
func TestV4ReadBroadcastOnBoundToWildcard(t *testing.T) {
	for _, flow := range []testFlow{broadcast, broadcastIn6} {
		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			// Bind to wildcard.
			if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
				c.t.Fatalf("Bind failed: %s (", err)
			}

			// Check that we receive both broadcast and unicast packets.
			testRead(c, flow)
			testRead(c, unicastV4)
		})
	}
}

// testFailingWrite sends a packet of the given test flow into the UDP endpoint
// and verifies it fails with the provided error code.
func testFailingWrite(c *testContext, flow testFlow, wantErr tcpip.Error) {
	c.t.Helper()
	// Take a snapshot of the stats to validate them at the end of the test.
	epstats := c.ep.Stats().(*tcpip.TransportEndpointStats).Clone()
	h := flow.header4Tuple(outgoing)
	writeDstAddr := flow.mapAddrIfApplicable(h.dstAddr.Addr)

	var r bytes.Reader
	r.Reset(newPayload())
	_, gotErr := c.ep.Write(&r, tcpip.WriteOptions{
		To: &tcpip.FullAddress{Addr: writeDstAddr, Port: h.dstAddr.Port},
	})
	c.checkEndpointWriteStats(1, epstats, gotErr)
	if gotErr != wantErr {
		c.t.Fatalf("Write returned unexpected error: got %v, want %v", gotErr, wantErr)
	}
}

// testWrite sends a packet of the given test flow from the UDP endpoint to the
// flow's destination address:port. It then receives it from the link endpoint
// and verifies its correctness including any additional checker functions
// provided.
func testWrite(c *testContext, flow testFlow, checkers ...checker.NetworkChecker) uint16 {
	c.t.Helper()
	return testWriteAndVerifyInternal(c, flow, true, checkers...)
}

// testWriteWithoutDestination sends a packet of the given test flow from the
// UDP endpoint without giving a destination address:port. It then receives it
// from the link endpoint and verifies its correctness including any additional
// checker functions provided.
func testWriteWithoutDestination(c *testContext, flow testFlow, checkers ...checker.NetworkChecker) uint16 {
	c.t.Helper()
	return testWriteAndVerifyInternal(c, flow, false, checkers...)
}

func testWriteNoVerify(c *testContext, flow testFlow, setDest bool) buffer.View {
	c.t.Helper()
	// Take a snapshot of the stats to validate them at the end of the test.
	epstats := c.ep.Stats().(*tcpip.TransportEndpointStats).Clone()

	writeOpts := tcpip.WriteOptions{}
	if setDest {
		h := flow.header4Tuple(outgoing)
		writeDstAddr := flow.mapAddrIfApplicable(h.dstAddr.Addr)
		writeOpts = tcpip.WriteOptions{
			To: &tcpip.FullAddress{Addr: writeDstAddr, Port: h.dstAddr.Port},
		}
	}
	var r bytes.Reader
	payload := newPayload()
	r.Reset(payload)
	n, err := c.ep.Write(&r, writeOpts)
	if err != nil {
		c.t.Fatalf("Write failed: %s", err)
	}
	if n != int64(len(payload)) {
		c.t.Fatalf("Bad number of bytes written: got %v, want %v", n, len(payload))
	}
	c.checkEndpointWriteStats(1, epstats, err)
	return payload
}

func testWriteAndVerifyInternal(c *testContext, flow testFlow, setDest bool, checkers ...checker.NetworkChecker) uint16 {
	c.t.Helper()
	payload := testWriteNoVerify(c, flow, setDest)
	// Received the packet and check the payload.
	b := c.getPacketAndVerify(flow, checkers...)
	var udp header.UDP
	if flow.isV4() {
		udp = header.UDP(header.IPv4(b).Payload())
	} else {
		udp = header.UDP(header.IPv6(b).Payload())
	}
	if !bytes.Equal(payload, udp.Payload()) {
		c.t.Fatalf("Bad payload: got %x, want %x", udp.Payload(), payload)
	}

	return udp.SourcePort()
}

func testDualWrite(c *testContext) uint16 {
	c.t.Helper()

	v4Port := testWrite(c, unicastV4in6)
	v6Port := testWrite(c, unicastV6)
	if v4Port != v6Port {
		c.t.Fatalf("expected v4 and v6 ports to be equal: got v4Port = %d, v6Port = %d", v4Port, v6Port)
	}

	return v4Port
}

func TestDualWriteUnbound(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	testDualWrite(c)
}

func TestDualWriteBoundToWildcard(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	p := testDualWrite(c)
	if p != stackPort {
		c.t.Fatalf("Bad port: got %v, want %v", p, stackPort)
	}
}

func TestDualWriteConnectedToV6(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	// Connect to v6 address.
	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	testWrite(c, unicastV6)

	// Write to V4 mapped address.
	testFailingWrite(c, unicastV4in6, &tcpip.ErrNetworkUnreachable{})
	const want = 1
	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).SendErrors.NoRoute.Value(); got != want {
		c.t.Fatalf("Endpoint stat not updated. got %d want %d", got, want)
	}
}

func TestDualWriteConnectedToV4Mapped(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	// Connect to v4 mapped address.
	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	testWrite(c, unicastV4in6)

	// Write to v6 address.
	testFailingWrite(c, unicastV6, &tcpip.ErrInvalidEndpointState{})
}

func TestV4WriteOnV6Only(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpointForFlow(unicastV6Only)

	// Write to V4 mapped address.
	testFailingWrite(c, unicastV4in6, &tcpip.ErrNoRoute{})
}

func TestV6WriteOnBoundToV4Mapped(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	// Bind to v4 mapped address.
	if err := c.ep.Bind(tcpip.FullAddress{Addr: stackV4MappedAddr, Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	// Write to v6 address.
	testFailingWrite(c, unicastV6, &tcpip.ErrInvalidEndpointState{})
}

func TestV6WriteOnConnected(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	// Connect to v6 address.
	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
		c.t.Fatalf("Connect failed: %s", err)
	}

	testWriteWithoutDestination(c, unicastV6)
}

func TestV4WriteOnConnected(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	// Connect to v4 mapped address.
	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}); err != nil {
		c.t.Fatalf("Connect failed: %s", err)
	}

	testWriteWithoutDestination(c, unicastV4)
}

func TestWriteOnConnectedInvalidPort(t *testing.T) {
	protocols := map[string]tcpip.NetworkProtocolNumber{
		"ipv4": ipv4.ProtocolNumber,
		"ipv6": ipv6.ProtocolNumber,
	}
	for name, pn := range protocols {
		t.Run(name, func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpoint(pn)
			if err := c.ep.Connect(tcpip.FullAddress{Addr: stackAddr, Port: invalidPort}); err != nil {
				c.t.Fatalf("Connect failed: %s", err)
			}
			writeOpts := tcpip.WriteOptions{
				To: &tcpip.FullAddress{Addr: stackAddr, Port: invalidPort},
			}
			var r bytes.Reader
			payload := newPayload()
			r.Reset(payload)
			n, err := c.ep.Write(&r, writeOpts)
			if err != nil {
				c.t.Fatalf("c.ep.Write(...) = %+s, want nil", err)
			}
			if got, want := n, int64(len(payload)); got != want {
				c.t.Fatalf("c.ep.Write(...) wrote %d bytes, want %d bytes", got, want)
			}

			{
				err := c.ep.LastError()
				if _, ok := err.(*tcpip.ErrConnectionRefused); !ok {
					c.t.Fatalf("expected c.ep.LastError() == ErrConnectionRefused, got: %+v", err)
				}
			}
		})
	}
}

// TestWriteOnBoundToV4Multicast checks that we can send packets out of a socket
// that is bound to a V4 multicast address.
func TestWriteOnBoundToV4Multicast(t *testing.T) {
	for _, flow := range []testFlow{unicastV4, multicastV4, broadcast} {
		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			// Bind to V4 mcast address.
			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastAddr, Port: stackPort}); err != nil {
				c.t.Fatal("Bind failed:", err)
			}

			testWrite(c, flow)
		})
	}
}

// TestWriteOnBoundToV4MappedMulticast checks that we can send packets out of a
// socket that is bound to a V4-mapped multicast address.
func TestWriteOnBoundToV4MappedMulticast(t *testing.T) {
	for _, flow := range []testFlow{unicastV4in6, multicastV4in6, broadcastIn6} {
		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			// Bind to V4Mapped mcast address.
			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastV4MappedAddr, Port: stackPort}); err != nil {
				c.t.Fatalf("Bind failed: %s", err)
			}

			testWrite(c, flow)
		})
	}
}

// TestWriteOnBoundToV6Multicast checks that we can send packets out of a
// socket that is bound to a V6 multicast address.
func TestWriteOnBoundToV6Multicast(t *testing.T) {
	for _, flow := range []testFlow{unicastV6, multicastV6} {
		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			// Bind to V6 mcast address.
			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastV6Addr, Port: stackPort}); err != nil {
				c.t.Fatalf("Bind failed: %s", err)
			}

			testWrite(c, flow)
		})
	}
}

// TestWriteOnBoundToV6Multicast checks that we can send packets out of a
// V6-only socket that is bound to a V6 multicast address.
func TestWriteOnBoundToV6OnlyMulticast(t *testing.T) {
	for _, flow := range []testFlow{unicastV6Only, multicastV6Only} {
		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			// Bind to V6 mcast address.
			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastV6Addr, Port: stackPort}); err != nil {
				c.t.Fatalf("Bind failed: %s", err)
			}

			testWrite(c, flow)
		})
	}
}

// TestWriteOnBoundToBroadcast checks that we can send packets out of a
// socket that is bound to the broadcast address.
func TestWriteOnBoundToBroadcast(t *testing.T) {
	for _, flow := range []testFlow{unicastV4, multicastV4, broadcast} {
		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			// Bind to V4 broadcast address.
			if err := c.ep.Bind(tcpip.FullAddress{Addr: broadcastAddr, Port: stackPort}); err != nil {
				c.t.Fatal("Bind failed:", err)
			}

			testWrite(c, flow)
		})
	}
}

// TestWriteOnBoundToV4MappedBroadcast checks that we can send packets out of a
// socket that is bound to the V4-mapped broadcast address.
func TestWriteOnBoundToV4MappedBroadcast(t *testing.T) {
	for _, flow := range []testFlow{unicastV4in6, multicastV4in6, broadcastIn6} {
		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			// Bind to V4Mapped mcast address.
			if err := c.ep.Bind(tcpip.FullAddress{Addr: broadcastV4MappedAddr, Port: stackPort}); err != nil {
				c.t.Fatalf("Bind failed: %s", err)
			}

			testWrite(c, flow)
		})
	}
}

func TestReadIncrementsPacketsReceived(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	// Create IPv4 UDP endpoint
	c.createEndpoint(ipv6.ProtocolNumber)

	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	testRead(c, unicastV4)

	var want uint64 = 1
	if got := c.s.Stats().UDP.PacketsReceived.Value(); got != want {
		c.t.Fatalf("Read did not increment PacketsReceived: got %v, want %v", got, want)
	}
}

func TestReadIPPacketInfo(t *testing.T) {
	tests := []struct {
		name              string
		proto             tcpip.NetworkProtocolNumber
		flow              testFlow
		expectedLocalAddr tcpip.Address
		expectedDestAddr  tcpip.Address
	}{
		{
			name:              "IPv4 unicast",
			proto:             header.IPv4ProtocolNumber,
			flow:              unicastV4,
			expectedLocalAddr: stackAddr,
			expectedDestAddr:  stackAddr,
		},
		{
			name:  "IPv4 multicast",
			proto: header.IPv4ProtocolNumber,
			flow:  multicastV4,
			// This should actually be a unicast address assigned to the interface.
			//
			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
			// behaviour. We still include the test so that once the bug is
			// resolved, this test will start to fail and the individual tasked
			// with fixing this bug knows to also fix this test :).
			expectedLocalAddr: multicastAddr,
			expectedDestAddr:  multicastAddr,
		},
		{
			name:  "IPv4 broadcast",
			proto: header.IPv4ProtocolNumber,
			flow:  broadcast,
			// This should actually be a unicast address assigned to the interface.
			//
			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
			// behaviour. We still include the test so that once the bug is
			// resolved, this test will start to fail and the individual tasked
			// with fixing this bug knows to also fix this test :).
			expectedLocalAddr: broadcastAddr,
			expectedDestAddr:  broadcastAddr,
		},
		{
			name:              "IPv6 unicast",
			proto:             header.IPv6ProtocolNumber,
			flow:              unicastV6,
			expectedLocalAddr: stackV6Addr,
			expectedDestAddr:  stackV6Addr,
		},
		{
			name:  "IPv6 multicast",
			proto: header.IPv6ProtocolNumber,
			flow:  multicastV6,
			// This should actually be a unicast address assigned to the interface.
			//
			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
			// behaviour. We still include the test so that once the bug is
			// resolved, this test will start to fail and the individual tasked
			// with fixing this bug knows to also fix this test :).
			expectedLocalAddr: multicastV6Addr,
			expectedDestAddr:  multicastV6Addr,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpoint(test.proto)

			bindAddr := tcpip.FullAddress{Port: stackPort}
			if err := c.ep.Bind(bindAddr); err != nil {
				t.Fatalf("Bind(%+v): %s", bindAddr, err)
			}

			if test.flow.isMulticast() {
				ifoptSet := tcpip.AddMembershipOption{NIC: 1, MulticastAddr: test.flow.getMcastAddr()}
				if err := c.ep.SetSockOpt(&ifoptSet); err != nil {
					c.t.Fatalf("SetSockOpt(&%#v): %s:", ifoptSet, err)
				}
			}

			c.ep.SocketOptions().SetReceivePacketInfo(true)

			testRead(c, test.flow, checker.ReceiveIPPacketInfo(tcpip.IPPacketInfo{
				NIC:             1,
				LocalAddr:       test.expectedLocalAddr,
				DestinationAddr: test.expectedDestAddr,
			}))

			if got := c.s.Stats().UDP.PacketsReceived.Value(); got != 1 {
				t.Fatalf("Read did not increment PacketsReceived: got = %d, want = 1", got)
			}
		})
	}
}

func TestReadRecvOriginalDstAddr(t *testing.T) {
	tests := []struct {
		name                    string
		proto                   tcpip.NetworkProtocolNumber
		flow                    testFlow
		expectedOriginalDstAddr tcpip.FullAddress
	}{
		{
			name:                    "IPv4 unicast",
			proto:                   header.IPv4ProtocolNumber,
			flow:                    unicastV4,
			expectedOriginalDstAddr: tcpip.FullAddress{1, stackAddr, stackPort},
		},
		{
			name:  "IPv4 multicast",
			proto: header.IPv4ProtocolNumber,
			flow:  multicastV4,
			// This should actually be a unicast address assigned to the interface.
			//
			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
			// behaviour. We still include the test so that once the bug is
			// resolved, this test will start to fail and the individual tasked
			// with fixing this bug knows to also fix this test :).
			expectedOriginalDstAddr: tcpip.FullAddress{1, multicastAddr, stackPort},
		},
		{
			name:  "IPv4 broadcast",
			proto: header.IPv4ProtocolNumber,
			flow:  broadcast,
			// This should actually be a unicast address assigned to the interface.
			//
			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
			// behaviour. We still include the test so that once the bug is
			// resolved, this test will start to fail and the individual tasked
			// with fixing this bug knows to also fix this test :).
			expectedOriginalDstAddr: tcpip.FullAddress{1, broadcastAddr, stackPort},
		},
		{
			name:                    "IPv6 unicast",
			proto:                   header.IPv6ProtocolNumber,
			flow:                    unicastV6,
			expectedOriginalDstAddr: tcpip.FullAddress{1, stackV6Addr, stackPort},
		},
		{
			name:  "IPv6 multicast",
			proto: header.IPv6ProtocolNumber,
			flow:  multicastV6,
			// This should actually be a unicast address assigned to the interface.
			//
			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
			// behaviour. We still include the test so that once the bug is
			// resolved, this test will start to fail and the individual tasked
			// with fixing this bug knows to also fix this test :).
			expectedOriginalDstAddr: tcpip.FullAddress{1, multicastV6Addr, stackPort},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpoint(test.proto)

			bindAddr := tcpip.FullAddress{Port: stackPort}
			if err := c.ep.Bind(bindAddr); err != nil {
				t.Fatalf("Bind(%#v): %s", bindAddr, err)
			}

			if test.flow.isMulticast() {
				ifoptSet := tcpip.AddMembershipOption{NIC: 1, MulticastAddr: test.flow.getMcastAddr()}
				if err := c.ep.SetSockOpt(&ifoptSet); err != nil {
					c.t.Fatalf("SetSockOpt(&%#v): %s:", ifoptSet, err)
				}
			}

			c.ep.SocketOptions().SetReceiveOriginalDstAddress(true)

			testRead(c, test.flow, checker.ReceiveOriginalDstAddr(test.expectedOriginalDstAddr))

			if got := c.s.Stats().UDP.PacketsReceived.Value(); got != 1 {
				t.Fatalf("Read did not increment PacketsReceived: got = %d, want = 1", got)
			}
		})
	}
}

func TestWriteIncrementsPacketsSent(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	testDualWrite(c)

	var want uint64 = 2
	if got := c.s.Stats().UDP.PacketsSent.Value(); got != want {
		c.t.Fatalf("Write did not increment PacketsSent: got %v, want %v", got, want)
	}
}

func TestNoChecksum(t *testing.T) {
	for _, flow := range []testFlow{unicastV4, unicastV6} {
		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			// Disable the checksum generation.
			c.ep.SocketOptions().SetNoChecksum(true)
			// This option is effective on IPv4 only.
			testWrite(c, flow, checker.UDP(checker.NoChecksum(flow.isV4())))

			// Enable the checksum generation.
			c.ep.SocketOptions().SetNoChecksum(false)
			testWrite(c, flow, checker.UDP(checker.NoChecksum(false)))
		})
	}
}

var _ stack.NetworkInterface = (*testInterface)(nil)

type testInterface struct {
	stack.NetworkInterface
}

func (*testInterface) ID() tcpip.NICID {
	return 0
}

func (*testInterface) Enabled() bool {
	return true
}

func TestTTL(t *testing.T) {
	for _, flow := range []testFlow{unicastV4, unicastV4in6, unicastV6, unicastV6Only, multicastV4, multicastV4in6, multicastV6, broadcast, broadcastIn6} {
		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			const multicastTTL = 42
			if err := c.ep.SetSockOptInt(tcpip.MulticastTTLOption, multicastTTL); err != nil {
				c.t.Fatalf("SetSockOptInt failed: %s", err)
			}

			var wantTTL uint8
			if flow.isMulticast() {
				wantTTL = multicastTTL
			} else {
				var p stack.NetworkProtocolFactory
				var n tcpip.NetworkProtocolNumber
				if flow.isV4() {
					p = ipv4.NewProtocol
					n = ipv4.ProtocolNumber
				} else {
					p = ipv6.NewProtocol
					n = ipv6.ProtocolNumber
				}
				s := stack.New(stack.Options{
					NetworkProtocols: []stack.NetworkProtocolFactory{p},
				})
				ep := s.NetworkProtocolInstance(n).NewEndpoint(&testInterface{}, nil)
				wantTTL = ep.DefaultTTL()
				ep.Close()
			}

			testWrite(c, flow, checker.TTL(wantTTL))
		})
	}
}

func TestSetTTL(t *testing.T) {
	for _, flow := range []testFlow{unicastV4, unicastV4in6, unicastV6, unicastV6Only, broadcast, broadcastIn6} {
		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
			for _, wantTTL := range []uint8{1, 2, 50, 64, 128, 254, 255} {
				t.Run(fmt.Sprintf("TTL:%d", wantTTL), func(t *testing.T) {
					c := newDualTestContext(t, defaultMTU)
					defer c.cleanup()

					c.createEndpointForFlow(flow)

					if err := c.ep.SetSockOptInt(tcpip.TTLOption, int(wantTTL)); err != nil {
						c.t.Fatalf("SetSockOptInt(TTLOption, %d) failed: %s", wantTTL, err)
					}

					testWrite(c, flow, checker.TTL(wantTTL))
				})
			}
		})
	}
}

func TestSetTOS(t *testing.T) {
	for _, flow := range []testFlow{unicastV4, multicastV4, broadcast} {
		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			const tos = testTOS
			v, err := c.ep.GetSockOptInt(tcpip.IPv4TOSOption)
			if err != nil {
				c.t.Errorf("GetSockOptInt(IPv4TOSOption) failed: %s", err)
			}
			// Test for expected default value.
			if v != 0 {
				c.t.Errorf("got GetSockOptInt(IPv4TOSOption) = 0x%x, want = 0x%x", v, 0)
			}

			if err := c.ep.SetSockOptInt(tcpip.IPv4TOSOption, tos); err != nil {
				c.t.Errorf("SetSockOptInt(IPv4TOSOption, 0x%x) failed: %s", tos, err)
			}

			v, err = c.ep.GetSockOptInt(tcpip.IPv4TOSOption)
			if err != nil {
				c.t.Errorf("GetSockOptInt(IPv4TOSOption) failed: %s", err)
			}

			if v != tos {
				c.t.Errorf("got GetSockOptInt(IPv4TOSOption) = 0x%x, want = 0x%x", v, tos)
			}

			testWrite(c, flow, checker.TOS(tos, 0))
		})
	}
}

func TestSetTClass(t *testing.T) {
	for _, flow := range []testFlow{unicastV4in6, unicastV6, unicastV6Only, multicastV4in6, multicastV6, broadcastIn6} {
		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
			c := newDualTestContext(t, defaultMTU)
			defer c.cleanup()

			c.createEndpointForFlow(flow)

			const tClass = testTOS
			v, err := c.ep.GetSockOptInt(tcpip.IPv6TrafficClassOption)
			if err != nil {
				c.t.Errorf("GetSockOptInt(IPv6TrafficClassOption) failed: %s", err)
			}
			// Test for expected default value.
			if v != 0 {
				c.t.Errorf("got GetSockOptInt(IPv6TrafficClassOption) = 0x%x, want = 0x%x", v, 0)
			}

			if err := c.ep.SetSockOptInt(tcpip.IPv6TrafficClassOption, tClass); err != nil {
				c.t.Errorf("SetSockOptInt(IPv6TrafficClassOption, 0x%x) failed: %s", tClass, err)
			}

			v, err = c.ep.GetSockOptInt(tcpip.IPv6TrafficClassOption)
			if err != nil {
				c.t.Errorf("GetSockOptInt(IPv6TrafficClassOption) failed: %s", err)
			}

			if v != tClass {
				c.t.Errorf("got GetSockOptInt(IPv6TrafficClassOption) = 0x%x, want = 0x%x", v, tClass)
			}

			// The header getter for TClass is called TOS, so use that checker.
			testWrite(c, flow, checker.TOS(tClass, 0))
		})
	}
}

func TestReceiveTosTClass(t *testing.T) {
	const RcvTOSOpt = "ReceiveTosOption"
	const RcvTClassOpt = "ReceiveTClassOption"

	testCases := []struct {
		name  string
		tests []testFlow
	}{
		{RcvTOSOpt, []testFlow{unicastV4, broadcast}},
		{RcvTClassOpt, []testFlow{unicastV4in6, unicastV6, unicastV6Only, broadcastIn6}},
	}
	for _, testCase := range testCases {
		for _, flow := range testCase.tests {
			t.Run(fmt.Sprintf("%s:flow:%s", testCase.name, flow), func(t *testing.T) {
				c := newDualTestContext(t, defaultMTU)
				defer c.cleanup()

				c.createEndpointForFlow(flow)
				name := testCase.name

				var optionGetter func() bool
				var optionSetter func(bool)
				switch name {
				case RcvTOSOpt:
					optionGetter = c.ep.SocketOptions().GetReceiveTOS
					optionSetter = c.ep.SocketOptions().SetReceiveTOS
				case RcvTClassOpt:
					optionGetter = c.ep.SocketOptions().GetReceiveTClass
					optionSetter = c.ep.SocketOptions().SetReceiveTClass
				default:
					t.Fatalf("unkown test variant: %s", name)
				}

				// Verify that setting and reading the option works.
				v := optionGetter()
				// Test for expected default value.
				if v != false {
					c.t.Errorf("got GetSockOptBool(%s) = %t, want = %t", name, v, false)
				}

				want := true
				optionSetter(want)

				got := optionGetter()
				if got != want {
					c.t.Errorf("got GetSockOptBool(%s) = %t, want = %t", name, got, want)
				}

				// Verify that the correct received TOS or TClass is handed through as
				// ancillary data to the ControlMessages struct.
				if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
					c.t.Fatalf("Bind failed: %s", err)
				}
				switch name {
				case RcvTClassOpt:
					testRead(c, flow, checker.ReceiveTClass(testTOS))
				case RcvTOSOpt:
					testRead(c, flow, checker.ReceiveTOS(testTOS))
				default:
					t.Fatalf("unknown test variant: %s", name)
				}
			})
		}
	}
}

func TestMulticastInterfaceOption(t *testing.T) {
	for _, flow := range []testFlow{multicastV4, multicastV4in6, multicastV6, multicastV6Only} {
		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
			for _, bindTyp := range []string{"bound", "unbound"} {
				t.Run(bindTyp, func(t *testing.T) {
					for _, optTyp := range []string{"use local-addr", "use NICID", "use local-addr and NIC"} {
						t.Run(optTyp, func(t *testing.T) {
							h := flow.header4Tuple(outgoing)
							mcastAddr := h.dstAddr.Addr
							localIfAddr := h.srcAddr.Addr

							var ifoptSet tcpip.MulticastInterfaceOption
							switch optTyp {
							case "use local-addr":
								ifoptSet.InterfaceAddr = localIfAddr
							case "use NICID":
								ifoptSet.NIC = 1
							case "use local-addr and NIC":
								ifoptSet.InterfaceAddr = localIfAddr
								ifoptSet.NIC = 1
							default:
								t.Fatal("unknown test variant")
							}

							c := newDualTestContext(t, defaultMTU)
							defer c.cleanup()

							c.createEndpoint(flow.sockProto())

							if bindTyp == "bound" {
								// Bind the socket by connecting to the multicast address.
								// This may have an influence on how the multicast interface
								// is set.
								addr := tcpip.FullAddress{
									Addr: flow.mapAddrIfApplicable(mcastAddr),
									Port: stackPort,
								}
								if err := c.ep.Connect(addr); err != nil {
									c.t.Fatalf("Connect failed: %s", err)
								}
							}

							if err := c.ep.SetSockOpt(&ifoptSet); err != nil {
								c.t.Fatalf("SetSockOpt(&%#v): %s", ifoptSet, err)
							}

							// Verify multicast interface addr and NIC were set correctly.
							// Note that NIC must be 1 since this is our outgoing interface.
							var ifoptGot tcpip.MulticastInterfaceOption
							if err := c.ep.GetSockOpt(&ifoptGot); err != nil {
								c.t.Fatalf("GetSockOpt(&%T): %s", ifoptGot, err)
							} else if ifoptWant := (tcpip.MulticastInterfaceOption{NIC: 1, InterfaceAddr: ifoptSet.InterfaceAddr}); ifoptGot != ifoptWant {
								c.t.Errorf("got multicast interface option = %#v, want = %#v", ifoptGot, ifoptWant)
							}
						})
					}
				})
			}
		})
	}
}

// TestV4UnknownDestination verifies that we generate an ICMPv4 Destination
// Unreachable message when a udp datagram is received on ports for which there
// is no bound udp socket.
func TestV4UnknownDestination(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	testCases := []struct {
		flow         testFlow
		icmpRequired bool
		// largePayload if true, will result in a payload large enough
		// so that the final generated IPv4 packet is larger than
		// header.IPv4MinimumProcessableDatagramSize.
		largePayload bool
		// badChecksum if true, will set an invalid checksum in the
		// header.
		badChecksum bool
	}{
		{unicastV4, true, false, false},
		{unicastV4, true, true, false},
		{unicastV4, false, false, true},
		{unicastV4, false, true, true},
		{multicastV4, false, false, false},
		{multicastV4, false, true, false},
		{broadcast, false, false, false},
		{broadcast, false, true, false},
	}
	checksumErrors := uint64(0)
	for _, tc := range testCases {
		t.Run(fmt.Sprintf("flow:%s icmpRequired:%t largePayload:%t badChecksum:%t", tc.flow, tc.icmpRequired, tc.largePayload, tc.badChecksum), func(t *testing.T) {
			payload := newPayload()
			if tc.largePayload {
				payload = newMinPayload(576)
			}
			c.injectPacket(tc.flow, payload, tc.badChecksum)
			if tc.badChecksum {
				checksumErrors++
				if got, want := c.s.Stats().UDP.ChecksumErrors.Value(), checksumErrors; got != want {
					t.Fatalf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
				}
			}
			if !tc.icmpRequired {
				ctx, cancel := context.WithTimeout(context.Background(), time.Second)
				defer cancel()
				if p, ok := c.linkEP.ReadContext(ctx); ok {
					t.Fatalf("unexpected packet received: %+v", p)
				}
				return
			}

			// ICMP required.
			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
			defer cancel()
			p, ok := c.linkEP.ReadContext(ctx)
			if !ok {
				t.Fatalf("packet wasn't written out")
				return
			}

			vv := buffer.NewVectorisedView(p.Pkt.Size(), p.Pkt.Views())
			pkt := vv.ToView()
			if got, want := len(pkt), header.IPv4MinimumProcessableDatagramSize; got > want {
				t.Fatalf("got an ICMP packet of size: %d, want: sz <= %d", got, want)
			}

			hdr := header.IPv4(pkt)
			checker.IPv4(t, hdr, checker.ICMPv4(
				checker.ICMPv4Type(header.ICMPv4DstUnreachable),
				checker.ICMPv4Code(header.ICMPv4PortUnreachable)))

			// We need to compare the included data part of the UDP packet that is in
			// the ICMP packet with the matching original data.
			icmpPkt := header.ICMPv4(hdr.Payload())
			payloadIPHeader := header.IPv4(icmpPkt.Payload())
			incomingHeaderLength := header.IPv4MinimumSize + header.UDPMinimumSize
			wantLen := len(payload)
			if tc.largePayload {
				// To work out the data size we need to simulate what the sender would
				// have done. The wanted size is the total available minus the sum of
				// the headers in the UDP AND ICMP packets, given that we know the test
				// had only a minimal IP header but the ICMP sender will have allowed
				// for a maximally sized packet header.
				wantLen = header.IPv4MinimumProcessableDatagramSize - header.IPv4MaximumHeaderSize - header.ICMPv4MinimumSize - incomingHeaderLength
			}

			// In the case of large payloads the IP packet may be truncated. Update
			// the length field before retrieving the udp datagram payload.
			// Add back the two headers within the payload.
			payloadIPHeader.SetTotalLength(uint16(wantLen + incomingHeaderLength))

			origDgram := header.UDP(payloadIPHeader.Payload())
			if got, want := len(origDgram.Payload()), wantLen; got != want {
				t.Fatalf("unexpected payload length got: %d, want: %d", got, want)
			}
			if got, want := origDgram.Payload(), payload[:wantLen]; !bytes.Equal(got, want) {
				t.Fatalf("unexpected payload got: %d, want: %d", got, want)
			}
		})
	}
}

// TestV6UnknownDestination verifies that we generate an ICMPv6 Destination
// Unreachable message when a udp datagram is received on ports for which there
// is no bound udp socket.
func TestV6UnknownDestination(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	testCases := []struct {
		flow         testFlow
		icmpRequired bool
		// largePayload if true will result in a payload large enough to
		// create an IPv6 packet > header.IPv6MinimumMTU bytes.
		largePayload bool
		// badChecksum if true, will set an invalid checksum in the
		// header.
		badChecksum bool
	}{
		{unicastV6, true, false, false},
		{unicastV6, true, true, false},
		{unicastV6, false, false, true},
		{unicastV6, false, true, true},
		{multicastV6, false, false, false},
		{multicastV6, false, true, false},
	}
	checksumErrors := uint64(0)
	for _, tc := range testCases {
		t.Run(fmt.Sprintf("flow:%s icmpRequired:%t largePayload:%t badChecksum:%t", tc.flow, tc.icmpRequired, tc.largePayload, tc.badChecksum), func(t *testing.T) {
			payload := newPayload()
			if tc.largePayload {
				payload = newMinPayload(1280)
			}
			c.injectPacket(tc.flow, payload, tc.badChecksum)
			if tc.badChecksum {
				checksumErrors++
				if got, want := c.s.Stats().UDP.ChecksumErrors.Value(), checksumErrors; got != want {
					t.Fatalf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
				}
			}
			if !tc.icmpRequired {
				ctx, cancel := context.WithTimeout(context.Background(), time.Second)
				defer cancel()
				if p, ok := c.linkEP.ReadContext(ctx); ok {
					t.Fatalf("unexpected packet received: %+v", p)
				}
				return
			}

			// ICMP required.
			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
			defer cancel()
			p, ok := c.linkEP.ReadContext(ctx)
			if !ok {
				t.Fatalf("packet wasn't written out")
				return
			}

			vv := buffer.NewVectorisedView(p.Pkt.Size(), p.Pkt.Views())
			pkt := vv.ToView()
			if got, want := len(pkt), header.IPv6MinimumMTU; got > want {
				t.Fatalf("got an ICMP packet of size: %d, want: sz <= %d", got, want)
			}

			hdr := header.IPv6(pkt)
			checker.IPv6(t, hdr, checker.ICMPv6(
				checker.ICMPv6Type(header.ICMPv6DstUnreachable),
				checker.ICMPv6Code(header.ICMPv6PortUnreachable)))

			icmpPkt := header.ICMPv6(hdr.Payload())
			payloadIPHeader := header.IPv6(icmpPkt.Payload())
			wantLen := len(payload)
			if tc.largePayload {
				wantLen = header.IPv6MinimumMTU - header.IPv6MinimumSize*2 - header.ICMPv6MinimumSize - header.UDPMinimumSize
			}
			// In case of large payloads the IP packet may be truncated. Update
			// the length field before retrieving the udp datagram payload.
			payloadIPHeader.SetPayloadLength(uint16(wantLen + header.UDPMinimumSize))

			origDgram := header.UDP(payloadIPHeader.Payload())
			if got, want := len(origDgram.Payload()), wantLen; got != want {
				t.Fatalf("unexpected payload length got: %d, want: %d", got, want)
			}
			if got, want := origDgram.Payload(), payload[:wantLen]; !bytes.Equal(got, want) {
				t.Fatalf("unexpected payload got: %v, want: %v", got, want)
			}
		})
	}
}

// TestIncrementMalformedPacketsReceived verifies if the malformed received
// global and endpoint stats are incremented.
func TestIncrementMalformedPacketsReceived(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)
	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	payload := newPayload()
	h := unicastV6.header4Tuple(incoming)
	buf := c.buildV6Packet(payload, &h)

	// Invalidate the UDP header length field.
	u := header.UDP(buf[header.IPv6MinimumSize:])
	u.SetLength(u.Length() + 1)

	c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: buf.ToVectorisedView(),
	}))

	const want = 1
	if got := c.s.Stats().UDP.MalformedPacketsReceived.Value(); got != want {
		t.Errorf("got stats.UDP.MalformedPacketsReceived.Value() = %d, want = %d", got, want)
	}
	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.MalformedPacketsReceived.Value(); got != want {
		t.Errorf("got EP Stats.ReceiveErrors.MalformedPacketsReceived stats = %d, want = %d", got, want)
	}
}

// TestShortHeader verifies that when a packet with a too-short UDP header is
// received, the malformed received global stat gets incremented.
func TestShortHeader(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)
	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	h := unicastV6.header4Tuple(incoming)

	// Allocate a buffer for an IPv6 and too-short UDP header.
	const udpSize = header.UDPMinimumSize - 1
	buf := buffer.NewView(header.IPv6MinimumSize + udpSize)
	// Initialize the IP header.
	ip := header.IPv6(buf)
	ip.Encode(&header.IPv6Fields{
		TrafficClass:      testTOS,
		PayloadLength:     uint16(udpSize),
		TransportProtocol: udp.ProtocolNumber,
		HopLimit:          65,
		SrcAddr:           h.srcAddr.Addr,
		DstAddr:           h.dstAddr.Addr,
	})

	// Initialize the UDP header.
	udpHdr := header.UDP(buffer.NewView(header.UDPMinimumSize))
	udpHdr.Encode(&header.UDPFields{
		SrcPort: h.srcAddr.Port,
		DstPort: h.dstAddr.Port,
		Length:  header.UDPMinimumSize,
	})
	// Calculate the UDP pseudo-header checksum.
	xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, h.srcAddr.Addr, h.dstAddr.Addr, uint16(len(udpHdr)))
	udpHdr.SetChecksum(^udpHdr.CalculateChecksum(xsum))
	// Copy all but the last byte of the UDP header into the packet.
	copy(buf[header.IPv6MinimumSize:], udpHdr)

	// Inject packet.
	c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: buf.ToVectorisedView(),
	}))

	if got, want := c.s.Stats().MalformedRcvdPackets.Value(), uint64(1); got != want {
		t.Errorf("got c.s.Stats().MalformedRcvdPackets.Value() = %d, want = %d", got, want)
	}
}

// TestBadChecksumErrors verifies if a checksum error is detected,
// global and endpoint stats are incremented.
func TestBadChecksumErrors(t *testing.T) {
	for _, flow := range []testFlow{unicastV4, unicastV6} {
		c := newDualTestContext(t, defaultMTU)
		defer c.cleanup()

		c.createEndpoint(flow.sockProto())
		// Bind to wildcard.
		if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
			c.t.Fatalf("Bind failed: %s", err)
		}

		payload := newPayload()
		c.injectPacket(flow, payload, true /* badChecksum */)

		const want = 1
		if got := c.s.Stats().UDP.ChecksumErrors.Value(); got != want {
			t.Errorf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
		}
		if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ChecksumErrors.Value(); got != want {
			t.Errorf("got EP Stats.ReceiveErrors.ChecksumErrors stats = %d, want = %d", got, want)
		}
	}
}

// TestPayloadModifiedV4 verifies if a checksum error is detected,
// global and endpoint stats are incremented.
func TestPayloadModifiedV4(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv4.ProtocolNumber)
	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	payload := newPayload()
	h := unicastV4.header4Tuple(incoming)
	buf := c.buildV4Packet(payload, &h)
	// Modify the payload so that the checksum value in the UDP header will be
	// incorrect.
	buf[len(buf)-1]++
	c.linkEP.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: buf.ToVectorisedView(),
	}))

	const want = 1
	if got := c.s.Stats().UDP.ChecksumErrors.Value(); got != want {
		t.Errorf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
	}
	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ChecksumErrors.Value(); got != want {
		t.Errorf("got EP Stats.ReceiveErrors.ChecksumErrors stats = %d, want = %d", got, want)
	}
}

// TestPayloadModifiedV6 verifies if a checksum error is detected,
// global and endpoint stats are incremented.
func TestPayloadModifiedV6(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)
	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	payload := newPayload()
	h := unicastV6.header4Tuple(incoming)
	buf := c.buildV6Packet(payload, &h)
	// Modify the payload so that the checksum value in the UDP header will be
	// incorrect.
	buf[len(buf)-1]++
	c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: buf.ToVectorisedView(),
	}))

	const want = 1
	if got := c.s.Stats().UDP.ChecksumErrors.Value(); got != want {
		t.Errorf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
	}
	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ChecksumErrors.Value(); got != want {
		t.Errorf("got EP Stats.ReceiveErrors.ChecksumErrors stats = %d, want = %d", got, want)
	}
}

// TestChecksumZeroV4 verifies if the checksum value is zero, global and
// endpoint states are *not* incremented (UDP checksum is optional on IPv4).
func TestChecksumZeroV4(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv4.ProtocolNumber)
	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	payload := newPayload()
	h := unicastV4.header4Tuple(incoming)
	buf := c.buildV4Packet(payload, &h)
	// Set the checksum field in the UDP header to zero.
	u := header.UDP(buf[header.IPv4MinimumSize:])
	u.SetChecksum(0)
	c.linkEP.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: buf.ToVectorisedView(),
	}))

	const want = 0
	if got := c.s.Stats().UDP.ChecksumErrors.Value(); got != want {
		t.Errorf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
	}
	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ChecksumErrors.Value(); got != want {
		t.Errorf("got EP Stats.ReceiveErrors.ChecksumErrors stats = %d, want = %d", got, want)
	}
}

// TestChecksumZeroV6 verifies if the checksum value is zero, global and
// endpoint states are incremented (UDP checksum is *not* optional on IPv6).
func TestChecksumZeroV6(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)
	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	payload := newPayload()
	h := unicastV6.header4Tuple(incoming)
	buf := c.buildV6Packet(payload, &h)
	// Set the checksum field in the UDP header to zero.
	u := header.UDP(buf[header.IPv6MinimumSize:])
	u.SetChecksum(0)
	c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: buf.ToVectorisedView(),
	}))

	const want = 1
	if got := c.s.Stats().UDP.ChecksumErrors.Value(); got != want {
		t.Errorf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
	}
	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ChecksumErrors.Value(); got != want {
		t.Errorf("got EP Stats.ReceiveErrors.ChecksumErrors stats = %d, want = %d", got, want)
	}
}

// TestShutdownRead verifies endpoint read shutdown and error
// stats increment on packet receive.
func TestShutdownRead(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	// Bind to wildcard.
	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
		c.t.Fatalf("Bind failed: %s", err)
	}

	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
		c.t.Fatalf("Connect failed: %s", err)
	}

	if err := c.ep.Shutdown(tcpip.ShutdownRead); err != nil {
		t.Fatalf("Shutdown failed: %s", err)
	}

	testFailingRead(c, unicastV6, true /* expectReadError */)

	var want uint64 = 1
	if got := c.s.Stats().UDP.ReceiveBufferErrors.Value(); got != want {
		t.Errorf("got stats.UDP.ReceiveBufferErrors.Value() = %v, want = %v", got, want)
	}
	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ClosedReceiver.Value(); got != want {
		t.Errorf("got EP Stats.ReceiveErrors.ClosedReceiver stats = %v, want = %v", got, want)
	}
}

// TestShutdownWrite verifies endpoint write shutdown and error
// stats increment on packet write.
func TestShutdownWrite(t *testing.T) {
	c := newDualTestContext(t, defaultMTU)
	defer c.cleanup()

	c.createEndpoint(ipv6.ProtocolNumber)

	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
		c.t.Fatalf("Connect failed: %s", err)
	}

	if err := c.ep.Shutdown(tcpip.ShutdownWrite); err != nil {
		t.Fatalf("Shutdown failed: %s", err)
	}

	testFailingWrite(c, unicastV6, &tcpip.ErrClosedForSend{})
}

func (c *testContext) checkEndpointWriteStats(incr uint64, want tcpip.TransportEndpointStats, err tcpip.Error) {
	got := c.ep.Stats().(*tcpip.TransportEndpointStats).Clone()
	switch err.(type) {
	case nil:
		want.PacketsSent.IncrementBy(incr)
	case *tcpip.ErrMessageTooLong, *tcpip.ErrInvalidOptionValue:
		want.WriteErrors.InvalidArgs.IncrementBy(incr)
	case *tcpip.ErrClosedForSend:
		want.WriteErrors.WriteClosed.IncrementBy(incr)
	case *tcpip.ErrInvalidEndpointState:
		want.WriteErrors.InvalidEndpointState.IncrementBy(incr)
	case *tcpip.ErrNoRoute, *tcpip.ErrBroadcastDisabled, *tcpip.ErrNetworkUnreachable:
		want.SendErrors.NoRoute.IncrementBy(incr)
	default:
		want.SendErrors.SendToNetworkFailed.IncrementBy(incr)
	}
	if got != want {
		c.t.Errorf("Endpoint stats not matching for error %s got %+v want %+v", err, got, want)
	}
}

func (c *testContext) checkEndpointReadStats(incr uint64, want tcpip.TransportEndpointStats, err tcpip.Error) {
	got := c.ep.Stats().(*tcpip.TransportEndpointStats).Clone()
	switch err.(type) {
	case nil, *tcpip.ErrWouldBlock:
	case *tcpip.ErrClosedForReceive:
		want.ReadErrors.ReadClosed.IncrementBy(incr)
	default:
		c.t.Errorf("Endpoint error missing stats update err %v", err)
	}
	if got != want {
		c.t.Errorf("Endpoint stats not matching for error %s got %+v want %+v", err, got, want)
	}
}

func TestOutgoingSubnetBroadcast(t *testing.T) {
	const nicID1 = 1

	ipv4Addr := tcpip.AddressWithPrefix{
		Address:   "\xc0\xa8\x01\x3a",
		PrefixLen: 24,
	}
	ipv4Subnet := ipv4Addr.Subnet()
	ipv4SubnetBcast := ipv4Subnet.Broadcast()
	ipv4Gateway := tcpip.Address("\xc0\xa8\x01\x01")
	ipv4AddrPrefix31 := tcpip.AddressWithPrefix{
		Address:   "\xc0\xa8\x01\x3a",
		PrefixLen: 31,
	}
	ipv4Subnet31 := ipv4AddrPrefix31.Subnet()
	ipv4Subnet31Bcast := ipv4Subnet31.Broadcast()
	ipv4AddrPrefix32 := tcpip.AddressWithPrefix{
		Address:   "\xc0\xa8\x01\x3a",
		PrefixLen: 32,
	}
	ipv4Subnet32 := ipv4AddrPrefix32.Subnet()
	ipv4Subnet32Bcast := ipv4Subnet32.Broadcast()
	ipv6Addr := tcpip.AddressWithPrefix{
		Address:   "\x20\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
		PrefixLen: 64,
	}
	ipv6Subnet := ipv6Addr.Subnet()
	ipv6SubnetBcast := ipv6Subnet.Broadcast()
	remNetAddr := tcpip.AddressWithPrefix{
		Address:   "\x64\x0a\x7b\x18",
		PrefixLen: 24,
	}
	remNetSubnet := remNetAddr.Subnet()
	remNetSubnetBcast := remNetSubnet.Broadcast()

	tests := []struct {
		name                 string
		nicAddr              tcpip.ProtocolAddress
		routes               []tcpip.Route
		remoteAddr           tcpip.Address
		requiresBroadcastOpt bool
	}{
		{
			name: "IPv4 Broadcast to local subnet",
			nicAddr: tcpip.ProtocolAddress{
				Protocol:          header.IPv4ProtocolNumber,
				AddressWithPrefix: ipv4Addr,
			},
			routes: []tcpip.Route{
				{
					Destination: ipv4Subnet,
					NIC:         nicID1,
				},
			},
			remoteAddr:           ipv4SubnetBcast,
			requiresBroadcastOpt: true,
		},
		{
			name: "IPv4 Broadcast to local /31 subnet",
			nicAddr: tcpip.ProtocolAddress{
				Protocol:          header.IPv4ProtocolNumber,
				AddressWithPrefix: ipv4AddrPrefix31,
			},
			routes: []tcpip.Route{
				{
					Destination: ipv4Subnet31,
					NIC:         nicID1,
				},
			},
			remoteAddr:           ipv4Subnet31Bcast,
			requiresBroadcastOpt: false,
		},
		{
			name: "IPv4 Broadcast to local /32 subnet",
			nicAddr: tcpip.ProtocolAddress{
				Protocol:          header.IPv4ProtocolNumber,
				AddressWithPrefix: ipv4AddrPrefix32,
			},
			routes: []tcpip.Route{
				{
					Destination: ipv4Subnet32,
					NIC:         nicID1,
				},
			},
			remoteAddr:           ipv4Subnet32Bcast,
			requiresBroadcastOpt: false,
		},
		// IPv6 has no notion of a broadcast.
		{
			name: "IPv6 'Broadcast' to local subnet",
			nicAddr: tcpip.ProtocolAddress{
				Protocol:          header.IPv6ProtocolNumber,
				AddressWithPrefix: ipv6Addr,
			},
			routes: []tcpip.Route{
				{
					Destination: ipv6Subnet,
					NIC:         nicID1,
				},
			},
			remoteAddr:           ipv6SubnetBcast,
			requiresBroadcastOpt: false,
		},
		{
			name: "IPv4 Broadcast to remote subnet",
			nicAddr: tcpip.ProtocolAddress{
				Protocol:          header.IPv4ProtocolNumber,
				AddressWithPrefix: ipv4Addr,
			},
			routes: []tcpip.Route{
				{
					Destination: remNetSubnet,
					Gateway:     ipv4Gateway,
					NIC:         nicID1,
				},
			},
			remoteAddr: remNetSubnetBcast,
			// TODO(gvisor.dev/issue/3938): Once we support marking a route as
			// broadcast, this test should require the broadcast option to be set.
			requiresBroadcastOpt: false,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			s := stack.New(stack.Options{
				NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
			})
			e := channel.New(0, defaultMTU, "")
			if err := s.CreateNIC(nicID1, e); err != nil {
				t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
			}
			if err := s.AddProtocolAddress(nicID1, test.nicAddr); err != nil {
				t.Fatalf("AddProtocolAddress(%d, %+v): %s", nicID1, test.nicAddr, err)
			}

			s.SetRouteTable(test.routes)

			var netProto tcpip.NetworkProtocolNumber
			switch l := len(test.remoteAddr); l {
			case header.IPv4AddressSize:
				netProto = header.IPv4ProtocolNumber
			case header.IPv6AddressSize:
				netProto = header.IPv6ProtocolNumber
			default:
				t.Fatalf("got unexpected address length = %d bytes", l)
			}

			wq := waiter.Queue{}
			ep, err := s.NewEndpoint(udp.ProtocolNumber, netProto, &wq)
			if err != nil {
				t.Fatalf("NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, netProto, err)
			}
			defer ep.Close()

			var r bytes.Reader
			data := []byte{1, 2, 3, 4}
			to := tcpip.FullAddress{
				Addr: test.remoteAddr,
				Port: 80,
			}
			opts := tcpip.WriteOptions{To: &to}
			expectedErrWithoutBcastOpt := func(err tcpip.Error) tcpip.Error {
				if _, ok := err.(*tcpip.ErrBroadcastDisabled); ok {
					return nil
				}
				return &tcpip.ErrBroadcastDisabled{}
			}
			if !test.requiresBroadcastOpt {
				expectedErrWithoutBcastOpt = nil
			}

			r.Reset(data)
			{
				n, err := ep.Write(&r, opts)
				if expectedErrWithoutBcastOpt != nil {
					if want := expectedErrWithoutBcastOpt(err); want != nil {
						t.Fatalf("got ep.Write(_, %#v) = (%d, %s), want = (_, %s)", opts, n, err, want)
					}
				} else if err != nil {
					t.Fatalf("got ep.Write(_, %#v) = (%d, %s), want = (_, nil)", opts, n, err)
				}
			}

			ep.SocketOptions().SetBroadcast(true)

			r.Reset(data)
			if n, err := ep.Write(&r, opts); err != nil {
				t.Fatalf("got ep.Write(_, %#v) = (%d, %s), want = (_, nil)", opts, n, err)
			}

			ep.SocketOptions().SetBroadcast(false)

			r.Reset(data)
			{
				n, err := ep.Write(&r, opts)
				if expectedErrWithoutBcastOpt != nil {
					if want := expectedErrWithoutBcastOpt(err); want != nil {
						t.Fatalf("got ep.Write(_, %#v) = (%d, %s), want = (_, %s)", opts, n, err, want)
					}
				} else if err != nil {
					t.Fatalf("got ep.Write(_, %#v) = (%d, %s), want = (_, nil)", opts, n, err)
				}
			}
		})
	}
}
