- get_close_nodes()/sendnodes()/sendnodes_ipv6(): when selecting for SEND_NODES/SEND_NODES_IPV6, treat embedded IPv4-in-IPv6 addresses as being IPv4

Messenger.c:
- added a named constant for sixty seconds friend/client dump
- fix logging to convert client_id to printable before printing
This commit is contained in:
Coren[m] 2013-09-14 12:55:56 +02:00
parent fa576e464e
commit 09cdd813c5
2 changed files with 51 additions and 25 deletions

View File

@ -32,6 +32,7 @@
#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. */
#define BAD_NODE_TIMEOUT 70
@ -215,15 +216,25 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list
* sent anyways for backwards compatibility)
* 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
*
* 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().
*/
#ifdef TOX_ENABLE_IPV6
ipv46x = 0;
if (sa_family == AF_INET)
ipv46x = dht->close_clientlist[i].ip_port.ip.family != AF_INET;
else
ipv46x = dht->close_clientlist[i].ip_port.ip.family == AF_INET;
IP *client_ip = &dht->close_clientlist[i].ip_port.ip;
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;
}
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. */
@ -267,11 +278,17 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list
dht->friends_list[i].client_list[j].client_id);
#ifdef TOX_ENABLE_IPV6
ipv46x = 0;
if (sa_family == AF_INET)
ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family != AF_INET;
else
ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family == AF_INET;
IP *client_ip = &dht->friends_list[i].client_list[j].ip_port.ip;
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;
}
ipv46x = !(sa_family == ip_treat_as_family);
#else
ipv46x = sa_family != AF_INET;
#endif
@ -578,14 +595,21 @@ 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++)
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);
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;
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;
num_nodes_ok++;
}
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];
else if (node_ip->family == AF_INET)
nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip4.uint32;
else /* shouldn't happen */
continue;
num_nodes_ok++;
}
if (num_nodes_ok < num_nodes) {
/* shouldn't happen */
@ -1461,13 +1485,13 @@ 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);
fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size);
return -1;
}
uint32_t friendlistsize = size - sizeof(dht->close_clientlist);
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 %u, got %u.\n", sizeof(DHT_Friend), friendlistsize);
return -1;
}

View File

@ -1220,6 +1220,7 @@ void doInbound(Messenger *m)
}
#ifdef LOGGING
#define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60
static time_t lastdump = 0;
static char IDString[CLIENT_ID_SIZE * 2 + 1];
static char *ID2String(uint8_t *client_id)
@ -1245,7 +1246,7 @@ void doMessenger(Messenger *m)
LANdiscovery(m);
#ifdef LOGGING
if (now() > lastdump + 60) {
if (now() > lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) {
loglog(" = = = = = = = = \n");
lastdump = now();
@ -1292,8 +1293,9 @@ void doMessenger(Messenger *m)
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, msgfptr->client_id);
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++) {
@ -1304,7 +1306,7 @@ void doMessenger(Messenger *m)
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,
cptr->client_id);
ID2String(cptr->client_id));
loglog(logbuffer);
}
}