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
Tasks
Specification
With the creation of
MDNSwe need to integrate it's usage into Polykey. With that comes some considerations surroundingwhat connection information needs to be stored in the
NodeGraphand what information needs to be shared between nodes.Right now the
NodeGraphis 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
NodeGraphlogic needs to be expanded to allow for more information relating to each node to be stored. We need to storeIPv4as well asIPv6addresses. 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
findNodedirectly, but as a separate method to be called by the callers offindNodein 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:
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:
getConnectionWithAddressandgetConnectionwill need to be amended to support multipleNodeAddresses 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,
scopeswill only be used for disabling holepunching onlocaladdresses. An address can be eitherlocal,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
localandexternalwill 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:224.0.0.250ff02::fa1764023250is decimal representation forfafa17looks likefaitinfait accompli64023is the decimal representation offa17All 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.
This might require alot of API changes. We'll see if we can get there in time.
Additional context
js-quicintegration and Agent migration #525MDNSintegration andNodeGraphstructure expansion #537Tasks
MDNSand it's usage into initial network entry and discovery.NodeConnectionManager.findNodeNodeGraphfunctionality needs to be expanded to handle connection metadata, support IPv6 and general policy for garbage collection, data updating and data sharing policy.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.setNodeNodeManager.findNode- this was moved out from NCM into NM now.