mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Merge branch 'onion'
This commit is contained in:
commit
aff6b112c0
|
@ -73,15 +73,15 @@ static int handle_test_3(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
{
|
||||
Onion *onion = object;
|
||||
|
||||
if (length != (1 + crypto_box_NONCEBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_hash_sha256_BYTES +
|
||||
if (length != (1 + crypto_box_NONCEBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + 1 + crypto_hash_sha256_BYTES +
|
||||
crypto_box_MACBYTES))
|
||||
return 1;
|
||||
|
||||
uint8_t plain[crypto_hash_sha256_BYTES];
|
||||
uint8_t plain[1 + crypto_hash_sha256_BYTES];
|
||||
//print_client_id(packet, length);
|
||||
int len = decrypt_data(test_3_pub_key, onion->dht->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
|
||||
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES,
|
||||
crypto_hash_sha256_BYTES + crypto_box_MACBYTES, plain);
|
||||
1 + crypto_hash_sha256_BYTES + crypto_box_MACBYTES, plain);
|
||||
|
||||
if (len == -1)
|
||||
return 1;
|
||||
|
@ -90,7 +90,7 @@ static int handle_test_3(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0)
|
||||
return 1;
|
||||
|
||||
memcpy(test_3_ping_id, plain, crypto_hash_sha256_BYTES);
|
||||
memcpy(test_3_ping_id, plain + 1, crypto_hash_sha256_BYTES);
|
||||
//print_client_id(test_3_ping_id, sizeof(test_3_ping_id));
|
||||
handled_test_3 = 1;
|
||||
return 0;
|
||||
|
@ -174,7 +174,7 @@ START_TEST(test_basic)
|
|||
randombytes(sb_data, sizeof(sb_data));
|
||||
memcpy(test_3_pub_key, nodes[3].client_id, crypto_box_PUBLICKEYBYTES);
|
||||
ret = send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key,
|
||||
zeroes, onion1->dht->c->self_public_key, sb_data);
|
||||
zeroes, onion1->dht->c->self_public_key, onion1->dht->c->self_public_key, sb_data);
|
||||
ck_assert_msg(ret == 0, "Failed to create/send onion announce_request packet.");
|
||||
handled_test_3 = 0;
|
||||
|
||||
|
@ -188,7 +188,7 @@ START_TEST(test_basic)
|
|||
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, sb_data);
|
||||
test_3_ping_id, onion1->dht->c->self_public_key, onion1->dht->c->self_public_key, sb_data);
|
||||
|
||||
while (memcmp(onion2_a->entries[ONION_ANNOUNCE_MAX_ENTRIES - 2].public_key, onion1->dht->c->self_public_key,
|
||||
crypto_box_PUBLICKEYBYTES) != 0) {
|
||||
|
@ -202,8 +202,8 @@ START_TEST(test_basic)
|
|||
ck_assert_msg((onion3 != NULL), "Onion failed initializing.");
|
||||
|
||||
new_nonce(nonce);
|
||||
ret = send_data_request(onion3->dht, nodes, onion1->dht->c->self_public_key, nonce, (uint8_t *)"Install gentoo",
|
||||
sizeof("Install gentoo"));
|
||||
ret = send_data_request(onion3->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_public_key,
|
||||
nonce, (uint8_t *)"Install gentoo", sizeof("Install gentoo"));
|
||||
ck_assert_msg(ret == 0, "Failed to create/send onion data_request packet.");
|
||||
handled_test_4 = 0;
|
||||
|
||||
|
|
|
@ -23,8 +23,9 @@ void accept_friend_request(uint8_t *public_key, uint8_t *data, uint16_t length,
|
|||
{
|
||||
Tox *t = userdata;
|
||||
|
||||
if (length == 7 && memcmp("Gentoo", data, 7) == 0)
|
||||
if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
|
||||
tox_add_friend_norequest(t, public_key);
|
||||
}
|
||||
}
|
||||
uint32_t messages_received;
|
||||
|
||||
|
@ -58,14 +59,22 @@ START_TEST(test_few_clients)
|
|||
tox_callback_friend_request(tox2, accept_friend_request, tox2);
|
||||
uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(tox2, address);
|
||||
int test = tox_add_friend(tox3, address, "Gentoo", 7);
|
||||
int test = tox_add_friend(tox3, address, (uint8_t *)"Gentoo", 7);
|
||||
ck_assert_msg(test == 0, "Failed to add friend error code: %i", test);
|
||||
|
||||
uint8_t off = 1;
|
||||
|
||||
while (1) {
|
||||
tox_do(tox1);
|
||||
tox_do(tox2);
|
||||
tox_do(tox3);
|
||||
|
||||
if (tox_isconnected(tox1) && tox_isconnected(tox2) && tox_isconnected(tox3) && off) {
|
||||
printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time);
|
||||
off = 0;
|
||||
}
|
||||
|
||||
|
||||
if (tox_get_friend_connection_status(tox2, 0) == 1 && tox_get_friend_connection_status(tox3, 0) == 1)
|
||||
break;
|
||||
|
||||
|
@ -75,7 +84,7 @@ START_TEST(test_few_clients)
|
|||
printf("tox clients connected\n");
|
||||
uint32_t to_compare = 974536;
|
||||
tox_callback_friend_message(tox3, print_message, &to_compare);
|
||||
tox_send_message(tox2, 0, "Install Gentoo", sizeof("Install Gentoo"));
|
||||
tox_send_message(tox2, 0, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
|
||||
|
||||
while (1) {
|
||||
messages_received = 0;
|
||||
|
@ -92,7 +101,7 @@ START_TEST(test_few_clients)
|
|||
printf("tox clients messaging succeeded\n");
|
||||
|
||||
tox_callback_name_change(tox3, print_nickchange, &to_compare);
|
||||
tox_set_name(tox2, "Gentoo", sizeof("Gentoo"));
|
||||
tox_set_name(tox2, (uint8_t *)"Gentoo", sizeof("Gentoo"));
|
||||
|
||||
while (1) {
|
||||
name_changes = 0;
|
||||
|
@ -113,8 +122,8 @@ START_TEST(test_few_clients)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
#define NUM_TOXES 66
|
||||
#define NUM_FRIENDS 20
|
||||
#define NUM_TOXES 33
|
||||
#define NUM_FRIENDS 10
|
||||
|
||||
START_TEST(test_many_clients)
|
||||
{
|
||||
|
@ -140,7 +149,7 @@ loop_top:
|
|||
pairs[i].tox1 = rand() % NUM_TOXES;
|
||||
pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES;
|
||||
tox_get_address(toxes[pairs[i].tox1], address);
|
||||
int test = tox_add_friend(toxes[pairs[i].tox2], address, "Gentoo", 7);
|
||||
int test = tox_add_friend(toxes[pairs[i].tox2], address, (uint8_t *)"Gentoo", 7);
|
||||
|
||||
if (test == TOX_FAERR_ALREADYSENT) {
|
||||
goto loop_top;
|
||||
|
|
|
@ -97,7 +97,8 @@ Data sent to Node D:
|
|||
|
||||
announce request packet:
|
||||
[uint8_t packet id (131)][nonce][our real long term public key or a temporary one (see next)]
|
||||
encrypted (with our real long term private key if we want to announce ourselves, a temporary one if we are searching for friends) and the pub key of Node D and the nonce:[[(32 bytes) ping_id][client id we are searching for][data to send back in response(fixed size)]]
|
||||
encrypted (with our real long term private key if we want to announce ourselves, a temporary one if we are searching for friends) and the pub key of Node D and the nonce:
|
||||
[[(32 bytes) ping_id][client id we are searching for][public key that we want those sending back data packets to use.][data to send back in response(fixed size)]]
|
||||
|
||||
(if the ping id is zero, respond with a announce response packet)
|
||||
(If the ping id matches the one the node sent in the announce response and the public key matches the one being searched for,
|
||||
|
@ -105,7 +106,7 @@ add the part used to send data to our list (if the list is full make it replace
|
|||
|
||||
data to route request packet:
|
||||
[uint8_t packet id (133)][public key of destination node][nonce][temporary just generated public key]
|
||||
encrypted with that temporary private key and the nonce and the real public key of the destination node:[data]
|
||||
encrypted with that temporary private key and the nonce and the public key from the announce response packet of the destination node:[data]
|
||||
(if Node D contains the ret data for the node, it sends the stuff in this packet as a data to route response packet to the right node)
|
||||
|
||||
The data in the previous packet is in format: [real public key of sender]
|
||||
|
@ -114,12 +115,13 @@ encrypted with real private key of the sender, the nonce in the data packet and
|
|||
Data sent to us:
|
||||
announce response packet:
|
||||
[uint8_t packet id (132)][data to send back in response(fixed size)][nonce]
|
||||
encrypted with the DHT private key of Node D, the public key in the request and the nonce:[[(32 bytes) ping_id][Node_Format * (maximum of 8)]]
|
||||
(if the ping id is zero, it means the information to reach the client id we are searching for is stored on this node)
|
||||
encrypted with the DHT private key of Node D, the public key in the request and the nonce:[[uint8_t is_stored]
|
||||
[(32 bytes) ping_id if is_stored is 0, public key that must be used to send data packets if is_stored is not 0][Node_Format * (maximum of 8)]]
|
||||
(if the is_stored is not 0, it means the information to reach the client id we are searching for is stored on this node)
|
||||
|
||||
data to route response packet:
|
||||
[uint8_t packet id (134)][nonce][temporary just generated public key]
|
||||
encrypted with that temporary private key and the nonce and the real public key of the destination node:[data]
|
||||
encrypted with that temporary private key, the nonce and the public key from the announce response packet of the destination node:[data]
|
||||
|
||||
|
||||
Onion packet (response):
|
||||
|
@ -145,3 +147,11 @@ encrypted with temp symmetric key of Node A: [IP_Port (of us)][data to send back
|
|||
(sent from node A to us):
|
||||
|
||||
[data to send back]
|
||||
|
||||
|
||||
Data packets:
|
||||
|
||||
To tell our friend what our DHT public key is so that he can connect to us we send a data packet with id 156 and
|
||||
the data being:[uint64_t (in network byte order) no_replay, the packet will only be accepted if this number is bigger than the last one recieved]
|
||||
[our dht public key][Node_Format * (maximum of 8) nodes closest to us so that the friend can find us faster]
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ case 1: Alice adds Bobs public key and bob waits for Alice to attempt to connect
|
|||
case 2: Bob and Alice add their respective public keys to their friends list at the same time.
|
||||
|
||||
case 1:
|
||||
Alice sends a crypto request packet to bob with the encrypted part containing the friends request like so:
|
||||
Alice sends a onion data (see: Prevent_tracking.txt) packet to bob with the encrypted part containing the friends request like so:
|
||||
```
|
||||
[char with a value of 32][nospam number (4 bytes)][Message]
|
||||
```
|
||||
|
|
|
@ -102,9 +102,19 @@ int main(int argc, char *argv[])
|
|||
ip_init(&ip, ipv6enabled);
|
||||
|
||||
DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT)));
|
||||
Onion *onion = new_onion(dht);
|
||||
Onion_Announce *onion_a = new_onion_announce(dht);
|
||||
|
||||
if (!(onion && onion_a)) {
|
||||
printf("Something failed to initialize.\n");
|
||||
exit(1);
|
||||
}
|
||||
perror("Initialization");
|
||||
|
||||
manage_keys(dht);
|
||||
/* We want our DHT public key to be the same as our internal one since this is a bootstrap server */
|
||||
memcpy(dht->self_public_key, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
memcpy(dht->self_secret_key, dht->c->self_secret_key, crypto_box_SECRETKEYBYTES);
|
||||
printf("Public key: ");
|
||||
uint32_t i;
|
||||
|
||||
|
@ -152,7 +162,7 @@ int main(int argc, char *argv[])
|
|||
do_DHT(dht);
|
||||
|
||||
if (is_timeout(last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) {
|
||||
send_LANdiscovery(htons(PORT), dht->c);
|
||||
send_LANdiscovery(htons(PORT), dht);
|
||||
last_LANdiscovery = unix_time();
|
||||
}
|
||||
|
||||
|
|
133
toxcore/DHT.c
133
toxcore/DHT.c
|
@ -28,7 +28,11 @@
|
|||
#endif
|
||||
|
||||
#include "DHT.h"
|
||||
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
#include "assoc.h"
|
||||
#endif
|
||||
|
||||
#include "ping.h"
|
||||
|
||||
#include "network.h"
|
||||
|
@ -285,7 +289,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
|
|||
*/
|
||||
sa_family_t ip_treat_as_family = client_ip->family;
|
||||
|
||||
if ((dht->c->lossless_udp->net->family == AF_INET6) &&
|
||||
if ((dht->net->family == AF_INET6) &&
|
||||
(client_ip->family == AF_INET6)) {
|
||||
/* socket is AF_INET6, address claims AF_INET6:
|
||||
* check for embedded IPv4-in-IPv6 (shouldn't happen anymore,
|
||||
|
@ -304,7 +308,8 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
|
|||
if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN)
|
||||
continue;
|
||||
|
||||
if (want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK && !id_equal(client_id, client->client_id))
|
||||
if (LAN_ip(ipptp->ip_port.ip) != 0 && want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK
|
||||
&& !id_equal(client_id, client->client_id))
|
||||
continue;
|
||||
|
||||
if (num_nodes < MAX_SENT_NODES) {
|
||||
|
@ -355,10 +360,16 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n
|
|||
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
|
||||
dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_good);
|
||||
|
||||
/*TODO uncomment this when hardening is added to close friend clients
|
||||
for (i = 0; i < dht->num_friends; ++i)
|
||||
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
|
||||
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
|
||||
&num_nodes, is_LAN, want_good);
|
||||
*/
|
||||
for (i = 0; i < dht->num_friends; ++i)
|
||||
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
|
||||
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
|
||||
&num_nodes, is_LAN, 0);
|
||||
|
||||
return num_nodes;
|
||||
}
|
||||
|
@ -366,9 +377,13 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n
|
|||
int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN,
|
||||
uint8_t want_good)
|
||||
{
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
|
||||
if (!dht->assoc)
|
||||
#endif
|
||||
return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good);
|
||||
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
Client_data *result[MAX_SENT_NODES];
|
||||
|
||||
Assoc_close_entries request;
|
||||
|
@ -420,6 +435,7 @@ int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_fa
|
|||
}
|
||||
|
||||
return num_returned;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Replace first bad (or empty) node with this one.
|
||||
|
@ -566,7 +582,7 @@ static int replace_good( Client_data *list,
|
|||
if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6))
|
||||
return 1;
|
||||
|
||||
sort_list(list, length, comp_client_id);
|
||||
//sort_list(list, length, comp_client_id);
|
||||
|
||||
int8_t replace = -1;
|
||||
|
||||
|
@ -636,10 +652,10 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
|
|||
if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
|
||||
if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
|
||||
if (replace_possible_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port,
|
||||
dht->c->self_public_key)) {
|
||||
dht->self_public_key)) {
|
||||
/* If we can't replace bad nodes we try replacing good ones. */
|
||||
if (!replace_good(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port,
|
||||
dht->c->self_public_key))
|
||||
dht->self_public_key))
|
||||
used++;
|
||||
} else
|
||||
used++;
|
||||
|
@ -669,6 +685,8 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
|
|||
used++;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
|
||||
if (dht->assoc) {
|
||||
IPPTs ippts;
|
||||
|
||||
|
@ -678,6 +696,7 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
|
|||
Assoc_add_entry(dht->assoc, client_id, &ippts, NULL, used ? 1 : 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
return used;
|
||||
}
|
||||
|
||||
|
@ -697,7 +716,7 @@ static int returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8
|
|||
ip_port.ip.ip4.uint32 = ip_port.ip.ip6.uint32[3];
|
||||
}
|
||||
|
||||
if (id_equal(client_id, dht->c->self_public_key)) {
|
||||
if (id_equal(client_id, dht->self_public_key)) {
|
||||
for (i = 0; i < LCLIENT_LIST; ++i) {
|
||||
if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) {
|
||||
if (ip_port.ip.family == AF_INET) {
|
||||
|
@ -734,6 +753,7 @@ static int returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8
|
|||
}
|
||||
|
||||
end:
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
|
||||
if (dht->assoc) {
|
||||
IPPTs ippts;
|
||||
|
@ -744,6 +764,7 @@ end:
|
|||
Assoc_add_entry(dht->assoc, client_id, &ippts, NULL, used ? 1 : 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -754,7 +775,7 @@ end:
|
|||
static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, Node_format *sendback_node)
|
||||
{
|
||||
/* Check if packet is going to be sent to ourself. */
|
||||
if (id_equal(public_key, dht->c->self_public_key))
|
||||
if (id_equal(public_key, dht->self_public_key))
|
||||
return -1;
|
||||
|
||||
uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH] = {0};
|
||||
|
@ -794,7 +815,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
|
|||
memcpy(plain + CLIENT_ID_SIZE, encrypted_message, NODES_ENCRYPTED_MESSAGE_LENGTH);
|
||||
|
||||
int len = encrypt_data( public_key,
|
||||
dht->c->self_secret_key,
|
||||
dht->self_secret_key,
|
||||
nonce,
|
||||
plain,
|
||||
CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH,
|
||||
|
@ -804,11 +825,11 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
|
|||
return -1;
|
||||
|
||||
data[0] = NET_PACKET_GET_NODES;
|
||||
memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE);
|
||||
memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE);
|
||||
memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
|
||||
memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
|
||||
|
||||
return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data));
|
||||
return sendpacket(dht->net, ip_port, data, sizeof(data));
|
||||
}
|
||||
|
||||
/* Send a send nodes response. */
|
||||
|
@ -818,7 +839,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
|
|||
static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data)
|
||||
{
|
||||
/* Check if packet is going to be sent to ourself. */
|
||||
if (id_equal(public_key, dht->c->self_public_key))
|
||||
if (id_equal(public_key, dht->self_public_key))
|
||||
return -1;
|
||||
|
||||
size_t Node4_format_size = sizeof(Node4_format);
|
||||
|
@ -863,7 +884,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
|
|||
|
||||
memcpy(plain + num_nodes * Node4_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
|
||||
int len = encrypt_data( public_key,
|
||||
dht->c->self_secret_key,
|
||||
dht->self_secret_key,
|
||||
nonce,
|
||||
plain,
|
||||
num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
|
||||
|
@ -874,11 +895,11 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
|
|||
return -1;
|
||||
|
||||
data[0] = NET_PACKET_SEND_NODES;
|
||||
memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE);
|
||||
memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE);
|
||||
memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
|
||||
memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
|
||||
|
||||
return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
|
||||
return sendpacket(dht->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
|
||||
}
|
||||
|
||||
void to_net_family(IP *ip)
|
||||
|
@ -904,7 +925,7 @@ void to_host_family(IP *ip)
|
|||
static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data)
|
||||
{
|
||||
/* Check if packet is going to be sent to ourself. */
|
||||
if (id_equal(public_key, dht->c->self_public_key))
|
||||
if (id_equal(public_key, dht->self_public_key))
|
||||
return -1;
|
||||
|
||||
size_t Node_format_size = sizeof(Node_format);
|
||||
|
@ -930,7 +951,7 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
|
|||
memcpy(plain, nodes_list, num_nodes * Node_format_size);
|
||||
memcpy(plain + num_nodes * Node_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
|
||||
int len = encrypt_data( public_key,
|
||||
dht->c->self_secret_key,
|
||||
dht->self_secret_key,
|
||||
nonce,
|
||||
plain,
|
||||
num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
|
||||
|
@ -940,11 +961,11 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
|
|||
return -1;
|
||||
|
||||
data[0] = NET_PACKET_SEND_NODES_IPV6;
|
||||
memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE);
|
||||
memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE);
|
||||
memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
|
||||
memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
|
||||
|
||||
return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
|
||||
return sendpacket(dht->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
|
||||
}
|
||||
|
||||
static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
|
||||
|
@ -956,13 +977,13 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32
|
|||
return 1;
|
||||
|
||||
/* Check if packet is from ourself. */
|
||||
if (id_equal(packet + 1, dht->c->self_public_key))
|
||||
if (id_equal(packet + 1, dht->self_public_key))
|
||||
return 1;
|
||||
|
||||
uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH];
|
||||
|
||||
int len = decrypt_data( packet + 1,
|
||||
dht->c->self_secret_key,
|
||||
dht->self_secret_key,
|
||||
packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
|
||||
|
@ -1038,7 +1059,7 @@ static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet,
|
|||
|
||||
int len = decrypt_data(
|
||||
packet + 1,
|
||||
dht->c->self_secret_key,
|
||||
dht->self_secret_key,
|
||||
packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
|
||||
|
@ -1140,6 +1161,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
|
|||
/*
|
||||
* Send get nodes requests with client_id to max_num peers in list of length length
|
||||
*/
|
||||
/*
|
||||
static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id)
|
||||
{
|
||||
uint32_t i, num = 0;
|
||||
|
@ -1159,7 +1181,7 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
int DHT_addfriend(DHT *dht, uint8_t *client_id)
|
||||
{
|
||||
if (friend_number(dht, client_id) != -1) /* Is friend already in DHT? */
|
||||
|
@ -1177,6 +1199,7 @@ int DHT_addfriend(DHT *dht, uint8_t *client_id)
|
|||
|
||||
dht->friends_list[dht->num_friends].nat.NATping_id = random_64b();
|
||||
++dht->num_friends;
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
|
||||
if (dht->assoc) {
|
||||
/* get up to MAX_FRIEND_CLIENTS connectable nodes */
|
||||
|
@ -1206,8 +1229,9 @@ int DHT_addfriend(DHT *dht, uint8_t *client_id)
|
|||
}
|
||||
}
|
||||
|
||||
/*TODO: make this better?*/
|
||||
get_bunchnodes(dht, dht->close_clientlist, LCLIENT_LIST, MAX_FRIEND_CLIENTS, client_id);
|
||||
#endif
|
||||
/*this isn't really useful anymore.
|
||||
get_bunchnodes(dht, dht->close_clientlist, LCLIENT_LIST, MAX_FRIEND_CLIENTS, client_id);*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1343,7 +1367,7 @@ static void do_DHT_friends(DHT *dht)
|
|||
*/
|
||||
static void do_Close(DHT *dht)
|
||||
{
|
||||
uint8_t not_killed = do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->c->self_public_key,
|
||||
uint8_t not_killed = do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->self_public_key,
|
||||
dht->close_clientlist, LCLIENT_LIST);
|
||||
|
||||
if (!not_killed) {
|
||||
|
@ -1374,16 +1398,17 @@ void DHT_getnodes(DHT *dht, IP_Port *from_ipp, uint8_t *from_id, uint8_t *which_
|
|||
|
||||
void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
|
||||
{
|
||||
/*
|
||||
/*#ifdef ENABLE_ASSOC_DHT
|
||||
if (dht->assoc) {
|
||||
IPPTs ippts;
|
||||
ippts.ip_port = ip_port;
|
||||
ippts.timestamp = 0;
|
||||
|
||||
Assoc_add_entry(dht->assoc, public_key, &ippts, NULL, 0);
|
||||
}*/
|
||||
}
|
||||
#endif*/
|
||||
|
||||
getnodes(dht, ip_port, public_key, dht->c->self_public_key, NULL);
|
||||
getnodes(dht, ip_port, public_key, dht->self_public_key, NULL);
|
||||
}
|
||||
int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
|
||||
uint16_t port, uint8_t *public_key)
|
||||
|
@ -1427,9 +1452,9 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
|
|||
Client_data *client = &dht->close_clientlist[i];
|
||||
|
||||
if (ip_isset(&client->assoc6.ip_port.ip))
|
||||
return sendpacket(dht->c->lossless_udp->net, client->assoc6.ip_port, packet, length);
|
||||
return sendpacket(dht->net, client->assoc6.ip_port, packet, length);
|
||||
else if (ip_isset(&client->assoc4.ip_port.ip))
|
||||
return sendpacket(dht->c->lossless_udp->net, client->assoc4.ip_port, packet, length);
|
||||
return sendpacket(dht->net, client->assoc4.ip_port, packet, length);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
@ -1552,7 +1577,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
|
|||
/* If ip is not zero and node is good. */
|
||||
if (ip_isset(&assoc->ret_ip_port.ip) &&
|
||||
!is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||
int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length);
|
||||
int retval = sendpacket(dht->net, assoc->ip_port, packet, length);
|
||||
|
||||
if ((unsigned int)retval == length) {
|
||||
++sent;
|
||||
|
@ -1606,7 +1631,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
|
|||
if (n < 1)
|
||||
return 0;
|
||||
|
||||
int retval = sendpacket(dht->c->lossless_udp->net, ip_list[rand() % n], packet, length);
|
||||
int retval = sendpacket(dht->net, ip_list[rand() % n], packet, length);
|
||||
|
||||
if ((unsigned int)retval == length)
|
||||
return 1;
|
||||
|
@ -1647,7 +1672,7 @@ static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t
|
|||
data[0] = type;
|
||||
memcpy(data + 1, &ping_id, sizeof(uint64_t));
|
||||
/* 254 is NAT ping request packet id */
|
||||
int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, data,
|
||||
int len = create_request(dht->self_public_key, dht->self_secret_key, packet, public_key, data,
|
||||
sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING);
|
||||
|
||||
if (len == -1)
|
||||
|
@ -1821,7 +1846,7 @@ static void do_NAT(DHT *dht)
|
|||
/*----------------------------------------------------------------------------------*/
|
||||
/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/
|
||||
|
||||
#define HARDREQ_DATA_SIZE 768 /* Attempt to prevent amplification/other attacks*/
|
||||
#define HARDREQ_DATA_SIZE 384 /* Attempt to prevent amplification/other attacks*/
|
||||
|
||||
#define CHECK_TYPE_ROUTE_REQ 0
|
||||
#define CHECK_TYPE_ROUTE_RES 1
|
||||
|
@ -1839,13 +1864,13 @@ static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8
|
|||
uint8_t data[HARDREQ_DATA_SIZE] = {0};
|
||||
data[0] = type;
|
||||
memcpy(data + 1, contents, length);
|
||||
int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data,
|
||||
int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data,
|
||||
sizeof(data), CRYPTO_PACKET_HARDENING);
|
||||
|
||||
if (len == -1)
|
||||
return -1;
|
||||
|
||||
return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len);
|
||||
return sendpacket(dht->net, sendto->ip_port, packet, len);
|
||||
}
|
||||
|
||||
/* Send a get node hardening request */
|
||||
|
@ -1869,13 +1894,13 @@ static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *qu
|
|||
data[0] = CHECK_TYPE_GETNODE_RES;
|
||||
memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE);
|
||||
memcpy(data + 1 + CLIENT_ID_SIZE, list, num_nodes * sizeof(Node_format));
|
||||
int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data,
|
||||
int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data,
|
||||
sizeof(data), CRYPTO_PACKET_HARDENING);
|
||||
|
||||
if (len == -1)
|
||||
return -1;
|
||||
|
||||
return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len);
|
||||
return sendpacket(dht->net, sendto->ip_port, packet, len);
|
||||
}
|
||||
|
||||
/* TODO: improve */
|
||||
|
@ -1906,7 +1931,7 @@ static uint32_t have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num)
|
|||
uint32_t i;
|
||||
|
||||
for (i = 0; i < num; ++i) {
|
||||
if (id_equal(nodes[i].client_id, dht->c->self_public_key)) {
|
||||
if (id_equal(nodes[i].client_id, dht->self_public_key)) {
|
||||
++counter;
|
||||
continue;
|
||||
}
|
||||
|
@ -2116,7 +2141,7 @@ uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num)
|
|||
uint32_t i;
|
||||
|
||||
for (i = 0; i < max_num; ++i) {
|
||||
uint16_t rand_num = rand() % dht->num_friends + 1;
|
||||
uint16_t rand_num = rand() % (dht->num_friends + 1);
|
||||
|
||||
if (rand_num == dht->num_friends) {
|
||||
list = dht->close_clientlist;
|
||||
|
@ -2173,7 +2198,7 @@ void do_hardening(DHT *dht)
|
|||
memcpy(to_test.client_id, client_id, CLIENT_ID_SIZE);
|
||||
|
||||
//TODO: The search id should maybe not be ours?
|
||||
if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->c->self_public_key) > 0) {
|
||||
if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) {
|
||||
memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.client_id, CLIENT_ID_SIZE);
|
||||
cur_iptspng->hardening.send_nodes_timestamp = unix_time();
|
||||
}
|
||||
|
@ -2203,24 +2228,34 @@ DHT *new_DHT(Net_Crypto *c)
|
|||
if (dht == NULL)
|
||||
return NULL;
|
||||
|
||||
dht->ping = new_ping(dht, c);
|
||||
dht->c = c;
|
||||
dht->net = c->lossless_udp->net;
|
||||
dht->ping = new_ping(dht);
|
||||
|
||||
if (dht->ping == NULL) {
|
||||
kill_DHT(dht);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dht->c = c;
|
||||
networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
|
||||
networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht);
|
||||
networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
|
||||
init_cryptopackets(dht);
|
||||
cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
|
||||
cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht);
|
||||
|
||||
new_symmetric_key(dht->secret_symmetric_key);
|
||||
crypto_box_keypair(dht->self_public_key, dht->self_secret_key);
|
||||
dht->assoc = new_Assoc_default(dht->c->self_public_key);
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
dht->assoc = new_Assoc_default(dht->self_public_key);
|
||||
#endif
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
|
||||
uint8_t random_key_bytes[CLIENT_ID_SIZE];
|
||||
randombytes(random_key_bytes, sizeof(random_key_bytes));
|
||||
DHT_addfriend(dht, random_key_bytes);
|
||||
}
|
||||
|
||||
return dht;
|
||||
}
|
||||
|
@ -2238,15 +2273,19 @@ void do_DHT(DHT *dht)
|
|||
do_NAT(dht);
|
||||
do_toping(dht->ping);
|
||||
do_hardening(dht);
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
|
||||
if (dht->assoc)
|
||||
do_Assoc(dht->assoc, dht);
|
||||
|
||||
#endif
|
||||
dht->last_run = unix_time();
|
||||
}
|
||||
void kill_DHT(DHT *dht)
|
||||
{
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
kill_Assoc(dht->assoc);
|
||||
#endif
|
||||
kill_ping(dht->ping);
|
||||
free(dht->friends_list);
|
||||
free(dht);
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
#define TOX_AF_INET 2
|
||||
#define TOX_AF_INET6 10
|
||||
|
||||
/* The number of "fake" friends to add (for optimization purposes and so our paths for the onion part are more random) */
|
||||
#define DHT_FAKE_FRIEND_NUMBER 4
|
||||
|
||||
/* Functions to transfer ips safely across wire. */
|
||||
void to_net_family(IP *ip);
|
||||
void to_host_family(IP *ip);
|
||||
|
@ -139,6 +142,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
Net_Crypto *c;
|
||||
Networking_Core *net;
|
||||
|
||||
Client_data close_clientlist[LCLIENT_LIST];
|
||||
uint64_t close_lastgetnodes;
|
||||
|
@ -153,9 +157,9 @@ typedef struct {
|
|||
uint16_t num_friends;
|
||||
|
||||
struct PING *ping;
|
||||
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
struct Assoc *assoc;
|
||||
|
||||
#endif
|
||||
uint64_t last_run;
|
||||
} DHT;
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -220,33 +220,33 @@ static int handle_LANdiscovery(void *object, IP_Port source, uint8_t *packet, ui
|
|||
}
|
||||
|
||||
|
||||
int send_LANdiscovery(uint16_t port, Net_Crypto *c)
|
||||
int send_LANdiscovery(uint16_t port, DHT *dht)
|
||||
{
|
||||
uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
|
||||
data[0] = NET_PACKET_LAN_DISCOVERY;
|
||||
id_copy(data + 1, c->self_public_key);
|
||||
id_copy(data + 1, dht->self_public_key);
|
||||
|
||||
#ifdef __linux
|
||||
send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
|
||||
send_broadcasts(dht->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
|
||||
#endif
|
||||
int res = -1;
|
||||
IP_Port ip_port;
|
||||
ip_port.port = port;
|
||||
|
||||
/* IPv6 multicast */
|
||||
if (c->lossless_udp->net->family == AF_INET6) {
|
||||
if (dht->net->family == AF_INET6) {
|
||||
ip_port.ip = broadcast_ip(AF_INET6, AF_INET6);
|
||||
|
||||
if (ip_isset(&ip_port.ip))
|
||||
if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES) > 0)
|
||||
if (sendpacket(dht->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES) > 0)
|
||||
res = 1;
|
||||
}
|
||||
|
||||
/* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is AF_INET6 */
|
||||
ip_port.ip = broadcast_ip(c->lossless_udp->net->family, AF_INET);
|
||||
ip_port.ip = broadcast_ip(dht->net->family, AF_INET);
|
||||
|
||||
if (ip_isset(&ip_port.ip))
|
||||
if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES))
|
||||
if (sendpacket(dht->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES))
|
||||
res = 1;
|
||||
|
||||
return res;
|
||||
|
@ -255,5 +255,5 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c)
|
|||
|
||||
void LANdiscovery_init(DHT *dht)
|
||||
{
|
||||
networking_registerhandler(dht->c->lossless_udp->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#define LAN_DISCOVERY_INTERVAL 60
|
||||
|
||||
/* Send a LAN discovery pcaket to the broadcast address with port port. */
|
||||
int send_LANdiscovery(uint16_t port, Net_Crypto *c);
|
||||
int send_LANdiscovery(uint16_t port, DHT *dht);
|
||||
|
||||
/* Sets up packet handlers. */
|
||||
void LANdiscovery_init(DHT *dht);
|
||||
|
|
|
@ -34,27 +34,6 @@
|
|||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
|
||||
void host_to_net(uint8_t *num, uint16_t numbytes)
|
||||
{
|
||||
union {
|
||||
uint32_t i;
|
||||
uint8_t c[4];
|
||||
} a;
|
||||
a.i = 1;
|
||||
|
||||
if (a.c[0] == 1) {
|
||||
uint32_t i;
|
||||
uint8_t buff[numbytes];
|
||||
|
||||
for (i = 0; i < numbytes; ++i) {
|
||||
buff[i] = num[numbytes - i - 1];
|
||||
}
|
||||
|
||||
memcpy(num, buff, numbytes);
|
||||
}
|
||||
}
|
||||
#define net_to_host(x, y) host_to_net(x, y)
|
||||
|
||||
static void set_friend_status(Messenger *m, int friendnumber, uint8_t status);
|
||||
static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length);
|
||||
|
||||
|
@ -206,11 +185,16 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
|
|||
|
||||
memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend));
|
||||
|
||||
int onion_friendnum = onion_addfriend(m->onion_c, client_id);
|
||||
|
||||
if (onion_friendnum == -1)
|
||||
return FAERR_UNKNOWN;
|
||||
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i <= m->numfriends; ++i) {
|
||||
if (m->friendlist[i].status == NOFRIEND) {
|
||||
DHT_addfriend(m->dht, client_id);
|
||||
m->friendlist[i].onion_friendnum = onion_friendnum;
|
||||
m->friendlist[i].status = FRIEND_ADDED;
|
||||
m->friendlist[i].crypt_connection_id = -1;
|
||||
m->friendlist[i].friendrequest_lastsent = 0;
|
||||
|
@ -249,11 +233,16 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
|
|||
|
||||
memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend));
|
||||
|
||||
int onion_friendnum = onion_addfriend(m->onion_c, client_id);
|
||||
|
||||
if (onion_friendnum == -1)
|
||||
return FAERR_UNKNOWN;
|
||||
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i <= m->numfriends; ++i) {
|
||||
if (m->friendlist[i].status == NOFRIEND) {
|
||||
DHT_addfriend(m->dht, client_id);
|
||||
m->friendlist[i].onion_friendnum = onion_friendnum;
|
||||
m->friendlist[i].status = FRIEND_CONFIRMED;
|
||||
m->friendlist[i].crypt_connection_id = -1;
|
||||
m->friendlist[i].friendrequest_lastsent = 0;
|
||||
|
@ -284,7 +273,7 @@ int m_delfriend(Messenger *m, int friendnumber)
|
|||
if (friend_not_valid(m, friendnumber))
|
||||
return -1;
|
||||
|
||||
DHT_delfriend(m->dht, m->friendlist[friendnumber].client_id);
|
||||
onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum);
|
||||
crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id);
|
||||
free(m->friendlist[friendnumber].statusmessage);
|
||||
memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend));
|
||||
|
@ -673,6 +662,8 @@ static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_
|
|||
const uint8_t was_online = m->friendlist[friendnumber].status == FRIEND_ONLINE;
|
||||
const uint8_t is_online = status == FRIEND_ONLINE;
|
||||
|
||||
onion_set_friend_online(m->onion_c, m->friendlist[friendnumber].onion_friendnum, is_online);
|
||||
|
||||
if (is_online != was_online) {
|
||||
if (was_online)
|
||||
break_files(m, friendnumber);
|
||||
|
@ -1513,7 +1504,7 @@ static int friend_already_added(uint8_t *client_id, void *data)
|
|||
static void LANdiscovery(Messenger *m)
|
||||
{
|
||||
if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) {
|
||||
send_LANdiscovery(htons(TOX_PORT_DEFAULT), m->net_crypto);
|
||||
send_LANdiscovery(htons(TOX_PORT_DEFAULT), m->dht);
|
||||
m->last_LANdiscovery = unix_time();
|
||||
}
|
||||
}
|
||||
|
@ -1552,9 +1543,24 @@ Messenger *new_messenger(uint8_t ipv6enabled)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
m->onion = new_onion(m->dht);
|
||||
m->onion_a = new_onion_announce(m->dht);
|
||||
m->onion_c = new_onion_client(m->dht);
|
||||
|
||||
if (!(m->onion && m->onion_a && m->onion_c)) {
|
||||
kill_onion(m->onion);
|
||||
kill_onion_announce(m->onion_a);
|
||||
kill_onion_client(m->onion_c);
|
||||
kill_DHT(m->dht);
|
||||
kill_net_crypto(m->net_crypto);
|
||||
kill_networking(m->net);
|
||||
free(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
|
||||
|
||||
friendreq_init(&(m->fr), m->net_crypto);
|
||||
friendreq_init(&(m->fr), m->onion_c);
|
||||
LANdiscovery_init(m->dht);
|
||||
set_nospam(&(m->fr), random_int());
|
||||
set_filter_function(&(m->fr), &friend_already_added, m);
|
||||
|
@ -1610,7 +1616,7 @@ void do_friends(Messenger *m)
|
|||
|
||||
for (i = 0; i < m->numfriends; ++i) {
|
||||
if (m->friendlist[i].status == FRIEND_ADDED) {
|
||||
int fr = send_friendrequest(m->dht, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam,
|
||||
int fr = send_friendrequest(m->onion_c, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam,
|
||||
m->friendlist[i].info,
|
||||
m->friendlist[i].info_size);
|
||||
|
||||
|
@ -1630,7 +1636,7 @@ void do_friends(Messenger *m)
|
|||
}
|
||||
|
||||
IP_Port friendip;
|
||||
int friendok = DHT_getfriendip(m->dht, m->friendlist[i].client_id, &friendip);
|
||||
int friendok = onion_getfriendip(m->onion_c, m->friendlist[i].onion_friendnum, &friendip);
|
||||
|
||||
switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) {
|
||||
case CRYPTO_CONN_NO_CONNECTION:
|
||||
|
@ -1957,6 +1963,7 @@ void do_messenger(Messenger *m)
|
|||
|
||||
do_DHT(m->dht);
|
||||
do_net_crypto(m->net_crypto);
|
||||
do_onion_client(m->onion_c);
|
||||
do_friends(m);
|
||||
do_inbound(m);
|
||||
do_allgroupchats(m);
|
||||
|
@ -2188,9 +2195,12 @@ static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t le
|
|||
if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) {
|
||||
set_nospam(&(m->fr), *(uint32_t *)data);
|
||||
load_keys(m->net_crypto, &data[sizeof(uint32_t)]);
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
|
||||
if (m->dht->assoc)
|
||||
Assoc_self_client_id_changed(m->dht->assoc, m->net_crypto->self_public_key);
|
||||
|
||||
#endif
|
||||
} else
|
||||
return -1; /* critical */
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "friend_requests.h"
|
||||
#include "LAN_discovery.h"
|
||||
#include "group_chats.h"
|
||||
#include "onion_client.h"
|
||||
|
||||
#define MAX_NAME_LENGTH 128
|
||||
#define MAX_STATUSMESSAGE_LENGTH 1007
|
||||
|
@ -130,6 +131,7 @@ enum {
|
|||
|
||||
typedef struct {
|
||||
uint8_t client_id[CLIENT_ID_SIZE];
|
||||
uint32_t onion_friendnum;
|
||||
int crypt_connection_id;
|
||||
uint64_t friendrequest_lastsent; // Time at which the last friend request was sent.
|
||||
uint32_t friendrequest_timeout; // The timeout between successful friendrequest sending attempts.
|
||||
|
@ -160,6 +162,11 @@ typedef struct Messenger {
|
|||
Networking_Core *net;
|
||||
Net_Crypto *net_crypto;
|
||||
DHT *dht;
|
||||
|
||||
Onion *onion;
|
||||
Onion_Announce *onion_a;
|
||||
Onion_Client *onion_c;
|
||||
|
||||
Friend_Requests fr;
|
||||
uint8_t name[MAX_NAME_LENGTH];
|
||||
uint16_t name_length;
|
||||
|
|
|
@ -35,41 +35,24 @@
|
|||
* return 0 if it sent the friend request directly to the friend.
|
||||
* return the number of peers it was routed through if it did not send it directly.
|
||||
*/
|
||||
int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
|
||||
int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
|
||||
{
|
||||
if (length + sizeof(nospam_num) > MAX_DATA_SIZE)
|
||||
return -1;
|
||||
|
||||
uint8_t temp[MAX_DATA_SIZE];
|
||||
memcpy(temp, &nospam_num, sizeof(nospam_num));
|
||||
memcpy(temp + sizeof(nospam_num), data, length);
|
||||
uint8_t packet[MAX_DATA_SIZE];
|
||||
int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, temp,
|
||||
length + sizeof(nospam_num),
|
||||
CRYPTO_PACKET_FRIEND_REQ);
|
||||
temp[0] = CRYPTO_PACKET_FRIEND_REQ;
|
||||
memcpy(temp + 1, &nospam_num, sizeof(nospam_num));
|
||||
memcpy(temp + 1 + sizeof(nospam_num), data, length);
|
||||
|
||||
if (len == -1)
|
||||
int friend_num = onion_friend_num(onion_c, public_key);
|
||||
|
||||
if (friend_num == -1)
|
||||
return -1;
|
||||
|
||||
IP_Port ip_port;
|
||||
int friendok = DHT_getfriendip(dht, public_key, &ip_port);
|
||||
int num = send_onion_data(onion_c, friend_num, temp, 1 + sizeof(nospam_num) + length);
|
||||
|
||||
// not a friend
|
||||
if (friendok == -1)
|
||||
return -1;
|
||||
|
||||
// is a friend and we know how to reach him
|
||||
if (friendok == 1) {
|
||||
if (sendpacket(dht->c->lossless_udp->net, ip_port, packet, len) != -1)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// is a friend, we DON'T know how to reach him
|
||||
int num = route_tofriend(dht, public_key, packet, len);
|
||||
|
||||
if (num == 0)
|
||||
if (num <= 0)
|
||||
return -1;
|
||||
|
||||
return num;
|
||||
|
@ -130,9 +113,14 @@ static int request_received(Friend_Requests *fr, uint8_t *client_id)
|
|||
}
|
||||
|
||||
|
||||
static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet,
|
||||
uint32_t length)
|
||||
static int friendreq_handlepacket(void *object, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
|
||||
{
|
||||
if (length == 0)
|
||||
return 1;
|
||||
|
||||
++packet;
|
||||
--length;
|
||||
|
||||
Friend_Requests *fr = object;
|
||||
|
||||
if (fr->handle_friendrequest_isset == 0)
|
||||
|
@ -156,7 +144,7 @@ static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_
|
|||
return 0;
|
||||
}
|
||||
|
||||
void friendreq_init(Friend_Requests *fr, Net_Crypto *c)
|
||||
void friendreq_init(Friend_Requests *fr, Onion_Client *onion_c)
|
||||
{
|
||||
cryptopacket_registerhandler(c, CRYPTO_PACKET_FRIEND_REQ, &friendreq_handlepacket, fr);
|
||||
oniondata_registerhandler(onion_c, CRYPTO_PACKET_FRIEND_REQ, &friendreq_handlepacket, fr);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#ifndef FRIEND_REQUESTS_H
|
||||
#define FRIEND_REQUESTS_H
|
||||
|
||||
#include "DHT.h"
|
||||
#include "onion_client.h"
|
||||
#include "net_crypto.h"
|
||||
|
||||
|
||||
|
@ -49,7 +49,7 @@ typedef struct {
|
|||
/* Try to send a friendrequest to peer with public_key.
|
||||
* data is the data in the request and length is the length.
|
||||
*/
|
||||
int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
|
||||
int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
|
||||
/* Set and get the nospam variable used to prevent one type of friend request spam. */
|
||||
void set_nospam(Friend_Requests *fr, uint32_t num);
|
||||
uint32_t get_nospam(Friend_Requests *fr);
|
||||
|
@ -67,7 +67,7 @@ void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uin
|
|||
void set_filter_function(Friend_Requests *fr, int (*function)(uint8_t *, void *), void *userdata);
|
||||
|
||||
/* Sets up friendreq packet handlers. */
|
||||
void friendreq_init(Friend_Requests *fr, Net_Crypto *c);
|
||||
void friendreq_init(Friend_Requests *fr, Onion_Client *onion_c);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -365,11 +365,11 @@ static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, ui
|
|||
length > MAX_DATA_SIZE + crypto_box_MACBYTES)
|
||||
return 1;
|
||||
|
||||
if (memcmp(packet + 1, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us.
|
||||
if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us.
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t data[MAX_DATA_SIZE];
|
||||
uint8_t number;
|
||||
int len = handle_request(dht->c->self_public_key, dht->c->self_secret_key, public_key, data, &number, packet, length);
|
||||
int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length);
|
||||
|
||||
if (len == -1 || len == 0)
|
||||
return 1;
|
||||
|
|
|
@ -363,6 +363,9 @@ Onion *new_onion(DHT *dht)
|
|||
|
||||
void kill_onion(Onion *onion)
|
||||
{
|
||||
if (onion == NULL)
|
||||
return;
|
||||
|
||||
networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, NULL, NULL);
|
||||
networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_1, NULL, NULL);
|
||||
networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_2, NULL, NULL);
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define PING_ID_TIMEOUT 20
|
||||
|
||||
#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES)
|
||||
#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 DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
|
||||
|
@ -43,6 +43,7 @@
|
|||
* 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.
|
||||
*
|
||||
|
@ -50,12 +51,14 @@
|
|||
* return 0 on success.
|
||||
*/
|
||||
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, uint8_t *sendback_data)
|
||||
uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data)
|
||||
{
|
||||
uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
|
||||
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, sendback_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
|
||||
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,
|
||||
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
|
||||
uint8_t packet[ANNOUNCE_REQUEST_SIZE];
|
||||
packet[0] = NET_PACKET_ANNOUNCE_REQUEST;
|
||||
new_nonce(packet + 1);
|
||||
|
@ -78,12 +81,15 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin
|
|||
* 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 send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, uint16_t length)
|
||||
int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce,
|
||||
uint8_t *data, uint16_t length)
|
||||
{
|
||||
uint8_t packet[DATA_REQUEST_MIN_SIZE + length];
|
||||
packet[0] = NET_PACKET_ONION_DATA_REQUEST;
|
||||
|
@ -96,7 +102,7 @@ int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t
|
|||
|
||||
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,
|
||||
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))
|
||||
|
@ -167,10 +173,11 @@ static int cmp_entry(const void *a, const void *b)
|
|||
|
||||
/* add entry to entries list
|
||||
*
|
||||
* return 0 if failure
|
||||
* return 1 if added
|
||||
* return -1 if failure
|
||||
* return position if added
|
||||
*/
|
||||
static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *ret)
|
||||
static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *data_public_key,
|
||||
uint8_t *ret)
|
||||
{
|
||||
|
||||
int pos = in_entries(onion_a, public_key);
|
||||
|
@ -190,16 +197,17 @@ static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t
|
|||
}
|
||||
|
||||
if (pos == -1)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
memcpy(onion_a->entries[pos].public_key, public_key, crypto_box_PUBLICKEYBYTES);
|
||||
onion_a->entries[pos].ret_ip_port = ret_ip_port;
|
||||
memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3);
|
||||
memcpy(onion_a->entries[pos].data_public_key, data_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
onion_a->entries[pos].time = unix_time();
|
||||
|
||||
memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry);
|
||||
return 1;
|
||||
return pos;
|
||||
}
|
||||
|
||||
static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length)
|
||||
|
@ -209,10 +217,11 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
|
|||
if (length != ANNOUNCE_REQUEST_SIZE_RECV)
|
||||
return 1;
|
||||
|
||||
uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
|
||||
uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
|
||||
int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, packet + 1,
|
||||
packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
|
||||
ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES, plain);
|
||||
ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH +
|
||||
crypto_box_MACBYTES, plain);
|
||||
|
||||
if ((uint32_t)len != sizeof(plain))
|
||||
return 1;
|
||||
|
@ -223,13 +232,14 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
|
|||
uint8_t ping_id2[ONION_PING_ID_SIZE];
|
||||
generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet + 1 + crypto_box_NONCEBYTES, source, ping_id2);
|
||||
|
||||
int stored = 0;
|
||||
int index = -1;
|
||||
|
||||
if (memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) {
|
||||
stored = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES,
|
||||
index = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES,
|
||||
plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES,
|
||||
packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3));
|
||||
} else {
|
||||
stored = (in_entries(onion_a, plain + ONION_PING_ID_SIZE) != -1);
|
||||
index = in_entries(onion_a, plain + ONION_PING_ID_SIZE);
|
||||
}
|
||||
|
||||
/*Respond with a announce response packet*/
|
||||
|
@ -245,24 +255,29 @@ 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[ONION_PING_ID_SIZE + sizeof(nodes_list)] = {0};
|
||||
uint8_t pl[1 + ONION_PING_ID_SIZE + sizeof(nodes_list)];
|
||||
|
||||
if (!stored) {
|
||||
memcpy(pl, ping_id2, ONION_PING_ID_SIZE);
|
||||
if (index == -1) {
|
||||
pl[0] = 0;
|
||||
memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE);
|
||||
} else {
|
||||
pl[0] = 1;
|
||||
memcpy(pl + 1, onion_a->entries[index].data_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
}
|
||||
|
||||
memcpy(pl + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format));
|
||||
memcpy(pl + 1 + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format));
|
||||
|
||||
uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE];
|
||||
len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl,
|
||||
ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format),
|
||||
1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format),
|
||||
data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES);
|
||||
|
||||
if ((uint32_t)len != ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES)
|
||||
if ((uint32_t)len != 1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES)
|
||||
return 1;
|
||||
|
||||
data[0] = NET_PACKET_ANNOUNCE_RESPONSE;
|
||||
memcpy(data + 1, plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
|
||||
memcpy(data + 1, plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES,
|
||||
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
|
||||
memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, crypto_box_NONCEBYTES);
|
||||
|
||||
if (send_onion_response(onion_a->net, source, data,
|
||||
|
@ -321,6 +336,9 @@ Onion_Announce *new_onion_announce(DHT *dht)
|
|||
|
||||
void kill_onion_announce(Onion_Announce *onion_a)
|
||||
{
|
||||
if (onion_a == NULL)
|
||||
return;
|
||||
|
||||
networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, NULL, NULL);
|
||||
networking_registerhandler(onion_a->net, NET_PACKET_ONION_DATA_REQUEST, NULL, NULL);
|
||||
free(onion_a);
|
||||
|
|
|
@ -31,15 +31,20 @@
|
|||
|
||||
#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES)
|
||||
|
||||
#define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + ONION_PING_ID_SIZE + 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)
|
||||
|
||||
#define ONION_DATA_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
|
||||
|
||||
#if ONION_PING_ID_SIZE != crypto_box_PUBLICKEYBYTES
|
||||
#error announce response packets assume that ONION_PING_ID_SIZE is equal to crypto_box_PUBLICKEYBYTES
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
IP_Port ret_ip_port;
|
||||
uint8_t ret[ONION_RETURN_3];
|
||||
uint8_t data_public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint64_t time;
|
||||
} Onion_Announce_Entry;
|
||||
|
||||
|
@ -59,6 +64,7 @@ typedef struct {
|
|||
* 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.
|
||||
*
|
||||
|
@ -66,7 +72,7 @@ typedef struct {
|
|||
* return 0 on success.
|
||||
*/
|
||||
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, uint8_t *sendback_data);
|
||||
uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data);
|
||||
|
||||
/* Create and send an onion data request packet.
|
||||
*
|
||||
|
@ -75,13 +81,15 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin
|
|||
* 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 send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data,
|
||||
uint16_t length);
|
||||
int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce,
|
||||
uint8_t *data, uint16_t length);
|
||||
|
||||
|
||||
Onion_Announce *new_onion_announce(DHT *dht);
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#define ANNOUNCE_TIMEOUT 10
|
||||
|
||||
static uint8_t zero_ping[ONION_PING_ID_SIZE];
|
||||
|
||||
/* Creates a sendback for use in an announce request.
|
||||
*
|
||||
|
@ -107,7 +106,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
|
|||
|
||||
uint8_t sendback[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
|
||||
|
||||
if (new_sendback(onion_c, 0, dest_pubkey, dest, sendback) == -1)
|
||||
if (new_sendback(onion_c, num, dest_pubkey, dest, sendback) == -1)
|
||||
return -1;
|
||||
|
||||
uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0};
|
||||
|
@ -126,11 +125,11 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
|
|||
if (num == 0) {
|
||||
return send_announce_request(onion_c->dht, nodes, onion_c->dht->c->self_public_key,
|
||||
onion_c->dht->c->self_secret_key, ping_id,
|
||||
onion_c->dht->c->self_public_key, sendback);
|
||||
onion_c->dht->c->self_public_key, onion_c->temp_public_key, sendback);
|
||||
} else {
|
||||
return send_announce_request(onion_c->dht, nodes, 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, sendback);
|
||||
onion_c->friends_list[num - 1].real_client_id, zero_ping_id, sendback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +163,7 @@ static int cmp_entry(const void *a, const void *b)
|
|||
}
|
||||
|
||||
static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port,
|
||||
uint8_t *ping_id)
|
||||
uint8_t is_stored, uint8_t *pingid_or_key)
|
||||
{
|
||||
if (num > onion_c->num_friends)
|
||||
return -1;
|
||||
|
@ -204,7 +203,14 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ
|
|||
|
||||
memcpy(list_nodes[index].client_id, public_key, CLIENT_ID_SIZE);
|
||||
list_nodes[index].ip_port = ip_port;
|
||||
memcpy(list_nodes[index].ping_id, ping_id, ONION_PING_ID_SIZE);
|
||||
|
||||
if (is_stored) {
|
||||
memcpy(list_nodes[index].data_public_key, pingid_or_key, crypto_box_PUBLICKEYBYTES);
|
||||
} else {
|
||||
memcpy(list_nodes[index].ping_id, pingid_or_key, ONION_PING_ID_SIZE);
|
||||
}
|
||||
|
||||
list_nodes[index].is_stored = is_stored;
|
||||
list_nodes[index].timestamp = unix_time();
|
||||
list_nodes[index].last_pinged = 0;
|
||||
return 0;
|
||||
|
@ -230,7 +236,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
|
|||
reference_id = onion_c->friends_list[num - 1].real_client_id;
|
||||
}
|
||||
|
||||
uint32_t i;
|
||||
uint32_t i, j;
|
||||
int lan_ips_accepted = (LAN_ip(source.ip) == 0);
|
||||
|
||||
for (i = 0; i < num_nodes; ++i) {
|
||||
|
@ -242,6 +248,14 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
|
|||
|
||||
if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT)
|
||||
|| id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) {
|
||||
/* check if node is already in list. */
|
||||
for (j = 0; j < MAX_ONION_CLIENTS; ++j) {
|
||||
if (memcmp(list_nodes[j].client_id, nodes[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == MAX_ONION_CLIENTS)
|
||||
client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +282,7 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
|
|||
if (num > onion_c->num_friends)
|
||||
return 1;
|
||||
|
||||
uint8_t plain[ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)];
|
||||
uint8_t plain[1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)];
|
||||
int len = -1;
|
||||
|
||||
if (num == 0) {
|
||||
|
@ -289,10 +303,10 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
|
|||
return 1;
|
||||
|
||||
|
||||
if (client_add_to_list(onion_c, num, public_key, ip_port, plain) == -1)
|
||||
if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1) == -1)
|
||||
return 1;
|
||||
|
||||
if (client_ping_nodes(onion_c, num, (Node_format *)plain + ONION_PING_ID_SIZE, num_nodes, source) == -1)
|
||||
if (client_ping_nodes(onion_c, num, (Node_format *)plain + 1 + ONION_PING_ID_SIZE, num_nodes, source) == -1)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
@ -311,7 +325,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u
|
|||
return 1;
|
||||
|
||||
uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE];
|
||||
int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_c->dht->c->self_secret_key, packet + 1,
|
||||
int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_c->temp_secret_key, packet + 1,
|
||||
packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
|
||||
length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), temp_plain);
|
||||
|
||||
|
@ -333,7 +347,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u
|
|||
}
|
||||
|
||||
#define FAKEID_DATA_ID 156
|
||||
#define FAKEID_DATA_MIN_LENGTH (1 + crypto_box_PUBLICKEYBYTES)
|
||||
#define FAKEID_DATA_MIN_LENGTH (1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES)
|
||||
#define FAKEID_DATA_MAX_LENGTH (FAKEID_DATA_MIN_LENGTH + sizeof(Node_format)*MAX_SENT_NODES)
|
||||
static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t length)
|
||||
{
|
||||
|
@ -353,19 +367,30 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
|
|||
if (friend_num == -1)
|
||||
return 1;
|
||||
|
||||
if (memcmp(data + 1, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES) != 0) {
|
||||
uint64_t no_replay;
|
||||
net_to_host(data + 1, sizeof(no_replay));
|
||||
memcpy(&no_replay, data + 1, sizeof(uint64_t));
|
||||
|
||||
if (no_replay <= onion_c->friends_list[friend_num].last_noreplay)
|
||||
return 1;
|
||||
|
||||
onion_c->friends_list[friend_num].last_noreplay = no_replay;
|
||||
|
||||
if (memcmp(data + 1 + sizeof(uint64_t), onion_c->friends_list[friend_num].fake_client_id,
|
||||
crypto_box_PUBLICKEYBYTES) != 0) {
|
||||
DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
|
||||
|
||||
if (DHT_addfriend(onion_c->dht, data + 1) == 1) {
|
||||
if (DHT_addfriend(onion_c->dht, data + 1 + sizeof(uint64_t)) == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1, crypto_box_PUBLICKEYBYTES);
|
||||
onion_c->friends_list[friend_num].is_fake_clientid = 1;
|
||||
memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
|
||||
}
|
||||
|
||||
uint16_t num_nodes = (length - FAKEID_DATA_MIN_LENGTH) / sizeof(Node_format);
|
||||
Node_format nodes[num_nodes];
|
||||
memcpy(nodes, data + 1 + crypto_box_PUBLICKEYBYTES, sizeof(nodes));
|
||||
memcpy(nodes, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, sizeof(nodes));
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < num_nodes; ++i) {
|
||||
|
@ -373,7 +398,6 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
|
|||
DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id);
|
||||
}
|
||||
|
||||
//TODO replay protection
|
||||
return 0;
|
||||
}
|
||||
/* Send data of length length to friendnum.
|
||||
|
@ -413,7 +437,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
|
|||
if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT))
|
||||
continue;
|
||||
|
||||
if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) {
|
||||
if (list_nodes[i].is_stored) {
|
||||
Node_format nodes[4];
|
||||
|
||||
if (random_path(onion_c, nodes) == -1)
|
||||
|
@ -422,8 +446,8 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
|
|||
memcpy(nodes[3].client_id, list_nodes[i].client_id, crypto_box_PUBLICKEYBYTES);
|
||||
nodes[3].ip_port = list_nodes[i].ip_port;
|
||||
|
||||
if (send_data_request(onion_c->dht, nodes, onion_c->friends_list[friend_num].real_client_id, nonce, packet,
|
||||
sizeof(packet)) == 0)
|
||||
if (send_data_request(onion_c->dht, nodes, onion_c->friends_list[friend_num].real_client_id,
|
||||
list_nodes[i].data_public_key, nonce, packet, sizeof(packet)) == 0)
|
||||
++good;
|
||||
}
|
||||
}
|
||||
|
@ -431,24 +455,104 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
|
|||
return good;
|
||||
}
|
||||
|
||||
/* Send the packets to tell our friends
|
||||
/* Try to send the fakeid via the DHT instead of onion
|
||||
*
|
||||
* Even if this function succeeds, the friend might not recieve any data.
|
||||
*
|
||||
* return the number of packets sent on success
|
||||
* return -1 on failure.
|
||||
*/
|
||||
static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num)
|
||||
static int send_dht_fakeid(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32_t length)
|
||||
{
|
||||
if ((uint32_t)friend_num >= onion_c->num_friends)
|
||||
return -1;
|
||||
|
||||
if (!onion_c->friends_list[friend_num].is_fake_clientid)
|
||||
return -1;
|
||||
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
new_nonce(nonce);
|
||||
|
||||
uint8_t temp[DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES + length];
|
||||
memcpy(temp, onion_c->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
memcpy(temp + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
|
||||
int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->dht->c->self_secret_key, nonce, data,
|
||||
length, temp + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
|
||||
|
||||
if ((uint32_t)len + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES != sizeof(temp))
|
||||
return -1;
|
||||
|
||||
uint8_t packet[MAX_DATA_SIZE];
|
||||
len = create_request(onion_c->dht->self_public_key, onion_c->dht->self_secret_key, packet,
|
||||
onion_c->friends_list[friend_num].fake_client_id, temp, sizeof(temp), FAKEID_DATA_ID);
|
||||
|
||||
if (len == -1)
|
||||
return -1;
|
||||
|
||||
return route_tofriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, packet, len);
|
||||
}
|
||||
|
||||
static int handle_dht_fakeid(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
|
||||
{
|
||||
Onion_Client *onion_c = object;
|
||||
|
||||
if (length < FAKEID_DATA_MIN_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)
|
||||
return 1;
|
||||
|
||||
if (length > FAKEID_DATA_MAX_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)
|
||||
return 1;
|
||||
|
||||
uint8_t plain[FAKEID_DATA_MAX_LENGTH];
|
||||
int len = decrypt_data(packet, onion_c->dht->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES,
|
||||
packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
|
||||
length - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES), plain);
|
||||
|
||||
if ((uint32_t)len != length - (DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES))
|
||||
return 1;
|
||||
|
||||
if (memcpy(source_pubkey, packet, crypto_box_PUBLICKEYBYTES) != 0)
|
||||
return 1;
|
||||
|
||||
return handle_fakeid_announce(onion_c, packet, plain, len);
|
||||
}
|
||||
/* Send the packets to tell our friends what our DHT public key is.
|
||||
*
|
||||
* if onion_dht_both is 0, use only the onion to send the packet.
|
||||
* if it is 1, use only the dht.
|
||||
* if it is something else, use both.
|
||||
*
|
||||
* return the number of packets sent on success
|
||||
* return -1 on failure.
|
||||
*/
|
||||
static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both)
|
||||
{
|
||||
if (friend_num >= onion_c->num_friends)
|
||||
return -1;
|
||||
|
||||
uint8_t data[FAKEID_DATA_MAX_LENGTH];
|
||||
data[0] = FAKEID_DATA_ID;
|
||||
memcpy(data + 1, onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
uint64_t no_replay = unix_time();
|
||||
host_to_net((uint8_t *)&no_replay, sizeof(no_replay));
|
||||
memcpy(data + 1, &no_replay, sizeof(no_replay));
|
||||
memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
Node_format nodes[MAX_SENT_NODES];
|
||||
uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES);
|
||||
memcpy(data + FAKEID_DATA_MIN_LENGTH, nodes, sizeof(Node_format) * num_nodes);
|
||||
return send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);
|
||||
//TODO: somehow make this function send our DHT client id directly to the other if we know theirs but they don't
|
||||
//seem to know ours.
|
||||
int num1 = -1, num2 = -1;
|
||||
|
||||
if (onion_dht_both != 1)
|
||||
num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);
|
||||
|
||||
if (onion_dht_both != 0)
|
||||
num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);
|
||||
|
||||
if (num1 == -1)
|
||||
return num2;
|
||||
|
||||
if (num2 == -1)
|
||||
return num1;
|
||||
|
||||
return num1 + num2;
|
||||
}
|
||||
|
||||
/* Get the friend_num of a friend.
|
||||
|
@ -525,6 +629,7 @@ int onion_addfriend(Onion_Client *onion_c, uint8_t *client_id)
|
|||
|
||||
onion_c->friends_list[index].status = 1;
|
||||
memcpy(onion_c->friends_list[index].real_client_id, client_id, crypto_box_PUBLICKEYBYTES);
|
||||
crypto_box_keypair(onion_c->friends_list[index].temp_public_key, onion_c->friends_list[index].temp_secret_key);
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -538,7 +643,9 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
|
|||
if ((uint32_t)friend_num >= onion_c->num_friends)
|
||||
return -1;
|
||||
|
||||
if (onion_c->friends_list[friend_num].is_fake_clientid)
|
||||
DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
|
||||
|
||||
memset(&(onion_c->friends_list[friend_num]), 0, sizeof(Onion_Friend));
|
||||
uint32_t i;
|
||||
|
||||
|
@ -557,8 +664,9 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
|
|||
|
||||
/* Get the ip of friend friendnum and put it in ip_port
|
||||
*
|
||||
* return -1 on failure
|
||||
* return 0 on success
|
||||
* return -1, -- if client_id does NOT refer to a friend
|
||||
* return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
|
||||
* return 1, ip if client_id refers to a friend and we found him
|
||||
*
|
||||
*/
|
||||
int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
|
||||
|
@ -569,10 +677,31 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
|
|||
if (onion_c->friends_list[friend_num].status == 0)
|
||||
return -1;
|
||||
|
||||
if (DHT_getfriendip(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, ip_port) == 1)
|
||||
return 0;
|
||||
|
||||
if (!onion_c->friends_list[friend_num].is_fake_clientid)
|
||||
return -1;
|
||||
|
||||
return DHT_getfriendip(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, ip_port);
|
||||
}
|
||||
|
||||
/* Set if friend is online or not.
|
||||
* NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
|
||||
*
|
||||
* is_online 1 means friend is online.
|
||||
* is_online 0 means friend is offline
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_online)
|
||||
{
|
||||
if ((uint32_t)friend_num >= onion_c->num_friends)
|
||||
return -1;
|
||||
|
||||
onion_c->friends_list[friend_num].is_online = is_online;
|
||||
/* Should we reset the no_replay when the other goes offline?
|
||||
if (!is_online)
|
||||
onion_c->friends_list[friend_num].last_noreplay = 0; */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Takes 3 random nodes that we know and puts them in nodes
|
||||
|
@ -591,7 +720,7 @@ int random_path(Onion_Client *onion_c, Node_format *nodes)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define ANNOUNCE_FRIEND 30
|
||||
#define ANNOUNCE_FRIEND 120
|
||||
|
||||
static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
|
||||
{
|
||||
|
@ -604,6 +733,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
|
|||
uint32_t i, count = 0;
|
||||
Onion_Node *list_nodes = onion_c->friends_list[friendnum].clients_list;
|
||||
|
||||
if (!onion_c->friends_list[friendnum].is_online) {
|
||||
for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
|
||||
if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT))
|
||||
continue;
|
||||
|
@ -619,17 +749,23 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
|
|||
|
||||
if (count < MAX_ONION_CLIENTS / 2) {
|
||||
Node_format nodes_list[MAX_SENT_NODES];
|
||||
uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->friends_list[i].real_client_id, nodes_list,
|
||||
rand() % 2 ? AF_INET : AF_INET6, rand() % 2, 1);
|
||||
uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->friends_list[friendnum].real_client_id, nodes_list,
|
||||
rand() % 2 ? AF_INET : AF_INET6, 1, 0);
|
||||
|
||||
for (i = 0; i < num_nodes; ++i)
|
||||
client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0);
|
||||
}
|
||||
|
||||
|
||||
/* send packets to friend telling them our fake DHT id. */
|
||||
if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_sent, ONION_FAKEID_INTERVAL))
|
||||
if (send_fakeid_announce(onion_c, friendnum) > 3)
|
||||
onion_c->friends_list[friendnum].last_fakeid_sent = unix_time();
|
||||
if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_onion_sent, ONION_FAKEID_INTERVAL))
|
||||
if (send_fakeid_announce(onion_c, friendnum, 0) > 1)
|
||||
onion_c->friends_list[friendnum].last_fakeid_onion_sent = unix_time();
|
||||
|
||||
if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_dht_sent, DHT_FAKEID_INTERVAL))
|
||||
if (send_fakeid_announce(onion_c, friendnum, 1) > 1)
|
||||
onion_c->friends_list[friendnum].last_fakeid_dht_sent = unix_time();
|
||||
}
|
||||
}
|
||||
/* Function to call when onion data packet with contents beginning with byte is received. */
|
||||
void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object)
|
||||
|
@ -639,7 +775,7 @@ void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_ha
|
|||
}
|
||||
|
||||
#define ANNOUNCE_INTERVAL_NOT_ANNOUNCED 10
|
||||
#define ANNOUNCE_INTERVAL_ANNOUNCED 60
|
||||
#define ANNOUNCE_INTERVAL_ANNOUNCED 120
|
||||
|
||||
static void do_announce(Onion_Client *onion_c)
|
||||
{
|
||||
|
@ -653,7 +789,7 @@ static void do_announce(Onion_Client *onion_c)
|
|||
++count;
|
||||
uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;
|
||||
|
||||
if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) {
|
||||
if (list_nodes[i].is_stored) {
|
||||
interval = ANNOUNCE_INTERVAL_ANNOUNCED;
|
||||
}
|
||||
|
||||
|
@ -668,7 +804,7 @@ static void do_announce(Onion_Client *onion_c)
|
|||
if (count < MAX_ONION_CLIENTS / 2) {
|
||||
Node_format nodes_list[MAX_SENT_NODES];
|
||||
uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->dht->c->self_public_key, nodes_list,
|
||||
rand() % 2 ? AF_INET : AF_INET6, rand() % 2, 1);
|
||||
rand() % 2 ? AF_INET : AF_INET6, 1, 0);
|
||||
|
||||
for (i = 0; i < num_nodes; ++i)
|
||||
client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0);
|
||||
|
@ -704,16 +840,20 @@ Onion_Client *new_onion_client(DHT *dht)
|
|||
onion_c->dht = dht;
|
||||
onion_c->net = dht->c->lossless_udp->net;
|
||||
new_symmetric_key(onion_c->secret_symmetric_key);
|
||||
|
||||
crypto_box_keypair(onion_c->temp_public_key, onion_c->temp_secret_key);
|
||||
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c);
|
||||
networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
|
||||
oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c);
|
||||
cryptopacket_registerhandler(onion_c->dht->c, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c);
|
||||
|
||||
return onion_c;
|
||||
}
|
||||
|
||||
void kill_onion_client(Onion_Client *onion_c)
|
||||
{
|
||||
if (onion_c == NULL)
|
||||
return;
|
||||
|
||||
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL);
|
||||
networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL);
|
||||
free(onion_c);
|
||||
|
|
|
@ -27,15 +27,19 @@
|
|||
#include "onion_announce.h"
|
||||
|
||||
#define MAX_ONION_CLIENTS 8
|
||||
#define ONION_NODE_TIMEOUT 200
|
||||
#define ONION_NODE_TIMEOUT 240
|
||||
|
||||
/* The interval in seconds at which to tell our friends where we are */
|
||||
#define ONION_FAKEID_INTERVAL 60
|
||||
#define DHT_FAKEID_INTERVAL 20
|
||||
|
||||
typedef struct {
|
||||
uint8_t client_id[CLIENT_ID_SIZE];
|
||||
IP_Port ip_port;
|
||||
uint8_t ping_id[ONION_PING_ID_SIZE];
|
||||
uint8_t data_public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t is_stored;
|
||||
|
||||
uint64_t timestamp;
|
||||
|
||||
uint64_t last_pinged;
|
||||
|
@ -43,7 +47,9 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/
|
||||
uint8_t is_online; /* Set by the onion_set_friend_status function. */
|
||||
|
||||
uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */
|
||||
uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t real_client_id[crypto_box_PUBLICKEYBYTES];
|
||||
|
||||
|
@ -51,7 +57,10 @@ typedef struct {
|
|||
uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
|
||||
|
||||
uint64_t last_fakeid_sent;
|
||||
uint64_t last_fakeid_onion_sent;
|
||||
uint64_t last_fakeid_dht_sent;
|
||||
|
||||
uint64_t last_noreplay;
|
||||
} Onion_Friend;
|
||||
|
||||
typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
|
||||
|
@ -67,6 +76,8 @@ typedef struct {
|
|||
uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES];
|
||||
uint64_t last_run;
|
||||
|
||||
uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
|
||||
struct {
|
||||
oniondata_handler_callback function;
|
||||
void *object;
|
||||
|
@ -94,10 +105,22 @@ int onion_addfriend(Onion_Client *onion_c, uint8_t *client_id);
|
|||
*/
|
||||
int onion_delfriend(Onion_Client *onion_c, int friend_num);
|
||||
|
||||
/* Set if friend is online or not.
|
||||
* NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
|
||||
*
|
||||
* is_online 1 means friend is online.
|
||||
* is_online 0 means friend is offline
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_online);
|
||||
|
||||
/* Get the ip of friend friendnum and put it in ip_port
|
||||
*
|
||||
* return -1 on failure
|
||||
* return 0 on success
|
||||
* return -1, -- if client_id does NOT refer to a friend
|
||||
* return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
|
||||
* return 1, ip if client_id refers to a friend and we found him
|
||||
*
|
||||
*/
|
||||
int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
|
||||
|
|
|
@ -47,7 +47,7 @@ typedef struct {
|
|||
} pinged_t;
|
||||
|
||||
struct PING {
|
||||
Net_Crypto *c;
|
||||
DHT *dht;
|
||||
|
||||
pinged_t pings[PING_NUM_MAX];
|
||||
size_t num_pings;
|
||||
|
@ -148,19 +148,19 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
|
|||
int rc;
|
||||
uint64_t ping_id;
|
||||
|
||||
if (is_pinging(ping, ipp, 0) || id_equal(client_id, ping->c->self_public_key))
|
||||
if (is_pinging(ping, ipp, 0) || id_equal(client_id, ping->dht->self_public_key))
|
||||
return 1;
|
||||
|
||||
// Generate random ping_id.
|
||||
ping_id = add_ping(ping, ipp);
|
||||
|
||||
pk[0] = NET_PACKET_PING_REQUEST;
|
||||
id_copy(pk + 1, ping->c->self_public_key); // Our pubkey
|
||||
id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey
|
||||
new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
|
||||
|
||||
// Encrypt ping_id using recipient privkey
|
||||
rc = encrypt_data(client_id,
|
||||
ping->c->self_secret_key,
|
||||
ping->dht->self_secret_key,
|
||||
pk + 1 + CLIENT_ID_SIZE,
|
||||
(uint8_t *) &ping_id, sizeof(ping_id),
|
||||
pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES);
|
||||
|
@ -168,7 +168,7 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
|
|||
if (rc != sizeof(ping_id) + crypto_box_MACBYTES)
|
||||
return 1;
|
||||
|
||||
return sendpacket(ping->c->lossless_udp->net, ipp, pk, sizeof(pk));
|
||||
return sendpacket(ping->dht->net, ipp, pk, sizeof(pk));
|
||||
}
|
||||
|
||||
static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint64_t ping_id)
|
||||
|
@ -176,16 +176,16 @@ static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint6
|
|||
uint8_t pk[DHT_PING_SIZE];
|
||||
int rc;
|
||||
|
||||
if (id_equal(client_id, ping->c->self_public_key))
|
||||
if (id_equal(client_id, ping->dht->self_public_key))
|
||||
return 1;
|
||||
|
||||
pk[0] = NET_PACKET_PING_RESPONSE;
|
||||
id_copy(pk + 1, ping->c->self_public_key); // Our pubkey
|
||||
id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey
|
||||
new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
|
||||
|
||||
// Encrypt ping_id using recipient privkey
|
||||
rc = encrypt_data(client_id,
|
||||
ping->c->self_secret_key,
|
||||
ping->dht->self_secret_key,
|
||||
pk + 1 + CLIENT_ID_SIZE,
|
||||
(uint8_t *) &ping_id, sizeof(ping_id),
|
||||
pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES);
|
||||
|
@ -193,7 +193,7 @@ static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint6
|
|||
if (rc != sizeof(ping_id) + crypto_box_MACBYTES)
|
||||
return 1;
|
||||
|
||||
return sendpacket(ping->c->lossless_udp->net, ipp, pk, sizeof(pk));
|
||||
return sendpacket(ping->dht->net, ipp, pk, sizeof(pk));
|
||||
}
|
||||
|
||||
static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint32_t length)
|
||||
|
@ -207,12 +207,12 @@ static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint
|
|||
|
||||
PING *ping = dht->ping;
|
||||
|
||||
if (id_equal(packet + 1, ping->c->self_public_key))
|
||||
if (id_equal(packet + 1, ping->dht->self_public_key))
|
||||
return 1;
|
||||
|
||||
// Decrypt ping_id
|
||||
rc = decrypt_data(packet + 1,
|
||||
ping->c->self_secret_key,
|
||||
ping->dht->self_secret_key,
|
||||
packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
sizeof(ping_id) + crypto_box_MACBYTES,
|
||||
|
@ -239,12 +239,12 @@ static int handle_ping_response(void *_dht, IP_Port source, uint8_t *packet, uin
|
|||
|
||||
PING *ping = dht->ping;
|
||||
|
||||
if (id_equal(packet + 1, ping->c->self_public_key))
|
||||
if (id_equal(packet + 1, ping->dht->self_public_key))
|
||||
return 1;
|
||||
|
||||
// Decrypt ping_id
|
||||
rc = decrypt_data(packet + 1,
|
||||
ping->c->self_secret_key,
|
||||
ping->dht->self_secret_key,
|
||||
packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
sizeof(ping_id) + crypto_box_MACBYTES,
|
||||
|
@ -291,7 +291,7 @@ int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port)
|
|||
}
|
||||
|
||||
for (i = 0; i < MAX_TOPING; ++i) {
|
||||
if (id_closest(ping->c->self_public_key, ping->toping[i].client_id, client_id) == 2) {
|
||||
if (id_closest(ping->dht->self_public_key, ping->toping[i].client_id, client_id) == 2) {
|
||||
memcpy(ping->toping[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||
ipport_copy(&ping->toping[i].ip_port, &ip_port);
|
||||
return 0;
|
||||
|
@ -323,24 +323,24 @@ void do_toping(PING *ping)
|
|||
}
|
||||
|
||||
|
||||
PING *new_ping(DHT *dht, Net_Crypto *c)
|
||||
PING *new_ping(DHT *dht)
|
||||
{
|
||||
PING *ping = calloc(1, sizeof(PING));
|
||||
|
||||
if (ping == NULL)
|
||||
return NULL;
|
||||
|
||||
ping->c = c;
|
||||
networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
|
||||
networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);
|
||||
ping->dht = dht;
|
||||
networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
|
||||
networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);
|
||||
|
||||
return ping;
|
||||
}
|
||||
|
||||
void kill_ping(PING *ping)
|
||||
{
|
||||
networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_REQUEST, NULL, NULL);
|
||||
networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_RESPONSE, NULL, NULL);
|
||||
networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, NULL, NULL);
|
||||
networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, NULL, NULL);
|
||||
|
||||
free(ping);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef struct PING PING;
|
|||
int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port);
|
||||
void do_toping(PING *ping);
|
||||
|
||||
PING *new_ping(DHT *dht, Net_Crypto *c);
|
||||
PING *new_ping(DHT *dht);
|
||||
void kill_ping(PING *ping);
|
||||
|
||||
int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id);
|
||||
|
|
|
@ -65,6 +65,25 @@ uint32_t id_copy(uint8_t *dest, uint8_t *src)
|
|||
return CLIENT_ID_SIZE;
|
||||
}
|
||||
|
||||
void host_to_net(uint8_t *num, uint16_t numbytes)
|
||||
{
|
||||
union {
|
||||
uint32_t i;
|
||||
uint8_t c[4];
|
||||
} a;
|
||||
a.i = 1;
|
||||
|
||||
if (a.c[0] == 1) {
|
||||
uint32_t i;
|
||||
uint8_t buff[numbytes];
|
||||
|
||||
for (i = 0; i < numbytes; ++i) {
|
||||
buff[i] = num[numbytes - i - 1];
|
||||
}
|
||||
|
||||
memcpy(num, buff, numbytes);
|
||||
}
|
||||
}
|
||||
|
||||
/* state load/save */
|
||||
int load_state(load_state_callback_func load_state_callback, void *outer,
|
||||
|
|
|
@ -37,6 +37,8 @@ int is_timeout(uint64_t timestamp, uint64_t timeout);
|
|||
bool id_equal(uint8_t *dest, uint8_t *src);
|
||||
uint32_t id_copy(uint8_t *dest, uint8_t *src); /* return value is CLIENT_ID_SIZE */
|
||||
|
||||
void host_to_net(uint8_t *num, uint16_t numbytes);
|
||||
#define net_to_host(x, y) host_to_net(x, y)
|
||||
|
||||
/* state load/save */
|
||||
typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type);
|
||||
|
|
Loading…
Reference in New Issue
Block a user