diff options
Diffstat (limited to 'pkg/tcpip/transport/tcp')
-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) } } |