summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
authorJfreegman <jfreegman@gmail.com>2016-09-07 12:14:31 -0400
committerJfreegman <jfreegman@gmail.com>2016-09-09 10:37:40 -0400
commit769db9dd9a73208d32c22c52c8eef7446e026f81 (patch)
treec8d563d9e070f3443960232b6205211375d5aba6 /toxcore/DHT.c
parent59075ba325dc91d3fa7760c6b84df0de7854ae7f (diff)
Separate IP_Port packing from pack_nodes() and unpack_nodes()
Allows us to pack IP_Port structs that are part of arbitrarily structured data.
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c237
1 files changed, 145 insertions, 92 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 2e475d01..1d9ad54f 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -27,9 +27,7 @@
27#include "config.h" 27#include "config.h"
28#endif 28#endif
29 29
30#ifdef TOX_DEBUG
31#include <assert.h> 30#include <assert.h>
32#endif
33 31
34#include "logger.h" 32#include "logger.h"
35 33
@@ -233,6 +231,129 @@ int packed_node_size(uint8_t ip_family)
233} 231}
234 232
235 233
234/* Packs an IP_Port structure into data of max size length.
235 *
236 * Returns size of packed IP_Port data on success
237 * Return -1 on failure.
238 */
239static int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port)
240{
241 if (data == NULL) {
242 return -1;
243 }
244
245 int ipv6 = -1;
246 uint8_t net_family;
247
248 if (ip_port->ip.family == AF_INET) {
249 // FIXME use functions to convert endianness
250 ipv6 = 0;
251 net_family = TOX_AF_INET;
252 } else if (ip_port->ip.family == TCP_INET) {
253 ipv6 = 0;
254 net_family = TOX_TCP_INET;
255 } else if (ip_port->ip.family == AF_INET6) {
256 ipv6 = 1;
257 net_family = TOX_AF_INET6;
258 } else if (ip_port->ip.family == TCP_INET6) {
259 ipv6 = 1;
260 net_family = TOX_TCP_INET6;
261 } else {
262 return -1;
263 }
264
265 if (ipv6 == 0) {
266 uint32_t size = 1 + SIZE_IP4 + sizeof(uint16_t);
267
268 if (size > length) {
269 return -1;
270 }
271
272 data[0] = net_family;
273 memcpy(data + 1, &ip_port->ip.ip4, SIZE_IP4);
274 memcpy(data + 1 + SIZE_IP4, &ip_port->port, sizeof(uint16_t));
275 return size;
276 } else if (ipv6 == 1) {
277 uint32_t size = 1 + SIZE_IP6 + sizeof(uint16_t);
278
279 if (size > length) {
280 return -1;
281 }
282
283 data[0] = net_family;
284 memcpy(data + 1, &ip_port->ip.ip6, SIZE_IP6);
285 memcpy(data + 1 + SIZE_IP6, &ip_port->port, sizeof(uint16_t));
286 return size;
287 } else {
288 return -1;
289 }
290}
291
292/* Unpack IP_Port structure from data of max size length into ip_port.
293 *
294 * Return size of unpacked ip_port on success.
295 * Return -1 on failure.
296 */
297static int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, uint8_t tcp_enabled)
298{
299 if (data == NULL) {
300 return -1;
301 }
302
303 int ipv6 = -1;
304 uint8_t host_family;
305
306 if (data[0] == TOX_AF_INET) {
307 ipv6 = 0;
308 host_family = AF_INET;
309 } else if (data[0] == TOX_TCP_INET) {
310 if (!tcp_enabled) {
311 return -1;
312 }
313
314 ipv6 = 0;
315 host_family = TCP_INET;
316 } else if (data[0] == TOX_AF_INET6) {
317 ipv6 = 1;
318 host_family = AF_INET6;
319 } else if (data[0] == TOX_TCP_INET6) {
320 if (!tcp_enabled) {
321 return -1;
322 }
323
324 ipv6 = 1;
325 host_family = TCP_INET6;
326 } else {
327 return -1;
328 }
329
330 if (ipv6 == 0) {
331 uint32_t size = 1 + SIZE_IP4 + sizeof(uint16_t);
332
333 if (size > length) {
334 return -1;
335 }
336
337 ip_port->ip.family = host_family;
338 memcpy(&ip_port->ip.ip4, data + 1, SIZE_IP4);
339 memcpy(&ip_port->port, data + 1 + SIZE_IP4, sizeof(uint16_t));
340 return size;
341 } else if (ipv6 == 1) {
342 uint32_t size = 1 + SIZE_IP6 + sizeof(uint16_t);
343
344 if (size > length) {
345 return -1;
346 }
347
348 ip_port->ip.family = host_family;
349 memcpy(&ip_port->ip.ip6, data + 1, SIZE_IP6);
350 memcpy(&ip_port->port, data + 1 + SIZE_IP6, sizeof(uint16_t));
351 return size;
352 } else {
353 return -1;
354 }
355}
356
236/* Pack number of nodes into data of maxlength length. 357/* Pack number of nodes into data of maxlength length.
237 * 358 *
238 * return length of packed nodes on success. 359 * return length of packed nodes on success.
@@ -242,54 +363,24 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_
242{ 363{
243 uint32_t i, packed_length = 0; 364 uint32_t i, packed_length = 0;
244 365
245 for (i = 0; i < number; ++i) { 366 for (i = 0; i < number && packed_length < length; ++i) {
246 int ipv6 = -1; 367 int ipp_size = pack_ip_port(data + packed_length, length - packed_length, &nodes[i].ip_port);
247 uint8_t net_family;
248 368
249 // FIXME use functions to convert endianness 369 if (ipp_size == -1) {
250 if (nodes[i].ip_port.ip.family == AF_INET) {
251 ipv6 = 0;
252 net_family = TOX_AF_INET;
253 } else if (nodes[i].ip_port.ip.family == TCP_INET) {
254 ipv6 = 0;
255 net_family = TOX_TCP_INET;
256 } else if (nodes[i].ip_port.ip.family == AF_INET6) {
257 ipv6 = 1;
258 net_family = TOX_AF_INET6;
259 } else if (nodes[i].ip_port.ip.family == TCP_INET6) {
260 ipv6 = 1;
261 net_family = TOX_TCP_INET6;
262 } else {
263 return -1; 370 return -1;
264 } 371 }
265 372
266 if (ipv6 == 0) { 373 packed_length += ipp_size;
267 uint32_t size = PACKED_NODE_SIZE_IP4;
268
269 if (packed_length + size > length) {
270 return -1;
271 }
272 374
273 data[packed_length] = net_family; 375 if (packed_length + crypto_box_PUBLICKEYBYTES > length) {
274 memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip4, SIZE_IP4);
275 memcpy(data + packed_length + 1 + SIZE_IP4, &nodes[i].ip_port.port, sizeof(uint16_t));
276 memcpy(data + packed_length + 1 + SIZE_IP4 + sizeof(uint16_t), nodes[i].public_key, crypto_box_PUBLICKEYBYTES);
277 packed_length += size;
278 } else if (ipv6 == 1) {
279 uint32_t size = PACKED_NODE_SIZE_IP6;
280
281 if (packed_length + size > length) {
282 return -1;
283 }
284
285 data[packed_length] = net_family;
286 memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip6, SIZE_IP6);
287 memcpy(data + packed_length + 1 + SIZE_IP6, &nodes[i].ip_port.port, sizeof(uint16_t));
288 memcpy(data + packed_length + 1 + SIZE_IP6 + sizeof(uint16_t), nodes[i].public_key, crypto_box_PUBLICKEYBYTES);
289 packed_length += size;
290 } else {
291 return -1; 376 return -1;
292 } 377 }
378
379 memcpy(data + packed_length, nodes[i].public_key, crypto_box_PUBLICKEYBYTES);
380 packed_length += crypto_box_PUBLICKEYBYTES;
381
382 uint32_t increment = ipp_size + crypto_box_PUBLICKEYBYTES;
383 assert(increment == PACKED_NODE_SIZE_IP4 || increment == PACKED_NODE_SIZE_IP6);
293 } 384 }
294 385
295 return packed_length; 386 return packed_length;
@@ -308,62 +399,24 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
308 uint32_t num = 0, len_processed = 0; 399 uint32_t num = 0, len_processed = 0;
309 400
310 while (num < max_num_nodes && len_processed < length) { 401 while (num < max_num_nodes && len_processed < length) {
311 int ipv6 = -1; 402 int ipp_size = unpack_ip_port(&nodes[num].ip_port, data + len_processed, length - len_processed, tcp_enabled);
312 uint8_t host_family;
313
314 if (data[len_processed] == TOX_AF_INET) {
315 ipv6 = 0;
316 host_family = AF_INET;
317 } else if (data[len_processed] == TOX_TCP_INET) {
318 if (!tcp_enabled) {
319 return -1;
320 }
321 403
322 ipv6 = 0; 404 if (ipp_size == -1) {
323 host_family = TCP_INET;
324 } else if (data[len_processed] == TOX_AF_INET6) {
325 ipv6 = 1;
326 host_family = AF_INET6;
327 } else if (data[len_processed] == TOX_TCP_INET6) {
328 if (!tcp_enabled) {
329 return -1;
330 }
331
332 ipv6 = 1;
333 host_family = TCP_INET6;
334 } else {
335 return -1; 405 return -1;
336 } 406 }
337 407
338 if (ipv6 == 0) { 408 len_processed += ipp_size;
339 uint32_t size = PACKED_NODE_SIZE_IP4;
340 409
341 if (len_processed + size > length) { 410 if (len_processed + crypto_box_PUBLICKEYBYTES > length) {
342 return -1;
343 }
344
345 nodes[num].ip_port.ip.family = host_family;
346 memcpy(&nodes[num].ip_port.ip.ip4, data + len_processed + 1, SIZE_IP4);
347 memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + SIZE_IP4, sizeof(uint16_t));
348 memcpy(nodes[num].public_key, data + len_processed + 1 + SIZE_IP4 + sizeof(uint16_t), crypto_box_PUBLICKEYBYTES);
349 len_processed += size;
350 ++num;
351 } else if (ipv6 == 1) {
352 uint32_t size = PACKED_NODE_SIZE_IP6;
353
354 if (len_processed + size > length) {
355 return -1;
356 }
357
358 nodes[num].ip_port.ip.family = host_family;
359 memcpy(&nodes[num].ip_port.ip.ip6, data + len_processed + 1, SIZE_IP6);
360 memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + SIZE_IP6, sizeof(uint16_t));
361 memcpy(nodes[num].public_key, data + len_processed + 1 + SIZE_IP6 + sizeof(uint16_t), crypto_box_PUBLICKEYBYTES);
362 len_processed += size;
363 ++num;
364 } else {
365 return -1; 411 return -1;
366 } 412 }
413
414 memcpy(nodes[num].public_key, data + len_processed, crypto_box_PUBLICKEYBYTES);
415 len_processed += crypto_box_PUBLICKEYBYTES;
416 ++num;
417
418 uint32_t increment = ipp_size + crypto_box_PUBLICKEYBYTES;
419 assert(increment == PACKED_NODE_SIZE_IP4 || increment == PACKED_NODE_SIZE_IP6);
367 } 420 }
368 421
369 if (processed_data_len) { 422 if (processed_data_len) {