summaryrefslogtreecommitdiffstats
path: root/doc/proto-doc-latest.txt
blob: 2ba4cd557d11603c7ee173aa0e9e000e2f918e50 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
Protocol Specification.

Terminology.

Client - a software instance that interacts with human users and lets them send
and receive encrypted messages over Pica Pica.

Node - a software instance that coordinates the Pica Pica network, maintains a
list of all active nodes and provides connectivity to clients.

UH - user hash - the SHA224 hash of a user certificate in DER format, 28
octets. It is used as a user identifier.

Connections.
There are 4 types of connections between Pica Pica nodes and clients.

-client to node (c2n) - a control connection from client to node

-client to client (c2c) - a data connection between clients through a node
acting as a proxy

-node to node (n2n) - a control & data connection between nodes

-direct client to client (directc2c) - a direct connection between clients,
using the IPv4/IPv6/DNS address of the accepting client previously
communicated over a c2c connection.

These connections use TCP transport. The first 3 connection types start
with a TLS 1.2 handshake using an anonymous Diffie-Hellman ciphersuite; the
connecting host acts as the TLS client, the accepting host as the TLS server.
After the connection type is identified by the accepting node, the anonymous
TLS session is gracefully closed in the case of c2n and c2c connections. In the
case of c2n the node starts a new TLS session with the client, where the node
acts as the TLS client and the client acts as the TLS server, using the
client's RSA certificate. In the case of a c2c connection the node acts as a
transparent proxy, sending chunks of data received from the first client to the
second one and vice versa. The clients establish a mutually authenticated TLS
session over the proxied connection; the initiator client is the TLS client,
the accepting client has the TLS server role.
An n2n connection continues to operate in the ADH TLS session, as by design
nodes do not store any state that identifies them other than their network
address.


Packet Format.

A Pica Pica protocol message packet contains a header and a tail.

[Header][Tail]

The header is a 2-octet sequence that identifies the packet. The first and
second octets are always equal to each other.
The tail is the remaining part of the packet and can be empty. The tail can
have a fixed predefined length or, in the case of a variable length packet, it
begins with a 1- or 2-octet sequence containing an unsigned integer that
defines the length in octets of the remaining part of the tail, not including
the length octets. The length field is stored in little-endian format, least
significant octet first.
The whole packet length is limited to 65536 octets, so the length field value
is within the 0..65532 range.

Example:

0x55 0x55 0x03 0x00 0xAA 0xBB 0xCC
[0x55 0x55] - header
[0x03 0x00] - tail length, 2 octets
[0xAA 0xBB 0xCC] - payload, 3 octets


C2N Messages.
====================================================
C2N connection initialization request.
Sent by the client.
ANON TLS

[0xCA 0xCA][VER_MAJOR][VER_MINOR]

4 octets

VER_MAJOR, VER_MINOR - the Pica Pica protocol version supported by the client

====================================================
C2N connection initialization success.
Sent by the node.
ANON TLS

[0x01 0x01]['O']['K']

4 octets

After this message the client and the node initiate an ANON TLS session
shutdown, and after a successful shutdown they initiate a new authenticated TLS
session over the same TCP connection. The client acts as the TLS server and
presents the client certificate; the node acts as the TLS client and does not
present a certificate.
====================================================
Protocol version mismatch.
Sent by the node.
ANON TLS

[0x02 0x02][VER_MAJOR][VER_MINOR]

4 octets

VER_MAJOR, VER_MINOR - the Pica Pica protocol version supported by the node

This message is sent if the node's and the client's protocol versions do not
match. After this message is sent and received, the TCP connection is closed by
both hosts.
====================================================

	The messages below are transmitted over the secure c2n control
	connection between a client and a node.

====================================================
Request to establish a connection with a peer.
Sent by the client.

[0x03 0x03][UH of the called user]

30 octets
====================================================
Incoming connection permission request.
Sent by the node.

[0x04 0x04][UH of the initiator]

30 octets
====================================================
The user with the given UH was not found (offline, or refused to talk).
Sent by the node.

[0x05 0x05][UH of the called user]

30 octets
====================================================
Connection allowed by the called user.
Sent by the called client.

[0x06 0x06][UH of the calling user]

30 octets

After sending this message, the called client connects to the node's data
exchange port (_DATA_PORT) and sends message 0x20 - new connection
identification - over that connection.
====================================================
The user with the given UH was found and is ready to talk.
Sent by the node to the calling client.

[0x07 0x07][UH of the called user]

30 octets
====================================================
Connection denied.
Sent by the called client.

[0x08 0x08][UH of the calling user]

30 octets
====================================================
Node list request.
Sent by the client.

[0x09 0x09][2 pseudo-random octets]

4 octets
====================================================
Node list.
Sent by the node.

[0x0A 0x0A] - see the 0xA4 message format
====================================================
Multilogin notification.
Sent by a client that has logged in. Relayed to other nodes.
Delivered to the existing connected client instance.

[0x0E 0x0E][length 2 octets][timestamp][node address][signature from UH, timestamp, node
address]

timestamp - the time when the client logged in, a 64-bit Unix timestamp in the
UTC timezone

node address - one of the 0xA0, 0xA1, 0xA2 messages; the announced address of
the node the sending client is connected to.

signature - a digital signature using the SHA224 hash and the private RSA key
of the sending client. The signature is calculated from the sender's
concatenated UH, timestamp and node address = Sign(UH|timestamp|node address)

====================================================

	The message below is transmitted over the connection between a node
	and a client which is used for data transfer.

====================================================
New connection identification.
Sent by the client.

[0x20 0x20][UH of the calling user][UH of the called user]

58 octets

Upon receiving this message the node checks the UHs. If they do not match, the
connection is closed. After the check the node switches into data relaying mode
between the two clients. The calling client initiates TLS connection
establishment.
====================================================


C2C Messages.
The messaging protocol between clients through node(s).
====================================================
C2C connection initialization request.
Sent by a client to another client.

[0xCC 0xCC][VER_MAJOR][VER_MINOR]

4 octets

VER_MAJOR, VER_MINOR - the c2c protocol version supported by the client

Possible responses - 0x01, 0x02
====================================================
Client direct address list.

[0x0B 0x0B] - see the 0xA4 message format
0xA0, 0xA1, 0xA2 - the same as in n2n messages

If a client is configured to accept incoming direct client to client
connections (bypassing the node), it can send a list of its own addresses.
Local network addresses (if there are any) from the 192.168.0.0/16,
172.16.0.0/12 and 10.0.0.0/8 subnets must be placed first in the list, so that
clients residing in the same local network are able to connect directly. Public
internet addresses follow them.
If the client is behind NAT and forwards an open port to its local address, the
external port number must be specified in the address.
Having received the announcement, the other client can create a connection to
that address and close the connection through the node.
====================================================
Direct connection attempts failed.

[0x0C 0x0C][2 pseudo-random octets]

4 octets

Sent by the initiator if it has received a direct address list from the called
client and all connection attempts to the received addresses were unsuccessful.
After receiving this message, the called client starts connection attempts to
the direct addresses of the initiator, if an address list was received from the
initiator and direct connections are allowed by the called client's settings.
====================================================
Switch to direct connection.

[0x0D 0x0D][2 pseudo-random octets]

4 octets

Sent by each side over the connection through the node after a successful TLS
handshake on the direct connection. After sending this message, all subsequent
messages are sent over the direct connection; the receiver of the message
correspondingly expects subsequent messages over the direct connection.
====================================================
Message - UTF-8 encoded text.

[0x30 0x30][length 2 octets][UTF-8 encoded message]
====================================================
Delivery report for the previous message.

[0x40 0x40][2 pseudo-random octets]

4 octets
====================================================
File sending request.

[0x50 0x50][length 2 octets, 9..263][file size, 8 octets][file name in UTF-8, 1 - 255 octets]
====================================================
File accepted.

[0x51 0x51][2 pseudo-random octets]

4 octets

After receiving this message, the sender starts sending the file.
====================================================
File rejected.

[0x52 0x52][2 pseudo-random octets]

4 octets
====================================================
File fragment.

[0x53 0x53][fragment length, 2 octets, 0 - 65532][file fragment]
====================================================
File transfer control.

[0x54 0x54][sender command][receiver command]

4 octets

Commands:
00 - void command (no action)
01 - pause
02 - resume
03 - cancel
04 - cancel because of a file read/write error
====================================================


Audio and Video Calls.
Sent between clients over a c2c or directc2c connection.
====================================================
Call request (ring)

[0x70 0x70]
[2 pseudo-random octets]

4 octets
====================================================
Call answer (pick up)

[0x71 0x71]
[2 pseudo-random octets]

4 octets
====================================================
Call reject

[0x72 0x72]
[2 pseudo-random octets]

4 octets
====================================================
Call hang up (finished)

[0x73 0x73]
[2 pseudo-random octets]

4 octets
====================================================
Audio stream parameters

[0x74 0x74]
[codec - a 20 octet string, left-aligned, padded with zeroes;
"opus", "adpcm_g722", "pcm_alaw", named as in ffmpeg]
[sample rate, uint16_t, little-endian]

24 octets
====================================================
Video stream parameters

[0x75 0x75]
[codec - a 20 octet string, left-aligned, padded with zeroes, e.g.
"hevc", "h264", "mjpeg", "vp9", named as in ffmpeg]
[width, uint16_t, little-endian]
[height, uint16_t, little-endian]

26 octets
====================================================
Voice (audio) packet

[0x76 0x76][length 2 octets][sequence number, uint16_t, little-endian][timestamp, uint32_t, little-endian, milliseconds since the start of the call][data]

length - covers everything following it: the 2-octet sequence number, the
4-octet timestamp and the data, i.e. data length + 6.

sequence number - incremented by one for every audio packet sent over this
call, wraps around at 65536. Since c2c/directc2c connections are carried
over TCP, packets already arrive in order and without loss; the sequence
number's purpose is to let the receiving side detect encoder-side gaps (e.g.
a dropped capture buffer) and, in the future, to support delivery over an
unordered/lossy transport (e.g. UDP).

timestamp - the capture timestamp of the packet's first sample, in
milliseconds, relative to the moment the call became active (the 0x71
message was processed). Used by the receiver for playout-buffer timing and
audio/video synchronization.
====================================================
Video packet

[0x77 0x77][length 2 octets][sequence number, uint16_t, little-endian][timestamp, uint32_t, little-endian, milliseconds since the start of the call][data]

length - covers everything following it: the 2-octet sequence number, the
4-octet timestamp and the data, i.e. data length + 6.

sequence number - the most significant bit (0x8000) is the last fragment
marker, see the fragmentation description below. The remaining 15 bits are a
counter incremented by one for every video packet sent over this call,
wrapping around at 32768. The counter serves the same purpose as in the 0x76
message: gap detection and future unordered/lossy transport support.

timestamp - the capture timestamp of the encoded video frame, in
milliseconds, relative to the moment the call became active. Used by the
receiver for playout timing and audio/video synchronization. All fragments
of one encoded frame carry the same timestamp, see below.

Fragmentation.

The length field limits the data carried by a single 0x77 message to 65526
octets, while an encoded video frame - an intra-coded (key) frame in
particular - can be larger than that. Such a frame is split into several
consecutive 0x77 messages.

All fragments of one encoded frame carry the same timestamp; the 15-bit
counter part of the sequence number is incremented for every fragment, as it
is for every other video packet. The last fragment of a frame has the last
fragment marker bit (0x8000) set in its sequence number; every preceding
fragment of the same frame has that bit cleared. A frame that fits into a
single message is sent as one message with the marker bit set.

The receiving side concatenates the data of the received fragments in the
order they arrive, and passes the result to the video decoder once a message
with the marker bit set has been received.
====================================================


Ping.
Can be sent by either side, both over the c2n control connection and over a
connection between clients.
====================================================
Ping request.

[0x68 0x68][2 pseudo-random octets]

4 octets
====================================================
Ping reply.

[0x69 0x69][2 pseudo-random octets]

4 octets
====================================================


N2N Messages.
The inter-node interaction protocol.
====================================================
Node connection request.
Sent by one node to another.

[0xCB 0xCB][VER_MAJOR][VER_MINOR]

4 octets

VER_MAJOR, VER_MINOR - the Pica Pica protocol version supported by the node

Possible responses - 0x01, 0x02 - the same as for a client
====================================================
New node announcement - IPv4 address.

[0xA0 0xA0][IP address of the new node - 4 octets, network byte order][port number - 2 octets, network byte order]

8 octets
====================================================
New node announcement - IPv6 address.

[0xA1 0xA1][IPv6 address of the new node - 16 octets, network byte order][port number - 2 octets, network byte order]

20 octets
====================================================
New node announcement - DNS address.

[0xA2 0xA2][address length - 1 octet][DNS address of the new node][port number - 2 octets, network byte order]
====================================================

The address declared in the announcement must match the address from which the
connection was made. The node that receives the announcement must verify this.

====================================================
Node list.

[0xA4 0xA4][address list size in octets, 2 octets - 0..65532][address list]

The address list is a sequence of elements of 3 possible types
[0xA0][IP address - 4 octets][port number - 2 octets] - 7 octets
[0xA1][IPv6 address][port number - 2 octets] - 19 octets
[0xA2][address length - 1 octet][DNS address][port number - 2 octets] - 4 ... 259 octets

The sending node's own address (in the given address space) always goes first
in the list.
A message can contain only a part of the node list instead of the whole list;
in that case the whole list is sent in parts. Addresses and port numbers are in
"network" byte order.
The whole packet size does not exceed 64kb.
====================================================
Node list request.

[0x90 0x90][2 pseudo-random octets]

4 octets
====================================================
Client search.
Sent to all nodes. The receiving node replies to this message only if the
requested UH is found among its local clients or in its cache.

[0xA5 0xA5][UH of the called user]

30 octets
====================================================
Client search result - client found.
Sent by a node that received 0xA5, if the requested UH is found among its local
connected clients.

[0xA8 0xA8][UH of the called user]

30 octets
====================================================
Client search result - client found in cache.
Sent by a node that received 0xA5, if the requested UH is found in its cache
(i.e. there is information that the client being searched for is connected to
another node).

[0xA9 0xA9][size, 2 octets, 32..287][UH of the called user][address of the node where the requested UH may be located, in A0|A1|A2 format, see the 0xA4 description]
====================================================
Request to allow a connection with a client of the receiving node.

[0xAA 0xAA][UH of the initiator][UH of the called user]

58 octets
====================================================
Connection allowed by the called user.
Sent after the called local client has replied with a 0x06 message and created
a new connection for message exchange.

[0xAB 0xAB][UH of the initiator][UH of the called user]

58 octets
====================================================
Client not found (offline, or refused to talk).

[0xB8 0xB8][UH of the initiator][UH of the called user]

58 octets

Sent by a node in reply to a 0xD0 message addressed to this UH, if that user
has already disconnected or is not in the list of local clients, or in reply to
0xAA, if the called client denied the connection.
====================================================
Message transmitted between nodes on behalf of clients.

[0xD0 0xD0][embedded message length in octets, 56..65532, 2 octets little-endian][UH of the local sending user][UH of the user on another node][embedded data]

embedded data - data transmitted over the CLIENT-CLIENT connection
====================================================