Featured image of post Peer-to-Peer networking with libp2p

Peer-to-Peer networking with libp2p

Introduction

Traditional communication is client-server based. The client initiates a connection to the server, and communicates with the server using a protocol suited for that server. As an example: suppose we have two WhatsApp clients lets say A and B. And A wants to send a message to B. Typically, they both initiate a connection to the server. A sends a message to the server and tells the server to relay this message to B. The server knows both clients so this communication is pretty straightforward.

In a peer-to-peer network (P2P), this communication happens quite differently. There is no longer a server, only clients (commonly they are referred to as nodes or peers) organized in a mesh network, and they communicate directly to each other. For this to work a few challenges have to be solved:

  • How do the nodes know and find each other? In a client-server communication, the client established the connection to the server, and the server is known by some pre-defined ip address (or addresses). In a P2P mesh network how to know the ip address of the client? Potentially, the client is roaming which means its ip address can change over time. In libp2p this is solved by mDNS, DHT/Kademlia, and more.

  • How can a node directly connect to another node? In client-server communication, the client initiates a connection to the server. This is an outbound connection. However, in a P2P connection, a node connects directly to another node, which is an inbound connection. Inbound connections are not always possible. Think of security/firewall (the router rejects inbound connection attempts), but also think of NAT devices (what is the correct ip address? A node might know a different ip address of itself than the outside world is able to connect to) In libp2p this is solved by autonat, holepunching, relay-service, and more.

  • Which wire protocol to use? In a client-server network the used protocol is obvious: the server dictates the protocol to be used, or else it rejects the connection. A server can easily support the current protocol version while also supporting the older version(s) temporarily. A server can also force a client upgrade. In a P2P network this is not obvious, because there are several nodes connected to each other. They all could have a different implementation with different capabilities and with different versions In libp2p this is solved by multiformats.

  • How to distribute content? In a client/server setup, this is almost trivial. If node A wants to send something to node B it ’tags’ the message with an ‘address’ or ‘phone-number’ and sends it to the server. Since the server knows B it forwards this message directly to B. In a P2P connection, however, all nodes are interconnected via a mesh and perhaps A does not have a direct connection to B but has an indirect connection via some intermediate nodes C, D and E. If A wants to send something to B it has to send it to C. C has to send it to D and so on until it reaches B. It has to find a ‘route’ through all the nodes from A to B. And, for efficiency reasons, C should not forward the message to all its peers, because this will lead to congestion; all messages are send to each and every node. Ideally, C should send the message only to a node that is the most optimal node in the route to B (This is not always achievable). In libp2p this is solved using different pubsub mechanisms.

There already exists some P2P network protocols, but they lacked standardization. Libp2p standardizes they way nodes communicate to each other and has a solution for the above-mentioned issues (and more).

For an in-depth description of libp2p, please see: https://libp2p.io/

Built with Hugo
Theme Stack designed by Jimmy