forked from Green-Sky/tomato
Squashed 'external/toxcore/c-toxcore/' content from commit 67badf69
git-subtree-dir: external/toxcore/c-toxcore git-subtree-split: 67badf69416a74e74f6d7eb51dd96f37282b8455
This commit is contained in:
154
docs/TCP_Network.txt
Normal file
154
docs/TCP_Network.txt
Normal file
@ -0,0 +1,154 @@
|
||||
It has come to our attention that to achieve decent market penetration Tox
|
||||
must work behind ALL internet connections, may they be behind enterprise NATs
|
||||
or any other bad network conditions.
|
||||
|
||||
The people who have issues with the UDP direct connection approach seem to be a
|
||||
small minority though it is hard to estimate how many.
|
||||
|
||||
This means that routing their packets using good nodes on the network will
|
||||
probably not take a huge toll on the network and will assure that people
|
||||
can use Tox regardless of the quality of their internet connection.
|
||||
|
||||
|
||||
How it's going to work:
|
||||
1. Alice, a Tox client on a TCP only network generates a temporary public key
|
||||
and connects to a bootstrap node.
|
||||
|
||||
2. Using the bootstrap node she finds and connects to a couple (exact number
|
||||
to be determined later) number of random nodes that have TCP relay support.
|
||||
|
||||
3. She uses the onion through the TCP relay connections to send friend requests
|
||||
or tell online friends which TCP nodes she is connected to and her temporary
|
||||
public key.
|
||||
|
||||
4. Bob receives an onion packet from Alice telling him which nodes she is
|
||||
connected to. Bob connects to these nodes and establishes a routed connection
|
||||
with Alice using that temporary public key.
|
||||
|
||||
5. That connection is used by both to transmit encrypted Messenger and A/V
|
||||
packets.
|
||||
|
||||
6. If one of the nodes shuts down while it is currently routing traffic, Alice
|
||||
and bob just switch to one of the other nodes they are both connected to.
|
||||
|
||||
|
||||
Detailed implementation details:
|
||||
|
||||
There are two distinct parts for TCP relays, the client part and the server
|
||||
part.
|
||||
|
||||
The server acts as the actual relay. Servers must have fully forwarded TCP
|
||||
ports (NAT-PMP and uPNP can help here). The first port the server will try
|
||||
binding to is 443 followed by port 3389 and possibly some others. Onion packets
|
||||
can be sent/received through the TCP servers.
|
||||
|
||||
|
||||
Server:
|
||||
|
||||
The public/private key pair the TCP server uses is the same one he uses for the
|
||||
DHT.
|
||||
|
||||
all crypto for communication with the server uses the crypto_box() function of
|
||||
NaCl.
|
||||
|
||||
TCP doesn't have packets so what we will refer to as packets are sent this way:
|
||||
[[uint16_t (length of data)][data]]
|
||||
|
||||
So if you would inspect the TCP stream you would see:
|
||||
[[uint16_t (length of data)][data]][[uint16_t (length of
|
||||
data)][data]][[uint16_t (length of data)][data]]
|
||||
|
||||
Note that both handshake packets don't have this format (the length for them is
|
||||
always the same so we don't need to specify it.)
|
||||
|
||||
When the client connects to the server, he sends this packet:
|
||||
[public key of client (32 bytes)][nonce for the encrypted data [24
|
||||
bytes]][encrypted with the private key of the client and public key of the
|
||||
server and the nonce:[public key (32 bytes) and][base nonce we want the server
|
||||
to use to encrypt the packets sent to us (24 bytes)]]
|
||||
|
||||
The server responds with:
|
||||
[nonce for the encrypted data [24 bytes]][encrypted with the public key of the
|
||||
client and private key of the server and the nonce:[public key (32 bytes)
|
||||
and][base nonce we want the client to use to encrypt the packets sent to us (24
|
||||
bytes)]]
|
||||
|
||||
All packets to the server are end to end encrypted with the information
|
||||
received
|
||||
(and sent) in the handshake.
|
||||
|
||||
(first packet is encrypted with the base nonce the private key for which the
|
||||
client sent the server the public key and the public key we sent to the client,
|
||||
the next with base nonce + 1...)
|
||||
|
||||
The connection is set to an unconfirmed state until a packet is received and
|
||||
decrypted correctly using the information in the handshake.
|
||||
|
||||
each packet sent to/from the server has an id (the first byte of the plain text
|
||||
data of the packet.)
|
||||
|
||||
ids 0 to 15 are reserved for special packets, ids 16 to 255 are used to denote
|
||||
who we want the data to be routed to/who the packet is from.
|
||||
|
||||
special ids and packets:
|
||||
0 - Routing request.
|
||||
[uint8_t id (0)][public key (32 bytes)]
|
||||
1 - Routing request response.
|
||||
[uint8_t id (1)][uint8_t (rpid) 0 if refused, packet id if accepted][public key
|
||||
(32 bytes)]
|
||||
2 - Connect notification:
|
||||
[uint8_t id (2)][uint8_t (packet id of connection that got connected)]
|
||||
3 - Disconnect notification:
|
||||
[uint8_t id (3)][uint8_t (packet id of connection that got disconnected)]
|
||||
4 - ping packet
|
||||
[uint8_t id (4)][uint64_t ping_id (0 is invalid)]
|
||||
5 - ping response (pong)
|
||||
[uint8_t id (5)][uint64_t ping_id (0 is invalid)]
|
||||
6 - OOB send
|
||||
[uint8_t id (6)][destination public key (32 bytes)][data]
|
||||
7 - OOB recv
|
||||
[uint8_t id (7)][senders public key (32 bytes)][data]
|
||||
8 - onion packet (same format as initial onion packet (See: Prevent
|
||||
tracking.txt) but packet id is 8 instead of 128)
|
||||
9 - onion packet response (same format as onion packet with id 142 but id is 9
|
||||
instead.)
|
||||
|
||||
The rest of the special ids are reserved for possible future usage.
|
||||
|
||||
If the server receives a routing request he stores server side that the client
|
||||
wants to connect to the person with that public key and sends back a Routing
|
||||
request response with the rpid along with the public key sent in the request.
|
||||
|
||||
If for some reason the server must refuse the routing request (too many) he
|
||||
sends the response with a rpid of 0.
|
||||
|
||||
If the person who the client wants to connect to is also online and wants to
|
||||
connect to the client a connect notification is sent to both with the
|
||||
appropriate packet id.
|
||||
|
||||
If either one disconnects, a disconnect notification is sent to the other with
|
||||
appropriate packet id.
|
||||
|
||||
If a client sends a disconnect notification, the entry on the server for that
|
||||
routed connection is cleared and a disconnect notification is sent to the peer
|
||||
(if he was online)
|
||||
|
||||
If the server receives an onion packet he handles it the same as he would if it
|
||||
was one received normally via UDP, he must also assure himself that any
|
||||
responses must be sent to the proper client.
|
||||
|
||||
Ping responses must have the same ping_id as the request.
|
||||
|
||||
If the server receives a ping packet he must respond with a ping response.
|
||||
|
||||
The server will send a ping packet to clients every 30 seconds, they have 30
|
||||
seconds to respond, if they don't the connection is deleted.
|
||||
|
||||
OOB send packets will be sent to the peer connected to the TCP server with the
|
||||
destination public key as a OOB recv packet. The client sending this packet has
|
||||
no way of knowing if the packet reached its destination.
|
||||
|
||||
|
||||
Client:
|
||||
|
||||
Implementation details coming soon.
|
Reference in New Issue
Block a user