diff options
Diffstat (limited to 'pkg/tcpip/transport')
-rw-r--r-- | pkg/tcpip/transport/tcp/connect.go | 13 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/endpoint.go | 47 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/endpoint_state.go | 10 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/tcp_state_autogen.go | 252 |
4 files changed, 171 insertions, 151 deletions
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¬ifyError != 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¬ifyError != 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) } |