diff options
Diffstat (limited to 'toxcore/onion_announce.c')
-rw-r--r-- | toxcore/onion_announce.c | 106 |
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 */ |
38 | static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, uint8_t *public_key, uint8_t *ret, | 40 | static 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 | */ |
55 | static int add_to_entries(Onion_Announce *onion_a, uint8_t *public_key, uint8_t *ret) | 57 | static 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 | |||
70 | uint8_t cmp_public_key[crypto_box_PUBLICKEYBYTES]; | ||
71 | static 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 | */ |
66 | static int in_entries(Onion_Announce *onion_a, uint8_t *public_key) | 104 | static 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 | ||
72 | static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 137 | static 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 | ||