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)

Reply via email to