summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/tcp/accept.go
diff options
context:
space:
mode:
authorZhaozhong Ni <nzz@google.com>2018-06-21 15:18:47 -0700
committerShentubot <shentubot@google.com>2018-06-21 15:19:45 -0700
commit0e434b66a625b937d90e4ebe632de4546101be5a (patch)
treef83a85aaa0b570f856c15ea965048ca3fe4dafa1 /pkg/tcpip/transport/tcp/accept.go
parent2dedbc7211fb6b7f8b86148e6627054e781eaa87 (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.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 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&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
}