- Elixir 52.7%
- Rust 42.6%
- Nix 4.7%
| lib | ||
| native/p2pchat_transport_tuntapport | ||
| priv/native | ||
| test | ||
| .envrc | ||
| .formatter.exs | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| flake.lock | ||
| flake.nix | ||
| mix.exs | ||
| mix.lock | ||
| README.md | ||
P2pChat
Wire-Protocol
The protocol is separated into two parts. The lower layer takes care of p2p coordination while the upper chat layer sits on top of it.
P2P
This protocol layer takes care of establishing a coherent Peer-to-Peer network over which arbitrary data can be transported from one node to another without regard to the underlying network topology.
It requires datagram transport from the IP layer between nodes full messh reachability is not required. To upper layers (e.g. the chat protocol) it offers unreliable transport between arbitrary nodes of the network and addressing by node IDs instead of IP addresses.
Concepts
- netid: A unique 32bit identifier of each node
- local neighbor: A local neighbor of node A is another node B that can be directly contacted by node A without NAT or firewalling.
- remote neighbor: A remote neighbor of node A is another node B that is part of the same P2P network but which cannot be reached directly via UDP datagrams and only through traversing the P2P network.
General Protocol Provisions
The protocol is encoded in binary and uses the following common header:
0 7 8 15 16 23 24 31
+-----------+-----------+-----------+------------+
| magic | version | message | flags |
| | | type | |
+-----------+-----------+-----------+------------+
| nonce |
| |
+-----------+-----------+-----------+------------+
| src netid |
| |
+-----------+-----------+-----------+------------+
| dst netid |
| |
+-----------+-----------+-----------+------------+
- magic: The 8 bit constant value
0xAC. It identifies this message as a P2P message. - version: 8 bit unsigned integer denoting the protocol version. In this spec always
0x01. - message type: 8 bit identifying the type of payload this message carries.
- nonce: A 32 bit, randomly generated, unique number associated with each packet.
- src netid: The unique identifier of the node who originated this message.
- dst netidc: The unique identifier of the node who this message is intended for.
| Flag Bit | Name | Description |
|---|---|---|
10000000 |
NO_FORWARD | This message should not be forwarded even if the recipient is not the target node |
01000000 |
reserved | |
00100000 |
reserved | |
00010000 |
reserved | |
00001000 |
reserved | |
00000100 |
reserved | |
00000010 |
reserved | |
00000001 |
reserved |
If a node receives a message without the NO_FORWARD flag set, and its own netid is not the dst netid, then it SHOULD forward the message unaltered to all its connected neighbors. To prevent packet loops, all participating nodes MUST store a hash of each received packet and not forward packets again that it has already processed. The local hash table SHOULD NOT be cleared more often than every 5 minutes.
Special netids
The following special netids are defined:
| netid | name | description |
|---|---|---|
0 |
any node | For message forwarding, all nodes consider this dst netid their own and do not forward the message |
0xFFFFFFFF |
all nodes | For message forwarding, all nodes consider dst netid their own and forward the message to all their neighbors |
Message Type Hello
- Message Type:
0x01
This message is the introductory message that a new node sends to any node of the network it can reach and which identifies the new one. It has no payload.
Any node which receives a Hello message SHOULD add the sending node to it's local neighbor table and associate the src IP address of the packet with that sending node.
Message Type Goodbye
- Message Type:
0x02
This message type MAY be sent by a node who is going offline or which is intending to leave the network. It has no payload.
Message Type Ping
- Message Type
0x03
A message which MAY be originated by a node to check for reachability of other nodes in the network. Nodes which receive this message SHOULD respond with a Pong message. It has no payload.
Message Type Pong
- Message Type
0x04
A message which MUST ONLY be originated by a node in response to a previous Ping message. It has no payload.
Message Type Inform
- Message Type
0x05
This message may be sent by a node to inform it's neighbors about other neighbors.
For example, if Node A is a local neighbor of Node B, Node B could use this message to signal a third Node C that Node A exists. Node C could then try to reach Node A on it's own and/or add it to it's remote neighbor table.
It has the following payload:
0 7 8 15 16 23 24 31
+-----------+-----------+-----------+------------+
| subject netid |
| |
+-----------+-----------+-----------+------------+
| subject ip address |
| |
+ + + + +
| |
| |
+ + + + +
| |
| |
+ + + + +
| |
| |
+-----------+-----------+-----------+------------+
| subject port |
| |
+-----------+-----------+
- subject netid: The netid of the third node which is being informed about (Node A in the example above).
- subject ip address: The IP Address at which the third node was reachable for the node which originated this message.
It is always assumed to be an IPv6 address by default but the special IPv4-mapped address space
::ffff:0:0/96may be used to encode an IPv4 address in the last 32 bits. - subject port: The port at which the third node was reachable for the node with originated this message.
Message Type Data
- Message Type
0x10
This message is used for actual data transfer between nodes. It's payload makes up the remainder of the UDP datagram and the content is up to the upper protocol to decide.
Chat
TODO
Installation
If available in Hex, the package can be installed
by adding p2p_chat to your list of dependencies in mix.exs:
def deps do
[
{:p2p_chat, "~> 0.1.0"}
]
end
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/p2p_chat.