loom

module
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2026 License: Apache-2.0

README

loom

loom is a distributed network traffic generation and measurement system for Linux. It weaves many independent traffic flows — raw protocols and realistic application behaviors — across many machines, on a schedule you define, and measures what happens in real time.

Think of it as iperf when you want a quick number, and a programmable traffic fabric when you don't: a measured client→server throughput test, or a declarative scenario driving dozens of agents with overlapping, randomized flows.

Measure throughput between two hosts (the iperf-style test). Run an agent on each host, then drive a flow between them from anywhere — both sides are measured:

# on the server host and the client host: run the agent
$ LOOMD_ADDR=:9551 loomd

# from your workstation: drive a 1 Gbps UDP flow client → server for 10s
$ cat > test.yaml <<'EOF'
scenario: quick-test
endpoints: [ { name: client }, { name: server } ]
timeline:
  - name: blast
    flow: { kind: udp, rate: 1Gbps, packet_size: 1400 }
    from: client
    to: server
    start: 0s
    stop: { after: 10s }
EOF
$ loomctl run -f test.yaml -a 'client=10.0.0.1:9551,server=10.0.0.2:9551'
[14:03:01] tx 0.99 Gbps  rx 0.99 Gbps  (2 flows)
...
--- summary --- elapsed 10.1s
  tx 1.24 GB   avg 0.99 Gbps
  rx 1.24 GB   avg 0.99 Gbps

The run ends as soon as the flow finishes (not at the horizon); add --per-flow for a per-flow breakdown — handy when flows take different network paths.

Or a quick one-host check — generate, pace, and measure a flow locally with no receiver (the discard datapath drops after accounting):

$ loom run --rate 50Mbps --duration 5s
[   1.0s]   49.98 Mbps   4459 pkts   5.95 MB
--- summary ---  sent 29.7 MB in 22300 packets, avg 49.9 Mbps

Why loom

  • One tool, two modes. A single-flow CLI for quick tests, and a control plane that runs multi-point scenarios across a fleet of agents.
  • Realistic, not just packet-blasting. Raw UDP/TCP today; HTTPS/VoIP/SSH/ Prometheus/FTP behavior emulation on the roadmap.
  • Fast where it counts. A zero-copy data plane with pluggable backends — kernel sockets by default, AF_XDP for line-rate, DPDK to come — behind one interface, so speed is a backend choice, not a rewrite.
  • Measurement-first. Streaming and end-of-run throughput, latency, jitter, and loss; one-way delay and NIC hardware timestamping are designed in.
  • Reproducible. Seeded scenarios replay identically, so you can compare runs and catch regressions.

Get started

You are… Start here
New to loom Getting StartedCore Concepts
Evaluating / an expert ArchitecturePerformance
Deploying it Deployment
Looking something up Reference · Scenario schema

The full manual lives in docs/.

Install

curl -fsSL https://raw.githubusercontent.com/bgrewell/loom/main/scripts/install.sh | bash

Installs loom, loomd, and loomctl — prebuilt binaries when available, else built from source. upgrade.sh and uninstall.sh are the counterparts; tuning and options are in scripts/README.md.

Or with the Go toolchain:

go install github.com/bgrewell/loom/cmd/loom@latest     # the CLI
go install github.com/bgrewell/loom/cmd/loomd@latest    # the agent
go install github.com/bgrewell/loom/cmd/loomctl@latest  # the controller

Linux only for now. See Getting Started for a guided first run.

Status

Active development. The architecture is settled and the single-host engine, distributed control plane, telemetry, and an AF_XDP datapath are in; application emulations and a web dashboard are next. Design decisions are recorded as ADRs in DECISIONS.md; the plan is in docs/roadmap.md.

License

Apache-2.0.

Directories

Path Synopsis
api
cmd
loom command
Command loom is the loom CLI — the primary human interface to the traffic generation & measurement system.
Command loom is the loom CLI — the primary human interface to the traffic generation & measurement system.
loomctl command
Command loomctl is the loom controller — it loads a scenario and drives it across agents (DESIGN.md §11).
Command loomctl is the loom controller — it loads a scenario and drives it across agents (DESIGN.md §11).
loomd command
Command loomd is the loom agent — the only component that touches the wire.
Command loomd is the loom agent — the only component that touches the wire.
Package control implements the loom.v1.Control gRPC service — the controller<->agent control plane (DESIGN.md §8).
Package control implements the loom.v1.Control gRPC service — the controller<->agent control plane (DESIGN.md §8).
Package controller orchestrates a scenario across agents: it resolves the endpoints each event runs between, plans the timeline, and at each fire wires a receiver and a sender on the right agents and starts them.
Package controller orchestrates a scenario across agents: it resolves the endpoints each event runs between, plans the timeline, and at each fire wires a receiver and a sender on the right agents and starts them.
core
accounting
Package accounting turns hot-path byte/packet counters into windowed throughput rates.
Package accounting turns hot-path byte/packet counters into windowed throughput rates.
app
Package app is the application-traffic framework: real protocol engines (VoIP, HTTP, video) packaged as clients and servers the agent can drive with its existing flow lifecycle.
Package app is the application-traffic framework: real protocol engines (VoIP, HTTP, video) packaged as clients and servers the agent can drive with its existing flow lifecycle.
app/httpx
Package httpx is loom's real web-traffic engine, registered as app "http": a genuine HTTP/1.1 + TLS 1.3 (+ optional HTTP/2) client and the HTTPOrigin server that is loom's own far end for web and video flows (design real-app-traffic §2.10 — the loom-owned origin, not nginx).
Package httpx is loom's real web-traffic engine, registered as app "http": a genuine HTTP/1.1 + TLS 1.3 (+ optional HTTP/2) client and the HTTPOrigin server that is loom's own far end for web and video flows (design real-app-traffic §2.10 — the loom-owned origin, not nginx).
app/vidstream
Package vidstream is loom's ABR video player model, registered as app "video" (design real-app-traffic §2.10).
Package vidstream is loom's ABR video player model, registered as app "video" (design real-app-traffic §2.10).
app/voip
Package voip is loom's real-media VoIP engine: a bidirectional RTP/RTCP session over an injected netpath.Network with live ITU-T G.107 quality scoring.
Package voip is loom's real-media VoIP engine: a bidirectional RTP/RTCP session over an injected netpath.Network with live ITU-T G.107 quality scoring.
components
Package components bundles the pluggable registries (datapath/generator/ scheduler/payload/netpath/app) into one injectable value (ADR-0022), so a flow builder or an agent depends on an explicit Components rather than reaching into global singletons.
Package components bundles the pluggable registries (datapath/generator/ scheduler/payload/netpath/app) into one injectable value (ADR-0022), so a flow builder or an agent depends on an explicit Components rather than reaching into global singletons.
contract
Package contract holds shared conformance checks that every implementation of a core interface must pass.
Package contract holds shared conformance checks that every implementation of a core interface must pass.
datapath
Package datapath is the packet-I/O backend abstraction.
Package datapath is the packet-I/O backend abstraction.
emul
Package emul is loom's application-behavior emulation engine: realistic traffic *shapes* (VoIP, HTTPS browsing, Prometheus, SSH) compiled to one shared behavior-script primitive and run over any datapath.
Package emul is loom's application-behavior emulation engine: realistic traffic *shapes* (VoIP, HTTPS browsing, Prometheus, SSH) compiled to one shared behavior-script primitive and run over any datapath.
flow
Package flow is the atomic unit of traffic: a generator paced by a scheduler, sent over a datapath, accounted, and bounded by a stop condition.
Package flow is the atomic unit of traffic: a generator paced by a scheduler, sent over a datapath, accounted, and bounded by a stop condition.
frameaddr
Package frameaddr resolves the layer-2/3 addressing a raw datapath (AF_XDP) needs to emit deliverable frames: the local NIC's MAC and IPv4, and the peer's MAC for a target on the same L2 segment.
Package frameaddr resolves the layer-2/3 addressing a raw datapath (AF_XDP) needs to emit deliverable frames: the local NIC's MAC and IPv4, and the peer's MAC for a target on the same L2 segment.
generator
Package generator produces a flow's traffic content: it decides what bytes go in each packet, using a payload source.
Package generator produces a flow's traffic content: it decides what bytes go in each packet, using a payload source.
latency
Package latency measures round-trip latency with typed results and an interval sampling model.
Package latency measures round-trip latency with typed results and an interval sampling model.
log
Package log provides the two halves of loom's logging model (DESIGN.md §6): a lock-free, non-blocking hot-path event Ring drained off the data plane, and an async leveled Logger for control/diagnostic output.
Package log provides the two halves of loom's logging model (DESIGN.md §6): a lock-free, non-blocking hot-path event Ring drained off the data plane, and an async leveled Logger for control/diagnostic output.
metrics
Package metrics is loom's application results plane: typed quality snapshots (VoIP MOS, HTTP timings, video QoE) that application engines expose through one tiny seam.
Package metrics is loom's application results plane: typed quality snapshots (VoIP MOS, HTTP timings, video QoE) that application engines expose through one tiny seam.
netpath
Package netpath provides connection-oriented network access (net.Conn / net.PacketConn semantics) as an injectable component: kernel stack, UDP-over-datapath, gVisor-over-datapath, or in-memory test loopback.
Package netpath provides connection-oriented network access (net.Conn / net.PacketConn semantics) as an injectable component: kernel stack, UDP-over-datapath, gVisor-over-datapath, or in-memory test loopback.
netpath/dgram
Package dgram is a UDP-only netpath.Network that encodes real IPv4+UDP headers into the frames of a raw-L3 datapath (datapath.Capabilities.RawL3): every WriteTo emits a complete, checksum-correct IP packet, and inbound frames are validated, demultiplexed by destination port, and delivered to the bound net.PacketConn.
Package dgram is a UDP-only netpath.Network that encodes real IPv4+UDP headers into the frames of a raw-L3 datapath (datapath.Capabilities.RawL3): every WriteTo emits a complete, checksum-correct IP packet, and inbound frames are validated, demultiplexed by destination port, and delivered to the bound net.PacketConn.
netstack
Package netstack is a userspace TCP/IP netpath backend: it wraps gVisor's pkg/tcpip (pure Go — no NET_ADMIN, no TUN, no netns) over loom's raw-L3 datapath frame contract, so TCP-based apps (HTTP/TLS, video) can ride a tunneled inner-IP packet lane that the kernel never sees.
Package netstack is a userspace TCP/IP netpath backend: it wraps gVisor's pkg/tcpip (pure Go — no NET_ADMIN, no TUN, no netns) over loom's raw-L3 datapath frame contract, so TCP-based apps (HTTP/TLS, video) can ride a tunneled inner-IP packet lane that the kernel never sees.
owd
Package owd estimates one-way delay with honest error bars.
Package owd estimates one-way delay with honest error bars.
payload
Package payload generates the bytes a flow sends.
Package payload generates the bytes a flow sends.
pump
Package pump is the data-plane inner loop: it draws packets from a generator, paces them with a scheduler, sends them over a datapath, and records them in accounting.
Package pump is the data-plane inner loop: it draws packets from a generator, paces them with a scheduler, sends them over a datapath, and records them in accounting.
quality/emodel
Package emodel scores conversational voice quality with the ITU-T E-model: narrowband per ITU-T G.107 (06/2015) and wideband per ITU-T G.107.1 (06/2019).
Package emodel scores conversational voice quality with the ITU-T E-model: narrowband per ITU-T G.107 (06/2015) and wideband per ITU-T G.107.1 (06/2019).
quality/gilbert
Package gilbert estimates packet-loss burstiness online.
Package gilbert estimates packet-loss burstiness online.
registry
Package registry provides a generic, concurrency-safe name→factory registry.
Package registry provides a generic, concurrency-safe name→factory registry.
report
Package report turns a flow's live counters into streaming interval reports and an end-of-run summary, emitted to a pluggable sink (human/json/...).
Package report turns a flow's live counters into streaming interval reports and an end-of-run summary, emitted to a pluggable sink (human/json/...).
rtp
Package rtp implements the RTP wire format and receiver statistics of RFC 3550 for loom's real-media traffic engines: header marshal/parse (RFC 3550 §5.1), a Packetizer whose SSRC, initial sequence number, and initial timestamp come from crypto/rand (§5.1, §8), synthetic G.711 and Opus payload sources (RFC 3551 §4.5.14 + ITU-T G.711; RFC 6716 §3.1 + RFC 7587), and ReceiverStats implementing RFC 3550 Appendix A exactly:
Package rtp implements the RTP wire format and receiver statistics of RFC 3550 for loom's real-media traffic engines: header marshal/parse (RFC 3550 §5.1), a Packetizer whose SSRC, initial sequence number, and initial timestamp come from crypto/rand (§5.1, §8), synthetic G.711 and Opus payload sources (RFC 3551 §4.5.14 + ITU-T G.711; RFC 6716 §3.1 + RFC 7587), and ReceiverStats implementing RFC 3550 Appendix A exactly:
rtp/codec
Package codec is the audio-codec table for loom's RTP engine: payload types and clock rates (RFC 3551 §6 static assignments; RFC 7587 §4.1 for Opus), per-ptime payload sizing, codec algorithmic delay, and the ITU-T G.113 Appendix I equipment-impairment parameters (Ie, Bpl) the G.107 E-model consumes.
Package codec is the audio-codec table for loom's RTP engine: payload types and clock rates (RFC 3551 §6 static assignments; RFC 7587 §4.1 for Opus), per-ptime payload sizing, codec algorithmic delay, and the ITU-T G.113 Appendix I equipment-impairment parameters (Ie, Bpl) the G.107 E-model consumes.
rtp/rtcp
Package rtcp implements the RTCP wire format and timing discipline for loom's real-media engines: sender and receiver reports, source description, and goodbye packets (RFC 3550 §6.4.1, §6.4.2, §6.5, §6.6), the extended report blocks loom uses for non-sender RTT and on-wire VoIP quality (RFC 3611 §4.4 Receiver Reference Time, §4.5 DLRR, §4.7 VoIP Metrics), compound-packet construction and parsing (RFC 3550 §6.1), RTP/RTCP demultiplexing on a shared port (RFC 5761 §4), the NTP timestamp discipline behind LSR/DLSR round-trip measurement (RFC 3550 §4, §6.4.1), and the randomized transmission-interval algorithm of RFC 3550 §6.3/Appendix A.7.
Package rtcp implements the RTCP wire format and timing discipline for loom's real-media engines: sender and receiver reports, source description, and goodbye packets (RFC 3550 §6.4.1, §6.4.2, §6.5, §6.6), the extended report blocks loom uses for non-sender RTT and on-wire VoIP quality (RFC 3611 §4.4 Receiver Reference Time, §4.5 DLRR, §4.7 VoIP Metrics), compound-packet construction and parsing (RFC 3550 §6.1), RTP/RTCP demultiplexing on a shared port (RFC 5761 §4), the NTP timestamp discipline behind LSR/DLSR round-trip measurement (RFC 3550 §4, §6.4.1), and the randomized transmission-interval algorithm of RFC 3550 §6.3/Appendix A.7.
scenario
Package scenario is the parsed model of a loom scenario file (docs/scenario-schema.md): endpoints, defaults, and a timeline of events with the value grammar (via core/units).
Package scenario is the parsed model of a loom scenario file (docs/scenario-schema.md): endpoints, defaults, and a timeline of events with the value grammar (via core/units).
scheduler
Package scheduler paces packets within a single flow (intra-flow rate control).
Package scheduler paces packets within a single flow (intra-flow rate control).
selection
Package selection resolves scenario endpoint selectors against the endpoint set: names, oneOf/allOf/any modes, and tag expressions like tags(all(10g, not(win))).
Package selection resolves scenario endpoint selectors against the endpoint set: names, oneOf/allOf/any modes, and tag expressions like tags(all(10g, not(win))).
stats
Package stats provides streaming measurement math — running mean/variance, jitter, and sequence-based loss/duplicate/reorder detection — as pure values with no global state.
Package stats provides streaming measurement math — running mean/variance, jitter, and sequence-based loss/duplicate/reorder detection — as pure values with no global state.
timeline
Package timeline turns a scenario's timeline into a schedule of "fires" — when each event (and each repeat instance) should start — and drives them in real time.
Package timeline turns a scenario's timeline into a schedule of "fires" — when each event (and each repeat instance) should start — and drives them in real time.
timesync
Package timesync computes the clock offset and round-trip delay between two hosts from the four-timestamp NTP exchange (DESIGN.md §10, ADR-0010).
Package timesync computes the clock offset and round-trip delay between two hosts from the four-timestamp NTP exchange (DESIGN.md §10, ADR-0010).
units
Package units parses the scenario value grammar — rates, sizes, durations, and "lo..hi" ranges of each (docs/scenario-schema.md).
Package units parses the scenario value grammar — rates, sizes, durations, and "lo..hi" ranges of each (docs/scenario-schema.md).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL