Send ACK to OTW SEQs/unacc ACKs in CLOSE_WAIT
This fixed the corresponding packetimpact test. PiperOrigin-RevId: 310593470
This commit is contained in:
parent
c59e7b832c
commit
5d7d5ed7d6
|
@ -609,5 +609,8 @@ func Acceptable(segSeq seqnum.Value, segLen seqnum.Size, rcvNxt, rcvAcc seqnum.V
|
||||||
}
|
}
|
||||||
// Page 70 of RFC 793 allows packets that can be made "acceptable" by trimming
|
// Page 70 of RFC 793 allows packets that can be made "acceptable" by trimming
|
||||||
// the payload, so we'll accept any payload that overlaps the receieve window.
|
// the payload, so we'll accept any payload that overlaps the receieve window.
|
||||||
return rcvNxt.LessThan(segSeq.Add(segLen)) && segSeq.LessThan(rcvAcc)
|
// segSeq < rcvAcc is more correct according to RFC, however, Linux does it
|
||||||
|
// differently, it uses segSeq <= rcvAcc, we'd want to keep the same behavior
|
||||||
|
// as Linux.
|
||||||
|
return rcvNxt.LessThan(segSeq.Add(segLen)) && segSeq.LessThanEq(rcvAcc)
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,16 @@ func newReceiver(ep *endpoint, irs seqnum.Value, rcvWnd seqnum.Size, rcvWndScale
|
||||||
// acceptable checks if the segment sequence number range is acceptable
|
// acceptable checks if the segment sequence number range is acceptable
|
||||||
// according to the table on page 26 of RFC 793.
|
// according to the table on page 26 of RFC 793.
|
||||||
func (r *receiver) acceptable(segSeq seqnum.Value, segLen seqnum.Size) bool {
|
func (r *receiver) acceptable(segSeq seqnum.Value, segLen seqnum.Size) bool {
|
||||||
return header.Acceptable(segSeq, segLen, r.rcvNxt, r.rcvAcc)
|
// r.rcvWnd could be much larger than the window size we advertised in our
|
||||||
|
// outgoing packets, we should use what we have advertised for acceptability
|
||||||
|
// test.
|
||||||
|
scaledWindowSize := r.rcvWnd >> r.rcvWndScale
|
||||||
|
if scaledWindowSize > 0xffff {
|
||||||
|
// This is what we actually put in the Window field.
|
||||||
|
scaledWindowSize = 0xffff
|
||||||
|
}
|
||||||
|
advertisedWindowSize := scaledWindowSize << r.rcvWndScale
|
||||||
|
return header.Acceptable(segSeq, segLen, r.rcvNxt, r.rcvNxt.Add(advertisedWindowSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSendParams returns the parameters needed by the sender when building
|
// getSendParams returns the parameters needed by the sender when building
|
||||||
|
@ -259,7 +268,14 @@ func (r *receiver) handleRcvdSegmentClosing(s *segment, state EndpointState, clo
|
||||||
// If we are in one of the shutdown states then we need to do
|
// If we are in one of the shutdown states then we need to do
|
||||||
// additional checks before we try and process the segment.
|
// additional checks before we try and process the segment.
|
||||||
switch state {
|
switch state {
|
||||||
case StateCloseWait, StateClosing, StateLastAck:
|
case StateCloseWait:
|
||||||
|
// If the ACK acks something not yet sent then we send an ACK.
|
||||||
|
if r.ep.snd.sndNxt.LessThan(s.ackNumber) {
|
||||||
|
r.ep.snd.sendAck()
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case StateClosing, StateLastAck:
|
||||||
if !s.sequenceNumber.LessThanEq(r.rcvNxt) {
|
if !s.sequenceNumber.LessThanEq(r.rcvNxt) {
|
||||||
// Just drop the segment as we have
|
// Just drop the segment as we have
|
||||||
// already received a FIN and this
|
// already received a FIN and this
|
||||||
|
@ -276,7 +292,7 @@ func (r *receiver) handleRcvdSegmentClosing(s *segment, state EndpointState, clo
|
||||||
// SHUT_RD) then any data past the rcvNxt should
|
// SHUT_RD) then any data past the rcvNxt should
|
||||||
// trigger a RST.
|
// trigger a RST.
|
||||||
endDataSeq := s.sequenceNumber.Add(seqnum.Size(s.data.Size()))
|
endDataSeq := s.sequenceNumber.Add(seqnum.Size(s.data.Size()))
|
||||||
if rcvClosed && r.rcvNxt.LessThan(endDataSeq) {
|
if state != StateCloseWait && rcvClosed && r.rcvNxt.LessThan(endDataSeq) {
|
||||||
return true, tcpip.ErrConnectionAborted
|
return true, tcpip.ErrConnectionAborted
|
||||||
}
|
}
|
||||||
if state == StateFinWait1 {
|
if state == StateFinWait1 {
|
||||||
|
@ -329,13 +345,6 @@ func (r *receiver) handleRcvdSegment(s *segment) (drop bool, err *tcpip.Error) {
|
||||||
state := r.ep.EndpointState()
|
state := r.ep.EndpointState()
|
||||||
closed := r.ep.closed
|
closed := r.ep.closed
|
||||||
|
|
||||||
if state != StateEstablished {
|
|
||||||
drop, err := r.handleRcvdSegmentClosing(s, state, closed)
|
|
||||||
if drop || err != nil {
|
|
||||||
return drop, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
segLen := seqnum.Size(s.data.Size())
|
segLen := seqnum.Size(s.data.Size())
|
||||||
segSeq := s.sequenceNumber
|
segSeq := s.sequenceNumber
|
||||||
|
|
||||||
|
@ -347,6 +356,13 @@ func (r *receiver) handleRcvdSegment(s *segment) (drop bool, err *tcpip.Error) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if state != StateEstablished {
|
||||||
|
drop, err := r.handleRcvdSegmentClosing(s, state, closed)
|
||||||
|
if drop || err != nil {
|
||||||
|
return drop, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Store the time of the last ack.
|
// Store the time of the last ack.
|
||||||
r.lastRcvdAckTime = time.Now()
|
r.lastRcvdAckTime = time.Now()
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ func TestAcceptable(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
// The segment is smaller than the window.
|
// The segment is smaller than the window.
|
||||||
{105, 2, 100, 104, false},
|
{105, 2, 100, 104, false},
|
||||||
{105, 2, 101, 105, false},
|
{105, 2, 101, 105, true},
|
||||||
{105, 2, 102, 106, true},
|
{105, 2, 102, 106, true},
|
||||||
{105, 2, 103, 107, true},
|
{105, 2, 103, 107, true},
|
||||||
{105, 2, 104, 108, true},
|
{105, 2, 104, 108, true},
|
||||||
|
@ -39,7 +39,7 @@ func TestAcceptable(t *testing.T) {
|
||||||
{105, 2, 107, 111, false},
|
{105, 2, 107, 111, false},
|
||||||
|
|
||||||
// The segment is larger than the window.
|
// The segment is larger than the window.
|
||||||
{105, 4, 103, 105, false},
|
{105, 4, 103, 105, true},
|
||||||
{105, 4, 104, 106, true},
|
{105, 4, 104, 106, true},
|
||||||
{105, 4, 105, 107, true},
|
{105, 4, 105, 107, true},
|
||||||
{105, 4, 106, 108, true},
|
{105, 4, 106, 108, true},
|
||||||
|
|
|
@ -117,8 +117,6 @@ packetimpact_go_test(
|
||||||
packetimpact_go_test(
|
packetimpact_go_test(
|
||||||
name = "tcp_close_wait_ack",
|
name = "tcp_close_wait_ack",
|
||||||
srcs = ["tcp_close_wait_ack_test.go"],
|
srcs = ["tcp_close_wait_ack_test.go"],
|
||||||
# TODO(b/153574037): Fix netstack then remove the line below.
|
|
||||||
netstack = False,
|
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/tcpip/header",
|
"//pkg/tcpip/header",
|
||||||
"//pkg/tcpip/seqnum",
|
"//pkg/tcpip/seqnum",
|
||||||
|
|
Loading…
Reference in New Issue