diff options
-rw-r--r-- | docs/Avatars.md | 144 | ||||
-rw-r--r-- | docs/Tox_middle_level_network_protocol.txt | 68 |
2 files changed, 106 insertions, 106 deletions
diff --git a/docs/Avatars.md b/docs/Avatars.md index 31138af7..9dd43079 100644 --- a/docs/Avatars.md +++ b/docs/Avatars.md | |||
@@ -12,7 +12,7 @@ This document describes the implementation of avatars in the Tox protocol, | |||
12 | according to the following design considerations: | 12 | according to the following design considerations: |
13 | 13 | ||
14 | - Avatars are handled as private information, i.e., they are only exchanged | 14 | - Avatars are handled as private information, i.e., they are only exchanged |
15 | over Tox encrypted channels among previously authenticated friends; | 15 | over Tox encrypted channels among previously authenticated friends. |
16 | 16 | ||
17 | - The library treats all images as blobs and does not interpret or | 17 | - The library treats all images as blobs and does not interpret or |
18 | understand image formats. It only ensures that the avatar data sent by | 18 | understand image formats. It only ensures that the avatar data sent by |
@@ -33,7 +33,7 @@ according to the following design considerations: | |||
33 | - The protocol MUST provide means to allow caching and avoid unnecessary | 33 | - The protocol MUST provide means to allow caching and avoid unnecessary |
34 | data transfers. | 34 | data transfers. |
35 | 35 | ||
36 | - Avatars are transfered between clients in a background operation. | 36 | - Avatars are transferred between clients in a background operation. |
37 | 37 | ||
38 | - Avatars are served on a "best effort" basis, without breaking clients | 38 | - Avatars are served on a "best effort" basis, without breaking clients |
39 | which do not support them. | 39 | which do not support them. |
@@ -76,7 +76,7 @@ protocol. Moving this feature to the core protocol also: | |||
76 | This is a very high level description. The usage patterns expected from | 76 | This is a very high level description. The usage patterns expected from |
77 | client applications are described in the section "Using Avatars in Client | 77 | client applications are described in the section "Using Avatars in Client |
78 | Applications", and a low level protocol description is available in the | 78 | Applications", and a low level protocol description is available in the |
79 | section "Internal Protocol Description".) | 79 | section "Internal Protocol Description"). |
80 | The avatar exchange is implemented with the following new elements in the | 80 | The avatar exchange is implemented with the following new elements in the |
81 | Tox protocol: | 81 | Tox protocol: |
82 | 82 | ||
@@ -84,7 +84,7 @@ Tox protocol: | |||
84 | a user to another anytime, but are usually sent after one of them | 84 | a user to another anytime, but are usually sent after one of them |
85 | connects to the network, changes his avatar, or in reply to an **avatar | 85 | connects to the network, changes his avatar, or in reply to an **avatar |
86 | information request**. They are delivered by a very lightweight message | 86 | information request**. They are delivered by a very lightweight message |
87 | but with information enough to allow a user to validate or discard an | 87 | but with enough information to allow a user to validate or discard an |
88 | avatar from the local cache and to decide if it is interesting to request | 88 | avatar from the local cache and to decide if it is interesting to request |
89 | the avatar data from the peer. | 89 | the avatar data from the peer. |
90 | 90 | ||
@@ -115,7 +115,7 @@ Tox protocol: | |||
115 | 115 | ||
116 | This event contains three data fields: (1) the image format, (2) the | 116 | This event contains three data fields: (1) the image format, (2) the |
117 | cryptographic hash of the image data, and (3) the raw image data. If the | 117 | cryptographic hash of the image data, and (3) the raw image data. If the |
118 | image format is NONE (i.e. no avatar) the hash is zeroed and the image | 118 | image format is NONE (i.e. no avatar), the hash is zeroed and the image |
119 | data is empty. The raw image data is locally validated and ensured to | 119 | data is empty. The raw image data is locally validated and ensured to |
120 | match the hash (the event is **not** triggered otherwise). | 120 | match the hash (the event is **not** triggered otherwise). |
121 | 121 | ||
@@ -146,13 +146,13 @@ TOX_AVATAR_FORMAT; | |||
146 | /* Set the user avatar image data. */ | 146 | /* Set the user avatar image data. */ |
147 | int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length); | 147 | int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length); |
148 | 148 | ||
149 | /* Removes the user avatar image data. */ | 149 | /* Remove the user avatar image data. */ |
150 | int tox_unset_avatar(Tox *tox); | 150 | int tox_unset_avatar(Tox *tox); |
151 | 151 | ||
152 | /* Get avatar data from the current user. */ | 152 | /* Get avatar data from the current user. */ |
153 | int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, uint8_t *hash); | 153 | int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, uint8_t *hash); |
154 | 154 | ||
155 | /* Generates a cryptographic hash of the given data (usually a cached avatar). */ | 155 | /* Generate a cryptographic hash of the given data (usually a cached avatar). */ |
156 | int tox_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen); | 156 | int tox_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen); |
157 | 157 | ||
158 | /* Request avatar information from a friend. */ | 158 | /* Request avatar information from a friend. */ |
@@ -181,17 +181,17 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint | |||
181 | 181 | ||
182 | - Clients MUST NOT imply the availability of avatars in other users. | 182 | - Clients MUST NOT imply the availability of avatars in other users. |
183 | Avatars are an optional feature and not all users and clients may | 183 | Avatars are an optional feature and not all users and clients may |
184 | support them; | 184 | support them. |
185 | 185 | ||
186 | - Clients MUST NOT block waiting for avatar information and avatar data | 186 | - Clients MUST NOT block waiting for avatar information and avatar data |
187 | packets; | 187 | packets. |
188 | 188 | ||
189 | - Clients MUST treat avatar data as insecure and potentially malicious; | 189 | - Clients MUST treat avatar data as insecure and potentially malicious. |
190 | For example, users may accidentally use corrupted images as avatars, | 190 | For example, users may accidentally use corrupted images as avatars, |
191 | a malicious user may send a specially crafted image to exploit a know | 191 | a malicious user may send a specially crafted image to exploit a known |
192 | vulnerability in an image decoding library, etc. It is recommended to | 192 | vulnerability in an image decoding library, etc. It is recommended to |
193 | handle the avatar image data in the same way as an image downloaded | 193 | handle the avatar image data in the same way as an image downloaded |
194 | from an unknown Internet source; | 194 | from an unknown Internet source. |
195 | 195 | ||
196 | - The peers MUST NOT assume any coupling between the operations of | 196 | - The peers MUST NOT assume any coupling between the operations of |
197 | receiving an avatar information packet, sending unrequested avatar | 197 | receiving an avatar information packet, sending unrequested avatar |
@@ -200,36 +200,36 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint | |||
200 | For example, the following situations are valid: | 200 | For example, the following situations are valid: |
201 | 201 | ||
202 | * A text-mode client may send avatars to other users, but never | 202 | * A text-mode client may send avatars to other users, but never |
203 | request them; | 203 | request them. |
204 | 204 | ||
205 | * A client may not understand a particular image format and ignore | 205 | * A client may not understand a particular image format and ignore |
206 | avatars using it, but request and handle other formats; | 206 | avatars using it, but request and handle other formats. |
207 | 207 | ||
208 | * A client on a slow mobile network may ask for avatar information to | 208 | * A client on a slow mobile network may ask for avatar information to |
209 | ensure its cached avatars are still valid, but do not request avatar | 209 | ensure its cached avatars are still valid, but not request avatar |
210 | data. The same client may start asking for avatar data once it | 210 | data. The same client may start asking for avatar data once it |
211 | connects through a fast network. | 211 | connects through a fast network. |
212 | 212 | ||
213 | - Clients SHOULD implement a local cache of avatars and do not request | 213 | - Clients SHOULD implement a local cache of avatars and not request |
214 | avatar data from other peers unless necessary; | 214 | avatar data from other peers unless necessary. |
215 | 215 | ||
216 | - When an avatar information is received, the client should delete the | 216 | - When avatar information is received, the client should delete the |
217 | avatar if the new avatar format is NONE or compare the hash received | 217 | avatar if the new avatar format is NONE or compare the hash received |
218 | from the peer with the hash of the currently cached avatar. If they | 218 | from the peer with the hash of the currently cached avatar. If they |
219 | differ, send an avatar data request; | 219 | differ, send an avatar data request. |
220 | 220 | ||
221 | - If the cached avatar is older than a given threshold, the client may | 221 | - If the cached avatar is older than a given threshold, the client may |
222 | also send an avatar info request to that friend once he is online and | 222 | also send an avatar info request to that friend once he is online and |
223 | mark the avatar as updated *before* any avatar information is received | 223 | mark the avatar as updated *before* any avatar information is received |
224 | (to not spam the peer with such requests); | 224 | (to not spam the peer with such requests). |
225 | 225 | ||
226 | - When an avatar data notification is received, the client must update | 226 | - When an avatar data notification is received, the client must update |
227 | the cached avatar with the new one; | 227 | the cached avatar with the new one. |
228 | 228 | ||
229 | - Clients should resize or crop the image to the way it better adapts | 229 | - Clients should resize or crop the image such that it better adapts |
230 | to the client user interface; | 230 | to the client's user interface. |
231 | 231 | ||
232 | - If the user already have an avatar defined in the client configuration, | 232 | - If the user already has an avatar defined in the client configuration, |
233 | it must be set before connecting to the network to avoid spurious avatar | 233 | it must be set before connecting to the network to avoid spurious avatar |
234 | change notifications and unnecessary data transfers. | 234 | change notifications and unnecessary data transfers. |
235 | 235 | ||
@@ -241,10 +241,10 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint | |||
241 | ### Interoperability and sharing avatars among different clients | 241 | ### Interoperability and sharing avatars among different clients |
242 | 242 | ||
243 | **This section is a tentative recommendation of how clients should store | 243 | **This section is a tentative recommendation of how clients should store |
244 | avatars to ensure local interoperability and should be revised if this | 244 | avatars to ensure local interoperability, and should be revised if this |
245 | code is accepted into Tox core.** | 245 | code is accepted into Tox core.** |
246 | 246 | ||
247 | It is desirable that the user avatar and the cached friends avatars could be | 247 | It is desirable that the user avatar and the cached friends' avatars could be |
248 | shared among different Tox clients in the same system, in the spirit of the | 248 | shared among different Tox clients in the same system, in the spirit of the |
249 | proposed Single Tox Standard. This not only makes switching from one client | 249 | proposed Single Tox Standard. This not only makes switching from one client |
250 | to another easier, but also minimizes the need of data transfers, as avatars | 250 | to another easier, but also minimizes the need of data transfers, as avatars |
@@ -262,10 +262,10 @@ Given the Tox data directory described in STS Draft v0.1.0: | |||
262 | - The client's own avatar is not special and is stored like any other. This | 262 | - The client's own avatar is not special and is stored like any other. This |
263 | is partially for simplicity, and partially in anticipation of profiles. | 263 | is partially for simplicity, and partially in anticipation of profiles. |
264 | 264 | ||
265 | - The avatar should be stored as its received, before any modifications by | 265 | - The avatar should be stored as it was received, before any modifications by |
266 | the client for display purposes. | 266 | the client for display purposes. |
267 | 267 | ||
268 | - The hash, as calculated by toxcore and passed in to the data callback, | 268 | - The hash, as calculated by toxcore and passed into the data callback, |
269 | should be saved in "avatars/xxxxx.hash" where "xxxxx" means the | 269 | should be saved in "avatars/xxxxx.hash" where "xxxxx" means the |
270 | same thing as for avatars. (The filename is longer than the file :) ) | 270 | same thing as for avatars. (The filename is longer than the file :) ) |
271 | 271 | ||
@@ -273,7 +273,7 @@ Given the Tox data directory described in STS Draft v0.1.0: | |||
273 | upper case strings, but lower case file names are more usual. | 273 | upper case strings, but lower case file names are more usual. |
274 | 274 | ||
275 | 275 | ||
276 | Example for Linux and other Unix systems, assuming an user called "gildor": | 276 | Example for Linux and other Unix systems, assuming a user called "gildor": |
277 | 277 | ||
278 | Tox data directory: /home/gildor/.config/tox/ | 278 | Tox data directory: /home/gildor/.config/tox/ |
279 | Tox data file: /home/gildor/.config/tox/data | 279 | Tox data file: /home/gildor/.config/tox/data |
@@ -294,13 +294,13 @@ This recommendation is partially implemented by "testing/test_avatars.c". | |||
294 | 294 | ||
295 | ### Common operations | 295 | ### Common operations |
296 | 296 | ||
297 | These are minimal examples of how perform common operations with avatar | 297 | These are minimal examples of how to perform common operations with avatar |
298 | functions. For a complete, working, example, see `testing/test_avatars.c`. | 298 | functions. For a complete working example, see `testing/test_avatars.c`. |
299 | 299 | ||
300 | 300 | ||
301 | #### Setting an avatar for the current user | 301 | #### Setting an avatar for the current user |
302 | 302 | ||
303 | In this example `load_data_file` is just an hypothetical function that loads | 303 | In this example, `load_data_file` is just a hypothetical function that loads |
304 | data from a file into the buffer and sets the length accordingly. | 304 | data from a file into the buffer and sets the length accordingly. |
305 | 305 | ||
306 | uint8_t buf[TOX_AVATAR_MAX_DATA_LENGTH]; | 306 | uint8_t buf[TOX_AVATAR_MAX_DATA_LENGTH]; |
@@ -313,7 +313,7 @@ data from a file into the buffer and sets the length accordingly. | |||
313 | If the user is connected, this function will also notify all connected | 313 | If the user is connected, this function will also notify all connected |
314 | friends about the avatar change. | 314 | friends about the avatar change. |
315 | 315 | ||
316 | If the user already have an avatar defined in the client configuration, it | 316 | If the user already has an avatar defined in the client configuration, it |
317 | must be set before connecting to the network to avoid spurious avatar change | 317 | must be set before connecting to the network to avoid spurious avatar change |
318 | notifications and unnecessary data transfers. | 318 | notifications and unnecessary data transfers. |
319 | 319 | ||
@@ -327,7 +327,7 @@ To remove the current avatar, an application must call | |||
327 | tox_unset_avatar(tox); | 327 | tox_unset_avatar(tox); |
328 | 328 | ||
329 | the effect is the same as setting the avatar format to `TOX_AVATAR_FORMAT_NONE` | 329 | the effect is the same as setting the avatar format to `TOX_AVATAR_FORMAT_NONE` |
330 | and with no data: | 330 | with no data: |
331 | 331 | ||
332 | tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0); | 332 | tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0); |
333 | 333 | ||
@@ -357,7 +357,7 @@ As in this example: | |||
357 | printf("\n"); | 357 | printf("\n"); |
358 | } | 358 | } |
359 | 359 | ||
360 | And, somewhere in the Tox initialization calls, set if as the callback to be | 360 | And, somewhere in the Tox initialization calls, set it as the callback to be |
361 | triggered when an avatar information event arrives: | 361 | triggered when an avatar information event arrives: |
362 | 362 | ||
363 | tox_callback_avatar_info(tox, avatar_info_cb, NULL); | 363 | tox_callback_avatar_info(tox, avatar_info_cb, NULL); |
@@ -370,7 +370,7 @@ in the avatar information event and, if needed, request the avatar data. | |||
370 | 370 | ||
371 | #### Receiving avatar data from friends | 371 | #### Receiving avatar data from friends |
372 | 372 | ||
373 | Avatar data events are only delivered in reply of avatar data requests which | 373 | Avatar data events are only delivered in reply to avatar data requests, which |
374 | **should** only be sent after getting the user avatar information (format | 374 | **should** only be sent after getting the user avatar information (format |
375 | and hash) from an avatar information event and checking it against a local | 375 | and hash) from an avatar information event and checking it against a local |
376 | cache. | 376 | cache. |
@@ -388,7 +388,7 @@ checks the local avatar cache and emits an avatar data request if necessary: | |||
388 | delete_avatar_from_cache(tox, friendnumber); | 388 | delete_avatar_from_cache(tox, friendnumber); |
389 | } else { | 389 | } else { |
390 | /* Use the received hash to check if the cached avatar is | 390 | /* Use the received hash to check if the cached avatar is |
391 | still updated. */ | 391 | still up to date. */ |
392 | if (!is_user_cached_avatar_updated(tox, friendnumber, hash)) { | 392 | if (!is_user_cached_avatar_updated(tox, friendnumber, hash)) { |
393 | /* User avatar is outdated, send data request */ | 393 | /* User avatar is outdated, send data request */ |
394 | tox_request_avatar_data(tox, friendnumber); | 394 | tox_request_avatar_data(tox, friendnumber); |
@@ -420,9 +420,9 @@ calls: | |||
420 | tox_callback_avatar_data(tox, avatar_data_cb, NULL); | 420 | tox_callback_avatar_data(tox, avatar_data_cb, NULL); |
421 | 421 | ||
422 | 422 | ||
423 | In the previous examples, implementation of the functions to check, store | 423 | In the previous examples, implementation of the functions to check, store, |
424 | and retrieve data from the cache were omitted for brevity. These functions | 424 | and retrieve data from the cache were omitted for brevity. These functions |
425 | will also need to get the friend public key (client id) from they friend | 425 | will also need to get the friend public key (client id) from the friend |
426 | number and, usually, convert it from a byte string to a hexadecimal | 426 | number and, usually, convert it from a byte string to a hexadecimal |
427 | string. A complete, yet more complex, example is available in the file | 427 | string. A complete, yet more complex, example is available in the file |
428 | `testing/test_avatars.c`. | 428 | `testing/test_avatars.c`. |
@@ -454,7 +454,7 @@ The avatar transfer protocol adds the following new packet types and ids: | |||
454 | 454 | ||
455 | ### Requesting avatar information | 455 | ### Requesting avatar information |
456 | 456 | ||
457 | To request avatar information, an user must send a packet of type | 457 | To request avatar information, a user must send a packet of type |
458 | `PACKET_ID_AVATAR_INFO_REQ`. This packet has no data fields. Upon | 458 | `PACKET_ID_AVATAR_INFO_REQ`. This packet has no data fields. Upon |
459 | receiving this packet, a client which supports avatars should answer with | 459 | receiving this packet, a client which supports avatars should answer with |
460 | a `PACKET_ID_AVATAR_INFO`. The sender must accept that the friend may | 460 | a `PACKET_ID_AVATAR_INFO`. The sender must accept that the friend may |
@@ -472,7 +472,7 @@ the following structure: | |||
472 | Packet data size: 33 bytes | 472 | Packet data size: 33 bytes |
473 | [1: uint8_t format][32: uint8_t hash] | 473 | [1: uint8_t format][32: uint8_t hash] |
474 | 474 | ||
475 | Where 'format' is the image data format, one of the following: | 475 | where 'format' is the image data format, one of the following: |
476 | 476 | ||
477 | 0 = AVATAR_FORMAT_NONE (no avatar set) | 477 | 0 = AVATAR_FORMAT_NONE (no avatar set) |
478 | 1 = AVATAR_FORMAT_PNG | 478 | 1 = AVATAR_FORMAT_PNG |
@@ -492,21 +492,21 @@ connects, in the same way Tox sends name, status and action information. | |||
492 | Transmission of avatar data is a multi-step procedure using three new packet | 492 | Transmission of avatar data is a multi-step procedure using three new packet |
493 | types. | 493 | types. |
494 | 494 | ||
495 | - Packet `PACKET_ID_AVATAR_DATA_CONTROL` have the format: | 495 | - Packet `PACKET_ID_AVATAR_DATA_CONTROL` has the format: |
496 | 496 | ||
497 | PACKET_ID_AVATAR_DATA_CONTROL (54) | 497 | PACKET_ID_AVATAR_DATA_CONTROL (54) |
498 | Packet data size: 1 byte | 498 | Packet data size: 1 byte |
499 | [1: uint8_t op] | 499 | [1: uint8_t op] |
500 | 500 | ||
501 | where 'op' is a code signaling both an operation request or a status | 501 | where 'op' is a code signaling either an operation request or a status |
502 | return, which semantics are explained bellow. The following values are | 502 | return, the semantics of which are explained below. The following values are |
503 | defined: | 503 | defined: |
504 | 504 | ||
505 | 0 = AVATAR_DATACONTROL_REQ | 505 | 0 = AVATAR_DATACONTROL_REQ |
506 | 1 = AVATAR_DATACONTROL_ERROR | 506 | 1 = AVATAR_DATACONTROL_ERROR |
507 | 507 | ||
508 | 508 | ||
509 | - Packet `PACKET_ID_AVATAR_DATA_START` have the following format: | 509 | - Packet `PACKET_ID_AVATAR_DATA_START` has the following format: |
510 | 510 | ||
511 | PACKET_ID_AVATAR_DATA_START (55) | 511 | PACKET_ID_AVATAR_DATA_START (55) |
512 | Packet data size: 37 bytes | 512 | Packet data size: 37 bytes |
@@ -515,13 +515,13 @@ types. | |||
515 | 515 | ||
516 | where 'format' is the image format, with the same values accepted for | 516 | where 'format' is the image format, with the same values accepted for |
517 | the field 'format' in packet type `PACKET_ID_AVATAR_INFO`, 'hash' is | 517 | the field 'format' in packet type `PACKET_ID_AVATAR_INFO`, 'hash' is |
518 | the SHA-256 cryptographic hash of the avatar raw data and 'data_length' | 518 | the SHA-256 cryptographic hash of the avatar raw data, and 'data_length' |
519 | is the total number of bytes the raw avatar data. | 519 | is the total number of bytes the raw avatar data. |
520 | 520 | ||
521 | 521 | ||
522 | - Packet `PACKET_ID_AVATAR_DATA_PUSH` has no format structure, just up | 522 | - Packet `PACKET_ID_AVATAR_DATA_PUSH` has no format structure, just up |
523 | to `AVATAR_DATA_MAX_CHUNK_SIZE` bytes of raw avatar image data; this | 523 | to `AVATAR_DATA_MAX_CHUNK_SIZE` bytes of raw avatar image data; this |
524 | value is defined according to the maximum amount of data a Tox crypted | 524 | value is defined according to the maximum amount of data a Tox encrypted |
525 | packet can hold. | 525 | packet can hold. |
526 | 526 | ||
527 | 527 | ||
@@ -534,9 +534,9 @@ from a client "B": | |||
534 | packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to | 534 | packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to |
535 | `AVATAR_DATACONTROL_REQ`. | 535 | `AVATAR_DATACONTROL_REQ`. |
536 | 536 | ||
537 | - If "B" accepts this transfer, it answers by sending an | 537 | - If "B" accepts this transfer, it answers by sending a |
538 | `PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash' and | 538 | `PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash', and |
539 | 'data_length' set to the respective values from the current avatar. | 539 | 'data_length' set to the respective values of the current avatar. |
540 | If "B" has no avatar set, 'format' must be `AVATAR_FORMAT_NONE`, 'hash' | 540 | If "B" has no avatar set, 'format' must be `AVATAR_FORMAT_NONE`, 'hash' |
541 | must be zeroed and 'data_length' must be zero. | 541 | must be zeroed and 'data_length' must be zero. |
542 | 542 | ||
@@ -545,12 +545,12 @@ from a client "B": | |||
545 | `AVATAR_DATACONTROL_ERROR` or simply ignore this request. "A" must cope | 545 | `AVATAR_DATACONTROL_ERROR` or simply ignore this request. "A" must cope |
546 | with this. | 546 | with this. |
547 | 547 | ||
548 | If "B" have an avatar, it sends a variable number of | 548 | If "B" has an avatar, it sends a variable number of |
549 | `PACKET_ID_AVATAR_DATA_PUSH` packets with the avatar data in a single | 549 | `PACKET_ID_AVATAR_DATA_PUSH` packets with the avatar data in a single |
550 | shot. | 550 | shot. |
551 | 551 | ||
552 | - Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it | 552 | - Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it |
553 | has sent a data request to "B". If not, just ignores the packet. | 553 | has sent a data request to "B". If not, it simply ignores the packet. |
554 | 554 | ||
555 | If "A" really requested avatar data and the format is `AVATAR_FORMAT_NONE`, | 555 | If "A" really requested avatar data and the format is `AVATAR_FORMAT_NONE`, |
556 | it triggers the avatar data callback, and clears all the temporary data, | 556 | it triggers the avatar data callback, and clears all the temporary data, |
@@ -559,36 +559,36 @@ from a client "B": | |||
559 | 559 | ||
560 | - Upon receiving a `PACKET_ID_AVATAR_DATA_PUSH`, "A" checks if it really | 560 | - Upon receiving a `PACKET_ID_AVATAR_DATA_PUSH`, "A" checks if it really |
561 | sent an avatar data request and if the `PACKET_ID_AVATAR_DATA_START` was | 561 | sent an avatar data request and if the `PACKET_ID_AVATAR_DATA_START` was |
562 | already received. If this conditions are valid, it checks if the total | 562 | already received. If these conditions were met, it checks if the total |
563 | length of the data already stored in the receiving buffer plus the data | 563 | length of the data already stored in the receiving buffer plus the data |
564 | present in the push packet is still less or equal than | 564 | present in the push packet is still less or equal than |
565 | `TOX_AVATAR_MAX_DATA_LENGTH`. If invalid, it replies with a | 565 | `TOX_AVATAR_MAX_DATA_LENGTH`. If that is not the case, it replies with a |
566 | `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to | 566 | `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to |
567 | `AVATAR_DATACONTROL_ERROR`. | 567 | `AVATAR_DATACONTROL_ERROR`. |
568 | 568 | ||
569 | If valid, "A" updates the 'bytes_received' counter and concatenates the | 569 | If valid, "A" updates the 'bytes_received' counter and concatenates the |
570 | newly arrived data to the buffer. | 570 | newly arrived data to the buffer. |
571 | 571 | ||
572 | Then "A" checks if all the data was already received by comparing the | 572 | Then "A" checks if all the data has already been received, by comparing the |
573 | counter 'bytes_received' with the field 'total_length'. If they are | 573 | counter 'bytes_received' with the field 'total_length'. If they are |
574 | equal, "A" takes a SHA-256 hash of the data and compares it with the | 574 | equal, "A" takes a SHA-256 hash of the data and compares it with the |
575 | hash stored in the field 'hash' received from the first | 575 | hash stored in the field 'hash' received with the first |
576 | `PACKET_ID_AVATAR_DATA_START`. | 576 | `PACKET_ID_AVATAR_DATA_START`. |
577 | 577 | ||
578 | If the hashes match, the avatar data was correctly received and "A" | 578 | If the hashes match, the avatar data was correctly received, and "A" |
579 | triggers the avatar data callback, and clears all the temporary data, | 579 | triggers the avatar data callback and clears all the temporary data, |
580 | finishing the process. | 580 | finishing the process. |
581 | 581 | ||
582 | If not all data was received, "A" simply waits for more data. | 582 | If not all data was received, "A" simply waits for more data. |
583 | 583 | ||
584 | Client "A" is always responsible for controlling the transfer and | 584 | Client "A" is always responsible for controlling the transfer and |
585 | validating the data received. "B" don't need to keep any state for the | 585 | validating the data received. "B" doesn't need to keep any state for the |
586 | protocol, have full control over the data sent and should implement | 586 | protocol, have full control over the data sent and should implement |
587 | some transfer limit for the data it sends. | 587 | some transfer limit for the data it sends. |
588 | 588 | ||
589 | - Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' | 589 | - Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' |
590 | set to `AVATAR_DATACONTROL_ERROR` clears any existing control state and | 590 | set to `AVATAR_DATACONTROL_ERROR` clears any existing control state and |
591 | finishes sending or receiving data. | 591 | aborts sending or receiving data. |
592 | 592 | ||
593 | 593 | ||
594 | 594 | ||
@@ -597,33 +597,33 @@ from a client "B": | |||
597 | ## Security considerations | 597 | ## Security considerations |
598 | 598 | ||
599 | The major security implication of background data transfers of large objects, | 599 | The major security implication of background data transfers of large objects, |
600 | like avatars, is the possibility of exhausting the network resources from a | 600 | like avatars, is the possibility of exhausting the network resources of a |
601 | client. This problem is exacerbated when there is the possibility of an | 601 | client. This problem is exacerbated when there is the possibility of an |
602 | amplification attack as happens, for example, when sending a very small | 602 | amplification attack, as happens, for example, when sending a very small |
603 | avatar request message will force the user to reply with a larger avatar | 603 | avatar request message will force the user to reply with a larger avatar |
604 | data message. | 604 | data message. |
605 | 605 | ||
606 | The present proposal mitigates this situation by: | 606 | The present proposal mitigates this situation by: |
607 | 607 | ||
608 | - Only transferring data between previously authenticated friends; | 608 | - only transferring data between previously authenticated friends, |
609 | 609 | ||
610 | - Enforcing strict limits on the avatar data size; | 610 | - enforcing strict limits on the avatar data size, |
611 | 611 | ||
612 | - Providing an alternate, smaller, message to cooperative users refresh | 612 | - providing an alternate, smaller message for cooperative users to refresh |
613 | avatar information when nothing has changed (`PACKET_ID_AVATAR_INFO`); | 613 | avatar information when nothing has changed (`PACKET_ID_AVATAR_INFO`), |
614 | 614 | ||
615 | - Having per-friend data transfer limit. As the current protocol still | 615 | - having a per-friend data transfer limit. As the current protocol still |
616 | allows an user to request avatar data again and again, the implementation | 616 | allows a user to request avatar data again and again, the implementation |
617 | limits the amount of data a particular user can request for some time. The | 617 | limits the amount of data a particular user can request for some time. The |
618 | exact values are defined in constants `AVATAR_DATA_TRANSFER_LIMIT` and | 618 | exact values are defined in constants `AVATAR_DATA_TRANSFER_LIMIT` and |
619 | `AVATAR_DATA_TRANSFER_TIMEOUT` in file `Messenger.c`. | 619 | `AVATAR_DATA_TRANSFER_TIMEOUT` in file `Messenger.c`. |
620 | 620 | ||
621 | - Making the requester responsible for storing partial data and state | 621 | - making the requester responsible for storing partial data and state |
622 | information; | 622 | information |
623 | 623 | ||
624 | Another problem present in the avatars is the possibility of a friend send | 624 | Another problem present in avatars is the possibility of a friend sending |
625 | a maliciously crafted image intended to exploit vulnerabilities in image | 625 | a maliciously crafted image intended to exploit vulnerabilities in image |
626 | decoders. Without an intermediate server to recompress and validate and | 626 | decoders. Without an intermediate server to recompress, validate, and |
627 | convert the images to neutral formats, the client applications must handle | 627 | convert the images to neutral formats, the client applications must handle |
628 | this situation by themselves using stable and secure image libraries and | 628 | this situation by themselves using stable and secure image libraries and |
629 | imposing limits on the maximum amount of system resources the decoding | 629 | imposing limits on the maximum amount of system resources the decoding |
diff --git a/docs/Tox_middle_level_network_protocol.txt b/docs/Tox_middle_level_network_protocol.txt index ca561474..69ab9858 100644 --- a/docs/Tox_middle_level_network_protocol.txt +++ b/docs/Tox_middle_level_network_protocol.txt | |||
@@ -3,58 +3,58 @@ feature complete. Why doesn't Tox support TCP yet even if those parts are | |||
3 | complete? | 3 | complete? |
4 | 4 | ||
5 | The answer is that a way to ensure a smooth switchover between the TCP and UDP | 5 | The answer is that a way to ensure a smooth switchover between the TCP and UDP |
6 | needs to be added. If Tox first connects to the other user using TCP but then | 6 | needs to be added. If Tox first connects to the other user using TCP but then, |
7 | due to pure chance manages to connect using the faster direct UDP connection | 7 | due to pure chance, manages to connect using the faster direct UDP connection, |
8 | Tox must switch seamlessly from the TCP to the UDP connection without there | 8 | Tox must switch seamlessly from the TCP to the UDP connection without there |
9 | being any data loss or the other user going offline and then back online. The | 9 | being any data loss or the other user going offline and then back online. The |
10 | transition must be seamless whatever both connected users are doing be it | 10 | transition must be seamless whatever both connected users are doing - be it |
11 | transferring files or simply chatting together. | 11 | transferring files or simply chatting together. |
12 | 12 | ||
13 | Possible evil/bad or simply TCP relays going offline must not impact the | 13 | Possible evil/bad or simply TCP relays going offline must not impact the |
14 | connection between both clients. | 14 | connection between both clients. |
15 | 15 | ||
16 | Typically Tox will use more than one TCP relay to connect to other peers for | 16 | Typically, Tox will use more than one TCP relay to connect to other peers for |
17 | maximum connection stability which means there must be a way for Tox to take | 17 | maximum connection stability, which means there must be a way for Tox to take |
18 | advantage of multiple relays in a way that the user will never be aware if one | 18 | advantage of multiple relays in a way that the user will never be aware of, if one |
19 | of them goes offline/tries to slow down the connection/decides to corrupt | 19 | of them goes offline/tries to slow down the connection/decides to corrupt |
20 | packets/etc.. | 20 | packets/etc. |
21 | 21 | ||
22 | To accomplish this Tox needs something between the low level protocol (TCP) and | 22 | To accomplish this, Tox needs something between the low level protocol (TCP) and |
23 | high level Tox messaging protocol hence the name middle level. | 23 | high level Tox messaging protocol; hence the name middle level. |
24 | 24 | ||
25 | The plan is to move some functionality from lossless_UDP to a higher level: | 25 | The plan is to move some functionality from lossless_UDP to a higher level: |
26 | more specifically the functionality for detecting which packets a peer is | 26 | more specifically, the functionality for detecting which packets a peer is |
27 | missing and the ability to request and send them again. lossless UDP uses plain | 27 | missing, and the ability to request and send them again. Lossless UDP uses plain |
28 | text packets to request missing packets from the other peer while Tox is | 28 | text packets to request missing packets from the other peer, while Tox is |
29 | currently designed to kill the connection if any packet tampering is detected. | 29 | currently designed to kill the connection if any packet tampering is detected. |
30 | This works very well when connecting directly with someone because if the | 30 | This works very well when connecting directly with someone because if the |
31 | attacker can modify packets it means he can kill your connection anyways. With | 31 | attacker can modify packets, it means he can kill your connection anyway. With |
32 | TCP relays however that is not the case as such the packets used to request | 32 | TCP relays, however, that is not the case. As such the packets used to request |
33 | missing packets must be encrypted. If it is detected that a packet has been | 33 | missing packets must be encrypted. If it is detected that a packet has been |
34 | tampered, the connection must stay intact while the evil relay must be | 34 | tampered, the connection must stay intact while the evil relay must be |
35 | disconnected from and replaced with a good relay, the behavior must be the same | 35 | disconnected from and replaced with a good relay; the behavior must be the same |
36 | as if the relay had just suddenly gone online. Of course something to protect | 36 | as if the relay had just suddenly gone offline. Of course, something to protect |
37 | from evil "friends" framing relays must also be implemented. | 37 | from evil "friends" framing relays must also be implemented. |
38 | 38 | ||
39 | Detailed implementation details: | 39 | Detailed implementation details: |
40 | 40 | ||
41 | cookie request packet: | 41 | cookie request packet: |
42 | [uint8_t 24][Senders DHT Public key (32 bytes)][Random nonce (24 | 42 | [uint8_t 24][Sender's DHT Public key (32 bytes)][Random nonce (24 |
43 | bytes)][Encrypted message containing: [Senders real public key (32 | 43 | bytes)][Encrypted message containing: [Sender's real public key (32 |
44 | bytes)][padding (32 bytes)][uint64_t number (must be sent | 44 | bytes)][padding (32 bytes)][uint64_t number (must be sent |
45 | back untouched in cookie response)]] | 45 | back untouched in cookie response)]] |
46 | Encrypted message is encrypted with sender DHT private key, receivers DHT | 46 | Encrypted message is encrypted with sender's DHT private key, receiver's DHT |
47 | public key and the nonce. | 47 | public key and the nonce. |
48 | 48 | ||
49 | cookie response packet: | 49 | cookie response packet: |
50 | [uint8_t 25][Random nonce (24 bytes)][Encrypted message containing: | 50 | [uint8_t 25][Random nonce (24 bytes)][Encrypted message containing: |
51 | [Cookie][uint64_t number (that was sent in the request)]] | 51 | [Cookie][uint64_t number (that was sent in the request)]] |
52 | Encrypted message is encrypted with sender DHT private key, receivers DHT | 52 | Encrypted message is encrypted with sender's DHT private key, receiver's DHT |
53 | public key and the nonce. | 53 | public key and the nonce. |
54 | 54 | ||
55 | The Cookie should be basically: | 55 | The Cookie should be basically: |
56 | [nonce][encrypted data:[uint64_t time][Senders real public key (32 | 56 | [nonce][encrypted data:[uint64_t time][Sender's real public key (32 |
57 | bytes)][Senders dht public key (32 bytes)]] | 57 | bytes)][Sender's DHT public key (32 bytes)]] |
58 | 58 | ||
59 | Handshake packet: | 59 | Handshake packet: |
60 | [uint8_t 26][Cookie][nonce][Encrypted message containing: [random 24 bytes base | 60 | [uint8_t 26][Cookie][nonce][Encrypted message containing: [random 24 bytes base |
@@ -66,25 +66,25 @@ The handshake packet is encrypted using the real private key of the sender, the | |||
66 | real public key of the receiver and the nonce. | 66 | real public key of the receiver and the nonce. |
67 | 67 | ||
68 | 68 | ||
69 | Alice wants to connect to bob. | 69 | Alice wants to connect to Bob: |
70 | 70 | ||
71 | Alice sends a cookie request packet to bob and gets a cookie response back. | 71 | Alice sends a cookie request packet to Bob and gets a cookie response back. |
72 | 72 | ||
73 | Alice then generates a nonce and a temporary public/private keypair. | 73 | Alice then generates a nonce and a temporary public/private keypair. |
74 | 74 | ||
75 | Alice then takes that nonce and just generated private key, the obtained | 75 | Alice then takes that nonce and just generated private key, the obtained |
76 | cookie, creates a new cookie and puts them in a handshake packet which she | 76 | cookie, creates a new cookie and puts them in a handshake packet, which she |
77 | sends to bob. | 77 | sends to Bob. |
78 | 78 | ||
79 | Bob gets the handshake packet, accepts the connection request, then generates a | 79 | Bob gets the handshake packet, accepts the connection request, then generates a |
80 | nonce and a temporary public/private keypair and sends a handshake packet back | 80 | nonce and a temporary public/private keypair and sends a handshake packet back |
81 | with this just generated information and with the cookie field being the Other | 81 | with this just generated information and with the cookie field being the Other |
82 | Cookie contained in the received handshake. | 82 | Cookie contained in the received handshake. |
83 | 83 | ||
84 | Both then use these temporary keys to generate the session key with which every | 84 | Both then use these temporary keys to generate the session key, with which every |
85 | data packet sent and received will be encrypted and decrypted. The nonce sent | 85 | data packet sent and received will be encrypted and decrypted. The nonce sent |
86 | in the handshake will be used to encrypt the first data packet sent, the nonce | 86 | in the handshake will be used to encrypt the first data packet sent, the nonce |
87 | + 1 the second, the nonce + 2 the third and so on. | 87 | + 1 for the second, the nonce + 2 for the third, and so on. |
88 | 88 | ||
89 | Data packets: | 89 | Data packets: |
90 | 90 | ||
@@ -109,12 +109,12 @@ data ids: | |||
109 | packet request packet: [uint8_t (1)][uint8_t num][uint8_t num][uint8_t | 109 | packet request packet: [uint8_t (1)][uint8_t num][uint8_t num][uint8_t |
110 | num]...[uint8_t num] | 110 | num]...[uint8_t num] |
111 | 111 | ||
112 | the list of nums are a list of packet numbers the other is requesting. | 112 | The list of nums are a list of packet numbers the other is requesting. |
113 | to get the real packet numbers from this list take the recvbuffers buffer_start | 113 | In order to get the real packet numbers from this list, take the recvbuffers buffer_start |
114 | from the packet, subtract 1 to it and put it in packet_num then start from the | 114 | from the packet, subtract 1 from it and put it in packet_num, then start from the |
115 | beginning of the num list: if num is zero, add 255 to packet_num then do the | 115 | beginning of the num list: if num is zero, add 255 to packet_num, then do the |
116 | next num. if num isn't zero, add its value to packet_num, note that the other | 116 | next num. If num isn't zero, add its value to packet_num, note that the other |
117 | has requested we send this packet again to them then continue to the next num in | 117 | has requested we send this packet again to them, then continue to the next num in |
118 | the list. | 118 | the list. |
119 | 119 | ||
120 | 120 | ||