]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Ticket 20540 - clean ups for DHCP-DDNS work, add an change dropped in the
authorShawn Routhier <sar@isc.org>
Thu, 19 Nov 2009 23:49:57 +0000 (23:49 +0000)
committerShawn Routhier <sar@isc.org>
Thu, 19 Nov 2009 23:49:57 +0000 (23:49 +0000)
merge, arrange to handle callbacks from the socket code after we've deleted
the socket and deal with the quantum issue in the tasks.  This last will
be removed shortly as a better fix is now available.

RELNOTES
includes/omapip/omapip_p.h
omapip/connection.c
omapip/dispatch.c
omapip/isclib.c
util/bindlib.sh

index 91cd5cbbb724aa2298965b912b5f9e7b3425ef46..fb919172c720d5bbe1e46c0a0f4d960fab03299a 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -13,6 +13,19 @@ Processing the DHCP to DNS server transactions in an asyncrhonous fashion.
 The DHCP server or client can now continue with it's processing while
 awaiting replies from the DNS server.
 
+As part of the changes to support asynchronous DNS the DHCP code was
+modified to use the current BIND libraries and a small number of changes
+were made to the BIND libraries to support DHCP.  There is a bug in one
+of these changes that can cause an exception in a DHCP server.  This bug
+requires either failover or omapi to be in use and a number of events
+(timeouts, packet reception, packet transmision) to happen within the same
+scheduling interval.  As a work around the number of events required to
+trigger this issue has been increased though this may affect the responsivness
+of the DNS code under load.  A fix is being developed but needs
+to go into a BIND release.  Note that the bug is in a part of the BIND
+libraries that is only used by the DHCP code and does NOT affect any
+other part of the BIND code.
+
 There are a number of DHCPv6 limitations and features missing in this
 release, which will be addressed in the future:
 
index 465f8fd3f99dc473b5536ac9a61983ea83fa3cfb..f94644ac1b7fd9f335bdedd5741254e2c3ad20a8 100644 (file)
@@ -214,6 +214,7 @@ typedef struct __omapi_io_object {
        isc_result_t (*writer) (omapi_object_t *);
        isc_result_t (*reaper) (omapi_object_t *);
        isc_socket_t *fd;
+       isc_boolean_t closed; /* ISC_TRUE = closed, do not use */
 } omapi_io_object_t;
 
 typedef struct __omapi_generic_object {
index b32ee74815f7e7d0501e9c964d61b202e463885e..1149c520b82c40bbf60bf1ff869618d928243a95 100644 (file)
@@ -587,6 +587,15 @@ isc_result_t omapi_connection_connect (omapi_object_t *h)
        status = omapi_connection_connect_internal (h);
        if (status != ISC_R_SUCCESS)
                omapi_signal (h, "status", status);
+
+       /*
+        * Currently we use the INPROGRESS error to indicate that
+        * we want more from the socket.  In this case we have now connected
+        * and are trying to write to the socket for the first time.
+        */
+       if (status == ISC_R_INPROGRESS) 
+               return ISC_R_INPROGRESS;
+
        return ISC_R_SUCCESS;
 }
 
@@ -699,7 +708,7 @@ static isc_result_t omapi_connection_connect_internal (omapi_object_t *h)
 
        omapi_signal_in (h, "connect");
        omapi_addr_list_dereference (&c -> connect_list, MDL);
-       return ISC_R_SUCCESS;
+       return ISC_R_INPROGRESS;
 }
 
 /* Reaper function for connection - if the connection is completely closed,
index 887a337b10aed05634faa44339e31e50b1af2882..8ee274327c84be660bdf8ac2177eb02ecbf11617 100644 (file)
@@ -116,6 +116,12 @@ trigger_event(struct eventqueue **queue)
  * we can write more.  If we indicate we don't have more to write we need
  * to poke the library via isc_socket_fdwatchpoke.
  */
+
+/*
+ * sockdelete indicates if we are deleting the socket or leaving it in place
+ * 1 is delete, 0 is leave in place
+ */
+#define SOCKDELETE 1
 int
 omapi_iscsock_cb(isc_task_t   *task,
                 isc_socket_t *socket,
@@ -128,12 +134,40 @@ omapi_iscsock_cb(isc_task_t   *task,
        /* Get the current time... */
        gettimeofday (&cur_tv, (struct timezone *)0);
 
+       /* isc socket stuff */
+#if SOCKDELETE
+       /*
+        * walk through the io states list, if our object is on there
+        * service it.  if not ignore it.
+        */
+       for (obj = omapi_io_states.next;
+            (obj != NULL) && (obj->next != NULL);
+            obj = obj->next) {
+               if (obj == cbarg)
+                       break;
+       }
+       if (obj == NULL) {
+               return(0);
+       }
+#else
        /* Not much to be done if we have the wrong type of object. */
        if (((omapi_object_t *)cbarg) -> type != omapi_type_io_object) {
                log_fatal ("Incorrect object type, must be of type io_object");
        }
        obj = (omapi_io_object_t *)cbarg;
 
+       /*
+        * If the object is marked as closed don't try and process
+        * anything just indicate that we don't want any more.
+        *
+        * This should be a temporary fix until we arrange to properly
+        * close the socket.
+        */
+       if (obj->closed == ISC_TRUE) {
+               return(0);
+       }
+#endif   
+
        if ((flags == ISC_SOCKFDWATCH_READ) &&
            (obj->reader != NULL) &&
            (obj->inner != NULL)) {
@@ -189,6 +223,7 @@ isc_result_t omapi_register_io_object (omapi_object_t *h,
        status = omapi_io_allocate (&obj, MDL);
        if (status != ISC_R_SUCCESS)
                return status;
+       obj->closed = ISC_FALSE;  /* mark as open */
 
        status = omapi_object_reference (&obj -> inner, h, MDL);
        if (status != ISC_R_SUCCESS) {
@@ -259,11 +294,13 @@ isc_result_t omapi_register_io_object (omapi_object_t *h,
        return ISC_R_SUCCESS;
 }
 
-/* ReRegister an I/O handle so that we can do asynchronous I/O on it.
+/*
+ * ReRegister an I/O handle so that we can do asynchronous I/O on it.
  * If the handle doesn't exist we call the register routine to build it.
- * if it does exist we change the functions associated with it, and
+ * If it does exist we change the functions associated with it, and
  * repoke the fd code to make it happy.  Neither the objects nor the
- * fd are allowed to have changed. */
+ * fd are allowed to have changed.
+ */
 
 isc_result_t omapi_reregister_io_object (omapi_object_t *h,
                                         int (*readfd) (omapi_object_t *),
@@ -276,9 +313,11 @@ isc_result_t omapi_reregister_io_object (omapi_object_t *h,
                                                (omapi_object_t *))
 {
        omapi_io_object_t *obj;
+       int fd_flags = 0;
 
        if ((!h -> outer) || (h -> outer -> type != omapi_type_io_object)) {
-               /* If we don't have an object or if the type isn't what 
+               /*
+                * If we don't have an object or if the type isn't what 
                 * we expect do the normal registration (which will overwrite
                 * an incorrect type, that's what we did historically, may
                 * want to change that)
@@ -294,18 +333,31 @@ isc_result_t omapi_reregister_io_object (omapi_object_t *h,
 
        obj = (omapi_io_object_t *)h->outer;
 
-       obj -> readfd = readfd;
-       obj -> writefd = writefd;
-       obj -> reader = reader;
-       obj -> writer = writer;
-       obj -> reaper = reaper;
+       obj->readfd = readfd;
+       obj->writefd = writefd;
+       obj->reader = reader;
+       obj->writer = writer;
+       obj->reaper = reaper;
+
+       if (readfd) {
+               fd_flags |= ISC_SOCKFDWATCH_READ;
+       }
+
+       if (writefd) {
+               fd_flags |= ISC_SOCKFDWATCH_WRITE;
+       }
+
+       isc_socket_fdwatchpoke(obj->fd, fd_flags);
        
        return (ISC_R_SUCCESS);
 }
 
 isc_result_t omapi_unregister_io_object (omapi_object_t *h)
 {
-       omapi_io_object_t *p, *obj, *last, *ph;
+       omapi_io_object_t *obj, *ph;
+#if SOCKDELETE
+       omapi_io_object_t *p, *last; 
+#endif
 
        if (!h -> outer || h -> outer -> type != omapi_type_io_object)
                return DHCP_R_INVALIDARG;
@@ -313,6 +365,14 @@ isc_result_t omapi_unregister_io_object (omapi_object_t *h)
        ph = (omapi_io_object_t *)0;
        omapi_io_reference (&ph, obj, MDL);
 
+#if SOCKDELETE
+       /*
+        * For now we leave this out.  We can't clean up the isc socket
+        * structure cleanly yet so we need to leave the io object in place.
+        * By leaving it on the io states list we avoid it being freed.
+        * We also mark it as closed to avoid using it.
+        */
+
        /* remove from the list of I/O states */
         last = &omapi_io_states;
        for (p = omapi_io_states.next; p; p = p -> next) {
@@ -325,6 +385,7 @@ isc_result_t omapi_unregister_io_object (omapi_object_t *h)
        }
        if (obj -> next)
                omapi_io_dereference (&obj -> next, MDL);
+#endif
 
        if (obj -> outer) {
                if (obj -> outer -> inner == (omapi_object_t *)obj)
@@ -335,10 +396,16 @@ isc_result_t omapi_unregister_io_object (omapi_object_t *h)
        omapi_object_dereference (&obj -> inner, MDL);
        omapi_object_dereference (&h -> outer, MDL);
 
+#if SOCKDELETE
        /* remove isc socket associations */
        if (obj->fd != NULL) {
+               isc_socket_cancel(obj->fd, dhcp_gbl_ctx.task,
+                                 ISC_SOCKCANCEL_ALL);
                isc_socket_detach(&obj->fd);
        }
+#else
+       obj->closed = ISC_TRUE;
+#endif
 
        omapi_io_dereference (&ph, MDL);
        return ISC_R_SUCCESS;
index 3225096d27fd658644e6a9e9affa667c2f63ed46..59bba1ffddabddf099ea912e7c01cf2c026db948 100644 (file)
@@ -127,7 +127,16 @@ dhcp_context_create(void) {
        if (result != ISC_R_SUCCESS)
                goto cleanup;
 
-       result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task);
+       /*sar*/
+       /*
+        * We currently use a large number for quantum to get around
+        * an issue in the fdwatchpoke code that allows us to re-check
+        * a socket for reading or writing even if it already has a pending
+        * read or write.  This event causes an exception and stops the
+        * program.  When that code is fixed the quantum can be reduced.
+        */
+       result = isc_task_create(dhcp_gbl_ctx.taskmgr, 100,
+                                &dhcp_gbl_ctx.task);
        if (result != ISC_R_SUCCESS)
                goto cleanup;
 
index 482b13b322c1da0a229b01eb7c99cc65d9ae1b01..23cafef7f822625f90482aebb2cceeab20231416 100644 (file)
@@ -14,7 +14,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: bindlib.sh,v 1.4 2009/11/03 02:57:22 marka Exp $
+# $Id: bindlib.sh,v 1.5 2009/11/19 23:49:57 sar Exp $
 
 # Configure, build and install the bind export libraries for use by DHCP
 #
@@ -45,10 +45,12 @@ if test -z "$gmake"; then
 fi
 
 # Configure the export libraries
+# Currently disable the epoll and devpoll options as they don't interact
+# well with the DHCP code.
 cd $bindsrcdir
-./configure --without-openssl --without-libxml2 --enable-exportlib --enable-threads=no --with-export-includedir=$binddir/include --with-export-libdir=$binddir/lib > $binddir/configure.log
+./configure --disable-epoll --disable-devpoll --without-openssl --without-libxml2 --enable-exportlib --enable-threads=no --with-export-includedir=$binddir/include --with-export-libdir=$binddir/lib > $binddir/configure.log
 
-# Build the export librares
+# Build the export libraries
 cd lib/export
 MAKE=$gmake $gmake > $binddir/build.log