On systems that support it, supply the AI_ADDRCONFIG flag to getaddrinfo().

This means that we shouldn't try to connect using IPv6 if the local machine
doesn't have an IPv6 address itself.

This also simplifies the IPv6 code in BX_connect_by_number() a bit.


git-svn-id: svn://svn.code.sf.net/p/bitchx/code/trunk@203 13b04d17-f746-0410-82c6-800466cd88b0
This commit is contained in:
Kevin Easton
2012-06-02 11:38:37 +00:00
parent 64605b326c
commit 252d1bf004
3 changed files with 22 additions and 21 deletions

View File

@@ -1,5 +1,8 @@
[Changes 1.2c01] [Changes 1.2c01]
* Use AI_ADDRCONFIG flag to improve server address selection when client
is built for IPv6 but we don't have an IPv6 address. (caf)
* Enable SSL support by default, if OpenSSL is present at build time. (caf) * Enable SSL support by default, if OpenSSL is present at build time. (caf)
* Fix leak and potential crash in lame_resolv() using IPv6. (caf, snadge) * Fix leak and potential crash in lame_resolv() using IPv6. (caf, snadge)
@@ -7,8 +10,8 @@
* Apply patch from snadge defining BIND_4_COMPAT on OpenBSD, to allow * Apply patch from snadge defining BIND_4_COMPAT on OpenBSD, to allow
/nslookup to build. (caf) /nslookup to build. (caf)
* Fix known problem with IPv6 on FreeBSD and enable IPv6 on all supporting * Fix problem connecting to IPv4 when IPv6 enabled on FreeBSD and enable
platforms. Thanks to brabes, snadge and packet. (caf) IPv6 on all supporting platforms. Thanks to brabes, snadge and packet. (caf)
* Improve connect() error handling. (caf) * Improve connect() error handling. (caf)

View File

@@ -99,6 +99,10 @@ extern char thing_star[4];
#include <netdb.h> #include <netdb.h>
#endif #endif
#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0
#endif
#include "bsdglob.h" #include "bsdglob.h"
#include "irc_std.h" #include "irc_std.h"

View File

@@ -506,7 +506,6 @@ int BX_connect_by_number(char *hostn, unsigned short *portnum, int service, int
#endif #endif
#ifdef IPV6 #ifdef IPV6
struct addrinfo hints, *res; struct addrinfo hints, *res;
struct sockaddr_foobar *sf = NULL;
#else #else
struct sockaddr_in localaddr; struct sockaddr_in localaddr;
if (LocalHostName) if (LocalHostName)
@@ -524,39 +523,34 @@ int BX_connect_by_number(char *hostn, unsigned short *portnum, int service, int
#ifndef WINNT #ifndef WINNT
#ifdef IPV6 #ifdef IPV6
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_socktype = proto_type;
if (!getaddrinfo(hostn, NULL, &hints, &res) && res) if (!getaddrinfo(hostn, NULL, &hints, &res) && res)
{ {
sf = (struct sockaddr_foobar*) res->ai_addr;
close(fd); close(fd);
proto_type = (protocol == PROTOCOL_TCP) ? SOCK_STREAM : SOCK_DGRAM; if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
if ((fd = socket(sf->sf_family, proto_type, 0)) < 0)
return -1; return -1;
set_socket_options (fd); set_socket_options (fd);
if ((server.sf_family = sf->sf_family) == AF_INET) memcpy(&server, res->ai_addr, res->ai_addrlen);
{ server_len = res->ai_addrlen;
memcpy(&server.sf_addr, &sf->sf_addr, sizeof(struct in_addr));
server_len = sizeof server.sins.sin;
}
else
{
memcpy(&server.sf_addr6, &sf->sf_addr6, sizeof(struct in6_addr));
server_len = sizeof server.sins.sin6;
}
server.sf_port = htons(*portnum); server.sf_port = htons(*portnum);
memset(&hints, 0, sizeof(struct addrinfo)); memset(&hints, 0, sizeof hints);
hints.ai_family = res->ai_family; hints.ai_family = res->ai_family;
freeaddrinfo(res); freeaddrinfo(res);
if (LocalHostName && !getaddrinfo(LocalHostName, NULL, &hints, &res) && res) if (LocalHostName && !getaddrinfo(LocalHostName, NULL, &hints, &res) && res)
{ {
if (bind(fd, (struct sockaddr *) res->ai_addr, res->ai_addrlen)) int retval = bind(fd, (struct sockaddr *) res->ai_addr, res->ai_addrlen);
return close(fd), -2;
freeaddrinfo(res); freeaddrinfo(res);
if (retval)
return close(fd), -2;
} }
} }
else else