[Feature Request]: Automatic global routing using a distributed hash table #6516
Replies: 2 comments
-
Trying to implement this as a proof of concept, I ran into one big issue. OpenDHT's REST API wants you to open a new TCP connection for every key you want to listen on, which is probably not going to make the ESP32 very happy at all in heavily loaded environments. It's also not very decentralized if the DHT gateways aren't running locally, so it seems to me like this kind of feature would be better off with the actual network gateway stuff running on a RasPi or similar. The edge nodes would then only need to transmit the global routing request messages, and a raspberry pi would just listen to the existing UDP messages(Incidentally, I've found it is extremely easy to receive and decode those UDP messages in Python!). So the topology would be: Any device -> (LoRa) -> ESP32 -> (UDP) -> Linux Gateway app -> DHTNode on same unit -> Global P2P mesh. Another issue I'm seeing is the lack of extra available header bits. Doing all the hard stuff on a Pi gives a lot more ability to keep track of such things, so you could handle enabling/disabling gateways adding position data in the request packets. Rather than enabling it per-packet, enable it per-nodeID/channel hash pair. Finally, it doesn't seem like the protocol directly specifies any way to send control messages that are not associated with a specific channel. Maybe a special destination address and channel hash could be reserved for these messages, everyone else would just see it as an encrypted packet. These could also be used by the gateways to broadcast the current time to nobody in particular, as a fallback for devices that don't have a better way of setting the time. |
Beta Was this translation helpful? Give feedback.
-
Further research: I've started working on actually implementing the Python side of this. Since the ability for meshtastic to send the rollling keys from the device doesn't exist, I just generate them locally, letting the user set a fixed channel to map to the DHT. I discovered another issue, people may not want even metadata to be public on the DHT, even hidden under a rolling code. So I've made the DHT key the hash of the temporary group key, adding another layer of hashing, while the temporary group key itself is used to encrypt anything we put in the DHT, so it can only be decoded if you are actually there to observe the temp group keys over the air. I've also added basic replay attack protection. Since a Pi or similar has plenty of RAM, we can just store the hash of every message in the last 80 minutes, by which time the rolling keys would have expired. This code is like, a quarter working( I can't properly test it without a second device, hopefully more people here will get into it and it will be worth investing more!), but it shows the concept. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Platform
Cross-Platform
Description
Now that mesh over IP is a thing, it seems like a very nice next logical step would be global mesh routing.
A user could set up an internet-connected node, and then any nearby user could communicate with anyone in the world. This would be especially useful for IoT type devices.
You would just need to mark a channel or just your own node as globally routable, and the firmware would let you pretend that it had unlimited range
It looks to me like the current protocol has almost everything needed for this as it is.
The way it could work is:
Nodes can have a secret global routing key that defines a distributed group channel
Every hour, a node wanting to send global routable packets generates a unique 48 byte rolling code by hashing this key.
It sends this key in a global routing request packet, along with the previous or next code, depending on what's closest, so we can deal with synchronization issues. This packet also contains the channel hint of the channel you want to be globally routed. It could also contain just a single node ID, to only make traffic to and from that node globally routable, which might be better in some specific cases.
The global routing access point replies, so UI can indicate that we are connected. For the next hour, if the router gets a message using that channel hint, with the global routing header flag set, it will publish the raw packet to OpenDHT via a gateway.
If two users select different gateways, OpenDHT will handle all the routing stuff by itself to make it work, there's no need to rely on any central server.
It will subscribe to both of those 48-byte IDs, valid for an hour. Whenever a new message is posted to OpenDHT on one of those keys, it will rebroadcast it, subject to rate limits.
You can't spam a repeater indefinitely without actually being there, because eventually the rolling codes will expire, and you can't observe traffic from a node for more than an hour unless you have the rolling code key. And nothing ever hits the DHT at all unless it specifically opts in with the flag bit.
It would use up an extra header byte, but a device could also have a flag to indicate that it wants repeaters to include metadata about themselves.
They would publish their location and the RSSI of the packet, allowing a device with no GPS to make itself findable with triangulation.
As a free side benefit, OpenDHT retains messages for about ten minutes, so it can store things for nodes that are roaming or sleeping.
Plus, if you know the key, you can talk to any device anywhere without actually having hardware, and OpenDHT is HTTP based.
People could build apps that run 100% in the browser, which would allow for some really cool things, like a zero-setup weather station that has a QR code on the side, for anyone to view the data live on a GitHub.io page.
Beta Was this translation helpful? Give feedback.
All reactions