mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Some fixes.
This commit is contained in:
parent
36e5636406
commit
64d000cdfa
|
@ -31,7 +31,6 @@
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "ping.h"
|
#include "ping.h"
|
||||||
#include "misc_tools.h"
|
#include "misc_tools.h"
|
||||||
#include "Messenger.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/* The number of seconds for a non responsive node to become bad. */
|
/* The number of seconds for a non responsive node to become bad. */
|
||||||
|
@ -202,6 +201,7 @@ static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *node
|
||||||
{
|
{
|
||||||
int num_nodes = 0;
|
int num_nodes = 0;
|
||||||
int i, tout, inlist, ipv46x, j, closest;
|
int i, tout, inlist, ipv46x, j, closest;
|
||||||
|
|
||||||
for (i = 0; i < client_list_length; i++) {
|
for (i = 0; i < client_list_length; i++) {
|
||||||
Client_data *client = &client_list[i];
|
Client_data *client = &client_list[i];
|
||||||
tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT);
|
tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT);
|
||||||
|
@ -216,6 +216,7 @@ static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *node
|
||||||
* IPv4-in-IPv6 here and convert it down in sendnodes().
|
* IPv4-in-IPv6 here and convert it down in sendnodes().
|
||||||
*/
|
*/
|
||||||
sa_family_t ip_treat_as_family = client_ip->family;
|
sa_family_t ip_treat_as_family = client_ip->family;
|
||||||
|
|
||||||
if ((dht->c->lossless_udp->net->family == AF_INET6) &&
|
if ((dht->c->lossless_udp->net->family == AF_INET6) &&
|
||||||
(client_ip->family == AF_INET6)) {
|
(client_ip->family == AF_INET6)) {
|
||||||
/* socket is AF_INET6, address claims AF_INET6:
|
/* socket is AF_INET6, address claims AF_INET6:
|
||||||
|
@ -554,11 +555,13 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
Node4_format *nodes4_list = (Node4_format *)(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++) {
|
||||||
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.port = nodes_list[i].ip_port.port;
|
nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port;
|
||||||
|
|
||||||
IP *node_ip = &nodes_list[i].ip_port.ip;
|
IP *node_ip = &nodes_list[i].ip_port.ip;
|
||||||
|
|
||||||
if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6))
|
if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6))
|
||||||
/* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */
|
/* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */
|
||||||
nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.s6_addr32[3];
|
nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.s6_addr32[3];
|
||||||
|
@ -574,6 +577,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
|
||||||
/* shouldn't happen */
|
/* shouldn't happen */
|
||||||
num_nodes = num_nodes_ok;
|
num_nodes = num_nodes_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node4_format_size);
|
memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node4_format_size);
|
||||||
#endif
|
#endif
|
||||||
|
@ -620,7 +624,7 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
|
||||||
uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES];
|
uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES];
|
||||||
uint8_t encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING];
|
uint8_t encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING];
|
||||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||||
random_nonce(nonce);
|
new_nonce(nonce);
|
||||||
|
|
||||||
memcpy(plain, &ping_id, sizeof(ping_id));
|
memcpy(plain, &ping_id, sizeof(ping_id));
|
||||||
memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size);
|
memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size);
|
||||||
|
@ -691,6 +695,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
|
||||||
cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
|
cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
|
||||||
|
|
||||||
size_t Node4_format_size = sizeof(Node4_format);
|
size_t Node4_format_size = sizeof(Node4_format);
|
||||||
|
|
||||||
if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) ||
|
if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) ||
|
||||||
((length - cid_size) % Node4_format_size) != 0 ||
|
((length - cid_size) % Node4_format_size) != 0 ||
|
||||||
(length < cid_size + Node4_format_size))
|
(length < cid_size + Node4_format_size))
|
||||||
|
@ -721,6 +726,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
|
||||||
Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
|
Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
|
||||||
|
|
||||||
int num_nodes_ok = 0;
|
int num_nodes_ok = 0;
|
||||||
|
|
||||||
for (i = 0; i < num_nodes; i++)
|
for (i = 0; i < num_nodes; i++)
|
||||||
if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != ~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);
|
||||||
|
@ -735,6 +741,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
|
||||||
/* shouldn't happen */
|
/* shouldn't happen */
|
||||||
num_nodes = num_nodes_ok;
|
num_nodes = num_nodes_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format));
|
memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format));
|
||||||
#endif
|
#endif
|
||||||
|
@ -758,6 +765,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
|
||||||
cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
|
cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
|
||||||
|
|
||||||
size_t Node_format_size = sizeof(Node4_format);
|
size_t Node_format_size = sizeof(Node4_format);
|
||||||
|
|
||||||
if (length > (cid_size + Node_format_size * MAX_SENT_NODES) ||
|
if (length > (cid_size + Node_format_size * MAX_SENT_NODES) ||
|
||||||
((length - cid_size) % Node_format_size) != 0 ||
|
((length - cid_size) % Node_format_size) != 0 ||
|
||||||
(length < cid_size + Node_format_size))
|
(length < cid_size + Node_format_size))
|
||||||
|
@ -970,11 +978,13 @@ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable
|
||||||
IP *ip_extra = NULL;
|
IP *ip_extra = NULL;
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
ip_init(&ip_port_v64.ip, ipv6enabled);
|
ip_init(&ip_port_v64.ip, ipv6enabled);
|
||||||
|
|
||||||
if (ipv6enabled) {
|
if (ipv6enabled) {
|
||||||
ip_port_v64.ip.family = AF_UNSPEC;
|
ip_port_v64.ip.family = AF_UNSPEC;
|
||||||
ip_reset(&ip_port_v4.ip);
|
ip_reset(&ip_port_v4.ip);
|
||||||
ip_extra = &ip_port_v4.ip;
|
ip_extra = &ip_port_v4.ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
ip_init(&ip_port_v64.ip, 0);
|
ip_init(&ip_port_v64.ip, 0);
|
||||||
#endif
|
#endif
|
||||||
|
@ -983,14 +993,15 @@ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable
|
||||||
ip_port_v64.port = port;
|
ip_port_v64.port = port;
|
||||||
DHT_bootstrap(dht, ip_port_v64, public_key);
|
DHT_bootstrap(dht, ip_port_v64, public_key);
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
|
||||||
if ((ip_extra != NULL) && ip_isset(ip_extra)) {
|
if ((ip_extra != NULL) && ip_isset(ip_extra)) {
|
||||||
ip_port_v4.port = port;
|
ip_port_v4.port = port;
|
||||||
DHT_bootstrap(dht, ip_port_v4, public_key);
|
DHT_bootstrap(dht, ip_port_v4, public_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1303,6 +1314,7 @@ static void do_NAT(DHT *dht)
|
||||||
dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
|
dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
|
||||||
|
|
||||||
IP 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_isset(&ip))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1449,6 +1461,7 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t friendlistsize = size - sizeof(dht->close_clientlist);
|
uint32_t friendlistsize = size - sizeof(dht->close_clientlist);
|
||||||
|
|
||||||
if (friendlistsize % sizeof(DHT_Friend) != 0) {
|
if (friendlistsize % sizeof(DHT_Friend) != 0) {
|
||||||
fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize);
|
fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1457,6 +1470,7 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size)
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
Client_data *client;
|
Client_data *client;
|
||||||
uint16_t friends_num = friendlistsize / sizeof(DHT_Friend);
|
uint16_t friends_num = friendlistsize / sizeof(DHT_Friend);
|
||||||
|
|
||||||
if (friends_num != 0) {
|
if (friends_num != 0) {
|
||||||
DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist));
|
DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist));
|
||||||
|
|
||||||
|
@ -1473,6 +1487,7 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
Client_data *tempclose_clientlist = (Client_data *)data;
|
Client_data *tempclose_clientlist = (Client_data *)data;
|
||||||
|
|
||||||
for (i = 0; i < LCLIENT_LIST; ++i) {
|
for (i = 0; i < LCLIENT_LIST; ++i) {
|
||||||
if (tempclose_clientlist[i].timestamp != 0)
|
if (tempclose_clientlist[i].timestamp != 0)
|
||||||
DHT_bootstrap(dht, tempclose_clientlist[i].ip_port,
|
DHT_bootstrap(dht, tempclose_clientlist[i].ip_port,
|
||||||
|
|
|
@ -80,26 +80,30 @@ static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source)
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
if (source.ip.family == AF_INET)
|
|
||||||
{
|
if (source.ip.family == AF_INET) {
|
||||||
IP4 ip4 = source.ip.ip4;
|
IP4 ip4 = source.ip.ip4;
|
||||||
#else
|
#else
|
||||||
IP4 ip4 = source.ip;
|
IP4 ip4 = source.ip;
|
||||||
#endif
|
#endif
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
for (k = 0; k < 4; k++) {
|
for (k = 0; k < 4; k++) {
|
||||||
id ^= randtable_initget(ludp, i++, ip4.uint8[k]);
|
id ^= randtable_initget(ludp, i++, ip4.uint8[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source.ip.family == AF_INET6)
|
if (source.ip.family == AF_INET6)
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
for (k = 0; k < 16; k++) {
|
for (k = 0; k < 16; k++) {
|
||||||
id ^= randtable_initget(ludp, i++, source.ip.ip6.s6_addr[k]);
|
id ^= randtable_initget(ludp, i++, source.ip.ip6.s6_addr[k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* id can't be zero. */
|
/* id can't be zero. */
|
||||||
|
@ -116,8 +120,21 @@ static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source)
|
||||||
*/
|
*/
|
||||||
static void change_handshake(Lossless_UDP *ludp, IP_Port source)
|
static void change_handshake(Lossless_UDP *ludp, IP_Port source)
|
||||||
{
|
{
|
||||||
uint8_t rand = random_int() % 4;
|
#ifdef TOX_ENABLE_IPV6
|
||||||
ludp->randtable[rand][((uint8_t *)&source)[rand]] = random_int();
|
uint8_t rand;
|
||||||
|
|
||||||
|
if (source.ip.family == AF_INET) {
|
||||||
|
rand = 2 + random_int() % 4;
|
||||||
|
} else if (source.ip.family == AF_INET6) {
|
||||||
|
rand = 2 + random_int() % 16;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
uint8_t rand = 2 + random_int() % 4;
|
||||||
|
#endif
|
||||||
|
ludp->randtable[rand][((uint8_t *)&source.ip)[rand]] = random_int();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -73,15 +73,18 @@ static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *i
|
||||||
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)
|
||||||
{
|
{
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
|
||||||
/* socket AF_INET, but target IP NOT: can't send */
|
/* socket AF_INET, but target IP NOT: can't send */
|
||||||
if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET))
|
if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET))
|
||||||
return 0;
|
return -1;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
size_t addrsize = 0;
|
size_t addrsize = 0;
|
||||||
|
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
|
||||||
if (ip_port.ip.family == AF_INET) {
|
if (ip_port.ip.family == AF_INET) {
|
||||||
if (net->family == AF_INET6) {
|
if (net->family == AF_INET6) {
|
||||||
/* must convert to IPV4-in-IPV6 address */
|
/* must convert to IPV4-in-IPV6 address */
|
||||||
|
@ -99,8 +102,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le
|
||||||
|
|
||||||
addr6->sin6_flowinfo = 0;
|
addr6->sin6_flowinfo = 0;
|
||||||
addr6->sin6_scope_id = 0;
|
addr6->sin6_scope_id = 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
IP4 ip4 = ip_port.ip.ip4;
|
IP4 ip4 = ip_port.ip.ip4;
|
||||||
#else
|
#else
|
||||||
IP4 ip4 = ip_port.ip;
|
IP4 ip4 = ip_port.ip;
|
||||||
|
@ -112,8 +114,8 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le
|
||||||
addr4->sin_port = ip_port.port;
|
addr4->sin_port = ip_port.port;
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
}
|
}
|
||||||
}
|
} else if (ip_port.ip.family == AF_INET6)
|
||||||
else if (ip_port.ip.family == AF_INET6) {
|
{
|
||||||
addrsize = sizeof(struct sockaddr_in6);
|
addrsize = sizeof(struct sockaddr_in6);
|
||||||
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
|
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
|
||||||
addr6->sin6_family = AF_INET6;
|
addr6->sin6_family = AF_INET6;
|
||||||
|
@ -122,10 +124,12 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le
|
||||||
|
|
||||||
addr6->sin6_flowinfo = 0;
|
addr6->sin6_flowinfo = 0;
|
||||||
addr6->sin6_scope_id = 0;
|
addr6->sin6_scope_id = 0;
|
||||||
} else {
|
} else
|
||||||
|
{
|
||||||
/* unknown address type*/
|
/* unknown address type*/
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int res = sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize);
|
int res = sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize);
|
||||||
|
@ -153,37 +157,40 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t
|
||||||
|
|
||||||
if (*(int32_t *)length <= 0) {
|
if (*(int32_t *)length <= 0) {
|
||||||
#ifdef LOGGING
|
#ifdef LOGGING
|
||||||
|
|
||||||
if ((length < 0) && (errno != EWOULDBLOCK)) {
|
if ((length < 0) && (errno != EWOULDBLOCK)) {
|
||||||
sprintf(logbuffer, "Unexpected error reading from socket: %u, %s\n", errno, strerror(errno));
|
sprintf(logbuffer, "Unexpected error reading from socket: %u, %s\n", errno, strerror(errno));
|
||||||
loglog(logbuffer);
|
loglog(logbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return -1; /* Nothing received or empty packet. */
|
return -1; /* Nothing received or empty packet. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
|
||||||
if (addr.ss_family == AF_INET) {
|
if (addr.ss_family == AF_INET) {
|
||||||
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
|
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
|
||||||
ip_port->ip.family = addr_in->sin_family;
|
ip_port->ip.family = addr_in->sin_family;
|
||||||
ip_port->ip.ip4.in_addr = addr_in->sin_addr;
|
ip_port->ip.ip4.in_addr = addr_in->sin_addr;
|
||||||
ip_port->port = addr_in->sin_port;
|
ip_port->port = addr_in->sin_port;
|
||||||
}
|
} else if (addr.ss_family == AF_INET6) {
|
||||||
else if (addr.ss_family == AF_INET6) {
|
|
||||||
struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr;
|
struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||||
ip_port->ip.family = addr_in6->sin6_family;
|
ip_port->ip.family = addr_in6->sin6_family;
|
||||||
ip_port->ip.ip6 = addr_in6->sin6_addr;
|
ip_port->ip.ip6 = addr_in6->sin6_addr;
|
||||||
ip_port->port = addr_in6->sin6_port;
|
ip_port->port = addr_in6->sin6_port;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (addr.ss_family == AF_INET) {
|
if (addr.ss_family == AF_INET) {
|
||||||
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
|
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
|
||||||
ip_port->ip.in_addr = addr_in->sin_addr;
|
ip_port->ip.in_addr = addr_in->sin_addr;
|
||||||
ip_port->port = addr_in->sin_port;
|
ip_port->port = addr_in->sin_port;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LOGGING
|
#ifdef LOGGING
|
||||||
|
@ -261,17 +268,20 @@ static void at_shutdown(void)
|
||||||
Networking_Core *new_networking(IP ip, uint16_t port)
|
Networking_Core *new_networking(IP ip, uint16_t port)
|
||||||
{
|
{
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
|
||||||
/* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */
|
/* 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) {
|
if (ip.family != AF_INET && ip.family != AF_INET6) {
|
||||||
fprintf(stderr, "Invalid address family: %u\n", ip.family);
|
fprintf(stderr, "Invalid address family: %u\n", ip.family);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (at_startup() != 0)
|
if (at_startup() != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -341,8 +351,8 @@ Networking_Core *new_networking(IP ip, uint16_t port)
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
size_t addrsize;
|
size_t addrsize;
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
if (temp->family == AF_INET)
|
|
||||||
{
|
if (temp->family == AF_INET) {
|
||||||
IP4 ip4 = ip.ip4;
|
IP4 ip4 = ip.ip4;
|
||||||
#else
|
#else
|
||||||
IP4 ip4 = ip;
|
IP4 ip4 = ip;
|
||||||
|
@ -355,8 +365,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
|
||||||
|
|
||||||
portptr = &addr4->sin_port;
|
portptr = &addr4->sin_port;
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
}
|
} else if (temp->family == AF_INET6)
|
||||||
else if (temp->family == AF_INET6)
|
|
||||||
{
|
{
|
||||||
addrsize = sizeof(struct sockaddr_in6);
|
addrsize = sizeof(struct sockaddr_in6);
|
||||||
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
|
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
|
||||||
|
@ -368,21 +377,23 @@ Networking_Core *new_networking(IP ip, uint16_t port)
|
||||||
addr6->sin6_scope_id = 0;
|
addr6->sin6_scope_id = 0;
|
||||||
|
|
||||||
portptr = &addr6->sin6_port;
|
portptr = &addr6->sin6_port;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (ip.family == AF_INET6) {
|
if (ip.family == AF_INET6)
|
||||||
|
{
|
||||||
char ipv6only = 0;
|
char ipv6only = 0;
|
||||||
int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only));
|
int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only));
|
||||||
#ifdef LOGGING
|
#ifdef LOGGING
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
sprintf(logbuffer, "Failed to enable dual-stack on IPv6 socket, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n",
|
sprintf(logbuffer,
|
||||||
|
"Failed to enable dual-stack on IPv6 socket, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
loglog(logbuffer);
|
loglog(logbuffer);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
loglog("Embedded IPv4 addresses enabled successfully.\n");
|
loglog("Embedded IPv4 addresses enabled successfully.\n");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* multicast local nodes */
|
/* multicast local nodes */
|
||||||
|
@ -394,15 +405,17 @@ Networking_Core *new_networking(IP ip, uint16_t port)
|
||||||
mreq.ipv6mr_interface = 0;
|
mreq.ipv6mr_interface = 0;
|
||||||
res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||||
#ifdef LOGGING
|
#ifdef LOGGING
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
sprintf(logbuffer, "Failed to activate local multicast membership. (%u, %s)\n",
|
sprintf(logbuffer, "Failed to activate local multicast membership. (%u, %s)\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
loglog(logbuffer);
|
loglog(logbuffer);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
loglog("Local multicast group FF02::1 joined successfully.\n");
|
loglog("Local multicast group FF02::1 joined successfully.\n");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* a hanging program or a different user might block the standard port;
|
/* a hanging program or a different user might block the standard port;
|
||||||
|
@ -424,16 +437,18 @@ Networking_Core *new_networking(IP ip, uint16_t port)
|
||||||
uint16_t port_to_try = port;
|
uint16_t port_to_try = port;
|
||||||
*portptr = htons(port_to_try);
|
*portptr = htons(port_to_try);
|
||||||
int tries, res;
|
int tries, res;
|
||||||
|
|
||||||
for (tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++)
|
for (tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++)
|
||||||
{
|
{
|
||||||
res = bind(temp->sock, (struct sockaddr *)&addr, addrsize);
|
res = bind(temp->sock, (struct sockaddr *)&addr, addrsize);
|
||||||
if (!res)
|
|
||||||
{
|
if (!res) {
|
||||||
temp->port = *portptr;
|
temp->port = *portptr;
|
||||||
#ifdef LOGGING
|
#ifdef LOGGING
|
||||||
sprintf(logbuffer, "Bound successfully to %s:%u.\n", ip_ntoa(&ip), ntohs(temp->port));
|
sprintf(logbuffer, "Bound successfully to %s:%u.\n", ip_ntoa(&ip), ntohs(temp->port));
|
||||||
loglog(logbuffer);
|
loglog(logbuffer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* errno isn't reset on success, only set on failure, the failed
|
/* errno isn't reset on success, only set on failure, the failed
|
||||||
* binds with parallel clients yield a -EPERM to the outside if
|
* binds with parallel clients yield a -EPERM to the outside if
|
||||||
* errno isn't cleared here */
|
* errno isn't cleared here */
|
||||||
|
@ -444,6 +459,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
|
||||||
}
|
}
|
||||||
|
|
||||||
port_to_try++;
|
port_to_try++;
|
||||||
|
|
||||||
if (port_to_try > TOX_PORTRANGE_TO)
|
if (port_to_try > TOX_PORTRANGE_TO)
|
||||||
port_to_try = TOX_PORTRANGE_FROM;
|
port_to_try = TOX_PORTRANGE_FROM;
|
||||||
|
|
||||||
|
@ -480,6 +496,7 @@ int ip_equal(IP *a, IP *b)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#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);
|
||||||
|
|
||||||
|
@ -589,28 +606,27 @@ const char *ip_ntoa(IP *ip)
|
||||||
{
|
{
|
||||||
if (ip) {
|
if (ip) {
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#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;
|
||||||
inet_ntop(ip->family, addr, addresstext, sizeof(addresstext));
|
inet_ntop(ip->family, addr, addresstext, sizeof(addresstext));
|
||||||
}
|
} else if (ip->family == AF_INET6) {
|
||||||
else if (ip->family == AF_INET6) {
|
|
||||||
addresstext[0] = '[';
|
addresstext[0] = '[';
|
||||||
struct in6_addr *addr = (struct in6_addr *)&ip->ip6;
|
struct in6_addr *addr = (struct in6_addr *)&ip->ip6;
|
||||||
inet_ntop(ip->family, addr, &addresstext[1], sizeof(addresstext) - 3);
|
inet_ntop(ip->family, addr, &addresstext[1], sizeof(addresstext) - 3);
|
||||||
size_t len = strlen(addresstext);
|
size_t len = strlen(addresstext);
|
||||||
addresstext[len] = ']';
|
addresstext[len] = ']';
|
||||||
addresstext[len + 1] = 0;
|
addresstext[len + 1] = 0;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family);
|
snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
addresstext[0] = 0;
|
addresstext[0] = 0;
|
||||||
struct in_addr *addr = (struct in_addr *)&ip;
|
struct in_addr *addr = (struct in_addr *)&ip;
|
||||||
inet_ntop(AF_INET, addr, addresstext, sizeof(addresstext));
|
inet_ntop(AF_INET, addr, addresstext, sizeof(addresstext));
|
||||||
#endif
|
#endif
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)");
|
snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)");
|
||||||
|
|
||||||
/* brute force protection against lacking termination */
|
/* brute force protection against lacking termination */
|
||||||
|
@ -639,6 +655,7 @@ int addr_parse_ip(const char *address, IP *to)
|
||||||
|
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#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;
|
||||||
to->ip4.in_addr = addr4;
|
to->ip4.in_addr = addr4;
|
||||||
|
@ -646,17 +663,21 @@ int addr_parse_ip(const char *address, IP *to)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct in6_addr addr6;
|
struct in6_addr addr6;
|
||||||
|
|
||||||
if (1 == inet_pton(AF_INET6, address, &addr6)) {
|
if (1 == inet_pton(AF_INET6, address, &addr6)) {
|
||||||
to->family = AF_INET6;
|
to->family = AF_INET6;
|
||||||
to->ip6 = addr6;
|
to->ip6 = addr6;
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
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->in_addr = addr4;
|
to->in_addr = addr4;
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -714,6 +735,7 @@ int addr_resolve(const char *address, IP *to, IP *extra)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rc = getaddrinfo(address, NULL, &hints, &server);
|
rc = getaddrinfo(address, NULL, &hints, &server);
|
||||||
|
|
||||||
// Lookup failed.
|
// Lookup failed.
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
|
@ -741,16 +763,18 @@ int addr_resolve(const char *address, IP *to, IP *extra)
|
||||||
#endif
|
#endif
|
||||||
rc = 3;
|
rc = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
else if (!(rc & 1)) {
|
else if (!(rc & 1)) {
|
||||||
struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
|
struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
|
||||||
to->ip4.in_addr = addr->sin_addr;
|
to->ip4.in_addr = addr->sin_addr;
|
||||||
rc |= 1;
|
rc |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
break; /* switch */
|
break; /* switch */
|
||||||
|
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
if (walker->ai_family == family) {
|
if (walker->ai_family == family) {
|
||||||
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
|
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
|
||||||
|
@ -765,28 +789,30 @@ int addr_resolve(const char *address, IP *to, IP *extra)
|
||||||
rc |= 2;
|
rc |= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break; /* switch */
|
break; /* switch */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOX_ENABLE_IPV6
|
#ifdef TOX_ENABLE_IPV6
|
||||||
|
|
||||||
if (to->family == AF_UNSPEC) {
|
if (to->family == AF_UNSPEC) {
|
||||||
if (rc & 2) {
|
if (rc & 2) {
|
||||||
to->family = AF_INET6;
|
to->family = AF_INET6;
|
||||||
to->ip6 = ip6;
|
to->ip6 = ip6;
|
||||||
|
|
||||||
if ((rc & 1) && (extra != NULL)) {
|
if ((rc & 1) && (extra != NULL)) {
|
||||||
extra->family = AF_INET;
|
extra->family = AF_INET;
|
||||||
extra->ip4 = ip4;
|
extra->ip4 = ip4;
|
||||||
}
|
}
|
||||||
}
|
} else if (rc & 1) {
|
||||||
else if (rc & 1) {
|
|
||||||
to->family = AF_INET;
|
to->family = AF_INET;
|
||||||
to->ip4 = ip4;
|
to->ip4 = ip4;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user