Skip to content

MDNS integration and NodeGraph structure expansion #537

@tegefaulkes

Description

@tegefaulkes

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

Untitled-2023-10-23-0424 excalidraw

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

Untitled-2023-10-23-0424 excalidraw(1)

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

  • 1. Step 1 - Integrate MDNS and it's usage into initial network entry and discovery.
    • Integrate MDNS querying into NodeConnectionManager.findNode
  • 2. Step 2 - NodeGraph functionality 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.start and be made a public function. It's usage should be called in PolykeyAgent when starting. We should make it optional for testing.
    • [ ] Integrate MDNS querying into NodeManager.syncNodeGraph
    • [ ] Integrate MDNS querying into NodeManager.getNodeAddress
    • [ ] Integrate MDNS querying into NodeManager.setNode
    • Integrate MDNS into NodeManager.findNode - this was moved out from NCM into NM now.

Metadata

Metadata

Labels

developmentStandard developmentepicBig issue with multiple subissuesr&d:polykey:core activity 4End to End Networking behind Consumer NAT Devices

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions