mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Some work done on onion_client
This commit is contained in:
parent
94b5e55189
commit
dac7fe0338
|
@ -27,7 +27,7 @@
|
||||||
#include "LAN_discovery.h"
|
#include "LAN_discovery.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define PING_ID_TIMEOUT 10
|
#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 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES)
|
||||||
#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3)
|
#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3)
|
||||||
|
@ -135,7 +135,7 @@ static int in_entries(Onion_Announce *onion_a, uint8_t *public_key)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t cmp_public_key[crypto_box_PUBLICKEYBYTES];
|
static uint8_t cmp_public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
static int cmp_entry(const void *a, const void *b)
|
static int cmp_entry(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
Onion_Announce_Entry entry1, entry2;
|
Onion_Announce_Entry entry1, entry2;
|
||||||
|
@ -237,13 +237,16 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
|
||||||
uint32_t num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, source.ip.family,
|
uint32_t num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, source.ip.family,
|
||||||
LAN_ip(source.ip) == 0, 1);
|
LAN_ip(source.ip) == 0, 1);
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_nodes; ++i)
|
||||||
|
to_net_family(&nodes_list[i].ip_port.ip);
|
||||||
|
|
||||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||||
new_nonce(nonce);
|
new_nonce(nonce);
|
||||||
|
|
||||||
uint8_t pl[ONION_PING_ID_SIZE + sizeof(nodes_list)] = {0};
|
uint8_t pl[ONION_PING_ID_SIZE + sizeof(nodes_list)] = {0};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!stored) {
|
if (!stored) {
|
||||||
memcpy(pl, ping_id2, ONION_PING_ID_SIZE);
|
memcpy(pl, ping_id2, ONION_PING_ID_SIZE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#define ONION_ANNOUNCE_TIMEOUT 300
|
#define ONION_ANNOUNCE_TIMEOUT 300
|
||||||
#define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES
|
#define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES
|
||||||
|
|
||||||
#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + crypto_secretbox_MACBYTES)
|
#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 + 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_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES)
|
||||||
|
|
|
@ -26,15 +26,19 @@
|
||||||
|
|
||||||
#include "onion_client.h"
|
#include "onion_client.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "LAN_discovery.h"
|
||||||
|
|
||||||
#define ANNOUNCE_TIMEOUT 10
|
#define ANNOUNCE_TIMEOUT 10
|
||||||
|
|
||||||
|
|
||||||
/* Creates a sendback for use in an announce request.
|
/* Creates a sendback for use in an announce request.
|
||||||
*
|
*
|
||||||
* num is 0 if we used our secret public key for the announce
|
* num is 0 if we used our secret public key for the announce
|
||||||
* num is 1 + friendnum if we use a temporary one.
|
* num is 1 + friendnum if we use a temporary one.
|
||||||
*
|
*
|
||||||
* Public key is the key we will be sending it to.
|
* Public key is the key we will be sending it to.
|
||||||
|
* ip_port is the ip_port of the node we will be sending
|
||||||
|
* it to.
|
||||||
*
|
*
|
||||||
* sendback must be at least ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
|
* sendback must be at least ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
|
||||||
*
|
*
|
||||||
|
@ -42,13 +46,15 @@
|
||||||
* return 0 on success
|
* return 0 on success
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int new_sendback(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, uint8_t *sendback)
|
static int new_sendback(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, uint8_t *sendback)
|
||||||
{
|
{
|
||||||
uint8_t plain[sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES];
|
uint8_t plain[sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port)];
|
||||||
uint64_t time = unix_time();
|
uint64_t time = unix_time();
|
||||||
|
new_nonce(sendback);
|
||||||
memcpy(plain, &num, sizeof(uint32_t));
|
memcpy(plain, &num, sizeof(uint32_t));
|
||||||
memcpy(plain + sizeof(uint32_t), &time, sizeof(uint64_t));
|
memcpy(plain + sizeof(uint32_t), &time, sizeof(uint64_t));
|
||||||
memcpy(plain + sizeof(uint32_t) + sizeof(uint64_t), public_key, crypto_box_PUBLICKEYBYTES);
|
memcpy(plain + sizeof(uint32_t) + sizeof(uint64_t), public_key, crypto_box_PUBLICKEYBYTES);
|
||||||
|
memcpy(plain + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, &ip_port, sizeof(IP_Port));
|
||||||
|
|
||||||
int len = encrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, plain, sizeof(plain),
|
int len = encrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, plain, sizeof(plain),
|
||||||
sendback + crypto_secretbox_NONCEBYTES);
|
sendback + crypto_secretbox_NONCEBYTES);
|
||||||
|
@ -59,34 +65,37 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, uint8_t *public_key
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checks if the sendback is valid and returns the public key contained in it in returned_pubkey
|
/* Checks if the sendback is valid and returns the public key contained in it in ret_pubkey and the
|
||||||
|
* ip contained in it in ret_ip_port
|
||||||
*
|
*
|
||||||
* sendback is the sendback ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
|
* sendback is the sendback ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
|
||||||
* returned_pubkey must be at least crypto_box_PUBLICKEYBYTES big
|
* ret_pubkey must be at least crypto_box_PUBLICKEYBYTES big
|
||||||
|
* ret_ip_port must be at least 1 big
|
||||||
*
|
*
|
||||||
* return ~0 on failure
|
* return ~0 on failure
|
||||||
* return num (see new_sendback(...)) on success
|
* return num (see new_sendback(...)) on success
|
||||||
*/
|
*/
|
||||||
static uint32_t check_sendback(Onion_Client *onion_c, uint8_t *sendback, uint8_t *returned_pubkey)
|
static uint32_t check_sendback(Onion_Client *onion_c, uint8_t *sendback, uint8_t *ret_pubkey, IP_Port *ret_ip_port)
|
||||||
{
|
{
|
||||||
uint8_t plain[sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES];
|
uint8_t plain[sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port)];
|
||||||
int len = decrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, sendback + crypto_secretbox_NONCEBYTES,
|
int len = decrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, sendback + crypto_secretbox_NONCEBYTES,
|
||||||
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH - crypto_secretbox_NONCEBYTES, plain);
|
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH - crypto_secretbox_NONCEBYTES, plain);
|
||||||
|
|
||||||
if ((uint32_t)len != sizeof(plain))
|
if ((uint32_t)len != sizeof(plain))
|
||||||
return -1;
|
return ~0;
|
||||||
|
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
memcpy(×tamp, plain + sizeof(uint32_t), sizeof(uint64_t));
|
memcpy(×tamp, plain + sizeof(uint32_t), sizeof(uint64_t));
|
||||||
uint64_t temp_time = unix_time();
|
uint64_t temp_time = unix_time();
|
||||||
|
|
||||||
if (timestamp + ANNOUNCE_TIMEOUT < temp_time || temp_time < timestamp)
|
if (timestamp + ANNOUNCE_TIMEOUT < temp_time || temp_time < timestamp)
|
||||||
return -1;
|
return ~0;
|
||||||
|
|
||||||
memcpy(returned_pubkey, plain + sizeof(uint32_t) + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
|
memcpy(ret_pubkey, plain + sizeof(uint32_t) + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
|
||||||
|
memcpy(ret_ip_port, plain + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, sizeof(IP_Port));
|
||||||
uint32_t num;
|
uint32_t num;
|
||||||
memcpy(&num, plain, sizeof(uint32_t));
|
memcpy(&num, plain, sizeof(uint32_t));
|
||||||
return plain[0];
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_Port dest, uint8_t *dest_pubkey,
|
static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_Port dest, uint8_t *dest_pubkey,
|
||||||
|
@ -97,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];
|
uint8_t sendback[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
|
||||||
|
|
||||||
if (new_sendback(onion_c, 0, dest_pubkey, sendback) == -1)
|
if (new_sendback(onion_c, 0, dest_pubkey, dest, sendback) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0};
|
uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0};
|
||||||
|
@ -124,14 +133,84 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port,
|
static uint8_t cmp_public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
uint8_t *ping_id)
|
static int cmp_entry(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
|
Onion_Node entry1, entry2;
|
||||||
|
memcpy(&entry1, a, sizeof(Onion_Node));
|
||||||
|
memcpy(&entry2, b, sizeof(Onion_Node));
|
||||||
|
int t1 = is_timeout(entry1.timestamp, ONION_NODE_TIMEOUT);
|
||||||
|
int t2 = is_timeout(entry2.timestamp, ONION_NODE_TIMEOUT);
|
||||||
|
|
||||||
|
if (t1 && t2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (t1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (t2)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int close = id_closest(cmp_public_key, entry1.client_id, entry2.client_id);
|
||||||
|
|
||||||
|
if (close == 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (close == 2)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *nodes, uint16_t num_nodes)
|
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)
|
||||||
|
{
|
||||||
|
if (num > onion_c->num_friends)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
Onion_Node *list_nodes = NULL;
|
||||||
|
uint8_t *reference_id = NULL;
|
||||||
|
|
||||||
|
if (num == 0) {
|
||||||
|
list_nodes = onion_c->clients_announce_list;
|
||||||
|
reference_id = onion_c->dht->c->self_public_key;
|
||||||
|
} else {
|
||||||
|
list_nodes = onion_c->friends_list[num - 1].clients_list;
|
||||||
|
reference_id = onion_c->friends_list[num - 1].real_client_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(cmp_public_key, reference_id, crypto_box_PUBLICKEYBYTES);
|
||||||
|
qsort(list_nodes, MAX_ONION_CLIENTS, sizeof(Onion_Node), cmp_entry);
|
||||||
|
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT)
|
||||||
|
|| id_closest(reference_id, list_nodes[0].client_id, public_key) == 2) {
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
|
||||||
|
if (memcmp(list_nodes[i].client_id, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
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);
|
||||||
|
list_nodes[index].timestamp = unix_time();
|
||||||
|
list_nodes[index].last_pinged = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *nodes, uint16_t num_nodes,
|
||||||
|
IP_Port source)
|
||||||
{
|
{
|
||||||
if (num > onion_c->num_friends)
|
if (num > onion_c->num_friends)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -151,8 +230,15 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
int lan_ips_accepted = (LAN_ip(source.ip) == 0);
|
||||||
|
|
||||||
for (i = 0; i < num_nodes; ++i) {
|
for (i = 0; i < num_nodes; ++i) {
|
||||||
|
to_host_family(&nodes[i].ip_port.ip);
|
||||||
|
|
||||||
|
if (!lan_ips_accepted)
|
||||||
|
if (LAN_ip(nodes[i].ip_port.ip) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT)
|
if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT)
|
||||||
|| id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) {
|
|| id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) {
|
||||||
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);
|
||||||
|
@ -175,8 +261,8 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
|
||||||
uint16_t num_nodes = (length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE) / sizeof(Node_format);
|
uint16_t num_nodes = (length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE) / sizeof(Node_format);
|
||||||
|
|
||||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
|
IP_Port ip_port;
|
||||||
uint32_t num = check_sendback(onion_c, packet + 1, public_key);
|
uint32_t num = check_sendback(onion_c, packet + 1, public_key, &ip_port);
|
||||||
|
|
||||||
if (num > onion_c->num_friends)
|
if (num > onion_c->num_friends)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -201,11 +287,11 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
|
||||||
if ((uint32_t)len != sizeof(plain))
|
if ((uint32_t)len != sizeof(plain))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
//TODO
|
|
||||||
//if (client_add_to_list(onion_c, num, uint8_t *public_key, IP_Port ip_port, plain) == -1)
|
|
||||||
// return 1;
|
|
||||||
|
|
||||||
if (client_ping_nodes(onion_c, num, (Node_format *)plain + ONION_PING_ID_SIZE, num_nodes) == -1)
|
if (client_add_to_list(onion_c, num, public_key, ip_port, plain) == -1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (client_ping_nodes(onion_c, num, (Node_format *)plain + ONION_PING_ID_SIZE, num_nodes, source) == -1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -232,18 +318,37 @@ int random_path(Onion_Client *onion_c, Node_format *nodes)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t zero_ping[ONION_PING_ID_SIZE];
|
||||||
static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
|
static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ANNOUNCE_INTERVAL_NOT_ANNOUNCED 10
|
||||||
|
#define ANNOUNCE_INTERVAL_ANNOUNCED 60
|
||||||
|
|
||||||
static void do_announce(Onion_Client *onion_c)
|
static void do_announce(Onion_Client *onion_c)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
Onion_Node *list_nodes = onion_c->clients_announce_list;
|
||||||
|
|
||||||
for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
|
for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
|
||||||
|
if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;
|
||||||
|
|
||||||
|
if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) {
|
||||||
|
interval = ANNOUNCE_INTERVAL_ANNOUNCED;
|
||||||
|
}
|
||||||
|
|
||||||
|
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].last_pinged = unix_time();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@ typedef struct {
|
||||||
IP_Port ip_port;
|
IP_Port ip_port;
|
||||||
uint8_t ping_id[ONION_PING_ID_SIZE];
|
uint8_t ping_id[ONION_PING_ID_SIZE];
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
|
|
||||||
|
uint64_t last_pinged;
|
||||||
} Onion_Node;
|
} Onion_Node;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user