*English version: 2026-07-29-request-response-traffic-analysis.en.md*
Datum: 2026-07-29
Request/Response-Pakete sind '38,4 % des gesamten Traffics' im EU-Mesh. Wir
haben untersucht, woher sie kommen — in der Erwartung, Missbrauch zu finden. Es
ist kein Missbrauch. Es ist ein 'Fehlermuster, das fast jedes Polling-Script
teilt':
'Eine Abfrage, die nie beantwortet wird, flutet das gesamte Netz — für immer,
und der Sender kann es nicht bemerken.'
Zwischen '88 % und 94 %' der gesamten Request-Last (je nach Zählweise)
entfallen auf FLOOD-Requests, die nie eine Antwort bekommen. Einzelne
wiederholen sich seit über einer Woche alle 39 Sekunden, Tag und Nacht.
Wer ein Script betreibt, das Repeater abfragt: 'dieser Text handelt
wahrscheinlich von deinem Script', und der Fix sind drei Zeilen (§7).
| Zeitraum | 2026-07-22 – 2026-07-28 (6 Tage) |
| Aktive Observer | 367 |
| Abgedeckte IATA-Zonen | 57 |
| Pakete | 524 115 |
| Sichtungen | 13 413 130 |
| Aktive Nodes | 8 939 |
| davon Request/Response | 201 448 Pakete (38,4 %) |
'Messgrösse „Empfangs-Bytes„': Paketgrösse × Anzahl der Observer, die es
gehört haben. Das misst die 'Verbreitung' eines Pakets im Netz, nicht die
Sendezeit. Im Fenster wurden 30 MB einmal gesendet und dabei als 688 MB über
alle Empfänger gehört — Faktor 23. Echte Airtime lässt sich daraus nicht
ableiten, weil wir Retransmissions der Repeater nicht zählen, sondern nur, was
Observer hören.
| Route | Pakete | Sichtungen | Ø Empfänger pro Paket |
|---|---|---|---|
| FLOOD | 48 173 | 2 302 805 | '47,8' |
| TRANSPORT_FLOOD | 14 663 | 973 176 | 66,4 |
| DIRECT | 40 400 | 69 067 | '1,71' |
Ein FLOOD-Request erreicht ~28× so viele Funkgeräte wie ein DIRECT-Request.
MeshCore löst das bereits, und der Mechanismus funktioniert: Der erste Request
geht als FLOOD raus. 'Die Antwort bringt den Rückweg mit.' Ab dann pollt der
Client DIRECT, und die Kosten brechen ein. Gemessen an einem realen Paar
(``e4``→``24``):
| Tag | Requests | davon FLOOD |
|---|---|---|
| 07-23 | 96 | 55 % |
| 07-24 | 473 | '4 %' |
| 07-26 | 224 | '5 %' |
Und hier der Fehlerfall: 'Der Pfad wird aus der Antwort gelernt.' Keine
Antwort, kein Pfad. Kein Pfad, und der nächste Request geht wieder als FLOOD
raus. Für immer.
In dieser Schleife gibt es keinen Backoff und keinen Fehlerzustand. Aus Sicht des Clients ist nichts kaputt — er fragt einfach weiter. Aus Sicht des Netzes wird jeder einzelne Versuch an jedes Funkgerät in Reichweite jedes Repeaters gesendet.
Kriterium A — pro (Sender→Ziel)-Paar, Paar gilt als bedient ab 20 % Antwortrate:
| Kategorie | Paare | Requests | Sichtungen | Anteil | Empfangs-Bytes |
|---|---|---|---|---|---|
'FLOOD, unbeantwortet — Verschwendung' | 4 088 | 57 184 | 2 902 094 | '88,1 %' | '92 MB' |
| FLOOD, wird beantwortet | 579 | 7 528 | 313 377 | 9,5 % | 10,0 MB |
| DIRECT (Pfad gelernt) — günstig | 927 | 37 895 | 78 816 | 2,4 % | 1,9 MB |
Kriterium B — pro einzelnem Paket, Antwort muss binnen 10 min eintreffen:
| Kategorie | Pakete | Sichtungen | Anteil |
|---|---|---|---|
| FLOOD, keine Antwort | 60 695 | 3 104 090 | '94,2 %' |
| FLOOD, Antwort binnen 10 min | 1 488 | 121 096 | 3,7 % |
| DIRECT | 40 424 | 69 101 | 2,1 % |
Beide Partitionen summieren exakt auf 3 294 287 Sichtungen — die Kontrollsumme
aller ausgewerteten Request-Sichtungen. Kriterium A ist das konservativere, weil
dort ein Paar oberhalb der Schwelle *alle* seine Requests als beantwortet
gutgeschrieben bekommt. Belastbare Aussage: '88–94 %'.
'Die DIRECT-Zeile ist die gute Nachricht:' sauber konfiguriertes Polling ist
praktisch gratis — 37 895 Requests kosten zusammen 2,4 % der Last. Es geht
nicht darum, weniger zu pollen.
| Sender | Ziel | Requests | Antworten | Sichtungen | Req/Tag |
|---|---|---|---|---|---|
| ``27`` | ``f1`` | 5 040 | '0' | 471 240 | 840 |
| ``f4`` | ``19`` | 1 596 | 44 | 186 252 | 266 |
| ``bb`` | ``30`` | 2 007 | '0' | 90 501 | 335 |
| ``5d`` | ``98`` | 1 361 | '0' | 68 536 | 227 |
| ``7f`` | ``74`` | 699 | '0' | 49 879 | 117 |
| ``7f`` | ``b5`` | 678 | '0' | 48 154 | 113 |
| ``13`` | ``89`` | 825 | 25 | 39 419 | 138 |
| ``10`` | ``3e`` | 1 037 | '0' | 32 476 | 173 |
| ``69`` | ``1f`` | 1 053 | '0' | 27 111 | 176 |
``27``→``f1`` allein ist '14,4 % der gesamten FLOOD-Request-Last': 100 % FLOOD an
allen 7 Tagen, am 27.07. 2 238 Requests (alle 39 s), auf dieser Strecke keine
einzige Antwort.
'Der Defekt ist streckenspezifisch, nicht generell' — beide Seiten sind aktiv:
- ``f1`` sendet 114 Responses an 19 andere Peers, nur nie an ``27``. - ``27`` empfängt Antworten: 186 von ``ae``, dazu einzelne von 19 weiteren Peers.
Naheliegende Erklärung: ein veralteter Schlüssel oder ein Kontakt, der auf einer
Seite entfernt wurde — die MAC-Prüfung schlägt fehl, es kommt keine Antwort.
Das ist eine Vermutung — verifiziert ist nur, dass beide Seiten leben und nur
diese eine Strecke tot ist. Genau so etwas fällt niemandem auf, weil es
nirgends gemeldet wird.
'Alle 23 Top-Sender sind über alle 24 Stunden aktiv', mit einem Nacht/Tag-
Verhältnis von 0,82–1,64 — mehrere senden nachts *mehr* als tagsüber.
Die Intervalle sind Cron-Takte (Median-Abstand pro Paar, Anteil innerhalb ±10 %):
| Sender→Ziel | Takt | Pakete | im Takt |
|---|---|---|---|
| ``6e`` → 4 Ziele | '3600,0 s' (1 h) | je ~130 | '100 %' |
| ``c1``→``3c`` | 3600,1 s | 102 | 94 % |
``2a`` → '14 Ziele' | '~2123 s' (35 min) | je ~165 | 89–94 % |
| ``52``→``96`` | 318 s (5 min) | 1 205 | 94 % |
| ``f6``→``c1`` | 1825 s (30 min) | 212 | 92 % |
| ``dd``→``79`` | 1827 s | 198 | 77 % |
| ``af``→``3e`` | 621 s (10 min) | 645 | 75 % |
| ``e4``→``cc`` | 631 s | 214 | 69 % |
``2a`` arbeitet '14 Repeater im selben 35-Minuten-Zyklus' ab. Dieser Scanner
sendet durchgehend DIRECT und kostet das Netz fast nichts — der Beweis, dass
Scannen an sich nicht das Problem ist.
Der ``src_hash`` im Request ist nur '1 Byte' (Firmware: ``MeshCore.h:18``
``PATH_HASH_SIZE 1``; ``Mesh.cpp:488-489`` ``dest.copyHashTo`` / ``self_id.copyHashTo``
in ``createDatagram``). Bei 8 940 bekannten Nodes teilen sich im Schnitt '35
Nodes' einen Hash — 'eine eindeutige Identifikation des Senders ist daraus
nicht möglich.'
Was *möglich* ist: der erste Path-Hash eines Flood-Pakets ist der erste
weiterleitende Repeater, also ein Funknachbar des Senders. Wo dieser Pfad mit
2–3 Byte Hashes läuft, ist er 'eindeutig auflösbar':
| Sender | Heimat-Repeater | Standort |
|---|---|---|
| ``bb`` | 'DE-NW-Ratingen-1' (3012 Pk.) + 'DE-NW-Ratingen-3' (2771 Pk.) | 51.303, 6.866 — identische Koordinaten, 'ein Standort' |
| ``f4`` | 'NL-ZH-NIE-T1' (908 Pk.) | 51.965, 4.596 (Nieuwerkerk a/d IJssel) |
| ``91`` | 'NFN-910#59-01(DE.ERL)' (730) + 'MeschBertsRepeater' (153) | Erlangen |
| ``db`` | 'Paul_repeater' (387) + 'RAKpeater' (289) | 52.073, 5.089 — ein Standort (Utrecht) |
| ``13`` | 'NL-HEN-RP01-PerksMC.nl' (45) | 50.878, 6.005 |
'Diese Repeater sind nicht die Ursache.' Ein Heimat-Repeater ist die erste
Station, die das Paket weitergeleitet hat — der pollende Client steht *in seiner*
Funkreichweite. Das ist eine Nachbarschaftsbeziehung, keine Betreiberbeziehung.
Die Betreiber sind nützliche Ansprechpartner, weil sie das Gerät vor Ort
erkennen können, mehr nicht.
Für ``27`` (den grössten Verursacher) gibt es nur 1-Byte-Hops: Heimat-Repeater
beginnt mit ``ae`` (99,6 % konsistent — also 'ein' fester Repeater). ``ae`` ist
über zwei unabhängige Datenpfade belegt: erster Hop im Hinweg *und* der Peer,
der ``27`` mit Abstand am häufigsten antwortet (186 Responses, mehr als alle
anderen zusammen).
Der ``dest_hash`` ist ebenfalls nur 1 Byte, aber die Ziele sind besser greifbar:
Repeater senden Adverts, und ein Advert enthält den 'vollen' Pubkey. Damit
lassen sich Kandidaten filtern — plausibel ist nur, wer (a) Repeater oder
Roomserver ist und (b) dessen Advert in einer Zone gehört wird, in der auch die
Requests des Senders ankommen (≥10 % der Sender-Sichtungen).
Das reduziert 21–38 Namensvetter auf '0–6 echte Kandidaten':
| Paar | Kandidaten | Namen | |
|---|---|---|---|
| ``bb``→``30`` | '0' | *kein passender Repeater in der Region — siehe unten* | |
| ``7f``→``b5`` | 2 | Taacha🛩️Flugplatz, 📡 Loehne Horst | |
| ``5d``→``98`` | 3 | D-NW-E-TripleZ, Zwickau Repeateu, Calberlah | |
| ``13``→``89`` | 3 | DLW_REP01_LS, FF MCR \ | BE Moabit+ ☀, RockyBeach_P1_Solar |
| ``7f``→``74`` | 3 | HAS Suedwest JO50EB, Heltec Repeater Algermi, nhf-li9urian | |
| ``69``→``1f`` | 4 | DE-NW-ME-VBT10, NL-LTM-RP02, Relais Roxel, BE-PUT-ON1EE-31A | |
| ``f4``→``19`` | 5 | NL-ZH-LID-LaMo-RPT☀, NL-AME-SR-r-001☀️, NL-ZWL-MeshJoeWindeshei, NL-ZH-LID-MAAR-solar, WNS Romeo 2 🔱 | |
| ``27``→``f1`` | 6 | NL-OV-FIETS, NL-NH-SMT3-Rood (beide AMS+RTM), ipoac.nl zuid/oost, NL6812-16 Yagi SW 240, NL-ZEM-LM, NL-ENS-Stadsveld | |
| ``10``→``3e`` | 16 | zu breit gestreut, nicht aussagekräftig |
Zwei Lesehilfen:
- '``bb``→``30`` mit null Kandidaten ist der stärkste Befund der ganzen Tabelle.'
Kein Repeater mit Präfix ``30`` sendet Adverts, die in ``bb``'s Empfangszonen ankommen. Das Ziel ist mit hoher Wahrscheinlichkeit abgeschaltet oder aus der Region verschwunden — und ein Script fragt es seit Tagen 335× täglich per FLOOD ab. Das ist das Fehlermuster in Reinform.
- Bei ``27``→``f1`` sind 'NL-OV-FIETS' und 'NL-NH-SMT3-Rood' die besten
Treffer: nur diese beiden werden in ''*beiden*'' Hauptzonen des Senders (AMS und RTM) gehört.
'Das sind Kandidatenlisten, keine Zuordnungen.' Ein 1-Byte-Hash lässt keine
Beweisführung zu; die Liste sagt „einer von diesen“, nicht „dieser„.
Das Problem ist nicht das Pollen. Es ist das 'unbegrenzte Wiederholen im
vollen Takt gegen ein Ziel, das nie antwortet.'
1. 'Fehlschläge pro Ziel zählen.' Antwortet ein Ziel in den letzten N
Versuchen nicht (N = 3 reicht), hör auf, es im Normaltakt abzufragen.
2. 'Exponentiell zurückfahren, mit Deckel.' 5 min → 10 → 20 → … → einmal
täglich. Ein Ziel, das zurückkommt, wird binnen eines Tages wieder erfasst; ein totes kostet dann fast nichts.
3. 'Die tote Strecke protokollieren.' Hätte das Script gemeldet, dass es seit
5 000 Versuchen keine Antwort bekommt, wäre es in der ersten Woche aufgefallen.
Wenn dein Client tagelang FLOOD an dasselbe Ziel schickt, ist genau das das Signal: er hat nie eine Antwort erhalten, denn die Antwort ist es, die den Pfad installiert.
'Wir können nicht feststellen, wer du bist, und haben es nicht versucht.'Das Absenderfeld ist ein 1-Byte-Hash; bei ~8 900 bekannten Nodes teilen sich
im Schnitt 35 davon denselben Wert. * '''Inhalte bleiben verschlüsselt.''' Request- und Response-Nutzlasten sind zwischen den beiden Endpunkten verschlüsselt (curve25519). Ein passiver Beobachter hat keinen der beiden Schlüssel. Diese Auswertung nutzt ausschliesslich Paket-Header und Zeitstempel — nie Nutzlast. * '''Es geht um kein Fehlverhalten von Repeater-Betreibern.''' Wir können oft sagen, welcher Repeater ein Paket zuerst weitergeleitet hat. Das verortet einen Client irgendwo in dessen Funkreichweite — mehr nicht.
'Standortbestimmung' stützt sich ausschliesslich auf den ersten Path-Hash
über die 83,7 % der Sichtungen mit befülltem Pfad. Zwei Wege scheiden aus:
*0-Hop-Sichtungen* — ``sightings.path`` ist zu 16,2 % NULL (Feld nichtgeliefert), echte 0-Hop-Sichtungen machen nur 0,1 % aus. Die Datenmenge trägt
keine Aussage, und NULL darf nicht als 0 gelesen werden. * ''*Signalstärke*'' — die Observer mit dem stärksten Empfang von ``bb`` (RSSI −19,3) sehen das Paket bei ``min_hops`` 4–5. Gemessen wird der letzte Repeater, nicht der Sender.
'Antwortraten sind eine Untergrenze.' Responses laufen meist DIRECT
(Ø 1,36 Empfänger) und werden von den Observern schlecht gehört. Bei den
0-Antworten-Paaren stützt sich der Befund deshalb nicht auf die Zählung allein,
sondern auf den '100-%-FLOOD-Anteil über alle 7 Tage' — hätte der Sender je
eine Antwort erhalten, wäre er auf DIRECT umgestiegen.
'IATA-Codes' in diesem Dokument (RTM, AMS, BER, BWE, LEJ …) bezeichnen die
Zonen der *empfangenden Observer* — also wo ein Paket gehört wurde. Sie sind
nicht die Flood-Scope-Region des Pakets.
Wer dieselbe Auswertung für seine eigene Region fahren möchte: die Methodik
teilen wir gern.
Diese Seite steht in keinerlei Verbindung zum MeshCore Projekt https://meshcore.io.
Erstellt 2025 für die deutschsprachige MeshCore Community •
Impressum