diff options
author | Bhasker Hariharan <bhaskerh@google.com> | 2019-05-03 10:49:58 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-05-03 10:51:18 -0700 |
commit | 458fe955a74bca6c33cb321901d771cf146f5cc6 (patch) | |
tree | 97641fe6228cf7444c32d97dbf39e04bca245b5d /pkg/tcpip/transport/tcp/testing | |
parent | 95614bbefa2f4657c77b2040630088fdec7f5dd1 (diff) |
Implement support for SACK based recovery(RFC 6675).
PiperOrigin-RevId: 246536003
Change-Id: I118b745f45040be9c70cb6a1028acdb06c78d8c9
Diffstat (limited to 'pkg/tcpip/transport/tcp/testing')
-rw-r--r-- | pkg/tcpip/transport/tcp/testing/context/context.go | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index fa721a7f8..e08eb6533 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -355,13 +355,27 @@ func (c *Context) SendPacket(payload []byte, h *Headers) { // SendAck sends an ACK packet. func (c *Context) SendAck(seq seqnum.Value, bytesReceived int) { + c.SendAckWithSACK(seq, bytesReceived, nil) +} + +// SendAckWithSACK sends an ACK packet which includes the sackBlocks specified. +func (c *Context) SendAckWithSACK(seq seqnum.Value, bytesReceived int, sackBlocks []header.SACKBlock) { + options := make([]byte, 40) + offset := 0 + if len(sackBlocks) > 0 { + offset += header.EncodeNOP(options[offset:]) + offset += header.EncodeNOP(options[offset:]) + offset += header.EncodeSACKBlocks(sackBlocks, options[offset:]) + } + c.SendPacket(nil, &Headers{ SrcPort: TestPort, DstPort: c.Port, Flags: header.TCPFlagAck, - SeqNum: seqnum.Value(testInitialSequenceNumber).Add(1), + SeqNum: seq, AckNum: c.IRS.Add(1 + seqnum.Size(bytesReceived)), RcvWnd: 30000, + TCPOpts: options[:offset], }) } @@ -369,9 +383,17 @@ func (c *Context) SendAck(seq seqnum.Value, bytesReceived int) { // verifies that the packet packet payload of packet matches the slice // of data indicated by offset & size. func (c *Context) ReceiveAndCheckPacket(data []byte, offset, size int) { + c.ReceiveAndCheckPacketWithOptions(data, offset, size, 0) +} + +// 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 (c *Context) ReceiveAndCheckPacketWithOptions(data []byte, offset, size, optlen int) { b := c.GetPacket() checker.IPv4(c.t, b, - checker.PayloadLen(size+header.TCPMinimumSize), + checker.PayloadLen(size+header.TCPMinimumSize+optlen), checker.TCP( checker.DstPort(TestPort), checker.SeqNum(uint32(c.IRS.Add(seqnum.Size(1+offset)))), @@ -381,7 +403,7 @@ func (c *Context) ReceiveAndCheckPacket(data []byte, offset, size int) { ) pdata := data[offset:][:size] - if p := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; bytes.Compare(pdata, p) != 0 { + if p := b[header.IPv4MinimumSize+header.TCPMinimumSize+optlen:]; bytes.Compare(pdata, p) != 0 { c.t.Fatalf("Data is different: expected %v, got %v", pdata, p) } } @@ -683,12 +705,14 @@ func (c *Context) CreateConnectedWithOptions(wantOptions header.TCPSynOptions) * b := c.GetPacket() // Validate that the syn has the timestamp option and a valid // TS value. + mss := uint16(c.linkEP.MTU() - header.IPv4MinimumSize - header.TCPMinimumSize) + checker.IPv4(c.t, b, checker.TCP( checker.DstPort(TestPort), checker.TCPFlags(header.TCPFlagSyn), checker.TCPSynOptions(header.TCPSynOptions{ - MSS: uint16(c.linkEP.MTU() - header.IPv4MinimumSize - header.TCPMinimumSize), + MSS: mss, TS: true, WS: defaultWindowScale, SACKPermitted: c.SACKEnabled(), |