Documentation
¶
Overview ¶
Package tracestitch joins connection records that belong to one logical flow across machines, and states how confident that join is.
The shape of the problem comes from the two-hop rig (SINGBOX-TRACE-DESIGN section 4.5). Inside one sing-box process the hops already share a log id, so the assembler links them itself. Across machines there is no shared id: hop 2 sees an inbound connection from hop 1's public address, and sing-box does not log the local port it dialled from, so the downstream record's SrcPort is not a join key and is never used here.
What is left is an inference, and the confidence is part of the answer rather than a footnote. An operator who can see what the stitcher could not decide is better served than one handed a confident wrong path.
Index ¶
Constants ¶
const DefaultWindow = 3 * time.Second
DefaultWindow is how long after an upstream record a downstream one may start and still be considered the same flow. Three seconds covers a chained dial over a slow link without stretching far enough to swallow the next connection to the same destination.
Variables ¶
This section is empty.
Functions ¶
func Stitch ¶
Stitch groups records into hop paths.
Every input record appears in exactly one returned path's RecordKeys, so a caller can stamp HopPathID onto records without a record belonging to two paths. A record that joined nothing is its own single-hop path with confidence none, which is a statement ("no downstream matched"), not a gap.
The input slice is not reordered or modified.
Types ¶
type Edge ¶
Edge is one declared chain edge, the skeleton every join hangs from. It mirrors store.LineChainDefinition{SourceLineUUID, TargetLineUUID}: only a chain an operator declared and the server compiled can carry a flow.
type Options ¶
type Options struct {
// Window bounds how long after the upstream record a downstream one may
// start. Zero or negative means DefaultWindow.
Window time.Duration
// NodePublicIPs maps node_id to the addresses that node dials out from.
// The downstream record's SrcIP has to be one of the upstream node's, which
// is the only physical evidence tying the two records together.
NodePublicIPs map[string][]string
}
Options tunes the join.