summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tcpip/transport')
-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)
}
}