mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Merge branch 'tcp_server'
This commit is contained in:
commit
7315ad08dd
|
@ -809,6 +809,196 @@ loop_top:
|
|||
}
|
||||
END_TEST
|
||||
|
||||
#define TCP_RELAY_PORT 33448
|
||||
|
||||
START_TEST(test_many_clients_tcp)
|
||||
{
|
||||
long long unsigned int cur_time = time(NULL);
|
||||
Tox *toxes[NUM_TOXES];
|
||||
uint32_t i, j;
|
||||
uint32_t to_comp = 974536;
|
||||
|
||||
for (i = 0; i < NUM_TOXES; ++i) {
|
||||
struct Tox_Options opts;
|
||||
tox_options_default(&opts);
|
||||
|
||||
if (i == 0) {
|
||||
opts.tcp_port = TCP_RELAY_PORT;
|
||||
} else {
|
||||
opts.udp_enabled = 0;
|
||||
}
|
||||
|
||||
toxes[i] = tox_new(&opts, 0, 0, 0);
|
||||
ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i);
|
||||
tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp);
|
||||
uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_dht_id(toxes[0], dpk);
|
||||
ck_assert_msg(tox_add_tcp_relay(toxes[i], "::1", TCP_RELAY_PORT, dpk, 0), "add relay error");
|
||||
ck_assert_msg(tox_bootstrap(toxes[i], "::1", 33445, dpk, 0), "Bootstrap error");
|
||||
}
|
||||
|
||||
{
|
||||
TOX_ERR_GET_PORT error;
|
||||
ck_assert_msg(tox_self_get_udp_port(toxes[0], &error) == 33445, "First Tox instance did not bind to udp port 33445.\n");
|
||||
ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error");
|
||||
ck_assert_msg(tox_self_get_tcp_port(toxes[0], &error) == TCP_RELAY_PORT,
|
||||
"First Tox instance did not bind to tcp port %u.\n", TCP_RELAY_PORT);
|
||||
ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error");
|
||||
}
|
||||
|
||||
struct {
|
||||
uint16_t tox1;
|
||||
uint16_t tox2;
|
||||
} pairs[NUM_FRIENDS];
|
||||
|
||||
uint8_t address[TOX_ADDRESS_SIZE];
|
||||
|
||||
for (i = 0; i < NUM_FRIENDS; ++i) {
|
||||
loop_top:
|
||||
pairs[i].tox1 = rand() % NUM_TOXES;
|
||||
pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES;
|
||||
|
||||
for (j = 0; j < i; ++j) {
|
||||
if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2)
|
||||
goto loop_top;
|
||||
}
|
||||
|
||||
tox_self_get_address(toxes[pairs[i].tox1], address);
|
||||
|
||||
TOX_ERR_FRIEND_ADD test;
|
||||
uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (uint8_t *)"Gentoo", 7, &test);
|
||||
|
||||
if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) {
|
||||
goto loop_top;
|
||||
}
|
||||
|
||||
ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
uint16_t counter = 0;
|
||||
|
||||
for (i = 0; i < NUM_TOXES; ++i) {
|
||||
for (j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j)
|
||||
if (tox_friend_get_connection_status(toxes[i], j, 0) == TOX_CONNECTION_TCP)
|
||||
++counter;
|
||||
}
|
||||
|
||||
if (counter == NUM_FRIENDS * 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_TOXES; ++i) {
|
||||
tox_iterate(toxes[i]);
|
||||
}
|
||||
|
||||
c_sleep(50);
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_TOXES; ++i) {
|
||||
tox_kill(toxes[i]);
|
||||
}
|
||||
|
||||
printf("test_many_clients_tcp succeeded, took %llu seconds\n", time(NULL) - cur_time);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#define NUM_TCP_RELAYS 3
|
||||
|
||||
START_TEST(test_many_clients_tcp_b)
|
||||
{
|
||||
long long unsigned int cur_time = time(NULL);
|
||||
Tox *toxes[NUM_TOXES];
|
||||
uint32_t i, j;
|
||||
uint32_t to_comp = 974536;
|
||||
|
||||
for (i = 0; i < NUM_TOXES; ++i) {
|
||||
struct Tox_Options opts;
|
||||
tox_options_default(&opts);
|
||||
|
||||
if (i < NUM_TCP_RELAYS) {
|
||||
opts.tcp_port = TCP_RELAY_PORT + i;
|
||||
} else {
|
||||
opts.udp_enabled = 0;
|
||||
}
|
||||
|
||||
toxes[i] = tox_new(&opts, 0, 0, 0);
|
||||
ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i);
|
||||
tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp);
|
||||
uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk);
|
||||
ck_assert_msg(tox_add_tcp_relay(toxes[i], "::1", TCP_RELAY_PORT + (i % NUM_TCP_RELAYS), dpk, 0), "add relay error");
|
||||
tox_self_get_dht_id(toxes[0], dpk);
|
||||
ck_assert_msg(tox_bootstrap(toxes[i], "::1", 33445, dpk, 0), "Bootstrap error");
|
||||
}
|
||||
|
||||
{
|
||||
TOX_ERR_GET_PORT error;
|
||||
ck_assert_msg(tox_self_get_udp_port(toxes[0], &error) == 33445, "First Tox instance did not bind to udp port 33445.\n");
|
||||
ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error");
|
||||
ck_assert_msg(tox_self_get_tcp_port(toxes[0], &error) == TCP_RELAY_PORT,
|
||||
"First Tox instance did not bind to tcp port %u.\n", TCP_RELAY_PORT);
|
||||
ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error");
|
||||
}
|
||||
|
||||
struct {
|
||||
uint16_t tox1;
|
||||
uint16_t tox2;
|
||||
} pairs[NUM_FRIENDS];
|
||||
|
||||
uint8_t address[TOX_ADDRESS_SIZE];
|
||||
|
||||
for (i = 0; i < NUM_FRIENDS; ++i) {
|
||||
loop_top:
|
||||
pairs[i].tox1 = rand() % NUM_TOXES;
|
||||
pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES;
|
||||
|
||||
for (j = 0; j < i; ++j) {
|
||||
if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2)
|
||||
goto loop_top;
|
||||
}
|
||||
|
||||
tox_self_get_address(toxes[pairs[i].tox1], address);
|
||||
|
||||
TOX_ERR_FRIEND_ADD test;
|
||||
uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (uint8_t *)"Gentoo", 7, &test);
|
||||
|
||||
if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) {
|
||||
goto loop_top;
|
||||
}
|
||||
|
||||
ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
uint16_t counter = 0;
|
||||
|
||||
for (i = 0; i < NUM_TOXES; ++i) {
|
||||
for (j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j)
|
||||
if (tox_friend_get_connection_status(toxes[i], j, 0) == TOX_CONNECTION_TCP)
|
||||
++counter;
|
||||
}
|
||||
|
||||
if (counter == NUM_FRIENDS * 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_TOXES; ++i) {
|
||||
tox_iterate(toxes[i]);
|
||||
}
|
||||
|
||||
c_sleep(50);
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_TOXES; ++i) {
|
||||
tox_kill(toxes[i]);
|
||||
}
|
||||
|
||||
printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(NULL) - cur_time);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
#define NUM_GROUP_TOX 32
|
||||
|
||||
void g_accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
|
||||
|
@ -996,6 +1186,8 @@ Suite *tox_suite(void)
|
|||
DEFTESTCASE(one);
|
||||
DEFTESTCASE_SLOW(few_clients, 50);
|
||||
DEFTESTCASE_SLOW(many_clients, 150);
|
||||
DEFTESTCASE_SLOW(many_clients_tcp, 20);
|
||||
DEFTESTCASE_SLOW(many_clients_tcp_b, 20);
|
||||
DEFTESTCASE_SLOW(many_group, 100);
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -411,6 +411,11 @@ static class options {
|
|||
* The end port of the inclusive port range to attempt to use.
|
||||
*/
|
||||
uint16_t end_port;
|
||||
|
||||
/**
|
||||
* The port to use for the TCP server. If 0, the tcp server is disabled.
|
||||
*/
|
||||
uint16_t tcp_port;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -163,9 +163,15 @@ void send_irc_group(Tox *tox, uint8_t *msg, uint16_t len)
|
|||
uint8_t req[len];
|
||||
unsigned int i;
|
||||
|
||||
unsigned int spaces = 0;
|
||||
|
||||
for (i = 0; i < (len - 1); ++i) {
|
||||
if (msg[i + 1] == ':') {
|
||||
break;
|
||||
if (msg[i + 1] == ' ') {
|
||||
++spaces;
|
||||
} else {
|
||||
if (spaces >= 3 && msg[i + 1] == ':') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
req[i] = msg[i + 1];
|
||||
|
@ -227,11 +233,6 @@ Tox *init_tox(int argc, char *argv[])
|
|||
tox_callback_group_message(tox, ©_groupmessage, 0);
|
||||
tox_callback_group_action(tox, ©_groupmessage, 0);
|
||||
|
||||
uint16_t port = atoi(argv[argvoffset + 2]);
|
||||
unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]);
|
||||
tox_bootstrap(tox, argv[argvoffset + 1], port, binary_string, 0);
|
||||
free(binary_string);
|
||||
|
||||
char temp_id[128];
|
||||
printf("\nEnter the address of irc_syncbots master (38 bytes HEX format):\n");
|
||||
|
||||
|
@ -239,6 +240,11 @@ Tox *init_tox(int argc, char *argv[])
|
|||
exit (1);
|
||||
}
|
||||
|
||||
uint16_t port = atoi(argv[argvoffset + 2]);
|
||||
unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]);
|
||||
tox_bootstrap(tox, argv[argvoffset + 1], port, binary_string, 0);
|
||||
free(binary_string);
|
||||
|
||||
uint8_t *bin_id = hex_string_to_bin(temp_id);
|
||||
uint32_t num = tox_friend_add(tox, bin_id, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo") - 1, 0);
|
||||
free(bin_id);
|
||||
|
|
|
@ -227,17 +227,42 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
|
|||
return ip;
|
||||
}
|
||||
|
||||
/* return 0 if ip is a LAN ip.
|
||||
* return -1 if it is not.
|
||||
*/
|
||||
int LAN_ip(IP ip)
|
||||
/* Is IP a local ip or not. */
|
||||
_Bool Local_ip(IP ip)
|
||||
{
|
||||
if (ip.family == AF_INET) {
|
||||
IP4 ip4 = ip.ip4;
|
||||
|
||||
/* Loopback. */
|
||||
if (ip4.uint8[0] == 127)
|
||||
return 0;
|
||||
return 1;
|
||||
} else {
|
||||
/* embedded IPv4-in-IPv6 */
|
||||
if (IPV6_IPV4_IN_V6(ip.ip6)) {
|
||||
IP ip4;
|
||||
ip4.family = AF_INET;
|
||||
ip4.ip4.uint32 = ip.ip6.uint32[3];
|
||||
return Local_ip(ip4);
|
||||
}
|
||||
|
||||
/* localhost in IPv6 (::1) */
|
||||
if (ip.ip6.uint64[0] == 0 && ip.ip6.uint32[2] == 0 && ip.ip6.uint32[3] == htonl(1))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return 0 if ip is a LAN ip.
|
||||
* return -1 if it is not.
|
||||
*/
|
||||
int LAN_ip(IP ip)
|
||||
{
|
||||
if (Local_ip(ip))
|
||||
return 0;
|
||||
|
||||
if (ip.family == AF_INET) {
|
||||
IP4 ip4 = ip.ip4;
|
||||
|
||||
/* 10.0.0.0 to 10.255.255.255 range. */
|
||||
if (ip4.uint8[0] == 10)
|
||||
|
@ -276,10 +301,6 @@ int LAN_ip(IP ip)
|
|||
ip4.ip4.uint32 = ip.ip6.uint32[3];
|
||||
return LAN_ip(ip4);
|
||||
}
|
||||
|
||||
/* localhost in IPv6 (::1) */
|
||||
if (ip.ip6.uint64[0] == 0 && ip.ip6.uint32[2] == 0 && ip.ip6.uint32[3] == htonl(1))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
|
|
@ -40,6 +40,9 @@ void LANdiscovery_init(DHT *dht);
|
|||
/* Clear packet handlers. */
|
||||
void LANdiscovery_kill(DHT *dht);
|
||||
|
||||
/* Is IP a local ip or not. */
|
||||
_Bool Local_ip(IP ip);
|
||||
|
||||
/* checks if a given IP isn't routable
|
||||
*
|
||||
* return 0 if ip is a LAN ip.
|
||||
|
|
|
@ -1807,6 +1807,27 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (options->tcp_server_port) {
|
||||
m->tcp_server = new_TCP_server(options->ipv6enabled, 1, &options->tcp_server_port, m->dht->self_public_key,
|
||||
m->dht->self_secret_key, m->onion);
|
||||
|
||||
if (m->tcp_server == NULL) {
|
||||
kill_friend_connections(m->fr_c);
|
||||
kill_onion(m->onion);
|
||||
kill_onion_announce(m->onion_a);
|
||||
kill_onion_client(m->onion_c);
|
||||
kill_DHT(m->dht);
|
||||
kill_net_crypto(m->net_crypto);
|
||||
kill_networking(m->net);
|
||||
free(m);
|
||||
|
||||
if (error)
|
||||
*error = MESSENGER_ERROR_TCP_SERVER;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
m->options = *options;
|
||||
friendreq_init(&(m->fr), m->fr_c);
|
||||
set_nospam(&(m->fr), random_int());
|
||||
|
@ -1826,6 +1847,10 @@ void kill_messenger(Messenger *m)
|
|||
|
||||
uint32_t i;
|
||||
|
||||
if (m->tcp_server) {
|
||||
kill_TCP_server(m->tcp_server);
|
||||
}
|
||||
|
||||
kill_friend_connections(m->fr_c);
|
||||
kill_onion(m->onion);
|
||||
kill_onion_announce(m->onion_a);
|
||||
|
@ -2261,6 +2286,15 @@ void do_messenger(Messenger *m)
|
|||
for (i = 0; i < NUM_SAVED_TCP_RELAYS; ++i) {
|
||||
add_tcp_relay(m->net_crypto, m->loaded_relays[i].ip_port, m->loaded_relays[i].public_key);
|
||||
}
|
||||
|
||||
if (m->tcp_server) {
|
||||
/* Add self tcp server. */
|
||||
IP_Port local_ip_port;
|
||||
local_ip_port.port = m->options.tcp_server_port;
|
||||
local_ip_port.ip.family = AF_INET;
|
||||
local_ip_port.ip.ip4.uint32 = INADDR_LOOPBACK;
|
||||
add_tcp_relay(m->net_crypto, local_ip_port, m->tcp_server->public_key);
|
||||
}
|
||||
}
|
||||
|
||||
unix_time_update();
|
||||
|
@ -2270,6 +2304,10 @@ void do_messenger(Messenger *m)
|
|||
do_DHT(m->dht);
|
||||
}
|
||||
|
||||
if (m->tcp_server) {
|
||||
do_TCP_server(m->tcp_server);
|
||||
}
|
||||
|
||||
do_net_crypto(m->net_crypto);
|
||||
do_onion_client(m->onion_c);
|
||||
do_friend_connections(m->fr_c);
|
||||
|
|
|
@ -70,6 +70,7 @@ typedef struct {
|
|||
uint8_t udp_disabled;
|
||||
TCP_Proxy_Info proxy_info;
|
||||
uint16_t port_range[2];
|
||||
uint16_t tcp_server_port;
|
||||
} Messenger_Options;
|
||||
|
||||
|
||||
|
@ -219,6 +220,7 @@ struct Messenger {
|
|||
|
||||
Friend_Connections *fr_c;
|
||||
|
||||
TCP_Server *tcp_server;
|
||||
Friend_Requests fr;
|
||||
uint8_t name[MAX_NAME_LENGTH];
|
||||
uint16_t name_length;
|
||||
|
@ -727,6 +729,7 @@ int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const
|
|||
enum {
|
||||
MESSENGER_ERROR_NONE,
|
||||
MESSENGER_ERROR_PORT,
|
||||
MESSENGER_ERROR_TCP_SERVER,
|
||||
MESSENGER_ERROR_OTHER
|
||||
};
|
||||
|
||||
|
|
|
@ -158,6 +158,15 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_
|
|||
if (!friend_con)
|
||||
return -1;
|
||||
|
||||
/* Local ip and same pk means that they are hosting a TCP relay. */
|
||||
if (Local_ip(ip_port.ip) && memcmp(friend_con->dht_temp_pk, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
|
||||
if (friend_con->dht_ip_port.ip.family != 0) {
|
||||
ip_port.ip = friend_con->dht_ip_port.ip;
|
||||
} else {
|
||||
friend_con->hosting_tcp_relay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int i;
|
||||
|
||||
uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS;
|
||||
|
@ -268,6 +277,11 @@ static void dht_ip_callback(void *object, int32_t number, IP_Port ip_port)
|
|||
set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, 1);
|
||||
friend_con->dht_ip_port = ip_port;
|
||||
friend_con->dht_ip_port_lastrecv = unix_time();
|
||||
|
||||
if (friend_con->hosting_tcp_relay) {
|
||||
friend_add_tcp_relay(fr_c, number, ip_port, friend_con->dht_temp_pk);
|
||||
friend_con->hosting_tcp_relay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_public_key)
|
||||
|
@ -317,6 +331,7 @@ static int handle_status(void *object, int number, uint8_t status)
|
|||
|
||||
friend_con->status = FRIENDCONN_STATUS_CONNECTING;
|
||||
friend_con->crypt_connection_id = -1;
|
||||
friend_con->hosting_tcp_relay = 0;
|
||||
}
|
||||
|
||||
if (call_cb) {
|
||||
|
|
|
@ -96,6 +96,8 @@ typedef struct {
|
|||
|
||||
Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS];
|
||||
uint16_t tcp_relay_counter;
|
||||
|
||||
_Bool hosting_tcp_relay;
|
||||
} Friend_Conn;
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "onion.h"
|
||||
|
||||
#define ONION_ANNOUNCE_MAX_ENTRIES 64
|
||||
#define ONION_ANNOUNCE_MAX_ENTRIES 96
|
||||
#define ONION_ANNOUNCE_TIMEOUT 300
|
||||
#define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES
|
||||
|
||||
|
|
|
@ -1204,7 +1204,7 @@ static void populate_path_nodes_tcp(Onion_Client *onion_c)
|
|||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num_nodes; ++i) {
|
||||
onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key);
|
||||
onion_add_bs_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
134
toxcore/tox.c
134
toxcore/tox.c
|
@ -152,6 +152,7 @@ Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t leng
|
|||
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;
|
||||
|
||||
switch (options->proxy_type) {
|
||||
case TOX_PROXY_TYPE_HTTP:
|
||||
|
@ -238,31 +239,6 @@ void tox_get_savedata(const Tox *tox, uint8_t *data)
|
|||
}
|
||||
}
|
||||
|
||||
static int address_to_ip(Messenger *m, const char *address, IP_Port *ip_port, IP_Port *ip_port_v4)
|
||||
{
|
||||
if (!addr_parse_ip(address, &ip_port->ip)) {
|
||||
if (m->options.udp_disabled) { /* Disable DNS when udp is disabled. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
IP *ip_extra = NULL;
|
||||
ip_init(&ip_port->ip, m->options.ipv6enabled);
|
||||
|
||||
if (m->options.ipv6enabled && ip_port_v4) {
|
||||
/* setup for getting BOTH: an IPv6 AND an IPv4 address */
|
||||
ip_port->ip.family = AF_UNSPEC;
|
||||
ip_reset(&ip_port_v4->ip);
|
||||
ip_extra = &ip_port_v4->ip;
|
||||
}
|
||||
|
||||
if (!addr_resolve(address, &ip_port->ip, ip_extra)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error)
|
||||
{
|
||||
if (!address || !public_key) {
|
||||
|
@ -270,23 +246,53 @@ bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *
|
|||
return 0;
|
||||
}
|
||||
|
||||
Messenger *m = tox;
|
||||
bool ret = tox_add_tcp_relay(tox, address, port, public_key, error);
|
||||
|
||||
if (!ret) {
|
||||
if (port == 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_PORT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m->options.udp_disabled) {
|
||||
return ret;
|
||||
} else { /* DHT only works on UDP. */
|
||||
if (DHT_bootstrap_from_address(m->dht, address, m->options.ipv6enabled, htons(port), public_key) == 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
|
||||
return 0;
|
||||
struct addrinfo *root, *info;
|
||||
|
||||
if (getaddrinfo(address, NULL, NULL, &root) != 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
|
||||
return 0;
|
||||
}
|
||||
|
||||
info = root;
|
||||
|
||||
unsigned int count = 0;
|
||||
|
||||
do {
|
||||
IP_Port ip_port;
|
||||
ip_port.port = htons(port);
|
||||
ip_port.ip.family = info->ai_family;
|
||||
|
||||
if (info->ai_socktype && info->ai_socktype != SOCK_DGRAM) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info->ai_family == AF_INET) {
|
||||
ip_port.ip.ip4.in_addr = ((struct sockaddr_in *)info->ai_addr)->sin_addr;
|
||||
} else if (info->ai_family == AF_INET6) {
|
||||
ip_port.ip.ip6.in6_addr = ((struct sockaddr_in6 *)info->ai_addr)->sin6_addr;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
Messenger *m = tox;
|
||||
onion_add_bs_path_node(m->onion_c, ip_port, public_key);
|
||||
DHT_bootstrap(m->dht, ip_port, public_key);
|
||||
++count;
|
||||
} while ((info = info->ai_next));
|
||||
|
||||
freeaddrinfo(root);
|
||||
|
||||
if (count) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK);
|
||||
return 1;
|
||||
} else {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,25 +304,53 @@ bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8
|
|||
return 0;
|
||||
}
|
||||
|
||||
Messenger *m = tox;
|
||||
IP_Port ip_port, ip_port_v4;
|
||||
|
||||
if (port == 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_PORT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (address_to_ip(m, address, &ip_port, &ip_port_v4) == -1) {
|
||||
struct addrinfo *root, *info;
|
||||
|
||||
if (getaddrinfo(address, NULL, NULL, &root) != 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ip_port.port = htons(port);
|
||||
add_tcp_relay(m->net_crypto, ip_port, public_key);
|
||||
onion_add_bs_path_node(m->onion_c, ip_port, public_key); //TODO: move this
|
||||
info = root;
|
||||
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK);
|
||||
return 1;
|
||||
unsigned int count = 0;
|
||||
|
||||
do {
|
||||
IP_Port ip_port;
|
||||
ip_port.port = htons(port);
|
||||
ip_port.ip.family = info->ai_family;
|
||||
|
||||
if (info->ai_socktype && info->ai_socktype != SOCK_STREAM) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info->ai_family == AF_INET) {
|
||||
ip_port.ip.ip4.in_addr = ((struct sockaddr_in *)info->ai_addr)->sin_addr;
|
||||
} else if (info->ai_family == AF_INET6) {
|
||||
ip_port.ip.ip6.in6_addr = ((struct sockaddr_in6 *)info->ai_addr)->sin6_addr;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
Messenger *m = tox;
|
||||
add_tcp_relay(m->net_crypto, ip_port, public_key);
|
||||
++count;
|
||||
} while ((info = info->ai_next));
|
||||
|
||||
freeaddrinfo(root);
|
||||
|
||||
if (count) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK);
|
||||
return 1;
|
||||
} else {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
TOX_CONNECTION tox_self_get_connection_status(const Tox *tox)
|
||||
|
@ -1205,9 +1239,15 @@ uint16_t tox_self_get_udp_port(const Tox *tox, TOX_ERR_GET_PORT *error)
|
|||
|
||||
uint16_t tox_self_get_tcp_port(const Tox *tox, TOX_ERR_GET_PORT *error)
|
||||
{
|
||||
/* TCP server not yet implemented in clients. */
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_NOT_BOUND);
|
||||
return 0;
|
||||
const Messenger *m = tox;
|
||||
|
||||
if (m->tcp_server) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_OK);
|
||||
return m->options.tcp_server_port;
|
||||
} else {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_NOT_BOUND);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#include "tox_old_code.h"
|
||||
|
|
|
@ -426,6 +426,12 @@ struct Tox_Options {
|
|||
*/
|
||||
uint16_t end_port;
|
||||
|
||||
|
||||
/**
|
||||
* The port to use for the TCP server. If 0, the tcp server is disabled.
|
||||
*/
|
||||
uint16_t tcp_port;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user