Clean up tcp segment sender functions.

sendRaw is entirely used to just send flags, so change the function to
explicitly send empty segments. The single use case for sending data can
be taken care of in sendSegment.

PiperOrigin-RevId: 442861994
This commit is contained in:
Lucas Manning
2022-04-19 11:20:50 -07:00
committed by gVisor bot
parent 02e1f2bb45
commit e380531bfb
2 changed files with 20 additions and 10 deletions
+11 -6
View File
@@ -290,7 +290,7 @@ func (h *handshake) checkAck(s *segment) bool {
// If the segment acknowledgment is not acceptable, form a reset segment,
// <SEQ=SEG.ACK><CTL=RST>
// and send it.
h.ep.sendRaw(buffer.VectorisedView{}, header.TCPFlagRst, s.ackNumber, 0, 0)
h.ep.sendEmptyRaw(header.TCPFlagRst, s.ackNumber, 0, 0)
return false
}
@@ -346,7 +346,7 @@ func (h *handshake) synSentState(s *segment) tcpip.Error {
h.state = handshakeCompleted
h.transitionToStateEstablishedLocked(s)
h.ep.sendRaw(buffer.VectorisedView{}, header.TCPFlagAck, h.iss+1, h.ackNum, h.rcvWnd>>h.effectiveRcvWndScale())
h.ep.sendEmptyRaw(header.TCPFlagAck, h.iss+1, h.ackNum, h.rcvWnd>>h.effectiveRcvWndScale())
return nil
}
@@ -407,7 +407,7 @@ func (h *handshake) synRcvdState(s *segment) tcpip.Error {
// segment and return."
if !s.sequenceNumber.InWindow(h.ackNum, h.rcvWnd) {
if h.ep.allowOutOfWindowAck() {
h.ep.sendRaw(buffer.VectorisedView{}, header.TCPFlagAck, h.iss+1, h.ackNum, h.rcvWnd)
h.ep.sendEmptyRaw(header.TCPFlagAck, h.iss+1, h.ackNum, h.rcvWnd)
}
return nil
}
@@ -421,7 +421,7 @@ func (h *handshake) synRcvdState(s *segment) tcpip.Error {
if s.flags.Contains(header.TCPFlagAck) {
seq = s.ackNumber
}
h.ep.sendRaw(buffer.VectorisedView{}, header.TCPFlagRst|header.TCPFlagAck, seq, ack, 0)
h.ep.sendEmptyRaw(header.TCPFlagRst|header.TCPFlagAck, seq, ack, 0)
if !h.active {
return &tcpip.ErrInvalidEndpointState{}
@@ -957,6 +957,11 @@ func (e *endpoint) makeOptions(sackBlocks []header.SACKBlock) []byte {
return options[:offset]
}
// sendEmptyRaw sends a TCP segment to the endpoint's peer.
func (e *endpoint) sendEmptyRaw(flags header.TCPFlags, seq, ack seqnum.Value, rcvWnd seqnum.Size) tcpip.Error {
return e.sendRaw(buffer.VectorisedView{}, flags, seq, ack, rcvWnd)
}
// sendRaw sends a TCP segment to the endpoint's peer.
func (e *endpoint) sendRaw(data buffer.VectorisedView, flags header.TCPFlags, seq, ack seqnum.Value, rcvWnd seqnum.Size) tcpip.Error {
var sackBlocks []header.SACKBlock
@@ -1017,7 +1022,7 @@ func (e *endpoint) resetConnectionLocked(err tcpip.Error) {
if !sndWndEnd.LessThan(e.snd.SndNxt) || e.snd.SndNxt.Size(sndWndEnd) < (1<<e.snd.SndWndScale) {
resetSeqNum = e.snd.SndNxt
}
e.sendRaw(buffer.VectorisedView{}, header.TCPFlagAck|header.TCPFlagRst, resetSeqNum, e.rcv.RcvNxt, 0)
e.sendEmptyRaw(header.TCPFlagAck|header.TCPFlagRst, resetSeqNum, e.rcv.RcvNxt, 0)
}
// Don't purge read queues here. If there's buffered data, it's still allowed
// to be read.
@@ -1301,7 +1306,7 @@ func (e *endpoint) keepaliveTimerExpired() tcpip.Error {
// seg.seq = snd.nxt-1.
e.keepalive.unacked++
e.keepalive.Unlock()
e.snd.sendSegmentFromView(buffer.VectorisedView{}, header.TCPFlagAck, e.snd.SndNxt-1)
e.snd.sendEmptySegment(header.TCPFlagAck, e.snd.SndNxt-1)
e.resetKeepaliveTimer(false)
return nil
}
+9 -4
View File
@@ -336,7 +336,7 @@ func (s *sender) updateMaxPayloadSize(mtu, count int) {
// sendAck sends an ACK segment.
// +checklocks:s.ep.mu
func (s *sender) sendAck() {
s.sendSegmentFromView(buffer.VectorisedView{}, header.TCPFlagAck, s.SndNxt)
s.sendEmptySegment(header.TCPFlagAck, s.SndNxt)
}
// updateRTO updates the retransmit timeout when a new roud-trip time is
@@ -879,13 +879,11 @@ func (s *sender) maybeSendSegment(seg *segment, limit int, end seqnum.Value) (se
}
// +checklocks:s.ep.mu
// +checklocksalias:s.ep.rcv.ep.mu=s.ep.mu
func (s *sender) sendZeroWindowProbe() {
ack, win := s.ep.rcv.getSendParams()
s.unackZeroWindowProbes++
// Send a zero window probe with sequence number pointing to
// the last acknowledged byte.
s.ep.sendRaw(buffer.VectorisedView{}, header.TCPFlagAck, s.SndUna-1, ack, win)
s.sendEmptySegment(header.TCPFlagAck, s.SndUna-1)
// Rearm the timer to continue probing.
s.resendTimer.enable(s.RTO)
}
@@ -1675,6 +1673,13 @@ func (s *sender) sendSegmentFromView(data buffer.VectorisedView, flags header.TC
return s.ep.sendRaw(data, flags, seq, rcvNxt, rcvWnd)
}
// sendEmptySegment sends a new segment containing the given flags and sequence
// number.
// +checklocks:s.ep.mu
func (s *sender) sendEmptySegment(flags header.TCPFlags, seq seqnum.Value) tcpip.Error {
return s.sendSegmentFromView(buffer.VectorisedView{}, flags, seq)
}
// maybeSendOutOfWindowAck sends an ACK if we are not being rate limited
// currently.
// +checklocks:s.ep.mu