Give TCP flags a dedicated type

- Implement Stringer for it so that we can improve error messages.
- Use TCPFlags through the code base. There used to be a mixed usage of byte,
  uint8 and int as TCP flags.

PiperOrigin-RevId: 361940150
This commit is contained in:
Zeling Feng
2021-03-09 18:00:03 -08:00
committed by gVisor bot
parent 6ef5bdab21
commit 2a888a106d
40 changed files with 253 additions and 219 deletions
+6 -6
View File
@@ -567,7 +567,7 @@ func TCPWindowLessThanEq(window uint16) TransportChecker {
}
// TCPFlags creates a checker that checks the tcp flags.
func TCPFlags(flags uint8) TransportChecker {
func TCPFlags(flags header.TCPFlags) TransportChecker {
return func(t *testing.T, h header.Transport) {
t.Helper()
@@ -576,15 +576,15 @@ func TCPFlags(flags uint8) TransportChecker {
t.Fatalf("TCP header not found in h: %T", h)
}
if f := tcp.Flags(); f != flags {
t.Errorf("Bad flags, got 0x%x, want 0x%x", f, flags)
if got := tcp.Flags(); got != flags {
t.Errorf("got tcp.Flags() = %s, want %s", got, flags)
}
}
}
// TCPFlagsMatch creates a checker that checks that the tcp flags, masked by the
// given mask, match the supplied flags.
func TCPFlagsMatch(flags, mask uint8) TransportChecker {
func TCPFlagsMatch(flags, mask header.TCPFlags) TransportChecker {
return func(t *testing.T, h header.Transport) {
t.Helper()
@@ -593,8 +593,8 @@ func TCPFlagsMatch(flags, mask uint8) TransportChecker {
t.Fatalf("TCP header not found in h: %T", h)
}
if f := tcp.Flags(); (f & mask) != (flags & mask) {
t.Errorf("Bad masked flags, got 0x%x, want 0x%x, mask 0x%x", f, flags, mask)
if got := tcp.Flags(); (got & mask) != (flags & mask) {
t.Errorf("got tcp.Flags() = %s, want %s, mask %s", got, flags, mask)
}
}
}
+21 -7
View File
@@ -45,9 +45,23 @@ const (
TCPMaxSACKBlocks = 4
)
// TCPFlags is the dedicated type for TCP flags.
type TCPFlags uint8
// String implements Stringer.String.
func (f TCPFlags) String() string {
flagsStr := []byte("FSRPAU")
for i := range flagsStr {
if f&(1<<uint(i)) == 0 {
flagsStr[i] = ' '
}
}
return string(flagsStr)
}
// Flags that may be set in a TCP segment.
const (
TCPFlagFin = 1 << iota
TCPFlagFin TCPFlags = 1 << iota
TCPFlagSyn
TCPFlagRst
TCPFlagPsh
@@ -94,7 +108,7 @@ type TCPFields struct {
DataOffset uint8
// Flags is the "flags" field of a TCP packet.
Flags uint8
Flags TCPFlags
// WindowSize is the "window size" field of a TCP packet.
WindowSize uint16
@@ -234,8 +248,8 @@ func (b TCP) Payload() []byte {
}
// Flags returns the flags field of the tcp header.
func (b TCP) Flags() uint8 {
return b[TCPFlagsOffset]
func (b TCP) Flags() TCPFlags {
return TCPFlags(b[TCPFlagsOffset])
}
// WindowSize returns the "window size" field of the tcp header.
@@ -319,10 +333,10 @@ func (b TCP) ParsedOptions() TCPOptions {
return ParseTCPOptions(b.Options())
}
func (b TCP) encodeSubset(seq, ack uint32, flags uint8, rcvwnd uint16) {
func (b TCP) encodeSubset(seq, ack uint32, flags TCPFlags, rcvwnd uint16) {
binary.BigEndian.PutUint32(b[TCPSeqNumOffset:], seq)
binary.BigEndian.PutUint32(b[TCPAckNumOffset:], ack)
b[TCPFlagsOffset] = flags
b[TCPFlagsOffset] = uint8(flags)
binary.BigEndian.PutUint16(b[TCPWinSizeOffset:], rcvwnd)
}
@@ -338,7 +352,7 @@ func (b TCP) Encode(t *TCPFields) {
// EncodePartial updates a subset of the fields of the tcp header. It is useful
// in cases when similar segments are produced.
func (b TCP) EncodePartial(partialChecksum, length uint16, seqnum, acknum uint32, flags byte, rcvwnd uint16) {
func (b TCP) EncodePartial(partialChecksum, length uint16, seqnum, acknum uint32, flags TCPFlags, rcvwnd uint16) {
// Add the total length and "flags" field contributions to the checksum.
// We don't use the flags field directly from the header because it's a
// one-byte field with an odd offset, so it would be accounted for
+20
View File
@@ -146,3 +146,23 @@ func TestTCPParseOptions(t *testing.T) {
}
}
}
func TestTCPFlags(t *testing.T) {
for _, tt := range []struct {
flags header.TCPFlags
want string
}{
{header.TCPFlagFin, "F "},
{header.TCPFlagSyn, " S "},
{header.TCPFlagRst, " R "},
{header.TCPFlagPsh, " P "},
{header.TCPFlagAck, " A "},
{header.TCPFlagUrg, " U"},
{header.TCPFlagSyn | header.TCPFlagAck, " S A "},
{header.TCPFlagFin | header.TCPFlagAck, "F A "},
} {
if got := tt.flags.String(); got != tt.want {
t.Errorf("got TCPFlags(%#b).String() = %s, want = %s", tt.flags, got, tt.want)
}
}
}
+1 -7
View File
@@ -398,13 +398,7 @@ func logPacket(prefix string, dir direction, protocol tcpip.NetworkProtocolNumbe
// Initialize the TCP flags.
flags := tcp.Flags()
flagsStr := []byte("FSRPAU")
for i := range flagsStr {
if flags&(1<<uint(i)) == 0 {
flagsStr[i] = ' '
}
}
details = fmt.Sprintf("flags:0x%02x (%s) seqnum: %d ack: %d win: %d xsum:0x%x", flags, string(flagsStr), tcp.SequenceNumber(), tcp.AckNumber(), tcp.WindowSize(), tcp.Checksum())
details = fmt.Sprintf("flags: %s seqnum: %d ack: %d win: %d xsum:0x%x", flags, tcp.SequenceNumber(), tcp.AckNumber(), tcp.WindowSize(), tcp.Checksum())
if flags&header.TCPFlagSyn != 0 {
details += fmt.Sprintf(" options: %+v", header.ParseSynOptions(tcp.Options(), flags&header.TCPFlagAck != 0))
} else {
+3 -3
View File
@@ -68,7 +68,7 @@ type handshake struct {
ep *endpoint
state handshakeState
active bool
flags uint8
flags header.TCPFlags
ackNum seqnum.Value
// iss is the initial send sequence number, as defined in RFC 793.
@@ -700,7 +700,7 @@ type tcpFields struct {
id stack.TransportEndpointID
ttl uint8
tos uint8
flags byte
flags header.TCPFlags
seq seqnum.Value
ack seqnum.Value
rcvWnd seqnum.Size
@@ -877,7 +877,7 @@ func (e *endpoint) makeOptions(sackBlocks []header.SACKBlock) []byte {
}
// sendRaw sends a TCP segment to the endpoint's peer.
func (e *endpoint) sendRaw(data buffer.VectorisedView, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size) tcpip.Error {
func (e *endpoint) sendRaw(data buffer.VectorisedView, flags header.TCPFlags, seq, ack seqnum.Value, rcvWnd seqnum.Size) tcpip.Error {
var sackBlocks []header.SACKBlock
if e.EndpointState() == StateEstablished && e.rcv.pendingRcvdSegments.Len() > 0 && (flags&header.TCPFlagAck != 0) {
sackBlocks = e.sack.Blocks[:e.sack.NumBlocks]
+1 -1
View File
@@ -226,7 +226,7 @@ func replyWithReset(stack *stack.Stack, s *segment, tos, ttl uint8) tcpip.Error
// Get the seqnum from the packet if the ack flag is set.
seq := seqnum.Value(0)
ack := seqnum.Value(0)
flags := byte(header.TCPFlagRst)
flags := header.TCPFlagRst
// As per RFC 793 page 35 (Reset Generation)
// 1. If the connection does not exist (CLOSED) then a reset is sent
// in response to any incoming segment except another reset. In
+3 -3
View File
@@ -62,7 +62,7 @@ type segment struct {
views [8]buffer.View `state:"nosave"`
sequenceNumber seqnum.Value
ackNumber seqnum.Value
flags uint8
flags header.TCPFlags
window seqnum.Size
// csum is only populated for received segments.
csum uint16
@@ -141,12 +141,12 @@ func (s *segment) clone() *segment {
}
// flagIsSet checks if at least one flag in flags is set in s.flags.
func (s *segment) flagIsSet(flags uint8) bool {
func (s *segment) flagIsSet(flags header.TCPFlags) bool {
return s.flags&flags != 0
}
// flagsAreSet checks if all flags in flags are set in s.flags.
func (s *segment) flagsAreSet(flags uint8) bool {
func (s *segment) flagsAreSet(flags header.TCPFlags) bool {
return s.flags&flags == flags
}
+1 -1
View File
@@ -1613,7 +1613,7 @@ func (s *sender) sendSegment(seg *segment) tcpip.Error {
// sendSegmentFromView sends a new segment containing the given payload, flags
// and sequence number.
func (s *sender) sendSegmentFromView(data buffer.VectorisedView, flags byte, seq seqnum.Value) tcpip.Error {
func (s *sender) sendSegmentFromView(data buffer.VectorisedView, flags header.TCPFlags, seq seqnum.Value) tcpip.Error {
s.lastSendTime = time.Now()
if seq == s.rttMeasureSeqNum {
s.rttMeasureTime = s.lastSendTime
+33 -33
View File
@@ -1372,7 +1372,7 @@ func TestTOSV4(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790), // Acknum is initial sequence number + 1
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
checker.TOS(tos, 0),
)
@@ -1420,7 +1420,7 @@ func TestTrafficClassV6(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
checker.TOS(tos, 0),
)
@@ -2201,7 +2201,7 @@ func TestSimpleSend(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -2241,7 +2241,7 @@ func TestZeroWindowSend(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -2263,7 +2263,7 @@ func TestZeroWindowSend(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -2310,7 +2310,7 @@ func TestScaledWindowConnect(t *testing.T) {
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPWindow(0x5fff),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
}
@@ -2341,7 +2341,7 @@ func TestNonScaledWindowConnect(t *testing.T) {
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPWindow(0xffff),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
}
@@ -2414,7 +2414,7 @@ func TestScaledWindowAccept(t *testing.T) {
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPWindow(0x5fff),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
}
@@ -2487,7 +2487,7 @@ func TestNonScaledWindowAccept(t *testing.T) {
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPWindow(0xffff),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
}
@@ -2665,7 +2665,7 @@ func TestSegmentMerging(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)+uint32(i)+1),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
}
@@ -2688,7 +2688,7 @@ func TestSegmentMerging(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)+11),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -2737,7 +2737,7 @@ func TestDelay(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(seq)),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -2785,7 +2785,7 @@ func TestUndelay(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(seq)),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -2808,7 +2808,7 @@ func TestUndelay(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(seq)),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -2871,7 +2871,7 @@ func TestMSSNotDelayed(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(seq)),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -2922,7 +2922,7 @@ func testBrokenUpWrite(t *testing.T, c *context.Context, maxPayload int) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)+1+uint32(bytesReceived)),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -3437,7 +3437,7 @@ func TestMaxRTO(t *testing.T) {
checker.IPv4(t, c.GetPacket(),
checker.TCP(
checker.DstPort(context.TestPort),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
const numRetransmits = 2
@@ -3446,7 +3446,7 @@ func TestMaxRTO(t *testing.T) {
checker.IPv4(t, c.GetPacket(),
checker.TCP(
checker.DstPort(context.TestPort),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
if time.Since(start).Round(time.Second).Seconds() != rto.Seconds() {
@@ -3489,7 +3489,7 @@ func TestRetransmitIPv4IDUniqueness(t *testing.T) {
checker.FragmentFlags(0),
checker.TCP(
checker.DstPort(context.TestPort),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
idSet := map[uint16]struct{}{header.IPv4(pkt).ID(): {}}
@@ -3501,7 +3501,7 @@ func TestRetransmitIPv4IDUniqueness(t *testing.T) {
checker.FragmentFlags(0),
checker.TCP(
checker.DstPort(context.TestPort),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
id := header.IPv4(pkt).ID()
@@ -3632,7 +3632,7 @@ func TestFinWithNoPendingData(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(next),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
next += uint32(len(view))
@@ -3709,7 +3709,7 @@ func TestFinWithPendingDataCwndFull(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(next),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
next += uint32(len(view))
@@ -3728,7 +3728,7 @@ func TestFinWithPendingDataCwndFull(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -3795,7 +3795,7 @@ func TestFinWithPendingData(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(next),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
next += uint32(len(view))
@@ -3821,7 +3821,7 @@ func TestFinWithPendingData(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(next),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
next += uint32(len(view))
@@ -3885,7 +3885,7 @@ func TestFinWithPartialAck(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(next),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
next += uint32(len(view))
@@ -3906,7 +3906,7 @@ func TestFinWithPartialAck(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(next),
checker.TCPAckNum(791),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -3922,7 +3922,7 @@ func TestFinWithPartialAck(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(next),
checker.TCPAckNum(791),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
next += uint32(len(view))
@@ -4032,7 +4032,7 @@ func scaledSendWindow(t *testing.T, scale uint8) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -4844,7 +4844,7 @@ func TestPathMTUDiscovery(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(seqNum),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
seqNum += uint32(size)
@@ -5129,7 +5129,7 @@ func TestKeepalive(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(next),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -7174,7 +7174,7 @@ func TestTCPCloseWithData(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(uint32(iss)+2), // Acknum is initial sequence number + 1
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -7274,7 +7274,7 @@ func TestTCPUserTimeout(t *testing.T) {
checker.DstPort(context.TestPort),
checker.TCPSeqNum(next),
checker.TCPAckNum(790),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -170,7 +170,7 @@ func timeStampEnabledAccept(t *testing.T, cookieEnabled bool, wndScale int, wndS
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPWindow(wndSize),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
checker.TCPTimestampChecker(true, 0, tsVal+1),
),
)
@@ -231,7 +231,7 @@ func timeStampDisabledAccept(t *testing.T, cookieEnabled bool, wndScale int, wnd
checker.TCPSeqNum(uint32(c.IRS)+1),
checker.TCPAckNum(790),
checker.TCPWindow(wndSize),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
checker.TCPTimestampChecker(false, 0, 0),
),
)
@@ -101,7 +101,7 @@ type Headers struct {
AckNum seqnum.Value
// Flags are the TCP flags in the TCP header.
Flags int
Flags header.TCPFlags
// RcvWnd is the window to be advertised in the ReceiveWindow field of
// the TCP header.
@@ -452,7 +452,7 @@ func (c *Context) BuildSegmentWithAddrs(payload []byte, h *Headers, src, dst tcp
SeqNum: uint32(h.SeqNum),
AckNum: uint32(h.AckNum),
DataOffset: uint8(header.TCPMinimumSize + len(h.TCPOpts)),
Flags: uint8(h.Flags),
Flags: h.Flags,
WindowSize: uint16(h.RcvWnd),
})
@@ -544,7 +544,7 @@ func (c *Context) ReceiveAndCheckPacketWithOptions(data []byte, offset, size, op
checker.DstPort(TestPort),
checker.TCPSeqNum(uint32(c.IRS.Add(seqnum.Size(1+offset)))),
checker.TCPAckNum(uint32(seqnum.Value(TestInitialSequenceNumber).Add(1))),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -571,7 +571,7 @@ func (c *Context) ReceiveNonBlockingAndCheckPacket(data []byte, offset, size int
checker.DstPort(TestPort),
checker.TCPSeqNum(uint32(c.IRS.Add(seqnum.Size(1+offset)))),
checker.TCPAckNum(uint32(seqnum.Value(TestInitialSequenceNumber).Add(1))),
checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
),
)
@@ -650,7 +650,7 @@ func (c *Context) SendV6PacketWithAddrs(payload []byte, h *Headers, src, dst tcp
SeqNum: uint32(h.SeqNum),
AckNum: uint32(h.AckNum),
DataOffset: header.TCPMinimumSize,
Flags: uint8(h.Flags),
Flags: h.Flags,
WindowSize: uint16(h.RcvWnd),
})
@@ -780,7 +780,7 @@ type RawEndpoint struct {
C *Context
SrcPort uint16
DstPort uint16
Flags int
Flags header.TCPFlags
NextSeqNum seqnum.Value
AckNum seqnum.Value
WndSize seqnum.Size
@@ -465,7 +465,7 @@ func TestIgnoreBadResetOnSynSent(t *testing.T) {
// Receive a RST with a bad ACK, it should not cause the connection to
// be reset.
acks := []uint32{1234, 1236, 1000, 5000}
flags := []uint8{header.TCPFlagRst, header.TCPFlagRst | header.TCPFlagAck}
flags := []header.TCPFlags{header.TCPFlagRst, header.TCPFlagRst | header.TCPFlagAck}
for _, a := range acks {
for _, f := range flags {
tcp.Encode(&header.TCPFields{
+6 -6
View File
@@ -677,17 +677,17 @@ func (conn *TCPIPv4) Connect(t *testing.T) {
t.Helper()
// Send the SYN.
conn.Send(t, TCP{Flags: Uint8(header.TCPFlagSyn)})
conn.Send(t, TCP{Flags: TCPFlags(header.TCPFlagSyn)})
// Wait for the SYN-ACK.
synAck, err := conn.Expect(t, TCP{Flags: Uint8(header.TCPFlagSyn | header.TCPFlagAck)}, time.Second)
synAck, err := conn.Expect(t, TCP{Flags: TCPFlags(header.TCPFlagSyn | header.TCPFlagAck)}, time.Second)
if err != nil {
t.Fatalf("didn't get synack during handshake: %s", err)
}
conn.layerStates[len(conn.layerStates)-1].(*tcpState).synAck = synAck
// Send an ACK.
conn.Send(t, TCP{Flags: Uint8(header.TCPFlagAck)})
conn.Send(t, TCP{Flags: TCPFlags(header.TCPFlagAck)})
}
// ConnectWithOptions performs a TCP 3-way handshake with given TCP options.
@@ -696,17 +696,17 @@ func (conn *TCPIPv4) ConnectWithOptions(t *testing.T, options []byte) {
t.Helper()
// Send the SYN.
conn.Send(t, TCP{Flags: Uint8(header.TCPFlagSyn), Options: options})
conn.Send(t, TCP{Flags: TCPFlags(header.TCPFlagSyn), Options: options})
// Wait for the SYN-ACK.
synAck, err := conn.Expect(t, TCP{Flags: Uint8(header.TCPFlagSyn | header.TCPFlagAck)}, time.Second)
synAck, err := conn.Expect(t, TCP{Flags: TCPFlags(header.TCPFlagSyn | header.TCPFlagAck)}, time.Second)
if err != nil {
t.Fatalf("didn't get synack during handshake: %s", err)
}
conn.layerStates[len(conn.layerStates)-1].(*tcpState).synAck = synAck
// Send an ACK.
conn.Send(t, TCP{Flags: Uint8(header.TCPFlagAck)})
conn.Send(t, TCP{Flags: TCPFlags(header.TCPFlagAck)})
}
// ExpectData is a convenient method that expects a Layer and the Layer after
+9 -3
View File
@@ -407,6 +407,12 @@ func Uint8(v uint8) *uint8 {
return &v
}
// TCPFlags is a helper routine that allocates a new
// header.TCPFlags value to store v and returns a pointer to it.
func TCPFlags(v header.TCPFlags) *header.TCPFlags {
return &v
}
// Address is a helper routine that allocates a new tcpip.Address value to
// store v and returns a pointer to it.
func Address(v tcpip.Address) *tcpip.Address {
@@ -1030,7 +1036,7 @@ type TCP struct {
SeqNum *uint32
AckNum *uint32
DataOffset *uint8
Flags *uint8
Flags *header.TCPFlags
WindowSize *uint16
Checksum *uint16
UrgentPointer *uint16
@@ -1063,7 +1069,7 @@ func (l *TCP) ToBytes() ([]byte, error) {
h.SetDataOffset(uint8(l.length()))
}
if l.Flags != nil {
h.SetFlags(*l.Flags)
h.SetFlags(uint8(*l.Flags))
}
if l.WindowSize != nil {
h.SetWindowSize(*l.WindowSize)
@@ -1157,7 +1163,7 @@ func parseTCP(b []byte) (Layer, layerParser) {
SeqNum: Uint32(h.SequenceNumber()),
AckNum: Uint32(h.AckNumber()),
DataOffset: Uint8(h.DataOffset()),
Flags: Uint8(h.Flags()),
Flags: TCPFlags(h.Flags()),
WindowSize: Uint16(h.WindowSize()),
Checksum: Uint16(h.Checksum()),
UrgentPointer: Uint16(h.UrgentPointer()),
+4 -4
View File
@@ -178,7 +178,7 @@ func TestLayerStringFormat(t *testing.T) {
SeqNum: Uint32(3452155723),
AckNum: Uint32(2596996163),
DataOffset: Uint8(5),
Flags: Uint8(20),
Flags: TCPFlags(header.TCPFlagRst | header.TCPFlagAck),
WindowSize: Uint16(64240),
Checksum: Uint16(0x2e2b),
},
@@ -188,7 +188,7 @@ func TestLayerStringFormat(t *testing.T) {
"SeqNum:3452155723 " +
"AckNum:2596996163 " +
"DataOffset:5 " +
"Flags:20 " +
"Flags: R A " +
"WindowSize:64240 " +
"Checksum:11819" +
"}",
@@ -436,7 +436,7 @@ func TestTCPOptions(t *testing.T) {
DstPort: Uint16(54321),
SeqNum: Uint32(0),
AckNum: Uint32(0),
Flags: Uint8(header.TCPFlagSyn),
Flags: TCPFlags(header.TCPFlagSyn),
WindowSize: Uint16(8192),
Checksum: Uint16(0xf51c),
UrgentPointer: Uint16(0),
@@ -480,7 +480,7 @@ func TestTCPOptions(t *testing.T) {
DstPort: Uint16(54321),
SeqNum: Uint32(0),
AckNum: Uint32(0),
Flags: Uint8(header.TCPFlagSyn),
Flags: TCPFlags(header.TCPFlagSyn),
WindowSize: Uint16(8192),
Checksum: Uint16(0xe521),
UrgentPointer: Uint16(0),
@@ -51,21 +51,21 @@ func TestFinWait2Timeout(t *testing.T) {
}
dut.Close(t, acceptFd)
if _, err := conn.Expect(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagFin | header.TCPFlagAck)}, time.Second); err != nil {
if _, err := conn.Expect(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagFin | header.TCPFlagAck)}, time.Second); err != nil {
t.Fatalf("expected a FIN-ACK within 1 second but got none: %s", err)
}
conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck)})
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
time.Sleep(5 * time.Second)
conn.Drain(t)
conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck)})
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
if tt.linger2 {
if _, err := conn.Expect(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagRst)}, time.Second); err != nil {
if _, err := conn.Expect(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagRst)}, time.Second); err != nil {
t.Fatalf("expected a RST packet within a second but got none: %s", err)
}
} else {
if got, err := conn.Expect(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagRst)}, 10*time.Second); got != nil || err == nil {
if got, err := conn.Expect(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagRst)}, 10*time.Second); got != nil || err == nil {
t.Fatalf("expected no RST packets within ten seconds but got one: %s", got)
}
}
@@ -100,7 +100,7 @@ func TestIPv4RetransmitIdentificationUniqueness(t *testing.T) {
// Let the DUT estimate RTO with RTT from the DATA-ACK.
// TODO(gvisor.dev/issue/2685) Estimate RTO during handshake, after which
// we can skip sending this ACK.
conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck)})
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
dut.Send(t, remoteFD, tc.payload, 0)
expectTCP := &testbench.TCP{SeqNum: testbench.Uint32(uint32(*conn.RemoteSeqNum(t)))}
+6 -6
View File
@@ -60,24 +60,24 @@ func TestTCPCorkMSS(t *testing.T) {
// Expect the segments to be coalesced and sent and capped to MSS.
expectedPayload := testbench.Payload{Bytes: expectedData[:mss]}
if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck)}, &expectedPayload, time.Second); err != nil {
if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)}, &expectedPayload, time.Second); err != nil {
t.Fatalf("expected payload was not received: %s", err)
}
conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck)})
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
// Expect the coalesced segment to be split and transmitted.
expectedPayload = testbench.Payload{Bytes: expectedData[mss:]}
if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck | header.TCPFlagPsh)}, &expectedPayload, time.Second); err != nil {
if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck | header.TCPFlagPsh)}, &expectedPayload, time.Second); err != nil {
t.Fatalf("expected payload was not received: %s", err)
}
// Check for segments to *not* be held up because of TCP_CORK when
// the current send window is less than MSS.
conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck), WindowSize: testbench.Uint16(uint16(2 * len(sampleData)))})
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck), WindowSize: testbench.Uint16(uint16(2 * len(sampleData)))})
dut.Send(t, acceptFD, sampleData, 0)
dut.Send(t, acceptFD, sampleData, 0)
expectedPayload = testbench.Payload{Bytes: append(sampleData, sampleData...)}
if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck | header.TCPFlagPsh)}, &expectedPayload, time.Second); err != nil {
if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck | header.TCPFlagPsh)}, &expectedPayload, time.Second); err != nil {
t.Fatalf("expected payload was not received: %s", err)
}
conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck)})
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
}
@@ -38,8 +38,8 @@ func TestTCPHandshakeWindowSize(t *testing.T) {
defer conn.Close(t)
// Start handshake with zero window size.
conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagSyn), WindowSize: testbench.Uint16(uint16(0))})
if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.Uint8(header.TCPFlagSyn | header.TCPFlagAck)}, nil, time.Second); err != nil {
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn), WindowSize: testbench.Uint16(uint16(0))})
if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn | header.TCPFlagAck)}, nil, time.Second); err != nil {
t.Fatalf("expected SYN-ACK: %s", err)
}
// Update the advertised window size to a non-zero value with the ACK that
@@ -47,7 +47,7 @@ func TestTCPHandshakeWindowSize(t *testing.T) {
//
// Set the window size with MSB set and expect the dut to treat it as
// an unsigned value.
conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck), WindowSize: testbench.Uint16(uint16(1 << 15))})
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck), WindowSize: testbench.Uint16(uint16(1 << 15))})
acceptFd, _ := dut.Accept(t, listenFD)
defer dut.Close(t, acceptFd)
@@ -59,7 +59,7 @@ func TestTCPHandshakeWindowSize(t *testing.T) {
// expect the dut to honor the recently advertised non-zero window
// and actually send out the data instead of probing for zero window.
dut.Send(t, acceptFd, sampleData, 0)
if _, err := conn.ExpectNextData(t, &testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck | header.TCPFlagPsh)}, samplePayload, time.Second); err != nil {
if _, err := conn.ExpectNextData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck | header.TCPFlagPsh)}, samplePayload, time.Second); err != nil {
t.Fatalf("expected payload was not received: %s", err)
}
}
+1 -1
View File
@@ -51,7 +51,7 @@ func TestTCPInfo(t *testing.T) {
if _, err := conn.ExpectData(t, &testbench.TCP{}, samplePayload, time.Second); err != nil {
t.Fatalf("expected a packet with payload %v: %s", samplePayload, err)
}
conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck)})
conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
info := linux.TCPInfo{}
infoBytes := dut.GetSockOpt(t, acceptFD, unix.SOL_TCP, unix.TCP_INFO, int32(linux.SizeOfTCPInfo))

Some files were not shown because too many files have changed in this diff Show More