[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: DHCP server stops with SIGPIPE when talking to LDAP server



Here is a draft patch to try to solve this issue.  I have not verified
that it work, given what I found out earlier, I suspect this is the
correct fix.  I lack the test bed to check if it work where I am now.

The theory is that new LDAP search requests result in SIGPIPE, which
kill dhcpd.  To avoid this, I copied the code currently present in
ldap_stop() to avoid dying because of SIGPIPE and wrapped the first
call to ldap_search_ext_s() with the same code.  Perhaps the second
call should have it too, but I guess ldap_open() will handle any
connection problems, and do not believe it make sense to handle LDAP
server timeouts in the sub-second range.

Here is the patch, to be applied after dhcp-3.1.0-ldap-code.dpatch.

========================================================================
#! /bin/sh /usr/share/dpatch/dpatch-run
## dhcp-3.1.0-ldap-nosigpipe by Petter Reinholdtsen

# Fix LDAP code to avoid SIGPIPE when submitting requests to the LDAP
# server if the server disconnected the connection because of
# inactivity.  Fixes BTS request #559160.

@DPATCH@

--- dhcp3-3.1.0.orig/server/ldap.c  2009-12-20 22:12:47.000000000 +0100
+++ dhcp3-3.1.0/server/ldap.c       2009-12-20 22:20:24.000000000 +0100
@@ -1862,6 +1862,7 @@
   isc_result_t status;
   ldap_dn_node *curr;
   char buf[1024];
+  struct sigaction old, new;

   if (ldap_method == LDAP_METHOD_STATIC)
     return (0);
@@ -1887,9 +1888,22 @@
 #if defined (DEBUG_LDAP)
       log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
 #endif
+      /*
+       ** ldap_search_ext_s after the connection timed out
+       ** causes a SIGPIPE and dhcpd gets terminated,
+       ** since it doesn't handle it...
+       */
+
+      new.sa_flags   = 0;
+      new.sa_handler = SIG_IGN;
+      sigemptyset (&new.sa_mask);
+      sigaction (SIGPIPE, &new, &old);
+
       ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
                                NULL, NULL, NULL, 0, &res);

+      sigaction (SIGPIPE, &old, &new);
+
       if(ret == LDAP_SERVER_DOWN)
         {
           log_info ("LDAP server was down, trying to reconnect...");
========================================================================

If testing show that it solve the problem, please get a fix into
Debian/Lenny.

Happy hacking,
-- 
Petter Reinholdtsen


Reply to: