summaryrefslogtreecommitdiff
path: root/toxcore/onion_announce.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/onion_announce.c')
-rw-r--r--toxcore/onion_announce.c106
1 files changed, 95 insertions, 11 deletions
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