mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Preparation work to make onion packets go through TCP.
This commit is contained in:
parent
881ccced56
commit
a82cbfff6a
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user