context

package
v0.0.0-...-385f433 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2024 License: Apache-2.0, MIT Imports: 17 Imported by: 1

Documentation

Overview

Package context provides a test context for use in tcp tests. It also provides helper methods to assert/check certain behaviours.

Index

Constants

View Source
const (

	// StackPort is used as the listening port in tests for passive
	// connects.
	StackPort = 1234

	// TestPort is the TCP port used for packets sent to the stack
	// via the link layer endpoint.
	TestPort = 4096

	// TestInitialSequenceNumber is the initial sequence number sent in packets that
	// are sent in response to a SYN or in the initial SYN sent to the stack.
	TestInitialSequenceNumber = 789
)

Variables

View Source
var (
	// StackAddr is the IPv4 address assigned to the stack.
	StackAddr = tcpip.AddrFromSlice([]byte("\x0a\x00\x00\x01"))

	// TestAddr is the source address for packets sent to the stack via the
	// link layer endpoint.
	TestAddr = tcpip.AddrFromSlice([]byte("\x0a\x00\x00\x02"))

	// StackV6Addr is the IPv6 address assigned to the stack.
	StackV6Addr = tcpip.AddrFromSlice([]byte("\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"))

	// TestV6Addr is the source address for packets sent to the stack via
	// the link layer endpoint.
	TestV6Addr = tcpip.AddrFromSlice([]byte("\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"))

	// StackV4MappedAddr is StackAddr as a mapped v6 address.
	StackV4MappedAddr = tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + string(StackAddr.AsSlice())))

	// TestV4MappedAddr is TestAddr as a mapped v6 address.
	TestV4MappedAddr = tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + string(TestAddr.AsSlice())))

	// V4MappedWildcardAddr is the mapped v6 representation of 0.0.0.0.
	V4MappedWildcardAddr = tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00"))
)
View Source
var StackAddrWithPrefix = tcpip.AddressWithPrefix{
	Address:   StackAddr,
	PrefixLen: 24,
}

StackAddrWithPrefix is StackAddr with its associated prefix length.

View Source
var StackV6AddrWithPrefix = tcpip.AddressWithPrefix{
	Address:   StackV6Addr,
	PrefixLen: header.IIDOffsetInIPv6Address * 8,
}

StackV6AddrWithPrefix is StackV6Addr with its associated prefix length.

Functions

This section is empty.

Types

type Context

type Context struct {

	// IRS holds the initial sequence number in the SYN sent by endpoint in
	// case of an active connect or the sequence number sent by the endpoint
	// in the SYN-ACK sent in response to a SYN when listening in passive
	// mode.
	IRS seqnum.Value

	// Port holds the port bound by EP below in case of an active connect or
	// the listening port number in case of a passive connect.
	Port uint16

	// EP is the test endpoint in the stack owned by this context. This endpoint
	// is used in various tests to either initiate an active connect or is used
	// as a passive listening endpoint to accept inbound connections.
	EP tcpip.Endpoint

	// Wq is the wait queue associated with EP and is used to block for events
	// on EP.
	WQ waiter.Queue

	// TimeStampEnabled is true if ep is connected with the timestamp option
	// enabled.
	TimeStampEnabled bool

	// WindowScale is the expected window scale in SYN packets sent by
	// the stack.
	WindowScale uint8

	// RcvdWindowScale is the actual window scale sent by the stack in
	// SYN/SYN-ACK.
	RcvdWindowScale uint8
	// contains filtered or unexported fields
}

Context provides an initialized Network stack and a link layer endpoint for use in TCP tests.

func New

func New(t *testing.T, mtu uint32) *Context

New allocates and initializes a test context containing a new stack and a link-layer endpoint.

func NewWithOpts

func NewWithOpts(t *testing.T, opts Options) *Context

NewWithOpts allocates and initializes a test context containing a new stack and a link-layer endpoint with specific options.

func (*Context) AcceptWithOptions

func (c *Context) AcceptWithOptions(wndScale int, synOptions header.TCPSynOptions, delay time.Duration) *RawEndpoint

AcceptWithOptions initializes a listening endpoint and connects to it with the provided options enabled. It delays before the final ACK of the 3WHS is sent. It also verifies that the SYN-ACK has the expected values for the provided options.

The function returns a RawEndpoint representing the other end of the accepted endpoint.

func (*Context) AcceptWithOptionsNoDelay

func (c *Context) AcceptWithOptionsNoDelay(wndScale int, synOptions header.TCPSynOptions) *RawEndpoint

AcceptWithOptionsNoDelay delegates call to AcceptWithOptions without delay.

func (*Context) BuildSegment

func (c *Context) BuildSegment(payload []byte, h *Headers) buffer.Buffer

BuildSegment builds a TCP segment based on the given Headers and payload.

func (*Context) BuildSegmentWithAddrs

func (c *Context) BuildSegmentWithAddrs(payload []byte, h *Headers, src, dst tcpip.Address) buffer.Buffer

BuildSegmentWithAddrs builds a TCP segment based on the given Headers, payload and source and destination IPv4 addresses.

func (*Context) CheckNoPacket

func (c *Context) CheckNoPacket(errMsg string)

CheckNoPacket verifies that no packet is received for 1 second.

func (*Context) CheckNoPacketTimeout

func (c *Context) CheckNoPacketTimeout(errMsg string, wait time.Duration)

CheckNoPacketTimeout verifies that no packet is received during the time specified by wait.

func (*Context) Cleanup

func (c *Context) Cleanup()

Cleanup closes the context endpoint if required.

func (*Context) CloseNoWait

func (c *Context) CloseNoWait()

CloseNoWait closes the link and transport endpoints and does not wait for them to finish processing.

func (*Context) Connect

func (c *Context) Connect(iss seqnum.Value, rcvWnd seqnum.Size, options []byte)

Connect performs the 3-way handshake for c.EP with the provided Initial Sequence Number (iss) and receive window(rcvWnd) and any options if specified.

It also sets the receive buffer for the endpoint to the specified value in epRcvBuf.

PreCondition: c.EP must already be created.

func (*Context) Create

func (c *Context) Create(epRcvBuf int)

Create creates a TCP endpoint.

func (*Context) CreateConnected

func (c *Context) CreateConnected(iss seqnum.Value, rcvWnd seqnum.Size, epRcvBuf int)

CreateConnected creates a connected TCP endpoint.

func (*Context) CreateConnectedWithOptions

func (c *Context) CreateConnectedWithOptions(wantOptions header.TCPSynOptions, delay time.Duration) *RawEndpoint

CreateConnectedWithOptions creates and connects c.ep with the specified TCP options enabled and returns a RawEndpoint which represents the other end of the connection. It delays before a SYNACK is sent. This makes c.EP have a higher RTT estimate so that spurious TLPs aren't sent in tests, which helps reduce flakiness.

It also verifies where required(eg.Timestamp) that the ACK to the SYN-ACK does not carry an option that was not requested.

func (*Context) CreateConnectedWithOptionsNoDelay

func (c *Context) CreateConnectedWithOptionsNoDelay(wantOptions header.TCPSynOptions) *RawEndpoint

CreateConnectedWithOptionsNoDelay just calls CreateConnectedWithOptions without delay.

func (*Context) CreateConnectedWithRawOptions

func (c *Context) CreateConnectedWithRawOptions(iss seqnum.Value, rcvWnd seqnum.Size, epRcvBuf int, options []byte)

CreateConnectedWithRawOptions creates a connected TCP endpoint and sends the specified option bytes as the Option field in the initial SYN packet.

It also sets the receive buffer for the endpoint to the specified value in epRcvBuf.

func (*Context) CreateV6Endpoint

func (c *Context) CreateV6Endpoint(v6only bool)

CreateV6Endpoint creates and initializes c.ep as a IPv6 Endpoint. If v6Only is true then it sets the IP_V6ONLY option on the socket to make it a IPv6 only endpoint instead of a default dual stack socket.

func (*Context) GetPacket

func (c *Context) GetPacket() *buffer.View

GetPacket reads a packet from the link layer endpoint and verifies that it is an IPv4 packet with the expected source and destination addresses.

func (*Context) GetPacketNonBlocking

func (c *Context) GetPacketNonBlocking() *buffer.View

GetPacketNonBlocking reads a packet from the link layer endpoint and verifies that it is an IPv4 packet with the expected source and destination address. If no packet is available it will return nil immediately.

func (*Context) GetPacketWithTimeout

func (c *Context) GetPacketWithTimeout(timeout time.Duration) *buffer.View

GetPacketWithTimeout reads a packet from the link layer endpoint and verifies that it is an IPv4 packet with the expected source and destination addresses. If no packet is received in the specified timeout it will return nil.

func (*Context) GetV6Packet

func (c *Context) GetV6Packet() *buffer.View

GetV6Packet reads a single packet from the link layer endpoint of the context and asserts that it is an IPv6 Packet with the expected src/dest addresses.

func (*Context) MSSWithoutOptions

func (c *Context) MSSWithoutOptions() uint16

MSSWithoutOptions returns the value for the MSS used by the stack when no options are in use.

func (*Context) MSSWithoutOptionsV6

func (c *Context) MSSWithoutOptionsV6() uint16

MSSWithoutOptionsV6 returns the value for the MSS used by the stack when no options are in use for IPv6 packets.

func (*Context) PassiveConnect

func (c *Context) PassiveConnect(maxPayload, wndScale int, synOptions header.TCPSynOptions)

PassiveConnect just disables WindowScaling and delegates the call to PassiveConnectWithOptions.

func (*Context) PassiveConnectWithOptions

func (c *Context) PassiveConnectWithOptions(maxPayload, wndScale int, synOptions header.TCPSynOptions, delay time.Duration) *RawEndpoint

PassiveConnectWithOptions initiates a new connection (with the specified TCP options enabled) to the port on which the Context.ep is listening for new connections. It also validates that the SYN-ACK has the expected values for the enabled options. The final ACK of the handshake is delayed by specified duration.

NOTE: MSS is not a negotiated option and it can be asymmetric in each direction. This function uses the maxPayload to set the MSS to be sent to the peer on a connect and validates that the MSS in the SYN-ACK response is equal to the MTU - (tcphdr len + iphdr len).

wndScale is the expected window scale in the SYN-ACK and synOptions.WS is the value of the window scaling option to be sent in the SYN. If synOptions.WS > 0 then we send the WindowScale option.

func (*Context) ReceiveAndCheckPacket

func (c *Context) ReceiveAndCheckPacket(data []byte, offset, size int)

ReceiveAndCheckPacket reads a packet from the link layer endpoint and verifies that the packet packet payload of packet matches the slice of data indicated by offset & size.

func (*Context) ReceiveAndCheckPacketWithOptions

func (c *Context) ReceiveAndCheckPacketWithOptions(data []byte, offset, size, optlen int)

ReceiveAndCheckPacketWithOptions reads a packet from the link layer endpoint and verifies that the packet packet payload of packet matches the slice of data indicated by offset & size and skips optlen bytes in addition to the IP TCP headers when comparing the data.

func (*Context) ReceiveNonBlockingAndCheckPacket

func (c *Context) ReceiveNonBlockingAndCheckPacket(data []byte, offset, size int) bool

ReceiveNonBlockingAndCheckPacket reads a packet from the link layer endpoint and verifies that the packet packet payload of packet matches the slice of data indicated by offset & size. It returns true if a packet was received and processed.

func (*Context) SACKEnabled

func (c *Context) SACKEnabled() bool

SACKEnabled returns true if the TCP Protocol option SACKEnabled is set to true for the Stack in the context.

func (*Context) SendAck

func (c *Context) SendAck(seq seqnum.Value, bytesReceived int)

SendAck sends an ACK packet.

func (*Context) SendAckWithSACK

func (c *Context) SendAckWithSACK(seq seqnum.Value, bytesReceived int, sackBlocks []header.SACKBlock)

SendAckWithSACK sends an ACK packet which includes the sackBlocks specified.

func (*Context) SendICMPPacket

func (c *Context) SendICMPPacket(typ header.ICMPv4Type, code header.ICMPv4Code, p1, p2 *buffer.View, maxTotalSize int)

SendICMPPacket builds and sends an ICMPv4 packet via the link layer endpoint.

func (*Context) SendPacket

func (c *Context) SendPacket(payload []byte, h *Headers)

SendPacket builds and sends a TCP segment(with the provided payload & TCP headers) in an IPv4 packet via the link layer endpoint.

func (*Context) SendPacketWithAddrs

func (c *Context) SendPacketWithAddrs(payload []byte, h *Headers, src, dst tcpip.Address)

SendPacketWithAddrs builds and sends a TCP segment(with the provided payload & TCPheaders) in an IPv4 packet via the link layer endpoint using the provided source and destination IPv4 addresses.

func (*Context) SendSegment

func (c *Context) SendSegment(s buffer.Buffer)

SendSegment sends a TCP segment that has already been built and written to a buffer.VectorisedView.

func (*Context) SendV6Packet

func (c *Context) SendV6Packet(payload []byte, h *Headers)

SendV6Packet builds and sends an IPv6 Packet via the link layer endpoint of the context.

func (*Context) SendV6PacketWithAddrs

func (c *Context) SendV6PacketWithAddrs(payload []byte, h *Headers, src, dst tcpip.Address)

SendV6PacketWithAddrs builds and sends an IPv6 Packet via the link layer endpoint of the context using the provided source and destination IPv6 addresses.

func (*Context) SetGSOEnabled

func (c *Context) SetGSOEnabled(enable bool)

SetGSOEnabled enables or disables generic segmentation offload.

func (*Context) Stack

func (c *Context) Stack() *stack.Stack

Stack returns a reference to the stack in the Context.

type Headers

type Headers struct {
	// SrcPort holds the src port value to be used in the packet.
	SrcPort uint16

	// DstPort holds the destination port value to be used in the packet.
	DstPort uint16

	// SeqNum is the value of the sequence number field in the TCP header.
	SeqNum seqnum.Value

	// AckNum represents the acknowledgement number field in the TCP header.
	AckNum seqnum.Value

	// Flags are the TCP flags in the TCP header.
	Flags header.TCPFlags

	// RcvWnd is the window to be advertised in the ReceiveWindow field of
	// the TCP header.
	RcvWnd seqnum.Size

	// TCPOpts holds the options to be sent in the option field of the TCP
	// header.
	TCPOpts []byte
}

Headers is used to represent the TCP header fields when building a new packet.

type Options

type Options struct {
	// EnableV4 indicates whether IPv4 should be enabled.
	EnableV4 bool

	// EnableV6 indicates whether IPv4 should be enabled.
	EnableV6 bool

	// MTU indicates the maximum transmission unit on the link layer.
	MTU uint32

	// Clock that is used by Stack.
	Clock tcpip.Clock
}

Options contains options for creating a new test context.

type RawEndpoint

type RawEndpoint struct {
	C          *Context
	SrcPort    uint16
	DstPort    uint16
	Flags      header.TCPFlags
	NextSeqNum seqnum.Value
	AckNum     seqnum.Value
	WndSize    seqnum.Size
	RecentTS   uint32 // Stores the latest timestamp to echo back.
	TSVal      uint32 // TSVal stores the last timestamp sent by this endpoint.

	// SackPermitted is true if SACKPermitted option was negotiated for this endpoint.
	SACKPermitted bool
}

RawEndpoint is just a small wrapper around a TCP endpoint's state to make sending data and ACK packets easy while being able to manipulate the sequence numbers and timestamp values as needed.

func (*RawEndpoint) SendPacket

func (r *RawEndpoint) SendPacket(payload []byte, opts []byte)

SendPacket is a small wrapper function to build and send packets.

func (*RawEndpoint) SendPacketWithTS

func (r *RawEndpoint) SendPacketWithTS(payload []byte, tsVal uint32)

SendPacketWithTS embeds the provided tsVal in the Timestamp option for the packet to be sent out.

func (*RawEndpoint) VerifyACKHasSACK

func (r *RawEndpoint) VerifyACKHasSACK(sackBlocks []header.SACKBlock)

VerifyACKHasSACK verifies that the ACK contains the specified SACKBlocks.

func (*RawEndpoint) VerifyACKNoSACK

func (r *RawEndpoint) VerifyACKNoSACK()

VerifyACKNoSACK verifies that the ACK does not contain a SACK block.

func (*RawEndpoint) VerifyACKRcvWnd

func (r *RawEndpoint) VerifyACKRcvWnd(rcvWnd uint16)

VerifyACKRcvWnd verifies that the window advertised by the incoming ACK matches the provided rcvWnd.

func (*RawEndpoint) VerifyACKWithTS

func (r *RawEndpoint) VerifyACKWithTS(tsVal uint32)

VerifyACKWithTS verifies that the tsEcr field in the ack matches the provided tsVal.

func (*RawEndpoint) VerifyAndReturnACKWithTS

func (r *RawEndpoint) VerifyAndReturnACKWithTS(tsVal uint32) *buffer.View

VerifyAndReturnACKWithTS verifies that the tsEcr field int he ACK matches the provided tsVal as well as returns the original packet.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL