Description
Full p2p connectivity requires NAT traversal (including the possibility of relaying messages between peers, e.g. STUN, TURN), so no p2p networking layer can be complete without incorporating a notion of p2p message routing.
In IPFS, p2p routing is solely the responsibility of the "Routing" layer (e.g. a Kademlia DHT).
Distinction
The line between Network
and Routing
layers is blurred significantly, and thus we must clearly distinguish the two responsibilities of Routing:
- Peer Routing, for peer-to-peer discovery and connectivity
- Content Routing, for data storage, discovery, and retrieval
To make this distinction more concrete, this essentially means splitting the Routing
interface:
type Routing interface {
PutValue(Key, Value)
GetValue(Key) Value
PutProvider(Key)
GetProviders(Key) []peer.ID
FindPeer(peer.ID) peer.Addr
}
into:
type ContentRouting interface {
PutValue(Key, Value)
GetValue(Key) Value
PutProvider(Key)
GetProviders(Key) []peer.ID
}
type PeerRouting interface {
FindPeer(peer.ID) peer.Addr
}
And allowing the Network
layer to use PeerRouting
. This cleanly
separates the layers and avoids confusion.
Important Routing Implementation Details
It should be noted that p2p content routing systems (beyond the context of ipfs) usually combine both Peer Routing and Content Routing. Consider, "Kademlia" which is the combination of "Kademlia Peer Routing" (address ring, buckets, xor distance, etc), and the "Kademlia DHT", which uses "Kademlia Peer Routing". From an implementation standpoint, it is much cleaner to think of the whole system.
Forcing implementors to completely separate these two components is difficult, and perhaps counter-productive. Thus IPFS implementations should be careful to make it possible for Routing layer implementations to solve both problems, and export two components, PeerRouting
and ContentRouting
. The Network
layer can then be a client of the PeerRouting
part.