summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/tcp
diff options
context:
space:
mode:
authorZhaozhong Ni <nzz@google.com>2018-12-05 15:01:41 -0800
committerShentubot <shentubot@google.com>2018-12-05 15:02:40 -0800
commit7f35daddd2cabef2e7ffb6899e1a54ff8c0475c6 (patch)
tree83b9c24e988cfdc315d8b8d0fb327cc6333225f9 /pkg/tcpip/transport/tcp
parent9f64e64a6ee1fe44a05ed57893785fa9064125e1 (diff)
sentry: support save / restore of TCP bind socket after shutdown.
PiperOrigin-RevId: 224227677 Change-Id: I08b0e0c0574170556269900653e5bcf9e9e5c9c9
Diffstat (limited to 'pkg/tcpip/transport/tcp')
-rw-r--r--pkg/tcpip/transport/tcp/endpoint_state.go39
1 files changed, 29 insertions, 10 deletions
diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go
index e32c73aae..4891c7941 100644
--- a/pkg/tcpip/transport/tcp/endpoint_state.go
+++ b/pkg/tcpip/transport/tcp/endpoint_state.go
@@ -92,8 +92,8 @@ func (e *endpoint) beforeSave() {
panic("endpoint still has waiters upon save")
}
- if !((e.state == stateBound || e.state == stateListen) == e.isPortReserved) {
- panic("endpoint port must and must only be reserved in bound or listen state")
+ if e.state != stateClosed && !((e.state == stateBound || e.state == stateListen) == e.isPortReserved) {
+ panic("endpoints which are not in the closed state must have a reserved port IFF they are in bound or listen state")
}
}
@@ -102,15 +102,21 @@ func (e *endpoint) saveAcceptedChan() []*endpoint {
if e.acceptedChan == nil {
return nil
}
- close(e.acceptedChan)
acceptedEndpoints := make([]*endpoint, len(e.acceptedChan), cap(e.acceptedChan))
- i := 0
- for ep := range e.acceptedChan {
- acceptedEndpoints[i] = ep
- i++
+ for i := 0; i < len(acceptedEndpoints); i++ {
+ select {
+ case ep := <-e.acceptedChan:
+ acceptedEndpoints[i] = ep
+ default:
+ panic("endpoint acceptedChan buffer got consumed by background context")
+ }
}
- if i != len(acceptedEndpoints) {
- panic("endpoint acceptedChan buffer got consumed by background context")
+ for i := 0; i < len(acceptedEndpoints); i++ {
+ select {
+ case e.acceptedChan <- acceptedEndpoints[i]:
+ default:
+ panic("endpoint acceptedChan buffer got populated by background context")
+ }
}
return acceptedEndpoints
}
@@ -235,7 +241,20 @@ func (e *endpoint) afterLoad() {
bind()
tcpip.AsyncLoading.Done()
}()
- case stateClosed, stateError:
+ case stateClosed:
+ if e.isPortReserved {
+ tcpip.AsyncLoading.Add(1)
+ go func() {
+ connectedLoading.Wait()
+ listenLoading.Wait()
+ connectingLoading.Wait()
+ bind()
+ e.state = stateClosed
+ tcpip.AsyncLoading.Done()
+ }()
+ }
+ fallthrough
+ case stateError:
tcpip.DeleteDanglingEndpoint(e)
}
}