On Mon, 15 Mar 2004, Marc Aurele La France wrote:

> OK.  I've committed this.  Perhaps someone else will step up to fix the
> remaining problems.

Hi Marc Aurele,

1. meanwhile I have done some testing and debugging (with some extra Debug(...)
statements in order to narrow down the problem). The result is an additional
patch (both are attached). With the two patches the IPv6 enabled chooser, xdm,
and XFree86 server work together quite well on a linux system without IPv6
support from the kernel. Each of the two patches begins with some comments.

There are still some warnings but with those we can live. Most of them will
probably disappear with '-nolisten inet6' and with a LISTEN statement in the
xdm config file.

Note: The change in xdmcp.c(NetworkAddressToHostname) is quite a kludge, but
somehow I got tired to further nail down what goes wrong. There is a comment
in the code to that effect and explaining exactly what went wrong. Unless
some brave soul fixes that, the modified code should probably be reformatted
(different indentation do to an additional brace level). Honestly I was just
too lazy to do that.

2. In browsing through xc/programs/xdm/*.c in noticed something strange:

xc/programs/xdm/xdmcp.c declares and uses both chooserFd and chooserFd6.

xc/programs/xdm/socket.c however creates just chooserFd as either an INET6 or
        INET socket, thus chooserFd6 keeps it's initial value -1 and none of
        the chooserFd6 related code in xdmcp.c will ever be executed.

It seems that originally there were plans to have two distinct sockets that
were abandonned in the middle. Maybe that ought to be cleaned up (fairly
trivial mods in xdmcp.c, just excise chooserFd6).

regards
Peter Breitenlohner <[EMAIL PROTECTED]>
        This patch fixes some (but not all) problems arising if
        XFree86 is compiled with IPv6 support, but the (linux) kernel
        does not support IPv6.

        1. chooser segfaults: fixed.

        2. xdm fails with "chooser socket creation failed" and consequently
        no Xserver is started: fixed.

        3. xdm fails to accept chooser connections: NOT fixed.

        With these changes we can use the IPv6 enabled xdm for local logins,
        but not in connection with a chooser.

        The chooser compiled with IPv6 support works fine together with
        xdm compiled without IPv6 support.

diff -ur -N XF86-4.4.0.orig/xc/programs/xdm/chooser.c 
XF86-4.4.0/xc/programs/xdm/chooser.c
--- XF86-4.4.0.orig/xc/programs/xdm/chooser.c   2003-11-23 23:57:31.000000000 +0100
+++ XF86-4.4.0/xc/programs/xdm/chooser.c        2004-03-08 08:59:09.000000000 +0100
@@ -856,6 +856,7 @@
     XtAddInput (socketFD, (XtPointer) XtInputReadMask, ReceivePacket,
                (XtPointer) &socketFD);
 #if defined(IPv6) && defined(AF_INET6)
+    if (socket6FD != -1)
     XtAddInput (socket6FD, (XtPointer) XtInputReadMask, ReceivePacket,
                (XtPointer) &socket6FD);
 #endif
diff -ur -N XF86-4.4.0.orig/xc/programs/xdm/socket.c 
XF86-4.4.0/xc/programs/xdm/socket.c
--- XF86-4.4.0.orig/xc/programs/xdm/socket.c    2003-11-25 23:21:08.000000000 +0100
+++ XF86-4.4.0/xc/programs/xdm/socket.c 2004-03-08 09:32:36.000000000 +0100
@@ -68,9 +68,9 @@
 
 #if defined(IPv6) && defined(AF_INET6)
     chooserFd = socket (AF_INET6, SOCK_STREAM, 0);
-#else
-    chooserFd = socket (AF_INET, SOCK_STREAM, 0);
+    if (chooserFd == -1)
 #endif
+    chooserFd = socket (AF_INET, SOCK_STREAM, 0);
     Debug ("Created chooser socket %d\n", chooserFd);
     if (chooserFd == -1)
     {
        This patch fixes the remaining problems arising if XFree86 is
        compiled with IPv6 support, but the (linux) kernel does not
        support IPv6. This patch is to be applied on top of patch-15-IPv6.

        Note: The original code for UpdateListener in xc/programs/xdm/socket.c
        could not possibly work for "addr == NULL || addr->length == 0"
        because &in resp. &in6 were used outside the domain of validity of
        these structures.

        Similarly all_query_respond in xc/programs/xdm/xdmcp.c couldn't
        possibly work due to some FamilyInternet(6) vs. AF_INET(6) confusion.

diff -ur -N XF86-4.4.0.orig/xc/programs/xdm/auth.c XF86-4.4.0/xc/programs/xdm/auth.c
--- XF86-4.4.0.orig/xc/programs/xdm/auth.c      2004-01-16 01:03:54.000000000 +0100
+++ XF86-4.4.0/xc/programs/xdm/auth.c   2004-03-21 16:24:04.000000000 +0100
@@ -1182,9 +1182,9 @@
 #ifdef TCPCONN
 #if defined(IPv6) && defined(AF_INET6)
     fd = socket (AF_INET6, SOCK_STREAM, 0);
-#else
-    fd = socket (AF_INET, SOCK_STREAM, 0);
+    if (fd == -1)
 #endif
+    fd = socket (AF_INET, SOCK_STREAM, 0);
     DefineSelf (fd, file, auth);
     close (fd);
 #endif
diff -ur -N XF86-4.4.0.orig/xc/programs/xdm/socket.c 
XF86-4.4.0/xc/programs/xdm/socket.c
--- XF86-4.4.0.orig/xc/programs/xdm/socket.c    2004-03-08 09:32:36.000000000 +0100
+++ XF86-4.4.0/xc/programs/xdm/socket.c 2004-03-22 16:28:48.000000000 +0100
@@ -298,22 +298,24 @@
 UpdateListener(ARRAY8Ptr addr, void **closure)
 {
     struct socklist *s;
-    ARRAY8 tmpaddr;
 
     *closure = NULL;
 
     if (addr == NULL || addr->length == 0) {
+       ARRAY8 tmpaddr;
+       struct in_addr in;
 #if defined(IPv6) && defined(AF_INET6)
        struct in6_addr in6 = in6addr_any;
        tmpaddr.length = sizeof(in6);
        tmpaddr.data = (CARD8Ptr) &in6;
-#else
-       struct in_addr in;
+       UpdateListener(&tmpaddr, closure);
+       if (*closure) return;
+#endif
        in.s_addr = htonl (INADDR_ANY);
        tmpaddr.length = sizeof(in);
        tmpaddr.data = (CARD8Ptr) &in;
-#endif
-       addr = &tmpaddr;
+       UpdateListener(&tmpaddr, closure);
+       return;
     }
     
     s = FindInList(listensocks, addr);
@@ -371,12 +373,12 @@
                  (op == JOIN_MCAST_GROUP) ? "join" : "drop",
                  inet_ntoa(((struct sockaddr_in *) g->addr)->sin_addr),
                  errno);
-               return;
            } else if (debugLevel > 0) {
                Debug ("XDMCP socket multicast %s to %s succeeded\n", 
                  (op == JOIN_MCAST_GROUP) ? "join" : "drop",
                  inet_ntoa(((struct sockaddr_in *) g->addr)->sin_addr));
            }
+           return;
        }
 #if defined(IPv6) && defined(AF_INET6)
 #ifndef IPV6_JOIN_GROUP
@@ -409,7 +411,6 @@
                LogError ("XDMCP socket multicast %s to %s failed, errno %d\n",
                  (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf,
                  saveerr);
-               return;
            } else if (debugLevel > 0) {
                char addrbuf[INET6_ADDRSTRLEN];
 
@@ -420,6 +421,7 @@
                Debug ("XDMCP socket multicast %s to %s succeeded\n", 
                  (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf);
            }
+           return;
        }
 #endif
     }
diff -ur -N XF86-4.4.0.orig/xc/programs/xdm/xdmcp.c XF86-4.4.0/xc/programs/xdm/xdmcp.c
--- XF86-4.4.0.orig/xc/programs/xdm/xdmcp.c     2004-01-07 05:28:06.000000000 +0100
+++ XF86-4.4.0/xc/programs/xdm/xdmcp.c  2004-03-22 18:53:04.000000000 +0100
@@ -261,12 +261,15 @@
     if (debugLevel > 0) {
 #if defined(IPv6) && defined(AF_INET6) 
        void *ipaddr;
-       if (family == AF_INET6) {
+       int af_type;
+       if (family == FamilyInternet6) {
            ipaddr = & ((struct sockaddr_in6 *) from)->sin6_addr;
+           af_type = AF_INET6;
        } else {
            ipaddr = & ((struct sockaddr_in *) from)->sin_addr;
+           af_type = AF_INET;
        }
-       addrstring = inet_ntop(family, ipaddr, addrbuf, sizeof(addrbuf));
+       addrstring = inet_ntop(af_type, ipaddr, addrbuf, sizeof(addrbuf));
 #else
        addrstring = inet_ntoa(((struct sockaddr_in *)from)->sin_addr);
 #endif
@@ -1388,7 +1391,7 @@
     CARD16     connectionType,
     ARRAY8Ptr   connectionAddress)
 {
-    char    *name = 0;
+    char    *name = NULL;
 
     switch (connectionType)
     {
@@ -1419,6 +1422,12 @@
            if (hostent) {
                /* check for DNS spoofing */
 #if defined(IPv6) && defined(AF_INET6)
+               /* This is a kludge! the "IPv6 && AF_INET6" part of the code somehow
+                  doesn't work for af_type==AF_INET (for a linux kernel not 
supporting IPv6) */
+               /* Tracing the call from AcceptableDisplayAddress it turned out that
+                  NetworkAddressToHostname returns NULL for a perfectly good IPv4 
address.
+                  What's wrong with this code ??? */
+               if (af_type == AF_INET6) {
                struct addrinfo *ai = NULL, *nai;
                if (getaddrinfo(hostent->h_name, NULL, NULL, &ai) == 0) {
                    for (nai = ai; nai != NULL; nai = nai->ai_next) {
@@ -1441,7 +1450,9 @@
                } else {
                    hostent = NULL;
                }
-#else
+               } else
+#endif
+               {
                char *s = strdup(hostent->h_name); /* fscking non-reentrancy of 
getXXX() */
                if ((hostent = gethostbyname(s))) {
                        if (memcmp((char*)connectionAddress->data, hostent->h_addr,
@@ -1453,7 +1464,7 @@
                        }
                }
                free(s);
-#endif
+               }
            }
 
            if (!hostent) {

Reply via email to