diff options
author | Zhaozhong Ni <nzz@google.com> | 2018-12-05 15:01:41 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-12-05 15:02:40 -0800 |
commit | 7f35daddd2cabef2e7ffb6899e1a54ff8c0475c6 (patch) | |
tree | 83b9c24e988cfdc315d8b8d0fb327cc6333225f9 /pkg/tcpip/transport | |
parent | 9f64e64a6ee1fe44a05ed57893785fa9064125e1 (diff) |
sentry: support save / restore of TCP bind socket after shutdown.
PiperOrigin-RevId: 224227677
Change-Id: I08b0e0c0574170556269900653e5bcf9e9e5c9c9
Diffstat (limited to 'pkg/tcpip/transport')
-rw-r--r-- | pkg/tcpip/transport/tcp/endpoint_state.go | 39 |
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) } } |