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]
* 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)
* 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
/nslookup to build. (caf)
* Fix known problem with IPv6 on FreeBSD and enable IPv6 on all supporting
platforms. Thanks to brabes, snadge and packet. (caf)
* Fix problem connecting to IPv4 when IPv6 enabled on FreeBSD and enable
IPv6 on all supporting platforms. Thanks to brabes, snadge and packet. (caf)
* Improve connect() error handling. (caf)

View File

@@ -99,6 +99,10 @@ extern char thing_star[4];
#include <netdb.h>
#endif
#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0
#endif
#include "bsdglob.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
#ifdef IPV6
struct addrinfo hints, *res;
struct sockaddr_foobar *sf = NULL;
#else
struct sockaddr_in localaddr;
if (LocalHostName)
@@ -524,39 +523,34 @@ int BX_connect_by_number(char *hostn, unsigned short *portnum, int service, int
#ifndef WINNT
#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)
{
sf = (struct sockaddr_foobar*) res->ai_addr;
close(fd);
proto_type = (protocol == PROTOCOL_TCP) ? SOCK_STREAM : SOCK_DGRAM;
if ((fd = socket(sf->sf_family, proto_type, 0)) < 0)
if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
return -1;
set_socket_options (fd);
if ((server.sf_family = sf->sf_family) == AF_INET)
{
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;
}
memcpy(&server, res->ai_addr, res->ai_addrlen);
server_len = res->ai_addrlen;
server.sf_port = htons(*portnum);
memset(&hints, 0, sizeof(struct addrinfo));
memset(&hints, 0, sizeof hints);
hints.ai_family = res->ai_family;
freeaddrinfo(res);
if (LocalHostName && !getaddrinfo(LocalHostName, NULL, &hints, &res) && res)
{
if (bind(fd, (struct sockaddr *) res->ai_addr, res->ai_addrlen))
return close(fd), -2;
int retval = bind(fd, (struct sockaddr *) res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
if (retval)
return close(fd), -2;
}
}
else