Zwiększ niezawodność i zasięg dostarczania prywatnych wiadomości poza ograniczenia routingu hop-by-hop
DTN (Delay-Tolerant Networking) to moduł overlay, który przechwytuje lokalne wiadomości prywatne (DM), pakuje je w ramki DTN i buduje łańcuch opieki (custody_path). Węzły FW+ przekazują "custodię/pakiet dtn" najbliższym sensownym sąsiadom, aż do celu. Stock FW jest tylko warstwą transportu punkt-punkt.
Dzięki mechanizmowi store-carry-forward, wiadomości wędrują nawet przez kilka–kilkanaście minut i wiele skoków, zamiast "znikać", gdy klasyczny routing zawiedzie.
Mechanizm nie rozwiązuje problemów radiowych/sprzętowych, wymaga minimalnie działającej infrastruktury, potrafi odczekać aż eter się zwolni i dokona przerzucenia do innego węzła DTN minimalizując straty miedzy hopami.
Domyślnie Meshtastic działa (a także inne rozwiązania) na bazie "online", rzucony pakiet dąży do celu bez większych refleksji, a nie wiemy czy odległe radio je odbierze, nie znamy jego stanu, każy kolejny hop zmniejsza szansę dostaw, a moduł DTN pozwala na lepsze zarządzanie ruchem i przekazywaniem wiadomości.
| Aspekt | Stock (bez DTN) | DTN (FW+) |
|---|---|---|
| Routing | Tylko klasyczny unicast routera, zwykle do 3 skoków, każdy kolejny skok zmniejsza szansę dostawy | Przechwytuje DM u źródła i wysyła via custody (magazynuje + ponawia), dynamicznie dobiera sąsiadów |
| Store-Carry-Forward | Brak — gdy ścieżka chwilowo "dziurawa" lub asymetryczna, DM potrafi przepaść | Pełna obsługa — wiadomości są przechowywane i przekazywane dalej, gdy topologia pozwala |
| Potwierdzenia | Brak niezawodnych potwierdzeń — aplikacja widzi głównie ACK/NAK, lub ciszę | Niezawodne potwierdzenia (receipts) odwrotnym łańcuchem custody nawet gdy routing natywny nie ma powrotu |
| Telemetria postępów | Brak telemetrycznych postępów | Postępy (PROGRESSED/milestones), "TRANSMITTED" i finalne "DELIVERED/FAILED/EXPIRED" do UI |
| Kompatybilność | — | Zachowuje kompatybilność ze stock: w TTL tail możliwy fallback do natywnego DM, węzły stock nic nie muszą zmieniać |
Jawnie śledzi łańcuch nosicieli (custody_path) i wymusza powrót potwierdzeń tą trasą, co rozwiązuje klasyczną asymetrię tras routingu.
PROGRESSED są oszczędne, limitowane globalnie/per-źródło/topologicznie; nie zalewają sieci niepotrzebnym ruchem.
Gdy węzeł "słyszy", że ktoś niesie to samo orig_id, adaptacyjnie opóźnia swoje próby (suppress), aby unikać dublowania.
Preferuje sprawdzone trasy (direct/handoff), a progressive relay włącza się ostrożnie, tylko gdy trzeba.
Statusy:
Receipty wracają łańcuchem odwrotnym do źródła; TTL receiptów jest osobny i krótki (status-based) oraz "capowany" względem pozostałego TTL oryginału.
Węzły pośrednie emitują "przejęte i pchnięte dalej" z reason=via (low byte node ID), jeśli przejdą limity i filtr topologiczny. Źródło wysyła też: DTN_ACCEPTED (custody przyjęte) i TRANSMITTED (poszło w eter na 1. próbie).
Widzę cudze DATA tego samego orig_id → opóźniam swoje próby (domyślnie ~35 s, z adaptacją mobilności), mocniejsze tłumienie blisko celu.
Globalny + per-źródło, filtr topologiczny (np. max ring) — ogranicza zalewanie sieci niepotrzebnymi informacjami o postępach.
Minimalny odstęp między próbami do tego samego celu — zapobiega nadmiernemu obciążeniu pojedynczych węzłów.
Globalny limit równoległych DTN DM — kontroluje całkowite obciążenie sieci przez jednoczesne wiadomości DTN.
Krótkie blokady orig_id (i skrótów receiptów), aby unikać re-capture czy powtórek po give-up. Historia blokad.
Bazowo ~50 s (dynamicznie modyfikowane przez mobilność), zwykle 2–5 prób zależnie od warunków; receipt reverse-path degraduje szybko po 1 nieudanym hopie.
DATA (ramka DTN) i custody-receipts lecą przez FWPLUS_DTN_APP (PSK kanału głównego); sąsiedzi "słyszą" ramki, lecz nie zdeszyfrują payload
Obsługiwane dla danych end-to-end, nadawca szyfruje payload kluczem publicznym odbiorcy (E2E PKI). Nagłówek DTN jest publiczny dla kontroli węzłow DTN, lecz tylko odbiorca może go odszyfrować. Jeżeli węzły nie wymieniły się kluczami PKI, to payload jest nieszyfrowany. Istnieje szansa, że w przyszłości DTN będzie mógł nieść nie tylko pakiety DM ale także innde (np. NodeInfo z kluczami publicznymi)
| Status | Opis |
|---|---|
DTN_ACCEPTED |
Source przyjął do custodi (PROGRESSED reason=0x11) |
TRANSMITTED |
Poszło w eter (PROGRESSED reason=0x00) |
PROGRESSED (milestone) |
"Idzie dalej" od pośrednika (reason=via low-byte) |
DELIVERED |
Finalne potwierdzenie dostarczenia — wycisza pending/duplikaty w UI |
FAILED |
Finalne potwierdzenie błędu — wycisza pending/duplikaty w UI |
EXPIRED |
Finalne potwierdzenie wygaśnięcia — wycisza pending/duplikaty w UI |
Blisko celu lub w TTL tail, gdy DTN nie pomoże – natywny DM (PSK/PKI decyduje Router). Źródło dostaje wtedy FAILED (UX: "wysłane przez Stock / DTN unavailable").
Beacony/hello-back to PROGRESSED z reason=FW+ version (id=0), TTL=0 (nie custody) – odkrywanie FW+ w siatce bez "ciężkiego" ruchu.
Beacony to niskokosztowe ogłoszenia "jestem FW+, mam wersję X" oraz lekkie "hello‑back" do odkrywania i potwierdzania węzłów FW+ bez obciążania kanału custodią.
Forma: to pakiety RECEIPT z status=PROGRESSED, zawsze z origId=0 (control‑plane), z polem reason niosącym numer wersji FW+ (np. v84). Nie są milestones konkretnej wiadomości.
Opcjonalne, bardzo krótkie PROGRESSED (origId=0, reason=0) do konkretnego węzła – też control‑plane, bez custody.
Zapis wersji/obecności w cache (wspomaga decyzje DTN).
Na bazie przekaźnika beacona budowany jest hint "kierunku" (który sąsiad prowadzi do danego FW+).
To nie jest milestone danej wiadomości; nie wpływa na TTL czy custody konkretnego DM.
Android/Router: "RECEIPT PROGRESSED (status=4) origId=0, reason=FW+ version". To nie milestone wiadomości, tylko sygnał control‑plane o wersji/zdolności FW+.
Moduł DTN korzysta z wielu sygnałów, aby zdecydować komu przekazać custody i jak utrzymać wiadomość w ruchu, gdy klasyczny routing jest niepewny. Poniżej skrót najważniejszych elementów procesu decyzyjnego.
Per-destination spacing, globalny max_active i bramka zajętości kanału ograniczają tempo generowania ruchu. Suppressions oraz kontrola progressive relay zapobiegają pętlom i nadmiarowym TX, a tombstony utrzymują historię prób.
Receipty (DELIVERED/FAILED/EXPIRED) wracają determinantnie po custody_path i szybko degradują, gdy hop jest nieświeży. Milestones PROGRESSED informują „idzie dalej” (rate-limit). W ogonie TTL źródło może wykonać late fallback do stock DM.
| Parametr | Wartość | Uwagi |
|---|---|---|
enabled |
false | Domyślnie wyłączony |
ttl_minutes |
6 | Minuty |
initial_delay_base_ms |
8000 | 8 sekund |
retry_backoff_ms |
50000 | 50 sekund |
max_tries |
2 | Silnik rozszerza do 5 przy trasach unknown/bez next_hop |
late_fallback_enabled |
false | Wyłączony |
fallback_tail_percent |
20 | Procent TTL |
milestones_enabled |
false | Włączony (opcjonalny), pomaga w informacji o postępach i wyciszaniu się pośrednich węzłów (wiedza DTN) |
per_dest_min_spacing_ms |
60000 | 60 sekund |
max_active_dm |
1 lub 2 | 1 dla słabszych MCU/gęstych sieci, 2 dla mocniejszych węzłów/czystszego kanału |
probe_fwplus_near_deadline |
false | Wyłączony |
Domyślnie: false
Włącza/wyłącza moduł DTN. OFF = zachowanie stock (bez DTN).
Domyślnie: 6 minut
Bazowy TTL (minuty) dla DTN DATA (custody). Większy = dłuższe okno dostawy przez wiele hopów, ale dłuższe wiszenie pendingów. Wszystkie węzły go używają po drodze i "wypalają"
Domyślnie: 8000 ms
Opóźnienie bazowe przed pierwszą próbą (slotting/election). Mniejsze = szybszy start, większe = więcej "oddechu" dla sąsiadów i routera (mniej kolizji).
Domyślnie: 50000 ms
Odstęp (backoff) między kolejnymi próbami. Większy = mniej obciążenia eteru, wolniejsze przekazywanie; mniejszy = szybsze retriale kosztem airtime.
Domyślnie: 2
Maksymalna liczba prób dla jednego id (poza ograniczeniami TTL). Więcej prób pomaga przy długich, niestabilnych trasach; za dużo = ryzyko nadmiarowych TX. Silnik rozszerza do 5 przy trasach unknown/bez next_hop.
Domyślnie: false
Zezwala na late fallback (natywny DM) blisko końca TTL (gdy DTN "nie rokuje"). Utrzymuje kompatybilność ze stock i ratuje dostawę blisko celu.
Domyślnie: 20%
Odsetek TTL (ogon), w którym rozważany jest fallback. Większy % = wcześniejsze przejście na alternatywę kosztem mniejszej szansy DTN na domknięcie.
Domyślnie: false
Włącza emisję PROGRESSED (milestones) – informację "idzie dalej". Pomaga w informacji o postępach, inne nody DTN używają tej informacji (np. do wyciszania się). Milestones powinny trafiać do nadawcy. Nie są wymagane.
Domyślnie: 60000 ms
Minimalny odstęp między próbami do tego samego celu. Większy = łagodniejszy ruch i mniejsze ryzyko kolizji, kosztem opóźnień.
Domyślnie: 1 lub 2
Limit równoległych aktywnych DTN DM. Niższy = oszczędny airtime i RAM; wyższy = większa przepustowość przy mocniejszym węźle/kanale. 1 dla słabszych MCU/gęstych sieci, 2 dla mocniejszych węzłów/czystszego kanału.
Domyślnie: false
Lekki probe (PROGRESSED, bez custody) blisko końca TTL, aby wykryć FW+ u celu/pośredników i zwiększyć szanse finalnej dostawy lub właściwego fallbacku. Włącz tylko, gdy faktycznie pomaga w Twojej topologii.
Route confidence i traceroute: DTN używa tylko traceroute dla zbudowania confidence (projekt nie używa ping).
Idealne dla sieci z okresowym brakiem tras, gdzie klasyczny routing może zawieść.
Szczególnie przydatne przy "kruchym" DV-ETX (NextHop), gdzie standardowy routing ma ograniczenia, a sieć zaczyna się znacznie rozwijać.
Działa w środowiskach stock + FW+ – bez konieczności aktualizacji wszystkich węzłów. Jest to znaczna zaleta, nie trzeba posiadać DTN na węzłach kluczowych typu backbone, np. routerów. Węzeł DTN może być obok i spełniać swoje zadanie.
DTN overlay zapewniający opportunistic store–carry–forward dla prywatnych DM, z niezawodnymi potwierdzeniami odwrotną ścieżką i oszczędnym systemem milestones.
Klasyczny routing bywa niepewny przy wielu hopach/asymetrii; DTN utrzymuje wiadomości "w ruchu" i dostarcza je, gdy topologia pozwala.
Custody_path, reverse receipts, suppression po podsłuchu, ostrożny progressive relay, kompatybilność stock.
Wyższy delivery rate, lepszą obserwowalność postępów, mniej "znikających" DM.
Strojenie limitów/TTL, obserwacja airtime, pamięć i stan pendingów.