Skip to content

Commit 819aa2b

Browse files
committed
feat: Add option to disable DNS lookups in toxcore.
Allows clients to prevent leaking IP addresses through DNS lookups. This option, together with disabling Tox UDP, entirely prevents any UDP packets being sent by toxcore.
1 parent 0ac23ce commit 819aa2b

File tree

13 files changed

+91
-36
lines changed

13 files changed

+91
-36
lines changed

auto_tests/network_test.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ static void test_addr_resolv_localhost(void)
2828
IP ip;
2929
ip_init(&ip, 0); // ipv6enabled = 0
3030

31-
bool res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr);
31+
bool res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr, true);
3232

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

4444
ip_init(&ip, 1); // ipv6enabled = 1
45-
res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr);
45+
res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr, true);
4646

4747
#if USE_IPV6
4848

4949
int localhost_split = 0;
5050

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

@@ -75,7 +75,7 @@ static void test_addr_resolv_localhost(void)
7575
ip.family = net_family_unspec();
7676
IP extra;
7777
ip_reset(&extra);
78-
res = addr_resolve_or_parse_ip(ns, localhost, &ip, &extra);
78+
res = addr_resolve_or_parse_ip(ns, localhost, &ip, &extra, true);
7979
error = net_error();
8080
strerror = net_new_strerror(error);
8181
ck_assert_msg(res, "Resolver failed: %d, %s", error, strerror);

other/DHT_bootstrap.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,12 @@ int main(int argc, char *argv[])
228228

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

231+
// TODO(iphydf): Maybe disable and only use IP addresses?
232+
const bool dns_enabled = true;
233+
231234
uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
232235
const bool res = dht_bootstrap_from_address(dht, argv[argvoffset + 1],
233-
ipv6enabled, port, bootstrap_key);
236+
ipv6enabled, dns_enabled, port, bootstrap_key);
234237
free(bootstrap_key);
235238

236239
if (!res) {

other/bootstrap_daemon/src/config.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,9 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
390390
bool address_resolved;
391391
uint8_t *bs_public_key_bin;
392392

393+
// TODO(iphydf): Maybe disable it and only use IP addresses?
394+
const bool dns_enabled = true;
395+
393396
node = config_setting_get_elem(node_list, 0);
394397

395398
if (node == nullptr) {
@@ -429,7 +432,7 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
429432
}
430433

431434
bs_public_key_bin = bootstrap_hex_string_to_bin(bs_public_key);
432-
address_resolved = dht_bootstrap_from_address(dht, bs_address, enable_ipv6, net_htons(bs_port),
435+
address_resolved = dht_bootstrap_from_address(dht, bs_address, enable_ipv6, dns_enabled, net_htons(bs_port),
433436
bs_public_key_bin);
434437
free(bs_public_key_bin);
435438

testing/Messenger_test.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,13 @@ int main(int argc, char *argv[])
118118
exit(1);
119119
}
120120

121+
// TODO(iphydf): Maybe disable.
122+
const bool dns_enabled = true;
123+
121124
const uint16_t port = net_htons((uint16_t)port_conv);
122125
uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
123126
bool res = dht_bootstrap_from_address(m->dht, argv[argvoffset + 1],
124-
ipv6enabled, port, bootstrap_key);
127+
ipv6enabled, dns_enabled, port, bootstrap_key);
125128
free(bootstrap_key);
126129

127130
if (!res) {

toxcore/DHT.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,7 +1840,7 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key)
18401840
return dht_getnodes(dht, ip_port, public_key, dht->self_public_key);
18411841
}
18421842

1843-
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
1843+
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
18441844
uint16_t port, const uint8_t *public_key)
18451845
{
18461846
IP_Port ip_port_v64;
@@ -1855,7 +1855,7 @@ bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
18551855
ip_extra = &ip_port_v4.ip;
18561856
}
18571857

1858-
if (addr_resolve_or_parse_ip(dht->ns, address, &ip_port_v64.ip, ip_extra)) {
1858+
if (addr_resolve_or_parse_ip(dht->ns, address, &ip_port_v64.ip, ip_extra, dns_enabled)) {
18591859
ip_port_v64.port = port;
18601860
dht_bootstrap(dht, &ip_port_v64, public_key);
18611861

toxcore/DHT.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,13 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key);
404404
* @param address can be a hostname or an IP address (IPv4 or IPv6).
405405
* @param ipv6enabled if false, the resolving sticks STRICTLY to IPv4 addresses.
406406
* Otherwise, the resolving looks for IPv6 addresses first, then IPv4 addresses.
407+
* @param dns_enabled if false, the resolving does not use DNS, only IP addresses are supported.
407408
*
408409
* @retval true if the address could be converted into an IP address
409410
* @retval false otherwise
410411
*/
411412
non_null()
412-
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
413+
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
413414
uint16_t port, const uint8_t *public_key);
414415

415416
/** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.

toxcore/Messenger.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ typedef struct Messenger_Options {
8686

8787
Messenger_State_Plugin *state_plugins;
8888
uint8_t state_plugins_length;
89+
90+
bool dns_enabled;
8991
} Messenger_Options;
9092

9193
struct Receipts {

toxcore/network.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,19 +1826,19 @@ bool addr_parse_ip(const char *address, IP *to)
18261826
* prefers v6 if `ip.family` was TOX_AF_UNSPEC and both available
18271827
* Returns in `*extra` an IPv4 address, if family was TOX_AF_UNSPEC and `*to` is TOX_AF_INET6
18281828
*
1829-
* @return 0 on failure, `TOX_ADDR_RESOLVE_*` on success.
1829+
* @return false on failure, true on success.
18301830
*/
18311831
non_null(1, 2, 3) nullable(4)
1832-
static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extra)
1832+
static bool addr_resolve(const Network *ns, const char *address, IP *to, IP *extra)
18331833
{
18341834
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
18351835
if ((true)) {
1836-
return 0;
1836+
return false;
18371837
}
18381838
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
18391839

18401840
if (address == nullptr || to == nullptr) {
1841-
return 0;
1841+
return false;
18421842
}
18431843

18441844
const Family tox_family = to->family;
@@ -1854,7 +1854,7 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr
18541854

18551855
// Lookup failed.
18561856
if (rc != 0) {
1857-
return 0;
1857+
return false;
18581858
}
18591859

18601860
IP ip4;
@@ -1918,18 +1918,16 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr
19181918
}
19191919

19201920
freeaddrinfo(server);
1921-
return result;
1921+
return result != 0;
19221922
}
19231923

1924-
bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra)
1924+
bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra, bool dns_enabled)
19251925
{
1926-
if (addr_resolve(ns, address, to, extra) == 0) {
1927-
if (!addr_parse_ip(address, to)) {
1928-
return false;
1929-
}
1926+
if (dns_enabled && addr_resolve(ns, address, to, extra)) {
1927+
return true;
19301928
}
19311929

1932-
return true;
1930+
return addr_parse_ip(address, to);
19331931
}
19341932

19351933
bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port)
@@ -1984,7 +1982,7 @@ bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket
19841982
return true;
19851983
}
19861984

1987-
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type)
1985+
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type, bool dns_enabled)
19881986
{
19891987
assert(node != nullptr);
19901988

@@ -2006,6 +2004,10 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
20062004
return 1;
20072005
}
20082006

2007+
if (!dns_enabled) {
2008+
return -1;
2009+
}
2010+
20092011
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
20102012
if ((true)) {
20112013
IP_Port *ip_port = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));

toxcore/network.h

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -398,21 +398,22 @@ non_null()
398398
void ipport_copy(IP_Port *target, const IP_Port *source);
399399

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

417418
/** @brief Function to receive data, ip and port of sender is put into ip_port.
418419
* Packet data is put into data.
@@ -512,14 +513,20 @@ bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket
512513
* address that can be specified by calling `net_connect()`, the port is ignored.
513514
*
514515
* Skip all addresses with socktype != type (use type = -1 to get all addresses)
515-
* To correctly deallocate array memory use `net_freeipport()`
516+
* To correctly deallocate array memory use `net_freeipport()`.
517+
*
518+
* @param mem Memory allocator.
519+
* @param node The node parameter identifies the host or service on which to connect.
520+
* @param[out] res An array of IP_Port structures will be allocated into this pointer.
521+
* @param tox_type The type of socket to use (stream or datagram), only relevant for DNS lookups.
522+
* @param dns_enabled If false, DNS resolution is skipped, when passed a hostname, this function will return an error.
516523
*
517524
* @return number of elements in res array.
518525
* @retval 0 if res array empty.
519526
* @retval -1 on error.
520527
*/
521528
non_null()
522-
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type);
529+
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type, bool dns_enabled);
523530

524531
/** Deallocates memory allocated by net_getipport */
525532
non_null(1) nullable(2)

toxcore/tox.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,8 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error
752752

753753
Messenger_Options m_options = {false};
754754

755+
m_options.dns_enabled = !tox_options_get_experimental_disable_dns(opts);
756+
755757
bool load_savedata_sk = false;
756758
bool load_savedata_tox = false;
757759

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

857859
const char *const proxy_host = tox_options_get_proxy_host(opts);
860+
const bool dns_enabled = !tox_options_get_experimental_disable_dns(opts);
858861

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

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

11441147
if (count < 1) {
11451148
LOGGER_DEBUG(tox->m->log, "could not resolve bootstrap node '%s'", host);

0 commit comments

Comments
 (0)