]> Sergey Matveev's repositories - vors.git/blob - doc/proto.texi
10fb381a89f09eb2dd9841a24d2473d148c44edfdecb68fda8486a6c76ca78d2
[vors.git] / doc / proto.texi
1 @node Protocol
2 @unnumbered Protocol
3
4 VoRS uses Opus codec with 20ms frames with 48kHz 1ch 16-bit S-LE sound.
5 It uses native @code{libopus}'es Packet Loss Concealment (PLC) feature
6 if number of lost frame does not excess 32 count.
7
8 Each frame has single byte stream identifier (unique identifier of the
9 participant) and 24-bit big-endian packet counter. Reordered packets are
10 dropped. 24-bit counter is long enough for very long talk sessions.
11
12 Each packet is encrypted with ChaCha20-Poly1305. Key is generated during
13 handshake procedure with the server and is shared among other participants.
14 Packet counter is used as a nonce. Stream identifier is additional
15 authenticated data.
16
17 It is tuned for 32Kbps bandwidth. 24Kbps should be enough, but 40B of
18 IPv6 header, +16B of Poly1305 authentication tag, +4B of stream
19 identifier with the counter, +8B of UDP header for 50pps means ~28Kbps
20 of bandwidth only for overhead transmission.
21
22 Each client handshakes with the server over TCP protocol using TLS 1.3
23 with curve25519 key-agreement protocol. @command{vors-keygen} generates
24 ed25519-based certificates -- so everything here is nearly completely
25 NIST-free.
26
27 After TLS session is established, simple text-based protocol is run:
28
29 @example
30 TLS 1.3:
31     S <- C : ClientHello
32     S -> C : ServerHello+ServerFinished
33     S <- C : ClientFinished
34
35 S -> C : HEX(128-bit random CHALLENGE)
36 S <- C : HEX(BLAKE2s-256(PASSWORD, CHALLENGE)) USERNAME
37 S -> C : OK SID
38
39 S <- C : PING
40 S -> C : PONG
41 S <> C : ...
42
43 S -> C : ADD SID USERNAME HEX(KEY)
44 S -> C : ...
45
46 S -> C : DEL SID
47 S -> C : ...
48 @end example
49
50 Client is authenticated by hashing the challenge with keyed hash. Every
51 ten seconds it PINGs server, awaiting for PONG in return. Server may
52 acknowledge client about new peer appearing, sending its SID (stream
53 identifier) in ASCII decimal form, username and encryption key. Also it
54 may notify about peer disappearing.
55
56 If client did not get @code{OK SID} reply, then it disconnects.
57 @code{SID} is our stream identifier. When we are successfully
58 authenticated, we both derive our encryption key for UDP packets by
59 "exporting keying material" (EKM) from TLS session context.
60
61 Every second client sends UDP packet with his single-byte stream
62 identifier, even if it is muted. That may help punching holes in
63 stateful firewalls.