summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/tcp/snd.go
diff options
context:
space:
mode:
authorIan Gudger <igudger@google.com>2018-11-05 15:38:32 -0800
committerShentubot <shentubot@google.com>2018-11-05 15:39:30 -0800
commit37cbce1f9156109a58ae3d350f8e0e9d027b3785 (patch)
treea76b631fd031c1f348562cc9b3a2275b43fb1556 /pkg/tcpip/transport/tcp/snd.go
parent704b56a40d0a041a4e6f814c3dbb1f9ec15f9002 (diff)
Merge segments in sender's writeList
PiperOrigin-RevId: 220185891 Change-Id: Iaea73fd7b2fa8c399b989cdcaabf4885f370df4b
Diffstat (limited to 'pkg/tcpip/transport/tcp/snd.go')
-rw-r--r--pkg/tcpip/transport/tcp/snd.go26
1 files changed, 24 insertions, 2 deletions
diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go
index b260c0e57..71bfcbd36 100644
--- a/pkg/tcpip/transport/tcp/snd.go
+++ b/pkg/tcpip/transport/tcp/snd.go
@@ -403,15 +403,36 @@ func (s *sender) sendData() {
// TODO: We currently don't merge multiple send buffers
// into one segment if they happen to fit. We should do that
// eventually.
- var seg *segment
+ seg := s.writeNext
end := s.sndUna.Add(s.sndWnd)
var dataSent bool
- for seg = s.writeNext; seg != nil && s.outstanding < s.sndCwnd; seg = seg.Next() {
+ for next := (*segment)(nil); seg != nil && s.outstanding < s.sndCwnd; seg = next {
+ next = seg.Next()
+
// We abuse the flags field to determine if we have already
// assigned a sequence number to this segment.
if seg.flags == 0 {
seg.sequenceNumber = s.sndNxt
seg.flags = flagAck | flagPsh
+ // Merge segments if allowed.
+ if seg.data.Size() != 0 {
+ available := int(seg.sequenceNumber.Size(end))
+ if available > limit {
+ available = limit
+ }
+
+ for next != nil && next.data.Size() != 0 {
+ if seg.data.Size()+next.data.Size() > available {
+ break
+ }
+
+ seg.data.Append(&next.data)
+
+ // Consume the segment that we just merged in.
+ s.writeList.Remove(next)
+ next = next.Next()
+ }
+ }
}
var segEnd seqnum.Value
@@ -442,6 +463,7 @@ func (s *sender) sendData() {
nSeg.data.TrimFront(available)
nSeg.sequenceNumber.UpdateForward(seqnum.Size(available))
s.writeList.InsertAfter(seg, nSeg)
+ next = nSeg
seg.data.CapLength(available)
}