mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
cleanup: Remove hardening code from DHT
This commit is contained in:
parent
eb4dc4326a
commit
64a48c0e78
|
@ -31,25 +31,11 @@ static inline IP get_loopback(void)
|
|||
static void mark_bad(const Mono_Time *mono_time, IPPTsPng *ipptp)
|
||||
{
|
||||
ipptp->timestamp = mono_time_get(mono_time) - 2 * BAD_NODE_TIMEOUT;
|
||||
ipptp->hardening.routes_requests_ok = 0;
|
||||
ipptp->hardening.send_nodes_ok = 0;
|
||||
ipptp->hardening.testing_requests = 0;
|
||||
}
|
||||
|
||||
static void mark_possible_bad(const Mono_Time *mono_time, IPPTsPng *ipptp)
|
||||
{
|
||||
ipptp->timestamp = mono_time_get(mono_time);
|
||||
ipptp->hardening.routes_requests_ok = 0;
|
||||
ipptp->hardening.send_nodes_ok = 0;
|
||||
ipptp->hardening.testing_requests = 0;
|
||||
}
|
||||
|
||||
static void mark_good(const Mono_Time *mono_time, IPPTsPng *ipptp)
|
||||
{
|
||||
ipptp->timestamp = mono_time_get(mono_time);
|
||||
ipptp->hardening.routes_requests_ok = (HARDENING_ALL_OK >> 0) & 1;
|
||||
ipptp->hardening.send_nodes_ok = (HARDENING_ALL_OK >> 1) & 1;
|
||||
ipptp->hardening.testing_requests = (HARDENING_ALL_OK >> 2) & 1;
|
||||
}
|
||||
|
||||
static void mark_all_good(const Mono_Time *mono_time, Client_data *list, uint32_t length, uint8_t ipv6)
|
||||
|
@ -210,71 +196,6 @@ static void test_addto_lists_bad(DHT *dht,
|
|||
ck_assert_msg(client_in_list(list, length, test_id3) >= 0, "Wrong bad client removed");
|
||||
}
|
||||
|
||||
static void test_addto_lists_possible_bad(DHT *dht,
|
||||
Client_data *list,
|
||||
uint32_t length,
|
||||
IP_Port *ip_port,
|
||||
const uint8_t *comp_client_id)
|
||||
{
|
||||
// check "possibly bad" clients replacement
|
||||
uint32_t used, test1, test2, test3;
|
||||
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], test_id1[CRYPTO_PUBLIC_KEY_SIZE], test_id2[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
test_id3[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t ipv6 = net_family_is_ipv6(ip_port->ip.family) ? 1 : 0;
|
||||
|
||||
random_bytes(public_key, sizeof(public_key));
|
||||
mark_all_good(dht->mono_time, list, length, ipv6);
|
||||
|
||||
test1 = random_u32() % (length / 3);
|
||||
test2 = random_u32() % (length / 3) + length / 3;
|
||||
test3 = random_u32() % (length / 3) + 2 * length / 3;
|
||||
ck_assert_msg(!(test1 == test2 || test1 == test3 || test2 == test3), "Wrong test indices are chosen");
|
||||
|
||||
id_copy((uint8_t *)&test_id1, list[test1].public_key);
|
||||
id_copy((uint8_t *)&test_id2, list[test2].public_key);
|
||||
id_copy((uint8_t *)&test_id3, list[test3].public_key);
|
||||
|
||||
// mark nodes as "possibly bad"
|
||||
if (ipv6) {
|
||||
mark_possible_bad(dht->mono_time, &list[test1].assoc6);
|
||||
mark_possible_bad(dht->mono_time, &list[test2].assoc6);
|
||||
mark_possible_bad(dht->mono_time, &list[test3].assoc6);
|
||||
} else {
|
||||
mark_possible_bad(dht->mono_time, &list[test1].assoc4);
|
||||
mark_possible_bad(dht->mono_time, &list[test2].assoc4);
|
||||
mark_possible_bad(dht->mono_time, &list[test3].assoc4);
|
||||
}
|
||||
|
||||
ip_port->port += 1;
|
||||
used = addto_lists(dht, *ip_port, public_key);
|
||||
ck_assert_msg(used >= 1, "Wrong number of added clients");
|
||||
|
||||
ck_assert_msg(client_in_list(list, length, public_key) >= 0, "Client id is not in the list");
|
||||
|
||||
bool inlist_id1 = client_in_list(list, length, test_id1) >= 0;
|
||||
bool inlist_id2 = client_in_list(list, length, test_id2) >= 0;
|
||||
bool inlist_id3 = client_in_list(list, length, test_id3) >= 0;
|
||||
|
||||
ck_assert_msg(inlist_id1 + inlist_id2 + inlist_id3 == 2, "Wrong client removed");
|
||||
|
||||
if (!inlist_id1) {
|
||||
ck_assert_msg(id_closest(comp_client_id, test_id2, test_id1) == 1,
|
||||
"Id has been removed but is closer to than another one");
|
||||
ck_assert_msg(id_closest(comp_client_id, test_id3, test_id1) == 1,
|
||||
"Id has been removed but is closer to than another one");
|
||||
} else if (!inlist_id2) {
|
||||
ck_assert_msg(id_closest(comp_client_id, test_id1, test_id2) == 1,
|
||||
"Id has been removed but is closer to than another one");
|
||||
ck_assert_msg(id_closest(comp_client_id, test_id3, test_id2) == 1,
|
||||
"Id has been removed but is closer to than another one");
|
||||
} else if (!inlist_id3) {
|
||||
ck_assert_msg(id_closest(comp_client_id, test_id1, test_id3) == 1,
|
||||
"Id has been removed but is closer to than another one");
|
||||
ck_assert_msg(id_closest(comp_client_id, test_id2, test_id3) == 1,
|
||||
"Id has been removed but is closer to than another one");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_addto_lists_good(DHT *dht,
|
||||
Client_data *list,
|
||||
uint32_t length,
|
||||
|
@ -365,16 +286,6 @@ static void test_addto_lists(IP ip)
|
|||
test_addto_lists_bad(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &ip_port);
|
||||
}
|
||||
|
||||
// check "possibly bad" entries
|
||||
if (enable_broken_tests) {
|
||||
test_addto_lists_possible_bad(dht, dht->close_clientlist, LCLIENT_LIST, &ip_port, dht->self_public_key);
|
||||
|
||||
for (i = 0; i < dht->num_friends; ++i) {
|
||||
test_addto_lists_possible_bad(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &ip_port,
|
||||
dht->friends_list[i].public_key);
|
||||
}
|
||||
}
|
||||
|
||||
// check "good" entries
|
||||
test_addto_lists_good(dht, dht->close_clientlist, LCLIENT_LIST, &ip_port, dht->self_public_key);
|
||||
|
||||
|
@ -543,7 +454,7 @@ static void test_list_main(void)
|
|||
ck_assert_msg(count == 1, "Nodes in search don't know ip of friend. %u %u %u", i, j, count);
|
||||
|
||||
Node_format ln[MAX_SENT_NODES];
|
||||
uint16_t n = get_close_nodes(dhts[(l + j) % NUM_DHT], dhts[l]->self_public_key, ln, net_family_unspec, 1, 0);
|
||||
uint16_t n = get_close_nodes(dhts[(l + j) % NUM_DHT], dhts[l]->self_public_key, ln, net_family_unspec, 1);
|
||||
ck_assert_msg(n == MAX_SENT_NODES, "bad num close %u | %u %u", n, i, j);
|
||||
|
||||
count = 0;
|
||||
|
|
|
@ -44,24 +44,6 @@ static void print_client_id(const uint8_t *public_key)
|
|||
}
|
||||
}
|
||||
|
||||
static void print_hardening(const Hardening *h)
|
||||
{
|
||||
printf("Hardening:\n");
|
||||
printf("routes_requests_ok: %u\n", h->routes_requests_ok);
|
||||
printf("routes_requests_timestamp: %llu\n", (long long unsigned int)h->routes_requests_timestamp);
|
||||
printf("routes_requests_pingedid: ");
|
||||
print_client_id(h->routes_requests_pingedid);
|
||||
printf("\nsend_nodes_ok: %u\n", h->send_nodes_ok);
|
||||
printf("send_nodes_timestamp: %llu\n", (long long unsigned int)h->send_nodes_timestamp);
|
||||
printf("send_nodes_pingedid: ");
|
||||
print_client_id(h->send_nodes_pingedid);
|
||||
printf("\ntesting_requests: %u\n", h->testing_requests);
|
||||
printf("testing_timestamp: %llu\n", (long long unsigned int)h->testing_timestamp);
|
||||
printf("testing_pingedid: ");
|
||||
print_client_id(h->testing_pingedid);
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
static void print_assoc(const IPPTsPng *assoc, uint8_t ours)
|
||||
{
|
||||
const IP_Port *ipp = &assoc->ip_port;
|
||||
|
@ -79,7 +61,6 @@ static void print_assoc(const IPPTsPng *assoc, uint8_t ours)
|
|||
}
|
||||
|
||||
printf("Timestamp: %llu\n", (long long unsigned int) assoc->ret_timestamp);
|
||||
print_hardening(&assoc->hardening);
|
||||
}
|
||||
|
||||
static void print_clientlist(DHT *dht)
|
||||
|
|
383
toxcore/DHT.c
383
toxcore/DHT.c
|
@ -99,7 +99,6 @@ struct DHT {
|
|||
|
||||
struct Ping *ping;
|
||||
Ping_Array *dht_ping_array;
|
||||
Ping_Array *dht_harden_ping_array;
|
||||
uint64_t cur_time;
|
||||
|
||||
Cryptopacket_Handler cryptopackethandlers[256];
|
||||
|
@ -781,25 +780,12 @@ bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, IP
|
|||
return false;
|
||||
}
|
||||
|
||||
/* TODO(irungentoo): change this to 7 when done*/
|
||||
#define HARDENING_ALL_OK 2
|
||||
/** return 0 if not.
|
||||
* return 1 if route request are ok
|
||||
* return 2 if it responds to send node packets correctly
|
||||
* return 4 if it can test other nodes correctly
|
||||
* return HARDENING_ALL_OK if all ok.
|
||||
*/
|
||||
static uint8_t hardening_correct(const Hardening *h)
|
||||
{
|
||||
return h->routes_requests_ok + (h->send_nodes_ok << 1) + (h->testing_requests << 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* helper for get_close_nodes(). argument list is a monster :D
|
||||
*/
|
||||
static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key, Node_format *nodes_list,
|
||||
Family sa_family, const Client_data *client_list, uint32_t client_list_length,
|
||||
uint32_t *num_nodes_ptr, bool is_LAN, uint8_t want_good)
|
||||
uint32_t *num_nodes_ptr, bool is_LAN)
|
||||
{
|
||||
if (!net_family_is_ipv4(sa_family) && !net_family_is_ipv6(sa_family) && !net_family_is_unspec(sa_family)) {
|
||||
return;
|
||||
|
@ -837,11 +823,6 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!ip_is_lan(ipptp->ip_port.ip) && want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK
|
||||
&& !id_equal(public_key, client->public_key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (num_nodes < MAX_SENT_NODES) {
|
||||
memcpy(nodes_list[num_nodes].public_key, client->public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
nodes_list[num_nodes].ip_port = ipptp->ip_port;
|
||||
|
@ -859,41 +840,28 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key,
|
|||
*
|
||||
* TODO(irungentoo): For the love of based <your favorite deity, in doubt use
|
||||
* "love"> make this function cleaner and much more efficient.
|
||||
*
|
||||
* want_good : do we want only good nodes as checked with the hardening returned or not?
|
||||
*/
|
||||
static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list,
|
||||
Family sa_family, bool is_LAN, uint8_t want_good)
|
||||
Family sa_family, bool is_LAN)
|
||||
{
|
||||
uint32_t num_nodes = 0;
|
||||
get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family,
|
||||
dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, 0);
|
||||
|
||||
/* TODO(irungentoo): uncomment this when hardening is added to close friend clients */
|
||||
#if 0
|
||||
|
||||
for (uint32_t i = 0; i < dht->num_friends; ++i) {
|
||||
get_close_nodes_inner(dht->mono_time, public_key, nodes_list, sa_family,
|
||||
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
|
||||
&num_nodes, is_LAN, want_good);
|
||||
}
|
||||
|
||||
#endif
|
||||
dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN);
|
||||
|
||||
for (uint32_t i = 0; i < dht->num_friends; ++i) {
|
||||
get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family,
|
||||
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
|
||||
&num_nodes, is_LAN, 0);
|
||||
&num_nodes, is_LAN);
|
||||
}
|
||||
|
||||
return num_nodes;
|
||||
}
|
||||
|
||||
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
|
||||
bool is_LAN, uint8_t want_good)
|
||||
bool is_LAN)
|
||||
{
|
||||
memset(nodes_list, 0, MAX_SENT_NODES * sizeof(Node_format));
|
||||
return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family, is_LAN, want_good);
|
||||
return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family, is_LAN);
|
||||
}
|
||||
|
||||
typedef struct DHT_Cmp_data {
|
||||
|
@ -902,11 +870,6 @@ typedef struct DHT_Cmp_data {
|
|||
Client_data entry;
|
||||
} DHT_Cmp_data;
|
||||
|
||||
static bool incorrect_hardening(const IPPTsPng *assoc)
|
||||
{
|
||||
return hardening_correct(&assoc->hardening) != HARDENING_ALL_OK;
|
||||
}
|
||||
|
||||
static int cmp_dht_entry(const void *a, const void *b)
|
||||
{
|
||||
DHT_Cmp_data cmp1;
|
||||
|
@ -932,9 +895,6 @@ static int cmp_dht_entry(const void *a, const void *b)
|
|||
return 1;
|
||||
}
|
||||
|
||||
t1 = incorrect_hardening(&entry1.assoc4) && incorrect_hardening(&entry1.assoc6);
|
||||
t2 = incorrect_hardening(&entry2.assoc4) && incorrect_hardening(&entry2.assoc6);
|
||||
|
||||
if (t1 && !t2) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1305,10 +1265,8 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_ke
|
|||
}
|
||||
}
|
||||
|
||||
/** Send a getnodes request.
|
||||
* sendback_node is the node that it will send back the response to (set to NULL to disable this) */
|
||||
static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const uint8_t *client_id,
|
||||
const Node_format *sendback_node)
|
||||
/* Send a getnodes request. */
|
||||
static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const uint8_t *client_id)
|
||||
{
|
||||
/* Check if packet is going to be sent to ourself. */
|
||||
if (id_equal(public_key, dht->self_public_key)) {
|
||||
|
@ -1324,12 +1282,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const
|
|||
|
||||
uint64_t ping_id = 0;
|
||||
|
||||
if (sendback_node != nullptr) {
|
||||
memcpy(plain_message + sizeof(receiver), sendback_node, sizeof(Node_format));
|
||||
ping_id = ping_array_add(dht->dht_harden_ping_array, dht->mono_time, plain_message, sizeof(plain_message));
|
||||
} else {
|
||||
ping_id = ping_array_add(dht->dht_ping_array, dht->mono_time, plain_message, sizeof(receiver));
|
||||
}
|
||||
ping_id = ping_array_add(dht->dht_ping_array, dht->mono_time, plain_message, sizeof(receiver));
|
||||
|
||||
if (ping_id == 0) {
|
||||
return -1;
|
||||
|
@ -1373,7 +1326,7 @@ static int sendnodes_ipv6(const DHT *dht, IP_Port ip_port, const uint8_t *public
|
|||
|
||||
Node_format nodes_list[MAX_SENT_NODES];
|
||||
const uint32_t num_nodes =
|
||||
get_close_nodes(dht, client_id, nodes_list, net_family_unspec, ip_is_lan(ip_port.ip), 1);
|
||||
get_close_nodes(dht, client_id, nodes_list, net_family_unspec, ip_is_lan(ip_port.ip));
|
||||
|
||||
VLA(uint8_t, plain, 1 + node_format_size * MAX_SENT_NODES + length);
|
||||
|
||||
|
@ -1445,16 +1398,11 @@ static int handle_getnodes(void *object, IP_Port source, const uint8_t *packet,
|
|||
|
||||
/** return false if no
|
||||
* return true if yes */
|
||||
static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, IP_Port node_ip_port, uint64_t ping_id,
|
||||
Node_format *sendback_node)
|
||||
static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, IP_Port node_ip_port, uint64_t ping_id)
|
||||
{
|
||||
uint8_t data[sizeof(Node_format) * 2];
|
||||
|
||||
if (ping_array_check(dht->dht_ping_array, dht->mono_time, data, sizeof(data), ping_id) == sizeof(Node_format)) {
|
||||
memset(sendback_node, 0, sizeof(Node_format));
|
||||
} else if (ping_array_check(dht->dht_harden_ping_array, dht->mono_time, data, sizeof(data), ping_id) == sizeof(data)) {
|
||||
memcpy(sendback_node, data + sizeof(Node_format), sizeof(Node_format));
|
||||
} else {
|
||||
if (ping_array_check(dht->dht_ping_array, dht->mono_time, data, sizeof(data), ping_id) != sizeof(Node_format)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1468,10 +1416,6 @@ static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, IP_Port no
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Function is needed in following functions. */
|
||||
static int send_hardening_getnode_res(const DHT *dht, const Node_format *sendto, const uint8_t *queried_client_id,
|
||||
const uint8_t *nodes_data, uint16_t nodes_data_length);
|
||||
|
||||
static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *packet, uint16_t length,
|
||||
Node_format *plain_nodes, uint16_t size_plain_nodes, uint32_t *num_nodes_out)
|
||||
{
|
||||
|
@ -1512,12 +1456,10 @@ static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *pa
|
|||
return 1;
|
||||
}
|
||||
|
||||
Node_format sendback_node;
|
||||
|
||||
uint64_t ping_id;
|
||||
memcpy(&ping_id, plain + 1 + data_size, sizeof(ping_id));
|
||||
|
||||
if (!sent_getnode_to_node(dht, packet + 1, source, ping_id, &sendback_node)) {
|
||||
if (!sent_getnode_to_node(dht, packet + 1, source, ping_id)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1541,7 +1483,6 @@ static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *pa
|
|||
|
||||
*num_nodes_out = num_nodes;
|
||||
|
||||
send_hardening_getnode_res(dht, &sendback_node, packet + 1, plain + 1, data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1624,7 +1565,7 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
|
|||
}
|
||||
|
||||
dht_friend->num_to_bootstrap = get_close_nodes(dht, dht_friend->public_key, dht_friend->to_bootstrap, net_family_unspec,
|
||||
1, 0);
|
||||
1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1733,7 +1674,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
|
|||
++not_kill;
|
||||
|
||||
if (mono_time_is_timeout(dht->mono_time, assoc->last_pinged, PING_INTERVAL)) {
|
||||
getnodes(dht, assoc->ip_port, client->public_key, public_key, nullptr);
|
||||
getnodes(dht, assoc->ip_port, client->public_key, public_key);
|
||||
assoc->last_pinged = temp_time;
|
||||
}
|
||||
|
||||
|
@ -1766,7 +1707,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
|
|||
rand_node += random_u32() % (num_nodes - (rand_node + 1));
|
||||
}
|
||||
|
||||
getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, public_key, nullptr);
|
||||
getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, public_key);
|
||||
|
||||
*lastgetnode = temp_time;
|
||||
++*bootstrap_times;
|
||||
|
@ -1784,8 +1725,7 @@ static void do_dht_friends(DHT *dht)
|
|||
DHT_Friend *const dht_friend = &dht->friends_list[i];
|
||||
|
||||
for (size_t j = 0; j < dht_friend->num_to_bootstrap; ++j) {
|
||||
getnodes(dht, dht_friend->to_bootstrap[j].ip_port, dht_friend->to_bootstrap[j].public_key, dht_friend->public_key,
|
||||
nullptr);
|
||||
getnodes(dht, dht_friend->to_bootstrap[j].ip_port, dht_friend->to_bootstrap[j].public_key, dht_friend->public_key);
|
||||
}
|
||||
|
||||
dht_friend->num_to_bootstrap = 0;
|
||||
|
@ -1802,7 +1742,7 @@ static void do_dht_friends(DHT *dht)
|
|||
static void do_Close(DHT *dht)
|
||||
{
|
||||
for (size_t i = 0; i < dht->num_to_bootstrap; ++i) {
|
||||
getnodes(dht, dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key, nullptr);
|
||||
getnodes(dht, dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key);
|
||||
}
|
||||
|
||||
dht->num_to_bootstrap = 0;
|
||||
|
@ -1840,12 +1780,12 @@ static void do_Close(DHT *dht)
|
|||
|
||||
void dht_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, const uint8_t *which_id)
|
||||
{
|
||||
getnodes(dht, *from_ipp, from_id, which_id, nullptr);
|
||||
getnodes(dht, *from_ipp, from_id, which_id);
|
||||
}
|
||||
|
||||
void dht_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
|
||||
{
|
||||
getnodes(dht, ip_port, public_key, dht->self_public_key, nullptr);
|
||||
getnodes(dht, ip_port, public_key, dht->self_public_key);
|
||||
}
|
||||
int dht_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
|
||||
uint16_t port, const uint8_t *public_key)
|
||||
|
@ -2305,227 +2245,6 @@ static void do_NAT(DHT *dht)
|
|||
/*----------------------------------------------------------------------------------*/
|
||||
/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/
|
||||
|
||||
#define DHT_HARDENING 0
|
||||
#define HARDREQ_DATA_SIZE 384 // Attempt to prevent amplification/other attacks
|
||||
|
||||
typedef enum Check_Type {
|
||||
CHECK_TYPE_ROUTE_REQ = 0,
|
||||
CHECK_TYPE_ROUTE_RES = 1,
|
||||
CHECK_TYPE_GETNODE_REQ = 2,
|
||||
CHECK_TYPE_GETNODE_RES = 3,
|
||||
CHECK_TYPE_TEST_REQ = 4,
|
||||
CHECK_TYPE_TEST_RES = 5,
|
||||
} Check_Type;
|
||||
|
||||
#if DHT_HARDENING
|
||||
static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8_t *contents, uint16_t length)
|
||||
{
|
||||
if (length > HARDREQ_DATA_SIZE - 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
|
||||
uint8_t data[HARDREQ_DATA_SIZE] = {0};
|
||||
data[0] = type;
|
||||
memcpy(data + 1, contents, length);
|
||||
const int len = create_request(
|
||||
dht->self_public_key, dht->self_secret_key, packet, sendto->public_key,
|
||||
data, sizeof(data), CRYPTO_PACKET_HARDENING);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sendpacket(dht->net, sendto->ip_port, packet, len);
|
||||
}
|
||||
|
||||
/** Send a get node hardening request */
|
||||
static int send_hardening_getnode_req(DHT *dht, Node_format *dest, Node_format *node_totest, uint8_t *search_id)
|
||||
{
|
||||
uint8_t data[sizeof(Node_format) + CRYPTO_PUBLIC_KEY_SIZE];
|
||||
memcpy(data, node_totest, sizeof(Node_format));
|
||||
memcpy(data + sizeof(Node_format), search_id, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
return send_hardening_req(dht, dest, CHECK_TYPE_GETNODE_REQ, data, sizeof(Node_format) + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Send a get node hardening response */
|
||||
static int send_hardening_getnode_res(const DHT *dht, const Node_format *sendto, const uint8_t *queried_client_id,
|
||||
const uint8_t *nodes_data, uint16_t nodes_data_length)
|
||||
{
|
||||
if (!ip_isset(&sendto->ip_port.ip)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
|
||||
VLA(uint8_t, data, 1 + CRYPTO_PUBLIC_KEY_SIZE + nodes_data_length);
|
||||
data[0] = CHECK_TYPE_GETNODE_RES;
|
||||
memcpy(data + 1, queried_client_id, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(data + 1 + CRYPTO_PUBLIC_KEY_SIZE, nodes_data, nodes_data_length);
|
||||
const int len = create_request(
|
||||
dht->self_public_key, dht->self_secret_key, packet, sendto->public_key,
|
||||
data, SIZEOF_VLA(data), CRYPTO_PACKET_HARDENING);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sendpacket(dht->net, sendto->ip_port, packet, len);
|
||||
}
|
||||
|
||||
/* TODO(irungentoo): improve */
|
||||
static IPPTsPng *get_closelist_IPPTsPng(DHT *dht, const uint8_t *public_key, Family sa_family)
|
||||
{
|
||||
for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
|
||||
if (!id_equal(dht->close_clientlist[i].public_key, public_key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (net_family_is_ipv4(sa_family)) {
|
||||
return &dht->close_clientlist[i].assoc4;
|
||||
}
|
||||
|
||||
if (net_family_is_ipv6(sa_family)) {
|
||||
return &dht->close_clientlist[i].assoc6;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* check how many nodes in nodes are also present in the closelist.
|
||||
* TODO(irungentoo): make this function better.
|
||||
*/
|
||||
static uint32_t have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num)
|
||||
{
|
||||
uint32_t counter = 0;
|
||||
|
||||
for (uint32_t i = 0; i < num; ++i) {
|
||||
if (id_equal(nodes[i].public_key, dht->self_public_key)) {
|
||||
++counter;
|
||||
continue;
|
||||
}
|
||||
|
||||
const IPPTsPng *const temp = get_closelist_IPPTsPng(dht, nodes[i].public_key, nodes[i].ip_port.ip.family);
|
||||
|
||||
if (temp) {
|
||||
if (!assoc_timeout(dht->cur_time, temp)) {
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
/* Interval in seconds between hardening checks */
|
||||
#define HARDENING_INTERVAL 120
|
||||
|
||||
/** Handle a received hardening packet */
|
||||
static int handle_hardening(void *object, IP_Port source, const uint8_t *source_pubkey, const uint8_t *packet,
|
||||
uint16_t length, void *userdata)
|
||||
{
|
||||
DHT *const dht = (DHT *)object;
|
||||
|
||||
if (length < 2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (packet[0]) {
|
||||
case CHECK_TYPE_GETNODE_REQ: {
|
||||
if (length != HARDREQ_DATA_SIZE) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Node_format node;
|
||||
Node_format tocheck_node;
|
||||
node.ip_port = source;
|
||||
memcpy(node.public_key, source_pubkey, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(&tocheck_node, packet + 1, sizeof(Node_format));
|
||||
|
||||
if (getnodes(dht, tocheck_node.ip_port, tocheck_node.public_key, packet + 1 + sizeof(Node_format), &node) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CHECK_TYPE_GETNODE_RES: {
|
||||
if (length <= CRYPTO_PUBLIC_KEY_SIZE + 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (length > 1 + CRYPTO_PUBLIC_KEY_SIZE + sizeof(Node_format) * MAX_SENT_NODES) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t length_nodes = length - 1 - CRYPTO_PUBLIC_KEY_SIZE;
|
||||
Node_format nodes[MAX_SENT_NODES];
|
||||
const int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, nullptr, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
length_nodes, 0);
|
||||
|
||||
/* TODO(irungentoo): MAX_SENT_NODES nodes should be returned at all times
|
||||
* (right now we have a small network size so it could cause problems for testing and etc..) */
|
||||
if (num_nodes <= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* NOTE: This should work for now but should be changed to something better. */
|
||||
if (have_nodes_closelist(dht, nodes, num_nodes) < (uint32_t)((num_nodes + 2) / 2)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
IPPTsPng *const temp = get_closelist_IPPTsPng(dht, packet + 1, nodes[0].ip_port.ip.family);
|
||||
|
||||
if (temp == nullptr) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mono_time_is_timeout(dht->mono_time, temp->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!id_equal(temp->hardening.send_nodes_pingedid, source_pubkey)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If Nodes look good and the request checks out */
|
||||
temp->hardening.send_nodes_ok = 1;
|
||||
return 0;/* success*/
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if DHT_HARDENING
|
||||
#define HARDEN_TIMEOUT 1200
|
||||
|
||||
/** Return a random node from all the nodes we are connected to.
|
||||
* TODO(irungentoo): improve this function.
|
||||
*/
|
||||
static Node_format random_node(DHT *dht, Family sa_family)
|
||||
{
|
||||
uint8_t id[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
|
||||
for (uint32_t i = 0; i < CRYPTO_PUBLIC_KEY_SIZE / 4; ++i) { /* populate the id with pseudorandom bytes.*/
|
||||
const uint32_t t = random_u32();
|
||||
memcpy(id + i * sizeof(t), &t, sizeof(t));
|
||||
}
|
||||
|
||||
Node_format nodes_list[MAX_SENT_NODES];
|
||||
memset(nodes_list, 0, sizeof(nodes_list));
|
||||
const uint32_t num_nodes = get_close_nodes(dht, id, nodes_list, sa_family, 1, 0);
|
||||
|
||||
if (num_nodes == 0) {
|
||||
return nodes_list[0];
|
||||
}
|
||||
|
||||
return nodes_list[random_u32() % num_nodes];
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Put up to max_num nodes in nodes from the closelist.
|
||||
*
|
||||
* return the number of nodes.
|
||||
|
@ -2602,59 +2321,6 @@ uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
|
|||
return list_nodes(dht->close_clientlist, LCLIENT_LIST, dht->cur_time, nodes, max_num);
|
||||
}
|
||||
|
||||
#if DHT_HARDENING
|
||||
static void do_hardening(DHT *dht)
|
||||
{
|
||||
for (uint32_t i = 0; i < LCLIENT_LIST * 2; ++i) {
|
||||
IPPTsPng *cur_iptspng;
|
||||
Family sa_family;
|
||||
const uint8_t *const public_key = dht->close_clientlist[i / 2].public_key;
|
||||
|
||||
if (i % 2 == 0) {
|
||||
cur_iptspng = &dht->close_clientlist[i / 2].assoc4;
|
||||
sa_family = net_family_ipv4;
|
||||
} else {
|
||||
cur_iptspng = &dht->close_clientlist[i / 2].assoc6;
|
||||
sa_family = net_family_ipv6;
|
||||
}
|
||||
|
||||
if (assoc_timeout(dht->mono_time, cur_iptspng)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cur_iptspng->hardening.send_nodes_ok == 0) {
|
||||
if (mono_time_is_timeout(dht->mono_time, cur_iptspng->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) {
|
||||
Node_format rand_node = random_node(dht, sa_family);
|
||||
|
||||
if (!ipport_isset(&rand_node.ip_port)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (id_equal(public_key, rand_node.public_key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Node_format to_test;
|
||||
to_test.ip_port = cur_iptspng->ip_port;
|
||||
memcpy(to_test.public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
// TODO(irungentoo): The search id should maybe not be ours?
|
||||
if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) {
|
||||
memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
cur_iptspng->hardening.send_nodes_timestamp = mono_time_get(dht->mono_time);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mono_time_is_timeout(dht->mono_time, cur_iptspng->hardening.send_nodes_timestamp, HARDEN_TIMEOUT)) {
|
||||
cur_iptspng->hardening.send_nodes_ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(irungentoo): add the 2 other testers.
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_cb *cb, void *object)
|
||||
|
@ -2737,14 +2403,12 @@ DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool
|
|||
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht);
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, &handle_hardening, dht);
|
||||
|
||||
crypto_new_keypair(dht->self_public_key, dht->self_secret_key);
|
||||
|
||||
dht->dht_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
|
||||
dht->dht_harden_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
|
||||
|
||||
if (dht->dht_ping_array == nullptr || dht->dht_harden_ping_array == nullptr) {
|
||||
if (dht->dht_ping_array == nullptr) {
|
||||
kill_dht(dht);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2783,9 +2447,6 @@ void do_dht(DHT *dht)
|
|||
do_dht_friends(dht);
|
||||
do_NAT(dht);
|
||||
ping_iterate(dht->ping);
|
||||
#if DHT_HARDENING
|
||||
do_hardening(dht);
|
||||
#endif
|
||||
}
|
||||
|
||||
void kill_dht(DHT *dht)
|
||||
|
@ -2793,9 +2454,7 @@ void kill_dht(DHT *dht)
|
|||
networking_registerhandler(dht->net, NET_PACKET_GET_NODES, nullptr, nullptr);
|
||||
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, nullptr, nullptr);
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, nullptr, nullptr);
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, nullptr, nullptr);
|
||||
ping_array_kill(dht->dht_ping_array);
|
||||
ping_array_kill(dht->dht_harden_ping_array);
|
||||
ping_kill(dht->ping);
|
||||
free(dht->friends_list);
|
||||
free(dht->loaded_nodes_list);
|
||||
|
|
|
@ -55,7 +55,6 @@ extern "C" {
|
|||
#define MAX_CRYPTO_REQUEST_SIZE 1024
|
||||
|
||||
#define CRYPTO_PACKET_FRIEND_REQ 32 // Friend request crypto packet ID.
|
||||
#define CRYPTO_PACKET_HARDENING 48 // Hardening crypto packet ID.
|
||||
#define CRYPTO_PACKET_DHTPK 156
|
||||
#define CRYPTO_PACKET_NAT_PING 254 // NAT ping crypto packet ID.
|
||||
|
||||
|
@ -86,30 +85,11 @@ typedef struct IPPTs {
|
|||
uint64_t timestamp;
|
||||
} IPPTs;
|
||||
|
||||
typedef struct Hardening {
|
||||
/* Node routes request correctly (true (1) or false/didn't check (0)) */
|
||||
uint8_t routes_requests_ok;
|
||||
/* Time which we last checked this.*/
|
||||
uint64_t routes_requests_timestamp;
|
||||
uint8_t routes_requests_pingedid[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
/* Node sends correct send_node (true (1) or false/didn't check (0)) */
|
||||
uint8_t send_nodes_ok;
|
||||
/* Time which we last checked this.*/
|
||||
uint64_t send_nodes_timestamp;
|
||||
uint8_t send_nodes_pingedid[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
/* Node can be used to test other nodes (true (1) or false/didn't check (0)) */
|
||||
uint8_t testing_requests;
|
||||
/* Time which we last checked this.*/
|
||||
uint64_t testing_timestamp;
|
||||
uint8_t testing_pingedid[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
} Hardening;
|
||||
|
||||
typedef struct IPPTsPng {
|
||||
IP_Port ip_port;
|
||||
uint64_t timestamp;
|
||||
uint64_t last_pinged;
|
||||
|
||||
Hardening hardening;
|
||||
/* Returned by this node */
|
||||
IP_Port ret_ip_port;
|
||||
uint64_t ret_timestamp;
|
||||
|
@ -319,7 +299,7 @@ bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_
|
|||
*
|
||||
*/
|
||||
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
|
||||
bool is_LAN, uint8_t want_good);
|
||||
bool is_LAN);
|
||||
|
||||
|
||||
/** Put up to max_num nodes in nodes from the random friends.
|
||||
|
|
|
@ -406,7 +406,7 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t *
|
|||
/*Respond with a announce response packet*/
|
||||
Node_format nodes_list[MAX_SENT_NODES];
|
||||
unsigned int num_nodes =
|
||||
get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, net_family_unspec, ip_is_lan(source.ip), 1);
|
||||
get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, net_family_unspec, ip_is_lan(source.ip));
|
||||
uint8_t nonce[CRYPTO_NONCE_SIZE];
|
||||
random_nonce(nonce);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user