mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
big push, putting all the infrastructure in place behind TOX_ENABLE_IPV6
This commit is contained in:
parent
bcf251ac31
commit
bcb283cf45
|
@ -81,10 +81,14 @@ void manage_keys(DHT *dht)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
/* let use decide by cmdline: TODO */
|
||||||
|
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT;
|
||||||
|
|
||||||
/* Initialize networking -
|
/* Initialize networking -
|
||||||
Bind to ip 0.0.0.0:PORT */
|
Bind to ip 0.0.0.0:PORT */
|
||||||
IP4 ip;
|
IP ip;
|
||||||
ip.uint32 = 0;
|
ip_init(&ip, ipv6enabled);
|
||||||
|
|
||||||
DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT)));
|
DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT)));
|
||||||
manage_keys(dht);
|
manage_keys(dht);
|
||||||
printf("Public key: ");
|
printf("Public key: ");
|
||||||
|
@ -110,11 +114,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argc > 3) {
|
if (argc > 3) {
|
||||||
printf("Trying to bootstrap into the network...\n");
|
printf("Trying to bootstrap into the network...\n");
|
||||||
IP_Port bootstrap_info;
|
|
||||||
bootstrap_info.ip.uint32 = inet_addr(argv[1]);
|
|
||||||
bootstrap_info.port = htons(atoi(argv[2]));
|
|
||||||
uint8_t *bootstrap_key = hex_string_to_bin(argv[3]);
|
uint8_t *bootstrap_key = hex_string_to_bin(argv[3]);
|
||||||
DHT_bootstrap(dht, bootstrap_info, bootstrap_key);
|
DHT_bootstrap_ex(dht, argv[1], ipv6enabled, htons(atoi(argv[2])), bootstrap_key);
|
||||||
free(bootstrap_key);
|
free(bootstrap_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,12 @@ struct server_conf_s configure_server(char *cfg_file)
|
||||||
printf("bootstrap_server %d: Invalid port.\n", i);
|
printf("bootstrap_server %d: Invalid port.\n", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
server_conf.info[i].conn.ip.family = AF_INET;
|
||||||
|
server_conf.info[i].conn.ip.ip4.uint32 = resolve_addr(strcpy(tmp_ip, bs_ip));
|
||||||
|
#else
|
||||||
server_conf.info[i].conn.ip.uint32 = resolve_addr(strcpy(tmp_ip, bs_ip));
|
server_conf.info[i].conn.ip.uint32 = resolve_addr(strcpy(tmp_ip, bs_ip));
|
||||||
|
#endif
|
||||||
server_conf.info[i].conn.port = htons(bs_port);
|
server_conf.info[i].conn.port = htons(bs_port);
|
||||||
b16_to_key(strcpy(tmp_pk, bs_pk), bs_pk_p);
|
b16_to_key(strcpy(tmp_pk, bs_pk), bs_pk_p);
|
||||||
}
|
}
|
||||||
|
@ -339,8 +344,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/* Initialize networking
|
/* Initialize networking
|
||||||
bind to ip 0.0.0.0:PORT */
|
bind to ip 0.0.0.0:PORT */
|
||||||
IP4 ip;
|
IP ip;
|
||||||
ip.uint32 = 0;
|
ip_init(&ip, 0);
|
||||||
DHT *dht = new_DHT(new_net_crypto(new_networking(ip, server_conf.port)));
|
DHT *dht = new_DHT(new_net_crypto(new_networking(ip, server_conf.port)));
|
||||||
/* Read the config file */
|
/* Read the config file */
|
||||||
printf("PID file: %s\n", server_conf.pid_file);
|
printf("PID file: %s\n", server_conf.pid_file);
|
||||||
|
|
|
@ -66,13 +66,11 @@ void print_clientlist(DHT *dht)
|
||||||
}
|
}
|
||||||
|
|
||||||
p_ip = dht->close_clientlist[i].ip_port;
|
p_ip = dht->close_clientlist[i].ip_port;
|
||||||
printf("\nIP: %u.%u.%u.%u Port: %u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3],
|
printf("\nIP: %s Port: %u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port));
|
||||||
ntohs(p_ip.port));
|
|
||||||
printf("\nTimestamp: %llu", (long long unsigned int) dht->close_clientlist[i].timestamp);
|
printf("\nTimestamp: %llu", (long long unsigned int) dht->close_clientlist[i].timestamp);
|
||||||
printf("\nLast pinged: %llu\n", (long long unsigned int) dht->close_clientlist[i].last_pinged);
|
printf("\nLast pinged: %llu\n", (long long unsigned int) dht->close_clientlist[i].last_pinged);
|
||||||
p_ip = dht->close_clientlist[i].ret_ip_port;
|
p_ip = dht->close_clientlist[i].ret_ip_port;
|
||||||
printf("OUR IP: %u.%u.%u.%u Port: %u\n", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3],
|
printf("OUR IP: %s Port: %u\n", ip_ntoa(&p_ip.ip), ntohs(p_ip.port));
|
||||||
ntohs(p_ip.port));
|
|
||||||
printf("Timestamp: %llu\n", (long long unsigned int) dht->close_clientlist[i].ret_timestamp);
|
printf("Timestamp: %llu\n", (long long unsigned int) dht->close_clientlist[i].ret_timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,9 +89,8 @@ void print_friendlist(DHT *dht)
|
||||||
printf("%c", dht->friends_list[k].client_id[j]);
|
printf("%c", dht->friends_list[k].client_id[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
p_ip = DHT_getfriendip(dht, dht->friends_list[k].client_id);
|
int friendok = DHT_getfriendip(dht, dht->friends_list[k].client_id, &p_ip);
|
||||||
printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3],
|
printf("\nIP: %s:%u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port));
|
||||||
ntohs(p_ip.port));
|
|
||||||
|
|
||||||
printf("\nCLIENTS IN LIST:\n\n");
|
printf("\nCLIENTS IN LIST:\n\n");
|
||||||
|
|
||||||
|
@ -108,13 +105,11 @@ void print_friendlist(DHT *dht)
|
||||||
}
|
}
|
||||||
|
|
||||||
p_ip = dht->friends_list[k].client_list[i].ip_port;
|
p_ip = dht->friends_list[k].client_list[i].ip_port;
|
||||||
printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3],
|
printf("\nIP: %s:%u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port));
|
||||||
ntohs(p_ip.port));
|
|
||||||
printf("\nTimestamp: %llu", (long long unsigned int) dht->friends_list[k].client_list[i].timestamp);
|
printf("\nTimestamp: %llu", (long long unsigned int) dht->friends_list[k].client_list[i].timestamp);
|
||||||
printf("\nLast pinged: %llu\n", (long long unsigned int) dht->friends_list[k].client_list[i].last_pinged);
|
printf("\nLast pinged: %llu\n", (long long unsigned int) dht->friends_list[k].client_list[i].last_pinged);
|
||||||
p_ip = dht->friends_list[k].client_list[i].ret_ip_port;
|
p_ip = dht->friends_list[k].client_list[i].ret_ip_port;
|
||||||
printf("ret IP: %u.%u.%u.%u:%u\n", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3],
|
printf("ret IP: %s:%u\n", ip_ntoa(&p_ip.ip), ntohs(p_ip.port));
|
||||||
ntohs(p_ip.port));
|
|
||||||
printf("Timestamp: %llu\n", (long long unsigned int)dht->friends_list[k].client_list[i].ret_timestamp);
|
printf("Timestamp: %llu\n", (long long unsigned int)dht->friends_list[k].client_list[i].ret_timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,11 +133,14 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
/* let use decide by cmdline: TODO */
|
||||||
|
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT;
|
||||||
|
|
||||||
//memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
|
//memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
|
||||||
/* initialize networking */
|
/* initialize networking */
|
||||||
/* bind to ip 0.0.0.0:PORT */
|
/* bind to ip 0.0.0.0:PORT */
|
||||||
IP4 ip;
|
IP ip;
|
||||||
ip.uint32 = 0;
|
ip_init(&ip, ipv6enabled);
|
||||||
|
|
||||||
DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT)));
|
DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT)));
|
||||||
|
|
||||||
|
@ -172,14 +170,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
|
|
||||||
perror("Initialization");
|
perror("Initialization");
|
||||||
IP_Port bootstrap_ip_port;
|
DHT_bootstrap_ex(dht, argv[1], ipv6enabled, htons(atoi(argv[2])), hex_string_to_bin(argv[3]));
|
||||||
bootstrap_ip_port.port = htons(atoi(argv[2]));
|
|
||||||
/* bootstrap_ip_port.ip.c[0] = 127;
|
|
||||||
* bootstrap_ip_port.ip.c[1] = 0;
|
|
||||||
* bootstrap_ip_port.ip.c[2] = 0;
|
|
||||||
* bootstrap_ip_port.ip.c[3] = 1; */
|
|
||||||
bootstrap_ip_port.ip.uint32 = inet_addr(argv[1]);
|
|
||||||
DHT_bootstrap(dht, bootstrap_ip_port, hex_string_to_bin(argv[3]));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
IP_Port ip_port;
|
IP_Port ip_port;
|
||||||
|
|
|
@ -66,8 +66,7 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
|
||||||
|
|
||||||
void printip(IP_Port ip_port)
|
void printip(IP_Port ip_port)
|
||||||
{
|
{
|
||||||
printf("\nIP: %u.%u.%u.%u Port: %u", ip_port.ip.uint8[0], ip_port.ip.uint8[1], ip_port.ip.uint8[2], ip_port.ip.uint8[3],
|
printf("\nIP: %s Port: %u", ip_ntoa(&ip_port.ip), ntohs(ip_port.port));
|
||||||
ntohs(ip_port.port));
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
void printpackets(Data test)
|
void printpackets(Data test)
|
||||||
|
@ -152,6 +151,9 @@ void printconnection(int connection_id)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
/* let use decide by cmdline: TODO */
|
||||||
|
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT;
|
||||||
|
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
printf("usage: %s ip port filename\n", argv[0]);
|
printf("usage: %s ip port filename\n", argv[0]);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -168,14 +170,18 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/* initialize networking */
|
/* initialize networking */
|
||||||
/* bind to ip 0.0.0.0:PORT */
|
/* bind to ip 0.0.0.0:PORT */
|
||||||
IP4 ip;
|
IP ip;
|
||||||
ip.uint32 = 0;
|
ip_init(&ip, ipv6enabled);
|
||||||
|
|
||||||
Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT));
|
Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT));
|
||||||
perror("Initialization");
|
perror("Initialization");
|
||||||
|
|
||||||
IP_Port serverip;
|
IP_Port serverip;
|
||||||
serverip.ip.uint32 = inet_addr(argv[1]);
|
ip_init(&serverip.ip, ipv6enabled);
|
||||||
|
addr_resolve(argv[1], &serverip.ip);
|
||||||
serverip.port = htons(atoi(argv[2]));
|
serverip.port = htons(atoi(argv[2]));
|
||||||
printip(serverip);
|
printip(serverip);
|
||||||
|
|
||||||
int connection = new_connection(ludp, serverip);
|
int connection = new_connection(ludp, serverip);
|
||||||
uint64_t timer = current_time();
|
uint64_t timer = current_time();
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,9 @@ void printconnection(int connection_id)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
/* let use decide by cmdline: TODO */
|
||||||
|
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
printf("usage: %s filename\n", argv[0]);
|
printf("usage: %s filename\n", argv[0]);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -163,8 +166,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
//initialize networking
|
//initialize networking
|
||||||
//bind to ip 0.0.0.0:PORT
|
//bind to ip 0.0.0.0:PORT
|
||||||
IP4 ip;
|
IP ip;
|
||||||
ip.uint32 = 0;
|
ip_init(&ip, ipv6enabled);
|
||||||
|
|
||||||
Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT));
|
Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT));
|
||||||
perror("Initialization");
|
perror("Initialization");
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,8 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IPv6: maybe allow from cmdline --ipv6? sticking to IPv4 for now */
|
/* IPv6: maybe allow from cmdline --ipv6? sticking to IPv4 for now */
|
||||||
m = initMessenger(0);
|
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT;
|
||||||
|
m = initMessenger(ipv6enabled);
|
||||||
|
|
||||||
if ( !m ) {
|
if ( !m ) {
|
||||||
fputs("Failed to allocate messenger datastructure\n", stderr);
|
fputs("Failed to allocate messenger datastructure\n", stderr);
|
||||||
|
@ -110,7 +111,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argc > 3) {
|
if (argc > 3) {
|
||||||
uint16_t port = htons(atoi(argv[2]));
|
uint16_t port = htons(atoi(argv[2]));
|
||||||
DHT_bootstrap_ex(m->dht, argv[1], port, hex_string_to_bin(argv[3]));
|
DHT_bootstrap_ex(m->dht, argv[1], ipv6enabled, port, hex_string_to_bin(argv[3]));
|
||||||
} else {
|
} else {
|
||||||
FILE *file = fopen(argv[1], "rb");
|
FILE *file = fopen(argv[1], "rb");
|
||||||
|
|
||||||
|
|
|
@ -537,6 +537,9 @@ void print_help(void)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
/* let use decide by cmdline: TODO */
|
||||||
|
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT;
|
||||||
|
|
||||||
int on = 0;
|
int on = 0;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -566,7 +569,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m = tox_new();
|
m = tox_new_ex(ipv6enabled);
|
||||||
|
|
||||||
if ( !m ) {
|
if ( !m ) {
|
||||||
fputs("Failed to allocate Messenger datastructure", stderr);
|
fputs("Failed to allocate Messenger datastructure", stderr);
|
||||||
|
@ -590,20 +593,12 @@ int main(int argc, char *argv[])
|
||||||
new_lines(idstring);
|
new_lines(idstring);
|
||||||
strcpy(line, "");
|
strcpy(line, "");
|
||||||
|
|
||||||
tox_IP_Port bootstrap_ip_port;
|
uint16_t port = htons(atoi(argv[2]));
|
||||||
bootstrap_ip_port.port = htons(atoi(argv[2]));
|
|
||||||
int resolved_address = resolve_addr(argv[1]);
|
|
||||||
|
|
||||||
if (resolved_address != 0)
|
|
||||||
bootstrap_ip_port.ip.i = resolved_address;
|
|
||||||
else
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
unsigned char *binary_string = hex_string_to_bin(argv[3]);
|
unsigned char *binary_string = hex_string_to_bin(argv[3]);
|
||||||
tox_bootstrap(m, bootstrap_ip_port, binary_string);
|
tox_bootstrap_ex(m, argv[1], ipv6enabled, port, binary_string);
|
||||||
free(binary_string);
|
free(binary_string);
|
||||||
nodelay(stdscr, TRUE);
|
|
||||||
|
|
||||||
|
nodelay(stdscr, TRUE);
|
||||||
while (1) {
|
while (1) {
|
||||||
if (on == 0 && tox_isconnected(m)) {
|
if (on == 0 && tox_isconnected(m)) {
|
||||||
new_lines("[i] connected to DHT\n[i] define username with /n");
|
new_lines("[i] connected to DHT\n[i] define username with /n");
|
||||||
|
|
118
toxcore/DHT.c
118
toxcore/DHT.c
|
@ -115,11 +115,6 @@ static int client_id_cmp(ClientPair p1, ClientPair p2)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ip4port_equal(IP_Port a, IP_Port b)
|
|
||||||
{
|
|
||||||
return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int id_equal(uint8_t *a, uint8_t *b)
|
static int id_equal(uint8_t *a, uint8_t *b)
|
||||||
{
|
{
|
||||||
return memcmp(a, b, CLIENT_ID_SIZE) == 0;
|
return memcmp(a, b, CLIENT_ID_SIZE) == 0;
|
||||||
|
@ -144,15 +139,14 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id
|
||||||
|
|
||||||
for (i = 0; i < length; ++i) {
|
for (i = 0; i < length; ++i) {
|
||||||
/* If ip_port is assigned to a different client_id replace it */
|
/* If ip_port is assigned to a different client_id replace it */
|
||||||
if (ip4port_equal(list[i].ip_port, ip_port)) {
|
if (ipport_equal(&list[i].ip_port, &ip_port)) {
|
||||||
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id_equal(list[i].client_id, client_id)) {
|
if (id_equal(list[i].client_id, client_id)) {
|
||||||
/* Refresh the client timestamp. */
|
/* Refresh the client timestamp. */
|
||||||
list[i].timestamp = temp_time;
|
list[i].timestamp = temp_time;
|
||||||
list[i].ip_port.ip.uint32 = ip_port.ip.uint32;
|
ipport_copy(&list[i].ip_port, &ip_port);
|
||||||
list[i].ip_port.port = ip_port.port;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +210,7 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list
|
||||||
* we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the
|
* we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the
|
||||||
* partner node understands - that's true if *they* are on IPv6
|
* partner node understands - that's true if *they* are on IPv6
|
||||||
*/
|
*/
|
||||||
#ifdef NETWORK_IP_PORT_IS_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
ipv46x = 0;
|
ipv46x = 0;
|
||||||
if (sa_family == AF_INET)
|
if (sa_family == AF_INET)
|
||||||
ipv46x = dht->close_clientlist[i].ip_port.ip.family != AF_INET;
|
ipv46x = dht->close_clientlist[i].ip_port.ip.family != AF_INET;
|
||||||
|
@ -266,7 +260,7 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list
|
||||||
MAX_SENT_NODES,
|
MAX_SENT_NODES,
|
||||||
dht->friends_list[i].client_list[j].client_id);
|
dht->friends_list[i].client_list[j].client_id);
|
||||||
|
|
||||||
#ifdef NETWORK_IP_PORT_IS_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
ipv46x = 0;
|
ipv46x = 0;
|
||||||
if (sa_family == AF_INET)
|
if (sa_family == AF_INET)
|
||||||
ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family != AF_INET;
|
ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family != AF_INET;
|
||||||
|
@ -330,7 +324,7 @@ static int replace_bad( Client_data *list,
|
||||||
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||||
list[i].ip_port = ip_port;
|
list[i].ip_port = ip_port;
|
||||||
list[i].timestamp = temp_time;
|
list[i].timestamp = temp_time;
|
||||||
list[i].ret_ip_port.ip.uint32 = 0;
|
ip_reset(&list[i].ret_ip_port.ip);
|
||||||
list[i].ret_ip_port.port = 0;
|
list[i].ret_ip_port.port = 0;
|
||||||
list[i].ret_timestamp = 0;
|
list[i].ret_timestamp = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -378,7 +372,7 @@ static int replace_good( Client_data *list,
|
||||||
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||||
list[i].ip_port = ip_port;
|
list[i].ip_port = ip_port;
|
||||||
list[i].timestamp = temp_time;
|
list[i].timestamp = temp_time;
|
||||||
list[i].ret_ip_port.ip.uint32 = 0;
|
ip_reset(&list[i].ret_ip_port.ip);
|
||||||
list[i].ret_ip_port.port = 0;
|
list[i].ret_ip_port.port = 0;
|
||||||
list[i].ret_timestamp = 0;
|
list[i].ret_timestamp = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -476,13 +470,13 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id)
|
||||||
if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) {
|
if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) {
|
||||||
pinging = 0;
|
pinging = 0;
|
||||||
|
|
||||||
if (ip_port.ip.uint32 != 0 && ip4port_equal(dht->send_nodes[i].ip_port, ip_port))
|
|
||||||
++pinging;
|
|
||||||
|
|
||||||
if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id)
|
if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id)
|
||||||
++pinging;
|
++pinging;
|
||||||
|
|
||||||
if (pinging == (ping_id != 0) + (ip_port.ip.uint32 != 0))
|
if (ip_isset(&ip_port.ip) && ipport_equal(&dht->send_nodes[i].ip_port, &ip_port))
|
||||||
|
++pinging;
|
||||||
|
|
||||||
|
if (pinging == (ping_id != 0) + (ip_isset(&ip_port.ip) != 0))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -575,11 +569,11 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
|
||||||
random_nonce(nonce);
|
random_nonce(nonce);
|
||||||
|
|
||||||
memcpy(plain, &ping_id, sizeof(ping_id));
|
memcpy(plain, &ping_id, sizeof(ping_id));
|
||||||
#if DHT_NODEFORMAT == 46
|
#ifdef TOX_ENABLE_IPV6
|
||||||
Node4_format *nodes4_list = &(plain + sizeof(ping_id));
|
Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
|
||||||
int i, num_nodes_ok = 0;
|
int i, num_nodes_ok = 0;
|
||||||
for(i = 0; i < num_nodes, i++)
|
for(i = 0; i < num_nodes; i++)
|
||||||
if (nodes_list[i].ip.family == AF_INET) {
|
if (nodes_list[i].ip_port.ip.family == AF_INET) {
|
||||||
memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE);
|
memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE);
|
||||||
nodes4_list[num_nodes_ok].ip_port.ip.uint32 = nodes_list[i].ip_port.ip.ip4.uint32;
|
nodes4_list[num_nodes_ok].ip_port.ip.uint32 = nodes_list[i].ip_port.ip.ip4.uint32;
|
||||||
nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port;
|
nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port;
|
||||||
|
@ -680,14 +674,15 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
|
||||||
if (!is_gettingnodes(dht, source, ping_id))
|
if (!is_gettingnodes(dht, source, ping_id))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
Node_format nodes_list[MAX_SENT_NODES];
|
Node_format nodes_list[MAX_SENT_NODES];
|
||||||
|
|
||||||
#if DHT_NODEFORMAT == 46
|
#ifdef TOX_ENABLE_IPV6
|
||||||
Node4_format *nodes4_list = &(plain + sizeof(ping_id));
|
Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
|
||||||
|
|
||||||
int i, num_nodes_ok = 0;
|
int num_nodes_ok = 0;
|
||||||
for(i = 0; i < num_nodes, i++)
|
for(i = 0; i < num_nodes; i++)
|
||||||
if ((nodes_list[i].ip != 0) && (nodes_list[i].ip != ~0)) {
|
if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != ~0)) {
|
||||||
memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE);
|
memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE);
|
||||||
nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET;
|
nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET;
|
||||||
nodes_list[num_nodes_ok].ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32;
|
nodes_list[num_nodes_ok].ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32;
|
||||||
|
@ -706,8 +701,6 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
|
||||||
|
|
||||||
addto_lists(dht, source, packet + 1);
|
addto_lists(dht, source, packet + 1);
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < num_nodes; ++i) {
|
for (i = 0; i < num_nodes; ++i) {
|
||||||
send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id);
|
send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id);
|
||||||
returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
|
returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
|
||||||
|
@ -775,27 +768,30 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Optimize this. */
|
/* TODO: Optimize this. */
|
||||||
IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id)
|
int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
|
||||||
{
|
{
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
uint64_t temp_time = unix_time();
|
uint64_t temp_time = unix_time();
|
||||||
IP_Port empty = {{{{0}}, 0, 0}};
|
|
||||||
|
ip_reset(&ip_port->ip);
|
||||||
|
ip_port->port = 0;
|
||||||
|
|
||||||
for (i = 0; i < dht->num_friends; ++i) {
|
for (i = 0; i < dht->num_friends; ++i) {
|
||||||
/* Equal */
|
/* Equal */
|
||||||
if (id_equal(dht->friends_list[i].client_id, client_id)) {
|
if (id_equal(dht->friends_list[i].client_id, client_id)) {
|
||||||
for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
|
for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
|
||||||
if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id)
|
if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id)
|
||||||
&& !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT))
|
&& !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
return dht->friends_list[i].client_list[j].ip_port;
|
*ip_port = dht->friends_list[i].client_list[j].ip_port;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return empty;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
empty.ip.uint32 = 1;
|
return -1;
|
||||||
return empty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request
|
/* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request
|
||||||
|
@ -880,16 +876,12 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
|
||||||
getnodes(dht, ip_port, public_key, dht->c->self_public_key);
|
getnodes(dht, ip_port, public_key, dht->c->self_public_key);
|
||||||
send_ping_request(dht->ping, dht->c, ip_port, public_key);
|
send_ping_request(dht->ping, dht->c, ip_port, public_key);
|
||||||
}
|
}
|
||||||
void DHT_bootstrap_ex(DHT *dht, const char *address, uint16_t port, uint8_t *public_key)
|
void DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key)
|
||||||
{
|
{
|
||||||
IPAny_Port ipany_port;
|
IP_Port ip_port;
|
||||||
ipany_port.ip.family = AF_INET;
|
ip_init(&ip_port.ip, ipv6enabled);
|
||||||
if (addr_resolve_or_parse_ip(address, &ipany_port.ip)) {
|
if (addr_resolve_or_parse_ip(address, &ip_port.ip)) {
|
||||||
/* IPAny temporary: copy down */
|
|
||||||
IP_Port ip_port;
|
|
||||||
ip_port.ip.uint32 = ipany_port.ip.ip4.uint32;
|
|
||||||
ip_port.port = port;
|
ip_port.port = port;
|
||||||
|
|
||||||
DHT_bootstrap(dht, ip_port, public_key);
|
DHT_bootstrap(dht, ip_port, public_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -933,7 +925,7 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
|
||||||
client = &friend->client_list[i];
|
client = &friend->client_list[i];
|
||||||
|
|
||||||
/* If ip is not zero and node is good. */
|
/* If ip is not zero and node is good. */
|
||||||
if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
|
|
||||||
if (id_equal(client->client_id, friend->client_id))
|
if (id_equal(client->client_id, friend->client_id))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -975,7 +967,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
|
||||||
client = &friend->client_list[i];
|
client = &friend->client_list[i];
|
||||||
|
|
||||||
/* If ip is not zero and node is good. */
|
/* If ip is not zero and node is good. */
|
||||||
if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
int retval = sendpacket(dht->c->lossless_udp->net, client->ip_port, packet, length);
|
int retval = sendpacket(dht->c->lossless_udp->net, client->ip_port, packet, length);
|
||||||
|
|
||||||
if ((unsigned int)retval == length)
|
if ((unsigned int)retval == length)
|
||||||
|
@ -1009,7 +1001,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
|
||||||
client = &friend->client_list[i];
|
client = &friend->client_list[i];
|
||||||
|
|
||||||
/* If ip is not zero and node is good. */
|
/* If ip is not zero and node is good. */
|
||||||
if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
ip_list[n] = client->ip_port;
|
ip_list[n] = client->ip_port;
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
@ -1115,9 +1107,10 @@ static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey,
|
||||||
*
|
*
|
||||||
* return ip of 0 if failure.
|
* return ip of 0 if failure.
|
||||||
*/
|
*/
|
||||||
static IP4 NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
|
static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
|
||||||
{
|
{
|
||||||
IP4 zero = {{0}};
|
IP zero;
|
||||||
|
ip_reset(&zero);
|
||||||
|
|
||||||
if (len > MAX_FRIEND_CLIENTS)
|
if (len > MAX_FRIEND_CLIENTS)
|
||||||
return zero;
|
return zero;
|
||||||
|
@ -1127,7 +1120,7 @@ static IP4 NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
|
||||||
|
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
for (j = 0; j < len; ++j) {
|
for (j = 0; j < len; ++j) {
|
||||||
if (ip_portlist[i].ip.uint32 == ip_portlist[j].ip.uint32)
|
if (ip_equal(&ip_portlist[i].ip, &ip_portlist[j].ip))
|
||||||
++numbers[i];
|
++numbers[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1144,13 +1137,13 @@ static IP4 NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
|
||||||
*
|
*
|
||||||
* return number of ports and puts the list of ports in portlist.
|
* return number of ports and puts the list of ports in portlist.
|
||||||
*/
|
*/
|
||||||
static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP4 ip)
|
static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint16_t num = 0;
|
uint16_t num = 0;
|
||||||
|
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
if (ip_portlist[i].ip.uint32 == ip.uint32) {
|
if (ip_equal(&ip_portlist[i].ip, &ip)) {
|
||||||
portlist[num] = ntohs(ip_portlist[i].port);
|
portlist[num] = ntohs(ip_portlist[i].port);
|
||||||
++num;
|
++num;
|
||||||
}
|
}
|
||||||
|
@ -1159,7 +1152,7 @@ static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void punch_holes(DHT *dht, IP4 ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num)
|
static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num)
|
||||||
{
|
{
|
||||||
if (numports > MAX_FRIEND_CLIENTS || numports == 0)
|
if (numports > MAX_FRIEND_CLIENTS || numports == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -1170,7 +1163,9 @@ static void punch_holes(DHT *dht, IP4 ip, uint16_t *port_list, uint16_t numports
|
||||||
for (i = dht->friends_list[friend_num].punching_index; i != top; i++) {
|
for (i = dht->friends_list[friend_num].punching_index; i != top; i++) {
|
||||||
/* TODO: Improve port guessing algorithm. */
|
/* TODO: Improve port guessing algorithm. */
|
||||||
uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1);
|
uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1);
|
||||||
IP_Port pinging = {{ip, htons(port), 0}};
|
IP_Port pinging;
|
||||||
|
ip_copy(&pinging.ip, &ip);
|
||||||
|
pinging.port = htons(port);
|
||||||
send_ping_request(dht->ping, dht->c, pinging, dht->friends_list[friend_num].client_id);
|
send_ping_request(dht->ping, dht->c, pinging, dht->friends_list[friend_num].client_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1199,9 +1194,8 @@ static void do_NAT(DHT *dht)
|
||||||
dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time &&
|
dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time &&
|
||||||
dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
|
dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
|
||||||
|
|
||||||
IP4 ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2);
|
IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2);
|
||||||
|
if (!ip_isset(&ip))
|
||||||
if (ip.uint32 == 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint16_t port_list[MAX_FRIEND_CLIENTS];
|
uint16_t port_list[MAX_FRIEND_CLIENTS];
|
||||||
|
@ -1230,16 +1224,15 @@ static void do_NAT(DHT *dht)
|
||||||
*/
|
*/
|
||||||
int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port)
|
int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port)
|
||||||
{
|
{
|
||||||
if (ip_port.ip.uint32 == 0)
|
if (!ip_isset(&ip_port.ip))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_TOPING; ++i) {
|
for (i = 0; i < MAX_TOPING; ++i) {
|
||||||
if (dht->toping[i].ip_port.ip.uint32 == 0) {
|
if (!ip_isset(&dht->toping[i].ip_port.ip)) {
|
||||||
memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE);
|
memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||||
dht->toping[i].ip_port.ip.uint32 = ip_port.ip.uint32;
|
ipport_copy(&dht->toping[i].ip_port, &ip_port);
|
||||||
dht->toping[i].ip_port.port = ip_port.port;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1247,8 +1240,7 @@ int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port)
|
||||||
for (i = 0; i < MAX_TOPING; ++i) {
|
for (i = 0; i < MAX_TOPING; ++i) {
|
||||||
if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) {
|
if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) {
|
||||||
memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE);
|
memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||||
dht->toping[i].ip_port.ip.uint32 = ip_port.ip.uint32;
|
ipport_copy(&dht->toping[i].ip_port, &ip_port);
|
||||||
dht->toping[i].ip_port.port = ip_port.port;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1270,11 +1262,11 @@ static void do_toping(DHT *dht)
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_TOPING; ++i) {
|
for (i = 0; i < MAX_TOPING; ++i) {
|
||||||
if (dht->toping[i].ip_port.ip.uint32 == 0)
|
if (!ip_isset(&dht->toping[i].ip_port.ip))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, dht->toping[i].client_id);
|
send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, dht->toping[i].client_id);
|
||||||
dht->toping[i].ip_port.ip.uint32 = 0;
|
ip_reset(&dht->toping[i].ip_port.ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,13 +83,14 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t client_id[CLIENT_ID_SIZE];
|
uint8_t client_id[CLIENT_ID_SIZE];
|
||||||
IPAny_Port ip_port;
|
IP_Port ip_port;
|
||||||
} Node46_format;
|
} Node46_format;
|
||||||
/* IPAny temporary: change to 46 */
|
|
||||||
#define DHT_NODEFORMAT 4
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
typedef Node46_format Node_format;
|
||||||
|
#else
|
||||||
typedef Node4_format Node_format;
|
typedef Node4_format Node_format;
|
||||||
/* #define DHT_NODEFORMAT 46 */
|
#endif
|
||||||
/* typedef Node46_format Node_format; */
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
IP_Port ip_port;
|
IP_Port ip_port;
|
||||||
|
@ -135,11 +136,21 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id);
|
||||||
* ip must be 4 bytes long.
|
* ip must be 4 bytes long.
|
||||||
* port must be 2 bytes long.
|
* port must be 2 bytes long.
|
||||||
*
|
*
|
||||||
|
* !!! Signature changed!!!
|
||||||
|
*
|
||||||
|
* OLD: IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id);
|
||||||
|
*
|
||||||
* return ip if success.
|
* return ip if success.
|
||||||
* return ip of 0 if failure (This means the friend is either offline or we have not found him yet).
|
* return ip of 0 if failure (This means the friend is either offline or we have not found him yet).
|
||||||
* return ip of 1 if friend is not in list.
|
* return ip of 1 if friend is not in list.
|
||||||
|
*
|
||||||
|
* NEW: int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port);
|
||||||
|
*
|
||||||
|
* return -1, -- if client_id does NOT refer to a friend
|
||||||
|
* return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
|
||||||
|
* return 1, ip if client_id refers to a friend and we found him
|
||||||
*/
|
*/
|
||||||
IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id);
|
int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port);
|
||||||
|
|
||||||
/* Run this function at least a couple times per second (It's the main loop). */
|
/* Run this function at least a couple times per second (It's the main loop). */
|
||||||
void do_DHT(DHT *dht);
|
void do_DHT(DHT *dht);
|
||||||
|
@ -148,7 +159,7 @@ void do_DHT(DHT *dht);
|
||||||
* Sends a get nodes request to the given node with ip port and public_key.
|
* Sends a get nodes request to the given node with ip port and public_key.
|
||||||
*/
|
*/
|
||||||
void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key);
|
void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key);
|
||||||
void DHT_bootstrap_ex(DHT *dht, const char *address, uint16_t port, uint8_t *public_key);
|
void DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key);
|
||||||
|
|
||||||
/* Add nodes to the toping list.
|
/* Add nodes to the toping list.
|
||||||
* All nodes in this list are pinged every TIME_TOPING seconds
|
* All nodes in this list are pinged every TIME_TOPING seconds
|
||||||
|
|
|
@ -81,33 +81,76 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t * d
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Return the broadcast ip. */
|
/* Return the broadcast ip. */
|
||||||
static IP4 broadcast_ip(void)
|
static IP broadcast_ip(sa_family_t sa_family)
|
||||||
{
|
{
|
||||||
IP4 ip;
|
IP ip;
|
||||||
ip.uint32 = ~0;
|
ip_reset(&ip);
|
||||||
|
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
if (sa_family == AF_INET)
|
||||||
|
{
|
||||||
|
ip.family = AF_INET;
|
||||||
|
ip.ip4.uint32 = INADDR_BROADCAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa_family == AF_INET6)
|
||||||
|
{
|
||||||
|
ip.family = AF_INET6;
|
||||||
|
/* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */
|
||||||
|
/* FE80::*: MUST be exact, for that we would need to look over all
|
||||||
|
* interfaces and check in which status they are */
|
||||||
|
ip.ip6.s6_addr[ 0] = 0xFF;
|
||||||
|
ip.ip6.s6_addr[ 1] = 0x02;
|
||||||
|
ip.ip6.s6_addr[15] = 0x01;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ip.uint32 = INADDR_BROADCAST;
|
||||||
|
#endif
|
||||||
|
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return 0 if ip is a LAN ip.
|
/* return 0 if ip is a LAN ip.
|
||||||
* return -1 if it is not.
|
* return -1 if it is not.
|
||||||
*/
|
*/
|
||||||
static int LAN_ip(IP4 ip)
|
static int LAN_ip(IP ip)
|
||||||
{
|
{
|
||||||
if (ip.uint8[0] == 127) /* Loopback. */
|
#ifdef TOX_ENABLE_IPV6
|
||||||
return 0;
|
if (ip.family == AF_INET) {
|
||||||
|
IP4 ip4 = ip.ip4;
|
||||||
|
#else
|
||||||
|
IP4 ip4 = ip;
|
||||||
|
#endif
|
||||||
|
/* Loopback. */
|
||||||
|
if (ip4.uint8[0] == 127)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (ip.uint8[0] == 10) /* 10.0.0.0 to 10.255.255.255 range. */
|
/* 10.0.0.0 to 10.255.255.255 range. */
|
||||||
return 0;
|
if (ip4.uint8[0] == 10)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (ip.uint8[0] == 172 && ip.uint8[1] >= 16 && ip.uint8[1] <= 31) /* 172.16.0.0 to 172.31.255.255 range. */
|
/* 172.16.0.0 to 172.31.255.255 range. */
|
||||||
return 0;
|
if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (ip.uint8[0] == 192 && ip.uint8[1] == 168) /* 192.168.0.0 to 192.168.255.255 range. */
|
/* 192.168.0.0 to 192.168.255.255 range. */
|
||||||
return 0;
|
if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (ip.uint8[0] == 169 && ip.uint8[1] == 254 && ip.uint8[2] != 0
|
/* 169.254.1.0 to 169.254.254.255 range. */
|
||||||
&& ip.uint8[2] != 255)/* 169.254.1.0 to 169.254.254.255 range. */
|
if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0
|
||||||
return 0;
|
&& ip4.uint8[2] != 255)
|
||||||
|
return 0;
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
}
|
||||||
|
else if (ip.family == AF_INET6) {
|
||||||
|
/* autogenerated for each interface: FE80::* (up to FEBF::*)
|
||||||
|
/* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */
|
||||||
|
if (((ip.ip6.s6_addr[0] == 0xFF) && (ip.ip6.s6_addr[1] < 3) && (ip.ip6.s6_addr[15] == 1)) ||
|
||||||
|
((ip.ip6.s6_addr[0] == 0xFE) && ((ip.ip6.s6_addr[1] & 0xC0) == 0x80)))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -135,7 +178,9 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c)
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
|
send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
|
||||||
#endif
|
#endif
|
||||||
IP_Port ip_port = {{broadcast_ip(), port, 0}};
|
IP_Port ip_port;
|
||||||
|
ip_port.ip = broadcast_ip(c->lossless_udp->net->family);
|
||||||
|
ip_port.port = port;
|
||||||
return sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES);
|
return sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,7 @@
|
||||||
int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port)
|
int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port)
|
||||||
{
|
{
|
||||||
tox_array_for_each(&ludp->connections, Connection, tmp) {
|
tox_array_for_each(&ludp->connections, Connection, tmp) {
|
||||||
if (tmp->ip_port.ip.uint32 == ip_port.ip.uint32 &&
|
if (tmp-> status > 0 && ipport_equal(&tmp->ip_port, &ip_port)) {
|
||||||
tmp->ip_port.port == ip_port.port &&
|
|
||||||
tmp->status > 0) {
|
|
||||||
return tmp_i;
|
return tmp_i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,17 +59,49 @@ int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port)
|
||||||
*
|
*
|
||||||
* TODO: make this better
|
* TODO: make this better
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static uint8_t randtable_initget(Lossless_UDP *ludp, uint32_t index, uint8_t value)
|
||||||
|
{
|
||||||
|
if (ludp->randtable[index][value] == 0)
|
||||||
|
ludp->randtable[index][value] = random_int();
|
||||||
|
|
||||||
|
return ludp->randtable[index][value];
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source)
|
static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source)
|
||||||
{
|
{
|
||||||
uint32_t id = 0, i;
|
uint32_t id = 0, i = 0;
|
||||||
|
|
||||||
for (i = 0; i < 6; ++i) {
|
uint8_t *uint8;
|
||||||
if (ludp->randtable[i][source.uint8[i]] == 0)
|
uint8 = (uint8_t *)&source.port;
|
||||||
ludp->randtable[i][source.uint8[i]] = random_int();
|
id ^= randtable_initget(ludp, i, *uint8);
|
||||||
|
i++, uint8++;
|
||||||
|
id ^= randtable_initget(ludp, i, *uint8);
|
||||||
|
i++;
|
||||||
|
|
||||||
id ^= ludp->randtable[i][source.uint8[i]];
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
if (source.ip.family == AF_INET)
|
||||||
|
{
|
||||||
|
IP4 ip4 = source.ip.ip4;
|
||||||
|
#else
|
||||||
|
IP4 ip4 = source.ip;
|
||||||
|
#endif
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < 4; k++) {
|
||||||
|
id ^= randtable_initget(ludp, i++, ip4.uint8[k]);
|
||||||
|
}
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (source.ip.family == AF_INET6)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < 16; k++) {
|
||||||
|
id ^= randtable_initget(ludp, i++, source.ip.ip6.s6_addr[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* id can't be zero. */
|
/* id can't be zero. */
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
id = 1;
|
id = 1;
|
||||||
|
@ -290,7 +320,9 @@ IP_Port connection_ip(Lossless_UDP *ludp, int connection_id)
|
||||||
if ((unsigned int)connection_id < ludp->connections.len)
|
if ((unsigned int)connection_id < ludp->connections.len)
|
||||||
return tox_array_get(&ludp->connections, connection_id, Connection).ip_port;
|
return tox_array_get(&ludp->connections, connection_id, Connection).ip_port;
|
||||||
|
|
||||||
IP_Port zero = {{{{0}}, 0, 0}};
|
IP_Port zero;
|
||||||
|
ip_reset(&zero.ip);
|
||||||
|
zero.port = 0;
|
||||||
return zero;
|
return zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,13 @@ typedef struct {
|
||||||
tox_array connections;
|
tox_array connections;
|
||||||
|
|
||||||
/* Table of random numbers used in handshake_id. */
|
/* Table of random numbers used in handshake_id. */
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
/* IPv6 (16) + port (2)*/
|
||||||
|
uint32_t randtable[18][256];
|
||||||
|
#else
|
||||||
|
/* IPv4 (4) + port (2) */
|
||||||
uint32_t randtable[6][256];
|
uint32_t randtable[6][256];
|
||||||
|
#endif
|
||||||
|
|
||||||
} Lossless_UDP;
|
} Lossless_UDP;
|
||||||
|
|
||||||
|
|
|
@ -658,14 +658,8 @@ Messenger *initMessenger(uint8_t ipv6enabled)
|
||||||
if ( ! m )
|
if ( ! m )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef NETWORK_IP_PORT_IS_IPV6
|
IP ip;
|
||||||
IPAny ip;
|
ip_init(&ip, ipv6enabled);
|
||||||
memset(&ip, 0, sizeof(ip));
|
|
||||||
ip.family = ipv6enabled ? AF_INET6 : AF_INET;
|
|
||||||
#else
|
|
||||||
IP4 ip;
|
|
||||||
ip.uint32 = 0;
|
|
||||||
#endif
|
|
||||||
m->net = new_networking(ip, PORT);
|
m->net = new_networking(ip, PORT);
|
||||||
|
|
||||||
if (m->net == NULL) {
|
if (m->net == NULL) {
|
||||||
|
@ -749,11 +743,12 @@ void doFriends(Messenger *m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Port friendip = DHT_getfriendip(m->dht, m->friendlist[i].client_id);
|
IP_Port friendip;
|
||||||
|
int friendok = DHT_getfriendip(m->dht, m->friendlist[i].client_id, &friendip);
|
||||||
|
|
||||||
switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) {
|
switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) {
|
||||||
case 0:
|
case 0:
|
||||||
if (friendip.ip.uint32 > 1)
|
if (friendok == 1)
|
||||||
m->friendlist[i].crypt_connection_id = crypto_connect(m->net_crypto, m->friendlist[i].client_id, friendip);
|
m->friendlist[i].crypt_connection_id = crypto_connect(m->net_crypto, m->friendlist[i].client_id, friendip);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -50,18 +50,22 @@ int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8
|
||||||
if (len == -1)
|
if (len == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
IP_Port ip_port = DHT_getfriendip(dht, public_key);
|
IP_Port ip_port;
|
||||||
|
int friendok = DHT_getfriendip(dht, public_key, &ip_port);
|
||||||
|
|
||||||
if (ip_port.ip.uint32 == 1)
|
// not a friend
|
||||||
|
if (friendok == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ip_port.ip.uint32 != 0) {
|
// is a friend and we know how to reach him
|
||||||
|
if (friendok == 1) {
|
||||||
if (sendpacket(dht->c->lossless_udp->net, ip_port, packet, len) != -1)
|
if (sendpacket(dht->c->lossless_udp->net, ip_port, packet, len) != -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// is a friend, we DON'T know how to reach him
|
||||||
int num = route_tofriend(dht, public_key, packet, len);
|
int num = route_tofriend(dht, public_key, packet, len);
|
||||||
|
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
|
|
|
@ -204,7 +204,7 @@ static uint8_t sendto_allpeers(Group_Chat *chat, uint8_t *data, uint16_t length,
|
||||||
uint64_t temp_time = unix_time();
|
uint64_t temp_time = unix_time();
|
||||||
|
|
||||||
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
|
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
|
||||||
if (chat->close[i].ip_port.ip.uint32 != 0 && chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) {
|
if (ip_isset(&chat->close[i].ip_port.ip) && chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) {
|
||||||
if (send_groupchatpacket(chat, chat->close[i].ip_port, chat->close[i].client_id, data, length, request_id) == 0)
|
if (send_groupchatpacket(chat, chat->close[i].ip_port, chat->close[i].client_id, data, length, request_id) == 0)
|
||||||
++sent;
|
++sent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -439,7 +439,7 @@ int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port)
|
||||||
if (id != -1) {
|
if (id != -1) {
|
||||||
IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id].number);
|
IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id].number);
|
||||||
|
|
||||||
if (c_ip.ip.uint32 == ip_port.ip.uint32 && c_ip.port == ip_port.port)
|
if (ipport_equal(&c_ip, &ip_port))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,63 @@ uint32_t random_int(void)
|
||||||
*/
|
*/
|
||||||
int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length)
|
int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length)
|
||||||
{
|
{
|
||||||
ADDR addr = {AF_INET, ip_port.port, ip_port.ip, {0}};
|
#ifdef TOX_ENABLE_IPV6
|
||||||
return sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr));
|
/* socket AF_INET, but target IP NOT: can't send */
|
||||||
|
if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET))
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct sockaddr_storage addr;
|
||||||
|
size_t addrsize = 0;
|
||||||
|
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
if (ip_port.ip.family == AF_INET) {
|
||||||
|
if (net->family == AF_INET6) {
|
||||||
|
/* must convert to IPV4-in-IPV6 address */
|
||||||
|
addrsize = sizeof(struct sockaddr_in6);
|
||||||
|
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
|
||||||
|
addr6->sin6_family = AF_INET6;
|
||||||
|
addr6->sin6_port = ip_port.port;
|
||||||
|
|
||||||
|
/* there should be a macro for this in a standards compliant
|
||||||
|
* environment, not found */
|
||||||
|
addr6->sin6_addr.s6_addr32[0] = 0;
|
||||||
|
addr6->sin6_addr.s6_addr32[1] = 0;
|
||||||
|
addr6->sin6_addr.s6_addr32[2] = htonl(0xFFFF);
|
||||||
|
addr6->sin6_addr.s6_addr32[3] = ip_port.ip.ip4.uint32;
|
||||||
|
|
||||||
|
addr6->sin6_flowinfo = 0;
|
||||||
|
addr6->sin6_scope_id = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IP4 ip4 = ip_port.ip.ip4;
|
||||||
|
#else
|
||||||
|
IP4 ip4 = ip_port.ip;
|
||||||
|
#endif
|
||||||
|
addrsize = sizeof(struct sockaddr_in);
|
||||||
|
struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
|
||||||
|
addr4->sin_family = AF_INET;
|
||||||
|
addr4->sin_addr = ip4.in_addr;
|
||||||
|
addr4->sin_port = ip_port.port;
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ip_port.ip.family == AF_INET6) {
|
||||||
|
addrsize = sizeof(struct sockaddr_in6);
|
||||||
|
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
|
||||||
|
addr6->sin6_family = AF_INET6;
|
||||||
|
addr6->sin6_port = ip_port.port;
|
||||||
|
addr6->sin6_addr = ip_port.ip.ip6;
|
||||||
|
|
||||||
|
addr6->sin6_flowinfo = 0;
|
||||||
|
addr6->sin6_scope_id = 0;
|
||||||
|
} else {
|
||||||
|
/* unknown address type*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function to receive data
|
/* Function to receive data
|
||||||
|
@ -82,7 +137,7 @@ static int receivepacket(unsigned int sock, IP_Port *ip_port, uint8_t *data, uin
|
||||||
static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
|
static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ADDR addr;
|
struct sockaddr_storage addr;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
int addrlen = sizeof(addr);
|
int addrlen = sizeof(addr);
|
||||||
#else
|
#else
|
||||||
|
@ -93,8 +148,31 @@ static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *le
|
||||||
if (*(int32_t *)length <= 0)
|
if (*(int32_t *)length <= 0)
|
||||||
return -1; /* Nothing received or empty packet. */
|
return -1; /* Nothing received or empty packet. */
|
||||||
|
|
||||||
ip_port->ip = addr.ip;
|
#ifdef TOX_ENABLE_IPV6
|
||||||
ip_port->port = addr.port;
|
if (addr.ss_family == AF_INET) {
|
||||||
|
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
|
||||||
|
ip_port->ip.family = addr_in->sin_family;
|
||||||
|
ip_port->ip.ip4.in_addr = addr_in->sin_addr;
|
||||||
|
ip_port->port = addr_in->sin_port;
|
||||||
|
}
|
||||||
|
else if (addr.ss_family == AF_INET6) {
|
||||||
|
struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||||
|
ip_port->ip.family = addr_in6->sin6_family;
|
||||||
|
ip_port->ip.ip6 = addr_in6->sin6_addr;
|
||||||
|
ip_port->port = addr_in6->sin6_port;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
|
if (addr.ss_family == AF_INET) {
|
||||||
|
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
|
||||||
|
ip_port->ip.in_addr = addr_in->sin_addr;
|
||||||
|
ip_port->port = addr_in->sin_port;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,18 +234,32 @@ static void at_shutdown(void)
|
||||||
* return Networking_Core object if no problems
|
* return Networking_Core object if no problems
|
||||||
* return NULL if there are problems.
|
* return NULL if there are problems.
|
||||||
*/
|
*/
|
||||||
Networking_Core *new_networking(IP4 ip, uint16_t port)
|
Networking_Core *new_networking(IP ip, uint16_t port)
|
||||||
{
|
{
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
/* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */
|
||||||
|
if (ip.family != AF_INET && ip.family != AF_INET6)
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (at_startup() != 0)
|
if (at_startup() != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Initialize our socket. */
|
|
||||||
Networking_Core *temp = calloc(1, sizeof(Networking_Core));
|
Networking_Core *temp = calloc(1, sizeof(Networking_Core));
|
||||||
|
|
||||||
if (temp == NULL)
|
if (temp == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
temp->family = AF_INET;
|
sa_family_t family = 0;
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
family = ip.family;
|
||||||
|
#else
|
||||||
|
family = AF_INET;
|
||||||
|
#endif
|
||||||
|
temp->family = family;
|
||||||
|
temp->port = 0;
|
||||||
|
|
||||||
|
/* Initialize our socket. */
|
||||||
|
/* add log message what we're creating */
|
||||||
temp->sock = socket(temp->family, SOCK_DGRAM, IPPROTO_UDP);
|
temp->sock = socket(temp->family, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
|
||||||
/* Check for socket error. */
|
/* Check for socket error. */
|
||||||
|
@ -201,7 +293,7 @@ Networking_Core *new_networking(IP4 ip, uint16_t port)
|
||||||
return -1;
|
return -1;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Enable broadcast on socket. */
|
/* Enable broadcast on socket? */
|
||||||
int broadcast = 1;
|
int broadcast = 1;
|
||||||
setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast));
|
setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast));
|
||||||
|
|
||||||
|
@ -216,11 +308,72 @@ Networking_Core *new_networking(IP4 ip, uint16_t port)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Bind our socket to port PORT and address 0.0.0.0 */
|
/* Bind our socket to port PORT and address 0.0.0.0 */
|
||||||
ADDR addr = {temp->family, htons(port), ip, {0}};
|
uint16_t *portptr = NULL;
|
||||||
if (!bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr)))
|
struct sockaddr_storage addr;
|
||||||
temp->port = port;
|
size_t addrsize;
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
if (temp->family == AF_INET)
|
||||||
|
{
|
||||||
|
IP4 ip4 = ip.ip4;
|
||||||
|
#else
|
||||||
|
IP4 ip4 = ip;
|
||||||
|
#endif
|
||||||
|
addrsize = sizeof(struct sockaddr_in);
|
||||||
|
struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
|
||||||
|
addr4->sin_family = AF_INET;
|
||||||
|
addr4->sin_port = htons(port);
|
||||||
|
addr4->sin_addr = ip4.in_addr;
|
||||||
|
|
||||||
return temp;
|
portptr = &addr4->sin_port;
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
}
|
||||||
|
else if (temp->family == AF_INET6)
|
||||||
|
{
|
||||||
|
addrsize = sizeof(struct sockaddr_in6);
|
||||||
|
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
|
||||||
|
addr6->sin6_family = AF_INET6;
|
||||||
|
addr6->sin6_port = htons(port);
|
||||||
|
addr6->sin6_addr = ip.ip6;
|
||||||
|
|
||||||
|
addr6->sin6_flowinfo = 0;
|
||||||
|
addr6->sin6_scope_id = 0;
|
||||||
|
|
||||||
|
portptr = &addr6->sin6_port;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (ip.family == AF_INET6) {
|
||||||
|
char ipv6only = 0;
|
||||||
|
int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only));
|
||||||
|
if (res < 0) {
|
||||||
|
/* add log message*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* a hanging program or a different user might block the standard port;
|
||||||
|
* as long as it isn't a parameter coming from the commandline,
|
||||||
|
* try a few ports after it, to see if we can find a "free" one
|
||||||
|
*/
|
||||||
|
int tries, res;
|
||||||
|
for(tries = 0; tries < 9; tries++)
|
||||||
|
{
|
||||||
|
res = bind(temp->sock, (struct sockaddr *)&addr, addrsize);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
temp->port = *portptr;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t port = ntohs(*portptr);
|
||||||
|
port++;
|
||||||
|
*portptr = htons(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Failed to bind socket: %s (IP/Port: %s:%u\n", strerror(errno), ip_ntoa(&ip), port);
|
||||||
|
free(temp);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function to cleanup networking stuff. */
|
/* Function to cleanup networking stuff. */
|
||||||
|
@ -241,11 +394,12 @@ void kill_networking(Networking_Core *net)
|
||||||
*
|
*
|
||||||
* returns 0 when not equal or when uninitialized
|
* returns 0 when not equal or when uninitialized
|
||||||
*/
|
*/
|
||||||
int ip_equal(IPAny *a, IPAny *b)
|
int ip_equal(IP *a, IP *b)
|
||||||
{
|
{
|
||||||
if (!a || !b)
|
if (!a || !b)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
if (a->family == AF_INET)
|
if (a->family == AF_INET)
|
||||||
return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr);
|
return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr);
|
||||||
|
|
||||||
|
@ -253,6 +407,9 @@ int ip_equal(IPAny *a, IPAny *b)
|
||||||
return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6);
|
return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
#else
|
||||||
|
return (a->uint32 == b->uint32);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ipport_equal
|
/* ipport_equal
|
||||||
|
@ -261,7 +418,7 @@ int ip_equal(IPAny *a, IPAny *b)
|
||||||
*
|
*
|
||||||
* returns 0 when not equal or when uninitialized
|
* returns 0 when not equal or when uninitialized
|
||||||
*/
|
*/
|
||||||
int ipport_equal(IPAny_Port *a, IPAny_Port *b)
|
int ipport_equal(IP_Port *a, IP_Port *b)
|
||||||
{
|
{
|
||||||
if (!a || !b)
|
if (!a || !b)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -272,15 +429,86 @@ int ipport_equal(IPAny_Port *a, IPAny_Port *b)
|
||||||
return ip_equal(&a->ip, &b->ip);
|
return ip_equal(&a->ip, &b->ip);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ipany_ntoa
|
/* nulls out ip */
|
||||||
|
void ip_reset(IP *ip)
|
||||||
|
{
|
||||||
|
if (!ip)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
memset(ip, 0, sizeof(*ip));
|
||||||
|
#else
|
||||||
|
ip->uint32 = 0;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* nulls out ip, sets family according to flag */
|
||||||
|
void ip_init(IP *ip, uint8_t ipv6enabled)
|
||||||
|
{
|
||||||
|
if (!ip)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
memset(ip, 0, sizeof(ip));
|
||||||
|
ip->family = ipv6enabled ? AF_INET6 : AF_INET;
|
||||||
|
#else
|
||||||
|
ip->uint32 = 0;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* checks if ip is valid */
|
||||||
|
int ip_isset(IP *ip)
|
||||||
|
{
|
||||||
|
if (!ip)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
return (ip->family != 0);
|
||||||
|
#else
|
||||||
|
return (ip->uint32 != 0);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* checks if ip is valid */
|
||||||
|
int ipport_isset(IP_Port *ipport)
|
||||||
|
{
|
||||||
|
if (!ipport)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!ipport->port)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ip_isset(&ipport->ip);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* copies an ip structure (careful about direction!) */
|
||||||
|
void ip_copy(IP *target, IP *source)
|
||||||
|
{
|
||||||
|
if (!source || !target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(target, source, sizeof(IP));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* copies an ip_port structure (careful about direction!) */
|
||||||
|
void ipport_copy(IP_Port *target, IP_Port *source)
|
||||||
|
{
|
||||||
|
if (!source || !target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(target, source, sizeof(IP_Port));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ip_ntoa
|
||||||
* converts ip into a string
|
* converts ip into a string
|
||||||
* uses a static buffer, so mustn't used multiple times in the same output
|
* uses a static buffer, so mustn't used multiple times in the same output
|
||||||
*/
|
*/
|
||||||
/* there would be INET6_ADDRSTRLEN, but it might be too short for the error message */
|
/* there would be INET6_ADDRSTRLEN, but it might be too short for the error message */
|
||||||
static char addresstext[96];
|
static char addresstext[96];
|
||||||
const char *ipany_ntoa(IPAny *ip)
|
const char *ip_ntoa(IP *ip)
|
||||||
{
|
{
|
||||||
if (ip) {
|
if (ip) {
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
if (ip->family == AF_INET) {
|
if (ip->family == AF_INET) {
|
||||||
addresstext[0] = 0;
|
addresstext[0] = 0;
|
||||||
struct in_addr *addr = (struct in_addr *)&ip->ip4;
|
struct in_addr *addr = (struct in_addr *)&ip->ip4;
|
||||||
|
@ -296,6 +524,11 @@ const char *ipany_ntoa(IPAny *ip)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family);
|
snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family);
|
||||||
|
#else
|
||||||
|
addresstext[0] = 0;
|
||||||
|
struct in_addr *addr = (struct in_addr *)&ip;
|
||||||
|
inet_ntop(AF_INET, addr, addresstext, sizeof(addresstext));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)");
|
snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)");
|
||||||
|
@ -318,8 +551,12 @@ const char *ipany_ntoa(IPAny *ip)
|
||||||
* returns 1 on success, 0 on failure
|
* returns 1 on success, 0 on failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int addr_parse_ip(const char *address, IPAny *to)
|
int addr_parse_ip(const char *address, IP *to)
|
||||||
{
|
{
|
||||||
|
if (!address || !to)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
struct in_addr addr4;
|
struct in_addr addr4;
|
||||||
if (1 == inet_pton(AF_INET, address, &addr4)) {
|
if (1 == inet_pton(AF_INET, address, &addr4)) {
|
||||||
to->family = AF_INET;
|
to->family = AF_INET;
|
||||||
|
@ -333,6 +570,13 @@ int addr_parse_ip(const char *address, IPAny *to)
|
||||||
to->ip6 = addr6;
|
to->ip6 = addr6;
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
struct in_addr addr4;
|
||||||
|
if (1 == inet_pton(AF_INET, address, &addr4)) {
|
||||||
|
to->in_addr = addr4;
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
@ -353,15 +597,25 @@ int addr_parse_ip(const char *address, IPAny *to)
|
||||||
* returns 0 on failure
|
* returns 0 on failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int addr_resolve(const char *address, IPAny *ip)
|
int addr_resolve(const char *address, IP *to)
|
||||||
{
|
{
|
||||||
|
if (!address || !to)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sa_family_t family;
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
family = to->family;
|
||||||
|
#else
|
||||||
|
family = AF_INET;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct addrinfo *server = NULL;
|
struct addrinfo *server = NULL;
|
||||||
struct addrinfo *walker = NULL;
|
struct addrinfo *walker = NULL;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = ip->family;
|
hints.ai_family = family;
|
||||||
hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
|
hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
|
@ -385,31 +639,40 @@ int addr_resolve(const char *address, IPAny *ip)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
IP4 ip4;
|
IP4 ip4;
|
||||||
memset(&ip4, 0, sizeof(ip4));
|
memset(&ip4, 0, sizeof(ip4));
|
||||||
IP6 ip6;
|
IP6 ip6;
|
||||||
memset(&ip6, 0, sizeof(ip6));
|
memset(&ip6, 0, sizeof(ip6));
|
||||||
|
#endif
|
||||||
|
|
||||||
walker = server;
|
walker = server;
|
||||||
while (walker && (rc != 3)) {
|
while (walker && (rc != 3)) {
|
||||||
if (ip->family != AF_UNSPEC) {
|
if (family != AF_UNSPEC) {
|
||||||
if (walker->ai_family == ip->family) {
|
if (walker->ai_family == family) {
|
||||||
if (ip->family == AF_INET) {
|
if (family == AF_INET) {
|
||||||
if (walker->ai_addrlen == sizeof(struct sockaddr_in)) {
|
if (walker->ai_addrlen == sizeof(struct sockaddr_in)) {
|
||||||
struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
|
struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
|
||||||
ip->ip4.in_addr = addr->sin_addr;
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
to->ip4.in_addr = addr->sin_addr;
|
||||||
|
#else
|
||||||
|
to->in_addr = addr->sin_addr;
|
||||||
|
#endif
|
||||||
rc = 3;
|
rc = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ip->family == AF_INET6) {
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
else if (family == AF_INET6) {
|
||||||
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
|
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
|
||||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
|
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
|
||||||
ip->ip6 = addr->sin6_addr;
|
to->ip6 = addr->sin6_addr;
|
||||||
rc = 3;
|
rc = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
else {
|
else {
|
||||||
if (walker->ai_family == AF_INET) {
|
if (walker->ai_family == AF_INET) {
|
||||||
if (walker->ai_addrlen == sizeof(struct sockaddr_in)) {
|
if (walker->ai_addrlen == sizeof(struct sockaddr_in)) {
|
||||||
|
@ -426,22 +689,25 @@ int addr_resolve(const char *address, IPAny *ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
walker = walker->ai_next;
|
walker = walker->ai_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip->family == AF_UNSPEC) {
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
if (to->family == AF_UNSPEC) {
|
||||||
if (rc & 2) {
|
if (rc & 2) {
|
||||||
ip->family = AF_INET6;
|
to->family = AF_INET6;
|
||||||
ip->ip6 = ip6;
|
to->ip6 = ip6;
|
||||||
}
|
}
|
||||||
else if (rc & 1) {
|
else if (rc & 1) {
|
||||||
ip->family = AF_INET;
|
to->family = AF_INET;
|
||||||
ip->ip4 = ip4;
|
to->ip4 = ip4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
freeaddrinfo(server);
|
freeaddrinfo(server);
|
||||||
|
@ -458,7 +724,7 @@ int addr_resolve(const char *address, IPAny *ip)
|
||||||
* to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6)
|
* to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6)
|
||||||
* returns 1 on success, 0 on failure
|
* returns 1 on success, 0 on failure
|
||||||
*/
|
*/
|
||||||
int addr_resolve_or_parse_ip(const char *address, IPAny *to)
|
int addr_resolve_or_parse_ip(const char *address, IP *to)
|
||||||
{
|
{
|
||||||
if (!addr_resolve(address, to))
|
if (!addr_resolve(address, to))
|
||||||
if (!addr_parse_ip(address, to))
|
if (!addr_parse_ip(address, to))
|
||||||
|
|
|
@ -101,12 +101,6 @@ typedef struct {
|
||||||
};
|
};
|
||||||
} IPAny;
|
} IPAny;
|
||||||
|
|
||||||
/* ipany_ntoa
|
|
||||||
* converts ip into a string
|
|
||||||
* uses a static buffer, so mustn't used multiple times in the same output
|
|
||||||
*/
|
|
||||||
const char *ipany_ntoa(IPAny *ip);
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
IP4 ip;
|
IP4 ip;
|
||||||
|
@ -124,29 +118,43 @@ typedef struct {
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
} IPAny_Port;
|
} IPAny_Port;
|
||||||
|
|
||||||
#ifdef NETWORK_IP_PORT_IS_IPV6
|
#undef TOX_ENABLE_IPV6
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
#define TOX_ENABLE_IPV6_DEFAULT 1
|
||||||
|
typedef IPAny IP;
|
||||||
typedef IPAny_Port IP_Port;
|
typedef IPAny_Port IP_Port;
|
||||||
#else
|
#else
|
||||||
|
#define TOX_ENABLE_IPV6_DEFAULT 0
|
||||||
|
typedef IP4 IP;
|
||||||
typedef IP4_Port IP_Port;
|
typedef IP4_Port IP_Port;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ip_ntoa
|
||||||
|
* converts ip into a string
|
||||||
|
* uses a static buffer, so mustn't used multiple times in the same output
|
||||||
|
*/
|
||||||
|
const char *ip_ntoa(IP *ip);
|
||||||
|
|
||||||
/* ipport_equal
|
/* ipport_equal
|
||||||
* compares two IPAny_Port structures
|
* compares two IPAny_Port structures
|
||||||
* unset means unequal
|
* unset means unequal
|
||||||
*
|
*
|
||||||
* returns 0 when not equal or when uninitialized
|
* returns 0 when not equal or when uninitialized
|
||||||
*/
|
*/
|
||||||
int ipport_equal(IPAny_Port *a, IPAny_Port *b);
|
int ipport_equal(IP_Port *a, IP_Port *b);
|
||||||
|
|
||||||
typedef struct {
|
/* nulls out ip */
|
||||||
int16_t family;
|
void ip_reset(IP *ip);
|
||||||
uint16_t port;
|
/* nulls out ip, sets family according to flag */
|
||||||
IP4 ip;
|
void ip_init(IP *ip, uint8_t ipv6enabled);
|
||||||
uint8_t zeroes[8];
|
/* checks if ip is valid */
|
||||||
#ifdef ENABLE_IPV6
|
int ip_isset(IP *ip);
|
||||||
uint8_t zeroes2[12];
|
/* checks if ip is valid */
|
||||||
#endif
|
int ipport_isset(IP_Port *ipport);
|
||||||
} ADDR;
|
/* copies an ip structure */
|
||||||
|
void ip_copy(IP *target, IP *source);
|
||||||
|
/* copies an ip_port structure */
|
||||||
|
void ipport_copy(IP_Port *target, IP_Port *source);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* addr_resolve_or_parse_ip
|
* addr_resolve_or_parse_ip
|
||||||
|
@ -155,7 +163,7 @@ typedef struct {
|
||||||
* to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6)
|
* to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6)
|
||||||
* returns 1 on success, 0 on failure
|
* returns 1 on success, 0 on failure
|
||||||
*/
|
*/
|
||||||
int addr_resolve_or_parse_ip(const char *address, IPAny *to);
|
int addr_resolve_or_parse_ip(const char *address, IP *to);
|
||||||
|
|
||||||
/* Function to receive data, ip and port of sender is put into ip_port.
|
/* Function to receive data, ip and port of sender is put into ip_port.
|
||||||
* Packet data is put into data.
|
* Packet data is put into data.
|
||||||
|
@ -204,7 +212,7 @@ void networking_poll(Networking_Core *net);
|
||||||
* return 0 if no problems.
|
* return 0 if no problems.
|
||||||
* return -1 if there were problems.
|
* return -1 if there were problems.
|
||||||
*/
|
*/
|
||||||
Networking_Core *new_networking(IP4 ip, uint16_t port);
|
Networking_Core *new_networking(IP ip, uint16_t port);
|
||||||
|
|
||||||
/* Function to cleanup networking stuff (doesn't do much right now). */
|
/* Function to cleanup networking stuff (doesn't do much right now). */
|
||||||
void kill_networking(Networking_Core *net);
|
void kill_networking(Networking_Core *net);
|
||||||
|
|
|
@ -100,7 +100,8 @@ bool is_pinging(void *ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: Repl
|
||||||
{
|
{
|
||||||
PING *png = ping;
|
PING *png = ping;
|
||||||
|
|
||||||
if (ipp.ip.uint32 == 0 && ping_id == 0)
|
/* shouldn't that be an OR ? */
|
||||||
|
if (!ip_isset(&ipp.ip) && ping_id == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t i, id;
|
size_t i, id;
|
||||||
|
@ -111,7 +112,8 @@ bool is_pinging(void *ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: Repl
|
||||||
id = (png->pos_pings + i) % PING_NUM_MAX;
|
id = (png->pos_pings + i) % PING_NUM_MAX;
|
||||||
|
|
||||||
/* ping_id = 0 means match any id. */
|
/* ping_id = 0 means match any id. */
|
||||||
if ((ipp_eq(png->pings[id].ipp, ipp) || ipp.ip.uint32 == 0) && (png->pings[id].id == ping_id || ping_id == 0)) {
|
if ((!ip_isset(&ipp.ip) || ipport_equal(&png->pings[id].ipp, &ipp)) &&
|
||||||
|
(png->pings[id].id == ping_id || ping_id == 0)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -374,10 +374,11 @@ void tox_bootstrap(void *tox, IP_Port ip_port, uint8_t *public_key)
|
||||||
Messenger *m = tox;
|
Messenger *m = tox;
|
||||||
DHT_bootstrap(m->dht, ip_port, public_key);
|
DHT_bootstrap(m->dht, ip_port, public_key);
|
||||||
}
|
}
|
||||||
void tox_bootstrap_ex(void *tox, const char *address, uint16_t port, uint8_t *public_key)
|
void tox_bootstrap_ex(void *tox, const char *address, uint8_t ipv6enabled,
|
||||||
|
uint16_t port, uint8_t *public_key)
|
||||||
{
|
{
|
||||||
Messenger *m = tox;
|
Messenger *m = tox;
|
||||||
DHT_bootstrap_ex(m->dht, address, port, public_key);
|
DHT_bootstrap_ex(m->dht, address, ipv6enabled, port, public_key);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* return 0 if we are not connected to the DHT.
|
/* return 0 if we are not connected to the DHT.
|
||||||
|
|
|
@ -36,21 +36,51 @@ extern "C" {
|
||||||
|
|
||||||
#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
|
#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
|
||||||
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
uint8_t c[4];
|
uint8_t c[4];
|
||||||
uint16_t s[2];
|
uint16_t s[2];
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
} tox_IP;
|
} tox_IP4;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct in6_addr tox_IP6;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
tox_IP ip;
|
sa_family_t family;
|
||||||
uint16_t port;
|
union {
|
||||||
/* Not used for anything right now. */
|
tox_IP4 ip4;
|
||||||
uint16_t padding;
|
tox_IP6 ip6;
|
||||||
} tox_IP_Port;
|
};
|
||||||
|
} tox_IPAny;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
tox_IP4 ip;
|
||||||
|
uint16_t port;
|
||||||
|
/* Not used for anything right now. */
|
||||||
|
uint16_t padding;
|
||||||
|
};
|
||||||
|
uint8_t uint8[8];
|
||||||
|
} tox_IP4_Port;
|
||||||
|
|
||||||
|
/* will replace IP_Port as soon as the complete infrastructure is in place
|
||||||
|
* removed the unused union and padding also */
|
||||||
|
typedef struct {
|
||||||
|
tox_IPAny ip;
|
||||||
|
uint16_t port;
|
||||||
|
} tox_IPAny_Port;
|
||||||
|
|
||||||
|
#undef TOX_ENABLE_IPV6
|
||||||
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
#define TOX_ENABLE_IPV6_DEFAULT 1
|
||||||
|
typedef tox_IPAny tox_IP;
|
||||||
|
typedef tox_IPAny_Port tox_IP_Port;
|
||||||
|
#else
|
||||||
|
#define TOX_ENABLE_IPV6_DEFAULT 0
|
||||||
|
typedef tox_IP4 tox_IP;
|
||||||
|
typedef tox_IP4_Port tox_IP_Port;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TOX_IP_IS_IPV6 0
|
|
||||||
|
|
||||||
/* Errors for m_addfriend
|
/* Errors for m_addfriend
|
||||||
* FAERR - Friend Add Error
|
* FAERR - Friend Add Error
|
||||||
|
@ -296,7 +326,8 @@ void tox_callback_connectionstatus(Tox *tox, void (*function)(Tox *tox, int, uin
|
||||||
* tox_bootstrap_ex converts the address into an IP_Port structure internally
|
* tox_bootstrap_ex converts the address into an IP_Port structure internally
|
||||||
*/
|
*/
|
||||||
void tox_bootstrap(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key);
|
void tox_bootstrap(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key);
|
||||||
void tox_bootstrap_ex(Tox *tox, const char *address, uint16_t port, uint8_t *public_key);
|
void tox_bootstrap_ex(Tox *tox, const char *address, uint8_t ipv6enabled,
|
||||||
|
uint16_t port, uint8_t *public_key);
|
||||||
|
|
||||||
/* return 0 if we are not connected to the DHT.
|
/* return 0 if we are not connected to the DHT.
|
||||||
* return 1 if we are.
|
* return 1 if we are.
|
||||||
|
|
|
@ -32,11 +32,6 @@ uint64_t random_64b()
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ipp_eq(IP_Port a, IP_Port b)
|
|
||||||
{
|
|
||||||
return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool id_eq(uint8_t *dest, uint8_t *src)
|
bool id_eq(uint8_t *dest, uint8_t *src)
|
||||||
{
|
{
|
||||||
return memcmp(dest, src, CLIENT_ID_SIZE) == 0;
|
return memcmp(dest, src, CLIENT_ID_SIZE) == 0;
|
||||||
|
|
|
@ -7,6 +7,5 @@
|
||||||
|
|
||||||
uint64_t now();
|
uint64_t now();
|
||||||
uint64_t random_64b();
|
uint64_t random_64b();
|
||||||
bool ipp_eq(IP_Port a, IP_Port b);
|
|
||||||
bool id_eq(uint8_t *dest, uint8_t *src);
|
bool id_eq(uint8_t *dest, uint8_t *src);
|
||||||
void id_cpy(uint8_t *dest, uint8_t *src);
|
void id_cpy(uint8_t *dest, uint8_t *src);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user