diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index dff05135..f5c38eea 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -29,16 +29,14 @@ #define PING_ID_TIMEOUT 20 -#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES) -#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3) +#define ANNOUNCE_REQUEST_SIZE_RECV (ONION_ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3) #define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE #define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3) -/* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE). - * - * path is the path the request will take before it is sent to dest. +/* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_ANNOUNCE_REQUEST_SIZE). * + * dest_client_id is the public key of the node the packet will be sent to. * 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. * client_id is the client id of the node we are searching for. @@ -49,10 +47,13 @@ * return -1 on failure. * return packet length on success. */ -int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, Node_format dest, +int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data) { + if (max_packet_length < ONION_ANNOUNCE_REQUEST_SIZE) + return -1; + uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; memcpy(plain, ping_id, ONION_PING_ID_SIZE); @@ -60,26 +61,22 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const O memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, data_public_key, crypto_box_PUBLICKEYBYTES); memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, &sendback_data, sizeof(sendback_data)); - uint8_t temp[ANNOUNCE_REQUEST_SIZE]; - temp[0] = NET_PACKET_ANNOUNCE_REQUEST; - random_nonce(temp + 1); - int len = encrypt_data(dest.client_id, secret_key, temp + 1, plain, sizeof(plain), - temp + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); + packet[0] = NET_PACKET_ANNOUNCE_REQUEST; + random_nonce(packet + 1); - if ((uint32_t)len + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES != ANNOUNCE_REQUEST_SIZE) + int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, sizeof(plain), + packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); + + if ((uint32_t)len + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES != ONION_ANNOUNCE_REQUEST_SIZE) return -1; - memcpy(temp + 1 + crypto_box_NONCEBYTES, public_key, crypto_box_PUBLICKEYBYTES); + memcpy(packet + 1 + crypto_box_NONCEBYTES, public_key, crypto_box_PUBLICKEYBYTES); - return create_onion_packet(packet, max_packet_length, path, dest.ip_port, temp, sizeof(temp)); + return ONION_ANNOUNCE_REQUEST_SIZE; } /* Create an onion data request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE). - * - * path is the path the request will take before it is sent to dest. - * (if dest 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. * encrypt_public_key is the public key used to encrypt the data packet. @@ -89,31 +86,33 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const O * return -1 on failure. * return 0 on success. */ -int create_data_request(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest, - const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, - uint16_t length) +int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, + const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length) { + if (DATA_REQUEST_MIN_SIZE + length > max_packet_length) + return -1; + if ((unsigned int)DATA_REQUEST_MIN_SIZE + length > ONION_MAX_DATA_SIZE) return -1; - uint8_t temp[DATA_REQUEST_MIN_SIZE + length]; - temp[0] = NET_PACKET_ONION_DATA_REQUEST; - memcpy(temp + 1, public_key, crypto_box_PUBLICKEYBYTES); - memcpy(temp + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); + packet[0] = NET_PACKET_ONION_DATA_REQUEST; + memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); + memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); 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(temp + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES); + memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES); - int len = encrypt_data(encrypt_public_key, random_secret_key, temp + 1 + crypto_box_PUBLICKEYBYTES, - data, length, temp + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); + int len = encrypt_data(encrypt_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(temp)) + if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + + (uint32_t)len != DATA_REQUEST_MIN_SIZE + length) return -1; - return create_onion_packet(packet, max_packet_length, path, dest, temp, sizeof(temp)); + return DATA_REQUEST_MIN_SIZE + length; } /* Create and send an onion announce request packet. @@ -134,10 +133,16 @@ int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_for const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data) { - uint8_t packet[ONION_MAX_PACKET_SIZE]; - int len = create_announce_request(packet, sizeof(packet), path, dest, public_key, secret_key, ping_id, client_id, + uint8_t request[ONION_ANNOUNCE_REQUEST_SIZE]; + int len = create_announce_request(request, sizeof(request), dest.client_id, public_key, secret_key, ping_id, client_id, data_public_key, sendback_data); + if (len != sizeof(request)) + return -1; + + uint8_t packet[ONION_MAX_PACKET_SIZE]; + len = create_onion_packet(packet, sizeof(packet), path, dest.ip_port, request, sizeof(request)); + if (len == -1) return -1; @@ -164,12 +169,15 @@ int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_for int send_data_request(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length) { - uint8_t packet[ONION_MAX_PACKET_SIZE]; - int len = create_data_request(packet, sizeof(packet), path, dest, public_key, encrypt_public_key, nonce, data, length); + uint8_t request[ONION_MAX_DATA_SIZE]; + int len = create_data_request(request, sizeof(request), public_key, encrypt_public_key, nonce, data, length); if (len == -1) return -1; + uint8_t packet[ONION_MAX_PACKET_SIZE]; + len = create_onion_packet(packet, sizeof(packet), path, dest, request, len); + if (sendpacket(net, path->ip_port1, packet, len) != len) return -1; diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index d31355e5..f2ba3715 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -31,6 +31,8 @@ #define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (sizeof(uint64_t)) +#define ONION_ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES) + #define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + 1 + ONION_PING_ID_SIZE + crypto_box_MACBYTES) #define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES) @@ -61,10 +63,9 @@ typedef struct { Shared_Keys shared_keys_recv; } Onion_Announce; -/* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE). - * - * path is the path the request will take before it is sent to dest. +/* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_ANNOUNCE_REQUEST_SIZE). * + * dest_client_id is the public key of the node the packet will be sent to. * 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. * client_id is the client id of the node we are searching for. @@ -75,15 +76,11 @@ typedef struct { * return -1 on failure. * return packet length on success. */ -int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, Node_format dest, +int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data); /* Create an onion data request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE). - * - * path is the path the request will take before it is sent to dest. - * (if dest 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. * encrypt_public_key is the public key used to encrypt the data packet. @@ -93,9 +90,8 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const O * return -1 on failure. * return 0 on success. */ -int create_data_request(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest, - const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, - uint16_t length); +int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, + const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length); /* Create and send an onion announce request packet. * diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 018526f4..5bffb114 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -172,14 +172,22 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, IP_Port s * return -1 on failure. * return 0 on success. */ -static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, IP_Port ip_port, const uint8_t *data, uint32_t length) +static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Path *path, IP_Port dest, + const uint8_t *data, uint32_t length) { - if (ip_port.ip.family == AF_INET || ip_port.ip.family == AF_INET6) { - if ((uint32_t)sendpacket(onion_c->net, ip_port, data, length) != length) + if (path->ip_port1.ip.family == AF_INET || path->ip_port1.ip.family == AF_INET6) { + uint8_t packet[ONION_MAX_PACKET_SIZE]; + int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length); + + if (len == -1) + return -1; + + if ((uint32_t)sendpacket(onion_c->net, path->ip_port1, packet, len) != len) return -1; return 0; } else { + return -1; //TODO: TCP } } @@ -262,35 +270,30 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_ Node_format dest_node; dest_node.ip_port = dest; memcpy(dest_node.client_id, dest_pubkey, crypto_box_PUBLICKEYBYTES); + uint8_t request[ONION_ANNOUNCE_REQUEST_SIZE]; + int len; if (num == 0) { if (random_path(onion_c, &onion_c->onion_paths, pathnum, &path) == -1) return -1; - uint8_t packet[ONION_MAX_PACKET_SIZE]; - int len = create_announce_request(packet, sizeof(packet), &path, dest_node, onion_c->c->self_public_key, - onion_c->c->self_secret_key, ping_id, onion_c->c->self_public_key, onion_c->temp_public_key, sendback); + len = create_announce_request(request, sizeof(request), dest_pubkey, onion_c->c->self_public_key, + onion_c->c->self_secret_key, ping_id, onion_c->c->self_public_key, onion_c->temp_public_key, sendback); - if (len == -1) { - return -1; - } - - return send_onion_packet_tcp_udp(onion_c, path.ip_port1, packet, len); } else { if (random_path(onion_c, &onion_c->friends_list[num - 1].onion_paths, pathnum, &path) == -1) return -1; - uint8_t packet[ONION_MAX_PACKET_SIZE]; - int len = create_announce_request(packet, sizeof(packet), &path, dest_node, - onion_c->friends_list[num - 1].temp_public_key, onion_c->friends_list[num - 1].temp_secret_key, ping_id, - onion_c->friends_list[num - 1].real_client_id, zero_ping_id, sendback); - - if (len == -1) { - return -1; - } - - return send_onion_packet_tcp_udp(onion_c, path.ip_port1, packet, len); + len = create_announce_request(request, sizeof(request), dest_pubkey, onion_c->friends_list[num - 1].temp_public_key, + onion_c->friends_list[num - 1].temp_secret_key, ping_id, onion_c->friends_list[num - 1].real_client_id, zero_ping_id, + sendback); } + + if (len == -1) { + return -1; + } + + return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len); } static uint8_t cmp_public_key[crypto_box_PUBLICKEYBYTES]; @@ -657,14 +660,13 @@ int send_onion_data(const Onion_Client *onion_c, int friend_num, const uint8_t * for (i = 0; i < num_good; ++i) { uint8_t o_packet[ONION_MAX_PACKET_SIZE]; - len = create_data_request(o_packet, sizeof(o_packet), &path[i], list_nodes[good_nodes[i]].ip_port, - onion_c->friends_list[friend_num].real_client_id, list_nodes[good_nodes[i]].data_public_key, nonce, packet, - sizeof(packet)); + len = create_data_request(o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_client_id, + list_nodes[good_nodes[i]].data_public_key, nonce, packet, sizeof(packet)); if (len == -1) continue; - if (send_onion_packet_tcp_udp(onion_c, path[i].ip_port1, o_packet, len) == 0) + if (send_onion_packet_tcp_udp(onion_c, &path[i], list_nodes[good_nodes[i]].ip_port, o_packet, len) == 0) ++good; }