mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
Fix network connection for hostnames resolving to several IPs: try all IPs in list until one succeeds (bug #21473, debian bug #498610)
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
WeeChat - Wee Enhanced Environment for Chat
|
||||
===========================================
|
||||
|
||||
ChangeLog - 2008-07-28
|
||||
ChangeLog - 2008-09-22
|
||||
|
||||
|
||||
Version 0.2.7 (under dev!):
|
||||
* fix network connection for hostnames resolving to several IPs: try all
|
||||
IPs in list until one succeeds (bug #21473, debian bug #498610)
|
||||
* fix display bug with some weird UTF-8 chars (bug #19687)
|
||||
* fix bug with wide chars in input (bug #16356)
|
||||
* add number of lines remaining after last line displayed in "-MORE-"
|
||||
|
||||
+71
-70
@@ -510,7 +510,7 @@ network_connect_to (int sock, unsigned long address, int port)
|
||||
void
|
||||
network_connect_child (struct t_hook *hook_connect)
|
||||
{
|
||||
struct addrinfo hints, *res, *res_local;
|
||||
struct addrinfo hints, *res, *res_local, *ptr_res;
|
||||
char status_str[2], *ptr_address, *status_ok_with_address;
|
||||
char ipv4_address[INET_ADDRSTRLEN + 1], ipv6_address[INET6_ADDRSTRLEN + 1];
|
||||
char status_ok_without_address[1 + 5 + 1];
|
||||
@@ -518,6 +518,7 @@ network_connect_child (struct t_hook *hook_connect)
|
||||
|
||||
res = NULL;
|
||||
res_local = NULL;
|
||||
|
||||
status_str[1] = '\0';
|
||||
|
||||
if (CONFIG_BOOLEAN(config_proxy_use))
|
||||
@@ -624,16 +625,6 @@ network_connect_child (struct t_hook *hook_connect)
|
||||
/* address not found */
|
||||
status_str[0] = '0' + WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND;
|
||||
write (HOOK_CONNECT(hook_connect, child_write), status_str, 1);
|
||||
if (res)
|
||||
freeaddrinfo (res);
|
||||
return;
|
||||
}
|
||||
if ((HOOK_CONNECT(hook_connect, ipv6) && (res->ai_family != AF_INET6))
|
||||
|| ((!HOOK_CONNECT(hook_connect, ipv6) && (res->ai_family != AF_INET))))
|
||||
{
|
||||
/* IP address not found */
|
||||
status_str[0] = '0' + WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND;
|
||||
write (HOOK_CONNECT(hook_connect, child_write), status_str, 1);
|
||||
if (res)
|
||||
freeaddrinfo (res);
|
||||
if (res_local)
|
||||
@@ -641,77 +632,87 @@ network_connect_child (struct t_hook *hook_connect)
|
||||
return;
|
||||
}
|
||||
|
||||
/* connect to peer */
|
||||
status_str[0] = '0' + WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND;
|
||||
|
||||
/* try all IP addresses found, stop when connection is ok */
|
||||
for (ptr_res = res; ptr_res; ptr_res = ptr_res->ai_next)
|
||||
{
|
||||
/* skip IP address if it's not good family */
|
||||
if ((HOOK_CONNECT(hook_connect, ipv6) && (ptr_res->ai_family != AF_INET6))
|
||||
|| ((!HOOK_CONNECT(hook_connect, ipv6) && (ptr_res->ai_family != AF_INET))))
|
||||
continue;
|
||||
|
||||
/* connect to peer */
|
||||
if (HOOK_CONNECT(hook_connect, ipv6))
|
||||
((struct sockaddr_in6 *)(ptr_res->ai_addr))->sin6_port =
|
||||
htons (HOOK_CONNECT(hook_connect, port));
|
||||
else
|
||||
((struct sockaddr_in *)(ptr_res->ai_addr))->sin_port =
|
||||
htons (HOOK_CONNECT(hook_connect, port));
|
||||
|
||||
if (connect (HOOK_CONNECT(hook_connect, sock),
|
||||
ptr_res->ai_addr, ptr_res->ai_addrlen) == 0)
|
||||
{
|
||||
status_str[0] = '0' + WEECHAT_HOOK_CONNECT_OK;
|
||||
break;
|
||||
}
|
||||
else
|
||||
status_str[0] = '0' + WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED;
|
||||
}
|
||||
}
|
||||
|
||||
if (status_str[0] == '0' + WEECHAT_HOOK_CONNECT_OK)
|
||||
{
|
||||
status_ok_with_address = NULL;
|
||||
ptr_address = NULL;
|
||||
if (HOOK_CONNECT(hook_connect, ipv6))
|
||||
((struct sockaddr_in6 *)(res->ai_addr))->sin6_port =
|
||||
htons (HOOK_CONNECT(hook_connect, port));
|
||||
{
|
||||
if (inet_ntop (AF_INET6,
|
||||
&((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr,
|
||||
ipv6_address,
|
||||
INET6_ADDRSTRLEN))
|
||||
{
|
||||
ptr_address = ipv6_address;
|
||||
}
|
||||
}
|
||||
else
|
||||
((struct sockaddr_in *)(res->ai_addr))->sin_port =
|
||||
htons (HOOK_CONNECT(hook_connect, port));
|
||||
|
||||
if (connect (HOOK_CONNECT(hook_connect, sock),
|
||||
res->ai_addr, res->ai_addrlen) != 0)
|
||||
{
|
||||
/* connection refused */
|
||||
status_str[0] = '0' + WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED;
|
||||
write (HOOK_CONNECT(hook_connect, child_write), status_str, 1);
|
||||
if (res)
|
||||
freeaddrinfo (res);
|
||||
if (res_local)
|
||||
freeaddrinfo (res_local);
|
||||
return;
|
||||
if (inet_ntop (AF_INET,
|
||||
&((struct sockaddr_in *)(res->ai_addr))->sin_addr,
|
||||
ipv4_address,
|
||||
INET_ADDRSTRLEN))
|
||||
{
|
||||
ptr_address = ipv4_address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* connection ok */
|
||||
status_str[0] = '0' + WEECHAT_HOOK_CONNECT_OK;
|
||||
|
||||
status_ok_with_address = NULL;
|
||||
ptr_address = NULL;
|
||||
if (HOOK_CONNECT(hook_connect, ipv6))
|
||||
{
|
||||
if (inet_ntop (AF_INET6,
|
||||
&((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr,
|
||||
ipv6_address,
|
||||
INET6_ADDRSTRLEN))
|
||||
if (ptr_address)
|
||||
{
|
||||
ptr_address = ipv6_address;
|
||||
length = strlen (status_str) + 5 + strlen (ptr_address) + 1;
|
||||
status_ok_with_address = malloc (length);
|
||||
if (status_ok_with_address)
|
||||
{
|
||||
snprintf (status_ok_with_address, length, "%s%05d%s",
|
||||
status_str, strlen (ptr_address), ptr_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//ip = inet_ntoa (((struct sockaddr_in *)(res->ai_addr))->sin_addr);
|
||||
if (inet_ntop (AF_INET,
|
||||
&((struct sockaddr_in *)(res->ai_addr))->sin_addr,
|
||||
ipv4_address,
|
||||
INET_ADDRSTRLEN))
|
||||
{
|
||||
ptr_address = ipv4_address;
|
||||
}
|
||||
}
|
||||
if (ptr_address)
|
||||
{
|
||||
length = strlen (status_str) + 5 + strlen (ptr_address) + 1;
|
||||
status_ok_with_address = malloc (length);
|
||||
|
||||
if (status_ok_with_address)
|
||||
{
|
||||
snprintf (status_ok_with_address, length, "%s%05d%s",
|
||||
status_str, strlen (ptr_address), ptr_address);
|
||||
write (HOOK_CONNECT(hook_connect, child_write),
|
||||
status_ok_with_address, strlen (status_ok_with_address));
|
||||
free (status_ok_with_address);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (status_ok_without_address, sizeof (status_ok_without_address),
|
||||
"%s%05d", status_str, 0);
|
||||
write (HOOK_CONNECT(hook_connect, child_write),
|
||||
status_ok_without_address, strlen (status_ok_without_address));
|
||||
}
|
||||
}
|
||||
|
||||
if (status_ok_with_address)
|
||||
{
|
||||
write (HOOK_CONNECT(hook_connect, child_write),
|
||||
status_ok_with_address, strlen (status_ok_with_address));
|
||||
free (status_ok_with_address);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (status_ok_without_address, sizeof (status_ok_without_address),
|
||||
"%s%05d", status_str, 0);
|
||||
write (HOOK_CONNECT(hook_connect, child_write),
|
||||
status_ok_without_address, strlen (status_ok_without_address));
|
||||
write (HOOK_CONNECT(hook_connect, child_write), status_str, 1);
|
||||
}
|
||||
|
||||
if (res)
|
||||
|
||||
Reference in New Issue
Block a user