-
Notifications
You must be signed in to change notification settings - Fork 985
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
protocols/kad: Support client mode #2032
Comments
I remember searching for specs/writeup regarding this behaviour at the time of introduction to go-ipfs (0.5 maybe?). Closest I can still find for in libp2p/specs or ipfs/go-ipfs this is libp2p/specs#108 which doesn't contain "client." @aschmahmann could the spec be in some other place? However your description of it does sound simple enough. |
Adding a couple of notes here to help getting started. For the greater picture I recommend reading the Kademlia paper and the Kademlia specification. As a first iteration, I would recommend making this a configuration option via When in client mode one can use A server already detects whether the remote supports the Kademlia protocol via the |
Assigning @whereistejas here. Thanks for offering your help. Edit: I can't assign you directly. Though I guess the comment here is good enough. |
I am now working on this, albeit several layers "down the stack". In particular, to ship this we need a way for all connections handlers on a connection to communicate. That is somewhat tracked in #2680 (the name is stale as the discussion evolved). There is a draft in #3651. A dependency of that PR is #2831 which I am working on in #3745. |
Discoverability of addresses of clients in client-modeRoles
ProblemWith Kademlia client-mode C will no longer be added to S's routing table. In the case where O asks S of the addresses of C, via the Possible Solutions
|
Discussed out-of-band with @mxinden : This can be shipped as an additional PR on top of client-mode in a backwards-compatible way, thus deferring for the initial implementation! |
Previously, a `NetworkBehaviour` could report an `AddressScore` for an external address. This score was a `u32` and addresses would be ranked amongst those. In reality, an address is either confirmed to be publicly reachable (via a protocol such as AutoNAT) or merely represents a candidate that might be an external address. In a way, addresses are guilty (private) until proven innocent (publicly reachable). When a `NetworkBehaviour` reports an address candidate, we perform address translation on it to potentially correct for ephemeral ports of TCP. These candidates are then injected back into the `NetworkBehaviour`. Protocols such as AutoNAT can use these addresses as a source for probing their NAT status. Once confirmed, they can emit a `ToSwarm::ExternalAddrConfirmed` event which again will be passed to all `NetworkBehaviour`s. This simplified approach will allow us implement Kademlia's client-mode (#2032) without additional configuration options: As soon as an address is reported as publicly reachable, we can activate server-mode for that connection. Related: #3877. Related: #3953. Related: #2032. Related: libp2p/go-libp2p#2229. Co-authored-by: Max Inden <mail@max-inden.de> Pull-Request: #3954.
Currently, the kademlia behaviour can only learn that the remote node supports kademlia on a particular connection if we successfully negotiate a stream to them. Using the newly introduced abstractions from #3651, we don't have to attempt to establish a stream to the remote to learn whether they support kademlia on a connection but we can directly learn it from the `ConnectionEvent::RemoteProtocolsChange` event. This happens directly once a connection is established which should overall benefit the DHT. Clients do not advertise the kademlia protocol and thus we will immediately learn that a given connection is not suitable for kadmelia requests. We may receive inbound messages from it but this does not affect the routing table. Resolves: #2032. Pull-Request: #3877.
Previously, a `NetworkBehaviour` could report an `AddressScore` for an external address. This score was a `u32` and addresses would be ranked amongst those. In reality, an address is either confirmed to be publicly reachable (via a protocol such as AutoNAT) or merely represents a candidate that might be an external address. In a way, addresses are guilty (private) until proven innocent (publicly reachable). When a `NetworkBehaviour` reports an address candidate, we perform address translation on it to potentially correct for ephemeral ports of TCP. These candidates are then injected back into the `NetworkBehaviour`. Protocols such as AutoNAT can use these addresses as a source for probing their NAT status. Once confirmed, they can emit a `ToSwarm::ExternalAddrConfirmed` event which again will be passed to all `NetworkBehaviour`s. This simplified approach will allow us implement Kademlia's client-mode (libp2p#2032) without additional configuration options: As soon as an address is reported as publicly reachable, we can activate server-mode for that connection. Related: libp2p#3877. Related: libp2p#3953. Related: libp2p#2032. Related: libp2p/go-libp2p#2229. Co-authored-by: Max Inden <mail@max-inden.de> Pull-Request: libp2p#3954.
From what I understand from #2025 (reply in thread) the Kademlia implementation does not support client mode. Client mode is quite useful as it allows lower quality (e.g. intermittent availability, high latency, low bandwidth, low CPU/RAM/Storage, etc.) nodes to utilize the DHT for discovery without decreasing the quality of the network.
This feature has been very helpful in go-libp2p and in the various consumers of it such as go-ipfs.
To implement client mode all that is really required is that the node does not advertise the DHT protocol (e.g.
/ipfs/kad/1.0.0
). Additionally, if the node is able to switch between client and server mode at runtime then updates to the supported protocols should be communicated viaidentify-push
/identify-delta
.Once we have the basic client-server mode switching then as a follow up it might be a good idea to, as go-libp2p does, have an "automatic" mode that switches between client and server mode based on educated guessing about what is appropriate for the user (e.g. peers behind relays probably shouldn't be servers, and peers who haven't been online for a while and are stable probably shouldn't either).
The text was updated successfully, but these errors were encountered: