summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Routhier <sar@isc.org>2009-10-14 02:14:23 +0000
committerShawn Routhier <sar@isc.org>2009-10-14 02:14:23 +0000
commit5ff75f34cd4c03368bb34bc2bca639146efe1c5e (patch)
tree5bb40fa9fa3d85f7187c7ec5a04c23ff78a39127
parentae1ece5ac2c2a04d9612b163a9bdda0d106f18cf (diff)
downloadisc-dhcp-5ff75f34cd4c03368bb34bc2bca639146efe1c5e.tar.gz
Fix hanlding of omapi io object during connection processing so we don't
release the memory while we are still using it.
-rw-r--r--RELNOTES5
-rw-r--r--includes/omapip/omapip.h6
-rw-r--r--omapip/connection.c20
-rw-r--r--omapip/dispatch.c44
4 files changed, 65 insertions, 10 deletions
diff --git a/RELNOTES b/RELNOTES
index 913c2818..79e3243d 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -59,6 +59,11 @@ suggested fixes to <dhcp-users@isc.org>.
- ./configure now checks to ensure the intX_t and u_intX_t types are defined,
correcting a compilation failure when using Sun's compiler.
+- Modified the handling of a connection to avoid releasing the omapi io
+ object for the connection while it is still in use. One symptom from
+ this error was a segfault when a failover secondary attempted to connect
+ to the failover primary if their clocks were not synchronized.
+
Changes since 4.0.2b1
- Fixed a bug where an OMAPI socket disconnection message would not result
diff --git a/includes/omapip/omapip.h b/includes/omapip/omapip.h
index 17181955..f40265a6 100644
--- a/includes/omapip/omapip.h
+++ b/includes/omapip/omapip.h
@@ -380,6 +380,12 @@ isc_result_t omapi_register_io_object (omapi_object_t *,
isc_result_t (*)(omapi_object_t *),
isc_result_t (*)(omapi_object_t *),
isc_result_t (*)(omapi_object_t *));
+isc_result_t omapi_reregister_io_object (omapi_object_t *,
+ int (*)(omapi_object_t *),
+ int (*)(omapi_object_t *),
+ isc_result_t (*)(omapi_object_t *),
+ isc_result_t (*)(omapi_object_t *),
+ isc_result_t (*)(omapi_object_t *));
isc_result_t omapi_unregister_io_object (omapi_object_t *);
isc_result_t omapi_dispatch (struct timeval *);
isc_result_t omapi_wait_for_completion (omapi_object_t *, struct timeval *);
diff --git a/omapip/connection.c b/omapip/connection.c
index ec6bc2ec..4d42b346 100644
--- a/omapip/connection.c
+++ b/omapip/connection.c
@@ -674,16 +674,16 @@ static isc_result_t omapi_connection_connect_internal (omapi_object_t *h)
(struct sockaddr *)&c -> local_addr, &sl) < 0) {
}
- /* Disconnect from I/O object, if any. */
- if (h -> outer)
- omapi_unregister_io_object (h);
-
- status = omapi_register_io_object (h,
- omapi_connection_readfd,
- omapi_connection_writefd,
- omapi_connection_reader,
- omapi_connection_writer,
- omapi_connection_reaper);
+ /* Reregister with the I/O object. If we don't already have an
+ I/O object this turns into a register call, otherwise we simply
+ modify the pointers in the I/O object. */
+
+ status = omapi_reregister_io_object (h,
+ omapi_connection_readfd,
+ omapi_connection_writefd,
+ omapi_connection_reader,
+ omapi_connection_writer,
+ omapi_connection_reaper);
if (status != ISC_R_SUCCESS) {
omapi_disconnect (h, 1);
diff --git a/omapip/dispatch.c b/omapip/dispatch.c
index f0f8c964..a806de2d 100644
--- a/omapip/dispatch.c
+++ b/omapip/dispatch.c
@@ -107,6 +107,50 @@ 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.
+ * 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
+ * repoke the fd code to make it happy. Neither the objects nor the
+ * fd are allowed to have changed. */
+
+isc_result_t omapi_reregister_io_object (omapi_object_t *h,
+ int (*readfd) (omapi_object_t *),
+ int (*writefd) (omapi_object_t *),
+ isc_result_t (*reader)
+ (omapi_object_t *),
+ isc_result_t (*writer)
+ (omapi_object_t *),
+ isc_result_t (*reaper)
+ (omapi_object_t *))
+{
+ omapi_io_object_t *obj;
+
+ if ((!h -> outer) || (h -> outer -> type != omapi_type_io_object)) {
+ /* 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)
+ */
+ return (omapi_register_io_object (h, readfd, writefd,
+ reader, writer, reaper));
+ }
+
+ /* We have an io object of the correct type, try to update it */
+ /*sar*/
+ /* Should we validate that the fd matches the previous one?
+ * It's suppossed to, that's a requirement, don't bother yet */
+
+ obj = (omapi_io_object_t *)h->outer;
+
+ obj -> readfd = readfd;
+ obj -> writefd = writefd;
+ obj -> reader = reader;
+ obj -> writer = writer;
+ obj -> reaper = reaper;
+
+ return (ISC_R_SUCCESS);
+}
+
isc_result_t omapi_unregister_io_object (omapi_object_t *h)
{
omapi_io_object_t *p, *obj, *last, *ph;