diff options
author | Zhaozhong Ni <nzz@google.com> | 2018-06-21 15:18:47 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-06-21 15:19:45 -0700 |
commit | 0e434b66a625b937d90e4ebe632de4546101be5a (patch) | |
tree | f83a85aaa0b570f856c15ea965048ca3fe4dafa1 /pkg/tcpip/transport/tcp/accept.go | |
parent | 2dedbc7211fb6b7f8b86148e6627054e781eaa87 (diff) |
netstack: tcp socket connected state S/R support.
PiperOrigin-RevId: 201596247
Change-Id: Id22f47b2cdcbe14aa0d930f7807ba75f91a56724
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 85adeef0e..410dfdad4 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -68,7 +68,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 @@ -102,6 +103,7 @@ func incSynRcvdCount() bool { return false } + synRcvdCount.pending.Add(1) synRcvdCount.value++ return true @@ -115,6 +117,7 @@ func decSynRcvdCount() { defer synRcvdCount.Unlock() synRcvdCount.value-- + synRcvdCount.pending.Done() } // newListenContext creates a new listen context. @@ -292,7 +295,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 @@ -381,10 +384,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 } |