
Rete mesh IoT/Radioamatori come prova di concetto con routing globale su Internet

Sistema di routing mesh che supporta l'uso di un proxy OpenDHT come backend, in modo che i nodi possano comunicare direttamente via internet. Molto presto pre-alpha, proof of concept, potrebbe non funzionare effettivamente, ecc.
È pensato sia per casi d'uso hobbistici/HAM, sia per il più tipico lavoro IoT consumer/commerciale, ma specificamente non cerca di sostituire internet o di coprire grandi aree ad alto traffico con antenne omnidirezionali.
Non ha il routing hop-by-hop stile Meshtastic, da qui il nome LazyMesh. Se vuoi usarlo per applicazioni offgrid in un'area densa, probabilmente avrai bisogno di antenne direzionali e ID di route coordinati manualmente.
Al momento questa è l'unica applicazione reale. Apri lo sketch Arduino di esempio, modificalo con il tuo nome utente e una chiave segreta del canale che deve essere una password forte.
Digita il tuo messaggio nel monitor seriale di Arduino e dovresti essere in grado di chattare con tutti gli altri dispositivi.
I messaggi dovrebbero passare fintanto che i nodi sono sulla stessa rete o entrambi hanno accesso a internet.
Visita il Web Client per chattare con il nodo via MQTT da internet. Imposta un nome utente, aggiungi un canale e inserisci la password del canale. Il nome del canale può essere qualsiasi cosa e influisce solo sull'etichettatura nell'interfaccia.
Puoi anche provare lo sketch di esempio Read/Write data. Questo espone l'ID dati 195 come leggibile e l'ID dati 196 come leggibile e scrivibile. Vai sul sito, inserisci i dettagli del tuo canale e usa il dialogo di richiesta dati per richiedere l'ID 196 da tutti i dispositivi.
Poi clicca "set" e impostalo su qualcos'altro, e prova a leggerlo di nuovo.
Il Web Client è attualmente hardcoded per usare test.mosquitto.org, questo cambierà in futuro.
I nodi necessitano di un modo per sincronizzare il tempo per comunicare. Attualmente, se non hanno mai ricevuto il tempo da una fonte attendibile, impostano il loro tempo da qualsiasi pacchetto casuale vedano.
Questo potrebbe essere un rischio per la sicurezza consentendo attacchi replay, quindi i dispositivi che necessitano di sicurezza dovrebbero avere una fonte temporale attendibile.
Una volta che il tempo è stato impostato inizialmente, il codice regolerà il tempo di sistema fino a 1 secondo al giorno per rimanere sincronizzato con gli altri nodi, quindi il disallineamento temporale non dovrebbe essere un problema importante.
In Lazymesh, tutto è un canale, non ci sono messaggi diretti. Se li vuoi, crea un canale privato dedicato.
I canali sono definiti da una password; conoscere la password consente l'accesso in lettura e scrittura.
Ci sono 256 numeri di route. Ogni pacchetto ne ha uno, e i ripetitori ripetono solo se hanno abilitato un numero di route corrispondente. Per impostazione predefinita, tutto viene inviato con il numero di route 0, che è abilitato di default.
Questo riguarda solo i ripetitori; i nodi ascolteranno qualsiasi numero di route mesh se è direttamente per loro.
I payload dei pacchetti sono array MessagePack. Alternano ID dati interi e elementi dati. 192-256 sono riservati per messaggi specifici dell'applicazione.
ID 32 è per messaggi di testo, che possono essere preceduti da un nome utente e due punti.
ID 2 è usato per un ID univoco, che deve essere un intero. Molte applicazioni potrebbero non averne affatto bisogno.
Aggiungi un byte di lunghezza dei metadati e N byte di metadati.
Per creare l'IV, prendi 12 byte casuali per l'IV. Quindi crittografa il tutto. Prependi l'IV e aggiungi 4 byte di tag di autenticazione.
Quindi prendi i primi 8 byte dell'hash dell'ID di route e converti in esadecimale.
L'argomento MQTT sarà lazymesh_route_HEX
Nota che usiamo un argomento di primo livello. Questo in modo che tu non possa usare wildcard per sottoscrivere tutti i canali lazymesh contemporaneamente su broker pubblici, il che ti permetterebbe di fare DoS a tutti abbastanza facilmente.
Semplici pacchetti grezzi trasmessi su 224.0.0.251:2221
Niente di questo è definitivo!!!
All numbers are little-endian.
1 byte header:
2 bit packet type(Either 1 or 2, depending on if we want ACK)
3 bits TTL hops remaining
1 bit allow slow transport(LoRa etc)
1 bit allow global routing
1 bit was already global routed
1 byte header 2:
1 bit first send attempt:
Whenever we create a or recieve a packet, set this bit. After trying to send it,
clear it. This way, as long as we assume packet loss is low-ish, we can count the repeaters in the area
without extra overhead.
1 bit repeater bit:
Marks that this packet should be included when counting repeaters.
Set it if you would repeat the packet or one like it, even if you originated it.
1 bit interest bit:
If this is set, the node who sent it is directly interested in the channel,
not purely just a repeater. If first send is also set, it is treated as an
implicit ack
1 bit location enabled
If this bit is set, repeaters may add location metadata to the packets forwarded to the internet. This metadata must be encrypted with the routing ID as the key,
meaning nearby people could track you for 1 hour after you get out of range.
Not implemented anywhere at the moment.
5 reserved 0 bits
1 byte mesh route number
1 byte path loss accumulated:
5 bits total
3 bits last hop
Every hop is a point of path loss,
plus whatever extra cost heuristic the transport applies.
1 extra point of loss should be roughly the same "badness" as
10dbm extra loss on wifi.
16 bytes routing ID:
Changes every hour, derived from the channel PSK by a hash.
The PSK is just the 16 byte SHA256 of the password.
The routing ID changes hourly, and is the SHA256 of:
The letter 'cr'
The count of hours since 1970 as a 32 bit unsigned int
the PSK
8 Bytes random entropy:
Used as part of the IV for the cipher
4 bytes timestamp:
Also part of the IV, also prevents replay attacks
N bytes ciphertext:
AES-GCM encrypted.
The encryption key changes hourly, and is the SHA256 of:
The letter 'c'
The count of hours since 1970 as a 32 bit unsigned int
the PSK
6 bytes auth tag:
The last 6 bytes are the GCM tag
Alcune implementazioni potrebbero scegliere di ignorare completamente questo.
Gli ACK sono puramente per hop a meno che un livello di protocollo superiore non voglia fare ACK end-to-end.
I pacchetti ACK non vengono ripetuti, instradati o altro, né sono autenticati. Ogni passo della ripetizione mesh ha il proprio riconoscimento; dalla prospettiva del mittente originale, è fuoco e dimentica.
Come Meshtastic e molti altri, il protocollo è "semi-affidabile", ci sono, come tutte le reti, casi limite che causano guasti.
L'affidabilità reale deve essere implementata a un livello superiore.