summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto_tests/onion_test.c16
-rw-r--r--docs/Prevent_Tracking.txt9
-rw-r--r--toxcore/Makefile.inc2
-rw-r--r--toxcore/onion.h6
-rw-r--r--toxcore/onion_announce.c106
-rw-r--r--toxcore/onion_announce.h21
6 files changed, 136 insertions, 24 deletions
diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c
index 745ca4ac..684b7a4f 100644
--- a/auto_tests/onion_test.c
+++ b/auto_tests/onion_test.c
@@ -10,7 +10,7 @@
10#include <time.h> 10#include <time.h>
11 11
12#include "../toxcore/onion.h" 12#include "../toxcore/onion.h"
13 13#include "../toxcore/onion_announce.h"
14 14
15void do_onion(Onion *onion) 15void do_onion(Onion *onion)
16{ 16{
@@ -26,7 +26,7 @@ static int handle_test_1(void *object, IP_Port source, uint8_t *packet, uint32_t
26 if (memcmp(packet, "Install Gentoo", sizeof("Install Gentoo")) != 0) 26 if (memcmp(packet, "Install Gentoo", sizeof("Install Gentoo")) != 0)
27 return 1; 27 return 1;
28 28
29 if (send_onion_response(onion->net, source, "install gentoo", sizeof("install gentoo"), 29 if (send_onion_response(onion->net, source, (uint8_t *)"install gentoo", sizeof("install gentoo"),
30 packet + sizeof("Install Gentoo")) == -1) 30 packet + sizeof("Install Gentoo")) == -1)
31 return 1; 31 return 1;
32 32
@@ -40,12 +40,13 @@ static int handle_test_2(void *object, IP_Port source, uint8_t *packet, uint32_t
40 if (length != sizeof("install Gentoo")) 40 if (length != sizeof("install Gentoo"))
41 return 1; 41 return 1;
42 42
43 if (memcmp(packet, "install gentoo", sizeof("install gentoo")) != 0) 43 if (memcmp(packet, (uint8_t *)"install gentoo", sizeof("install gentoo")) != 0)
44 return 1; 44 return 1;
45 45
46 handled_test_2 = 1; 46 handled_test_2 = 1;
47 return 0; 47 return 0;
48} 48}
49
49START_TEST(test_basic) 50START_TEST(test_basic)
50{ 51{
51 IP ip; 52 IP ip;
@@ -71,7 +72,7 @@ START_TEST(test_basic)
71 nodes[1] = n2; 72 nodes[1] = n2;
72 nodes[2] = n1; 73 nodes[2] = n1;
73 nodes[3] = n2; 74 nodes[3] = n2;
74 int ret = send_onion_packet(onion1, nodes, "Install Gentoo", sizeof("Install Gentoo")); 75 int ret = send_onion_packet(onion1, nodes, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
75 ck_assert_msg(ret == 0, "Failed to create/send onion packet."); 76 ck_assert_msg(ret == 0, "Failed to create/send onion packet.");
76 77
77 handled_test_1 = 0; 78 handled_test_1 = 0;
@@ -91,6 +92,12 @@ START_TEST(test_basic)
91} 92}
92END_TEST 93END_TEST
93 94
95START_TEST(test_announce)
96{
97
98
99}
100END_TEST
94 101
95#define DEFTESTCASE(NAME) \ 102#define DEFTESTCASE(NAME) \
96 TCase *tc_##NAME = tcase_create(#NAME); \ 103 TCase *tc_##NAME = tcase_create(#NAME); \
@@ -105,6 +112,7 @@ Suite *onion_suite(void)
105 Suite *s = suite_create("Onion"); 112 Suite *s = suite_create("Onion");
106 113
107 DEFTESTCASE_SLOW(basic, 5); 114 DEFTESTCASE_SLOW(basic, 5);
115 DEFTESTCASE_SLOW(announce, 5);
108 return s; 116 return s;
109} 117}
110 118
diff --git a/docs/Prevent_Tracking.txt b/docs/Prevent_Tracking.txt
index e4d19edc..d8087070 100644
--- a/docs/Prevent_Tracking.txt
+++ b/docs/Prevent_Tracking.txt
@@ -104,8 +104,9 @@ encrypted (with our real long term private key if we want to announce ourselves,
104add the part used to send data to our list (if the list is full make it replace the furthest entry)) 104add the part used to send data to our list (if the list is full make it replace the furthest entry))
105 105
106data to route request packet: 106data to route request packet:
107[uint8_t packet id (133)][public key of destination node][nonce][temporary just generated public key]encrypted with that temporary private key and the nonce:[data] 107[uint8_t packet id (133)][public key of destination node][nonce][temporary just generated public key]
108(if Node D contains the used to send data for, it sends the stuff in this packet as a data to route response packet to the right node) 108encrypted with that temporary private key and the nonce and the real public key of the destination node:[data]
109(if Node D contains the ret data for the node, it sends the stuff in this packet as a data to route response packet to the right node)
109 110
110Data sent to us: 111Data sent to us:
111announce response packet: 112announce response packet:
@@ -114,8 +115,8 @@ encrypted with the DHT private key of Node D, the public key in the request and
114(if the ping id is zero, it means the information to reach the client id we are searching for is stored on this node) 115(if the ping id is zero, it means the information to reach the client id we are searching for is stored on this node)
115 116
116data to route response packet: 117data to route response packet:
117[uint8_t packet id (134)][nonce]encrypted with that temporary private key and the nonce:[data] 118[uint8_t packet id (134)][nonce][temporary just generated public key]
118 119encrypted with that temporary private key and the nonce and the real public key of the destination node:[data]
119Onion packet (response): 120Onion packet (response):
120 121
121initial (sent from node D to node C): 122initial (sent from node D to node C):
diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc
index d808bde3..56114553 100644
--- a/toxcore/Makefile.inc
+++ b/toxcore/Makefile.inc
@@ -31,6 +31,8 @@ libtoxcore_la_SOURCES = ../toxcore/DHT.h \
31 ../toxcore/assoc.c \ 31 ../toxcore/assoc.c \
32 ../toxcore/onion.h \ 32 ../toxcore/onion.h \
33 ../toxcore/onion.c \ 33 ../toxcore/onion.c \
34 ../toxcore/onion_announce.h \
35 ../toxcore/onion_announce.c \
34 ../toxcore/misc_tools.h 36 ../toxcore/misc_tools.h
35 37
36libtoxcore_la_CFLAGS = -I$(top_srcdir) \ 38libtoxcore_la_CFLAGS = -I$(top_srcdir) \
diff --git a/toxcore/onion.h b/toxcore/onion.h
index 84aa72e1..bb4687fe 100644
--- a/toxcore/onion.h
+++ b/toxcore/onion.h
@@ -20,6 +20,9 @@
20* 20*
21*/ 21*/
22 22
23#ifndef ONION_H
24#define ONION_H
25
23#include "DHT.h" 26#include "DHT.h"
24 27
25typedef struct { 28typedef struct {
@@ -58,3 +61,6 @@ int send_onion_response(Networking_Core *net, IP_Port dest, uint8_t *data, uint3
58Onion *new_onion(DHT *dht); 61Onion *new_onion(DHT *dht);
59 62
60void kill_onion(Onion *onion); 63void kill_onion(Onion *onion);
64
65
66#endif
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c
index a2d6760e..891c308e 100644
--- a/toxcore/onion_announce.c
+++ b/toxcore/onion_announce.c
@@ -34,6 +34,8 @@
34#define ANNOUNCE_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + PING_ID_SIZE + crypto_box_MACBYTES) 34#define ANNOUNCE_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + PING_ID_SIZE + crypto_box_MACBYTES)
35#define ANNOUNCE_RESPONSE_MAX_SIZE (ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES) 35#define ANNOUNCE_RESPONSE_MAX_SIZE (ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES)
36 36
37#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES + ONION_RETURN_3)
38
37/* Generate a ping_id and put it in ping_id */ 39/* Generate a ping_id and put it in ping_id */
38static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, uint8_t *public_key, uint8_t *ret, 40static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, uint8_t *public_key, uint8_t *ret,
39 uint8_t *ping_id) 41 uint8_t *ping_id)
@@ -47,26 +49,89 @@ static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, uint8_t *pu
47 crypto_hash_sha256(ping_id, data, sizeof(data)); 49 crypto_hash_sha256(ping_id, data, sizeof(data));
48} 50}
49 51
50/* add entry to entries list 52/* check if public key is in entries list
51 * 53 *
52 * return 0 if failure 54 * return -1 if no
53 * return 1 if added 55 * return position in list if yes
54 */ 56 */
55static int add_to_entries(Onion_Announce *onion_a, uint8_t *public_key, uint8_t *ret) 57static int in_entries(Onion_Announce *onion_a, uint8_t *public_key)
58{
59 uint32_t i;
60
61 for (i = 0; i < ONION_ANNOUNCE_MAX_ENTRIES; ++i) {
62 if (!is_timeout(onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT)
63 && memcpy(onion_a->entries[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
64 return i;
65 }
66
67 return -1;
68}
69
70uint8_t cmp_public_key[crypto_box_PUBLICKEYBYTES];
71static int cmp_entry(const void *a, const void *b)
56{ 72{
73 Onion_Announce_Entry entry1, entry2;
74 memcpy(&entry1, a, sizeof(Onion_Announce_Entry));
75 memcpy(&entry2, b, sizeof(Onion_Announce_Entry));
76 int t1 = is_timeout(entry1.time, ONION_ANNOUNCE_TIMEOUT);
77 int t2 = is_timeout(entry2.time, ONION_ANNOUNCE_TIMEOUT);
78
79 if (t1 && t2)
80 return 0;
81
82 if (t1)
83 return -1;
84
85 if (t2)
86 return 1;
87
88 int close = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
89
90 if (close == 1)
91 return 1;
92
93 if (close == 2)
94 return -1;
57 95
58 return 0; 96 return 0;
59} 97}
60 98
61/* check if public key is in entries list 99/* add entry to entries list
62 * 100 *
63 * return 0 if no 101 * return 0 if failure
64 * return 1 if yes 102 * return 1 if added
65 */ 103 */
66static int in_entries(Onion_Announce *onion_a, uint8_t *public_key) 104static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *ret)
67{ 105{
68 106
69 return 0; 107 int pos = in_entries(onion_a, public_key);
108
109 uint32_t i;
110
111 if (pos == -1) {
112 for (i = 0; i < ONION_ANNOUNCE_MAX_ENTRIES; ++i) {
113 if (is_timeout(onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT))
114 pos = i;
115 }
116 }
117
118 if (pos == -1) {
119 if (id_closest(onion_a->dht->self_public_key, public_key, onion_a->entries[0].public_key) == 1)
120 pos = 0;
121 }
122
123 if (pos == -1)
124 return 0;
125
126
127 memcpy(onion_a->entries[pos].public_key, public_key, crypto_box_PUBLICKEYBYTES);
128 onion_a->entries[pos].ret_ip_port = ret_ip_port;
129 memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3);
130 onion_a->entries[pos].time = unix_time();
131
132 memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
133 qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry);
134 return 1;
70} 135}
71 136
72static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) 137static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length)
@@ -95,10 +160,10 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
95 int stored = 0; 160 int stored = 0;
96 161
97 if (memcmp(ping_id1, plain, PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, PING_ID_SIZE) == 0) { 162 if (memcmp(ping_id1, plain, PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, PING_ID_SIZE) == 0) {
98 stored = add_to_entries(onion_a, packet + 1 + crypto_box_NONCEBYTES, 163 stored = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES,
99 packet + (ANNOUNCE_REQUEST_SIZE - ONION_RETURN_3)); 164 packet + (ANNOUNCE_REQUEST_SIZE - ONION_RETURN_3));
100 } else { 165 } else {
101 stored = in_entries(onion_a, plain + PING_ID_SIZE); 166 stored = (in_entries(onion_a, plain + PING_ID_SIZE) != -1);
102 } 167 }
103 168
104 /*Respond with a announce response packet*/ 169 /*Respond with a announce response packet*/
@@ -138,6 +203,25 @@ static int handle_data_request(void *object, IP_Port source, uint8_t *packet, ui
138{ 203{
139 Onion_Announce *onion_a = object; 204 Onion_Announce *onion_a = object;
140 205
206 if (length <= DATA_REQUEST_MIN_SIZE)
207 return 1;
208
209 if (length >= MAX_DATA_SIZE)
210 return 1;
211
212 int index = in_entries(onion_a, packet + 1);
213
214 if (index == -1)
215 return 1;
216
217 uint8_t data[length - (crypto_box_PUBLICKEYBYTES + ONION_RETURN_3)];
218 data[0] = NET_PACKET_ONION_DATA_RESPONSE;
219 memcpy(data + 1, packet + 1 + crypto_box_PUBLICKEYBYTES, length - (1 + crypto_box_PUBLICKEYBYTES + ONION_RETURN_3));
220
221 if (send_onion_response(onion_a->net, onion_a->entries[index].ret_ip_port, data, sizeof(data),
222 onion_a->entries[index].ret) == -1)
223 return 1;
224
141 return 0; 225 return 0;
142} 226}
143 227
diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h
index d06865c8..c8d9b442 100644
--- a/toxcore/onion_announce.h
+++ b/toxcore/onion_announce.h
@@ -20,17 +20,25 @@
20* 20*
21*/ 21*/
22 22
23#ifndef ONION_ANNOUNCE_H
24#define ONION_ANNOUNCE_H
25
23#include "onion.h" 26#include "onion.h"
24 27
25#define ONION_ANNOUNCE_MAX_ENTRIES 32 28#define ONION_ANNOUNCE_MAX_ENTRIES 32
29#define ONION_ANNOUNCE_TIMEOUT 300
30
26typedef struct { 31typedef struct {
27 DHT *dht;
28 Networking_Core *net;
29 struct {
30 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 32 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
31 IP_Port first; 33 IP_Port ret_ip_port;
32 uint8_t ret[ONION_RETURN_3]; 34 uint8_t ret[ONION_RETURN_3];
33 } entries[ONION_ANNOUNCE_MAX_ENTRIES]; 35 uint64_t time;
36} Onion_Announce_Entry;
37
38typedef struct {
39 DHT *dht;
40 Networking_Core *net;
41 Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES];
34 /* This is crypto_secretbox_KEYBYTES long just so we can use new_symmetric_key() to fill it */ 42 /* This is crypto_secretbox_KEYBYTES long just so we can use new_symmetric_key() to fill it */
35 uint8_t secret_bytes[crypto_secretbox_KEYBYTES]; 43 uint8_t secret_bytes[crypto_secretbox_KEYBYTES];
36} Onion_Announce; 44} Onion_Announce;
@@ -40,3 +48,6 @@ typedef struct {
40Onion_Announce *new_onion_announce(DHT *dht); 48Onion_Announce *new_onion_announce(DHT *dht);
41 49
42void kill_onion_announce(Onion_Announce *onion_a); 50void kill_onion_announce(Onion_Announce *onion_a);
51
52
53#endif