← RFC

Design note — relay-abuse mitigation ("QSL hunters" and the selfish-flooder class)

Status: Design note / concept. Date: 2026-06-16. Origin: Matt (KD4HME), from real North-Georgia/Atlanta experience.

Captures a mitigation concept for semi-malicious nodes that abuse shared relaying. Not an implementation plan yet — it develops the idea, shows why Loomwave's architecture is well-positioned for it, and names the hard parts (chiefly: a shared blocklist is itself an attack surface). Relates to red-team F11 (slot exhaustion), F13 (Sybil), F12 (jamming); to mac-spec.md §9(downlink/relay governance); and to the future map/activity aggregator ([operational-vision-note.md`](operational-vision-note.md)).

1. The problem

QSL hunters. A ham-radio habit ("collecting QSLs" = confirmations of contact) imported into mesh: a node sets its hop limit to max and broadcasts to see how far it can be heard and who answers. In a flat flooding mesh (Meshtastic) every relay rebroadcasts, so a node states away on a high site hears the hunter and relays it onward — and the message floods into a dense, far-away metro (Atlanta) that has no recipient for it and no relationship to the sender. Multiplied across hunters, this is a broadcast-storm amplifier: the channel fills with long-haul traffic of zero local value. It is semi-malicious — usually selfishness or misconfiguration, not an attack — but the channel damage is real, and flooding has no authority that can decide to stop carrying it.

This is one instance of a broader selfish-flooder class: max-hop broadcasters, RANGE_TEST spammers, chatty/high-rate nodes, and "relay everything" misconfigurations. They all share a signature: airtime consumed ≫ value delivered to a local recipient.

2. Why Loomwave is structurally positioned to fix this (Meshtastic isn't)

Flooding has no one in charge: hop-limit is set by the sender (the abuser), and every node independently rebroadcasts. There is no natural place to observe, decide, or enforce.

Loomwave already has the levers, because it is coordinator/INFRA-mediated: - Coordinators see everything in their cell — they schedule it. That makes them the natural observer and enforcement point (no new vantage needed). - The data plane is admission-controlled — a node must register to a cell to get a slot. The coordinator can already deny, deprioritize, or rate-limit a node's slots. - Relaying is governed, not universal — REPEATER / CLIENT_RELAY are explicit roles, and cross-cell / backhaul forwarding already passes a locality filter (mac-spec.md §9`: only inject traffic for a local recipient). The QSL-hunter pattern is exactly "traffic with no local destination propagating widely" — the locality-filter principle, extended from backhaul to RF cross-cell relay, directly kills it. - The INFRA backbone is a sharing channel — LSAs already propagate among coordinators; reputation can ride the same path.

So the mechanism is less "invent a new subsystem" and more "apply the governance Loomwave already has to relay, and add a reputation layer."

3. Detection — what flags an abuser, and where

Signal Caught by
Airtime share — node consumes a disproportionate fraction of cell airtime coordinator (local)
Reach-without-recipient — its broadcasts are relayed across cells but never delivered to a local member (low "usefulness ratio") coordinator + backbone
Geographic implausibility — traffic travels far with no local dst (the "states-away-into-Atlanta" pattern) aggregator (wide-area geo view)
Excessive hop/reach requests beyond local relevance coordinator
Rate / duty-cycle beyond a fair-share budget coordinator

Two tiers, by design: - Local (coordinator, works offline): airtime-share, fair-use, usefulness-ratio — a single coordinator can detect a node hogging its cell with no LoRa-internet dependency. This must keep working with zero infrastructure (goal #4). - Wide-area (aggregator, optional enhancement): the cross-network, geo-aware patterns a single coordinator can't see (a hunter whose traffic is relayed across ten cells). The aggregator has the data to spot the long-haul-no-local-value pattern that defines the QSL-hunter problem.

4. Enforcement — graduated and reversible (it's usually misconfiguration)

A ladder, not a binary ban — favor the gentlest step that protects the channel: 1. Don't propagate widely. Cap cross-cell / multi-hop relay for traffic with no local dst (locality filter for RF). This alone solves the QSL-hunter case — the hunter is still heard locally, just not flooded statewide. 2. Rate-limit repeats of the node's broadcasts (carry 1 of N; cap its airtime share). 3. Deprioritize its scheduled slots / contention priority under load. 4. Deny admission to the scheduled plane (it can still use the contention plane at low priority). 5. Block (last resort, confirmed/egregious).

All steps decay (flags expire) and are operator-overridable. Because the cause is often a misconfigured radio, the default should notify (so the owner can fix it) before it escalates.

5. Sharing the intelligence (the interesting part — and the risky one)

The goal: a coordinator that identifies an abuser shouldn't make every other node rediscover it.

The hard part — a blocklist is itself an attack surface. A naive shared blocklist lets a malicious or buggy coordinator frame an innocent node = a censorship / DoS vector (worse than the original abuse). So the reputation layer needs the same discipline as a trust system: - Signed claims — every advisory is signed by its issuing coordinator; the aggregator signs its published list. No anonymous accusations. - Corroboration — act on a flag only when multiple independent coordinators agree (reuse the election-corroboration pattern, routing-spec.md §5.2`), with thresholds — one coordinator's word rate-limits locally at most, never network-bans. - Decay + appeal — flags expire; behavior is re-evaluated; a reformed/fixed node recovers. - Local override — a coordinator always keeps final say in its own cell; the shared list is advice, not a mandate. Preserves decentralization. - Keep it optional — like all backhaul, the aggregator/shared-reputation layer is an enhancement, never a dependency. Local fair-use enforcement must work with no internet (goal #4). The aggregator makes detection smarter, not required.

6. Risks / open questions

7. How it connects to existing work

8. Suggested next steps (when prioritized)

  1. Sim it (cheap, high value): add a "selfish-flooder" node to the adversarial sim batch (S6) — measure channel damage in flood vs. Loomwave-with-locality-filter; quantify how much step-1 alone recovers.
  2. Spec the locality filter for RF relay (enforcement step 1) — the highest-leverage, lowest-risk piece, and it needs no reputation system or aggregator.
  3. Threat-model the shared-reputation layer before specifying it (the blocklist-as-attack-surface pass).
  4. Defer the aggregator advisory service to the map/activity-site work; design the signed-advisory format alongside it.