mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
friend_iplist and route_tofriend behaviour fixes.
This commit is contained in:
parent
d14ba73bc3
commit
ed07194eb6
123
toxcore/DHT.c
123
toxcore/DHT.c
|
@ -1357,6 +1357,7 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
|
||||||
|
|
||||||
/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist.
|
/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist.
|
||||||
* ip_portlist must be at least MAX_FRIEND_CLIENTS big.
|
* ip_portlist must be at least MAX_FRIEND_CLIENTS big.
|
||||||
|
* unless CLIENT_ONETOONE_IP is defined, returns an array with ips of the same family.
|
||||||
*
|
*
|
||||||
* return the number of ips returned.
|
* return the number of ips returned.
|
||||||
* return 0 if we are connected to friend or if no ips were found.
|
* return 0 if we are connected to friend or if no ips were found.
|
||||||
|
@ -1364,7 +1365,7 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
|
||||||
*/
|
*/
|
||||||
static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
|
static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
|
||||||
{
|
{
|
||||||
int i, num_ips = 0;
|
int i;
|
||||||
uint64_t temp_time = unix_time();
|
uint64_t temp_time = unix_time();
|
||||||
|
|
||||||
if (friend_num >= dht->num_friends)
|
if (friend_num >= dht->num_friends)
|
||||||
|
@ -1372,97 +1373,59 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
|
||||||
|
|
||||||
DHT_Friend *friend = &dht->friends_list[friend_num];
|
DHT_Friend *friend = &dht->friends_list[friend_num];
|
||||||
Client_data *client;
|
Client_data *client;
|
||||||
|
IP_Port ipv4s[MAX_FRIEND_CLIENTS];
|
||||||
|
int num_ipv4s = 0;
|
||||||
|
IP_Port ipv6s[MAX_FRIEND_CLIENTS];
|
||||||
|
int num_ipv6s = 0;
|
||||||
|
|
||||||
#ifndef CLIENT_ONETOONE_IP
|
for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
|
||||||
/* extra legwork, because having the outside allocating the space for us
|
client = &(friend->client_list[i]);
|
||||||
* is *usually* good(tm) (bites us in the behind in this case though) */
|
|
||||||
int client_friend = -1;
|
|
||||||
uint8_t client_friend_flags = 0;
|
|
||||||
uint32_t a;
|
|
||||||
|
|
||||||
for (a = 0; a < 2; a++)
|
IPPTsPng *assoc = NULL;
|
||||||
#endif
|
|
||||||
for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
|
|
||||||
client = &(friend->client_list[i]);
|
|
||||||
|
|
||||||
IPPTsPng *assoc = NULL;
|
|
||||||
#ifdef CLIENT_ONETOONE_IP
|
#ifdef CLIENT_ONETOONE_IP
|
||||||
assoc = &client->assoc;
|
assoc = &client->assoc;
|
||||||
#else
|
#else
|
||||||
|
assoc = &client->assoc4;
|
||||||
/* this is the one place where ipv4 is favored over ipv6, because
|
|
||||||
* we can't be sure there's enough space to return both, and we do
|
|
||||||
* need to return IPv4 (because of the majority of the people still
|
|
||||||
* lacking IPv6 connectivity) */
|
|
||||||
if (!a)
|
|
||||||
assoc = &client->assoc4;
|
|
||||||
else
|
|
||||||
assoc = &client->assoc6;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (id_equal(client->client_id, friend->client_id) &&
|
if (id_equal(client->client_id, friend->client_id) &&
|
||||||
!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT))
|
!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If ip is not zero and node is good. */
|
/* If ip is not zero and node is good. */
|
||||||
if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
ip_portlist[num_ips] = assoc->ret_ip_port;
|
ipv4s[num_ipv4s] = assoc->ret_ip_port;
|
||||||
++num_ips;
|
++num_ipv4s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef CLIENT_ONETOONE_IP
|
#ifndef CLIENT_ONETOONE_IP
|
||||||
|
|
||||||
if ((client_friend == -1) && id_equal(client->client_id, friend->client_id))
|
for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
|
||||||
client_friend = i;
|
client = &(friend->client_list[i]);
|
||||||
|
|
||||||
if (client_friend == i)
|
IPPTsPng *assoc = NULL;
|
||||||
client_friend_flags |= 1 << a;
|
assoc = &client->assoc6;
|
||||||
|
|
||||||
if (num_ips == MAX_FRIEND_CLIENTS) {
|
if (id_equal(client->client_id, friend->client_id) &&
|
||||||
/* if we got "real" IP addresses for the friend and we added
|
!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT))
|
||||||
* the ipv4 one, but (maybe) couldn't add the ipv6 one
|
return 0;
|
||||||
* due to space constraints... */
|
|
||||||
if ((client_friend != -1) && (client_friend_flags == 1)) {
|
|
||||||
assoc = &friend->client_list[client_friend].assoc6;
|
|
||||||
|
|
||||||
/* but the IPv6 address WOULD be valid... (which also
|
/* If ip is not zero and node is good. */
|
||||||
* means there is DEFINITELY a functioning IPv6 stack
|
if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
* and connectivity!) */
|
ipv6s[num_ipv6s] = assoc->ret_ip_port;
|
||||||
if (ip_isset(&assoc->ret_ip_port.ip) &&
|
++num_ipv6s;
|
||||||
!is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
}
|
||||||
uint32_t r;
|
}
|
||||||
|
|
||||||
/* then kick another entry out:
|
if (num_ipv6s >= num_ipv4s) {
|
||||||
* first, try to find an IPv6 entry to kick
|
memcpy(ip_portlist, ipv6s, num_ipv6s * sizeof(IP_Port));
|
||||||
* (don't need to look for friend's, because he
|
return num_ipv6s;
|
||||||
* definitely hasn't been added yet) */
|
}
|
||||||
for (r = 0; r < MAX_FRIEND_CLIENTS; r++)
|
|
||||||
if (ip_portlist[r].ip.family == AF_INET6) {
|
|
||||||
ip_portlist[r] = assoc->ip_port;
|
|
||||||
return num_ips;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no IPv6 found to kick:
|
|
||||||
* kick the first IPv4 that is NOT the friend's one */
|
|
||||||
for (r = 0; r < MAX_FRIEND_CLIENTS; r++)
|
|
||||||
if ((ip_portlist[r].ip.family == AF_INET) &&
|
|
||||||
!ipport_equal(&ip_portlist[r], &assoc->ip_port)) {
|
|
||||||
ip_portlist[r] = assoc->ip_port;
|
|
||||||
return num_ips;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* shouldn't be reached... */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return num_ips;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
memcpy(ip_portlist, ipv4s, num_ipv4s * sizeof(IP_Port));
|
||||||
}
|
return num_ipv4s;
|
||||||
|
|
||||||
return num_ips;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1479,6 +1442,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint32_t i, sent = 0;
|
uint32_t i, sent = 0;
|
||||||
|
uint8_t friend_sent[MAX_FRIEND_CLIENTS] = {0};
|
||||||
|
|
||||||
IP_Port ip_list[MAX_FRIEND_CLIENTS];
|
IP_Port ip_list[MAX_FRIEND_CLIENTS];
|
||||||
int ip_num = friend_iplist(dht, ip_list, num);
|
int ip_num = friend_iplist(dht, ip_list, num);
|
||||||
|
@ -1498,6 +1462,9 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
|
||||||
for (a = 0; a < 2; a++)
|
for (a = 0; a < 2; a++)
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
|
for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
|
||||||
|
if (friend_sent[i])/* Send one packet per client.*/
|
||||||
|
continue;
|
||||||
|
|
||||||
client = &friend->client_list[i];
|
client = &friend->client_list[i];
|
||||||
IPPTsPng *assoc = NULL;
|
IPPTsPng *assoc = NULL;
|
||||||
#ifdef CLIENT_ONETOONE_IP
|
#ifdef CLIENT_ONETOONE_IP
|
||||||
|
@ -1516,8 +1483,10 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
|
||||||
!is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
!is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length);
|
int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length);
|
||||||
|
|
||||||
if ((unsigned int)retval == length)
|
if ((unsigned int)retval == length) {
|
||||||
++sent;
|
++sent;
|
||||||
|
friend_sent[i] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user