Package: weechat Version: 0.2.6-1 Severity: normal Tags: patch When a server hostname resolves to several IPs, weechat tries only the first one. Here is a patch that makes it try them all, until one succeeds (at the TCP connection level, not at the IRC nick registration level) or they all fail.
On the way, I fixed the "bug" that under some conditions res_local was not being freed; not that it matters much, because the process dies right after that. -- System Information: Debian Release: lenny/sid APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: amd64 (x86_64) Kernel: Linux 2.6.26-1-amd64 (SMP w/2 CPU cores) Locale: LANG=fr_LU.UTF-8, LC_CTYPE=fr_LU.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages weechat depends on: ii weechat-common 0.2.6-1 Common files for WeeChat ii weechat-curses 0.2.6-1 Fast, light and extensible IRC cli weechat recommends no packages. weechat suggests no packages. -- no debconf information
--- weechat-0.2.6/src/irc/irc-server.c 2007-08-20 10:37:46.000000000 +0200 +++ weechat-0.2.6.lio/src/irc/irc-server.c 2008-09-11 15:35:16.881484343 +0200 @@ -1681,8 +1681,9 @@ int irc_server_child (t_irc_server *server) { - struct addrinfo hints, *res, *res_local; + struct addrinfo hints, *res, *res_local, *res_iter; int rc; + char *child_result; res = NULL; res_local = NULL; @@ -1730,6 +1731,8 @@ freeaddrinfo (res); return 0; } + + child_result="0"; } else { @@ -1768,37 +1771,36 @@ write (server->child_write, "1", 1); if (res) freeaddrinfo (res); - return 0; - } - if ((server->ipv6 && (res->ai_family != AF_INET6)) - || ((!server->ipv6 && (res->ai_family != AF_INET)))) - { - write (server->child_write, "2", 1); - if (res) - freeaddrinfo (res); if (res_local) freeaddrinfo (res_local); return 0; } - - /* connect to server */ - if (server->ipv6) - ((struct sockaddr_in6 *)(res->ai_addr))->sin6_port = htons (server->port); - else - ((struct sockaddr_in *)(res->ai_addr))->sin_port = htons (server->port); - - if (connect (server->sock, res->ai_addr, res->ai_addrlen) != 0) + + child_result = "2"; + + for (res_iter=res; res_iter != NULL; res_iter=res_iter->ai_next) { - write (server->child_write, "3", 1); - if (res) - freeaddrinfo (res); - if (res_local) - freeaddrinfo (res_local); - return 0; + if ((server->ipv6 && (res_iter->ai_family != AF_INET6)) + || ((!server->ipv6 && (res_iter->ai_family != AF_INET)))) + continue; + + child_result="3"; + + /* connect to server */ + if (server->ipv6) + ((struct sockaddr_in6 *)(res_iter->ai_addr))->sin6_port = htons (server->port); + else + ((struct sockaddr_in *)(res_iter->ai_addr))->sin_port = htons (server->port); + + if (connect (server->sock, res_iter->ai_addr, res_iter->ai_addrlen) == 0) + { + child_result="0"; + break; + } } } - write (server->child_write, "0", 1); + write (server->child_write, child_result, 1); if (res) freeaddrinfo (res); if (res_local)