Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-hop service advertisment model, with plugins #385

Open
makew0rld opened this issue Apr 19, 2019 · 5 comments
Open

Multi-hop service advertisment model, with plugins #385

makew0rld opened this issue Apr 19, 2019 · 5 comments

Comments

@makew0rld
Copy link
Contributor

makew0rld commented Apr 19, 2019

This issue details an idea proposed by @darkdrgn2k, originally beginning in chat here.

Basics:

  • Nodes can send UDP packets advertising the services they have to neighbour nodes
  • Plugins can process the services, so the reaction to the info can be modularized
  • Messages can have a TTL (time-to-live) on them
    • This allows the message to be passed from node to node, decreasing the TTL until it reaches 0
    • This allows multi-hop message delivery and service advertisement without crawling the network, assuming peers do what they're told
  • Messages also have a hop number on them, a bit like a reverse TTL
    • This allows peers to know how far away nodes are geographically (roughly) and decide what to do with the info

Message format:

  • Potentially just contains a list of services, and then an interested node can reply and ask for the info for a specific service
    • This saves on space since a single UDP packet only has about 508 bytes for info to be used reliably
  • @darkdrgn2k suggested something similar to IPv6|service,service|TTL|hop|Identifier
    • I am unsure what identifier means here, in other parts of the chat he said WHATEVER as a placeholder
  • I would possibly suggest using Cap'n Proto as an efficient binary data format we can use to encode the messages in a small amount of space, instead of just plain text
    • Cap’n Proto is an insanely fast data interchange format and capability-based RPC system. Think JSON, except binary. Or think Protocol Buffers, except faster.

Logic:

Modules/Plugins:

  • Base pkg that sets up this framework
  • Other pkgs can have plugins that make use of the framework
  • The framework pkg should be an optional dependency of these modules, so that they can function without needing to advertise, and needing another dependency
  • The framework should have a way to configure which pkgs notify or not, possibly in a config file and later in a Web UI for advanced users
  • We will have to decide on defaults for this, maybe it can be on a per pkg basis
@darkdrgn2k
Copy link
Contributor

@darkdrgn2k suggested something similar to IPv6|service,service|TTL|hop|Identifier

What im currently theorizing. SSB uses : as delimiter but that conflicts with ipv6

We need a way of identifying each packet so that a node knows if they already received once and it came back, or if its a new one that it needs to forward

whatever or identifier needs to be figured out

Easiest way is a counter, but that could cause forged packets (if thats a problem)

@darkdrgn2k
Copy link
Contributor

We will have to decide on defaults for this, maybe it can be on a per pkg basis

Should also have a hard limit on TTL so its not abused. IE broadcast to the WHOLE network. IE no more than 5

@darkdrgn2k
Copy link
Contributor

darkdrgn2k commented Apr 19, 2019

Modules/Plugins:

I built this model in bash and i think its pretty simple

Main Service receive packet
Content of packet is passed through every shell script in a folder (ie run-parts multhop-system-name-whatever.d/*) similat to nodeinfo.d

Each script process the packet's data and decides what to do with it (if anything).

ie the IPFS process would not care about SSB so it would skip it

The modules would place a file in that folder to deal with a certain type of service if they wanted to
ie IPFS would swarm add while SSB would gossip add

@darkdrgn2k
Copy link
Contributor

This saves on space since a single UDP packet only has about 508 bytes for info to be used reliably

I think your betting on 576 MTU which would never happen on a cjdns/yggdrasill network.

A UDP packet on a standard 1500 MTU network after header overhead is 1460
To be safe for IPSEC/GRE etc some system drop it as low as 1300
If it grows beyond that the packet is fragmented.

Also these packets are informational and will be resent at regular intervals, so if one doesn't make it.. it wont matter

@makew0rld
Copy link
Contributor Author

makew0rld commented Apr 19, 2019

We need a way of identifying each packet so that a node knows if they already received once and it came back, or if its a new one that it needs to forward

So obviously nodes won't send the message back to where they got it from, but messages can still be received twice ofc. I'm thinking the identifier part can just be a randomly generated UUID, possibly a truncated one depending on how many bytes we get. Nodes can cache the UUIDs they know of for a certain amount of time, and recognize messages based off of that.

Easiest way is a counter, but that could cause forged packets (if thats a problem)

Maybe another way to do it would be to have a small signature using the node's public key, the same one their IP address is derived from? So that way nodes will check if the IPv6 address listed in the message matches the public key of the signed part of the message. Idk if that's too intensive or large (byte-wise) though, I'd be happy to hear your thoughts.

We will have to decide on defaults for this, maybe it can be on a per pkg basis

Should also have a hard limit on TTL so its not abused. IE broadcast to the WHOLE network. IE no more than 5

I was talking about defaults for notification, which each pkg should decide, but be able to be overriden. But about TTL, I agree yeah. This can be enforced by other nodes, who will drop any packet with a TTL larger than 5, or whatever we decide on later.

I built this model in bash and i think its pretty simple [...]

That sounds like a great model, and pretty simple too. My only concern is that passing the packet through each script could take a long time as more services/scripts get added, so we'll have to watch out for that.

Another model could be to have sub-folders like whatever.d/IPFS/ and whatever.d/SSB/, each sub-folder having multiple scripts inside it. So we only run the scripts that are known to handle IPFS services when the node gets a packet about IPFS.

I think your betting on 576 MTU which would never happen on a cjdns/yggdrasill network.

Good point. CJDNS MTU is 1304 with headers subtracted (chat, file), and Yggdrasil MTU is very high, 65535.

One thing I said you didn't comment on:

Potentially just contains a list of services, and then an interested node can reply and ask for the info for a specific service

Is this a good model, or now that we have more packet space, should nodes send out a list of all their services with their relevant info? You also didn't comment on my suggestion of using Cap'n Proto instead, what do you think of that? Especially if we're doing binary stuff like signatures, or listing many services, I think it'll be more efficient.

Some things I didn't mention in the original post:

  • These messages would need an assigned port that all the nodes use to receive them and reply to them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants