120 lines
4.7 KiB
Markdown
120 lines
4.7 KiB
Markdown
# 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.
|
|
|
|
#### 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.
|
|
|
|
#### Message Type *Pong*
|
|
|
|
- Message Type `0x04`
|
|
|
|
A message which MUST ONLY be originated by a node in response to a previous *Ping* message.
|
|
|
|
|
|
### Chat
|
|
|
|
TODO
|
|
|
|
## Installation
|
|
|
|
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
|
|
by adding `p2p_chat` to your list of dependencies in `mix.exs`:
|
|
|
|
```elixir
|
|
def deps do
|
|
[
|
|
{:p2p_chat, "~> 0.1.0"}
|
|
]
|
|
end
|
|
```
|
|
|
|
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
|
|
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
|
|
be found at <https://hexdocs.pm/p2p_chat>.
|
|
|