Documentation
¶
Overview ¶
Package exchange is the controller's message layer: the sessions and the exchanges of the initiator role over one UDP socket, with the Message Reliability Protocol (MRP) on every exchange. It is the port of matter.js packages/protocol/src/protocol/ExchangeManager.ts and MessageExchange.ts for the client role (ADR 0020, stage 1), and the layer the PASE and CASE clients of controller/handshake run on.
A Manager owns the socket's send side, the session table and the exchange table, and is fed every received datagram through Manager.HandleDatagram (a transport/udp Handler). A Session is either the unsecured session of a handshake (Manager.NewUnsecuredSession) or a secure PASE / CASE session (Manager.NewSecureSession) whose encryption is a secure/channel Session. An Exchange is one exchange this node initiated (Manager.Initiate): Exchange.Send transmits reliably and returns once the peer acknowledged, Exchange.Next waits for the peer's next message, Exchange.Close ends it.
Scope: UDP only and unicast only (no group sessions). An exchange a peer opens reaches a ProtocolHandler installed with Manager.SetProtocolHandler (ADR 0020, stage 3): on a secure session any protocol's but the Secure Channel's, whose CloseSession handling is built in as matter.js's StatusReportOnlySecureChannelProtocol; on an unsecured session the peer opens, a Sigma1 for the CASE responder, a PBKDFParamRequest being refused. A message no handler takes is acknowledged when it asks for an acknowledgement and otherwise dropped.
Index ¶
- Constants
- Variables
- func CheckStatusReport(payload []byte) error
- func DefaultLocalParameters() sessionparams.Parameters
- func MaxPeerResponseTime(peer *Intervals, peerActive bool, local Intervals, ...) time.Duration
- func Overlay(base sessionparams.Parameters, over *sessionparams.Parameters) sessionparams.Parameters
- func PeerParameters(reported *sessionparams.Parameters) sessionparams.Parameters
- func ReliableMaxPeerResponseTime(expectedProcessingTime time.Duration) time.Duration
- func RetransmissionInterval(n int, p Intervals, peerActive bool, rand01 float64) time.Duration
- type Clock
- type Config
- type Conn
- type Exchange
- func (x *Exchange) Abort(cause error)
- func (x *Exchange) Close()
- func (x *Exchange) ConsiderClosed() bool
- func (x *Exchange) Done() <-chan struct{}
- func (x *Exchange) HasUnackedMessage() bool
- func (x *Exchange) ID() uint16
- func (x *Exchange) Next(ctx context.Context, opts ReceiveOptions) (*Message, error)
- func (x *Exchange) RetransmissionCount() int
- func (x *Exchange) RetransmissionRestartSaving() time.Duration
- func (x *Exchange) Send(ctx context.Context, opcode uint8, payload []byte, opts SendOptions) error
- func (x *Exchange) Session() *Session
- type Intervals
- type Manager
- func (m *Manager) AllocateSessionID(ctx context.Context) (uint16, error)
- func (m *Manager) Close()
- func (m *Manager) CloseSession(ctx context.Context, s *Session)
- func (m *Manager) HandleDatagram(buf []byte, src *net.UDPAddr)
- func (m *Manager) HandlePeerLoss(peer PeerAddress, cause error, asOf time.Time)
- func (m *Manager) Initiate(s *Session, protocol uint16, opts Options) (*Exchange, error)
- func (m *Manager) LocalParameters() sessionparams.Parameters
- func (m *Manager) NewSecureSession(cfg SecureSessionConfig) (*Session, error)
- func (m *Manager) NewUnsecuredSession(addr *net.UDPAddr, peer *sessionparams.Parameters) (*Session, error)
- func (m *Manager) Reliable() bool
- func (m *Manager) Session(id uint16) *Session
- func (m *Manager) SessionsFor(peer PeerAddress) []*Session
- func (m *Manager) SetProtocolHandler(protocol uint16, h ProtocolHandler)
- type Message
- type Options
- type PeerAddress
- type PeerInitiatedCloseError
- type PeerMessageMissingError
- type PeerUnresponsiveError
- type ProtocolHandler
- type ReceiveOptions
- type SecureSessionConfig
- type SendOptions
- type Session
- func (s *Session) ActiveTimestamp() time.Time
- func (s *Session) Addr() *net.UDPAddr
- func (s *Session) AttestationChallenge() []byte
- func (s *Session) CaseAuthenticatedTags() []uint32
- func (s *Session) Close()
- func (s *Session) Closing() <-chan struct{}
- func (s *Session) CreatedAt() time.Time
- func (s *Session) FabricIndex() uint8
- func (s *Session) HandlePeerLoss(cause error)
- func (s *Session) ID() uint16
- func (s *Session) IsClosed() bool
- func (s *Session) IsInbound() bool
- func (s *Session) IsPeerActive() bool
- func (s *Session) IsPeerLost() bool
- func (s *Session) IsSecure() bool
- func (s *Session) NodeID() uint64
- func (s *Session) Parameters() sessionparams.Parameters
- func (s *Session) PeerNodeID() uint64
- func (s *Session) PeerSessionID() uint16
- func (s *Session) ReportedParameters() *sessionparams.Parameters
- func (s *Session) Resumed() bool
- func (s *Session) SetAddr(addr *net.UDPAddr)
- func (s *Session) SetTimingParameters(p sessionparams.Parameters)
- func (s *Session) UsesMRP() bool
- type StatusReport
- type StatusReportError
- type SystemClock
- type Timer
- type UnexpectedMessageError
Constants ¶
const ( // MaxTransmissions is the number of transmissions of one reliable // message, the first included. Mirrors matter.js // packages/protocol/src/protocol/MRP.ts:33 (MAX_TRANSMISSIONS = 5) at // 0ceb202d. MaxTransmissions = 5 // StandaloneAckTimeout is how long a received reliable message waits // for an outbound message to piggyback its acknowledgement before a // standalone ack goes out. Mirrors matter.js MRP.ts:48 // (STANDALONE_ACK_TIMEOUT = 200 ms), the delay of mrp.AckTracker. StandaloneAckTimeout = mrp.DefaultStandaloneAckDelay // DefaultExpectedProcessingTime is the peer's processing time an // exchange assumes when the caller states none. Mirrors matter.js // MRP.ts:55 (DEFAULT_EXPECTED_PROCESSING_TIME = 2 s). DefaultExpectedProcessingTime = 2 * time.Second // MaxPayloadSize is the largest message payload an exchange sends over // UDP: the 1232-byte UDP payload of an IPv6 minimum MTU less the Matter // message overhead (26 + 12 + 16). Mirrors matter.js // packages/protocol/src/protocol/MessageExchange.ts:156 // (MATTER_MESSAGE_OVERHEAD), :435-439 (maxPayloadSize) and // packages/general/src/net/udp/UdpSocket.ts:12 (MAX_UDP_MESSAGE_SIZE). MaxPayloadSize = 1232 - (26 + 12 + 16) )
MRP constants of the exchange layer.
const ( FallbackIdleInterval uint32 = 500 // ms, SessionIntervals.ts:46 FallbackActiveInterval uint32 = 300 // ms, SessionIntervals.ts:47 FallbackActiveThreshold uint16 = 4000 // ms, SessionIntervals.ts:48 FallbackDataModelRevision uint16 = 17 // SessionParameters.ts:125 FallbackInteractionModelRevision uint16 = 11 // SessionParameters.ts:131 FallbackMaxPathsPerInvoke uint16 = 1 // SessionParameters.ts:145 )
Fallbacks for session parameters a peer did not report. Mirrors matter.js packages/protocol/src/session/SessionIntervals.ts:45-49 (the intervals) and SessionParameters.ts:118-153 (the rest) at 0ceb202d.
const MaxConcurrentExchangesPerSession = 30
MaxConcurrentExchangesPerSession is the number of open exchanges one secure session keeps; opening one more closes the least recently active one. Mirrors matter.js packages/protocol/src/protocol/ExchangeManager.ts:54 (MAXIMUM_CONCURRENT_OUTGOING_EXCHANGES_PER_SESSION = 30) and the eviction of :494-531 at 0ceb202d; the unsecured session is exempt (:511-514).
const UnsecuredSessionID uint16 = 0
UnsecuredSessionID is the session id of the unsecured session. Mirrors matter.js packages/protocol/src/session/UnsecuredSession.ts:18 (UNICAST_UNSECURE_SESSION_ID) at 0ceb202d.
Variables ¶
var ( // ErrTransient is the class of every error after which the peer may // still be present but cannot be reached right now — matter.js // TransientPeerCommunicationError (PeerCommunicationError.ts:19). // [PeerUnresponsiveError], [PeerMessageMissingError] and // [StatusReportError] are transient. ErrTransient = errors.New("exchange: transient peer communication error") // ErrNetwork wraps a failure of the socket to send — matter.js // NetworkError. ErrNetwork = errors.New("exchange: network error") // ErrRetransmissionLimit is matter.js RetransmissionLimitReachedError // (packages/protocol/src/protocol/errors.ts:17, deprecated there and thrown by no exchange at // 0ceb202d). It is kept so the handshakes' "do not report an error to // a peer we cannot reach" rule names the same three classes matter.js // names (PaseClient.ts:101, CaseClient.ts:89). ErrRetransmissionLimit = errors.New("exchange: retransmission limit reached") // ErrFlow is a call the exchange's state forbids — a second send // while the previous message is unacknowledged (MessageExchange.ts:669-673), // a message that fails to acknowledge our pending one // (MessageExchange.ts:493-504) — matter.js MatterFlowError. ErrFlow = errors.New("exchange: flow error") // ErrExchangeClosed is returned by a call on a closed exchange // (MessageExchange.ts:606-608, ClosedError). ErrExchangeClosed = errors.New("exchange: exchange closed") // ErrSessionClosed is returned by a call on a closed session // (matter.js SessionClosedError, protocol/errors.ts:35). ErrSessionClosed = errors.New("exchange: session closed") // ErrUnexpectedMessage is a reply the exchange did not expect — an // ack-only send answered with data (MessageExchange.ts:815-817). ErrUnexpectedMessage = errors.New("exchange: unexpected message") // ErrNoSessionID is returned when every session id is taken and no // session can be closed to free one (SessionManager.ts:515-523). ErrNoSessionID = errors.New("exchange: no session id available") )
Errors of the exchange layer. The classes follow matter.js packages/protocol/src/peer/PeerCommunicationError.ts and packages/protocol/src/protocol/errors.ts at 0ceb202d; a caller tests them with errors.Is.
Functions ¶
func CheckStatusReport ¶
CheckStatusReport returns a *StatusReportError unless payload is a StatusReport with general code Success and protocol code Success (SESSION_ESTABLISHMENT_SUCCESS) — SecureChannelMessenger.ts:234-259 throwIfErrorStatusReport. A body too short to decode is an ErrUnexpectedMessage.
func DefaultLocalParameters ¶
func DefaultLocalParameters() sessionparams.Parameters
DefaultLocalParameters is the session parameters a controller sends when its host chose none: matter.js SessionParameters.defaults (SessionParameters.ts:158-164), the fallbacks with this module's data-model revision, interaction-model revision and specification version.
func MaxPeerResponseTime ¶
func MaxPeerResponseTime(peer *Intervals, peerActive bool, local Intervals, expectedProcessingTime time.Duration) time.Duration
MaxPeerResponseTime is how long an exchange waits for the peer's next message over UDP with MRP: our own worst-case retransmission time (local intervals, assumed active), the expected processing time and a 5 s buffer, plus — when peer is not nil — the peer's worst-case retransmission time back to us. Mirrors matter.js MRP.ts:79-120 (maxPeerResponseTimeOf, the "udp" case).
Exchange.Next passes no peer intervals: matter.js MessageExchange.ts:840-847 calls calculateMaximumPeerResponseTime with includeMaximumSendingTime undefined, and MessageChannel.ts:224-226 then omits the peer direction.
func Overlay ¶
func Overlay(base sessionparams.Parameters, over *sessionparams.Parameters) sessionparams.Parameters
Overlay returns base with every field over states replacing it — the object spread `{...base, ...over}` matter.js uses to combine parameter sets (PaseClient.ts:168-171, CaseClient.ts:184-188).
func PeerParameters ¶
func PeerParameters(reported *sessionparams.Parameters) sessionparams.Parameters
PeerParameters is the parameters a session assumes for its peer: the fallbacks overlaid by what the peer reported (nil reported nothing), with TCP cleared for a peer below Matter 1.5, MaxTCPMessageSize only when TCP remains, and a MaxPathsPerInvoke of 0 taking the fallback. Mirrors matter.js SessionParameters.ts:42-81 (the SessionParameters factory).
func ReliableMaxPeerResponseTime ¶ added in v0.7.0
ReliableMaxPeerResponseTime is how long an exchange waits for the peer's next message on a reliable channel without MRP: 30 s, or the expected processing time when longer, plus the 5 s buffer. Mirrors matter.js MRP.ts:111-113 (the "ble" case; the "tcp" case at :90-92 is the same).
func RetransmissionInterval ¶
RetransmissionInterval is the wait after transmission number n (0 is the first transmission) of a reliable message to a peer with intervals p: the peer's active interval while it is active, its idle interval otherwise, grown by the §4.12.2.1 backoff and jittered by rand01 (a value in [0, 1); 1 gives the maximum), floored to whole milliseconds.
Mirrors matter.js packages/protocol/src/protocol/MRP.ts:162-190 (retransmissionIntervalOf) at 0ceb202d with additionalDelay and fixedBackoff zero — the controller has no network profile — through transport/mrp.BackoffDuration, the same formula.
Types ¶
type Clock ¶
Clock is the time source of a Manager: the current time and timers. The default is the system clock; a test supplies its own (github.com/SukramJ/go-fabric/clock/clocktest.Fake) to step the retransmission and acknowledgement timers deterministically.
Clock is the module's one time port, clock.Clock; the alias keeps every existing reference to exchange.Clock compiling.
type Config ¶
type Config struct {
// LocalParameters are our session parameters: sent in the handshakes
// and the timing of our own retransmissions. Nil is
// [DefaultLocalParameters].
LocalParameters *sessionparams.Parameters
// Clock is the time source; nil is [SystemClock].
Clock Clock
// Rand returns the MRP jitter draw in [0, 1); nil is math/rand/v2.Float64.
Rand func() float64
// Logger receives debug diagnostics; nil discards them.
Logger *slog.Logger
// PeerLost is called when a send or a wait on an exchange of a secure
// session fails in a way that shows the peer is gone — matter.js
// MessageExchangeContext.peerLost (ExchangeManager.ts:556-579), fired
// from MessageExchange.ts:613-621 and :822-832. Nil ignores it.
PeerLost func(s *Session, cause error)
// Reliable marks the manager's carrier as reliable (BTP): its sessions
// do not use MRP — no acknowledgement requested, none sent, no
// retransmission — and a wait for the peer is the reliable channel's.
// Mirrors matter.js packages/protocol/src/session/Session.ts:355-356
// (`usesMrp = supportsMRP && !channel?.isReliable`) for a manager whose
// one channel is a BleChannel (packages/protocol/src/ble/Ble.ts:38).
Reliable bool
}
Config configures a Manager.
type Conn ¶
Conn is the send side of the socket a Manager uses. A *transport/udp.Listener satisfies it; its Serve handler is Manager.HandleDatagram.
type Exchange ¶
type Exchange struct {
// contains filtered or unexported fields
}
Exchange is one exchange this node initiated. Send and Next are not meant for concurrent use with each other on one exchange (an exchange is one conversation), but every method is safe to call from any goroutine.
func (*Exchange) Abort ¶
Abort closes the exchange at once with cause: an acknowledgement still owed goes out, nothing is waited for, and further calls fail with cause — matter.js MessageExchange.ts:1053-1105 (close with a cause).
func (*Exchange) Close ¶
func (x *Exchange) Close()
Close ends the exchange gracefully — matter.js MessageExchange.ts:1053-1130 (close without a cause): an acknowledgement still owed goes out at once; with no message of ours unacknowledged the exchange closes now, otherwise it stays open for the maximum time our remaining transmissions can take, so a late acknowledgement is still taken, and closes then. An exchange that never sent closes at once. Close returns without waiting; Exchange.Done reports the end. It is idempotent.
func (*Exchange) ConsiderClosed ¶
ConsiderClosed reports whether the exchange counts as closed: closed, or — for an exchange we initiated — closing. It is matter.js MessageExchange.considerClosed (MessageExchange.ts:376-378), which a CASE responder reads before its error report (CaseServer.ts:82-86).
func (*Exchange) Done ¶
func (x *Exchange) Done() <-chan struct{}
Done is closed once the exchange is closed and left the manager.
func (*Exchange) HasUnackedMessage ¶
HasUnackedMessage reports whether a message we sent still waits for its acknowledgement — matter.js MessageExchange.ts:415-422. The exchange cannot send again in that state, so a handshake skips its best-effort error report.
func (*Exchange) Next ¶
Next waits for the peer's next message on the exchange — matter.js MessageExchange.ts:822-860. The wait is opts.Timeout, or MaxPeerResponseTime of our own intervals and the expected processing time; on expiry it is a *PeerMessageMissingError, which reports the peer lost when nothing was received on the exchange. On a closed session the wait is unbounded but for ctx.
func (*Exchange) RetransmissionCount ¶
RetransmissionCount is the number of retransmissions of the message the exchange sent last, reset by a new send and by its acknowledgement — matter.js MessageExchange.ts:410-413 (retransmissionCount): the counter of :263, reset at :508 (ack), :611 (send) and :786 (first transmission), incremented at :886 and taken back at :907 when only the final wait remains.
func (*Exchange) RetransmissionRestartSaving ¶
RetransmissionRestartSaving is how much restarting the exchange — a fresh exchange whose first transmission waits the base backoff — would shorten the wait until the next (re)transmission: the interval of the retransmission timer armed last minus the backoff of transmission 0, never negative, and 0 before the exchange armed a timer. Mirrors matter.js MessageExchange.ts:1258-1266 (retransmissionRestartSaving), which reads the last timer's interval whether or not it still runs.
func (*Exchange) Send ¶
Send sends one message on the exchange and, when it travels reliably, returns once the peer acknowledged it. Mirrors matter.js MessageExchange.ts:605-820 (send, #send) at 0ceb202d:
- a closed exchange refuses (:606-608);
- the message asks for an acknowledgement unless SuppressAck (:660); a StatusReport travels on the Secure Channel protocol whatever the exchange's protocol (:662-665);
- a send while the previous message is unacknowledged is an ErrFlow (:669-673);
- the acknowledgement owed for the last received message rides along, and its standalone-ack timer stops (:679-686);
- the message is retransmitted on the MRP schedule until acknowledged; after the last transmission and the final wait the send fails with a *PeerUnresponsiveError (:752-766, :879-966);
- a failure with nothing received on the exchange that shows the peer gone reports it to the manager's PeerLost hook (:613-638).
A ctx already done sends nothing; a ctx done while waiting for the acknowledgement stops the retransmissions and leaves the message unacknowledged (:793-805). Both return ctx's error.
type Intervals ¶
type Intervals struct {
// Idle is SESSION_IDLE_INTERVAL: the retry base while the node is idle.
Idle time.Duration
// Active is SESSION_ACTIVE_INTERVAL: the retry base while it is active.
Active time.Duration
// ActiveThreshold is SESSION_ACTIVE_THRESHOLD: how long after its last
// message the node counts as active.
ActiveThreshold time.Duration
}
Intervals are the MRP timing parameters of one side of a session.
func IntervalsOf ¶
func IntervalsOf(p sessionparams.Parameters) Intervals
IntervalsOf is the MRP timing of p, the fallback for every interval p does not state (SessionIntervals.ts:36-42).
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager is the controller's exchange manager: one socket, the session table, the exchange table and the receive path. It is safe for concurrent use.
func NewManager ¶
NewManager returns a manager that sends on conn.
func (*Manager) AllocateSessionID ¶
AllocateSessionID returns the next free local session id for a PASE or CASE session: the cursor's next id that no session holds, cycling through 1..0xFFFF; when every id is taken the least recently used session is closed (the peer is told) and its id reused. Mirrors matter.js SessionManager.ts:504-557 (getNextAvailableSessionId, findOldestInactiveSession, #takeSessionId).
func (*Manager) Close ¶
func (m *Manager) Close()
Close closes every exchange and session without telling the peers. It is idempotent; the manager accepts no new session afterwards.
func (*Manager) CloseSession ¶
CloseSession ends a session: a secure session whose peer is not lost (NodeSession.ts:389-395) first sends CloseSession on a fresh exchange — a StatusReport (Success, CloseSession) without an acknowledgement request — then is dropped. Mirrors matter.js ExchangeManager.ts:716-726 (#sendCloseSession) and SecureChannelMessenger.ts:193-195 (sendCloseSession, suppressAck). A failure to send is logged, never returned: the session is gone either way.
func (*Manager) HandleDatagram ¶
HandleDatagram processes one received datagram; it is the transport/udp Handler of the controller's socket. Mirrors matter.js ExchangeManager.ts:220-475 (#receiveMessage) for unicast messages: a message for an unknown session is dropped, the counter goes through the session's reception window (a duplicate still reaches its exchange, which acknowledges it), every decoded message marks the peer active, and a message no exchange of ours accepts is acknowledged when it asks for it and dropped otherwise.
func (*Manager) HandlePeerLoss ¶
func (m *Manager) HandlePeerLoss(peer PeerAddress, cause error, asOf time.Time)
HandlePeerLoss gives up every secure session with peer created before asOf (a zero asOf: all of them) — each as Session.HandlePeerLoss does. Mirrors matter.js SessionManager.ts:636-638 (handlePeerLoss, asOf defaulting to now) and :677-696 (#handlePeerLoss: a session created at or after asOf is kept).
func (*Manager) Initiate ¶
Initiate opens an exchange on s for protocol — matter.js ExchangeManager.ts:145-156 (initiateExchangeForSession): the exchange id is the next value of a counter that starts at random and wraps at 0xFFFF (:729-743), and the exchange is indexed apart from received ones.
func (*Manager) LocalParameters ¶
func (m *Manager) LocalParameters() sessionparams.Parameters
LocalParameters is our session parameters.
func (*Manager) NewSecureSession ¶
func (m *Manager) NewSecureSession(cfg SecureSessionConfig) (*Session, error)
NewSecureSession registers the secure session a handshake established. It counts the peer as active from the start (NodeSession.ts:119).
func (*Manager) NewUnsecuredSession ¶
func (m *Manager) NewUnsecuredSession(addr *net.UDPAddr, peer *sessionparams.Parameters) (*Session, error)
NewUnsecuredSession opens the unsecured session of a handshake with the peer at addr. peer is what is known of the peer's session parameters (from its DNS-SD record), nil for none. Our side is the initiator: the session draws a random ephemeral node id, sends with the global unencrypted counter and counts the peer as idle until it answers — matter.js SessionManager.ts:418-458 (createUnsecuredSession) and UnsecuredSession.ts:26-34.
func (*Manager) Reliable ¶ added in v0.7.0
Reliable reports whether the manager's carrier is reliable (Config.Reliable).
func (*Manager) SessionsFor ¶
func (m *Manager) SessionsFor(peer PeerAddress) []*Session
SessionsFor returns the open secure sessions with peer — matter.js SessionManager.sessionsFor.
func (*Manager) SetProtocolHandler ¶
func (m *Manager) SetProtocolHandler(protocol uint16, h ProtocolHandler)
SetProtocolHandler installs h for the exchanges the peer opens with protocol — matter.js ExchangeManager.addProtocolHandler, consulted for the first message of an exchange at ExchangeManager.ts:391-440. A nil h removes it. The Secure Channel protocol is special:
- on a secure session its handler stays the built-in one (the StatusReport-only handler of SecureChannelProtocol.ts:30-88), h is not consulted;
- on an unsecured session h receives a Sigma1 — matter.js SecureChannelProtocol.ts:146-148 hands it to the CaseServer — and a PBKDFParamRequest is refused with InvalidParam, the controller having no PASE server (:129-137).
Every other protocol's handler runs for the exchanges opened on a secure session only, as matter.js's InteractionServer and ClientSubscriptionHandler require (requiresSecureSession, ExchangeManager.ts:393-405). A message no handler takes is acknowledged when it asks for it and dropped (:441-473).
type Message ¶
type Message struct {
// Counter is the message counter of the packet header.
Counter uint32
// ProtocolID and Opcode name the message.
ProtocolID uint16
Opcode uint8
// ExchangeID is the exchange the message belongs to.
ExchangeID uint16
// Initiator is the sender's I flag.
Initiator bool
// RequiresAck is the R flag; HasAck and AckCounter the piggybacked
// acknowledgement.
RequiresAck bool
HasAck bool
AckCounter uint32
// Payload is the application payload.
Payload []byte
}
Message is one message received on an exchange.
type Options ¶
type Options struct {
// SuppressPeerLoss waives the peer-loss report for this exchange —
// matter.js MessageExchange.Options.suppressPeerLoss
// (MessageExchange.ts:1272-1273).
SuppressPeerLoss bool
// OnSend is called before every transmission of a message on the
// exchange with its retransmission number: 0 for a first
// transmission (a standalone ack included), n for the n-th
// retransmission — matter.js MessageExchange.Options.onSend
// (:1240-1243), called at :768 and :943. It runs on the sending
// goroutine, for a first transmission with the exchange locked, so it
// must not block for long or call back into the exchange.
OnSend func(retransmission int)
// AddressOverride sends the exchange's messages to this address instead
// of the session's, leaving the session's address and its other
// exchanges alone — matter.js MessageExchange.Options.addressOverride
// (:1266-1270), stored at :297 and used for every transmission (:488,
// :771-774, :953). Nil sends to the session's address.
AddressOverride *net.UDPAddr
// OnReceive is called for every message the exchange takes, a
// duplicate and a standalone ack included — matter.js
// MessageExchange.Options.onReceive (:1245-1248), called at :469
// after the protocol check.
OnReceive func()
}
Options configures Manager.Initiate — matter.js MessageExchange.Options (MessageExchange.ts:1239-1274).
type PeerAddress ¶
PeerAddress names a peer on one of our fabrics: our fabric index and the peer's operational node id — matter.js PeerAddress (packages/protocol/src/peer/PeerAddress.ts); handshake.PeerAddress and the peer package use this type.
type PeerInitiatedCloseError ¶
type PeerInitiatedCloseError struct{}
PeerInitiatedCloseError is the cause a session ends with when the peer closed it with a CloseSession StatusReport — matter.js PeerInitiatedCloseError (PeerCommunicationError.ts:71-75), raised by NodeSession.handlePeerClose (NodeSession.ts:305-309). It is transient.
func (*PeerInitiatedCloseError) Error ¶
func (*PeerInitiatedCloseError) Error() string
func (*PeerInitiatedCloseError) Is ¶
func (*PeerInitiatedCloseError) Is(target error) bool
Is makes the error match ErrTransient.
type PeerMessageMissingError ¶
PeerMessageMissingError is an expected message that did not arrive on the exchange before the timeout — matter.js PeerMessageMissingError (PeerCommunicationError.ts:57), raised by MessageExchange.ts:854-856.
func (*PeerMessageMissingError) Error ¶
func (e *PeerMessageMissingError) Error() string
func (*PeerMessageMissingError) Is ¶
func (e *PeerMessageMissingError) Is(target error) bool
Is makes the error match ErrTransient and a *PeerUnresponsiveError target, as the matter.js class extends PeerUnresponsiveError.
type PeerUnresponsiveError ¶
type PeerUnresponsiveError struct {
// Waited is how long the exchange waited for the acknowledgement.
Waited time.Duration
}
PeerUnresponsiveError is a reliable message the peer never acknowledged within MaxTransmissions transmissions and the final wait — matter.js PeerUnresponsiveError (PeerCommunicationError.ts:40-46), raised by MessageExchange.ts:763-765.
func (*PeerUnresponsiveError) Error ¶
func (e *PeerUnresponsiveError) Error() string
func (*PeerUnresponsiveError) Is ¶
func (e *PeerUnresponsiveError) Is(target error) bool
Is makes the error match ErrTransient.
type ProtocolHandler ¶
ProtocolHandler handles an exchange the peer opened: x is the new exchange, first its first message, already taken by x — acknowledged as x acknowledges any message, and not returned by Exchange.Next, which waits for the message after it. It is matter.js ProtocolHandler.onNewExchange (packages/protocol/src/protocol/ProtocolHandler.ts:22-23 at 0ceb202d). It runs on a goroutine of its own, one per exchange, so the receive path never waits for it; the exchange is closed when it returns, if the handler did not close it.
type ReceiveOptions ¶
type ReceiveOptions struct {
// Timeout overrides the computed wait; 0 computes it from
// [MaxPeerResponseTime].
Timeout time.Duration
// ExpectedProcessingTime enters the computed wait; 0 is
// [DefaultExpectedProcessingTime].
ExpectedProcessingTime time.Duration
// SuppressPeerLoss waives the peer-loss report for this wait.
SuppressPeerLoss bool
}
ReceiveOptions configures Exchange.Next — matter.js ExchangeReceiveOptions (MessageExchange.ts:134-148).
type SecureSessionConfig ¶
type SecureSessionConfig struct {
// ID is the local session id ([Manager.AllocateSessionID]).
ID uint16
// Addr is the peer's address.
Addr *net.UDPAddr
// Channel carries the keys, the node ids and the peer's session id.
Channel channel.Config
// PeerParameters is the peer's parameters: the fallbacks overlaid by
// what it reported (SessionParameters.ts:42-81).
PeerParameters sessionparams.Parameters
// ReportedParameters is what the peer reported, nil for nothing.
ReportedParameters *sessionparams.Parameters
// CaseAuthenticatedTags are the session's CATs (CASE only).
CaseAuthenticatedTags []uint32
// AttestationChallenge is the third 16 bytes of the session keys.
AttestationChallenge []byte
// SuppressPeerLoss keeps the session open when an exchange fails
// instead of reporting the peer lost — matter.js NodeSession
// suppressPeerLoss (NodeSession.ts:316-318), set for the PASE session
// of a commissioning.
SuppressPeerLoss bool
// Resumed marks a session from Sigma2_Resume.
Resumed bool
// FabricIndex is our fabric index of a CASE session, 0 for PASE: with
// the channel's peer node id it is the session's peer address
// (NodeSession.ts:408-413), the key of [Manager.HandlePeerLoss].
FabricIndex uint8
}
SecureSessionConfig describes a session a handshake established.
type SendOptions ¶
type SendOptions struct {
// ExpectAckOnly makes a reply that carries data in place of a
// standalone ack an [ErrUnexpectedMessage].
ExpectAckOnly bool
// ExpectedProcessingTime is the peer's processing time for the final
// wait after the last retransmission; 0 is
// [DefaultExpectedProcessingTime].
ExpectedProcessingTime time.Duration
// SuppressAck sends without requesting an acknowledgement (a
// CloseSession or Busy StatusReport).
SuppressAck bool
// DisableMRP sends once, without retransmission and without waiting
// for the acknowledgement.
DisableMRP bool
// MaxRetransmissions caps the transmissions; 0 is [MaxTransmissions],
// a negative value is unlimited.
MaxRetransmissions int
// MaxRetransmissionTime caps each backoff, never below the peer's idle
// interval; 0 is no cap.
MaxRetransmissionTime time.Duration
// InitialRetransmissionTime is added to every backoff.
InitialRetransmissionTime time.Duration
// SuppressPeerLoss waives the peer-loss report for this send.
SuppressPeerLoss bool
// AckWaitAbort, once closed, ends only the waits for the
// acknowledgement and for retransmissions: the message is still
// transmitted once, even when it closed before, and Send then returns
// nil; the message stays unacknowledged for [Exchange.Close]. ctx —
// matter.js's abort — still stops the transmission. Mirrors matter.js
// ExchangeSendOptions.ackWaitAbort (MessageExchange.ts:125-130).
AckWaitAbort <-chan struct{}
}
SendOptions configures Exchange.Send — matter.js ExchangeSendOptions (MessageExchange.ts:82-132).
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session is one session of the controller with a peer: the unsecured session a PASE or CASE handshake runs on, or a secure session the handshake established. It is safe for concurrent use.
func (*Session) ActiveTimestamp ¶
ActiveTimestamp is the time of the last message received from the peer on the session — matter.js Session.activeTimestamp (session/Session.ts:61-65, updated by notifyActivity :141-147), the order of Peer.newestSession (peer/Peer.ts:581-601). A secure session starts at its creation time (Session.ts:119-121 with NodeSession.ts:119); the unsecured session is zero until the peer's first message.
func (*Session) AttestationChallenge ¶
AttestationChallenge is the attestation challenge the session keys yielded (the third 16 bytes of the key schedule; NodeSession.ts:88).
func (*Session) CaseAuthenticatedTags ¶
CaseAuthenticatedTags are the session's CASE Authenticated Tags (nil on PASE) — matter.js NodeSession caseAuthenticatedTags.
func (*Session) Close ¶
func (s *Session) Close()
Close drops the session without telling the peer: its exchanges are closed with ErrSessionClosed, it leaves the manager's tables and its keys are dropped. Manager.CloseSession tells the peer first. It is idempotent.
func (*Session) Closing ¶
func (s *Session) Closing() <-chan struct{}
Closing is closed once the session begins to close — Session.Close, Manager.CloseSession or a peer loss — matter.js Session.closing (Session.ts:70, emitted at :299), which a peer watches to drop the session (Peer.ts:169-174).
func (*Session) CreatedAt ¶
CreatedAt is when the session was established — matter.js Session.createdAt, the cutoff SessionManager.#handlePeerLoss compares (SessionManager.ts:690-692 at 0ceb202d).
func (*Session) FabricIndex ¶
FabricIndex is our fabric index of a CASE session, 0 on the unsecured and on a PASE session — the fabric half of matter.js NodeSession.peerAddress (NodeSession.ts:408-413).
func (*Session) HandlePeerLoss ¶
HandlePeerLoss gives the session up because the peer is gone: it is marked lost, the manager's PeerLost hook is called, every exchange on it is aborted with cause, and it is closed without a CloseSession on the wire. Mirrors matter.js NodeSession.ts:311-314 (handlePeerLoss) and :349-352 with Session.ts:318-331 (initiateForceClose). It is a no-op on a session already closed or lost.
func (*Session) ID ¶
ID is the local session id: UnsecuredSessionID for the unsecured session, the id the peer addresses its messages to otherwise.
func (*Session) IsInbound ¶
IsInbound reports whether the session is an unsecured session the peer opened with an initiating message — the session a CASE responder runs on (matter.js ExchangeManager.ts:261-264).
func (*Session) IsPeerActive ¶
IsPeerActive reports whether the peer sent a message within its active threshold — matter.js Session.ts:149-151. The unsecured session of an initiator starts idle (UnsecuredSession.ts:30), a secure one active (NodeSession.ts:119).
func (*Session) IsPeerLost ¶
IsPeerLost reports whether the session was given up because the peer is gone or closed it — matter.js NodeSession.isPeerLost (NodeSession.ts:320-322). A lost session is closing: no CloseSession goes to the peer.
func (*Session) NodeID ¶
NodeID is our node id on the session: the ephemeral initiator node id on an unsecured session we opened, the operational node id on a CASE session and 0 on a PASE session and on an unsecured session the peer opened.
func (*Session) Parameters ¶
func (s *Session) Parameters() sessionparams.Parameters
Parameters is the peer's session parameters as the session uses them: the fallbacks overlaid by what the peer reported — matter.js Session.ts:204-227 (parameters).
func (*Session) PeerNodeID ¶
PeerNodeID is the peer's operational node id: 0 on the unsecured and on a PASE session.
func (*Session) PeerSessionID ¶
PeerSessionID is the peer's session id for this session.
func (*Session) ReportedParameters ¶
func (s *Session) ReportedParameters() *sessionparams.Parameters
ReportedParameters is what the peer reported in the handshake, nil when it reported nothing — matter.js NodeSession reportedSessionParameters.
func (*Session) SetAddr ¶
SetAddr moves the session to the peer's address addr: every later transmission on the session goes there, an exchange with an address override aside — matter.js `session.channel.networkAddress = address`, the in-place migration of PeerAddressMonitor.ts:243 and :170 (packages/protocol/src/peer/, 0ceb202d). A nil addr is ignored.
func (*Session) SetTimingParameters ¶
func (s *Session) SetTimingParameters(p sessionparams.Parameters)
SetTimingParameters replaces the peer's MRP intervals with those p states, the fallback for each one it does not — matter.js Session.ts:249-254 (set timingParameters), which the handshakes call when the responder's parameters arrive (PaseClient.ts:163-165, CaseClient.ts:245-247).
type StatusReport ¶
type StatusReport struct {
GeneralCode uint16
ProtocolID uint32
ProtocolCode uint16
ProtocolData []byte
}
StatusReport is a Secure Channel StatusReport body: general code, protocol id, protocol code and optional protocol data, little-endian — the layout transport/mrp.EncodeStatusReport writes.
func DecodeStatusReport ¶
func DecodeStatusReport(payload []byte) (StatusReport, bool)
DecodeStatusReport splits a StatusReport body. Mirrors matter.js packages/protocol/src/protocol/ProtocolStatusMessage.ts:50-66 (decodeInternal) at 0ceb202d, which SecureChannelStatusMessageSchema.ts:14 instantiates for the Secure Channel; ProtocolID carries the vendor id in its upper 16 bits as on the wire. ok is false for a body shorter than 8 bytes.
type StatusReportError ¶
type StatusReportError struct {
Report StatusReport
}
StatusReportError is a StatusReport the peer answered with that is not Success — matter.js ChannelStatusResponseError (SecureChannelMessenger.ts:32-52, thrown at :234-259). It is transient.
func (*StatusReportError) Error ¶
func (e *StatusReportError) Error() string
func (*StatusReportError) Is ¶
func (e *StatusReportError) Is(target error) bool
Is makes the error match ErrTransient.
type SystemClock ¶
SystemClock is the Clock of the time package; it is clock.System.
type Timer ¶
Timer is a timer [Clock.AfterFunc] started; it is clock.Timer.
type UnexpectedMessageError ¶
type UnexpectedMessageError struct {
Message *Message
}
UnexpectedMessageError is the message that answered a send expecting an acknowledgement only — matter.js UnexpectedMessageError (protocol/errors.ts:22-28) with its receivedMessage, thrown at MessageExchange.ts:815-817, which InteractionMessenger.ts:1155-1161 inspects. It matches ErrUnexpectedMessage.
func (*UnexpectedMessageError) Error ¶
func (e *UnexpectedMessageError) Error() string
func (*UnexpectedMessageError) Is ¶
func (e *UnexpectedMessageError) Is(target error) bool
Is makes the error match ErrUnexpectedMessage.