-
Notifications
You must be signed in to change notification settings - Fork 666
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
Add an UDP listening endpoint to prove reachability #563
Comments
I can see two possible ways to design the protocol:
If we go the second option, one quick brainstorming I went with a packet containing:
Recipient sends back an answer containing the bytes that the sender sent. |
Something that I don't understand is the following: The addresses reported by a peer are multiaddresses. A multiaddress specifies the transport protocol to use. To check whether the address is reachable, we surely must use the transport specified in the address? I.e. in the context of #564 I don't even see how there can be such a choice of transport protocol? |
To me, that's why we're going to put this code in Substrate and not libp2p. On the long term, though, we can probably remove this feature once we switched to QUIC? |
(Here I assume that dialing UDP on the same port as your TCP listeners is a good design and a feature we want to keep; it's far from obvious, but for now let's ignore that) There are two major threat categories here:
The same list also improves our defenses against
|
If I understand, this proves nothing about the identity of the node reached, except perhaps that substrate runs there, right? |
@burdges pongs should be signed by the key that matches expected peer id. devp2p design has a few strong points on rate limiting and replay protection already. |
Given that we support multiple listen addresses we would need to bind one UDP socket to each address in order to answer PINGs to those addresses if they are reported via identify. |
Currently every address reported via libp2p-identify is inserted into the DHT which thus contains a multitude of unreachable addresses such as from 127.0.0.0/8 or 10.0.0.0/8. Issue #5099 suggested a dedicated service over UDP to gauge the reachability of an address, which would however incur extra I/O costs and be of limited use. As an alternative and simpler tactic, this PR only allows global IP addresses to be inserted into the DHT unless an explicit command-line flag `--allow-non-global-addresses-in-dht` is given or a node is started with `--dev`. This opt-in behaviour is meant to allow site-local networks to still make use of a DHT.
* network: Only insert global addresses into the DHT. Currently every address reported via libp2p-identify is inserted into the DHT which thus contains a multitude of unreachable addresses such as from 127.0.0.0/8 or 10.0.0.0/8. Issue #5099 suggested a dedicated service over UDP to gauge the reachability of an address, which would however incur extra I/O costs and be of limited use. As an alternative and simpler tactic, this PR only allows global IP addresses to be inserted into the DHT unless an explicit command-line flag `--allow-non-global-addresses-in-dht` is given or a node is started with `--dev`. This opt-in behaviour is meant to allow site-local networks to still make use of a DHT. * Enable non-global in more test setups. * Replace command-line option with different name. * Another test fix.
To expand on the previous comment, the problem we have is: if a node connects to us through TCP, how do you know which UDP port to ping? Do we hard-code a specific port into the client? This means that you could for example no longer start two nodes on the same machine, and it is generally frown upon to not make ports configurable. But if we make the port configurable, then we need to somehow communicate to remotes which UDP port to try. This means designing a new protocol just for that. |
There are claims that merely opening a QUIC connection might prove heavier than you'd like, but computationally the crypto for opening a QUIC connection should only cost twice the unencrypted signed message proposed here. We could gain other stuff from doing that if either idling QUIC connections proves cheap or if we used them to initiate 0-RTT. |
* rebased main and fixed tests * Added doc comments * changed error handling to log on failure * fixed new ethereum tests
* Use versioned `extrinsic_filter` on pending transactions rpc * Use versioned `current_block` in eth_call when no gas limit * fmt
With the intent to solve #564
The idea is to add a small UDP listening endpoint that answers requests. Then we can tackle #564 by sending out these requests.
cc'ing @romanb @arkpar @kirushik
The text was updated successfully, but these errors were encountered: