From cebae58ddc492869b627eb7b69c7565084a74a34 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Wed, 26 Feb 2014 12:18:47 -0500 Subject: Major speed/cpu usage/bandwidth improvements to onion. --- toxcore/onion.c | 79 +++++++++++++++++++++--------- toxcore/onion.h | 29 +++++++++-- toxcore/onion_announce.c | 21 ++++---- toxcore/onion_announce.h | 15 +++--- toxcore/onion_client.c | 122 +++++++++++++++++++++++++++++++++-------------- toxcore/onion_client.h | 27 +++++++---- 6 files changed, 202 insertions(+), 91 deletions(-) (limited to 'toxcore') diff --git a/toxcore/onion.c b/toxcore/onion.c index 578621cc..57001784 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -47,48 +47,81 @@ static void change_symmetric_key(Onion *onion) } } +/* Create a new onion path. + * + * Create a new onion path out of nodes (nodes is a list of 3 nodes) + * + * new_path must be an empty memory location of atleast Onion_Path size. + * + * return -1 on failure. + * return 0 on success. + */ +int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes) +{ + if (!new_path || !nodes) + return -1; + + encrypt_precompute(nodes[0].client_id, dht->self_secret_key, new_path->shared_key1); + memcpy(new_path->public_key1, dht->self_public_key, crypto_box_PUBLICKEYBYTES); + + uint8_t random_public_key[crypto_box_PUBLICKEYBYTES]; + uint8_t random_secret_key[crypto_box_SECRETKEYBYTES]; + + crypto_box_keypair(random_public_key, random_secret_key); + encrypt_precompute(nodes[1].client_id, random_secret_key, new_path->shared_key2); + memcpy(new_path->public_key2, random_public_key, crypto_box_PUBLICKEYBYTES); + + crypto_box_keypair(random_public_key, random_secret_key); + encrypt_precompute(nodes[2].client_id, random_secret_key, new_path->shared_key3); + memcpy(new_path->public_key3, random_public_key, crypto_box_PUBLICKEYBYTES); + + new_path->ip_port1 = nodes[0].ip_port; + new_path->ip_port2 = nodes[1].ip_port; + new_path->ip_port3 = nodes[2].ip_port; + + /* to_net_family(&new_path->ip_port1.ip); */ + to_net_family(&new_path->ip_port2.ip); + to_net_family(&new_path->ip_port3.ip); + + return 0; +} + /* Create and send a onion packet. * - * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the data - * with length length will arrive at 3. + * Use Onion_Path path to send data of length to dest. * * return -1 on failure. * return 0 on success. */ -int send_onion_packet(DHT *dht, Node_format *nodes, uint8_t *data, uint32_t length) +int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length) { if (1 + length + SEND_1 > MAX_ONION_SIZE || length == 0) return -1; + to_net_family(&dest.ip); uint8_t step1[sizeof(IP_Port) + length]; - to_net_family(&nodes[3].ip_port.ip); - memcpy(step1, &nodes[3].ip_port, sizeof(IP_Port)); + + memcpy(step1, &dest, sizeof(IP_Port)); memcpy(step1 + sizeof(IP_Port), data, length); uint8_t nonce[crypto_box_NONCEBYTES]; random_nonce(nonce); - uint8_t random_public_key[crypto_box_PUBLICKEYBYTES]; - uint8_t random_secret_key[crypto_box_SECRETKEYBYTES]; - crypto_box_keypair(random_public_key, random_secret_key); uint8_t step2[sizeof(IP_Port) + SEND_BASE + length]; - to_net_family(&nodes[2].ip_port.ip); - memcpy(step2, &nodes[2].ip_port, sizeof(IP_Port)); - memcpy(step2 + sizeof(IP_Port), random_public_key, crypto_box_PUBLICKEYBYTES); + memcpy(step2, &path->ip_port3, sizeof(IP_Port)); + memcpy(step2 + sizeof(IP_Port), path->public_key3, crypto_box_PUBLICKEYBYTES); - int len = encrypt_data(nodes[2].client_id, random_secret_key, nonce, - step1, sizeof(step1), step2 + sizeof(IP_Port) + crypto_box_PUBLICKEYBYTES); + int len = encrypt_data_fast(path->shared_key3, nonce, step1, sizeof(step1), + step2 + sizeof(IP_Port) + crypto_box_PUBLICKEYBYTES); if ((uint32_t)len != sizeof(IP_Port) + length + crypto_box_MACBYTES) return -1; - crypto_box_keypair(random_public_key, random_secret_key); uint8_t step3[sizeof(IP_Port) + SEND_BASE * 2 + length]; - to_net_family(&nodes[1].ip_port.ip); - memcpy(step3, &nodes[1].ip_port, sizeof(IP_Port)); - memcpy(step3 + sizeof(IP_Port), random_public_key, crypto_box_PUBLICKEYBYTES); - len = encrypt_data(nodes[1].client_id, random_secret_key, nonce, - step2, sizeof(step2), step3 + sizeof(IP_Port) + crypto_box_PUBLICKEYBYTES); + memcpy(step3, &path->ip_port2, sizeof(IP_Port)); + memcpy(step3 + sizeof(IP_Port), path->public_key2, crypto_box_PUBLICKEYBYTES); + len = encrypt_data_fast(path->shared_key2, nonce, step2, sizeof(step2), + step3 + sizeof(IP_Port) + crypto_box_PUBLICKEYBYTES); if ((uint32_t)len != sizeof(IP_Port) + SEND_BASE + length + crypto_box_MACBYTES) return -1; @@ -96,15 +129,15 @@ int send_onion_packet(DHT *dht, Node_format *nodes, uint8_t *data, uint32_t leng uint8_t packet[1 + length + SEND_1]; packet[0] = NET_PACKET_ONION_SEND_INITIAL; memcpy(packet + 1, nonce, crypto_box_NONCEBYTES); - memcpy(packet + 1 + crypto_box_NONCEBYTES, dht->self_public_key, crypto_box_PUBLICKEYBYTES); + memcpy(packet + 1 + crypto_box_NONCEBYTES, path->public_key1, crypto_box_PUBLICKEYBYTES); - len = encrypt_data(nodes[0].client_id, dht->self_secret_key, nonce, - step3, sizeof(step3), packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); + len = encrypt_data_fast(path->shared_key1, nonce, step3, sizeof(step3), + packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); if ((uint32_t)len != sizeof(IP_Port) + SEND_BASE * 2 + length + crypto_box_MACBYTES) return -1; - if ((uint32_t)sendpacket(dht->c->lossless_udp->net, nodes[0].ip_port, packet, sizeof(packet)) != sizeof(packet)) + if ((uint32_t)sendpacket(net, path->ip_port1, packet, sizeof(packet)) != sizeof(packet)) return -1; return 0; diff --git a/toxcore/onion.h b/toxcore/onion.h index a52bcb86..951a5d1f 100644 --- a/toxcore/onion.h +++ b/toxcore/onion.h @@ -41,16 +41,39 @@ typedef struct { #define ONION_SEND_2 (crypto_box_NONCEBYTES + ONION_SEND_BASE*2 + ONION_RETURN_1) #define ONION_SEND_1 (crypto_box_NONCEBYTES + ONION_SEND_BASE*3) +typedef struct { + uint8_t shared_key1[crypto_box_BEFORENMBYTES]; + uint8_t shared_key2[crypto_box_BEFORENMBYTES]; + uint8_t shared_key3[crypto_box_BEFORENMBYTES]; + + uint8_t public_key1[crypto_box_PUBLICKEYBYTES]; + uint8_t public_key2[crypto_box_PUBLICKEYBYTES]; + uint8_t public_key3[crypto_box_PUBLICKEYBYTES]; + + IP_Port ip_port1; + IP_Port ip_port2; + IP_Port ip_port3; +} Onion_Path; + +/* Create a new onion path. + * + * Create a new onion path out of nodes (nodes is a list of 3 nodes) + * + * new_path must be an empty memory location of atleast Onion_Path size. + * + * return -1 on failure. + * return 0 on success. + */ +int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes); /* Create and send a onion packet. * - * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the data - * with length length will arrive at 3. + * Use Onion_Path path to send data of length to dest. * * return -1 on failure. * return 0 on success. */ -int send_onion_packet(DHT *dht, Node_format *nodes, uint8_t *data, uint32_t length); +int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length); /* Create and send a onion response sent initially to dest with. * diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index 28e27d91..481e995c 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -37,8 +37,7 @@ /* Create and send an onion announce request packet. * - * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the announe - * request will be sent to 3. + * path is the path the request will take before it is sent to dest. * * public_key and secret_key is the kepair which will be used to encrypt the request. * ping_id is the ping id that will be sent in the request. @@ -50,8 +49,8 @@ * return -1 on failure. * 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 *data_public_key, uint8_t *sendback_data) +int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key, + uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data) { uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; memcpy(plain, ping_id, ONION_PING_ID_SIZE); @@ -63,7 +62,7 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin packet[0] = NET_PACKET_ANNOUNCE_REQUEST; random_nonce(packet + 1); - int len = encrypt_data(nodes[3].client_id, secret_key, packet + 1, plain, sizeof(plain), + int len = encrypt_data(dest.client_id, secret_key, packet + 1, plain, sizeof(plain), packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); if ((uint32_t)len + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES != ANNOUNCE_REQUEST_SIZE) @@ -71,13 +70,13 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin memcpy(packet + 1 + crypto_box_NONCEBYTES, public_key, crypto_box_PUBLICKEYBYTES); - return send_onion_packet(dht, nodes, packet, sizeof(packet)); + return send_onion_packet(net, path, dest.ip_port, packet, sizeof(packet)); } /* Create and send an onion data request packet. * - * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the data - * request packet will arrive at 3. (if 3 knows the person with the public_key they should + * path is the path the request will take before it is sent to dest. + * (if dest knows the person with the public_key they should * send the packet to that person in the form of a response) * * public_key is the real public key of the node which we want to send the data of length length to. @@ -88,8 +87,8 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin * return -1 on failure. * return 0 on success. */ -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) +int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key, + uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length) { uint8_t packet[DATA_REQUEST_MIN_SIZE + length]; packet[0] = NET_PACKET_ONION_DATA_REQUEST; @@ -108,7 +107,7 @@ int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(packet)) return -1; - return send_onion_packet(dht, nodes, packet, sizeof(packet)); + return send_onion_packet(net, path, dest, packet, sizeof(packet)); } /* Generate a ping_id and put it in ping_id */ diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 27b25bd4..24240436 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -58,8 +58,7 @@ typedef struct { /* Create and send an onion announce request packet. * - * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the announe - * request will be sent to 3. + * path is the path the request will take before it is sent to dest. * * public_key and secret_key is the kepair which will be used to encrypt the request. * ping_id is the ping id that will be sent in the request. @@ -71,13 +70,13 @@ typedef struct { * return -1 on failure. * 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 *data_public_key, uint8_t *sendback_data); +int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key, + uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data); /* Create and send an onion data request packet. * - * nodes is a list of 4 nodes, the packet will route through nodes 0, 1, 2 and the data - * request packet will arrive at 3. (if 3 knows the person with the public_key they should + * path is the path the request will take before it is sent to dest. + * (if dest knows the person with the public_key they should * send the packet to that person in the form of a response) * * public_key is the real public key of the node which we want to send the data of length length to. @@ -88,8 +87,8 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin * return -1 on failure. * return 0 on success. */ -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); +int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key, + uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length); Onion_Announce *new_onion_announce(DHT *dht); diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index b3c665b7..6d7785f3 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -30,6 +30,63 @@ #define ANNOUNCE_TIMEOUT 10 +/* Create a new path or use an old suitable one (if pathnum is valid) + * or a rondom one from onion_paths. + * + * return -1 on failure + * return 0 on success + * + * TODO: Make this function better, it currently probably is vulnerable to some attacks that + * could de anonimize us. + */ +static int random_path(DHT *dht, Onion_Client_Paths *onion_paths, uint32_t pathnum, Onion_Path *path) +{ + if (pathnum >= NUMBER_ONION_PATHS) + pathnum = rand() % NUMBER_ONION_PATHS; + + if (is_timeout(onion_paths->last_path_success[pathnum], ONION_PATH_TIMEOUT)) { + Node_format nodes[3]; + + if (random_nodes_path(dht, nodes, 3) != 3) + return -1; + + if (create_onion_path(dht, &onion_paths->paths[pathnum], nodes) == -1) + return -1; + + onion_paths->last_path_success[pathnum] = unix_time() + ONION_PATH_FIRST_TIMEOUT - ONION_PATH_TIMEOUT; + } + + memcpy(path, &onion_paths->paths[pathnum], sizeof(Onion_Path)); + return 0; +} + +/* Set path timeouts, return the path number. + * + */ +static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, IP_Port source) +{ + if (num > onion_c->num_friends) + return -1; + + Onion_Client_Paths *onion_paths; + + if (num == 0) { + onion_paths = &onion_c->onion_paths; + } else { + onion_paths = &onion_c->friends_list[num - 1].onion_paths; + } + + uint32_t i; + + for (i = 0; i < NUMBER_ONION_PATHS; ++i) { + if (ipport_equal(&onion_paths->paths[i].ip_port1, &source)) { + onion_paths->last_path_success[i] = unix_time(); + return i; + } + } + + return ~0; +} /* Creates a sendback for use in an announce request. * @@ -99,7 +156,7 @@ static uint32_t check_sendback(Onion_Client *onion_c, uint8_t *sendback, uint8_t } static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_Port dest, uint8_t *dest_pubkey, - uint8_t *ping_id) + uint8_t *ping_id, uint32_t pathnum) { if (num > onion_c->num_friends) return -1; @@ -114,20 +171,24 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_ if (ping_id == NULL) ping_id = zero_ping_id; - Node_format nodes[4]; - - if (random_path(onion_c, nodes) == -1) - return -1; + Onion_Path path; - nodes[3].ip_port = dest; - memcpy(nodes[3].client_id, dest_pubkey, crypto_box_PUBLICKEYBYTES); + Node_format dest_node; + dest_node.ip_port = dest; + memcpy(dest_node.client_id, dest_pubkey, crypto_box_PUBLICKEYBYTES); if (num == 0) { - return send_announce_request(onion_c->dht, nodes, onion_c->dht->c->self_public_key, + if (random_path(onion_c->dht, &onion_c->onion_paths, pathnum, &path) == -1) + return -1; + + return send_announce_request(onion_c->net, &path, dest_node, onion_c->dht->c->self_public_key, onion_c->dht->c->self_secret_key, ping_id, 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, + if (random_path(onion_c->dht, &onion_c->friends_list[num - 1].onion_paths, pathnum, &path) == -1) + return -1; + + return send_announce_request(onion_c->net, &path, dest_node, onion_c->friends_list[num - 1].temp_public_key, onion_c->friends_list[num - 1].temp_secret_key, ping_id, onion_c->friends_list[num - 1].real_client_id, zero_ping_id, sendback); } @@ -163,7 +224,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 is_stored, uint8_t *pingid_or_key) + uint8_t is_stored, uint8_t *pingid_or_key, IP_Port source) { if (num > onion_c->num_friends) return -1; @@ -223,7 +284,8 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ list_nodes[index].is_stored = is_stored; list_nodes[index].timestamp = unix_time(); - list_nodes[index].last_pinged = 0; + list_nodes[index].last_pinged = unix_time(); + list_nodes[index].path_used = set_path_timeouts(onion_c, num, source); return 0; } @@ -267,7 +329,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n } if (j == MAX_ONION_CLIENTS) { - client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL); + client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL, ~0); } } } @@ -315,7 +377,7 @@ 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[0], plain + 1) == -1) + if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1, source) == -1) return 1; Node_format nodes[MAX_SENT_NODES]; @@ -457,13 +519,15 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32 if (list_nodes[i].is_stored) { Node_format nodes[4]; - if (random_path(onion_c, nodes) == -1) + Onion_Path path; + + if (random_path(onion_c->dht, &onion_c->friends_list[friend_num].onion_paths, ~0, &path) == -1) continue; 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, + if (send_data_request(onion_c->net, &path, list_nodes[i].ip_port, onion_c->friends_list[friend_num].real_client_id, list_nodes[i].data_public_key, nonce, packet, sizeof(packet)) == 0) ++good; } @@ -731,23 +795,6 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on return 0; } -/* Takes 3 random nodes that we know and puts them in nodes - * - * nodes must be longer than 3. - * - * return -1 on failure - * return 0 on success - * - * TODO: Make this function better, it currently might be vulnerable to some attacks that - * could de anonimize us. - */ -int random_path(Onion_Client *onion_c, Node_format *nodes) -{ - if (random_nodes_path(onion_c->dht, nodes, 3) != 3) - return -1; - - return 0; -} #define ANNOUNCE_FRIEND 30 @@ -770,7 +817,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum) ++count; if (is_timeout(list_nodes[i].last_pinged, ANNOUNCE_FRIEND)) { - if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0) == 0) { + if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0, ~0) == 0) { list_nodes[i].last_pinged = unix_time(); } } @@ -783,7 +830,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum) 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); + client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0, ~0); } } @@ -845,7 +892,7 @@ static void do_announce(Onion_Client *onion_c) if (is_timeout(list_nodes[i].last_pinged, interval)) { if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].client_id, - list_nodes[i].ping_id) == 0) { + list_nodes[i].ping_id, list_nodes[i].path_used) == 0) { list_nodes[i].last_pinged = unix_time(); } } @@ -857,8 +904,9 @@ static void do_announce(Onion_Client *onion_c) 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, 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); + 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, ~0); + } } } } diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index 36b5b5c3..d14406a2 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h @@ -33,6 +33,13 @@ #define ONION_FAKEID_INTERVAL 30 #define DHT_FAKEID_INTERVAL 20 +#define NUMBER_ONION_PATHS 3 + +/* The timeout the first time the path is added and + then for all the next consecutive times */ +#define ONION_PATH_FIRST_TIMEOUT 5 +#define ONION_PATH_TIMEOUT 30 + typedef struct { uint8_t client_id[CLIENT_ID_SIZE]; IP_Port ip_port; @@ -43,8 +50,15 @@ typedef struct { uint64_t timestamp; uint64_t last_pinged; + + uint32_t path_used; } Onion_Node; +typedef struct { + Onion_Path paths[NUMBER_ONION_PATHS]; + uint64_t last_path_success[NUMBER_ONION_PATHS]; +} Onion_Client_Paths; + 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. */ @@ -63,6 +77,8 @@ typedef struct { uint64_t last_noreplay; uint64_t last_seen; + + Onion_Client_Paths onion_paths; } Onion_Friend; typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len); @@ -75,6 +91,8 @@ typedef struct { Onion_Node clients_announce_list[MAX_ONION_CLIENTS]; + Onion_Client_Paths onion_paths; + uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES]; uint64_t last_run; @@ -127,15 +145,6 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on */ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); -/* Takes 3 random nodes that we know and puts them in nodes - * - * nodes must be longer than 3. - * - * return -1 on failure - * return 0 on success - * - */ -int random_path(Onion_Client *onion_c, Node_format *nodes); /* Send data of length length to friendnum. * This data will be recieved by the friend using the Onion_Data_Handlers callbacks. -- cgit v1.2.3