summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/tcp/accept.go
diff options
context:
space:
mode:
authorZhaozhong Ni <nzz@google.com>2018-07-10 09:22:37 -0700
committerShentubot <shentubot@google.com>2018-07-10 09:23:35 -0700
commitb1683df90bf81974e9e309ed66edaff30537c1be (patch)
tree728061e78466951d1f069e5a73358f84aa16d6c0 /pkg/tcpip/transport/tcp/accept.go
parentafd655a5d8b9d9bc747ee99b1ec2475cc526c996 (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.go11
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&notifyDrain != 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
}