diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index a5175566..745ca4ac 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c @@ -26,13 +26,8 @@ static int handle_test_1(void *object, IP_Port source, uint8_t *packet, uint32_t if (memcmp(packet, "Install Gentoo", sizeof("Install Gentoo")) != 0) return 1; - uint8_t data[1024]; - data[0] = NET_PACKET_ONION_RECV_3; - memcpy(data + 1, packet + sizeof("Install Gentoo"), length - sizeof("Install Gentoo")); - memcpy(data + 1 + length - sizeof("Install Gentoo"), "install gentoo", sizeof("install gentoo")); - uint32_t data_len = 1 + length; - - if ((uint32_t)sendpacket(onion->net, source, data, data_len) != data_len) + if (send_onion_response(onion->net, source, "install gentoo", sizeof("install gentoo"), + packet + sizeof("Install Gentoo")) == -1) return 1; handled_test_1 = 1; diff --git a/toxcore/onion.c b/toxcore/onion.c index b7a19716..17443fe0 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -95,6 +95,23 @@ int send_onion_packet(Onion *onion, Node_format *nodes, uint8_t *data, uint32_t return 0; } +/* Create and send a onion response sent initially to dest with. + * + * return -1 on failure. + * return 0 on success. + */ +int send_onion_response(Networking_Core *net, IP_Port dest, uint8_t *data, uint32_t length, uint8_t *ret) +{ + uint8_t packet[1 + RETURN_3 + length]; + packet[0] = NET_PACKET_ONION_RECV_3; + memcpy(packet + 1, ret, RETURN_3); + memcpy(packet + 1 + RETURN_3, data, length); + + if ((uint32_t)sendpacket(net, dest, packet, sizeof(packet)) != sizeof(packet)) + return -1; + + return 0; +} static int handle_send_initial(void *object, IP_Port source, uint8_t *packet, uint32_t length) { diff --git a/toxcore/onion.h b/toxcore/onion.h index 8a972e17..84aa72e1 100644 --- a/toxcore/onion.h +++ b/toxcore/onion.h @@ -48,6 +48,13 @@ typedef struct { */ int send_onion_packet(Onion *onion, Node_format *nodes, uint8_t *data, uint32_t length); +/* Create and send a onion response sent initially to dest with. + * + * return -1 on failure. + * return 0 on success. + */ +int send_onion_response(Networking_Core *net, IP_Port dest, uint8_t *data, uint32_t length, uint8_t *ret); + Onion *new_onion(DHT *dht); void kill_onion(Onion *onion); diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index b6f78430..a2d6760e 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -31,8 +31,8 @@ #define PING_ID_TIMEOUT 10 #define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES + ONION_RETURN_3) - -uint8_t ping_id_zero[PING_ID_SIZE]; +#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) /* 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, uint8_t *ret, @@ -101,6 +101,7 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet stored = in_entries(onion_a, plain + PING_ID_SIZE); } + /*Respond with a announce response packet*/ Node_format nodes_list[MAX_SENT_NODES]; uint32_t num_nodes = get_close_nodes(onion_a->dht, plain + PING_ID_SIZE, nodes_list, source.ip.family, LAN_ip(source.ip) == 0, 1); @@ -108,6 +109,28 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet uint8_t nonce[crypto_box_NONCEBYTES]; new_nonce(nonce); + uint8_t pl[PING_ID_SIZE + sizeof(nodes_list)] = {0}; + + if (!stored) { + memcpy(pl, ping_id2, PING_ID_SIZE); + } + + memcpy(pl + PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format)); + + uint8_t data[ANNOUNCE_RESPONSE_MAX_SIZE]; + len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl, + PING_ID_SIZE + num_nodes * sizeof(Node_format), data + 1 + crypto_box_NONCEBYTES); + + if ((uint32_t)len != PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES) + return 1; + + data[0] = NET_PACKET_ANNOUNCE_RESPONSE; + memcpy(data + 1, nonce, crypto_box_NONCEBYTES); + + if (send_onion_response(onion_a->net, source, data, 1 + crypto_box_NONCEBYTES + len, + packet + (ANNOUNCE_REQUEST_SIZE - ONION_RETURN_3)) == -1) + return 1; + return 0; } diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 2b36d35c..d06865c8 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -28,6 +28,7 @@ typedef struct { Networking_Core *net; struct { uint8_t public_key[crypto_box_PUBLICKEYBYTES]; + IP_Port first; uint8_t ret[ONION_RETURN_3]; } entries[ONION_ANNOUNCE_MAX_ENTRIES]; /* This is crypto_secretbox_KEYBYTES long just so we can use new_symmetric_key() to fill it */