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:
* 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,
/* 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)) {
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) {
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 *),
(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)
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;
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) {
}
if (obj -> next)
omapi_io_dereference (&obj -> next, MDL);
+#endif
if (obj -> outer) {
if (obj -> outer -> inner == (omapi_object_t *)obj)
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;
# 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
#
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