mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
146 lines
5.7 KiB
Plaintext
146 lines
5.7 KiB
Plaintext
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 recieved 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]
|
|
5 - ping response (pong)
|
|
[uint8_t id (5)][uint64_t ping_id]
|
|
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 recieves 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.
|
|
|
|
Client:
|
|
|
|
Implementation details coming soon.
|