diff options
50 files changed, 1345 insertions, 1703 deletions
@@ -71,3 +71,6 @@ toxcore-android-* | |||
71 | 71 | ||
72 | # cscope files list | 72 | # cscope files list |
73 | cscope.files | 73 | cscope.files |
74 | |||
75 | # rpm | ||
76 | tox.spec | ||
diff --git a/.travis.yml b/.travis.yml index 304c52e5..c90a92f2 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -7,7 +7,7 @@ before_script: | |||
7 | #installing libsodium, needed for Core | 7 | #installing libsodium, needed for Core |
8 | - git clone git://github.com/jedisct1/libsodium.git > /dev/null | 8 | - git clone git://github.com/jedisct1/libsodium.git > /dev/null |
9 | - cd libsodium | 9 | - cd libsodium |
10 | - git checkout tags/0.7.0 > /dev/null | 10 | - git checkout tags/1.0.0 > /dev/null |
11 | - ./autogen.sh > /dev/null | 11 | - ./autogen.sh > /dev/null |
12 | - ./configure > /dev/null | 12 | - ./configure > /dev/null |
13 | - make check -j3 > /dev/null | 13 | - make check -j3 > /dev/null |
@@ -105,6 +105,8 @@ sudo make install | |||
105 | You need the latest XCode with the Developer Tools (Preferences -> Downloads -> Command Line Tools). | 105 | You need the latest XCode with the Developer Tools (Preferences -> Downloads -> Command Line Tools). |
106 | The following libraries are required along with libsodium and cmake for Mountain Lion and XCode 4.6.3 install libtool, automake and autoconf. You can download them with Homebrew, or install them manually. | 106 | The following libraries are required along with libsodium and cmake for Mountain Lion and XCode 4.6.3 install libtool, automake and autoconf. You can download them with Homebrew, or install them manually. |
107 | 107 | ||
108 | **Note: OS X users can also install Toxcore using [osx_build_script_toxcore.sh](other/osx_build_script_toxcore.sh)** | ||
109 | |||
108 | There are no binaries/executables going to /bin/ or /usr/bin/ now. Everything is compiled and ran from the inside your local branch. See [Usage](#usage) below. | 110 | There are no binaries/executables going to /bin/ or /usr/bin/ now. Everything is compiled and ran from the inside your local branch. See [Usage](#usage) below. |
109 | <a name="homebrew" /> | 111 | <a name="homebrew" /> |
110 | ####Homebrew: | 112 | ####Homebrew: |
diff --git a/Makefile.am b/Makefile.am index 6b28280e..995620ef 100644 --- a/Makefile.am +++ b/Makefile.am | |||
@@ -11,7 +11,9 @@ CLEANFILES = $(top_builddir)/libtoxcore.pc | |||
11 | 11 | ||
12 | 12 | ||
13 | EXTRA_DIST = \ | 13 | EXTRA_DIST = \ |
14 | README.md \ | ||
14 | libtoxcore.pc.in \ | 15 | libtoxcore.pc.in \ |
16 | tox.spec \ | ||
15 | dist-build/android-arm.sh \ | 17 | dist-build/android-arm.sh \ |
16 | dist-build/android-armv7.sh \ | 18 | dist-build/android-armv7.sh \ |
17 | dist-build/android-x86.sh \ | 19 | dist-build/android-x86.sh \ |
@@ -3,9 +3,8 @@ | |||
3 | 3 | ||
4 | With the rise of governmental monitoring programs, Tox, a FOSS initiative, aims to be an easy to use, all-in-one communication platform that ensures their users full privacy and secure message delivery.<br /> <br /> | 4 | With the rise of governmental monitoring programs, Tox, a FOSS initiative, aims to be an easy to use, all-in-one communication platform that ensures their users full privacy and secure message delivery.<br /> <br /> |
5 | 5 | ||
6 | [**Website**](https://tox.im) **|** [**Download**](https://wiki.tox.im/Binaries) **|** [**Wiki**](https://wiki.tox.im/) **|** [**Blog**](https://blog.libtoxcore.so/) **|** [**FAQ**](https://wiki.tox.im/FAQ) **|** [**Binaries**](https://wiki.tox.im/Binaries) **|** [**Clients**](https://wiki.tox.im/Client) **|** [**Compiling**](/INSTALL.md) **|** | 6 | [**Website**](https://tox.im) **|** [**Wiki**](https://wiki.tox.im/) **|** [**Blog**](https://blog.tox.im/) **|** [**FAQ**](https://wiki.tox.im/FAQ) **|** [**Binaries/Downloads**](https://wiki.tox.im/Binaries) **|** [**Clients**](https://wiki.tox.im/Client) **|** [**Compiling**](/INSTALL.md) **|** |
7 | [**API**](https://libtoxcore.so/) **|** [**bugs**](http://tox.lighthouseapp.com/projects/123754-tox/tickets) **|** [**help and suggestions**](http://support.libtoxcore.so) **|** | 7 | [**API**](https://libtoxcore.so/) **|** [**Bugs**](http://tox.lighthouseapp.com/) **|** [**Help and Suggestions**](http://support.libtoxcore.so) **|** **IRC Channel:** [#tox@freenode](https://webchat.freenode.net/?channels=tox) |
8 | **IRC:** #tox@freenode | ||
9 | 8 | ||
10 | 9 | ||
11 | ## The Complex Stuff: | 10 | ## The Complex Stuff: |
@@ -38,6 +37,7 @@ The goal of this project is to create a configuration-free P2P Skype replacement | |||
38 | - [Compiling](/INSTALL.md) | 37 | - [Compiling](/INSTALL.md) |
39 | - [DHT Protocol](/docs/updates/DHT.md)<br /> | 38 | - [DHT Protocol](/docs/updates/DHT.md)<br /> |
40 | - [Crypto](/docs/updates/Crypto.md)<br /> | 39 | - [Crypto](/docs/updates/Crypto.md)<br /> |
41 | - [Ideas](https://wiki.tox.im/index.php/Ideas) | 40 | |
41 | Additional developer documentation can be found at [Libtoxcore.so](https://libtoxcore.so/) | ||
42 | 42 | ||
43 | [String]: https://en.wikipedia.org/wiki/String_(computer_science) | 43 | [String]: https://en.wikipedia.org/wiki/String_(computer_science) |
diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c index 566013d7..e222cf01 100644 --- a/auto_tests/TCP_test.c +++ b/auto_tests/TCP_test.c | |||
@@ -118,6 +118,7 @@ START_TEST(test_basic) | |||
118 | ck_assert_msg(packet_resp_plain[0] == 1, "wrong packet id %u", packet_resp_plain[0]); | 118 | ck_assert_msg(packet_resp_plain[0] == 1, "wrong packet id %u", packet_resp_plain[0]); |
119 | ck_assert_msg(packet_resp_plain[1] == 0, "connection not refused %u", packet_resp_plain[1]); | 119 | ck_assert_msg(packet_resp_plain[1] == 0, "connection not refused %u", packet_resp_plain[1]); |
120 | ck_assert_msg(memcmp(packet_resp_plain + 2, f_public_key, crypto_box_PUBLICKEYBYTES) == 0, "key in packet wrong"); | 120 | ck_assert_msg(memcmp(packet_resp_plain + 2, f_public_key, crypto_box_PUBLICKEYBYTES) == 0, "key in packet wrong"); |
121 | kill_TCP_server(tcp_s); | ||
121 | } | 122 | } |
122 | END_TEST | 123 | END_TEST |
123 | 124 | ||
@@ -175,6 +176,12 @@ struct sec_TCP_con *new_TCP_con(TCP_Server *tcp_s) | |||
175 | return sec_c; | 176 | return sec_c; |
176 | } | 177 | } |
177 | 178 | ||
179 | void kill_TCP_con(struct sec_TCP_con *con) | ||
180 | { | ||
181 | kill_sock(con->sock); | ||
182 | free(con); | ||
183 | } | ||
184 | |||
178 | int write_packet_TCP_secure_connection(struct sec_TCP_con *con, uint8_t *data, uint16_t length) | 185 | int write_packet_TCP_secure_connection(struct sec_TCP_con *con, uint8_t *data, uint16_t length) |
179 | { | 186 | { |
180 | uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; | 187 | uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; |
@@ -290,6 +297,10 @@ START_TEST(test_some) | |||
290 | ck_assert_msg(len == sizeof(ping_packet), "wrong len %u", len); | 297 | ck_assert_msg(len == sizeof(ping_packet), "wrong len %u", len); |
291 | ck_assert_msg(data[0] == 5, "wrong packet id %u", data[0]); | 298 | ck_assert_msg(data[0] == 5, "wrong packet id %u", data[0]); |
292 | ck_assert_msg(memcmp(ping_packet + 1, data + 1, sizeof(uint64_t)) == 0, "wrong packet data"); | 299 | ck_assert_msg(memcmp(ping_packet + 1, data + 1, sizeof(uint64_t)) == 0, "wrong packet data"); |
300 | kill_TCP_server(tcp_s); | ||
301 | kill_TCP_con(con1); | ||
302 | kill_TCP_con(con2); | ||
303 | kill_TCP_con(con3); | ||
293 | } | 304 | } |
294 | END_TEST | 305 | END_TEST |
295 | 306 | ||
@@ -457,6 +468,9 @@ START_TEST(test_client) | |||
457 | do_TCP_connection(conn2); | 468 | do_TCP_connection(conn2); |
458 | ck_assert_msg(status_callback_good == 1, "status callback not called"); | 469 | ck_assert_msg(status_callback_good == 1, "status callback not called"); |
459 | ck_assert_msg(status_callback_status == 1, "wrong status"); | 470 | ck_assert_msg(status_callback_status == 1, "wrong status"); |
471 | kill_TCP_server(tcp_s); | ||
472 | kill_TCP_connection(conn); | ||
473 | kill_TCP_connection(conn2); | ||
460 | } | 474 | } |
461 | END_TEST | 475 | END_TEST |
462 | 476 | ||
@@ -488,6 +502,8 @@ START_TEST(test_client_invalid) | |||
488 | do_TCP_connection(conn); | 502 | do_TCP_connection(conn); |
489 | ck_assert_msg(conn->status == TCP_CLIENT_DISCONNECTED, "Wrong status. Expected: %u, is: %u", TCP_CLIENT_DISCONNECTED, | 503 | ck_assert_msg(conn->status == TCP_CLIENT_DISCONNECTED, "Wrong status. Expected: %u, is: %u", TCP_CLIENT_DISCONNECTED, |
490 | conn->status); | 504 | conn->status); |
505 | |||
506 | kill_TCP_connection(conn); | ||
491 | } | 507 | } |
492 | END_TEST | 508 | END_TEST |
493 | 509 | ||
diff --git a/auto_tests/assoc_test.c b/auto_tests/assoc_test.c index b377cadf..bcf5d3fa 100644 --- a/auto_tests/assoc_test.c +++ b/auto_tests/assoc_test.c | |||
@@ -55,6 +55,7 @@ START_TEST(test_basics) | |||
55 | 55 | ||
56 | uint8_t found = Assoc_get_close_entries(assoc, &close_entries); | 56 | uint8_t found = Assoc_get_close_entries(assoc, &close_entries); |
57 | ck_assert_msg(found == 1, "get_close_entries(): expected %u, got %u", 1, found); | 57 | ck_assert_msg(found == 1, "get_close_entries(): expected %u, got %u", 1, found); |
58 | kill_Assoc(assoc); | ||
58 | } | 59 | } |
59 | END_TEST | 60 | END_TEST |
60 | 61 | ||
@@ -130,6 +131,7 @@ START_TEST(test_fillup) | |||
130 | 131 | ||
131 | ck_assert_msg(good == 8, "Entries found were not the closest ones. Only %u/8 were.", good); | 132 | ck_assert_msg(good == 8, "Entries found were not the closest ones. Only %u/8 were.", good); |
132 | //printf("good: %u %u %u\n", good, a, ((uint32_t)current_time() - a)); | 133 | //printf("good: %u %u %u\n", good, a, ((uint32_t)current_time() - a)); |
134 | kill_Assoc(assoc); | ||
133 | } | 135 | } |
134 | END_TEST | 136 | END_TEST |
135 | 137 | ||
diff --git a/auto_tests/encryptsave_test.c b/auto_tests/encryptsave_test.c index aa5bef3f..338c9ef1 100644 --- a/auto_tests/encryptsave_test.c +++ b/auto_tests/encryptsave_test.c | |||
@@ -114,6 +114,12 @@ START_TEST(test_save_friend) | |||
114 | test = tox_get_client_id(tox4, 0, address5); | 114 | test = tox_get_client_id(tox4, 0, address5); |
115 | ck_assert_msg(test == 0, "no friends! the third"); | 115 | ck_assert_msg(test == 0, "no friends! the third"); |
116 | ck_assert_msg(memcmp(address, address2, TOX_CLIENT_ID_SIZE) == 0, "addresses don't match! the third"); | 116 | ck_assert_msg(memcmp(address, address2, TOX_CLIENT_ID_SIZE) == 0, "addresses don't match! the third"); |
117 | |||
118 | tox_kill(tox1); | ||
119 | tox_kill(tox2); | ||
120 | tox_kill(tox3); | ||
121 | tox_kill(tox4); | ||
122 | tox_kill(tox5); | ||
117 | } | 123 | } |
118 | END_TEST | 124 | END_TEST |
119 | 125 | ||
@@ -160,8 +166,8 @@ Suite *encryptsave_suite(void) | |||
160 | Suite *s = suite_create("encryptsave"); | 166 | Suite *s = suite_create("encryptsave"); |
161 | 167 | ||
162 | DEFTESTCASE_SLOW(known_kdf, 60); /* is 5-10 seconds on my computer, but is directly dependent on CPU */ | 168 | DEFTESTCASE_SLOW(known_kdf, 60); /* is 5-10 seconds on my computer, but is directly dependent on CPU */ |
163 | DEFTESTCASE(save_friend); | 169 | DEFTESTCASE_SLOW(save_friend, 20); |
164 | DEFTESTCASE(keys); | 170 | DEFTESTCASE_SLOW(keys, 30); |
165 | 171 | ||
166 | return s; | 172 | return s; |
167 | } | 173 | } |
diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index 8e10eb11..f27fefb8 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c | |||
@@ -138,12 +138,12 @@ START_TEST(test_basic) | |||
138 | 138 | ||
139 | IP_Port on1 = {ip, onion1->net->port}; | 139 | IP_Port on1 = {ip, onion1->net->port}; |
140 | Node_format n1; | 140 | Node_format n1; |
141 | memcpy(n1.client_id, onion1->dht->self_public_key, crypto_box_PUBLICKEYBYTES); | 141 | memcpy(n1.public_key, onion1->dht->self_public_key, crypto_box_PUBLICKEYBYTES); |
142 | n1.ip_port = on1; | 142 | n1.ip_port = on1; |
143 | 143 | ||
144 | IP_Port on2 = {ip, onion2->net->port}; | 144 | IP_Port on2 = {ip, onion2->net->port}; |
145 | Node_format n2; | 145 | Node_format n2; |
146 | memcpy(n2.client_id, onion2->dht->self_public_key, crypto_box_PUBLICKEYBYTES); | 146 | memcpy(n2.public_key, onion2->dht->self_public_key, crypto_box_PUBLICKEYBYTES); |
147 | n2.ip_port = on2; | 147 | n2.ip_port = on2; |
148 | 148 | ||
149 | Node_format nodes[4]; | 149 | Node_format nodes[4]; |
@@ -180,7 +180,7 @@ START_TEST(test_basic) | |||
180 | randombytes(sb_data, sizeof(sb_data)); | 180 | randombytes(sb_data, sizeof(sb_data)); |
181 | uint64_t s; | 181 | uint64_t s; |
182 | memcpy(&s, sb_data, sizeof(uint64_t)); | 182 | memcpy(&s, sb_data, sizeof(uint64_t)); |
183 | memcpy(test_3_pub_key, nodes[3].client_id, crypto_box_PUBLICKEYBYTES); | 183 | memcpy(test_3_pub_key, nodes[3].public_key, crypto_box_PUBLICKEYBYTES); |
184 | ret = send_announce_request(onion1->net, &path, nodes[3], onion1->dht->self_public_key, | 184 | ret = send_announce_request(onion1->net, &path, nodes[3], onion1->dht->self_public_key, |
185 | onion1->dht->self_secret_key, | 185 | onion1->dht->self_secret_key, |
186 | zeroes, onion1->dht->self_public_key, onion1->dht->self_public_key, s); | 186 | zeroes, onion1->dht->self_public_key, onion1->dht->self_public_key, s); |
@@ -224,6 +224,39 @@ START_TEST(test_basic) | |||
224 | do_onion(onion2); | 224 | do_onion(onion2); |
225 | c_sleep(50); | 225 | c_sleep(50); |
226 | } | 226 | } |
227 | |||
228 | kill_onion_announce(onion1_a); | ||
229 | kill_onion_announce(onion2_a); | ||
230 | |||
231 | { | ||
232 | Onion *onion = onion1; | ||
233 | |||
234 | Networking_Core *net = onion->dht->net; | ||
235 | DHT *dht = onion->dht; | ||
236 | kill_onion(onion); | ||
237 | kill_DHT(dht); | ||
238 | kill_networking(net); | ||
239 | } | ||
240 | |||
241 | { | ||
242 | Onion *onion = onion2; | ||
243 | |||
244 | Networking_Core *net = onion->dht->net; | ||
245 | DHT *dht = onion->dht; | ||
246 | kill_onion(onion); | ||
247 | kill_DHT(dht); | ||
248 | kill_networking(net); | ||
249 | } | ||
250 | |||
251 | { | ||
252 | Onion *onion = onion3; | ||
253 | |||
254 | Networking_Core *net = onion->dht->net; | ||
255 | DHT *dht = onion->dht; | ||
256 | kill_onion(onion); | ||
257 | kill_DHT(dht); | ||
258 | kill_networking(net); | ||
259 | } | ||
227 | } | 260 | } |
228 | END_TEST | 261 | END_TEST |
229 | 262 | ||
@@ -257,6 +290,18 @@ void do_onions(Onions *on) | |||
257 | do_onion_client(on->onion_c); | 290 | do_onion_client(on->onion_c); |
258 | } | 291 | } |
259 | 292 | ||
293 | void kill_onions(Onions *on) | ||
294 | { | ||
295 | Networking_Core *net = on->onion->dht->net; | ||
296 | DHT *dht = on->onion->dht; | ||
297 | kill_onion_client(on->onion_c); | ||
298 | kill_onion_announce(on->onion_a); | ||
299 | kill_onion(on->onion); | ||
300 | kill_DHT(dht); | ||
301 | kill_networking(net); | ||
302 | free(on); | ||
303 | } | ||
304 | |||
260 | #define NUM_ONIONS 50 | 305 | #define NUM_ONIONS 50 |
261 | 306 | ||
262 | START_TEST(test_announce) | 307 | START_TEST(test_announce) |
@@ -334,6 +379,10 @@ START_TEST(test_announce) | |||
334 | } | 379 | } |
335 | 380 | ||
336 | ck_assert_msg(ip_port.port == onions[7]->onion->net->port, "Port in returned ip not correct."); | 381 | ck_assert_msg(ip_port.port == onions[7]->onion->net->port, "Port in returned ip not correct."); |
382 | |||
383 | for (i = 0; i < NUM_ONIONS; ++i) { | ||
384 | kill_onions(onions[i]); | ||
385 | } | ||
337 | } | 386 | } |
338 | END_TEST | 387 | END_TEST |
339 | 388 | ||
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c index db1db3fb..3139c844 100644 --- a/auto_tests/toxav_basic_test.c +++ b/auto_tests/toxav_basic_test.c | |||
@@ -595,8 +595,12 @@ START_TEST(test_AV_flows) | |||
595 | printf("\n"); | 595 | printf("\n"); |
596 | } | 596 | } |
597 | 597 | ||
598 | 598 | vpx_img_free(sample_image); | |
599 | 599 | toxav_kill(status_control.Alice.av); | |
600 | toxav_kill(status_control.Bob.av); | ||
601 | tox_kill(bootstrap_node); | ||
602 | tox_kill(Alice); | ||
603 | tox_kill(Bob); | ||
600 | 604 | ||
601 | printf("Calls ended!\n"); | 605 | printf("Calls ended!\n"); |
602 | } | 606 | } |
diff --git a/configure.ac b/configure.ac index 3a45b35d..e43e8f78 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -6,7 +6,7 @@ AC_INIT([tox], [0.0.0], [https://tox.im]) | |||
6 | AC_CONFIG_AUX_DIR(configure_aux) | 6 | AC_CONFIG_AUX_DIR(configure_aux) |
7 | AC_CONFIG_SRCDIR([toxcore/net_crypto.c]) | 7 | AC_CONFIG_SRCDIR([toxcore/net_crypto.c]) |
8 | AC_CONFIG_HEADERS([config.h]) | 8 | AC_CONFIG_HEADERS([config.h]) |
9 | AM_INIT_AUTOMAKE([1.10 -Wall subdir-objects]) | 9 | AM_INIT_AUTOMAKE([1.10 -Wall subdir-objects tar-ustar]) |
10 | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) | 10 | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) |
11 | AC_CONFIG_MACRO_DIR([m4]) | 11 | AC_CONFIG_MACRO_DIR([m4]) |
12 | 12 | ||
@@ -693,6 +693,7 @@ AM_CONDITIONAL(WIN32, test "x$WIN32" = "xyes") | |||
693 | AC_CONFIG_FILES([Makefile | 693 | AC_CONFIG_FILES([Makefile |
694 | build/Makefile | 694 | build/Makefile |
695 | libtoxcore.pc | 695 | libtoxcore.pc |
696 | tox.spec | ||
696 | ]) | 697 | ]) |
697 | 698 | ||
698 | AM_COND_IF(BUILD_AV, | 699 | AM_COND_IF(BUILD_AV, |
diff --git a/docs/Avatars.md b/docs/Avatars.md index 1dcbba96..9dd43079 100644 --- a/docs/Avatars.md +++ b/docs/Avatars.md | |||
@@ -11,8 +11,8 @@ way for one user to identify another in the friend list. | |||
11 | This document describes the implementation of avatars in the Tox protocol, | 11 | This document describes the implementation of avatars in the Tox protocol, |
12 | according to the following design considerations: | 12 | according to the following design considerations: |
13 | 13 | ||
14 | - Avatars are handled as private information, i.e., they are only exchanged over | 14 | - Avatars are handled as private information, i.e., they are only exchanged |
15 | Tox encrypted channels among previously authenticated friends; | 15 | over Tox encrypted channels among previously authenticated friends. |
16 | 16 | ||
17 | - The library treats all images as blobs and does not interpret or | 17 | - The library treats all images as blobs and does not interpret or |
18 | understand image formats. It only ensures that the avatar data sent by | 18 | understand image formats. It only ensures that the avatar data sent by |
@@ -33,7 +33,7 @@ according to the following design considerations: | |||
33 | - The protocol MUST provide means to allow caching and avoid unnecessary | 33 | - The protocol MUST provide means to allow caching and avoid unnecessary |
34 | data transfers. | 34 | data transfers. |
35 | 35 | ||
36 | - Avatars are transfered between clients in a background operation. | 36 | - Avatars are transferred between clients in a background operation. |
37 | 37 | ||
38 | - Avatars are served on a "best effort" basis, without breaking clients | 38 | - Avatars are served on a "best effort" basis, without breaking clients |
39 | which do not support them. | 39 | which do not support them. |
@@ -76,7 +76,7 @@ protocol. Moving this feature to the core protocol also: | |||
76 | This is a very high level description. The usage patterns expected from | 76 | This is a very high level description. The usage patterns expected from |
77 | client applications are described in the section "Using Avatars in Client | 77 | client applications are described in the section "Using Avatars in Client |
78 | Applications", and a low level protocol description is available in the | 78 | Applications", and a low level protocol description is available in the |
79 | section "Internal Protocol Description".) | 79 | section "Internal Protocol Description"). |
80 | The avatar exchange is implemented with the following new elements in the | 80 | The avatar exchange is implemented with the following new elements in the |
81 | Tox protocol: | 81 | Tox protocol: |
82 | 82 | ||
@@ -84,15 +84,16 @@ Tox protocol: | |||
84 | a user to another anytime, but are usually sent after one of them | 84 | a user to another anytime, but are usually sent after one of them |
85 | connects to the network, changes his avatar, or in reply to an **avatar | 85 | connects to the network, changes his avatar, or in reply to an **avatar |
86 | information request**. They are delivered by a very lightweight message | 86 | information request**. They are delivered by a very lightweight message |
87 | but with information enough to allow a user to validate or discard an | 87 | but with enough information to allow a user to validate or discard an |
88 | avatar from the local cache and to decide if it is interesting to request the | 88 | avatar from the local cache and to decide if it is interesting to request |
89 | avatar data from the peer. | 89 | the avatar data from the peer. |
90 | 90 | ||
91 | This event contains two data fields: (1) the image format, and (2) the | 91 | This event contains two data fields: (1) the image format, and (2) the |
92 | cryptographic hash of the actual image data. The image format may be NONE | 92 | cryptographic hash of the current image data. The image format may be |
93 | (for users who have no avatar or removed their avatars) or PNG. The | 93 | NONE (for users who have no avatar or removed their avatars) or PNG. The |
94 | cryptographic hash is intended to be compared with the hash of the | 94 | cryptographic hash is intended to be compared with the hash of the |
95 | currently cached avatar (if any) in order to check if it is still up to date. | 95 | currently cached avatar (if any) in order to check if it is still up to |
96 | date. | ||
96 | 97 | ||
97 | - **Avatar Information Requests** are very lightweight messages sent by a | 98 | - **Avatar Information Requests** are very lightweight messages sent by a |
98 | user asking for an **avatar information notification**. They may be sent | 99 | user asking for an **avatar information notification**. They may be sent |
@@ -114,7 +115,7 @@ Tox protocol: | |||
114 | 115 | ||
115 | This event contains three data fields: (1) the image format, (2) the | 116 | This event contains three data fields: (1) the image format, (2) the |
116 | cryptographic hash of the image data, and (3) the raw image data. If the | 117 | cryptographic hash of the image data, and (3) the raw image data. If the |
117 | image format is NONE (i.e. no avatar) the hash is zeroed and the image | 118 | image format is NONE (i.e. no avatar), the hash is zeroed and the image |
118 | data is empty. The raw image data is locally validated and ensured to | 119 | data is empty. The raw image data is locally validated and ensured to |
119 | match the hash (the event is **not** triggered otherwise). | 120 | match the hash (the event is **not** triggered otherwise). |
120 | 121 | ||
@@ -145,10 +146,13 @@ TOX_AVATAR_FORMAT; | |||
145 | /* Set the user avatar image data. */ | 146 | /* Set the user avatar image data. */ |
146 | int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length); | 147 | int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length); |
147 | 148 | ||
149 | /* Remove the user avatar image data. */ | ||
150 | int tox_unset_avatar(Tox *tox); | ||
151 | |||
148 | /* Get avatar data from the current user. */ | 152 | /* Get avatar data from the current user. */ |
149 | int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, uint8_t *hash); | 153 | int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, uint8_t *hash); |
150 | 154 | ||
151 | /* Generates a cryptographic hash of the given data (usually a cached avatar). */ | 155 | /* Generate a cryptographic hash of the given data (usually a cached avatar). */ |
152 | int tox_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen); | 156 | int tox_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen); |
153 | 157 | ||
154 | /* Request avatar information from a friend. */ | 158 | /* Request avatar information from a friend. */ |
@@ -177,17 +181,17 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint | |||
177 | 181 | ||
178 | - Clients MUST NOT imply the availability of avatars in other users. | 182 | - Clients MUST NOT imply the availability of avatars in other users. |
179 | Avatars are an optional feature and not all users and clients may | 183 | Avatars are an optional feature and not all users and clients may |
180 | support them; | 184 | support them. |
181 | 185 | ||
182 | - Clients MUST NOT block waiting for avatar information and avatar data | 186 | - Clients MUST NOT block waiting for avatar information and avatar data |
183 | packets; | 187 | packets. |
184 | 188 | ||
185 | - Clients MUST treat avatar data as insecure and potentially malicious; | 189 | - Clients MUST treat avatar data as insecure and potentially malicious. |
186 | For example, users may accidentally use corrupted images as avatars, | 190 | For example, users may accidentally use corrupted images as avatars, |
187 | a malicious user may send a specially crafted image to exploit a know | 191 | a malicious user may send a specially crafted image to exploit a known |
188 | vulnerability in an image decoding library, etc. It is recommended to | 192 | vulnerability in an image decoding library, etc. It is recommended to |
189 | handle the avatar image data in the same way as an image downloaded | 193 | handle the avatar image data in the same way as an image downloaded |
190 | from an unknown Internet source; | 194 | from an unknown Internet source. |
191 | 195 | ||
192 | - The peers MUST NOT assume any coupling between the operations of | 196 | - The peers MUST NOT assume any coupling between the operations of |
193 | receiving an avatar information packet, sending unrequested avatar | 197 | receiving an avatar information packet, sending unrequested avatar |
@@ -196,31 +200,36 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint | |||
196 | For example, the following situations are valid: | 200 | For example, the following situations are valid: |
197 | 201 | ||
198 | * A text-mode client may send avatars to other users, but never | 202 | * A text-mode client may send avatars to other users, but never |
199 | request them; | 203 | request them. |
200 | 204 | ||
201 | * A client may not understand a particular image format and ignore | 205 | * A client may not understand a particular image format and ignore |
202 | avatars using it, but request and handle other formats; | 206 | avatars using it, but request and handle other formats. |
207 | |||
208 | * A client on a slow mobile network may ask for avatar information to | ||
209 | ensure its cached avatars are still valid, but not request avatar | ||
210 | data. The same client may start asking for avatar data once it | ||
211 | connects through a fast network. | ||
203 | 212 | ||
204 | - Clients SHOULD implement a local cache of avatars and do not request | 213 | - Clients SHOULD implement a local cache of avatars and not request |
205 | avatar data from other peers unless necessary; | 214 | avatar data from other peers unless necessary. |
206 | 215 | ||
207 | - When an avatar information is received, the client should delete the | 216 | - When avatar information is received, the client should delete the |
208 | avatar if the new avatar format is NONE or compare the hash received | 217 | avatar if the new avatar format is NONE or compare the hash received |
209 | from the peer with the hash of the currently cached avatar. If they | 218 | from the peer with the hash of the currently cached avatar. If they |
210 | differ, send an avatar data request; | 219 | differ, send an avatar data request. |
211 | 220 | ||
212 | - If the cached avatar is older than a given threshold, the client may | 221 | - If the cached avatar is older than a given threshold, the client may |
213 | also send an avatar info request to that friend once he is online and | 222 | also send an avatar info request to that friend once he is online and |
214 | mark the avatar as updated *before* any avatar information is received | 223 | mark the avatar as updated *before* any avatar information is received |
215 | (to not spam the peer with such requests); | 224 | (to not spam the peer with such requests). |
216 | 225 | ||
217 | - When an avatar data notification is received, the client must update | 226 | - When an avatar data notification is received, the client must update |
218 | the cached avatar with the new one; | 227 | the cached avatar with the new one. |
219 | 228 | ||
220 | - Clients should resize or crop the image to the way it better adapts | 229 | - Clients should resize or crop the image such that it better adapts |
221 | to the client user interface; | 230 | to the client's user interface. |
222 | 231 | ||
223 | - If the user already have an avatar defined in the client configuration, | 232 | - If the user already has an avatar defined in the client configuration, |
224 | it must be set before connecting to the network to avoid spurious avatar | 233 | it must be set before connecting to the network to avoid spurious avatar |
225 | change notifications and unnecessary data transfers. | 234 | change notifications and unnecessary data transfers. |
226 | 235 | ||
@@ -232,10 +241,10 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint | |||
232 | ### Interoperability and sharing avatars among different clients | 241 | ### Interoperability and sharing avatars among different clients |
233 | 242 | ||
234 | **This section is a tentative recommendation of how clients should store | 243 | **This section is a tentative recommendation of how clients should store |
235 | avatars to ensure local interoperability and should be revised if this | 244 | avatars to ensure local interoperability, and should be revised if this |
236 | code is accepted into Tox core.** | 245 | code is accepted into Tox core.** |
237 | 246 | ||
238 | It is desirable that the user avatar and the cached friends avatars could be | 247 | It is desirable that the user avatar and the cached friends' avatars could be |
239 | shared among different Tox clients in the same system, in the spirit of the | 248 | shared among different Tox clients in the same system, in the spirit of the |
240 | proposed Single Tox Standard. This not only makes switching from one client | 249 | proposed Single Tox Standard. This not only makes switching from one client |
241 | to another easier, but also minimizes the need of data transfers, as avatars | 250 | to another easier, but also minimizes the need of data transfers, as avatars |
@@ -244,7 +253,7 @@ already downloaded by other clients can be reused. | |||
244 | Given the Tox data directory described in STS Draft v0.1.0: | 253 | Given the Tox data directory described in STS Draft v0.1.0: |
245 | 254 | ||
246 | - Avatars are stored in a directory called "avatars" and named | 255 | - Avatars are stored in a directory called "avatars" and named |
247 | as "xxxxx.png", where "xxxxx" is the complete client id (but not friend | 256 | as "xxxxx.png", where "xxxxx" is the complete public key (but not friend |
248 | address!) encoded as an uppercase hexadecimal string and "png" is the | 257 | address!) encoded as an uppercase hexadecimal string and "png" is the |
249 | extension for the PNG avatar. As new image formats may be used in the | 258 | extension for the PNG avatar. As new image formats may be used in the |
250 | future, clients should ensure no other file "xxxxx.*" exists. No file | 259 | future, clients should ensure no other file "xxxxx.*" exists. No file |
@@ -253,10 +262,10 @@ Given the Tox data directory described in STS Draft v0.1.0: | |||
253 | - The client's own avatar is not special and is stored like any other. This | 262 | - The client's own avatar is not special and is stored like any other. This |
254 | is partially for simplicity, and partially in anticipation of profiles. | 263 | is partially for simplicity, and partially in anticipation of profiles. |
255 | 264 | ||
256 | - The avatar should be stored as its recieved, before any modifications by | 265 | - The avatar should be stored as it was received, before any modifications by |
257 | the client for display purposes. | 266 | the client for display purposes. |
258 | 267 | ||
259 | - The hash, as calculated by toxcore and passed in to the data callback, | 268 | - The hash, as calculated by toxcore and passed into the data callback, |
260 | should be saved in "avatars/xxxxx.hash" where "xxxxx" means the | 269 | should be saved in "avatars/xxxxx.hash" where "xxxxx" means the |
261 | same thing as for avatars. (The filename is longer than the file :) ) | 270 | same thing as for avatars. (The filename is longer than the file :) ) |
262 | 271 | ||
@@ -264,12 +273,12 @@ Given the Tox data directory described in STS Draft v0.1.0: | |||
264 | upper case strings, but lower case file names are more usual. | 273 | upper case strings, but lower case file names are more usual. |
265 | 274 | ||
266 | 275 | ||
267 | Example for Linux and other Unix systems, assuming an user called "gildor": | 276 | Example for Linux and other Unix systems, assuming a user called "gildor": |
268 | 277 | ||
269 | Tox data directory: /home/gildor/.config/tox/ | 278 | Tox data directory: /home/gildor/.config/tox/ |
270 | Tox data file: /home/gildor/.config/tox/data | 279 | Tox data file: /home/gildor/.config/tox/data |
271 | Avatar data dir: /home/gildor/.config/tox/avatars/ | 280 | Avatar data dir: /home/gildor/.config/tox/avatars/ |
272 | Gildor's avatar: /home/gildor/.config/tox/avatars/E5809EEF5F11AB29B9BDF543C05B58DDF454AB9CA176C235C7699FDC2757DC33.png | 281 | Gildor's avatar: /home/gildor/.config/tox/avatars/446F4E6F744D6564646C65496E546865416666616972734F6657697A61726473.png |
273 | Elrond's avatar: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.png | 282 | Elrond's avatar: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.png |
274 | Elrond's hash: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.hash | 283 | Elrond's hash: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.hash |
275 | Elladan's avatar: /home/gildor/.config/tox/avatars/49486174655768656E48756D616E735468696E6B49416D4D7942726F74686572.png | 284 | Elladan's avatar: /home/gildor/.config/tox/avatars/49486174655768656E48756D616E735468696E6B49416D4D7942726F74686572.png |
@@ -285,13 +294,13 @@ This recommendation is partially implemented by "testing/test_avatars.c". | |||
285 | 294 | ||
286 | ### Common operations | 295 | ### Common operations |
287 | 296 | ||
288 | These are minimal examples of how perform common operations with avatar | 297 | These are minimal examples of how to perform common operations with avatar |
289 | functions. For a complete, working, example, see `testing/test_avatars.c`. | 298 | functions. For a complete working example, see `testing/test_avatars.c`. |
290 | 299 | ||
291 | 300 | ||
292 | #### Setting an avatar for the current user | 301 | #### Setting an avatar for the current user |
293 | 302 | ||
294 | In this example `load_data_file` is just an hypothetical function that loads | 303 | In this example, `load_data_file` is just a hypothetical function that loads |
295 | data from a file into the buffer and sets the length accordingly. | 304 | data from a file into the buffer and sets the length accordingly. |
296 | 305 | ||
297 | uint8_t buf[TOX_AVATAR_MAX_DATA_LENGTH]; | 306 | uint8_t buf[TOX_AVATAR_MAX_DATA_LENGTH]; |
@@ -304,7 +313,7 @@ data from a file into the buffer and sets the length accordingly. | |||
304 | If the user is connected, this function will also notify all connected | 313 | If the user is connected, this function will also notify all connected |
305 | friends about the avatar change. | 314 | friends about the avatar change. |
306 | 315 | ||
307 | If the user already have an avatar defined in the client configuration, it | 316 | If the user already has an avatar defined in the client configuration, it |
308 | must be set before connecting to the network to avoid spurious avatar change | 317 | must be set before connecting to the network to avoid spurious avatar change |
309 | notifications and unnecessary data transfers. | 318 | notifications and unnecessary data transfers. |
310 | 319 | ||
@@ -313,7 +322,12 @@ notifications and unnecessary data transfers. | |||
313 | 322 | ||
314 | #### Removing the avatar from the current user | 323 | #### Removing the avatar from the current user |
315 | 324 | ||
316 | To remove an avatar, an application must set it to `TOX_AVATAR_FORMAT_NONE`. | 325 | To remove the current avatar, an application must call |
326 | |||
327 | tox_unset_avatar(tox); | ||
328 | |||
329 | the effect is the same as setting the avatar format to `TOX_AVATAR_FORMAT_NONE` | ||
330 | with no data: | ||
317 | 331 | ||
318 | tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0); | 332 | tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0); |
319 | 333 | ||
@@ -343,7 +357,7 @@ As in this example: | |||
343 | printf("\n"); | 357 | printf("\n"); |
344 | } | 358 | } |
345 | 359 | ||
346 | And, somewhere in the Tox initialization calls, set if as the callback to be | 360 | And, somewhere in the Tox initialization calls, set it as the callback to be |
347 | triggered when an avatar information event arrives: | 361 | triggered when an avatar information event arrives: |
348 | 362 | ||
349 | tox_callback_avatar_info(tox, avatar_info_cb, NULL); | 363 | tox_callback_avatar_info(tox, avatar_info_cb, NULL); |
@@ -356,7 +370,7 @@ in the avatar information event and, if needed, request the avatar data. | |||
356 | 370 | ||
357 | #### Receiving avatar data from friends | 371 | #### Receiving avatar data from friends |
358 | 372 | ||
359 | Avatar data events are only delivered in reply of avatar data requests which | 373 | Avatar data events are only delivered in reply to avatar data requests, which |
360 | **should** only be sent after getting the user avatar information (format | 374 | **should** only be sent after getting the user avatar information (format |
361 | and hash) from an avatar information event and checking it against a local | 375 | and hash) from an avatar information event and checking it against a local |
362 | cache. | 376 | cache. |
@@ -374,7 +388,7 @@ checks the local avatar cache and emits an avatar data request if necessary: | |||
374 | delete_avatar_from_cache(tox, friendnumber); | 388 | delete_avatar_from_cache(tox, friendnumber); |
375 | } else { | 389 | } else { |
376 | /* Use the received hash to check if the cached avatar is | 390 | /* Use the received hash to check if the cached avatar is |
377 | still updated. */ | 391 | still up to date. */ |
378 | if (!is_user_cached_avatar_updated(tox, friendnumber, hash)) { | 392 | if (!is_user_cached_avatar_updated(tox, friendnumber, hash)) { |
379 | /* User avatar is outdated, send data request */ | 393 | /* User avatar is outdated, send data request */ |
380 | tox_request_avatar_data(tox, friendnumber); | 394 | tox_request_avatar_data(tox, friendnumber); |
@@ -406,9 +420,9 @@ calls: | |||
406 | tox_callback_avatar_data(tox, avatar_data_cb, NULL); | 420 | tox_callback_avatar_data(tox, avatar_data_cb, NULL); |
407 | 421 | ||
408 | 422 | ||
409 | In the previous examples, implementation of the functions to check, store | 423 | In the previous examples, implementation of the functions to check, store, |
410 | and retrieve data from the cache were omitted for brevity. These functions | 424 | and retrieve data from the cache were omitted for brevity. These functions |
411 | will also need to get the friend client ID (public key) from they friend | 425 | will also need to get the friend public key (client id) from the friend |
412 | number and, usually, convert it from a byte string to a hexadecimal | 426 | number and, usually, convert it from a byte string to a hexadecimal |
413 | string. A complete, yet more complex, example is available in the file | 427 | string. A complete, yet more complex, example is available in the file |
414 | `testing/test_avatars.c`. | 428 | `testing/test_avatars.c`. |
@@ -440,7 +454,7 @@ The avatar transfer protocol adds the following new packet types and ids: | |||
440 | 454 | ||
441 | ### Requesting avatar information | 455 | ### Requesting avatar information |
442 | 456 | ||
443 | To request avatar information, an user must send a packet of type | 457 | To request avatar information, a user must send a packet of type |
444 | `PACKET_ID_AVATAR_INFO_REQ`. This packet has no data fields. Upon | 458 | `PACKET_ID_AVATAR_INFO_REQ`. This packet has no data fields. Upon |
445 | receiving this packet, a client which supports avatars should answer with | 459 | receiving this packet, a client which supports avatars should answer with |
446 | a `PACKET_ID_AVATAR_INFO`. The sender must accept that the friend may | 460 | a `PACKET_ID_AVATAR_INFO`. The sender must accept that the friend may |
@@ -458,7 +472,7 @@ the following structure: | |||
458 | Packet data size: 33 bytes | 472 | Packet data size: 33 bytes |
459 | [1: uint8_t format][32: uint8_t hash] | 473 | [1: uint8_t format][32: uint8_t hash] |
460 | 474 | ||
461 | Where 'format' is the image data format, one of the following: | 475 | where 'format' is the image data format, one of the following: |
462 | 476 | ||
463 | 0 = AVATAR_FORMAT_NONE (no avatar set) | 477 | 0 = AVATAR_FORMAT_NONE (no avatar set) |
464 | 1 = AVATAR_FORMAT_PNG | 478 | 1 = AVATAR_FORMAT_PNG |
@@ -478,21 +492,21 @@ connects, in the same way Tox sends name, status and action information. | |||
478 | Transmission of avatar data is a multi-step procedure using three new packet | 492 | Transmission of avatar data is a multi-step procedure using three new packet |
479 | types. | 493 | types. |
480 | 494 | ||
481 | - Packet `PACKET_ID_AVATAR_DATA_CONTROL` have the format: | 495 | - Packet `PACKET_ID_AVATAR_DATA_CONTROL` has the format: |
482 | 496 | ||
483 | PACKET_ID_AVATAR_DATA_CONTROL (54) | 497 | PACKET_ID_AVATAR_DATA_CONTROL (54) |
484 | Packet data size: 1 byte | 498 | Packet data size: 1 byte |
485 | [1: uint8_t op] | 499 | [1: uint8_t op] |
486 | 500 | ||
487 | where 'op' is a code signaling both an operation request or a status | 501 | where 'op' is a code signaling either an operation request or a status |
488 | return, which semantics are explained bellow. The following values are | 502 | return, the semantics of which are explained below. The following values are |
489 | defined: | 503 | defined: |
490 | 504 | ||
491 | 0 = AVATAR_DATACONTROL_REQ | 505 | 0 = AVATAR_DATACONTROL_REQ |
492 | 1 = AVATAR_DATACONTROL_ERROR | 506 | 1 = AVATAR_DATACONTROL_ERROR |
493 | 507 | ||
494 | 508 | ||
495 | - Packet `PACKET_ID_AVATAR_DATA_START` have the following format: | 509 | - Packet `PACKET_ID_AVATAR_DATA_START` has the following format: |
496 | 510 | ||
497 | PACKET_ID_AVATAR_DATA_START (55) | 511 | PACKET_ID_AVATAR_DATA_START (55) |
498 | Packet data size: 37 bytes | 512 | Packet data size: 37 bytes |
@@ -501,13 +515,13 @@ types. | |||
501 | 515 | ||
502 | where 'format' is the image format, with the same values accepted for | 516 | where 'format' is the image format, with the same values accepted for |
503 | the field 'format' in packet type `PACKET_ID_AVATAR_INFO`, 'hash' is | 517 | the field 'format' in packet type `PACKET_ID_AVATAR_INFO`, 'hash' is |
504 | the SHA-256 cryptographic hash of the avatar raw data and 'data_length' | 518 | the SHA-256 cryptographic hash of the avatar raw data, and 'data_length' |
505 | is the total number of bytes the raw avatar data. | 519 | is the total number of bytes the raw avatar data. |
506 | 520 | ||
507 | 521 | ||
508 | - Packet `PACKET_ID_AVATAR_DATA_PUSH` has no format structure, just up | 522 | - Packet `PACKET_ID_AVATAR_DATA_PUSH` has no format structure, just up |
509 | to `AVATAR_DATA_MAX_CHUNK_SIZE` bytes of raw avatar image data; this | 523 | to `AVATAR_DATA_MAX_CHUNK_SIZE` bytes of raw avatar image data; this |
510 | value is defined according to the maximum amount of data a Tox crypted | 524 | value is defined according to the maximum amount of data a Tox encrypted |
511 | packet can hold. | 525 | packet can hold. |
512 | 526 | ||
513 | 527 | ||
@@ -520,9 +534,9 @@ from a client "B": | |||
520 | packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to | 534 | packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to |
521 | `AVATAR_DATACONTROL_REQ`. | 535 | `AVATAR_DATACONTROL_REQ`. |
522 | 536 | ||
523 | - If "B" accepts this transfer, it answers by sending an | 537 | - If "B" accepts this transfer, it answers by sending a |
524 | `PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash' and | 538 | `PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash', and |
525 | 'data_length' set to the respective values from the current avatar. | 539 | 'data_length' set to the respective values of the current avatar. |
526 | If "B" has no avatar set, 'format' must be `AVATAR_FORMAT_NONE`, 'hash' | 540 | If "B" has no avatar set, 'format' must be `AVATAR_FORMAT_NONE`, 'hash' |
527 | must be zeroed and 'data_length' must be zero. | 541 | must be zeroed and 'data_length' must be zero. |
528 | 542 | ||
@@ -531,12 +545,12 @@ from a client "B": | |||
531 | `AVATAR_DATACONTROL_ERROR` or simply ignore this request. "A" must cope | 545 | `AVATAR_DATACONTROL_ERROR` or simply ignore this request. "A" must cope |
532 | with this. | 546 | with this. |
533 | 547 | ||
534 | If "B" have an avatar, it sends a variable number of | 548 | If "B" has an avatar, it sends a variable number of |
535 | `PACKET_ID_AVATAR_DATA_PUSH` packets with the avatar data in a single | 549 | `PACKET_ID_AVATAR_DATA_PUSH` packets with the avatar data in a single |
536 | shot. | 550 | shot. |
537 | 551 | ||
538 | - Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it | 552 | - Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it |
539 | has sent a data request to "B". If not, just ignores the packet. | 553 | has sent a data request to "B". If not, it simply ignores the packet. |
540 | 554 | ||
541 | If "A" really requested avatar data and the format is `AVATAR_FORMAT_NONE`, | 555 | If "A" really requested avatar data and the format is `AVATAR_FORMAT_NONE`, |
542 | it triggers the avatar data callback, and clears all the temporary data, | 556 | it triggers the avatar data callback, and clears all the temporary data, |
@@ -545,36 +559,36 @@ from a client "B": | |||
545 | 559 | ||
546 | - Upon receiving a `PACKET_ID_AVATAR_DATA_PUSH`, "A" checks if it really | 560 | - Upon receiving a `PACKET_ID_AVATAR_DATA_PUSH`, "A" checks if it really |
547 | sent an avatar data request and if the `PACKET_ID_AVATAR_DATA_START` was | 561 | sent an avatar data request and if the `PACKET_ID_AVATAR_DATA_START` was |
548 | already received. If this conditions are valid, it checks if the total | 562 | already received. If these conditions were met, it checks if the total |
549 | length of the data already stored in the receiving buffer plus the data | 563 | length of the data already stored in the receiving buffer plus the data |
550 | present in the push packet is still less or equal than | 564 | present in the push packet is still less or equal than |
551 | `TOX_AVATAR_MAX_DATA_LENGTH`. If invalid, it replies with a | 565 | `TOX_AVATAR_MAX_DATA_LENGTH`. If that is not the case, it replies with a |
552 | `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to | 566 | `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to |
553 | `AVATAR_DATACONTROL_ERROR`. | 567 | `AVATAR_DATACONTROL_ERROR`. |
554 | 568 | ||
555 | If valid, "A" updates the 'bytes_received' counter and concatenates the | 569 | If valid, "A" updates the 'bytes_received' counter and concatenates the |
556 | newly arrived data to the buffer. | 570 | newly arrived data to the buffer. |
557 | 571 | ||
558 | The "A" checks if all the data was already received by comparing the | 572 | Then "A" checks if all the data has already been received, by comparing the |
559 | counter 'bytes_received' with the field 'total_length'. If they are | 573 | counter 'bytes_received' with the field 'total_length'. If they are |
560 | equal, "A" takes a SHA-256 hash of the data and compares it with the | 574 | equal, "A" takes a SHA-256 hash of the data and compares it with the |
561 | hash stored in the field 'hash' received from the first | 575 | hash stored in the field 'hash' received with the first |
562 | `PACKET_ID_AVATAR_DATA_START`. | 576 | `PACKET_ID_AVATAR_DATA_START`. |
563 | 577 | ||
564 | If the hashes match, the avatar data was correctly received and "A" | 578 | If the hashes match, the avatar data was correctly received, and "A" |
565 | triggers the avatar data callback, and clears all the temporary data, | 579 | triggers the avatar data callback and clears all the temporary data, |
566 | finishing the process. | 580 | finishing the process. |
567 | 581 | ||
568 | If not all data was received, "A" simply waits for more data. | 582 | If not all data was received, "A" simply waits for more data. |
569 | 583 | ||
570 | Client "A" is always responsible for controlling the transfer and | 584 | Client "A" is always responsible for controlling the transfer and |
571 | validating the data received. "B" don't need to keep any state for the | 585 | validating the data received. "B" doesn't need to keep any state for the |
572 | protocol, have full control over the data sent and should implement | 586 | protocol, have full control over the data sent and should implement |
573 | some transfer limit for the data it sends. | 587 | some transfer limit for the data it sends. |
574 | 588 | ||
575 | - Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' | 589 | - Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' |
576 | set to `AVATAR_DATACONTROL_ERROR` clears any existing control state and | 590 | set to `AVATAR_DATACONTROL_ERROR` clears any existing control state and |
577 | finishes sending or receiving data. | 591 | aborts sending or receiving data. |
578 | 592 | ||
579 | 593 | ||
580 | 594 | ||
@@ -583,33 +597,33 @@ from a client "B": | |||
583 | ## Security considerations | 597 | ## Security considerations |
584 | 598 | ||
585 | The major security implication of background data transfers of large objects, | 599 | The major security implication of background data transfers of large objects, |
586 | like avatars, is the possibility of exhausting the network resources from a | 600 | like avatars, is the possibility of exhausting the network resources of a |
587 | client. This problem is exacerbated when there is the possibility of an | 601 | client. This problem is exacerbated when there is the possibility of an |
588 | amplification attack as happens, for example, when sending a very small | 602 | amplification attack, as happens, for example, when sending a very small |
589 | avatar request message will force the user to reply with a larger avatar | 603 | avatar request message will force the user to reply with a larger avatar |
590 | data message. | 604 | data message. |
591 | 605 | ||
592 | The present proposal mitigates this situation by: | 606 | The present proposal mitigates this situation by: |
593 | 607 | ||
594 | - Only transferring data between previously authenticated friends; | 608 | - only transferring data between previously authenticated friends, |
595 | 609 | ||
596 | - Enforcing strict limits on the avatar data size; | 610 | - enforcing strict limits on the avatar data size, |
597 | 611 | ||
598 | - Providing an alternate, smaller, message to cooperative users refresh | 612 | - providing an alternate, smaller message for cooperative users to refresh |
599 | avatar information when nothing has changed (`PACKET_ID_AVATAR_INFO`); | 613 | avatar information when nothing has changed (`PACKET_ID_AVATAR_INFO`), |
600 | 614 | ||
601 | - Having per-friend data transfer limit. As the current protocol still | 615 | - having a per-friend data transfer limit. As the current protocol still |
602 | allows an user to request avatar data again and again, the implementation | 616 | allows a user to request avatar data again and again, the implementation |
603 | limits the amount of data a particular user can request for some time. The | 617 | limits the amount of data a particular user can request for some time. The |
604 | exact values are defined in constants `AVATAR_DATA_TRANSFER_LIMIT` and | 618 | exact values are defined in constants `AVATAR_DATA_TRANSFER_LIMIT` and |
605 | `AVATAR_DATA_TRANSFER_TIMEOUT` in file `Messenger.c`. | 619 | `AVATAR_DATA_TRANSFER_TIMEOUT` in file `Messenger.c`. |
606 | 620 | ||
607 | - Making the requester responsible for storing partial data and state | 621 | - making the requester responsible for storing partial data and state |
608 | information; | 622 | information |
609 | 623 | ||
610 | Another problem present in the avatars is the possibility of a friend send | 624 | Another problem present in avatars is the possibility of a friend sending |
611 | a maliciously crafted image intended to exploit vulnerabilities in image | 625 | a maliciously crafted image intended to exploit vulnerabilities in image |
612 | decoders. Without an intermediate server to recompress and validate and | 626 | decoders. Without an intermediate server to recompress, validate, and |
613 | convert the images to neutral formats, the client applications must handle | 627 | convert the images to neutral formats, the client applications must handle |
614 | this situation by themselves using stable and secure image libraries and | 628 | this situation by themselves using stable and secure image libraries and |
615 | imposing limits on the maximum amount of system resources the decoding | 629 | imposing limits on the maximum amount of system resources the decoding |
@@ -11,9 +11,11 @@ DHT: | |||
11 | [IN PROGRESS] Hardening against attacks. | 11 | [IN PROGRESS] Hardening against attacks. |
12 | [IN PROGRESS] Optimizing the code. | 12 | [IN PROGRESS] Optimizing the code. |
13 | 13 | ||
14 | [IN PROGRESS] Friend only group chats | 14 | [DONE] Friend only group chats |
15 | [IN PROGRESS] Networking base. | 15 | [DONE] Networking base. |
16 | [IN PROGRESS] Syncing chat state between clients (nicknames, list of who is in chat, etc...) | 16 | [MOSTLY DONE] Syncing chat state between clients (nicknames, list of who is in chat, etc...) |
17 | [NOT STARTED] Private messages. (and adding friends from group chats using those private messages.) | ||
18 | [NOT STARTED] File transfers. | ||
17 | 19 | ||
18 | [IN PROGRESS] Audio/Video | 20 | [IN PROGRESS] Audio/Video |
19 | [DONE] encoding/streaming/decoding | 21 | [DONE] encoding/streaming/decoding |
@@ -22,7 +24,7 @@ DHT: | |||
22 | [IN PROGRESS] Auditing. | 24 | [IN PROGRESS] Auditing. |
23 | [NEEDS TESTING] Video packet splitting. | 25 | [NEEDS TESTING] Video packet splitting. |
24 | [IN PROGRESS] Prevent audio skew (seems to be easily solvable client side.) | 26 | [IN PROGRESS] Prevent audio skew (seems to be easily solvable client side.) |
25 | [IN PROGRESS] Group chats. | 27 | [IN PROGRESS] Group chats, audio done. |
26 | 28 | ||
27 | Friend_requests.c: | 29 | Friend_requests.c: |
28 | [NOT STARTED] What happens when a friend request is received needs to be changed. | 30 | [NOT STARTED] What happens when a friend request is received needs to be changed. |
@@ -30,7 +32,7 @@ Friend_requests.c: | |||
30 | 32 | ||
31 | [DONE] File transfers | 33 | [DONE] File transfers |
32 | [NOT STARTED] Offline messaging | 34 | [NOT STARTED] Offline messaging |
33 | [NOT STARTED] Friends list syncing | 35 | [IN PROGRESS] Friends list syncing |
34 | [DONE] IPV6 support | 36 | [DONE] IPV6 support |
35 | 37 | ||
36 | [IN PROGRESS] Make toxcore thread safe. | 38 | [IN PROGRESS] Make toxcore thread safe. |
@@ -38,14 +40,9 @@ Friend_requests.c: | |||
38 | [NOT STARTED] Make the core save/datafile portable across client versions/different processor architectures. | 40 | [NOT STARTED] Make the core save/datafile portable across client versions/different processor architectures. |
39 | 41 | ||
40 | [MOSTLY DONE] A way for people to connect to people on Tox if they are behind a bad NAT that | 42 | [MOSTLY DONE] A way for people to connect to people on Tox if they are behind a bad NAT that |
41 | blocks UDP (or is just unpunchable) (docs/TCP_Network.txt) | 43 | blocks UDP (or is just unpunchable) (docs/TCP_Network.txt) (Current way doesn't scale very well.) |
42 | 44 | ||
43 | [DONE] Encrypted Saves. (see: toxencryptsave) | 45 | [DONE] Encrypted Saves. (see: toxencryptsave) |
44 | 46 | ||
45 | 47 | ||
46 | [IN PROGRESS] GUI (no official one chosen yet, a list of promising ones follows) | ||
47 | https://github.com/notsecure/uTox | ||
48 | https://github.com/tux3/qTox | ||
49 | https://github.com/Reverp/Toxy | ||
50 | |||
51 | [NOT STARTED] Security audit from professionals | 48 | [NOT STARTED] Security audit from professionals |
diff --git a/docs/Tox_middle_level_network_protocol.txt b/docs/Tox_middle_level_network_protocol.txt index ca561474..69ab9858 100644 --- a/docs/Tox_middle_level_network_protocol.txt +++ b/docs/Tox_middle_level_network_protocol.txt | |||
@@ -3,58 +3,58 @@ feature complete. Why doesn't Tox support TCP yet even if those parts are | |||
3 | complete? | 3 | complete? |
4 | 4 | ||
5 | The answer is that a way to ensure a smooth switchover between the TCP and UDP | 5 | The answer is that a way to ensure a smooth switchover between the TCP and UDP |
6 | needs to be added. If Tox first connects to the other user using TCP but then | 6 | needs to be added. If Tox first connects to the other user using TCP but then, |
7 | due to pure chance manages to connect using the faster direct UDP connection | 7 | due to pure chance, manages to connect using the faster direct UDP connection, |
8 | Tox must switch seamlessly from the TCP to the UDP connection without there | 8 | Tox must switch seamlessly from the TCP to the UDP connection without there |
9 | being any data loss or the other user going offline and then back online. The | 9 | being any data loss or the other user going offline and then back online. The |
10 | transition must be seamless whatever both connected users are doing be it | 10 | transition must be seamless whatever both connected users are doing - be it |
11 | transferring files or simply chatting together. | 11 | transferring files or simply chatting together. |
12 | 12 | ||
13 | Possible evil/bad or simply TCP relays going offline must not impact the | 13 | Possible evil/bad or simply TCP relays going offline must not impact the |
14 | connection between both clients. | 14 | connection between both clients. |
15 | 15 | ||
16 | Typically Tox will use more than one TCP relay to connect to other peers for | 16 | Typically, Tox will use more than one TCP relay to connect to other peers for |
17 | maximum connection stability which means there must be a way for Tox to take | 17 | maximum connection stability, which means there must be a way for Tox to take |
18 | advantage of multiple relays in a way that the user will never be aware if one | 18 | advantage of multiple relays in a way that the user will never be aware of, if one |
19 | of them goes offline/tries to slow down the connection/decides to corrupt | 19 | of them goes offline/tries to slow down the connection/decides to corrupt |
20 | packets/etc.. | 20 | packets/etc. |
21 | 21 | ||
22 | To accomplish this Tox needs something between the low level protocol (TCP) and | 22 | To accomplish this, Tox needs something between the low level protocol (TCP) and |
23 | high level Tox messaging protocol hence the name middle level. | 23 | high level Tox messaging protocol; hence the name middle level. |
24 | 24 | ||
25 | The plan is to move some functionality from lossless_UDP to a higher level: | 25 | The plan is to move some functionality from lossless_UDP to a higher level: |
26 | more specifically the functionality for detecting which packets a peer is | 26 | more specifically, the functionality for detecting which packets a peer is |
27 | missing and the ability to request and send them again. lossless UDP uses plain | 27 | missing, and the ability to request and send them again. Lossless UDP uses plain |
28 | text packets to request missing packets from the other peer while Tox is | 28 | text packets to request missing packets from the other peer, while Tox is |
29 | currently designed to kill the connection if any packet tampering is detected. | 29 | currently designed to kill the connection if any packet tampering is detected. |
30 | This works very well when connecting directly with someone because if the | 30 | This works very well when connecting directly with someone because if the |
31 | attacker can modify packets it means he can kill your connection anyways. With | 31 | attacker can modify packets, it means he can kill your connection anyway. With |
32 | TCP relays however that is not the case as such the packets used to request | 32 | TCP relays, however, that is not the case. As such the packets used to request |
33 | missing packets must be encrypted. If it is detected that a packet has been | 33 | missing packets must be encrypted. If it is detected that a packet has been |
34 | tampered, the connection must stay intact while the evil relay must be | 34 | tampered, the connection must stay intact while the evil relay must be |
35 | disconnected from and replaced with a good relay, the behavior must be the same | 35 | disconnected from and replaced with a good relay; the behavior must be the same |
36 | as if the relay had just suddenly gone online. Of course something to protect | 36 | as if the relay had just suddenly gone offline. Of course, something to protect |
37 | from evil "friends" framing relays must also be implemented. | 37 | from evil "friends" framing relays must also be implemented. |
38 | 38 | ||
39 | Detailed implementation details: | 39 | Detailed implementation details: |
40 | 40 | ||
41 | cookie request packet: | 41 | cookie request packet: |
42 | [uint8_t 24][Senders DHT Public key (32 bytes)][Random nonce (24 | 42 | [uint8_t 24][Sender's DHT Public key (32 bytes)][Random nonce (24 |
43 | bytes)][Encrypted message containing: [Senders real public key (32 | 43 | bytes)][Encrypted message containing: [Sender's real public key (32 |
44 | bytes)][padding (32 bytes)][uint64_t number (must be sent | 44 | bytes)][padding (32 bytes)][uint64_t number (must be sent |
45 | back untouched in cookie response)]] | 45 | back untouched in cookie response)]] |
46 | Encrypted message is encrypted with sender DHT private key, receivers DHT | 46 | Encrypted message is encrypted with sender's DHT private key, receiver's DHT |
47 | public key and the nonce. | 47 | public key and the nonce. |
48 | 48 | ||
49 | cookie response packet: | 49 | cookie response packet: |
50 | [uint8_t 25][Random nonce (24 bytes)][Encrypted message containing: | 50 | [uint8_t 25][Random nonce (24 bytes)][Encrypted message containing: |
51 | [Cookie][uint64_t number (that was sent in the request)]] | 51 | [Cookie][uint64_t number (that was sent in the request)]] |
52 | Encrypted message is encrypted with sender DHT private key, receivers DHT | 52 | Encrypted message is encrypted with sender's DHT private key, receiver's DHT |
53 | public key and the nonce. | 53 | public key and the nonce. |
54 | 54 | ||
55 | The Cookie should be basically: | 55 | The Cookie should be basically: |
56 | [nonce][encrypted data:[uint64_t time][Senders real public key (32 | 56 | [nonce][encrypted data:[uint64_t time][Sender's real public key (32 |
57 | bytes)][Senders dht public key (32 bytes)]] | 57 | bytes)][Sender's DHT public key (32 bytes)]] |
58 | 58 | ||
59 | Handshake packet: | 59 | Handshake packet: |
60 | [uint8_t 26][Cookie][nonce][Encrypted message containing: [random 24 bytes base | 60 | [uint8_t 26][Cookie][nonce][Encrypted message containing: [random 24 bytes base |
@@ -66,25 +66,25 @@ The handshake packet is encrypted using the real private key of the sender, the | |||
66 | real public key of the receiver and the nonce. | 66 | real public key of the receiver and the nonce. |
67 | 67 | ||
68 | 68 | ||
69 | Alice wants to connect to bob. | 69 | Alice wants to connect to Bob: |
70 | 70 | ||
71 | Alice sends a cookie request packet to bob and gets a cookie response back. | 71 | Alice sends a cookie request packet to Bob and gets a cookie response back. |
72 | 72 | ||
73 | Alice then generates a nonce and a temporary public/private keypair. | 73 | Alice then generates a nonce and a temporary public/private keypair. |
74 | 74 | ||
75 | Alice then takes that nonce and just generated private key, the obtained | 75 | Alice then takes that nonce and just generated private key, the obtained |
76 | cookie, creates a new cookie and puts them in a handshake packet which she | 76 | cookie, creates a new cookie and puts them in a handshake packet, which she |
77 | sends to bob. | 77 | sends to Bob. |
78 | 78 | ||
79 | Bob gets the handshake packet, accepts the connection request, then generates a | 79 | Bob gets the handshake packet, accepts the connection request, then generates a |
80 | nonce and a temporary public/private keypair and sends a handshake packet back | 80 | nonce and a temporary public/private keypair and sends a handshake packet back |
81 | with this just generated information and with the cookie field being the Other | 81 | with this just generated information and with the cookie field being the Other |
82 | Cookie contained in the received handshake. | 82 | Cookie contained in the received handshake. |
83 | 83 | ||
84 | Both then use these temporary keys to generate the session key with which every | 84 | Both then use these temporary keys to generate the session key, with which every |
85 | data packet sent and received will be encrypted and decrypted. The nonce sent | 85 | data packet sent and received will be encrypted and decrypted. The nonce sent |
86 | in the handshake will be used to encrypt the first data packet sent, the nonce | 86 | in the handshake will be used to encrypt the first data packet sent, the nonce |
87 | + 1 the second, the nonce + 2 the third and so on. | 87 | + 1 for the second, the nonce + 2 for the third, and so on. |
88 | 88 | ||
89 | Data packets: | 89 | Data packets: |
90 | 90 | ||
@@ -109,12 +109,12 @@ data ids: | |||
109 | packet request packet: [uint8_t (1)][uint8_t num][uint8_t num][uint8_t | 109 | packet request packet: [uint8_t (1)][uint8_t num][uint8_t num][uint8_t |
110 | num]...[uint8_t num] | 110 | num]...[uint8_t num] |
111 | 111 | ||
112 | the list of nums are a list of packet numbers the other is requesting. | 112 | The list of nums are a list of packet numbers the other is requesting. |
113 | to get the real packet numbers from this list take the recvbuffers buffer_start | 113 | In order to get the real packet numbers from this list, take the recvbuffers buffer_start |
114 | from the packet, subtract 1 to it and put it in packet_num then start from the | 114 | from the packet, subtract 1 from it and put it in packet_num, then start from the |
115 | beginning of the num list: if num is zero, add 255 to packet_num then do the | 115 | beginning of the num list: if num is zero, add 255 to packet_num, then do the |
116 | next num. if num isn't zero, add its value to packet_num, note that the other | 116 | next num. If num isn't zero, add its value to packet_num, note that the other |
117 | has requested we send this packet again to them then continue to the next num in | 117 | has requested we send this packet again to them, then continue to the next num in |
118 | the list. | 118 | the list. |
119 | 119 | ||
120 | 120 | ||
diff --git a/other/bootstrap_daemon/README.md b/other/bootstrap_daemon/README.md index 9a2dff4b..d0c16eb1 100644 --- a/other/bootstrap_daemon/README.md +++ b/other/bootstrap_daemon/README.md | |||
@@ -1,29 +1,32 @@ | |||
1 | ##Instructions for Debian | 1 | ##Instructions |
2 | |||
3 | This instruction primarily tested on Linux but, may be, will work on other POSIX-compliant systems. | ||
2 | 4 | ||
3 | For security reasons we run the daemon under its own user. | 5 | For security reasons we run the daemon under its own user. |
6 | |||
4 | Create a new user by executing the following: | 7 | Create a new user by executing the following: |
5 | ```sh | 8 | ```sh |
6 | sudo useradd --system --shell /sbin/nologin --comment "Account to run Tox's DHT bootstrap daemon" --user-group tox-bootstrapd | 9 | sudo useradd --home-dir /var/lib/tox-bootstrapd --create-home --system --shell /sbin/nologin --comment "Account to run Tox's DHT bootstrap daemon" --user-group tox-bootstrapd |
7 | ``` | 10 | ``` |
8 | 11 | ||
9 | Create a directory where the daemon will store its keys: | 12 | Copy `tox-bootstrapd.conf` file to where `CFGFILE` variable from `tox-bootstrapd.sh` tells (for `init.d` users) or `ExecStart=` from `tox-bootstrap.service` ( for `systemd` users). By default it's `/etc/tox-bootstrapd.conf`. |
10 | ```sh | 13 | |
11 | sudo mkdir /var/lib/tox-bootstrapd/ | 14 | Go over everything in `tox-bootstrapd.conf`. Make sure `pid_file_path` matches `PIDFILE` from `tox-bootstrapd.sh` (`init.d`) or `PIDFile=` from `tox-bootstrap.service` AND file in `ExecStartPre`(`systemd`). |
12 | ``` | 15 | |
13 | 16 | ||
14 | Restrain other users from accessing the directory: | 17 | Restrict access to home directory: |
15 | ```sh | 18 | ```sh |
16 | sudo chown tox-bootstrapd:tox-bootstrapd /var/lib/tox-bootstrapd/ | 19 | sudo chmod 700 /var/lib/tox-bootstrapd |
17 | sudo chmod 700 /var/lib/tox-bootstrapd/ | ||
18 | ``` | 20 | ``` |
19 | 21 | ||
20 | Look at the variable declarations in the beginning of `tox-bootstrapd.sh` init script to see if you need to change anything for it to work for you. The default values must be fine for most users and we assume that you use those next. | 22 | ##For `init.d` users: |
21 | |||
22 | Go over everything in `tox-bootstrapd.conf`. Make sure `pid_file_path` matches `PIDFILE` from `tox-bootstrapd.sh`. | ||
23 | 23 | ||
24 | Place `tox-bootstrapd.conf` file to where `CFGFILE` variable from `tox-bootstrapd.sh` tells. By default it's `/etc/tox-bootstrapd.conf`. | 24 | Look at the variable declarations in the beginning of `tox-bootstrapd.sh` init script to see if you need to change anything for it to work for you. The default values must be fine for most users and we assume that you use those next. |
25 | 25 | ||
26 | Place `tox-bootstrapd.sh` init file at `/etc/init.d/tox-bootstrapd` (note the disappearance of ".sh" ending). | 26 | Copy `tox-bootstrapd.sh` init file to `/etc/init.d/tox-bootstrapd` (note the disappearance of ".sh" ending). |
27 | ```sh | ||
28 | sudo cp tox-bootstrapd.sh /etc/init.d/tox-bootstrapd | ||
29 | ``` | ||
27 | 30 | ||
28 | Set permissions for the init system to run the script: | 31 | Set permissions for the init system to run the script: |
29 | ```sh | 32 | ```sh |
@@ -50,23 +53,56 @@ Get your public key and check that the daemon initialized correctly: | |||
50 | sudo grep "tox-bootstrapd" /var/log/syslog | 53 | sudo grep "tox-bootstrapd" /var/log/syslog |
51 | ``` | 54 | ``` |
52 | 55 | ||
56 | ##For `systemd` users: | ||
57 | |||
58 | Copy tox-bootstrap.service to /etc/systemd/system/: | ||
59 | ```sh | ||
60 | sudo cp tox-bootstrap.service /etc/systemd/system/ | ||
61 | ``` | ||
62 | |||
63 | Make sure, that path to `chown` and `mkdir` is correct in `tox-bootstrap.service` (they may be different in some distributions, by default `/bin/chown` and `/bin/mkdir`) | ||
64 | |||
65 | You must uncomment the next line in tox-bootstrap.service, if you want to use port number <1024 | ||
66 | |||
67 | #CapabilityBoundingSet=CAP_NET_BIND_SERVICE | ||
68 | |||
69 | and, possibly, install `libcap2-bin` or `libcap2` package, depending of your distribution. | ||
70 | |||
53 | 71 | ||
72 | Reload systemd units definitions, enable service for automatic start (if needed), and start it: | ||
73 | ```sh | ||
74 | sudo systemctl daemon-reload | ||
75 | sudo systemctl enable tox-bootstrap.service | ||
76 | sudo systemctl start tox-bootstrap.service | ||
77 | ``` | ||
54 | ###Troubleshooting: | 78 | ###Troubleshooting: |
55 | 79 | ||
56 | - Check daemon's status: | 80 | - Check daemon's status: |
57 | ```sh | 81 | ```sh |
82 | #init.d | ||
58 | sudo service tox-bootstrapd status | 83 | sudo service tox-bootstrapd status |
84 | |||
85 | #systemd | ||
86 | sudo systemctl status tox-bootstrap.service | ||
59 | ``` | 87 | ``` |
60 | 88 | ||
61 | - Check the log for errors: | 89 | - Check the log for errors: |
62 | ```sh | 90 | ```sh |
91 | #init.d | ||
63 | sudo grep "tox-bootstrapd" /var/log/syslog | 92 | sudo grep "tox-bootstrapd" /var/log/syslog |
93 | |||
94 | #systemd | ||
95 | sudo journalctl -f _SYSTEMD_UNIT=tox-bootstrap.service | ||
64 | ``` | 96 | ``` |
65 | 97 | ||
98 | `init.d`: | ||
66 | - Check that variables in the beginning of `/etc/init.d/tox-bootstrapd` are valid. | 99 | - Check that variables in the beginning of `/etc/init.d/tox-bootstrapd` are valid. |
67 | 100 | ||
68 | - Make sure `pid_file_path` in `/etc/tox-bootstrapd.conf` matches `PIDFILE` from `/etc/init.d/tox-bootstrapd`. | ||
69 | 101 | ||
70 | - Make sure you have write permission for keys and pid files. | 102 | Common: |
103 | |||
104 | - Make sure tox-bootstrapd user has write permission for keys and pid files (in systemd pid file insured by unit definition). | ||
105 | |||
106 | - Make sure tox-bootstrapd has read permission for the config file. | ||
71 | 107 | ||
72 | - Make sure you have read permission for the config file. | 108 | - Make sure tox-bootstrapd location matches its path in init scripts, if you specified non-default `--prefix`, when building. |
diff --git a/other/bootstrap_daemon/tox-bootstrapd.conf b/other/bootstrap_daemon/tox-bootstrapd.conf index 4547d83d..d02eb3d0 100644 --- a/other/bootstrap_daemon/tox-bootstrapd.conf +++ b/other/bootstrap_daemon/tox-bootstrapd.conf | |||
@@ -24,8 +24,8 @@ enable_lan_discovery = true | |||
24 | 24 | ||
25 | enable_tcp_relay = true | 25 | enable_tcp_relay = true |
26 | 26 | ||
27 | // Tox uses 443, 3389 and 33445 ports by default, so it's highly encouraged to keep | 27 | // While Tox uses 33445 port by default, 443 (https) and 3389 (rdp) ports are very |
28 | // them. | 28 | // common among nodes, so it's encouraged to keep them in place. |
29 | tcp_relay_ports = [443, 3389, 33445] | 29 | tcp_relay_ports = [443, 3389, 33445] |
30 | 30 | ||
31 | // Reply to MOTD (Message Of The Day) requests. | 31 | // Reply to MOTD (Message Of The Day) requests. |
@@ -45,48 +45,21 @@ motd = "tox-bootstrapd" | |||
45 | // in both cases this will be interpreted as if you don't want to bootstrap | 45 | // in both cases this will be interpreted as if you don't want to bootstrap |
46 | // from anyone. | 46 | // from anyone. |
47 | // | 47 | // |
48 | // address = any ipv4 or ipv6 address and also any US-ASCII domain name. | 48 | // address = any IPv4 or IPv6 address and also any US-ASCII domain name. |
49 | bootstrap_nodes = ( | 49 | bootstrap_nodes = ( |
50 | { | 50 | { // Example Node 1 (IPv4) |
51 | // NikolaiToryzin - US | 51 | address = "127.0.0.1" |
52 | address = "192.254.75.98" | ||
53 | port = 33445 | 52 | port = 33445 |
54 | public_key = "951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F" | 53 | public_key = "728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854" |
55 | }, | 54 | }, |
56 | { | 55 | { // Example Node 2 (IPv6) |
57 | // Proplex - US | 56 | address = "::1/128" |
58 | address = "107.161.17.51" | ||
59 | port = 33445 | 57 | port = 33445 |
60 | public_key = "7BE3951B97CA4B9ECDDA768E8C52BA19E9E2690AB584787BF4C90E04DBB75111" | 58 | public_key = "3E78BACF0F84235B30054B54898F56793E1DEF8BD46B1038B9D822E8460FAB67" |
61 | }, | 59 | }, |
62 | { | 60 | { // Example Node 3 (US-ASCII domain name) |
63 | // SonOfRa - DE | 61 | address = "example.org" |
64 | address = "144.76.60.215" | ||
65 | port = 33445 | 62 | port = 33445 |
66 | public_key = "04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F" | 63 | public_key = "8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858" |
67 | }, | ||
68 | { | ||
69 | // Astonex - FR | ||
70 | address = "37.59.102.176" | ||
71 | port = 33445 | ||
72 | public_key = "B98A2CEAA6C6A2FADC2C3632D284318B60FE5375CCB41EFA081AB67F500C1B0B" | ||
73 | }, | ||
74 | { | ||
75 | // SylvieLorxu - NL | ||
76 | address = "178.21.112.187" | ||
77 | port = 33445 | ||
78 | public_key = "4B2C19E924972CB9B57732FB172F8A8604DE13EEDA2A6234E348983344B23057" | ||
79 | }, | ||
80 | { | ||
81 | // aitjcize - JP | ||
82 | address = "54.199.139.199" | ||
83 | port = 33445 | ||
84 | public_key = "7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029" | ||
85 | }, | ||
86 | { | ||
87 | // NikolaiToryzin - CH | ||
88 | address = "31.7.57.236" | ||
89 | port = 443 | ||
90 | public_key = "2A4B50D1D525DA2E669592A20C327B5FAD6C7E5962DC69296F9FEC77C4436E4E" | ||
91 | } | 64 | } |
92 | ) | 65 | ) \ No newline at end of file |
diff --git a/other/bootstrap_daemon/tox-bootstrapd.service b/other/bootstrap_daemon/tox-bootstrapd.service new file mode 100644 index 00000000..4b499311 --- /dev/null +++ b/other/bootstrap_daemon/tox-bootstrapd.service | |||
@@ -0,0 +1,19 @@ | |||
1 | [Unit] | ||
2 | Description=Tox DHT Bootstrap Daemon | ||
3 | After=network.target | ||
4 | |||
5 | [Service] | ||
6 | Type=forking | ||
7 | PermissionsStartOnly=true | ||
8 | ExecStartPre=-/bin/mkdir /var/run/tox-bootstrapd -p | ||
9 | ExecStartPre=/bin/chown tox-bootstrapd:tox-bootstrapd -R /var/run/tox-bootstrapd | ||
10 | WorkingDirectory=/var/lib/tox-bootstrapd | ||
11 | ExecStart=/usr/local/bin/tox-bootstrapd /etc/tox-bootstrapd.conf | ||
12 | User=tox-bootstrapd | ||
13 | Group=tox-bootstrapd | ||
14 | PIDFile=/var/run/tox-bootstrapd/tox-bootstrapd.pid | ||
15 | #CapabilityBoundingSet=CAP_NET_BIND_SERVICE | ||
16 | |||
17 | [Install] | ||
18 | WantedBy=multi-user.target | ||
19 | |||
diff --git a/other/bootstrap_node_packets.c b/other/bootstrap_node_packets.c index e8df3289..0bf9b9b0 100644 --- a/other/bootstrap_node_packets.c +++ b/other/bootstrap_node_packets.c | |||
@@ -34,7 +34,7 @@ static uint16_t bootstrap_motd_length; | |||
34 | /* To request this packet just send a packet of length INFO_REQUEST_PACKET_LENGTH | 34 | /* To request this packet just send a packet of length INFO_REQUEST_PACKET_LENGTH |
35 | * with the first byte being BOOTSTRAP_INFO_PACKET_ID | 35 | * with the first byte being BOOTSTRAP_INFO_PACKET_ID |
36 | */ | 36 | */ |
37 | static int handle_info_request(void *object, IP_Port source, const uint8_t *packet, uint32_t length) | 37 | static int handle_info_request(void *object, IP_Port source, const uint8_t *packet, uint16_t length) |
38 | { | 38 | { |
39 | if (length != INFO_REQUEST_PACKET_LENGTH) | 39 | if (length != INFO_REQUEST_PACKET_LENGTH) |
40 | return 1; | 40 | return 1; |
diff --git a/other/fun/make-funny-savefile.py b/other/fun/make-funny-savefile.py new file mode 100755 index 00000000..43f14a6e --- /dev/null +++ b/other/fun/make-funny-savefile.py | |||
@@ -0,0 +1,122 @@ | |||
1 | #!/usr/bin/python | ||
2 | |||
3 | """ | ||
4 | Generate a new (and empty) save file with predefined keys. Used to play | ||
5 | with externally generated keys. | ||
6 | |||
7 | (c) 2015 Alexandre Erwin Ittner | ||
8 | |||
9 | Distributed under the GNU GPL v3 or later, WITHOUT ANY WARRANTY. See the | ||
10 | file "COPYING" for license information. | ||
11 | |||
12 | |||
13 | Usage: | ||
14 | |||
15 | ./make-funny-savefile.py <public key> <private key> <user name> <out file> | ||
16 | |||
17 | The new user profile will be saved to <out file>. | ||
18 | |||
19 | The keys must be an hex-encoded valid key pair generated by any means | ||
20 | (eg. strkey.c); username may be anything. A random nospam value will be | ||
21 | generated. | ||
22 | |||
23 | Once the savefile is done, load it in your favorite client to get some | ||
24 | DHT nodes, set status and status messages, add friends, etc. | ||
25 | |||
26 | |||
27 | Example (of course, do not try using this key for anything real): | ||
28 | |||
29 | ./make-funny-savefile.py 123411DC8B1A4760B648E0C7243B65F01069E4858F45C612CE1A6F673B603830 CC39440CFC063E4A95B7F2FB2580210558BE5C073AFC1C9604D431CCA3132238 "Test user" test.tox | ||
30 | |||
31 | |||
32 | """ | ||
33 | |||
34 | |||
35 | PUBLIC_KEY_LENGTH = 32 | ||
36 | PRIVATE_KEY_LENGTH = 32 | ||
37 | |||
38 | # Constants taken from messenger.c | ||
39 | MESSENGER_STATE_COOKIE_GLOBAL = 0x15ed1b1f | ||
40 | MESSENGER_STATE_COOKIE_TYPE = 0x01ce | ||
41 | MESSENGER_STATE_TYPE_NOSPAMKEYS = 1 | ||
42 | MESSENGER_STATE_TYPE_DHT = 2 | ||
43 | MESSENGER_STATE_TYPE_FRIENDS = 3 | ||
44 | MESSENGER_STATE_TYPE_NAME = 4 | ||
45 | MESSENGER_STATE_TYPE_STATUSMESSAGE = 5 | ||
46 | MESSENGER_STATE_TYPE_STATUS = 6 | ||
47 | MESSENGER_STATE_TYPE_TCP_RELAY = 10 | ||
48 | MESSENGER_STATE_TYPE_PATH_NODE = 11 | ||
49 | |||
50 | STATUS_MESSAGE = "New user".encode("utf-8") | ||
51 | |||
52 | |||
53 | |||
54 | import sys | ||
55 | import struct | ||
56 | import os | ||
57 | |||
58 | def abort(msg): | ||
59 | print(msg) | ||
60 | exit(1) | ||
61 | |||
62 | |||
63 | |||
64 | if len(sys.argv) != 5: | ||
65 | abort("Usage: %s <public key> <private key> <user name> <out file>" % (sys.argv[0])) | ||
66 | |||
67 | try: | ||
68 | public_key = sys.argv[1].decode("hex") | ||
69 | except: | ||
70 | abort("Bad public key") | ||
71 | |||
72 | try: | ||
73 | private_key = sys.argv[2].decode("hex") | ||
74 | except: | ||
75 | abort("Bad private key") | ||
76 | |||
77 | if len(public_key) != PUBLIC_KEY_LENGTH: | ||
78 | abort("Public key with wrong length") | ||
79 | |||
80 | if len(private_key) != PRIVATE_KEY_LENGTH: | ||
81 | abort("Private key with wrong length") | ||
82 | |||
83 | user_name = sys.argv[3].encode("utf-8") | ||
84 | |||
85 | if len(user_name) > 32: | ||
86 | abort("User name too long (for this script, at least)") | ||
87 | |||
88 | out_file_name = sys.argv[4] | ||
89 | nospam = os.urandom(4) | ||
90 | |||
91 | |||
92 | def make_subheader(h_type, h_length): | ||
93 | return ( | ||
94 | struct.pack("<I", h_length) + | ||
95 | struct.pack("<H", h_type) + | ||
96 | struct.pack("<H", MESSENGER_STATE_COOKIE_TYPE)) | ||
97 | |||
98 | data = ( | ||
99 | # Main header | ||
100 | struct.pack("<I", 0) + | ||
101 | struct.pack("<I", MESSENGER_STATE_COOKIE_GLOBAL) + | ||
102 | |||
103 | # Keys | ||
104 | make_subheader(MESSENGER_STATE_TYPE_NOSPAMKEYS, | ||
105 | len(nospam) + PUBLIC_KEY_LENGTH + PRIVATE_KEY_LENGTH) + | ||
106 | nospam + public_key + private_key + | ||
107 | |||
108 | # Name (not really needed, but helps) | ||
109 | make_subheader(MESSENGER_STATE_TYPE_NAME, len(user_name)) + | ||
110 | user_name + | ||
111 | |||
112 | # Status message (not really needed, but helps) | ||
113 | make_subheader(MESSENGER_STATE_TYPE_STATUSMESSAGE, len(STATUS_MESSAGE)) + | ||
114 | STATUS_MESSAGE | ||
115 | ) | ||
116 | |||
117 | |||
118 | try: | ||
119 | with open(out_file_name, "wb") as fp: | ||
120 | fp.write(data) | ||
121 | except Exception as e: | ||
122 | abort(str(e)) | ||
diff --git a/osx_build_script_toxcore.txt b/other/osx_build_script_toxcore.sh index 8aea0d1c..8aea0d1c 100644 --- a/osx_build_script_toxcore.txt +++ b/other/osx_build_script_toxcore.sh | |||
diff --git a/testing/test_avatars.c b/testing/test_avatars.c index 71a0330e..b4adc48f 100644 --- a/testing/test_avatars.c +++ b/testing/test_avatars.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * Data dir MAY have: | 18 | * Data dir MAY have: |
19 | * | 19 | * |
20 | * - A directory named "avatars" with the user's avatar and cached avatars. | 20 | * - A directory named "avatars" with the user's avatar and cached avatars. |
21 | * The user avatar must be named in the format: "<uppercase user id>.png" | 21 | * The user avatar must be named in the format: "<uppercase pub key>.png" |
22 | * | 22 | * |
23 | * | 23 | * |
24 | * The bot will answer to these commands: | 24 | * The bot will answer to these commands: |
@@ -163,14 +163,14 @@ static void byte_to_hex_str(const uint8_t *buf, const size_t buflen, char *dst) | |||
163 | dst[j++] = '\0'; | 163 | dst[j++] = '\0'; |
164 | } | 164 | } |
165 | 165 | ||
166 | /* Make the cache file name for a avatar of the given format for the given | 166 | /* Make the cache file name for an avatar of the given format for the given |
167 | * client id. | 167 | * public key. |
168 | */ | 168 | */ |
169 | static int make_avatar_file_name(char *dst, size_t dst_len, const char *base_dir, | 169 | static int make_avatar_file_name(char *dst, size_t dst_len, const char *base_dir, |
170 | const uint8_t format, uint8_t *client_id) | 170 | const uint8_t format, uint8_t *public_key) |
171 | { | 171 | { |
172 | char client_id_str[2 * TOX_CLIENT_ID_SIZE + 1]; | 172 | char public_key_str[2 * TOX_PUBLIC_KEY_SIZE + 1]; |
173 | byte_to_hex_str(client_id, TOX_CLIENT_ID_SIZE, client_id_str); | 173 | byte_to_hex_str(public_key, TOX_PUBLIC_KEY_SIZE, public_key_str); |
174 | 174 | ||
175 | const char *suffix = get_avatar_suffix_from_format(format); | 175 | const char *suffix = get_avatar_suffix_from_format(format); |
176 | 176 | ||
@@ -178,7 +178,7 @@ static int make_avatar_file_name(char *dst, size_t dst_len, const char *base_dir | |||
178 | return -1; /* Error */ | 178 | return -1; /* Error */ |
179 | 179 | ||
180 | int n = snprintf(dst, dst_len, "%s/%s/%s.%s", base_dir, AVATAR_DIR_NAME, | 180 | int n = snprintf(dst, dst_len, "%s/%s/%s.%s", base_dir, AVATAR_DIR_NAME, |
181 | client_id_str, suffix); | 181 | public_key_str, suffix); |
182 | dst[dst_len - 1] = '\0'; | 182 | dst[dst_len - 1] = '\0'; |
183 | 183 | ||
184 | if (n >= dst_len) | 184 | if (n >= dst_len) |
@@ -196,7 +196,7 @@ static int make_avatar_file_name(char *dst, size_t dst_len, const char *base_dir | |||
196 | static int load_user_avatar(Tox *tox, char *base_dir, int friendnum, | 196 | static int load_user_avatar(Tox *tox, char *base_dir, int friendnum, |
197 | uint8_t format, uint8_t *hash, uint8_t *data, uint32_t *datalen) | 197 | uint8_t format, uint8_t *hash, uint8_t *data, uint32_t *datalen) |
198 | { | 198 | { |
199 | uint8_t addr[TOX_CLIENT_ID_SIZE]; | 199 | uint8_t addr[TOX_PUBLIC_KEY_SIZE]; |
200 | 200 | ||
201 | if (tox_get_client_id(tox, friendnum, addr) != 0) { | 201 | if (tox_get_client_id(tox, friendnum, addr) != 0) { |
202 | DEBUG("Bad client id, friendnumber=%d", friendnum); | 202 | DEBUG("Bad client id, friendnumber=%d", friendnum); |
@@ -224,14 +224,14 @@ static int load_user_avatar(Tox *tox, char *base_dir, int friendnum, | |||
224 | return 0; | 224 | return 0; |
225 | } | 225 | } |
226 | 226 | ||
227 | /* Save a user avatar into the cache. Gets the file name from client id and | 227 | /* Save a user avatar into the cache. Gets the file name from the public key |
228 | * the given data format. | 228 | * and the given data format. |
229 | * Returns 0 on success, or -1 on error. | 229 | * Returns 0 on success, or -1 on error. |
230 | */ | 230 | */ |
231 | static int save_user_avatar(Tox *tox, char *base_dir, int friendnum, | 231 | static int save_user_avatar(Tox *tox, char *base_dir, int friendnum, |
232 | uint8_t format, uint8_t *data, uint32_t datalen) | 232 | uint8_t format, uint8_t *data, uint32_t datalen) |
233 | { | 233 | { |
234 | uint8_t addr[TOX_CLIENT_ID_SIZE]; | 234 | uint8_t addr[TOX_PUBLIC_KEY_SIZE]; |
235 | 235 | ||
236 | if (tox_get_client_id(tox, friendnum, addr) != 0) { | 236 | if (tox_get_client_id(tox, friendnum, addr) != 0) { |
237 | DEBUG("Bad client id, friendnumber=%d", friendnum); | 237 | DEBUG("Bad client id, friendnumber=%d", friendnum); |
@@ -252,7 +252,7 @@ static int save_user_avatar(Tox *tox, char *base_dir, int friendnum, | |||
252 | /* Delete all cached avatars for a given user */ | 252 | /* Delete all cached avatars for a given user */ |
253 | static int delete_user_avatar(Tox *tox, char *base_dir, int friendnum) | 253 | static int delete_user_avatar(Tox *tox, char *base_dir, int friendnum) |
254 | { | 254 | { |
255 | uint8_t addr[TOX_CLIENT_ID_SIZE]; | 255 | uint8_t addr[TOX_PUBLIC_KEY_SIZE]; |
256 | 256 | ||
257 | if (tox_get_client_id(tox, friendnum, addr) != 0) { | 257 | if (tox_get_client_id(tox, friendnum, addr) != 0) { |
258 | DEBUG("Bad client id, friendnumber=%d", friendnum); | 258 | DEBUG("Bad client id, friendnumber=%d", friendnum); |
@@ -288,11 +288,11 @@ static int delete_user_avatar(Tox *tox, char *base_dir, int friendnum) | |||
288 | 288 | ||
289 | static void friend_status_cb(Tox *tox, int n, uint8_t status, void *ud) | 289 | static void friend_status_cb(Tox *tox, int n, uint8_t status, void *ud) |
290 | { | 290 | { |
291 | uint8_t addr[TOX_CLIENT_ID_SIZE]; | 291 | uint8_t addr[TOX_PUBLIC_KEY_SIZE]; |
292 | char addr_str[2 * TOX_CLIENT_ID_SIZE + 1]; | 292 | char addr_str[2 * TOX_PUBLIC_KEY_SIZE + 1]; |
293 | 293 | ||
294 | if (tox_get_client_id(tox, n, addr) == 0) { | 294 | if (tox_get_client_id(tox, n, addr) == 0) { |
295 | byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str); | 295 | byte_to_hex_str(addr, TOX_PUBLIC_KEY_SIZE, addr_str); |
296 | printf("Receiving status from %s: %u\n", addr_str, status); | 296 | printf("Receiving status from %s: %u\n", addr_str, status); |
297 | } | 297 | } |
298 | } | 298 | } |
@@ -300,12 +300,12 @@ static void friend_status_cb(Tox *tox, int n, uint8_t status, void *ud) | |||
300 | static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t *hash, void *ud) | 300 | static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t *hash, void *ud) |
301 | { | 301 | { |
302 | char *base_dir = (char *) ud; | 302 | char *base_dir = (char *) ud; |
303 | uint8_t addr[TOX_CLIENT_ID_SIZE]; | 303 | uint8_t addr[TOX_PUBLIC_KEY_SIZE]; |
304 | char addr_str[2 * TOX_CLIENT_ID_SIZE + 1]; | 304 | char addr_str[2 * TOX_PUBLIC_KEY_SIZE + 1]; |
305 | char hash_str[2 * TOX_HASH_LENGTH + 1]; | 305 | char hash_str[2 * TOX_HASH_LENGTH + 1]; |
306 | 306 | ||
307 | if (tox_get_client_id(tox, n, addr) == 0) { | 307 | if (tox_get_client_id(tox, n, addr) == 0) { |
308 | byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str); | 308 | byte_to_hex_str(addr, TOX_PUBLIC_KEY_SIZE, addr_str); |
309 | printf("Receiving avatar information from %s.\n", addr_str); | 309 | printf("Receiving avatar information from %s.\n", addr_str); |
310 | } else { | 310 | } else { |
311 | DEBUG("tox_get_client_id failed"); | 311 | DEBUG("tox_get_client_id failed"); |
@@ -350,12 +350,12 @@ static void friend_avatar_data_cb(Tox *tox, int32_t n, uint8_t format, | |||
350 | uint8_t *hash, uint8_t *data, uint32_t datalen, void *ud) | 350 | uint8_t *hash, uint8_t *data, uint32_t datalen, void *ud) |
351 | { | 351 | { |
352 | char *base_dir = (char *) ud; | 352 | char *base_dir = (char *) ud; |
353 | uint8_t addr[TOX_CLIENT_ID_SIZE]; | 353 | uint8_t addr[TOX_PUBLIC_KEY_SIZE]; |
354 | char addr_str[2 * TOX_CLIENT_ID_SIZE + 1]; | 354 | char addr_str[2 * TOX_PUBLIC_KEY_SIZE + 1]; |
355 | char hash_str[2 * TOX_HASH_LENGTH + 1]; | 355 | char hash_str[2 * TOX_HASH_LENGTH + 1]; |
356 | 356 | ||
357 | if (tox_get_client_id(tox, n, addr) == 0) { | 357 | if (tox_get_client_id(tox, n, addr) == 0) { |
358 | byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str); | 358 | byte_to_hex_str(addr, TOX_PUBLIC_KEY_SIZE, addr_str); |
359 | printf("Receiving avatar data from %s.\n", addr_str); | 359 | printf("Receiving avatar data from %s.\n", addr_str); |
360 | } else { | 360 | } else { |
361 | DEBUG("tox_get_client_id failed"); | 361 | DEBUG("tox_get_client_id failed"); |
@@ -382,8 +382,8 @@ static void friend_msg_cb(Tox *tox, int n, const uint8_t *msg, uint16_t len, voi | |||
382 | { | 382 | { |
383 | const char *base_dir = (char *) ud; | 383 | const char *base_dir = (char *) ud; |
384 | const char *msg_str = (char *) msg; | 384 | const char *msg_str = (char *) msg; |
385 | uint8_t addr[TOX_CLIENT_ID_SIZE]; | 385 | uint8_t addr[TOX_PUBLIC_KEY_SIZE]; |
386 | char addr_str[2 * TOX_CLIENT_ID_SIZE + 1]; | 386 | char addr_str[2 * TOX_PUBLIC_KEY_SIZE + 1]; |
387 | 387 | ||
388 | if (tox_get_client_id(tox, n, addr) == 0) { | 388 | if (tox_get_client_id(tox, n, addr) == 0) { |
389 | byte_to_hex_str(addr, TOX_FRIEND_ADDRESS_SIZE, addr_str); | 389 | byte_to_hex_str(addr, TOX_FRIEND_ADDRESS_SIZE, addr_str); |
@@ -428,8 +428,8 @@ static void friend_msg_cb(Tox *tox, int n, const uint8_t *msg, uint16_t len, voi | |||
428 | static void friend_request_cb(Tox *tox, const uint8_t *public_key, | 428 | static void friend_request_cb(Tox *tox, const uint8_t *public_key, |
429 | const uint8_t *data, uint16_t length, void *ud) | 429 | const uint8_t *data, uint16_t length, void *ud) |
430 | { | 430 | { |
431 | char addr_str[2 * TOX_CLIENT_ID_SIZE + 1]; | 431 | char addr_str[2 * TOX_PUBLIC_KEY_SIZE + 1]; |
432 | byte_to_hex_str(public_key, TOX_CLIENT_ID_SIZE, addr_str); | 432 | byte_to_hex_str(public_key, TOX_PUBLIC_KEY_SIZE, addr_str); |
433 | printf("Accepting friend request from %s.\n %s\n", addr_str, data); | 433 | printf("Accepting friend request from %s.\n %s\n", addr_str, data); |
434 | tox_add_friend_norequest(tox, public_key); | 434 | tox_add_friend_norequest(tox, public_key); |
435 | } | 435 | } |
diff --git a/tox.spec.in b/tox.spec.in new file mode 100644 index 00000000..f6136dc7 --- /dev/null +++ b/tox.spec.in | |||
@@ -0,0 +1,67 @@ | |||
1 | Name: @PACKAGE_NAME@ | ||
2 | Version: @VERSION@ | ||
3 | Release: 1%{?dist} | ||
4 | Summary: All-in-one secure communication platform | ||
5 | |||
6 | License: GPLv3 | ||
7 | URL: https://github.com/irungentoo/toxcore | ||
8 | Source0: https://github.com/irungentoo/toxcore/releases/tox-%{version}.tar.gz | ||
9 | |||
10 | BuildRequires: autoconf automake libtool libvpx-devel opus-devel | ||
11 | BuildRequires: libsodium-devel libconfig-devel | ||
12 | |||
13 | %description | ||
14 | With the rise of governmental monitoring programs, Tox, a FOSS initiative, aims to be an easy to use, all-in-one communication platform that ensures their users full privacy and secure message delivery. | ||
15 | |||
16 | %package devel | ||
17 | Summary: Development files for @PACKAGE_NAME@ | ||
18 | Requires: %{name} = %{version}-%{release} | ||
19 | |||
20 | %description devel | ||
21 | Development package for @PACKAGE_NAME@ | ||
22 | |||
23 | %prep | ||
24 | %setup -q | ||
25 | |||
26 | |||
27 | %build | ||
28 | %configure \ | ||
29 | --enable-shared \ | ||
30 | --disable-static \ | ||
31 | --enable-av \ | ||
32 | --disable-ntox \ | ||
33 | --disable-daemon \ | ||
34 | --disable-testing | ||
35 | |||
36 | make %{?_smp_mflags} | ||
37 | |||
38 | |||
39 | %install | ||
40 | %make_install | ||
41 | |||
42 | # remove la files | ||
43 | find %{buildroot} -name '*.la' -delete -print | ||
44 | |||
45 | # not handling DHT_bootstrap yet | ||
46 | rm -f %{buildroot}%{_bindir}/DHT_bootstrap | ||
47 | |||
48 | %post | ||
49 | /sbin/ldconfig | ||
50 | |||
51 | %postun | ||
52 | /sbin/ldconfig | ||
53 | |||
54 | %files | ||
55 | %defattr(-,root,root) | ||
56 | %doc COPYING README.md | ||
57 | %{_libdir}/libtox*.so.* | ||
58 | |||
59 | %files devel | ||
60 | %defattr(-, root, root) | ||
61 | %{_includedir}/tox/ | ||
62 | %{_libdir}/libtox*.so | ||
63 | %{_libdir}/pkgconfig/libtox*.pc | ||
64 | |||
65 | %changelog | ||
66 | * Tue Mar 3 2015 Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc> - 0.0.0-1 | ||
67 | - initial package | ||
diff --git a/toxav/Makefile.inc b/toxav/Makefile.inc index 6458260d..b61c1ea0 100644 --- a/toxav/Makefile.inc +++ b/toxav/Makefile.inc | |||
@@ -49,6 +49,7 @@ av_test_LDADD = $(LIBSODIUM_LDFLAGS) \ | |||
49 | libtoxcore.la \ | 49 | libtoxcore.la \ |
50 | $(LIBSODIUM_LIBS) \ | 50 | $(LIBSODIUM_LIBS) \ |
51 | $(NACL_OBJECTS) \ | 51 | $(NACL_OBJECTS) \ |
52 | -lopenal \ | ||
52 | $(NACL_LIBS) | 53 | $(NACL_LIBS) |
53 | 54 | ||
54 | 55 | ||
diff --git a/toxav/av_test.c b/toxav/av_test.c index bb79eedc..01484249 100644 --- a/toxav/av_test.c +++ b/toxav/av_test.c | |||
@@ -1,6 +1,18 @@ | |||
1 | #include "toxav.h" | 1 | #include "toxav.h" |
2 | #include "../toxcore/tox.h" | 2 | #include "../toxcore/tox.h" |
3 | 3 | ||
4 | #ifdef __APPLE__ | ||
5 | # include <OpenAL/al.h> | ||
6 | # include <OpenAL/alc.h> | ||
7 | #else | ||
8 | # include <AL/al.h> | ||
9 | # include <AL/alc.h> | ||
10 | /* compatibility with older versions of OpenAL */ | ||
11 | # ifndef ALC_ALL_DEVICES_SPECIFIER | ||
12 | # include <AL/alext.h> | ||
13 | # endif /* ALC_ALL_DEVICES_SPECIFIER */ | ||
14 | #endif /* __APPLE__ */ | ||
15 | |||
4 | #include <assert.h> | 16 | #include <assert.h> |
5 | #include <stdio.h> | 17 | #include <stdio.h> |
6 | #include <stdlib.h> | 18 | #include <stdlib.h> |
@@ -14,6 +26,16 @@ | |||
14 | #define c_sleep(x) usleep(1000*x) | 26 | #define c_sleep(x) usleep(1000*x) |
15 | #endif | 27 | #endif |
16 | 28 | ||
29 | /* Enable/disable tests */ | ||
30 | #define TEST_REGULAR_AV 0 | ||
31 | #define TEST_REGULAR_A 0 | ||
32 | #define TEST_REGULAR_V 0 | ||
33 | #define TEST_REJECT 0 | ||
34 | #define TEST_CANCEL 0 | ||
35 | #define TEST_MUTE_UNMUTE 0 | ||
36 | #define TEST_TRANSFER_A 1 | ||
37 | |||
38 | |||
17 | typedef struct { | 39 | typedef struct { |
18 | bool incoming; | 40 | bool incoming; |
19 | uint32_t state; | 41 | uint32_t state; |
@@ -134,9 +156,201 @@ void iterate(Tox* Bsn, ToxAV* AliceAV, ToxAV* BobAV) | |||
134 | c_sleep(20); | 156 | c_sleep(20); |
135 | } | 157 | } |
136 | 158 | ||
159 | int device_read_frame(ALCdevice* device, int32_t frame_dur, int16_t* PCM, size_t max_size) | ||
160 | { | ||
161 | int f_size = (48000 * frame_dur / 1000); | ||
162 | |||
163 | if (max_size < f_size) | ||
164 | return -1; | ||
165 | |||
166 | /* Don't block if not enough data */ | ||
167 | int32_t samples; | ||
168 | alcGetIntegerv(device, ALC_CAPTURE_SAMPLES, sizeof(int32_t), &samples); | ||
169 | if (samples < f_size) | ||
170 | return 0; | ||
171 | |||
172 | alcCaptureSamples(device, PCM, f_size); | ||
173 | return f_size; | ||
174 | } | ||
175 | |||
176 | int device_play_frame(uint32_t source, int16_t* PCM, size_t size) | ||
177 | { | ||
178 | uint32_t bufid; | ||
179 | int32_t processed, queued; | ||
180 | alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); | ||
181 | alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); | ||
182 | |||
183 | if(processed) { | ||
184 | uint32_t bufids[processed]; | ||
185 | alSourceUnqueueBuffers(source, processed, bufids); | ||
186 | alDeleteBuffers(processed - 1, bufids + 1); | ||
187 | bufid = bufids[0]; | ||
188 | } | ||
189 | else if(queued < 16) | ||
190 | alGenBuffers(1, &bufid); | ||
191 | else | ||
192 | return 0; | ||
193 | |||
194 | |||
195 | alBufferData(bufid, AL_FORMAT_STEREO16, PCM, size * 2 * 2, 48000); | ||
196 | alSourceQueueBuffers(source, 1, &bufid); | ||
197 | |||
198 | int32_t state; | ||
199 | alGetSourcei(source, AL_SOURCE_STATE, &state); | ||
200 | |||
201 | if(state != AL_PLAYING) | ||
202 | alSourcePlay(source); | ||
203 | return 1; | ||
204 | } | ||
205 | |||
206 | int print_devices() | ||
207 | { | ||
208 | const char* default_input; | ||
209 | const char* default_output; | ||
210 | |||
211 | const char *device; | ||
212 | |||
213 | printf("Default input device: %s\n", alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)); | ||
214 | printf("Default output device: %s\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER)); | ||
215 | |||
216 | printf("\n"); | ||
217 | |||
218 | printf("Input devices:\n"); | ||
219 | |||
220 | int i = 0; | ||
221 | for(device = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); *device; | ||
222 | device += strlen( device ) + 1, ++i) { | ||
223 | printf("%d) %s\n", i, device); | ||
224 | } | ||
225 | |||
226 | printf("\n"); | ||
227 | printf("Output devices:\n"); | ||
228 | |||
229 | i = 0; | ||
230 | for(device = alcGetString(NULL, ALC_DEVICE_SPECIFIER); *device; | ||
231 | device += strlen( device ) + 1, ++i) { | ||
232 | printf("%d) %s\n", i, device); | ||
233 | } | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | int print_help(const char* name, int rc) | ||
239 | { | ||
240 | fprintf(stderr, "Usage: %s [-h] <in device> <out device>\n", name); | ||
241 | return rc; | ||
242 | } | ||
243 | |||
244 | long get_device_idx(const char* arg) | ||
245 | { | ||
246 | if (strcmp(arg, "-") == 0) | ||
247 | return -1; /* Default */ | ||
248 | |||
249 | char *p; | ||
250 | long res = strtol(arg, &p, 10); | ||
251 | |||
252 | if (*p) { | ||
253 | fprintf(stderr, "Invalid device!"); | ||
254 | exit(1); | ||
255 | } | ||
256 | |||
257 | return res; | ||
258 | } | ||
137 | 259 | ||
138 | int main (int argc, char** argv) | 260 | int main (int argc, char** argv) |
139 | { | 261 | { |
262 | if (argc == 2) { | ||
263 | if (strcmp(argv[1], "-d") == 0 || strcmp(argv[1], "--devices") == 0) { | ||
264 | return print_devices(); | ||
265 | } | ||
266 | if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { | ||
267 | return print_help(argv[0], 0); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | if (argc != 3) { | ||
272 | fprintf(stderr, "Invalid input!\n"); | ||
273 | return print_help(argv[0], 1); | ||
274 | } | ||
275 | |||
276 | int i; | ||
277 | |||
278 | const char* in_device_name = ""; | ||
279 | const char* out_device_name = ""; | ||
280 | |||
281 | { | ||
282 | long dev = get_device_idx(argv[1]); | ||
283 | if (dev == -1) | ||
284 | in_device_name = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER); | ||
285 | else | ||
286 | { | ||
287 | const char* tmp; | ||
288 | i = -1; | ||
289 | for(tmp = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); *tmp && i != dev; | ||
290 | tmp += strlen( tmp ) + 1, ++i) | ||
291 | in_device_name = tmp; | ||
292 | } | ||
293 | |||
294 | printf("Input device: %s\n", in_device_name); | ||
295 | } | ||
296 | |||
297 | { | ||
298 | long dev = get_device_idx(argv[1]); | ||
299 | if (dev == -1) | ||
300 | out_device_name = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); | ||
301 | else | ||
302 | { | ||
303 | const char* tmp; | ||
304 | i = -1; | ||
305 | for(tmp = alcGetString(NULL, ALC_DEVICE_SPECIFIER); *tmp && i != dev; | ||
306 | tmp += strlen( tmp ) + 1, ++i) | ||
307 | out_device_name = tmp; | ||
308 | } | ||
309 | |||
310 | printf("Output device: %s\n", out_device_name); | ||
311 | } | ||
312 | |||
313 | ALCdevice* out_device; | ||
314 | ALCcontext* out_ctx; | ||
315 | uint32_t source; | ||
316 | uint32_t buffers[5]; | ||
317 | |||
318 | { /* Open output device */ | ||
319 | out_device = alcOpenDevice(out_device_name); | ||
320 | if ( !out_device ) { | ||
321 | fprintf(stderr, "Failed to open playback device: %s: %d\n", out_device_name, alGetError()); | ||
322 | return 1; | ||
323 | } | ||
324 | |||
325 | out_ctx = alcCreateContext(out_device, NULL); | ||
326 | alcMakeContextCurrent(out_ctx); | ||
327 | |||
328 | alGenBuffers(5, buffers); | ||
329 | alGenSources((uint32_t)1, &source); | ||
330 | alSourcei(source, AL_LOOPING, AL_FALSE); | ||
331 | |||
332 | uint16_t zeros[10000]; | ||
333 | memset(zeros, 0, 10000); | ||
334 | |||
335 | for ( i = 0; i < 5; ++i ) | ||
336 | alBufferData(buffers[i], AL_FORMAT_STEREO16, zeros, 10000, 48000); | ||
337 | |||
338 | alSourceQueueBuffers(source, 5, buffers); | ||
339 | alSourcePlay(source); | ||
340 | } | ||
341 | |||
342 | ALCdevice* in_device; | ||
343 | |||
344 | { /* Open input device */ | ||
345 | in_device = alcCaptureOpenDevice(in_device_name, 48000, AL_FORMAT_STEREO16, 10000); | ||
346 | if ( !in_device ) { | ||
347 | fprintf(stderr, "Failed to open capture device: %s: %d\n", in_device_name, alGetError()); | ||
348 | return 1; | ||
349 | } | ||
350 | |||
351 | alcCaptureStart(in_device); | ||
352 | } | ||
353 | |||
140 | Tox *Bsn = tox_new(0); | 354 | Tox *Bsn = tox_new(0); |
141 | Tox *Alice = tox_new(0); | 355 | Tox *Alice = tox_new(0); |
142 | Tox *Bob = tox_new(0); | 356 | Tox *Bob = tox_new(0); |
@@ -163,7 +377,7 @@ int main (int argc, char** argv) | |||
163 | 377 | ||
164 | 378 | ||
165 | #define REGULAR_CALL_FLOW(A_BR, V_BR) \ | 379 | #define REGULAR_CALL_FLOW(A_BR, V_BR) \ |
166 | { \ | 380 | do { \ |
167 | memset(&AliceCC, 0, sizeof(CallControl)); \ | 381 | memset(&AliceCC, 0, sizeof(CallControl)); \ |
168 | memset(&BobCC, 0, sizeof(CallControl)); \ | 382 | memset(&BobCC, 0, sizeof(CallControl)); \ |
169 | \ | 383 | \ |
@@ -208,20 +422,26 @@ int main (int argc, char** argv) | |||
208 | iterate(Bsn, AliceAV, BobAV); \ | 422 | iterate(Bsn, AliceAV, BobAV); \ |
209 | } \ | 423 | } \ |
210 | printf("Success!\n");\ | 424 | printf("Success!\n");\ |
211 | } | 425 | } while(0) |
212 | |||
213 | printf("\nTrying regular call (Audio and Video)...\n"); | ||
214 | REGULAR_CALL_FLOW(48, 4000); | ||
215 | |||
216 | printf("\nTrying regular call (Audio only)...\n"); | ||
217 | REGULAR_CALL_FLOW(48, 0); | ||
218 | |||
219 | printf("\nTrying regular call (Video only)...\n"); | ||
220 | REGULAR_CALL_FLOW(0, 4000); | ||
221 | 426 | ||
427 | if (TEST_REGULAR_AV) { | ||
428 | printf("\nTrying regular call (Audio and Video)...\n"); | ||
429 | REGULAR_CALL_FLOW(48, 4000); | ||
430 | } | ||
431 | |||
432 | if (TEST_REGULAR_A) { | ||
433 | printf("\nTrying regular call (Audio only)...\n"); | ||
434 | REGULAR_CALL_FLOW(48, 0); | ||
435 | } | ||
436 | |||
437 | if (TEST_REGULAR_V) { | ||
438 | printf("\nTrying regular call (Video only)...\n"); | ||
439 | REGULAR_CALL_FLOW(0, 4000); | ||
440 | } | ||
441 | |||
222 | #undef REGULAR_CALL_FLOW | 442 | #undef REGULAR_CALL_FLOW |
223 | 443 | ||
224 | { /* Alice calls; Bob rejects */ | 444 | if (TEST_REJECT) { /* Alice calls; Bob rejects */ |
225 | printf("\nTrying reject flow...\n"); | 445 | printf("\nTrying reject flow...\n"); |
226 | 446 | ||
227 | memset(&AliceCC, 0, sizeof(CallControl)); | 447 | memset(&AliceCC, 0, sizeof(CallControl)); |
@@ -257,7 +477,7 @@ int main (int argc, char** argv) | |||
257 | printf("Success!\n"); | 477 | printf("Success!\n"); |
258 | } | 478 | } |
259 | 479 | ||
260 | { /* Alice calls; Alice cancels while ringing */ | 480 | if (TEST_CANCEL) { /* Alice calls; Alice cancels while ringing */ |
261 | printf("\nTrying cancel (while ringing) flow...\n"); | 481 | printf("\nTrying cancel (while ringing) flow...\n"); |
262 | 482 | ||
263 | memset(&AliceCC, 0, sizeof(CallControl)); | 483 | memset(&AliceCC, 0, sizeof(CallControl)); |
@@ -294,10 +514,9 @@ int main (int argc, char** argv) | |||
294 | printf("Success!\n"); | 514 | printf("Success!\n"); |
295 | } | 515 | } |
296 | 516 | ||
297 | { /* Check Mute-Unmute etc */ | 517 | if (TEST_MUTE_UNMUTE) { /* Check Mute-Unmute etc */ |
298 | printf("\nTrying mute functionality...\n"); | 518 | printf("\nTrying mute functionality...\n"); |
299 | 519 | ||
300 | |||
301 | memset(&AliceCC, 0, sizeof(CallControl)); | 520 | memset(&AliceCC, 0, sizeof(CallControl)); |
302 | memset(&BobCC, 0, sizeof(CallControl)); | 521 | memset(&BobCC, 0, sizeof(CallControl)); |
303 | 522 | ||
@@ -382,7 +601,23 @@ int main (int argc, char** argv) | |||
382 | printf("Success!\n"); | 601 | printf("Success!\n"); |
383 | } | 602 | } |
384 | 603 | ||
385 | 604 | if (TEST_TRANSFER_A) { /* Audio encoding/decoding and transfer */ | |
605 | printf("\nTrying audio enc/dec...\n"); | ||
606 | |||
607 | int16_t PCM[10000]; | ||
608 | time_t start_time = time(NULL); | ||
609 | |||
610 | /* Run for 5 seconds */ | ||
611 | while ( start_time + 10 > time(NULL) ) { | ||
612 | int frame_size = device_read_frame(in_device, 20, PCM, sizeof(PCM)); | ||
613 | if (frame_size > 0) | ||
614 | device_play_frame(source, PCM, frame_size); | ||
615 | // c_sleep(20); | ||
616 | } | ||
617 | |||
618 | printf("Success!"); | ||
619 | } | ||
620 | |||
386 | toxav_kill(BobAV); | 621 | toxav_kill(BobAV); |
387 | toxav_kill(AliceAV); | 622 | toxav_kill(AliceAV); |
388 | tox_kill(Bob); | 623 | tox_kill(Bob); |
@@ -390,5 +625,8 @@ int main (int argc, char** argv) | |||
390 | tox_kill(Bsn); | 625 | tox_kill(Bsn); |
391 | 626 | ||
392 | printf("\nTest successful!\n"); | 627 | printf("\nTest successful!\n"); |
628 | |||
629 | alcCloseDevice(out_device); | ||
630 | alcCaptureCloseDevice(in_device); | ||
393 | return 0; | 631 | return 0; |
394 | } \ No newline at end of file | 632 | } \ No newline at end of file |
diff --git a/toxav/codec.c b/toxav/codec.c index 95e0beb4..bf94115e 100644 --- a/toxav/codec.c +++ b/toxav/codec.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #define DEFAULT_JBUF 6 | 41 | #define DEFAULT_JBUF 6 |
42 | 42 | ||
43 | /* Good quality encode. */ | 43 | /* Good quality encode. */ |
44 | #define MAX_ENCODE_TIME_US VPX_DL_GOOD_QUALITY | ||
45 | #define MAX_DECODE_TIME_US 0 | 44 | #define MAX_DECODE_TIME_US 0 |
46 | 45 | ||
47 | #define MAX_VIDEOFRAME_SIZE 0x40000 /* 256KiB */ | 46 | #define MAX_VIDEOFRAME_SIZE 0x40000 /* 256KiB */ |
diff --git a/toxav/msi.c b/toxav/msi.c index ac900dac..e21ec948 100644 --- a/toxav/msi.c +++ b/toxav/msi.c | |||
@@ -783,4 +783,4 @@ void handle_msi_packet ( Messenger *m, int friend_id, const uint8_t *data, uint1 | |||
783 | handle_pop(call, &msg); /* always kills the call */ | 783 | handle_pop(call, &msg); /* always kills the call */ |
784 | 784 | ||
785 | pthread_mutex_unlock(session->mutex); | 785 | pthread_mutex_unlock(session->mutex); |
786 | } \ No newline at end of file | 786 | } |
diff --git a/toxav/toxav_new_1.c b/toxav/toxav_new_1.c deleted file mode 100644 index 145dcf48..00000000 --- a/toxav/toxav_new_1.c +++ /dev/null | |||
@@ -1,688 +0,0 @@ | |||
1 | /** toxav.c | ||
2 | * | ||
3 | * Copyright (C) 2013 Tox project All Rights Reserved. | ||
4 | * | ||
5 | * This file is part of Tox. | ||
6 | * | ||
7 | * Tox is free software: you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation, either version 3 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * Tox is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifdef HAVE_CONFIG_H | ||
23 | #include "config.h" | ||
24 | #endif /* HAVE_CONFIG_H */ | ||
25 | |||
26 | #define __TOX_DEFINED__ | ||
27 | typedef struct Messenger Tox; | ||
28 | |||
29 | #define _GNU_SOURCE /* implicit declaration warning */ | ||
30 | |||
31 | #include "codec.h" | ||
32 | #include "msi.h" | ||
33 | #include "group.h" | ||
34 | |||
35 | #include "../toxcore/logger.h" | ||
36 | #include "../toxcore/util.h" | ||
37 | |||
38 | #include <assert.h> | ||
39 | #include <stdlib.h> | ||
40 | #include <string.h> | ||
41 | |||
42 | /* Assume 24 fps*/ | ||
43 | #define MAX_ENCODE_TIME_US ((1000 / 24) * 1000) | ||
44 | |||
45 | /* true if invalid call index */ | ||
46 | #define CALL_INVALID_INDEX(idx, max) (idx < 0 || idx >= max) | ||
47 | |||
48 | const ToxAvCSettings av_DefaultSettings = { | ||
49 | av_TypeAudio, | ||
50 | |||
51 | 500, | ||
52 | 1280, | ||
53 | 720, | ||
54 | |||
55 | 32000, | ||
56 | 20, | ||
57 | 48000, | ||
58 | 1 | ||
59 | }; | ||
60 | |||
61 | static const uint32_t jbuf_capacity = 6; | ||
62 | static const uint8_t audio_index = 0, video_index = 1; | ||
63 | |||
64 | typedef struct _ToxAvCall { | ||
65 | pthread_mutex_t mutex_control[1]; | ||
66 | pthread_mutex_t mutex_encoding_audio[1]; | ||
67 | pthread_mutex_t mutex_encoding_video[1]; | ||
68 | pthread_mutex_t mutex_do[1]; | ||
69 | RTPSession *crtps[2]; /** Audio is first and video is second */ | ||
70 | CSSession *cs; | ||
71 | _Bool active; | ||
72 | } ToxAvCall; | ||
73 | |||
74 | struct _ToxAv { | ||
75 | Messenger *messenger; | ||
76 | MSISession *msi_session; /** Main msi session */ | ||
77 | ToxAvCall *calls; /** Per-call params */ | ||
78 | uint32_t max_calls; | ||
79 | |||
80 | PAIR(ToxAvAudioCallback, void *) acb; | ||
81 | PAIR(ToxAvVideoCallback, void *) vcb; | ||
82 | |||
83 | /* Decode time measure */ | ||
84 | int32_t dectmsscount; /** Measure count */ | ||
85 | int32_t dectmsstotal; /** Last cycle total */ | ||
86 | int32_t avgdectms; /** Average decoding time in ms */ | ||
87 | }; | ||
88 | |||
89 | static const MSICSettings *msicsettings_cast (const ToxAvCSettings *from) | ||
90 | { | ||
91 | assert(sizeof(MSICSettings) == sizeof(ToxAvCSettings)); | ||
92 | return (const MSICSettings *) from; | ||
93 | } | ||
94 | |||
95 | static const ToxAvCSettings *toxavcsettings_cast (const MSICSettings *from) | ||
96 | { | ||
97 | assert(sizeof(MSICSettings) == sizeof(ToxAvCSettings)); | ||
98 | return (const ToxAvCSettings *) from; | ||
99 | |||
100 | } | ||
101 | |||
102 | ToxAv *toxav_new( Tox *messenger, int32_t max_calls) | ||
103 | { | ||
104 | ToxAv *av = calloc ( sizeof(ToxAv), 1); | ||
105 | |||
106 | if (av == NULL) { | ||
107 | LOGGER_WARNING("Allocation failed!"); | ||
108 | return NULL; | ||
109 | } | ||
110 | |||
111 | av->messenger = (Messenger *)messenger; | ||
112 | av->msi_session = msi_new(av->messenger, max_calls); | ||
113 | av->msi_session->agent_handler = av; | ||
114 | av->calls = calloc(sizeof(ToxAvCall), max_calls); | ||
115 | av->max_calls = max_calls; | ||
116 | |||
117 | unsigned int i; | ||
118 | |||
119 | for (i = 0; i < max_calls; ++i) { | ||
120 | if (create_recursive_mutex(av->calls[i].mutex_control) != 0 ) { | ||
121 | LOGGER_WARNING("Failed to init call(%u) mutex!", i); | ||
122 | msi_kill(av->msi_session); | ||
123 | |||
124 | free(av->calls); | ||
125 | free(av); | ||
126 | return NULL; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | return av; | ||
131 | } | ||
132 | |||
133 | void toxav_kill ( ToxAv *av ) | ||
134 | { | ||
135 | uint32_t i; | ||
136 | |||
137 | for (i = 0; i < av->max_calls; i ++) { | ||
138 | if ( av->calls[i].crtps[audio_index] ) | ||
139 | rtp_kill(av->calls[i].crtps[audio_index], av->msi_session->messenger_handle); | ||
140 | |||
141 | |||
142 | if ( av->calls[i].crtps[video_index] ) | ||
143 | rtp_kill(av->calls[i].crtps[video_index], av->msi_session->messenger_handle); | ||
144 | |||
145 | if ( av->calls[i].cs ) | ||
146 | cs_kill(av->calls[i].cs); | ||
147 | |||
148 | pthread_mutex_destroy(av->calls[i].mutex_control); | ||
149 | } | ||
150 | |||
151 | msi_kill(av->msi_session); | ||
152 | |||
153 | free(av->calls); | ||
154 | free(av); | ||
155 | } | ||
156 | |||
157 | uint32_t toxav_do_interval(ToxAv *av) | ||
158 | { | ||
159 | int i = 0; | ||
160 | uint32_t rc = 200 + av->avgdectms; /* Return 200 if no call is active */ | ||
161 | |||
162 | for (; i < av->max_calls; i ++) { | ||
163 | pthread_mutex_lock(av->calls[i].mutex_control); | ||
164 | |||
165 | if (av->calls[i].active) { | ||
166 | /* This should work. Video payload will always come in greater intervals */ | ||
167 | rc = MIN(av->calls[i].cs->audio_decoder_frame_duration, rc); | ||
168 | } | ||
169 | |||
170 | pthread_mutex_unlock(av->calls[i].mutex_control); | ||
171 | } | ||
172 | |||
173 | return rc < av->avgdectms ? 0 : rc - av->avgdectms; | ||
174 | } | ||
175 | |||
176 | void toxav_do(ToxAv *av) | ||
177 | { | ||
178 | msi_do(av->msi_session); | ||
179 | |||
180 | uint64_t start = current_time_monotonic(); | ||
181 | |||
182 | uint32_t i = 0; | ||
183 | |||
184 | for (; i < av->max_calls; i ++) { | ||
185 | pthread_mutex_lock(av->calls[i].mutex_control); | ||
186 | |||
187 | if (av->calls[i].active) { | ||
188 | pthread_mutex_lock(av->calls[i].mutex_do); | ||
189 | pthread_mutex_unlock(av->calls[i].mutex_control); | ||
190 | cs_do(av->calls[i].cs); | ||
191 | pthread_mutex_unlock(av->calls[i].mutex_do); | ||
192 | } else { | ||
193 | pthread_mutex_unlock(av->calls[i].mutex_control); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | uint64_t end = current_time_monotonic(); | ||
198 | |||
199 | /* TODO maybe use variable for sizes */ | ||
200 | av->dectmsstotal += end - start; | ||
201 | |||
202 | if (++av->dectmsscount == 3) { | ||
203 | av->avgdectms = av->dectmsstotal / 3 + 2 /* NOTE Magic Offset */; | ||
204 | av->dectmsscount = 0; | ||
205 | av->dectmsstotal = 0; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | void toxav_register_callstate_callback ( ToxAv *av, ToxAVCallback cb, ToxAvCallbackID id, void *userdata ) | ||
210 | { | ||
211 | msi_register_callback(av->msi_session, (MSICallbackType)cb, (MSICallbackID) id, userdata); | ||
212 | } | ||
213 | |||
214 | void toxav_register_audio_callback(ToxAv *av, ToxAvAudioCallback cb, void *userdata) | ||
215 | { | ||
216 | av->acb.first = cb; | ||
217 | av->acb.second = userdata; | ||
218 | } | ||
219 | |||
220 | void toxav_register_video_callback(ToxAv *av, ToxAvVideoCallback cb, void *userdata) | ||
221 | { | ||
222 | av->vcb.first = cb; | ||
223 | av->vcb.second = userdata; | ||
224 | } | ||
225 | |||
226 | int toxav_call (ToxAv *av, | ||
227 | int32_t *call_index, | ||
228 | int user, | ||
229 | const ToxAvCSettings *csettings, | ||
230 | int ringing_seconds ) | ||
231 | { | ||
232 | return msi_invite(av->msi_session, call_index, msicsettings_cast(csettings), ringing_seconds * 1000, user); | ||
233 | } | ||
234 | |||
235 | int toxav_hangup ( ToxAv *av, int32_t call_index ) | ||
236 | { | ||
237 | return msi_hangup(av->msi_session, call_index); | ||
238 | } | ||
239 | |||
240 | int toxav_answer ( ToxAv *av, int32_t call_index, const ToxAvCSettings *csettings ) | ||
241 | { | ||
242 | return msi_answer(av->msi_session, call_index, msicsettings_cast(csettings)); | ||
243 | } | ||
244 | |||
245 | int toxav_reject ( ToxAv *av, int32_t call_index, const char *reason ) | ||
246 | { | ||
247 | return msi_reject(av->msi_session, call_index, reason); | ||
248 | } | ||
249 | |||
250 | int toxav_cancel ( ToxAv *av, int32_t call_index, int peer_id, const char *reason ) | ||
251 | { | ||
252 | return msi_cancel(av->msi_session, call_index, peer_id, reason); | ||
253 | } | ||
254 | |||
255 | int toxav_change_settings(ToxAv *av, int32_t call_index, const ToxAvCSettings *csettings) | ||
256 | { | ||
257 | return msi_change_csettings(av->msi_session, call_index, msicsettings_cast(csettings)); | ||
258 | } | ||
259 | |||
260 | int toxav_stop_call ( ToxAv *av, int32_t call_index ) | ||
261 | { | ||
262 | return msi_stopcall(av->msi_session, call_index); | ||
263 | } | ||
264 | |||
265 | int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, int support_video ) | ||
266 | { | ||
267 | if ( !av->msi_session || CALL_INVALID_INDEX(call_index, av->msi_session->max_calls) || | ||
268 | !av->msi_session->calls[call_index] || !av->msi_session->calls[call_index]->csettings_peer) { | ||
269 | LOGGER_ERROR("Error while starting RTP session: invalid call!\n"); | ||
270 | return av_ErrorNoCall; | ||
271 | } | ||
272 | |||
273 | ToxAvCall *call = &av->calls[call_index]; | ||
274 | |||
275 | pthread_mutex_lock(call->mutex_control); | ||
276 | |||
277 | if (call->active) { | ||
278 | pthread_mutex_unlock(call->mutex_control); | ||
279 | LOGGER_ERROR("Error while starting RTP session: call already active!\n"); | ||
280 | return av_ErrorAlreadyInCallWithPeer; | ||
281 | } | ||
282 | |||
283 | if (pthread_mutex_init(call->mutex_encoding_audio, NULL) != 0 | ||
284 | || pthread_mutex_init(call->mutex_encoding_video, NULL) != 0 || pthread_mutex_init(call->mutex_do, NULL) != 0) { | ||
285 | pthread_mutex_unlock(call->mutex_control); | ||
286 | LOGGER_ERROR("Error while starting RTP session: mutex initializing failed!\n"); | ||
287 | return av_ErrorUnknown; | ||
288 | } | ||
289 | |||
290 | const ToxAvCSettings *c_peer = toxavcsettings_cast | ||
291 | (&av->msi_session->calls[call_index]->csettings_peer[0]); | ||
292 | const ToxAvCSettings *c_self = toxavcsettings_cast | ||
293 | (&av->msi_session->calls[call_index]->csettings_local); | ||
294 | |||
295 | LOGGER_DEBUG( | ||
296 | "Type: %u(s) %u(p)\n" | ||
297 | "Video bitrate: %u(s) %u(p)\n" | ||
298 | "Video height: %u(s) %u(p)\n" | ||
299 | "Video width: %u(s) %u(p)\n" | ||
300 | "Audio bitrate: %u(s) %u(p)\n" | ||
301 | "Audio framedur: %u(s) %u(p)\n" | ||
302 | "Audio sample rate: %u(s) %u(p)\n" | ||
303 | "Audio channels: %u(s) %u(p)\n", | ||
304 | c_self->call_type, c_peer->call_type, | ||
305 | c_self->video_bitrate, c_peer->video_bitrate, | ||
306 | c_self->max_video_height, c_peer->max_video_height, | ||
307 | c_self->max_video_width, c_peer->max_video_width, | ||
308 | c_self->audio_bitrate, c_peer->audio_bitrate, | ||
309 | c_self->audio_frame_duration, c_peer->audio_frame_duration, | ||
310 | c_self->audio_sample_rate, c_peer->audio_sample_rate, | ||
311 | c_self->audio_channels, c_peer->audio_channels ); | ||
312 | |||
313 | if ( !(call->cs = cs_new(c_self, c_peer, jbuf_capacity, support_video)) ) { | ||
314 | LOGGER_ERROR("Error while starting Codec State!\n"); | ||
315 | pthread_mutex_unlock(call->mutex_control); | ||
316 | return av_ErrorInitializingCodecs; | ||
317 | } | ||
318 | |||
319 | call->cs->agent = av; | ||
320 | |||
321 | call->cs->acb.first = av->acb.first; | ||
322 | call->cs->acb.second = av->acb.second; | ||
323 | |||
324 | call->cs->vcb.first = av->vcb.first; | ||
325 | call->cs->vcb.second = av->vcb.second; | ||
326 | |||
327 | |||
328 | call->crtps[audio_index] = | ||
329 | rtp_new(msi_TypeAudio, av->messenger, av->msi_session->calls[call_index]->peers[0]); | ||
330 | |||
331 | if ( !call->crtps[audio_index] ) { | ||
332 | LOGGER_ERROR("Error while starting audio RTP session!\n"); | ||
333 | goto error; | ||
334 | } | ||
335 | |||
336 | call->crtps[audio_index]->cs = call->cs; | ||
337 | |||
338 | if ( support_video ) { | ||
339 | call->crtps[video_index] = | ||
340 | rtp_new(msi_TypeVideo, av->messenger, av->msi_session->calls[call_index]->peers[0]); | ||
341 | |||
342 | if ( !call->crtps[video_index] ) { | ||
343 | LOGGER_ERROR("Error while starting video RTP session!\n"); | ||
344 | goto error; | ||
345 | } | ||
346 | |||
347 | call->crtps[video_index]->cs = call->cs; | ||
348 | } | ||
349 | |||
350 | call->active = 1; | ||
351 | pthread_mutex_unlock(call->mutex_control); | ||
352 | return av_ErrorNone; | ||
353 | error: | ||
354 | rtp_kill(call->crtps[audio_index], av->messenger); | ||
355 | call->crtps[audio_index] = NULL; | ||
356 | rtp_kill(call->crtps[video_index], av->messenger); | ||
357 | call->crtps[video_index] = NULL; | ||
358 | cs_kill(call->cs); | ||
359 | call->cs = NULL; | ||
360 | call->active = 0; | ||
361 | pthread_mutex_destroy(call->mutex_encoding_audio); | ||
362 | pthread_mutex_destroy(call->mutex_encoding_video); | ||
363 | pthread_mutex_destroy(call->mutex_do); | ||
364 | |||
365 | pthread_mutex_unlock(call->mutex_control); | ||
366 | return av_ErrorCreatingRtpSessions; | ||
367 | } | ||
368 | |||
369 | int toxav_kill_transmission ( ToxAv *av, int32_t call_index ) | ||
370 | { | ||
371 | if (CALL_INVALID_INDEX(call_index, av->msi_session->max_calls)) { | ||
372 | LOGGER_WARNING("Invalid call index: %d", call_index); | ||
373 | return av_ErrorNoCall; | ||
374 | } | ||
375 | |||
376 | ToxAvCall *call = &av->calls[call_index]; | ||
377 | |||
378 | pthread_mutex_lock(call->mutex_control); | ||
379 | |||
380 | if (!call->active) { | ||
381 | pthread_mutex_unlock(call->mutex_control); | ||
382 | LOGGER_WARNING("Action on inactive call: %d", call_index); | ||
383 | return av_ErrorInvalidState; | ||
384 | } | ||
385 | |||
386 | call->active = 0; | ||
387 | |||
388 | pthread_mutex_lock(call->mutex_encoding_audio); | ||
389 | pthread_mutex_unlock(call->mutex_encoding_audio); | ||
390 | pthread_mutex_lock(call->mutex_encoding_video); | ||
391 | pthread_mutex_unlock(call->mutex_encoding_video); | ||
392 | pthread_mutex_lock(call->mutex_do); | ||
393 | pthread_mutex_unlock(call->mutex_do); | ||
394 | |||
395 | rtp_kill(call->crtps[audio_index], av->messenger); | ||
396 | call->crtps[audio_index] = NULL; | ||
397 | rtp_kill(call->crtps[video_index], av->messenger); | ||
398 | call->crtps[video_index] = NULL; | ||
399 | cs_kill(call->cs); | ||
400 | call->cs = NULL; | ||
401 | |||
402 | pthread_mutex_destroy(call->mutex_encoding_audio); | ||
403 | pthread_mutex_destroy(call->mutex_encoding_video); | ||
404 | pthread_mutex_destroy(call->mutex_do); | ||
405 | |||
406 | pthread_mutex_unlock(call->mutex_control); | ||
407 | |||
408 | return av_ErrorNone; | ||
409 | } | ||
410 | |||
411 | static int toxav_send_rtp_payload(ToxAv *av, | ||
412 | ToxAvCall *call, | ||
413 | ToxAvCallType type, | ||
414 | const uint8_t *payload, | ||
415 | unsigned int length) | ||
416 | { | ||
417 | if (call->crtps[type - av_TypeAudio]) { | ||
418 | |||
419 | /* Audio */ | ||
420 | if (type == av_TypeAudio) | ||
421 | return rtp_send_msg(call->crtps[audio_index], av->messenger, payload, length); | ||
422 | |||
423 | /* Video */ | ||
424 | int parts = cs_split_video_payload(call->cs, payload, length); | ||
425 | |||
426 | if (parts < 0) return parts; | ||
427 | |||
428 | uint16_t part_size; | ||
429 | const uint8_t *iter; | ||
430 | |||
431 | int i; | ||
432 | |||
433 | for (i = 0; i < parts; i++) { | ||
434 | iter = cs_iterate_split_video_frame(call->cs, &part_size); | ||
435 | |||
436 | if (rtp_send_msg(call->crtps[video_index], av->messenger, iter, part_size) < 0) | ||
437 | return av_ErrorSendingPayload; | ||
438 | } | ||
439 | |||
440 | return av_ErrorNone; | ||
441 | |||
442 | } else return av_ErrorNoRtpSession; | ||
443 | } | ||
444 | |||
445 | int toxav_prepare_video_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input) | ||
446 | { | ||
447 | if (CALL_INVALID_INDEX(call_index, av->msi_session->max_calls)) { | ||
448 | LOGGER_WARNING("Invalid call index: %d", call_index); | ||
449 | return av_ErrorNoCall; | ||
450 | } | ||
451 | |||
452 | |||
453 | ToxAvCall *call = &av->calls[call_index]; | ||
454 | pthread_mutex_lock(call->mutex_control); | ||
455 | |||
456 | if (!call->active) { | ||
457 | pthread_mutex_unlock(call->mutex_control); | ||
458 | LOGGER_WARNING("Action on inactive call: %d", call_index); | ||
459 | return av_ErrorInvalidState; | ||
460 | } | ||
461 | |||
462 | if (cs_set_sending_video_resolution(call->cs, input->d_w, input->d_h) < 0) { | ||
463 | pthread_mutex_unlock(call->mutex_control); | ||
464 | return av_ErrorSettingVideoResolution; | ||
465 | } | ||
466 | |||
467 | pthread_mutex_lock(call->mutex_encoding_video); | ||
468 | pthread_mutex_unlock(call->mutex_control); | ||
469 | |||
470 | int rc = vpx_codec_encode(call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); | ||
471 | |||
472 | if ( rc != VPX_CODEC_OK) { | ||
473 | LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc)); | ||
474 | pthread_mutex_unlock(call->mutex_encoding_video); | ||
475 | return av_ErrorEncodingVideo; | ||
476 | } | ||
477 | |||
478 | ++call->cs->frame_counter; | ||
479 | |||
480 | vpx_codec_iter_t iter = NULL; | ||
481 | const vpx_codec_cx_pkt_t *pkt; | ||
482 | int copied = 0; | ||
483 | |||
484 | while ( (pkt = vpx_codec_get_cx_data(call->cs->v_encoder, &iter)) ) { | ||
485 | if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { | ||
486 | if ( copied + pkt->data.frame.sz > dest_max ) { | ||
487 | pthread_mutex_unlock(call->mutex_encoding_video); | ||
488 | return av_ErrorPacketTooLarge; | ||
489 | } | ||
490 | |||
491 | memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz); | ||
492 | copied += pkt->data.frame.sz; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | pthread_mutex_unlock(call->mutex_encoding_video); | ||
497 | return copied; | ||
498 | } | ||
499 | |||
500 | int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *frame, unsigned int frame_size) | ||
501 | { | ||
502 | |||
503 | if (CALL_INVALID_INDEX(call_index, av->msi_session->max_calls)) { | ||
504 | LOGGER_WARNING("Invalid call index: %d", call_index); | ||
505 | return av_ErrorNoCall; | ||
506 | } | ||
507 | |||
508 | ToxAvCall *call = &av->calls[call_index]; | ||
509 | pthread_mutex_lock(call->mutex_control); | ||
510 | |||
511 | |||
512 | if (!call->active) { | ||
513 | pthread_mutex_unlock(call->mutex_control); | ||
514 | LOGGER_WARNING("Action on inactive call: %d", call_index); | ||
515 | return av_ErrorInvalidState; | ||
516 | } | ||
517 | |||
518 | int rc = toxav_send_rtp_payload(av, call, av_TypeVideo, frame, frame_size); | ||
519 | pthread_mutex_unlock(call->mutex_control); | ||
520 | |||
521 | return rc; | ||
522 | } | ||
523 | |||
524 | int toxav_prepare_audio_frame ( ToxAv *av, | ||
525 | int32_t call_index, | ||
526 | uint8_t *dest, | ||
527 | int dest_max, | ||
528 | const int16_t *frame, | ||
529 | int frame_size) | ||
530 | { | ||
531 | if (CALL_INVALID_INDEX(call_index, av->msi_session->max_calls)) { | ||
532 | LOGGER_WARNING("Action on nonexisting call: %d", call_index); | ||
533 | return av_ErrorNoCall; | ||
534 | } | ||
535 | |||
536 | ToxAvCall *call = &av->calls[call_index]; | ||
537 | pthread_mutex_lock(call->mutex_control); | ||
538 | |||
539 | if (!call->active) { | ||
540 | pthread_mutex_unlock(call->mutex_control); | ||
541 | LOGGER_WARNING("Action on inactive call: %d", call_index); | ||
542 | return av_ErrorInvalidState; | ||
543 | } | ||
544 | |||
545 | pthread_mutex_lock(call->mutex_encoding_audio); | ||
546 | pthread_mutex_unlock(call->mutex_control); | ||
547 | int32_t rc = opus_encode(call->cs->audio_encoder, frame, frame_size, dest, dest_max); | ||
548 | pthread_mutex_unlock(call->mutex_encoding_audio); | ||
549 | |||
550 | if (rc < 0) { | ||
551 | LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); | ||
552 | return av_ErrorEncodingAudio; | ||
553 | } | ||
554 | |||
555 | return rc; | ||
556 | } | ||
557 | |||
558 | int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *data, unsigned int size) | ||
559 | { | ||
560 | if (CALL_INVALID_INDEX(call_index, av->msi_session->max_calls)) { | ||
561 | LOGGER_WARNING("Action on nonexisting call: %d", call_index); | ||
562 | return av_ErrorNoCall; | ||
563 | } | ||
564 | |||
565 | ToxAvCall *call = &av->calls[call_index]; | ||
566 | pthread_mutex_lock(call->mutex_control); | ||
567 | |||
568 | |||
569 | if (!call->active) { | ||
570 | pthread_mutex_unlock(call->mutex_control); | ||
571 | LOGGER_WARNING("Action on inactive call: %d", call_index); | ||
572 | return av_ErrorInvalidState; | ||
573 | } | ||
574 | |||
575 | int rc = toxav_send_rtp_payload(av, call, av_TypeAudio, data, size); | ||
576 | pthread_mutex_unlock(call->mutex_control); | ||
577 | return rc; | ||
578 | } | ||
579 | |||
580 | int toxav_get_peer_csettings ( ToxAv *av, int32_t call_index, int peer, ToxAvCSettings *dest ) | ||
581 | { | ||
582 | if ( peer < 0 || CALL_INVALID_INDEX(call_index, av->msi_session->max_calls) || | ||
583 | !av->msi_session->calls[call_index] || av->msi_session->calls[call_index]->peer_count <= peer ) | ||
584 | return av_ErrorNoCall; | ||
585 | |||
586 | *dest = *toxavcsettings_cast(&av->msi_session->calls[call_index]->csettings_peer[peer]); | ||
587 | return av_ErrorNone; | ||
588 | } | ||
589 | |||
590 | int toxav_get_peer_id ( ToxAv *av, int32_t call_index, int peer ) | ||
591 | { | ||
592 | if ( peer < 0 || CALL_INVALID_INDEX(call_index, av->msi_session->max_calls) || !av->msi_session->calls[call_index] | ||
593 | || av->msi_session->calls[call_index]->peer_count <= peer ) | ||
594 | return av_ErrorNoCall; | ||
595 | |||
596 | return av->msi_session->calls[call_index]->peers[peer]; | ||
597 | } | ||
598 | |||
599 | ToxAvCallState toxav_get_call_state(ToxAv *av, int32_t call_index) | ||
600 | { | ||
601 | if ( CALL_INVALID_INDEX(call_index, av->msi_session->max_calls) || !av->msi_session->calls[call_index] ) | ||
602 | return av_CallNonExistent; | ||
603 | |||
604 | return av->msi_session->calls[call_index]->state; | ||
605 | |||
606 | } | ||
607 | |||
608 | int toxav_capability_supported ( ToxAv *av, int32_t call_index, ToxAvCapabilities capability ) | ||
609 | { | ||
610 | } | ||
611 | |||
612 | Tox *toxav_get_tox(ToxAv *av) | ||
613 | { | ||
614 | return (Tox *)av->messenger; | ||
615 | } | ||
616 | |||
617 | int toxav_get_active_count(ToxAv *av) | ||
618 | { | ||
619 | if (!av) return -1; | ||
620 | |||
621 | int rc = 0, i = 0; | ||
622 | |||
623 | for (; i < av->max_calls; i++) { | ||
624 | pthread_mutex_lock(av->calls[i].mutex_control); | ||
625 | |||
626 | if (av->calls[i].active) rc++; | ||
627 | |||
628 | pthread_mutex_unlock(av->calls[i].mutex_control); | ||
629 | } | ||
630 | |||
631 | return rc; | ||
632 | } | ||
633 | |||
634 | /* Create a new toxav group. | ||
635 | * | ||
636 | * return group number on success. | ||
637 | * return -1 on failure. | ||
638 | * | ||
639 | * Audio data callback format: | ||
640 | * audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata) | ||
641 | * | ||
642 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | ||
643 | */ | ||
644 | int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(Messenger *, int, int, const int16_t *, unsigned int, | ||
645 | uint8_t, unsigned int, void *), void *userdata) | ||
646 | { | ||
647 | Messenger *m = tox; | ||
648 | return add_av_groupchat(m->group_chat_object, audio_callback, userdata); | ||
649 | } | ||
650 | |||
651 | /* Join a AV group (you need to have been invited first.) | ||
652 | * | ||
653 | * returns group number on success | ||
654 | * returns -1 on failure. | ||
655 | * | ||
656 | * Audio data callback format (same as the one for toxav_add_av_groupchat()): | ||
657 | * audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata) | ||
658 | * | ||
659 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | ||
660 | */ | ||
661 | int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length, | ||
662 | void (*audio_callback)(Messenger *, int, int, const int16_t *, unsigned int, uint8_t, unsigned int, void *), | ||
663 | void *userdata) | ||
664 | { | ||
665 | Messenger *m = tox; | ||
666 | return join_av_groupchat(m->group_chat_object, friendnumber, data, length, audio_callback, userdata); | ||
667 | } | ||
668 | |||
669 | /* Send audio to the group chat. | ||
670 | * | ||
671 | * return 0 on success. | ||
672 | * return -1 on failure. | ||
673 | * | ||
674 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | ||
675 | * | ||
676 | * Valid number of samples are ((sample rate) * (audio length (Valid ones are: 2.5, 5, 10, 20, 40 or 60 ms)) / 1000) | ||
677 | * Valid number of channels are 1 or 2. | ||
678 | * Valid sample rates are 8000, 12000, 16000, 24000, or 48000. | ||
679 | * | ||
680 | * Recommended values are: samples = 960, channels = 1, sample_rate = 48000 | ||
681 | */ | ||
682 | int toxav_group_send_audio(Tox *tox, int groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels, | ||
683 | unsigned int sample_rate) | ||
684 | { | ||
685 | Messenger *m = tox; | ||
686 | return group_send_audio(m->group_chat_object, groupnumber, pcm, samples, channels, sample_rate); | ||
687 | } | ||
688 | |||
diff --git a/toxav/toxav_new_1.h b/toxav/toxav_new_1.h deleted file mode 100644 index 3696f961..00000000 --- a/toxav/toxav_new_1.h +++ /dev/null | |||
@@ -1,329 +0,0 @@ | |||
1 | /** toxav.h | ||
2 | * | ||
3 | * Copyright (C) 2013 Tox project All Rights Reserved. | ||
4 | * | ||
5 | * This file is part of Tox. | ||
6 | * | ||
7 | * Tox is free software: you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation, either version 3 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * Tox is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | |||
23 | #ifndef __TOXAV | ||
24 | #define __TOXAV | ||
25 | #include <inttypes.h> | ||
26 | |||
27 | #ifdef __cplusplus | ||
28 | extern "C" { | ||
29 | #endif | ||
30 | |||
31 | typedef struct _ToxAv ToxAv; | ||
32 | |||
33 | /* vpx_image_t */ | ||
34 | #include <vpx/vpx_image.h> | ||
35 | |||
36 | typedef void ( *ToxAVCallback ) ( void *agent, int32_t call_idx, void *arg ); | ||
37 | typedef void ( *ToxAvAudioCallback ) (void *agent, int32_t call_idx, const int16_t *PCM, uint16_t size, void *data); | ||
38 | typedef void ( *ToxAvVideoCallback ) (void *agent, int32_t call_idx, const vpx_image_t *img, void *data); | ||
39 | |||
40 | #ifndef __TOX_DEFINED__ | ||
41 | #define __TOX_DEFINED__ | ||
42 | typedef struct Tox Tox; | ||
43 | #endif | ||
44 | |||
45 | #define RTP_PAYLOAD_SIZE 65535 | ||
46 | |||
47 | |||
48 | /** | ||
49 | * Callbacks ids that handle the call states. | ||
50 | */ | ||
51 | typedef enum { | ||
52 | av_OnInvite, /* Incoming call */ | ||
53 | av_OnRinging, /* When peer is ready to accept/reject the call */ | ||
54 | av_OnStart, /* Call (RTP transmission) started */ | ||
55 | av_OnCancel, /* The side that initiated call canceled invite */ | ||
56 | av_OnReject, /* The side that was invited rejected the call */ | ||
57 | av_OnEnd, /* Call that was active ended */ | ||
58 | av_OnRequestTimeout, /* When the requested action didn't get response in specified time */ | ||
59 | av_OnPeerTimeout, /* Peer timed out; stop the call */ | ||
60 | av_OnPeerCSChange, /* Peer changing Csettings. Prepare for changed AV */ | ||
61 | av_OnSelfCSChange /* Csettings change confirmation. Once triggered peer is ready to recv changed AV */ | ||
62 | } ToxAvCallbackID; | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Call type identifier. | ||
67 | */ | ||
68 | typedef enum { | ||
69 | av_TypeAudio = 192, | ||
70 | av_TypeVideo | ||
71 | } ToxAvCallType; | ||
72 | |||
73 | |||
74 | typedef enum { | ||
75 | av_CallNonExistent = -1, | ||
76 | av_CallInviting, /* when sending call invite */ | ||
77 | av_CallStarting, /* when getting call invite */ | ||
78 | av_CallActive, | ||
79 | av_CallHold, | ||
80 | av_CallHungUp | ||
81 | } ToxAvCallState; | ||
82 | |||
83 | /** | ||
84 | * Error indicators. Values under -20 are reserved for toxcore. | ||
85 | */ | ||
86 | typedef enum { | ||
87 | av_ErrorNone = 0, | ||
88 | av_ErrorUnknown = -1, /* Unknown error */ | ||
89 | av_ErrorNoCall = -20, /* Trying to perform call action while not in a call */ | ||
90 | av_ErrorInvalidState = -21, /* Trying to perform call action while in invalid state*/ | ||
91 | av_ErrorAlreadyInCallWithPeer = -22, /* Trying to call peer when already in a call with peer */ | ||
92 | av_ErrorReachedCallLimit = -23, /* Cannot handle more calls */ | ||
93 | av_ErrorInitializingCodecs = -30, /* Failed creating CSSession */ | ||
94 | av_ErrorSettingVideoResolution = -31, /* Error setting resolution */ | ||
95 | av_ErrorSettingVideoBitrate = -32, /* Error setting bitrate */ | ||
96 | av_ErrorSplittingVideoPayload = -33, /* Error splitting video payload */ | ||
97 | av_ErrorEncodingVideo = -34, /* vpx_codec_encode failed */ | ||
98 | av_ErrorEncodingAudio = -35, /* opus_encode failed */ | ||
99 | av_ErrorSendingPayload = -40, /* Sending lossy packet failed */ | ||
100 | av_ErrorCreatingRtpSessions = -41, /* One of the rtp sessions failed to initialize */ | ||
101 | av_ErrorNoRtpSession = -50, /* Trying to perform rtp action on invalid session */ | ||
102 | av_ErrorInvalidCodecState = -51, /* Codec state not initialized */ | ||
103 | av_ErrorPacketTooLarge = -52, /* Split packet exceeds it's limit */ | ||
104 | } ToxAvError; | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Locally supported capabilities. | ||
109 | */ | ||
110 | typedef enum { | ||
111 | av_AudioEncoding = 1 << 0, | ||
112 | av_AudioDecoding = 1 << 1, | ||
113 | av_VideoEncoding = 1 << 2, | ||
114 | av_VideoDecoding = 1 << 3 | ||
115 | } ToxAvCapabilities; | ||
116 | |||
117 | |||
118 | /** | ||
119 | * Encoding settings. | ||
120 | */ | ||
121 | typedef struct _ToxAvCSettings { | ||
122 | ToxAvCallType call_type; | ||
123 | |||
124 | uint32_t video_bitrate; /* In kbits/s */ | ||
125 | uint16_t max_video_width; /* In px */ | ||
126 | uint16_t max_video_height; /* In px */ | ||
127 | |||
128 | uint32_t audio_bitrate; /* In bits/s */ | ||
129 | uint16_t audio_frame_duration; /* In ms */ | ||
130 | uint32_t audio_sample_rate; /* In Hz */ | ||
131 | uint32_t audio_channels; | ||
132 | } ToxAvCSettings; | ||
133 | |||
134 | extern const ToxAvCSettings av_DefaultSettings; | ||
135 | |||
136 | /** | ||
137 | * Start new A/V session. There can only be one session at the time. | ||
138 | */ | ||
139 | ToxAv *toxav_new(Tox *messenger, int32_t max_calls); | ||
140 | |||
141 | /** | ||
142 | * Remove A/V session. | ||
143 | */ | ||
144 | void toxav_kill(ToxAv *av); | ||
145 | |||
146 | /** | ||
147 | * Returns the interval in milliseconds when the next toxav_do() should be called. | ||
148 | * If no call is active at the moment returns 200. | ||
149 | */ | ||
150 | uint32_t toxav_do_interval(ToxAv *av); | ||
151 | |||
152 | /** | ||
153 | * Main loop for the session. Best called right after tox_do(); | ||
154 | */ | ||
155 | void toxav_do(ToxAv *av); | ||
156 | |||
157 | /** | ||
158 | * Register callback for call state. | ||
159 | */ | ||
160 | void toxav_register_callstate_callback (ToxAv *av, ToxAVCallback cb, ToxAvCallbackID id, void *userdata); | ||
161 | |||
162 | /** | ||
163 | * Register callback for audio data. | ||
164 | */ | ||
165 | void toxav_register_audio_callback (ToxAv *av, ToxAvAudioCallback cb, void *userdata); | ||
166 | |||
167 | /** | ||
168 | * Register callback for video data. | ||
169 | */ | ||
170 | void toxav_register_video_callback (ToxAv *av, ToxAvVideoCallback cb, void *userdata); | ||
171 | |||
172 | /** | ||
173 | * Call user. Use its friend_id. | ||
174 | */ | ||
175 | int toxav_call(ToxAv *av, | ||
176 | int32_t *call_index, | ||
177 | int friend_id, | ||
178 | const ToxAvCSettings *csettings, | ||
179 | int ringing_seconds); | ||
180 | |||
181 | /** | ||
182 | * Hangup active call. | ||
183 | */ | ||
184 | int toxav_hangup(ToxAv *av, int32_t call_index); | ||
185 | |||
186 | /** | ||
187 | * Answer incoming call. Pass the csettings that you will use. | ||
188 | */ | ||
189 | int toxav_answer(ToxAv *av, int32_t call_index, const ToxAvCSettings *csettings ); | ||
190 | |||
191 | /** | ||
192 | * Reject incoming call. | ||
193 | */ | ||
194 | int toxav_reject(ToxAv *av, int32_t call_index, const char *reason); | ||
195 | |||
196 | /** | ||
197 | * Cancel outgoing request. | ||
198 | */ | ||
199 | int toxav_cancel(ToxAv *av, int32_t call_index, int peer_id, const char *reason); | ||
200 | |||
201 | /** | ||
202 | * Notify peer that we are changing codec settings. | ||
203 | */ | ||
204 | int toxav_change_settings(ToxAv *av, int32_t call_index, const ToxAvCSettings *csettings); | ||
205 | |||
206 | /** | ||
207 | * Terminate transmission. Note that transmission will be | ||
208 | * terminated without informing remote peer. Usually called when we can't inform peer. | ||
209 | */ | ||
210 | int toxav_stop_call(ToxAv *av, int32_t call_index); | ||
211 | |||
212 | /** | ||
213 | * Allocates transmission data. Must be call before calling toxav_prepare_* and toxav_send_*. | ||
214 | * Also, it must be called when call is started | ||
215 | */ | ||
216 | int toxav_prepare_transmission(ToxAv *av, int32_t call_index, int support_video); | ||
217 | |||
218 | /** | ||
219 | * Clears transmission data. Call this at the end of the transmission. | ||
220 | */ | ||
221 | int toxav_kill_transmission(ToxAv *av, int32_t call_index); | ||
222 | |||
223 | /** | ||
224 | * Encode video frame. | ||
225 | */ | ||
226 | int toxav_prepare_video_frame ( ToxAv *av, | ||
227 | int32_t call_index, | ||
228 | uint8_t *dest, | ||
229 | int dest_max, | ||
230 | vpx_image_t *input); | ||
231 | |||
232 | /** | ||
233 | * Send encoded video packet. | ||
234 | */ | ||
235 | int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *frame, uint32_t frame_size); | ||
236 | |||
237 | /** | ||
238 | * Encode audio frame. | ||
239 | */ | ||
240 | int toxav_prepare_audio_frame ( ToxAv *av, | ||
241 | int32_t call_index, | ||
242 | uint8_t *dest, | ||
243 | int dest_max, | ||
244 | const int16_t *frame, | ||
245 | int frame_size); | ||
246 | |||
247 | /** | ||
248 | * Send encoded audio frame. | ||
249 | */ | ||
250 | int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *frame, unsigned int size); | ||
251 | |||
252 | /** | ||
253 | * Get codec settings from the peer. These were exchanged during call initialization | ||
254 | * or when peer send us new csettings. | ||
255 | */ | ||
256 | int toxav_get_peer_csettings ( ToxAv *av, int32_t call_index, int peer, ToxAvCSettings *dest ); | ||
257 | |||
258 | /** | ||
259 | * Get friend id of peer participating in conversation. | ||
260 | */ | ||
261 | int toxav_get_peer_id ( ToxAv *av, int32_t call_index, int peer ); | ||
262 | |||
263 | /** | ||
264 | * Get current call state. | ||
265 | */ | ||
266 | ToxAvCallState toxav_get_call_state ( ToxAv *av, int32_t call_index ); | ||
267 | |||
268 | /** | ||
269 | * Is certain capability supported. Used to determine if encoding/decoding is ready. | ||
270 | */ | ||
271 | int toxav_capability_supported ( ToxAv *av, int32_t call_index, ToxAvCapabilities capability ); | ||
272 | |||
273 | /** | ||
274 | * Returns tox reference. | ||
275 | */ | ||
276 | Tox *toxav_get_tox (ToxAv *av); | ||
277 | |||
278 | /** | ||
279 | * Returns number of active calls or -1 on error. | ||
280 | */ | ||
281 | int toxav_get_active_count (ToxAv *av); | ||
282 | |||
283 | /* Create a new toxav group. | ||
284 | * | ||
285 | * return group number on success. | ||
286 | * return -1 on failure. | ||
287 | * | ||
288 | * Audio data callback format: | ||
289 | * audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata) | ||
290 | * | ||
291 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | ||
292 | */ | ||
293 | int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(Tox *, int, int, const int16_t *, unsigned int, uint8_t, | ||
294 | unsigned int, void *), void *userdata); | ||
295 | |||
296 | /* Join a AV group (you need to have been invited first.) | ||
297 | * | ||
298 | * returns group number on success | ||
299 | * returns -1 on failure. | ||
300 | * | ||
301 | * Audio data callback format (same as the one for toxav_add_av_groupchat()): | ||
302 | * audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata) | ||
303 | * | ||
304 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | ||
305 | */ | ||
306 | int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length, | ||
307 | void (*audio_callback)(Tox *, int, int, const int16_t *, unsigned int, uint8_t, unsigned int, void *), void *userdata); | ||
308 | |||
309 | /* Send audio to the group chat. | ||
310 | * | ||
311 | * return 0 on success. | ||
312 | * return -1 on failure. | ||
313 | * | ||
314 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | ||
315 | * | ||
316 | * Valid number of samples are ((sample rate) * (audio length (Valid ones are: 2.5, 5, 10, 20, 40 or 60 ms)) / 1000) | ||
317 | * Valid number of channels are 1 or 2. | ||
318 | * Valid sample rates are 8000, 12000, 16000, 24000, or 48000. | ||
319 | * | ||
320 | * Recommended values are: samples = 960, channels = 1, sample_rate = 48000 | ||
321 | */ | ||
322 | int toxav_group_send_audio(Tox *tox, int groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels, | ||
323 | unsigned int sample_rate); | ||
324 | |||
325 | #ifdef __cplusplus | ||
326 | } | ||
327 | #endif | ||
328 | |||
329 | #endif /* __TOXAV */ | ||
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 919655a2..2d3d6ffe 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -207,7 +207,7 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_ | |||
207 | } | 207 | } |
208 | 208 | ||
209 | if (ipv6 == 0) { | 209 | if (ipv6 == 0) { |
210 | uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + CLIENT_ID_SIZE; | 210 | uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES; |
211 | 211 | ||
212 | if (packed_length + size > length) | 212 | if (packed_length + size > length) |
213 | return -1; | 213 | return -1; |
@@ -215,10 +215,10 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_ | |||
215 | data[packed_length] = net_family; | 215 | data[packed_length] = net_family; |
216 | memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip4, sizeof(IP4)); | 216 | memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip4, sizeof(IP4)); |
217 | memcpy(data + packed_length + 1 + sizeof(IP4), &nodes[i].ip_port.port, sizeof(uint16_t)); | 217 | memcpy(data + packed_length + 1 + sizeof(IP4), &nodes[i].ip_port.port, sizeof(uint16_t)); |
218 | memcpy(data + packed_length + 1 + sizeof(IP4) + sizeof(uint16_t), nodes[i].client_id, CLIENT_ID_SIZE); | 218 | memcpy(data + packed_length + 1 + sizeof(IP4) + sizeof(uint16_t), nodes[i].public_key, crypto_box_PUBLICKEYBYTES); |
219 | packed_length += size; | 219 | packed_length += size; |
220 | } else if (ipv6 == 1) { | 220 | } else if (ipv6 == 1) { |
221 | uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + CLIENT_ID_SIZE; | 221 | uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES; |
222 | 222 | ||
223 | if (packed_length + size > length) | 223 | if (packed_length + size > length) |
224 | return -1; | 224 | return -1; |
@@ -226,7 +226,7 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_ | |||
226 | data[packed_length] = net_family; | 226 | data[packed_length] = net_family; |
227 | memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip6, sizeof(IP6)); | 227 | memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip6, sizeof(IP6)); |
228 | memcpy(data + packed_length + 1 + sizeof(IP6), &nodes[i].ip_port.port, sizeof(uint16_t)); | 228 | memcpy(data + packed_length + 1 + sizeof(IP6), &nodes[i].ip_port.port, sizeof(uint16_t)); |
229 | memcpy(data + packed_length + 1 + sizeof(IP6) + sizeof(uint16_t), nodes[i].client_id, CLIENT_ID_SIZE); | 229 | memcpy(data + packed_length + 1 + sizeof(IP6) + sizeof(uint16_t), nodes[i].public_key, crypto_box_PUBLICKEYBYTES); |
230 | packed_length += size; | 230 | packed_length += size; |
231 | } else { | 231 | } else { |
232 | return -1; | 232 | return -1; |
@@ -275,7 +275,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed | |||
275 | } | 275 | } |
276 | 276 | ||
277 | if (ipv6 == 0) { | 277 | if (ipv6 == 0) { |
278 | uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + CLIENT_ID_SIZE; | 278 | uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES; |
279 | 279 | ||
280 | if (len_processed + size > length) | 280 | if (len_processed + size > length) |
281 | return -1; | 281 | return -1; |
@@ -283,11 +283,11 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed | |||
283 | nodes[num].ip_port.ip.family = host_family; | 283 | nodes[num].ip_port.ip.family = host_family; |
284 | memcpy(&nodes[num].ip_port.ip.ip4, data + len_processed + 1, sizeof(IP4)); | 284 | memcpy(&nodes[num].ip_port.ip.ip4, data + len_processed + 1, sizeof(IP4)); |
285 | memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP4), sizeof(uint16_t)); | 285 | memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP4), sizeof(uint16_t)); |
286 | memcpy(nodes[num].client_id, data + len_processed + 1 + sizeof(IP4) + sizeof(uint16_t), CLIENT_ID_SIZE); | 286 | memcpy(nodes[num].public_key, data + len_processed + 1 + sizeof(IP4) + sizeof(uint16_t), crypto_box_PUBLICKEYBYTES); |
287 | len_processed += size; | 287 | len_processed += size; |
288 | ++num; | 288 | ++num; |
289 | } else if (ipv6 == 1) { | 289 | } else if (ipv6 == 1) { |
290 | uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + CLIENT_ID_SIZE; | 290 | uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES; |
291 | 291 | ||
292 | if (len_processed + size > length) | 292 | if (len_processed + size > length) |
293 | return -1; | 293 | return -1; |
@@ -295,7 +295,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed | |||
295 | nodes[num].ip_port.ip.family = host_family; | 295 | nodes[num].ip_port.ip.family = host_family; |
296 | memcpy(&nodes[num].ip_port.ip.ip6, data + len_processed + 1, sizeof(IP6)); | 296 | memcpy(&nodes[num].ip_port.ip.ip6, data + len_processed + 1, sizeof(IP6)); |
297 | memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP6), sizeof(uint16_t)); | 297 | memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP6), sizeof(uint16_t)); |
298 | memcpy(nodes[num].client_id, data + len_processed + 1 + sizeof(IP6) + sizeof(uint16_t), CLIENT_ID_SIZE); | 298 | memcpy(nodes[num].public_key, data + len_processed + 1 + sizeof(IP6) + sizeof(uint16_t), crypto_box_PUBLICKEYBYTES); |
299 | len_processed += size; | 299 | len_processed += size; |
300 | ++num; | 300 | ++num; |
301 | } else { | 301 | } else { |
@@ -397,12 +397,12 @@ static int client_or_ip_port_in_list(Client_data *list, uint16_t length, const u | |||
397 | * return 1 if true. | 397 | * return 1 if true. |
398 | * return 0 if false. | 398 | * return 0 if false. |
399 | */ | 399 | */ |
400 | static int client_in_nodelist(const Node_format *list, uint16_t length, const uint8_t *client_id) | 400 | static int client_in_nodelist(const Node_format *list, uint16_t length, const uint8_t *public_key) |
401 | { | 401 | { |
402 | uint32_t i; | 402 | uint32_t i; |
403 | 403 | ||
404 | for (i = 0; i < length; ++i) { | 404 | for (i = 0; i < length; ++i) { |
405 | if (id_equal(list[i].client_id, client_id)) | 405 | if (id_equal(list[i].public_key, public_key)) |
406 | return 1; | 406 | return 1; |
407 | } | 407 | } |
408 | 408 | ||
@@ -484,9 +484,9 @@ static void get_close_nodes_inner(const uint8_t *client_id, Node_format *nodes_l | |||
484 | continue; | 484 | continue; |
485 | 485 | ||
486 | if (num_nodes < MAX_SENT_NODES) { | 486 | if (num_nodes < MAX_SENT_NODES) { |
487 | memcpy(nodes_list[num_nodes].client_id, | 487 | memcpy(nodes_list[num_nodes].public_key, |
488 | client->client_id, | 488 | client->client_id, |
489 | CLIENT_ID_SIZE ); | 489 | crypto_box_PUBLICKEYBYTES ); |
490 | 490 | ||
491 | nodes_list[num_nodes].ip_port = ipptp->ip_port; | 491 | nodes_list[num_nodes].ip_port = ipptp->ip_port; |
492 | num_nodes++; | 492 | num_nodes++; |
@@ -497,14 +497,14 @@ static void get_close_nodes_inner(const uint8_t *client_id, Node_format *nodes_l | |||
497 | */ | 497 | */ |
498 | for (j = 0; j < MAX_SENT_NODES; ++j) { | 498 | for (j = 0; j < MAX_SENT_NODES; ++j) { |
499 | closest = id_closest( client_id, | 499 | closest = id_closest( client_id, |
500 | nodes_list[j].client_id, | 500 | nodes_list[j].public_key, |
501 | client->client_id ); | 501 | client->client_id ); |
502 | 502 | ||
503 | /* second client_id is closer than current: change to it */ | 503 | /* second client_id is closer than current: change to it */ |
504 | if (closest == 2) { | 504 | if (closest == 2) { |
505 | memcpy( nodes_list[j].client_id, | 505 | memcpy( nodes_list[j].public_key, |
506 | client->client_id, | 506 | client->client_id, |
507 | CLIENT_ID_SIZE); | 507 | crypto_box_PUBLICKEYBYTES); |
508 | 508 | ||
509 | nodes_list[j].ip_port = ipptp->ip_port; | 509 | nodes_list[j].ip_port = ipptp->ip_port; |
510 | break; | 510 | break; |
@@ -583,7 +583,7 @@ int get_close_nodes(const DHT *dht, const uint8_t *client_id, Node_format *nodes | |||
583 | Client_data *client = result[i]; | 583 | Client_data *client = result[i]; |
584 | 584 | ||
585 | if (client) { | 585 | if (client) { |
586 | id_copy(nodes_list[num_returned].client_id, client->client_id); | 586 | id_copy(nodes_list[num_returned].public_key, client->client_id); |
587 | 587 | ||
588 | if (sa_family == AF_INET) | 588 | if (sa_family == AF_INET) |
589 | if (ipport_isset(&client->assoc4.ip_port)) { | 589 | if (ipport_isset(&client->assoc4.ip_port)) { |
@@ -647,6 +647,21 @@ static int cmp_dht_entry(const void *a, const void *b) | |||
647 | return 0; | 647 | return 0; |
648 | } | 648 | } |
649 | 649 | ||
650 | /* Is it ok to store node with client_id in client. | ||
651 | * | ||
652 | * return 0 if node can't be stored. | ||
653 | * return 1 if it can. | ||
654 | */ | ||
655 | static unsigned int store_node_ok(const Client_data *client, const uint8_t *client_id, const uint8_t *comp_client_id) | ||
656 | { | ||
657 | if ((is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) | ||
658 | || (id_closest(comp_client_id, client->client_id, client_id) == 2)) { | ||
659 | return 1; | ||
660 | } else { | ||
661 | return 0; | ||
662 | } | ||
663 | } | ||
664 | |||
650 | /* Replace a first bad (or empty) node with this one | 665 | /* Replace a first bad (or empty) node with this one |
651 | * or replace a possibly bad node (tests failed or not done yet) | 666 | * or replace a possibly bad node (tests failed or not done yet) |
652 | * that is further than any other in the list | 667 | * that is further than any other in the list |
@@ -674,8 +689,7 @@ static int replace_all( Client_data *list, | |||
674 | 689 | ||
675 | Client_data *client = &list[0]; | 690 | Client_data *client = &list[0]; |
676 | 691 | ||
677 | if ((is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) | 692 | if (store_node_ok(client, client_id, comp_client_id)) { |
678 | || (id_closest(comp_client_id, client->client_id, client_id) == 2)) { | ||
679 | IPPTsPng *ipptp_write = NULL; | 693 | IPPTsPng *ipptp_write = NULL; |
680 | IPPTsPng *ipptp_clear = NULL; | 694 | IPPTsPng *ipptp_clear = NULL; |
681 | 695 | ||
@@ -704,6 +718,29 @@ static int replace_all( Client_data *list, | |||
704 | return 0; | 718 | return 0; |
705 | } | 719 | } |
706 | 720 | ||
721 | /* Check if the node obtained with a get_nodes with client_id should be pinged. | ||
722 | * NOTE: for best results call it after addto_lists; | ||
723 | * | ||
724 | * return 0 if the node should not be pinged. | ||
725 | * return 1 if it should. | ||
726 | */ | ||
727 | static unsigned int ping_node_from_getnodes_ok(DHT *dht, const uint8_t *client_id) | ||
728 | { | ||
729 | if (store_node_ok(&dht->close_clientlist[0], client_id, dht->self_public_key)) { | ||
730 | return 1; | ||
731 | } | ||
732 | |||
733 | unsigned int i; | ||
734 | |||
735 | for (i = 0; i < dht->num_friends; ++i) { | ||
736 | if (store_node_ok(&dht->friends_list[i].client_list[0], client_id, dht->self_public_key)) { | ||
737 | return 1; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | return 0; | ||
742 | } | ||
743 | |||
707 | /* Attempt to add client with ip_port and client_id to the friends client list | 744 | /* Attempt to add client with ip_port and client_id to the friends client list |
708 | * and close_clientlist. | 745 | * and close_clientlist. |
709 | * | 746 | * |
@@ -860,7 +897,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const | |||
860 | uint8_t plain_message[sizeof(Node_format) * 2] = {0}; | 897 | uint8_t plain_message[sizeof(Node_format) * 2] = {0}; |
861 | 898 | ||
862 | Node_format receiver; | 899 | Node_format receiver; |
863 | memcpy(receiver.client_id, public_key, CLIENT_ID_SIZE); | 900 | memcpy(receiver.public_key, public_key, CLIENT_ID_SIZE); |
864 | receiver.ip_port = ip_port; | 901 | receiver.ip_port = ip_port; |
865 | memcpy(plain_message, &receiver, sizeof(receiver)); | 902 | memcpy(plain_message, &receiver, sizeof(receiver)); |
866 | 903 | ||
@@ -1004,7 +1041,7 @@ static uint8_t sent_getnode_to_node(DHT *dht, const uint8_t *client_id, IP_Port | |||
1004 | Node_format test; | 1041 | Node_format test; |
1005 | memcpy(&test, data, sizeof(Node_format)); | 1042 | memcpy(&test, data, sizeof(Node_format)); |
1006 | 1043 | ||
1007 | if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.client_id, client_id, CLIENT_ID_SIZE) != 0) | 1044 | if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.public_key, client_id, CLIENT_ID_SIZE) != 0) |
1008 | return 0; | 1045 | return 0; |
1009 | 1046 | ||
1010 | return 1; | 1047 | return 1; |
@@ -1091,9 +1128,10 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *pa | |||
1091 | uint32_t i; | 1128 | uint32_t i; |
1092 | 1129 | ||
1093 | for (i = 0; i < num_nodes; i++) { | 1130 | for (i = 0; i < num_nodes; i++) { |
1094 | if (ipport_isset(&plain_nodes[i].ip_port)) { | 1131 | if (ipport_isset(&plain_nodes[i].ip_port) && (LAN_ip(plain_nodes[i].ip_port.ip) == 0 |
1095 | send_ping_request(dht->ping, plain_nodes[i].ip_port, plain_nodes[i].client_id); | 1132 | || ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key))) { |
1096 | returnedip_ports(dht, plain_nodes[i].ip_port, plain_nodes[i].client_id, packet + 1); | 1133 | send_ping_request(dht->ping, plain_nodes[i].ip_port, plain_nodes[i].public_key); |
1134 | returnedip_ports(dht, plain_nodes[i].ip_port, plain_nodes[i].public_key, packet + 1); | ||
1097 | } | 1135 | } |
1098 | } | 1136 | } |
1099 | 1137 | ||
@@ -1847,7 +1885,7 @@ static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8 | |||
1847 | uint8_t data[HARDREQ_DATA_SIZE] = {0}; | 1885 | uint8_t data[HARDREQ_DATA_SIZE] = {0}; |
1848 | data[0] = type; | 1886 | data[0] = type; |
1849 | memcpy(data + 1, contents, length); | 1887 | memcpy(data + 1, contents, length); |
1850 | int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data, | 1888 | int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->public_key, data, |
1851 | sizeof(data), CRYPTO_PACKET_HARDENING); | 1889 | sizeof(data), CRYPTO_PACKET_HARDENING); |
1852 | 1890 | ||
1853 | if (len == -1) | 1891 | if (len == -1) |
@@ -1877,7 +1915,7 @@ static int send_hardening_getnode_res(const DHT *dht, const Node_format *sendto, | |||
1877 | data[0] = CHECK_TYPE_GETNODE_RES; | 1915 | data[0] = CHECK_TYPE_GETNODE_RES; |
1878 | memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE); | 1916 | memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE); |
1879 | memcpy(data + 1 + CLIENT_ID_SIZE, nodes_data, nodes_data_length); | 1917 | memcpy(data + 1 + CLIENT_ID_SIZE, nodes_data, nodes_data_length); |
1880 | int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data, | 1918 | int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->public_key, data, |
1881 | sizeof(data), CRYPTO_PACKET_HARDENING); | 1919 | sizeof(data), CRYPTO_PACKET_HARDENING); |
1882 | 1920 | ||
1883 | if (len == -1) | 1921 | if (len == -1) |
@@ -1914,12 +1952,12 @@ static uint32_t have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num) | |||
1914 | uint32_t i; | 1952 | uint32_t i; |
1915 | 1953 | ||
1916 | for (i = 0; i < num; ++i) { | 1954 | for (i = 0; i < num; ++i) { |
1917 | if (id_equal(nodes[i].client_id, dht->self_public_key)) { | 1955 | if (id_equal(nodes[i].public_key, dht->self_public_key)) { |
1918 | ++counter; | 1956 | ++counter; |
1919 | continue; | 1957 | continue; |
1920 | } | 1958 | } |
1921 | 1959 | ||
1922 | IPPTsPng *temp = get_closelist_IPPTsPng(dht, nodes[i].client_id, nodes[i].ip_port.ip.family); | 1960 | IPPTsPng *temp = get_closelist_IPPTsPng(dht, nodes[i].public_key, nodes[i].ip_port.ip.family); |
1923 | 1961 | ||
1924 | if (temp) { | 1962 | if (temp) { |
1925 | if (!is_timeout(temp->timestamp, BAD_NODE_TIMEOUT)) { | 1963 | if (!is_timeout(temp->timestamp, BAD_NODE_TIMEOUT)) { |
@@ -1952,10 +1990,10 @@ static int handle_hardening(void *object, IP_Port source, const uint8_t *source_ | |||
1952 | 1990 | ||
1953 | Node_format node, tocheck_node; | 1991 | Node_format node, tocheck_node; |
1954 | node.ip_port = source; | 1992 | node.ip_port = source; |
1955 | memcpy(node.client_id, source_pubkey, CLIENT_ID_SIZE); | 1993 | memcpy(node.public_key, source_pubkey, crypto_box_PUBLICKEYBYTES); |
1956 | memcpy(&tocheck_node, packet + 1, sizeof(Node_format)); | 1994 | memcpy(&tocheck_node, packet + 1, sizeof(Node_format)); |
1957 | 1995 | ||
1958 | if (getnodes(dht, tocheck_node.ip_port, tocheck_node.client_id, packet + 1 + sizeof(Node_format), &node) == -1) | 1996 | if (getnodes(dht, tocheck_node.ip_port, tocheck_node.public_key, packet + 1 + sizeof(Node_format), &node) == -1) |
1959 | return 1; | 1997 | return 1; |
1960 | 1998 | ||
1961 | return 0; | 1999 | return 0; |
@@ -2052,7 +2090,7 @@ uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num) | |||
2052 | } | 2090 | } |
2053 | 2091 | ||
2054 | if (assoc != NULL) { | 2092 | if (assoc != NULL) { |
2055 | memcpy(nodes[count].client_id, list[i - 1].client_id, CLIENT_ID_SIZE); | 2093 | memcpy(nodes[count].public_key, list[i - 1].client_id, CLIENT_ID_SIZE); |
2056 | nodes[count].ip_port = assoc->ip_port; | 2094 | nodes[count].ip_port = assoc->ip_port; |
2057 | ++count; | 2095 | ++count; |
2058 | 2096 | ||
@@ -2091,16 +2129,16 @@ void do_hardening(DHT *dht) | |||
2091 | if (!ipport_isset(&rand_node.ip_port)) | 2129 | if (!ipport_isset(&rand_node.ip_port)) |
2092 | continue; | 2130 | continue; |
2093 | 2131 | ||
2094 | if (id_equal(client_id, rand_node.client_id)) | 2132 | if (id_equal(client_id, rand_node.public_key)) |
2095 | continue; | 2133 | continue; |
2096 | 2134 | ||
2097 | Node_format to_test; | 2135 | Node_format to_test; |
2098 | to_test.ip_port = cur_iptspng->ip_port; | 2136 | to_test.ip_port = cur_iptspng->ip_port; |
2099 | memcpy(to_test.client_id, client_id, CLIENT_ID_SIZE); | 2137 | memcpy(to_test.public_key, client_id, crypto_box_PUBLICKEYBYTES); |
2100 | 2138 | ||
2101 | //TODO: The search id should maybe not be ours? | 2139 | //TODO: The search id should maybe not be ours? |
2102 | if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) { | 2140 | if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) { |
2103 | memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.client_id, CLIENT_ID_SIZE); | 2141 | memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.public_key, crypto_box_PUBLICKEYBYTES); |
2104 | cur_iptspng->hardening.send_nodes_timestamp = unix_time(); | 2142 | cur_iptspng->hardening.send_nodes_timestamp = unix_time(); |
2105 | } | 2143 | } |
2106 | } | 2144 | } |
diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 47a828d7..318a6002 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h | |||
@@ -148,7 +148,7 @@ typedef struct { | |||
148 | } DHT_Friend; | 148 | } DHT_Friend; |
149 | 149 | ||
150 | typedef struct { | 150 | typedef struct { |
151 | uint8_t client_id[CLIENT_ID_SIZE]; | 151 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
152 | IP_Port ip_port; | 152 | IP_Port ip_port; |
153 | } | 153 | } |
154 | Node_format; | 154 | Node_format; |
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index f87f1348..bc020d87 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c | |||
@@ -152,6 +152,11 @@ static void fetch_broadcast_info(uint16_t port) | |||
152 | IP_Port *ip_port = &broadcast_ip_port[broadcast_count]; | 152 | IP_Port *ip_port = &broadcast_ip_port[broadcast_count]; |
153 | ip_port->ip.family = AF_INET; | 153 | ip_port->ip.family = AF_INET; |
154 | ip_port->ip.ip4.in_addr = sock4->sin_addr; | 154 | ip_port->ip.ip4.in_addr = sock4->sin_addr; |
155 | |||
156 | if (ip_port->ip.ip4.uint32 == 0) { | ||
157 | continue; | ||
158 | } | ||
159 | |||
155 | ip_port->port = port; | 160 | ip_port->port = port; |
156 | broadcast_count++; | 161 | broadcast_count++; |
157 | } | 162 | } |
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index c310412d..4cf0edeb 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -89,32 +89,32 @@ int realloc_friendlist(Messenger *m, uint32_t num) | |||
89 | /* return the friend id associated to that public key. | 89 | /* return the friend id associated to that public key. |
90 | * return -1 if no such friend. | 90 | * return -1 if no such friend. |
91 | */ | 91 | */ |
92 | int32_t getfriend_id(const Messenger *m, const uint8_t *client_id) | 92 | int32_t getfriend_id(const Messenger *m, const uint8_t *real_pk) |
93 | { | 93 | { |
94 | uint32_t i; | 94 | uint32_t i; |
95 | 95 | ||
96 | for (i = 0; i < m->numfriends; ++i) { | 96 | for (i = 0; i < m->numfriends; ++i) { |
97 | if (m->friendlist[i].status > 0) | 97 | if (m->friendlist[i].status > 0) |
98 | if (id_equal(client_id, m->friendlist[i].client_id)) | 98 | if (id_equal(real_pk, m->friendlist[i].real_pk)) |
99 | return i; | 99 | return i; |
100 | } | 100 | } |
101 | 101 | ||
102 | return -1; | 102 | return -1; |
103 | } | 103 | } |
104 | 104 | ||
105 | /* Copies the public key associated to that friend id into client_id buffer. | 105 | /* Copies the public key associated to that friend id into real_pk buffer. |
106 | * Make sure that client_id is of size CLIENT_ID_SIZE. | 106 | * Make sure that real_pk is of size crypto_box_PUBLICKEYBYTES. |
107 | * | 107 | * |
108 | * return 0 if success. | 108 | * return 0 if success. |
109 | * return -1 if failure. | 109 | * return -1 if failure. |
110 | */ | 110 | */ |
111 | int getclient_id(const Messenger *m, int32_t friendnumber, uint8_t *client_id) | 111 | int get_real_pk(const Messenger *m, int32_t friendnumber, uint8_t *real_pk) |
112 | { | 112 | { |
113 | if (friend_not_valid(m, friendnumber)) | 113 | if (friend_not_valid(m, friendnumber)) |
114 | return -1; | 114 | return -1; |
115 | 115 | ||
116 | if (m->friendlist[friendnumber].status > 0) { | 116 | if (m->friendlist[friendnumber].status > 0) { |
117 | memcpy(client_id, m->friendlist[friendnumber].client_id, CLIENT_ID_SIZE); | 117 | memcpy(real_pk, m->friendlist[friendnumber].real_pk, crypto_box_PUBLICKEYBYTES); |
118 | return 0; | 118 | return 0; |
119 | } | 119 | } |
120 | 120 | ||
@@ -149,7 +149,7 @@ static uint16_t address_checksum(const uint8_t *address, uint32_t len) | |||
149 | return check; | 149 | return check; |
150 | } | 150 | } |
151 | 151 | ||
152 | /* Format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] | 152 | /* Format: [real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] |
153 | * | 153 | * |
154 | * return FRIEND_ADDRESS_SIZE byte address to give to others. | 154 | * return FRIEND_ADDRESS_SIZE byte address to give to others. |
155 | */ | 155 | */ |
@@ -183,6 +183,54 @@ static int handle_status(void *object, int i, uint8_t status); | |||
183 | static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len); | 183 | static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len); |
184 | static int handle_custom_lossy_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length); | 184 | static int handle_custom_lossy_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length); |
185 | 185 | ||
186 | static int32_t init_new_friend(Messenger *m, const uint8_t *real_pk, uint8_t status) | ||
187 | { | ||
188 | /* Resize the friend list if necessary. */ | ||
189 | if (realloc_friendlist(m, m->numfriends + 1) != 0) | ||
190 | return FAERR_NOMEM; | ||
191 | |||
192 | memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); | ||
193 | |||
194 | int friendcon_id = new_friend_connection(m->fr_c, real_pk); | ||
195 | |||
196 | if (friendcon_id == -1) | ||
197 | return FAERR_UNKNOWN; | ||
198 | |||
199 | uint32_t i; | ||
200 | |||
201 | for (i = 0; i <= m->numfriends; ++i) { | ||
202 | if (m->friendlist[i].status == NOFRIEND) { | ||
203 | m->friendlist[i].status = status; | ||
204 | m->friendlist[i].friendcon_id = friendcon_id; | ||
205 | m->friendlist[i].friendrequest_lastsent = 0; | ||
206 | id_copy(m->friendlist[i].real_pk, real_pk); | ||
207 | m->friendlist[i].statusmessage = calloc(1, 1); | ||
208 | m->friendlist[i].statusmessage_length = 1; | ||
209 | m->friendlist[i].userstatus = USERSTATUS_NONE; | ||
210 | m->friendlist[i].avatar_info_sent = 0; | ||
211 | m->friendlist[i].avatar_recv_data = NULL; | ||
212 | m->friendlist[i].avatar_send_data.bytes_sent = 0; | ||
213 | m->friendlist[i].avatar_send_data.last_reset = 0; | ||
214 | m->friendlist[i].is_typing = 0; | ||
215 | m->friendlist[i].message_id = 0; | ||
216 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ | ||
217 | friend_connection_callbacks(m->fr_c, friendcon_id, MESSENGER_CALLBACK_INDEX, &handle_status, &handle_packet, | ||
218 | &handle_custom_lossy_packet, m, i); | ||
219 | |||
220 | if (m->numfriends == i) | ||
221 | ++m->numfriends; | ||
222 | |||
223 | if (friend_con_connected(m->fr_c, friendcon_id) == FRIENDCONN_STATUS_CONNECTED) { | ||
224 | send_online_packet(m, i); | ||
225 | } | ||
226 | |||
227 | return i; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | return FAERR_UNKNOWN; | ||
232 | } | ||
233 | |||
186 | /* | 234 | /* |
187 | * Add a friend. | 235 | * Add a friend. |
188 | * Set the data that will be sent along with friend request. | 236 | * Set the data that will be sent along with friend request. |
@@ -205,10 +253,10 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u | |||
205 | if (length > MAX_FRIEND_REQUEST_DATA_SIZE) | 253 | if (length > MAX_FRIEND_REQUEST_DATA_SIZE) |
206 | return FAERR_TOOLONG; | 254 | return FAERR_TOOLONG; |
207 | 255 | ||
208 | uint8_t client_id[crypto_box_PUBLICKEYBYTES]; | 256 | uint8_t real_pk[crypto_box_PUBLICKEYBYTES]; |
209 | id_copy(client_id, address); | 257 | id_copy(real_pk, address); |
210 | 258 | ||
211 | if (!public_key_valid(client_id)) | 259 | if (!public_key_valid(real_pk)) |
212 | return FAERR_BADCHECKSUM; | 260 | return FAERR_BADCHECKSUM; |
213 | 261 | ||
214 | uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); | 262 | uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); |
@@ -220,10 +268,10 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u | |||
220 | if (length < 1) | 268 | if (length < 1) |
221 | return FAERR_NOMESSAGE; | 269 | return FAERR_NOMESSAGE; |
222 | 270 | ||
223 | if (id_equal(client_id, m->net_crypto->self_public_key)) | 271 | if (id_equal(real_pk, m->net_crypto->self_public_key)) |
224 | return FAERR_OWNKEY; | 272 | return FAERR_OWNKEY; |
225 | 273 | ||
226 | int32_t friend_id = getfriend_id(m, client_id); | 274 | int32_t friend_id = getfriend_id(m, real_pk); |
227 | 275 | ||
228 | if (friend_id != -1) { | 276 | if (friend_id != -1) { |
229 | if (m->friendlist[friend_id].status >= FRIEND_CONFIRMED) | 277 | if (m->friendlist[friend_id].status >= FRIEND_CONFIRMED) |
@@ -239,111 +287,38 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u | |||
239 | return FAERR_SETNEWNOSPAM; | 287 | return FAERR_SETNEWNOSPAM; |
240 | } | 288 | } |
241 | 289 | ||
242 | /* Resize the friend list if necessary. */ | 290 | int32_t ret = init_new_friend(m, real_pk, FRIEND_ADDED); |
243 | if (realloc_friendlist(m, m->numfriends + 1) != 0) | ||
244 | return FAERR_NOMEM; | ||
245 | |||
246 | memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); | ||
247 | |||
248 | int friendcon_id = new_friend_connection(m->fr_c, client_id); | ||
249 | 291 | ||
250 | if (friendcon_id == -1) | 292 | if (ret < 0) { |
251 | return -1; | 293 | return ret; |
252 | |||
253 | uint32_t i; | ||
254 | |||
255 | for (i = 0; i <= m->numfriends; ++i) { | ||
256 | if (m->friendlist[i].status == NOFRIEND) { | ||
257 | m->friendlist[i].status = FRIEND_ADDED; | ||
258 | m->friendlist[i].friendcon_id = friendcon_id; | ||
259 | m->friendlist[i].friendrequest_lastsent = 0; | ||
260 | m->friendlist[i].friendrequest_timeout = FRIENDREQUEST_TIMEOUT; | ||
261 | id_copy(m->friendlist[i].client_id, client_id); | ||
262 | m->friendlist[i].statusmessage = calloc(1, 1); | ||
263 | m->friendlist[i].statusmessage_length = 1; | ||
264 | m->friendlist[i].userstatus = USERSTATUS_NONE; | ||
265 | m->friendlist[i].avatar_info_sent = 0; | ||
266 | m->friendlist[i].avatar_recv_data = NULL; | ||
267 | m->friendlist[i].avatar_send_data.bytes_sent = 0; | ||
268 | m->friendlist[i].avatar_send_data.last_reset = 0; | ||
269 | m->friendlist[i].is_typing = 0; | ||
270 | memcpy(m->friendlist[i].info, data, length); | ||
271 | m->friendlist[i].info_size = length; | ||
272 | m->friendlist[i].message_id = 0; | ||
273 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ | ||
274 | memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); | ||
275 | friend_connection_callbacks(m->fr_c, friendcon_id, MESSENGER_CALLBACK_INDEX, &handle_status, &handle_packet, | ||
276 | &handle_custom_lossy_packet, m, i); | ||
277 | |||
278 | if (m->numfriends == i) | ||
279 | ++m->numfriends; | ||
280 | |||
281 | if (friend_con_connected(m->fr_c, friendcon_id) == FRIENDCONN_STATUS_CONNECTED) { | ||
282 | send_online_packet(m, i); | ||
283 | } | ||
284 | |||
285 | return i; | ||
286 | } | ||
287 | } | 294 | } |
288 | 295 | ||
289 | return FAERR_UNKNOWN; | 296 | m->friendlist[ret].friendrequest_timeout = FRIENDREQUEST_TIMEOUT; |
297 | memcpy(m->friendlist[ret].info, data, length); | ||
298 | m->friendlist[ret].info_size = length; | ||
299 | memcpy(&(m->friendlist[ret].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); | ||
300 | |||
301 | return ret; | ||
290 | } | 302 | } |
291 | 303 | ||
292 | int32_t m_addfriend_norequest(Messenger *m, const uint8_t *client_id) | 304 | int32_t m_addfriend_norequest(Messenger *m, const uint8_t *real_pk) |
293 | { | 305 | { |
294 | if (getfriend_id(m, client_id) != -1) | 306 | if (getfriend_id(m, real_pk) != -1) |
295 | return -1; | 307 | return -1; |
296 | 308 | ||
297 | if (!public_key_valid(client_id)) | 309 | if (!public_key_valid(real_pk)) |
298 | return -1; | 310 | return -1; |
299 | 311 | ||
300 | /* Resize the friend list if necessary. */ | 312 | if (id_equal(real_pk, m->net_crypto->self_public_key)) |
301 | if (realloc_friendlist(m, m->numfriends + 1) != 0) | ||
302 | return -1; | 313 | return -1; |
303 | 314 | ||
304 | if (id_equal(client_id, m->net_crypto->self_public_key)) | 315 | int32_t ret = init_new_friend(m, real_pk, FRIEND_CONFIRMED); |
305 | return -1; | ||
306 | |||
307 | memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); | ||
308 | |||
309 | int friendcon_id = new_friend_connection(m->fr_c, client_id); | ||
310 | 316 | ||
311 | if (friendcon_id == -1) | 317 | if (ret < 0) { |
312 | return -1; | 318 | return -1; |
313 | 319 | } else { | |
314 | uint32_t i; | 320 | return ret; |
315 | |||
316 | for (i = 0; i <= m->numfriends; ++i) { | ||
317 | if (m->friendlist[i].status == NOFRIEND) { | ||
318 | m->friendlist[i].status = FRIEND_CONFIRMED; | ||
319 | m->friendlist[i].friendcon_id = friendcon_id; | ||
320 | m->friendlist[i].friendrequest_lastsent = 0; | ||
321 | id_copy(m->friendlist[i].client_id, client_id); | ||
322 | m->friendlist[i].statusmessage = calloc(1, 1); | ||
323 | m->friendlist[i].statusmessage_length = 1; | ||
324 | m->friendlist[i].userstatus = USERSTATUS_NONE; | ||
325 | m->friendlist[i].avatar_info_sent = 0; | ||
326 | m->friendlist[i].avatar_recv_data = NULL; | ||
327 | m->friendlist[i].avatar_send_data.bytes_sent = 0; | ||
328 | m->friendlist[i].avatar_send_data.last_reset = 0; | ||
329 | m->friendlist[i].is_typing = 0; | ||
330 | m->friendlist[i].message_id = 0; | ||
331 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ | ||
332 | friend_connection_callbacks(m->fr_c, friendcon_id, MESSENGER_CALLBACK_INDEX, &handle_status, &handle_packet, | ||
333 | &handle_custom_lossy_packet, m, i); | ||
334 | |||
335 | if (m->numfriends == i) | ||
336 | ++m->numfriends; | ||
337 | |||
338 | if (friend_con_connected(m->fr_c, friendcon_id) == FRIENDCONN_STATUS_CONNECTED) { | ||
339 | send_online_packet(m, i); | ||
340 | } | ||
341 | |||
342 | return i; | ||
343 | } | ||
344 | } | 321 | } |
345 | |||
346 | return -1; | ||
347 | } | 322 | } |
348 | 323 | ||
349 | /* Remove a friend. | 324 | /* Remove a friend. |
@@ -361,7 +336,7 @@ int m_delfriend(Messenger *m, int32_t friendnumber) | |||
361 | 336 | ||
362 | free(m->friendlist[friendnumber].statusmessage); | 337 | free(m->friendlist[friendnumber].statusmessage); |
363 | free(m->friendlist[friendnumber].avatar_recv_data); | 338 | free(m->friendlist[friendnumber].avatar_recv_data); |
364 | remove_request_received(&(m->fr), m->friendlist[friendnumber].client_id); | 339 | remove_request_received(&(m->fr), m->friendlist[friendnumber].real_pk); |
365 | friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0); | 340 | friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0); |
366 | kill_friend_connection(m->fr_c, m->friendlist[friendnumber].friendcon_id); | 341 | kill_friend_connection(m->fr_c, m->friendlist[friendnumber].friendcon_id); |
367 | 342 | ||
@@ -513,6 +488,9 @@ int setname(Messenger *m, const uint8_t *name, uint16_t length) | |||
513 | if (length > MAX_NAME_LENGTH || length == 0) | 488 | if (length > MAX_NAME_LENGTH || length == 0) |
514 | return -1; | 489 | return -1; |
515 | 490 | ||
491 | if (m->name_length == length && memcmp(name, m->name, length) == 0) | ||
492 | return 0; | ||
493 | |||
516 | memcpy(m->name, name, length); | 494 | memcpy(m->name, name, length); |
517 | m->name_length = length; | 495 | m->name_length = length; |
518 | uint32_t i; | 496 | uint32_t i; |
@@ -572,6 +550,9 @@ int m_set_statusmessage(Messenger *m, const uint8_t *status, uint16_t length) | |||
572 | if (length > MAX_STATUSMESSAGE_LENGTH) | 550 | if (length > MAX_STATUSMESSAGE_LENGTH) |
573 | return -1; | 551 | return -1; |
574 | 552 | ||
553 | if (m->statusmessage_length == length && memcmp(m->statusmessage, status, length) == 0) | ||
554 | return 0; | ||
555 | |||
575 | memcpy(m->statusmessage, status, length); | 556 | memcpy(m->statusmessage, status, length); |
576 | m->statusmessage_length = length; | 557 | m->statusmessage_length = length; |
577 | 558 | ||
@@ -585,9 +566,11 @@ int m_set_statusmessage(Messenger *m, const uint8_t *status, uint16_t length) | |||
585 | 566 | ||
586 | int m_set_userstatus(Messenger *m, uint8_t status) | 567 | int m_set_userstatus(Messenger *m, uint8_t status) |
587 | { | 568 | { |
588 | if (status >= USERSTATUS_INVALID) { | 569 | if (status >= USERSTATUS_INVALID) |
589 | return -1; | 570 | return -1; |
590 | } | 571 | |
572 | if (m->userstatus == status) | ||
573 | return 0; | ||
591 | 574 | ||
592 | m->userstatus = status; | 575 | m->userstatus = status; |
593 | uint32_t i; | 576 | uint32_t i; |
@@ -813,13 +796,15 @@ uint64_t m_get_last_online(const Messenger *m, int32_t friendnumber) | |||
813 | int m_set_usertyping(Messenger *m, int32_t friendnumber, uint8_t is_typing) | 796 | int m_set_usertyping(Messenger *m, int32_t friendnumber, uint8_t is_typing) |
814 | 797 | ||
815 | { | 798 | { |
816 | if (is_typing != 0 && is_typing != 1) { | 799 | if (is_typing != 0 && is_typing != 1) |
817 | return -1; | 800 | return -1; |
818 | } | ||
819 | 801 | ||
820 | if (friend_not_valid(m, friendnumber)) | 802 | if (friend_not_valid(m, friendnumber)) |
821 | return -1; | 803 | return -1; |
822 | 804 | ||
805 | if (m->friendlist[friendnumber].user_istyping == is_typing) | ||
806 | return 0; | ||
807 | |||
823 | m->friendlist[friendnumber].user_istyping = is_typing; | 808 | m->friendlist[friendnumber].user_istyping = is_typing; |
824 | m->friendlist[friendnumber].user_istyping_sent = 0; | 809 | m->friendlist[friendnumber].user_istyping_sent = 0; |
825 | 810 | ||
@@ -1543,11 +1528,11 @@ int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const | |||
1543 | } | 1528 | } |
1544 | 1529 | ||
1545 | /* Function to filter out some friend requests*/ | 1530 | /* Function to filter out some friend requests*/ |
1546 | static int friend_already_added(const uint8_t *client_id, void *data) | 1531 | static int friend_already_added(const uint8_t *real_pk, void *data) |
1547 | { | 1532 | { |
1548 | const Messenger *m = data; | 1533 | const Messenger *m = data; |
1549 | 1534 | ||
1550 | if (getfriend_id(m, client_id) == -1) | 1535 | if (getfriend_id(m, real_pk) == -1) |
1551 | return 0; | 1536 | return 0; |
1552 | 1537 | ||
1553 | return -1; | 1538 | return -1; |
@@ -1684,6 +1669,8 @@ static int handle_status(void *object, int i, uint8_t status) | |||
1684 | m->friendlist[i].name_sent = 0; | 1669 | m->friendlist[i].name_sent = 0; |
1685 | m->friendlist[i].userstatus_sent = 0; | 1670 | m->friendlist[i].userstatus_sent = 0; |
1686 | m->friendlist[i].statusmessage_sent = 0; | 1671 | m->friendlist[i].statusmessage_sent = 0; |
1672 | m->friendlist[i].user_istyping_sent = 0; | ||
1673 | m->friendlist[i].avatar_info_sent = 0; | ||
1687 | m->friendlist[i].ping_lastrecv = temp_time; | 1674 | m->friendlist[i].ping_lastrecv = temp_time; |
1688 | } else { /* Went offline. */ | 1675 | } else { /* Went offline. */ |
1689 | if (m->friendlist[i].status == FRIEND_ONLINE) { | 1676 | if (m->friendlist[i].status == FRIEND_ONLINE) { |
@@ -2259,7 +2246,7 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) | |||
2259 | int i; | 2246 | int i; |
2260 | 2247 | ||
2261 | for (i = 0; i < n; i++) { | 2248 | for (i = 0; i < n; i++) { |
2262 | add_tcp_relay(m->net_crypto, nodes[i].ip_port, nodes[i].client_id); | 2249 | add_tcp_relay(m->net_crypto, nodes[i].ip_port, nodes[i].public_key); |
2263 | } | 2250 | } |
2264 | 2251 | ||
2265 | break; | 2252 | break; |
@@ -2341,15 +2328,15 @@ void do_friends(Messenger *m) | |||
2341 | #ifdef LOGGING | 2328 | #ifdef LOGGING |
2342 | #define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60UL | 2329 | #define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60UL |
2343 | static time_t lastdump = 0; | 2330 | static time_t lastdump = 0; |
2344 | static char IDString[CLIENT_ID_SIZE * 2 + 1]; | 2331 | static char IDString[crypto_box_PUBLICKEYBYTES * 2 + 1]; |
2345 | static char *ID2String(const uint8_t *client_id) | 2332 | static char *ID2String(const uint8_t *pk) |
2346 | { | 2333 | { |
2347 | uint32_t i; | 2334 | uint32_t i; |
2348 | 2335 | ||
2349 | for (i = 0; i < CLIENT_ID_SIZE; i++) | 2336 | for (i = 0; i < crypto_box_PUBLICKEYBYTES; i++) |
2350 | sprintf(&IDString[i * 2], "%02X", client_id[i]); | 2337 | sprintf(&IDString[i * 2], "%02X", pk[i]); |
2351 | 2338 | ||
2352 | IDString[CLIENT_ID_SIZE * 2] = 0; | 2339 | IDString[crypto_box_PUBLICKEYBYTES * 2] = 0; |
2353 | return IDString; | 2340 | return IDString; |
2354 | } | 2341 | } |
2355 | #endif | 2342 | #endif |
@@ -2384,7 +2371,7 @@ void do_messenger(Messenger *m) | |||
2384 | int i; | 2371 | int i; |
2385 | 2372 | ||
2386 | for (i = 0; i < NUM_SAVED_TCP_RELAYS; ++i) { | 2373 | for (i = 0; i < NUM_SAVED_TCP_RELAYS; ++i) { |
2387 | add_tcp_relay(m->net_crypto, m->loaded_relays[i].ip_port, m->loaded_relays[i].client_id); | 2374 | add_tcp_relay(m->net_crypto, m->loaded_relays[i].ip_port, m->loaded_relays[i].public_key); |
2388 | } | 2375 | } |
2389 | } | 2376 | } |
2390 | 2377 | ||
@@ -2446,7 +2433,7 @@ void do_messenger(Messenger *m) | |||
2446 | continue; | 2433 | continue; |
2447 | 2434 | ||
2448 | for (dhtfriend = 0; dhtfriend < m->dht->num_friends; dhtfriend++) | 2435 | for (dhtfriend = 0; dhtfriend < m->dht->num_friends; dhtfriend++) |
2449 | if (id_equal(m->friendlist[friend].client_id, m->dht->friends_list[dhtfriend].client_id)) { | 2436 | if (id_equal(m->friendlist[friend].real_pk, m->dht->friends_list[dhtfriend].client_id)) { |
2450 | m2dht[friend] = dhtfriend; | 2437 | m2dht[friend] = dhtfriend; |
2451 | break; | 2438 | break; |
2452 | } | 2439 | } |
@@ -2480,7 +2467,7 @@ void do_messenger(Messenger *m) | |||
2480 | 2467 | ||
2481 | LOGGER_TRACE("F[%2u:%2u] <%s> [%03u] %s", | 2468 | LOGGER_TRACE("F[%2u:%2u] <%s> [%03u] %s", |
2482 | dht2m[friend], friend, msgfptr->name, | 2469 | dht2m[friend], friend, msgfptr->name, |
2483 | ping_lastrecv, ID2String(msgfptr->client_id)); | 2470 | ping_lastrecv, ID2String(msgfptr->real_pk)); |
2484 | } else { | 2471 | } else { |
2485 | LOGGER_TRACE("F[--:%2u] %s", friend, ID2String(dhtfptr->client_id)); | 2472 | LOGGER_TRACE("F[--:%2u] %s", friend, ID2String(dhtfptr->client_id)); |
2486 | } | 2473 | } |
@@ -2527,7 +2514,7 @@ void do_messenger(Messenger *m) | |||
2527 | #define NUM_SAVED_PATH_NODES 8 | 2514 | #define NUM_SAVED_PATH_NODES 8 |
2528 | struct SAVED_FRIEND { | 2515 | struct SAVED_FRIEND { |
2529 | uint8_t status; | 2516 | uint8_t status; |
2530 | uint8_t client_id[CLIENT_ID_SIZE]; | 2517 | uint8_t real_pk[crypto_box_PUBLICKEYBYTES]; |
2531 | uint8_t info[SAVED_FRIEND_REQUEST_SIZE]; // the data that is sent during the friend requests we do. | 2518 | uint8_t info[SAVED_FRIEND_REQUEST_SIZE]; // the data that is sent during the friend requests we do. |
2532 | uint16_t info_size; // Length of the info. | 2519 | uint16_t info_size; // Length of the info. |
2533 | uint8_t name[MAX_NAME_LENGTH]; | 2520 | uint8_t name[MAX_NAME_LENGTH]; |
@@ -2554,7 +2541,7 @@ static uint32_t friends_list_save(const Messenger *m, uint8_t *data) | |||
2554 | struct SAVED_FRIEND temp; | 2541 | struct SAVED_FRIEND temp; |
2555 | memset(&temp, 0, sizeof(struct SAVED_FRIEND)); | 2542 | memset(&temp, 0, sizeof(struct SAVED_FRIEND)); |
2556 | temp.status = m->friendlist[i].status; | 2543 | temp.status = m->friendlist[i].status; |
2557 | memcpy(temp.client_id, m->friendlist[i].client_id, CLIENT_ID_SIZE); | 2544 | memcpy(temp.real_pk, m->friendlist[i].real_pk, crypto_box_PUBLICKEYBYTES); |
2558 | 2545 | ||
2559 | if (temp.status < 3) { | 2546 | if (temp.status < 3) { |
2560 | if (m->friendlist[i].info_size > SAVED_FRIEND_REQUEST_SIZE) { | 2547 | if (m->friendlist[i].info_size > SAVED_FRIEND_REQUEST_SIZE) { |
@@ -2600,7 +2587,7 @@ static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length) | |||
2600 | memcpy(&temp, data + i * sizeof(struct SAVED_FRIEND), sizeof(struct SAVED_FRIEND)); | 2587 | memcpy(&temp, data + i * sizeof(struct SAVED_FRIEND), sizeof(struct SAVED_FRIEND)); |
2601 | 2588 | ||
2602 | if (temp.status >= 3) { | 2589 | if (temp.status >= 3) { |
2603 | int fnum = m_addfriend_norequest(m, temp.client_id); | 2590 | int fnum = m_addfriend_norequest(m, temp.real_pk); |
2604 | 2591 | ||
2605 | if (fnum < 0) | 2592 | if (fnum < 0) |
2606 | continue; | 2593 | continue; |
@@ -2615,7 +2602,7 @@ static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length) | |||
2615 | } else if (temp.status != 0) { | 2602 | } else if (temp.status != 0) { |
2616 | /* TODO: This is not a good way to do this. */ | 2603 | /* TODO: This is not a good way to do this. */ |
2617 | uint8_t address[FRIEND_ADDRESS_SIZE]; | 2604 | uint8_t address[FRIEND_ADDRESS_SIZE]; |
2618 | id_copy(address, temp.client_id); | 2605 | id_copy(address, temp.real_pk); |
2619 | memcpy(address + crypto_box_PUBLICKEYBYTES, &(temp.friendrequest_nospam), sizeof(uint32_t)); | 2606 | memcpy(address + crypto_box_PUBLICKEYBYTES, &(temp.friendrequest_nospam), sizeof(uint32_t)); |
2620 | uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); | 2607 | uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); |
2621 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum)); | 2608 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum)); |
@@ -2792,7 +2779,7 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3 | |||
2792 | uint32_t i; | 2779 | uint32_t i; |
2793 | 2780 | ||
2794 | for (i = 0; i < NUM_SAVED_PATH_NODES; ++i) { | 2781 | for (i = 0; i < NUM_SAVED_PATH_NODES; ++i) { |
2795 | onion_add_bs_path_node(m->onion_c, nodes[i].ip_port, nodes[i].client_id); | 2782 | onion_add_bs_path_node(m->onion_c, nodes[i].ip_port, nodes[i].public_key); |
2796 | } | 2783 | } |
2797 | 2784 | ||
2798 | break; | 2785 | break; |
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 3851edf7..a9931d1f 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h | |||
@@ -191,7 +191,7 @@ enum { | |||
191 | typedef struct Messenger Messenger; | 191 | typedef struct Messenger Messenger; |
192 | 192 | ||
193 | typedef struct { | 193 | typedef struct { |
194 | uint8_t client_id[crypto_box_PUBLICKEYBYTES]; | 194 | uint8_t real_pk[crypto_box_PUBLICKEYBYTES]; |
195 | int friendcon_id; | 195 | int friendcon_id; |
196 | 196 | ||
197 | uint64_t friendrequest_lastsent; // Time at which the last friend request was sent. | 197 | uint64_t friendrequest_lastsent; // Time at which the last friend request was sent. |
@@ -313,7 +313,7 @@ struct Messenger { | |||
313 | Messenger_Options options; | 313 | Messenger_Options options; |
314 | }; | 314 | }; |
315 | 315 | ||
316 | /* Format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] | 316 | /* Format: [real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] |
317 | * | 317 | * |
318 | * return FRIEND_ADDRESS_SIZE byte address to give to others. | 318 | * return FRIEND_ADDRESS_SIZE byte address to give to others. |
319 | */ | 319 | */ |
@@ -342,20 +342,20 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u | |||
342 | * return the friend number if success. | 342 | * return the friend number if success. |
343 | * return -1 if failure. | 343 | * return -1 if failure. |
344 | */ | 344 | */ |
345 | int32_t m_addfriend_norequest(Messenger *m, const uint8_t *client_id); | 345 | int32_t m_addfriend_norequest(Messenger *m, const uint8_t *real_pk); |
346 | 346 | ||
347 | /* return the friend number associated to that client id. | 347 | /* return the friend number associated to that client id. |
348 | * return -1 if no such friend. | 348 | * return -1 if no such friend. |
349 | */ | 349 | */ |
350 | int32_t getfriend_id(const Messenger *m, const uint8_t *client_id); | 350 | int32_t getfriend_id(const Messenger *m, const uint8_t *real_pk); |
351 | 351 | ||
352 | /* Copies the public key associated to that friend id into client_id buffer. | 352 | /* Copies the public key associated to that friend id into real_pk buffer. |
353 | * Make sure that client_id is of size CLIENT_ID_SIZE. | 353 | * Make sure that real_pk is of size crypto_box_PUBLICKEYBYTES. |
354 | * | 354 | * |
355 | * return 0 if success | 355 | * return 0 if success |
356 | * return -1 if failure | 356 | * return -1 if failure |
357 | */ | 357 | */ |
358 | int getclient_id(const Messenger *m, int32_t friendnumber, uint8_t *client_id); | 358 | int get_real_pk(const Messenger *m, int32_t friendnumber, uint8_t *real_pk); |
359 | 359 | ||
360 | /* return friend connection id on success. | 360 | /* return friend connection id on success. |
361 | * return -1 if failure. | 361 | * return -1 if failure. |
diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index 250d6c44..e85a506d 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c | |||
@@ -812,6 +812,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint | |||
812 | source.port = 0; // dummy initialise | 812 | source.port = 0; // dummy initialise |
813 | source.ip.family = TCP_ONION_FAMILY; | 813 | source.ip.family = TCP_ONION_FAMILY; |
814 | source.ip.ip6.uint32[0] = con_id; | 814 | source.ip.ip6.uint32[0] = con_id; |
815 | source.ip.ip6.uint32[1] = 0; | ||
815 | source.ip.ip6.uint64[1] = con->identifier; | 816 | source.ip.ip6.uint64[1] = con->identifier; |
816 | onion_send_1(TCP_server->onion, data + 1 + crypto_box_NONCEBYTES, length - (1 + crypto_box_NONCEBYTES), source, | 817 | onion_send_1(TCP_server->onion, data + 1 + crypto_box_NONCEBYTES, length - (1 + crypto_box_NONCEBYTES), source, |
817 | data + 1); | 818 | data + 1); |
@@ -862,36 +863,42 @@ static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection | |||
862 | { | 863 | { |
863 | int index = add_accepted(TCP_server, con); | 864 | int index = add_accepted(TCP_server, con); |
864 | 865 | ||
865 | if (index == -1) | 866 | if (index == -1) { |
867 | kill_TCP_connection(con); | ||
866 | return -1; | 868 | return -1; |
869 | } | ||
870 | |||
871 | memset(con, 0, sizeof(TCP_Secure_Connection)); | ||
867 | 872 | ||
868 | if (handle_TCP_packet(TCP_server, index, data, length) == -1) { | 873 | if (handle_TCP_packet(TCP_server, index, data, length) == -1) { |
869 | kill_accepted(TCP_server, index); | 874 | kill_accepted(TCP_server, index); |
875 | return -1; | ||
870 | } | 876 | } |
871 | 877 | ||
872 | return index; | 878 | return index; |
873 | } | 879 | } |
874 | 880 | ||
875 | /* return 1 on success | 881 | /* return index on success |
876 | * return 0 on failure | 882 | * return -1 on failure |
877 | */ | 883 | */ |
878 | static int accept_connection(TCP_Server *TCP_server, sock_t sock) | 884 | static int accept_connection(TCP_Server *TCP_server, sock_t sock) |
879 | { | 885 | { |
880 | if (!sock_valid(sock)) | 886 | if (!sock_valid(sock)) |
881 | return 0; | 887 | return -1; |
882 | 888 | ||
883 | if (!set_socket_nonblock(sock)) { | 889 | if (!set_socket_nonblock(sock)) { |
884 | kill_sock(sock); | 890 | kill_sock(sock); |
885 | return 0; | 891 | return -1; |
886 | } | 892 | } |
887 | 893 | ||
888 | if (!set_socket_nosigpipe(sock)) { | 894 | if (!set_socket_nosigpipe(sock)) { |
889 | kill_sock(sock); | 895 | kill_sock(sock); |
890 | return 0; | 896 | return -1; |
891 | } | 897 | } |
892 | 898 | ||
893 | TCP_Secure_Connection *conn = | 899 | uint16_t index = TCP_server->incomming_connection_queue_index % MAX_INCOMMING_CONNECTIONS; |
894 | &TCP_server->incomming_connection_queue[TCP_server->incomming_connection_queue_index % MAX_INCOMMING_CONNECTIONS]; | 900 | |
901 | TCP_Secure_Connection *conn = &TCP_server->incomming_connection_queue[index]; | ||
895 | 902 | ||
896 | if (conn->status != TCP_STATUS_NO_STATUS) | 903 | if (conn->status != TCP_STATUS_NO_STATUS) |
897 | kill_TCP_connection(conn); | 904 | kill_TCP_connection(conn); |
@@ -901,7 +908,7 @@ static int accept_connection(TCP_Server *TCP_server, sock_t sock) | |||
901 | conn->next_packet_length = 0; | 908 | conn->next_packet_length = 0; |
902 | 909 | ||
903 | ++TCP_server->incomming_connection_queue_index; | 910 | ++TCP_server->incomming_connection_queue_index; |
904 | return 1; | 911 | return index; |
905 | } | 912 | } |
906 | 913 | ||
907 | static sock_t new_listening_TCP_socket(int family, uint16_t port) | 914 | static sock_t new_listening_TCP_socket(int family, uint16_t port) |
@@ -912,11 +919,7 @@ static sock_t new_listening_TCP_socket(int family, uint16_t port) | |||
912 | return ~0; | 919 | return ~0; |
913 | } | 920 | } |
914 | 921 | ||
915 | #ifndef TCP_SERVER_USE_EPOLL | ||
916 | int ok = set_socket_nonblock(sock); | 922 | int ok = set_socket_nonblock(sock); |
917 | #else | ||
918 | int ok = 1; | ||
919 | #endif | ||
920 | 923 | ||
921 | if (ok && family == AF_INET6) { | 924 | if (ok && family == AF_INET6) { |
922 | ok = set_socket_dualstack(sock); | 925 | ok = set_socket_dualstack(sock); |
@@ -983,7 +986,7 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin | |||
983 | 986 | ||
984 | if (sock_valid(sock)) { | 987 | if (sock_valid(sock)) { |
985 | #ifdef TCP_SERVER_USE_EPOLL | 988 | #ifdef TCP_SERVER_USE_EPOLL |
986 | ev.events = EPOLLIN; | 989 | ev.events = EPOLLIN | EPOLLET; |
987 | ev.data.u64 = sock | ((uint64_t)TCP_SOCKET_LISTENING << 32); | 990 | ev.data.u64 = sock | ((uint64_t)TCP_SOCKET_LISTENING << 32); |
988 | 991 | ||
989 | if (epoll_ctl(temp->efd, EPOLL_CTL_ADD, sock, &ev) == -1) { | 992 | if (epoll_ctl(temp->efd, EPOLL_CTL_ADD, sock, &ev) == -1) { |
@@ -1027,7 +1030,7 @@ static void do_TCP_accept_new(TCP_Server *TCP_server) | |||
1027 | 1030 | ||
1028 | do { | 1031 | do { |
1029 | sock = accept(TCP_server->socks_listening[i], (struct sockaddr *)&addr, &addrlen); | 1032 | sock = accept(TCP_server->socks_listening[i], (struct sockaddr *)&addr, &addrlen); |
1030 | } while (accept_connection(TCP_server, sock)); | 1033 | } while (accept_connection(TCP_server, sock) != -1); |
1031 | } | 1034 | } |
1032 | } | 1035 | } |
1033 | 1036 | ||
@@ -1075,15 +1078,7 @@ static int do_unconfirmed(TCP_Server *TCP_server, uint32_t i) | |||
1075 | kill_TCP_connection(conn); | 1078 | kill_TCP_connection(conn); |
1076 | return -1; | 1079 | return -1; |
1077 | } else { | 1080 | } else { |
1078 | int index_new; | 1081 | return confirm_TCP_connection(TCP_server, conn, packet, len); |
1079 | |||
1080 | if ((index_new = confirm_TCP_connection(TCP_server, conn, packet, len)) == -1) { | ||
1081 | kill_TCP_connection(conn); | ||
1082 | } else { | ||
1083 | memset(conn, 0, sizeof(TCP_Secure_Connection)); | ||
1084 | } | ||
1085 | |||
1086 | return index_new; | ||
1087 | } | 1082 | } |
1088 | } | 1083 | } |
1089 | 1084 | ||
@@ -1194,7 +1189,7 @@ static void do_TCP_epoll(TCP_Server *TCP_server) | |||
1194 | sock_t sock = events[n].data.u64 & 0xFFFFFFFF; | 1189 | sock_t sock = events[n].data.u64 & 0xFFFFFFFF; |
1195 | int status = (events[n].data.u64 >> 32) & 0xFFFF, index = (events[n].data.u64 >> 48); | 1190 | int status = (events[n].data.u64 >> 32) & 0xFFFF, index = (events[n].data.u64 >> 48); |
1196 | 1191 | ||
1197 | if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP)) { | 1192 | if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP) || (events[n].events & EPOLLRDHUP)) { |
1198 | switch (status) { | 1193 | switch (status) { |
1199 | case TCP_SOCKET_LISTENING: { | 1194 | case TCP_SOCKET_LISTENING: { |
1200 | //should never happen | 1195 | //should never happen |
@@ -1230,24 +1225,29 @@ static void do_TCP_epoll(TCP_Server *TCP_server) | |||
1230 | //socket is from socks_listening, accept connection | 1225 | //socket is from socks_listening, accept connection |
1231 | struct sockaddr_storage addr; | 1226 | struct sockaddr_storage addr; |
1232 | unsigned int addrlen = sizeof(addr); | 1227 | unsigned int addrlen = sizeof(addr); |
1233 | sock_t sock_new; | ||
1234 | 1228 | ||
1235 | sock_new = accept(sock, (struct sockaddr *)&addr, &addrlen); | 1229 | while (1) { |
1230 | sock_t sock_new = accept(sock, (struct sockaddr *)&addr, &addrlen); | ||
1236 | 1231 | ||
1237 | int index_new = TCP_server->incomming_connection_queue_index % MAX_INCOMMING_CONNECTIONS; | 1232 | if (!sock_valid(sock_new)) { |
1233 | break; | ||
1234 | } | ||
1238 | 1235 | ||
1239 | if (!accept_connection(TCP_server, sock_new)) { | 1236 | int index_new = accept_connection(TCP_server, sock_new); |
1240 | break; | ||
1241 | } | ||
1242 | 1237 | ||
1243 | struct epoll_event ev = { | 1238 | if (index_new == -1) { |
1244 | .events = EPOLLIN | EPOLLET, | 1239 | continue; |
1245 | .data.u64 = sock_new | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 48) | 1240 | } |
1246 | }; | ||
1247 | 1241 | ||
1248 | if (epoll_ctl(TCP_server->efd, EPOLL_CTL_ADD, sock_new, &ev) == -1) { | 1242 | struct epoll_event ev = { |
1249 | kill_TCP_connection(&TCP_server->incomming_connection_queue[index_new]); | 1243 | .events = EPOLLIN | EPOLLET | EPOLLRDHUP, |
1250 | break; | 1244 | .data.u64 = sock_new | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 48) |
1245 | }; | ||
1246 | |||
1247 | if (epoll_ctl(TCP_server->efd, EPOLL_CTL_ADD, sock_new, &ev) == -1) { | ||
1248 | kill_TCP_connection(&TCP_server->incomming_connection_queue[index_new]); | ||
1249 | continue; | ||
1250 | } | ||
1251 | } | 1251 | } |
1252 | 1252 | ||
1253 | break; | 1253 | break; |
@@ -1257,7 +1257,7 @@ static void do_TCP_epoll(TCP_Server *TCP_server) | |||
1257 | int index_new; | 1257 | int index_new; |
1258 | 1258 | ||
1259 | if ((index_new = do_incoming(TCP_server, index)) != -1) { | 1259 | if ((index_new = do_incoming(TCP_server, index)) != -1) { |
1260 | events[n].events = EPOLLIN | EPOLLET; | 1260 | events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; |
1261 | events[n].data.u64 = sock | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 48); | 1261 | events[n].data.u64 = sock | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 48); |
1262 | 1262 | ||
1263 | if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock, &events[n]) == -1) { | 1263 | if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock, &events[n]) == -1) { |
@@ -1273,7 +1273,7 @@ static void do_TCP_epoll(TCP_Server *TCP_server) | |||
1273 | int index_new; | 1273 | int index_new; |
1274 | 1274 | ||
1275 | if ((index_new = do_unconfirmed(TCP_server, index)) != -1) { | 1275 | if ((index_new = do_unconfirmed(TCP_server, index)) != -1) { |
1276 | events[n].events = EPOLLIN | EPOLLET; | 1276 | events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; |
1277 | events[n].data.u64 = sock | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 48); | 1277 | events[n].data.u64 = sock | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 48); |
1278 | 1278 | ||
1279 | if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock, &events[n]) == -1) { | 1279 | if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock, &events[n]) == -1) { |
@@ -1333,5 +1333,6 @@ void kill_TCP_server(TCP_Server *TCP_server) | |||
1333 | #endif | 1333 | #endif |
1334 | 1334 | ||
1335 | free(TCP_server->socks_listening); | 1335 | free(TCP_server->socks_listening); |
1336 | free(TCP_server->accepted_connection_array); | ||
1336 | free(TCP_server); | 1337 | free(TCP_server); |
1337 | } | 1338 | } |
diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 58bdc2f3..afd2f7b8 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h | |||
@@ -122,6 +122,7 @@ void new_nonce(uint8_t *nonce); | |||
122 | 122 | ||
123 | #define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */ | 123 | #define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */ |
124 | #define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */ | 124 | #define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */ |
125 | #define CRYPTO_PACKET_FAKEID 156 | ||
125 | #define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */ | 126 | #define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */ |
126 | 127 | ||
127 | /* Create a request to peer. | 128 | /* Create a request to peer. |
diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c index 98937131..e4a10008 100644 --- a/toxcore/friend_requests.c +++ b/toxcore/friend_requests.c | |||
@@ -58,12 +58,12 @@ void set_filter_function(Friend_Requests *fr, int (*function)(const uint8_t *, v | |||
58 | } | 58 | } |
59 | 59 | ||
60 | /* Add to list of received friend requests. */ | 60 | /* Add to list of received friend requests. */ |
61 | static void addto_receivedlist(Friend_Requests *fr, const uint8_t *client_id) | 61 | static void addto_receivedlist(Friend_Requests *fr, const uint8_t *real_pk) |
62 | { | 62 | { |
63 | if (fr->received_requests_index >= MAX_RECEIVED_STORED) | 63 | if (fr->received_requests_index >= MAX_RECEIVED_STORED) |
64 | fr->received_requests_index = 0; | 64 | fr->received_requests_index = 0; |
65 | 65 | ||
66 | id_copy(fr->received_requests[fr->received_requests_index], client_id); | 66 | id_copy(fr->received_requests[fr->received_requests_index], real_pk); |
67 | ++fr->received_requests_index; | 67 | ++fr->received_requests_index; |
68 | } | 68 | } |
69 | 69 | ||
@@ -72,28 +72,28 @@ static void addto_receivedlist(Friend_Requests *fr, const uint8_t *client_id) | |||
72 | * return 0 if it did not. | 72 | * return 0 if it did not. |
73 | * return 1 if it did. | 73 | * return 1 if it did. |
74 | */ | 74 | */ |
75 | static int request_received(Friend_Requests *fr, const uint8_t *client_id) | 75 | static int request_received(Friend_Requests *fr, const uint8_t *real_pk) |
76 | { | 76 | { |
77 | uint32_t i; | 77 | uint32_t i; |
78 | 78 | ||
79 | for (i = 0; i < MAX_RECEIVED_STORED; ++i) | 79 | for (i = 0; i < MAX_RECEIVED_STORED; ++i) |
80 | if (id_equal(fr->received_requests[i], client_id)) | 80 | if (id_equal(fr->received_requests[i], real_pk)) |
81 | return 1; | 81 | return 1; |
82 | 82 | ||
83 | return 0; | 83 | return 0; |
84 | } | 84 | } |
85 | 85 | ||
86 | /* Remove client id from received_requests list. | 86 | /* Remove real pk from received_requests list. |
87 | * | 87 | * |
88 | * return 0 if it removed it successfully. | 88 | * return 0 if it removed it successfully. |
89 | * return -1 if it didn't find it. | 89 | * return -1 if it didn't find it. |
90 | */ | 90 | */ |
91 | int remove_request_received(Friend_Requests *fr, const uint8_t *client_id) | 91 | int remove_request_received(Friend_Requests *fr, const uint8_t *real_pk) |
92 | { | 92 | { |
93 | uint32_t i; | 93 | uint32_t i; |
94 | 94 | ||
95 | for (i = 0; i < MAX_RECEIVED_STORED; ++i) { | 95 | for (i = 0; i < MAX_RECEIVED_STORED; ++i) { |
96 | if (id_equal(fr->received_requests[i], client_id)) { | 96 | if (id_equal(fr->received_requests[i], real_pk)) { |
97 | memset(fr->received_requests[i], 0, crypto_box_PUBLICKEYBYTES); | 97 | memset(fr->received_requests[i], 0, crypto_box_PUBLICKEYBYTES); |
98 | return 0; | 98 | return 0; |
99 | } | 99 | } |
diff --git a/toxcore/friend_requests.h b/toxcore/friend_requests.h index b7e07af4..86069f3b 100644 --- a/toxcore/friend_requests.h +++ b/toxcore/friend_requests.h | |||
@@ -51,12 +51,12 @@ typedef struct { | |||
51 | void set_nospam(Friend_Requests *fr, uint32_t num); | 51 | void set_nospam(Friend_Requests *fr, uint32_t num); |
52 | uint32_t get_nospam(const Friend_Requests *fr); | 52 | uint32_t get_nospam(const Friend_Requests *fr); |
53 | 53 | ||
54 | /* Remove client id from received_requests list. | 54 | /* Remove real_pk from received_requests list. |
55 | * | 55 | * |
56 | * return 0 if it removed it successfully. | 56 | * return 0 if it removed it successfully. |
57 | * return -1 if it didn't find it. | 57 | * return -1 if it didn't find it. |
58 | */ | 58 | */ |
59 | int remove_request_received(Friend_Requests *fr, const uint8_t *client_id); | 59 | int remove_request_received(Friend_Requests *fr, const uint8_t *real_pk); |
60 | 60 | ||
61 | /* Set the function that will be executed when a friend request for us is received. | 61 | /* Set the function that will be executed when a friend request for us is received. |
62 | * Function format is function(uint8_t * public_key, uint8_t * data, uint16_t length, void * userdata) | 62 | * Function format is function(uint8_t * public_key, uint8_t * data, uint16_t length, void * userdata) |
diff --git a/toxcore/group.c b/toxcore/group.c index eb795721..c1a60851 100644 --- a/toxcore/group.c +++ b/toxcore/group.c | |||
@@ -447,7 +447,7 @@ static int remove_close_conn(Group_Chats *g_c, int groupnumber, int friendcon_id | |||
447 | if (g->close[i].type == GROUPCHAT_CLOSE_NONE) | 447 | if (g->close[i].type == GROUPCHAT_CLOSE_NONE) |
448 | continue; | 448 | continue; |
449 | 449 | ||
450 | if (g->close[i].number == friendcon_id) { | 450 | if (g->close[i].number == (unsigned int)friendcon_id) { |
451 | g->close[i].type = GROUPCHAT_CLOSE_NONE; | 451 | g->close[i].type = GROUPCHAT_CLOSE_NONE; |
452 | kill_friend_connection(g_c->fr_c, friendcon_id); | 452 | kill_friend_connection(g_c->fr_c, friendcon_id); |
453 | return 0; | 453 | return 0; |
@@ -576,7 +576,7 @@ static void set_conns_type_close(Group_Chats *g_c, int groupnumber, int friendco | |||
576 | if (g->close[i].type == GROUPCHAT_CLOSE_NONE) | 576 | if (g->close[i].type == GROUPCHAT_CLOSE_NONE) |
577 | continue; | 577 | continue; |
578 | 578 | ||
579 | if (g->close[i].number != friendcon_id) | 579 | if (g->close[i].number != (unsigned int)friendcon_id) |
580 | continue; | 580 | continue; |
581 | 581 | ||
582 | if (type == GROUPCHAT_CLOSE_ONLINE) { | 582 | if (type == GROUPCHAT_CLOSE_ONLINE) { |
@@ -789,7 +789,7 @@ int group_names(const Group_Chats *g_c, int groupnumber, uint8_t names[][MAX_NAM | |||
789 | if (!g) | 789 | if (!g) |
790 | return -1; | 790 | return -1; |
791 | 791 | ||
792 | int i; | 792 | unsigned int i; |
793 | 793 | ||
794 | for (i = 0; i < g->numpeers && i < length; ++i) { | 794 | for (i = 0; i < g->numpeers && i < length; ++i) { |
795 | lengths[i] = group_peername(g_c, groupnumber, i, names[i]); | 795 | lengths[i] = group_peername(g_c, groupnumber, i, names[i]); |
diff --git a/toxcore/logger.c b/toxcore/logger.c index ac81a900..e8aef7e0 100644 --- a/toxcore/logger.c +++ b/toxcore/logger.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* logger.c | 1 | /* logger.c |
2 | * | 2 | * |
3 | * Copyright (C) 2013 Tox project All Rights Reserved. | 3 | * Copyright (C) 2013, 2015 Tox project All Rights Reserved. |
4 | * | 4 | * |
5 | * This file is part of Tox. | 5 | * This file is part of Tox. |
6 | * | 6 | * |
@@ -37,8 +37,10 @@ | |||
37 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) | 37 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) |
38 | # define getpid() ((unsigned) GetCurrentProcessId()) | 38 | # define getpid() ((unsigned) GetCurrentProcessId()) |
39 | # define SFILE(FILE__M) (strrchr(FILE__M, '\\') ? strrchr(FILE__M, '\\') + 1 : FILE__M) | 39 | # define SFILE(FILE__M) (strrchr(FILE__M, '\\') ? strrchr(FILE__M, '\\') + 1 : FILE__M) |
40 | # define WIN_CR "\r" | ||
40 | #else | 41 | #else |
41 | # define SFILE(FILE__M) (strrchr(FILE__M, '/') ? strrchr(FILE__M, '/') + 1 : FILE__M) | 42 | # define SFILE(FILE__M) (strrchr(FILE__M, '/') ? strrchr(FILE__M, '/') + 1 : FILE__M) |
43 | # define WIN_CR "" | ||
42 | #endif | 44 | #endif |
43 | 45 | ||
44 | 46 | ||
@@ -57,7 +59,7 @@ struct logger { | |||
57 | pthread_mutex_t mutex[1]; | 59 | pthread_mutex_t mutex[1]; |
58 | }; | 60 | }; |
59 | 61 | ||
60 | logger *global = NULL; | 62 | Logger *global = NULL; |
61 | 63 | ||
62 | const char *LOG_LEVEL_STR [] = { | 64 | const char *LOG_LEVEL_STR [] = { |
63 | [LOG_TRACE] = "TRACE", | 65 | [LOG_TRACE] = "TRACE", |
@@ -83,13 +85,13 @@ char *strtime(char *dest, size_t max_len) | |||
83 | /** | 85 | /** |
84 | * Public Functions | 86 | * Public Functions |
85 | */ | 87 | */ |
86 | logger *logger_new (const char *file_name, LOG_LEVEL level, const char *id) | 88 | Logger *logger_new (const char *file_name, LOG_LEVEL level, const char *id) |
87 | { | 89 | { |
88 | #ifndef LOGGING /* Disabled */ | 90 | #ifndef LOGGING /* Disabled */ |
89 | return NULL; | 91 | return NULL; |
90 | #endif | 92 | #endif |
91 | 93 | ||
92 | logger *retu = calloc(1, sizeof(logger)); | 94 | Logger *retu = calloc(1, sizeof(Logger)); |
93 | 95 | ||
94 | if (!retu) | 96 | if (!retu) |
95 | return NULL; | 97 | return NULL; |
@@ -100,7 +102,7 @@ logger *logger_new (const char *file_name, LOG_LEVEL level, const char *id) | |||
100 | } | 102 | } |
101 | 103 | ||
102 | if (!(retu->log_file = fopen(file_name, "ab"))) { | 104 | if (!(retu->log_file = fopen(file_name, "ab"))) { |
103 | fprintf(stderr, "Error opening logger file: %s; info: %s\n", file_name, strerror(errno)); | 105 | fprintf(stderr, "Error opening logger file: %s; info: %s" WIN_CR "\n", file_name, strerror(errno)); |
104 | free(retu); | 106 | free(retu); |
105 | pthread_mutex_destroy(retu->mutex); | 107 | pthread_mutex_destroy(retu->mutex); |
106 | return NULL; | 108 | return NULL; |
@@ -109,16 +111,16 @@ logger *logger_new (const char *file_name, LOG_LEVEL level, const char *id) | |||
109 | if (!(retu->tstr = calloc(16, sizeof (char))) || | 111 | if (!(retu->tstr = calloc(16, sizeof (char))) || |
110 | !(retu->posstr = calloc(300, sizeof (char))) || | 112 | !(retu->posstr = calloc(300, sizeof (char))) || |
111 | !(retu->msg = calloc(4096, sizeof (char))) ) | 113 | !(retu->msg = calloc(4096, sizeof (char))) ) |
112 | goto ERROR; | 114 | goto FAILURE; |
113 | 115 | ||
114 | if (id) { | 116 | if (id) { |
115 | if (!(retu->id = calloc(strlen(id) + 1, 1))) | 117 | if (!(retu->id = calloc(strlen(id) + 1, 1))) |
116 | goto ERROR; | 118 | goto FAILURE; |
117 | 119 | ||
118 | strcpy(retu->id, id); | 120 | strcpy(retu->id, id); |
119 | } else { | 121 | } else { |
120 | if (!(retu->id = malloc(8))) | 122 | if (!(retu->id = malloc(8))) |
121 | goto ERROR; | 123 | goto FAILURE; |
122 | 124 | ||
123 | snprintf(retu->id, 8, "%u", random_int()); | 125 | snprintf(retu->id, 8, "%u", random_int()); |
124 | } | 126 | } |
@@ -126,13 +128,13 @@ logger *logger_new (const char *file_name, LOG_LEVEL level, const char *id) | |||
126 | retu->level = level; | 128 | retu->level = level; |
127 | retu->start_time = current_time_monotonic(); | 129 | retu->start_time = current_time_monotonic(); |
128 | 130 | ||
129 | fprintf(retu->log_file, "Successfully created and running logger id: %s; time: %s\n", | 131 | fprintf(retu->log_file, "Successfully created and running logger id: %s; time: %s" WIN_CR "\n", |
130 | retu->id, strtime(retu->tstr, 16)); | 132 | retu->id, strtime(retu->tstr, 16)); |
131 | 133 | ||
132 | return retu; | 134 | return retu; |
133 | 135 | ||
134 | ERROR: | 136 | FAILURE: |
135 | fprintf(stderr, "Failed to create logger!\n"); | 137 | fprintf(stderr, "Failed to create logger!" WIN_CR "\n"); |
136 | pthread_mutex_destroy(retu->mutex); | 138 | pthread_mutex_destroy(retu->mutex); |
137 | fclose(retu->log_file); | 139 | fclose(retu->log_file); |
138 | free(retu->tstr); | 140 | free(retu->tstr); |
@@ -143,7 +145,7 @@ ERROR: | |||
143 | return NULL; | 145 | return NULL; |
144 | } | 146 | } |
145 | 147 | ||
146 | void logger_kill(logger *log) | 148 | void logger_kill(Logger *log) |
147 | { | 149 | { |
148 | #ifndef LOGGING /* Disabled */ | 150 | #ifndef LOGGING /* Disabled */ |
149 | return; | 151 | return; |
@@ -173,7 +175,7 @@ void logger_kill_global(void) | |||
173 | global = NULL; | 175 | global = NULL; |
174 | } | 176 | } |
175 | 177 | ||
176 | void logger_set_global(logger *log) | 178 | void logger_set_global(Logger *log) |
177 | { | 179 | { |
178 | #ifndef LOGGING /* Disabled */ | 180 | #ifndef LOGGING /* Disabled */ |
179 | return; | 181 | return; |
@@ -182,7 +184,7 @@ void logger_set_global(logger *log) | |||
182 | global = log; | 184 | global = log; |
183 | } | 185 | } |
184 | 186 | ||
185 | logger *logger_get_global(void) | 187 | Logger *logger_get_global(void) |
186 | { | 188 | { |
187 | #ifndef LOGGING /* Disabled */ | 189 | #ifndef LOGGING /* Disabled */ |
188 | return NULL; | 190 | return NULL; |
@@ -191,7 +193,7 @@ logger *logger_get_global(void) | |||
191 | return global; | 193 | return global; |
192 | } | 194 | } |
193 | 195 | ||
194 | void logger_write (logger *log, LOG_LEVEL level, const char *file, int line, const char *format, ...) | 196 | void logger_write (Logger *log, LOG_LEVEL level, const char *file, int line, const char *format, ...) |
195 | { | 197 | { |
196 | #ifndef LOGGING /* Disabled */ | 198 | #ifndef LOGGING /* Disabled */ |
197 | return; | 199 | return; |
@@ -204,10 +206,10 @@ void logger_write (logger *log, LOG_LEVEL level, const char *file, int line, con | |||
204 | "%-5s " /* Logger lever string */ | 206 | "%-5s " /* Logger lever string */ |
205 | "%-20s " /* File:line string */ | 207 | "%-20s " /* File:line string */ |
206 | "- %s" /* Output message */ | 208 | "- %s" /* Output message */ |
207 | "\n"; /* Every new print new line */ | 209 | WIN_CR "\n"; /* Every new print new line */ |
208 | 210 | ||
209 | 211 | ||
210 | logger *this_log = log ? log : global; | 212 | Logger *this_log = log ? log : global; |
211 | 213 | ||
212 | if (!this_log) | 214 | if (!this_log) |
213 | return; | 215 | return; |
diff --git a/toxcore/logger.h b/toxcore/logger.h index 6f1f6075..0513b32c 100644 --- a/toxcore/logger.h +++ b/toxcore/logger.h | |||
@@ -43,26 +43,26 @@ typedef enum { | |||
43 | LOG_ERROR | 43 | LOG_ERROR |
44 | } LOG_LEVEL; | 44 | } LOG_LEVEL; |
45 | 45 | ||
46 | typedef struct logger logger; | 46 | typedef struct logger Logger; |
47 | 47 | ||
48 | /** | 48 | /** |
49 | * Set 'level' as the lowest printable level. If id == NULL, random number is used. | 49 | * Set 'level' as the lowest printable level. If id == NULL, random number is used. |
50 | */ | 50 | */ |
51 | logger *logger_new (const char *file_name, LOG_LEVEL level, const char *id); | 51 | Logger *logger_new (const char *file_name, LOG_LEVEL level, const char *id); |
52 | 52 | ||
53 | void logger_kill (logger *log); | 53 | void logger_kill (Logger *log); |
54 | void logger_kill_global (void); | 54 | void logger_kill_global (void); |
55 | 55 | ||
56 | /** | 56 | /** |
57 | * Global logger setter and getter. | 57 | * Global logger setter and getter. |
58 | */ | 58 | */ |
59 | void logger_set_global (logger *log); | 59 | void logger_set_global (Logger *log); |
60 | logger *logger_get_global (void); | 60 | Logger *logger_get_global (void); |
61 | 61 | ||
62 | /** | 62 | /** |
63 | * Main write function. If logging disabled does nothing. If log == NULL uses global logger. | 63 | * Main write function. If logging disabled does nothing. If log == NULL uses global logger. |
64 | */ | 64 | */ |
65 | void logger_write (logger *log, LOG_LEVEL level, const char *file, int line, const char *format, ...); | 65 | void logger_write (Logger *log, LOG_LEVEL level, const char *file, int line, const char *format, ...); |
66 | 66 | ||
67 | 67 | ||
68 | /* To do some checks or similar only when logging, use this */ | 68 | /* To do some checks or similar only when logging, use this */ |
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 8af3cbbc..bd5616a2 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -608,6 +608,23 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number) | |||
608 | return 0; | 608 | return 0; |
609 | } | 609 | } |
610 | 610 | ||
611 | static int clear_buffer(Packets_Array *array) | ||
612 | { | ||
613 | uint32_t i; | ||
614 | |||
615 | for (i = array->buffer_start; i != array->buffer_end; ++i) { | ||
616 | uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; | ||
617 | |||
618 | if (array->buffer[num]) { | ||
619 | free(array->buffer[num]); | ||
620 | array->buffer[num] = NULL; | ||
621 | } | ||
622 | } | ||
623 | |||
624 | array->buffer_start = i; | ||
625 | return 0; | ||
626 | } | ||
627 | |||
611 | /* Set array buffer end to number. | 628 | /* Set array buffer end to number. |
612 | * | 629 | * |
613 | * return -1 on failure. | 630 | * return -1 on failure. |
@@ -1378,12 +1395,18 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) | |||
1378 | return -1; | 1395 | return -1; |
1379 | 1396 | ||
1380 | uint32_t i; | 1397 | uint32_t i; |
1381 | pthread_mutex_destroy(&c->crypto_connections[crypt_connection_id].mutex); | 1398 | |
1399 | /* Keep mutex, only destroy it when connection is realloced out. */ | ||
1400 | pthread_mutex_t mutex = c->crypto_connections[crypt_connection_id].mutex; | ||
1382 | memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection)); | 1401 | memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection)); |
1402 | c->crypto_connections[crypt_connection_id].mutex = mutex; | ||
1383 | 1403 | ||
1384 | for (i = c->crypto_connections_length; i != 0; --i) { | 1404 | for (i = c->crypto_connections_length; i != 0; --i) { |
1385 | if (c->crypto_connections[i - 1].status != CRYPTO_CONN_NO_CONNECTION) | 1405 | if (c->crypto_connections[i - 1].status == CRYPTO_CONN_NO_CONNECTION) { |
1406 | pthread_mutex_destroy(&c->crypto_connections[i - 1].mutex); | ||
1407 | } else { | ||
1386 | break; | 1408 | break; |
1409 | } | ||
1387 | } | 1410 | } |
1388 | 1411 | ||
1389 | if (c->crypto_connections_length != i) { | 1412 | if (c->crypto_connections_length != i) { |
@@ -1798,7 +1821,7 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint | |||
1798 | uint32_t i; | 1821 | uint32_t i; |
1799 | 1822 | ||
1800 | for (i = 0; i < conn->num_tcp_relays; ++i) { | 1823 | for (i = 0; i < conn->num_tcp_relays; ++i) { |
1801 | if (memcmp(TCP_con->public_key, conn->tcp_relays[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) { | 1824 | if (memcmp(TCP_con->public_key, conn->tcp_relays[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
1802 | set_conn_tcp_status(conn, location, STATUS_TCP_INVISIBLE); | 1825 | set_conn_tcp_status(conn, location, STATUS_TCP_INVISIBLE); |
1803 | return 0; | 1826 | return 0; |
1804 | } | 1827 | } |
@@ -1977,7 +2000,7 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, | |||
1977 | uint32_t i; | 2000 | uint32_t i; |
1978 | 2001 | ||
1979 | for (i = 0; i < conn->num_tcp_relays; ++i) { | 2002 | for (i = 0; i < conn->num_tcp_relays; ++i) { |
1980 | if (memcmp(conn->tcp_relays[i].client_id, public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 2003 | if (memcmp(conn->tcp_relays[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
1981 | conn->tcp_relays[i].ip_port = ip_port; | 2004 | conn->tcp_relays[i].ip_port = ip_port; |
1982 | return 0; | 2005 | return 0; |
1983 | } | 2006 | } |
@@ -1986,10 +2009,10 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, | |||
1986 | if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) { | 2009 | if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) { |
1987 | uint16_t index = rand() % MAX_TCP_RELAYS_PEER; | 2010 | uint16_t index = rand() % MAX_TCP_RELAYS_PEER; |
1988 | conn->tcp_relays[index].ip_port = ip_port; | 2011 | conn->tcp_relays[index].ip_port = ip_port; |
1989 | memcpy(conn->tcp_relays[index].client_id, public_key, crypto_box_PUBLICKEYBYTES); | 2012 | memcpy(conn->tcp_relays[index].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
1990 | } else { | 2013 | } else { |
1991 | conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port; | 2014 | conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port; |
1992 | memcpy(conn->tcp_relays[conn->num_tcp_relays].client_id, public_key, crypto_box_PUBLICKEYBYTES); | 2015 | memcpy(conn->tcp_relays[conn->num_tcp_relays].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
1993 | ++conn->num_tcp_relays; | 2016 | ++conn->num_tcp_relays; |
1994 | } | 2017 | } |
1995 | 2018 | ||
@@ -2039,29 +2062,50 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key) | |||
2039 | return -1; | 2062 | return -1; |
2040 | } | 2063 | } |
2041 | 2064 | ||
2042 | /* Send an onion packet via a random connected TCP relay. | 2065 | /* Return a random TCP connection number for use in send_tcp_onion_request. |
2043 | * | 2066 | * |
2044 | * return 0 on success. | 2067 | * TODO: This number is just the index of an array that the elements can |
2068 | * change without warning. | ||
2069 | * | ||
2070 | * return TCP connection number on success. | ||
2045 | * return -1 on failure. | 2071 | * return -1 on failure. |
2046 | */ | 2072 | */ |
2047 | int send_tcp_onion_request(Net_Crypto *c, const uint8_t *data, uint16_t length) | 2073 | int get_random_tcp_con_number(Net_Crypto *c) |
2048 | { | 2074 | { |
2049 | unsigned int i, r = rand(); | 2075 | unsigned int i, r = rand(); |
2050 | 2076 | ||
2051 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | 2077 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { |
2052 | if (c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS]) { | 2078 | if (c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS]) { |
2053 | pthread_mutex_lock(&c->tcp_mutex); | 2079 | return (i + r) % MAX_TCP_CONNECTIONS; |
2054 | int ret = send_onion_request(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], data, length); | ||
2055 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2056 | |||
2057 | if (ret == 1) | ||
2058 | return 0; | ||
2059 | } | 2080 | } |
2060 | } | 2081 | } |
2061 | 2082 | ||
2062 | return -1; | 2083 | return -1; |
2063 | } | 2084 | } |
2064 | 2085 | ||
2086 | /* Send an onion packet via the TCP relay corresponding to TCP_conn_number. | ||
2087 | * | ||
2088 | * return 0 on success. | ||
2089 | * return -1 on failure. | ||
2090 | */ | ||
2091 | int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const uint8_t *data, uint16_t length) | ||
2092 | { | ||
2093 | if (TCP_conn_number > MAX_TCP_CONNECTIONS) { | ||
2094 | return -1; | ||
2095 | } | ||
2096 | |||
2097 | if (c->tcp_connections[TCP_conn_number]) { | ||
2098 | pthread_mutex_lock(&c->tcp_mutex); | ||
2099 | int ret = send_onion_request(c->tcp_connections[TCP_conn_number], data, length); | ||
2100 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2101 | |||
2102 | if (ret == 1) | ||
2103 | return 0; | ||
2104 | } | ||
2105 | |||
2106 | return -1; | ||
2107 | } | ||
2108 | |||
2065 | /* Set the function to be called when an onion response packet is received by one of the TCP connections. | 2109 | /* Set the function to be called when an onion response packet is received by one of the TCP connections. |
2066 | */ | 2110 | */ |
2067 | void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data, | 2111 | void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data, |
@@ -2087,7 +2131,7 @@ unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_rel | |||
2087 | 2131 | ||
2088 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | 2132 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { |
2089 | if (c->tcp_connections[i] != NULL) { | 2133 | if (c->tcp_connections[i] != NULL) { |
2090 | memcpy(tcp_relays[copied].client_id, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES); | 2134 | memcpy(tcp_relays[copied].public_key, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES); |
2091 | tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port; | 2135 | tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port; |
2092 | 2136 | ||
2093 | if (tcp_relays[copied].ip_port.ip.family == AF_INET) { | 2137 | if (tcp_relays[copied].ip_port.ip.family == AF_INET) { |
@@ -2391,7 +2435,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet | |||
2391 | 2435 | ||
2392 | /* The dT for the average packet receiving rate calculations. | 2436 | /* The dT for the average packet receiving rate calculations. |
2393 | Also used as the */ | 2437 | Also used as the */ |
2394 | #define PACKET_COUNTER_AVERAGE_INTERVAL 100 | 2438 | #define PACKET_COUNTER_AVERAGE_INTERVAL 50 |
2395 | 2439 | ||
2396 | /* Ratio of recv queue size / recv packet rate (in seconds) times | 2440 | /* Ratio of recv queue size / recv packet rate (in seconds) times |
2397 | * the number of ms between request packets to send at that ratio | 2441 | * the number of ms between request packets to send at that ratio |
@@ -2474,7 +2518,7 @@ static void send_crypto_packets(Net_Crypto *c) | |||
2474 | double min_speed = 1000.0 * (((double)(total_sent)) / ((double)(CONGESTION_QUEUE_ARRAY_SIZE) * | 2518 | double min_speed = 1000.0 * (((double)(total_sent)) / ((double)(CONGESTION_QUEUE_ARRAY_SIZE) * |
2475 | PACKET_COUNTER_AVERAGE_INTERVAL)); | 2519 | PACKET_COUNTER_AVERAGE_INTERVAL)); |
2476 | 2520 | ||
2477 | conn->packet_send_rate = min_speed * 1.3; | 2521 | conn->packet_send_rate = min_speed * 1.2; |
2478 | 2522 | ||
2479 | if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE) { | 2523 | if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE) { |
2480 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; | 2524 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; |
@@ -2678,6 +2722,9 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) | |||
2678 | 2722 | ||
2679 | disconnect_peer_tcp(c, crypt_connection_id); | 2723 | disconnect_peer_tcp(c, crypt_connection_id); |
2680 | bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id); | 2724 | bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id); |
2725 | clear_temp_packet(c, crypt_connection_id); | ||
2726 | clear_buffer(&conn->send_array); | ||
2727 | clear_buffer(&conn->recv_array); | ||
2681 | ret = wipe_crypto_connection(c, crypt_connection_id); | 2728 | ret = wipe_crypto_connection(c, crypt_connection_id); |
2682 | } | 2729 | } |
2683 | 2730 | ||
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index b9fb1747..7e59475e 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h | |||
@@ -86,7 +86,7 @@ | |||
86 | 86 | ||
87 | /* Base current transfer speed on last CONGESTION_QUEUE_ARRAY_SIZE number of points taken | 87 | /* Base current transfer speed on last CONGESTION_QUEUE_ARRAY_SIZE number of points taken |
88 | at the dT defined in net_crypto.c */ | 88 | at the dT defined in net_crypto.c */ |
89 | #define CONGESTION_QUEUE_ARRAY_SIZE 8 | 89 | #define CONGESTION_QUEUE_ARRAY_SIZE 24 |
90 | 90 | ||
91 | typedef struct { | 91 | typedef struct { |
92 | uint64_t time; | 92 | uint64_t time; |
@@ -364,12 +364,19 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key); | |||
364 | void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data, | 364 | void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data, |
365 | uint16_t length), void *object); | 365 | uint16_t length), void *object); |
366 | 366 | ||
367 | /* Send an onion packet via a random connected TCP relay. | 367 | /* Return a random TCP connection number for use in send_tcp_onion_request. |
368 | * | ||
369 | * return TCP connection number on success. | ||
370 | * return -1 on failure. | ||
371 | */ | ||
372 | int get_random_tcp_con_number(Net_Crypto *c); | ||
373 | |||
374 | /* Send an onion packet via the TCP relay corresponding to TCP_conn_number. | ||
368 | * | 375 | * |
369 | * return 0 on success. | 376 | * return 0 on success. |
370 | * return -1 on failure. | 377 | * return -1 on failure. |
371 | */ | 378 | */ |
372 | int send_tcp_onion_request(Net_Crypto *c, const uint8_t *data, uint16_t length); | 379 | int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const uint8_t *data, uint16_t length); |
373 | 380 | ||
374 | /* Copy a maximum of num TCP relays we are connected to to tcp_relays. | 381 | /* Copy a maximum of num TCP relays we are connected to to tcp_relays. |
375 | * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. | 382 | * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. |
diff --git a/toxcore/onion.c b/toxcore/onion.c index 05dbaae6..c6093f0c 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c | |||
@@ -61,7 +61,7 @@ static void ip_pack(uint8_t *data, IP source) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | /* return 0 on success, -1 on failure. */ | 63 | /* return 0 on success, -1 on failure. */ |
64 | static int ip_unpack(IP *target, const uint8_t *data, unsigned int data_size) | 64 | static int ip_unpack(IP *target, const uint8_t *data, unsigned int data_size, _Bool disable_family_check) |
65 | { | 65 | { |
66 | if (data_size < (1 + SIZE_IP6)) | 66 | if (data_size < (1 + SIZE_IP6)) |
67 | return -1; | 67 | return -1; |
@@ -74,7 +74,12 @@ static int ip_unpack(IP *target, const uint8_t *data, unsigned int data_size) | |||
74 | memcpy(target->ip6.uint8, data + 1, SIZE_IP6); | 74 | memcpy(target->ip6.uint8, data + 1, SIZE_IP6); |
75 | } | 75 | } |
76 | 76 | ||
77 | return to_host_family(target); | 77 | if (!disable_family_check) { |
78 | return to_host_family(target); | ||
79 | } else { | ||
80 | to_host_family(target); | ||
81 | return 0; | ||
82 | } | ||
78 | } | 83 | } |
79 | 84 | ||
80 | static void ipport_pack(uint8_t *data, const IP_Port *source) | 85 | static void ipport_pack(uint8_t *data, const IP_Port *source) |
@@ -84,12 +89,12 @@ static void ipport_pack(uint8_t *data, const IP_Port *source) | |||
84 | } | 89 | } |
85 | 90 | ||
86 | /* return 0 on success, -1 on failure. */ | 91 | /* return 0 on success, -1 on failure. */ |
87 | static int ipport_unpack(IP_Port *target, const uint8_t *data, unsigned int data_size) | 92 | static int ipport_unpack(IP_Port *target, const uint8_t *data, unsigned int data_size, _Bool disable_family_check) |
88 | { | 93 | { |
89 | if (data_size < (SIZE_IP + SIZE_PORT)) | 94 | if (data_size < (SIZE_IP + SIZE_PORT)) |
90 | return -1; | 95 | return -1; |
91 | 96 | ||
92 | if (ip_unpack(&target->ip, data, data_size) == -1) | 97 | if (ip_unpack(&target->ip, data, data_size, disable_family_check) == -1) |
93 | return -1; | 98 | return -1; |
94 | 99 | ||
95 | memcpy(&target->port, data + SIZE_IP, SIZE_PORT); | 100 | memcpy(&target->port, data + SIZE_IP, SIZE_PORT); |
@@ -111,27 +116,27 @@ int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *n | |||
111 | if (!new_path || !nodes) | 116 | if (!new_path || !nodes) |
112 | return -1; | 117 | return -1; |
113 | 118 | ||
114 | encrypt_precompute(nodes[0].client_id, dht->self_secret_key, new_path->shared_key1); | 119 | encrypt_precompute(nodes[0].public_key, dht->self_secret_key, new_path->shared_key1); |
115 | memcpy(new_path->public_key1, dht->self_public_key, crypto_box_PUBLICKEYBYTES); | 120 | memcpy(new_path->public_key1, dht->self_public_key, crypto_box_PUBLICKEYBYTES); |
116 | 121 | ||
117 | uint8_t random_public_key[crypto_box_PUBLICKEYBYTES]; | 122 | uint8_t random_public_key[crypto_box_PUBLICKEYBYTES]; |
118 | uint8_t random_secret_key[crypto_box_SECRETKEYBYTES]; | 123 | uint8_t random_secret_key[crypto_box_SECRETKEYBYTES]; |
119 | 124 | ||
120 | crypto_box_keypair(random_public_key, random_secret_key); | 125 | crypto_box_keypair(random_public_key, random_secret_key); |
121 | encrypt_precompute(nodes[1].client_id, random_secret_key, new_path->shared_key2); | 126 | encrypt_precompute(nodes[1].public_key, random_secret_key, new_path->shared_key2); |
122 | memcpy(new_path->public_key2, random_public_key, crypto_box_PUBLICKEYBYTES); | 127 | memcpy(new_path->public_key2, random_public_key, crypto_box_PUBLICKEYBYTES); |
123 | 128 | ||
124 | crypto_box_keypair(random_public_key, random_secret_key); | 129 | crypto_box_keypair(random_public_key, random_secret_key); |
125 | encrypt_precompute(nodes[2].client_id, random_secret_key, new_path->shared_key3); | 130 | encrypt_precompute(nodes[2].public_key, random_secret_key, new_path->shared_key3); |
126 | memcpy(new_path->public_key3, random_public_key, crypto_box_PUBLICKEYBYTES); | 131 | memcpy(new_path->public_key3, random_public_key, crypto_box_PUBLICKEYBYTES); |
127 | 132 | ||
128 | new_path->ip_port1 = nodes[0].ip_port; | 133 | new_path->ip_port1 = nodes[0].ip_port; |
129 | new_path->ip_port2 = nodes[1].ip_port; | 134 | new_path->ip_port2 = nodes[1].ip_port; |
130 | new_path->ip_port3 = nodes[2].ip_port; | 135 | new_path->ip_port3 = nodes[2].ip_port; |
131 | 136 | ||
132 | memcpy(new_path->node_public_key1, nodes[0].client_id, crypto_box_PUBLICKEYBYTES); | 137 | memcpy(new_path->node_public_key1, nodes[0].public_key, crypto_box_PUBLICKEYBYTES); |
133 | memcpy(new_path->node_public_key2, nodes[1].client_id, crypto_box_PUBLICKEYBYTES); | 138 | memcpy(new_path->node_public_key2, nodes[1].public_key, crypto_box_PUBLICKEYBYTES); |
134 | memcpy(new_path->node_public_key3, nodes[2].client_id, crypto_box_PUBLICKEYBYTES); | 139 | memcpy(new_path->node_public_key3, nodes[2].public_key, crypto_box_PUBLICKEYBYTES); |
135 | 140 | ||
136 | return 0; | 141 | return 0; |
137 | } | 142 | } |
@@ -150,9 +155,9 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_ | |||
150 | nodes[1].ip_port = path->ip_port2; | 155 | nodes[1].ip_port = path->ip_port2; |
151 | nodes[2].ip_port = path->ip_port3; | 156 | nodes[2].ip_port = path->ip_port3; |
152 | 157 | ||
153 | memcpy(nodes[0].client_id, path->node_public_key1, crypto_box_PUBLICKEYBYTES); | 158 | memcpy(nodes[0].public_key, path->node_public_key1, crypto_box_PUBLICKEYBYTES); |
154 | memcpy(nodes[1].client_id, path->node_public_key2, crypto_box_PUBLICKEYBYTES); | 159 | memcpy(nodes[1].public_key, path->node_public_key2, crypto_box_PUBLICKEYBYTES); |
155 | memcpy(nodes[2].client_id, path->node_public_key3, crypto_box_PUBLICKEYBYTES); | 160 | memcpy(nodes[2].public_key, path->node_public_key3, crypto_box_PUBLICKEYBYTES); |
156 | return 0; | 161 | return 0; |
157 | } | 162 | } |
158 | 163 | ||
@@ -186,7 +191,7 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion | |||
186 | int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, sizeof(step1), | 191 | int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, sizeof(step1), |
187 | step2 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES); | 192 | step2 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES); |
188 | 193 | ||
189 | if ((uint32_t)len != SIZE_IPPORT + length + crypto_box_MACBYTES) | 194 | if (len != SIZE_IPPORT + length + crypto_box_MACBYTES) |
190 | return -1; | 195 | return -1; |
191 | 196 | ||
192 | uint8_t step3[SIZE_IPPORT + SEND_BASE * 2 + length]; | 197 | uint8_t step3[SIZE_IPPORT + SEND_BASE * 2 + length]; |
@@ -195,7 +200,7 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion | |||
195 | len = encrypt_data_symmetric(path->shared_key2, nonce, step2, sizeof(step2), | 200 | len = encrypt_data_symmetric(path->shared_key2, nonce, step2, sizeof(step2), |
196 | step3 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES); | 201 | step3 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES); |
197 | 202 | ||
198 | if ((uint32_t)len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES) | 203 | if (len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES) |
199 | return -1; | 204 | return -1; |
200 | 205 | ||
201 | packet[0] = NET_PACKET_ONION_SEND_INITIAL; | 206 | packet[0] = NET_PACKET_ONION_SEND_INITIAL; |
@@ -205,7 +210,7 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion | |||
205 | len = encrypt_data_symmetric(path->shared_key1, nonce, step3, sizeof(step3), | 210 | len = encrypt_data_symmetric(path->shared_key1, nonce, step3, sizeof(step3), |
206 | packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); | 211 | packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); |
207 | 212 | ||
208 | if ((uint32_t)len != SIZE_IPPORT + SEND_BASE * 2 + length + crypto_box_MACBYTES) | 213 | if (len != SIZE_IPPORT + SEND_BASE * 2 + length + crypto_box_MACBYTES) |
209 | return -1; | 214 | return -1; |
210 | 215 | ||
211 | return 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + len; | 216 | return 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + len; |
@@ -241,7 +246,7 @@ int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const O | |||
241 | int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, sizeof(step1), | 246 | int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, sizeof(step1), |
242 | step2 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES); | 247 | step2 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES); |
243 | 248 | ||
244 | if ((uint32_t)len != SIZE_IPPORT + length + crypto_box_MACBYTES) | 249 | if (len != SIZE_IPPORT + length + crypto_box_MACBYTES) |
245 | return -1; | 250 | return -1; |
246 | 251 | ||
247 | ipport_pack(packet + crypto_box_NONCEBYTES, &path->ip_port2); | 252 | ipport_pack(packet + crypto_box_NONCEBYTES, &path->ip_port2); |
@@ -249,7 +254,7 @@ int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const O | |||
249 | len = encrypt_data_symmetric(path->shared_key2, nonce, step2, sizeof(step2), | 254 | len = encrypt_data_symmetric(path->shared_key2, nonce, step2, sizeof(step2), |
250 | packet + crypto_box_NONCEBYTES + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES); | 255 | packet + crypto_box_NONCEBYTES + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES); |
251 | 256 | ||
252 | if ((uint32_t)len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES) | 257 | if (len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES) |
253 | return -1; | 258 | return -1; |
254 | 259 | ||
255 | memcpy(packet, nonce, crypto_box_NONCEBYTES); | 260 | memcpy(packet, nonce, crypto_box_NONCEBYTES); |
@@ -319,7 +324,7 @@ static int handle_send_initial(void *object, IP_Port source, const uint8_t *pack | |||
319 | int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, | 324 | int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, |
320 | length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), plain); | 325 | length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), plain); |
321 | 326 | ||
322 | if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)) | 327 | if (len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)) |
323 | return 1; | 328 | return 1; |
324 | 329 | ||
325 | return onion_send_1(onion, plain, len, source, packet + 1); | 330 | return onion_send_1(onion, plain, len, source, packet + 1); |
@@ -335,7 +340,7 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, IP_Port | |||
335 | 340 | ||
336 | IP_Port send_to; | 341 | IP_Port send_to; |
337 | 342 | ||
338 | if (ipport_unpack(&send_to, plain, len) == -1) | 343 | if (ipport_unpack(&send_to, plain, len, 0) == -1) |
339 | return 1; | 344 | return 1; |
340 | 345 | ||
341 | uint8_t ip_port[SIZE_IPPORT]; | 346 | uint8_t ip_port[SIZE_IPPORT]; |
@@ -380,12 +385,12 @@ static int handle_send_1(void *object, IP_Port source, const uint8_t *packet, ui | |||
380 | int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, | 385 | int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, |
381 | length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1), plain); | 386 | length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1), plain); |
382 | 387 | ||
383 | if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1 + crypto_box_MACBYTES)) | 388 | if (len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1 + crypto_box_MACBYTES)) |
384 | return 1; | 389 | return 1; |
385 | 390 | ||
386 | IP_Port send_to; | 391 | IP_Port send_to; |
387 | 392 | ||
388 | if (ipport_unpack(&send_to, plain, len) == -1) | 393 | if (ipport_unpack(&send_to, plain, len, 0) == -1) |
389 | return 1; | 394 | return 1; |
390 | 395 | ||
391 | uint8_t data[ONION_MAX_PACKET_SIZE]; | 396 | uint8_t data[ONION_MAX_PACKET_SIZE]; |
@@ -430,12 +435,12 @@ static int handle_send_2(void *object, IP_Port source, const uint8_t *packet, ui | |||
430 | int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, | 435 | int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, |
431 | length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2), plain); | 436 | length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2), plain); |
432 | 437 | ||
433 | if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2 + crypto_box_MACBYTES)) | 438 | if (len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2 + crypto_box_MACBYTES)) |
434 | return 1; | 439 | return 1; |
435 | 440 | ||
436 | IP_Port send_to; | 441 | IP_Port send_to; |
437 | 442 | ||
438 | if (ipport_unpack(&send_to, plain, len) == -1) | 443 | if (ipport_unpack(&send_to, plain, len, 0) == -1) |
439 | return 1; | 444 | return 1; |
440 | 445 | ||
441 | uint8_t data[ONION_MAX_PACKET_SIZE]; | 446 | uint8_t data[ONION_MAX_PACKET_SIZE]; |
@@ -482,7 +487,7 @@ static int handle_recv_3(void *object, IP_Port source, const uint8_t *packet, ui | |||
482 | 487 | ||
483 | IP_Port send_to; | 488 | IP_Port send_to; |
484 | 489 | ||
485 | if (ipport_unpack(&send_to, plain, len) == -1) | 490 | if (ipport_unpack(&send_to, plain, len, 0) == -1) |
486 | return 1; | 491 | return 1; |
487 | 492 | ||
488 | uint8_t data[ONION_MAX_PACKET_SIZE]; | 493 | uint8_t data[ONION_MAX_PACKET_SIZE]; |
@@ -518,7 +523,7 @@ static int handle_recv_2(void *object, IP_Port source, const uint8_t *packet, ui | |||
518 | 523 | ||
519 | IP_Port send_to; | 524 | IP_Port send_to; |
520 | 525 | ||
521 | if (ipport_unpack(&send_to, plain, len) == -1) | 526 | if (ipport_unpack(&send_to, plain, len, 0) == -1) |
522 | return 1; | 527 | return 1; |
523 | 528 | ||
524 | uint8_t data[ONION_MAX_PACKET_SIZE]; | 529 | uint8_t data[ONION_MAX_PACKET_SIZE]; |
@@ -554,7 +559,7 @@ static int handle_recv_1(void *object, IP_Port source, const uint8_t *packet, ui | |||
554 | 559 | ||
555 | IP_Port send_to; | 560 | IP_Port send_to; |
556 | 561 | ||
557 | if (ipport_unpack(&send_to, plain, len) == -1) | 562 | if (ipport_unpack(&send_to, plain, len, 1) == -1) |
558 | return 1; | 563 | return 1; |
559 | 564 | ||
560 | uint16_t data_len = length - (1 + RETURN_1); | 565 | uint16_t data_len = length - (1 + RETURN_1); |
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index 32442797..25f3e0f8 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c | |||
@@ -134,7 +134,7 @@ int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_for | |||
134 | uint64_t sendback_data) | 134 | uint64_t sendback_data) |
135 | { | 135 | { |
136 | uint8_t request[ONION_ANNOUNCE_REQUEST_SIZE]; | 136 | uint8_t request[ONION_ANNOUNCE_REQUEST_SIZE]; |
137 | int len = create_announce_request(request, sizeof(request), dest.client_id, public_key, secret_key, ping_id, client_id, | 137 | int len = create_announce_request(request, sizeof(request), dest.public_key, public_key, secret_key, ping_id, client_id, |
138 | data_public_key, sendback_data); | 138 | data_public_key, sendback_data); |
139 | 139 | ||
140 | if (len != sizeof(request)) | 140 | if (len != sizeof(request)) |
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index b02b7c24..61034167 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c | |||
@@ -38,7 +38,7 @@ | |||
38 | * return -1 on failure | 38 | * return -1 on failure |
39 | * return 0 on success | 39 | * return 0 on success |
40 | */ | 40 | */ |
41 | int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *client_id) | 41 | int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key) |
42 | { | 42 | { |
43 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) | 43 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) |
44 | return -1; | 44 | return -1; |
@@ -46,12 +46,12 @@ int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t | |||
46 | unsigned int i; | 46 | unsigned int i; |
47 | 47 | ||
48 | for (i = 0; i < MAX_PATH_NODES; ++i) { | 48 | for (i = 0; i < MAX_PATH_NODES; ++i) { |
49 | if (memcmp(client_id, onion_c->path_nodes_bs[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) | 49 | if (memcmp(public_key, onion_c->path_nodes_bs[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) |
50 | return -1; | 50 | return -1; |
51 | } | 51 | } |
52 | 52 | ||
53 | onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].ip_port = ip_port; | 53 | onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].ip_port = ip_port; |
54 | memcpy(onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].client_id, client_id, | 54 | memcpy(onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].public_key, public_key, |
55 | crypto_box_PUBLICKEYBYTES); | 55 | crypto_box_PUBLICKEYBYTES); |
56 | 56 | ||
57 | uint16_t last = onion_c->path_nodes_index_bs; | 57 | uint16_t last = onion_c->path_nodes_index_bs; |
@@ -68,7 +68,7 @@ int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t | |||
68 | * return -1 on failure | 68 | * return -1 on failure |
69 | * return 0 on success | 69 | * return 0 on success |
70 | */ | 70 | */ |
71 | static int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *client_id) | 71 | static int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key) |
72 | { | 72 | { |
73 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) | 73 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) |
74 | return -1; | 74 | return -1; |
@@ -76,12 +76,13 @@ static int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uin | |||
76 | unsigned int i; | 76 | unsigned int i; |
77 | 77 | ||
78 | for (i = 0; i < MAX_PATH_NODES; ++i) { | 78 | for (i = 0; i < MAX_PATH_NODES; ++i) { |
79 | if (memcmp(client_id, onion_c->path_nodes[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) | 79 | if (memcmp(public_key, onion_c->path_nodes[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) |
80 | return -1; | 80 | return -1; |
81 | } | 81 | } |
82 | 82 | ||
83 | onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].ip_port = ip_port; | 83 | onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].ip_port = ip_port; |
84 | memcpy(onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].client_id, client_id, crypto_box_PUBLICKEYBYTES); | 84 | memcpy(onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].public_key, public_key, |
85 | crypto_box_PUBLICKEYBYTES); | ||
85 | 86 | ||
86 | uint16_t last = onion_c->path_nodes_index; | 87 | uint16_t last = onion_c->path_nodes_index; |
87 | ++onion_c->path_nodes_index; | 88 | ++onion_c->path_nodes_index; |
@@ -140,8 +141,15 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format | |||
140 | nodes[i] = onion_c->path_nodes[rand() % num_nodes]; | 141 | nodes[i] = onion_c->path_nodes[rand() % num_nodes]; |
141 | } | 142 | } |
142 | } else { | 143 | } else { |
144 | int random_tcp = get_random_tcp_con_number(onion_c->c); | ||
145 | |||
146 | if (random_tcp == -1) { | ||
147 | return 0; | ||
148 | } | ||
149 | |||
143 | if (num_nodes >= 2) { | 150 | if (num_nodes >= 2) { |
144 | nodes[0].ip_port.ip.family = TCP_FAMILY; | 151 | nodes[0].ip_port.ip.family = TCP_FAMILY; |
152 | nodes[0].ip_port.ip.ip4.uint32 = random_tcp; | ||
145 | 153 | ||
146 | for (i = 1; i < max_num; ++i) { | 154 | for (i = 1; i < max_num; ++i) { |
147 | nodes[i] = onion_c->path_nodes[rand() % num_nodes]; | 155 | nodes[i] = onion_c->path_nodes[rand() % num_nodes]; |
@@ -154,6 +162,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format | |||
154 | return 0; | 162 | return 0; |
155 | 163 | ||
156 | nodes[0].ip_port.ip.family = TCP_FAMILY; | 164 | nodes[0].ip_port.ip.family = TCP_FAMILY; |
165 | nodes[0].ip_port.ip.ip4.uint32 = random_tcp; | ||
157 | 166 | ||
158 | for (i = 1; i < max_num; ++i) { | 167 | for (i = 1; i < max_num; ++i) { |
159 | nodes[i] = onion_c->path_nodes_bs[rand() % num_nodes_bs]; | 168 | nodes[i] = onion_c->path_nodes_bs[rand() % num_nodes_bs]; |
@@ -249,9 +258,9 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t | |||
249 | Onion_Client_Paths *onion_paths; | 258 | Onion_Client_Paths *onion_paths; |
250 | 259 | ||
251 | if (num == 0) { | 260 | if (num == 0) { |
252 | onion_paths = &onion_c->onion_paths; | 261 | onion_paths = &onion_c->onion_paths_self; |
253 | } else { | 262 | } else { |
254 | onion_paths = &onion_c->friends_list[num - 1].onion_paths; | 263 | onion_paths = &onion_c->onion_paths_friends; |
255 | } | 264 | } |
256 | 265 | ||
257 | if (onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num) { | 266 | if (onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num) { |
@@ -265,7 +274,7 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t | |||
265 | unsigned int i; | 274 | unsigned int i; |
266 | 275 | ||
267 | for (i = 0; i < path_len; ++i) { | 276 | for (i = 0; i < path_len; ++i) { |
268 | onion_add_path_node(onion_c, nodes[i].ip_port, nodes[i].client_id); | 277 | onion_add_path_node(onion_c, nodes[i].ip_port, nodes[i].public_key); |
269 | } | 278 | } |
270 | } | 279 | } |
271 | 280 | ||
@@ -301,7 +310,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa | |||
301 | if (len == -1) | 310 | if (len == -1) |
302 | return -1; | 311 | return -1; |
303 | 312 | ||
304 | return send_tcp_onion_request(onion_c->c, packet, len); | 313 | return send_tcp_onion_request(onion_c->c, path->ip_port1.ip.ip4.uint32, packet, len); |
305 | } else { | 314 | } else { |
306 | return -1; | 315 | return -1; |
307 | } | 316 | } |
@@ -377,10 +386,10 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_ | |||
377 | Onion_Path path; | 386 | Onion_Path path; |
378 | 387 | ||
379 | if (num == 0) { | 388 | if (num == 0) { |
380 | if (random_path(onion_c, &onion_c->onion_paths, pathnum, &path) == -1) | 389 | if (random_path(onion_c, &onion_c->onion_paths_self, pathnum, &path) == -1) |
381 | return -1; | 390 | return -1; |
382 | } else { | 391 | } else { |
383 | if (random_path(onion_c, &onion_c->friends_list[num - 1].onion_paths, pathnum, &path) == -1) | 392 | if (random_path(onion_c, &onion_c->onion_paths_friends, pathnum, &path) == -1) |
384 | return -1; | 393 | return -1; |
385 | } | 394 | } |
386 | 395 | ||
@@ -401,7 +410,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_ | |||
401 | 410 | ||
402 | } else { | 411 | } else { |
403 | len = create_announce_request(request, sizeof(request), dest_pubkey, onion_c->friends_list[num - 1].temp_public_key, | 412 | len = create_announce_request(request, sizeof(request), dest_pubkey, onion_c->friends_list[num - 1].temp_public_key, |
404 | onion_c->friends_list[num - 1].temp_secret_key, ping_id, onion_c->friends_list[num - 1].real_client_id, zero_ping_id, | 413 | onion_c->friends_list[num - 1].temp_secret_key, ping_id, onion_c->friends_list[num - 1].real_public_key, zero_ping_id, |
405 | sendback); | 414 | sendback); |
406 | } | 415 | } |
407 | 416 | ||
@@ -430,7 +439,7 @@ static int cmp_entry(const void *a, const void *b) | |||
430 | if (t2) | 439 | if (t2) |
431 | return 1; | 440 | return 1; |
432 | 441 | ||
433 | int close = id_closest(cmp_public_key, entry1.client_id, entry2.client_id); | 442 | int close = id_closest(cmp_public_key, entry1.public_key, entry2.public_key); |
434 | 443 | ||
435 | if (close == 1) | 444 | if (close == 1) |
436 | return 1; | 445 | return 1; |
@@ -463,7 +472,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t | |||
463 | return -1; | 472 | return -1; |
464 | 473 | ||
465 | list_nodes = onion_c->friends_list[num - 1].clients_list; | 474 | list_nodes = onion_c->friends_list[num - 1].clients_list; |
466 | reference_id = onion_c->friends_list[num - 1].real_client_id; | 475 | reference_id = onion_c->friends_list[num - 1].real_public_key; |
467 | } | 476 | } |
468 | 477 | ||
469 | memcpy(cmp_public_key, reference_id, crypto_box_PUBLICKEYBYTES); | 478 | memcpy(cmp_public_key, reference_id, crypto_box_PUBLICKEYBYTES); |
@@ -473,12 +482,12 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t | |||
473 | unsigned int i; | 482 | unsigned int i; |
474 | 483 | ||
475 | if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT) | 484 | if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT) |
476 | || id_closest(reference_id, list_nodes[0].client_id, public_key) == 2) { | 485 | || id_closest(reference_id, list_nodes[0].public_key, public_key) == 2) { |
477 | index = 0; | 486 | index = 0; |
478 | } | 487 | } |
479 | 488 | ||
480 | for (i = 0; i < MAX_ONION_CLIENTS; ++i) { | 489 | for (i = 0; i < MAX_ONION_CLIENTS; ++i) { |
481 | if (memcmp(list_nodes[i].client_id, public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 490 | if (memcmp(list_nodes[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
482 | index = i; | 491 | index = i; |
483 | stored = 1; | 492 | stored = 1; |
484 | break; | 493 | break; |
@@ -488,7 +497,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t | |||
488 | if (index == -1) | 497 | if (index == -1) |
489 | return 0; | 498 | return 0; |
490 | 499 | ||
491 | memcpy(list_nodes[index].client_id, public_key, CLIENT_ID_SIZE); | 500 | memcpy(list_nodes[index].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
492 | list_nodes[index].ip_port = ip_port; | 501 | list_nodes[index].ip_port = ip_port; |
493 | 502 | ||
494 | //TODO: remove this and find a better source of nodes to use for paths. | 503 | //TODO: remove this and find a better source of nodes to use for paths. |
@@ -510,17 +519,17 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t | |||
510 | return 0; | 519 | return 0; |
511 | } | 520 | } |
512 | 521 | ||
513 | static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, const uint8_t *client_id) | 522 | static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, const uint8_t *public_key) |
514 | { | 523 | { |
515 | unsigned int i; | 524 | unsigned int i; |
516 | 525 | ||
517 | for (i = 0; i < MAX_STORED_PINGED_NODES; ++i) { | 526 | for (i = 0; i < MAX_STORED_PINGED_NODES; ++i) { |
518 | if (!is_timeout(last_pinged[i].timestamp, MIN_NODE_PING_TIME)) | 527 | if (!is_timeout(last_pinged[i].timestamp, MIN_NODE_PING_TIME)) |
519 | if (memcmp(last_pinged[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0) | 528 | if (memcmp(last_pinged[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) |
520 | return 0; | 529 | return 0; |
521 | } | 530 | } |
522 | 531 | ||
523 | memcpy(last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].client_id, client_id, crypto_box_PUBLICKEYBYTES); | 532 | memcpy(last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
524 | last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].timestamp = unix_time(); | 533 | last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].timestamp = unix_time(); |
525 | ++*last_pinged_index; | 534 | ++*last_pinged_index; |
526 | return 1; | 535 | return 1; |
@@ -548,7 +557,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for | |||
548 | last_pinged_index = &onion_c->last_pinged_index; | 557 | last_pinged_index = &onion_c->last_pinged_index; |
549 | } else { | 558 | } else { |
550 | list_nodes = onion_c->friends_list[num - 1].clients_list; | 559 | list_nodes = onion_c->friends_list[num - 1].clients_list; |
551 | reference_id = onion_c->friends_list[num - 1].real_client_id; | 560 | reference_id = onion_c->friends_list[num - 1].real_public_key; |
552 | last_pinged = onion_c->friends_list[num - 1].last_pinged; | 561 | last_pinged = onion_c->friends_list[num - 1].last_pinged; |
553 | last_pinged_index = &onion_c->friends_list[num - 1].last_pinged_index; | 562 | last_pinged_index = &onion_c->friends_list[num - 1].last_pinged_index; |
554 | } | 563 | } |
@@ -563,16 +572,16 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for | |||
563 | continue; | 572 | continue; |
564 | 573 | ||
565 | if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT) | 574 | if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT) |
566 | || id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) { | 575 | || id_closest(reference_id, list_nodes[0].public_key, nodes[i].public_key) == 2) { |
567 | /* check if node is already in list. */ | 576 | /* check if node is already in list. */ |
568 | for (j = 0; j < MAX_ONION_CLIENTS; ++j) { | 577 | for (j = 0; j < MAX_ONION_CLIENTS; ++j) { |
569 | if (memcmp(list_nodes[j].client_id, nodes[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) { | 578 | if (memcmp(list_nodes[j].public_key, nodes[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
570 | break; | 579 | break; |
571 | } | 580 | } |
572 | } | 581 | } |
573 | 582 | ||
574 | if (j == MAX_ONION_CLIENTS && good_to_ping(last_pinged, last_pinged_index, nodes[i].client_id)) { | 583 | if (j == MAX_ONION_CLIENTS && good_to_ping(last_pinged, last_pinged_index, nodes[i].public_key)) { |
575 | client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL, ~0); | 584 | client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].public_key, NULL, ~0); |
576 | } | 585 | } |
577 | } | 586 | } |
578 | } | 587 | } |
@@ -670,17 +679,16 @@ static int handle_data_response(void *object, IP_Port source, const uint8_t *pac | |||
670 | sizeof(plain)); | 679 | sizeof(plain)); |
671 | } | 680 | } |
672 | 681 | ||
673 | #define FAKEID_DATA_ID 156 | 682 | #define DHTPK_DATA_MIN_LENGTH (1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES) |
674 | #define FAKEID_DATA_MIN_LENGTH (1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES) | 683 | #define DHTPK_DATA_MAX_LENGTH (DHTPK_DATA_MIN_LENGTH + sizeof(Node_format)*MAX_SENT_NODES) |
675 | #define FAKEID_DATA_MAX_LENGTH (FAKEID_DATA_MIN_LENGTH + sizeof(Node_format)*MAX_SENT_NODES) | 684 | static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t length) |
676 | static int handle_fakeid_announce(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t length) | ||
677 | { | 685 | { |
678 | Onion_Client *onion_c = object; | 686 | Onion_Client *onion_c = object; |
679 | 687 | ||
680 | if (length < FAKEID_DATA_MIN_LENGTH) | 688 | if (length < DHTPK_DATA_MIN_LENGTH) |
681 | return 1; | 689 | return 1; |
682 | 690 | ||
683 | if (length > FAKEID_DATA_MAX_LENGTH) | 691 | if (length > DHTPK_DATA_MAX_LENGTH) |
684 | return 1; | 692 | return 1; |
685 | 693 | ||
686 | int friend_num = onion_friend_num(onion_c, source_pubkey); | 694 | int friend_num = onion_friend_num(onion_c, source_pubkey); |
@@ -704,7 +712,7 @@ static int handle_fakeid_announce(void *object, const uint8_t *source_pubkey, co | |||
704 | onion_set_friend_DHT_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t)); | 712 | onion_set_friend_DHT_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t)); |
705 | onion_c->friends_list[friend_num].last_seen = unix_time(); | 713 | onion_c->friends_list[friend_num].last_seen = unix_time(); |
706 | 714 | ||
707 | uint16_t len_nodes = length - FAKEID_DATA_MIN_LENGTH; | 715 | uint16_t len_nodes = length - DHTPK_DATA_MIN_LENGTH; |
708 | 716 | ||
709 | if (len_nodes != 0) { | 717 | if (len_nodes != 0) { |
710 | Node_format nodes[MAX_SENT_NODES]; | 718 | Node_format nodes[MAX_SENT_NODES]; |
@@ -720,12 +728,12 @@ static int handle_fakeid_announce(void *object, const uint8_t *source_pubkey, co | |||
720 | uint8_t family = nodes[i].ip_port.ip.family; | 728 | uint8_t family = nodes[i].ip_port.ip.family; |
721 | 729 | ||
722 | if (family == AF_INET || family == AF_INET6) { | 730 | if (family == AF_INET || family == AF_INET6) { |
723 | DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id); | 731 | DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key); |
724 | } else if (family == TCP_INET || family == TCP_INET6) { | 732 | } else if (family == TCP_INET || family == TCP_INET6) { |
725 | if (onion_c->friends_list[friend_num].tcp_relay_node_callback) { | 733 | if (onion_c->friends_list[friend_num].tcp_relay_node_callback) { |
726 | void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object; | 734 | void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object; |
727 | uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number; | 735 | uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number; |
728 | onion_c->friends_list[friend_num].tcp_relay_node_callback(obj, number, nodes[i].ip_port, nodes[i].client_id); | 736 | onion_c->friends_list[friend_num].tcp_relay_node_callback(obj, number, nodes[i].ip_port, nodes[i].public_key); |
729 | } | 737 | } |
730 | } | 738 | } |
731 | } | 739 | } |
@@ -759,7 +767,7 @@ static int handle_tcp_onion(void *object, const uint8_t *data, uint16_t length) | |||
759 | * return the number of packets sent on success | 767 | * return the number of packets sent on success |
760 | * return -1 on failure. | 768 | * return -1 on failure. |
761 | */ | 769 | */ |
762 | int send_onion_data(const Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length) | 770 | int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length) |
763 | { | 771 | { |
764 | if ((uint32_t)friend_num >= onion_c->num_friends) | 772 | if ((uint32_t)friend_num >= onion_c->num_friends) |
765 | return -1; | 773 | return -1; |
@@ -770,19 +778,7 @@ int send_onion_data(const Onion_Client *onion_c, int friend_num, const uint8_t * | |||
770 | if (length == 0) | 778 | if (length == 0) |
771 | return -1; | 779 | return -1; |
772 | 780 | ||
773 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
774 | random_nonce(nonce); | ||
775 | |||
776 | uint8_t packet[DATA_IN_RESPONSE_MIN_SIZE + length]; | ||
777 | memcpy(packet, onion_c->c->self_public_key, crypto_box_PUBLICKEYBYTES); | ||
778 | int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->c->self_secret_key, nonce, data, | ||
779 | length, packet + crypto_box_PUBLICKEYBYTES); | ||
780 | |||
781 | if ((uint32_t)len + crypto_box_PUBLICKEYBYTES != sizeof(packet)) | ||
782 | return -1; | ||
783 | |||
784 | unsigned int i, good_nodes[MAX_ONION_CLIENTS], num_good = 0, num_nodes = 0; | 781 | unsigned int i, good_nodes[MAX_ONION_CLIENTS], num_good = 0, num_nodes = 0; |
785 | Onion_Path path[MAX_ONION_CLIENTS]; | ||
786 | Onion_Node *list_nodes = onion_c->friends_list[friend_num].clients_list; | 782 | Onion_Node *list_nodes = onion_c->friends_list[friend_num].clients_list; |
787 | 783 | ||
788 | for (i = 0; i < MAX_ONION_CLIENTS; ++i) { | 784 | for (i = 0; i < MAX_ONION_CLIENTS; ++i) { |
@@ -792,9 +788,6 @@ int send_onion_data(const Onion_Client *onion_c, int friend_num, const uint8_t * | |||
792 | ++num_nodes; | 788 | ++num_nodes; |
793 | 789 | ||
794 | if (list_nodes[i].is_stored) { | 790 | if (list_nodes[i].is_stored) { |
795 | if (random_path(onion_c, &onion_c->friends_list[friend_num].onion_paths, ~0, &path[num_good]) == -1) | ||
796 | continue; | ||
797 | |||
798 | good_nodes[num_good] = i; | 791 | good_nodes[num_good] = i; |
799 | ++num_good; | 792 | ++num_good; |
800 | } | 793 | } |
@@ -803,36 +796,52 @@ int send_onion_data(const Onion_Client *onion_c, int friend_num, const uint8_t * | |||
803 | if (num_good < (num_nodes / 4) + 1) | 796 | if (num_good < (num_nodes / 4) + 1) |
804 | return -1; | 797 | return -1; |
805 | 798 | ||
799 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
800 | random_nonce(nonce); | ||
801 | |||
802 | uint8_t packet[DATA_IN_RESPONSE_MIN_SIZE + length]; | ||
803 | memcpy(packet, onion_c->c->self_public_key, crypto_box_PUBLICKEYBYTES); | ||
804 | int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, onion_c->c->self_secret_key, nonce, data, | ||
805 | length, packet + crypto_box_PUBLICKEYBYTES); | ||
806 | |||
807 | if ((uint32_t)len + crypto_box_PUBLICKEYBYTES != sizeof(packet)) | ||
808 | return -1; | ||
809 | |||
806 | unsigned int good = 0; | 810 | unsigned int good = 0; |
807 | 811 | ||
808 | for (i = 0; i < num_good; ++i) { | 812 | for (i = 0; i < num_good; ++i) { |
813 | Onion_Path path; | ||
814 | |||
815 | if (random_path(onion_c, &onion_c->onion_paths_friends, ~0, &path) == -1) | ||
816 | continue; | ||
817 | |||
809 | uint8_t o_packet[ONION_MAX_PACKET_SIZE]; | 818 | uint8_t o_packet[ONION_MAX_PACKET_SIZE]; |
810 | len = create_data_request(o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_client_id, | 819 | len = create_data_request(o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key, |
811 | list_nodes[good_nodes[i]].data_public_key, nonce, packet, sizeof(packet)); | 820 | list_nodes[good_nodes[i]].data_public_key, nonce, packet, sizeof(packet)); |
812 | 821 | ||
813 | if (len == -1) | 822 | if (len == -1) |
814 | continue; | 823 | continue; |
815 | 824 | ||
816 | if (send_onion_packet_tcp_udp(onion_c, &path[i], list_nodes[good_nodes[i]].ip_port, o_packet, len) == 0) | 825 | if (send_onion_packet_tcp_udp(onion_c, &path, list_nodes[good_nodes[i]].ip_port, o_packet, len) == 0) |
817 | ++good; | 826 | ++good; |
818 | } | 827 | } |
819 | 828 | ||
820 | return good; | 829 | return good; |
821 | } | 830 | } |
822 | 831 | ||
823 | /* Try to send the fakeid via the DHT instead of onion | 832 | /* Try to send the dht public key via the DHT instead of onion |
824 | * | 833 | * |
825 | * Even if this function succeeds, the friend might not receive any data. | 834 | * Even if this function succeeds, the friend might not receive any data. |
826 | * | 835 | * |
827 | * return the number of packets sent on success | 836 | * return the number of packets sent on success |
828 | * return -1 on failure. | 837 | * return -1 on failure. |
829 | */ | 838 | */ |
830 | static int send_dht_fakeid(const Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length) | 839 | static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length) |
831 | { | 840 | { |
832 | if ((uint32_t)friend_num >= onion_c->num_friends) | 841 | if ((uint32_t)friend_num >= onion_c->num_friends) |
833 | return -1; | 842 | return -1; |
834 | 843 | ||
835 | if (!onion_c->friends_list[friend_num].is_fake_clientid) | 844 | if (!onion_c->friends_list[friend_num].know_dht_public_key) |
836 | return -1; | 845 | return -1; |
837 | 846 | ||
838 | uint8_t nonce[crypto_box_NONCEBYTES]; | 847 | uint8_t nonce[crypto_box_NONCEBYTES]; |
@@ -841,7 +850,7 @@ static int send_dht_fakeid(const Onion_Client *onion_c, int friend_num, const ui | |||
841 | uint8_t temp[DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES + length]; | 850 | uint8_t temp[DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES + length]; |
842 | memcpy(temp, onion_c->c->self_public_key, crypto_box_PUBLICKEYBYTES); | 851 | memcpy(temp, onion_c->c->self_public_key, crypto_box_PUBLICKEYBYTES); |
843 | memcpy(temp + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); | 852 | memcpy(temp + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); |
844 | int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->c->self_secret_key, nonce, data, | 853 | int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, onion_c->c->self_secret_key, nonce, data, |
845 | length, temp + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); | 854 | length, temp + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); |
846 | 855 | ||
847 | if ((uint32_t)len + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES != sizeof(temp)) | 856 | if ((uint32_t)len + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES != sizeof(temp)) |
@@ -849,37 +858,37 @@ static int send_dht_fakeid(const Onion_Client *onion_c, int friend_num, const ui | |||
849 | 858 | ||
850 | uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; | 859 | uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; |
851 | len = create_request(onion_c->dht->self_public_key, onion_c->dht->self_secret_key, packet, | 860 | len = create_request(onion_c->dht->self_public_key, onion_c->dht->self_secret_key, packet, |
852 | onion_c->friends_list[friend_num].fake_client_id, temp, sizeof(temp), FAKEID_DATA_ID); | 861 | onion_c->friends_list[friend_num].dht_public_key, temp, sizeof(temp), CRYPTO_PACKET_FAKEID); |
853 | 862 | ||
854 | if (len == -1) | 863 | if (len == -1) |
855 | return -1; | 864 | return -1; |
856 | 865 | ||
857 | return route_tofriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, packet, len); | 866 | return route_tofriend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, packet, len); |
858 | } | 867 | } |
859 | 868 | ||
860 | static int handle_dht_fakeid(void *object, IP_Port source, const uint8_t *source_pubkey, const uint8_t *packet, | 869 | static int handle_dht_dhtpk(void *object, IP_Port source, const uint8_t *source_pubkey, const uint8_t *packet, |
861 | uint16_t length) | 870 | uint16_t length) |
862 | { | 871 | { |
863 | Onion_Client *onion_c = object; | 872 | Onion_Client *onion_c = object; |
864 | 873 | ||
865 | if (length < FAKEID_DATA_MIN_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES) | 874 | if (length < DHTPK_DATA_MIN_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES) |
866 | return 1; | 875 | return 1; |
867 | 876 | ||
868 | if (length > FAKEID_DATA_MAX_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES) | 877 | if (length > DHTPK_DATA_MAX_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES) |
869 | return 1; | 878 | return 1; |
870 | 879 | ||
871 | uint8_t plain[FAKEID_DATA_MAX_LENGTH]; | 880 | uint8_t plain[DHTPK_DATA_MAX_LENGTH]; |
872 | int len = decrypt_data(packet, onion_c->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES, | 881 | int len = decrypt_data(packet, onion_c->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES, |
873 | packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, | 882 | packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, |
874 | length - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES), plain); | 883 | length - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES), plain); |
875 | 884 | ||
876 | if ((uint32_t)len != length - (DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)) | 885 | if (len != length - (DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)) |
877 | return 1; | 886 | return 1; |
878 | 887 | ||
879 | if (memcmp(source_pubkey, plain + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES) != 0) | 888 | if (memcmp(source_pubkey, plain + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES) != 0) |
880 | return 1; | 889 | return 1; |
881 | 890 | ||
882 | return handle_fakeid_announce(onion_c, packet, plain, len); | 891 | return handle_dhtpk_announce(onion_c, packet, plain, len); |
883 | } | 892 | } |
884 | /* Send the packets to tell our friends what our DHT public key is. | 893 | /* Send the packets to tell our friends what our DHT public key is. |
885 | * | 894 | * |
@@ -890,13 +899,13 @@ static int handle_dht_fakeid(void *object, IP_Port source, const uint8_t *source | |||
890 | * return the number of packets sent on success | 899 | * return the number of packets sent on success |
891 | * return -1 on failure. | 900 | * return -1 on failure. |
892 | */ | 901 | */ |
893 | static int send_fakeid_announce(const Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both) | 902 | static int send_dhtpk_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both) |
894 | { | 903 | { |
895 | if (friend_num >= onion_c->num_friends) | 904 | if (friend_num >= onion_c->num_friends) |
896 | return -1; | 905 | return -1; |
897 | 906 | ||
898 | uint8_t data[FAKEID_DATA_MAX_LENGTH]; | 907 | uint8_t data[DHTPK_DATA_MAX_LENGTH]; |
899 | data[0] = FAKEID_DATA_ID; | 908 | data[0] = ONION_DATA_DHTPK; |
900 | uint64_t no_replay = unix_time(); | 909 | uint64_t no_replay = unix_time(); |
901 | host_to_net((uint8_t *)&no_replay, sizeof(no_replay)); | 910 | host_to_net((uint8_t *)&no_replay, sizeof(no_replay)); |
902 | memcpy(data + 1, &no_replay, sizeof(no_replay)); | 911 | memcpy(data + 1, &no_replay, sizeof(no_replay)); |
@@ -908,7 +917,7 @@ static int send_fakeid_announce(const Onion_Client *onion_c, uint16_t friend_num | |||
908 | int nodes_len = 0; | 917 | int nodes_len = 0; |
909 | 918 | ||
910 | if (num_nodes != 0) { | 919 | if (num_nodes != 0) { |
911 | nodes_len = pack_nodes(data + FAKEID_DATA_MIN_LENGTH, FAKEID_DATA_MAX_LENGTH - FAKEID_DATA_MIN_LENGTH, nodes, | 920 | nodes_len = pack_nodes(data + DHTPK_DATA_MIN_LENGTH, DHTPK_DATA_MAX_LENGTH - DHTPK_DATA_MIN_LENGTH, nodes, |
912 | num_nodes); | 921 | num_nodes); |
913 | 922 | ||
914 | if (nodes_len <= 0) | 923 | if (nodes_len <= 0) |
@@ -918,10 +927,10 @@ static int send_fakeid_announce(const Onion_Client *onion_c, uint16_t friend_num | |||
918 | int num1 = -1, num2 = -1; | 927 | int num1 = -1, num2 = -1; |
919 | 928 | ||
920 | if (onion_dht_both != 1) | 929 | if (onion_dht_both != 1) |
921 | num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + nodes_len); | 930 | num1 = send_onion_data(onion_c, friend_num, data, DHTPK_DATA_MIN_LENGTH + nodes_len); |
922 | 931 | ||
923 | if (onion_dht_both != 0) | 932 | if (onion_dht_both != 0) |
924 | num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + nodes_len); | 933 | num2 = send_dht_dhtpk(onion_c, friend_num, data, DHTPK_DATA_MIN_LENGTH + nodes_len); |
925 | 934 | ||
926 | if (num1 == -1) | 935 | if (num1 == -1) |
927 | return num2; | 936 | return num2; |
@@ -937,7 +946,7 @@ static int send_fakeid_announce(const Onion_Client *onion_c, uint16_t friend_num | |||
937 | * return -1 on failure. | 946 | * return -1 on failure. |
938 | * return friend number on success. | 947 | * return friend number on success. |
939 | */ | 948 | */ |
940 | int onion_friend_num(const Onion_Client *onion_c, const uint8_t *client_id) | 949 | int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key) |
941 | { | 950 | { |
942 | unsigned int i; | 951 | unsigned int i; |
943 | 952 | ||
@@ -945,7 +954,7 @@ int onion_friend_num(const Onion_Client *onion_c, const uint8_t *client_id) | |||
945 | if (onion_c->friends_list[i].status == 0) | 954 | if (onion_c->friends_list[i].status == 0) |
946 | continue; | 955 | continue; |
947 | 956 | ||
948 | if (memcmp(client_id, onion_c->friends_list[i].real_client_id, crypto_box_PUBLICKEYBYTES) == 0) | 957 | if (memcmp(public_key, onion_c->friends_list[i].real_public_key, crypto_box_PUBLICKEYBYTES) == 0) |
949 | return i; | 958 | return i; |
950 | } | 959 | } |
951 | 960 | ||
@@ -979,9 +988,9 @@ static int realloc_onion_friends(Onion_Client *onion_c, uint32_t num) | |||
979 | * return -1 on failure. | 988 | * return -1 on failure. |
980 | * return the friend number on success or if the friend was already added. | 989 | * return the friend number on success or if the friend was already added. |
981 | */ | 990 | */ |
982 | int onion_addfriend(Onion_Client *onion_c, const uint8_t *client_id) | 991 | int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key) |
983 | { | 992 | { |
984 | int num = onion_friend_num(onion_c, client_id); | 993 | int num = onion_friend_num(onion_c, public_key); |
985 | 994 | ||
986 | if (num != -1) | 995 | if (num != -1) |
987 | return num; | 996 | return num; |
@@ -1005,7 +1014,7 @@ int onion_addfriend(Onion_Client *onion_c, const uint8_t *client_id) | |||
1005 | } | 1014 | } |
1006 | 1015 | ||
1007 | onion_c->friends_list[index].status = 1; | 1016 | onion_c->friends_list[index].status = 1; |
1008 | memcpy(onion_c->friends_list[index].real_client_id, client_id, crypto_box_PUBLICKEYBYTES); | 1017 | memcpy(onion_c->friends_list[index].real_public_key, public_key, crypto_box_PUBLICKEYBYTES); |
1009 | crypto_box_keypair(onion_c->friends_list[index].temp_public_key, onion_c->friends_list[index].temp_secret_key); | 1018 | crypto_box_keypair(onion_c->friends_list[index].temp_public_key, onion_c->friends_list[index].temp_secret_key); |
1010 | return index; | 1019 | return index; |
1011 | } | 1020 | } |
@@ -1020,8 +1029,8 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num) | |||
1020 | if ((uint32_t)friend_num >= onion_c->num_friends) | 1029 | if ((uint32_t)friend_num >= onion_c->num_friends) |
1021 | return -1; | 1030 | return -1; |
1022 | 1031 | ||
1023 | //if (onion_c->friends_list[friend_num].is_fake_clientid) | 1032 | //if (onion_c->friends_list[friend_num].know_dht_public_key) |
1024 | // DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, 0); | 1033 | // DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, 0); |
1025 | 1034 | ||
1026 | memset(&(onion_c->friends_list[friend_num]), 0, sizeof(Onion_Friend)); | 1035 | memset(&(onion_c->friends_list[friend_num]), 0, sizeof(Onion_Friend)); |
1027 | unsigned int i; | 1036 | unsigned int i; |
@@ -1092,17 +1101,17 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin | |||
1092 | if (onion_c->friends_list[friend_num].status == 0) | 1101 | if (onion_c->friends_list[friend_num].status == 0) |
1093 | return -1; | 1102 | return -1; |
1094 | 1103 | ||
1095 | if (onion_c->friends_list[friend_num].is_fake_clientid) { | 1104 | if (onion_c->friends_list[friend_num].know_dht_public_key) { |
1096 | if (memcmp(dht_key, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES) == 0) { | 1105 | if (memcmp(dht_key, onion_c->friends_list[friend_num].dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
1097 | return -1; | 1106 | return -1; |
1098 | } | 1107 | } |
1099 | 1108 | ||
1100 | onion_c->friends_list[friend_num].is_fake_clientid = 0; | 1109 | onion_c->friends_list[friend_num].know_dht_public_key = 0; |
1101 | } | 1110 | } |
1102 | 1111 | ||
1103 | onion_c->friends_list[friend_num].last_seen = unix_time(); | 1112 | onion_c->friends_list[friend_num].last_seen = unix_time(); |
1104 | onion_c->friends_list[friend_num].is_fake_clientid = 1; | 1113 | onion_c->friends_list[friend_num].know_dht_public_key = 1; |
1105 | memcpy(onion_c->friends_list[friend_num].fake_client_id, dht_key, crypto_box_PUBLICKEYBYTES); | 1114 | memcpy(onion_c->friends_list[friend_num].dht_public_key, dht_key, crypto_box_PUBLICKEYBYTES); |
1106 | 1115 | ||
1107 | return 0; | 1116 | return 0; |
1108 | } | 1117 | } |
@@ -1120,18 +1129,18 @@ unsigned int onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_ | |||
1120 | if (onion_c->friends_list[friend_num].status == 0) | 1129 | if (onion_c->friends_list[friend_num].status == 0) |
1121 | return 0; | 1130 | return 0; |
1122 | 1131 | ||
1123 | if (!onion_c->friends_list[friend_num].is_fake_clientid) | 1132 | if (!onion_c->friends_list[friend_num].know_dht_public_key) |
1124 | return 0; | 1133 | return 0; |
1125 | 1134 | ||
1126 | memcpy(dht_key, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES); | 1135 | memcpy(dht_key, onion_c->friends_list[friend_num].dht_public_key, crypto_box_PUBLICKEYBYTES); |
1127 | return 1; | 1136 | return 1; |
1128 | } | 1137 | } |
1129 | 1138 | ||
1130 | /* Get the ip of friend friendnum and put it in ip_port | 1139 | /* Get the ip of friend friendnum and put it in ip_port |
1131 | * | 1140 | * |
1132 | * return -1, -- if client_id does NOT refer to a friend | 1141 | * return -1, -- if public_key does NOT refer to a friend |
1133 | * return 0, -- if client_id refers to a friend and we failed to find the friend (yet) | 1142 | * return 0, -- if public_key refers to a friend and we failed to find the friend (yet) |
1134 | * return 1, ip if client_id refers to a friend and we found him | 1143 | * return 1, ip if public_key refers to a friend and we found him |
1135 | * | 1144 | * |
1136 | */ | 1145 | */ |
1137 | int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port) | 1146 | int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port) |
@@ -1176,15 +1185,15 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on | |||
1176 | static void populate_path_nodes(Onion_Client *onion_c) | 1185 | static void populate_path_nodes(Onion_Client *onion_c) |
1177 | { | 1186 | { |
1178 | Node_format nodes_list[MAX_SENT_NODES]; | 1187 | Node_format nodes_list[MAX_SENT_NODES]; |
1179 | uint8_t client_id[crypto_box_PUBLICKEYBYTES]; | 1188 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
1180 | uint32_t random_num = rand(); | 1189 | uint32_t random_num = rand(); |
1181 | memcpy(client_id, &random_num, sizeof(random_num)); | 1190 | memcpy(public_key, &random_num, sizeof(random_num)); |
1182 | 1191 | ||
1183 | unsigned int num_nodes = get_close_nodes(onion_c->dht, client_id, nodes_list, (rand() % 2) ? AF_INET : AF_INET6, 1, 0); | 1192 | unsigned int num_nodes = get_close_nodes(onion_c->dht, public_key, nodes_list, (rand() % 2) ? AF_INET : AF_INET6, 1, 0); |
1184 | unsigned int i; | 1193 | unsigned int i; |
1185 | 1194 | ||
1186 | for (i = 0; i < num_nodes; ++i) { | 1195 | for (i = 0; i < num_nodes; ++i) { |
1187 | onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].client_id); | 1196 | onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key); |
1188 | } | 1197 | } |
1189 | } | 1198 | } |
1190 | 1199 | ||
@@ -1196,7 +1205,7 @@ static void populate_path_nodes_tcp(Onion_Client *onion_c) | |||
1196 | unsigned int i; | 1205 | unsigned int i; |
1197 | 1206 | ||
1198 | for (i = 0; i < num_nodes; ++i) { | 1207 | for (i = 0; i < num_nodes; ++i) { |
1199 | onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].client_id); | 1208 | onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key); |
1200 | } | 1209 | } |
1201 | } | 1210 | } |
1202 | 1211 | ||
@@ -1236,7 +1245,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum) | |||
1236 | } | 1245 | } |
1237 | 1246 | ||
1238 | if (is_timeout(list_nodes[i].last_pinged, interval)) { | 1247 | if (is_timeout(list_nodes[i].last_pinged, interval)) { |
1239 | if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0, ~0) == 0) { | 1248 | if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].public_key, 0, ~0) == 0) { |
1240 | list_nodes[i].last_pinged = unix_time(); | 1249 | list_nodes[i].last_pinged = unix_time(); |
1241 | } | 1250 | } |
1242 | } | 1251 | } |
@@ -1256,7 +1265,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum) | |||
1256 | for (j = 0; j < n; ++j) { | 1265 | for (j = 0; j < n; ++j) { |
1257 | unsigned int num = rand() % num_nodes; | 1266 | unsigned int num = rand() % num_nodes; |
1258 | client_send_announce_request(onion_c, friendnum + 1, onion_c->path_nodes[num].ip_port, | 1267 | client_send_announce_request(onion_c, friendnum + 1, onion_c->path_nodes[num].ip_port, |
1259 | onion_c->path_nodes[num].client_id, 0, ~0); | 1268 | onion_c->path_nodes[num].public_key, 0, ~0); |
1260 | } | 1269 | } |
1261 | 1270 | ||
1262 | ++onion_c->friends_list[friendnum].run_count; | 1271 | ++onion_c->friends_list[friendnum].run_count; |
@@ -1265,14 +1274,14 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum) | |||
1265 | ++onion_c->friends_list[friendnum].run_count; | 1274 | ++onion_c->friends_list[friendnum].run_count; |
1266 | } | 1275 | } |
1267 | 1276 | ||
1268 | /* send packets to friend telling them our fake DHT id. */ | 1277 | /* send packets to friend telling them our DHT public key. */ |
1269 | if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_onion_sent, ONION_FAKEID_INTERVAL)) | 1278 | if (is_timeout(onion_c->friends_list[friendnum].last_dht_pk_onion_sent, ONION_DHTPK_SEND_INTERVAL)) |
1270 | if (send_fakeid_announce(onion_c, friendnum, 0) >= 1) | 1279 | if (send_dhtpk_announce(onion_c, friendnum, 0) >= 1) |
1271 | onion_c->friends_list[friendnum].last_fakeid_onion_sent = unix_time(); | 1280 | onion_c->friends_list[friendnum].last_dht_pk_onion_sent = unix_time(); |
1272 | 1281 | ||
1273 | if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_dht_sent, DHT_FAKEID_INTERVAL)) | 1282 | if (is_timeout(onion_c->friends_list[friendnum].last_dht_pk_dht_sent, DHT_DHTPK_SEND_INTERVAL)) |
1274 | if (send_fakeid_announce(onion_c, friendnum, 1) >= 1) | 1283 | if (send_dhtpk_announce(onion_c, friendnum, 1) >= 1) |
1275 | onion_c->friends_list[friendnum].last_fakeid_dht_sent = unix_time(); | 1284 | onion_c->friends_list[friendnum].last_dht_pk_dht_sent = unix_time(); |
1276 | 1285 | ||
1277 | } | 1286 | } |
1278 | } | 1287 | } |
@@ -1312,7 +1321,7 @@ static void do_announce(Onion_Client *onion_c) | |||
1312 | } | 1321 | } |
1313 | 1322 | ||
1314 | if (is_timeout(list_nodes[i].last_pinged, interval)) { | 1323 | if (is_timeout(list_nodes[i].last_pinged, interval)) { |
1315 | if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].client_id, | 1324 | if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].public_key, |
1316 | list_nodes[i].ping_id, list_nodes[i].path_used) == 0) { | 1325 | list_nodes[i].ping_id, list_nodes[i].path_used) == 0) { |
1317 | list_nodes[i].last_pinged = unix_time(); | 1326 | list_nodes[i].last_pinged = unix_time(); |
1318 | } | 1327 | } |
@@ -1335,7 +1344,7 @@ static void do_announce(Onion_Client *onion_c) | |||
1335 | if (num_nodes != 0) { | 1344 | if (num_nodes != 0) { |
1336 | for (i = 0; i < (MAX_ONION_CLIENTS / 2); ++i) { | 1345 | for (i = 0; i < (MAX_ONION_CLIENTS / 2); ++i) { |
1337 | unsigned int num = rand() % num_nodes; | 1346 | unsigned int num = rand() % num_nodes; |
1338 | client_send_announce_request(onion_c, 0, path_nodes[num].ip_port, path_nodes[num].client_id, 0, ~0); | 1347 | client_send_announce_request(onion_c, 0, path_nodes[num].ip_port, path_nodes[num].public_key, 0, ~0); |
1339 | } | 1348 | } |
1340 | } | 1349 | } |
1341 | } | 1350 | } |
@@ -1386,8 +1395,8 @@ Onion_Client *new_onion_client(Net_Crypto *c) | |||
1386 | crypto_box_keypair(onion_c->temp_public_key, onion_c->temp_secret_key); | 1395 | crypto_box_keypair(onion_c->temp_public_key, onion_c->temp_secret_key); |
1387 | networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c); | 1396 | networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c); |
1388 | networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); | 1397 | networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); |
1389 | oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c); | 1398 | oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c); |
1390 | cryptopacket_registerhandler(onion_c->dht, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c); | 1399 | cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_FAKEID, &handle_dht_dhtpk, onion_c); |
1391 | tcp_onion_response_handler(onion_c->c, &handle_tcp_onion, onion_c); | 1400 | tcp_onion_response_handler(onion_c->c, &handle_tcp_onion, onion_c); |
1392 | 1401 | ||
1393 | return onion_c; | 1402 | return onion_c; |
@@ -1402,8 +1411,8 @@ void kill_onion_client(Onion_Client *onion_c) | |||
1402 | realloc_onion_friends(onion_c, 0); | 1411 | realloc_onion_friends(onion_c, 0); |
1403 | networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL); | 1412 | networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL); |
1404 | networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); | 1413 | networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); |
1405 | oniondata_registerhandler(onion_c, FAKEID_DATA_ID, NULL, NULL); | 1414 | oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL); |
1406 | cryptopacket_registerhandler(onion_c->dht, FAKEID_DATA_ID, NULL, NULL); | 1415 | cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_FAKEID, NULL, NULL); |
1407 | tcp_onion_response_handler(onion_c->c, NULL, NULL); | 1416 | tcp_onion_response_handler(onion_c->c, NULL, NULL); |
1408 | memset(onion_c, 0, sizeof(Onion_Client)); | 1417 | memset(onion_c, 0, sizeof(Onion_Client)); |
1409 | free(onion_c); | 1418 | free(onion_c); |
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index fe586c5b..b4e7a1b7 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h | |||
@@ -33,8 +33,8 @@ | |||
33 | #define ONION_NODE_TIMEOUT (ONION_NODE_PING_INTERVAL * 3) | 33 | #define ONION_NODE_TIMEOUT (ONION_NODE_PING_INTERVAL * 3) |
34 | 34 | ||
35 | /* The interval in seconds at which to tell our friends where we are */ | 35 | /* The interval in seconds at which to tell our friends where we are */ |
36 | #define ONION_FAKEID_INTERVAL 30 | 36 | #define ONION_DHTPK_SEND_INTERVAL 30 |
37 | #define DHT_FAKEID_INTERVAL 20 | 37 | #define DHT_DHTPK_SEND_INTERVAL 20 |
38 | 38 | ||
39 | #define NUMBER_ONION_PATHS 6 | 39 | #define NUMBER_ONION_PATHS 6 |
40 | 40 | ||
@@ -55,8 +55,12 @@ | |||
55 | */ | 55 | */ |
56 | #define ONION_OFFLINE_TIMEOUT (ONION_NODE_PING_INTERVAL * 1.25) | 56 | #define ONION_OFFLINE_TIMEOUT (ONION_NODE_PING_INTERVAL * 1.25) |
57 | 57 | ||
58 | /* Onion data packet ids. */ | ||
59 | #define ONION_DATA_FRIEND_REQ CRYPTO_PACKET_FRIEND_REQ | ||
60 | #define ONION_DATA_DHTPK CRYPTO_PACKET_FAKEID | ||
61 | |||
58 | typedef struct { | 62 | typedef struct { |
59 | uint8_t client_id[CLIENT_ID_SIZE]; | 63 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
60 | IP_Port ip_port; | 64 | IP_Port ip_port; |
61 | uint8_t ping_id[ONION_PING_ID_SIZE]; | 65 | uint8_t ping_id[ONION_PING_ID_SIZE]; |
62 | uint8_t data_public_key[crypto_box_PUBLICKEYBYTES]; | 66 | uint8_t data_public_key[crypto_box_PUBLICKEYBYTES]; |
@@ -79,7 +83,7 @@ typedef struct { | |||
79 | } Onion_Client_Paths; | 83 | } Onion_Client_Paths; |
80 | 84 | ||
81 | typedef struct { | 85 | typedef struct { |
82 | uint8_t client_id[CLIENT_ID_SIZE]; | 86 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
83 | uint64_t timestamp; | 87 | uint64_t timestamp; |
84 | } Last_Pinged; | 88 | } Last_Pinged; |
85 | 89 | ||
@@ -87,23 +91,21 @@ typedef struct { | |||
87 | uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/ | 91 | uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/ |
88 | uint8_t is_online; /* Set by the onion_set_friend_status function. */ | 92 | uint8_t is_online; /* Set by the onion_set_friend_status function. */ |
89 | 93 | ||
90 | uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */ | 94 | uint8_t know_dht_public_key; /* 0 if we don't know the dht public key of the other, 1 if we do. */ |
91 | uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES]; | 95 | uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; |
92 | uint8_t real_client_id[crypto_box_PUBLICKEYBYTES]; | 96 | uint8_t real_public_key[crypto_box_PUBLICKEYBYTES]; |
93 | 97 | ||
94 | Onion_Node clients_list[MAX_ONION_CLIENTS]; | 98 | Onion_Node clients_list[MAX_ONION_CLIENTS]; |
95 | uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; | 99 | uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; |
96 | uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; | 100 | uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; |
97 | 101 | ||
98 | uint64_t last_fakeid_onion_sent; | 102 | uint64_t last_dht_pk_onion_sent; |
99 | uint64_t last_fakeid_dht_sent; | 103 | uint64_t last_dht_pk_dht_sent; |
100 | 104 | ||
101 | uint64_t last_noreplay; | 105 | uint64_t last_noreplay; |
102 | 106 | ||
103 | uint64_t last_seen; | 107 | uint64_t last_seen; |
104 | 108 | ||
105 | Onion_Client_Paths onion_paths; | ||
106 | |||
107 | Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; | 109 | Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; |
108 | uint8_t last_pinged_index; | 110 | uint8_t last_pinged_index; |
109 | 111 | ||
@@ -130,7 +132,8 @@ typedef struct { | |||
130 | 132 | ||
131 | Onion_Node clients_announce_list[MAX_ONION_CLIENTS]; | 133 | Onion_Node clients_announce_list[MAX_ONION_CLIENTS]; |
132 | 134 | ||
133 | Onion_Client_Paths onion_paths; | 135 | Onion_Client_Paths onion_paths_self; |
136 | Onion_Client_Paths onion_paths_friends; | ||
134 | 137 | ||
135 | uint8_t secret_symmetric_key[crypto_box_KEYBYTES]; | 138 | uint8_t secret_symmetric_key[crypto_box_KEYBYTES]; |
136 | uint64_t last_run; | 139 | uint64_t last_run; |
@@ -162,7 +165,7 @@ typedef struct { | |||
162 | * return -1 on failure | 165 | * return -1 on failure |
163 | * return 0 on success | 166 | * return 0 on success |
164 | */ | 167 | */ |
165 | int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *client_id); | 168 | int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key); |
166 | 169 | ||
167 | /* Put up to max_num nodes in nodes. | 170 | /* Put up to max_num nodes in nodes. |
168 | * | 171 | * |
@@ -175,14 +178,14 @@ uint16_t onion_backup_nodes(const Onion_Client *onion_c, Node_format *nodes, uin | |||
175 | * return -1 on failure. | 178 | * return -1 on failure. |
176 | * return the friend number on success or if the friend was already added. | 179 | * return the friend number on success or if the friend was already added. |
177 | */ | 180 | */ |
178 | int onion_friend_num(const Onion_Client *onion_c, const uint8_t *client_id); | 181 | int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key); |
179 | 182 | ||
180 | /* Add a friend who we want to connect to. | 183 | /* Add a friend who we want to connect to. |
181 | * | 184 | * |
182 | * return -1 on failure. | 185 | * return -1 on failure. |
183 | * return the friend number on success. | 186 | * return the friend number on success. |
184 | */ | 187 | */ |
185 | int onion_addfriend(Onion_Client *onion_c, const uint8_t *client_id); | 188 | int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key); |
186 | 189 | ||
187 | /* Delete a friend. | 190 | /* Delete a friend. |
188 | * | 191 | * |
@@ -204,9 +207,9 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on | |||
204 | 207 | ||
205 | /* Get the ip of friend friendnum and put it in ip_port | 208 | /* Get the ip of friend friendnum and put it in ip_port |
206 | * | 209 | * |
207 | * return -1, -- if client_id does NOT refer to a friend | 210 | * return -1, -- if public_key does NOT refer to a friend |
208 | * return 0, -- if client_id refers to a friend and we failed to find the friend (yet) | 211 | * return 0, -- if public_key refers to a friend and we failed to find the friend (yet) |
209 | * return 1, ip if client_id refers to a friend and we found him | 212 | * return 1, ip if public_key refers to a friend and we found him |
210 | * | 213 | * |
211 | */ | 214 | */ |
212 | int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port); | 215 | int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port); |
@@ -262,7 +265,7 @@ unsigned int onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_ | |||
262 | * return the number of packets sent on success | 265 | * return the number of packets sent on success |
263 | * return -1 on failure. | 266 | * return -1 on failure. |
264 | */ | 267 | */ |
265 | int send_onion_data(const Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length); | 268 | int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length); |
266 | 269 | ||
267 | /* Function to call when onion data packet with contents beginning with byte is received. */ | 270 | /* Function to call when onion data packet with contents beginning with byte is received. */ |
268 | void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object); | 271 | void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object); |
diff --git a/toxcore/ping.c b/toxcore/ping.c index a29c1a12..1c3564a3 100644 --- a/toxcore/ping.c +++ b/toxcore/ping.c | |||
@@ -269,12 +269,12 @@ int add_to_ping(PING *ping, const uint8_t *client_id, IP_Port ip_port) | |||
269 | 269 | ||
270 | for (i = 0; i < MAX_TO_PING; ++i) { | 270 | for (i = 0; i < MAX_TO_PING; ++i) { |
271 | if (!ip_isset(&ping->to_ping[i].ip_port.ip)) { | 271 | if (!ip_isset(&ping->to_ping[i].ip_port.ip)) { |
272 | memcpy(ping->to_ping[i].client_id, client_id, CLIENT_ID_SIZE); | 272 | memcpy(ping->to_ping[i].public_key, client_id, CLIENT_ID_SIZE); |
273 | ipport_copy(&ping->to_ping[i].ip_port, &ip_port); | 273 | ipport_copy(&ping->to_ping[i].ip_port, &ip_port); |
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
276 | 276 | ||
277 | if (memcmp(ping->to_ping[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { | 277 | if (memcmp(ping->to_ping[i].public_key, client_id, CLIENT_ID_SIZE) == 0) { |
278 | return -1; | 278 | return -1; |
279 | } | 279 | } |
280 | } | 280 | } |
@@ -282,8 +282,8 @@ int add_to_ping(PING *ping, const uint8_t *client_id, IP_Port ip_port) | |||
282 | uint32_t r = rand(); | 282 | uint32_t r = rand(); |
283 | 283 | ||
284 | for (i = 0; i < MAX_TO_PING; ++i) { | 284 | for (i = 0; i < MAX_TO_PING; ++i) { |
285 | if (id_closest(ping->dht->self_public_key, ping->to_ping[(i + r) % MAX_TO_PING].client_id, client_id) == 2) { | 285 | if (id_closest(ping->dht->self_public_key, ping->to_ping[(i + r) % MAX_TO_PING].public_key, client_id) == 2) { |
286 | memcpy(ping->to_ping[(i + r) % MAX_TO_PING].client_id, client_id, CLIENT_ID_SIZE); | 286 | memcpy(ping->to_ping[(i + r) % MAX_TO_PING].public_key, client_id, CLIENT_ID_SIZE); |
287 | ipport_copy(&ping->to_ping[(i + r) % MAX_TO_PING].ip_port, &ip_port); | 287 | ipport_copy(&ping->to_ping[(i + r) % MAX_TO_PING].ip_port, &ip_port); |
288 | return 0; | 288 | return 0; |
289 | } | 289 | } |
@@ -311,7 +311,7 @@ void do_to_ping(PING *ping) | |||
311 | if (!ip_isset(&ping->to_ping[i].ip_port.ip)) | 311 | if (!ip_isset(&ping->to_ping[i].ip_port.ip)) |
312 | return; | 312 | return; |
313 | 313 | ||
314 | send_ping_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].client_id); | 314 | send_ping_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].public_key); |
315 | ip_reset(&ping->to_ping[i].ip_port.ip); | 315 | ip_reset(&ping->to_ping[i].ip_port.ip); |
316 | } | 316 | } |
317 | } | 317 | } |
diff --git a/toxcore/tox.c b/toxcore/tox.c index a4a73838..82beb561 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -36,7 +36,7 @@ typedef struct Messenger Tox; | |||
36 | 36 | ||
37 | /* | 37 | /* |
38 | * returns a FRIEND_ADDRESS_SIZE byte address to give to others. | 38 | * returns a FRIEND_ADDRESS_SIZE byte address to give to others. |
39 | * Format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] | 39 | * Format: [public_key (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] |
40 | * | 40 | * |
41 | */ | 41 | */ |
42 | void tox_get_address(const Tox *tox, uint8_t *address) | 42 | void tox_get_address(const Tox *tox, uint8_t *address) |
@@ -73,31 +73,31 @@ int32_t tox_add_friend(Tox *tox, const uint8_t *address, const uint8_t *data, ui | |||
73 | * return the friend number if success. | 73 | * return the friend number if success. |
74 | * return -1 if failure. | 74 | * return -1 if failure. |
75 | */ | 75 | */ |
76 | int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *client_id) | 76 | int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *public_key) |
77 | { | 77 | { |
78 | Messenger *m = tox; | 78 | Messenger *m = tox; |
79 | return m_addfriend_norequest(m, client_id); | 79 | return m_addfriend_norequest(m, public_key); |
80 | } | 80 | } |
81 | 81 | ||
82 | /* return the friend number associated to that client id. | 82 | /* return the friend number associated to that client id. |
83 | * return -1 if no such friend. | 83 | * return -1 if no such friend. |
84 | */ | 84 | */ |
85 | int32_t tox_get_friend_number(const Tox *tox, const uint8_t *client_id) | 85 | int32_t tox_get_friend_number(const Tox *tox, const uint8_t *public_key) |
86 | { | 86 | { |
87 | const Messenger *m = tox; | 87 | const Messenger *m = tox; |
88 | return getfriend_id(m, client_id); | 88 | return getfriend_id(m, public_key); |
89 | } | 89 | } |
90 | 90 | ||
91 | /* Copies the public key associated to that friend id into client_id buffer. | 91 | /* Copies the public key associated to that friend id into public_key buffer. |
92 | * Make sure that client_id is of size CLIENT_ID_SIZE. | 92 | * Make sure that public_key is of size crypto_box_PUBLICKEYBYTES. |
93 | * | 93 | * |
94 | * return 0 if success. | 94 | * return 0 if success. |
95 | * return -1 if failure. | 95 | * return -1 if failure. |
96 | */ | 96 | */ |
97 | int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *client_id) | 97 | int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *public_key) |
98 | { | 98 | { |
99 | const Messenger *m = tox; | 99 | const Messenger *m = tox; |
100 | return getclient_id(m, friendnumber, client_id); | 100 | return get_real_pk(m, friendnumber, public_key); |
101 | } | 101 | } |
102 | 102 | ||
103 | /* Remove a friend. */ | 103 | /* Remove a friend. */ |
@@ -643,16 +643,16 @@ int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t | |||
643 | return group_peername(m->group_chat_object, groupnumber, peernumber, name); | 643 | return group_peername(m->group_chat_object, groupnumber, peernumber, name); |
644 | } | 644 | } |
645 | 645 | ||
646 | /* Copy the public key of peernumber who is in groupnumber to pk. | 646 | /* Copy the public key of peernumber who is in groupnumber to public_key. |
647 | * pk must be TOX_CLIENT_ID_SIZE long. | 647 | * public_key must be crypto_box_PUBLICKEYBYTES long. |
648 | * | 648 | * |
649 | * returns 0 on success | 649 | * returns 0 on success |
650 | * returns -1 on failure | 650 | * returns -1 on failure |
651 | */ | 651 | */ |
652 | int tox_group_peer_pubkey(const Tox *tox, int groupnumber, int peernumber, uint8_t *pk) | 652 | int tox_group_peer_pubkey(const Tox *tox, int groupnumber, int peernumber, uint8_t *public_key) |
653 | { | 653 | { |
654 | const Messenger *m = tox; | 654 | const Messenger *m = tox; |
655 | return group_peer_pubkey(m->group_chat_object, groupnumber, peernumber, pk); | 655 | return group_peer_pubkey(m->group_chat_object, groupnumber, peernumber, public_key); |
656 | } | 656 | } |
657 | 657 | ||
658 | /* invite friendnumber to groupnumber | 658 | /* invite friendnumber to groupnumber |
@@ -1012,8 +1012,8 @@ uint32_t tox_do_interval(Tox *tox) | |||
1012 | */ | 1012 | */ |
1013 | Tox *tox_new(Tox_Options *options) | 1013 | Tox *tox_new(Tox_Options *options) |
1014 | { | 1014 | { |
1015 | logger_set_global(logger_new(LOGGER_OUTPUT_FILE, LOGGER_LEVEL, "toxcore")); | 1015 | if (!logger_get_global()) |
1016 | 1016 | logger_set_global(logger_new(LOGGER_OUTPUT_FILE, LOGGER_LEVEL, "toxcore")); | |
1017 | 1017 | ||
1018 | Messenger_Options m_options = {0}; | 1018 | Messenger_Options m_options = {0}; |
1019 | 1019 | ||
diff --git a/toxcore/tox.h b/toxcore/tox.h index db1b1033..ee678cc1 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h | |||
@@ -38,11 +38,14 @@ extern "C" { | |||
38 | #define TOX_MAX_STATUSMESSAGE_LENGTH 1007 | 38 | #define TOX_MAX_STATUSMESSAGE_LENGTH 1007 |
39 | #define TOX_MAX_FRIENDREQUEST_LENGTH 1016 | 39 | #define TOX_MAX_FRIENDREQUEST_LENGTH 1016 |
40 | 40 | ||
41 | #define TOX_CLIENT_ID_SIZE 32 | 41 | #define TOX_PUBLIC_KEY_SIZE 32 |
42 | /* TODO: remove */ | ||
43 | #define TOX_CLIENT_ID_SIZE TOX_PUBLIC_KEY_SIZE | ||
44 | |||
42 | #define TOX_AVATAR_MAX_DATA_LENGTH 16384 | 45 | #define TOX_AVATAR_MAX_DATA_LENGTH 16384 |
43 | #define TOX_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32 | 46 | #define TOX_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32 |
44 | 47 | ||
45 | #define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) | 48 | #define TOX_FRIEND_ADDRESS_SIZE (TOX_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) |
46 | 49 | ||
47 | #define TOX_ENABLE_IPV6_DEFAULT 1 | 50 | #define TOX_ENABLE_IPV6_DEFAULT 1 |
48 | 51 | ||
@@ -97,7 +100,7 @@ typedef struct Tox Tox; | |||
97 | */ | 100 | */ |
98 | 101 | ||
99 | /* return TOX_FRIEND_ADDRESS_SIZE byte address to give to others. | 102 | /* return TOX_FRIEND_ADDRESS_SIZE byte address to give to others. |
100 | * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] | 103 | * format: [public_key (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] |
101 | */ | 104 | */ |
102 | void tox_get_address(const Tox *tox, uint8_t *address); | 105 | void tox_get_address(const Tox *tox, uint8_t *address); |
103 | 106 | ||
@@ -124,18 +127,18 @@ int32_t tox_add_friend(Tox *tox, const uint8_t *address, const uint8_t *data, ui | |||
124 | * return the friend number if success. | 127 | * return the friend number if success. |
125 | * return -1 if failure. | 128 | * return -1 if failure. |
126 | */ | 129 | */ |
127 | int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *client_id); | 130 | int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *public_key); |
128 | 131 | ||
129 | /* return the friend number associated to that client id. | 132 | /* return the friend number associated to that client id. |
130 | return -1 if no such friend */ | 133 | return -1 if no such friend */ |
131 | int32_t tox_get_friend_number(const Tox *tox, const uint8_t *client_id); | 134 | int32_t tox_get_friend_number(const Tox *tox, const uint8_t *public_key); |
132 | 135 | ||
133 | /* Copies the public key associated to that friend id into client_id buffer. | 136 | /* Copies the public key associated to that friend id into public_key buffer. |
134 | * Make sure that client_id is of size CLIENT_ID_SIZE. | 137 | * Make sure that public_key is of size TOX_PUBLIC_KEY_SIZE. |
135 | * return 0 if success. | 138 | * return 0 if success. |
136 | * return -1 if failure. | 139 | * return -1 if failure. |
137 | */ | 140 | */ |
138 | int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *client_id); | 141 | int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *public_key); |
139 | 142 | ||
140 | /* Remove a friend. | 143 | /* Remove a friend. |
141 | * | 144 | * |
@@ -500,13 +503,13 @@ int tox_del_groupchat(Tox *tox, int groupnumber); | |||
500 | */ | 503 | */ |
501 | int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t *name); | 504 | int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t *name); |
502 | 505 | ||
503 | /* Copy the public key of peernumber who is in groupnumber to pk. | 506 | /* Copy the public key of peernumber who is in groupnumber to public_key. |
504 | * pk must be TOX_CLIENT_ID_SIZE long. | 507 | * public_key must be TOX_PUBLIC_KEY_SIZE long. |
505 | * | 508 | * |
506 | * returns 0 on success | 509 | * returns 0 on success |
507 | * returns -1 on failure | 510 | * returns -1 on failure |
508 | */ | 511 | */ |
509 | int tox_group_peer_pubkey(const Tox *tox, int groupnumber, int peernumber, uint8_t *pk); | 512 | int tox_group_peer_pubkey(const Tox *tox, int groupnumber, int peernumber, uint8_t *public_key); |
510 | 513 | ||
511 | /* invite friendnumber to groupnumber | 514 | /* invite friendnumber to groupnumber |
512 | * return 0 on success | 515 | * return 0 on success |
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c index b6453a89..9172f512 100644 --- a/toxencryptsave/toxencryptsave.c +++ b/toxencryptsave/toxencryptsave.c | |||
@@ -121,7 +121,7 @@ int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *sa | |||
121 | /* note that, according to the documentation, a generic pwhash interface will be created | 121 | /* note that, according to the documentation, a generic pwhash interface will be created |
122 | * once the pwhash competition (https://password-hashing.net/) is over */ | 122 | * once the pwhash competition (https://password-hashing.net/) is over */ |
123 | if (crypto_pwhash_scryptsalsa208sha256( | 123 | if (crypto_pwhash_scryptsalsa208sha256( |
124 | key, sizeof(key), passkey, sizeof(passkey), salt, | 124 | key, sizeof(key), (char *)passkey, sizeof(passkey), salt, |
125 | crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ | 125 | crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ |
126 | crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { | 126 | crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { |
127 | /* out of memory most likely */ | 127 | /* out of memory most likely */ |
@@ -280,7 +280,7 @@ int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase, | |||
280 | 280 | ||
281 | if (crypto_pwhash_scryptsalsa208sha256( | 281 | if (crypto_pwhash_scryptsalsa208sha256( |
282 | key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, | 282 | key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, |
283 | crypto_box_KEYBYTES, passkey, sizeof(passkey), salt, | 283 | crypto_box_KEYBYTES, (char *)passkey, sizeof(passkey), salt, |
284 | crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ | 284 | crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ |
285 | crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { | 285 | crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { |
286 | /* out of memory most likely */ | 286 | /* out of memory most likely */ |