diff options
author | Zhaozhong Ni <nzz@google.com> | 2018-07-10 09:22:37 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-07-10 09:23:35 -0700 |
commit | b1683df90bf81974e9e309ed66edaff30537c1be (patch) | |
tree | 728061e78466951d1f069e5a73358f84aa16d6c0 /pkg/tcpip/transport/tcp/accept.go | |
parent | afd655a5d8b9d9bc747ee99b1ec2475cc526c996 (diff) |
netstack: tcp socket connected state S/R support.
PiperOrigin-RevId: 203958972
Change-Id: Ia6fe16547539296d48e2c6731edacdd96bd6e93c
Diffstat (limited to 'pkg/tcpip/transport/tcp/accept.go')
-rw-r--r-- | pkg/tcpip/transport/tcp/accept.go | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index ae4359ff4..d6d2b4555 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -78,7 +78,8 @@ func encodeMSS(mss uint16) uint32 { // to go above a threshold. var synRcvdCount struct { sync.Mutex - value uint64 + value uint64 + pending sync.WaitGroup } // listenContext is used by a listening endpoint to store state used while @@ -112,6 +113,7 @@ func incSynRcvdCount() bool { return false } + synRcvdCount.pending.Add(1) synRcvdCount.value++ return true @@ -125,6 +127,7 @@ func decSynRcvdCount() { defer synRcvdCount.Unlock() synRcvdCount.value-- + synRcvdCount.pending.Done() } // newListenContext creates a new listen context. @@ -302,7 +305,7 @@ func (e *endpoint) handleListenSegment(ctx *listenContext, s *segment) { opts := parseSynSegmentOptions(s) if incSynRcvdCount() { s.incRef() - go e.handleSynSegment(ctx, s, &opts) // S/R-FIXME + go e.handleSynSegment(ctx, s, &opts) // S/R-SAFE: synRcvdCount is the barrier. } else { cookie := ctx.createCookie(s.id, s.sequenceNumber, encodeMSS(opts.MSS)) // Send SYN with window scaling because we currently @@ -391,10 +394,12 @@ func (e *endpoint) protocolListenLoop(rcvWnd seqnum.Size) *tcpip.Error { return nil } if n¬ifyDrain != 0 { - for s := e.segmentQueue.dequeue(); s != nil; s = e.segmentQueue.dequeue() { + for !e.segmentQueue.empty() { + s := e.segmentQueue.dequeue() e.handleListenSegment(ctx, s) s.decRef() } + synRcvdCount.pending.Wait() close(e.drainDone) <-e.undrain } |