summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--auto_tests/messenger_test.c13
-rw-r--r--auto_tests/onion_test.c36
-rw-r--r--docs/TCP_Network.txt35
-rw-r--r--docs/TODO15
-rw-r--r--other/DHT_bootstrap.c12
-rw-r--r--other/bootstrap_server_packets.c65
-rw-r--r--other/bootstrap_serverdaemon/tox_bootstrap_daemon.c7
-rw-r--r--other/fun/cracker.c75
-rw-r--r--other/fun/sign.c15
-rw-r--r--testing/DHT_test.c4
-rw-r--r--testing/Messenger_test.c8
-rw-r--r--testing/experiment/group_chats_test.c105
-rw-r--r--testing/experiment/group_chats_test1.c114
-rw-r--r--testing/misc_tools.c18
-rw-r--r--testing/tox_sync.c5
-rw-r--r--toxcore/LAN_discovery.h2
-rw-r--r--toxcore/group_chats.c29
-rw-r--r--toxcore/group_chats.h3
-rw-r--r--toxcore/onion_announce.c2
-rw-r--r--toxcore/onion_client.c5
21 files changed, 296 insertions, 276 deletions
diff --git a/README.md b/README.md
index d526a4c5..4e6ebf0e 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,8 @@ With the rise of governmental monitoring programs, Tox aims to be an easy to use
7 7
8**IRC**: #tox on freenode, alternatively, you can use the [webchat](https://webchat.freenode.net/?channels=#tox).<br /> 8**IRC**: #tox on freenode, alternatively, you can use the [webchat](https://webchat.freenode.net/?channels=#tox).<br />
9**Website**: [https://tox.im](https://tox.im)<br> 9**Website**: [https://tox.im](https://tox.im)<br>
10**Developer Blog**: [http://dev.tox.im](http://dev.tox.im)<br> 10**Jenkins**: [http://jenkins.tox.im](http://jenkins.tox.im)<br>
11**Jenkins**: [http://jenkins.tox.im](http://jenkins.tox.im) 11**Nightly Binary Downloads***: [http://download.tox.im](http://download.tox.im)
12 12
13**Website translations**: [here](https://github.com/Tox/tox.im)<br/> 13**Website translations**: [here](https://github.com/Tox/tox.im)<br/>
14**Qt GUI**: [see nurupo's repository](https://github.com/nurupo/ProjectTox-Qt-GUI) 14**Qt GUI**: [see nurupo's repository](https://github.com/nurupo/ProjectTox-Qt-GUI)
diff --git a/auto_tests/messenger_test.c b/auto_tests/messenger_test.c
index 5c8e242e..0393e6d9 100644
--- a/auto_tests/messenger_test.c
+++ b/auto_tests/messenger_test.c
@@ -14,6 +14,7 @@
14#include "config.h" 14#include "config.h"
15#endif 15#endif
16 16
17#include "../testing/misc_tools.c" // hex_string_to_bin
17#include "../toxcore/Messenger.h" 18#include "../toxcore/Messenger.h"
18#include "../toxcore/Lossless_UDP.h" 19#include "../toxcore/Lossless_UDP.h"
19#include <sys/types.h> 20#include <sys/types.h>
@@ -41,18 +42,6 @@ int friend_id_num = 0;
41 42
42Messenger *m; 43Messenger *m;
43 44
44unsigned char *hex_string_to_bin(char hex_string[])
45{
46 size_t i, len = strlen(hex_string);
47 unsigned char *val = calloc(1, len);
48 char *pos = hex_string;
49
50 for (i = 0; i < len; ++i, pos += 2)
51 sscanf(pos, "%2hhx", &val[i]);
52
53 return val;
54}
55
56START_TEST(test_m_sendmesage) 45START_TEST(test_m_sendmesage)
57{ 46{
58 char *message = "h-hi :3"; 47 char *message = "h-hi :3";
diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c
index 73f69744..1a458f65 100644
--- a/auto_tests/onion_test.c
+++ b/auto_tests/onion_test.c
@@ -262,9 +262,13 @@ START_TEST(test_announce)
262 ip_init(&ip, 1); 262 ip_init(&ip, 1);
263 ip.ip6.uint8[15] = 1; 263 ip.ip6.uint8[15] = 1;
264 264
265 for (i = 1; i < NUM_ONIONS; ++i) { 265 for (i = 3; i < NUM_ONIONS; ++i) {
266 IP_Port ip_port = {ip, onions[i - 1]->onion->net->port}; 266 IP_Port ip_port = {ip, onions[i - 1]->onion->net->port};
267 DHT_bootstrap(onions[i]->onion->dht, ip_port, onions[i - 1]->onion->dht->self_public_key); 267 DHT_bootstrap(onions[i]->onion->dht, ip_port, onions[i - 1]->onion->dht->self_public_key);
268 IP_Port ip_port1 = {ip, onions[i - 2]->onion->net->port};
269 DHT_bootstrap(onions[i]->onion->dht, ip_port1, onions[i - 2]->onion->dht->self_public_key);
270 IP_Port ip_port2 = {ip, onions[i - 3]->onion->net->port};
271 DHT_bootstrap(onions[i]->onion->dht, ip_port2, onions[i - 3]->onion->dht->self_public_key);
268 } 272 }
269 273
270 uint32_t connected = 0; 274 uint32_t connected = 0;
@@ -276,23 +280,41 @@ START_TEST(test_announce)
276 do_onions(onions[i]); 280 do_onions(onions[i]);
277 connected += DHT_isconnected(onions[i]->onion->dht); 281 connected += DHT_isconnected(onions[i]->onion->dht);
278 } 282 }
283
284 c_sleep(50);
279 } 285 }
280 286
281 onion_addfriend(onions[7]->onion_c, onions[23]->onion->dht->c->self_public_key); 287 onion_addfriend(onions[7]->onion_c, onions[27]->onion->dht->c->self_public_key);
282 int frnum = onion_addfriend(onions[23]->onion_c, onions[7]->onion->dht->c->self_public_key); 288 int frnum = onion_addfriend(onions[27]->onion_c, onions[7]->onion->dht->c->self_public_key);
289
290 int ok = -1;
291
292 IP_Port ip_port;
293
294 while (ok == -1) {
295 for (i = 0; i < NUM_ONIONS; ++i) {
296 networking_poll(onions[i]->onion->net);
297 do_onion_client(onions[i]->onion_c);
298 }
299
300 ok = onion_getfriendip(onions[27]->onion_c, frnum, &ip_port);
301
302 c_sleep(50);
303 }
283 304
284 uint32_t ok = 0; 305 printf("id discovered\n");
285 306
286 while (ok != 1) { 307 while (ok != 1) {
287 for (i = 0; i < NUM_ONIONS; ++i) { 308 for (i = 0; i < NUM_ONIONS; ++i) {
288 do_onions(onions[i]); 309 do_onions(onions[i]);
289 } 310 }
290 311
291 IP_Port ip_port; 312 ok = onion_getfriendip(onions[27]->onion_c, frnum, &ip_port);
292 ok = onion_getfriendip(onions[23]->onion_c, frnum, &ip_port);
293 313
294 c_sleep(50); 314 c_sleep(50);
295 } 315 }
316
317 ck_assert_msg(ip_port.port == onions[7]->onion->net->port, "Port in returned ip not correct.");
296} 318}
297END_TEST 319END_TEST
298 320
@@ -309,7 +331,7 @@ Suite *onion_suite(void)
309 Suite *s = suite_create("Onion"); 331 Suite *s = suite_create("Onion");
310 332
311 DEFTESTCASE_SLOW(basic, 5); 333 DEFTESTCASE_SLOW(basic, 5);
312 DEFTESTCASE_SLOW(announce, 80); 334 DEFTESTCASE_SLOW(announce, 200);
313 return s; 335 return s;
314} 336}
315 337
diff --git a/docs/TCP_Network.txt b/docs/TCP_Network.txt
new file mode 100644
index 00000000..f44cca71
--- /dev/null
+++ b/docs/TCP_Network.txt
@@ -0,0 +1,35 @@
1It has come to our attention that to achieve decent market penetration Tox
2must work behind ALL internet connections, may they be behind enterprise NATs
3or any other bad network conditions.
4
5The people who have issues with the UDP direct connection approach seem to be a
6small minority though it is hard to estimate how many.
7
8This means that routing their packets using good nodes on the network will
9probably not take a huge toll on the network and will assure that people
10can use Tox regardless of the quality of their internet connection.
11
12
13How it's probably going to work:
141. Alice, a Tox client on a TCP only network generates a temporary public key
15and connects to a bootstrap server.
16
172. Using the bootstrap server she find and connects to a couple (exact number
18to be determined later) number of random nodes that have TCP relay support.
19
203. She uses the onion through the TCP relay connections to send friend requests
21or tell online friends which TCP nodes she is connected to and her temporary
22public key.
23
244. Bob receives an onion packet from Alice telling him which nodes she is
25connected to. Bob connects to these nodes and establishes a routed connection
26with alice using that temporary public key.
27
285. That connection is used by both to transmit encrypted Messenger and A/V
29packets.
30
316. If one of the nodes shuts down while it is currently routing traffic, Alice
32and bob just switch to one of the other nodes they are both connected to.
33
34
35Actual detailed implementation details coming soon.
diff --git a/docs/TODO b/docs/TODO
index fbbd0614..0b5aa4ab 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -7,7 +7,7 @@ Networking:
7 [NOT STARTED] NAT-PMP port forwarding. 7 [NOT STARTED] NAT-PMP port forwarding.
8 8
9DHT: 9DHT:
10 [IN PROGRESS] Metadata collection prevention. (docs/Prevent_Tracking.txt) 10 [ALMOST DONE] Metadata collection prevention. (docs/Prevent_Tracking.txt)
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
@@ -20,14 +20,15 @@ Lossless UDP:
20 [NOT STARTED] Make clients sign their messages so that peers can't modify them. 20 [NOT STARTED] Make clients sign their messages so that peers can't modify them.
21 21
22[IN PROGRESS] Audio/Video 22[IN PROGRESS] Audio/Video
23 [DONE] Capture/encoding/streaming/decoding/displaying 23 [DONE] encoding/streaming/decoding
24 [IN PROGRESS] Call initiation 24 [IN PROGRESS] Call initiation
25 [NOT STARTED] Encryption 25 [IN PROGRESS] Encryption
26 [IN PROGRESS] Auditing.
26 [NOT STARTED] Small group chats 27 [NOT STARTED] Small group chats
27 [NOT STARTED] Push to talk for audio
28 28
29Friend_requests.c: 29Friend_requests.c:
30 [NOT STARTED] What happens when a friend request is recieved needs to be changed. 30 [NOT STARTED] What happens when a friend request is received needs to be changed.
31 [NOT STARTED] Add multiple nospam functionality.
31 32
32[DONE] File transfers 33[DONE] File transfers
33[NOT STARTED] Offline messaging 34[NOT STARTED] Offline messaging
@@ -37,6 +38,10 @@ Friend_requests.c:
37 [DONE] DHT + Messenger 38 [DONE] DHT + Messenger
38 [NOT STARTED] Group chats (They work with IPv6 but some things need to be tested.) 39 [NOT STARTED] Group chats (They work with IPv6 but some things need to be tested.)
39 40
41
42[NOT STARTED] A way for people to connect to people on Tox if they are behind a bad NAT that
43blocks UDP (or is just unpunchable) (docs/TCP_Network.txt)
44
40[NEEDS TESTING] Make the save made with tox_save_encrypted(...) harder to brute force. 45[NEEDS TESTING] Make the save made with tox_save_encrypted(...) harder to brute force.
41See: (https://github.com/jencka/ProjectTox-libtoxdata) 46See: (https://github.com/jencka/ProjectTox-libtoxdata)
42 47
diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c
index ebb0ab78..307f80f6 100644
--- a/other/DHT_bootstrap.c
+++ b/other/DHT_bootstrap.c
@@ -33,6 +33,13 @@
33 33
34#include "../testing/misc_tools.c" 34#include "../testing/misc_tools.c"
35 35
36#ifdef DHT_SERVER_EXTRA_PACKETS
37#include "./bootstrap_server_packets.c"
38
39#define DHT_VERSION_NUMBER 1
40#define DHT_MOTD "This is a test motd"
41#endif
42
36/* Sleep function (x = milliseconds) */ 43/* Sleep function (x = milliseconds) */
37#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 44#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
38#define c_sleep(x) Sleep(1*x) 45#define c_sleep(x) Sleep(1*x)
@@ -45,7 +52,6 @@
45#define PORT 33445 52#define PORT 33445
46 53
47 54
48
49void manage_keys(DHT *dht) 55void manage_keys(DHT *dht)
50{ 56{
51 const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 57 const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
@@ -105,6 +111,10 @@ int main(int argc, char *argv[])
105 Onion *onion = new_onion(dht); 111 Onion *onion = new_onion(dht);
106 Onion_Announce *onion_a = new_onion_announce(dht); 112 Onion_Announce *onion_a = new_onion_announce(dht);
107 113
114#ifdef DHT_SERVER_EXTRA_PACKETS
115 bootstrap_set_callbacks(dht->net, DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD));
116#endif
117
108 if (!(onion && onion_a)) { 118 if (!(onion && onion_a)) {
109 printf("Something failed to initialize.\n"); 119 printf("Something failed to initialize.\n");
110 exit(1); 120 exit(1);
diff --git a/other/bootstrap_server_packets.c b/other/bootstrap_server_packets.c
new file mode 100644
index 00000000..c9297535
--- /dev/null
+++ b/other/bootstrap_server_packets.c
@@ -0,0 +1,65 @@
1/* bootstrap_server_packets.c
2 *
3 * Special bootstrap server only packets.
4 *
5 * Include it in your bootstrap server and use: bootstrap_set_callbacks() to enable.
6 *
7 * Copyright (C) 2013 Tox project All Rights Reserved.
8 *
9 * This file is part of Tox.
10 *
11 * Tox is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * Tox is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
23 *
24 */
25
26#define MAX_MOTD_LENGTH 256 /* I recommend you use a maximum of 96 bytes. The hard maximum is this though. */
27
28#define INFO_REQUEST_PACKET_LENGTH 78
29
30static uint32_t bootstrap_version;
31static uint8_t bootstrap_motd[MAX_MOTD_LENGTH];
32static uint16_t bootstrap_motd_length;
33
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
36 */
37static int handle_info_request(void *object, IP_Port source, uint8_t *packet, uint32_t length)
38{
39 if (length != INFO_REQUEST_PACKET_LENGTH)
40 return 1;
41
42 uint8_t data[1 + sizeof(bootstrap_version) + MAX_MOTD_LENGTH];
43 data[0] = BOOTSTRAP_INFO_PACKET_ID;
44 memcpy(data + 1, &bootstrap_version, sizeof(bootstrap_version));
45 uint16_t len = 1 + sizeof(bootstrap_version) + bootstrap_motd_length;
46 memcpy(data + 1 + sizeof(bootstrap_version), bootstrap_motd, bootstrap_motd_length);
47
48 if (sendpacket(object, source, data, len) == len)
49 return 0;
50
51 return 1;
52}
53
54int bootstrap_set_callbacks(Networking_Core *net, uint32_t version, uint8_t *motd, uint16_t motd_length)
55{
56 if (motd_length > MAX_MOTD_LENGTH)
57 return -1;
58
59 bootstrap_version = htonl(version);
60 memcpy(bootstrap_motd, motd, motd_length);
61 bootstrap_motd_length = motd_length;
62
63 networking_registerhandler(net, BOOTSTRAP_INFO_PACKET_ID, &handle_info_request, net);
64 return 0;
65}
diff --git a/other/bootstrap_serverdaemon/tox_bootstrap_daemon.c b/other/bootstrap_serverdaemon/tox_bootstrap_daemon.c
index f2c54bb1..b7684115 100644
--- a/other/bootstrap_serverdaemon/tox_bootstrap_daemon.c
+++ b/other/bootstrap_serverdaemon/tox_bootstrap_daemon.c
@@ -256,7 +256,8 @@ int bootstrap_from_config(char *cfg_file_path, DHT *dht, int enable_ipv6)
256 256
257 // Process settings 257 // Process settings
258 if (strlen(bs_public_key) != 64) { 258 if (strlen(bs_public_key) != 64) {
259 syslog(LOG_WARNING, "Bootstrap server #%d: Invalid '%s': %s. Skipping the server.\n", i, NAME_PUBLIC_KEY, bs_public_key); 259 syslog(LOG_WARNING, "Bootstrap server #%d: Invalid '%s': %s. Skipping the server.\n", i, NAME_PUBLIC_KEY,
260 bs_public_key);
260 goto next; 261 goto next;
261 } 262 }
262 263
@@ -266,8 +267,10 @@ int bootstrap_from_config(char *cfg_file_path, DHT *dht, int enable_ipv6)
266 goto next; 267 goto next;
267 } 268 }
268 269
270 uint8_t *bs_public_key_bin = hex_string_to_bin((char *)bs_public_key);
269 const int address_resolved = DHT_bootstrap_from_address(dht, bs_address, enable_ipv6, htons(bs_port), 271 const int address_resolved = DHT_bootstrap_from_address(dht, bs_address, enable_ipv6, htons(bs_port),
270 hex_string_to_bin((char *)bs_public_key)); 272 bs_public_key_bin);
273 free(bs_public_key_bin);
271 274
272 if (!address_resolved) { 275 if (!address_resolved) {
273 syslog(LOG_WARNING, "Bootstrap server #%d: Invalid '%s': %s. Skipping the server.\n", i, NAME_ADDRESS, bs_address); 276 syslog(LOG_WARNING, "Bootstrap server #%d: Invalid '%s': %s. Skipping the server.\n", i, NAME_ADDRESS, bs_address);
diff --git a/other/fun/cracker.c b/other/fun/cracker.c
new file mode 100644
index 00000000..9921df31
--- /dev/null
+++ b/other/fun/cracker.c
@@ -0,0 +1,75 @@
1/* Public key cracker.
2 *
3 * Can be used to find public keys starting with specific hex (ABCD) for example.
4 *
5 * NOTE: There's probably a way to make this faster.
6 *
7 * Usage: ./cracker ABCDEF
8 *
9 * Will try to find a public key starting with: ABCDEF
10 */
11
12#include "../../testing/misc_tools.c"
13#include <time.h>
14
15/* NaCl includes*/
16#include <crypto_scalarmult_curve25519.h>
17#include <randombytes.h>
18
19/* Sodium include*/
20//#include <libsodium.h>
21
22void print_key(uint8_t *client_id)
23{
24 uint32_t j;
25
26 for (j = 0; j < 32; j++) {
27 printf("%02hhX", client_id[j]);
28 }
29}
30
31
32int main(int argc, char *argv[])
33{
34 if (argc < 2) {
35 printf("usage: ./cracker public_key(or beggining of one in hex format)\n");
36 return 0;
37 }
38
39 long long unsigned int num_tries = 0;
40
41 uint32_t len = strlen(argv[1]) / 2;
42 unsigned char *key = hex_string_to_bin(argv[1]);
43 uint8_t pub_key[32], priv_key[32], c_key[32];
44
45 if (len > 32)
46 len = 32;
47
48 memcpy(c_key, key, len);
49 free(key);
50 randombytes(priv_key, 32);
51
52 while (1) {
53 crypto_scalarmult_curve25519_base(pub_key, priv_key);
54 uint32_t i;
55
56 if (memcmp(c_key, pub_key, len) == 0)
57 break;
58
59 for (i = 32; i != 0; --i) {
60 priv_key[i - 1] += 1;
61
62 if (priv_key[i - 1] != 0)
63 break;
64 }
65
66 ++num_tries;
67 }
68
69 printf("Public key:\n");
70 print_key(pub_key);
71 printf("\nPrivate key:\n");
72 print_key(priv_key);
73 printf("\n %llu keys tried\n", num_tries);
74 return 0;
75}
diff --git a/other/fun/sign.c b/other/fun/sign.c
index 423d974a..eaea9d6a 100644
--- a/other/fun/sign.c
+++ b/other/fun/sign.c
@@ -17,19 +17,7 @@
17 */ 17 */
18#include <sodium.h> 18#include <sodium.h>
19#include <string.h> 19#include <string.h>
20 20#include "../../testing/misc_tools.c" // hex_string_to_bin
21unsigned char *hex_string_to_bin(char hex_string[])
22{
23 size_t len = strlen(hex_string);
24 unsigned char *val = malloc(len);
25 char *pos = hex_string;
26 int i;
27
28 for (i = 0; i < len; ++i, pos += 2)
29 sscanf(pos, "%2hhx", &val[i]);
30
31 return val;
32}
33 21
34int load_file(char *filename, char **result) 22int load_file(char *filename, char **result)
35{ 23{
@@ -90,6 +78,7 @@ int main(int argc, char *argv[])
90 unsigned long long smlen; 78 unsigned long long smlen;
91 char *sm = malloc(size + crypto_sign_ed25519_BYTES * 2); 79 char *sm = malloc(size + crypto_sign_ed25519_BYTES * 2);
92 crypto_sign_ed25519(sm, &smlen, data, size, secret_key); 80 crypto_sign_ed25519(sm, &smlen, data, size, secret_key);
81 free(secret_key);
93 82
94 if (smlen - size != crypto_sign_ed25519_BYTES) 83 if (smlen - size != crypto_sign_ed25519_BYTES)
95 goto fail; 84 goto fail;
diff --git a/testing/DHT_test.c b/testing/DHT_test.c
index a8ad8426..cae88ce4 100644
--- a/testing/DHT_test.c
+++ b/testing/DHT_test.c
@@ -206,7 +206,9 @@ int main(int argc, char *argv[])
206 if (scanf("%s", temp_id) != 1) 206 if (scanf("%s", temp_id) != 1)
207 exit(0); 207 exit(0);
208 208
209 DHT_addfriend(dht, hex_string_to_bin(temp_id)); 209 uint8_t *bin_id = hex_string_to_bin(temp_id);
210 DHT_addfriend(dht, bin_id);
211 free(bin_id);
210 212
211 perror("Initialization"); 213 perror("Initialization");
212 214
diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c
index 969d6b1f..895a23d9 100644
--- a/testing/Messenger_test.c
+++ b/testing/Messenger_test.c
@@ -161,14 +161,16 @@ int main(int argc, char *argv[])
161 161
162 setname(m, (uint8_t *)"Anon", 5); 162 setname(m, (uint8_t *)"Anon", 5);
163 163
164 char temp_id[128]; 164 char temp_hex_id[128];
165 printf("\nEnter the address of the friend you wish to add (38 bytes HEX format):\n"); 165 printf("\nEnter the address of the friend you wish to add (38 bytes HEX format):\n");
166 166
167 if (scanf("%s", temp_id) != 1) { 167 if (scanf("%s", temp_hex_id) != 1) {
168 return 1; 168 return 1;
169 } 169 }
170 170
171 int num = m_addfriend(m, hex_string_to_bin(temp_id), (uint8_t *)"Install Gentoo", sizeof("Install Gentoo")); 171 uint8_t *bin_id = hex_string_to_bin(temp_hex_id);
172 int num = m_addfriend(m, bin_id, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
173 free(bin_id);
172 174
173 perror("Initialization"); 175 perror("Initialization");
174 176
diff --git a/testing/experiment/group_chats_test.c b/testing/experiment/group_chats_test.c
deleted file mode 100644
index 04fee327..00000000
--- a/testing/experiment/group_chats_test.c
+++ /dev/null
@@ -1,105 +0,0 @@
1#include "../../toxcore/group_chats.h"
2#define NUM_CHATS 8
3
4#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
5#define c_sleep(x) Sleep(1*x)
6#else
7#define c_sleep(x) usleep(1000*x)
8#endif
9Group_Chat *chats[NUM_CHATS];
10
11void print_close(Group_Close *close)
12{
13 uint32_t i, j;
14 IP_Port p_ip;
15 printf("___________________CLOSE________________________________\n");
16
17 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; i++) {
18 printf("ClientID: ");
19
20 for (j = 0; j < CLIENT_ID_SIZE; j++) {
21 printf("%02hhX", close[i].client_id[j]);
22 }
23
24 p_ip = close[i].ip_port;
25 printf("\nIP: %u.%u.%u.%u Port: %u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3],
26 ntohs(p_ip.port));
27 printf("\nTimestamp: %llu", (long long unsigned int) close[i].last_recv);
28 printf("\n");
29 }
30}
31
32void print_group(Group_Chat *chat)
33{
34 uint32_t i, j;
35 printf("-----------------\nClientID: ");
36
37 for (j = 0; j < CLIENT_ID_SIZE; j++) {
38 printf("%02hhX", chat->self_public_key[j]);
39 }
40
41 printf("\n___________________GROUP________________________________\n");
42
43 for (i = 0; i < chat->numpeers; i++) {
44 printf("ClientID: ");
45
46 for (j = 0; j < CLIENT_ID_SIZE; j++) {
47 printf("%02hhX", chat->group[i].client_id[j]);
48 }
49
50 printf("\nTimestamp: %llu", (long long unsigned int) chat->group[i].last_recv);
51 printf("\nlast_pinged: %llu", (long long unsigned int) chat->group[i].last_pinged);
52 printf("\npingid: %llu", (long long unsigned int) chat->group[i].pingid);
53 printf("\n");
54 }
55}
56
57void print_message(Group_Chat *chat, int peer_number, uint8_t *message, uint16_t length, void *userdata)
58{
59 printf("%u: %s | %u\n", peer_number, message, length);
60}
61
62int main()
63{
64 IP ip;
65 ip.uint32 = 0;
66 uint32_t i;
67
68
69 for (i = 0; i < NUM_CHATS; ++i) {
70 chats[i] = new_groupchat(new_networking(ip, 12745));
71
72 if (chats[i] == 0)
73 exit(1);
74
75 networking_registerhandler(chats[i]->net, 48, &handle_groupchatpacket, chats[i]);
76 callback_groupmessage(chats[i], &print_message, 0);
77 }
78
79 printf("ok\n");
80 IP_Port ip_port;
81 ip_port.ip.uint32 = 0;
82 ip_port.ip.uint8[0] = 127;
83 ip_port.ip.uint8[3] = 1;
84 ip_port.port = htons(12745);
85
86 for (i = 0; i < NUM_CHATS; ++i) {
87 group_newpeer(chats[0], chats[i]->self_public_key);
88 chat_bootstrap(chats[i], ip_port, chats[0]->self_public_key);
89 printf("%u\n", i);
90 }
91
92 while (1) {
93 for (i = 0; i < NUM_CHATS; ++i) {
94 networking_poll(chats[i]->net);
95 do_groupchat(chats[i]);
96 printf("%u\n", chats[i]->numpeers);
97 print_close(chats[i]->close);
98 print_group(chats[i]);
99 }
100
101 c_sleep(100);
102 }
103
104 return 0;
105}
diff --git a/testing/experiment/group_chats_test1.c b/testing/experiment/group_chats_test1.c
deleted file mode 100644
index a74f808a..00000000
--- a/testing/experiment/group_chats_test1.c
+++ /dev/null
@@ -1,114 +0,0 @@
1#include "../../toxcore/group_chats.h"
2#define NUM_CHATS 8
3
4#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
5#define c_sleep(x) Sleep(1*x)
6#else
7#define c_sleep(x) usleep(1000*x)
8#endif
9Group_Chat *chat;
10
11void print_close(Group_Close *close)
12{
13 uint32_t i, j;
14 IP_Port p_ip;
15 printf("___________________CLOSE________________________________\n");
16
17 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; i++) {
18 printf("ClientID: ");
19
20 for (j = 0; j < CLIENT_ID_SIZE; j++) {
21 printf("%02hhX", close[i].client_id[j]);
22 }
23
24 p_ip = close[i].ip_port;
25 printf("\nIP: %u.%u.%u.%u Port: %u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3],
26 ntohs(p_ip.port));
27 printf("\nTimestamp: %llu", (long long unsigned int) close[i].last_recv);
28 printf("\n");
29 }
30}
31
32void print_group(Group_Chat *chat)
33{
34 uint32_t i, j;
35 printf("-----------------\nClientID: ");
36
37 for (j = 0; j < CLIENT_ID_SIZE; j++) {
38 printf("%02hhX", chat->self_public_key[j]);
39 }
40
41 printf("\n___________________GROUP________________________________\n");
42
43 for (i = 0; i < chat->numpeers; i++) {
44 printf("ClientID: ");
45
46 for (j = 0; j < CLIENT_ID_SIZE; j++) {
47 printf("%02hhX", chat->group[i].client_id[j]);
48 }
49
50 printf("\nTimestamp: %llu", (long long unsigned int) chat->group[i].last_recv);
51 printf("\nlast_pinged: %llu", (long long unsigned int) chat->group[i].last_pinged);
52 printf("\npingid: %llu", (long long unsigned int) chat->group[i].pingid);
53 printf("\n");
54 }
55}
56
57unsigned char *hex_string_to_bin(char hex_string[])
58{
59 size_t len = strlen(hex_string);
60 unsigned char *val = malloc(len);
61 char *pos = hex_string;
62 int i;
63
64 for (i = 0; i < len; ++i, pos += 2)
65 sscanf(pos, "%2hhx", &val[i]);
66
67 return val;
68}
69
70void print_message(Group_Chat *chat, int peer_number, uint8_t *message, uint16_t length, void *userdata)
71{
72 printf("%u: %s | %u\n", peer_number, message, length);
73}
74
75int main(int argc, char *argv[])
76{
77 IP ip;
78 ip.uint32 = 0;
79 uint32_t i;
80
81 chat = new_groupchat(new_networking(ip, 12745));
82
83 if (chat == 0)
84 exit(1);
85
86 networking_registerhandler(chat->net, 48, &handle_groupchatpacket, chat);
87
88 callback_groupmessage(chat, &print_message, 0);
89
90 printf("ok\n");
91 IP_Port bootstrap_ip_port;
92 bootstrap_ip_port.port = htons(atoi(argv[2]));
93 /* bootstrap_ip_port.ip.c[0] = 127;
94 * bootstrap_ip_port.ip.c[1] = 0;
95 * bootstrap_ip_port.ip.c[2] = 0;
96 * bootstrap_ip_port.ip.c[3] = 1; */
97 bootstrap_ip_port.ip.uint32 = inet_addr(argv[1]);
98
99 chat_bootstrap(chat, bootstrap_ip_port, hex_string_to_bin(argv[3]));
100
101 while (1) {
102
103 networking_poll(chat->net);
104 do_groupchat(chat);
105 printf("%u ", chat->numpeers);
106 printf("%u\n", group_sendmessage(chat, "Install Gentoo", sizeof("Install Gentoo")));
107 //print_close(chat->close);
108 // print_group(chat);
109
110 c_sleep(100);
111 }
112
113 return 0;
114}
diff --git a/testing/misc_tools.c b/testing/misc_tools.c
index efe1a555..ad6b2bff 100644
--- a/testing/misc_tools.c
+++ b/testing/misc_tools.c
@@ -28,22 +28,28 @@
28#include <string.h> 28#include <string.h>
29#include <stdlib.h> 29#include <stdlib.h>
30#include <stdio.h> 30#include <stdio.h>
31#include <stdint.h>
31 32
32#ifdef DEBUG 33#ifdef DEBUG
33#include <assert.h> 34#include <assert.h>
34#endif // DEBUG 35#endif // DEBUG
35 36
36/* TODO: rewrite */ 37// You are responsible for freeing the return value!
37unsigned char *hex_string_to_bin(char hex_string[]) 38uint8_t *hex_string_to_bin(char *hex_string)
38{ 39{
39 size_t i, len = strlen(hex_string); 40 // byte is represented by exactly 2 hex digits, so lenth of binary string
40 unsigned char *val = malloc(len); 41 // is half of that of the hex one. only hex string with even length
42 // valid. the more proper implementation would be to check if strlen(hex_string)
43 // is odd and return error code if it is. we assume strlen is even. if it's not
44 // then the last byte just won't be written in 'ret'.
45 size_t i, len = strlen(hex_string) / 2;
46 uint8_t *ret = malloc(len);
41 char *pos = hex_string; 47 char *pos = hex_string;
42 48
43 for (i = 0; i < len; ++i, pos += 2) 49 for (i = 0; i < len; ++i, pos += 2)
44 sscanf(pos, "%2hhx", &val[i]); 50 sscanf(pos, "%2hhx", &ret[i]);
45 51
46 return val; 52 return ret;
47} 53}
48 54
49int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled) 55int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled)
diff --git a/testing/tox_sync.c b/testing/tox_sync.c
index ccb5d20d..2799e7fe 100644
--- a/testing/tox_sync.c
+++ b/testing/tox_sync.c
@@ -221,6 +221,7 @@ int main(int argc, char *argv[])
221 uint16_t port = htons(atoi(argv[argvoffset + 2])); 221 uint16_t port = htons(atoi(argv[argvoffset + 2]));
222 unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); 222 unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]);
223 int res = tox_bootstrap_from_address(tox, argv[argvoffset + 1], ipv6enabled, port, binary_string); 223 int res = tox_bootstrap_from_address(tox, argv[argvoffset + 1], ipv6enabled, port, binary_string);
224 free(binary_string);
224 225
225 if (!res) { 226 if (!res) {
226 printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]); 227 printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]);
@@ -242,7 +243,9 @@ int main(int argc, char *argv[])
242 return 1; 243 return 1;
243 } 244 }
244 245
245 int num = tox_add_friend(tox, hex_string_to_bin(temp_id), (uint8_t *)"Install Gentoo", sizeof("Install Gentoo")); 246 uint8_t *bin_id = hex_string_to_bin(temp_id);
247 int num = tox_add_friend(tox, bin_id, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
248 free(bin_id);
246 249
247 if (num < 0) { 250 if (num < 0) {
248 printf("\nSomething went wrong when adding friend.\n"); 251 printf("\nSomething went wrong when adding friend.\n");
diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h
index 58bd2bee..fcb094e4 100644
--- a/toxcore/LAN_discovery.h
+++ b/toxcore/LAN_discovery.h
@@ -36,7 +36,7 @@
36#endif 36#endif
37 37
38/* Interval in seconds between LAN discovery packet sending. */ 38/* Interval in seconds between LAN discovery packet sending. */
39#define LAN_DISCOVERY_INTERVAL 60 39#define LAN_DISCOVERY_INTERVAL 10
40 40
41/* Send a LAN discovery pcaket to the broadcast address with port port. */ 41/* Send a LAN discovery pcaket to the broadcast address with port port. */
42int send_LANdiscovery(uint16_t port, DHT *dht); 42int send_LANdiscovery(uint16_t port, DHT *dht);
diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c
index 6dff52ef..17914038 100644
--- a/toxcore/group_chats.c
+++ b/toxcore/group_chats.c
@@ -251,6 +251,22 @@ static int addpeer(Group_Chat *chat, uint8_t *client_id)
251} 251}
252 252
253/* 253/*
254 * Set a peer from the group chat to deleted.
255 *
256 * return 0 if success
257 * return -1 if error.
258 */
259static int del_peer_set(Group_Chat *chat, int peernum)
260{
261 if ((uint32_t)peernum >= chat->numpeers)
262 return -1;
263
264 chat->group[peernum].deleted = 1;
265 chat->group[peernum].deleted_time = unix_time();
266 return 0;
267}
268
269/*
254 * Delete a peer from the group chat. 270 * Delete a peer from the group chat.
255 * 271 *
256 * return 0 if success 272 * return 0 if success
@@ -488,6 +504,9 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
488 if (peernum == -1) 504 if (peernum == -1)
489 return 1; 505 return 1;
490 506
507 if (chat->group[peernum].deleted)
508 return 1;
509
491 /* Spam prevention (1 message per peer per second limit.) 510 /* Spam prevention (1 message per peer per second limit.)
492 511
493 if (chat->group[peernum].last_recv == temp_time) 512 if (chat->group[peernum].last_recv == temp_time)
@@ -531,7 +550,7 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
531 if (contents_len != 0) 550 if (contents_len != 0)
532 return 1; 551 return 1;
533 552
534 delpeer(chat, peernum); 553 del_peer_set(chat, peernum);
535 break; 554 break;
536 555
537 case GROUP_CHAT_PEER_NICK: 556 case GROUP_CHAT_PEER_NICK:
@@ -758,6 +777,7 @@ static void ping_group(Group_Chat *chat)
758 } 777 }
759} 778}
760 779
780#define DEL_PEER_DELAY 3
761static void del_dead_peers(Group_Chat *chat) 781static void del_dead_peers(Group_Chat *chat)
762{ 782{
763 uint32_t i; 783 uint32_t i;
@@ -766,6 +786,11 @@ static void del_dead_peers(Group_Chat *chat)
766 if (is_timeout(chat->group[i].last_recv_msgping, GROUP_PING_INTERVAL * 4)) { 786 if (is_timeout(chat->group[i].last_recv_msgping, GROUP_PING_INTERVAL * 4)) {
767 delpeer(chat, i); 787 delpeer(chat, i);
768 } 788 }
789
790 if (chat->group[i].deleted) {
791 if (is_timeout(chat->group[i].deleted_time, DEL_PEER_DELAY))
792 delpeer(chat, i);
793 }
769 } 794 }
770} 795}
771 796
@@ -773,7 +798,7 @@ static void del_dead_peers(Group_Chat *chat)
773static void send_names_new_peer(Group_Chat *chat) 798static void send_names_new_peer(Group_Chat *chat)
774{ 799{
775 group_send_nick(chat, chat->nick, chat->nick_len); 800 group_send_nick(chat, chat->nick, chat->nick_len);
776 chat->last_sent_nick = (unix_time() - NICK_SEND_INTERVAL) + 10; 801 chat->last_sent_nick = (unix_time() - NICK_SEND_INTERVAL) + 15;
777} 802}
778static void send_names(Group_Chat *chat) 803static void send_names(Group_Chat *chat)
779{ 804{
diff --git a/toxcore/group_chats.h b/toxcore/group_chats.h
index 8d5f5e50..e31aa229 100644
--- a/toxcore/group_chats.h
+++ b/toxcore/group_chats.h
@@ -41,6 +41,9 @@ typedef struct {
41 41
42 uint8_t nick[MAX_NICK_BYTES]; 42 uint8_t nick[MAX_NICK_BYTES];
43 uint16_t nick_len; 43 uint16_t nick_len;
44
45 uint8_t deleted;
46 uint64_t deleted_time;
44} Group_Peer; 47} Group_Peer;
45 48
46typedef struct { 49typedef struct {
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c
index da40584d..28e27d91 100644
--- a/toxcore/onion_announce.c
+++ b/toxcore/onion_announce.c
@@ -207,7 +207,7 @@ static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t
207 207
208 memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES); 208 memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
209 qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry); 209 qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry);
210 return pos; 210 return in_entries(onion_a, public_key);
211} 211}
212 212
213static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) 213static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length)
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index c03dfcea..b3c665b7 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -174,6 +174,11 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ
174 if (num == 0) { 174 if (num == 0) {
175 list_nodes = onion_c->clients_announce_list; 175 list_nodes = onion_c->clients_announce_list;
176 reference_id = onion_c->dht->c->self_public_key; 176 reference_id = onion_c->dht->c->self_public_key;
177
178 if (is_stored && memcmp(pingid_or_key, onion_c->temp_public_key, crypto_box_PUBLICKEYBYTES) != 0) {
179 is_stored = 0;
180 }
181
177 } else { 182 } else {
178 list_nodes = onion_c->friends_list[num - 1].clients_list; 183 list_nodes = onion_c->friends_list[num - 1].clients_list;
179 reference_id = onion_c->friends_list[num - 1].real_client_id; 184 reference_id = onion_c->friends_list[num - 1].real_client_id;