func (r *receiver) handleRcvdSegment(s *segment) (drop bool, err *tcpip.Error) {
	r.ep.mu.RLock()
	state := r.ep.state
	closed := r.ep.closed
	r.ep.mu.RUnlock()
	if state != StateEstablished {
		drop, err := r.handleRcvdSegmentClosing(s, state, closed)
		if drop || err != nil {
			return drop, err
		}
	}
	segLen := seqnum.Size(s.data.Size())
	segSeq := s.sequenceNumber
	if !r.acceptable(segSeq, segLen) {
		r.ep.snd.sendAck()
		return true, nil
	}
	if !r.consumeSegment(s, segSeq, segLen) {
		if segLen > 0 || s.flagIsSet(header.TCPFlagFin) {
			if r.pendingBufUsed < r.pendingBufSize {
				r.pendingBufUsed += s.logicalLen()
				s.incRef()
				heap.Push(&r.pendingRcvdSegments, s)
				UpdateSACKBlocks(&r.ep.sack, segSeq, segSeq.Add(segLen), r.rcvNxt)
			}
			r.ep.snd.sendAck()
		}
		return false, nil
	}
	if segLen > 0 {
		r.updateRTT()
	}
	for !r.closed && r.pendingRcvdSegments.Len() > 0 {
		s := r.pendingRcvdSegments[0]
		segLen := seqnum.Size(s.data.Size())
		segSeq := s.sequenceNumber
		if !segSeq.Add(segLen-1).LessThan(r.rcvNxt) &&
			!r.consumeSegment(s, segSeq, segLen) {
			break
		}
		heap.Pop(&r.pendingRcvdSegments)
		r.pendingBufUsed -= s.logicalLen()
		s.decRef()
	}
	return false, nil
}
handleRcvdSegment handles TCP segments directed at the connection managed by
r as they arrive. It is called by the protocol main loop.
package tcp
import (
	"container/heap"
	"time"
	"github.com/google/netstack/tcpip"
	"github.com/google/netstack/tcpip/header"
	"github.com/google/netstack/tcpip/seqnum"
)
type receiver struct {
	ep *endpoint
	rcvNxt seqnum.Value
	rcvAcc seqnum.Value
	rcvWnd seqnum.Size
	rcvWndScale uint8
	closed bool
	pendingRcvdSegments segmentHeap
	pendingBufUsed      seqnum.Size
	pendingBufSize      seqnum.Size
}
func newReceiver(ep *endpoint, irs seqnum.Value, rcvWnd seqnum.Size, rcvWndScale uint8, pendingBufSize seqnum.Size) *receiver {
	return &receiver{
		ep:             ep,
		rcvNxt:         irs + 1,
		rcvAcc:         irs.Add(rcvWnd + 1),
		rcvWnd:         rcvWnd,
		rcvWndScale:    rcvWndScale,
		pendingBufSize: pendingBufSize,
	}
}
func (r *receiver) acceptable(segSeq seqnum.Value, segLen seqnum.Size) bool {
	rcvWnd := r.rcvNxt.Size(r.rcvAcc)
	if rcvWnd == 0 {
		return segLen == 0 && segSeq == r.rcvNxt
	}
	return segSeq.InWindow(r.rcvNxt, rcvWnd) ||
		seqnum.Overlap(r.rcvNxt, rcvWnd, segSeq, segLen)
}
func (r *receiver) getSendParams() (rcvNxt seqnum.Value, rcvWnd seqnum.Size) {
	receiveBufferAvailable := r.ep.receiveBufferAvailable()
	acc := r.rcvNxt.Add(seqnum.Size(receiveBufferAvailable))
	if r.rcvAcc.LessThan(acc) {
		r.rcvAcc = acc
	}
	r.rcvWnd = r.rcvNxt.Size(r.rcvAcc)
	return r.rcvNxt, r.rcvWnd >> r.rcvWndScale
}
func (r *receiver) nonZeroWindow() {
	if (r.rcvAcc-r.rcvNxt)>>r.rcvWndScale != 0 {
		return
	}
	r.ep.snd.sendAck()
}
func (r *receiver) consumeSegment(s *segment, segSeq seqnum.Value, segLen seqnum.Size) bool {
	if segLen > 0 {
		if !r.rcvNxt.InWindow(segSeq, segLen) {
			return false
		}
		if segSeq.LessThan(r.rcvNxt) {
			diff := segSeq.Size(r.rcvNxt)
			segLen -= diff
			segSeq.UpdateForward(diff)
			s.sequenceNumber.UpdateForward(diff)
			s.data.TrimFront(int(diff))
		}
		r.ep.readyToRead(s)
	} else if segSeq != r.rcvNxt {
		return false
	}
	r.rcvNxt = segSeq.Add(segLen)
	if r.rcvAcc.LessThan(r.rcvNxt) {
		r.rcvAcc = r.rcvNxt
	}
	TrimSACKBlockList(&r.ep.sack, r.rcvNxt)
	if s.flagIsSet(header.TCPFlagFin) {
		r.rcvNxt++
		r.ep.snd.sendAck()
		r.closed = true
		r.ep.readyToRead(nil)
		r.ep.mu.Lock()
		switch r.ep.state {
		case StateEstablished:
			r.ep.state = StateCloseWait
		case StateFinWait1:
			if s.flagIsSet(header.TCPFlagAck) {
				r.ep.state = StateTimeWait
			} else {
				r.ep.state = StateClosing
			}
		case StateFinWait2:
			r.ep.state = StateTimeWait
		}
		r.ep.mu.Unlock()
		first := 0
		if len(r.pendingRcvdSegments) != 0 && r.pendingRcvdSegments[0] == s {
			first = 1
		}
		for i := first; i < len(r.pendingRcvdSegments); i++ {
			r.pendingRcvdSegments[i].decRef()
		}
		r.pendingRcvdSegments = r.pendingRcvdSegments[:first]
		return true
	}
	if s.flagIsSet(header.TCPFlagAck) {
		r.ep.mu.Lock()
		switch r.ep.state {
		case StateFinWait1:
			r.ep.state = StateFinWait2
			r.ep.notifyProtocolGoroutine(notifyClose)
		case StateClosing:
			r.ep.state = StateTimeWait
		case StateLastAck:
			r.ep.transitionToStateCloseLocked()
		}
		r.ep.mu.Unlock()
	}
	return true
}
func (r *receiver) updateRTT() {
	r.ep.rcvListMu.Lock()
	if r.ep.rcvAutoParams.rttMeasureTime.IsZero() {
		r.ep.rcvAutoParams.rttMeasureTime = time.Now()
		r.ep.rcvAutoParams.rttMeasureSeqNumber = r.rcvNxt.Add(r.rcvWnd)
		r.ep.rcvListMu.Unlock()
		return
	}
	if r.rcvNxt.LessThan(r.ep.rcvAutoParams.rttMeasureSeqNumber) {
		r.ep.rcvListMu.Unlock()
		return
	}
	rtt := time.Since(r.ep.rcvAutoParams.rttMeasureTime)
	if r.ep.rcvAutoParams.rtt == 0 || rtt < r.ep.rcvAutoParams.rtt {
		r.ep.rcvAutoParams.rtt = rtt
	}
	r.ep.rcvAutoParams.rttMeasureTime = time.Now()
	r.ep.rcvAutoParams.rttMeasureSeqNumber = r.rcvNxt.Add(r.rcvWnd)
	r.ep.rcvListMu.Unlock()
}
func (r *receiver) handleRcvdSegmentClosing(s *segment, state EndpointState, closed bool) (drop bool, err *tcpip.Error) {
	r.ep.rcvListMu.Lock()
	rcvClosed := r.ep.rcvClosed || r.closed
	r.ep.rcvListMu.Unlock()
	switch state {
	case StateCloseWait, StateClosing, StateLastAck:
		if !s.sequenceNumber.LessThanEq(r.rcvNxt) {
			s.decRef()
			return true, nil
		}
		fallthrough
	case StateFinWait1:
		fallthrough
	case StateFinWait2:
		endDataSeq := s.sequenceNumber.Add(seqnum.Size(s.data.Size()))
		if rcvClosed && r.rcvNxt.LessThan(endDataSeq) {
			s.decRef()
			return true, tcpip.ErrConnectionAborted
		}
		if state == StateFinWait1 {
			break
		}
		if s.sequenceNumber.Add(s.logicalLen()).LessThanEq(r.rcvNxt) ||
			s.logicalLen() == 0 {
			break
		}
		if closed && (!s.flagIsSet(header.TCPFlagFin) || s.sequenceNumber.Add(s.logicalLen()) != r.rcvNxt+1) {
			s.decRef()
			return true, tcpip.ErrConnectionAborted
		}
	}
	segEnd := s.sequenceNumber.Add(seqnum.Size(s.data.Size()))
	if rcvClosed && !segEnd.LessThanEq(r.rcvNxt) {
		return true, nil
	}
	return false, nil
}