From 252d1bf004d57434caaf25b404c218bf067b6ca4 Mon Sep 17 00:00:00 2001 From: Kevin Easton Date: Sat, 2 Jun 2012 11:38:37 +0000 Subject: [PATCH] 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 --- Changelog | 7 +++++-- include/irc.h | 4 ++++ source/network.c | 32 +++++++++++++------------------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Changelog b/Changelog index e4f6f21..0400d6b 100644 --- a/Changelog +++ b/Changelog @@ -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) diff --git a/include/irc.h b/include/irc.h index 2863ff0..d4f6fcc 100644 --- a/include/irc.h +++ b/include/irc.h @@ -99,6 +99,10 @@ extern char thing_star[4]; #include #endif +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0 +#endif + #include "bsdglob.h" #include "irc_std.h" diff --git a/source/network.c b/source/network.c index 2ffaa59..e71b024 100644 --- a/source/network.c +++ b/source/network.c @@ -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