Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add option to disable DNS lookups in toxcore. #2694

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions auto_tests/network_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static void test_addr_resolv_localhost(void)
IP ip;
ip_init(&ip, 0); // ipv6enabled = 0

bool res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr);
bool res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr, true);

int error = net_error();
char *strerror = net_new_strerror(error);
Expand All @@ -42,14 +42,14 @@ static void test_addr_resolv_localhost(void)
net_ip_ntoa(&ip, &ip_str));

ip_init(&ip, 1); // ipv6enabled = 1
res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr);
res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr, true);

#if USE_IPV6

int localhost_split = 0;

if (!net_family_is_ipv6(ip.family)) {
res = addr_resolve_or_parse_ip(ns, "ip6-localhost", &ip, nullptr);
res = addr_resolve_or_parse_ip(ns, "ip6-localhost", &ip, nullptr, true);
localhost_split = 1;
}

Expand All @@ -75,7 +75,7 @@ static void test_addr_resolv_localhost(void)
ip.family = net_family_unspec();
IP extra;
ip_reset(&extra);
res = addr_resolve_or_parse_ip(ns, localhost, &ip, &extra);
res = addr_resolve_or_parse_ip(ns, localhost, &ip, &extra, true);
error = net_error();
strerror = net_new_strerror(error);
ck_assert_msg(res, "Resolver failed: %d, %s", error, strerror);
Expand Down
5 changes: 4 additions & 1 deletion other/DHT_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,12 @@ int main(int argc, char *argv[])

const uint16_t port = net_htons((uint16_t)port_conv);

// TODO(iphydf): Maybe disable and only use IP addresses?
const bool dns_enabled = true;

uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
const bool res = dht_bootstrap_from_address(dht, argv[argvoffset + 1],
ipv6enabled, port, bootstrap_key);
ipv6enabled, dns_enabled, port, bootstrap_key);
free(bootstrap_key);

if (!res) {
Expand Down
5 changes: 4 additions & 1 deletion other/bootstrap_daemon/src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,9 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
bool address_resolved;
uint8_t *bs_public_key_bin;

// TODO(iphydf): Maybe disable it and only use IP addresses?
const bool dns_enabled = true;

node = config_setting_get_elem(node_list, 0);

if (node == nullptr) {
Expand Down Expand Up @@ -416,7 +419,7 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
}

bs_public_key_bin = bootstrap_hex_string_to_bin(bs_public_key);
address_resolved = dht_bootstrap_from_address(dht, bs_address, enable_ipv6, net_htons(bs_port),
address_resolved = dht_bootstrap_from_address(dht, bs_address, enable_ipv6, dns_enabled, net_htons(bs_port),
bs_public_key_bin);
free(bs_public_key_bin);

Expand Down
5 changes: 4 additions & 1 deletion testing/Messenger_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,13 @@ int main(int argc, char *argv[])
exit(1);
}

// TODO(iphydf): Maybe disable.
const bool dns_enabled = true;

const uint16_t port = net_htons((uint16_t)port_conv);
uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
bool res = dht_bootstrap_from_address(m->dht, argv[argvoffset + 1],
ipv6enabled, port, bootstrap_key);
ipv6enabled, dns_enabled, port, bootstrap_key);
free(bootstrap_key);

if (!res) {
Expand Down
4 changes: 2 additions & 2 deletions toxcore/DHT.c
Original file line number Diff line number Diff line change
Expand Up @@ -1840,7 +1840,7 @@
return dht_getnodes(dht, ip_port, public_key, dht->self_public_key);
}

bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
uint16_t port, const uint8_t *public_key)
{
IP_Port ip_port_v64;
Expand All @@ -1855,7 +1855,7 @@
ip_extra = &ip_port_v4.ip;
}

if (addr_resolve_or_parse_ip(dht->ns, address, &ip_port_v64.ip, ip_extra)) {
if (addr_resolve_or_parse_ip(dht->ns, address, &ip_port_v64.ip, ip_extra, dns_enabled)) {

Check warning on line 1858 in toxcore/DHT.c

View check run for this annotation

Codecov / codecov/patch

toxcore/DHT.c#L1858

Added line #L1858 was not covered by tests
ip_port_v64.port = port;
dht_bootstrap(dht, &ip_port_v64, public_key);

Expand Down
3 changes: 2 additions & 1 deletion toxcore/DHT.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,12 +404,13 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key);
* @param address can be a hostname or an IP address (IPv4 or IPv6).
* @param ipv6enabled if false, the resolving sticks STRICTLY to IPv4 addresses.
* Otherwise, the resolving looks for IPv6 addresses first, then IPv4 addresses.
* @param dns_enabled if false, the resolving does not use DNS, only IP addresses are supported.
*
* @retval true if the address could be converted into an IP address
* @retval false otherwise
*/
non_null()
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
uint16_t port, const uint8_t *public_key);

/** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.
Expand Down
2 changes: 2 additions & 0 deletions toxcore/Messenger.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ typedef struct Messenger_Options {

Messenger_State_Plugin *state_plugins;
uint8_t state_plugins_length;

bool dns_enabled;
} Messenger_Options;

struct Receipts {
Expand Down
28 changes: 15 additions & 13 deletions toxcore/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -1815,19 +1815,19 @@
* prefers v6 if `ip.family` was TOX_AF_UNSPEC and both available
* Returns in `*extra` an IPv4 address, if family was TOX_AF_UNSPEC and `*to` is TOX_AF_INET6
*
* @return 0 on failure, `TOX_ADDR_RESOLVE_*` on success.
* @return false on failure, true on success.
*/
non_null(1, 2, 3) nullable(4)
static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extra)
static bool addr_resolve(const Network *ns, const char *address, IP *to, IP *extra)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if ((true)) {
return 0;
return false;
}
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */

if (address == nullptr || to == nullptr) {
return 0;
return false;

Check warning on line 1830 in toxcore/network.c

View check run for this annotation

Codecov / codecov/patch

toxcore/network.c#L1830

Added line #L1830 was not covered by tests
}

const Family tox_family = to->family;
Expand All @@ -1843,7 +1843,7 @@

// Lookup failed.
if (rc != 0) {
return 0;
return false;

Check warning on line 1846 in toxcore/network.c

View check run for this annotation

Codecov / codecov/patch

toxcore/network.c#L1846

Added line #L1846 was not covered by tests
}

IP ip4;
Expand Down Expand Up @@ -1907,18 +1907,16 @@
}

freeaddrinfo(server);
return result;
return result != 0;

Check warning on line 1910 in toxcore/network.c

View check run for this annotation

Codecov / codecov/patch

toxcore/network.c#L1910

Added line #L1910 was not covered by tests
}

bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra)
bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra, bool dns_enabled)
{
if (addr_resolve(ns, address, to, extra) == 0) {
if (!addr_parse_ip(address, to)) {
return false;
}
if (dns_enabled && addr_resolve(ns, address, to, extra)) {
return true;
}

return true;
return addr_parse_ip(address, to);
}

bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port)
Expand Down Expand Up @@ -1974,7 +1972,7 @@
return true;
}

int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type)
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type, bool dns_enabled)
{
assert(node != nullptr);

Expand All @@ -1996,6 +1994,10 @@
return 1;
}

if (!dns_enabled) {
return -1;

Check warning on line 1998 in toxcore/network.c

View check run for this annotation

Codecov / codecov/patch

toxcore/network.c#L1998

Added line #L1998 was not covered by tests
}

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if ((true)) {
IP_Port *ip_port = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));
Expand Down
27 changes: 17 additions & 10 deletions toxcore/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,21 +396,22 @@ non_null()
void ipport_copy(IP_Port *target, const IP_Port *source);

/**
* Resolves string into an IP address
* @brief Resolves string into an IP address.
*
* @param address a hostname (or something parseable to an IP address)
* @param to to.family MUST be initialized, either set to a specific IP version
* @param[in] address a hostname (or something parseable to an IP address).
* @param[in,out] to to.family MUST be initialized, either set to a specific IP version
* (TOX_AF_INET/TOX_AF_INET6) or to the unspecified TOX_AF_UNSPEC (0), if both
* IP versions are acceptable
* @param extra can be NULL and is only set in special circumstances, see returns
* IP versions are acceptable.
* @param[out] extra can be NULL and is only set in special circumstances, see returns.
* @param[in] dns_enabled if false, DNS resolution is skipped.
*
* Returns in `*to` a matching address (IPv6 or IPv4)
* Returns in `*extra`, if not NULL, an IPv4 address, if `to->family` was TOX_AF_UNSPEC
* Returns in `*to` a matching address (IPv6 or IPv4).
* Returns in `*extra`, if not NULL, an IPv4 address, if `to->family` was `TOX_AF_UNSPEC`.
*
* @return true on success, false on failure
*/
non_null(1, 2, 3) nullable(4)
bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra);
bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra, bool dns_enabled);

/** @brief Function to receive data, ip and port of sender is put into ip_port.
* Packet data is put into data.
Expand Down Expand Up @@ -510,14 +511,20 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por
* address that can be specified by calling `net_connect()`, the port is ignored.
*
* Skip all addresses with socktype != type (use type = -1 to get all addresses)
* To correctly deallocate array memory use `net_freeipport()`
* To correctly deallocate array memory use `net_freeipport()`.
*
* @param mem Memory allocator.
* @param node The node parameter identifies the host or service on which to connect.
* @param[out] res An array of IP_Port structures will be allocated into this pointer.
* @param tox_type The type of socket to use (stream or datagram), only relevant for DNS lookups.
* @param dns_enabled If false, DNS resolution is skipped, when passed a hostname, this function will return an error.
*
* @return number of elements in res array.
* @retval 0 if res array empty.
* @retval -1 on error.
*/
non_null()
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type);
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type, bool dns_enabled);

/** Deallocates memory allocated by net_getipport */
non_null(1) nullable(2)
Expand Down
7 changes: 5 additions & 2 deletions toxcore/tox.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,8 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error

Messenger_Options m_options = {false};

m_options.dns_enabled = tox_options_get_dns_enabled(opts);

bool load_savedata_sk = false;
bool load_savedata_tox = false;

Expand Down Expand Up @@ -855,9 +857,10 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error
}

const char *const proxy_host = tox_options_get_proxy_host(opts);
const bool dns_enabled = tox_options_get_dns_enabled(opts);

if (proxy_host == nullptr
|| !addr_resolve_or_parse_ip(tox->sys.ns, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr)) {
|| !addr_resolve_or_parse_ip(tox->sys.ns, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr, dns_enabled)) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST);
// TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain.
mem_delete(sys->mem, tox);
Expand Down Expand Up @@ -1139,7 +1142,7 @@ static int32_t resolve_bootstrap_node(Tox *tox, const char *host, uint16_t port,
return -1;
}

const int32_t count = net_getipport(tox->sys.mem, host, root, TOX_SOCK_DGRAM);
const int32_t count = net_getipport(tox->sys.mem, host, root, TOX_SOCK_DGRAM, tox->m->options.dns_enabled);

if (count < 1) {
LOGGER_DEBUG(tox->m->log, "could not resolve bootstrap node '%s'", host);
Expand Down
20 changes: 20 additions & 0 deletions toxcore/tox.h
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,22 @@ struct Tox_Options {
* Default: false.
*/
bool experimental_groups_persistence;

/**
* @brief Allow passing unresolved DNS hostnames to hostname parameters.
*
* Hostnames or IP addresses are passed to the bootstrap/add_tcp_relay function
* and proxy host options. If disabled, only IP addresses are allowed.
*
* If this is set to false, the library will not attempt to resolve hostnames.
* This is useful for clients that want to resolve hostnames themselves and
* pass the resolved IP addresses to the library (e.g. in case it wants to use Tor).
* Passing hostnames will result in a TOX_ERR_BOOTSTRAP_BAD_HOST error if this is
* set to false.
*
* Default: true. May become false in the future (0.3.0).
*/
bool dns_enabled;
};

bool tox_options_get_ipv6_enabled(const Tox_Options *options);
Expand Down Expand Up @@ -742,6 +758,10 @@ bool tox_options_get_experimental_groups_persistence(const Tox_Options *options)

void tox_options_set_experimental_groups_persistence(Tox_Options *options, bool experimental_groups_persistence);

bool tox_options_get_dns_enabled(const Tox_Options *options);

void tox_options_set_dns_enabled(Tox_Options *options, bool dns_enabled);

/**
* @brief Initialises a Tox_Options object with the default options.
*
Expand Down
9 changes: 9 additions & 0 deletions toxcore/tox_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,14 @@ void tox_options_set_experimental_groups_persistence(
{
options->experimental_groups_persistence = experimental_groups_persistence;
}
bool tox_options_get_dns_enabled(const Tox_Options *options)
{
return options->dns_enabled;
}
void tox_options_set_dns_enabled(Tox_Options *options, bool dns_enabled)
{
options->dns_enabled = dns_enabled;
}

const uint8_t *tox_options_get_savedata_data(const Tox_Options *options)
{
Expand All @@ -299,6 +307,7 @@ void tox_options_default(Tox_Options *options)
tox_options_set_dht_announcements_enabled(options, true);
tox_options_set_experimental_thread_safety(options, false);
tox_options_set_experimental_groups_persistence(options, false);
tox_options_set_dns_enabled(options, true);
}
}

Expand Down
2 changes: 1 addition & 1 deletion toxcore/tox_private.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip

IP_Port *root;

const int32_t count = net_getipport(tox->sys.mem, ip, &root, TOX_SOCK_DGRAM);
const int32_t count = net_getipport(tox->sys.mem, ip, &root, TOX_SOCK_DGRAM, tox->m->options.dns_enabled);

if (count < 1) {
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_IP);
Expand Down
Loading