summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip
diff options
context:
space:
mode:
authorZhaozhong Ni <nzz@google.com>2018-07-30 15:42:01 -0700
committerShentubot <shentubot@google.com>2018-07-30 15:43:25 -0700
commit0a55f8c1c11dc6d2dfb1bed02489f92bab437ea1 (patch)
tree803d15586a86a79f30e2905d03ad06a11fe38bee /pkg/tcpip
parent3188859742e802a2e7d1d5d0ab22a6e2b426dfb8 (diff)
netstack: support disconnect-on-save option per fdbased link.
PiperOrigin-RevId: 206659972 Change-Id: I5e0e035f97743b6525ad36bed2c802791609beaf
Diffstat (limited to 'pkg/tcpip')
-rw-r--r--pkg/tcpip/link/fdbased/endpoint.go10
-rw-r--r--pkg/tcpip/stack/registration.go1
-rw-r--r--pkg/tcpip/transport/tcp/connect.go4
-rw-r--r--pkg/tcpip/transport/tcp/endpoint_state.go11
4 files changed, 23 insertions, 3 deletions
diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go
index 8fc009160..4e20cfbf8 100644
--- a/pkg/tcpip/link/fdbased/endpoint.go
+++ b/pkg/tcpip/link/fdbased/endpoint.go
@@ -69,6 +69,8 @@ type Options struct {
ChecksumOffload bool
ClosedFunc func(*tcpip.Error)
Address tcpip.LinkAddress
+ SaveRestore bool
+ DisconnectOk bool
}
// New creates a new fd-based endpoint.
@@ -89,6 +91,14 @@ func New(opts *Options) tcpip.LinkEndpointID {
caps |= stack.CapabilityResolutionRequired
}
+ if opts.SaveRestore {
+ caps |= stack.CapabilitySaveRestore
+ }
+
+ if opts.DisconnectOk {
+ caps |= stack.CapabilityDisconnectOk
+ }
+
e := &endpoint{
fd: opts.FD,
mtu: opts.MTU,
diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go
index c66f925a8..01a29689d 100644
--- a/pkg/tcpip/stack/registration.go
+++ b/pkg/tcpip/stack/registration.go
@@ -204,6 +204,7 @@ const (
CapabilityChecksumOffload LinkEndpointCapabilities = 1 << iota
CapabilityResolutionRequired
CapabilitySaveRestore
+ CapabilityDisconnectOk
)
// LinkEndpoint is the interface implemented by data link layer protocols (e.g.,
diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go
index 8d70eb45a..b90d3fe48 100644
--- a/pkg/tcpip/transport/tcp/connect.go
+++ b/pkg/tcpip/transport/tcp/connect.go
@@ -1023,7 +1023,9 @@ func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error {
// Mark endpoint as closed.
e.mu.Lock()
- e.state = stateClosed
+ if e.state != stateError {
+ e.state = stateClosed
+ }
// Lock released below.
epilogue()
diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go
index 9c2e8878f..6143390b3 100644
--- a/pkg/tcpip/transport/tcp/endpoint_state.go
+++ b/pkg/tcpip/transport/tcp/endpoint_state.go
@@ -52,10 +52,17 @@ func (e *endpoint) beforeSave() {
case stateInitial, stateBound:
case stateConnected:
if e.route.Capabilities()&stack.CapabilitySaveRestore == 0 {
- panic(tcpip.ErrSaveRejection{fmt.Errorf("endpoint cannot be saved in connected state: local %v:%d, remote %v:%d", e.id.LocalAddress, e.id.LocalPort, e.id.RemoteAddress, e.id.RemotePort)})
+ if e.route.Capabilities()&stack.CapabilityDisconnectOk == 0 {
+ panic(tcpip.ErrSaveRejection{fmt.Errorf("endpoint cannot be saved in connected state: local %v:%d, remote %v:%d", e.id.LocalAddress, e.id.LocalPort, e.id.RemoteAddress, e.id.RemotePort)})
+ }
+ e.resetConnectionLocked(tcpip.ErrConnectionAborted)
+ e.mu.Unlock()
+ e.Close()
+ e.mu.Lock()
}
if !e.workerRunning {
- // The endpoint must be in acceptedChan.
+ // The endpoint must be in acceptedChan or has been just
+ // disconnected and closed.
break
}
fallthrough