Preparation work to make onion packets go through TCP.

This commit is contained in:
irungentoo 2014-06-18 19:44:49 -04:00
parent 881ccced56
commit a82cbfff6a
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
6 changed files with 214 additions and 51 deletions

View File

@ -933,7 +933,7 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
LOGGER_WARNING("Allocation failed!");
return NULL;
}
_call->call_idx = _call_idx;
_call->type_peer = calloc ( sizeof ( MSICallType ), peers );
@ -1028,7 +1028,7 @@ void *handle_timeout ( void *arg )
if (_call) {
LOGGER_DEBUG("[Call: %s] Request timed out!", _call->id);
invoke_callback(_call->call_idx, MSI_OnRequestTimeout);
}

View File

@ -84,17 +84,19 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes)
return 0;
}
/* Create and send a onion packet.
/* Create a onion packet.
*
* Use Onion_Path path to send data of length to dest.
* Use Onion_Path path to create packet for data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
* packet should be at least ONION_MAX_PACKET_SIZE big.
*
* return -1 on failure.
* return 0 on success.
* return length of created packet on success.
*/
int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length)
int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, Onion_Path *path, IP_Port dest, uint8_t *data,
uint32_t length)
{
if (1 + length + SEND_1 > ONION_MAX_PACKET_SIZE || length == 0)
if (1 + length + SEND_1 > max_packet_length || length == 0)
return -1;
to_net_family(&dest.ip);
@ -126,7 +128,6 @@ int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint
if ((uint32_t)len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES)
return -1;
uint8_t packet[1 + length + SEND_1];
packet[0] = NET_PACKET_ONION_SEND_INITIAL;
memcpy(packet + 1, nonce, crypto_box_NONCEBYTES);
memcpy(packet + 1 + crypto_box_NONCEBYTES, path->public_key1, crypto_box_PUBLICKEYBYTES);
@ -137,7 +138,26 @@ int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint
if ((uint32_t)len != SIZE_IPPORT + SEND_BASE * 2 + length + crypto_box_MACBYTES)
return -1;
if ((uint32_t)sendpacket(net, path->ip_port1, packet, sizeof(packet)) != sizeof(packet))
return 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + len;
}
/* Create and send a onion packet.
*
* Use Onion_Path path to send data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
*
* return -1 on failure.
* return 0 on success.
*/
int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length)
{
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 (sendpacket(net, path->ip_port1, packet, len) != len)
return -1;
return 0;

View File

@ -78,6 +78,18 @@ typedef struct {
*/
int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes);
/* Create a onion packet.
*
* Use Onion_Path path to create packet for data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
* packet should be at least ONION_MAX_PACKET_SIZE big.
*
* return -1 on failure.
* return length of created packet on success.
*/
int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, Onion_Path *path, IP_Port dest, uint8_t *data,
uint32_t length);
/* Create and send a onion packet.
*
* Use Onion_Path path to send data of length to dest.

View File

@ -35,6 +35,86 @@
#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.
*
* 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.
* data_public_key is the public key we want others to encrypt their data packets with.
* sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
* receive back in the response.
*
* return -1 on failure.
* return packet length on success.
*/
int create_announce_request(uint8_t *packet, uint16_t max_packet_length, Onion_Path *path, Node_format dest,
uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key,
uint64_t sendback_data)
{
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);
memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES);
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);
if ((uint32_t)len + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES != ANNOUNCE_REQUEST_SIZE)
return -1;
memcpy(temp + 1 + crypto_box_NONCEBYTES, public_key, crypto_box_PUBLICKEYBYTES);
return create_onion_packet(packet, max_packet_length, path, dest.ip_port, temp, sizeof(temp));
}
/* 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.
*
* nonce is the nonce to encrypt this packet with
*
* return -1 on failure.
* return 0 on success.
*/
int create_data_request(uint8_t *packet, uint16_t max_packet_length, Onion_Path *path, IP_Port dest,
uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length)
{
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);
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);
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);
if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(temp))
return -1;
return create_onion_packet(packet, max_packet_length, path, dest, temp, sizeof(temp));
}
/* Create and send an onion announce request packet.
*
* path is the path the request will take before it is sent to dest.
@ -52,26 +132,17 @@
int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key,
uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key, uint64_t sendback_data)
{
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);
memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES);
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 packet[ANNOUNCE_REQUEST_SIZE];
packet[0] = NET_PACKET_ANNOUNCE_REQUEST;
random_nonce(packet + 1);
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,
data_public_key, sendback_data);
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 != ANNOUNCE_REQUEST_SIZE)
if (len == -1)
return -1;
memcpy(packet + 1 + crypto_box_NONCEBYTES, public_key, crypto_box_PUBLICKEYBYTES);
if (sendpacket(net, path->ip_port1, packet, len) != len)
return -1;
return send_onion_packet(net, path, dest.ip_port, packet, sizeof(packet));
return 0;
}
/* Create and send an onion data request packet.
@ -91,27 +162,16 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de
int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key,
uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length)
{
if ((unsigned int)DATA_REQUEST_MIN_SIZE + length > ONION_MAX_DATA_SIZE)
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);
if (len == -1)
return -1;
uint8_t packet[DATA_REQUEST_MIN_SIZE + length];
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(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, 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(packet))
if (sendpacket(net, path->ip_port1, packet, len) != len)
return -1;
return send_onion_packet(net, path, dest, packet, sizeof(packet));
return 0;
}
/* Generate a ping_id and put it in ping_id */

View File

@ -61,6 +61,41 @@ 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.
*
* 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.
* data_public_key is the public key we want others to encrypt their data packets with.
* sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
* receive back in the response.
*
* return -1 on failure.
* return packet length on success.
*/
int create_announce_request(uint8_t *packet, uint16_t max_packet_length, Onion_Path *path, Node_format dest,
uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, 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.
*
* nonce is the nonce to encrypt this packet with
*
* return -1 on failure.
* return 0 on success.
*/
int create_data_request(uint8_t *packet, uint16_t max_packet_length, Onion_Path *path, IP_Port dest,
uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length);
/* Create and send an onion announce request packet.
*
* path is the path the request will take before it is sent to dest.

View File

@ -125,6 +125,23 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, IP_Port s
return ~0;
}
/* Function to send onion packet via TCP and UDP.
*
* return -1 on failure.
* return 0 on success.
*/
static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, IP_Port ip_port, 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)
return -1;
return 0;
} else {
return -1; //TODO: TCP
}
}
/* Creates a sendback for use in an announce request.
*
* num is 0 if we used our secret public key for the announce
@ -207,16 +224,29 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
if (random_path(onion_c->dht, &onion_c->onion_paths, pathnum, &path) == -1)
return -1;
return send_announce_request(onion_c->net, &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);
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);
if (len == -1) {
return -1;
}
return send_onion_packet_tcp_udp(onion_c, path.ip_port1, packet, len);
} else {
if (random_path(onion_c->dht, &onion_c->friends_list[num - 1].onion_paths, pathnum, &path) == -1)
return -1;
return send_announce_request(onion_c->net, &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);
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);
}
}
@ -578,9 +608,15 @@ int send_onion_data(const Onion_Client *onion_c, int friend_num, const uint8_t *
uint32_t good = 0;
for (i = 0; i < num_good; ++i) {
if (send_data_request(onion_c->net, &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)) == 0)
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));
if (len == -1)
continue;
if (send_onion_packet_tcp_udp(onion_c, path[i].ip_port1, o_packet, len) == 0)
++good;
}