Merge remote-tracking branch 'upstream/master' into Integration

This commit is contained in:
Coren[m] 2013-09-15 08:54:14 +02:00
commit 16a6c9fb59
17 changed files with 416 additions and 301 deletions

View File

@ -22,5 +22,9 @@ Lossless UDP:
[NOT STARTED] Offline messaging
[NOT STARTED] Friends list syncing
[IN PROGRESS] IPV6 support
[DONE] Networking
[DONE] DHT + Messenger
[NOT STARTED] Group chats
[IN PROGRESS] GUI (https://github.com/nurupo/ProjectTox-Qt-GUI)
[NOT STARTED] Security audit from professionals

View File

@ -94,6 +94,7 @@ int main(int argc, char *argv[])
/* let user override default by cmdline */
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
if (argvoffset < 0)
exit(1);
@ -130,7 +131,7 @@ int main(int argc, char *argv[])
uint16_t port = htons(atoi(argv[argvoffset + 2]));
uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
int res = DHT_bootstrap_from_address(dht, argv[argvoffset + 1],
ipv6enabled, port, bootstrap_key);
ipv6enabled, port, bootstrap_key);
free(bootstrap_key);
if (!res) {
@ -151,6 +152,7 @@ int main(int argc, char *argv[])
}
do_DHT(dht);
if (last_LANdiscovery + (is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL) < unix_time()) {
send_LANdiscovery(htons(PORT), dht->c);
last_LANdiscovery = unix_time();

View File

@ -141,6 +141,7 @@ int main(int argc, char *argv[])
/* let user override default by cmdline */
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
if (argvoffset < 0)
exit(1);
@ -177,6 +178,7 @@ int main(int argc, char *argv[])
unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]);
int res = DHT_bootstrap_from_address(dht, argv[argvoffset + 1], ipv6enabled, port, binary_string);
free(binary_string);
if (!res) {
printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]);
return 1;

View File

@ -155,6 +155,7 @@ int main(int argc, char *argv[])
/* let user override default by cmdline */
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
if (argvoffset < 0)
exit(1);
@ -184,10 +185,12 @@ int main(int argc, char *argv[])
IP_Port serverip;
ip_init(&serverip.ip, ipv6enabled);
if (!addr_resolve(argv[argvoffset + 1], &serverip.ip, NULL)) {
printf("Failed to convert \"%s\" into an IP address.\n", argv[argvoffset + 1]);
return 1;
}
serverip.port = htons(atoi(argv[argvoffset + 2]));
printip(serverip);

View File

@ -151,6 +151,7 @@ int main(int argc, char *argv[])
/* let user override default by cmdline */
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
if (argvoffset < 0)
exit(1);

View File

@ -98,6 +98,7 @@ int main(int argc, char *argv[])
/* let user override default by cmdline */
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
if (argvoffset < 0)
exit(1);
@ -120,14 +121,16 @@ int main(int argc, char *argv[])
uint16_t port = htons(atoi(argv[argvoffset + 2]));
uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
int res = DHT_bootstrap_from_address(m->dht, argv[argvoffset + 1],
ipv6enabled, port, bootstrap_key);
ipv6enabled, port, bootstrap_key);
free(bootstrap_key);
if (!res) {
printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]);
exit(1);
}
} else {
FILE *file = fopen(argv[argvoffset + 1], "rb");
if ( file == NULL ) {
printf("Failed to open \"%s\" - does it exist?\n", argv[argvoffset + 1]);
return 1;

View File

@ -51,10 +51,12 @@ unsigned char *hex_string_to_bin(char hex_string[])
int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled)
{
int argvoffset = 0, argi;
for(argi = 1; argi < argc; argi++)
for (argi = 1; argi < argc; argi++)
if (!strncasecmp(argv[argi], "--ipv", 5)) {
if (argv[argi][5] && !argv[argi][6]) {
char c = argv[argi][5];
if (c == '4')
*ipv6enabled = 0;
else if (c == '6')
@ -63,8 +65,7 @@ int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled)
printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]);
return -1;
}
}
else {
} else {
printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]);
return -1;
}

View File

@ -284,7 +284,7 @@ void line_eval(Tox *m, char *line)
int num = atoi(numstring);
if (tox_sendmessage(m, num, (uint8_t *) message, strlen(message) + 1) != 1) {
if (tox_sendmessage(m, num, (uint8_t *) message, strlen(message) + 1) < 1) {
new_lines("[i] could not send message");
} else {
new_lines(format_message(m, message, -1));
@ -582,12 +582,12 @@ int main(int argc, char *argv[])
/* let user override default by cmdline */
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
if (argvoffset < 0)
exit(1);
int on = 0;
int c = 0;
int i = 0;
char *filename = "data";
char idstring[200] = {0};
Tox *m;
@ -641,6 +641,7 @@ int main(int argc, char *argv[])
}
nodelay(stdscr, TRUE);
while (1) {
if (on == 0 && tox_isconnected(m)) {
new_lines("[i] connected to DHT\n[i] define username with /n");

View File

@ -31,7 +31,6 @@
#include "network.h"
#include "ping.h"
#include "misc_tools.h"
#include "Messenger.h"
#include "util.h"
/* The number of seconds for a non responsive node to become bad. */
@ -196,74 +195,76 @@ static int friend_number(DHT *dht, uint8_t *client_id)
/*
* helper for get_close_nodes(). argument list is a monster :D
*/
static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list,
sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length,
time_t timestamp, int *num_nodes_ptr)
static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list,
sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length,
time_t timestamp, int *num_nodes_ptr)
{
int num_nodes = 0;
int i, tout, inlist, ipv46x, j, closest;
for(i = 0; i < client_list_length; i++) {
Client_data *client = &client_list[i];
tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT);
inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, client->client_id);
int num_nodes = *num_nodes_ptr;
int i, tout, inlist, ipv46x, j, closest;
for (i = 0; i < client_list_length; i++) {
Client_data *client = &client_list[i];
tout = is_timeout(timestamp, client->timestamp, BAD_NODE_TIMEOUT);
inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, client->client_id);
#ifdef TOX_ENABLE_IPV6
IP *client_ip = &client->ip_port.ip;
IP *client_ip = &client->ip_port.ip;
/*
* Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for
* our connections, instead we have to look if it is an embedded
* IPv4-in-IPv6 here and convert it down in sendnodes().
*/
sa_family_t ip_treat_as_family = client_ip->family;
if ((dht->c->lossless_udp->net->family == AF_INET6) &&
(client_ip->family == AF_INET6)) {
/* socket is AF_INET6, address claims AF_INET6:
* check for embedded IPv4-in-IPv6 */
if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6))
ip_treat_as_family = AF_INET;
}
/*
* Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for
* our connections, instead we have to look if it is an embedded
* IPv4-in-IPv6 here and convert it down in sendnodes().
*/
sa_family_t ip_treat_as_family = client_ip->family;
ipv46x = !(sa_family == ip_treat_as_family);
if ((dht->c->lossless_udp->net->family == AF_INET6) &&
(client_ip->family == AF_INET6)) {
/* socket is AF_INET6, address claims AF_INET6:
* check for embedded IPv4-in-IPv6 */
if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6))
ip_treat_as_family = AF_INET;
}
ipv46x = !(sa_family == ip_treat_as_family);
#else
ipv46x = !(sa_family == AF_INET);
ipv46x = !(sa_family == AF_INET);
#endif
/* If node isn't good or is already in list. */
if (tout || inlist || ipv46x)
continue;
/* If node isn't good or is already in list. */
if (tout || inlist || ipv46x)
continue;
if (num_nodes < MAX_SENT_NODES) {
memcpy(nodes_list[num_nodes].client_id,
client->client_id,
CLIENT_ID_SIZE );
if (num_nodes < MAX_SENT_NODES) {
memcpy(nodes_list[num_nodes].client_id,
client->client_id,
CLIENT_ID_SIZE );
nodes_list[num_nodes].ip_port = client->ip_port;
num_nodes++;
} else {
/* see if node_list contains a client_id that's "further away"
* compared to the one we're looking at at the moment, if there
* is, replace it
*/
for (j = 0; j < MAX_SENT_NODES; ++j) {
closest = id_closest( client_id,
nodes_list[j].client_id,
client->client_id );
nodes_list[num_nodes].ip_port = client->ip_port;
num_nodes++;
} else {
/* see if node_list contains a client_id that's "further away"
* compared to the one we're looking at at the moment, if there
* is, replace it
*/
for (j = 0; j < MAX_SENT_NODES; ++j) {
closest = id_closest( client_id,
nodes_list[j].client_id,
client->client_id );
/* second client_id is closer than current: change to it */
if (closest == 2) {
memcpy( nodes_list[j].client_id,
client->client_id,
CLIENT_ID_SIZE);
/* second client_id is closer than current: change to it */
if (closest == 2) {
memcpy( nodes_list[j].client_id,
client->client_id,
CLIENT_ID_SIZE);
nodes_list[j].ip_port = client->ip_port;
break;
}
}
}
}
nodes_list[j].ip_port = client->ip_port;
break;
}
}
}
}
*num_nodes_ptr = num_nodes;
*num_nodes_ptr = num_nodes;
}
/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request:
@ -274,15 +275,15 @@ static int get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *node
*/
static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family)
{
time_t timestamp = unix_time();
int num_nodes = 0, i;
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes);
time_t timestamp = unix_time();
int num_nodes = 0, i;
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes);
for (i = 0; i < dht->num_friends; ++i)
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
timestamp, &num_nodes);
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
timestamp, &num_nodes);
return num_nodes;
}
@ -458,7 +459,7 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id)
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))
if (pinging == (ping_id != 0) + ip_isset(&ip_port.ip))
return 1;
}
}
@ -554,11 +555,13 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
#ifdef TOX_ENABLE_IPV6
Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
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);
nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port;
IP *node_ip = &nodes_list[i].ip_port.ip;
if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6))
/* 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];
@ -574,6 +577,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
/* shouldn't happen */
num_nodes = num_nodes_ok;
}
#else
memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node4_format_size);
#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 encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING];
uint8_t nonce[crypto_box_NONCEBYTES];
random_nonce(nonce);
new_nonce(nonce);
memcpy(plain, &ping_id, sizeof(ping_id));
memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size);
@ -675,7 +679,8 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32
memcpy(&ping_id, plain, sizeof(ping_id));
sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id);
#ifdef TOX_ENABLE_IPV6
sendnodes_ipv6(dht, source, packet + 1, plain + sizeof(ping_id), ping_id);
sendnodes_ipv6(dht, source, packet + 1, plain + sizeof(ping_id),
ping_id); /* TODO: prevent possible amplification attacks */
#endif
//send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */
@ -691,6 +696,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
size_t Node4_format_size = sizeof(Node4_format);
if (length > (cid_size + Node4_format_size * MAX_SENT_NODES) ||
((length - cid_size) % Node4_format_size) != 0 ||
(length < cid_size + Node4_format_size))
@ -721,7 +727,8 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
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)) {
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;
@ -735,6 +742,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
/* shouldn't happen */
num_nodes = num_nodes_ok;
}
#else
memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format));
#endif
@ -757,7 +765,8 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
uint32_t cid_size = 1 + CLIENT_ID_SIZE;
cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
size_t Node_format_size = sizeof(Node4_format);
size_t Node_format_size = sizeof(Node_format);
if (length > (cid_size + Node_format_size * MAX_SENT_NODES) ||
((length - cid_size) % Node_format_size) != 0 ||
(length < cid_size + Node_format_size))
@ -799,6 +808,24 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
/*----------------------------------------------------------------------------------*/
/*------------------------END of packet handling functions--------------------------*/
/*
* Send get nodes requests with client_id to max_num peers in list of length length
*/
static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id)
{
uint64_t temp_time = unix_time();
uint32_t i, num = 0;
for (i = 0; i < length; ++i)
if (ipport_isset(&(list[i].ip_port)) && !is_timeout(temp_time, list[i].ret_timestamp, BAD_NODE_TIMEOUT)) {
getnodes(dht, list[i].ip_port, list[i].client_id, client_id);
++num;
if (num >= max_num)
return;
}
}
int DHT_addfriend(DHT *dht, uint8_t *client_id)
{
if (friend_number(dht, client_id) != -1) /* Is friend already in DHT? */
@ -816,6 +843,7 @@ int DHT_addfriend(DHT *dht, uint8_t *client_id)
dht->friends_list[dht->num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int();
++dht->num_friends;
get_bunchnodes(dht, dht->close_clientlist, LCLIENT_LIST, MAX_FRIEND_CLIENTS, client_id);/*TODO: make this better?*/
return 0;
}
@ -964,17 +992,20 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
send_ping_request(dht->ping, dht->c, ip_port, public_key);
}
int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
uint16_t port, uint8_t *public_key)
uint16_t port, uint8_t *public_key)
{
IP_Port ip_port_v64, ip_port_v4;
IP_Port ip_port_v64;
IP *ip_extra = NULL;
#ifdef TOX_ENABLE_IPV6
IP_Port ip_port_v4;
ip_init(&ip_port_v64.ip, ipv6enabled);
if (ipv6enabled) {
ip_port_v64.ip.family = AF_UNSPEC;
ip_reset(&ip_port_v4.ip);
ip_extra = &ip_port_v4.ip;
}
#else
ip_init(&ip_port_v64.ip, 0);
#endif
@ -983,14 +1014,15 @@ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable
ip_port_v64.port = port;
DHT_bootstrap(dht, ip_port_v64, public_key);
#ifdef TOX_ENABLE_IPV6
if ((ip_extra != NULL) && ip_isset(ip_extra)) {
ip_port_v4.port = port;
DHT_bootstrap(dht, ip_port_v4, public_key);
}
#endif
return 1;
}
else
} else
return 0;
}
@ -1303,6 +1335,7 @@ static void do_NAT(DHT *dht)
dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2);
if (!ip_isset(&ip))
continue;
@ -1443,20 +1476,22 @@ void DHT_save(DHT *dht, uint8_t *data)
*/
int DHT_load(DHT *dht, uint8_t *data, uint32_t size)
{
if (size < sizeof(dht->close_clientlist)) {
fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size);
if (size < sizeof(dht->close_clientlist)) {
fprintf(stderr, "DHT_load: Expected at least %lu bytes, got %u.\n", sizeof(dht->close_clientlist), size);
return -1;
}
uint32_t friendlistsize = size - sizeof(dht->close_clientlist);
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 %lu, got %u.\n", sizeof(DHT_Friend), friendlistsize);
return -1;
}
uint32_t i, j;
Client_data *client;
uint16_t friends_num = friendlistsize / sizeof(DHT_Friend);
if (friends_num != 0) {
DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist));
@ -1473,6 +1508,7 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size)
}
Client_data *tempclose_clientlist = (Client_data *)data;
for (i = 0; i < LCLIENT_LIST; ++i) {
if (tempclose_clientlist[i].timestamp != 0)
DHT_bootstrap(dht, tempclose_clientlist[i].ip_port,

View File

@ -169,12 +169,12 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key);
* if ipv6enabled is 0 (zero), the resolving sticks STRICTLY to IPv4 addresses
* if ipv6enabled is not 0 (zero), the resolving looks for IPv6 addresses first,
* then IPv4 addresses.
*
*
* returns 1 if the address could be converted into an IP address
* returns 0 otherwise
*/
int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
uint16_t port, uint8_t *public_key);
uint16_t port, uint8_t *public_key);
/* Add nodes to the toping list.
* All nodes in this list are pinged every TIME_TOPING seconds

View File

@ -30,12 +30,15 @@
#define MAX_INTERFACES 16
#ifdef __linux
#ifndef TOX_ENABLE_IPV6
/* Send packet to all broadcast addresses
*
* return higher than 0 on success.
* return 0 on error.
*
* TODO: Make this work with IPv6 and remove the #ifndef TOX_ENABLE_IPV6.
*/
static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t * data, uint16_t length)
static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t *data, uint16_t length)
{
/* Not sure how many platforms this will run on,
* so it's wrapped in __linux for now.
@ -63,22 +66,24 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t * d
}
for (i = 0; i < count; i++) {
if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) {
return 1;
}
if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) {
return 1;
}
/* Just to clarify where we're getting the values from. */
sock_holder = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr;
if (sock_holder != NULL) {
IP_Port ip_port = {{{{sock_holder->sin_addr.s_addr}}, port, 0}};
sendpacket(net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES);
}
/* Just to clarify where we're getting the values from. */
sock_holder = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr;
if (sock_holder != NULL) {
IP_Port ip_port = {{{{sock_holder->sin_addr.s_addr}}, port, 0}};
sendpacket(net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES);
}
}
close(sock);
return 0;
}
#endif
#endif
/* Return the broadcast ip. */
static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
@ -87,6 +92,7 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
ip_reset(&ip);
#ifdef TOX_ENABLE_IPV6
if (family_socket == AF_INET6) {
if (family_broadcast == AF_INET6) {
ip.family = AF_INET6;
@ -96,25 +102,26 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
ip.ip6.s6_addr[ 0] = 0xFF;
ip.ip6.s6_addr[ 1] = 0x02;
ip.ip6.s6_addr[15] = 0x01;
}
else if (family_broadcast == AF_INET) {
} else if (family_broadcast == AF_INET) {
ip.family = AF_INET6;
ip.ip6.s6_addr32[0] = 0;
ip.ip6.s6_addr32[1] = 0;
ip.ip6.s6_addr32[2] = htonl(0xFFFF);
ip.ip6.s6_addr32[3] = INADDR_BROADCAST;
}
}
else if (family_socket == AF_INET) {
} else if (family_socket == AF_INET) {
if (family_broadcast == AF_INET) {
ip.family = AF_INET;
ip.ip4.uint32 = INADDR_BROADCAST;
}
}
#else
if (family_socket == AF_INET)
if (family_broadcast == AF_INET)
ip.uint32 = INADDR_BROADCAST;
#endif
return ip;
@ -126,11 +133,13 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
static int LAN_ip(IP ip)
{
#ifdef TOX_ENABLE_IPV6
if (ip.family == AF_INET) {
IP4 ip4 = ip.ip4;
#else
IP4 ip4 = ip;
IP4 ip4 = ip;
#endif
/* Loopback. */
if (ip4.uint8[0] == 127)
return 0;
@ -151,13 +160,14 @@ static int LAN_ip(IP ip)
if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0
&& ip4.uint8[2] != 255)
return 0;
#ifdef TOX_ENABLE_IPV6
}
else if (ip.family == AF_INET6) {
} 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 */
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)))
((ip.ip6.s6_addr[0] == 0xFE) && ((ip.ip6.s6_addr[1] & 0xC0) == 0x80)))
return 0;
/* embedded IPv4-in-IPv6 */
@ -168,6 +178,7 @@ static int LAN_ip(IP ip)
return LAN_ip(ip4);
}
}
#endif
return -1;
@ -195,17 +206,20 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c)
memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES);
#ifdef __linux
#ifndef TOX_ENABLE_IPV6
send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
#endif
#endif
int res = -1;
IP_Port ip_port;
ip_port.port = port;
#ifdef TOX_ENABLE_IPV6
/* IPv6 multicast */
if (c->lossless_udp->net->family == AF_INET6) {
ip_port.ip = broadcast_ip(AF_INET6, AF_INET6);
if (ip_isset(&ip_port.ip))
if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES) > 0)
res = 1;
@ -216,6 +230,7 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c)
#else
ip_port.ip = broadcast_ip(AF_INET, AF_INET);
#endif
if (ip_isset(&ip_port.ip))
if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES))
res = 1;

View File

@ -80,26 +80,30 @@ static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source)
i++;
#ifdef TOX_ENABLE_IPV6
if (source.ip.family == AF_INET)
{
if (source.ip.family == AF_INET) {
IP4 ip4 = source.ip.ip4;
#else
IP4 ip4 = source.ip;
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. */
@ -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)
{
uint8_t rand = random_int() % 4;
ludp->randtable[rand][((uint8_t *)&source)[rand]] = random_int();
#ifdef TOX_ENABLE_IPV6
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();
}
/*

View File

@ -1225,11 +1225,13 @@ static time_t lastdump = 0;
static char IDString[CLIENT_ID_SIZE * 2 + 1];
static char *ID2String(uint8_t *client_id)
{
uint32_t i;
for(i = 0; i < CLIENT_ID_SIZE; i++)
sprintf(&IDString[i], "%02X", client_id[i]);
IDString[CLIENT_ID_SIZE * 2] = 0;
return IDString;
uint32_t i;
for (i = 0; i < CLIENT_ID_SIZE; i++)
sprintf(&IDString[i], "%02X", client_id[i]);
IDString[CLIENT_ID_SIZE * 2] = 0;
return IDString;
}
#endif
@ -1246,73 +1248,85 @@ void doMessenger(Messenger *m)
LANdiscovery(m);
#ifdef LOGGING
if (now() > lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) {
loglog(" = = = = = = = = \n");
lastdump = now();
uint32_t client, last_pinged;
for(client = 0; client < LCLIENT_LIST; client++) {
Client_data *cptr = &m->dht->close_clientlist[client];
if (ip_isset(&cptr->ip_port.ip)) {
last_pinged = lastdump - cptr->last_pinged;
if (last_pinged > 999)
last_pinged = 999;
snprintf(logbuffer, sizeof(logbuffer), "C[%2u] %s:%u [%3u] %s\n",
client, ip_ntoa(&cptr->ip_port.ip), ntohs(cptr->ip_port.port),
last_pinged, ID2String(cptr->client_id));
loglog(logbuffer);
}
}
if (now() > lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) {
loglog(" = = = = = = = = \n");
loglog(" = = = = = = = = \n");
lastdump = now();
uint32_t client, last_pinged;
uint32_t num_friends = MIN(m->numfriends, m->dht->num_friends);
if (m->numfriends != m->dht->num_friends) {
sprintf(logbuffer, "Friend num in DHT %u != friend num in msger %u\n",
m->dht->num_friends, m->numfriends);
loglog(logbuffer);
}
for (client = 0; client < LCLIENT_LIST; client++) {
Client_data *cptr = &m->dht->close_clientlist[client];
uint32_t friend, ping_lastrecv;
for(friend = 0; friend < num_friends; friend++) {
Friend *msgfptr = &m->friendlist[friend];
DHT_Friend *dhtfptr = &m->dht->friends_list[friend];
if (memcmp(msgfptr->client_id, dhtfptr->client_id, CLIENT_ID_SIZE)) {
if (sizeof(logbuffer) > 2 * CLIENT_ID_SIZE + 64) {
sprintf(logbuffer, "F[%2u] ID(m) %s != ID(d) ", friend,
ID2String(msgfptr->client_id));
strcat(logbuffer + strlen(logbuffer), ID2String(dhtfptr->client_id));
strcat(logbuffer + strlen(logbuffer), "\n");
}
else
sprintf(logbuffer, "F[%2u] ID(m) != ID(d) ", friend);
if (ip_isset(&cptr->ip_port.ip)) {
last_pinged = lastdump - cptr->last_pinged;
loglog(logbuffer);
}
if (last_pinged > 999)
last_pinged = 999;
ping_lastrecv = lastdump - msgfptr->ping_lastrecv;
if (ping_lastrecv > 999)
ping_lastrecv = 999;
snprintf(logbuffer, sizeof(logbuffer), "F[%2u] <%s> %02u [%03u] %s\n",
friend, msgfptr->name, msgfptr->crypt_connection_id,
ping_lastrecv, ID2String(msgfptr->client_id));
loglog(logbuffer);
snprintf(logbuffer, sizeof(logbuffer), "C[%2u] %s:%u [%3u] %s\n",
client, ip_ntoa(&cptr->ip_port.ip), ntohs(cptr->ip_port.port),
last_pinged, ID2String(cptr->client_id));
loglog(logbuffer);
}
}
for(client = 0; client < MAX_FRIEND_CLIENTS; client++) {
Client_data *cptr = &dhtfptr->client_list[client];
last_pinged = lastdump - cptr->last_pinged;
if (last_pinged > 999)
last_pinged = 999;
snprintf(logbuffer, sizeof(logbuffer), "F[%2u] => C[%2u] %s:%u [%3u] %s\n",
friend, client, ip_ntoa(&cptr->ip_port.ip),
ntohs(cptr->ip_port.port), last_pinged,
ID2String(cptr->client_id));
loglog(logbuffer);
}
}
loglog(" = = = = = = = = \n");
uint32_t num_friends = MIN(m->numfriends, m->dht->num_friends);
if (m->numfriends != m->dht->num_friends) {
sprintf(logbuffer, "Friend num in DHT %u != friend num in msger %u\n",
m->dht->num_friends, m->numfriends);
loglog(logbuffer);
}
uint32_t friend, ping_lastrecv;
for (friend = 0; friend < num_friends; friend++) {
Friend *msgfptr = &m->friendlist[friend];
DHT_Friend *dhtfptr = &m->dht->friends_list[friend];
if (memcmp(msgfptr->client_id, dhtfptr->client_id, CLIENT_ID_SIZE)) {
if (sizeof(logbuffer) > 2 * CLIENT_ID_SIZE + 64) {
sprintf(logbuffer, "F[%2u] ID(m) %s != ID(d) ", friend,
ID2String(msgfptr->client_id));
strcat(logbuffer + strlen(logbuffer), ID2String(dhtfptr->client_id));
strcat(logbuffer + strlen(logbuffer), "\n");
} else
sprintf(logbuffer, "F[%2u] ID(m) != ID(d) ", friend);
loglog(logbuffer);
}
ping_lastrecv = lastdump - msgfptr->ping_lastrecv;
if (ping_lastrecv > 999)
ping_lastrecv = 999;
snprintf(logbuffer, sizeof(logbuffer), "F[%2u] <%s> %02u [%03u] %s\n",
friend, msgfptr->name, msgfptr->crypt_connection_id,
ping_lastrecv, ID2String(msgfptr->client_id));
loglog(logbuffer);
for (client = 0; client < MAX_FRIEND_CLIENTS; client++) {
Client_data *cptr = &dhtfptr->client_list[client];
last_pinged = lastdump - cptr->last_pinged;
if (last_pinged > 999)
last_pinged = 999;
snprintf(logbuffer, sizeof(logbuffer), "F[%2u] => C[%2u] %s:%u [%3u] %s\n",
friend, client, ip_ntoa(&cptr->ip_port.ip),
ntohs(cptr->ip_port.port), last_pinged,
ID2String(cptr->client_id));
loglog(logbuffer);
}
}
loglog(" = = = = = = = = \n");
}
loglog(" = = = = = = = = \n");
}
#endif
}
@ -1410,6 +1424,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length)
memcpy(temp, data, size);
uint32_t i;
for (i = 0; i < num; ++i) {
if (temp[i].status >= 3) {
int fnum = m_addfriend_norequest(m, temp[i].client_id);

View File

@ -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)
{
#ifdef TOX_ENABLE_IPV6
/* socket AF_INET, but target IP NOT: can't send */
if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET))
return 0;
if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET))
return -1;
#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 */
@ -99,11 +102,10 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le
addr6->sin6_flowinfo = 0;
addr6->sin6_scope_id = 0;
}
else {
} else {
IP4 ip4 = ip_port.ip.ip4;
#else
IP4 ip4 = ip_port.ip;
IP4 ip4 = ip_port.ip;
#endif
addrsize = sizeof(struct sockaddr_in);
struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
@ -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;
#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);
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
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_scope_id = 0;
} else {
} else
{
/* unknown address type*/
return 0;
return -1;
}
#endif
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) {
#ifdef LOGGING
if ((length < 0) && (errno != EWOULDBLOCK)) {
sprintf(logbuffer, "Unexpected error reading from socket: %u, %s\n", errno, strerror(errno));
loglog(logbuffer);
}
#endif
return -1; /* Nothing received or empty packet. */
}
#ifdef TOX_ENABLE_IPV6
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) {
} 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
} 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
} else
return -1;
#endif
#ifdef LOGGING
@ -261,17 +268,20 @@ static void at_shutdown(void)
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) {
fprintf(stderr, "Invalid address family: %u\n", ip.family);
return NULL;
}
#endif
if (at_startup() != 0)
return NULL;
Networking_Core *temp = calloc(1, sizeof(Networking_Core));
if (temp == NULL)
return NULL;
@ -297,7 +307,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
#else
if (temp->sock < 0) {
fprintf(stderr, "Failed to get a scoket?! %u, %s\n", errno, strerror(errno));
fprintf(stderr, "Failed to get a socket?! %u, %s\n", errno, strerror(errno));
free(temp);
return NULL;
}
@ -341,11 +351,11 @@ Networking_Core *new_networking(IP ip, uint16_t port)
struct sockaddr_storage addr;
size_t addrsize;
#ifdef TOX_ENABLE_IPV6
if (temp->family == AF_INET)
{
if (temp->family == AF_INET) {
IP4 ip4 = ip.ip4;
#else
IP4 ip4 = ip;
IP4 ip4 = ip;
#endif
addrsize = sizeof(struct sockaddr_in);
struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
@ -355,8 +365,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
portptr = &addr4->sin_port;
#ifdef TOX_ENABLE_IPV6
}
else if (temp->family == AF_INET6)
} else if (temp->family == AF_INET6)
{
addrsize = sizeof(struct sockaddr_in6);
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
@ -368,21 +377,26 @@ Networking_Core *new_networking(IP ip, uint16_t port)
addr6->sin6_scope_id = 0;
portptr = &addr6->sin6_port;
}
else
} else
return NULL;
if (ip.family == AF_INET6) {
if (ip.family == AF_INET6)
{
char ipv6only = 0;
int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only));
#ifdef LOGGING
int res =
#endif
setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only));
#ifdef LOGGING
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));
loglog(logbuffer);
}
else
} else
loglog("Embedded IPv4 addresses enabled successfully.\n");
#endif
/* multicast local nodes */
@ -392,17 +406,22 @@ Networking_Core *new_networking(IP ip, uint16_t port)
mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02;
mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01;
mreq.ipv6mr_interface = 0;
res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
#ifdef LOGGING
res =
#endif
setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
#ifdef LOGGING
if (res < 0) {
sprintf(logbuffer, "Failed to activate local multicast membership. (%u, %s)\n",
errno, strerror(errno));
loglog(logbuffer);
}
else
} else
loglog("Local multicast group FF02::1 joined successfully.\n");
#endif
}
#endif
/* a hanging program or a different user might block the standard port;
@ -424,16 +443,18 @@ Networking_Core *new_networking(IP ip, uint16_t port)
uint16_t port_to_try = port;
*portptr = htons(port_to_try);
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);
if (!res)
{
if (!res) {
temp->port = *portptr;
#ifdef LOGGING
sprintf(logbuffer, "Bound successfully to %s:%u.\n", ip_ntoa(&ip), ntohs(temp->port));
loglog(logbuffer);
#endif
/* errno isn't reset on success, only set on failure, the failed
* binds with parallel clients yield a -EPERM to the outside if
* errno isn't cleared here */
@ -444,6 +465,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
}
port_to_try++;
if (port_to_try > TOX_PORTRANGE_TO)
port_to_try = TOX_PORTRANGE_FROM;
@ -451,8 +473,8 @@ Networking_Core *new_networking(IP ip, uint16_t port)
}
fprintf(stderr, "Failed to bind socket: %u, %s (IP/Port: %s:%u\n", errno,
strerror(errno), ip_ntoa(&ip), port);
free(temp);
strerror(errno), ip_ntoa(&ip), port);
kill_networking(temp);
return NULL;
}
@ -480,24 +502,24 @@ int ip_equal(IP *a, IP *b)
return 0;
#ifdef TOX_ENABLE_IPV6
/* same family */
if (a->family == b->family) {
if (a->family == AF_INET)
return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr);
else if (a->family == AF_INET6)
return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6);
else
return 0;
}
/* same family */
if (a->family == b->family) {
if (a->family == AF_INET)
return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr);
else if (a->family == AF_INET6)
return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6);
else
return 0;
}
/* different family: check on the IPv6 one if it is the IPv4 one embedded */
/* different family: check on the IPv6 one if it is the IPv4 one embedded */
if ((a->family == AF_INET) && (b->family == AF_INET6)) {
if (IN6_IS_ADDR_V4COMPAT(&b->ip6))
return (a->ip4.in_addr.s_addr == b->ip6.s6_addr32[3]);
} else if ((a->family == AF_INET6) && (b->family == AF_INET)) {
if (IN6_IS_ADDR_V4COMPAT(&a->ip6))
return (a->ip6.s6_addr32[3] == b->ip4.in_addr.s_addr);
}
if (IN6_IS_ADDR_V4COMPAT(&b->ip6))
return (a->ip4.in_addr.s_addr == b->ip6.s6_addr32[3]);
} else if ((a->family == AF_INET6) && (b->family == AF_INET)) {
if (IN6_IS_ADDR_V4COMPAT(&a->ip6))
return (a->ip6.s6_addr32[3] == b->ip4.in_addr.s_addr);
}
return 0;
#else
@ -602,28 +624,27 @@ const char *ip_ntoa(IP *ip)
{
if (ip) {
#ifdef TOX_ENABLE_IPV6
if (ip->family == AF_INET) {
addresstext[0] = 0;
struct in_addr *addr = (struct in_addr *)&ip->ip4;
inet_ntop(ip->family, addr, addresstext, sizeof(addresstext));
}
else if (ip->family == AF_INET6) {
} else if (ip->family == AF_INET6) {
addresstext[0] = '[';
struct in6_addr *addr = (struct in6_addr *)&ip->ip6;
inet_ntop(ip->family, addr, &addresstext[1], sizeof(addresstext) - 3);
size_t len = strlen(addresstext);
addresstext[len] = ']';
addresstext[len + 1] = 0;
}
else
} else
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)");
/* brute force protection against lacking termination */
@ -652,6 +673,7 @@ int addr_parse_ip(const char *address, IP *to)
#ifdef TOX_ENABLE_IPV6
struct in_addr addr4;
if (1 == inet_pton(AF_INET, address, &addr4)) {
to->family = AF_INET;
to->ip4.in_addr = addr4;
@ -659,17 +681,21 @@ int addr_parse_ip(const char *address, IP *to)
};
struct in6_addr addr6;
if (1 == inet_pton(AF_INET6, address, &addr6)) {
to->family = AF_INET6;
to->ip6 = addr6;
return 1;
};
#else
struct in_addr addr4;
if (1 == inet_pton(AF_INET, address, &addr4)) {
to->in_addr = addr4;
return 1;
};
#endif
return 0;
@ -714,24 +740,13 @@ int addr_resolve(const char *address, IP *to, IP *extra)
hints.ai_family = family;
hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
#ifdef __WIN32__
WSADATA wsa_data;
/* CLEANUP: really not the best place to put this */
rc = WSAStartup(MAKEWORD(2, 2), &wsa_data);
if (rc != 0) {
if (at_startup() != 0)
return 0;
}
#endif
rc = getaddrinfo(address, NULL, &hints, &server);
// Lookup failed.
if (rc != 0) {
#ifdef __WIN32__
WSACleanup();
#endif
return 0;
}
@ -742,71 +757,71 @@ int addr_resolve(const char *address, IP *to, IP *extra)
memset(&ip6, 0, sizeof(ip6));
#endif
for(walker = server; (walker != NULL) && (rc != 3); walker = walker->ai_next) {
switch(walker->ai_family) {
case AF_INET:
if (walker->ai_family == family) {
struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
for (walker = server; (walker != NULL) && (rc != 3); walker = walker->ai_next) {
switch (walker->ai_family) {
case AF_INET:
if (walker->ai_family == family) { /* AF_INET requested, done */
struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
#ifdef TOX_ENABLE_IPV6
to->ip4.in_addr = addr->sin_addr;
to->ip4.in_addr = addr->sin_addr;
#else
to->in_addr = addr->sin_addr;
to->in_addr = addr->sin_addr;
#endif
rc = 3;
}
#ifdef TOX_ENABLE_IPV6
else if (!(rc & 1)) {
struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
ip4.in_addr = addr->sin_addr;
rc |= 1;
}
#endif
break; /* switch */
#ifdef TOX_ENABLE_IPV6
case AF_INET6:
if (walker->ai_family == family) {
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
to->ip6 = addr->sin6_addr;
rc = 3;
}
} else if (!(rc & 2)) {
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
ip6 = addr->sin6_addr;
rc |= 2;
#ifdef TOX_ENABLE_IPV6
else if (!(rc & 1)) { /* AF_UNSPEC requested, store away */
struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
ip4.in_addr = addr->sin_addr;
rc |= 1;
}
}
break; /* switch */
#endif
break; /* switch */
#ifdef TOX_ENABLE_IPV6
case AF_INET6:
if (walker->ai_family == family) { /* AF_INET6 requested, done */
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
to->ip6 = addr->sin6_addr;
rc = 3;
}
} else if (!(rc & 2)) { /* AF_UNSPEC requested, store away */
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
ip6 = addr->sin6_addr;
rc |= 2;
}
}
break; /* switch */
#endif
}
}
#ifdef TOX_ENABLE_IPV6
if (to->family == AF_UNSPEC) {
if (rc & 2) {
to->family = AF_INET6;
to->ip6 = ip6;
if ((rc & 1) && (extra != NULL)) {
extra->family = AF_INET;
extra->ip4 = ip4;
}
}
else if (rc & 1) {
} else if (rc & 1) {
to->family = AF_INET;
to->ip4 = ip4;
}
else
} else
rc = 0;
}
#endif
freeaddrinfo(server);
#ifdef __WIN32__
WSACleanup();
#endif
return rc;
}
@ -839,22 +854,22 @@ static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *i
{
if (res < 0)
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x\n",
buffer[0], message, buflen < 999 ? buflen : 999, 'E',
ip_ntoa(&ip_port->ip), ntohs(ip_port->port), errno,
strerror(errno), buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
buffer[0], message, buflen < 999 ? buflen : 999, 'E',
ip_ntoa(&ip_port->ip), ntohs(ip_port->port), errno,
strerror(errno), buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
else if ((res > 0) && (res <= buflen))
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x\n",
buffer[0], message, res < 999 ? res : 999, res < buflen ? '<' : '=',
ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0,
"OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
buffer[0], message, res < 999 ? res : 999, res < buflen ? '<' : '=',
ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0,
"OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
else /* empty or overwrite */
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %u%c%u %s:%u (%u: %s) | %04x%04x\n",
buffer[0], message, res, !res ? '0' : '>', buflen,
ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0,
"OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
buffer[0], message, res, !res ? '0' : '>', buflen,
ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0,
"OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
logbuffer[sizeof(logbuffer) - 1] = 0;
loglog(logbuffer);

View File

@ -113,7 +113,7 @@ bool is_pinging(void *ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: Repl
/* ping_id = 0 means match any id. */
if ((!ip_isset(&ipp.ip) || ipport_equal(&png->pings[id].ipp, &ipp)) &&
(png->pings[id].id == ping_id || ping_id == 0)) {
(png->pings[id].id == ping_id || ping_id == 0)) {
return true;
}
}

View File

@ -450,7 +450,7 @@ void tox_bootstrap_from_ip(void *tox, IP_Port ip_port, uint8_t *public_key)
DHT_bootstrap(m->dht, ip_port, public_key);
}
int tox_bootstrap_from_address(void *tox, const char *address,
uint8_t ipv6enabled, uint16_t port, uint8_t *public_key)
uint8_t ipv6enabled, uint16_t port, uint8_t *public_key)
{
Messenger *m = tox;
return DHT_bootstrap_from_address(m->dht, address, ipv6enabled, port, public_key);

View File

@ -409,12 +409,12 @@ void tox_bootstrap_from_ip(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key);
* if ipv6enabled is 0 (zero), the resolving sticks STRICTLY to IPv4 addresses
* if ipv6enabled is not 0 (zero), the resolving looks for IPv6 addresses first,
* then IPv4 addresses.
*
*
* returns 1 if the address could be converted into an IP address
* returns 0 otherwise
*/
int tox_bootstrap_from_address(Tox *tox, const char *address, uint8_t ipv6enabled,
uint16_t port, uint8_t *public_key);
uint16_t port, uint8_t *public_key);
/* return 0 if we are not connected to the DHT.
* return 1 if we are.