Author: vlendec
Date: 2004-09-01 12:46:56 +0000 (Wed, 01 Sep 2004)
New Revision: 2171

WebSVN: 
http://websvn.samba.org/websvn/changeset.php?rep=samba&path=/trunk/source&rev=2171&nolog=1

Log:
Two bugfixes for winbind connection establishing:

* When the GetDC requests all fail due to a negative connection cache entry,
  don't wipe out the IP address, but note that in a bitmap, so that the
  fallback to the old method still works.

* Non-blocking connect() was wrong. According to Stevens, select-read/write
  means error, select-writeonly means connected.

Volker

Modified:
   trunk/source/lib/util_sock.c
   trunk/source/nsswitch/winbindd_cm.c


Changeset:
Modified: trunk/source/lib/util_sock.c
===================================================================
--- trunk/source/lib/util_sock.c        2004-09-01 09:45:33 UTC (rev 2170)
+++ trunk/source/lib/util_sock.c        2004-09-01 12:46:56 UTC (rev 2171)
@@ -873,7 +873,7 @@
        int *sockets;
        BOOL good_connect;
 
-       fd_set wr_fds;
+       fd_set r_fds, wr_fds;
        struct timeval tv;
        int maxfd;
 
@@ -928,9 +928,11 @@
 
        maxfd = 0;
        FD_ZERO(&wr_fds);
+       FD_ZERO(&r_fds);
 
        for (i=0; i<num_addrs; i++) {
                FD_SET(sockets[i], &wr_fds);
+               FD_SET(sockets[i], &r_fds);
                if (sockets[i]>maxfd)
                        maxfd = sockets[i];
        }
@@ -938,7 +940,7 @@
        tv.tv_sec = 0;
        tv.tv_usec = connect_loop;
 
-       res = sys_select(maxfd+1, NULL, &wr_fds, NULL, &tv);
+       res = sys_select(maxfd+1, &r_fds, &wr_fds, NULL, &tv);
 
        if (res < 0)
                goto done;
@@ -948,21 +950,15 @@
 
        for (i=0; i<num_addrs; i++) {
 
-               int sockerr, sockerr_len;
-               
                if (!FD_ISSET(sockets[i], &wr_fds))
                        continue;
 
-               sockerr_len = sizeof(sockerr);
+               /* Stevens, Network Programming says that if there's a
+                * successful connect, the socket is only writable. Upon an
+                * error, it's both readable and writable. */
 
-               res = getsockopt(sockets[i], SOL_SOCKET, SO_ERROR, &sockerr,
-                                &sockerr_len);
-
-               if (res < 0)
-                       goto done;
-
-               if (sockerr == 0) {
-                       /* Hey, we got a connection */
+               if (!FD_ISSET(sockets[i], &r_fds)) {
+                       /* Only writable, so it's connected */
                        resulting_index = i;
                        goto done;
                }

Modified: trunk/source/nsswitch/winbindd_cm.c
===================================================================
--- trunk/source/nsswitch/winbindd_cm.c 2004-09-01 09:45:33 UTC (rev 2170)
+++ trunk/source/nsswitch/winbindd_cm.c 2004-09-01 12:46:56 UTC (rev 2171)
@@ -593,11 +593,17 @@
 {
        struct ip_service *iplist = NULL;
        int i, num = 0;
+       struct bitmap *replied;
 
        if (!internal_resolve_name(domain->name, 0x1c, &iplist, &num,
                                   lp_name_resolve_order()))
                return False;
 
+       replied = bitmap_talloc(mem_ctx, num);
+
+       if (replied == NULL)
+               return False;
+
        for (i=0; i<num; i++) {
                if (!send_getdc_request(iplist[i].ip, domain->name,
                                        &domain->sid)) {
@@ -614,7 +620,7 @@
 
                        fstring dcname;
 
-                       if (iplist[j].ip.s_addr == 0)
+                       if (bitmap_query(replied, j))
                                continue;
 
                        if (receive_getdc_response(iplist[j].ip,
@@ -623,7 +629,7 @@
                                add_one_dc_unique(mem_ctx, domain->name,
                                                  dcname, iplist[j].ip,
                                                  dcs, num_dcs);
-                               iplist[i].ip.s_addr = 0;
+                               bitmap_set(replied, j);
                        } else {
                                retry = True;
                        }

Reply via email to