-
-
Notifications
You must be signed in to change notification settings - Fork 31
1. Introduction
Pinecone is an implemenatation of the Sequentially Networked Edwards Key (SNEK) name-independent routing scheme that combines two network topologies in order to build an efficient and scalable overlay network.
Pinecone is:
-
Name-independent:
- Node identifiers are not related to the physical network topology;
- They do not change as the node moves around the network;
- The address space is considered to be global — there is no subnetting;
-
Built up of equal players:
- Nodes will forward traffic on behalf of other nodes;
- There are no specific points of centralisation;
- A node can join a larger network by connecting to any other node;
-
Self-healing:
- Tolerates node mobility far better than Batman-adv, Babel and many other routing protocols;
- Alternative paths will be discovered automatically if possible when nodes go offline or connections are lost.
-
Transport-agnostic:
- The only requirements for a peering today are that it is stream-oriented and reliable;
- Any connection medium that can offer these semantics is appropriate for a peering, including TCP over regular IP networks, WebSockets, Bluetooth L2CAP (with infinite retransmit) or RFCOMM etc.
Note, however, that Pinecone is:
-
Not anonymous:
- Anonymity networks make significant trade-offs in order to achieve anonymity, both in overall complexity and in path/routing cost, which are unacceptable in resource-constrained environments;
- It is not a goal of the Matrix project to guarantee anonymity — at best Matrix can provide pseudonymity and the same is true with Pinecone public keys;
-
Not strongly resistant to traffic analysis:
- Although traffic packet contents will be encrypted end-to-end by default, the source and destination fields in the packet headers are visible to intermediate nodes;
- In some cases, source addresses could be sealed/encrypted, although this is not implemented today;
-
Not fully resilient against malicious nodes:
- If a node peers with malicious nodes which (for instance) drop traffic, then connectivity will inevitably be disrupted. This can never be fully mitigated (for instance, if you are in a 2 node network and the other node is malicious, there is nothing you can do) — but work is ongoing to detect and route around malicious behaviour where possible.
The Pinecone routing scheme effectively is built up of two major components:
-
A global spanning tree:
- Provides efficient, low-stretch and strictly loop-free routing;
- Effective means of exchanging path setup messages, even before SNEK bootstrap has taken place;
-
A virtual snake (or SNEK) — a double-linked linear routing topology:
- Provides resilient public key-based routing across the overlay network.
Strictly speaking, a Pinecone network is formed every time two or more nodes connect to each other. Any two networks that are joined together by a common node will merge into a single larger network.
Even though the Pinecone address space is considered to be global in scope, it is important to note that there is no true “single” Pinecone network. It is possible for multiple disjoint and disconnected Pinecone network segments to exist.
This does mean that if every node globally is connected somehow to the same mesh, Pinecone will converge on a single global network and all nodes will be routable to each other as a result.
It is possible to create private/closed networks within trusted environments by enforcing mutual authentication of peering connections, although this is an implementation-specific detail and not specified here. This may be desirable in some particularly sensitive settings to ensure that trusted nodes do not participate in untrusted networks and that untrusted nodes do not participate in trusted networks.
A Pinecone node is effectively a form of user-space hybrid router/switch. The switch has a number of “ports” which can connect to other Pinecone nodes using stream-oriented and reliable transports (such as TCP connections).
Each port is numbered. There is no requirement for a Pinecone node to have a specific number of ports. However, switch port 0 is always reserved for the local Pinecone router. Traffic going to and from the local node will always use this port. Port number assignment is an implementation-specific detail, although it typically makes sense to always assign the lowest free port number.
The router maintains state that allows it to participate in the network, including:
- Information about all directly connected peers, including their public key, last tree announcement received, how they are connected to us etc;
- Which of the node’s directly connected peers is our chosen parent in the tree, if any;
- A routing table, containing information about SNEK paths that have been set up through this node by other nodes;
- Information about our ascending and descending keyspace neighbours — that is, which node has the next highest (ascending) and next lowest (descending) key to the node’s own;
- A sequence number, used when operating as a root node and sending the nodes own root announcements into the network;
- Maintenance timers for tree and SNEK maintenance.
When receiving an incoming data frame on a port, the switch then uses the correct lookup method for the frame type to determine which port to forward the frame to.
Pinecone separates frames into two types: protocol frames and traffic frames.
Protocol frames often have specific rules governing their behaviour, including inspecting and processing the protocol control messages at intermediate or destination hops, and which routing scheme should be used to forward them onwards.
Traffic frames, on the other hand, are always forwarded using SNEK routing or tree routing (typically the former) and are not required to be otherwise inspected by an intermediate node.
If a suitable next-hop is identified, the frame will be forwarded to the chosen next-hop peer.