From 566c9f63bcaa87cbded56e9365b908d2b7e10673 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Mon, 6 Jan 2014 17:59:44 -0500 Subject: [PATCH] onion_announce seems to be working perfectly. Stuff added and fixed. --- auto_tests/onion_test.c | 42 +++++++++++++++++++++++++++++++++++++- toxcore/onion_announce.c | 44 +++++++++++++++++++++++++++++++++++----- toxcore/onion_announce.h | 18 ++++++++++++++-- 3 files changed, 96 insertions(+), 8 deletions(-) diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index 57ac71d8..70bea4a1 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c @@ -11,6 +11,7 @@ #include "../toxcore/onion.h" #include "../toxcore/onion_announce.h" +#include "../toxcore/util.h" #ifdef __WIN32__ #define c_sleep(x) Sleep(1*x) @@ -86,6 +87,28 @@ static int handle_test_3(void *object, IP_Port source, uint8_t *packet, uint32_t return 0; } +static int handled_test_4; +static int handle_test_4(void *object, IP_Port source, uint8_t *packet, uint32_t length) +{ + Onion *onion = object; + + if (length != (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + sizeof("Install gentoo") + crypto_box_MACBYTES)) + return 1; + + uint8_t plain[sizeof("Install gentoo")] = {0}; + int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion->dht->c->self_secret_key, packet + 1, + packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, sizeof("Install gentoo") + crypto_box_MACBYTES, plain); + + if (len == -1) + return 1; + + if (memcmp(plain, "Install gentoo", sizeof("Install gentoo")) != 0) + return 1; + + handled_test_4 = 1; + return 0; +} + START_TEST(test_basic) { IP ip; @@ -145,15 +168,32 @@ START_TEST(test_basic) do_onion(onion2); } + memcpy(onion2_a->entries[1].public_key, onion2->dht->self_public_key, crypto_box_PUBLICKEYBYTES); + onion2_a->entries[1].time = unix_time(); + networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1); send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key, test_3_ping_id, onion1->dht->c->self_public_key); - while (memcmp(onion2_a->entries[ONION_ANNOUNCE_MAX_ENTRIES - 1].public_key, onion1->dht->c->self_public_key, + while (memcmp(onion2_a->entries[ONION_ANNOUNCE_MAX_ENTRIES - 2].public_key, onion1->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) != 0) { do_onion(onion1); do_onion(onion2); c_sleep(50); } + + c_sleep(1000); + Onion *onion3 = new_onion(new_DHT(new_net_crypto(new_networking(ip, 34569)))); + ck_assert_msg((onion3 != NULL), "Onion failed initializing."); + ret = send_data_request(onion3->dht, nodes, onion1->dht->c->self_public_key, (uint8_t *)"Install gentoo", + sizeof("Install gentoo")); + ck_assert_msg(ret == 0, "Failed to create/send onion data_request packet."); + handled_test_4 = 0; + + while (handled_test_4 == 0) { + do_onion(onion1); + do_onion(onion2); + c_sleep(50); + } } END_TEST diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index 8c314b18..a749c2ef 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -35,12 +35,13 @@ #define ANNOUNCE_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + PING_ID_SIZE + crypto_box_MACBYTES) #define ANNOUNCE_RESPONSE_MAX_SIZE (ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES) -#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES + ONION_RETURN_3) +#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) +#define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3) /* Create and send an onion announce request packet. * - * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the data - * with length length will arrive at 3. + * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the announe + * request will be sent to 3. * * public_key and secret_key is the kepair which will be used to encrypt the request. * ping_id is the ping id that will be sent in the request. @@ -71,6 +72,39 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin return send_onion_packet(dht, nodes, packet, sizeof(packet)); } +/* Create and send an onion data request packet. + * + * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the data + * request packet will arrive at 3. (if 3 knows the person with the public_key they should + * send the packet to that person in the form of a response) + * + * public_key is the real public key of the node which we want to send the data of length length to. + * + * return -1 on failure. + * return 0 on success. + */ +int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *data, uint16_t length) +{ + uint8_t packet[DATA_REQUEST_MIN_SIZE + length]; + packet[0] = NET_PACKET_ONION_DATA_REQUEST; + memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); + new_nonce(packet + 1 + crypto_box_PUBLICKEYBYTES); + + uint8_t random_public_key[crypto_box_PUBLICKEYBYTES]; + uint8_t random_secret_key[crypto_box_SECRETKEYBYTES]; + crypto_box_keypair(random_public_key, random_secret_key); + + memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES); + + int len = encrypt_data(public_key, random_secret_key, packet + 1 + crypto_box_PUBLICKEYBYTES, + data, length, packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); + + if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(packet)) + return -1; + + return send_onion_packet(dht, nodes, packet, sizeof(packet)); +} + /* Generate a ping_id and put it in ping_id */ static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, uint8_t *public_key, IP_Port ret_ip_port, uint8_t *ping_id) @@ -95,7 +129,7 @@ static int in_entries(Onion_Announce *onion_a, uint8_t *public_key) for (i = 0; i < ONION_ANNOUNCE_MAX_ENTRIES; ++i) { if (!is_timeout(onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT) - && memcpy(onion_a->entries[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) + && memcmp(onion_a->entries[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) return i; } @@ -236,7 +270,7 @@ static int handle_data_request(void *object, IP_Port source, uint8_t *packet, ui { Onion_Announce *onion_a = object; - if (length <= DATA_REQUEST_MIN_SIZE) + if (length <= DATA_REQUEST_MIN_SIZE_RECV) return 1; if (length >= MAX_DATA_SIZE) diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 66a8702d..29cbaf58 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -45,8 +45,8 @@ typedef struct { /* Create and send an onion announce request packet. * - * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the data - * with length length will arrive at 3. + * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the announe + * request will be sent to 3. * * public_key and secret_key is the kepair which will be used to encrypt the request. * ping_id is the ping id that will be sent in the request. @@ -58,6 +58,20 @@ typedef struct { int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id); +/* Create and send an onion data request packet. + * + * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the data + * request packet will arrive at 3. (if 3 knows the person with the public_key they should + * send the packet to that person in the form of a response) + * + * public_key is the real public key of the node which we want to send the data of length length to. + * + * return -1 on failure. + * return 0 on success. + */ +int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *data, uint16_t length); + + Onion_Announce *new_onion_announce(DHT *dht); void kill_onion_announce(Onion_Announce *onion_a);