-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Specification
With the creation of MDNS we need to integrate it's usage into Polykey. With that comes some considerations surrounding
what connection information needs to be stored in the NodeGraph and what information needs to be shared between nodes.
Right now the NodeGraph is based on the Kademlia spec and is pretty simple. It only stores a single Address for each node. A There are only 20 nodes per bucket and only the oldest active ones are stored. This is all based on the Kademlia spec.
The NodeGraph logic needs to be expanded to allow for more information relating to each node to be stored. We need to store IPv4 as well as IPv6 addresses. We need to track information about if the node is publicly contactable or needs to be hole punched. We need sticky nodes such as the seed nodes or user defined static information.
Step 1 - MDNS Sidecar onto NodeConnectionManager and NodeManager
I've decided as the simplest solution, MDNS can be integrated into methods of NodeConnectionManager and NodeManager related to discovery, like findNode, etc. This essentially allows NodeConnectionManager and NodeManager use both MDNS and NodeGraph as discovery mechanisms independent of each other.
Note: MDNS should not be integrated into findNode directly, but as a separate method to be called by the callers of findNode in non-kademllia contexts.
The NodeGraph related data structures will still have to be edited like so to facilitate the separation of MDNS addresses and NodeGraph addresses:
type NodeAddressScope = 'local' | 'external';
type NodeAddress = {
host: Host | Hostname;
port: Port;
scopes: Array<NodeAddressScope>;
};This will mean that there will be overlapping NodeData that exists on both the NodeGraph and MDNS, this will have to be dealt with.
The methods on NCM: getConnectionWithAddress and getConnection will need to be amended to support multiple NodeAddresses as input. This isn't the ideal way to do this, but it will have to be like this until the NodeGraph itself is made to support storing multiple IP addresses in Step 2. Much of the flow will need to be rewritten to support this change.
Scopes
Currently in Step 1, scopes will only be used for disabling holepunching on local addresses. An address can be either local, external, or both. Local means that the address is locally routable, so holepunching is not required when connecting to that address. External means the that the address is gliobally routable, but will require holepunching to establish a connection.
Scopes aren't just for disabling signaling or not, they are also used for the purpose of classifying IP addresses into different levels. This means that in future, when scopes are incorporated as part of the nodegraph, we can specify for only external addresses to be shared on the public mainnet.
Being able to define scopes as an array also means that i address could have multiple classifications, which would be useful in the future if we ever needed it expanded. Also addresses with both local and external will be understood to be shared on the mainnet, but not require holepunching to be connected to.
Custom Group Address and Port
We're going to need to select a port and ipv4 + ipv6 groups for now, as to not interfere with existing MDNS stacks. However, as native integration of MDNS improves, this may eventually no longer be needed.
I've decided to take inspiration from our slogan fait accompli, to choose these addresses:
| IPv4 | IPv6 | Port | |
|---|---|---|---|
| Value | 224.0.0.250 |
ff02::fa17 |
64023 |
| Reasoning | 250 is decimal representation for fa |
fa17 looks like fait in fait accompli |
64023 is the decimal representation of fa17 |
All these Values have been checked against IANA to be not of conflict with any existing reservations.
Step 2 - Full Integration of MDNS to Supply Data to NodeGraph
The NodeGraph is expanded to support multiple IPv4 and IPv6 addresses.
This will allow us to integrate MDNS into the NodeGraph, so that it is used as the central Node address book.
type NodeData = {
addresses: Array<NodeAddress>;
lastUpdated: number;
};This might require alot of API changes. We'll see if we can get there in time.
Additional context
- Related:
js-quicintegration and Agent migration #525 - Related: Using QUIC/HTTP3 to replace utp-native for the Data Transfer Layer in the networking domain #234
- Related: IPv6 Support #400
- Related:
MDNSintegration andNodeGraphstructure expansion #537 - Related: Fix hole punching to work in both directions #605
Tasks
- 1. Step 1 - Integrate
MDNSand it's usage into initial network entry and discovery.- Integrate MDNS querying into
NodeConnectionManager.findNode
- Integrate MDNS querying into
- 2. Step 2 -
NodeGraphfunctionality needs to be expanded to handle connection metadata, support IPv6 and general policy for garbage collection, data updating and data sharing policy.- The initial sync node graph proceedure should be extracted out of
NodeManager.startand be made a public function. It's usage should be called inPolykeyAgentwhen starting. We should make it optional for testing. [ ] Integrate MDNS querying intoNodeManager.syncNodeGraph[ ] Integrate MDNS querying intoNodeManager.getNodeAddress[ ] Integrate MDNS querying intoNodeManager.setNode- Integrate MDNS into
NodeManager.findNode- this was moved out from NCM into NM now.
- The initial sync node graph proceedure should be extracted out of