summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL.md10
-rw-r--r--README.md2
-rw-r--r--other/apidsl/README.md11
-rw-r--r--other/apidsl/tox.in.h2076
-rw-r--r--other/astyle/README (renamed from tools/README)0
-rw-r--r--other/astyle/astylerc (renamed from tools/astylerc)0
-rw-r--r--other/astyle/pre-commit (renamed from tools/pre-commit)0
-rw-r--r--toxcore/LAN_discovery.c5
-rw-r--r--toxcore/LAN_discovery.h3
-rw-r--r--toxcore/Messenger.c75
-rw-r--r--toxcore/Messenger.h15
-rw-r--r--toxcore/TCP_client.c2
-rw-r--r--toxcore/TCP_client.h4
-rw-r--r--toxcore/TCP_connection.c480
-rw-r--r--toxcore/TCP_connection.h57
-rw-r--r--toxcore/crypto_core.c22
-rw-r--r--toxcore/crypto_core.h4
-rw-r--r--toxcore/friend_connection.c199
-rw-r--r--toxcore/friend_connection.h24
-rw-r--r--toxcore/net_crypto.c882
-rw-r--r--toxcore/net_crypto.h66
-rw-r--r--toxcore/onion.c4
-rw-r--r--toxcore/onion_client.c15
-rw-r--r--toxcore/onion_client.h2
-rw-r--r--toxcore/tox.h742
25 files changed, 3537 insertions, 1163 deletions
diff --git a/INSTALL.md b/INSTALL.md
index c2a8c0d9..549a3a4f 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -171,15 +171,21 @@ Different: libvpx (webm) libopus pkgconfig gettext
171(the libintl, from gettext, built into OS X 10.5 is missing libintl_setlocale, but the Macports build has it) 171(the libintl, from gettext, built into OS X 10.5 is missing libintl_setlocale, but the Macports build has it)
172 172
173Verify where libintl is on your system: (MacPorts puts it in /opt/local) 173Verify where libintl is on your system: (MacPorts puts it in /opt/local)
174$ for d in /usr/local/lib /opt/local/lib /usr/lib /lib; do ls -l $d/libintl.*; done 174```
175for d in /usr/local/lib /opt/local/lib /usr/lib /lib; do ls -l $d/libintl.*; done
176```
175 177
176Check if that copy has libintl_setlocale: 178Check if that copy has libintl_setlocale:
179```
177nm /opt/local/lib/libintl.8.dylib | grep _libintl_setlocale 180nm /opt/local/lib/libintl.8.dylib | grep _libintl_setlocale
181```
178 182
179Certain other tools may not be installed, or outdated, and should also be installed from MacPorts for simplicity: git cmake 183Certain other tools may not be installed, or outdated, and should also be installed from MacPorts for simplicity: git cmake
180 184
181If libsodium was installed with MacPorts, you may want to symlink the copy in /opt/local/lib to /usr/local/lib. That way you don't need special configure switches for toxcore to find libsodium, and every time MacPorts updates libsodium, the new version will be linked to toxcore every time you build: 185If libsodium was installed with MacPorts, you may want to symlink the copy in /opt/local/lib to /usr/local/lib. That way you don't need special configure switches for toxcore to find libsodium, and every time MacPorts updates libsodium, the new version will be linked to toxcore every time you build:
186```
182ln -s /opt/local/lib/libsodium.dylib /usr/local/lib/libsodium.dylib 187ln -s /opt/local/lib/libsodium.dylib /usr/local/lib/libsodium.dylib
188```
183 189
184Much of the build can then be done as for other platforms: git clone, and so on. Differences will be noted with (OS X 10.5 specific) 190Much of the build can then be done as for other platforms: git clone, and so on. Differences will be noted with (OS X 10.5 specific)
185 191
@@ -217,7 +223,9 @@ There is also a shell script called "osx_build_script_toxcore.txt" which automat
217 223
218If after running ./configure you get an error about core being unable to find libsodium (and you have installed it) run the following in place of ./configure; 224If after running ./configure you get an error about core being unable to find libsodium (and you have installed it) run the following in place of ./configure;
219 225
226```
220./configure --with-libsodium-headers=/usr/local/include/ --with-libsodium-libs=/usr/local/lib 227./configure --with-libsodium-headers=/usr/local/include/ --with-libsodium-libs=/usr/local/lib
228```
221 229
222Ensure you set the locations correctly depending on where you installed libsodium on your computer. 230Ensure you set the locations correctly depending on where you installed libsodium on your computer.
223 231
diff --git a/README.md b/README.md
index 2a7945f9..67a877c1 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ We want Tox to be as simple as possible while remaining as secure as possible.
29The goal of this project is to create a configuration-free P2P Skype replacement. “Configuration-free” means that the user will simply have to open the program and will be capable of adding people and communicating with them without having to set up an account. There are many so-called Skype replacements, but all of them are either hard to configure for the normal user or suffer from being way too centralized. 29The goal of this project is to create a configuration-free P2P Skype replacement. “Configuration-free” means that the user will simply have to open the program and will be capable of adding people and communicating with them without having to set up an account. There are many so-called Skype replacements, but all of them are either hard to configure for the normal user or suffer from being way too centralized.
30 30
31## TODO: 31## TODO:
32- [TODO](/docs/TODO) 32- [TODO](/docs/TODO.md)
33 33
34 34
35## Documentation: 35## Documentation:
diff --git a/other/apidsl/README.md b/other/apidsl/README.md
new file mode 100644
index 00000000..c8241eb8
--- /dev/null
+++ b/other/apidsl/README.md
@@ -0,0 +1,11 @@
1This folder contains the input file that can be used to generate the tox.h api
2with: https://github.com/iphydf/apidsl
3
4You can also use the following command if you can't install it:
5
6```
7cat tox.in.h | curl -X POST --data-binary @- https://criticism.herokuapp.com/apidsl > tox.h
8```
9
10Note that the output must be passed through astyle with the config in
11other/astyle/astylerc to generate the exact same file.
diff --git a/other/apidsl/tox.in.h b/other/apidsl/tox.in.h
new file mode 100644
index 00000000..84a4a03e
--- /dev/null
+++ b/other/apidsl/tox.in.h
@@ -0,0 +1,2076 @@
1%{
2/* tox.h
3 *
4 * The Tox public API.
5 *
6 * Copyright (C) 2013 Tox project All Rights Reserved.
7 *
8 * This file is part of Tox.
9 *
10 * Tox is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * Tox is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
22 *
23 */
24
25#ifndef TOX_H
26#define TOX_H
27
28#include <stdbool.h>
29#include <stddef.h>
30#include <stdint.h>
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35%}
36
37/** \page core Public core API for Tox clients.
38 *
39 * Every function that can fail takes a function-specific error code pointer
40 * that can be used to diagnose problems with the Tox state or the function
41 * arguments. The error code pointer can be NULL, which does not influence the
42 * function's behaviour, but can be done if the reason for failure is irrelevant
43 * to the client.
44 *
45 * The exception to this rule are simple allocation functions whose only failure
46 * mode is allocation failure. They return NULL in that case, and do not set an
47 * error code.
48 *
49 * Every error code type has an OK value to which functions will set their error
50 * code value on success. Clients can keep their error code uninitialised before
51 * passing it to a function. The library guarantees that after returning, the
52 * value pointed to by the error code pointer has been initialised.
53 *
54 * Functions with pointer parameters often have a NULL error code, meaning they
55 * could not perform any operation, because one of the required parameters was
56 * NULL. Some functions operate correctly or are defined as effectless on NULL.
57 *
58 * Some functions additionally return a value outside their
59 * return type domain, or a bool containing true on success and false on
60 * failure.
61 *
62 * All functions that take a Tox instance pointer will cause undefined behaviour
63 * when passed a NULL Tox pointer.
64 *
65 * All integer values are expected in host byte order.
66 *
67 * Functions with parameters with enum types cause unspecified behaviour if the
68 * enumeration value is outside the valid range of the type. If possible, the
69 * function will try to use a sane default, but there will be no error code,
70 * and one possible action for the function to take is to have no effect.
71 */
72
73/** \subsection events Events and callbacks
74 *
75 * Events are handled by callbacks. One callback can be registered per event.
76 * All events have a callback function type named `tox_{event}_cb` and a
77 * function to register it named `tox_callback_{event}`. Passing a NULL
78 * callback will result in no callback being registered for that event. Only
79 * one callback per event can be registered, so if a client needs multiple
80 * event listeners, it needs to implement the dispatch functionality itself.
81 */
82
83/** \subsection threading Threading implications
84 *
85 * It is possible to run multiple concurrent threads with a Tox instance for
86 * each thread. It is also possible to run all Tox instances in the same thread.
87 * A common way to run Tox (multiple or single instance) is to have one thread
88 * running a simple ${tox.iterate} loop, sleeping for ${tox.iteration_interval}
89 * milliseconds on each iteration.
90 *
91 * If you want to access a single Tox instance from multiple threads, access
92 * to the instance must be synchronised. While multiple threads can concurrently
93 * access multiple different Tox instances, no more than one API function can
94 * operate on a single instance at any given time.
95 *
96 * Functions that write to variable length byte arrays will always have a size
97 * function associated with them. The result of this size function is only valid
98 * until another mutating function (one that takes a pointer to non-const Tox)
99 * is called. Thus, clients must ensure that no other thread calls a mutating
100 * function between the call to the size function and the call to the retrieval
101 * function.
102 *
103 * E.g. to get the current nickname, one would write
104 *
105 * \code
106 * size_t length = ${tox.self.name.size}(tox);
107 * uint8_t *name = malloc(length);
108 * if (!name) abort();
109 * ${tox.self.name.get}(tox, name);
110 * \endcode
111 *
112 * If any other thread calls ${tox.self.name.set} while this thread is allocating
113 * memory, the length may have become invalid, and the call to
114 * ${tox.self.name.get} may cause undefined behaviour.
115 */
116
117// The rest of this file is in class tox.
118class tox {
119
120/**
121 * The Tox instance type. All the state associated with a connection is held
122 * within the instance. Multiple instances can exist and operate concurrently.
123 * The maximum number of Tox instances that can exist on a single network
124 * device is limited. Note that this is not just a per-process limit, since the
125 * limiting factor is the number of usable ports on a device.
126 */
127struct this;
128
129
130/*******************************************************************************
131 *
132 * :: API version
133 *
134 ******************************************************************************/
135
136
137/**
138 * The major version number. Incremented when the API or ABI changes in an
139 * incompatible way.
140 */
141#define TOX_VERSION_MAJOR 0u
142/**
143 * The minor version number. Incremented when functionality is added without
144 * breaking the API or ABI. Set to 0 when the major version number is
145 * incremented.
146 */
147#define TOX_VERSION_MINOR 0u
148/**
149 * The patch or revision number. Incremented when bugfixes are applied without
150 * changing any functionality or API or ABI.
151 */
152#define TOX_VERSION_PATCH 0u
153
154/**
155 * A macro to check at preprocessing time whether the client code is compatible
156 * with the installed version of Tox.
157 */
158#define TOX_VERSION_IS_API_COMPATIBLE(MAJOR, MINOR, PATCH) \
159 (TOX_VERSION_MAJOR == MAJOR && \
160 (TOX_VERSION_MINOR > MINOR || \
161 (TOX_VERSION_MINOR == MINOR && \
162 TOX_VERSION_PATCH >= PATCH)))
163
164/**
165 * A macro to make compilation fail if the client code is not compatible with
166 * the installed version of Tox.
167 */
168#define TOX_VERSION_REQUIRE(MAJOR, MINOR, PATCH) \
169 typedef char tox_required_version[TOX_IS_COMPATIBLE(MAJOR, MINOR, PATCH) ? 1 : -1]
170
171static namespace version {
172
173 /**
174 * Return the major version number of the library. Can be used to display the
175 * Tox library version or to check whether the client is compatible with the
176 * dynamically linked version of Tox.
177 */
178 uint32_t major();
179
180 /**
181 * Return the minor version number of the library.
182 */
183 uint32_t minor();
184
185 /**
186 * Return the patch number of the library.
187 */
188 uint32_t patch();
189
190 /**
191 * Return whether the compiled library version is compatible with the passed
192 * version numbers.
193 */
194 bool is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
195
196}
197
198/**
199 * A convenience macro to call tox_version_is_compatible with the currently
200 * compiling API version.
201 */
202#define TOX_VERSION_IS_ABI_COMPATIBLE() \
203 tox_version_is_compatible(TOX_VERSION_MAJOR, TOX_VERSION_MINOR, TOX_VERSION_PATCH)
204
205/*******************************************************************************
206 *
207 * :: Numeric constants
208 *
209 ******************************************************************************/
210
211
212/**
213 * The size of a Tox Public Key in bytes.
214 */
215const PUBLIC_KEY_SIZE = 32;
216
217/**
218 * The size of a Tox Secret Key in bytes.
219 */
220const SECRET_KEY_SIZE = 32;
221
222/**
223 * The size of a Tox address in bytes. Tox addresses are in the format
224 * [Public Key ($PUBLIC_KEY_SIZE bytes)][nospam (4 bytes)][checksum (2 bytes)].
225 *
226 * The checksum is computed over the Public Key and the nospam value. The first
227 * byte is an XOR of all the even bytes (0, 2, 4, ...), the second byte is an
228 * XOR of all the odd bytes (1, 3, 5, ...) of the Public Key and nospam.
229 */
230const ADDRESS_SIZE = PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t);
231
232/**
233 * Maximum length of a nickname in bytes.
234 */
235const MAX_NAME_LENGTH = 128;
236
237/**
238 * Maximum length of a status message in bytes.
239 */
240const MAX_STATUS_MESSAGE_LENGTH = 1007;
241
242/**
243 * Maximum length of a friend request message in bytes.
244 */
245const MAX_FRIEND_REQUEST_LENGTH = 1016;
246
247/**
248 * Maximum length of a single message after which it should be split.
249 */
250const MAX_MESSAGE_LENGTH = 1372;
251
252/**
253 * Maximum size of custom packets. TODO: should be LENGTH?
254 */
255const MAX_CUSTOM_PACKET_SIZE = 1373;
256
257/**
258 * The number of bytes in a hash generated by $hash.
259 */
260const HASH_LENGTH = 32;
261
262/**
263 * The number of bytes in a file id.
264 */
265const FILE_ID_LENGTH = 32;
266
267/**
268 * Maximum file name length for file transfers.
269 */
270const MAX_FILENAME_LENGTH = 255;
271
272
273/*******************************************************************************
274 *
275 * :: Global enumerations
276 *
277 ******************************************************************************/
278
279
280/**
281 * Represents the possible statuses a client can have.
282 */
283enum class USER_STATUS {
284 /**
285 * User is online and available.
286 */
287 NONE,
288 /**
289 * User is away. Clients can set this e.g. after a user defined
290 * inactivity time.
291 */
292 AWAY,
293 /**
294 * User is busy. Signals to other clients that this client does not
295 * currently wish to communicate.
296 */
297 BUSY,
298}
299
300
301/**
302 * Represents message types for ${tox.friend.send.message} and group chat
303 * messages.
304 */
305enum class MESSAGE_TYPE {
306 /**
307 * Normal text message. Similar to PRIVMSG on IRC.
308 */
309 NORMAL,
310 /**
311 * A message describing an user action. This is similar to /me (CTCP ACTION)
312 * on IRC.
313 */
314 ACTION,
315}
316
317
318/*******************************************************************************
319 *
320 * :: Startup options
321 *
322 ******************************************************************************/
323
324
325/**
326 * Type of proxy used to connect to TCP relays.
327 */
328enum class PROXY_TYPE {
329 /**
330 * Don't use a proxy.
331 */
332 NONE,
333 /**
334 * HTTP proxy using CONNECT.
335 */
336 HTTP,
337 /**
338 * SOCKS proxy for simple socket pipes.
339 */
340 SOCKS5,
341}
342
343
344static class options {
345 /**
346 * This struct contains all the startup options for Tox. You can either allocate
347 * this object yourself, and pass it to $default, or call
348 * $new to get a new default options object.
349 */
350 struct this {
351 /**
352 * The type of socket to create.
353 *
354 * If this is set to false, an IPv4 socket is created, which subsequently
355 * only allows IPv4 communication.
356 * If it is set to true, an IPv6 socket is created, allowing both IPv4 and
357 * IPv6 communication.
358 */
359 bool ipv6_enabled;
360
361 /**
362 * Enable the use of UDP communication when available.
363 *
364 * Setting this to false will force Tox to use TCP only. Communications will
365 * need to be relayed through a TCP relay node, potentially slowing them down.
366 * Disabling UDP support is necessary when using anonymous proxies or Tor.
367 */
368 bool udp_enabled;
369
370 namespace proxy {
371 /**
372 * Pass communications through a proxy.
373 */
374 PROXY_TYPE type;
375
376 /**
377 * The IP address or DNS name of the proxy to be used.
378 *
379 * If used, this must be non-NULL and be a valid DNS name. The name must not
380 * exceed 255 characters, and be in a NUL-terminated C string format
381 * (255 chars + 1 NUL byte).
382 *
383 * This member is ignored (it can be NULL) if proxy_type is TOX_PROXY_TYPE_NONE.
384 */
385 string host;
386
387 /**
388 * The port to use to connect to the proxy server.
389 *
390 * Ports must be in the range (1, 65535). The value is ignored if
391 * proxy_type is TOX_PROXY_TYPE_NONE.
392 */
393 uint16_t port;
394 }
395
396 /**
397 * The start port of the inclusive port range to attempt to use.
398 *
399 * If both start_port and end_port are 0, the default port range will be
400 * used: [33445, 33545].
401 *
402 * If either start_port or end_port is 0 while the other is non-zero, the
403 * non-zero port will be the only port in the range.
404 *
405 * Having start_port > end_port will yield the same behavior as if start_port
406 * and end_port were swapped.
407 */
408 uint16_t start_port;
409
410 /**
411 * The end port of the inclusive port range to attempt to use.
412 */
413 uint16_t end_port;
414 }
415
416
417 /**
418 * Initialises a $this object with the default options.
419 *
420 * The result of this function is independent of the original options. All
421 * values will be overwritten, no values will be read (so it is permissible
422 * to pass an uninitialised object).
423 *
424 * If options is NULL, this function has no effect.
425 *
426 * @param options An options object to be filled with default options.
427 */
428 void default();
429
430
431 /**
432 * Allocates a new $this object and initialises it with the default
433 * options. This function can be used to preserve long term ABI compatibility by
434 * giving the responsibility of allocation and deallocation to the Tox library.
435 *
436 * Objects returned from this function must be freed using the $free
437 * function.
438 *
439 * @return A new $this object with default options or NULL on failure.
440 */
441 static this new() {
442 /**
443 * The function failed to allocate enough memory for the options struct.
444 */
445 MALLOC,
446 }
447
448
449 /**
450 * Releases all resources associated with an options objects.
451 *
452 * Passing a pointer that was not returned by $new results in
453 * undefined behaviour.
454 */
455 void free();
456}
457
458
459/*******************************************************************************
460 *
461 * :: Creation and destruction
462 *
463 ******************************************************************************/
464
465
466/**
467 * @brief Creates and initialises a new Tox instance with the options passed.
468 *
469 * This function will bring the instance into a valid state. Running the event
470 * loop with a new instance will operate correctly.
471 *
472 * If the data parameter is not NULL, this function will load the Tox instance
473 * from a byte array previously filled by ${savedata.get}.
474 *
475 * If loading failed or succeeded only partially, the new or partially loaded
476 * instance is returned and an error code is set.
477 *
478 * @param options An options object as described above. If this parameter is
479 * NULL, the default options are used.
480 * @param data A byte array containing data previously stored by ${savedata.get}.
481 * @param length The length of the byte array data. If this parameter is 0, the
482 * data parameter is ignored.
483 *
484 * @see $iterate for the event loop.
485 */
486static this new(const options_t *options, const uint8_t[length] data) {
487 NULL,
488 /**
489 * The function was unable to allocate enough memory to store the internal
490 * structures for the Tox object.
491 */
492 MALLOC,
493 /**
494 * The function was unable to bind to a port. This may mean that all ports
495 * have already been bound, e.g. by other Tox instances, or it may mean
496 * a permission error. You may be able to gather more information from errno.
497 */
498 PORT_ALLOC,
499
500 namespace PROXY {
501 /**
502 * proxy_type was invalid.
503 */
504 BAD_TYPE,
505 /**
506 * proxy_type was valid but the proxy_host passed had an invalid format
507 * or was NULL.
508 */
509 BAD_HOST,
510 /**
511 * proxy_type was valid, but the proxy_port was invalid.
512 */
513 BAD_PORT,
514 /**
515 * The proxy address passed could not be resolved.
516 */
517 NOT_FOUND,
518 }
519
520 namespace LOAD {
521 /**
522 * The byte array to be loaded contained an encrypted save.
523 */
524 ENCRYPTED,
525 /**
526 * The data format was invalid. This can happen when loading data that was
527 * saved by an older version of Tox, or when the data has been corrupted.
528 * When loading from badly formatted data, some data may have been loaded,
529 * and the rest is discarded. Passing an invalid length parameter also
530 * causes this error.
531 */
532 BAD_FORMAT,
533 }
534}
535
536
537/**
538 * Releases all resources associated with the Tox instance and disconnects from
539 * the network.
540 *
541 * After calling this function, the Tox pointer becomes invalid. No other
542 * functions can be called, and the pointer value can no longer be read.
543 */
544void kill();
545
546
547uint8_t[size] savedata {
548 /**
549 * Calculates the number of bytes required to store the tox instance with
550 * $get. This function cannot fail. The result is always greater than 0.
551 *
552 * @see threading for concurrency implications.
553 */
554 size();
555
556 /**
557 * Store all information associated with the tox instance to a byte array.
558 *
559 * @param data A memory region large enough to store the tox instance data.
560 * Call $size to find the number of bytes required. If this parameter
561 * is NULL, this function has no effect.
562 */
563 get();
564}
565
566
567/*******************************************************************************
568 *
569 * :: Connection lifecycle and event loop
570 *
571 ******************************************************************************/
572
573
574/**
575 * Sends a "get nodes" request to the given bootstrap node with IP, port, and
576 * public key to setup connections.
577 *
578 * This function will attempt to connect to the node using UDP and TCP at the
579 * same time.
580 *
581 * Tox will use the node as a TCP relay in case ${options.this.udp_enabled} was
582 * false, and also to connect to friends that are in TCP-only mode. Tox will
583 * also use the TCP connection when NAT hole punching is slow, and later switch
584 * to UDP if hole punching succeeds.
585 *
586 * @param address The hostname or IP address (IPv4 or IPv6) of the node.
587 * @param port The port on the host on which the bootstrap Tox instance is
588 * listening.
589 * @param public_key The long term public key of the bootstrap node
590 * ($PUBLIC_KEY_SIZE bytes).
591 * @return true on success.
592 */
593bool bootstrap(string address, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] public_key) {
594 NULL,
595 /**
596 * The address could not be resolved to an IP address, or the IP address
597 * passed was invalid.
598 */
599 BAD_HOST,
600 /**
601 * The port passed was invalid. The valid port range is (1, 65535).
602 */
603 BAD_PORT,
604}
605
606
607/**
608 * Adds additional host:port pair as TCP relay.
609 *
610 * This function can be used to initiate TCP connections to different ports on
611 * the same bootstrap node, or to add TCP relays without using them as
612 * bootstrap nodes.
613 *
614 * @param address The hostname or IP address (IPv4 or IPv6) of the TCP relay.
615 * @param port The port on the host on which the TCP relay is listening.
616 * @param public_key The long term public key of the TCP relay
617 * ($PUBLIC_KEY_SIZE bytes).
618 * @return true on success.
619 */
620bool add_tcp_relay(string address, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] public_key)
621 with error for bootstrap;
622
623
624/**
625 * Protocols that can be used to connect to the network or friends.
626 */
627enum class CONNECTION {
628 /**
629 * There is no connection. This instance, or the friend the state change is
630 * about, is now offline.
631 */
632 NONE,
633 /**
634 * A TCP connection has been established. For the own instance, this means it
635 * is connected through a TCP relay, only. For a friend, this means that the
636 * connection to that particular friend goes through a TCP relay.
637 */
638 TCP,
639 /**
640 * A UDP connection has been established. For the own instance, this means it
641 * is able to send UDP packets to DHT nodes, but may still be connected to
642 * a TCP relay. For a friend, this means that the connection to that
643 * particular friend was built using direct UDP packets.
644 */
645 UDP,
646}
647
648
649inline namespace self {
650
651 CONNECTION connection_status {
652 /**
653 * Return whether we are connected to the DHT. The return value is equal to the
654 * last value received through the `${event connection_status}` callback.
655 */
656 get();
657 }
658
659
660 /**
661 * This event is triggered whenever there is a change in the DHT connection
662 * state. When disconnected, a client may choose to call $bootstrap again, to
663 * reconnect to the DHT. Note that this state may frequently change for short
664 * amounts of time. Clients should therefore not immediately bootstrap on
665 * receiving a disconnect.
666 *
667 * TODO: how long should a client wait before bootstrapping again?
668 */
669 event connection_status {
670 /**
671 * @param connection_status Whether we are connected to the DHT.
672 */
673 typedef void(CONNECTION connection_status);
674 }
675
676}
677
678
679/**
680 * Return the time in milliseconds before $iterate() should be called again
681 * for optimal performance.
682 */
683const uint32_t iteration_interval();
684
685
686/**
687 * The main loop that needs to be run in intervals of $iteration_interval()
688 * milliseconds.
689 */
690void iterate();
691
692
693/*******************************************************************************
694 *
695 * :: Internal client information (Tox address/id)
696 *
697 ******************************************************************************/
698
699
700inline namespace self {
701
702 uint8_t[ADDRESS_SIZE] address {
703 /**
704 * Writes the Tox friend address of the client to a byte array. The address is
705 * not in human-readable format. If a client wants to display the address,
706 * formatting is required.
707 *
708 * @param address A memory region of at least $ADDRESS_SIZE bytes. If this
709 * parameter is NULL, this function has no effect.
710 * @see $ADDRESS_SIZE for the address format.
711 */
712 get();
713 }
714
715
716 uint32_t nospam {
717 /**
718 * Set the 4-byte nospam part of the address.
719 *
720 * @param nospam Any 32 bit unsigned integer.
721 */
722 set();
723
724 /**
725 * Get the 4-byte nospam part of the address.
726 */
727 get();
728 }
729
730
731 uint8_t[PUBLIC_KEY_SIZE] public_key {
732 /**
733 * Copy the Tox Public Key (long term) from the Tox object.
734 *
735 * @param public_key A memory region of at least $PUBLIC_KEY_SIZE bytes. If
736 * this parameter is NULL, this function has no effect.
737 */
738 get();
739 }
740
741
742 uint8_t[SECRET_KEY_SIZE] secret_key {
743 /**
744 * Copy the Tox Secret Key from the Tox object.
745 *
746 * @param secret_key A memory region of at least $SECRET_KEY_SIZE bytes. If
747 * this parameter is NULL, this function has no effect.
748 */
749 get();
750 }
751
752}
753
754
755/*******************************************************************************
756 *
757 * :: User-visible client information (nickname/status)
758 *
759 ******************************************************************************/
760
761
762/**
763 * Common error codes for all functions that set a piece of user-visible
764 * client information.
765 */
766error for set_info {
767 NULL,
768 /**
769 * Information length exceeded maximum permissible size.
770 */
771 TOO_LONG,
772}
773
774
775inline namespace self {
776
777 uint8_t[length <= MAX_NAME_LENGTH] name {
778 /**
779 * Set the nickname for the Tox client.
780 *
781 * Nickname length cannot exceed $MAX_NAME_LENGTH. If length is 0, the name
782 * parameter is ignored (it can be NULL), and the nickname is set back to empty.
783 *
784 * @param name A byte array containing the new nickname.
785 * @param length The size of the name byte array.
786 *
787 * @return true on success.
788 */
789 set() with error for set_info;
790
791 /**
792 * Return the length of the current nickname as passed to $set.
793 *
794 * If no nickname was set before calling this function, the name is empty,
795 * and this function returns 0.
796 *
797 * @see threading for concurrency implications.
798 */
799 size();
800
801 /**
802 * Write the nickname set by $set to a byte array.
803 *
804 * If no nickname was set before calling this function, the name is empty,
805 * and this function has no effect.
806 *
807 * Call $size to find out how much memory to allocate for
808 * the result.
809 *
810 * @param name A valid memory location large enough to hold the nickname.
811 * If this parameter is NULL, the function has no effect.
812 */
813 get();
814
815 }
816
817
818 uint8_t[length <= MAX_STATUS_MESSAGE_LENGTH] status_message {
819 /**
820 * Set the client's status message.
821 *
822 * Status message length cannot exceed $MAX_STATUS_MESSAGE_LENGTH. If
823 * length is 0, the status parameter is ignored (it can be NULL), and the
824 * user status is set back to empty.
825 */
826 set() with error for set_info;
827
828 /**
829 * Return the length of the current status message as passed to $set.
830 *
831 * If no status message was set before calling this function, the status
832 * is empty, and this function returns 0.
833 *
834 * @see threading for concurrency implications.
835 */
836 size();
837
838 /**
839 * Write the status message set by $set to a byte array.
840 *
841 * If no status message was set before calling this function, the status is
842 * empty, and this function has no effect.
843 *
844 * Call $size to find out how much memory to allocate for
845 * the result.
846 *
847 * @param status A valid memory location large enough to hold the status message.
848 * If this parameter is NULL, the function has no effect.
849 */
850 get();
851 }
852
853
854 USER_STATUS status {
855 /**
856 * Set the client's user status.
857 *
858 * @param user_status One of the user statuses listed in the enumeration above.
859 */
860 set();
861
862 /**
863 * Returns the client's user status.
864 */
865 get();
866 }
867
868}
869
870
871/*******************************************************************************
872 *
873 * :: Friend list management
874 *
875 ******************************************************************************/
876
877
878namespace friend {
879
880 /**
881 * Add a friend to the friend list and send a friend request.
882 *
883 * A friend request message must be at least 1 byte long and at most
884 * $MAX_FRIEND_REQUEST_LENGTH.
885 *
886 * Friend numbers are unique identifiers used in all functions that operate on
887 * friends. Once added, a friend number is stable for the lifetime of the Tox
888 * object. After saving the state and reloading it, the friend numbers may not
889 * be the same as before. Deleting a friend creates a gap in the friend number
890 * set, which is filled by the next adding of a friend. Any pattern in friend
891 * numbers should not be relied on.
892 *
893 * If more than INT32_MAX friends are added, this function causes undefined
894 * behaviour.
895 *
896 * @param address The address of the friend (returned by ${self.address.get} of
897 * the friend you wish to add) it must be $ADDRESS_SIZE bytes.
898 * @param message The message that will be sent along with the friend request.
899 * @param length The length of the data byte array.
900 *
901 * @return the friend number on success, UINT32_MAX on failure.
902 */
903 uint32_t add(
904 const uint8_t[ADDRESS_SIZE] address,
905 const uint8_t[length <= MAX_FRIEND_REQUEST_LENGTH] message
906 ) {
907 NULL,
908 /**
909 * The length of the friend request message exceeded
910 * $MAX_FRIEND_REQUEST_LENGTH.
911 */
912 TOO_LONG,
913 /**
914 * The friend request message was empty. This, and the TOO_LONG code will
915 * never be returned from $add_norequest.
916 */
917 NO_MESSAGE,
918 /**
919 * The friend address belongs to the sending client.
920 */
921 OWN_KEY,
922 /**
923 * A friend request has already been sent, or the address belongs to a friend
924 * that is already on the friend list.
925 */
926 ALREADY_SENT,
927 /**
928 * The friend address checksum failed.
929 */
930 BAD_CHECKSUM,
931 /**
932 * The friend was already there, but the nospam value was different.
933 */
934 SET_NEW_NOSPAM,
935 /**
936 * A memory allocation failed when trying to increase the friend list size.
937 */
938 MALLOC,
939 }
940
941
942 /**
943 * Add a friend without sending a friend request.
944 *
945 * This function is used to add a friend in response to a friend request. If the
946 * client receives a friend request, it can be reasonably sure that the other
947 * client added this client as a friend, eliminating the need for a friend
948 * request.
949 *
950 * This function is also useful in a situation where both instances are
951 * controlled by the same entity, so that this entity can perform the mutual
952 * friend adding. In this case, there is no need for a friend request, either.
953 *
954 * @param public_key A byte array of length $PUBLIC_KEY_SIZE containing the
955 * Public Key (not the Address) of the friend to add.
956 *
957 * @return the friend number on success, UINT32_MAX on failure.
958 * @see $add for a more detailed description of friend numbers.
959 */
960 uint32_t add_norequest(const uint8_t[PUBLIC_KEY_SIZE] public_key)
961 with error for add;
962
963
964 /**
965 * Remove a friend from the friend list.
966 *
967 * This does not notify the friend of their deletion. After calling this
968 * function, this client will appear offline to the friend and no communication
969 * can occur between the two.
970 *
971 * @param friend_number Friend number for the friend to be deleted.
972 *
973 * @return true on success.
974 */
975 bool delete(uint32_t friend_number) {
976 /**
977 * There was no friend with the given friend number. No friends were deleted.
978 */
979 FRIEND_NOT_FOUND,
980 }
981
982}
983
984
985/*******************************************************************************
986 *
987 * :: Friend list queries
988 *
989 ******************************************************************************/
990
991namespace friend {
992
993 /**
994 * Return the friend number associated with that Public Key.
995 *
996 * @return the friend number on success, UINT32_MAX on failure.
997 * @param public_key A byte array containing the Public Key.
998 */
999 const uint32_t by_public_key(const uint8_t[PUBLIC_KEY_SIZE] public_key) {
1000 NULL,
1001 /**
1002 * No friend with the given Public Key exists on the friend list.
1003 */
1004 NOT_FOUND,
1005 }
1006
1007
1008 /**
1009 * Checks if a friend with the given friend number exists and returns true if
1010 * it does.
1011 */
1012 const bool exists(uint32_t friend_number);
1013
1014
1015}
1016
1017inline namespace self {
1018
1019 uint32_t[size] friend_list {
1020 /**
1021 * Return the number of friends on the friend list.
1022 *
1023 * This function can be used to determine how much memory to allocate for
1024 * $get.
1025 */
1026 size();
1027
1028
1029 /**
1030 * Copy a list of valid friend numbers into an array.
1031 *
1032 * Call $size to determine the number of elements to allocate.
1033 *
1034 * @param list A memory region with enough space to hold the friend list. If
1035 * this parameter is NULL, this function has no effect.
1036 */
1037 get();
1038 }
1039
1040}
1041
1042
1043
1044namespace friend {
1045
1046 uint8_t[PUBLIC_KEY_SIZE] public_key {
1047 /**
1048 * Copies the Public Key associated with a given friend number to a byte array.
1049 *
1050 * @param friend_number The friend number you want the Public Key of.
1051 * @param public_key A memory region of at least $PUBLIC_KEY_SIZE bytes. If
1052 * this parameter is NULL, this function has no effect.
1053 *
1054 * @return true on success.
1055 */
1056 get(uint32_t friend_number) {
1057 /**
1058 * No friend with the given number exists on the friend list.
1059 */
1060 FRIEND_NOT_FOUND,
1061 }
1062 }
1063
1064}
1065
1066namespace friend {
1067
1068 uint64_t last_online {
1069 /**
1070 * Return a unix-time timestamp of the last time the friend associated with a given
1071 * friend number was seen online. This function will return UINT64_MAX on error.
1072 *
1073 * @param friend_number The friend number you want to query.
1074 */
1075 get(uint32_t friend_number) {
1076 /**
1077 * No friend with the given number exists on the friend list.
1078 */
1079 FRIEND_NOT_FOUND,
1080 }
1081 }
1082
1083}
1084
1085/*******************************************************************************
1086 *
1087 * :: Friend-specific state queries (can also be received through callbacks)
1088 *
1089 ******************************************************************************/
1090
1091
1092namespace friend {
1093
1094 /**
1095 * Common error codes for friend state query functions.
1096 */
1097 error for query {
1098 /**
1099 * The pointer parameter for storing the query result (name, message) was
1100 * NULL. Unlike the `_self_` variants of these functions, which have no effect
1101 * when a parameter is NULL, these functions return an error in that case.
1102 */
1103 NULL,
1104 /**
1105 * The friend_number did not designate a valid friend.
1106 */
1107 FRIEND_NOT_FOUND,
1108 }
1109
1110
1111 uint8_t[length <= MAX_NAME_LENGTH] name {
1112 /**
1113 * Return the length of the friend's name. If the friend number is invalid, the
1114 * return value is unspecified.
1115 *
1116 * The return value is equal to the `length` argument received by the last
1117 * `${event name}` callback.
1118 */
1119 size(uint32_t friend_number)
1120 with error for query;
1121
1122 /**
1123 * Write the name of the friend designated by the given friend number to a byte
1124 * array.
1125 *
1126 * Call $size to determine the allocation size for the `name`
1127 * parameter.
1128 *
1129 * The data written to `name` is equal to the data received by the last
1130 * `${event name}` callback.
1131 *
1132 * @param name A valid memory region large enough to store the friend's name.
1133 *
1134 * @return true on success.
1135 */
1136 get(uint32_t friend_number)
1137 with error for query;
1138 }
1139
1140
1141 /**
1142 * This event is triggered when a friend changes their name.
1143 */
1144 event name {
1145 /**
1146 * @param friend_number The friend number of the friend whose name changed.
1147 * @param name A byte array containing the same data as
1148 * ${name.get} would write to its `name` parameter.
1149 * @param length A value equal to the return value of
1150 * ${name.size}.
1151 */
1152 typedef void(uint32_t friend_number, const uint8_t[length <= MAX_NAME_LENGTH] name);
1153 }
1154
1155
1156 uint8_t[length <= MAX_STATUS_MESSAGE_LENGTH] status_message {
1157 /**
1158 * Return the length of the friend's status message. If the friend number is
1159 * invalid, the return value is SIZE_MAX.
1160 */
1161 size(uint32_t friend_number)
1162 with error for query;
1163
1164 /**
1165 * Write the name of the friend designated by the given friend number to a byte
1166 * array.
1167 *
1168 * Call $size to determine the allocation size for the `status_name`
1169 * parameter.
1170 *
1171 * The data written to `status_message` is equal to the data received by the last
1172 * `${event status_message}` callback.
1173 *
1174 * @param name A valid memory region large enough to store the friend's name.
1175 */
1176 get(uint32_t friend_number)
1177 with error for query;
1178
1179 }
1180
1181
1182 /**
1183 * This event is triggered when a friend changes their status message.
1184 */
1185 event status_message {
1186 /**
1187 * @param friend_number The friend number of the friend whose status message
1188 * changed.
1189 * @param message A byte array containing the same data as
1190 * ${status_message.get} would write to its `status_message` parameter.
1191 * @param length A value equal to the return value of
1192 * ${status_message.size}.
1193 */
1194 typedef void(uint32_t friend_number, const uint8_t[length <= MAX_STATUS_MESSAGE_LENGTH] message);
1195 }
1196
1197
1198 USER_STATUS status {
1199 /**
1200 * Return the friend's user status (away/busy/...). If the friend number is
1201 * invalid, the return value is unspecified.
1202 *
1203 * The status returned is equal to the last status received through the
1204 * `${event status}` callback.
1205 */
1206 get(uint32_t friend_number)
1207 with error for query;
1208 }
1209
1210
1211 /**
1212 * This event is triggered when a friend changes their user status.
1213 */
1214 event status {
1215 /**
1216 * @param friend_number The friend number of the friend whose user status
1217 * changed.
1218 * @param status The new user status.
1219 */
1220 typedef void(uint32_t friend_number, USER_STATUS status);
1221 }
1222
1223
1224 CONNECTION connection_status {
1225 /**
1226 * Check whether a friend is currently connected to this client.
1227 *
1228 * The result of this function is equal to the last value received by the
1229 * `${event connection_status}` callback.
1230 *
1231 * @param friend_number The friend number for which to query the connection
1232 * status.
1233 *
1234 * @return the friend's connection status as it was received through the
1235 * `${event connection_status}` event.
1236 */
1237 get(uint32_t friend_number)
1238 with error for query;
1239 }
1240
1241
1242 /**
1243 * This event is triggered when a friend goes offline after having been online,
1244 * or when a friend goes online.
1245 *
1246 * This callback is not called when adding friends. It is assumed that when
1247 * adding friends, their connection status is initially offline.
1248 */
1249 event connection_status {
1250 /**
1251 * @param friend_number The friend number of the friend whose connection status
1252 * changed.
1253 * @param connection_status The result of calling
1254 * ${connection_status.get} on the passed friend_number.
1255 */
1256 typedef void(uint32_t friend_number, CONNECTION connection_status);
1257 }
1258
1259
1260 bool typing {
1261 /**
1262 * Check whether a friend is currently typing a message.
1263 *
1264 * @param friend_number The friend number for which to query the typing status.
1265 *
1266 * @return true if the friend is typing.
1267 * @return false if the friend is not typing, or the friend number was
1268 * invalid. Inspect the error code to determine which case it is.
1269 */
1270 get(uint32_t friend_number)
1271 with error for query;
1272 }
1273
1274
1275 /**
1276 * This event is triggered when a friend starts or stops typing.
1277 */
1278 event typing {
1279 /**
1280 * @param friend_number The friend number of the friend who started or stopped
1281 * typing.
1282 * @param is_typing The result of calling ${typing.get} on the passed
1283 * friend_number.
1284 */
1285 typedef void(uint32_t friend_number, bool is_typing);
1286 }
1287
1288}
1289
1290
1291/*******************************************************************************
1292 *
1293 * :: Sending private messages
1294 *
1295 ******************************************************************************/
1296
1297
1298inline namespace self {
1299
1300 bool typing {
1301 /**
1302 * Set the client's typing status for a friend.
1303 *
1304 * The client is responsible for turning it on or off.
1305 *
1306 * @param friend_number The friend to which the client is typing a message.
1307 * @param typing The typing status. True means the client is typing.
1308 *
1309 * @return true on success.
1310 */
1311 set(uint32_t friend_number) {
1312 /**
1313 * The friend number did not designate a valid friend.
1314 */
1315 FRIEND_NOT_FOUND,
1316 }
1317 }
1318
1319}
1320
1321
1322namespace friend {
1323
1324 namespace send {
1325
1326 /**
1327 * Send a text chat message to an online friend.
1328 *
1329 * This function creates a chat message packet and pushes it into the send
1330 * queue.
1331 *
1332 * The message length may not exceed $MAX_MESSAGE_LENGTH. Larger messages
1333 * must be split by the client and sent as separate messages. Other clients can
1334 * then reassemble the fragments. Messages may not be empty.
1335 *
1336 * The return value of this function is the message ID. If a read receipt is
1337 * received, the triggered `${event read_receipt}` event will be passed this message ID.
1338 *
1339 * Message IDs are unique per friend. The first message ID is 0. Message IDs are
1340 * incremented by 1 each time a message is sent. If UINT32_MAX messages were
1341 * sent, the next message ID is 0.
1342 *
1343 * @param type Message type (normal, action, ...).
1344 * @param friend_number The friend number of the friend to send the message to.
1345 * @param message A non-NULL pointer to the first element of a byte array
1346 * containing the message text.
1347 * @param length Length of the message to be sent.
1348 */
1349 uint32_t message(uint32_t friend_number, MESSAGE_TYPE type, const uint8_t[length <= MAX_MESSAGE_LENGTH] message) {
1350 NULL,
1351 /**
1352 * The friend number did not designate a valid friend.
1353 */
1354 FRIEND_NOT_FOUND,
1355 /**
1356 * This client is currently not connected to the friend.
1357 */
1358 FRIEND_NOT_CONNECTED,
1359 /**
1360 * An allocation error occurred while increasing the send queue size.
1361 */
1362 SENDQ,
1363 /**
1364 * Message length exceeded $MAX_MESSAGE_LENGTH.
1365 */
1366 TOO_LONG,
1367 /**
1368 * Attempted to send a zero-length message.
1369 */
1370 EMPTY,
1371 }
1372
1373 }
1374
1375
1376 /**
1377 * This event is triggered when the friend receives the message sent with
1378 * ${send.message} with the corresponding message ID.
1379 */
1380 event read_receipt {
1381 /**
1382 * @param friend_number The friend number of the friend who received the message.
1383 * @param message_id The message ID as returned from ${send.message}
1384 * corresponding to the message sent.
1385 */
1386 typedef void(uint32_t friend_number, uint32_t message_id);
1387 }
1388
1389}
1390
1391
1392/*******************************************************************************
1393 *
1394 * :: Receiving private messages and friend requests
1395 *
1396 ******************************************************************************/
1397
1398
1399namespace friend {
1400
1401 /**
1402 * This event is triggered when a friend request is received.
1403 */
1404 event request {
1405 /**
1406 * @param public_key The Public Key of the user who sent the friend request.
1407 * @param time_delta A delta in seconds between when the message was composed
1408 * and when it is being transmitted. For messages that are sent immediately,
1409 * it will be 0. If a message was written and couldn't be sent immediately
1410 * (due to a connection failure, for example), the time_delta is an
1411 * approximation of when it was composed.
1412 * @param message The message they sent along with the request.
1413 * @param length The size of the message byte array.
1414 */
1415 typedef void(const uint8_t[PUBLIC_KEY_SIZE] public_key
1416 //, uint32_t time_delta
1417 , const uint8_t[length <= MAX_MESSAGE_LENGTH] message);
1418 }
1419
1420
1421 /**
1422 * This event is triggered when a message from a friend is received.
1423 */
1424 event message {
1425 /**
1426 * @param friend_number The friend number of the friend who sent the message.
1427 * @param time_delta Time between composition and sending.
1428 * @param message The message data they sent.
1429 * @param length The size of the message byte array.
1430 *
1431 * @see ${event request} for more information on time_delta.
1432 */
1433 typedef void(uint32_t friend_number
1434 //, uint32_t time_delta
1435 , MESSAGE_TYPE type, const uint8_t[length <= MAX_MESSAGE_LENGTH] message);
1436 }
1437
1438}
1439
1440
1441/*******************************************************************************
1442 *
1443 * :: File transmission: common between sending and receiving
1444 *
1445 ******************************************************************************/
1446
1447
1448/**
1449 * Generates a cryptographic hash of the given data.
1450 *
1451 * This function may be used by clients for any purpose, but is provided
1452 * primarily for validating cached avatars. This use is highly recommended to
1453 * avoid unnecessary avatar updates.
1454 *
1455 * If hash is NULL or data is NULL while length is not 0 the function returns false,
1456 * otherwise it returns true.
1457 *
1458 * This function is a wrapper to internal message-digest functions.
1459 *
1460 * @param hash A valid memory location the hash data. It must be at least
1461 * TOX_HASH_LENGTH bytes in size.
1462 * @param data Data to be hashed or NULL.
1463 * @param length Size of the data array or 0.
1464 *
1465 * @return true if hash was not NULL.
1466 */
1467static bool hash(uint8_t[HASH_LENGTH] hash, const uint8_t[length] data);
1468
1469
1470namespace file {
1471
1472 enum KIND {
1473 /**
1474 * Arbitrary file data. Clients can choose to handle it based on the file name
1475 * or magic or any other way they choose.
1476 */
1477 DATA,
1478 /**
1479 * Avatar filename. This consists of $hash(image).
1480 * Avatar data. This consists of the image data.
1481 *
1482 * Avatars can be sent at any time the client wishes. Generally, a client will
1483 * send the avatar to a friend when that friend comes online, and to all
1484 * friends when the avatar changed. A client can save some traffic by
1485 * remembering which friend received the updated avatar already and only send
1486 * it if the friend has an out of date avatar.
1487 *
1488 * Clients who receive avatar send requests can reject it (by sending
1489 * ${CONTROL.CANCEL} before any other controls), or accept it (by
1490 * sending ${CONTROL.RESUME}). The file_id of length $HASH_LENGTH bytes
1491 * (same length as $FILE_ID_LENGTH) will contain the hash. A client can compare
1492 * this hash with a saved hash and send ${CONTROL.CANCEL} to terminate the avatar
1493 * transfer if it matches.
1494 *
1495 * When file_size is set to 0 in the transfer request it means that the client
1496 * has no avatar.
1497 */
1498 AVATAR,
1499 }
1500
1501
1502 enum class CONTROL {
1503 /**
1504 * Sent by the receiving side to accept a file send request. Also sent after a
1505 * $PAUSE command to continue sending or receiving.
1506 */
1507 RESUME,
1508 /**
1509 * Sent by clients to pause the file transfer. The initial state of a file
1510 * transfer is always paused on the receiving side and running on the sending
1511 * side. If both the sending and receiving side pause the transfer, then both
1512 * need to send $RESUME for the transfer to resume.
1513 */
1514 PAUSE,
1515 /**
1516 * Sent by the receiving side to reject a file send request before any other
1517 * commands are sent. Also sent by either side to terminate a file transfer.
1518 */
1519 CANCEL,
1520 }
1521
1522
1523 /**
1524 * Sends a file control command to a friend for a given file transfer.
1525 *
1526 * @param friend_number The friend number of the friend the file is being
1527 * transferred to or received from.
1528 * @param file_number The friend-specific identifier for the file transfer.
1529 * @param control The control command to send.
1530 *
1531 * @return true on success.
1532 */
1533 bool control(uint32_t friend_number, uint32_t file_number, CONTROL control) {
1534 /**
1535 * The friend_number passed did not designate a valid friend.
1536 */
1537 FRIEND_NOT_FOUND,
1538 /**
1539 * This client is currently not connected to the friend.
1540 */
1541 FRIEND_NOT_CONNECTED,
1542 /**
1543 * No file transfer with the given file number was found for the given friend.
1544 */
1545 NOT_FOUND,
1546 /**
1547 * A RESUME control was sent, but the file transfer is running normally.
1548 */
1549 NOT_PAUSED,
1550 /**
1551 * A RESUME control was sent, but the file transfer was paused by the other
1552 * party. Only the party that paused the transfer can resume it.
1553 */
1554 DENIED,
1555 /**
1556 * A PAUSE control was sent, but the file transfer was already paused.
1557 */
1558 ALREADY_PAUSED,
1559 /**
1560 * Packet queue is full.
1561 */
1562 SENDQ,
1563 }
1564
1565
1566 /**
1567 * This event is triggered when a file control command is received from a
1568 * friend.
1569 */
1570 event recv_control {
1571 /**
1572 * When receiving ${CONTROL.CANCEL}, the client should release the
1573 * resources associated with the file number and consider the transfer failed.
1574 *
1575 * @param friend_number The friend number of the friend who is sending the file.
1576 * @param file_number The friend-specific file number the data received is
1577 * associated with.
1578 * @param control The file control command received.
1579 */
1580 typedef void(uint32_t friend_number, uint32_t file_number, CONTROL control);
1581 }
1582
1583 /**
1584 * Sends a file seek control command to a friend for a given file transfer.
1585 *
1586 * This function can only be called to resume a file transfer right before
1587 * ${CONTROL.RESUME} is sent.
1588 *
1589 * @param friend_number The friend number of the friend the file is being
1590 * received from.
1591 * @param file_number The friend-specific identifier for the file transfer.
1592 * @param position The position that the file should be seeked to.
1593 */
1594 bool seek(uint32_t friend_number, uint32_t file_number, uint64_t position) {
1595 /**
1596 * The friend_number passed did not designate a valid friend.
1597 */
1598 FRIEND_NOT_FOUND,
1599 /**
1600 * This client is currently not connected to the friend.
1601 */
1602 FRIEND_NOT_CONNECTED,
1603 /**
1604 * No file transfer with the given file number was found for the given friend.
1605 */
1606 NOT_FOUND,
1607 /**
1608 * File was not in a state where it could be seeked.
1609 */
1610 DENIED,
1611 /**
1612 * Seek position was invalid
1613 */
1614 INVALID_POSITION,
1615 /**
1616 * Packet queue is full.
1617 */
1618 SENDQ,
1619 }
1620
1621
1622 error for get {
1623 /**
1624 * The friend_number passed did not designate a valid friend.
1625 */
1626 FRIEND_NOT_FOUND,
1627 /**
1628 * No file transfer with the given file number was found for the given friend.
1629 */
1630 NOT_FOUND,
1631 }
1632
1633 /**
1634 * Copy the file id associated to the file transfer to a byte array.
1635 *
1636 * @param friend_number The friend number of the friend the file is being
1637 * transferred to or received from.
1638 * @param file_number The friend-specific identifier for the file transfer.
1639 * @param file_id A memory region of at least $FILE_ID_LENGTH bytes. If
1640 * this parameter is NULL, this function has no effect.
1641 *
1642 * @return true on success.
1643 */
1644 const bool get_file_id(uint32_t friend_number, uint32_t file_number, uint8_t[FILE_ID_LENGTH] file_id)
1645 with error for get;
1646
1647}
1648
1649
1650/*******************************************************************************
1651 *
1652 * :: File transmission: sending
1653 *
1654 ******************************************************************************/
1655
1656
1657namespace file {
1658
1659 /**
1660 * Send a file transmission request.
1661 *
1662 * Maximum filename length is $MAX_FILENAME_LENGTH bytes. The filename
1663 * should generally just be a file name, not a path with directory names.
1664 *
1665 * If a non-UINT64_MAX file size is provided, it can be used by both sides to
1666 * determine the sending progress. File size can be set to UINT64_MAX for streaming
1667 * data of unknown size.
1668 *
1669 * File transmission occurs in chunks, which are requested through the
1670 * `${event chunk_request}` event.
1671 *
1672 * When a friend goes offline, all file transfers associated with the friend are
1673 * purged from core.
1674 *
1675 * If the file contents change during a transfer, the behaviour is unspecified
1676 * in general. What will actually happen depends on the mode in which the file
1677 * was modified and how the client determines the file size.
1678 *
1679 * - If the file size was increased
1680 * - and sending mode was streaming (file_size = UINT64_MAX), the behaviour
1681 * will be as expected.
1682 * - and sending mode was file (file_size != UINT64_MAX), the
1683 * ${event chunk_request} callback will receive length = 0 when Core thinks
1684 * the file transfer has finished. If the client remembers the file size as
1685 * it was when sending the request, it will terminate the transfer normally.
1686 * If the client re-reads the size, it will think the friend cancelled the
1687 * transfer.
1688 * - If the file size was decreased
1689 * - and sending mode was streaming, the behaviour is as expected.
1690 * - and sending mode was file, the callback will return 0 at the new
1691 * (earlier) end-of-file, signalling to the friend that the transfer was
1692 * cancelled.
1693 * - If the file contents were modified
1694 * - at a position before the current read, the two files (local and remote)
1695 * will differ after the transfer terminates.
1696 * - at a position after the current read, the file transfer will succeed as
1697 * expected.
1698 * - In either case, both sides will regard the transfer as complete and
1699 * successful.
1700 *
1701 * @param friend_number The friend number of the friend the file send request
1702 * should be sent to.
1703 * @param kind The meaning of the file to be sent.
1704 * @param file_size Size in bytes of the file the client wants to send, UINT64_MAX if
1705 * unknown or streaming.
1706 * @param file_id A file identifier of length $FILE_ID_LENGTH that can be used to
1707 * uniquely identify file transfers across core restarts. If NULL, a random one will
1708 * be generated by core. It can then be obtained by using $get_file_id().
1709 * @param filename Name of the file. Does not need to be the actual name. This
1710 * name will be sent along with the file send request.
1711 * @param filename_length Size in bytes of the filename.
1712 *
1713 * @return A file number used as an identifier in subsequent callbacks. This
1714 * number is per friend. File numbers are reused after a transfer terminates.
1715 * On failure, this function returns UINT32_MAX. Any pattern in file numbers
1716 * should not be relied on.
1717 */
1718 uint32_t send(uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t[FILE_ID_LENGTH] file_id, const uint8_t[filename_length <= MAX_FILENAME_LENGTH] filename) {
1719 NULL,
1720 /**
1721 * The friend_number passed did not designate a valid friend.
1722 */
1723 FRIEND_NOT_FOUND,
1724 /**
1725 * This client is currently not connected to the friend.
1726 */
1727 FRIEND_NOT_CONNECTED,
1728 /**
1729 * Filename length exceeded $MAX_FILENAME_LENGTH bytes.
1730 */
1731 NAME_TOO_LONG,
1732 /**
1733 * Too many ongoing transfers. The maximum number of concurrent file transfers
1734 * is 256 per friend per direction (sending and receiving).
1735 */
1736 TOO_MANY,
1737 }
1738
1739
1740 /**
1741 * Send a chunk of file data to a friend.
1742 *
1743 * This function is called in response to the `${event chunk_request}` callback. The
1744 * length parameter should be equal to the one received though the callback.
1745 * If it is zero, the transfer is assumed complete. For files with known size,
1746 * Core will know that the transfer is complete after the last byte has been
1747 * received, so it is not necessary (though not harmful) to send a zero-length
1748 * chunk to terminate. For streams, core will know that the transfer is finished
1749 * if a chunk with length less than the length requested in the callback is sent.
1750 *
1751 * @param friend_number The friend number of the receiving friend for this file.
1752 * @param file_number The file transfer identifier returned by tox_file_send.
1753 * @param position The file or stream position from which to continue reading.
1754 * @return true on success.
1755 */
1756 bool send_chunk(uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t[length] data) {
1757 /**
1758 * The length parameter was non-zero, but data was NULL.
1759 */
1760 NULL,
1761 /**
1762 * The friend_number passed did not designate a valid friend.
1763 */
1764 FRIEND_NOT_FOUND,
1765 /**
1766 * This client is currently not connected to the friend.
1767 */
1768 FRIEND_NOT_CONNECTED,
1769 /**
1770 * No file transfer with the given file number was found for the given friend.
1771 */
1772 NOT_FOUND,
1773 /**
1774 * File transfer was found but isn't in a transferring state: (paused, done,
1775 * broken, etc...) (happens only when not called from the request chunk callback).
1776 */
1777 NOT_TRANSFERRING,
1778 /**
1779 * Attempted to send more or less data than requested. The requested data size is
1780 * adjusted according to maximum transmission unit and the expected end of
1781 * the file. Trying to send less or more than requested will return this error.
1782 */
1783 INVALID_LENGTH,
1784 /**
1785 * Packet queue is full.
1786 */
1787 SENDQ,
1788 /**
1789 * Position parameter was wrong.
1790 */
1791 WRONG_POSITION,
1792 }
1793
1794
1795 /**
1796 * This event is triggered when Core is ready to send more file data.
1797 */
1798 event chunk_request {
1799 /**
1800 * If the length parameter is 0, the file transfer is finished, and the client's
1801 * resources associated with the file number should be released. After a call
1802 * with zero length, the file number can be reused for future file transfers.
1803 *
1804 * If the requested position is not equal to the client's idea of the current
1805 * file or stream position, it will need to seek. In case of read-once streams,
1806 * the client should keep the last read chunk so that a seek back can be
1807 * supported. A seek-back only ever needs to read from the last requested chunk.
1808 * This happens when a chunk was requested, but the send failed. A seek-back
1809 * request can occur an arbitrary number of times for any given chunk.
1810 *
1811 * In response to receiving this callback, the client should call the function
1812 * `$send_chunk` with the requested chunk. If the number of bytes sent
1813 * through that function is zero, the file transfer is assumed complete. A
1814 * client must send the full length of data requested with this callback.
1815 *
1816 * @param friend_number The friend number of the receiving friend for this file.
1817 * @param file_number The file transfer identifier returned by $send.
1818 * @param position The file or stream position from which to continue reading.
1819 * @param length The number of bytes requested for the current chunk.
1820 */
1821 typedef void(uint32_t friend_number, uint32_t file_number, uint64_t position, size_t length);
1822 }
1823
1824}
1825
1826
1827/*******************************************************************************
1828 *
1829 * :: File transmission: receiving
1830 *
1831 ******************************************************************************/
1832
1833
1834namespace file {
1835
1836 /**
1837 * This event is triggered when a file transfer request is received.
1838 */
1839 event recv {
1840 /**
1841 * The client should acquire resources to be associated with the file transfer.
1842 * Incoming file transfers start in the PAUSED state. After this callback
1843 * returns, a transfer can be rejected by sending a ${CONTROL.CANCEL}
1844 * control command before any other control commands. It can be accepted by
1845 * sending ${CONTROL.RESUME}.
1846 *
1847 * @param friend_number The friend number of the friend who is sending the file
1848 * transfer request.
1849 * @param file_number The friend-specific file number the data received is
1850 * associated with.
1851 * @param kind The meaning of the file to be sent.
1852 * @param file_size Size in bytes of the file the client wants to send,
1853 * UINT64_MAX if unknown or streaming.
1854 * @param filename Name of the file. Does not need to be the actual name. This
1855 * name will be sent along with the file send request.
1856 * @param filename_length Size in bytes of the filename.
1857 */
1858 typedef void(uint32_t friend_number, uint32_t file_number, uint32_t kind,
1859 uint64_t file_size, const uint8_t[filename_length <= MAX_FILENAME_LENGTH] filename);
1860 }
1861
1862
1863 /**
1864 * This event is first triggered when a file transfer request is received, and
1865 * subsequently when a chunk of file data for an accepted request was received.
1866 */
1867 event recv_chunk {
1868 /**
1869 * When length is 0, the transfer is finished and the client should release the
1870 * resources it acquired for the transfer. After a call with length = 0, the
1871 * file number can be reused for new file transfers.
1872 *
1873 * If position is equal to file_size (received in the file_receive callback)
1874 * when the transfer finishes, the file was received completely. Otherwise, if
1875 * file_size was UINT64_MAX, streaming ended successfully when length is 0.
1876 *
1877 * @param friend_number The friend number of the friend who is sending the file.
1878 * @param file_number The friend-specific file number the data received is
1879 * associated with.
1880 * @param position The file position of the first byte in data.
1881 * @param data A byte array containing the received chunk.
1882 * @param length The length of the received chunk.
1883 */
1884 typedef void(uint32_t friend_number, uint32_t file_number, uint64_t position,
1885 const uint8_t[length] data);
1886 }
1887
1888}
1889
1890
1891/*******************************************************************************
1892 *
1893 * :: Group chat management
1894 *
1895 ******************************************************************************/
1896
1897
1898/******************************************************************************
1899 *
1900 * :: Group chat message sending and receiving
1901 *
1902 ******************************************************************************/
1903
1904
1905/*******************************************************************************
1906 *
1907 * :: Low-level custom packet sending and receiving
1908 *
1909 ******************************************************************************/
1910
1911
1912namespace friend {
1913
1914 inline namespace send {
1915
1916 error for custom_packet {
1917 NULL,
1918 /**
1919 * The friend number did not designate a valid friend.
1920 */
1921 FRIEND_NOT_FOUND,
1922 /**
1923 * This client is currently not connected to the friend.
1924 */
1925 FRIEND_NOT_CONNECTED,
1926 /**
1927 * The first byte of data was not in the specified range for the packet type.
1928 * This range is 200-254 for lossy, and 160-191 for lossless packets.
1929 */
1930 INVALID,
1931 /**
1932 * Attempted to send an empty packet.
1933 */
1934 EMPTY,
1935 /**
1936 * Packet data length exceeded $MAX_CUSTOM_PACKET_SIZE.
1937 */
1938 TOO_LONG,
1939 /**
1940 * Packet queue is full.
1941 */
1942 SENDQ,
1943 }
1944
1945 /**
1946 * Send a custom lossy packet to a friend.
1947 *
1948 * The first byte of data must be in the range 200-254. Maximum length of a
1949 * custom packet is $MAX_CUSTOM_PACKET_SIZE.
1950 *
1951 * Lossy packets behave like UDP packets, meaning they might never reach the
1952 * other side or might arrive more than once (if someone is messing with the
1953 * connection) or might arrive in the wrong order.
1954 *
1955 * Unless latency is an issue, it is recommended that you use lossless custom
1956 * packets instead.
1957 *
1958 * @param friend_number The friend number of the friend this lossy packet
1959 * should be sent to.
1960 * @param data A byte array containing the packet data.
1961 * @param length The length of the packet data byte array.
1962 *
1963 * @return true on success.
1964 */
1965 bool lossy_packet(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data)
1966 with error for custom_packet;
1967
1968
1969 /**
1970 * Send a custom lossless packet to a friend.
1971 *
1972 * The first byte of data must be in the range 160-191. Maximum length of a
1973 * custom packet is $MAX_CUSTOM_PACKET_SIZE.
1974 *
1975 * Lossless packet behaviour is comparable to TCP (reliability, arrive in order)
1976 * but with packets instead of a stream.
1977 *
1978 * @param friend_number The friend number of the friend this lossless packet
1979 * should be sent to.
1980 * @param data A byte array containing the packet data.
1981 * @param length The length of the packet data byte array.
1982 *
1983 * @return true on success.
1984 */
1985 bool lossless_packet(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data)
1986 with error for custom_packet;
1987
1988 }
1989
1990
1991 event lossy_packet {
1992 /**
1993 * @param friend_number The friend number of the friend who sent a lossy packet.
1994 * @param data A byte array containing the received packet data.
1995 * @param length The length of the packet data byte array.
1996 */
1997 typedef void(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data);
1998 }
1999
2000
2001 event lossless_packet {
2002 /**
2003 * @param friend_number The friend number of the friend who sent the packet.
2004 * @param data A byte array containing the received packet data.
2005 * @param length The length of the packet data byte array.
2006 */
2007 typedef void(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data);
2008 }
2009
2010}
2011
2012
2013
2014/*******************************************************************************
2015 *
2016 * :: Low-level network information
2017 *
2018 ******************************************************************************/
2019
2020
2021inline namespace self {
2022
2023 uint8_t[PUBLIC_KEY_SIZE] dht_id {
2024 /**
2025 * Writes the temporary DHT public key of this instance to a byte array.
2026 *
2027 * This can be used in combination with an externally accessible IP address and
2028 * the bound port (from ${udp_port.get}) to run a temporary bootstrap node.
2029 *
2030 * Be aware that every time a new instance is created, the DHT public key
2031 * changes, meaning this cannot be used to run a permanent bootstrap node.
2032 *
2033 * @param dht_id A memory region of at least $PUBLIC_KEY_SIZE bytes. If this
2034 * parameter is NULL, this function has no effect.
2035 */
2036 get();
2037 }
2038
2039
2040 error for get_port {
2041 /**
2042 * The instance was not bound to any port.
2043 */
2044 NOT_BOUND,
2045 }
2046
2047
2048 uint16_t udp_port {
2049 /**
2050 * Return the UDP port this Tox instance is bound to.
2051 */
2052 get() with error for get_port;
2053 }
2054
2055
2056 uint16_t tcp_port {
2057 /**
2058 * Return the TCP port this Tox instance is bound to. This is only relevant if
2059 * the instance is acting as a TCP relay.
2060 */
2061 get() with error for get_port;
2062 }
2063
2064}
2065
2066} // class tox
2067
2068%{
2069#include "tox_old.h"
2070
2071#ifdef __cplusplus
2072}
2073#endif
2074
2075#endif
2076%}
diff --git a/tools/README b/other/astyle/README
index 26802ec7..26802ec7 100644
--- a/tools/README
+++ b/other/astyle/README
diff --git a/tools/astylerc b/other/astyle/astylerc
index dd738b74..dd738b74 100644
--- a/tools/astylerc
+++ b/other/astyle/astylerc
diff --git a/tools/pre-commit b/other/astyle/pre-commit
index 8f91779d..8f91779d 100644
--- a/tools/pre-commit
+++ b/other/astyle/pre-commit
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index bc020d87..dbce762e 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -336,3 +336,8 @@ void LANdiscovery_init(DHT *dht)
336{ 336{
337 networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht); 337 networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht);
338} 338}
339
340void LANdiscovery_kill(DHT *dht)
341{
342 networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, NULL, NULL);
343}
diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h
index 5dffc3ad..5243bd93 100644
--- a/toxcore/LAN_discovery.h
+++ b/toxcore/LAN_discovery.h
@@ -37,6 +37,9 @@ int send_LANdiscovery(uint16_t port, DHT *dht);
37/* Sets up packet handlers. */ 37/* Sets up packet handlers. */
38void LANdiscovery_init(DHT *dht); 38void LANdiscovery_init(DHT *dht);
39 39
40/* Clear packet handlers. */
41void LANdiscovery_kill(DHT *dht);
42
40/* checks if a given IP isn't routable 43/* checks if a given IP isn't routable
41 * 44 *
42 * return 0 if ip is a LAN ip. 45 * return 0 if ip is a LAN ip.
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index fefc3b17..a7e0a9fe 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -433,14 +433,19 @@ int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber)
433 return -1; 433 return -1;
434 434
435 if (m->friendlist[friendnumber].status == FRIEND_ONLINE) { 435 if (m->friendlist[friendnumber].status == FRIEND_ONLINE) {
436 uint8_t direct_connected = 0; 436 _Bool direct_connected = 0;
437 unsigned int num_online_relays = 0;
437 crypto_connection_status(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, 438 crypto_connection_status(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c,
438 m->friendlist[friendnumber].friendcon_id), &direct_connected); 439 m->friendlist[friendnumber].friendcon_id), &direct_connected, &num_online_relays);
439 440
440 if (direct_connected) { 441 if (direct_connected) {
441 return CONNECTION_UDP; 442 return CONNECTION_UDP;
442 } else { 443 } else {
443 return CONNECTION_TCP; 444 if (num_online_relays) {
445 return CONNECTION_TCP;
446 } else {
447 return CONNECTION_UNKNOWN;
448 }
444 } 449 }
445 } else { 450 } else {
446 return CONNECTION_NONE; 451 return CONNECTION_NONE;
@@ -493,10 +498,6 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con
493 498
494 uint32_t msg_id = ++m->friendlist[friendnumber].message_id; 499 uint32_t msg_id = ++m->friendlist[friendnumber].message_id;
495 500
496 if (msg_id == 0) {
497 msg_id = ++m->friendlist[friendnumber].message_id; // Otherwise, false error
498 }
499
500 add_receipt(m, friendnumber, packet_num, msg_id); 501 add_receipt(m, friendnumber, packet_num, msg_id);
501 502
502 if (message_id) 503 if (message_id)
@@ -753,25 +754,6 @@ static int send_user_istyping(const Messenger *m, int32_t friendnumber, uint8_t
753 return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing), 0); 754 return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing), 0);
754} 755}
755 756
756static int send_relays(const Messenger *m, int32_t friendnumber)
757{
758 Node_format nodes[MAX_SHARED_RELAYS];
759 uint8_t data[1024];
760 int n, length;
761
762 n = copy_connected_tcp_relays(m->net_crypto, nodes, MAX_SHARED_RELAYS);
763 length = pack_nodes(data, sizeof(data), nodes, n);
764
765 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_SHARE_RELAYS, data, length, 0);
766
767 if (ret == 1)
768 m->friendlist[friendnumber].share_relays_lastsent = unix_time();
769
770 return ret;
771}
772
773
774
775static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, const uint8_t *status, uint16_t length) 757static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, const uint8_t *status, uint16_t length)
776{ 758{
777 if (friend_not_valid(m, friendnumber)) 759 if (friend_not_valid(m, friendnumber))
@@ -874,6 +856,14 @@ static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber)
874 if (ret == -1) 856 if (ret == -1)
875 return; 857 return;
876 858
859 if (ret == CONNECTION_UNKNOWN) {
860 if (last_connection_udp_tcp == CONNECTION_UDP) {
861 return;
862 } else {
863 ret = CONNECTION_TCP;
864 }
865 }
866
877 if (last_connection_udp_tcp != ret) { 867 if (last_connection_udp_tcp != ret) {
878 if (m->friend_connectionstatuschange) 868 if (m->friend_connectionstatuschange)
879 m->friend_connectionstatuschange(m, friendnumber, ret, m->friend_connectionstatuschange_userdata); 869 m->friend_connectionstatuschange(m, friendnumber, ret, m->friend_connectionstatuschange_userdata);
@@ -1350,7 +1340,7 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin
1350 if (m->friendlist[friendnumber].status != FRIEND_ONLINE) 1340 if (m->friendlist[friendnumber].status != FRIEND_ONLINE)
1351 return -2; 1341 return -2;
1352 1342
1353 if (filenumber > MAX_CONCURRENT_FILE_PIPES) 1343 if (filenumber >= MAX_CONCURRENT_FILE_PIPES)
1354 return -3; 1344 return -3;
1355 1345
1356 struct File_Transfers *ft = &m->friendlist[friendnumber].file_sending[filenumber]; 1346 struct File_Transfers *ft = &m->friendlist[friendnumber].file_sending[filenumber];
@@ -1775,15 +1765,6 @@ static int friend_already_added(const uint8_t *real_pk, void *data)
1775 return -1; 1765 return -1;
1776} 1766}
1777 1767
1778/* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */
1779static void LANdiscovery(Messenger *m)
1780{
1781 if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) {
1782 send_LANdiscovery(htons(TOX_PORT_DEFAULT), m->dht);
1783 m->last_LANdiscovery = unix_time();
1784 }
1785}
1786
1787/* Run this at startup. */ 1768/* Run this at startup. */
1788Messenger *new_messenger(Messenger_Options *options, unsigned int *error) 1769Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
1789{ 1770{
@@ -1852,7 +1833,6 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
1852 1833
1853 m->options = *options; 1834 m->options = *options;
1854 friendreq_init(&(m->fr), m->fr_c); 1835 friendreq_init(&(m->fr), m->fr_c);
1855 LANdiscovery_init(m->dht);
1856 set_nospam(&(m->fr), random_int()); 1836 set_nospam(&(m->fr), random_int());
1857 set_filter_function(&(m->fr), &friend_already_added, m); 1837 set_filter_function(&(m->fr), &friend_already_added, m);
1858 1838
@@ -2178,22 +2158,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2178 break; 2158 break;
2179 } 2159 }
2180 2160
2181 case PACKET_ID_SHARE_RELAYS: {
2182 Node_format nodes[MAX_SHARED_RELAYS];
2183 int n;
2184
2185 if ((n = unpack_nodes(nodes, MAX_SHARED_RELAYS, NULL, data, data_length, 1)) == -1)
2186 break;
2187
2188 int i;
2189
2190 for (i = 0; i < n; i++) {
2191 add_tcp_relay(m->net_crypto, nodes[i].ip_port, nodes[i].public_key);
2192 }
2193
2194 break;
2195 }
2196
2197 default: { 2161 default: {
2198 handle_custom_lossless_packet(object, i, temp, len); 2162 handle_custom_lossless_packet(object, i, temp, len);
2199 break; 2163 break;
@@ -2251,10 +2215,6 @@ void do_friends(Messenger *m)
2251 m->friendlist[i].user_istyping_sent = 1; 2215 m->friendlist[i].user_istyping_sent = 1;
2252 } 2216 }
2253 2217
2254 if (m->friendlist[i].share_relays_lastsent + FRIEND_SHARE_RELAYS_INTERVAL < temp_time) {
2255 send_relays(m, i);
2256 }
2257
2258 check_friend_tcp_udp(m, i); 2218 check_friend_tcp_udp(m, i);
2259 do_receipts(m, i); 2219 do_receipts(m, i);
2260 do_reqchunk_filecb(m, i); 2220 do_reqchunk_filecb(m, i);
@@ -2338,7 +2298,6 @@ void do_messenger(Messenger *m)
2338 do_onion_client(m->onion_c); 2298 do_onion_client(m->onion_c);
2339 do_friend_connections(m->fr_c); 2299 do_friend_connections(m->fr_c);
2340 do_friends(m); 2300 do_friends(m);
2341 LANdiscovery(m);
2342 connection_status_cb(m); 2301 connection_status_cb(m);
2343 2302
2344#ifdef LOGGING 2303#ifdef LOGGING
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index 63fb2820..6943475f 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -42,8 +42,7 @@ enum {
42 MESSAGE_ACTION 42 MESSAGE_ACTION
43}; 43};
44 44
45/* NOTE: Packet ids below 20 must never be used. */ 45/* NOTE: Packet ids below 24 must never be used. */
46#define PACKET_ID_SHARE_RELAYS 23
47#define PACKET_ID_ONLINE 24 46#define PACKET_ID_ONLINE 24
48#define PACKET_ID_OFFLINE 25 47#define PACKET_ID_OFFLINE 25
49#define PACKET_ID_NICKNAME 48 48#define PACKET_ID_NICKNAME 48
@@ -62,9 +61,6 @@ enum {
62#define PACKET_ID_MESSAGE_GROUPCHAT 99 61#define PACKET_ID_MESSAGE_GROUPCHAT 99
63#define PACKET_ID_LOSSY_GROUPCHAT 199 62#define PACKET_ID_LOSSY_GROUPCHAT 199
64 63
65/* Max number of tcp relays sent to friends */
66#define MAX_SHARED_RELAYS 16
67
68/* All packets starting with a byte in this range can be used for anything. */ 64/* All packets starting with a byte in this range can be used for anything. */
69#define PACKET_ID_LOSSLESS_RANGE_START 160 65#define PACKET_ID_LOSSLESS_RANGE_START 160
70#define PACKET_ID_LOSSLESS_RANGE_SIZE 32 66#define PACKET_ID_LOSSLESS_RANGE_SIZE 32
@@ -110,13 +106,11 @@ enum {
110/* Default start timeout in seconds between friend requests. */ 106/* Default start timeout in seconds between friend requests. */
111#define FRIENDREQUEST_TIMEOUT 5; 107#define FRIENDREQUEST_TIMEOUT 5;
112 108
113/* Interval between the sending of tcp relay information */
114#define FRIEND_SHARE_RELAYS_INTERVAL (5 * 60)
115
116enum { 109enum {
117 CONNECTION_NONE, 110 CONNECTION_NONE,
118 CONNECTION_TCP, 111 CONNECTION_TCP,
119 CONNECTION_UDP 112 CONNECTION_UDP,
113 CONNECTION_UNKNOWN
120}; 114};
121 115
122/* USERSTATUS - 116/* USERSTATUS -
@@ -199,7 +193,6 @@ typedef struct {
199 uint32_t message_id; // a semi-unique id used in read receipts. 193 uint32_t message_id; // a semi-unique id used in read receipts.
200 uint32_t friendrequest_nospam; // The nospam number used in the friend request. 194 uint32_t friendrequest_nospam; // The nospam number used in the friend request.
201 uint64_t last_seen_time; 195 uint64_t last_seen_time;
202 uint64_t share_relays_lastsent;
203 uint8_t last_connection_udp_tcp; 196 uint8_t last_connection_udp_tcp;
204 struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES]; 197 struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES];
205 unsigned int num_sending_files; 198 unsigned int num_sending_files;
@@ -241,8 +234,6 @@ struct Messenger {
241 234
242 uint32_t numonline_friends; 235 uint32_t numonline_friends;
243 236
244 uint64_t last_LANdiscovery;
245
246#define NUM_SAVED_TCP_RELAYS 8 237#define NUM_SAVED_TCP_RELAYS 8
247 uint8_t has_added_relays; // If the first connection has occurred in do_messenger 238 uint8_t has_added_relays; // If the first connection has occurred in do_messenger
248 Node_format loaded_relays[NUM_SAVED_TCP_RELAYS]; // Relays loaded from config 239 Node_format loaded_relays[NUM_SAVED_TCP_RELAYS]; // Relays loaded from config
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index d89b157c..1bd11a1d 100644
--- a/toxcore/TCP_client.c
+++ b/toxcore/TCP_client.c
@@ -87,7 +87,7 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con
87 const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, 87 const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two,
88 ip, port, three); 88 ip, port, three);
89 89
90 if (written < 0) { 90 if (written < 0 || MAX_PACKET_SIZE < written) {
91 return 0; 91 return 0;
92 } 92 }
93 93
diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h
index d4d18a4b..722430e0 100644
--- a/toxcore/TCP_client.h
+++ b/toxcore/TCP_client.h
@@ -78,10 +78,6 @@ typedef struct {
78 uint64_t ping_response_id; 78 uint64_t ping_response_id;
79 uint64_t ping_request_id; 79 uint64_t ping_request_id;
80 80
81 //TODO: remove
82 void *net_crypto_pointer;
83 uint32_t net_crypto_location;
84
85 struct { 81 struct {
86 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ 82 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */
87 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 83 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c
index e11e1318..fe39dc52 100644
--- a/toxcore/TCP_connection.c
+++ b/toxcore/TCP_connection.c
@@ -26,6 +26,7 @@
26#endif 26#endif
27 27
28#include "TCP_connection.h" 28#include "TCP_connection.h"
29#include "util.h"
29 30
30/* Set the size of the array to num. 31/* Set the size of the array to num.
31 * 32 *
@@ -212,6 +213,8 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
212 unsigned int i; 213 unsigned int i;
213 int ret = -1; 214 int ret = -1;
214 215
216 _Bool limit_reached = 0;
217
215 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { 218 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
216 uint32_t tcp_con_num = con_to->connections[i].tcp_connection; 219 uint32_t tcp_con_num = con_to->connections[i].tcp_connection;
217 uint8_t status = con_to->connections[i].status; 220 uint8_t status = con_to->connections[i].status;
@@ -227,6 +230,10 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
227 230
228 ret = send_data(tcp_con->connection, connection_id, packet, length); 231 ret = send_data(tcp_con->connection, connection_id, packet, length);
229 232
233 if (ret == 0) {
234 limit_reached = 1;
235 }
236
230 if (ret == 1) { 237 if (ret == 1) {
231 break; 238 break;
232 } 239 }
@@ -235,7 +242,10 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
235 242
236 if (ret == 1) { 243 if (ret == 1) {
237 return 0; 244 return 0;
238 } else { 245 } else if (!limit_reached) {
246 ret = 0;
247
248 /* Send oob packets to all relays tied to the connection. */
239 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { 249 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
240 uint32_t tcp_con_num = con_to->connections[i].tcp_connection; 250 uint32_t tcp_con_num = con_to->connections[i].tcp_connection;
241 uint8_t status = con_to->connections[i].status; 251 uint8_t status = con_to->connections[i].status;
@@ -249,19 +259,19 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
249 continue; 259 continue;
250 } 260 }
251 261
252 ret = send_oob_packet(tcp_con->connection, con_to->public_key, packet, length); 262 if (send_oob_packet(tcp_con->connection, con_to->public_key, packet, length) == 1) {
253 263 ret += 1;
254 if (ret == 1) {
255 break;
256 } 264 }
257 } 265 }
258 } 266 }
259 267
260 if (ret == 1) { 268 if (ret >= 1) {
261 return 0; 269 return 0;
262 } else { 270 } else {
263 return -1; 271 return -1;
264 } 272 }
273 } else {
274 return -1;
265 } 275 }
266} 276}
267 277
@@ -273,13 +283,15 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
273 * return TCP connection number on success. 283 * return TCP connection number on success.
274 * return -1 on failure. 284 * return -1 on failure.
275 */ 285 */
276int get_random_tcp_conn_number(TCP_Connections *tcp_c) 286int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c)
277{ 287{
278 unsigned int i, r = rand(); 288 unsigned int i, r = rand();
279 289
280 for (i = 0; i < tcp_c->tcp_connections_length; ++i) { 290 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
281 if (tcp_c->tcp_connections[(i + r) % tcp_c->tcp_connections_length].status == TCP_CONN_CONNECTED) { 291 unsigned int index = ((i + r) % tcp_c->tcp_connections_length);
282 return ((i + r) % tcp_c->tcp_connections_length); 292
293 if (tcp_c->tcp_connections[index].onion && tcp_c->tcp_connections[index].status == TCP_CONN_CONNECTED) {
294 return index;
283 } 295 }
284 } 296 }
285 297
@@ -321,6 +333,9 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num
321 if (!tcp_con) 333 if (!tcp_con)
322 return -1; 334 return -1;
323 335
336 if (tcp_con->status != TCP_CONN_CONNECTED)
337 return -1;
338
324 int ret = send_oob_packet(tcp_con->connection, public_key, packet, length); 339 int ret = send_oob_packet(tcp_con->connection, public_key, packet, length);
325 340
326 if (ret == 1) 341 if (ret == 1)
@@ -392,8 +407,14 @@ static int find_tcp_connection_relay(TCP_Connections *tcp_c, const uint8_t *rela
392 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 407 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
393 408
394 if (tcp_con) { 409 if (tcp_con) {
395 if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) { 410 if (tcp_con->status == TCP_CONN_SLEEPING) {
396 return i; 411 if (memcmp(tcp_con->relay_pk, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) {
412 return i;
413 }
414 } else {
415 if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) {
416 return i;
417 }
397 } 418 }
398 } 419 }
399 } 420 }
@@ -451,14 +472,86 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
451 send_disconnect_request(tcp_con->connection, con_to->connections[i].connection_id); 472 send_disconnect_request(tcp_con->connection, con_to->connections[i].connection_id);
452 } 473 }
453 474
454 --tcp_con->lock_count; 475 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
476 --tcp_con->lock_count;
477
478 if (con_to->status == TCP_CONN_SLEEPING) {
479 --tcp_con->sleep_count;
480 }
481 }
455 } 482 }
456 } 483 }
457 484
458 return wipe_connection(tcp_c, connections_number); 485 return wipe_connection(tcp_c, connections_number);
459} 486}
460 487
461static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connections_number) 488/* Set connection status.
489 *
490 * status of 1 means we are using the connection.
491 * status of 0 means we are not using it.
492 *
493 * Unused tcp connections will be disconnected from but kept in case they are needed.
494 *
495 * return 0 on success.
496 * return -1 on failure.
497 */
498int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status)
499{
500 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
501
502 if (!con_to)
503 return -1;
504
505 if (status) {
506 /* Conection is unsleeping. */
507 if (con_to->status != TCP_CONN_SLEEPING)
508 return -1;
509
510 unsigned int i;
511
512 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
513 if (con_to->connections[i].tcp_connection) {
514 unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
515 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
516
517 if (!tcp_con)
518 continue;
519
520 if (tcp_con->status == TCP_CONN_SLEEPING) {
521 tcp_con->unsleep = 1;
522 }
523 }
524 }
525
526 con_to->status = TCP_CONN_VALID;
527 return 0;
528 } else {
529 /* Conection is going to sleep. */
530 if (con_to->status != TCP_CONN_VALID)
531 return -1;
532
533 unsigned int i;
534
535 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
536 if (con_to->connections[i].tcp_connection) {
537 unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
538 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
539
540 if (!tcp_con)
541 continue;
542
543 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
544 ++tcp_con->sleep_count;
545 }
546 }
547 }
548
549 con_to->status = TCP_CONN_SLEEPING;
550 return 0;
551 }
552}
553
554static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
462{ 555{
463 unsigned int i; 556 unsigned int i;
464 557
@@ -474,7 +567,7 @@ static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connectio
474/* return index on success. 567/* return index on success.
475 * return -1 on failure. 568 * return -1 on failure.
476 */ 569 */
477static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, int tcp_connections_number) 570static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
478{ 571{
479 unsigned int i; 572 unsigned int i;
480 573
@@ -496,7 +589,7 @@ static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, int tcp_connect
496/* return index on success. 589/* return index on success.
497 * return -1 on failure. 590 * return -1 on failure.
498 */ 591 */
499static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, int tcp_connections_number) 592static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
500{ 593{
501 unsigned int i; 594 unsigned int i;
502 595
@@ -512,16 +605,39 @@ static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, int tcp_connec
512 return -1; 605 return -1;
513} 606}
514 607
608/* return number of online connections on success.
609 * return -1 on failure.
610 */
611static unsigned int online_tcp_connection_from_conn(TCP_Connection_to *con_to)
612{
613 unsigned int i, count = 0;
614
615 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
616 if (con_to->connections[i].tcp_connection) {
617 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
618 ++count;
619 }
620 }
621 }
622
623 return count;
624}
625
515/* return index on success. 626/* return index on success.
516 * return -1 on failure. 627 * return -1 on failure.
517 */ 628 */
518static int set_tcp_connection_status(TCP_Connection_to *con_to, int tcp_connections_number, unsigned int status, 629static int set_tcp_connection_status(TCP_Connection_to *con_to, unsigned int tcp_connections_number,
519 uint8_t connection_id) 630 unsigned int status, uint8_t connection_id)
520{ 631{
521 unsigned int i; 632 unsigned int i;
522 633
523 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { 634 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
524 if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) { 635 if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) {
636
637 if (con_to->connections[i].status == status) {
638 return -1;
639 }
640
525 con_to->connections[i].status = status; 641 con_to->connections[i].status = status;
526 con_to->connections[i].connection_id = connection_id; 642 con_to->connections[i].connection_id = connection_id;
527 return i; 643 return i;
@@ -553,11 +669,130 @@ static int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections
553 } 669 }
554 } 670 }
555 671
672 if (tcp_con->onion) {
673 --tcp_c->onion_num_conns;
674 }
675
556 kill_TCP_connection(tcp_con->connection); 676 kill_TCP_connection(tcp_con->connection);
557 677
558 return wipe_tcp_connection(tcp_c, tcp_connections_number); 678 return wipe_tcp_connection(tcp_c, tcp_connections_number);
559} 679}
560 680
681static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
682{
683 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
684
685 if (!tcp_con)
686 return -1;
687
688 if (tcp_con->status == TCP_CONN_SLEEPING)
689 return -1;
690
691 IP_Port ip_port = tcp_con->connection->ip_port;
692 uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
693 memcpy(relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES);
694 kill_TCP_connection(tcp_con->connection);
695 tcp_con->connection = new_TCP_connection(ip_port, relay_pk, tcp_c->dht->self_public_key, tcp_c->dht->self_secret_key,
696 &tcp_c->proxy_info);
697
698 if (!tcp_con->connection) {
699 kill_tcp_relay_connection(tcp_c, tcp_connections_number);
700 return -1;
701 }
702
703 unsigned int i;
704
705 for (i = 0; i < tcp_c->connections_length; ++i) {
706 TCP_Connection_to *con_to = get_connection(tcp_c, i);
707
708 if (con_to) {
709 set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0);
710 }
711 }
712
713 if (tcp_con->onion) {
714 --tcp_c->onion_num_conns;
715 tcp_con->onion = 0;
716 }
717
718 tcp_con->lock_count = 0;
719 tcp_con->sleep_count = 0;
720 tcp_con->connected_time = 0;
721 tcp_con->status = TCP_CONN_VALID;
722 tcp_con->unsleep = 0;
723
724 return 0;
725}
726
727static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
728{
729 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
730
731 if (!tcp_con)
732 return -1;
733
734 if (tcp_con->status != TCP_CONN_CONNECTED)
735 return -1;
736
737 if (tcp_con->lock_count != tcp_con->sleep_count)
738 return -1;
739
740 tcp_con->ip_port = tcp_con->connection->ip_port;
741 memcpy(tcp_con->relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES);
742
743 kill_TCP_connection(tcp_con->connection);
744 tcp_con->connection = NULL;
745
746 unsigned int i;
747
748 for (i = 0; i < tcp_c->connections_length; ++i) {
749 TCP_Connection_to *con_to = get_connection(tcp_c, i);
750
751 if (con_to) {
752 set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0);
753 }
754 }
755
756 if (tcp_con->onion) {
757 --tcp_c->onion_num_conns;
758 tcp_con->onion = 0;
759 }
760
761 tcp_con->lock_count = 0;
762 tcp_con->sleep_count = 0;
763 tcp_con->connected_time = 0;
764 tcp_con->status = TCP_CONN_SLEEPING;
765 tcp_con->unsleep = 0;
766
767 return 0;
768}
769
770static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
771{
772 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
773
774 if (!tcp_con)
775 return -1;
776
777 if (tcp_con->status != TCP_CONN_SLEEPING)
778 return -1;
779
780 tcp_con->connection = new_TCP_connection(tcp_con->ip_port, tcp_con->relay_pk, tcp_c->dht->self_public_key,
781 tcp_c->dht->self_secret_key, &tcp_c->proxy_info);
782
783 if (!tcp_con->connection) {
784 kill_tcp_relay_connection(tcp_c, tcp_connections_number);
785 return -1;
786 }
787
788 tcp_con->lock_count = 0;
789 tcp_con->sleep_count = 0;
790 tcp_con->connected_time = 0;
791 tcp_con->status = TCP_CONN_VALID;
792 tcp_con->unsleep = 0;
793 return 0;
794}
795
561/* Send a TCP routing request. 796/* Send a TCP routing request.
562 * 797 *
563 * return 0 on success. 798 * return 0 on success.
@@ -570,6 +805,9 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec
570 if (!tcp_con) 805 if (!tcp_con)
571 return -1; 806 return -1;
572 807
808 if (tcp_con->status == TCP_CONN_SLEEPING)
809 return -1;
810
573 if (send_routing_request(tcp_con->connection, public_key) != 1) 811 if (send_routing_request(tcp_con->connection, public_key) != 1)
574 return -1; 812 return -1;
575 813
@@ -592,8 +830,6 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint
592 if (connections_number == -1) 830 if (connections_number == -1)
593 return -1; 831 return -1;
594 832
595 set_tcp_connection_number(tcp_con->connection, connection_id, connections_number);
596
597 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); 833 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
598 834
599 if (con_to == NULL) 835 if (con_to == NULL)
@@ -602,6 +838,8 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint
602 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1) 838 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1)
603 return -1; 839 return -1;
604 840
841 set_tcp_connection_number(tcp_con->connection, connection_id, connections_number);
842
605 return 0; 843 return 0;
606} 844}
607 845
@@ -621,10 +859,20 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection
621 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1) 859 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1)
622 return -1; 860 return -1;
623 861
862 --tcp_con->lock_count;
863
864 if (con_to->status == TCP_CONN_SLEEPING) {
865 --tcp_con->sleep_count;
866 }
624 } else if (status == 2) { 867 } else if (status == 2) {
625 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1) 868 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1)
626 return -1; 869 return -1;
627 870
871 ++tcp_con->lock_count;
872
873 if (con_to->status == TCP_CONN_SLEEPING) {
874 ++tcp_con->sleep_count;
875 }
628 } 876 }
629 877
630 return 0; 878 return 0;
@@ -673,11 +921,13 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8
673 /* TODO: optimize */ 921 /* TODO: optimize */
674 int connections_number = find_tcp_connection_to(tcp_c, public_key); 922 int connections_number = find_tcp_connection_to(tcp_c, public_key);
675 923
676 if (connections_number == -1) { 924 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
925
926 if (con_to && tcp_connection_in_conn(con_to, tcp_connections_number)) {
927 return tcp_data_callback(object, connections_number, 0, data, length);
928 } else {
677 if (tcp_c->tcp_oob_callback) 929 if (tcp_c->tcp_oob_callback)
678 tcp_c->tcp_oob_callback(tcp_c->tcp_oob_callback_object, public_key, tcp_connections_number, data, length); 930 tcp_c->tcp_oob_callback(tcp_c->tcp_oob_callback_object, public_key, tcp_connections_number, data, length);
679 } else {
680 return tcp_data_callback(object, connections_number, 0, data, length);
681 } 931 }
682 932
683 return 0; 933 return 0;
@@ -725,20 +975,35 @@ static int tcp_relay_on_online(TCP_Connections *tcp_c, int tcp_connections_numbe
725 if (!tcp_con) 975 if (!tcp_con)
726 return -1; 976 return -1;
727 977
728 unsigned int i; 978 unsigned int i, sent = 0;
729 979
730 for (i = 0; i < tcp_c->connections_length; ++i) { 980 for (i = 0; i < tcp_c->connections_length; ++i) {
731 TCP_Connection_to *con_to = get_connection(tcp_c, i); 981 TCP_Connection_to *con_to = get_connection(tcp_c, i);
732 982
733 if (con_to) { 983 if (con_to) {
734 if (tcp_connection_in_conn(con_to, tcp_connections_number)) { 984 if (tcp_connection_in_conn(con_to, tcp_connections_number)) {
735 send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); 985 if (send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key) == 0) {
986 ++sent;
987 }
736 } 988 }
737 } 989 }
738 } 990 }
739 991
740 tcp_relay_set_callbacks(tcp_c, tcp_connections_number); 992 tcp_relay_set_callbacks(tcp_c, tcp_connections_number);
741 tcp_con->status = TCP_CONN_CONNECTED; 993 tcp_con->status = TCP_CONN_CONNECTED;
994
995 /* If this connection isn't used by any connection, we don't need to wait for them to come online. */
996 if (sent) {
997 tcp_con->connected_time = unix_time();
998 } else {
999 tcp_con->connected_time = 0;
1000 }
1001
1002 if (tcp_c->onion_status && tcp_c->onion_num_conns < NUM_ONION_TCP_CONNECTIONS) {
1003 tcp_con->onion = 1;
1004 ++tcp_c->onion_num_conns;
1005 }
1006
742 return 0; 1007 return 0;
743} 1008}
744 1009
@@ -807,13 +1072,17 @@ int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_numb
807 if (!tcp_con) 1072 if (!tcp_con)
808 return -1; 1073 return -1;
809 1074
1075 if (con_to->status != TCP_CONN_SLEEPING && tcp_con->status == TCP_CONN_SLEEPING) {
1076 tcp_con->unsleep = 1;
1077 }
1078
810 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) 1079 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1)
811 return -1; 1080 return -1;
812 1081
813 ++tcp_con->lock_count;
814
815 if (tcp_con->status == TCP_CONN_CONNECTED) { 1082 if (tcp_con->status == TCP_CONN_CONNECTED) {
816 send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); 1083 if (send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key) == 0) {
1084 tcp_con->connected_time = unix_time();
1085 }
817 } 1086 }
818 1087
819 return 0; 1088 return 0;
@@ -836,22 +1105,38 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_
836 if (tcp_connections_number != -1) { 1105 if (tcp_connections_number != -1) {
837 return add_tcp_number_relay_connection(tcp_c, connections_number, tcp_connections_number); 1106 return add_tcp_number_relay_connection(tcp_c, connections_number, tcp_connections_number);
838 } else { 1107 } else {
839 int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk); 1108 if (online_tcp_connection_from_conn(con_to) >= RECOMMENDED_FRIEND_TCP_CONNECTIONS) {
840
841 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) {
842 return -1; 1109 return -1;
843 } 1110 }
844 1111
1112 int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk);
1113
845 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); 1114 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
846 1115
847 if (!tcp_con) 1116 if (!tcp_con)
848 return -1; 1117 return -1;
849 1118
850 ++tcp_con->lock_count; 1119 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) {
1120 return -1;
1121 }
1122
851 return 0; 1123 return 0;
852 } 1124 }
853} 1125}
854 1126
1127/* return number of online tcp relays tied to the connection on success.
1128 * return 0 on failure.
1129 */
1130unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number)
1131{
1132 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
1133
1134 if (!con_to)
1135 return 0;
1136
1137 return online_tcp_connection_from_conn(con_to);
1138}
1139
855/* Copy a maximum of max_num TCP relays we are connected to to tcp_relays. 1140/* Copy a maximum of max_num TCP relays we are connected to to tcp_relays.
856 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. 1141 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
857 * 1142 *
@@ -860,10 +1145,10 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_
860 */ 1145 */
861unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num) 1146unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num)
862{ 1147{
863 unsigned int i, copied = 0; 1148 unsigned int i, copied = 0, r = rand();
864 1149
865 for (i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) { 1150 for (i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) {
866 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 1151 TCP_con *tcp_con = get_tcp_connection(tcp_c, (i + r) % tcp_c->tcp_connections_length);
867 1152
868 if (!tcp_con) { 1153 if (!tcp_con) {
869 continue; 1154 continue;
@@ -886,7 +1171,74 @@ unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_
886 return copied; 1171 return copied;
887} 1172}
888 1173
889TCP_Connections *new_tcp_connections(DHT *dht) 1174/* Set if we want TCP_connection to allocate some connection for onion use.
1175 *
1176 * If status is 1, allocate some connections. if status is 0, don't.
1177 *
1178 * return 0 on success.
1179 * return -1 on failure.
1180 */
1181int set_tcp_onion_status(TCP_Connections *tcp_c, _Bool status)
1182{
1183 if (tcp_c->onion_status == status)
1184 return -1;
1185
1186 if (status) {
1187 unsigned int i;
1188
1189 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
1190 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
1191
1192 if (tcp_con) {
1193 if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion) {
1194 ++tcp_c->onion_num_conns;
1195 tcp_con->onion = 1;
1196 }
1197 }
1198
1199 if (tcp_c->onion_num_conns >= NUM_ONION_TCP_CONNECTIONS)
1200 break;
1201 }
1202
1203 if (tcp_c->onion_num_conns < NUM_ONION_TCP_CONNECTIONS) {
1204 unsigned int wakeup = NUM_ONION_TCP_CONNECTIONS - tcp_c->onion_num_conns;
1205
1206 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
1207 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
1208
1209 if (tcp_con) {
1210 if (tcp_con->status == TCP_CONN_SLEEPING) {
1211 tcp_con->unsleep = 1;
1212 }
1213 }
1214
1215 if (!wakeup)
1216 break;
1217 }
1218 }
1219
1220 tcp_c->onion_status = 1;
1221 } else {
1222 unsigned int i;
1223
1224 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
1225 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
1226
1227 if (tcp_con) {
1228 if (tcp_con->onion) {
1229 --tcp_c->onion_num_conns;
1230 tcp_con->onion = 0;
1231 }
1232 }
1233 }
1234
1235 tcp_c->onion_status = 0;
1236 }
1237
1238 return 0;
1239}
1240
1241TCP_Connections *new_tcp_connections(DHT *dht, TCP_Proxy_Info *proxy_info)
890{ 1242{
891 if (dht == NULL) 1243 if (dht == NULL)
892 return NULL; 1244 return NULL;
@@ -897,6 +1249,8 @@ TCP_Connections *new_tcp_connections(DHT *dht)
897 return NULL; 1249 return NULL;
898 1250
899 temp->dht = dht; 1251 temp->dht = dht;
1252 temp->proxy_info = *proxy_info;
1253
900 return temp; 1254 return temp;
901} 1255}
902 1256
@@ -908,18 +1262,35 @@ static void do_tcp_conns(TCP_Connections *tcp_c)
908 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 1262 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
909 1263
910 if (tcp_con) { 1264 if (tcp_con) {
911 do_TCP_connection(tcp_con->connection); 1265 if (tcp_con->status != TCP_CONN_SLEEPING) {
1266 do_TCP_connection(tcp_con->connection);
912 1267
913 /* callbacks can change TCP connection address. */ 1268 /* callbacks can change TCP connection address. */
914 tcp_con = get_tcp_connection(tcp_c, i); 1269 tcp_con = get_tcp_connection(tcp_c, i);
915 1270
916 if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) { 1271 if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) {
917 kill_tcp_relay_connection(tcp_c, i); 1272 if (tcp_con->status == TCP_CONN_CONNECTED) {
918 continue; 1273 reconnect_tcp_relay_connection(tcp_c, i);
1274 } else {
1275 kill_tcp_relay_connection(tcp_c, i);
1276 }
1277
1278 continue;
1279 }
1280
1281 if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) {
1282 tcp_relay_on_online(tcp_c, i);
1283 }
1284
1285 if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion && tcp_con->lock_count
1286 && tcp_con->lock_count == tcp_con->sleep_count
1287 && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
1288 sleep_tcp_relay_connection(tcp_c, i);
1289 }
919 } 1290 }
920 1291
921 if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) { 1292 if (tcp_con->status == TCP_CONN_SLEEPING && tcp_con->unsleep) {
922 tcp_relay_on_online(tcp_c, i); 1293 unsleep_tcp_relay_connection(tcp_c, i);
923 } 1294 }
924 } 1295 }
925 } 1296 }
@@ -927,27 +1298,42 @@ static void do_tcp_conns(TCP_Connections *tcp_c)
927 1298
928static void kill_nonused_tcp(TCP_Connections *tcp_c) 1299static void kill_nonused_tcp(TCP_Connections *tcp_c)
929{ 1300{
930 unsigned int i, num_online = 0; 1301 if (tcp_c->tcp_connections_length == 0)
1302 return;
1303
1304 unsigned int i, num_online = 0, num_kill = 0, to_kill[tcp_c->tcp_connections_length];
931 1305
932 for (i = 0; i < tcp_c->tcp_connections_length; ++i) { 1306 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
933 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 1307 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
934 1308
935 if (tcp_con) { 1309 if (tcp_con) {
936 if (tcp_con->status == TCP_CONN_CONNECTED) { 1310 if (tcp_con->status == TCP_CONN_CONNECTED) {
937 if (!tcp_con->lock_count && num_online >= MAX_FRIEND_TCP_CONNECTIONS) { 1311 if (!tcp_con->onion && !tcp_con->lock_count && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
938 kill_tcp_relay_connection(tcp_c, i); 1312 to_kill[num_kill] = i;
939 continue; 1313 ++num_kill;
940 } 1314 }
941 1315
942 ++num_online; 1316 ++num_online;
943 } 1317 }
944 } 1318 }
945 } 1319 }
1320
1321 if (num_online <= RECOMMENDED_FRIEND_TCP_CONNECTIONS) {
1322 return;
1323 } else {
1324 unsigned int n = num_online - RECOMMENDED_FRIEND_TCP_CONNECTIONS;
1325
1326 if (n < num_kill)
1327 num_kill = n;
1328 }
1329
1330 for (i = 0; i < num_kill; ++i) {
1331 kill_tcp_relay_connection(tcp_c, to_kill[i]);
1332 }
946} 1333}
947 1334
948void do_tcp_connections(TCP_Connections *tcp_c) 1335void do_tcp_connections(TCP_Connections *tcp_c)
949{ 1336{
950 //TODO reconnect to TCP relays if disconnects happen.
951 do_tcp_conns(tcp_c); 1337 do_tcp_conns(tcp_c);
952 kill_nonused_tcp(tcp_c); 1338 kill_nonused_tcp(tcp_c);
953} 1339}
diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h
index 2c86304f..29fbdee0 100644
--- a/toxcore/TCP_connection.h
+++ b/toxcore/TCP_connection.h
@@ -28,14 +28,28 @@
28 28
29#define TCP_CONN_NONE 0 29#define TCP_CONN_NONE 0
30#define TCP_CONN_VALID 1 30#define TCP_CONN_VALID 1
31
32/* NOTE: only used by TCP_con */
31#define TCP_CONN_CONNECTED 2 33#define TCP_CONN_CONNECTED 2
32 34
35/* Connection is not connected but can be quickly reconnected in case it is needed. */
36#define TCP_CONN_SLEEPING 3
37
33#define TCP_CONNECTIONS_STATUS_NONE 0 38#define TCP_CONNECTIONS_STATUS_NONE 0
34#define TCP_CONNECTIONS_STATUS_REGISTERED 1 39#define TCP_CONNECTIONS_STATUS_REGISTERED 1
35#define TCP_CONNECTIONS_STATUS_ONLINE 2 40#define TCP_CONNECTIONS_STATUS_ONLINE 2
36 41
37#define MAX_FRIEND_TCP_CONNECTIONS 4 42#define MAX_FRIEND_TCP_CONNECTIONS 6
43
44/* Time until connection to friend gets killed (if it doesn't get locked withing that time) */
45#define TCP_CONNECTION_ANNOUNCE_TIMEOUT (TCP_CONNECTION_TIMEOUT)
38 46
47/* The amount of recommended connections for each friend
48 NOTE: Must be at most (MAX_FRIEND_TCP_CONNECTIONS / 2) */
49#define RECOMMENDED_FRIEND_TCP_CONNECTIONS (MAX_FRIEND_TCP_CONNECTIONS / 2)
50
51/* Number of TCP connections used for onion purposes. */
52#define NUM_ONION_TCP_CONNECTIONS RECOMMENDED_FRIEND_TCP_CONNECTIONS
39 53
40typedef struct { 54typedef struct {
41 uint8_t status; 55 uint8_t status;
@@ -53,7 +67,15 @@ typedef struct {
53typedef struct { 67typedef struct {
54 uint8_t status; 68 uint8_t status;
55 TCP_Client_Connection *connection; 69 TCP_Client_Connection *connection;
70 uint64_t connected_time;
56 uint32_t lock_count; 71 uint32_t lock_count;
72 uint32_t sleep_count;
73 _Bool onion;
74
75 /* Only used when connection is sleeping. */
76 IP_Port ip_port;
77 uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
78 _Bool unsleep; /* set to 1 to unsleep connection. */
57} TCP_con; 79} TCP_con;
58 80
59typedef struct { 81typedef struct {
@@ -76,6 +98,9 @@ typedef struct {
76 void *tcp_onion_callback_object; 98 void *tcp_onion_callback_object;
77 99
78 TCP_Proxy_Info proxy_info; 100 TCP_Proxy_Info proxy_info;
101
102 _Bool onion_status;
103 uint16_t onion_num_conns;
79} TCP_Connections; 104} TCP_Connections;
80 105
81/* Send a packet to the TCP connection. 106/* Send a packet to the TCP connection.
@@ -93,7 +118,7 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
93 * return TCP connection number on success. 118 * return TCP connection number on success.
94 * return -1 on failure. 119 * return -1 on failure.
95 */ 120 */
96int get_random_tcp_conn_number(TCP_Connections *tcp_c); 121int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c);
97 122
98/* Send an onion packet via the TCP relay corresponding to tcp_connections_number. 123/* Send an onion packet via the TCP relay corresponding to tcp_connections_number.
99 * 124 *
@@ -103,6 +128,15 @@ int get_random_tcp_conn_number(TCP_Connections *tcp_c);
103int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data, 128int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data,
104 uint16_t length); 129 uint16_t length);
105 130
131/* Set if we want TCP_connection to allocate some connection for onion use.
132 *
133 * If status is 1, allocate some connections. if status is 0, don't.
134 *
135 * return 0 on success.
136 * return -1 on failure.
137 */
138int set_tcp_onion_status(TCP_Connections *tcp_c, _Bool status);
139
106/* Send an oob packet via the TCP relay corresponding to tcp_connections_number. 140/* Send an oob packet via the TCP relay corresponding to tcp_connections_number.
107 * 141 *
108 * return 0 on success. 142 * return 0 on success.
@@ -140,6 +174,23 @@ int new_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_key, int
140 */ 174 */
141int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number); 175int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number);
142 176
177/* Set connection status.
178 *
179 * status of 1 means we are using the connection.
180 * status of 0 means we are not using it.
181 *
182 * Unused tcp connections will be disconnected from but kept in case they are needed.
183 *
184 * return 0 on success.
185 * return -1 on failure.
186 */
187int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status);
188
189/* return number of online tcp relays tied to the connection on success.
190 * return 0 on failure.
191 */
192unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number);
193
143/* Add a TCP relay tied to a connection. 194/* Add a TCP relay tied to a connection.
144 * 195 *
145 * NOTE: This can only be used during the tcp_oob_callback. 196 * NOTE: This can only be used during the tcp_oob_callback.
@@ -172,7 +223,7 @@ int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t
172 */ 223 */
173unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num); 224unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num);
174 225
175TCP_Connections *new_tcp_connections(DHT *dht); 226TCP_Connections *new_tcp_connections(DHT *dht, TCP_Proxy_Info *proxy_info);
176void do_tcp_connections(TCP_Connections *tcp_c); 227void do_tcp_connections(TCP_Connections *tcp_c);
177void kill_tcp_connections(TCP_Connections *tcp_c); 228void kill_tcp_connections(TCP_Connections *tcp_c);
178 229
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c
index a364084a..418edcad 100644
--- a/toxcore/crypto_core.c
+++ b/toxcore/crypto_core.c
@@ -29,26 +29,16 @@
29 29
30#include "crypto_core.h" 30#include "crypto_core.h"
31 31
32#if crypto_box_PUBLICKEYBYTES != 32
33#error crypto_box_PUBLICKEYBYTES is required to be 32 bytes for public_key_cmp to work,
34#endif
32 35
33/* Use this instead of memcmp; not vulnerable to timing attacks. 36/* compare 2 public keys of length crypto_box_PUBLICKEYBYTES, not vulnerable to timing attacks.
34 returns 0 if both mem locations of length are equal, 37 returns 0 if both mem locations of length are equal,
35 return -1 if they are not. */ 38 return -1 if they are not. */
36int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t length) 39int public_key_cmp(const uint8_t *pk1, const uint8_t *pk2)
37{ 40{
38 if (length == 16) { 41 return crypto_verify_32(pk1, pk2);
39 return crypto_verify_16(mem1, mem2);
40 } else if (length == 32) {
41 return crypto_verify_32(mem1, mem2);
42 }
43
44 unsigned int check = 0;
45 size_t i;
46
47 for (i = 0; i < length; ++i) {
48 check |= mem1[i] ^ mem2[i];
49 }
50
51 return (1 & ((check - 1) >> 8)) - 1;
52} 42}
53 43
54/* return a random number. 44/* return a random number.
diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h
index decc7fb9..d7306a8a 100644
--- a/toxcore/crypto_core.h
+++ b/toxcore/crypto_core.h
@@ -40,10 +40,10 @@
40 40
41#define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES) 41#define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES)
42 42
43/* Use this instead of memcmp; not vulnerable to timing attacks. 43/* compare 2 public keys of length crypto_box_PUBLICKEYBYTES, not vulnerable to timing attacks.
44 returns 0 if both mem locations of length are equal, 44 returns 0 if both mem locations of length are equal,
45 return -1 if they are not. */ 45 return -1 if they are not. */
46int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t length); 46int public_key_cmp(const uint8_t *pk1, const uint8_t *pk2);
47 47
48/* return a random number. 48/* return a random number.
49 * 49 *
diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c
index 074021da..c13ca949 100644
--- a/toxcore/friend_connection.c
+++ b/toxcore/friend_connection.c
@@ -146,6 +146,95 @@ int getfriend_conn_id_pk(Friend_Connections *fr_c, const uint8_t *real_pk)
146 return -1; 146 return -1;
147} 147}
148 148
149/* Add a TCP relay associated to the friend.
150 *
151 * return -1 on failure.
152 * return 0 on success.
153 */
154int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key)
155{
156 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
157
158 if (!friend_con)
159 return -1;
160
161 unsigned int i;
162
163 uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS;
164
165 for (i = 0; i < FRIEND_MAX_STORED_TCP_RELAYS; ++i) {
166 if (friend_con->tcp_relays[i].ip_port.ip.family != 0
167 && memcmp(friend_con->tcp_relays[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
168 memset(&friend_con->tcp_relays[i], 0, sizeof(Node_format));
169 }
170 }
171
172 friend_con->tcp_relays[index].ip_port = ip_port;
173 memcpy(friend_con->tcp_relays[index].public_key, public_key, crypto_box_PUBLICKEYBYTES);
174 ++friend_con->tcp_relay_counter;
175
176 return add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, public_key);
177}
178
179/* Connect to number saved relays for friend. */
180static void connect_to_saved_tcp_relays(Friend_Connections *fr_c, int friendcon_id, unsigned int number)
181{
182 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
183
184 if (!friend_con)
185 return;
186
187 unsigned int i;
188
189 for (i = 0; (i < FRIEND_MAX_STORED_TCP_RELAYS) && (number != 0); ++i) {
190 uint16_t index = (friend_con->tcp_relay_counter - (i + 1)) % FRIEND_MAX_STORED_TCP_RELAYS;
191
192 if (friend_con->tcp_relays[index].ip_port.ip.family) {
193 if (add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->tcp_relays[index].ip_port,
194 friend_con->tcp_relays[index].public_key) == 0) {
195 --number;
196 }
197 }
198 }
199}
200
201static unsigned int send_relays(Friend_Connections *fr_c, int friendcon_id)
202{
203 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
204
205 if (!friend_con)
206 return 0;
207
208 Node_format nodes[MAX_SHARED_RELAYS];
209 uint8_t data[1024];
210 int n, length;
211
212 n = copy_connected_tcp_relays(fr_c->net_crypto, nodes, MAX_SHARED_RELAYS);
213
214 unsigned int i;
215
216 for (i = 0; i < n; ++i) {
217 /* Associated the relays being sent with this connection.
218 On receiving the peer will do the same which will establish the connection. */
219 friend_add_tcp_relay(fr_c, friendcon_id, nodes[i].ip_port, nodes[i].public_key);
220 }
221
222 length = pack_nodes(data + 1, sizeof(data) - 1, nodes, n);
223
224 if (length <= 0)
225 return 0;
226
227 data[0] = PACKET_ID_SHARE_RELAYS;
228 ++length;
229
230 if (write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, data, length, 0) != -1) {
231 friend_con->share_relays_lastsent = unix_time();
232 return 1;
233 }
234
235 return 0;
236}
237
149/* callback for recv TCP relay nodes. */ 238/* callback for recv TCP relay nodes. */
150static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key) 239static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key)
151{ 240{
@@ -156,7 +245,7 @@ static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_por
156 return -1; 245 return -1;
157 246
158 if (friend_con->crypt_connection_id != -1) { 247 if (friend_con->crypt_connection_id != -1) {
159 return add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, public_key); 248 return friend_add_tcp_relay(fr_c, number, ip_port, public_key);
160 } else { 249 } else {
161 return add_tcp_relay(fr_c->net_crypto, ip_port, public_key); 250 return add_tcp_relay(fr_c->net_crypto, ip_port, public_key);
162 } 251 }
@@ -181,19 +270,14 @@ static void dht_ip_callback(void *object, int32_t number, IP_Port ip_port)
181 friend_con->dht_ip_port_lastrecv = unix_time(); 270 friend_con->dht_ip_port_lastrecv = unix_time();
182} 271}
183 272
184/* Callback for dht public key changes. */ 273static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_public_key)
185static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key)
186{ 274{
187 Friend_Connections *fr_c = object; 275 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
188 Friend_Conn *friend_con = get_conn(fr_c, number);
189 276
190 if (!friend_con) 277 if (!friend_con)
191 return; 278 return;
192 279
193 friend_con->dht_ping_lastrecv = unix_time(); 280 friend_con->dht_pk_lastrecv = unix_time();
194
195 if (memcmp(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
196 return;
197 281
198 if (friend_con->dht_lock) { 282 if (friend_con->dht_lock) {
199 if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) { 283 if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) {
@@ -204,15 +288,7 @@ static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_pub
204 friend_con->dht_lock = 0; 288 friend_con->dht_lock = 0;
205 } 289 }
206 290
207 DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, object, number, &friend_con->dht_lock); 291 DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, fr_c, friendcon_id, &friend_con->dht_lock);
208
209 if (friend_con->crypt_connection_id == -1) {
210 friend_new_connection(fr_c, number);
211 }
212
213 set_connection_dht_public_key(fr_c->net_crypto, friend_con->crypt_connection_id, dht_public_key);
214 onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key);
215
216 memcpy(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES); 292 memcpy(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES);
217} 293}
218 294
@@ -230,11 +306,12 @@ static int handle_status(void *object, int number, uint8_t status)
230 call_cb = 1; 306 call_cb = 1;
231 friend_con->status = FRIENDCONN_STATUS_CONNECTED; 307 friend_con->status = FRIENDCONN_STATUS_CONNECTED;
232 friend_con->ping_lastrecv = unix_time(); 308 friend_con->ping_lastrecv = unix_time();
309 friend_con->share_relays_lastsent = 0;
233 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); 310 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status);
234 } else { /* Went offline. */ 311 } else { /* Went offline. */
235 if (friend_con->status != FRIENDCONN_STATUS_CONNECTING) { 312 if (friend_con->status != FRIENDCONN_STATUS_CONNECTING) {
236 call_cb = 1; 313 call_cb = 1;
237 friend_con->dht_ping_lastrecv = unix_time(); 314 friend_con->dht_pk_lastrecv = unix_time();
238 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); 315 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status);
239 } 316 }
240 317
@@ -255,6 +332,31 @@ static int handle_status(void *object, int number, uint8_t status)
255 return 0; 332 return 0;
256} 333}
257 334
335/* Callback for dht public key changes. */
336static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key)
337{
338 Friend_Connections *fr_c = object;
339 Friend_Conn *friend_con = get_conn(fr_c, number);
340
341 if (!friend_con)
342 return;
343
344 if (memcmp(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
345 return;
346
347 change_dht_pk(fr_c, number, dht_public_key);
348
349 /* if pk changed, create a new connection.*/
350 if (friend_con->crypt_connection_id != -1) {
351 crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id);
352 friend_con->crypt_connection_id = -1;
353 handle_status(object, number, 0); /* Going offline. */
354 }
355
356 friend_new_connection(fr_c, number);
357 onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key);
358}
359
258static int handle_packet(void *object, int number, uint8_t *data, uint16_t length) 360static int handle_packet(void *object, int number, uint8_t *data, uint16_t length)
259{ 361{
260 if (length == 0) 362 if (length == 0)
@@ -263,18 +365,30 @@ static int handle_packet(void *object, int number, uint8_t *data, uint16_t lengt
263 Friend_Connections *fr_c = object; 365 Friend_Connections *fr_c = object;
264 Friend_Conn *friend_con = get_conn(fr_c, number); 366 Friend_Conn *friend_con = get_conn(fr_c, number);
265 367
368 if (!friend_con)
369 return -1;
370
266 if (data[0] == PACKET_ID_FRIEND_REQUESTS) { 371 if (data[0] == PACKET_ID_FRIEND_REQUESTS) {
267 if (fr_c->fr_request_callback) 372 if (fr_c->fr_request_callback)
268 fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length); 373 fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length);
269 374
270 return 0; 375 return 0;
271 } 376 } else if (data[0] == PACKET_ID_ALIVE) {
377 friend_con->ping_lastrecv = unix_time();
378 return 0;
379 } else if (data[0] == PACKET_ID_SHARE_RELAYS) {
380 Node_format nodes[MAX_SHARED_RELAYS];
381 int n;
272 382
273 if (!friend_con) 383 if ((n = unpack_nodes(nodes, MAX_SHARED_RELAYS, NULL, data + 1, length - 1, 1)) == -1)
274 return -1; 384 return -1;
385
386 int j;
387
388 for (j = 0; j < n; j++) {
389 friend_add_tcp_relay(fr_c, number, nodes[j].ip_port, nodes[j].public_key);
390 }
275 391
276 if (data[0] == PACKET_ID_ALIVE) {
277 friend_con->ping_lastrecv = unix_time();
278 return 0; 392 return 0;
279 } 393 }
280 394
@@ -333,6 +447,11 @@ static int handle_new_connections(void *object, New_Connection *n_c)
333 return -1; 447 return -1;
334 448
335 int id = accept_crypto_connection(fr_c->net_crypto, n_c); 449 int id = accept_crypto_connection(fr_c->net_crypto, n_c);
450
451 if (id == -1) {
452 return -1;
453 }
454
336 connection_status_handler(fr_c->net_crypto, id, &handle_status, fr_c, friendcon_id); 455 connection_status_handler(fr_c->net_crypto, id, &handle_status, fr_c, friendcon_id);
337 connection_data_handler(fr_c->net_crypto, id, &handle_packet, fr_c, friendcon_id); 456 connection_data_handler(fr_c->net_crypto, id, &handle_packet, fr_c, friendcon_id);
338 connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id); 457 connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id);
@@ -345,7 +464,9 @@ static int handle_new_connections(void *object, New_Connection *n_c)
345 friend_con->dht_ip_port_lastrecv = unix_time(); 464 friend_con->dht_ip_port_lastrecv = unix_time();
346 } 465 }
347 466
348 dht_pk_callback(fr_c, friendcon_id, n_c->dht_public_key); 467 if (memcmp(friend_con->dht_temp_pk, n_c->dht_public_key, crypto_box_PUBLICKEYBYTES) != 0) {
468 change_dht_pk(fr_c, friendcon_id, n_c->dht_public_key);
469 }
349 470
350 nc_dht_pk_callback(fr_c->net_crypto, id, &dht_pk_callback, fr_c, friendcon_id); 471 nc_dht_pk_callback(fr_c->net_crypto, id, &dht_pk_callback, fr_c, friendcon_id);
351 return 0; 472 return 0;
@@ -365,7 +486,12 @@ static int friend_new_connection(Friend_Connections *fr_c, int friendcon_id)
365 return -1; 486 return -1;
366 } 487 }
367 488
368 int id = new_crypto_connection(fr_c->net_crypto, friend_con->real_public_key); 489 /* If dht_temp_pk does not contains a pk. */
490 if (!friend_con->dht_lock) {
491 return -1;
492 }
493
494 int id = new_crypto_connection(fr_c->net_crypto, friend_con->real_public_key, friend_con->dht_temp_pk);
369 495
370 if (id == -1) 496 if (id == -1)
371 return -1; 497 return -1;
@@ -632,10 +758,20 @@ Friend_Connections *new_friend_connections(Onion_Client *onion_c)
632 temp->onion_c = onion_c; 758 temp->onion_c = onion_c;
633 759
634 new_connection_handler(temp->net_crypto, &handle_new_connections, temp); 760 new_connection_handler(temp->net_crypto, &handle_new_connections, temp);
761 LANdiscovery_init(temp->dht);
635 762
636 return temp; 763 return temp;
637} 764}
638 765
766/* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */
767static void LANdiscovery(Friend_Connections *fr_c)
768{
769 if (fr_c->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) {
770 send_LANdiscovery(htons(TOX_PORT_DEFAULT), fr_c->dht);
771 fr_c->last_LANdiscovery = unix_time();
772 }
773}
774
639/* main friend_connections loop. */ 775/* main friend_connections loop. */
640void do_friend_connections(Friend_Connections *fr_c) 776void do_friend_connections(Friend_Connections *fr_c)
641{ 777{
@@ -647,7 +783,7 @@ void do_friend_connections(Friend_Connections *fr_c)
647 783
648 if (friend_con) { 784 if (friend_con) {
649 if (friend_con->status == FRIENDCONN_STATUS_CONNECTING) { 785 if (friend_con->status == FRIENDCONN_STATUS_CONNECTING) {
650 if (friend_con->dht_ping_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) { 786 if (friend_con->dht_pk_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) {
651 if (friend_con->dht_lock) { 787 if (friend_con->dht_lock) {
652 DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock); 788 DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock);
653 friend_con->dht_lock = 0; 789 friend_con->dht_lock = 0;
@@ -660,8 +796,8 @@ void do_friend_connections(Friend_Connections *fr_c)
660 796
661 if (friend_con->dht_lock) { 797 if (friend_con->dht_lock) {
662 if (friend_new_connection(fr_c, i) == 0) { 798 if (friend_new_connection(fr_c, i) == 0) {
663 set_connection_dht_public_key(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_temp_pk);
664 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port); 799 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port);
800 connect_to_saved_tcp_relays(fr_c, i, (MAX_FRIEND_TCP_CONNECTIONS / 2)); /* Only fill it half up. */
665 } 801 }
666 } 802 }
667 803
@@ -670,6 +806,10 @@ void do_friend_connections(Friend_Connections *fr_c)
670 send_ping(fr_c, i); 806 send_ping(fr_c, i);
671 } 807 }
672 808
809 if (friend_con->share_relays_lastsent + SHARE_RELAYS_INTERVAL < temp_time) {
810 send_relays(fr_c, i);
811 }
812
673 if (friend_con->ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { 813 if (friend_con->ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) {
674 /* If we stopped receiving ping packets, kill it. */ 814 /* If we stopped receiving ping packets, kill it. */
675 crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id); 815 crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id);
@@ -679,6 +819,8 @@ void do_friend_connections(Friend_Connections *fr_c)
679 } 819 }
680 } 820 }
681 } 821 }
822
823 LANdiscovery(fr_c);
682} 824}
683 825
684/* Free everything related with friend_connections. */ 826/* Free everything related with friend_connections. */
@@ -693,5 +835,6 @@ void kill_friend_connections(Friend_Connections *fr_c)
693 kill_friend_connection(fr_c, i); 835 kill_friend_connection(fr_c, i);
694 } 836 }
695 837
838 LANdiscovery_kill(fr_c->dht);
696 free(fr_c); 839 free(fr_c);
697} 840}
diff --git a/toxcore/friend_connection.h b/toxcore/friend_connection.h
index b814eb0c..baca4b76 100644
--- a/toxcore/friend_connection.h
+++ b/toxcore/friend_connection.h
@@ -36,6 +36,7 @@
36#define GROUPCHAT_CALLBACK_INDEX 1 36#define GROUPCHAT_CALLBACK_INDEX 1
37 37
38#define PACKET_ID_ALIVE 16 38#define PACKET_ID_ALIVE 16
39#define PACKET_ID_SHARE_RELAYS 17
39#define PACKET_ID_FRIEND_REQUESTS 18 40#define PACKET_ID_FRIEND_REQUESTS 18
40 41
41/* Interval between the sending of ping packets. */ 42/* Interval between the sending of ping packets. */
@@ -47,6 +48,14 @@
47/* Time before friend is removed from the DHT after last hearing about him. */ 48/* Time before friend is removed from the DHT after last hearing about him. */
48#define FRIEND_DHT_TIMEOUT BAD_NODE_TIMEOUT 49#define FRIEND_DHT_TIMEOUT BAD_NODE_TIMEOUT
49 50
51#define FRIEND_MAX_STORED_TCP_RELAYS (MAX_FRIEND_TCP_CONNECTIONS * 4)
52
53/* Max number of tcp relays sent to friends */
54#define MAX_SHARED_RELAYS (RECOMMENDED_FRIEND_TCP_CONNECTIONS)
55
56/* Interval between the sending of tcp relay information */
57#define SHARE_RELAYS_INTERVAL (5 * 60)
58
50 59
51enum { 60enum {
52 FRIENDCONN_STATUS_NONE, 61 FRIENDCONN_STATUS_NONE,
@@ -61,12 +70,13 @@ typedef struct {
61 uint8_t dht_temp_pk[crypto_box_PUBLICKEYBYTES]; 70 uint8_t dht_temp_pk[crypto_box_PUBLICKEYBYTES];
62 uint16_t dht_lock; 71 uint16_t dht_lock;
63 IP_Port dht_ip_port; 72 IP_Port dht_ip_port;
64 uint64_t dht_ping_lastrecv, dht_ip_port_lastrecv; 73 uint64_t dht_pk_lastrecv, dht_ip_port_lastrecv;
65 74
66 int onion_friendnum; 75 int onion_friendnum;
67 int crypt_connection_id; 76 int crypt_connection_id;
68 77
69 uint64_t ping_lastrecv, ping_lastsent; 78 uint64_t ping_lastrecv, ping_lastsent;
79 uint64_t share_relays_lastsent;
70 80
71 struct { 81 struct {
72 int (*status_callback)(void *object, int id, uint8_t status); 82 int (*status_callback)(void *object, int id, uint8_t status);
@@ -83,6 +93,9 @@ typedef struct {
83 } callbacks[MAX_FRIEND_CONNECTION_CALLBACKS]; 93 } callbacks[MAX_FRIEND_CONNECTION_CALLBACKS];
84 94
85 uint16_t lock_count; 95 uint16_t lock_count;
96
97 Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS];
98 uint16_t tcp_relay_counter;
86} Friend_Conn; 99} Friend_Conn;
87 100
88 101
@@ -96,6 +109,8 @@ typedef struct {
96 109
97 int (*fr_request_callback)(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t len); 110 int (*fr_request_callback)(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t len);
98 void *fr_request_object; 111 void *fr_request_object;
112
113 uint64_t last_LANdiscovery;
99} Friend_Connections; 114} Friend_Connections;
100 115
101/* return friendcon_id corresponding to the real public key on success. 116/* return friendcon_id corresponding to the real public key on success.
@@ -127,6 +142,13 @@ int get_friendcon_public_keys(uint8_t *real_pk, uint8_t *dht_temp_pk, Friend_Con
127 */ 142 */
128void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk); 143void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk);
129 144
145/* Add a TCP relay associated to the friend.
146 *
147 * return -1 on failure.
148 * return 0 on success.
149 */
150int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key);
151
130/* Set the callbacks for the friend connection. 152/* Set the callbacks for the friend connection.
131 * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array. 153 * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array.
132 * 154 *
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 3e596a5f..0ed855bb 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -35,7 +35,16 @@
35 35
36static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id) 36static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id)
37{ 37{
38 return (uint32_t)crypt_connection_id >= c->crypto_connections_length; 38 if ((uint32_t)crypt_connection_id >= c->crypto_connections_length)
39 return 1;
40
41 if (c->crypto_connections == NULL)
42 return 1;
43
44 if (c->crypto_connections[crypt_connection_id].status == CRYPTO_CONN_NO_CONNECTION)
45 return 1;
46
47 return 0;
39} 48}
40 49
41/* cookie timeout in seconds */ 50/* cookie timeout in seconds */
@@ -206,8 +215,7 @@ static int udp_handle_cookie_request(void *object, IP_Port source, const uint8_t
206 215
207/* Handle the cookie request packet (for TCP) 216/* Handle the cookie request packet (for TCP)
208 */ 217 */
209static int tcp_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id, 218static int tcp_handle_cookie_request(Net_Crypto *c, int connections_number, const uint8_t *packet, uint16_t length)
210 const uint8_t *packet, uint16_t length)
211{ 219{
212 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; 220 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
213 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 221 uint8_t shared_key[crypto_box_BEFORENMBYTES];
@@ -221,15 +229,13 @@ static int tcp_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection
221 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) 229 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
222 return -1; 230 return -1;
223 231
224 if (send_data(TCP_con, conn_id, data, sizeof(data)) != 1) 232 int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data));
225 return -1; 233 return ret;
226
227 return 0;
228} 234}
229 235
230/* Handle the cookie request packet (for TCP oob packets) 236/* Handle the cookie request packet (for TCP oob packets)
231 */ 237 */
232static int tcp_oob_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con, 238static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_connections_number,
233 const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) 239 const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length)
234{ 240{
235 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; 241 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
@@ -247,10 +253,8 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connect
247 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) 253 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
248 return -1; 254 return -1;
249 255
250 if (send_oob_packet(TCP_con, dht_public_key, data, sizeof(data)) != 1) 256 int ret = tcp_send_oob_packet(c->tcp_c, tcp_connections_number, dht_public_key, data, sizeof(data));
251 return -1; 257 return ret;
252
253 return 0;
254} 258}
255 259
256/* Handle a cookie response packet of length encrypted with shared_key. 260/* Handle a cookie response packet of length encrypted with shared_key.
@@ -346,7 +350,7 @@ static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
346 return -1; 350 return -1;
347 351
348 if (expected_real_pk) 352 if (expected_real_pk)
349 if (crypto_cmp(cookie_plain, expected_real_pk, crypto_box_PUBLICKEYBYTES) != 0) 353 if (public_key_cmp(cookie_plain, expected_real_pk) != 0)
350 return -1; 354 return -1;
351 355
352 uint8_t cookie_hash[crypto_hash_sha512_BYTES]; 356 uint8_t cookie_hash[crypto_hash_sha512_BYTES];
@@ -400,12 +404,17 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
400 404
401 //TODO: on bad networks, direct connections might not last indefinitely. 405 //TODO: on bad networks, direct connections might not last indefinitely.
402 if (conn->ip_port.ip.family != 0) { 406 if (conn->ip_port.ip.family != 0) {
403 uint8_t direct_connected = 0; 407 _Bool direct_connected = 0;
404 crypto_connection_status(c, crypt_connection_id, &direct_connected); 408 crypto_connection_status(c, crypt_connection_id, &direct_connected, NULL);
405 409
406 if (direct_connected && (uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) { 410 if (direct_connected) {
407 pthread_mutex_unlock(&conn->mutex); 411 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) {
408 return 0; 412 pthread_mutex_unlock(&conn->mutex);
413 return 0;
414 } else {
415 pthread_mutex_unlock(&conn->mutex);
416 return -1;
417 }
409 } 418 }
410 419
411 //TODO: a better way of sending packets directly to confirm the others ip. 420 //TODO: a better way of sending packets directly to confirm the others ip.
@@ -413,61 +422,14 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
413 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) 422 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length)
414 direct_send_attempt = 1; 423 direct_send_attempt = 1;
415 } 424 }
416
417 } 425 }
418 426
419 pthread_mutex_unlock(&conn->mutex); 427 pthread_mutex_unlock(&conn->mutex);
428 pthread_mutex_lock(&c->tcp_mutex);
429 int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length);
430 pthread_mutex_unlock(&c->tcp_mutex);
420 431
421 //TODO: detect and kill bad relays. 432 if (ret == 0 || direct_send_attempt) {
422 uint32_t i;
423
424 unsigned int r;
425
426 if (!conn->last_relay_sentto) {
427 r = rand();
428 } else {
429 r = conn->last_relay_sentto - 1;
430 }
431
432 if (conn->num_tcp_online) {
433 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
434 pthread_mutex_lock(&c->tcp_mutex);
435
436 unsigned int tcp_index = (i + r) % MAX_TCP_CONNECTIONS;
437 int ret = 0;
438
439 if (conn->status_tcp[tcp_index] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */
440 ret = send_data(c->tcp_connections[tcp_index], conn->con_number_tcp[tcp_index], data, length);
441 }
442
443 pthread_mutex_unlock(&c->tcp_mutex);
444
445 if (ret == 1) {
446 conn->last_relay_sentto = tcp_index + 1;
447 return 0;
448 }
449 }
450 }
451
452 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
453 pthread_mutex_lock(&c->tcp_mutex);
454
455 unsigned int tcp_index = (i + r) % MAX_TCP_CONNECTIONS;
456 int ret = 0;
457
458 if (conn->status_tcp[tcp_index] == STATUS_TCP_INVISIBLE) {
459 ret = send_oob_packet(c->tcp_connections[tcp_index], conn->dht_public_key, data, length);
460 }
461
462 pthread_mutex_unlock(&c->tcp_mutex);
463
464 if (ret == 1) {
465 conn->last_relay_sentto = tcp_index + 1;
466 return 0;
467 }
468 }
469
470 if (direct_send_attempt) {
471 return 0; 433 return 0;
472 } 434 }
473 435
@@ -1136,13 +1098,26 @@ static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
1136 &kill_packet, sizeof(kill_packet)); 1098 &kill_packet, sizeof(kill_packet));
1137} 1099}
1138 1100
1101static void connection_kill(Net_Crypto *c, int crypt_connection_id)
1102{
1103 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1104
1105 if (conn == 0)
1106 return;
1107
1108 if (conn->connection_status_callback) {
1109 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0);
1110 }
1111
1112 crypto_kill(c, crypt_connection_id);
1113}
1114
1139/* Handle a received data packet. 1115/* Handle a received data packet.
1140 * 1116 *
1141 * return -1 on failure. 1117 * return -1 on failure.
1142 * return 0 on success. 1118 * return 0 on success.
1143 */ 1119 */
1144static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, 1120static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
1145 uint16_t length)
1146{ 1121{
1147 if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) 1122 if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE)
1148 return -1; 1123 return -1;
@@ -1179,7 +1154,7 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i
1179 } 1154 }
1180 1155
1181 if (real_data[0] == PACKET_ID_KILL) { 1156 if (real_data[0] == PACKET_ID_KILL) {
1182 conn->killed = 1; 1157 connection_kill(c, crypt_connection_id);
1183 return 0; 1158 return 0;
1184 } 1159 }
1185 1160
@@ -1294,19 +1269,19 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons
1294 packet, length, conn->public_key) != 0) 1269 packet, length, conn->public_key) != 0)
1295 return -1; 1270 return -1;
1296 1271
1297 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); 1272 if (public_key_cmp(dht_public_key, conn->dht_public_key) == 0) {
1298 1273 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1299 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1300 if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0)
1301 return -1;
1302 }
1303 1274
1304 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1275 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1305 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ 1276 if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0)
1306 set_connection_dht_public_key(c, crypt_connection_id, dht_public_key); 1277 return -1;
1278 }
1307 1279
1308 if (conn->dht_pk_callback) 1280 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1309 conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key); 1281 } else {
1282 if (conn->dht_pk_callback)
1283 conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key);
1284 }
1310 1285
1311 } else { 1286 } else {
1312 return -1; 1287 return -1;
@@ -1448,31 +1423,12 @@ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key)
1448 return -1; 1423 return -1;
1449} 1424}
1450 1425
1451/* Get crypto connection id from public key of peer.
1452 *
1453 * return -1 if there are no connections like we are looking for.
1454 * return id if it found it.
1455 */
1456static int getcryptconnection_id_dht_pubkey(const Net_Crypto *c, const uint8_t *dht_public_key)
1457{
1458 uint32_t i;
1459
1460 for (i = 0; i < c->crypto_connections_length; ++i) {
1461 if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION && c->crypto_connections[i].dht_public_key_set)
1462 if (memcmp(dht_public_key, c->crypto_connections[i].dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1463 return i;
1464 }
1465
1466 return -1;
1467}
1468
1469/* Add a source to the crypto connection. 1426/* Add a source to the crypto connection.
1470 * This is to be used only when we have received a packet from that source. 1427 * This is to be used only when we have received a packet from that source.
1471 * 1428 *
1472 * return -1 on failure. 1429 * return -1 on failure.
1473 * return positive number on success. 1430 * return positive number on success.
1474 * 0 if source was a direct UDP connection. 1431 * 0 if source was a direct UDP connection.
1475 * TODO
1476 */ 1432 */
1477static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source) 1433static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source)
1478{ 1434{
@@ -1490,8 +1446,11 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
1490 conn->ip_port = source; 1446 conn->ip_port = source;
1491 } 1447 }
1492 1448
1493 conn->direct_lastrecv_time = current_time_monotonic(); 1449 conn->direct_lastrecv_time = unix_time();
1494 return 0; 1450 return 0;
1451 } else if (source.ip.family == TCP_FAMILY) {
1452 if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip6.uint32[0]) == 0)
1453 return 1;
1495 } 1454 }
1496 1455
1497 return -1; 1456 return -1;
@@ -1537,30 +1496,29 @@ static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, const
1537 int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); 1496 int crypt_connection_id = getcryptconnection_id(c, n_c.public_key);
1538 1497
1539 if (crypt_connection_id != -1) { 1498 if (crypt_connection_id != -1) {
1540 int ret = -1;
1541 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1499 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1542 1500
1543 if (conn != 0 && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) { 1501 if (public_key_cmp(n_c.dht_public_key, conn->dht_public_key) != 0) {
1544 memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES); 1502 connection_kill(c, crypt_connection_id);
1545 memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES); 1503 } else {
1546 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); 1504 int ret = -1;
1547
1548 crypto_connection_add_source(c, crypt_connection_id, source);
1549 1505
1550 if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) { 1506 if (conn && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) {
1551 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1507 memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES);
1552 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ 1508 memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES);
1553 set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key); 1509 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1554 1510
1555 if (conn->dht_pk_callback) 1511 crypto_connection_add_source(c, crypt_connection_id, source);
1556 conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, n_c.dht_public_key);
1557 1512
1558 ret = 0; 1513 if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) {
1514 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1515 ret = 0;
1516 }
1559 } 1517 }
1560 }
1561 1518
1562 free(n_c.cookie); 1519 free(n_c.cookie);
1563 return ret; 1520 return ret;
1521 }
1564 } 1522 }
1565 1523
1566 int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); 1524 int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c);
@@ -1583,9 +1541,16 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1583 if (crypt_connection_id == -1) 1541 if (crypt_connection_id == -1)
1584 return -1; 1542 return -1;
1585 1543
1586 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1544 Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id];
1587 1545
1588 if (conn == 0) 1546 if (n_c->cookie_length != COOKIE_LENGTH)
1547 return -1;
1548
1549 pthread_mutex_lock(&c->tcp_mutex);
1550 conn->connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->dht_public_key, crypt_connection_id);
1551 pthread_mutex_unlock(&c->tcp_mutex);
1552
1553 if (conn->connection_number_tcp == -1)
1589 return -1; 1554 return -1;
1590 1555
1591 memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES); 1556 memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES);
@@ -1594,16 +1559,17 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1594 random_nonce(conn->sent_nonce); 1559 random_nonce(conn->sent_nonce);
1595 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); 1560 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1596 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); 1561 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1562 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1597 1563
1598 if (n_c->cookie_length != COOKIE_LENGTH) 1564 if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) {
1599 return -1; 1565 pthread_mutex_lock(&c->tcp_mutex);
1600 1566 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
1601 if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) 1567 pthread_mutex_unlock(&c->tcp_mutex);
1568 conn->status = CRYPTO_CONN_NO_CONNECTION;
1602 return -1; 1569 return -1;
1570 }
1603 1571
1604 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1572 memcpy(conn->dht_public_key, n_c->dht_public_key, crypto_box_PUBLICKEYBYTES);
1605 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1606 set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key);
1607 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 1573 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1608 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; 1574 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
1609 crypto_connection_add_source(c, crypt_connection_id, n_c->source); 1575 crypto_connection_add_source(c, crypt_connection_id, n_c->source);
@@ -1616,7 +1582,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1616 * return -1 on failure. 1582 * return -1 on failure.
1617 * return connection id on success. 1583 * return connection id on success.
1618 */ 1584 */
1619int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key) 1585int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key)
1620{ 1586{
1621 int crypt_connection_id = getcryptconnection_id(c, real_public_key); 1587 int crypt_connection_id = getcryptconnection_id(c, real_public_key);
1622 1588
@@ -1628,149 +1594,40 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key)
1628 if (crypt_connection_id == -1) 1594 if (crypt_connection_id == -1)
1629 return -1; 1595 return -1;
1630 1596
1631 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1597 Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id];
1632 1598
1633 if (conn == 0) 1599 if (conn == 0)
1634 return -1; 1600 return -1;
1635 1601
1602 pthread_mutex_lock(&c->tcp_mutex);
1603 conn->connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id);
1604 pthread_mutex_unlock(&c->tcp_mutex);
1605
1606 if (conn->connection_number_tcp == -1)
1607 return -1;
1608
1636 memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES); 1609 memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES);
1637 random_nonce(conn->sent_nonce); 1610 random_nonce(conn->sent_nonce);
1638 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); 1611 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1639 conn->status = CRYPTO_CONN_COOKIE_REQUESTING; 1612 conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
1640 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 1613 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1641 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; 1614 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
1642 return crypt_connection_id; 1615 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES);
1643}
1644
1645/* Set the status for the TCP connection for conn in location to status.
1646 */
1647static void set_conn_tcp_status(Crypto_Connection *conn, unsigned int location, unsigned int status)
1648{
1649 if (conn->status_tcp[location] == status) {
1650 return;
1651 }
1652
1653 if (conn->status_tcp[location] == STATUS_TCP_ONLINE) {
1654 --conn->num_tcp_online;
1655 }
1656
1657 if (status == STATUS_TCP_ONLINE) {
1658 ++conn->num_tcp_online;
1659 }
1660
1661 conn->status_tcp[location] = status;
1662}
1663
1664/* Disconnect peer from all associated TCP connections.
1665 *
1666 * return -1 on failure.
1667 * return 0 on success.
1668 */
1669static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1670{
1671 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1672
1673 if (conn == 0)
1674 return -1;
1675
1676 uint32_t i;
1677
1678 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1679 if (conn->status_tcp[i] != STATUS_TCP_NULL) {
1680 pthread_mutex_lock(&c->tcp_mutex);
1681 send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]);
1682 set_conn_tcp_status(conn, i, STATUS_TCP_NULL);
1683 conn->con_number_tcp[i] = 0;
1684 pthread_mutex_unlock(&c->tcp_mutex);
1685 }
1686 }
1687
1688 return 0;
1689}
1690
1691/* Connect peer to all associated TCP connections.
1692 *
1693 * return -1 on failure.
1694 * return 0 on success.
1695 */
1696static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1697{
1698 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1699
1700 if (conn == 0)
1701 return -1;
1702
1703 uint32_t i;
1704 1616
1705 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { 1617 conn->cookie_request_number = random_64b();
1706 if (c->tcp_connections[i] == NULL) 1618 uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
1707 continue;
1708 1619
1620 if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
1621 conn->shared_key) != sizeof(cookie_request)
1622 || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) {
1709 pthread_mutex_lock(&c->tcp_mutex); 1623 pthread_mutex_lock(&c->tcp_mutex);
1710 //TODO check function return? 1624 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
1711 send_routing_request(c->tcp_connections[i], conn->dht_public_key);
1712 pthread_mutex_unlock(&c->tcp_mutex); 1625 pthread_mutex_unlock(&c->tcp_mutex);
1713 } 1626 conn->status = CRYPTO_CONN_NO_CONNECTION;
1714
1715 return 0;
1716}
1717
1718/* Copy friends DHT public key into dht_key.
1719 *
1720 * return 0 on failure (no key copied).
1721 * return 1 on success (key copied).
1722 */
1723unsigned int get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key)
1724{
1725 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1726
1727 if (conn == 0)
1728 return 0;
1729
1730 if (conn->dht_public_key_set == 0)
1731 return 0;
1732
1733 memcpy(dht_public_key, conn->dht_public_key, crypto_box_PUBLICKEYBYTES);
1734 return 1;
1735}
1736
1737
1738/* Set the DHT public key of the crypto connection.
1739 *
1740 * return -1 on failure.
1741 * return 0 on success.
1742 */
1743int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key)
1744{
1745 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1746
1747 if (conn == 0)
1748 return -1;
1749
1750 if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1751 return -1; 1627 return -1;
1752
1753 if (conn->dht_public_key_set == 1) {
1754 disconnect_peer_tcp(c, crypt_connection_id);
1755 } 1628 }
1756 1629
1757 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES); 1630 return crypt_connection_id;
1758 conn->dht_public_key_set = 1;
1759
1760 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1761 conn->cookie_request_number = random_64b();
1762 uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
1763
1764 if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
1765 conn->shared_key) != sizeof(cookie_request))
1766 return -1;
1767
1768 if (new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0)
1769 return -1;
1770 }//TODO
1771
1772 connect_peer_tcp(c, crypt_connection_id);
1773 return 0;
1774} 1631}
1775 1632
1776/* Set the direct ip of the crypto connection. 1633/* Set the direct ip of the crypto connection.
@@ -1789,8 +1646,13 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1789 return -1; 1646 return -1;
1790 1647
1791 if (!ipport_equal(&ip_port, &conn->ip_port)) { 1648 if (!ipport_equal(&ip_port, &conn->ip_port)) {
1792 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic()) { 1649 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time()) {
1793 if (LAN_ip(ip_port.ip) == 0 && LAN_ip(conn->ip_port.ip) == 0 && conn->ip_port.port == ip_port.port) 1650 /* We already know a LAN ip, no need to switch. */
1651 if (LAN_ip(conn->ip_port.ip) == 0)
1652 return -1;
1653
1654 /* Prefer ipv6. */
1655 if (conn->ip_port.ip.family == AF_INET6 && ip_port.ip.family == AF_INET)
1794 return -1; 1656 return -1;
1795 } 1657 }
1796 1658
@@ -1805,93 +1667,25 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1805 return -1; 1667 return -1;
1806} 1668}
1807 1669
1808static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key)
1809{
1810 TCP_Client_Connection *TCP_con = object;
1811 Net_Crypto *c = TCP_con->net_crypto_pointer;
1812
1813 int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1814
1815 if (crypt_connection_id == -1)
1816 return -1;
1817
1818 set_tcp_connection_number(TCP_con, connection_id, crypt_connection_id);
1819
1820 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1821
1822 if (conn == 0)
1823 return -1;
1824 1670
1825 uint32_t location = TCP_con->net_crypto_location; 1671static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t length)
1826
1827 if (location >= MAX_TCP_CONNECTIONS)
1828 return -1;
1829
1830 if (c->tcp_connections[location] != TCP_con)
1831 return -1;
1832
1833 conn->con_number_tcp[location] = connection_id;
1834 uint32_t i;
1835
1836 for (i = 0; i < conn->num_tcp_relays; ++i) {
1837 if (memcmp(TCP_con->public_key, conn->tcp_relays[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
1838 set_conn_tcp_status(conn, location, STATUS_TCP_INVISIBLE);
1839 return 0;
1840 }
1841 }
1842
1843 set_conn_tcp_status(conn, location, STATUS_TCP_OFFLINE);
1844 return 0;
1845}
1846
1847static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status)
1848{ 1672{
1849 TCP_Client_Connection *TCP_con = object; 1673 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1850 Net_Crypto *c = TCP_con->net_crypto_pointer;
1851
1852 Crypto_Connection *conn = get_crypto_connection(c, number);
1853
1854 if (conn == 0)
1855 return -1;
1856
1857 uint32_t location = TCP_con->net_crypto_location;
1858
1859 if (location >= MAX_TCP_CONNECTIONS)
1860 return -1;
1861
1862 if (c->tcp_connections[location] != TCP_con)
1863 return -1; 1674 return -1;
1864 1675
1865 if (status == 1) { 1676 Net_Crypto *c = object;
1866 set_conn_tcp_status(conn, location, STATUS_TCP_OFFLINE);
1867 } else if (status == 2) {
1868 set_conn_tcp_status(conn, location, STATUS_TCP_ONLINE);
1869 }
1870
1871 conn->con_number_tcp[location] = connection_id;
1872 return 0;
1873}
1874 1677
1875static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length) 1678 Crypto_Connection *conn = get_crypto_connection(c, id);
1876{
1877 1679
1878 if (length == 0) 1680 if (conn == 0)
1879 return -1; 1681 return -1;
1880 1682
1881 TCP_Client_Connection *TCP_con = object;
1882 Net_Crypto *c = TCP_con->net_crypto_pointer;
1883
1884 if (data[0] == NET_PACKET_COOKIE_REQUEST) { 1683 if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1885 return tcp_handle_cookie_request(c, TCP_con, connection_id, data, length); 1684 return tcp_handle_cookie_request(c, conn->connection_number_tcp, data, length);
1886 } 1685 }
1887 1686
1888 Crypto_Connection *conn = get_crypto_connection(c, number);
1889
1890 if (conn == 0)
1891 return -1;
1892
1893 pthread_mutex_unlock(&c->tcp_mutex); 1687 pthread_mutex_unlock(&c->tcp_mutex);
1894 int ret = handle_packet_connection(c, number, data, length); 1688 int ret = handle_packet_connection(c, id, data, length);
1895 pthread_mutex_lock(&c->tcp_mutex); 1689 pthread_mutex_lock(&c->tcp_mutex);
1896 1690
1897 if (ret != 0) 1691 if (ret != 0)
@@ -1901,92 +1695,29 @@ static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_i
1901 return 0; 1695 return 0;
1902} 1696}
1903 1697
1904static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length) 1698static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned int tcp_connections_number,
1699 const uint8_t *data, uint16_t length)
1905{ 1700{
1906 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) 1701 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1907 return -1; 1702 return -1;
1908 1703
1909 TCP_Client_Connection *TCP_con = object; 1704 Net_Crypto *c = object;
1910 Net_Crypto *c = TCP_con->net_crypto_pointer;
1911 uint32_t location = TCP_con->net_crypto_location;
1912 1705
1913 if (data[0] == NET_PACKET_COOKIE_REQUEST) { 1706 if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1914 return tcp_oob_handle_cookie_request(c, TCP_con, public_key, data, length); 1707 return tcp_oob_handle_cookie_request(c, tcp_connections_number, public_key, data, length);
1915 } 1708 } else if (data[0] == NET_PACKET_CRYPTO_HS) {
1916
1917 int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1918
1919 if (crypt_connection_id == -1) {
1920 IP_Port source; 1709 IP_Port source;
1921 source.port = 0; 1710 source.port = 0;
1922 source.ip.family = TCP_FAMILY; 1711 source.ip.family = TCP_FAMILY;
1923 source.ip.ip6.uint32[0] = location; 1712 source.ip.ip6.uint32[0] = tcp_connections_number;
1924
1925 if (data[0] != NET_PACKET_CRYPTO_HS) {
1926 LOGGER_DEBUG("tcp snhappen %u\n", data[0]);
1927 return -1;
1928 }
1929 1713
1930 if (handle_new_connection_handshake(c, source, data, length) != 0) 1714 if (handle_new_connection_handshake(c, source, data, length) != 0)
1931 return -1; 1715 return -1;
1932 1716
1933 return 0; 1717 return 0;
1934 } 1718 } else {
1935
1936 pthread_mutex_unlock(&c->tcp_mutex);
1937 int ret = handle_packet_connection(c, crypt_connection_id, data, length);
1938 pthread_mutex_lock(&c->tcp_mutex);
1939
1940 if (ret != 0)
1941 return -1; 1719 return -1;
1942
1943 return 0;
1944}
1945
1946static int tcp_onion_callback(void *object, const uint8_t *data, uint16_t length)
1947{
1948 Net_Crypto *c = object;
1949
1950 if (c->tcp_onion_callback)
1951 return c->tcp_onion_callback(c->tcp_onion_callback_object, data, length);
1952
1953 return 1;
1954}
1955
1956
1957/* Check if tcp connection to public key can be created.
1958 *
1959 * return -1 if it can't.
1960 * return 0 if it can.
1961 */
1962static int tcp_connection_check(const Net_Crypto *c, const uint8_t *public_key)
1963{
1964 uint32_t i;
1965
1966 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1967 if (c->tcp_connections_new[i] == NULL)
1968 continue;
1969
1970 if (memcmp(c->tcp_connections_new[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1971 return -1;
1972 }
1973
1974 uint32_t num = 0;
1975
1976 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1977 if (c->tcp_connections[i] == NULL)
1978 continue;
1979
1980 if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1981 return -1;
1982
1983 ++num;
1984 } 1720 }
1985
1986 if (num == MAX_TCP_CONNECTIONS)
1987 return -1;
1988
1989 return 0;
1990} 1721}
1991 1722
1992/* Add a tcp relay, associating it to a crypt_connection_id. 1723/* Add a tcp relay, associating it to a crypt_connection_id.
@@ -2001,45 +1732,10 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
2001 if (conn == 0) 1732 if (conn == 0)
2002 return -1; 1733 return -1;
2003 1734
2004 if (ip_port.ip.family == TCP_INET) { 1735 pthread_mutex_lock(&c->tcp_mutex);
2005 ip_port.ip.family = AF_INET; 1736 int ret = add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key);
2006 } else if (ip_port.ip.family == TCP_INET6) { 1737 pthread_mutex_unlock(&c->tcp_mutex);
2007 ip_port.ip.family = AF_INET6; 1738 return ret;
2008 }
2009
2010 if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6)
2011 return -1;
2012
2013 uint32_t i;
2014
2015 for (i = 0; i < conn->num_tcp_relays; ++i) {
2016 if (memcmp(conn->tcp_relays[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
2017 conn->tcp_relays[i].ip_port = ip_port;
2018 return 0;
2019 }
2020 }
2021
2022 if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) {
2023 uint16_t index = rand() % MAX_TCP_RELAYS_PEER;
2024 conn->tcp_relays[index].ip_port = ip_port;
2025 memcpy(conn->tcp_relays[index].public_key, public_key, crypto_box_PUBLICKEYBYTES);
2026 } else {
2027 conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port;
2028 memcpy(conn->tcp_relays[conn->num_tcp_relays].public_key, public_key, crypto_box_PUBLICKEYBYTES);
2029 ++conn->num_tcp_relays;
2030 }
2031
2032 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2033 if (c->tcp_connections[i] == NULL)
2034 continue;
2035
2036 if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
2037 if (conn->status_tcp[i] == STATUS_TCP_OFFLINE)
2038 set_conn_tcp_status(conn, i, STATUS_TCP_INVISIBLE);
2039 }
2040 }
2041
2042 return add_tcp_relay(c, ip_port, public_key);
2043} 1739}
2044 1740
2045/* Add a tcp relay to the array. 1741/* Add a tcp relay to the array.
@@ -2049,30 +1745,10 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
2049 */ 1745 */
2050int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key) 1746int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
2051{ 1747{
2052 if (ip_port.ip.family == TCP_INET) { 1748 pthread_mutex_lock(&c->tcp_mutex);
2053 ip_port.ip.family = AF_INET; 1749 int ret = add_tcp_relay_global(c->tcp_c, ip_port, public_key);
2054 } else if (ip_port.ip.family == TCP_INET6) { 1750 pthread_mutex_unlock(&c->tcp_mutex);
2055 ip_port.ip.family = AF_INET6; 1751 return ret;
2056 }
2057
2058 if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6)
2059 return -1;
2060
2061 if (tcp_connection_check(c, public_key) != 0)
2062 return -1;
2063
2064 uint32_t i;
2065
2066 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2067 if (c->tcp_connections_new[i] == NULL) {
2068 c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key,
2069 &c->proxy_info);
2070
2071 return 0;
2072 }
2073 }
2074
2075 return -1;
2076} 1752}
2077 1753
2078/* Return a random TCP connection number for use in send_tcp_onion_request. 1754/* Return a random TCP connection number for use in send_tcp_onion_request.
@@ -2085,47 +1761,25 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
2085 */ 1761 */
2086int get_random_tcp_con_number(Net_Crypto *c) 1762int get_random_tcp_con_number(Net_Crypto *c)
2087{ 1763{
2088 unsigned int i, r = rand(); 1764 pthread_mutex_lock(&c->tcp_mutex);
2089 1765 int ret = get_random_tcp_onion_conn_number(c->tcp_c);
2090 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { 1766 pthread_mutex_unlock(&c->tcp_mutex);
2091 if (c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS]) {
2092 return (i + r) % MAX_TCP_CONNECTIONS;
2093 }
2094 }
2095 1767
2096 return -1; 1768 return ret;
2097} 1769}
2098 1770
2099/* Send an onion packet via the TCP relay corresponding to TCP_conn_number. 1771/* Send an onion packet via the TCP relay corresponding to tcp_connections_number.
2100 * 1772 *
2101 * return 0 on success. 1773 * return 0 on success.
2102 * return -1 on failure. 1774 * return -1 on failure.
2103 */ 1775 */
2104int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const uint8_t *data, uint16_t length) 1776int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length)
2105{ 1777{
2106 if (TCP_conn_number > MAX_TCP_CONNECTIONS) { 1778 pthread_mutex_lock(&c->tcp_mutex);
2107 return -1; 1779 int ret = tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length);
2108 } 1780 pthread_mutex_unlock(&c->tcp_mutex);
2109
2110 if (c->tcp_connections[TCP_conn_number]) {
2111 pthread_mutex_lock(&c->tcp_mutex);
2112 int ret = send_onion_request(c->tcp_connections[TCP_conn_number], data, length);
2113 pthread_mutex_unlock(&c->tcp_mutex);
2114
2115 if (ret == 1)
2116 return 0;
2117 }
2118
2119 return -1;
2120}
2121 1781
2122/* Set the function to be called when an onion response packet is received by one of the TCP connections. 1782 return ret;
2123 */
2124void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data,
2125 uint16_t length), void *object)
2126{
2127 c->tcp_onion_callback = tcp_onion_callback;
2128 c->tcp_onion_callback_object = object;
2129} 1783}
2130 1784
2131/* Copy a maximum of num TCP relays we are connected to to tcp_relays. 1785/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
@@ -2134,173 +1788,47 @@ void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *o
2134 * return number of relays copied to tcp_relays on success. 1788 * return number of relays copied to tcp_relays on success.
2135 * return 0 on failure. 1789 * return 0 on failure.
2136 */ 1790 */
2137unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num) 1791unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
2138{ 1792{
2139 if (num == 0) 1793 if (num == 0)
2140 return 0; 1794 return 0;
2141 1795
2142 uint32_t i; 1796 pthread_mutex_lock(&c->tcp_mutex);
2143 uint16_t copied = 0; 1797 unsigned int ret = tcp_copy_connected_relays(c->tcp_c, tcp_relays, num);
2144 1798 pthread_mutex_unlock(&c->tcp_mutex);
2145 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2146 if (c->tcp_connections[i] != NULL) {
2147 memcpy(tcp_relays[copied].public_key, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES);
2148 tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port;
2149
2150 if (tcp_relays[copied].ip_port.ip.family == AF_INET) {
2151 tcp_relays[copied].ip_port.ip.family = TCP_INET;
2152 } else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) {
2153 tcp_relays[copied].ip_port.ip.family = TCP_INET6;
2154 }
2155
2156 ++copied;
2157
2158 if (copied == num)
2159 return copied;
2160 }
2161 }
2162 1799
2163 return copied; 1800 return ret;
2164} 1801}
2165 1802
2166/* Add a connected tcp connection to the tcp_connections array. 1803static void do_tcp(Net_Crypto *c)
2167 *
2168 * return 0 if it was added.
2169 * return -1 if it wasn't.
2170 */
2171static int add_tcp_connected(Net_Crypto *c, TCP_Client_Connection *tcp_con)
2172{ 1804{
2173 uint32_t i; 1805 pthread_mutex_lock(&c->tcp_mutex);
2174 1806 do_tcp_connections(c->tcp_c);
2175 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { 1807 pthread_mutex_unlock(&c->tcp_mutex);
2176 if (c->tcp_connections[i] == NULL)
2177 break;
2178 }
2179
2180 if (i == MAX_TCP_CONNECTIONS)
2181 return -1;
2182 1808
2183 uint32_t tcp_num = i; 1809 uint32_t i;
2184 1810
2185 for (i = 0; i < c->crypto_connections_length; ++i) { 1811 for (i = 0; i < c->crypto_connections_length; ++i) {
2186 Crypto_Connection *conn = get_crypto_connection(c, i); 1812 Crypto_Connection *conn = get_crypto_connection(c, i);
2187 1813
2188 if (conn == 0) 1814 if (conn == 0)
2189 return -1; 1815 return;
2190
2191 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2192 continue;
2193
2194 if (conn->status == CRYPTO_CONN_TIMED_OUT)
2195 continue;
2196
2197 if (conn->dht_public_key_set)
2198 if (send_routing_request(tcp_con, conn->dht_public_key) != 1)
2199 return -1;
2200
2201 }
2202
2203 tcp_con->net_crypto_pointer = c;
2204 tcp_con->net_crypto_location = tcp_num;
2205 routing_response_handler(tcp_con, tcp_response_callback, tcp_con);
2206 routing_status_handler(tcp_con, tcp_status_callback, tcp_con);
2207 routing_data_handler(tcp_con, tcp_data_callback, tcp_con);
2208 oob_data_handler(tcp_con, tcp_oob_callback, tcp_con);
2209 onion_response_handler(tcp_con, tcp_onion_callback, c);
2210 c->tcp_connections[tcp_num] = tcp_con;
2211 return 0;
2212}
2213
2214static void do_tcp(Net_Crypto *c)
2215{
2216 uint32_t i;
2217
2218 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2219 if (c->tcp_connections_new[i] == NULL)
2220 continue;
2221
2222 pthread_mutex_lock(&c->tcp_mutex);
2223 do_TCP_connection(c->tcp_connections_new[i]);
2224 pthread_mutex_unlock(&c->tcp_mutex);
2225 1816
2226 if (c->tcp_connections_new[i]->status == TCP_CLIENT_CONFIRMED) { 1817 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
2227 pthread_mutex_lock(&c->tcp_mutex); 1818 _Bool direct_connected = 0;
2228 int ret = add_tcp_connected(c, c->tcp_connections_new[i]); 1819 crypto_connection_status(c, i, &direct_connected, NULL);
2229 pthread_mutex_unlock(&c->tcp_mutex);
2230 1820
2231 if (ret == 0) { 1821 if (direct_connected) {
2232 c->tcp_connections_new[i] = NULL; 1822 pthread_mutex_lock(&c->tcp_mutex);
1823 set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 0);
1824 pthread_mutex_unlock(&c->tcp_mutex);
2233 } else { 1825 } else {
2234 kill_TCP_connection(c->tcp_connections_new[i]); 1826 pthread_mutex_lock(&c->tcp_mutex);
2235 c->tcp_connections_new[i] = NULL; 1827 set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 1);
1828 pthread_mutex_unlock(&c->tcp_mutex);
2236 } 1829 }
2237 } 1830 }
2238 } 1831 }
2239
2240 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2241 if (c->tcp_connections[i] == NULL)
2242 continue;
2243
2244 pthread_mutex_lock(&c->tcp_mutex);
2245 do_TCP_connection(c->tcp_connections[i]);
2246 pthread_mutex_unlock(&c->tcp_mutex);
2247 }
2248}
2249
2250static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number)
2251{
2252 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2253 return;
2254
2255 if (number >= MAX_TCP_CONNECTIONS)
2256 return;
2257
2258 set_conn_tcp_status(conn, number, STATUS_TCP_NULL);
2259 conn->con_number_tcp[number] = 0;
2260}
2261
2262static void clear_disconnected_tcp(Net_Crypto *c)
2263{
2264 uint32_t i, j;
2265
2266 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2267 if (c->tcp_connections_new[i] == NULL)
2268 continue;
2269
2270 if (c->tcp_connections_new[i]->status != TCP_CLIENT_DISCONNECTED)
2271 continue;
2272
2273 kill_TCP_connection(c->tcp_connections_new[i]);
2274 c->tcp_connections_new[i] = NULL;
2275 }
2276
2277 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2278 if (c->tcp_connections[i] == NULL)
2279 continue;
2280
2281 TCP_Client_Connection *tcp_con = c->tcp_connections[i];
2282
2283 if (tcp_con->status != TCP_CLIENT_DISCONNECTED)
2284 continue;
2285
2286 /* Try reconnecting to relay on disconnect. */
2287 add_tcp_relay(c, tcp_con->ip_port, tcp_con->public_key);
2288
2289 pthread_mutex_lock(&c->tcp_mutex);
2290 c->tcp_connections[i] = NULL;
2291 kill_TCP_connection(tcp_con);
2292
2293 for (j = 0; j < c->crypto_connections_length; ++j) {
2294 Crypto_Connection *conn = get_crypto_connection(c, j);
2295
2296 if (conn == 0)
2297 continue;
2298
2299 clear_disconnected_tcp_peer(conn, i);
2300 }
2301
2302 pthread_mutex_unlock(&c->tcp_mutex);
2303 }
2304} 1832}
2305 1833
2306/* Set function to be called when connection with crypt_connection_id goes connects/disconnects. 1834/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
@@ -2372,8 +1900,10 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
2372} 1900}
2373 1901
2374 1902
2375/* Set the function for this friend that will be callbacked with object and number 1903/* Set the function for this friend that will be callbacked with object and number if
2376 * when that friend gives us his DHT temporary public key. 1904 * the friend sends us a different dht public key than we have associated to him.
1905 *
1906 * If this function is called, the connection should be recreated with the new public key.
2377 * 1907 *
2378 * object and number will be passed as argument to this function. 1908 * object and number will be passed as argument to this function.
2379 * 1909 *
@@ -2441,7 +1971,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
2441 return -1; 1971 return -1;
2442 1972
2443 pthread_mutex_lock(&conn->mutex); 1973 pthread_mutex_lock(&conn->mutex);
2444 conn->direct_lastrecv_time = current_time_monotonic(); 1974 conn->direct_lastrecv_time = unix_time();
2445 pthread_mutex_unlock(&conn->mutex); 1975 pthread_mutex_unlock(&conn->mutex);
2446 return 0; 1976 return 0;
2447} 1977}
@@ -2746,7 +2276,10 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2746 if (conn->status == CRYPTO_CONN_ESTABLISHED) 2276 if (conn->status == CRYPTO_CONN_ESTABLISHED)
2747 send_kill_packet(c, crypt_connection_id); 2277 send_kill_packet(c, crypt_connection_id);
2748 2278
2749 disconnect_peer_tcp(c, crypt_connection_id); 2279 pthread_mutex_lock(&c->tcp_mutex);
2280 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
2281 pthread_mutex_unlock(&c->tcp_mutex);
2282
2750 bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id); 2283 bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id);
2751 clear_temp_packet(c, crypt_connection_id); 2284 clear_temp_packet(c, crypt_connection_id);
2752 clear_buffer(&conn->send_array); 2285 clear_buffer(&conn->send_array);
@@ -2762,18 +2295,26 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2762/* return one of CRYPTO_CONN_* values indicating the state of the connection. 2295/* return one of CRYPTO_CONN_* values indicating the state of the connection.
2763 * 2296 *
2764 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. 2297 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
2298 * sets online_tcp_relays to the number of connected tcp relays this connection has.
2765 */ 2299 */
2766unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected) 2300unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, _Bool *direct_connected,
2301 unsigned int *online_tcp_relays)
2767{ 2302{
2768 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 2303 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2769 2304
2770 if (conn == 0) 2305 if (conn == 0)
2771 return CRYPTO_CONN_NO_CONNECTION; 2306 return CRYPTO_CONN_NO_CONNECTION;
2772 2307
2773 *direct_connected = 0; 2308 if (direct_connected) {
2309 *direct_connected = 0;
2774 2310
2775 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic()) 2311 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time())
2776 *direct_connected = 1; 2312 *direct_connected = 1;
2313 }
2314
2315 if (online_tcp_relays) {
2316 *online_tcp_relays = tcp_connection_to_online_tcp_relays(c->tcp_c, conn->connection_number_tcp);
2317 }
2777 2318
2778 return conn->status; 2319 return conn->status;
2779} 2320}
@@ -2816,8 +2357,19 @@ Net_Crypto *new_net_crypto(DHT *dht, TCP_Proxy_Info *proxy_info)
2816 if (temp == NULL) 2357 if (temp == NULL)
2817 return NULL; 2358 return NULL;
2818 2359
2360 temp->tcp_c = new_tcp_connections(dht, proxy_info);
2361
2362 if (temp->tcp_c == NULL) {
2363 free(temp);
2364 return NULL;
2365 }
2366
2367 set_packet_tcp_connection_callback(temp->tcp_c, &tcp_data_callback, temp);
2368 set_oob_packet_tcp_connection_callback(temp->tcp_c, &tcp_oob_callback, temp);
2369
2819 if (create_recursive_mutex(&temp->tcp_mutex) != 0 || 2370 if (create_recursive_mutex(&temp->tcp_mutex) != 0 ||
2820 pthread_mutex_init(&temp->connections_mutex, NULL) != 0) { 2371 pthread_mutex_init(&temp->connections_mutex, NULL) != 0) {
2372 kill_tcp_connections(temp->tcp_c);
2821 free(temp); 2373 free(temp);
2822 return NULL; 2374 return NULL;
2823 } 2375 }
@@ -2836,8 +2388,6 @@ Net_Crypto *new_net_crypto(DHT *dht, TCP_Proxy_Info *proxy_info)
2836 2388
2837 bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8); 2389 bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8);
2838 2390
2839 temp->proxy_info = *proxy_info;
2840
2841 return temp; 2391 return temp;
2842} 2392}
2843 2393
@@ -2852,7 +2402,7 @@ static void kill_timedout(Net_Crypto *c)
2852 if (conn == 0) 2402 if (conn == 0)
2853 return; 2403 return;
2854 2404
2855 if (conn->status == CRYPTO_CONN_NO_CONNECTION || conn->status == CRYPTO_CONN_TIMED_OUT) 2405 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2856 continue; 2406 continue;
2857 2407
2858 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT 2408 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT
@@ -2860,19 +2410,8 @@ static void kill_timedout(Net_Crypto *c)
2860 if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES) 2410 if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES)
2861 continue; 2411 continue;
2862 2412
2863 conn->killed = 1; 2413 connection_kill(c, i);
2864
2865 }
2866
2867 if (conn->killed) {
2868 if (conn->connection_status_callback) {
2869 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0);
2870 crypto_kill(c, i);
2871 continue;
2872 }
2873 2414
2874 conn->status = CRYPTO_CONN_TIMED_OUT;
2875 continue;
2876 } 2415 }
2877 2416
2878 if (conn->status == CRYPTO_CONN_ESTABLISHED) { 2417 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
@@ -2894,7 +2433,6 @@ void do_net_crypto(Net_Crypto *c)
2894 unix_time_update(); 2433 unix_time_update();
2895 kill_timedout(c); 2434 kill_timedout(c);
2896 do_tcp(c); 2435 do_tcp(c);
2897 clear_disconnected_tcp(c);
2898 send_crypto_packets(c); 2436 send_crypto_packets(c);
2899} 2437}
2900 2438
@@ -2906,14 +2444,10 @@ void kill_net_crypto(Net_Crypto *c)
2906 crypto_kill(c, i); 2444 crypto_kill(c, i);
2907 } 2445 }
2908 2446
2909 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2910 kill_TCP_connection(c->tcp_connections_new[i]);
2911 kill_TCP_connection(c->tcp_connections[i]);
2912 }
2913
2914 pthread_mutex_destroy(&c->tcp_mutex); 2447 pthread_mutex_destroy(&c->tcp_mutex);
2915 pthread_mutex_destroy(&c->connections_mutex); 2448 pthread_mutex_destroy(&c->connections_mutex);
2916 2449
2450 kill_tcp_connections(c->tcp_c);
2917 bs_list_free(&c->ip_port_list); 2451 bs_list_free(&c->ip_port_list);
2918 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL); 2452 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL);
2919 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL); 2453 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL);
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index fab72cb3..9eb5e2d3 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -26,7 +26,7 @@
26 26
27#include "DHT.h" 27#include "DHT.h"
28#include "LAN_discovery.h" 28#include "LAN_discovery.h"
29#include "TCP_client.h" 29#include "TCP_connection.h"
30#include <pthread.h> 30#include <pthread.h>
31 31
32#define CRYPTO_CONN_NO_CONNECTION 0 32#define CRYPTO_CONN_NO_CONNECTION 0
@@ -34,7 +34,6 @@
34#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets 34#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets
35#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets, we have received one from the other 35#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets, we have received one from the other
36#define CRYPTO_CONN_ESTABLISHED 4 36#define CRYPTO_CONN_ESTABLISHED 4
37#define CRYPTO_CONN_TIMED_OUT 5
38 37
39/* Maximum size of receiving and sending packet buffers. */ 38/* Maximum size of receiving and sending packet buffers. */
40#define CRYPTO_PACKET_BUFFER_SIZE 16384 /* Must be a power of 2 */ 39#define CRYPTO_PACKET_BUFFER_SIZE 16384 /* Must be a power of 2 */
@@ -61,7 +60,7 @@
61#define MAX_NUM_SENDPACKET_TRIES 8 60#define MAX_NUM_SENDPACKET_TRIES 8
62 61
63/* The timeout of no received UDP packets before the direct UDP connection is considered dead. */ 62/* The timeout of no received UDP packets before the direct UDP connection is considered dead. */
64#define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 2) 63#define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 1000)
65 64
66#define PACKET_ID_PADDING 0 /* Denotes padding */ 65#define PACKET_ID_PADDING 0 /* Denotes padding */
67#define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */ 66#define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */
@@ -73,11 +72,6 @@
73#define MAX_TCP_CONNECTIONS 64 72#define MAX_TCP_CONNECTIONS 64
74#define MAX_TCP_RELAYS_PEER 4 73#define MAX_TCP_RELAYS_PEER 4
75 74
76#define STATUS_TCP_NULL 0
77#define STATUS_TCP_OFFLINE 1
78#define STATUS_TCP_INVISIBLE 2 /* we know the other peer is connected to this relay but he isn't appearing online */
79#define STATUS_TCP_ONLINE 3
80
81/* All packets starting with a byte in this range are considered lossy packets. */ 75/* All packets starting with a byte in this range are considered lossy packets. */
82#define PACKET_ID_LOSSY_RANGE_START 192 76#define PACKET_ID_LOSSY_RANGE_START 192
83#define PACKET_ID_LOSSY_RANGE_SIZE 63 77#define PACKET_ID_LOSSY_RANGE_SIZE 63
@@ -112,11 +106,9 @@ typedef struct {
112 * 2 if we are sending handshake packets 106 * 2 if we are sending handshake packets
113 * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet), 107 * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet),
114 * 4 if the connection is established. 108 * 4 if the connection is established.
115 * 5 if the connection is timed out.
116 */ 109 */
117 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ 110 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */
118 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */ 111 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */
119 uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */
120 112
121 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ 113 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */
122 uint16_t temp_packet_length; 114 uint16_t temp_packet_length;
@@ -155,15 +147,8 @@ typedef struct {
155 long signed int last_num_packets_sent[CONGESTION_QUEUE_ARRAY_SIZE]; 147 long signed int last_num_packets_sent[CONGESTION_QUEUE_ARRAY_SIZE];
156 uint32_t packets_sent; 148 uint32_t packets_sent;
157 149
158 uint8_t killed; /* set to 1 to kill the connection. */ 150 /* TCP_connection connection_number */
159 151 unsigned int connection_number_tcp;
160 uint8_t status_tcp[MAX_TCP_CONNECTIONS]; /* set to one of STATUS_TCP_* */
161 uint8_t con_number_tcp[MAX_TCP_CONNECTIONS];
162 unsigned int last_relay_sentto;
163 unsigned int num_tcp_online;
164
165 Node_format tcp_relays[MAX_TCP_RELAYS_PEER];
166 uint16_t num_tcp_relays;
167 152
168 uint8_t maximum_speed_reached; 153 uint8_t maximum_speed_reached;
169 154
@@ -186,10 +171,9 @@ typedef struct {
186 171
187typedef struct { 172typedef struct {
188 DHT *dht; 173 DHT *dht;
174 TCP_Connections *tcp_c;
189 175
190 Crypto_Connection *crypto_connections; 176 Crypto_Connection *crypto_connections;
191 TCP_Client_Connection *tcp_connections_new[MAX_TCP_CONNECTIONS];
192 TCP_Client_Connection *tcp_connections[MAX_TCP_CONNECTIONS];
193 pthread_mutex_t tcp_mutex; 177 pthread_mutex_t tcp_mutex;
194 178
195 pthread_mutex_t connections_mutex; 179 pthread_mutex_t connections_mutex;
@@ -211,11 +195,6 @@ typedef struct {
211 uint32_t current_sleep_time; 195 uint32_t current_sleep_time;
212 196
213 BS_LIST ip_port_list; 197 BS_LIST ip_port_list;
214
215 int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length);
216 void *tcp_onion_callback_object;
217
218 TCP_Proxy_Info proxy_info;
219} Net_Crypto; 198} Net_Crypto;
220 199
221 200
@@ -241,21 +220,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
241 * return -1 on failure. 220 * return -1 on failure.
242 * return connection id on success. 221 * return connection id on success.
243 */ 222 */
244int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key); 223int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key);
245
246/* Copy friends DHT public key into dht_key.
247 *
248 * return 0 on failure (no key copied).
249 * return 1 on success (key copied).
250 */
251unsigned int get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key);
252
253/* Set the DHT public key of the crypto connection.
254 *
255 * return -1 on failure.
256 * return 0 on success.
257 */
258int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key);
259 224
260/* Set the direct ip of the crypto connection. 225/* Set the direct ip of the crypto connection.
261 * 226 *
@@ -301,8 +266,10 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
301 int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object, 266 int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object,
302 int id); 267 int id);
303 268
304/* Set the function for this friend that will be callbacked with object and number 269/* Set the function for this friend that will be callbacked with object and number if
305 * when that friend gives us his DHT temporary public key. 270 * the friend sends us a different dht public key than we have associated to him.
271 *
272 * If this function is called, the connection should be recreated with the new public key.
306 * 273 *
307 * object and number will be passed as argument to this function. 274 * object and number will be passed as argument to this function.
308 * 275 *
@@ -364,11 +331,6 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
364 */ 331 */
365int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key); 332int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key);
366 333
367/* Set the function to be called when an onion response packet is received by one of the TCP connections.
368 */
369void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data,
370 uint16_t length), void *object);
371
372/* Return a random TCP connection number for use in send_tcp_onion_request. 334/* Return a random TCP connection number for use in send_tcp_onion_request.
373 * 335 *
374 * return TCP connection number on success. 336 * return TCP connection number on success.
@@ -389,7 +351,7 @@ int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const ui
389 * return number of relays copied to tcp_relays on success. 351 * return number of relays copied to tcp_relays on success.
390 * return 0 on failure. 352 * return 0 on failure.
391 */ 353 */
392unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num); 354unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num);
393 355
394/* Kill a crypto connection. 356/* Kill a crypto connection.
395 * 357 *
@@ -398,13 +360,13 @@ unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_rel
398 */ 360 */
399int crypto_kill(Net_Crypto *c, int crypt_connection_id); 361int crypto_kill(Net_Crypto *c, int crypt_connection_id);
400 362
401
402/* return one of CRYPTO_CONN_* values indicating the state of the connection. 363/* return one of CRYPTO_CONN_* values indicating the state of the connection.
403 * 364 *
404 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. 365 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
366 * sets online_tcp_relays to the number of connected tcp relays this connection has.
405 */ 367 */
406unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected); 368unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, _Bool *direct_connected,
407 369 unsigned int *online_tcp_relays);
408 370
409/* Generate our public and private keys. 371/* Generate our public and private keys.
410 * Only call this function the first time the program starts. 372 * Only call this function the first time the program starts.
diff --git a/toxcore/onion.c b/toxcore/onion.c
index c6093f0c..48e4c769 100644
--- a/toxcore/onion.c
+++ b/toxcore/onion.c
@@ -35,8 +35,8 @@
35#define SEND_2 ONION_SEND_2 35#define SEND_2 ONION_SEND_2
36#define SEND_1 ONION_SEND_1 36#define SEND_1 ONION_SEND_1
37 37
38/* Change symmetric keys every hour to make paths expire eventually. */ 38/* Change symmetric keys every 2 hours to make paths expire eventually. */
39#define KEY_REFRESH_INTERVAL (60 * 60) 39#define KEY_REFRESH_INTERVAL (2 * 60 * 60)
40static void change_symmetric_key(Onion *onion) 40static void change_symmetric_key(Onion *onion)
41{ 41{
42 if (is_timeout(onion->timestamp, KEY_REFRESH_INTERVAL)) { 42 if (is_timeout(onion->timestamp, KEY_REFRESH_INTERVAL)) {
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index a9fc1643..ed328fb3 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -1425,7 +1425,6 @@ void do_onion_client(Onion_Client *onion_c)
1425 ++onion_c->onion_connected; 1425 ++onion_c->onion_connected;
1426 } 1426 }
1427 1427
1428 onion_c->UDP_connected = DHT_non_lan_connected(onion_c->dht);
1429 } else { 1428 } else {
1430 populate_path_nodes_tcp(onion_c); 1429 populate_path_nodes_tcp(onion_c);
1431 1430
@@ -1434,12 +1433,22 @@ void do_onion_client(Onion_Client *onion_c)
1434 } 1433 }
1435 } 1434 }
1436 1435
1436 onion_c->UDP_connected = DHT_non_lan_connected(onion_c->dht);
1437
1438 if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS)) {
1439 set_tcp_onion_status(onion_c->c->tcp_c, !onion_c->UDP_connected);
1440 }
1441
1437 if (onion_connection_status(onion_c)) { 1442 if (onion_connection_status(onion_c)) {
1438 for (i = 0; i < onion_c->num_friends; ++i) { 1443 for (i = 0; i < onion_c->num_friends; ++i) {
1439 do_friend(onion_c, i); 1444 do_friend(onion_c, i);
1440 } 1445 }
1441 } 1446 }
1442 1447
1448 if (onion_c->last_run == 0) {
1449 onion_c->first_run = unix_time();
1450 }
1451
1443 onion_c->last_run = unix_time(); 1452 onion_c->last_run = unix_time();
1444} 1453}
1445 1454
@@ -1467,7 +1476,7 @@ Onion_Client *new_onion_client(Net_Crypto *c)
1467 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); 1476 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
1468 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c); 1477 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c);
1469 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c); 1478 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c);
1470 tcp_onion_response_handler(onion_c->c, &handle_tcp_onion, onion_c); 1479 set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, &handle_tcp_onion, onion_c);
1471 1480
1472 return onion_c; 1481 return onion_c;
1473} 1482}
@@ -1483,7 +1492,7 @@ void kill_onion_client(Onion_Client *onion_c)
1483 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); 1492 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL);
1484 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL); 1493 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL);
1485 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, NULL, NULL); 1494 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, NULL, NULL);
1486 tcp_onion_response_handler(onion_c->c, NULL, NULL); 1495 set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, NULL, NULL);
1487 memset(onion_c, 0, sizeof(Onion_Client)); 1496 memset(onion_c, 0, sizeof(Onion_Client));
1488 free(onion_c); 1497 free(onion_c);
1489} 1498}
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h
index e10a86c5..ad28ac51 100644
--- a/toxcore/onion_client.h
+++ b/toxcore/onion_client.h
@@ -136,7 +136,7 @@ typedef struct {
136 Onion_Client_Paths onion_paths_friends; 136 Onion_Client_Paths onion_paths_friends;
137 137
138 uint8_t secret_symmetric_key[crypto_box_KEYBYTES]; 138 uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
139 uint64_t last_run; 139 uint64_t last_run, first_run;
140 140
141 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; 141 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
142 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; 142 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
diff --git a/toxcore/tox.h b/toxcore/tox.h
index 8e368851..abd2f051 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -67,23 +67,21 @@ extern "C" {
67 * function will try to use a sane default, but there will be no error code, 67 * function will try to use a sane default, but there will be no error code,
68 * and one possible action for the function to take is to have no effect. 68 * and one possible action for the function to take is to have no effect.
69 */ 69 */
70
71/** \subsection events Events and callbacks 70/** \subsection events Events and callbacks
72 * 71 *
73 * Events are handled by callbacks. One callback can be registered per event. 72 * Events are handled by callbacks. One callback can be registered per event.
74 * All events have a callback function type named `tox_${event}_cb` and a 73 * All events have a callback function type named `tox_{event}_cb` and a
75 * function to register it named `tox_callback_${event}`. Passing a NULL 74 * function to register it named `tox_callback_{event}`. Passing a NULL
76 * callback will result in no callback being registered for that event. Only 75 * callback will result in no callback being registered for that event. Only
77 * one callback per event can be registered, so if a client needs multiple 76 * one callback per event can be registered, so if a client needs multiple
78 * event listeners, it needs to implement the dispatch functionality itself. 77 * event listeners, it needs to implement the dispatch functionality itself.
79 */ 78 */
80
81/** \subsection threading Threading implications 79/** \subsection threading Threading implications
82 * 80 *
83 * It is possible to run multiple concurrent threads with a Tox instance for 81 * It is possible to run multiple concurrent threads with a Tox instance for
84 * each thread. It is also possible to run all Tox instances in the same thread. 82 * each thread. It is also possible to run all Tox instances in the same thread.
85 * A common way to run Tox (multiple or single instance) is to have one thread 83 * A common way to run Tox (multiple or single instance) is to have one thread
86 * running a simple tox_iteration loop, sleeping for tox_iteration_interval 84 * running a simple tox_iterate loop, sleeping for tox_iteration_interval
87 * milliseconds on each iteration. 85 * milliseconds on each iteration.
88 * 86 *
89 * If you want to access a single Tox instance from multiple threads, access 87 * If you want to access a single Tox instance from multiple threads, access
@@ -108,12 +106,9 @@ extern "C" {
108 * \endcode 106 * \endcode
109 * 107 *
110 * If any other thread calls tox_self_set_name while this thread is allocating 108 * If any other thread calls tox_self_set_name while this thread is allocating
111 * memory, the length will have become invalid, and the call to 109 * memory, the length may have become invalid, and the call to
112 * tox_self_get_name may cause undefined behaviour. 110 * tox_self_get_name may cause undefined behaviour.
113 */ 111 */
114
115#ifndef TOX_DEFINED
116#define TOX_DEFINED
117/** 112/**
118 * The Tox instance type. All the state associated with a connection is held 113 * The Tox instance type. All the state associated with a connection is held
119 * within the instance. Multiple instances can exist and operate concurrently. 114 * within the instance. Multiple instances can exist and operate concurrently.
@@ -121,8 +116,10 @@ extern "C" {
121 * device is limited. Note that this is not just a per-process limit, since the 116 * device is limited. Note that this is not just a per-process limit, since the
122 * limiting factor is the number of usable ports on a device. 117 * limiting factor is the number of usable ports on a device.
123 */ 118 */
119#ifndef TOX_DEFINED
120#define TOX_DEFINED
124typedef struct Tox Tox; 121typedef struct Tox Tox;
125#endif 122#endif /* TOX_DEFINED */
126 123
127 124
128/******************************************************************************* 125/*******************************************************************************
@@ -132,17 +129,20 @@ typedef struct Tox Tox;
132 ******************************************************************************/ 129 ******************************************************************************/
133 130
134 131
132
135/** 133/**
136 * The major version number. Incremented when the API or ABI changes in an 134 * The major version number. Incremented when the API or ABI changes in an
137 * incompatible way. 135 * incompatible way.
138 */ 136 */
139#define TOX_VERSION_MAJOR 0u 137#define TOX_VERSION_MAJOR 0u
138
140/** 139/**
141 * The minor version number. Incremented when functionality is added without 140 * The minor version number. Incremented when functionality is added without
142 * breaking the API or ABI. Set to 0 when the major version number is 141 * breaking the API or ABI. Set to 0 when the major version number is
143 * incremented. 142 * incremented.
144 */ 143 */
145#define TOX_VERSION_MINOR 0u 144#define TOX_VERSION_MINOR 0u
145
146/** 146/**
147 * The patch or revision number. Incremented when bugfixes are applied without 147 * The patch or revision number. Incremented when bugfixes are applied without
148 * changing any functionality or API or ABI. 148 * changing any functionality or API or ABI.
@@ -166,7 +166,6 @@ typedef struct Tox Tox;
166#define TOX_VERSION_REQUIRE(MAJOR, MINOR, PATCH) \ 166#define TOX_VERSION_REQUIRE(MAJOR, MINOR, PATCH) \
167 typedef char tox_required_version[TOX_IS_COMPATIBLE(MAJOR, MINOR, PATCH) ? 1 : -1] 167 typedef char tox_required_version[TOX_IS_COMPATIBLE(MAJOR, MINOR, PATCH) ? 1 : -1]
168 168
169
170/** 169/**
171 * Return the major version number of the library. Can be used to display the 170 * Return the major version number of the library. Can be used to display the
172 * Tox library version or to check whether the client is compatible with the 171 * Tox library version or to check whether the client is compatible with the
@@ -205,15 +204,16 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
205 ******************************************************************************/ 204 ******************************************************************************/
206 205
207 206
207
208/** 208/**
209 * The size of a Tox Public Key in bytes. 209 * The size of a Tox Public Key in bytes.
210 */ 210 */
211#define TOX_PUBLIC_KEY_SIZE 32 211#define TOX_PUBLIC_KEY_SIZE 32
212 212
213/** 213/**
214 * The size of a Tox Secret Key in bytes. 214 * The size of a Tox Secret Key in bytes.
215 */ 215 */
216#define TOX_SECRET_KEY_SIZE 32 216#define TOX_SECRET_KEY_SIZE 32
217 217
218/** 218/**
219 * The size of a Tox address in bytes. Tox addresses are in the format 219 * The size of a Tox address in bytes. Tox addresses are in the format
@@ -223,47 +223,48 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
223 * byte is an XOR of all the even bytes (0, 2, 4, ...), the second byte is an 223 * byte is an XOR of all the even bytes (0, 2, 4, ...), the second byte is an
224 * XOR of all the odd bytes (1, 3, 5, ...) of the Public Key and nospam. 224 * XOR of all the odd bytes (1, 3, 5, ...) of the Public Key and nospam.
225 */ 225 */
226#define TOX_ADDRESS_SIZE (TOX_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) 226#define TOX_ADDRESS_SIZE (TOX_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
227 227
228/** 228/**
229 * Maximum length of a nickname in bytes. 229 * Maximum length of a nickname in bytes.
230 */ 230 */
231#define TOX_MAX_NAME_LENGTH 128 231#define TOX_MAX_NAME_LENGTH 128
232 232
233/** 233/**
234 * Maximum length of a status message in bytes. 234 * Maximum length of a status message in bytes.
235 */ 235 */
236#define TOX_MAX_STATUS_MESSAGE_LENGTH 1007 236#define TOX_MAX_STATUS_MESSAGE_LENGTH 1007
237 237
238/** 238/**
239 * Maximum length of a friend request message in bytes. 239 * Maximum length of a friend request message in bytes.
240 */ 240 */
241#define TOX_MAX_FRIEND_REQUEST_LENGTH 1016 241#define TOX_MAX_FRIEND_REQUEST_LENGTH 1016
242 242
243/** 243/**
244 * Maximum length of a single message after which it should be split. 244 * Maximum length of a single message after which it should be split.
245 */ 245 */
246#define TOX_MAX_MESSAGE_LENGTH 1372 246#define TOX_MAX_MESSAGE_LENGTH 1372
247 247
248/** 248/**
249 * Maximum size of custom packets. TODO: should be LENGTH? 249 * Maximum size of custom packets. TODO: should be LENGTH?
250 */ 250 */
251#define TOX_MAX_CUSTOM_PACKET_SIZE 1373 251#define TOX_MAX_CUSTOM_PACKET_SIZE 1373
252 252
253/** 253/**
254 * The number of bytes in a hash generated by tox_hash. 254 * The number of bytes in a hash generated by tox_hash.
255 */ 255 */
256#define TOX_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32 256#define TOX_HASH_LENGTH 32
257 257
258/** 258/**
259 * The number of bytes in a file id. 259 * The number of bytes in a file id.
260 */ 260 */
261#define TOX_FILE_ID_LENGTH 32 261#define TOX_FILE_ID_LENGTH 32
262 262
263/** 263/**
264 * Maximum file name length for file tran. 264 * Maximum file name length for file transfers.
265 */ 265 */
266#define TOX_MAX_FILENAME_LENGTH 255 266#define TOX_MAX_FILENAME_LENGTH 255
267
267 268
268/******************************************************************************* 269/*******************************************************************************
269 * 270 *
@@ -272,42 +273,53 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
272 ******************************************************************************/ 273 ******************************************************************************/
273 274
274 275
276
275/** 277/**
276 * Represents the possible statuses a client can have. 278 * Represents the possible statuses a client can have.
277 */ 279 */
278typedef enum TOX_USER_STATUS { 280typedef enum TOX_USER_STATUS {
281
279 /** 282 /**
280 * User is online and available. 283 * User is online and available.
281 */ 284 */
282 TOX_USER_STATUS_NONE, 285 TOX_USER_STATUS_NONE,
286
283 /** 287 /**
284 * User is away. Clients can set this e.g. after a user defined 288 * User is away. Clients can set this e.g. after a user defined
285 * inactivity time. 289 * inactivity time.
286 */ 290 */
287 TOX_USER_STATUS_AWAY, 291 TOX_USER_STATUS_AWAY,
292
288 /** 293 /**
289 * User is busy. Signals to other clients that this client does not 294 * User is busy. Signals to other clients that this client does not
290 * currently wish to communicate. 295 * currently wish to communicate.
291 */ 296 */
292 TOX_USER_STATUS_BUSY 297 TOX_USER_STATUS_BUSY,
298
293} TOX_USER_STATUS; 299} TOX_USER_STATUS;
294 300
301
295/** 302/**
296 * Represents message types for friend messages and group chat 303 * Represents message types for tox_friend_send_message and group chat
297 * messages. 304 * messages.
298 */ 305 */
299typedef enum TOX_MESSAGE_TYPE { 306typedef enum TOX_MESSAGE_TYPE {
307
300 /** 308 /**
301 * Normal text message. Similar to PRIVMSG on IRC. 309 * Normal text message. Similar to PRIVMSG on IRC.
302 */ 310 */
303 TOX_MESSAGE_TYPE_NORMAL, 311 TOX_MESSAGE_TYPE_NORMAL,
312
304 /** 313 /**
305 * A message describing an user action. This is similar to /me (CTCP ACTION) 314 * A message describing an user action. This is similar to /me (CTCP ACTION)
306 * on IRC. 315 * on IRC.
307 */ 316 */
308 TOX_MESSAGE_TYPE_ACTION 317 TOX_MESSAGE_TYPE_ACTION,
318
309} TOX_MESSAGE_TYPE; 319} TOX_MESSAGE_TYPE;
310 320
321
322
311/******************************************************************************* 323/*******************************************************************************
312 * 324 *
313 * :: Startup options 325 * :: Startup options
@@ -315,19 +327,27 @@ typedef enum TOX_MESSAGE_TYPE {
315 ******************************************************************************/ 327 ******************************************************************************/
316 328
317 329
330
331/**
332 * Type of proxy used to connect to TCP relays.
333 */
318typedef enum TOX_PROXY_TYPE { 334typedef enum TOX_PROXY_TYPE {
335
319 /** 336 /**
320 * Don't use a proxy. 337 * Don't use a proxy.
321 */ 338 */
322 TOX_PROXY_TYPE_NONE, 339 TOX_PROXY_TYPE_NONE,
340
323 /** 341 /**
324 * HTTP proxy using CONNECT. 342 * HTTP proxy using CONNECT.
325 */ 343 */
326 TOX_PROXY_TYPE_HTTP, 344 TOX_PROXY_TYPE_HTTP,
345
327 /** 346 /**
328 * SOCKS proxy for simple socket pipes. 347 * SOCKS proxy for simple socket pipes.
329 */ 348 */
330 TOX_PROXY_TYPE_SOCKS5 349 TOX_PROXY_TYPE_SOCKS5,
350
331} TOX_PROXY_TYPE; 351} TOX_PROXY_TYPE;
332 352
333 353
@@ -337,6 +357,7 @@ typedef enum TOX_PROXY_TYPE {
337 * tox_options_new to get a new default options object. 357 * tox_options_new to get a new default options object.
338 */ 358 */
339struct Tox_Options { 359struct Tox_Options {
360
340 /** 361 /**
341 * The type of socket to create. 362 * The type of socket to create.
342 * 363 *
@@ -347,6 +368,7 @@ struct Tox_Options {
347 */ 368 */
348 bool ipv6_enabled; 369 bool ipv6_enabled;
349 370
371
350 /** 372 /**
351 * Enable the use of UDP communication when available. 373 * Enable the use of UDP communication when available.
352 * 374 *
@@ -356,11 +378,13 @@ struct Tox_Options {
356 */ 378 */
357 bool udp_enabled; 379 bool udp_enabled;
358 380
381
359 /** 382 /**
360 * Pass communications through a proxy. 383 * Pass communications through a proxy.
361 */ 384 */
362 TOX_PROXY_TYPE proxy_type; 385 TOX_PROXY_TYPE proxy_type;
363 386
387
364 /** 388 /**
365 * The IP address or DNS name of the proxy to be used. 389 * The IP address or DNS name of the proxy to be used.
366 * 390 *
@@ -368,18 +392,20 @@ struct Tox_Options {
368 * exceed 255 characters, and be in a NUL-terminated C string format 392 * exceed 255 characters, and be in a NUL-terminated C string format
369 * (255 chars + 1 NUL byte). 393 * (255 chars + 1 NUL byte).
370 * 394 *
371 * This member is ignored (it can be NULL) if proxy_enabled is false. 395 * This member is ignored (it can be NULL) if proxy_type is TOX_PROXY_TYPE_NONE.
372 */ 396 */
373 const char *proxy_host; 397 const char *proxy_host;
374 398
399
375 /** 400 /**
376 * The port to use to connect to the proxy server. 401 * The port to use to connect to the proxy server.
377 * 402 *
378 * Ports must be in the range (1, 65535). The value is ignored if 403 * Ports must be in the range (1, 65535). The value is ignored if
379 * proxy_enabled is false. 404 * proxy_type is TOX_PROXY_TYPE_NONE.
380 */ 405 */
381 uint16_t proxy_port; 406 uint16_t proxy_port;
382 407
408
383 /** 409 /**
384 * The start port of the inclusive port range to attempt to use. 410 * The start port of the inclusive port range to attempt to use.
385 * 411 *
@@ -394,10 +420,12 @@ struct Tox_Options {
394 */ 420 */
395 uint16_t start_port; 421 uint16_t start_port;
396 422
423
397 /** 424 /**
398 * The end port of the inclusive port range to attempt to use. 425 * The end port of the inclusive port range to attempt to use.
399 */ 426 */
400 uint16_t end_port; 427 uint16_t end_port;
428
401}; 429};
402 430
403 431
@@ -414,15 +442,21 @@ struct Tox_Options {
414 */ 442 */
415void tox_options_default(struct Tox_Options *options); 443void tox_options_default(struct Tox_Options *options);
416 444
417
418typedef enum TOX_ERR_OPTIONS_NEW { 445typedef enum TOX_ERR_OPTIONS_NEW {
446
447 /**
448 * The function returned successfully.
449 */
419 TOX_ERR_OPTIONS_NEW_OK, 450 TOX_ERR_OPTIONS_NEW_OK,
451
420 /** 452 /**
421 * The function failed to allocate enough memory for the options struct. 453 * The function failed to allocate enough memory for the options struct.
422 */ 454 */
423 TOX_ERR_OPTIONS_NEW_MALLOC 455 TOX_ERR_OPTIONS_NEW_MALLOC,
456
424} TOX_ERR_OPTIONS_NEW; 457} TOX_ERR_OPTIONS_NEW;
425 458
459
426/** 460/**
427 * Allocates a new Tox_Options object and initialises it with the default 461 * Allocates a new Tox_Options object and initialises it with the default
428 * options. This function can be used to preserve long term ABI compatibility by 462 * options. This function can be used to preserve long term ABI compatibility by
@@ -435,7 +469,6 @@ typedef enum TOX_ERR_OPTIONS_NEW {
435 */ 469 */
436struct Tox_Options *tox_options_new(TOX_ERR_OPTIONS_NEW *error); 470struct Tox_Options *tox_options_new(TOX_ERR_OPTIONS_NEW *error);
437 471
438
439/** 472/**
440 * Releases all resources associated with an options objects. 473 * Releases all resources associated with an options objects.
441 * 474 *
@@ -452,41 +485,58 @@ void tox_options_free(struct Tox_Options *options);
452 ******************************************************************************/ 485 ******************************************************************************/
453 486
454 487
488
455typedef enum TOX_ERR_NEW { 489typedef enum TOX_ERR_NEW {
490
491 /**
492 * The function returned successfully.
493 */
456 TOX_ERR_NEW_OK, 494 TOX_ERR_NEW_OK,
495
496 /**
497 * One of the arguments to the function was NULL when it was not expected.
498 */
457 TOX_ERR_NEW_NULL, 499 TOX_ERR_NEW_NULL,
500
458 /** 501 /**
459 * The function was unable to allocate enough memory to store the internal 502 * The function was unable to allocate enough memory to store the internal
460 * structures for the Tox object. 503 * structures for the Tox object.
461 */ 504 */
462 TOX_ERR_NEW_MALLOC, 505 TOX_ERR_NEW_MALLOC,
506
463 /** 507 /**
464 * The function was unable to bind to a port. This may mean that all ports 508 * The function was unable to bind to a port. This may mean that all ports
465 * have already been bound, e.g. by other Tox instances, or it may mean 509 * have already been bound, e.g. by other Tox instances, or it may mean
466 * a permission error. You may be able to gather more information from errno. 510 * a permission error. You may be able to gather more information from errno.
467 */ 511 */
468 TOX_ERR_NEW_PORT_ALLOC, 512 TOX_ERR_NEW_PORT_ALLOC,
513
469 /** 514 /**
470 * proxy_type was invalid. 515 * proxy_type was invalid.
471 */ 516 */
472 TOX_ERR_NEW_PROXY_BAD_TYPE, 517 TOX_ERR_NEW_PROXY_BAD_TYPE,
518
473 /** 519 /**
474 * proxy_type was valid but the proxy_host passed had an invalid format 520 * proxy_type was valid but the proxy_host passed had an invalid format
475 * or was NULL. 521 * or was NULL.
476 */ 522 */
477 TOX_ERR_NEW_PROXY_BAD_HOST, 523 TOX_ERR_NEW_PROXY_BAD_HOST,
524
478 /** 525 /**
479 * proxy_type was valid, but the proxy_port was invalid. 526 * proxy_type was valid, but the proxy_port was invalid.
480 */ 527 */
481 TOX_ERR_NEW_PROXY_BAD_PORT, 528 TOX_ERR_NEW_PROXY_BAD_PORT,
529
482 /** 530 /**
483 * The proxy host passed could not be resolved. 531 * The proxy address passed could not be resolved.
484 */ 532 */
485 TOX_ERR_NEW_PROXY_NOT_FOUND, 533 TOX_ERR_NEW_PROXY_NOT_FOUND,
534
486 /** 535 /**
487 * The byte array to be loaded contained an encrypted save. 536 * The byte array to be loaded contained an encrypted save.
488 */ 537 */
489 TOX_ERR_NEW_LOAD_ENCRYPTED, 538 TOX_ERR_NEW_LOAD_ENCRYPTED,
539
490 /** 540 /**
491 * The data format was invalid. This can happen when loading data that was 541 * The data format was invalid. This can happen when loading data that was
492 * saved by an older version of Tox, or when the data has been corrupted. 542 * saved by an older version of Tox, or when the data has been corrupted.
@@ -494,7 +544,8 @@ typedef enum TOX_ERR_NEW {
494 * and the rest is discarded. Passing an invalid length parameter also 544 * and the rest is discarded. Passing an invalid length parameter also
495 * causes this error. 545 * causes this error.
496 */ 546 */
497 TOX_ERR_NEW_LOAD_BAD_FORMAT 547 TOX_ERR_NEW_LOAD_BAD_FORMAT,
548
498} TOX_ERR_NEW; 549} TOX_ERR_NEW;
499 550
500 551
@@ -516,11 +567,10 @@ typedef enum TOX_ERR_NEW {
516 * @param length The length of the byte array data. If this parameter is 0, the 567 * @param length The length of the byte array data. If this parameter is 0, the
517 * data parameter is ignored. 568 * data parameter is ignored.
518 * 569 *
519 * @see tox_iteration for the event loop. 570 * @see tox_iterate for the event loop.
520 */ 571 */
521Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t length, TOX_ERR_NEW *error); 572Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t length, TOX_ERR_NEW *error);
522 573
523
524/** 574/**
525 * Releases all resources associated with the Tox instance and disconnects from 575 * Releases all resources associated with the Tox instance and disconnects from
526 * the network. 576 * the network.
@@ -530,11 +580,9 @@ Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t leng
530 */ 580 */
531void tox_kill(Tox *tox); 581void tox_kill(Tox *tox);
532 582
533
534/** 583/**
535 * Calculates the number of bytes required to store the tox instance with 584 * Calculates the number of bytes required to store the tox instance with
536 * tox_get_savedata. This function cannot fail. The result is always greater 585 * tox_get_savedata. This function cannot fail. The result is always greater than 0.
537 * than 0.
538 * 586 *
539 * @see threading for concurrency implications. 587 * @see threading for concurrency implications.
540 */ 588 */
@@ -547,7 +595,7 @@ size_t tox_get_savedata_size(const Tox *tox);
547 * Call tox_get_savedata_size to find the number of bytes required. If this parameter 595 * Call tox_get_savedata_size to find the number of bytes required. If this parameter
548 * is NULL, this function has no effect. 596 * is NULL, this function has no effect.
549 */ 597 */
550void tox_get_savedata(const Tox *tox, uint8_t *data); 598void tox_get_savedata(const Tox *tox, uint8_t *savedata);
551 599
552 600
553/******************************************************************************* 601/*******************************************************************************
@@ -557,20 +605,33 @@ void tox_get_savedata(const Tox *tox, uint8_t *data);
557 ******************************************************************************/ 605 ******************************************************************************/
558 606
559 607
608
560typedef enum TOX_ERR_BOOTSTRAP { 609typedef enum TOX_ERR_BOOTSTRAP {
610
611 /**
612 * The function returned successfully.
613 */
561 TOX_ERR_BOOTSTRAP_OK, 614 TOX_ERR_BOOTSTRAP_OK,
615
616 /**
617 * One of the arguments to the function was NULL when it was not expected.
618 */
562 TOX_ERR_BOOTSTRAP_NULL, 619 TOX_ERR_BOOTSTRAP_NULL,
620
563 /** 621 /**
564 * The host could not be resolved to an IP address, or the IP address 622 * The address could not be resolved to an IP address, or the IP address
565 * passed was invalid. 623 * passed was invalid.
566 */ 624 */
567 TOX_ERR_BOOTSTRAP_BAD_HOST, 625 TOX_ERR_BOOTSTRAP_BAD_HOST,
626
568 /** 627 /**
569 * The port passed was invalid. The valid port range is (1, 65535). 628 * The port passed was invalid. The valid port range is (1, 65535).
570 */ 629 */
571 TOX_ERR_BOOTSTRAP_BAD_PORT 630 TOX_ERR_BOOTSTRAP_BAD_PORT,
631
572} TOX_ERR_BOOTSTRAP; 632} TOX_ERR_BOOTSTRAP;
573 633
634
574/** 635/**
575 * Sends a "get nodes" request to the given bootstrap node with IP, port, and 636 * Sends a "get nodes" request to the given bootstrap node with IP, port, and
576 * public key to setup connections. 637 * public key to setup connections.
@@ -583,15 +644,14 @@ typedef enum TOX_ERR_BOOTSTRAP {
583 * also use the TCP connection when NAT hole punching is slow, and later switch 644 * also use the TCP connection when NAT hole punching is slow, and later switch
584 * to UDP if hole punching succeeds. 645 * to UDP if hole punching succeeds.
585 * 646 *
586 * @param host The hostname or IP address (IPv4 or IPv6) of the node. 647 * @param address The hostname or IP address (IPv4 or IPv6) of the node.
587 * @param port The port on the host on which the bootstrap Tox instance is 648 * @param port The port on the host on which the bootstrap Tox instance is
588 * listening. 649 * listening.
589 * @param public_key The long term public key of the bootstrap node 650 * @param public_key The long term public key of the bootstrap node
590 * (TOX_PUBLIC_KEY_SIZE bytes). 651 * (TOX_PUBLIC_KEY_SIZE bytes).
591 * @return true on success. 652 * @return true on success.
592 */ 653 */
593bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error); 654bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error);
594
595 655
596/** 656/**
597 * Adds additional host:port pair as TCP relay. 657 * Adds additional host:port pair as TCP relay.
@@ -600,35 +660,41 @@ bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *pub
600 * the same bootstrap node, or to add TCP relays without using them as 660 * the same bootstrap node, or to add TCP relays without using them as
601 * bootstrap nodes. 661 * bootstrap nodes.
602 * 662 *
603 * @param host The hostname or IP address (IPv4 or IPv6) of the TCP relay. 663 * @param address The hostname or IP address (IPv4 or IPv6) of the TCP relay.
604 * @param port The port on the host on which the TCP relay is listening. 664 * @param port The port on the host on which the TCP relay is listening.
605 * @param public_key The long term public key of the TCP relay 665 * @param public_key The long term public key of the TCP relay
606 * (TOX_PUBLIC_KEY_SIZE bytes). 666 * (TOX_PUBLIC_KEY_SIZE bytes).
607 * @return true on success. 667 * @return true on success.
608 */ 668 */
609bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, 669bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key,
610 TOX_ERR_BOOTSTRAP *error); 670 TOX_ERR_BOOTSTRAP *error);
611 671
612 672/**
673 * Protocols that can be used to connect to the network or friends.
674 */
613typedef enum TOX_CONNECTION { 675typedef enum TOX_CONNECTION {
676
614 /** 677 /**
615 * There is no connection. This instance, or the friend the state change is 678 * There is no connection. This instance, or the friend the state change is
616 * about, is now offline. 679 * about, is now offline.
617 */ 680 */
618 TOX_CONNECTION_NONE, 681 TOX_CONNECTION_NONE,
682
619 /** 683 /**
620 * A TCP connection has been established. For the own instance, this means it 684 * A TCP connection has been established. For the own instance, this means it
621 * is connected through a TCP relay, only. For a friend, this means that the 685 * is connected through a TCP relay, only. For a friend, this means that the
622 * connection to that particular friend goes through a TCP relay. 686 * connection to that particular friend goes through a TCP relay.
623 */ 687 */
624 TOX_CONNECTION_TCP, 688 TOX_CONNECTION_TCP,
689
625 /** 690 /**
626 * A UDP connection has been established. For the own instance, this means it 691 * A UDP connection has been established. For the own instance, this means it
627 * is able to send UDP packets to DHT nodes, but may still be connected to 692 * is able to send UDP packets to DHT nodes, but may still be connected to
628 * a TCP relay. For a friend, this means that the connection to that 693 * a TCP relay. For a friend, this means that the connection to that
629 * particular friend was built using direct UDP packets. 694 * particular friend was built using direct UDP packets.
630 */ 695 */
631 TOX_CONNECTION_UDP 696 TOX_CONNECTION_UDP,
697
632} TOX_CONNECTION; 698} TOX_CONNECTION;
633 699
634 700
@@ -639,13 +705,11 @@ typedef enum TOX_CONNECTION {
639TOX_CONNECTION tox_self_get_connection_status(const Tox *tox); 705TOX_CONNECTION tox_self_get_connection_status(const Tox *tox);
640 706
641/** 707/**
642 * The function type for the `self_connection_status` callback. 708 * @param connection_status Whether we are connected to the DHT.
643 *
644 * @param connection_status Equal to the return value of
645 * tox_self_get_connection_status.
646 */ 709 */
647typedef void tox_self_connection_status_cb(Tox *tox, TOX_CONNECTION connection_status, void *user_data); 710typedef void tox_self_connection_status_cb(Tox *tox, TOX_CONNECTION connection_status, void *user_data);
648 711
712
649/** 713/**
650 * Set the callback for the `self_connection_status` event. Pass NULL to unset. 714 * Set the callback for the `self_connection_status` event. Pass NULL to unset.
651 * 715 *
@@ -657,16 +721,14 @@ typedef void tox_self_connection_status_cb(Tox *tox, TOX_CONNECTION connection_s
657 * 721 *
658 * TODO: how long should a client wait before bootstrapping again? 722 * TODO: how long should a client wait before bootstrapping again?
659 */ 723 */
660void tox_callback_self_connection_status(Tox *tox, tox_self_connection_status_cb *function, void *user_data); 724void tox_callback_self_connection_status(Tox *tox, tox_self_connection_status_cb *callback, void *user_data);
661
662 725
663/** 726/**
664 * Return the time in milliseconds before tox_iteration() should be called again 727 * Return the time in milliseconds before tox_iterate() should be called again
665 * for optimal performance. 728 * for optimal performance.
666 */ 729 */
667uint32_t tox_iteration_interval(const Tox *tox); 730uint32_t tox_iteration_interval(const Tox *tox);
668 731
669
670/** 732/**
671 * The main loop that needs to be run in intervals of tox_iteration_interval() 733 * The main loop that needs to be run in intervals of tox_iteration_interval()
672 * milliseconds. 734 * milliseconds.
@@ -681,6 +743,7 @@ void tox_iterate(Tox *tox);
681 ******************************************************************************/ 743 ******************************************************************************/
682 744
683 745
746
684/** 747/**
685 * Writes the Tox friend address of the client to a byte array. The address is 748 * Writes the Tox friend address of the client to a byte array. The address is
686 * not in human-readable format. If a client wants to display the address, 749 * not in human-readable format. If a client wants to display the address,
@@ -692,7 +755,6 @@ void tox_iterate(Tox *tox);
692 */ 755 */
693void tox_self_get_address(const Tox *tox, uint8_t *address); 756void tox_self_get_address(const Tox *tox, uint8_t *address);
694 757
695
696/** 758/**
697 * Set the 4-byte nospam part of the address. 759 * Set the 4-byte nospam part of the address.
698 * 760 *
@@ -706,7 +768,7 @@ void tox_self_set_nospam(Tox *tox, uint32_t nospam);
706uint32_t tox_self_get_nospam(const Tox *tox); 768uint32_t tox_self_get_nospam(const Tox *tox);
707 769
708/** 770/**
709 * Copy the Tox Public Key (long term public key) from the Tox object. 771 * Copy the Tox Public Key (long term) from the Tox object.
710 * 772 *
711 * @param public_key A memory region of at least TOX_PUBLIC_KEY_SIZE bytes. If 773 * @param public_key A memory region of at least TOX_PUBLIC_KEY_SIZE bytes. If
712 * this parameter is NULL, this function has no effect. 774 * this parameter is NULL, this function has no effect.
@@ -714,7 +776,7 @@ uint32_t tox_self_get_nospam(const Tox *tox);
714void tox_self_get_public_key(const Tox *tox, uint8_t *public_key); 776void tox_self_get_public_key(const Tox *tox, uint8_t *public_key);
715 777
716/** 778/**
717 * Copy the secret key from the Tox object. 779 * Copy the Tox Secret Key from the Tox object.
718 * 780 *
719 * @param secret_key A memory region of at least TOX_SECRET_KEY_SIZE bytes. If 781 * @param secret_key A memory region of at least TOX_SECRET_KEY_SIZE bytes. If
720 * this parameter is NULL, this function has no effect. 782 * this parameter is NULL, this function has no effect.
@@ -729,17 +791,28 @@ void tox_self_get_secret_key(const Tox *tox, uint8_t *secret_key);
729 ******************************************************************************/ 791 ******************************************************************************/
730 792
731 793
794
732/** 795/**
733 * Common error codes for all functions that set a piece of user-visible 796 * Common error codes for all functions that set a piece of user-visible
734 * client information. 797 * client information.
735 */ 798 */
736typedef enum TOX_ERR_SET_INFO { 799typedef enum TOX_ERR_SET_INFO {
800
801 /**
802 * The function returned successfully.
803 */
737 TOX_ERR_SET_INFO_OK, 804 TOX_ERR_SET_INFO_OK,
805
806 /**
807 * One of the arguments to the function was NULL when it was not expected.
808 */
738 TOX_ERR_SET_INFO_NULL, 809 TOX_ERR_SET_INFO_NULL,
810
739 /** 811 /**
740 * Information length exceeded maximum permissible size. 812 * Information length exceeded maximum permissible size.
741 */ 813 */
742 TOX_ERR_SET_INFO_TOO_LONG 814 TOX_ERR_SET_INFO_TOO_LONG,
815
743} TOX_ERR_SET_INFO; 816} TOX_ERR_SET_INFO;
744 817
745 818
@@ -787,11 +860,10 @@ void tox_self_get_name(const Tox *tox, uint8_t *name);
787 * length is 0, the status parameter is ignored (it can be NULL), and the 860 * length is 0, the status parameter is ignored (it can be NULL), and the
788 * user status is set back to empty. 861 * user status is set back to empty.
789 */ 862 */
790bool tox_self_set_status_message(Tox *tox, const uint8_t *status, size_t length, TOX_ERR_SET_INFO *error); 863bool tox_self_set_status_message(Tox *tox, const uint8_t *status_message, size_t length, TOX_ERR_SET_INFO *error);
791 864
792/** 865/**
793 * Return the length of the current status message as passed to 866 * Return the length of the current status message as passed to tox_self_set_status_message.
794 * tox_self_set_status_message.
795 * 867 *
796 * If no status message was set before calling this function, the status 868 * If no status message was set before calling this function, the status
797 * is empty, and this function returns 0. 869 * is empty, and this function returns 0.
@@ -806,21 +878,20 @@ size_t tox_self_get_status_message_size(const Tox *tox);
806 * If no status message was set before calling this function, the status is 878 * If no status message was set before calling this function, the status is
807 * empty, and this function has no effect. 879 * empty, and this function has no effect.
808 * 880 *
809 * Call tox_self_status_message_size to find out how much memory to allocate for 881 * Call tox_self_get_status_message_size to find out how much memory to allocate for
810 * the result. 882 * the result.
811 * 883 *
812 * @param status A valid memory location large enough to hold the status message. 884 * @param status A valid memory location large enough to hold the status message.
813 * If this parameter is NULL, the function has no effect. 885 * If this parameter is NULL, the function has no effect.
814 */ 886 */
815void tox_self_get_status_message(const Tox *tox, uint8_t *status); 887void tox_self_get_status_message(const Tox *tox, uint8_t *status_message);
816
817 888
818/** 889/**
819 * Set the client's user status. 890 * Set the client's user status.
820 * 891 *
821 * @param user_status One of the user statuses listed in the enumeration above. 892 * @param user_status One of the user statuses listed in the enumeration above.
822 */ 893 */
823void tox_self_set_status(Tox *tox, TOX_USER_STATUS user_status); 894void tox_self_set_status(Tox *tox, TOX_USER_STATUS status);
824 895
825/** 896/**
826 * Returns the client's user status. 897 * Returns the client's user status.
@@ -835,42 +906,60 @@ TOX_USER_STATUS tox_self_get_status(const Tox *tox);
835 ******************************************************************************/ 906 ******************************************************************************/
836 907
837 908
909
838typedef enum TOX_ERR_FRIEND_ADD { 910typedef enum TOX_ERR_FRIEND_ADD {
911
912 /**
913 * The function returned successfully.
914 */
839 TOX_ERR_FRIEND_ADD_OK, 915 TOX_ERR_FRIEND_ADD_OK,
916
917 /**
918 * One of the arguments to the function was NULL when it was not expected.
919 */
840 TOX_ERR_FRIEND_ADD_NULL, 920 TOX_ERR_FRIEND_ADD_NULL,
921
841 /** 922 /**
842 * The length of the friend request message exceeded 923 * The length of the friend request message exceeded
843 * TOX_MAX_FRIEND_REQUEST_LENGTH. 924 * TOX_MAX_FRIEND_REQUEST_LENGTH.
844 */ 925 */
845 TOX_ERR_FRIEND_ADD_TOO_LONG, 926 TOX_ERR_FRIEND_ADD_TOO_LONG,
927
846 /** 928 /**
847 * The friend request message was empty. This, and the TOO_LONG code will 929 * The friend request message was empty. This, and the TOO_LONG code will
848 * never be returned from tox_friend_add_norequest. 930 * never be returned from tox_friend_add_norequest.
849 */ 931 */
850 TOX_ERR_FRIEND_ADD_NO_MESSAGE, 932 TOX_ERR_FRIEND_ADD_NO_MESSAGE,
933
851 /** 934 /**
852 * The friend address belongs to the sending client. 935 * The friend address belongs to the sending client.
853 */ 936 */
854 TOX_ERR_FRIEND_ADD_OWN_KEY, 937 TOX_ERR_FRIEND_ADD_OWN_KEY,
938
855 /** 939 /**
856 * A friend request has already been sent, or the address belongs to a friend 940 * A friend request has already been sent, or the address belongs to a friend
857 * that is already on the friend list. 941 * that is already on the friend list.
858 */ 942 */
859 TOX_ERR_FRIEND_ADD_ALREADY_SENT, 943 TOX_ERR_FRIEND_ADD_ALREADY_SENT,
944
860 /** 945 /**
861 * The friend address checksum failed. 946 * The friend address checksum failed.
862 */ 947 */
863 TOX_ERR_FRIEND_ADD_BAD_CHECKSUM, 948 TOX_ERR_FRIEND_ADD_BAD_CHECKSUM,
949
864 /** 950 /**
865 * The friend was already there, but the nospam value was different. 951 * The friend was already there, but the nospam value was different.
866 */ 952 */
867 TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM, 953 TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM,
954
868 /** 955 /**
869 * A memory allocation failed when trying to increase the friend list size. 956 * A memory allocation failed when trying to increase the friend list size.
870 */ 957 */
871 TOX_ERR_FRIEND_ADD_MALLOC 958 TOX_ERR_FRIEND_ADD_MALLOC,
959
872} TOX_ERR_FRIEND_ADD; 960} TOX_ERR_FRIEND_ADD;
873 961
962
874/** 963/**
875 * Add a friend to the friend list and send a friend request. 964 * Add a friend to the friend list and send a friend request.
876 * 965 *
@@ -897,7 +986,6 @@ typedef enum TOX_ERR_FRIEND_ADD {
897uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message, size_t length, 986uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message, size_t length,
898 TOX_ERR_FRIEND_ADD *error); 987 TOX_ERR_FRIEND_ADD *error);
899 988
900
901/** 989/**
902 * Add a friend without sending a friend request. 990 * Add a friend without sending a friend request.
903 * 991 *
@@ -918,28 +1006,31 @@ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message
918 */ 1006 */
919uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_ADD *error); 1007uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_ADD *error);
920 1008
921
922typedef enum TOX_ERR_FRIEND_DELETE { 1009typedef enum TOX_ERR_FRIEND_DELETE {
1010
1011 /**
1012 * The function returned successfully.
1013 */
923 TOX_ERR_FRIEND_DELETE_OK, 1014 TOX_ERR_FRIEND_DELETE_OK,
1015
924 /** 1016 /**
925 * There was no friend with the given friend number. No friends were deleted. 1017 * There was no friend with the given friend number. No friends were deleted.
926 */ 1018 */
927 TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND 1019 TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND,
1020
928} TOX_ERR_FRIEND_DELETE; 1021} TOX_ERR_FRIEND_DELETE;
929 1022
1023
930/** 1024/**
931 * Remove a friend from the friend list. 1025 * Remove a friend from the friend list.
932 * Other friend numbers are unchanged.
933 * The friend_number can be reused by toxcore as a friend number for a new friend.
934 * 1026 *
935 * This does not notify the friend of their deletion. After calling this 1027 * This does not notify the friend of their deletion. After calling this
936 * function, this client will appear offline to the friend and no communication 1028 * function, this client will appear offline to the friend and no communication
937 * can occur between the two. 1029 * can occur between the two.
938 * 1030 *
939 * @friend_number Friend number for the friend to be deleted. 1031 * @param friend_number Friend number for the friend to be deleted.
940 * 1032 *
941 * @return true on success. 1033 * @return true on success.
942 * @see tox_friend_add for detailed description of friend numbers.
943 */ 1034 */
944bool tox_friend_delete(Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_DELETE *error); 1035bool tox_friend_delete(Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_DELETE *error);
945 1036
@@ -951,15 +1042,27 @@ bool tox_friend_delete(Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_DELETE *
951 ******************************************************************************/ 1042 ******************************************************************************/
952 1043
953 1044
1045
954typedef enum TOX_ERR_FRIEND_BY_PUBLIC_KEY { 1046typedef enum TOX_ERR_FRIEND_BY_PUBLIC_KEY {
1047
1048 /**
1049 * The function returned successfully.
1050 */
955 TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK, 1051 TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK,
1052
1053 /**
1054 * One of the arguments to the function was NULL when it was not expected.
1055 */
956 TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL, 1056 TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL,
1057
957 /** 1058 /**
958 * No friend with the given Public Key exists on the friend list. 1059 * No friend with the given Public Key exists on the friend list.
959 */ 1060 */
960 TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND 1061 TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND,
1062
961} TOX_ERR_FRIEND_BY_PUBLIC_KEY; 1063} TOX_ERR_FRIEND_BY_PUBLIC_KEY;
962 1064
1065
963/** 1066/**
964 * Return the friend number associated with that Public Key. 1067 * Return the friend number associated with that Public Key.
965 * 1068 *
@@ -968,15 +1071,45 @@ typedef enum TOX_ERR_FRIEND_BY_PUBLIC_KEY {
968 */ 1071 */
969uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_BY_PUBLIC_KEY *error); 1072uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_BY_PUBLIC_KEY *error);
970 1073
1074/**
1075 * Checks if a friend with the given friend number exists and returns true if
1076 * it does.
1077 */
1078bool tox_friend_exists(const Tox *tox, uint32_t friend_number);
1079
1080/**
1081 * Return the number of friends on the friend list.
1082 *
1083 * This function can be used to determine how much memory to allocate for
1084 * tox_self_get_friend_list.
1085 */
1086size_t tox_self_get_friend_list_size(const Tox *tox);
1087
1088/**
1089 * Copy a list of valid friend numbers into an array.
1090 *
1091 * Call tox_self_get_friend_list_size to determine the number of elements to allocate.
1092 *
1093 * @param list A memory region with enough space to hold the friend list. If
1094 * this parameter is NULL, this function has no effect.
1095 */
1096void tox_self_get_friend_list(const Tox *tox, uint32_t *friend_list);
971 1097
972typedef enum TOX_ERR_FRIEND_GET_PUBLIC_KEY { 1098typedef enum TOX_ERR_FRIEND_GET_PUBLIC_KEY {
1099
1100 /**
1101 * The function returned successfully.
1102 */
973 TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK, 1103 TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK,
1104
974 /** 1105 /**
975 * No friend with the given number exists on the friend list. 1106 * No friend with the given number exists on the friend list.
976 */ 1107 */
977 TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND 1108 TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND,
1109
978} TOX_ERR_FRIEND_GET_PUBLIC_KEY; 1110} TOX_ERR_FRIEND_GET_PUBLIC_KEY;
979 1111
1112
980/** 1113/**
981 * Copies the Public Key associated with a given friend number to a byte array. 1114 * Copies the Public Key associated with a given friend number to a byte array.
982 * 1115 *
@@ -989,21 +1122,21 @@ typedef enum TOX_ERR_FRIEND_GET_PUBLIC_KEY {
989bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *public_key, 1122bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *public_key,
990 TOX_ERR_FRIEND_GET_PUBLIC_KEY *error); 1123 TOX_ERR_FRIEND_GET_PUBLIC_KEY *error);
991 1124
992
993/**
994 * Checks if a friend with the given friend number exists and returns true if
995 * it does.
996 */
997bool tox_friend_exists(const Tox *tox, uint32_t friend_number);
998
999typedef enum TOX_ERR_FRIEND_GET_LAST_ONLINE { 1125typedef enum TOX_ERR_FRIEND_GET_LAST_ONLINE {
1126
1127 /**
1128 * The function returned successfully.
1129 */
1000 TOX_ERR_FRIEND_GET_LAST_ONLINE_OK, 1130 TOX_ERR_FRIEND_GET_LAST_ONLINE_OK,
1131
1001 /** 1132 /**
1002 * No friend with the given number exists on the friend list. 1133 * No friend with the given number exists on the friend list.
1003 */ 1134 */
1004 TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND, 1135 TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND,
1136
1005} TOX_ERR_FRIEND_GET_LAST_ONLINE; 1137} TOX_ERR_FRIEND_GET_LAST_ONLINE;
1006 1138
1139
1007/** 1140/**
1008 * Return a unix-time timestamp of the last time the friend associated with a given 1141 * Return a unix-time timestamp of the last time the friend associated with a given
1009 * friend number was seen online. This function will return UINT64_MAX on error. 1142 * friend number was seen online. This function will return UINT64_MAX on error.
@@ -1012,26 +1145,6 @@ typedef enum TOX_ERR_FRIEND_GET_LAST_ONLINE {
1012 */ 1145 */
1013uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_GET_LAST_ONLINE *error); 1146uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_GET_LAST_ONLINE *error);
1014 1147
1015/**
1016 * Return the number of friends on the friend list.
1017 *
1018 * This function can be used to determine how much memory to allocate for
1019 * tox_self_get_friend_list.
1020 */
1021size_t tox_self_get_friend_list_size(const Tox *tox);
1022
1023
1024/**
1025 * Copy a list of valid friend numbers into an array.
1026 *
1027 * Call tox_self_get_friend_list_size to determine the number of elements to allocate.
1028 *
1029 * @param list A memory region with enough space to hold the friend list. If
1030 * this parameter is NULL, this function has no effect.
1031 */
1032void tox_self_get_friend_list(const Tox *tox, uint32_t *list);
1033
1034
1035 1148
1036/******************************************************************************* 1149/*******************************************************************************
1037 * 1150 *
@@ -1040,27 +1153,35 @@ void tox_self_get_friend_list(const Tox *tox, uint32_t *list);
1040 ******************************************************************************/ 1153 ******************************************************************************/
1041 1154
1042 1155
1156
1043/** 1157/**
1044 * Common error codes for friend state query functions. 1158 * Common error codes for friend state query functions.
1045 */ 1159 */
1046typedef enum TOX_ERR_FRIEND_QUERY { 1160typedef enum TOX_ERR_FRIEND_QUERY {
1161
1162 /**
1163 * The function returned successfully.
1164 */
1047 TOX_ERR_FRIEND_QUERY_OK, 1165 TOX_ERR_FRIEND_QUERY_OK,
1166
1048 /** 1167 /**
1049 * The pointer parameter for storing the query result (name, message) was 1168 * The pointer parameter for storing the query result (name, message) was
1050 * NULL. Unlike the `_self_` variants of these functions, which have no effect 1169 * NULL. Unlike the `_self_` variants of these functions, which have no effect
1051 * when a parameter is NULL, these functions return an error in that case. 1170 * when a parameter is NULL, these functions return an error in that case.
1052 */ 1171 */
1053 TOX_ERR_FRIEND_QUERY_NULL, 1172 TOX_ERR_FRIEND_QUERY_NULL,
1173
1054 /** 1174 /**
1055 * The friend_number did not designate a valid friend. 1175 * The friend_number did not designate a valid friend.
1056 */ 1176 */
1057 TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND 1177 TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND,
1178
1058} TOX_ERR_FRIEND_QUERY; 1179} TOX_ERR_FRIEND_QUERY;
1059 1180
1060 1181
1061/** 1182/**
1062 * Return the length of the friend's name. If the friend number is invalid, the 1183 * Return the length of the friend's name. If the friend number is invalid, the
1063 * return value is SIZE_MAX. 1184 * return value is unspecified.
1064 * 1185 *
1065 * The return value is equal to the `length` argument received by the last 1186 * The return value is equal to the `length` argument received by the last
1066 * `friend_name` callback. 1187 * `friend_name` callback.
@@ -1084,8 +1205,6 @@ size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, TOX_ERR_
1084bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, TOX_ERR_FRIEND_QUERY *error); 1205bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, TOX_ERR_FRIEND_QUERY *error);
1085 1206
1086/** 1207/**
1087 * The function type for the `friend_name` callback.
1088 *
1089 * @param friend_number The friend number of the friend whose name changed. 1208 * @param friend_number The friend number of the friend whose name changed.
1090 * @param name A byte array containing the same data as 1209 * @param name A byte array containing the same data as
1091 * tox_friend_get_name would write to its `name` parameter. 1210 * tox_friend_get_name would write to its `name` parameter.
@@ -1094,13 +1213,13 @@ bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name,
1094 */ 1213 */
1095typedef void tox_friend_name_cb(Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length, void *user_data); 1214typedef void tox_friend_name_cb(Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length, void *user_data);
1096 1215
1216
1097/** 1217/**
1098 * Set the callback for the `friend_name` event. Pass NULL to unset. 1218 * Set the callback for the `friend_name` event. Pass NULL to unset.
1099 * 1219 *
1100 * This event is triggered when a friend changes their name. 1220 * This event is triggered when a friend changes their name.
1101 */ 1221 */
1102void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *function, void *user_data); 1222void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *callback, void *user_data);
1103
1104 1223
1105/** 1224/**
1106 * Return the length of the friend's status message. If the friend number is 1225 * Return the length of the friend's status message. If the friend number is
@@ -1112,37 +1231,35 @@ size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number
1112 * Write the name of the friend designated by the given friend number to a byte 1231 * Write the name of the friend designated by the given friend number to a byte
1113 * array. 1232 * array.
1114 * 1233 *
1115 * Call tox_friend_get_name_size to determine the allocation size for the `name` 1234 * Call tox_friend_get_status_message_size to determine the allocation size for the `status_name`
1116 * parameter. 1235 * parameter.
1117 * 1236 *
1118 * The data written to `message` is equal to the data received by the last 1237 * The data written to `status_message` is equal to the data received by the last
1119 * `friend_status_message` callback. 1238 * `friend_status_message` callback.
1120 * 1239 *
1121 * @param name A valid memory region large enough to store the friend's name. 1240 * @param name A valid memory region large enough to store the friend's name.
1122 */ 1241 */
1123bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8_t *message, 1242bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8_t *status_message,
1124 TOX_ERR_FRIEND_QUERY *error); 1243 TOX_ERR_FRIEND_QUERY *error);
1125 1244
1126/** 1245/**
1127 * The function type for the `friend_status_message` callback.
1128 *
1129 * @param friend_number The friend number of the friend whose status message 1246 * @param friend_number The friend number of the friend whose status message
1130 * changed. 1247 * changed.
1131 * @param message A byte array containing the same data as 1248 * @param message A byte array containing the same data as
1132 * tox_friend_get_status_message would write to its `message` parameter. 1249 * tox_friend_get_status_message would write to its `status_message` parameter.
1133 * @param length A value equal to the return value of 1250 * @param length A value equal to the return value of
1134 * tox_friend_get_status_message_size. 1251 * tox_friend_get_status_message_size.
1135 */ 1252 */
1136typedef void tox_friend_status_message_cb(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length, 1253typedef void tox_friend_status_message_cb(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length,
1137 void *user_data); 1254 void *user_data);
1255
1138 1256
1139/** 1257/**
1140 * Set the callback for the `friend_status_message` event. Pass NULL to unset. 1258 * Set the callback for the `friend_status_message` event. Pass NULL to unset.
1141 * 1259 *
1142 * This event is triggered when a friend changes their status message. 1260 * This event is triggered when a friend changes their status message.
1143 */ 1261 */
1144void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *function, void *user_data); 1262void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *callback, void *user_data);
1145
1146 1263
1147/** 1264/**
1148 * Return the friend's user status (away/busy/...). If the friend number is 1265 * Return the friend's user status (away/busy/...). If the friend number is
@@ -1154,21 +1271,19 @@ void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *
1154TOX_USER_STATUS tox_friend_get_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error); 1271TOX_USER_STATUS tox_friend_get_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
1155 1272
1156/** 1273/**
1157 * The function type for the `friend_status` callback.
1158 *
1159 * @param friend_number The friend number of the friend whose user status 1274 * @param friend_number The friend number of the friend whose user status
1160 * changed. 1275 * changed.
1161 * @param status The new user status. 1276 * @param status The new user status.
1162 */ 1277 */
1163typedef void tox_friend_status_cb(Tox *tox, uint32_t friend_number, TOX_USER_STATUS status, void *user_data); 1278typedef void tox_friend_status_cb(Tox *tox, uint32_t friend_number, TOX_USER_STATUS status, void *user_data);
1164 1279
1280
1165/** 1281/**
1166 * Set the callback for the `friend_status` event. Pass NULL to unset. 1282 * Set the callback for the `friend_status` event. Pass NULL to unset.
1167 * 1283 *
1168 * This event is triggered when a friend changes their user status. 1284 * This event is triggered when a friend changes their user status.
1169 */ 1285 */
1170void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *function, void *user_data); 1286void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *callback, void *user_data);
1171
1172 1287
1173/** 1288/**
1174 * Check whether a friend is currently connected to this client. 1289 * Check whether a friend is currently connected to this client.
@@ -1185,28 +1300,25 @@ void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *function, void *
1185TOX_CONNECTION tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error); 1300TOX_CONNECTION tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
1186 1301
1187/** 1302/**
1188 * The function type for the `friend_connection_status` callback.
1189 *
1190 * @param friend_number The friend number of the friend whose connection status 1303 * @param friend_number The friend number of the friend whose connection status
1191 * changed. 1304 * changed.
1192 * @param connection_status The result of calling 1305 * @param connection_status The result of calling
1193 * tox_friend_get_connection_status on the passed friend_number. 1306 * tox_friend_get_connection_status on the passed friend_number.
1194 */ 1307 */
1195typedef void tox_friend_connection_status_cb(Tox *tox, uint32_t friend_number, TOX_CONNECTION connection_status, 1308typedef void tox_friend_connection_status_cb(Tox *tox, uint32_t friend_number, TOX_CONNECTION connection_status,
1196 void *user_data); 1309 void *user_data);
1310
1197 1311
1198/** 1312/**
1199 * Set the callback for the `friend_connection_status` event. Pass NULL to 1313 * Set the callback for the `friend_connection_status` event. Pass NULL to unset.
1200 * unset.
1201 * 1314 *
1202 * This event is triggered when a friend goes offline after having been online, 1315 * This event is triggered when a friend goes offline after having been online,
1203 * or when a friend goes online. 1316 * or when a friend goes online.
1204 * 1317 *
1205 * This callback is not called when adding friends. It is assumed that when 1318 * This callback is not called when adding friends. It is assumed that when
1206 * adding friends, their connection status is offline. 1319 * adding friends, their connection status is initially offline.
1207 */ 1320 */
1208void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_status_cb *function, void *user_data); 1321void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_status_cb *callback, void *user_data);
1209
1210 1322
1211/** 1323/**
1212 * Check whether a friend is currently typing a message. 1324 * Check whether a friend is currently typing a message.
@@ -1220,8 +1332,6 @@ void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_statu
1220bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error); 1332bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
1221 1333
1222/** 1334/**
1223 * The function type for the `friend_typing` callback.
1224 *
1225 * @param friend_number The friend number of the friend who started or stopped 1335 * @param friend_number The friend number of the friend who started or stopped
1226 * typing. 1336 * typing.
1227 * @param is_typing The result of calling tox_friend_get_typing on the passed 1337 * @param is_typing The result of calling tox_friend_get_typing on the passed
@@ -1229,12 +1339,13 @@ bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEN
1229 */ 1339 */
1230typedef void tox_friend_typing_cb(Tox *tox, uint32_t friend_number, bool is_typing, void *user_data); 1340typedef void tox_friend_typing_cb(Tox *tox, uint32_t friend_number, bool is_typing, void *user_data);
1231 1341
1342
1232/** 1343/**
1233 * Set the callback for the `friend_typing` event. Pass NULL to unset. 1344 * Set the callback for the `friend_typing` event. Pass NULL to unset.
1234 * 1345 *
1235 * This event is triggered when a friend starts or stops typing. 1346 * This event is triggered when a friend starts or stops typing.
1236 */ 1347 */
1237void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *function, void *user_data); 1348void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *callback, void *user_data);
1238 1349
1239 1350
1240/******************************************************************************* 1351/*******************************************************************************
@@ -1244,90 +1355,115 @@ void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *function, void *
1244 ******************************************************************************/ 1355 ******************************************************************************/
1245 1356
1246 1357
1358
1247typedef enum TOX_ERR_SET_TYPING { 1359typedef enum TOX_ERR_SET_TYPING {
1360
1361 /**
1362 * The function returned successfully.
1363 */
1248 TOX_ERR_SET_TYPING_OK, 1364 TOX_ERR_SET_TYPING_OK,
1365
1249 /** 1366 /**
1250 * The friend number did not designate a valid friend. 1367 * The friend number did not designate a valid friend.
1251 */ 1368 */
1252 TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND 1369 TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND,
1370
1253} TOX_ERR_SET_TYPING; 1371} TOX_ERR_SET_TYPING;
1254 1372
1373
1255/** 1374/**
1256 * Set the client's typing status for a friend. 1375 * Set the client's typing status for a friend.
1257 * 1376 *
1258 * The client is responsible for turning it on or off. 1377 * The client is responsible for turning it on or off.
1259 * 1378 *
1260 * @param friend_number The friend to which the client is typing a message. 1379 * @param friend_number The friend to which the client is typing a message.
1261 * @param is_typing The typing status. True means the client is typing. 1380 * @param typing The typing status. True means the client is typing.
1262 * 1381 *
1263 * @return true on success. 1382 * @return true on success.
1264 */ 1383 */
1265bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool is_typing, TOX_ERR_SET_TYPING *error); 1384bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool typing, TOX_ERR_SET_TYPING *error);
1266
1267 1385
1268typedef enum TOX_ERR_FRIEND_SEND_MESSAGE { 1386typedef enum TOX_ERR_FRIEND_SEND_MESSAGE {
1387
1388 /**
1389 * The function returned successfully.
1390 */
1269 TOX_ERR_FRIEND_SEND_MESSAGE_OK, 1391 TOX_ERR_FRIEND_SEND_MESSAGE_OK,
1392
1393 /**
1394 * One of the arguments to the function was NULL when it was not expected.
1395 */
1270 TOX_ERR_FRIEND_SEND_MESSAGE_NULL, 1396 TOX_ERR_FRIEND_SEND_MESSAGE_NULL,
1397
1271 /** 1398 /**
1272 * The friend number did not designate a valid friend. 1399 * The friend number did not designate a valid friend.
1273 */ 1400 */
1274 TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND, 1401 TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND,
1402
1275 /** 1403 /**
1276 * This client is currently not connected to the friend. 1404 * This client is currently not connected to the friend.
1277 */ 1405 */
1278 TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED, 1406 TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED,
1407
1279 /** 1408 /**
1280 * An allocation error occurred while increasing the send queue size. 1409 * An allocation error occurred while increasing the send queue size.
1281 */ 1410 */
1282 TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ, 1411 TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ,
1412
1283 /** 1413 /**
1284 * Message length exceeded TOX_MAX_MESSAGE_LENGTH. 1414 * Message length exceeded TOX_MAX_MESSAGE_LENGTH.
1285 */ 1415 */
1286 TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG, 1416 TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG,
1417
1287 /** 1418 /**
1288 * Attempted to send a zero-length message. 1419 * Attempted to send a zero-length message.
1289 */ 1420 */
1290 TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY 1421 TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY,
1422
1291} TOX_ERR_FRIEND_SEND_MESSAGE; 1423} TOX_ERR_FRIEND_SEND_MESSAGE;
1292 1424
1425
1293/** 1426/**
1294 * Send a text chat message to an online friend. 1427 * Send a text chat message to an online friend.
1295 * 1428 *
1296 * This function creates a chat message packet and pushes it into the send 1429 * This function creates a chat message packet and pushes it into the send
1297 * queue. 1430 * queue.
1298 * 1431 *
1299 * Type corresponds to the message type, for a list of valid types see TOX_MESSAGE_TYPE.
1300 *
1301 * The message length may not exceed TOX_MAX_MESSAGE_LENGTH. Larger messages 1432 * The message length may not exceed TOX_MAX_MESSAGE_LENGTH. Larger messages
1302 * must be split by the client and sent as separate messages. Other clients can 1433 * must be split by the client and sent as separate messages. Other clients can
1303 * then reassemble the fragments. Messages may not be empty. 1434 * then reassemble the fragments. Messages may not be empty.
1304 * 1435 *
1305 * The return value of this function is the message ID. If a read receipt is 1436 * The return value of this function is the message ID. If a read receipt is
1306 * received, the triggered `read_receipt` event will be passed this message ID. 1437 * received, the triggered `friend_read_receipt` event will be passed this message ID.
1307 * 1438 *
1308 * Message IDs are unique per friend. The first message ID is 0. Message IDs are 1439 * Message IDs are unique per friend. The first message ID is 0. Message IDs are
1309 * incremented by 1 each time a message is sent. If UINT32_MAX messages were 1440 * incremented by 1 each time a message is sent. If UINT32_MAX messages were
1310 * sent, the next message ID is 0. 1441 * sent, the next message ID is 0.
1442 *
1443 * @param type Message type (normal, action, ...).
1444 * @param friend_number The friend number of the friend to send the message to.
1445 * @param message A non-NULL pointer to the first element of a byte array
1446 * containing the message text.
1447 * @param length Length of the message to be sent.
1311 */ 1448 */
1312uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message, 1449uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message,
1313 size_t length, TOX_ERR_FRIEND_SEND_MESSAGE *error); 1450 size_t length, TOX_ERR_FRIEND_SEND_MESSAGE *error);
1314 1451
1315/** 1452/**
1316 * The function type for the `read_receipt` callback.
1317 *
1318 * @param friend_number The friend number of the friend who received the message. 1453 * @param friend_number The friend number of the friend who received the message.
1319 * @param message_id The message ID as returned from tox_friend_send_message 1454 * @param message_id The message ID as returned from tox_friend_send_message
1320 * corresponding to the message sent. 1455 * corresponding to the message sent.
1321 */ 1456 */
1322typedef void tox_friend_read_receipt_cb(Tox *tox, uint32_t friend_number, uint32_t message_id, void *user_data); 1457typedef void tox_friend_read_receipt_cb(Tox *tox, uint32_t friend_number, uint32_t message_id, void *user_data);
1323 1458
1459
1324/** 1460/**
1325 * Set the callback for the `read_receipt` event. Pass NULL to unset. 1461 * Set the callback for the `friend_read_receipt` event. Pass NULL to unset.
1326 * 1462 *
1327 * This event is triggered when the friend receives the message sent with 1463 * This event is triggered when the friend receives the message sent with
1328 * tox_friend_send_message with the corresponding message ID. 1464 * tox_friend_send_message with the corresponding message ID.
1329 */ 1465 */
1330void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *function, void *user_data); 1466void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *callback, void *user_data);
1331 1467
1332 1468
1333/******************************************************************************* 1469/*******************************************************************************
@@ -1337,41 +1473,46 @@ void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *func
1337 ******************************************************************************/ 1473 ******************************************************************************/
1338 1474
1339 1475
1476
1340/** 1477/**
1341 * The function type for the `friend_request` callback.
1342 *
1343 * @param public_key The Public Key of the user who sent the friend request. 1478 * @param public_key The Public Key of the user who sent the friend request.
1479 * @param time_delta A delta in seconds between when the message was composed
1480 * and when it is being transmitted. For messages that are sent immediately,
1481 * it will be 0. If a message was written and couldn't be sent immediately
1482 * (due to a connection failure, for example), the time_delta is an
1483 * approximation of when it was composed.
1344 * @param message The message they sent along with the request. 1484 * @param message The message they sent along with the request.
1345 * @param length The size of the message byte array. 1485 * @param length The size of the message byte array.
1346 */ 1486 */
1347typedef void tox_friend_request_cb(Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length, 1487typedef void tox_friend_request_cb(Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length,
1348 void *user_data); 1488 void *user_data);
1349 1489
1490
1350/** 1491/**
1351 * Set the callback for the `friend_request` event. Pass NULL to unset. 1492 * Set the callback for the `friend_request` event. Pass NULL to unset.
1352 * 1493 *
1353 * This event is triggered when a friend request is received. 1494 * This event is triggered when a friend request is received.
1354 */ 1495 */
1355void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *function, void *user_data); 1496void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *callback, void *user_data);
1356
1357 1497
1358/** 1498/**
1359 * The function type for the `friend_message` callback.
1360 *
1361 * @param friend_number The friend number of the friend who sent the message. 1499 * @param friend_number The friend number of the friend who sent the message.
1362 * @param type The message type, for a list of valid types see TOX_MESSAGE_TYPE. 1500 * @param time_delta Time between composition and sending.
1363 * @param message The message data they sent. 1501 * @param message The message data they sent.
1364 * @param length The size of the message byte array. 1502 * @param length The size of the message byte array.
1503 *
1504 * @see friend_request for more information on time_delta.
1365 */ 1505 */
1366typedef void tox_friend_message_cb(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message, 1506typedef void tox_friend_message_cb(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message,
1367 size_t length, void *user_data); 1507 size_t length, void *user_data);
1368 1508
1509
1369/** 1510/**
1370 * Set the callback for the `friend_message` event. Pass NULL to unset. 1511 * Set the callback for the `friend_message` event. Pass NULL to unset.
1371 * 1512 *
1372 * This event is triggered when a message from a friend is received. 1513 * This event is triggered when a message from a friend is received.
1373 */ 1514 */
1374void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *function, void *user_data); 1515void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *callback, void *user_data);
1375 1516
1376 1517
1377/******************************************************************************* 1518/*******************************************************************************
@@ -1381,12 +1522,36 @@ void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *function, void
1381 ******************************************************************************/ 1522 ******************************************************************************/
1382 1523
1383 1524
1525
1526/**
1527 * Generates a cryptographic hash of the given data.
1528 *
1529 * This function may be used by clients for any purpose, but is provided
1530 * primarily for validating cached avatars. This use is highly recommended to
1531 * avoid unnecessary avatar updates.
1532 *
1533 * If hash is NULL or data is NULL while length is not 0 the function returns false,
1534 * otherwise it returns true.
1535 *
1536 * This function is a wrapper to internal message-digest functions.
1537 *
1538 * @param hash A valid memory location the hash data. It must be at least
1539 * TOX_HASH_LENGTH bytes in size.
1540 * @param data Data to be hashed or NULL.
1541 * @param length Size of the data array or 0.
1542 *
1543 * @return true if hash was not NULL.
1544 */
1545bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length);
1546
1384enum TOX_FILE_KIND { 1547enum TOX_FILE_KIND {
1548
1385 /** 1549 /**
1386 * Arbitrary file data. Clients can choose to handle it based on the file name 1550 * Arbitrary file data. Clients can choose to handle it based on the file name
1387 * or magic or any other way they choose. 1551 * or magic or any other way they choose.
1388 */ 1552 */
1389 TOX_FILE_KIND_DATA, 1553 TOX_FILE_KIND_DATA,
1554
1390 /** 1555 /**
1391 * Avatar filename. This consists of tox_hash(image). 1556 * Avatar filename. This consists of tox_hash(image).
1392 * Avatar data. This consists of the image data. 1557 * Avatar data. This consists of the image data.
@@ -1404,41 +1569,22 @@ enum TOX_FILE_KIND {
1404 * this hash with a saved hash and send TOX_FILE_CONTROL_CANCEL to terminate the avatar 1569 * this hash with a saved hash and send TOX_FILE_CONTROL_CANCEL to terminate the avatar
1405 * transfer if it matches. 1570 * transfer if it matches.
1406 * 1571 *
1407 * When file_size is set to 0 in the transfer request it means that the client has no 1572 * When file_size is set to 0 in the transfer request it means that the client
1408 * avatar. 1573 * has no avatar.
1409 */ 1574 */
1410 TOX_FILE_KIND_AVATAR 1575 TOX_FILE_KIND_AVATAR,
1411};
1412
1413 1576
1414/** 1577};
1415 * Generates a cryptographic hash of the given data.
1416 *
1417 * This function may be used by clients for any purpose, but is provided
1418 * primarily for validating cached avatars. This use is highly recommended to
1419 * avoid unnecessary avatar updates.
1420 *
1421 * If hash is NULL or data is NULL while length is not 0 the function returns false,
1422 * otherwise it returns true.
1423 *
1424 * This function is a wrapper to internal message-digest functions.
1425 *
1426 * @param hash A valid memory location the hash data. It must be at least
1427 * TOX_HASH_LENGTH bytes in size.
1428 * @param data Data to be hashed or NULL.
1429 * @param length Size of the data array or 0.
1430 *
1431 * @return true if hash was not NULL.
1432 */
1433bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length);
1434 1578
1435 1579
1436typedef enum TOX_FILE_CONTROL { 1580typedef enum TOX_FILE_CONTROL {
1581
1437 /** 1582 /**
1438 * Sent by the receiving side to accept a file send request. Also sent after a 1583 * Sent by the receiving side to accept a file send request. Also sent after a
1439 * TOX_FILE_CONTROL_PAUSE command to continue sending or receiving. 1584 * TOX_FILE_CONTROL_PAUSE command to continue sending or receiving.
1440 */ 1585 */
1441 TOX_FILE_CONTROL_RESUME, 1586 TOX_FILE_CONTROL_RESUME,
1587
1442 /** 1588 /**
1443 * Sent by clients to pause the file transfer. The initial state of a file 1589 * Sent by clients to pause the file transfer. The initial state of a file
1444 * transfer is always paused on the receiving side and running on the sending 1590 * transfer is always paused on the receiving side and running on the sending
@@ -1446,47 +1592,62 @@ typedef enum TOX_FILE_CONTROL {
1446 * need to send TOX_FILE_CONTROL_RESUME for the transfer to resume. 1592 * need to send TOX_FILE_CONTROL_RESUME for the transfer to resume.
1447 */ 1593 */
1448 TOX_FILE_CONTROL_PAUSE, 1594 TOX_FILE_CONTROL_PAUSE,
1595
1449 /** 1596 /**
1450 * Sent by the receiving side to reject a file send request before any other 1597 * Sent by the receiving side to reject a file send request before any other
1451 * commands are sent. Also sent by either side to terminate a file transfer. 1598 * commands are sent. Also sent by either side to terminate a file transfer.
1452 */ 1599 */
1453 TOX_FILE_CONTROL_CANCEL 1600 TOX_FILE_CONTROL_CANCEL,
1601
1454} TOX_FILE_CONTROL; 1602} TOX_FILE_CONTROL;
1455 1603
1456 1604
1457typedef enum TOX_ERR_FILE_CONTROL { 1605typedef enum TOX_ERR_FILE_CONTROL {
1606
1607 /**
1608 * The function returned successfully.
1609 */
1458 TOX_ERR_FILE_CONTROL_OK, 1610 TOX_ERR_FILE_CONTROL_OK,
1611
1459 /** 1612 /**
1460 * The friend_number passed did not designate a valid friend. 1613 * The friend_number passed did not designate a valid friend.
1461 */ 1614 */
1462 TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND, 1615 TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND,
1616
1463 /** 1617 /**
1464 * This client is currently not connected to the friend. 1618 * This client is currently not connected to the friend.
1465 */ 1619 */
1466 TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED, 1620 TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED,
1621
1467 /** 1622 /**
1468 * No file transfer with the given file number was found for the given friend. 1623 * No file transfer with the given file number was found for the given friend.
1469 */ 1624 */
1470 TOX_ERR_FILE_CONTROL_NOT_FOUND, 1625 TOX_ERR_FILE_CONTROL_NOT_FOUND,
1626
1471 /** 1627 /**
1472 * A RESUME control was sent, but the file transfer is running normally. 1628 * A RESUME control was sent, but the file transfer is running normally.
1473 */ 1629 */
1474 TOX_ERR_FILE_CONTROL_NOT_PAUSED, 1630 TOX_ERR_FILE_CONTROL_NOT_PAUSED,
1631
1475 /** 1632 /**
1476 * A RESUME control was sent, but the file transfer was paused by the other 1633 * A RESUME control was sent, but the file transfer was paused by the other
1477 * party. Only the party that paused the transfer can resume it. 1634 * party. Only the party that paused the transfer can resume it.
1478 */ 1635 */
1479 TOX_ERR_FILE_CONTROL_DENIED, 1636 TOX_ERR_FILE_CONTROL_DENIED,
1637
1480 /** 1638 /**
1481 * A PAUSE control was sent, but the file transfer was already paused. 1639 * A PAUSE control was sent, but the file transfer was already paused.
1482 */ 1640 */
1483 TOX_ERR_FILE_CONTROL_ALREADY_PAUSED, 1641 TOX_ERR_FILE_CONTROL_ALREADY_PAUSED,
1642
1484 /** 1643 /**
1485 * Packet queue is full. 1644 * Packet queue is full.
1486 */ 1645 */
1487 TOX_ERR_FILE_CONTROL_SENDQ 1646 TOX_ERR_FILE_CONTROL_SENDQ,
1647
1488} TOX_ERR_FILE_CONTROL; 1648} TOX_ERR_FILE_CONTROL;
1489 1649
1650
1490/** 1651/**
1491 * Sends a file control command to a friend for a given file transfer. 1652 * Sends a file control command to a friend for a given file transfer.
1492 * 1653 *
@@ -1500,10 +1661,7 @@ typedef enum TOX_ERR_FILE_CONTROL {
1500bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control, 1661bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control,
1501 TOX_ERR_FILE_CONTROL *error); 1662 TOX_ERR_FILE_CONTROL *error);
1502 1663
1503
1504/** 1664/**
1505 * The function type for the `file_control` callback.
1506 *
1507 * When receiving TOX_FILE_CONTROL_CANCEL, the client should release the 1665 * When receiving TOX_FILE_CONTROL_CANCEL, the client should release the
1508 * resources associated with the file number and consider the transfer failed. 1666 * resources associated with the file number and consider the transfer failed.
1509 * 1667 *
@@ -1515,43 +1673,55 @@ bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TO
1515typedef void tox_file_recv_control_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control, 1673typedef void tox_file_recv_control_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control,
1516 void *user_data); 1674 void *user_data);
1517 1675
1676
1518/** 1677/**
1519 * Set the callback for the `file_control` event. Pass NULL to unset. 1678 * Set the callback for the `file_recv_control` event. Pass NULL to unset.
1520 * 1679 *
1521 * This event is triggered when a file control command is received from a 1680 * This event is triggered when a file control command is received from a
1522 * friend. 1681 * friend.
1523 */ 1682 */
1524void tox_callback_file_recv_control(Tox *tox, tox_file_recv_control_cb *function, void *user_data); 1683void tox_callback_file_recv_control(Tox *tox, tox_file_recv_control_cb *callback, void *user_data);
1525
1526 1684
1527typedef enum TOX_ERR_FILE_SEEK { 1685typedef enum TOX_ERR_FILE_SEEK {
1686
1687 /**
1688 * The function returned successfully.
1689 */
1528 TOX_ERR_FILE_SEEK_OK, 1690 TOX_ERR_FILE_SEEK_OK,
1691
1529 /** 1692 /**
1530 * The friend_number passed did not designate a valid friend. 1693 * The friend_number passed did not designate a valid friend.
1531 */ 1694 */
1532 TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND, 1695 TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND,
1696
1533 /** 1697 /**
1534 * This client is currently not connected to the friend. 1698 * This client is currently not connected to the friend.
1535 */ 1699 */
1536 TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED, 1700 TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED,
1701
1537 /** 1702 /**
1538 * No file transfer with the given file number was found for the given friend. 1703 * No file transfer with the given file number was found for the given friend.
1539 */ 1704 */
1540 TOX_ERR_FILE_SEEK_NOT_FOUND, 1705 TOX_ERR_FILE_SEEK_NOT_FOUND,
1706
1541 /** 1707 /**
1542 * File was not in a state where it could be seeked. 1708 * File was not in a state where it could be seeked.
1543 */ 1709 */
1544 TOX_ERR_FILE_SEEK_DENIED, 1710 TOX_ERR_FILE_SEEK_DENIED,
1711
1545 /** 1712 /**
1546 * Seek position was invalid 1713 * Seek position was invalid
1547 */ 1714 */
1548 TOX_ERR_FILE_SEEK_INVALID_POSITION, 1715 TOX_ERR_FILE_SEEK_INVALID_POSITION,
1716
1549 /** 1717 /**
1550 * Packet queue is full. 1718 * Packet queue is full.
1551 */ 1719 */
1552 TOX_ERR_FILE_SEEK_SENDQ 1720 TOX_ERR_FILE_SEEK_SENDQ,
1721
1553} TOX_ERR_FILE_SEEK; 1722} TOX_ERR_FILE_SEEK;
1554 1723
1724
1555/** 1725/**
1556 * Sends a file seek control command to a friend for a given file transfer. 1726 * Sends a file seek control command to a friend for a given file transfer.
1557 * 1727 *
@@ -1563,26 +1733,33 @@ typedef enum TOX_ERR_FILE_SEEK {
1563 * @param file_number The friend-specific identifier for the file transfer. 1733 * @param file_number The friend-specific identifier for the file transfer.
1564 * @param position The position that the file should be seeked to. 1734 * @param position The position that the file should be seeked to.
1565 */ 1735 */
1566bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, 1736bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, TOX_ERR_FILE_SEEK *error);
1567 TOX_ERR_FILE_SEEK *error);
1568 1737
1569typedef enum TOX_ERR_FILE_GET { 1738typedef enum TOX_ERR_FILE_GET {
1739
1740 /**
1741 * The function returned successfully.
1742 */
1570 TOX_ERR_FILE_GET_OK, 1743 TOX_ERR_FILE_GET_OK,
1744
1571 /** 1745 /**
1572 * The friend_number passed did not designate a valid friend. 1746 * The friend_number passed did not designate a valid friend.
1573 */ 1747 */
1574 TOX_ERR_FILE_GET_FRIEND_NOT_FOUND, 1748 TOX_ERR_FILE_GET_FRIEND_NOT_FOUND,
1749
1575 /** 1750 /**
1576 * No file transfer with the given file number was found for the given friend. 1751 * No file transfer with the given file number was found for the given friend.
1577 */ 1752 */
1578 TOX_ERR_FILE_GET_NOT_FOUND 1753 TOX_ERR_FILE_GET_NOT_FOUND,
1754
1579} TOX_ERR_FILE_GET; 1755} TOX_ERR_FILE_GET;
1580 1756
1757
1581/** 1758/**
1582 * Copy the file id associated to the file transfer to a byte array. 1759 * Copy the file id associated to the file transfer to a byte array.
1583 * 1760 *
1584 * @param friend_number The friend number of the friend the file is being 1761 * @param friend_number The friend number of the friend the file is being
1585 * transferred to. 1762 * transferred to or received from.
1586 * @param file_number The friend-specific identifier for the file transfer. 1763 * @param file_number The friend-specific identifier for the file transfer.
1587 * @param file_id A memory region of at least TOX_FILE_ID_LENGTH bytes. If 1764 * @param file_id A memory region of at least TOX_FILE_ID_LENGTH bytes. If
1588 * this parameter is NULL, this function has no effect. 1765 * this parameter is NULL, this function has no effect.
@@ -1592,6 +1769,7 @@ typedef enum TOX_ERR_FILE_GET {
1592bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_number, uint8_t *file_id, 1769bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_number, uint8_t *file_id,
1593 TOX_ERR_FILE_GET *error); 1770 TOX_ERR_FILE_GET *error);
1594 1771
1772
1595/******************************************************************************* 1773/*******************************************************************************
1596 * 1774 *
1597 * :: File transmission: sending 1775 * :: File transmission: sending
@@ -1599,36 +1777,51 @@ bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_
1599 ******************************************************************************/ 1777 ******************************************************************************/
1600 1778
1601 1779
1780
1602typedef enum TOX_ERR_FILE_SEND { 1781typedef enum TOX_ERR_FILE_SEND {
1782
1783 /**
1784 * The function returned successfully.
1785 */
1603 TOX_ERR_FILE_SEND_OK, 1786 TOX_ERR_FILE_SEND_OK,
1787
1788 /**
1789 * One of the arguments to the function was NULL when it was not expected.
1790 */
1604 TOX_ERR_FILE_SEND_NULL, 1791 TOX_ERR_FILE_SEND_NULL,
1792
1605 /** 1793 /**
1606 * The friend_number passed did not designate a valid friend. 1794 * The friend_number passed did not designate a valid friend.
1607 */ 1795 */
1608 TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND, 1796 TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND,
1797
1609 /** 1798 /**
1610 * This client is currently not connected to the friend. 1799 * This client is currently not connected to the friend.
1611 */ 1800 */
1612 TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED, 1801 TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED,
1802
1613 /** 1803 /**
1614 * Filename length exceeded TOX_MAX_FILENAME_LENGTH bytes. 1804 * Filename length exceeded TOX_MAX_FILENAME_LENGTH bytes.
1615 */ 1805 */
1616 TOX_ERR_FILE_SEND_NAME_TOO_LONG, 1806 TOX_ERR_FILE_SEND_NAME_TOO_LONG,
1807
1617 /** 1808 /**
1618 * Too many ongoing transfers. The maximum number of concurrent file transfers 1809 * Too many ongoing transfers. The maximum number of concurrent file transfers
1619 * is 256 per friend per direction (sending and receiving). 1810 * is 256 per friend per direction (sending and receiving).
1620 */ 1811 */
1621 TOX_ERR_FILE_SEND_TOO_MANY 1812 TOX_ERR_FILE_SEND_TOO_MANY,
1813
1622} TOX_ERR_FILE_SEND; 1814} TOX_ERR_FILE_SEND;
1623 1815
1816
1624/** 1817/**
1625 * Send a file transmission request. 1818 * Send a file transmission request.
1626 * 1819 *
1627 * Maximum filename length is TOX_MAX_FILENAME_LENGTH bytes. The filename should generally just be 1820 * Maximum filename length is TOX_MAX_FILENAME_LENGTH bytes. The filename
1628 * a file name, not a path with directory names. 1821 * should generally just be a file name, not a path with directory names.
1629 * 1822 *
1630 * If a non-zero file size is provided, this can be used by both sides to 1823 * If a non-UINT64_MAX file size is provided, it can be used by both sides to
1631 * determine the sending progress. File size can be set to zero for streaming 1824 * determine the sending progress. File size can be set to UINT64_MAX for streaming
1632 * data of unknown size. 1825 * data of unknown size.
1633 * 1826 *
1634 * File transmission occurs in chunks, which are requested through the 1827 * File transmission occurs in chunks, which are requested through the
@@ -1642,13 +1835,14 @@ typedef enum TOX_ERR_FILE_SEND {
1642 * was modified and how the client determines the file size. 1835 * was modified and how the client determines the file size.
1643 * 1836 *
1644 * - If the file size was increased 1837 * - If the file size was increased
1645 * - and sending mode was streaming (file_size = UINT64_MAX), the behaviour will be as 1838 * - and sending mode was streaming (file_size = UINT64_MAX), the behaviour
1646 * expected. 1839 * will be as expected.
1647 * - and sending mode was file (file_size != UINT64_MAX), the file_chunk_request 1840 * - and sending mode was file (file_size != UINT64_MAX), the
1648 * callback will receive length = 0 when Core thinks the file transfer has 1841 * file_chunk_request callback will receive length = 0 when Core thinks
1649 * finished. If the client remembers the file size as it was when sending 1842 * the file transfer has finished. If the client remembers the file size as
1650 * the request, it will terminate the transfer normally. If the client 1843 * it was when sending the request, it will terminate the transfer normally.
1651 * re-reads the size, it will think the friend cancelled the transfer. 1844 * If the client re-reads the size, it will think the friend cancelled the
1845 * transfer.
1652 * - If the file size was decreased 1846 * - If the file size was decreased
1653 * - and sending mode was streaming, the behaviour is as expected. 1847 * - and sending mode was streaming, the behaviour is as expected.
1654 * - and sending mode was file, the callback will return 0 at the new 1848 * - and sending mode was file, the callback will return 0 at the new
@@ -1676,52 +1870,65 @@ typedef enum TOX_ERR_FILE_SEND {
1676 * 1870 *
1677 * @return A file number used as an identifier in subsequent callbacks. This 1871 * @return A file number used as an identifier in subsequent callbacks. This
1678 * number is per friend. File numbers are reused after a transfer terminates. 1872 * number is per friend. File numbers are reused after a transfer terminates.
1679 * on failure, this function returns UINT32_MAX. Any pattern in file numbers 1873 * On failure, this function returns UINT32_MAX. Any pattern in file numbers
1680 * should not be relied on. 1874 * should not be relied on.
1681 */ 1875 */
1682uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t *file_id, 1876uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t *file_id,
1683 const uint8_t *filename, size_t filename_length, TOX_ERR_FILE_SEND *error); 1877 const uint8_t *filename, size_t filename_length, TOX_ERR_FILE_SEND *error);
1684 1878
1685
1686typedef enum TOX_ERR_FILE_SEND_CHUNK { 1879typedef enum TOX_ERR_FILE_SEND_CHUNK {
1880
1881 /**
1882 * The function returned successfully.
1883 */
1687 TOX_ERR_FILE_SEND_CHUNK_OK, 1884 TOX_ERR_FILE_SEND_CHUNK_OK,
1885
1688 /** 1886 /**
1689 * The length parameter was non-zero, but data was NULL. 1887 * The length parameter was non-zero, but data was NULL.
1690 */ 1888 */
1691 TOX_ERR_FILE_SEND_CHUNK_NULL, 1889 TOX_ERR_FILE_SEND_CHUNK_NULL,
1890
1692 /** 1891 /**
1693 * The friend_number passed did not designate a valid friend. 1892 * The friend_number passed did not designate a valid friend.
1694 */ 1893 */
1695 TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND, 1894 TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND,
1895
1696 /** 1896 /**
1697 * This client is currently not connected to the friend. 1897 * This client is currently not connected to the friend.
1698 */ 1898 */
1699 TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED, 1899 TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED,
1900
1700 /** 1901 /**
1701 * No file transfer with the given file number was found for the given friend. 1902 * No file transfer with the given file number was found for the given friend.
1702 */ 1903 */
1703 TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND, 1904 TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND,
1905
1704 /** 1906 /**
1705 * File transfer was found but isn't in a transferring state: (paused, done, 1907 * File transfer was found but isn't in a transferring state: (paused, done,
1706 * broken, etc...) (happens only when not called from the request chunk callback). 1908 * broken, etc...) (happens only when not called from the request chunk callback).
1707 */ 1909 */
1708 TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING, 1910 TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING,
1911
1709 /** 1912 /**
1710 * Attempted to send more or less data than requested. The requested data size is 1913 * Attempted to send more or less data than requested. The requested data size is
1711 * adjusted according to maximum transmission unit and the expected end of 1914 * adjusted according to maximum transmission unit and the expected end of
1712 * the file. Trying to send less or more than requested will return this error. 1915 * the file. Trying to send less or more than requested will return this error.
1713 */ 1916 */
1714 TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH, 1917 TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH,
1918
1715 /** 1919 /**
1716 * Packet queue is full. 1920 * Packet queue is full.
1717 */ 1921 */
1718 TOX_ERR_FILE_SEND_CHUNK_SENDQ, 1922 TOX_ERR_FILE_SEND_CHUNK_SENDQ,
1923
1719 /** 1924 /**
1720 * Position parameter was wrong. 1925 * Position parameter was wrong.
1721 */ 1926 */
1722 TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION 1927 TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION,
1928
1723} TOX_ERR_FILE_SEND_CHUNK; 1929} TOX_ERR_FILE_SEND_CHUNK;
1724 1930
1931
1725/** 1932/**
1726 * Send a chunk of file data to a friend. 1933 * Send a chunk of file data to a friend.
1727 * 1934 *
@@ -1741,10 +1948,7 @@ typedef enum TOX_ERR_FILE_SEND_CHUNK {
1741bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data, 1948bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data,
1742 size_t length, TOX_ERR_FILE_SEND_CHUNK *error); 1949 size_t length, TOX_ERR_FILE_SEND_CHUNK *error);
1743 1950
1744
1745/** 1951/**
1746 * The function type for the `file_chunk_request` callback.
1747 *
1748 * If the length parameter is 0, the file transfer is finished, and the client's 1952 * If the length parameter is 0, the file transfer is finished, and the client's
1749 * resources associated with the file number should be released. After a call 1953 * resources associated with the file number should be released. After a call
1750 * with zero length, the file number can be reused for future file transfers. 1954 * with zero length, the file number can be reused for future file transfers.
@@ -1769,10 +1973,13 @@ bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number,
1769typedef void tox_file_chunk_request_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, 1973typedef void tox_file_chunk_request_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position,
1770 size_t length, void *user_data); 1974 size_t length, void *user_data);
1771 1975
1976
1772/** 1977/**
1773 * Set the callback for the `file_chunk_request` event. Pass NULL to unset. 1978 * Set the callback for the `file_chunk_request` event. Pass NULL to unset.
1979 *
1980 * This event is triggered when Core is ready to send more file data.
1774 */ 1981 */
1775void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *function, void *user_data); 1982void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *callback, void *user_data);
1776 1983
1777 1984
1778/******************************************************************************* 1985/*******************************************************************************
@@ -1782,12 +1989,8 @@ void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *functi
1782 ******************************************************************************/ 1989 ******************************************************************************/
1783 1990
1784 1991
1992
1785/** 1993/**
1786 * The function type for the `file_receive` callback.
1787 *
1788 * Maximum filename length is TOX_MAX_FILENAME_LENGTH bytes. The filename should generally just be
1789 * a file name, not a path with directory names.
1790 *
1791 * The client should acquire resources to be associated with the file transfer. 1994 * The client should acquire resources to be associated with the file transfer.
1792 * Incoming file transfers start in the PAUSED state. After this callback 1995 * Incoming file transfers start in the PAUSED state. After this callback
1793 * returns, a transfer can be rejected by sending a TOX_FILE_CONTROL_CANCEL 1996 * returns, a transfer can be rejected by sending a TOX_FILE_CONTROL_CANCEL
@@ -1799,27 +2002,24 @@ void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *functi
1799 * @param file_number The friend-specific file number the data received is 2002 * @param file_number The friend-specific file number the data received is
1800 * associated with. 2003 * associated with.
1801 * @param kind The meaning of the file to be sent. 2004 * @param kind The meaning of the file to be sent.
1802 * @param file_size Size in bytes of the file about to be received from the client, 2005 * @param file_size Size in bytes of the file the client wants to send,
1803 * UINT64_MAX if unknown or streaming. 2006 * UINT64_MAX if unknown or streaming.
2007 * @param filename Name of the file. Does not need to be the actual name. This
2008 * name will be sent along with the file send request.
1804 * @param filename_length Size in bytes of the filename. 2009 * @param filename_length Size in bytes of the filename.
1805 */ 2010 */
1806typedef void tox_file_recv_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, 2011typedef void tox_file_recv_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, uint64_t file_size,
1807 uint64_t file_size, const uint8_t *filename, size_t filename_length, void *user_data); 2012 const uint8_t *filename, size_t filename_length, void *user_data);
2013
1808 2014
1809/** 2015/**
1810 * Set the callback for the `file_receive` event. Pass NULL to unset. 2016 * Set the callback for the `file_recv` event. Pass NULL to unset.
1811 * 2017 *
1812 * This event is triggered when a file transfer request is received. 2018 * This event is triggered when a file transfer request is received.
1813 */ 2019 */
1814void tox_callback_file_recv(Tox *tox, tox_file_recv_cb *function, void *user_data); 2020void tox_callback_file_recv(Tox *tox, tox_file_recv_cb *callback, void *user_data);
1815
1816 2021
1817/** 2022/**
1818 * The function type for the `file_receive_chunk` callback.
1819 *
1820 * This function is first called when a file transfer request is received, and
1821 * subsequently when a chunk of file data for an accepted request was received.
1822 *
1823 * When length is 0, the transfer is finished and the client should release the 2023 * When length is 0, the transfer is finished and the client should release the
1824 * resources it acquired for the transfer. After a call with length = 0, the 2024 * resources it acquired for the transfer. After a call with length = 0, the
1825 * file number can be reused for new file transfers. 2025 * file number can be reused for new file transfers.
@@ -1838,10 +2038,14 @@ void tox_callback_file_recv(Tox *tox, tox_file_recv_cb *function, void *user_dat
1838typedef void tox_file_recv_chunk_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, 2038typedef void tox_file_recv_chunk_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position,
1839 const uint8_t *data, size_t length, void *user_data); 2039 const uint8_t *data, size_t length, void *user_data);
1840 2040
2041
1841/** 2042/**
1842 * Set the callback for the `file_receive_chunk` event. Pass NULL to unset. 2043 * Set the callback for the `file_recv_chunk` event. Pass NULL to unset.
2044 *
2045 * This event is first triggered when a file transfer request is received, and
2046 * subsequently when a chunk of file data for an accepted request was received.
1843 */ 2047 */
1844void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *function, void *user_data); 2048void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *callback, void *user_data);
1845 2049
1846 2050
1847/******************************************************************************* 2051/*******************************************************************************
@@ -1851,13 +2055,16 @@ void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *function, vo
1851 ******************************************************************************/ 2055 ******************************************************************************/
1852 2056
1853 2057
1854/****************************************************************************** 2058
2059
2060/*******************************************************************************
1855 * 2061 *
1856 * :: Group chat message sending and receiving 2062 * :: Group chat message sending and receiving
1857 * 2063 *
1858 ******************************************************************************/ 2064 ******************************************************************************/
1859 2065
1860/* See: tox_old.h for now. */ 2066
2067
1861 2068
1862/******************************************************************************* 2069/*******************************************************************************
1863 * 2070 *
@@ -1866,34 +2073,50 @@ void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *function, vo
1866 ******************************************************************************/ 2073 ******************************************************************************/
1867 2074
1868 2075
2076
1869typedef enum TOX_ERR_FRIEND_CUSTOM_PACKET { 2077typedef enum TOX_ERR_FRIEND_CUSTOM_PACKET {
2078
2079 /**
2080 * The function returned successfully.
2081 */
1870 TOX_ERR_FRIEND_CUSTOM_PACKET_OK, 2082 TOX_ERR_FRIEND_CUSTOM_PACKET_OK,
2083
2084 /**
2085 * One of the arguments to the function was NULL when it was not expected.
2086 */
1871 TOX_ERR_FRIEND_CUSTOM_PACKET_NULL, 2087 TOX_ERR_FRIEND_CUSTOM_PACKET_NULL,
2088
1872 /** 2089 /**
1873 * The friend number did not designate a valid friend. 2090 * The friend number did not designate a valid friend.
1874 */ 2091 */
1875 TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND, 2092 TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND,
2093
1876 /** 2094 /**
1877 * This client is currently not connected to the friend. 2095 * This client is currently not connected to the friend.
1878 */ 2096 */
1879 TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED, 2097 TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED,
2098
1880 /** 2099 /**
1881 * The first byte of data was not in the specified range for the packet type. 2100 * The first byte of data was not in the specified range for the packet type.
1882 * This range is 200-254 for lossy, and 160-191 for lossless packets. 2101 * This range is 200-254 for lossy, and 160-191 for lossless packets.
1883 */ 2102 */
1884 TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID, 2103 TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID,
2104
1885 /** 2105 /**
1886 * Attempted to send an empty packet. 2106 * Attempted to send an empty packet.
1887 */ 2107 */
1888 TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY, 2108 TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY,
2109
1889 /** 2110 /**
1890 * Packet data length exceeded TOX_MAX_CUSTOM_PACKET_SIZE. 2111 * Packet data length exceeded TOX_MAX_CUSTOM_PACKET_SIZE.
1891 */ 2112 */
1892 TOX_ERR_FRIEND_CUSTOM_PACKET_TOO_LONG, 2113 TOX_ERR_FRIEND_CUSTOM_PACKET_TOO_LONG,
2114
1893 /** 2115 /**
1894 * Send queue size exceeded. 2116 * Packet queue is full.
1895 */ 2117 */
1896 TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ 2118 TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ,
2119
1897} TOX_ERR_FRIEND_CUSTOM_PACKET; 2120} TOX_ERR_FRIEND_CUSTOM_PACKET;
1898 2121
1899 2122
@@ -1921,22 +2144,6 @@ bool tox_friend_send_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_
1921 TOX_ERR_FRIEND_CUSTOM_PACKET *error); 2144 TOX_ERR_FRIEND_CUSTOM_PACKET *error);
1922 2145
1923/** 2146/**
1924 * The function type for the `friend_lossy_packet` callback.
1925 *
1926 * @param friend_number The friend number of the friend who sent a lossy packet.
1927 * @param data A byte array containing the received packet data.
1928 * @param length The length of the packet data byte array.
1929 */
1930typedef void tox_friend_lossy_packet_cb(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
1931 void *user_data);
1932
1933/**
1934 * Set the callback for the `friend_lossy_packet` event. Pass NULL to unset.
1935 */
1936void tox_callback_friend_lossy_packet(Tox *tox, tox_friend_lossy_packet_cb *function, void *user_data);
1937
1938
1939/**
1940 * Send a custom lossless packet to a friend. 2147 * Send a custom lossless packet to a friend.
1941 * 2148 *
1942 * The first byte of data must be in the range 160-191. Maximum length of a 2149 * The first byte of data must be in the range 160-191. Maximum length of a
@@ -1956,20 +2163,34 @@ bool tox_friend_send_lossless_packet(Tox *tox, uint32_t friend_number, const uin
1956 TOX_ERR_FRIEND_CUSTOM_PACKET *error); 2163 TOX_ERR_FRIEND_CUSTOM_PACKET *error);
1957 2164
1958/** 2165/**
1959 * The function type for the `friend_lossless_packet` callback. 2166 * @param friend_number The friend number of the friend who sent a lossy packet.
2167 * @param data A byte array containing the received packet data.
2168 * @param length The length of the packet data byte array.
2169 */
2170typedef void tox_friend_lossy_packet_cb(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
2171 void *user_data);
2172
2173
2174/**
2175 * Set the callback for the `friend_lossy_packet` event. Pass NULL to unset.
1960 * 2176 *
2177 */
2178void tox_callback_friend_lossy_packet(Tox *tox, tox_friend_lossy_packet_cb *callback, void *user_data);
2179
2180/**
1961 * @param friend_number The friend number of the friend who sent the packet. 2181 * @param friend_number The friend number of the friend who sent the packet.
1962 * @param data A byte array containing the received packet data. 2182 * @param data A byte array containing the received packet data.
1963 * @param length The length of the packet data byte array. 2183 * @param length The length of the packet data byte array.
1964 */ 2184 */
1965typedef void tox_friend_lossless_packet_cb(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, 2185typedef void tox_friend_lossless_packet_cb(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
1966 void *user_data); 2186 void *user_data);
2187
1967 2188
1968/** 2189/**
1969 * Set the callback for the `friend_lossless_packet` event. Pass NULL to unset. 2190 * Set the callback for the `friend_lossless_packet` event. Pass NULL to unset.
2191 *
1970 */ 2192 */
1971void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb *function, void *user_data); 2193void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb *callback, void *user_data);
1972
1973 2194
1974 2195
1975/******************************************************************************* 2196/*******************************************************************************
@@ -1979,11 +2200,12 @@ void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb
1979 ******************************************************************************/ 2200 ******************************************************************************/
1980 2201
1981 2202
2203
1982/** 2204/**
1983 * Writes the temporary DHT public key of this instance to a byte array. 2205 * Writes the temporary DHT public key of this instance to a byte array.
1984 * 2206 *
1985 * This can be used in combination with an externally accessible IP address and 2207 * This can be used in combination with an externally accessible IP address and
1986 * the bound port (from tox_get_udp_port) to run a temporary bootstrap node. 2208 * the bound port (from tox_self_get_udp_port) to run a temporary bootstrap node.
1987 * 2209 *
1988 * Be aware that every time a new instance is created, the DHT public key 2210 * Be aware that every time a new instance is created, the DHT public key
1989 * changes, meaning this cannot be used to run a permanent bootstrap node. 2211 * changes, meaning this cannot be used to run a permanent bootstrap node.
@@ -1993,15 +2215,21 @@ void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb
1993 */ 2215 */
1994void tox_self_get_dht_id(const Tox *tox, uint8_t *dht_id); 2216void tox_self_get_dht_id(const Tox *tox, uint8_t *dht_id);
1995 2217
1996
1997typedef enum TOX_ERR_GET_PORT { 2218typedef enum TOX_ERR_GET_PORT {
2219
2220 /**
2221 * The function returned successfully.
2222 */
1998 TOX_ERR_GET_PORT_OK, 2223 TOX_ERR_GET_PORT_OK,
2224
1999 /** 2225 /**
2000 * The instance was not bound to any port. 2226 * The instance was not bound to any port.
2001 */ 2227 */
2002 TOX_ERR_GET_PORT_NOT_BOUND 2228 TOX_ERR_GET_PORT_NOT_BOUND,
2229
2003} TOX_ERR_GET_PORT; 2230} TOX_ERR_GET_PORT;
2004 2231
2232
2005/** 2233/**
2006 * Return the UDP port this Tox instance is bound to. 2234 * Return the UDP port this Tox instance is bound to.
2007 */ 2235 */