summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/sentry/socket/netstack/netstack.go13
-rw-r--r--pkg/tcpip/transport/tcp/connect.go13
-rw-r--r--pkg/tcpip/transport/tcp/endpoint.go47
-rw-r--r--pkg/tcpip/transport/tcp/endpoint_state.go10
-rw-r--r--pkg/tcpip/transport/tcp/tcp_state_autogen.go252
5 files changed, 180 insertions, 155 deletions
diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go
index 7d0ae15ca..5afe77858 100644
--- a/pkg/sentry/socket/netstack/netstack.go
+++ b/pkg/sentry/socket/netstack/netstack.go
@@ -2686,7 +2686,7 @@ func (s *socketOpsCommon) coalescingRead(ctx context.Context, dst usermem.IOSequ
// Always do at least one fetchReadView, even if the number of bytes to
// read is 0.
err = s.fetchReadView()
- if err != nil {
+ if err != nil || len(s.readView) == 0 {
break
}
if dst.NumBytes() == 0 {
@@ -2709,15 +2709,20 @@ func (s *socketOpsCommon) coalescingRead(ctx context.Context, dst usermem.IOSequ
}
copied += n
s.readView.TrimFront(n)
- if len(s.readView) == 0 {
- atomic.StoreUint32(&s.readViewHasData, 0)
- }
dst = dst.DropFirst(n)
if e != nil {
err = syserr.FromError(e)
break
}
+ // If we are done reading requested data then stop.
+ if dst.NumBytes() == 0 {
+ break
+ }
+ }
+
+ if len(s.readView) == 0 {
+ atomic.StoreUint32(&s.readViewHasData, 0)
}
// If we managed to copy something, we must deliver it.
diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go
index ac6d879a7..6661e8915 100644
--- a/pkg/tcpip/transport/tcp/connect.go
+++ b/pkg/tcpip/transport/tcp/connect.go
@@ -496,7 +496,7 @@ func (h *handshake) resolveRoute() *tcpip.Error {
h.ep.mu.Lock()
}
if n&notifyError != 0 {
- return h.ep.LastError()
+ return h.ep.lastErrorLocked()
}
}
@@ -575,7 +575,6 @@ func (h *handshake) complete() *tcpip.Error {
return err
}
defer timer.stop()
-
for h.state != handshakeCompleted {
// Unlock before blocking, and reacquire again afterwards (h.ep.mu is held
// throughout handshake processing).
@@ -631,9 +630,8 @@ func (h *handshake) complete() *tcpip.Error {
h.ep.mu.Lock()
}
if n&notifyError != 0 {
- return h.ep.LastError()
+ return h.ep.lastErrorLocked()
}
-
case wakerForNewSegment:
if err := h.processSegments(); err != nil {
return err
@@ -1002,7 +1000,7 @@ func (e *endpoint) resetConnectionLocked(err *tcpip.Error) {
// Only send a reset if the connection is being aborted for a reason
// other than receiving a reset.
e.setEndpointState(StateError)
- e.HardError = err
+ e.hardError = err
if err != tcpip.ErrConnectionReset && err != tcpip.ErrTimeout {
// The exact sequence number to be used for the RST is the same as the
// one used by Linux. We need to handle the case of window being shrunk
@@ -1141,7 +1139,7 @@ func (e *endpoint) handleReset(s *segment) (ok bool, err *tcpip.Error) {
// delete the TCB, and return.
case StateCloseWait:
e.transitionToStateCloseLocked()
- e.HardError = tcpip.ErrAborted
+ e.hardError = tcpip.ErrAborted
e.notifyProtocolGoroutine(notifyTickleWorker)
return false, nil
default:
@@ -1353,7 +1351,6 @@ func (e *endpoint) protocolMainLoop(handshake bool, wakerInitDone chan<- struct{
epilogue := func() {
// e.mu is expected to be hold upon entering this section.
-
if e.snd != nil {
e.snd.resendTimer.cleanup()
}
@@ -1383,7 +1380,7 @@ func (e *endpoint) protocolMainLoop(handshake bool, wakerInitDone chan<- struct{
e.lastErrorMu.Unlock()
e.setEndpointState(StateError)
- e.HardError = err
+ e.hardError = err
e.workerCleanup = true
// Lock released below.
diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go
index 4f4f4c65e..a2161e49d 100644
--- a/pkg/tcpip/transport/tcp/endpoint.go
+++ b/pkg/tcpip/transport/tcp/endpoint.go
@@ -315,11 +315,6 @@ func (*Stats) IsEndpointStats() {}
// +stateify savable
type EndpointInfo struct {
stack.TransportEndpointInfo
-
- // HardError is meaningful only when state is stateError. It stores the
- // error to be returned when read/write syscalls are called and the
- // endpoint is in this state. HardError is protected by endpoint mu.
- HardError *tcpip.Error `state:".(string)"`
}
// IsEndpointInfo is an empty method to implement the tcpip.EndpointInfo
@@ -386,6 +381,11 @@ type endpoint struct {
waiterQueue *waiter.Queue `state:"wait"`
uniqueID uint64
+ // hardError is meaningful only when state is stateError. It stores the
+ // error to be returned when read/write syscalls are called and the
+ // endpoint is in this state. hardError is protected by endpoint mu.
+ hardError *tcpip.Error `state:".(string)"`
+
// lastError represents the last error that the endpoint reported;
// access to it is protected by the following mutex.
lastErrorMu sync.Mutex `state:"nosave"`
@@ -1283,7 +1283,15 @@ func (e *endpoint) SetOwner(owner tcpip.PacketOwner) {
e.owner = owner
}
-func (e *endpoint) LastError() *tcpip.Error {
+// Preconditions: e.mu must be held to call this function.
+func (e *endpoint) hardErrorLocked() *tcpip.Error {
+ err := e.hardError
+ e.hardError = nil
+ return err
+}
+
+// Preconditions: e.mu must be held to call this function.
+func (e *endpoint) lastErrorLocked() *tcpip.Error {
e.lastErrorMu.Lock()
defer e.lastErrorMu.Unlock()
err := e.lastError
@@ -1291,6 +1299,15 @@ func (e *endpoint) LastError() *tcpip.Error {
return err
}
+func (e *endpoint) LastError() *tcpip.Error {
+ e.LockUser()
+ defer e.UnlockUser()
+ if err := e.hardErrorLocked(); err != nil {
+ return err
+ }
+ return e.lastErrorLocked()
+}
+
// Read reads data from the endpoint.
func (e *endpoint) Read(*tcpip.FullAddress) (buffer.View, tcpip.ControlMessages, *tcpip.Error) {
e.LockUser()
@@ -1312,9 +1329,8 @@ func (e *endpoint) Read(*tcpip.FullAddress) (buffer.View, tcpip.ControlMessages,
bufUsed := e.rcvBufUsed
if s := e.EndpointState(); !s.connected() && s != StateClose && bufUsed == 0 {
e.rcvListMu.Unlock()
- he := e.HardError
if s == StateError {
- return buffer.View{}, tcpip.ControlMessages{}, he
+ return buffer.View{}, tcpip.ControlMessages{}, e.hardErrorLocked()
}
e.stats.ReadErrors.NotConnected.Increment()
return buffer.View{}, tcpip.ControlMessages{}, tcpip.ErrNotConnected
@@ -1370,9 +1386,13 @@ func (e *endpoint) readLocked() (buffer.View, *tcpip.Error) {
// indicating the reason why it's not writable.
// Caller must hold e.mu and e.sndBufMu
func (e *endpoint) isEndpointWritableLocked() (int, *tcpip.Error) {
+ // The endpoint cannot be written to if it's not connected.
switch s := e.EndpointState(); {
case s == StateError:
- return 0, e.HardError
+ if err := e.hardErrorLocked(); err != nil {
+ return 0, err
+ }
+ return 0, tcpip.ErrClosedForSend
case !s.connecting() && !s.connected():
return 0, tcpip.ErrClosedForSend
case s.connecting():
@@ -1486,7 +1506,7 @@ func (e *endpoint) Peek(vec [][]byte) (int64, tcpip.ControlMessages, *tcpip.Erro
// but has some pending unread data.
if s := e.EndpointState(); !s.connected() && s != StateClose {
if s == StateError {
- return 0, tcpip.ControlMessages{}, e.HardError
+ return 0, tcpip.ControlMessages{}, e.hardErrorLocked()
}
e.stats.ReadErrors.InvalidEndpointState.Increment()
return 0, tcpip.ControlMessages{}, tcpip.ErrInvalidEndpointState
@@ -2243,7 +2263,10 @@ func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) *tc
return tcpip.ErrAlreadyConnecting
case StateError:
- return e.HardError
+ if err := e.hardErrorLocked(); err != nil {
+ return err
+ }
+ return tcpip.ErrConnectionAborted
default:
return tcpip.ErrInvalidEndpointState
@@ -2417,7 +2440,7 @@ func (e *endpoint) startMainLoop(handshake bool) *tcpip.Error {
e.lastErrorMu.Unlock()
e.setEndpointState(StateError)
- e.HardError = err
+ e.hardError = err
// Call cleanupLocked to free up any reservations.
e.cleanupLocked()
diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go
index bb901c0f8..ba67176b5 100644
--- a/pkg/tcpip/transport/tcp/endpoint_state.go
+++ b/pkg/tcpip/transport/tcp/endpoint_state.go
@@ -321,21 +321,21 @@ func (e *endpoint) loadRecentTSTime(unix unixTime) {
}
// saveHardError is invoked by stateify.
-func (e *EndpointInfo) saveHardError() string {
- if e.HardError == nil {
+func (e *endpoint) saveHardError() string {
+ if e.hardError == nil {
return ""
}
- return e.HardError.String()
+ return e.hardError.String()
}
// loadHardError is invoked by stateify.
-func (e *EndpointInfo) loadHardError(s string) {
+func (e *endpoint) loadHardError(s string) {
if s == "" {
return
}
- e.HardError = tcpip.StringToError(s)
+ e.hardError = tcpip.StringToError(s)
}
// saveMeasureTime is invoked by stateify.
diff --git a/pkg/tcpip/transport/tcp/tcp_state_autogen.go b/pkg/tcpip/transport/tcp/tcp_state_autogen.go
index 1d348afe0..9786a71bf 100644
--- a/pkg/tcpip/transport/tcp/tcp_state_autogen.go
+++ b/pkg/tcpip/transport/tcp/tcp_state_autogen.go
@@ -134,7 +134,6 @@ func (e *EndpointInfo) StateTypeName() string {
func (e *EndpointInfo) StateFields() []string {
return []string{
"TransportEndpointInfo",
- "HardError",
}
}
@@ -142,8 +141,6 @@ func (e *EndpointInfo) beforeSave() {}
func (e *EndpointInfo) StateSave(stateSinkObject state.Sink) {
e.beforeSave()
- var HardErrorValue string = e.saveHardError()
- stateSinkObject.SaveValue(1, HardErrorValue)
stateSinkObject.Save(0, &e.TransportEndpointInfo)
}
@@ -151,7 +148,6 @@ func (e *EndpointInfo) afterLoad() {}
func (e *EndpointInfo) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &e.TransportEndpointInfo)
- stateSourceObject.LoadValue(1, new(string), func(y interface{}) { e.loadHardError(y.(string)) })
}
func (e *endpoint) StateTypeName() string {
@@ -163,6 +159,7 @@ func (e *endpoint) StateFields() []string {
"EndpointInfo",
"waiterQueue",
"uniqueID",
+ "hardError",
"lastError",
"rcvList",
"rcvClosed",
@@ -229,141 +226,144 @@ func (e *endpoint) StateFields() []string {
func (e *endpoint) StateSave(stateSinkObject state.Sink) {
e.beforeSave()
+ var hardErrorValue string = e.saveHardError()
+ stateSinkObject.SaveValue(3, hardErrorValue)
var lastErrorValue string = e.saveLastError()
- stateSinkObject.SaveValue(3, lastErrorValue)
+ stateSinkObject.SaveValue(4, lastErrorValue)
var stateValue EndpointState = e.saveState()
- stateSinkObject.SaveValue(11, stateValue)
+ stateSinkObject.SaveValue(12, stateValue)
var recentTSTimeValue unixTime = e.saveRecentTSTime()
- stateSinkObject.SaveValue(25, recentTSTimeValue)
+ stateSinkObject.SaveValue(26, recentTSTimeValue)
var acceptedChanValue []*endpoint = e.saveAcceptedChan()
- stateSinkObject.SaveValue(51, acceptedChanValue)
+ stateSinkObject.SaveValue(52, acceptedChanValue)
stateSinkObject.Save(0, &e.EndpointInfo)
stateSinkObject.Save(1, &e.waiterQueue)
stateSinkObject.Save(2, &e.uniqueID)
- stateSinkObject.Save(4, &e.rcvList)
- stateSinkObject.Save(5, &e.rcvClosed)
- stateSinkObject.Save(6, &e.rcvBufSize)
- stateSinkObject.Save(7, &e.rcvBufUsed)
- stateSinkObject.Save(8, &e.rcvAutoParams)
- stateSinkObject.Save(9, &e.rcvMemUsed)
- stateSinkObject.Save(10, &e.ownedByUser)
- stateSinkObject.Save(12, &e.boundNICID)
- stateSinkObject.Save(13, &e.ttl)
- stateSinkObject.Save(14, &e.v6only)
- stateSinkObject.Save(15, &e.isConnectNotified)
- stateSinkObject.Save(16, &e.portFlags)
- stateSinkObject.Save(17, &e.boundBindToDevice)
- stateSinkObject.Save(18, &e.boundPortFlags)
- stateSinkObject.Save(19, &e.boundDest)
- stateSinkObject.Save(20, &e.effectiveNetProtos)
- stateSinkObject.Save(21, &e.workerRunning)
- stateSinkObject.Save(22, &e.workerCleanup)
- stateSinkObject.Save(23, &e.sendTSOk)
- stateSinkObject.Save(24, &e.recentTS)
- stateSinkObject.Save(26, &e.tsOffset)
- stateSinkObject.Save(27, &e.shutdownFlags)
- stateSinkObject.Save(28, &e.sackPermitted)
- stateSinkObject.Save(29, &e.sack)
- stateSinkObject.Save(30, &e.bindToDevice)
- stateSinkObject.Save(31, &e.delay)
- stateSinkObject.Save(32, &e.cork)
- stateSinkObject.Save(33, &e.scoreboard)
- stateSinkObject.Save(34, &e.slowAck)
- stateSinkObject.Save(35, &e.segmentQueue)
- stateSinkObject.Save(36, &e.synRcvdCount)
- stateSinkObject.Save(37, &e.userMSS)
- stateSinkObject.Save(38, &e.maxSynRetries)
- stateSinkObject.Save(39, &e.windowClamp)
- stateSinkObject.Save(40, &e.sndBufSize)
- stateSinkObject.Save(41, &e.sndBufUsed)
- stateSinkObject.Save(42, &e.sndClosed)
- stateSinkObject.Save(43, &e.sndBufInQueue)
- stateSinkObject.Save(44, &e.sndQueue)
- stateSinkObject.Save(45, &e.cc)
- stateSinkObject.Save(46, &e.packetTooBigCount)
- stateSinkObject.Save(47, &e.sndMTU)
- stateSinkObject.Save(48, &e.keepalive)
- stateSinkObject.Save(49, &e.userTimeout)
- stateSinkObject.Save(50, &e.deferAccept)
- stateSinkObject.Save(52, &e.rcv)
- stateSinkObject.Save(53, &e.snd)
- stateSinkObject.Save(54, &e.connectingAddress)
- stateSinkObject.Save(55, &e.amss)
- stateSinkObject.Save(56, &e.sendTOS)
- stateSinkObject.Save(57, &e.gso)
- stateSinkObject.Save(58, &e.tcpLingerTimeout)
- stateSinkObject.Save(59, &e.closed)
- stateSinkObject.Save(60, &e.txHash)
- stateSinkObject.Save(61, &e.owner)
- stateSinkObject.Save(62, &e.linger)
- stateSinkObject.Save(63, &e.ops)
+ stateSinkObject.Save(5, &e.rcvList)
+ stateSinkObject.Save(6, &e.rcvClosed)
+ stateSinkObject.Save(7, &e.rcvBufSize)
+ stateSinkObject.Save(8, &e.rcvBufUsed)
+ stateSinkObject.Save(9, &e.rcvAutoParams)
+ stateSinkObject.Save(10, &e.rcvMemUsed)
+ stateSinkObject.Save(11, &e.ownedByUser)
+ stateSinkObject.Save(13, &e.boundNICID)
+ stateSinkObject.Save(14, &e.ttl)
+ stateSinkObject.Save(15, &e.v6only)
+ stateSinkObject.Save(16, &e.isConnectNotified)
+ stateSinkObject.Save(17, &e.portFlags)
+ stateSinkObject.Save(18, &e.boundBindToDevice)
+ stateSinkObject.Save(19, &e.boundPortFlags)
+ stateSinkObject.Save(20, &e.boundDest)
+ stateSinkObject.Save(21, &e.effectiveNetProtos)
+ stateSinkObject.Save(22, &e.workerRunning)
+ stateSinkObject.Save(23, &e.workerCleanup)
+ stateSinkObject.Save(24, &e.sendTSOk)
+ stateSinkObject.Save(25, &e.recentTS)
+ stateSinkObject.Save(27, &e.tsOffset)
+ stateSinkObject.Save(28, &e.shutdownFlags)
+ stateSinkObject.Save(29, &e.sackPermitted)
+ stateSinkObject.Save(30, &e.sack)
+ stateSinkObject.Save(31, &e.bindToDevice)
+ stateSinkObject.Save(32, &e.delay)
+ stateSinkObject.Save(33, &e.cork)
+ stateSinkObject.Save(34, &e.scoreboard)
+ stateSinkObject.Save(35, &e.slowAck)
+ stateSinkObject.Save(36, &e.segmentQueue)
+ stateSinkObject.Save(37, &e.synRcvdCount)
+ stateSinkObject.Save(38, &e.userMSS)
+ stateSinkObject.Save(39, &e.maxSynRetries)
+ stateSinkObject.Save(40, &e.windowClamp)
+ stateSinkObject.Save(41, &e.sndBufSize)
+ stateSinkObject.Save(42, &e.sndBufUsed)
+ stateSinkObject.Save(43, &e.sndClosed)
+ stateSinkObject.Save(44, &e.sndBufInQueue)
+ stateSinkObject.Save(45, &e.sndQueue)
+ stateSinkObject.Save(46, &e.cc)
+ stateSinkObject.Save(47, &e.packetTooBigCount)
+ stateSinkObject.Save(48, &e.sndMTU)
+ stateSinkObject.Save(49, &e.keepalive)
+ stateSinkObject.Save(50, &e.userTimeout)
+ stateSinkObject.Save(51, &e.deferAccept)
+ stateSinkObject.Save(53, &e.rcv)
+ stateSinkObject.Save(54, &e.snd)
+ stateSinkObject.Save(55, &e.connectingAddress)
+ stateSinkObject.Save(56, &e.amss)
+ stateSinkObject.Save(57, &e.sendTOS)
+ stateSinkObject.Save(58, &e.gso)
+ stateSinkObject.Save(59, &e.tcpLingerTimeout)
+ stateSinkObject.Save(60, &e.closed)
+ stateSinkObject.Save(61, &e.txHash)
+ stateSinkObject.Save(62, &e.owner)
+ stateSinkObject.Save(63, &e.linger)
+ stateSinkObject.Save(64, &e.ops)
}
func (e *endpoint) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &e.EndpointInfo)
stateSourceObject.LoadWait(1, &e.waiterQueue)
stateSourceObject.Load(2, &e.uniqueID)
- stateSourceObject.LoadWait(4, &e.rcvList)
- stateSourceObject.Load(5, &e.rcvClosed)
- stateSourceObject.Load(6, &e.rcvBufSize)
- stateSourceObject.Load(7, &e.rcvBufUsed)
- stateSourceObject.Load(8, &e.rcvAutoParams)
- stateSourceObject.Load(9, &e.rcvMemUsed)
- stateSourceObject.Load(10, &e.ownedByUser)
- stateSourceObject.Load(12, &e.boundNICID)
- stateSourceObject.Load(13, &e.ttl)
- stateSourceObject.Load(14, &e.v6only)
- stateSourceObject.Load(15, &e.isConnectNotified)
- stateSourceObject.Load(16, &e.portFlags)
- stateSourceObject.Load(17, &e.boundBindToDevice)
- stateSourceObject.Load(18, &e.boundPortFlags)
- stateSourceObject.Load(19, &e.boundDest)
- stateSourceObject.Load(20, &e.effectiveNetProtos)
- stateSourceObject.Load(21, &e.workerRunning)
- stateSourceObject.Load(22, &e.workerCleanup)
- stateSourceObject.Load(23, &e.sendTSOk)
- stateSourceObject.Load(24, &e.recentTS)
- stateSourceObject.Load(26, &e.tsOffset)
- stateSourceObject.Load(27, &e.shutdownFlags)
- stateSourceObject.Load(28, &e.sackPermitted)
- stateSourceObject.Load(29, &e.sack)
- stateSourceObject.Load(30, &e.bindToDevice)
- stateSourceObject.Load(31, &e.delay)
- stateSourceObject.Load(32, &e.cork)
- stateSourceObject.Load(33, &e.scoreboard)
- stateSourceObject.Load(34, &e.slowAck)
- stateSourceObject.LoadWait(35, &e.segmentQueue)
- stateSourceObject.Load(36, &e.synRcvdCount)
- stateSourceObject.Load(37, &e.userMSS)
- stateSourceObject.Load(38, &e.maxSynRetries)
- stateSourceObject.Load(39, &e.windowClamp)
- stateSourceObject.Load(40, &e.sndBufSize)
- stateSourceObject.Load(41, &e.sndBufUsed)
- stateSourceObject.Load(42, &e.sndClosed)
- stateSourceObject.Load(43, &e.sndBufInQueue)
- stateSourceObject.LoadWait(44, &e.sndQueue)
- stateSourceObject.Load(45, &e.cc)
- stateSourceObject.Load(46, &e.packetTooBigCount)
- stateSourceObject.Load(47, &e.sndMTU)
- stateSourceObject.Load(48, &e.keepalive)
- stateSourceObject.Load(49, &e.userTimeout)
- stateSourceObject.Load(50, &e.deferAccept)
- stateSourceObject.LoadWait(52, &e.rcv)
- stateSourceObject.LoadWait(53, &e.snd)
- stateSourceObject.Load(54, &e.connectingAddress)
- stateSourceObject.Load(55, &e.amss)
- stateSourceObject.Load(56, &e.sendTOS)
- stateSourceObject.Load(57, &e.gso)
- stateSourceObject.Load(58, &e.tcpLingerTimeout)
- stateSourceObject.Load(59, &e.closed)
- stateSourceObject.Load(60, &e.txHash)
- stateSourceObject.Load(61, &e.owner)
- stateSourceObject.Load(62, &e.linger)
- stateSourceObject.Load(63, &e.ops)
- stateSourceObject.LoadValue(3, new(string), func(y interface{}) { e.loadLastError(y.(string)) })
- stateSourceObject.LoadValue(11, new(EndpointState), func(y interface{}) { e.loadState(y.(EndpointState)) })
- stateSourceObject.LoadValue(25, new(unixTime), func(y interface{}) { e.loadRecentTSTime(y.(unixTime)) })
- stateSourceObject.LoadValue(51, new([]*endpoint), func(y interface{}) { e.loadAcceptedChan(y.([]*endpoint)) })
+ stateSourceObject.LoadWait(5, &e.rcvList)
+ stateSourceObject.Load(6, &e.rcvClosed)
+ stateSourceObject.Load(7, &e.rcvBufSize)
+ stateSourceObject.Load(8, &e.rcvBufUsed)
+ stateSourceObject.Load(9, &e.rcvAutoParams)
+ stateSourceObject.Load(10, &e.rcvMemUsed)
+ stateSourceObject.Load(11, &e.ownedByUser)
+ stateSourceObject.Load(13, &e.boundNICID)
+ stateSourceObject.Load(14, &e.ttl)
+ stateSourceObject.Load(15, &e.v6only)
+ stateSourceObject.Load(16, &e.isConnectNotified)
+ stateSourceObject.Load(17, &e.portFlags)
+ stateSourceObject.Load(18, &e.boundBindToDevice)
+ stateSourceObject.Load(19, &e.boundPortFlags)
+ stateSourceObject.Load(20, &e.boundDest)
+ stateSourceObject.Load(21, &e.effectiveNetProtos)
+ stateSourceObject.Load(22, &e.workerRunning)
+ stateSourceObject.Load(23, &e.workerCleanup)
+ stateSourceObject.Load(24, &e.sendTSOk)
+ stateSourceObject.Load(25, &e.recentTS)
+ stateSourceObject.Load(27, &e.tsOffset)
+ stateSourceObject.Load(28, &e.shutdownFlags)
+ stateSourceObject.Load(29, &e.sackPermitted)
+ stateSourceObject.Load(30, &e.sack)
+ stateSourceObject.Load(31, &e.bindToDevice)
+ stateSourceObject.Load(32, &e.delay)
+ stateSourceObject.Load(33, &e.cork)
+ stateSourceObject.Load(34, &e.scoreboard)
+ stateSourceObject.Load(35, &e.slowAck)
+ stateSourceObject.LoadWait(36, &e.segmentQueue)
+ stateSourceObject.Load(37, &e.synRcvdCount)
+ stateSourceObject.Load(38, &e.userMSS)
+ stateSourceObject.Load(39, &e.maxSynRetries)
+ stateSourceObject.Load(40, &e.windowClamp)
+ stateSourceObject.Load(41, &e.sndBufSize)
+ stateSourceObject.Load(42, &e.sndBufUsed)
+ stateSourceObject.Load(43, &e.sndClosed)
+ stateSourceObject.Load(44, &e.sndBufInQueue)
+ stateSourceObject.LoadWait(45, &e.sndQueue)
+ stateSourceObject.Load(46, &e.cc)
+ stateSourceObject.Load(47, &e.packetTooBigCount)
+ stateSourceObject.Load(48, &e.sndMTU)
+ stateSourceObject.Load(49, &e.keepalive)
+ stateSourceObject.Load(50, &e.userTimeout)
+ stateSourceObject.Load(51, &e.deferAccept)
+ stateSourceObject.LoadWait(53, &e.rcv)
+ stateSourceObject.LoadWait(54, &e.snd)
+ stateSourceObject.Load(55, &e.connectingAddress)
+ stateSourceObject.Load(56, &e.amss)
+ stateSourceObject.Load(57, &e.sendTOS)
+ stateSourceObject.Load(58, &e.gso)
+ stateSourceObject.Load(59, &e.tcpLingerTimeout)
+ stateSourceObject.Load(60, &e.closed)
+ stateSourceObject.Load(61, &e.txHash)
+ stateSourceObject.Load(62, &e.owner)
+ stateSourceObject.Load(63, &e.linger)
+ stateSourceObject.Load(64, &e.ops)
+ stateSourceObject.LoadValue(3, new(string), func(y interface{}) { e.loadHardError(y.(string)) })
+ stateSourceObject.LoadValue(4, new(string), func(y interface{}) { e.loadLastError(y.(string)) })
+ stateSourceObject.LoadValue(12, new(EndpointState), func(y interface{}) { e.loadState(y.(EndpointState)) })
+ stateSourceObject.LoadValue(26, new(unixTime), func(y interface{}) { e.loadRecentTSTime(y.(unixTime)) })
+ stateSourceObject.LoadValue(52, new([]*endpoint), func(y interface{}) { e.loadAcceptedChan(y.([]*endpoint)) })
stateSourceObject.AfterLoad(e.afterLoad)
}