Source File
multipath_manager.go
Belonging Package
github.com/tmc/go-iroh/internal/qng
package quicimport ()// multipathManager records the read-side state of QUIC multipath// (draft-ietf-quic-multipath) paths keyed by protocol.PathID. It mirrors the// recovery-irrelevant subset of n0ext/reference/paths.rs that the receive// pipeline updates from incoming PATH_STATUS_*, PATH_ABANDON, MAX_PATH_ID,// PATHS_BLOCKED and PATH_CIDS_BLOCKED frames.//// Stage 4c is read side only: the manager records what the peer tells us. It// does NOT schedule sends, open paths, or issue path connection IDs — that is// Stage 5. Until then no second path is opened on the send side, so the// per-path packet-number state in the ackhandler only ever holds PathIDZero;// the manager is the place that accumulates the peer's path signaling so the// send side can consume it later.type multipathManager struct {paths map[protocol.PathID]*multipathState// peerMaxPathID is the largest PathID the peer will accept, as raised by// MAX_PATH_ID frames. It gates how many paths we may open (Stage 5).// paths.rs tracks the analogous remote max path id; a MAX_PATH_ID frame// that does not increase it is ignored.peerMaxPathID protocol.PathIDpeerMaxPathIDSet bool// peerPathsBlocked / peerPathCIDsBlocked record the most recent// informational PATHS_BLOCKED / PATH_CIDS_BLOCKED signaling from the peer.// They are advisory: the peer wants more paths / more path CIDs than we// have granted. Stage 4c only records them.peerPathsBlocked *protocol.PathIDpeerPathCIDsBlocked map[protocol.PathID]uint64}// pathStatus is the QUIC-MULTIPATH path status carried by PATH_STATUS_AVAILABLE// and PATH_STATUS_BACKUP frames. It mirrors reference/paths.rs PathStatus// (paths.rs:1026-1038); Available is the zero value, matching the Rust default.type pathStatus uint8const (pathStatusAvailable pathStatus = iotapathStatusBackup)// pathStatusState holds the remote-set status for a path and the highest// status sequence number seen, mirroring reference/paths.rs PathStatusState// (paths.rs:977-1018). The receive side only consumes the remote status; the// local status is a Stage 5 send-side concern.type pathStatusState struct {// remoteStatus is the status last set by the peer.remoteStatus pathStatus// remoteSeq is the status_seq_no of the frame that set remoteStatus.remoteSeq uint64// remoteSet reports whether the peer has set the status at least once;// before that there is no valid remoteSeq to compare against.remoteSet bool}// remoteUpdate applies a received PATH_STATUS_AVAILABLE/PATH_STATUS_BACKUP// frame. It mirrors PathStatusState::remote_update (paths.rs:990-1001): a// non-increasing sequence number is ignored, so reordered or replayed status// frames cannot move the status backwards. It reports whether the status was// updated.func ( *pathStatusState) ( pathStatus, uint64) bool {// paths.rs:993-995: if self.remote_status.is_some_and(|(curr, _)| curr >= seq) { return }if .remoteSet && .remoteSeq >= {return false}.remoteStatus =.remoteSeq =.remoteSet = truereturn true}// multipathState is the per-path read-side state.type multipathState struct {status pathStatusState// abandoned reports whether the peer sent a PATH_ABANDON for this path.// Stage 4c records it without tearing down send state (Stage 5).abandoned bool// abandonErrorCode is the error code carried by the peer's PATH_ABANDON.abandonErrorCode uint64}// newMultipathManager returns a multipathManager seeded with the PathIDZero// entry, the only path that exists until Stage 5 opens additional paths. The// initial path is always available, matching the Rust default status.func newMultipathManager() *multipathManager {return &multipathManager{paths: map[protocol.PathID]*multipathState{protocol.PathIDZero: {},},peerPathCIDsBlocked: make(map[protocol.PathID]uint64),}}// pathState returns the state for pid, creating it on first reference. The peer// can signal status for a path before the send side opens it, so the read-side// manager admits any pid the frame parser let through (the parser already gates// on multipathNegotiated()).func ( *multipathManager) ( protocol.PathID) *multipathState {, := .paths[]if ! {= &multipathState{}.paths[] =}return}// handleStatusBackup records a PATH_STATUS_BACKUP frame. It reports whether the// remote status changed (the seq was increasing).func ( *multipathManager) ( protocol.PathID, uint64) bool {return .pathState().status.remoteUpdate(pathStatusBackup, )}// handleStatusAvailable records a PATH_STATUS_AVAILABLE frame. It reports// whether the remote status changed (the seq was increasing).func ( *multipathManager) ( protocol.PathID, uint64) bool {return .pathState().status.remoteUpdate(pathStatusAvailable, )}// handleAbandon records a PATH_ABANDON frame from the peer.func ( *multipathManager) ( protocol.PathID, uint64) {:= .pathState().abandoned = true.abandonErrorCode =}// handleMaxPathID records a MAX_PATH_ID frame, raising the largest PathID the// peer will accept. A frame that does not increase the value is ignored,// matching the monotonic semantics of QUIC's MAX_* frames.func ( *multipathManager) ( protocol.PathID) {if !.peerMaxPathIDSet || > .peerMaxPathID {.peerMaxPathID =.peerMaxPathIDSet = true}}// peerMax returns the largest PathID the peer will accept and whether the peer// has raised its initial transport-parameter limit with a MAX_PATH_ID frame.func ( *multipathManager) () (protocol.PathID, bool) {return .peerMaxPathID, .peerMaxPathIDSet}// handlePathsBlocked records a PATHS_BLOCKED frame: the peer wants to open more// paths than its current max path id allows. Informational in Stage 4c.func ( *multipathManager) ( protocol.PathID) {:=.peerPathsBlocked = &}// handlePathCIDsBlocked records a PATH_CIDS_BLOCKED frame: the peer wants more// connection IDs for pid than we have issued. Informational in Stage 4c.func ( *multipathManager) ( protocol.PathID, uint64) {.peerPathCIDsBlocked[] =}
![]() |
The pages are generated with Golds v0.8.4. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |