mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Move presence methods from segment to TCPFlags
PiperOrigin-RevId: 376001032
This commit is contained in:
committed by
gVisor bot
parent
14a70624ce
commit
c006b9b1c8
@@ -48,6 +48,16 @@ const (
|
||||
// TCPFlags is the dedicated type for TCP flags.
|
||||
type TCPFlags uint8
|
||||
|
||||
// Intersects returns true iff there are flags common to both f and o.
|
||||
func (f TCPFlags) Intersects(o TCPFlags) bool {
|
||||
return f&o != 0
|
||||
}
|
||||
|
||||
// Contains returns true iff all the flags in o are contained within f.
|
||||
func (f TCPFlags) Contains(o TCPFlags) bool {
|
||||
return f&o == o
|
||||
}
|
||||
|
||||
// String implements Stringer.String.
|
||||
func (f TCPFlags) String() string {
|
||||
flagsStr := []byte("FSRPAU")
|
||||
|
||||
@@ -550,7 +550,7 @@ func (e *endpoint) handleListenSegment(ctx *listenContext, s *segment) tcpip.Err
|
||||
e.rcvQueueInfo.rcvQueueMu.Lock()
|
||||
rcvClosed := e.rcvQueueInfo.RcvClosed
|
||||
e.rcvQueueInfo.rcvQueueMu.Unlock()
|
||||
if rcvClosed || s.flagsAreSet(header.TCPFlagSyn|header.TCPFlagAck) {
|
||||
if rcvClosed || s.flags.Contains(header.TCPFlagSyn|header.TCPFlagAck) {
|
||||
// If the endpoint is shutdown, reply with reset.
|
||||
//
|
||||
// RFC 793 section 3.4 page 35 (figure 12) outlines that a RST
|
||||
|
||||
@@ -212,7 +212,7 @@ func (h *handshake) resetToSynRcvd(iss seqnum.Value, irs seqnum.Value, opts *hea
|
||||
// a TCP 3-way handshake is valid. If it's not, a RST segment is sent back in
|
||||
// response.
|
||||
func (h *handshake) checkAck(s *segment) bool {
|
||||
if s.flagIsSet(header.TCPFlagAck) && s.ackNumber != h.iss+1 {
|
||||
if s.flags.Contains(header.TCPFlagAck) && s.ackNumber != h.iss+1 {
|
||||
// RFC 793, page 36, states that a reset must be generated when
|
||||
// the connection is in any non-synchronized state and an
|
||||
// incoming segment acknowledges something not yet sent. The
|
||||
@@ -230,8 +230,8 @@ func (h *handshake) checkAck(s *segment) bool {
|
||||
func (h *handshake) synSentState(s *segment) tcpip.Error {
|
||||
// RFC 793, page 37, states that in the SYN-SENT state, a reset is
|
||||
// acceptable if the ack field acknowledges the SYN.
|
||||
if s.flagIsSet(header.TCPFlagRst) {
|
||||
if s.flagIsSet(header.TCPFlagAck) && s.ackNumber == h.iss+1 {
|
||||
if s.flags.Contains(header.TCPFlagRst) {
|
||||
if s.flags.Contains(header.TCPFlagAck) && s.ackNumber == h.iss+1 {
|
||||
// RFC 793, page 67, states that "If the RST bit is set [and] If the ACK
|
||||
// was acceptable then signal the user "error: connection reset", drop
|
||||
// the segment, enter CLOSED state, delete TCB, and return."
|
||||
@@ -249,7 +249,7 @@ func (h *handshake) synSentState(s *segment) tcpip.Error {
|
||||
|
||||
// We are in the SYN-SENT state. We only care about segments that have
|
||||
// the SYN flag.
|
||||
if !s.flagIsSet(header.TCPFlagSyn) {
|
||||
if !s.flags.Contains(header.TCPFlagSyn) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ func (h *handshake) synSentState(s *segment) tcpip.Error {
|
||||
|
||||
// If this is a SYN ACK response, we only need to acknowledge the SYN
|
||||
// and the handshake is completed.
|
||||
if s.flagIsSet(header.TCPFlagAck) {
|
||||
if s.flags.Contains(header.TCPFlagAck) {
|
||||
h.state = handshakeCompleted
|
||||
|
||||
h.ep.transitionToStateEstablishedLocked(h)
|
||||
@@ -316,7 +316,7 @@ func (h *handshake) synSentState(s *segment) tcpip.Error {
|
||||
// synRcvdState handles a segment received when the TCP 3-way handshake is in
|
||||
// the SYN-RCVD state.
|
||||
func (h *handshake) synRcvdState(s *segment) tcpip.Error {
|
||||
if s.flagIsSet(header.TCPFlagRst) {
|
||||
if s.flags.Contains(header.TCPFlagRst) {
|
||||
// RFC 793, page 37, states that in the SYN-RCVD state, a reset
|
||||
// is acceptable if the sequence number is in the window.
|
||||
if s.sequenceNumber.InWindow(h.ackNum, h.rcvWnd) {
|
||||
@@ -340,13 +340,13 @@ func (h *handshake) synRcvdState(s *segment) tcpip.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.flagIsSet(header.TCPFlagSyn) && s.sequenceNumber != h.ackNum-1 {
|
||||
if s.flags.Contains(header.TCPFlagSyn) && s.sequenceNumber != h.ackNum-1 {
|
||||
// We received two SYN segments with different sequence
|
||||
// numbers, so we reset this and restart the whole
|
||||
// process, except that we don't reset the timer.
|
||||
ack := s.sequenceNumber.Add(s.logicalLen())
|
||||
seq := seqnum.Value(0)
|
||||
if s.flagIsSet(header.TCPFlagAck) {
|
||||
if s.flags.Contains(header.TCPFlagAck) {
|
||||
seq = s.ackNumber
|
||||
}
|
||||
h.ep.sendRaw(buffer.VectorisedView{}, header.TCPFlagRst|header.TCPFlagAck, seq, ack, 0)
|
||||
@@ -378,7 +378,7 @@ func (h *handshake) synRcvdState(s *segment) tcpip.Error {
|
||||
|
||||
// We have previously received (and acknowledged) the peer's SYN. If the
|
||||
// peer acknowledges our SYN, the handshake is completed.
|
||||
if s.flagIsSet(header.TCPFlagAck) {
|
||||
if s.flags.Contains(header.TCPFlagAck) {
|
||||
// If deferAccept is not zero and this is a bare ACK and the
|
||||
// timeout is not hit then drop the ACK.
|
||||
if h.deferAccept != 0 && s.data.Size() == 0 && h.ep.stack.Clock().NowMonotonic().Sub(h.startTime) < h.deferAccept {
|
||||
@@ -426,7 +426,7 @@ func (h *handshake) synRcvdState(s *segment) tcpip.Error {
|
||||
|
||||
func (h *handshake) handleSegment(s *segment) tcpip.Error {
|
||||
h.sndWnd = s.window
|
||||
if !s.flagIsSet(header.TCPFlagSyn) && h.sndWndScale > 0 {
|
||||
if !s.flags.Contains(header.TCPFlagSyn) && h.sndWndScale > 0 {
|
||||
h.sndWnd <<= uint8(h.sndWndScale)
|
||||
}
|
||||
|
||||
@@ -634,7 +634,7 @@ func (bt *backoffTimer) stop() {
|
||||
}
|
||||
|
||||
func parseSynSegmentOptions(s *segment) header.TCPSynOptions {
|
||||
synOpts := header.ParseSynOptions(s.options, s.flagIsSet(header.TCPFlagAck))
|
||||
synOpts := header.ParseSynOptions(s.options, s.flags.Contains(header.TCPFlagAck))
|
||||
if synOpts.TS {
|
||||
s.parsedOptions.TSVal = synOpts.TSVal
|
||||
s.parsedOptions.TSEcr = synOpts.TSEcr
|
||||
@@ -1188,11 +1188,11 @@ func (e *endpoint) handleSegmentLocked(s *segment) (cont bool, err tcpip.Error)
|
||||
// the TCPEndpointState after the segment is processed.
|
||||
defer e.probeSegmentLocked()
|
||||
|
||||
if s.flagIsSet(header.TCPFlagRst) {
|
||||
if s.flags.Contains(header.TCPFlagRst) {
|
||||
if ok, err := e.handleReset(s); !ok {
|
||||
return false, err
|
||||
}
|
||||
} else if s.flagIsSet(header.TCPFlagSyn) {
|
||||
} else if s.flags.Contains(header.TCPFlagSyn) {
|
||||
// See: https://tools.ietf.org/html/rfc5961#section-4.1
|
||||
// 1) If the SYN bit is set, irrespective of the sequence number, TCP
|
||||
// MUST send an ACK (also referred to as challenge ACK) to the remote
|
||||
@@ -1216,7 +1216,7 @@ func (e *endpoint) handleSegmentLocked(s *segment) (cont bool, err tcpip.Error)
|
||||
// should then rely on SYN retransmission from the remote end to
|
||||
// re-establish the connection.
|
||||
e.snd.maybeSendOutOfWindowAck(s)
|
||||
} else if s.flagIsSet(header.TCPFlagAck) {
|
||||
} else if s.flags.Contains(header.TCPFlagAck) {
|
||||
// Patch the window size in the segment according to the
|
||||
// send window scale.
|
||||
s.window <<= e.snd.SndWndScale
|
||||
|
||||
@@ -149,7 +149,7 @@ func (p *protocol) HandleUnknownDestinationPacket(id stack.TransportEndpointID,
|
||||
return stack.UnknownDestinationPacketMalformed
|
||||
}
|
||||
|
||||
if !s.flagIsSet(header.TCPFlagRst) {
|
||||
if !s.flags.Contains(header.TCPFlagRst) {
|
||||
replyWithReset(p.stack, s, stack.DefaultTOS, 0)
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ func replyWithReset(st *stack.Stack, s *segment, tos, ttl uint8) tcpip.Error {
|
||||
// reset has sequence number zero and the ACK field is set to the sum
|
||||
// of the sequence number and segment length of the incoming segment.
|
||||
// The connection remains in the CLOSED state.
|
||||
if s.flagIsSet(header.TCPFlagAck) {
|
||||
if s.flags.Contains(header.TCPFlagAck) {
|
||||
seq = s.ackNumber
|
||||
} else {
|
||||
flags |= header.TCPFlagAck
|
||||
|
||||
@@ -244,7 +244,7 @@ func (r *receiver) consumeSegment(s *segment, segSeq seqnum.Value, segLen seqnum
|
||||
TrimSACKBlockList(&r.ep.sack, r.RcvNxt)
|
||||
|
||||
// Handle FIN or FIN-ACK.
|
||||
if s.flagIsSet(header.TCPFlagFin) {
|
||||
if s.flags.Contains(header.TCPFlagFin) {
|
||||
r.RcvNxt++
|
||||
|
||||
// Send ACK immediately.
|
||||
@@ -260,7 +260,7 @@ func (r *receiver) consumeSegment(s *segment, segSeq seqnum.Value, segLen seqnum
|
||||
case StateEstablished:
|
||||
r.ep.setEndpointState(StateCloseWait)
|
||||
case StateFinWait1:
|
||||
if s.flagIsSet(header.TCPFlagAck) && s.ackNumber == r.ep.snd.SndNxt {
|
||||
if s.flags.Contains(header.TCPFlagAck) && s.ackNumber == r.ep.snd.SndNxt {
|
||||
// FIN-ACK, transition to TIME-WAIT.
|
||||
r.ep.setEndpointState(StateTimeWait)
|
||||
} else {
|
||||
@@ -295,7 +295,7 @@ func (r *receiver) consumeSegment(s *segment, segSeq seqnum.Value, segLen seqnum
|
||||
|
||||
// Handle ACK (not FIN-ACK, which we handled above) during one of the
|
||||
// shutdown states.
|
||||
if s.flagIsSet(header.TCPFlagAck) && s.ackNumber == r.ep.snd.SndNxt {
|
||||
if s.flags.Contains(header.TCPFlagAck) && s.ackNumber == r.ep.snd.SndNxt {
|
||||
switch r.ep.EndpointState() {
|
||||
case StateFinWait1:
|
||||
r.ep.setEndpointState(StateFinWait2)
|
||||
@@ -423,7 +423,7 @@ func (r *receiver) handleRcvdSegmentClosing(s *segment, state EndpointState, clo
|
||||
// while the FIN is considered to occur after
|
||||
// the last actual data octet in a segment in
|
||||
// which it occurs.
|
||||
if closed && (!s.flagIsSet(header.TCPFlagFin) || s.sequenceNumber.Add(s.logicalLen()) != r.RcvNxt+1) {
|
||||
if closed && (!s.flags.Contains(header.TCPFlagFin) || s.sequenceNumber.Add(s.logicalLen()) != r.RcvNxt+1) {
|
||||
return true, &tcpip.ErrConnectionAborted{}
|
||||
}
|
||||
}
|
||||
@@ -470,7 +470,7 @@ func (r *receiver) handleRcvdSegment(s *segment) (drop bool, err tcpip.Error) {
|
||||
|
||||
// Defer segment processing if it can't be consumed now.
|
||||
if !r.consumeSegment(s, segSeq, segLen) {
|
||||
if segLen > 0 || s.flagIsSet(header.TCPFlagFin) {
|
||||
if segLen > 0 || s.flags.Contains(header.TCPFlagFin) {
|
||||
// We only store the segment if it's within our buffer size limit.
|
||||
//
|
||||
// Only use 75% of the receive buffer queue for out-of-order
|
||||
@@ -538,7 +538,7 @@ func (r *receiver) handleTimeWaitSegment(s *segment) (resetTimeWait bool, newSyn
|
||||
//
|
||||
// As we do not yet support PAWS, we are being conservative in ignoring
|
||||
// RSTs by default.
|
||||
if s.flagIsSet(header.TCPFlagRst) {
|
||||
if s.flags.Contains(header.TCPFlagRst) {
|
||||
return false, false
|
||||
}
|
||||
|
||||
@@ -558,13 +558,13 @@ func (r *receiver) handleTimeWaitSegment(s *segment) (resetTimeWait bool, newSyn
|
||||
|
||||
// (2) returns to TIME-WAIT state if the SYN turns out
|
||||
// to be an old duplicate".
|
||||
if s.flagIsSet(header.TCPFlagSyn) && r.RcvNxt.LessThan(segSeq) {
|
||||
if s.flags.Contains(header.TCPFlagSyn) && r.RcvNxt.LessThan(segSeq) {
|
||||
|
||||
return false, true
|
||||
}
|
||||
|
||||
// Drop the segment if it does not contain an ACK.
|
||||
if !s.flagIsSet(header.TCPFlagAck) {
|
||||
if !s.flags.Contains(header.TCPFlagAck) {
|
||||
return false, false
|
||||
}
|
||||
|
||||
@@ -573,7 +573,7 @@ func (r *receiver) handleTimeWaitSegment(s *segment) (resetTimeWait bool, newSyn
|
||||
r.ep.updateRecentTimestamp(s.parsedOptions.TSVal, r.ep.snd.MaxSentAck, segSeq)
|
||||
}
|
||||
|
||||
if segSeq.Add(1) == r.RcvNxt && s.flagIsSet(header.TCPFlagFin) {
|
||||
if segSeq.Add(1) == r.RcvNxt && s.flags.Contains(header.TCPFlagFin) {
|
||||
// If it's a FIN-ACK then resetTimeWait and send an ACK, as it
|
||||
// indicates our final ACK could have been lost.
|
||||
r.ep.snd.sendAck()
|
||||
|
||||
@@ -148,16 +148,6 @@ func (s *segment) merge(oth *segment) {
|
||||
oth.dataMemSize = oth.data.Size()
|
||||
}
|
||||
|
||||
// flagIsSet checks if at least one flag in flags is set in s.flags.
|
||||
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 header.TCPFlags) bool {
|
||||
return s.flags&flags == flags
|
||||
}
|
||||
|
||||
// setOwner sets the owning endpoint for this segment. Its required
|
||||
// to be called to ensure memory accounting for receive/send buffer
|
||||
// queues is done properly.
|
||||
@@ -197,10 +187,10 @@ func (s *segment) incRef() {
|
||||
// as the data length plus one for each of the SYN and FIN bits set.
|
||||
func (s *segment) logicalLen() seqnum.Size {
|
||||
l := seqnum.Size(s.data.Size())
|
||||
if s.flagIsSet(header.TCPFlagSyn) {
|
||||
if s.flags.Contains(header.TCPFlagSyn) {
|
||||
l++
|
||||
}
|
||||
if s.flagIsSet(header.TCPFlagFin) {
|
||||
if s.flags.Contains(header.TCPFlagFin) {
|
||||
l++
|
||||
}
|
||||
return l
|
||||
|
||||
@@ -1132,7 +1132,7 @@ func (s *sender) isDupAck(seg *segment) bool {
|
||||
// (b) The incoming acknowledgment carries no data.
|
||||
seg.logicalLen() == 0 &&
|
||||
// (c) The SYN and FIN bits are both off.
|
||||
!seg.flagIsSet(header.TCPFlagFin) && !seg.flagIsSet(header.TCPFlagSyn) &&
|
||||
!seg.flags.Intersects(header.TCPFlagFin|header.TCPFlagSyn) &&
|
||||
// (d) the ACK number is equal to the greatest acknowledgment received on
|
||||
// the given connection (TCP.UNA from RFC793).
|
||||
seg.ackNumber == s.SndUna &&
|
||||
|
||||
Reference in New Issue
Block a user