Skip to content

Commit

Permalink
add NAT hole punching level to Tox API
Browse files Browse the repository at this point in the history
  • Loading branch information
Gregory Mullen (grayhatter) committed Nov 13, 2016
1 parent fe1fea8 commit 95b4637
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 63 deletions.
6 changes: 3 additions & 3 deletions auto_tests/dht_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ static void test_addto_lists(IP ip)
Networking_Core *net = new_networking(NULL, ip, TOX_PORT_DEFAULT);
ck_assert_msg(net != 0, "Failed to create Networking_Core");

DHT *dht = new_DHT(NULL, net);
DHT *dht = new_DHT(NULL, net, TOX_DHT_NAT_LEVEL_NORMAL);
ck_assert_msg(dht != 0, "Failed to create DHT");

IP_Port ip_port = { .ip = ip, .port = TOX_PORT_DEFAULT };
Expand Down Expand Up @@ -440,7 +440,7 @@ static void test_list_main(void)
IP ip;
ip_init(&ip, 1);

dhts[i] = new_DHT(NULL, new_networking(NULL, ip, DHT_DEFAULT_PORT + i));
dhts[i] = new_DHT(NULL, new_networking(NULL, ip, DHT_DEFAULT_PORT + i), TOX_DHT_NAT_LEVEL_NORMAL);
ck_assert_msg(dhts[i] != 0, "Failed to create dht instances %u", i);
ck_assert_msg(dhts[i]->net->port != DHT_DEFAULT_PORT + i, "Bound to wrong port");
}
Expand Down Expand Up @@ -584,7 +584,7 @@ START_TEST(test_DHT_test)
IP ip;
ip_init(&ip, 1);

dhts[i] = new_DHT(NULL, new_networking(NULL, ip, DHT_DEFAULT_PORT + i));
dhts[i] = new_DHT(NULL, new_networking(NULL, ip, DHT_DEFAULT_PORT + i), TOX_DHT_NAT_LEVEL_NORMAL);
ck_assert_msg(dhts[i] != 0, "Failed to create dht instances %u", i);
ck_assert_msg(dhts[i]->net->port != DHT_DEFAULT_PORT + i, "Bound to wrong port");
}
Expand Down
8 changes: 4 additions & 4 deletions auto_tests/onion_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ START_TEST(test_basic)
IP ip;
ip_init(&ip, 1);
ip.ip6.uint8[15] = 1;
Onion *onion1 = new_onion(new_DHT(NULL, new_networking(NULL, ip, 34567)));
Onion *onion2 = new_onion(new_DHT(NULL, new_networking(NULL, ip, 34568)));
Onion *onion1 = new_onion(new_DHT(NULL, new_networking(NULL, ip, 34567), 2));
Onion *onion2 = new_onion(new_DHT(NULL, new_networking(NULL, ip, 34568), 2));
ck_assert_msg((onion1 != NULL) && (onion2 != NULL), "Onion failed initializing.");
networking_registerhandler(onion2->net, 'I', &handle_test_1, onion2);

Expand Down Expand Up @@ -222,7 +222,7 @@ START_TEST(test_basic)
}

c_sleep(1000);
Onion *onion3 = new_onion(new_DHT(NULL, new_networking(NULL, ip, 34569)));
Onion *onion3 = new_onion(new_DHT(NULL, new_networking(NULL, ip, 34569), 2));
ck_assert_msg((onion3 != NULL), "Onion failed initializing.");

random_nonce(nonce);
Expand Down Expand Up @@ -285,7 +285,7 @@ static Onions *new_onions(uint16_t port)
ip_init(&ip, 1);
ip.ip6.uint8[15] = 1;
Onions *on = (Onions *)malloc(sizeof(Onions));
DHT *dht = new_DHT(NULL, new_networking(NULL, ip, port));
DHT *dht = new_DHT(NULL, new_networking(NULL, ip, port), 2);
on->onion = new_onion(dht);
on->onion_a = new_onion_announce(dht);
TCP_Proxy_Info inf = {{{0}}};
Expand Down
4 changes: 2 additions & 2 deletions auto_tests/tox_many_tcp_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ START_TEST(test_many_clients_tcp)
tox_options_default(&opts);

if (i == 0) {
opts.tcp_port = TCP_RELAY_PORT;
opts.dht_tcp_port = TCP_RELAY_PORT;
} else {
opts.udp_enabled = 0;
}
Expand Down Expand Up @@ -160,7 +160,7 @@ START_TEST(test_many_clients_tcp_b)
tox_options_default(&opts);

if (i < NUM_TCP_RELAYS) {
opts.tcp_port = TCP_RELAY_PORT + i;
opts.dht_tcp_port = TCP_RELAY_PORT + i;
} else {
opts.udp_enabled = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion other/DHT_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ int main(int argc, char *argv[])
IP ip;
ip_init(&ip, ipv6enabled);

DHT *dht = new_DHT(NULL, new_networking(NULL, ip, PORT));
DHT *dht = new_DHT(NULL, new_networking(NULL, ip, PORT), 2);
Onion *onion = new_onion(dht);
Onion_Announce *onion_a = new_onion_announce(dht);

Expand Down
3 changes: 2 additions & 1 deletion other/bootstrap_daemon/src/tox-bootstrapd.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <sys/stat.h>

// toxcore
#include "../../../toxcore/tox.h"
#include "../../../toxcore/LAN_discovery.h"
#include "../../../toxcore/TCP_server.h"
#include "../../../toxcore/onion_announce.h"
Expand Down Expand Up @@ -243,7 +244,7 @@ int main(int argc, char *argv[])
}
}

DHT *dht = new_DHT(NULL, net);
DHT *dht = new_DHT(NULL, net, TOX_DHT_NAT_LEVEL_NORMAL);

if (dht == NULL) {
write_log(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
Expand Down
2 changes: 1 addition & 1 deletion testing/DHT_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ int main(int argc, char *argv[])
IP ip;
ip_init(&ip, ipv6enabled);

DHT *dht = new_DHT(NULL, new_networking(NULL, ip, PORT));
DHT *dht = new_DHT(NULL, new_networking(NULL, ip, PORT), 2);
printf("OUR ID: ");
uint32_t i;

Expand Down
8 changes: 4 additions & 4 deletions testing/av_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,21 +231,21 @@ static void initialize_tox(Tox **bootstrap, ToxAV **AliceAV, CallControl *AliceC
struct Tox_Options opts;
tox_options_default(&opts);

opts.end_port = 0;
opts.dht_end_port = 0;
opts.ipv6_enabled = false;

{
TOX_ERR_NEW error;

opts.start_port = 33445;
opts.dht_start_port = 33445;
*bootstrap = tox_new(&opts, &error);
assert(error == TOX_ERR_NEW_OK);

opts.start_port = 33455;
opts.dht_start_port = 33455;
Alice = tox_new(&opts, &error);
assert(error == TOX_ERR_NEW_OK);

opts.start_port = 33465;
opts.dht_start_port = 33465;
Bob = tox_new(&opts, &error);
assert(error == TOX_ERR_NEW_OK);
}
Expand Down
25 changes: 24 additions & 1 deletion toxcore/DHT.c
Original file line number Diff line number Diff line change
Expand Up @@ -2090,6 +2090,26 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports,
return;
}

// TODO(toktok/c-toxcore#214)
/* The NAT_LEVEL set here is specified by the user, higher numbers allow toxcore to be
* more agressive when it tries to establish a direct UDP connection to friends. Because
* DHT is stateless, and some routers are known to hold on to DHT routing rules longer
* than needed, being to agressive may exaust all routes the NAT can handle causing a DoS
* effect to the whole network. */
switch (dht->nat_hole_punching_level) {

case 0: { // None
return;
}

case 1: // Polite
case 2: // Normal
case 3: { // Aggressive
break;
// TODO(toktok/c-toxcore#266) enable other levels.
}
}

uint32_t i;
uint32_t top = dht->friends_list[friend_num].nat.punching_index + MAX_PUNCHING_PORTS;
uint16_t firstport = port_list[0];
Expand Down Expand Up @@ -2575,7 +2595,7 @@ static int cryptopacket_handle(void *object, IP_Port source, const uint8_t *pack

/*----------------------------------------------------------------------------------*/

DHT *new_DHT(Logger *log, Networking_Core *net)
DHT *new_DHT(Logger *log, Networking_Core *net, uint8_t nat_level)
{
/* init time */
unix_time_update();
Expand All @@ -2592,6 +2612,9 @@ DHT *new_DHT(Logger *log, Networking_Core *net)

dht->log = log;
dht->net = net;

dht->nat_hole_punching_level = nat_level;

dht->ping = new_ping(dht);

if (dht->ping == NULL) {
Expand Down
4 changes: 3 additions & 1 deletion toxcore/DHT.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ typedef struct {
Logger *log;
Networking_Core *net;

uint8_t nat_hole_punching_level;

Client_data close_clientlist[LCLIENT_LIST];
uint64_t close_lastgetnodes;
uint32_t close_bootstrap_times;
Expand Down Expand Up @@ -435,7 +437,7 @@ void DHT_save(DHT *dht, uint8_t *data);
int DHT_load(DHT *dht, const uint8_t *data, uint32_t length);

/* Initialize DHT. */
DHT *new_DHT(Logger *log, Networking_Core *net);
DHT *new_DHT(Logger *log, Networking_Core *net, uint8_t nat_level);

void kill_DHT(DHT *dht);

Expand Down
2 changes: 1 addition & 1 deletion toxcore/Messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -1930,7 +1930,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
return NULL;
}

m->dht = new_DHT(m->log, m->net);
m->dht = new_DHT(m->log, m->net, options->nat_level);

if (m->dht == NULL) {
kill_networking(m->net);
Expand Down
2 changes: 2 additions & 0 deletions toxcore/Messenger.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ typedef struct {
uint16_t port_range[2];
uint16_t tcp_server_port;

uint8_t nat_level;

logger_cb *log_callback;
void *log_user_data;
} Messenger_Options;
Expand Down
97 changes: 68 additions & 29 deletions toxcore/tox.api.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,32 @@ enum class PROXY_TYPE {
SOCKS5,
}

enum class DHT_NAT_LEVEL {
/**
* Don't try to hole punch through a NAT device at all (Not Recommended).
*/
NONE,
/**
* Only try small port ranges, and wait a long time between attempts.
* (This level currently unsupported and is equivalent to $NORMAL)
*/
POLITE,
/**
* Try to establish a direct UDP connection through any supported NAT device,
* by "hole punching" or sending outgoing UDP packets to IP and Port we're expecting
* to receive data from.
* NORMAL is the default setting
*/
NORMAL,
/**
* Aggressively try to establish a direct connection to all friends.
* USE WITH CAUTION, this may interfere with some poorly configured NAT devices
* leading to a denial of service effect to all devices behind the NAT.
* (This level currently unsupported and is equivalent to $NORMAL)
*/
AGGRESSIVE,
}

/**
* Type of savedata to create the Tox instance from.
*/
Expand Down Expand Up @@ -486,37 +512,50 @@ static class options {
uint16_t port;
}

/**
* The start port of the inclusive port range to attempt to use.
*
* If both start_port and end_port are 0, the default port range will be
* used: [33445, 33545].
*
* If either start_port or end_port is 0 while the other is non-zero, the
* non-zero port will be the only port in the range.
*
* Having start_port > end_port will yield the same behavior as if start_port
* and end_port were swapped.
*/
uint16_t start_port;
namespace dht {

/**
* The end port of the inclusive port range to attempt to use.
*/
uint16_t end_port;
/**
* The start port of the inclusive port range to attempt to use.
*
* If both start_port and end_port are 0, the default port range will be
* used: [33445, 33545].
*
* If either start_port or end_port is 0 while the other is non-zero, the
* non-zero port will be the only port in the range.
*
* Having start_port > end_port will yield the same behavior as if start_port
* and end_port were swapped.
*/
uint16_t start_port;

/**
* The port to use for the TCP server (relay). If 0, the TCP server is
* disabled.
*
* Enabling it is not required for Tox to function properly.
*
* When enabled, your Tox instance can act as a TCP relay for other Tox
* instance. This leads to increased traffic, thus when writing a client
* it is recommended to enable TCP server only if the user has an option
* to disable it.
*/
uint16_t tcp_port;
/**
* The end port of the inclusive port range to attempt to use.
*/
uint16_t end_port;

/**
* The port to use for the TCP server (relay). If 0, the TCP server is
* disabled.
*
* Enabling it is not required for Tox to function properly.
*
* When enabled, your Tox instance can act as a TCP relay for other Tox
* instance. This leads to increased traffic, thus when writing a client
* it is recommended to enable TCP server only if the user has an option
* to disable it.
*/
uint16_t tcp_port;

/**
* Sets how aggressive toxcore is allowed to be when trying to establish a direct UDP
* connection with friends when either are behind a NAT device.
*
* Clients should be aware of the implications of changing this from its default.
* Setting too low of a level could stop toxcore from creating a direct connections,
* and too high could cause a DoS effect for all users, on some networks.
*/
DHT_NAT_LEVEL nat_level;
}

namespace savedata {
/**
Expand Down
15 changes: 9 additions & 6 deletions toxcore/tox.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,10 @@ ACCESSORS(bool, , udp_enabled)
ACCESSORS(TOX_PROXY_TYPE, proxy_ , type)
ACCESSORS(const char *, proxy_ , host)
ACCESSORS(uint16_t, proxy_ , port)
ACCESSORS(uint16_t, , start_port)
ACCESSORS(uint16_t, , end_port)
ACCESSORS(uint16_t, , tcp_port)
ACCESSORS(uint16_t, , dht_start_port)
ACCESSORS(uint16_t, , dht_end_port)
ACCESSORS(uint16_t, , dht_tcp_port)
ACCESSORS(TOX_DHT_NAT_LEVEL, , dht_nat_level)
ACCESSORS(TOX_SAVEDATA_TYPE, savedata_, type)
ACCESSORS(size_t, savedata_, length)
ACCESSORS(tox_log_cb *, log_, callback)
Expand All @@ -155,6 +156,7 @@ void tox_options_default(struct Tox_Options *options)
options->ipv6_enabled = 1;
options->udp_enabled = 1;
options->proxy_type = TOX_PROXY_TYPE_NONE;
options->dht_nat_level = TOX_DHT_NAT_LEVEL_NORMAL;
}
}

Expand Down Expand Up @@ -216,9 +218,10 @@ Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error)

m_options.ipv6enabled = options->ipv6_enabled;
m_options.udp_disabled = !options->udp_enabled;
m_options.port_range[0] = options->start_port;
m_options.port_range[1] = options->end_port;
m_options.tcp_server_port = options->tcp_port;
m_options.port_range[0] = options->dht_start_port;
m_options.port_range[1] = options->dht_end_port;
m_options.tcp_server_port = options->dht_tcp_port;
m_options.nat_level = options->dht_nat_level;

m_options.log_callback = (logger_cb *)options->log_callback;
m_options.log_user_data = options->log_user_data;
Expand Down
Loading

0 comments on commit 95b4637

Please sign in to comment.