diff --git a/lib/omapi/Makefile.in b/lib/omapi/Makefile.in index fca43db662..e6b3f2cfbf 100644 --- a/lib/omapi/Makefile.in +++ b/lib/omapi/Makefile.in @@ -31,14 +31,14 @@ CDEFINES = CWARNINGS = # Alphabetically -OBJS = alloc.@O@ buffer.@O@ connection.@O@ dispatch.@O@ generic.@O@ \ - handle.@O@ listener.@O@ message.@O@ protocol.@O@ support.@O@ \ - version.@O@ +OBJS = buffer.@O@ connection.@O@ data.@O@ dispatch.@O@ generic.@O@ \ + handle.@O@ listener.@O@ message.@O@ object.@O@ protocol.@O@ \ + support.@O@ version.@O@ # Alphabetically -SRCS = alloc.c buffer.c connection.c dispatch.c generic.c \ - handle.c listener.c message.c protocol.c support.c \ - version.c +SRCS = buffer.c connection.c data.c dispatch.c generic.c \ + handle.c listener.c message.c object.c protocol.c \ + support.c version.c LIBS = @LIBS@ diff --git a/lib/omapi/alloc.c b/lib/omapi/alloc.c deleted file mode 100644 index 726e06520c..0000000000 --- a/lib/omapi/alloc.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (C) 1996, 1997, 1998, 1999 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* $Id: alloc.c,v 1.2 1999/11/02 04:01:30 tale Exp $ */ - -/* Principal Author: Ted Lemon */ - -/* - * Functions supporting memory allocation for the object management protocol. - */ -#include /* malloc, free */ -#include /* memset */ - -#include -#include - -#include - -void -omapi_object_reference(omapi_object_t **r, omapi_object_t *h, - const char *name) -{ - REQUIRE(r != NULL && *r == NULL); - REQUIRE(h != NULL); - - (void)name; /* Unused. */ - - *r = h; - h->refcnt++; -} - -void -omapi_object_dereference(omapi_object_t **h, const char *name) { - int outer_reference = 0; - int inner_reference = 0; - int handle_reference = 0; - int extra_references; - omapi_object_t *p; - - REQUIRE(h != NULL && *h != NULL); - REQUIRE((*h)->refcnt > 0); - - /* - * See if this object's inner object refers to it, but don't - * count this as a reference if we're being asked to free the - * reference from the inner object. - */ - if ((*h)->inner && (*h)->inner->outer && h != &((*h)->inner->outer)) - inner_reference = 1; - - /* - * Ditto for the outer object. - */ - if ((*h)->outer && (*h)->outer->inner && h != &((*h)->outer->inner)) - outer_reference = 1; - - /* - * Ditto for the outer object. The code below assumes that - * the only reason we'd get a dereference from the handle - * table is if this function does it - otherwise we'd have to - * traverse the handle table to find the address where the - * reference is stored and compare against that, and we don't - * want to do that if we can avoid it. - */ - if ((*h)->handle != 0) - handle_reference = 1; - - /* - * If we are getting rid of the last reference other than - * references to inner and outer objects, or from the handle - * table, then we must examine all the objects in either - * direction to see if they hold any non-inner, non-outer, - * non-handle-table references. If not, we need to free the - * entire chain of objects. - */ - if ((*h)->refcnt == - inner_reference + outer_reference + handle_reference + 1) { - if (inner_reference != 0 || - outer_reference != 0 || - handle_reference != 0) { - /* - * XXXTL we could check for a reference from the - * handle table here. - */ - extra_references = 0; - for (p = (*h)->inner; - p != NULL && extra_references == 0; - p = p->inner) { - extra_references += p->refcnt - 1; - if (p->inner != NULL) - --extra_references; - if (p->handle != 0) - --extra_references; - } - for (p = (*h)->outer; - p != NULL && extra_references == 0; - p = p->outer) { - extra_references += p->refcnt - 1; - if (p->outer != NULL) - --extra_references; - if (p->handle != 0) - --extra_references; - } - } else - extra_references = 0; - - if (extra_references == 0) { - if (inner_reference != 0) - omapi_object_dereference(&(*h)->inner->outer, - name); - if (outer_reference != 0) - omapi_object_dereference(&(*h)->outer->inner, - name); - if ((*h)->type->destroy != NULL) - (*((*h)->type->destroy))(*h, name); - free(*h); - } - } - *h = NULL; -} - -isc_result_t -omapi_buffer_new(omapi_buffer_t **h, const char *name) { - omapi_buffer_t *t; - - REQUIRE(h != NULL && *h == NULL); - - t = (omapi_buffer_t *)malloc(sizeof *t); - if (t == NULL) - return (ISC_R_NOMEMORY); - memset(t, 0, sizeof *t); - - omapi_buffer_reference(h, t, name); - - (*h)->head = sizeof((*h)->data) - 1; - - return (ISC_R_SUCCESS); -} - -void -omapi_buffer_reference(omapi_buffer_t **r, omapi_buffer_t *h, const char *name) -{ - REQUIRE(r != NULL && h != NULL); - REQUIRE(*r == NULL); - - (void)name; /* Unused. */ - - *r = h; - h->refcnt++; -} - -void -omapi_buffer_dereference(omapi_buffer_t **h, const char *name) { - REQUIRE(h != NULL && *h != NULL); - REQUIRE((*h)->refcnt > 0); - - (void)name; /* Unused. */ - - if (--(*h)->refcnt == 0) - free (*h); - *h = NULL; -} - -isc_result_t -omapi_typed_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) { - va_list l; - omapi_typed_data_t *new; - unsigned int len; - unsigned int val; - int intval; - char *s; - - REQUIRE(type == omapi_datatype_int || - type == omapi_datatype_string || - type == omapi_datatype_data || - type == omapi_datatype_object); - - va_start(l, type); - - /* - * Quiet bogus "might be used uninitialized in this function" warnings. - */ - val = 0; - intval = 0; - s = NULL; - - switch (type) { - case omapi_datatype_int: - len = OMAPI_TYPED_DATA_INT_LEN; - intval = va_arg(l, int); - break; - case omapi_datatype_string: - s = va_arg(l, char *); - val = strlen(s); - len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val; - break; - case omapi_datatype_data: - val = va_arg(l, unsigned int); - len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val; - break; - case omapi_datatype_object: - len = OMAPI_TYPED_DATA_OBJECT_LEN; - break; - default: - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unknown type in omapi_typed_data_new: %d\n", - type); - return (ISC_R_UNEXPECTED); - } - - new = malloc(len); - if (new == NULL) - return (ISC_R_NOMEMORY); - memset(new, 0, len); - - switch (type) { - case omapi_datatype_int: - new->u.integer = intval; - break; - case omapi_datatype_string: - memcpy(new->u.buffer.value, s, val); - new->u.buffer.len = val; - break; - case omapi_datatype_data: - new->u.buffer.len = val; - break; - case omapi_datatype_object: - omapi_object_reference(&new->u.object, - va_arg(l, omapi_object_t *), - "omapi_datatype_new"); - break; - } - new->type = type; - omapi_typed_data_reference(t, new, "omapi_typed_data_new"); - - return (ISC_R_SUCCESS); -} - -void -omapi_typed_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h, - const char *name) -{ - REQUIRE(r != NULL && h != NULL); - REQUIRE(*r != NULL); - - (void)name; /* Unused. */ - - *r = h; - h->refcnt++; -} - -void -omapi_typed_data_dereference(omapi_typed_data_t **h, const char *name) { - REQUIRE(h != NULL && *h != NULL); - REQUIRE((*h)->refcnt > 0); - - if (--((*h)->refcnt) <= 0) { - switch ((*h)->type) { - case omapi_datatype_int: - case omapi_datatype_string: - case omapi_datatype_data: - default: - break; - case omapi_datatype_object: - omapi_object_dereference(&(*h)->u.object, name); - break; - } - free(*h); - } - *h = NULL; -} - -isc_result_t -omapi_data_string_new(omapi_data_string_t **d, unsigned int len, - const char *name) -{ - omapi_data_string_t *new; - - new = malloc(OMAPI_DATA_STRING_EMPTY_SIZE + len); - if (new != NULL) - return (ISC_R_NOMEMORY); - memset(new, 0, OMAPI_DATA_STRING_EMPTY_SIZE); - new->len = len; - - omapi_data_string_reference(d, new, name); - - return (ISC_R_SUCCESS); -} - -void -omapi_data_string_reference(omapi_data_string_t **r, omapi_data_string_t *h, - const char *name) -{ - REQUIRE(r != NULL && h != NULL); - REQUIRE(*r == NULL); - - (void)name; /* Unused. */ - - *r = h; - h->refcnt++; -} - -void -omapi_data_string_dereference(omapi_data_string_t **h, const char *name) { - REQUIRE(h != NULL && *h != NULL); - REQUIRE((*h)->refcnt > 0); - - (void)name; /* Unused. */ - - if (--((*h)->refcnt) <= 0) - free (*h); - - *h = NULL; -} - -isc_result_t -omapi_value_new(omapi_value_t **d, const char *name) { - omapi_value_t *new; - - new = malloc(sizeof *new); - if (new != NULL) - return (ISC_R_NOMEMORY); - memset(new, 0, sizeof *new); - - omapi_value_reference(d, new, name); - - return (ISC_R_SUCCESS); -} - -void -omapi_value_reference(omapi_value_t **r, omapi_value_t *h, const char *name) { - REQUIRE(r != NULL && h != NULL); - REQUIRE(*r == NULL); - - (void)name; /* Unused. */ - - *r = h; - h->refcnt++; -} - -void -omapi_value_dereference(omapi_value_t **h, const char *name) { - REQUIRE(h != NULL && *h != NULL); - REQUIRE((*h)->refcnt > 0); - - (void)name; /* Unused. */ - - if (--((*h)->refcnt) <= 0) { - if ((*h)->name) - omapi_data_string_dereference(&(*h)->name, name); - if ((*h)->value) - omapi_typed_data_dereference(&(*h)->value, name); - free (*h); - } - *h = NULL; -} - diff --git a/lib/omapi/buffer.c b/lib/omapi/buffer.c index 4f2453072a..52212fb7c5 100644 --- a/lib/omapi/buffer.c +++ b/lib/omapi/buffer.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: buffer.c,v 1.2 1999/11/02 04:01:31 tale Exp $ */ +/* $Id: buffer.c,v 1.3 2000/01/04 20:04:37 tale Exp $ */ /* Principal Author: Ted Lemon */ @@ -28,160 +28,124 @@ #include #include +#include -#include +#include -/* - * Make sure that at least len bytes are in the input buffer, and if not, - * read enough bytes to make up the difference. - */ +void +omapi_connection_read(isc_task_t *task, isc_event_t *event) { + isc_buffer_t *buffer; + isc_socket_t *socket; + isc_socketevent_t *socketevent; + omapi_connection_object_t *connection; -isc_result_t -omapi_connection_reader(omapi_object_t *h) { - omapi_buffer_t *buffer; - isc_result_t result; - unsigned int read_len; - int read_status; - omapi_connection_object_t *c; - unsigned int bytes_to_read; + socket = event->sender; + socketevent = (isc_socketevent_t *)event; + connection = event->arg; - REQUIRE(h != NULL && h->type == omapi_type_connection); + buffer = ISC_LIST_HEAD(socketevent->bufferlist); - c = (omapi_connection_object_t *)h; + if (socketevent->result != ISC_R_SUCCESS) { + /* + * Abandon this socket. + */ + isc_socket_detach(&socket); + + /* XXXDCL nope, not right at all */ + ISC_LIST_UNLINK(socketevent->bufferlist, buffer, link); + isc_buffer_free(&buffer); + + isc_event_free(&event); + isc_task_shutdown(task); + return; + } + + connection->in_bytes += socketevent->n; + + /* XXXDCL more screwage */ + while (buffer != NULL) { + ISC_LIST_APPEND(connection->input_buffers, buffer, link); + buffer = ISC_LIST_NEXT(buffer, link); + } + + while (connection->bytes_needed <= connection->in_bytes) + omapi_signal(event->arg, "ready", connection); /* - * See if there are enough bytes. + * Queue up another recv task. */ - if (c->in_bytes >= OMAPI_BUFFER_SIZE - 1 && - c->in_bytes > c->bytes_needed) - return (ISC_R_SUCCESS); + isc_socket_recvv(socket, &connection->input_buffers, + connection->bytes_needed - connection->in_bytes, + task, omapi_connection_read, connection); - if (c->inbufs) { - for (buffer = c->inbufs; buffer->next; buffer = buffer->next) - ; - if (BUFFER_BYTES_FREE(buffer) == 0) { - result = omapi_buffer_new(&buffer->next, - "omapi_private_read"); - if (result != ISC_R_SUCCESS) - return (result); - buffer = buffer->next; - } + isc_event_free(&event); - } else { - result = omapi_buffer_new(&c->inbufs, "omapi_private_read"); - if (result != ISC_R_SUCCESS) - return (result); - buffer = c->inbufs; +} + +void +omapi_connection_written(isc_task_t *task, isc_event_t *event) { + isc_buffer_t *buffer; + isc_socket_t *socket; + isc_socketevent_t *socketevent; + omapi_connection_object_t *connection; + + socket = event->sender; + socketevent = (isc_socketevent_t *)event; + connection = event->arg; + + /* XXXDCL more screwage */ + buffer = ISC_LIST_HEAD(socketevent->bufferlist); + while (buffer != NULL) { + ISC_LIST_ENQUEUE(connection->output_buffers, buffer, link); + buffer = ISC_LIST_NEXT(buffer, link); + } + buffer = ISC_LIST_HEAD(connection->output_buffers); + + if (socketevent->result != ISC_R_SUCCESS) { + /* + * Abandon this socket. + */ + isc_socket_detach(&socket); + + /* XXXDCL nope, not right at all */ + ISC_LIST_UNLINK(connection->output_buffers, buffer, link); + isc_buffer_free(&buffer); + isc_event_free(&event); + isc_task_shutdown(task); + OBJECT_DEREF(&connection, "omapi_connection_written"); + return; } - bytes_to_read = BUFFER_BYTES_FREE(buffer); + connection->out_bytes -= socketevent->n; + isc_buffer_compact(buffer); - while (bytes_to_read > 0) { - if (buffer->tail > buffer->head) - read_len = sizeof(buffer->data) - buffer->tail; - else - read_len = buffer->head - buffer->tail; + if (connection->out_bytes > 0) + isc_socket_sendv(socket, &connection->output_buffers, task, + omapi_connection_written, connection); - read_status = read(c->socket, &buffer->data[buffer->tail], - read_len); - if (read_status < 0) { - if (errno == EWOULDBLOCK) - break; - else if (errno == EIO) - return (ISC_R_IOERROR); - else if (errno == ECONNRESET) { - omapi_disconnect(h, OMAPI_CLEAN_DISCONNECT); - return (ISC_R_SHUTTINGDOWN); - } else - return (ISC_R_UNEXPECTED); - } - - /* - * If we got a zero-length read, as opposed to EWOULDBLOCK, - * the remote end closed the connection. - */ - if (read_status == 0) { - omapi_disconnect(h, OMAPI_CLEAN_DISCONNECT); - return (ISC_R_SHUTTINGDOWN); - } - buffer->tail += read_status; - c->in_bytes += read_status; - if (buffer->tail == sizeof(buffer->data)) - buffer->tail = 0; - /* - * Comparison between signed and unsigned. - * The cast is ok because read_status < 0 was checked above. - */ - if ((unsigned int)read_status < read_len) - break; - bytes_to_read -= read_status; - } - - if (c->bytes_needed <= c->in_bytes) - omapi_signal(h, "ready", c); - - return (ISC_R_SUCCESS); + return; } /* * Put some bytes into the output buffer for a connection. */ - isc_result_t -omapi_connection_copyin(omapi_object_t *h, const unsigned char *bufp, +omapi_connection_copyin(omapi_object_t *h, unsigned char *bufp, unsigned int len) { - omapi_buffer_t *buffer; - isc_result_t result; - unsigned int bytes_copied = 0; - unsigned int copy_len; - omapi_connection_object_t *c; + omapi_connection_object_t *connection; + isc_buffer_t *obuffer; REQUIRE(h != NULL && h->type == omapi_type_connection); - c = (omapi_connection_object_t *)h; + connection = (omapi_connection_object_t *)h; - if (c->outbufs) { - for (buffer = c->outbufs; - buffer->next; buffer = buffer->next) - ; - } else { - result = omapi_buffer_new(&c->outbufs, - "omapi_private_buffer_copyin"); - if (result != ISC_R_SUCCESS) - return (result); - buffer = c->outbufs; - } + obuffer = ISC_LIST_HEAD(connection->output_buffers); + /* XXXDCL check for space first */ + isc_buffer_putmem(obuffer, bufp, len); - while (bytes_copied < len) { - /* - * If there is no space available in this buffer, - * allocate a new one. - */ - if (BUFFER_BYTES_FREE (buffer) == 0) { - result = omapi_buffer_new(&buffer->next, - "omapi_private_buffer_copyin"); - if (result != ISC_R_SUCCESS) - return (result); - buffer = buffer->next; - } + connection->out_bytes += len; - if (buffer->tail > buffer->head) - copy_len = sizeof(buffer->data) - buffer->tail; - else - copy_len = buffer->head - buffer->tail; - - if (copy_len > (len - bytes_copied)) - copy_len = len - bytes_copied; - - memcpy (&buffer->data[buffer->tail], - &bufp[bytes_copied], copy_len); - buffer->tail += copy_len; - c->out_bytes += copy_len; - bytes_copied += copy_len; - if (buffer->tail == sizeof(buffer->data)) - buffer->tail = 0; - } return (ISC_R_SUCCESS); } @@ -194,185 +158,24 @@ isc_result_t omapi_connection_copyout(unsigned char *buf, omapi_object_t *h, unsigned int size) { - unsigned int bytes_remaining; - unsigned int bytes_this_copy; - unsigned int first_byte; - omapi_buffer_t *buffer; - unsigned char *bufp; - omapi_connection_object_t *c; + omapi_connection_object_t *connection; + isc_buffer_t *ibuffer; REQUIRE(h != NULL && h->type == omapi_type_connection); - c = (omapi_connection_object_t *)h; + connection = (omapi_connection_object_t *)h; - if (size > c->in_bytes) + if (size > connection->in_bytes) return (ISC_R_NOMORE); - bufp = buf; - bytes_remaining = size; - buffer = c->inbufs; + + ibuffer = ISC_LIST_HEAD(connection->input_buffers); - while (bytes_remaining > 0) { - if (buffer == NULL) - return (ISC_R_UNEXPECTED); + (void)memcpy(buf, ibuffer->base, size); + isc_buffer_forward(ibuffer, size); + isc_buffer_compact(ibuffer); + + connection->in_bytes -= size; - if (BYTES_IN_BUFFER(buffer) != 0) { - if (buffer->head == sizeof(buffer->data) - 1) - first_byte = 0; - else - first_byte = buffer->head + 1; - - if (first_byte > buffer->tail) - bytes_this_copy = sizeof(buffer->data) - - first_byte; - else - bytes_this_copy = - buffer->tail - first_byte; - - if (bytes_this_copy > bytes_remaining) - bytes_this_copy = bytes_remaining; - if (bufp != NULL) { - memcpy(bufp, &buffer->data[first_byte], - bytes_this_copy); - bufp += bytes_this_copy; - } - bytes_remaining -= bytes_this_copy; - buffer->head = first_byte + bytes_this_copy - 1; - c->in_bytes -= bytes_this_copy; - } - - if (BYTES_IN_BUFFER (buffer) == 0) - buffer = buffer->next; - } - - /* - * Get rid of any input buffers that we emptied. - */ - buffer = NULL; - while (c->inbufs != NULL && BYTES_IN_BUFFER(c->inbufs) == 0) { - if (c->inbufs->next != NULL) { - omapi_buffer_reference(&buffer, - c->inbufs->next, - "omapi_private_buffer_copyout"); - omapi_buffer_dereference(&c->inbufs->next, - "omapi_private_buffer_copyout"); - } - omapi_buffer_dereference(&c->inbufs, - "omapi_private_buffer_copyout"); - if (buffer != NULL) { - omapi_buffer_reference(&c->inbufs, buffer, - "omapi_private_buffer_copyout"); - omapi_buffer_dereference(&buffer, - "omapi_private_buffer_copyout"); - } - } - return (ISC_R_SUCCESS); -} - -isc_result_t -omapi_connection_writer(omapi_object_t *h) { - int bytes_written; - unsigned int bytes_this_write; - unsigned int first_byte; - omapi_buffer_t *buffer; - omapi_connection_object_t *c; - - REQUIRE(h != NULL && h->type == omapi_type_connection); - - c = (omapi_connection_object_t *)h; - - /* - * Already flushed. - */ - if (c->out_bytes == 0) - return (ISC_R_SUCCESS); - - buffer = c->outbufs; - - while (c->out_bytes > 0) { - if (buffer == NULL) - return (ISC_R_UNEXPECTED); - - if (BYTES_IN_BUFFER (buffer) != 0) { - if (buffer->head == sizeof(buffer->data) - 1) - first_byte = 0; - else - first_byte = buffer->head + 1; - - if (first_byte > buffer->tail) - bytes_this_write = (sizeof(buffer->data) - - first_byte); - else - bytes_this_write = buffer->tail - first_byte; - - bytes_written = write(c->socket, - &buffer->data[first_byte], - bytes_this_write); - /* - * If the write failed with EWOULDBLOCK or we wrote - * zero bytes, a further write would block, so we have - * flushed as much as we can for now. Other errors - * are really errors. - */ - if (bytes_written < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) - return (ISC_R_SUCCESS); - else if (errno == EPIPE) - return (ISC_R_NOCONN); - else if (errno == EFBIG || errno == EDQUOT) - return (ISC_R_NORESOURCES); - else if (errno == ENOSPC) - return (ISC_R_NOSPACE); - else if (errno == EIO) - return (ISC_R_IOERROR); - else if (errno == ECONNRESET) - return (ISC_R_SHUTTINGDOWN); - else - return (ISC_R_UNEXPECTED); - } - if (bytes_written == 0) - return (ISC_R_SUCCESS); - - buffer->head = first_byte + bytes_written - 1; - c->out_bytes -= bytes_written; - - /* - * If we didn't finish out the write, we filled the - * O.S. output buffer and a further write would block, - * so stop trying to flush now. - * - * bytes_written was already checked to not be < 0, - * so the cast is ok. - */ - - if ((unsigned int)bytes_written != bytes_this_write) - return (ISC_R_SUCCESS); - } - - if (BYTES_IN_BUFFER (buffer) == 0) - buffer = buffer->next; - } - - /* - * Get rid of any output buffers we emptied. - */ - buffer = NULL; - while (c->outbufs != NULL && BYTES_IN_BUFFER(c->outbufs) == 0) { - if (c->outbufs->next != NULL) { - omapi_buffer_reference(&buffer, c->outbufs->next, - "omapi_private_flush"); - omapi_buffer_dereference(&c->outbufs->next, - "omapi_private_flush"); - } - - omapi_buffer_dereference(&c->outbufs, "omapi_private_flush"); - - if (buffer != NULL) { - omapi_buffer_reference(&c->outbufs, buffer, - "omapi_private_flush"); - omapi_buffer_dereference(&buffer, - "omapi_private_flush"); - } - } return (ISC_R_SUCCESS); } @@ -489,7 +292,7 @@ omapi_connection_put_name(omapi_object_t *c, const char *name) { if (result != ISC_R_SUCCESS) return (result); - return (omapi_connection_copyin(c, (const unsigned char *)name, len)); + return (omapi_connection_copyin(c, (char *)name, len)); } isc_result_t @@ -505,9 +308,7 @@ omapi_connection_put_string(omapi_object_t *c, const char *string) { result = omapi_connection_put_uint32(c, len); if (result == ISC_R_SUCCESS && len > 0) - result = omapi_connection_copyin(c, - (const unsigned char *)string, - len); + result = omapi_connection_copyin(c, (char *)string, len); return (result); } diff --git a/lib/omapi/connection.c b/lib/omapi/connection.c index 78bef9fed3..fafd6e1994 100644 --- a/lib/omapi/connection.c +++ b/lib/omapi/connection.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: connection.c,v 1.2 1999/11/02 04:01:32 tale Exp $ */ +/* $Id: connection.c,v 1.3 2000/01/04 20:04:37 tale Exp $ */ /* Principal Author: Ted Lemon */ @@ -25,139 +25,190 @@ #include #include /* F_SETFL, O_NONBLOCK */ #include /* NULL */ -#include /* malloc, free */ #include /* memset */ #include /* close */ #include #include -#include +#include -isc_result_t -omapi_connect(omapi_object_t *c, const char *server_name, int port) { +/* + * Swiped from bin/tests/sdig.c. + */ +static isc_result_t +get_address(const char *hostname, in_port_t port, isc_sockaddr_t *sockaddr) { + struct in_addr in4; + struct in6_addr in6; struct hostent *he; - int hix; - isc_result_t result; - omapi_connection_object_t *obj; - int flag; - obj = (omapi_connection_object_t *)malloc(sizeof(*obj)); + /* + * Is this an IPv6 numeric address? + */ + if (omapi_ipv6 && inet_pton(AF_INET6, hostname, &in6) == 1) + isc_sockaddr_fromin6(sockaddr, &in6, port); + + /* + * What about an IPv4 numeric address? + */ + else if (inet_pton(AF_INET, hostname, &in4) == 1) + isc_sockaddr_fromin(sockaddr, &in4, port); + + else { + /* + * Look up the host name. + */ + he = gethostbyname(hostname); + if (he == NULL) + return (ISC_R_NOTFOUND); + + INSIST(he->h_addrtype == AF_INET); + isc_sockaddr_fromin(sockaddr, + (struct in_addr *)(he->h_addr_list[0]), + port); + } + + return (ISC_R_SUCCESS); +} + +/* + * This is the function that is called when a CONNECT event is posted on + * the socket as a result of isc_socket_connect. + */ +static void +omapi_connection_connect(isc_task_t *task, isc_event_t *event) { + isc_result_t result; + isc_socket_connev_t *connect_event; + omapi_connection_object_t *connection; + + ENSURE(event->sender == connection->socket); + + connect_event = (isc_socket_connev_t *)event; + if (connect_event->result != ISC_R_SUCCESS) { + isc_socket_detach(&connection->socket); + isc_event_free(&event); + isc_task_shutdown(task); + return; + } + + connection = event->arg; + + result = isc_socket_getpeername(connection->socket, + &connection->remote_addr); + if (result != ISC_R_SUCCESS) { + OBJECT_DEREF(&connection, "omapi_connection_connect"); + return; + } + + result = isc_socket_getsockname(connection->socket, + &connection->local_addr); + if (result != ISC_R_SUCCESS) { + OBJECT_DEREF(&connection, "omapi_connection_connect"); + return; + } + + connection->state = omapi_connection_connected; + + isc_event_free(&event); + + return; +} + +/* + * Make an outgoing connection to an OMAPI server. + */ +isc_result_t +omapi_connection_toserver(omapi_object_t *c, const char *server_name, int port) +{ + isc_result_t result; + isc_buffer_t *ibuffer, *obuffer; + isc_task_t *task; + isc_sockaddr_t sockaddr; + omapi_connection_object_t *obj; +#if 0 /*XXXDCL*/ + int flag; +#endif + + result = get_address(server_name, port, &sockaddr); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * Prepare the task that will wait for the connection to be made. + */ + task = NULL; + result = isc_task_create(omapi_taskmgr, NULL, 0, &task); + if (result != ISC_R_SUCCESS) + return (result); + + ibuffer = NULL; + result = isc_buffer_allocate(omapi_mctx, &ibuffer, OMAPI_BUFFER_SIZE, + ISC_BUFFERTYPE_BINARY); + if (result != ISC_R_SUCCESS) + return (result); + + obuffer = NULL; + result = isc_buffer_allocate(omapi_mctx, &obuffer, OMAPI_BUFFER_SIZE, + ISC_BUFFERTYPE_BINARY); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * XXXDCL on errors I need to also blast the task and buffers. + */ + + /* + * Create a new connection object. + */ + obj = isc_mem_get(omapi_mctx, sizeof(*obj)); if (obj == NULL) return (ISC_R_NOMEMORY); memset(obj, 0, sizeof(*obj)); obj->refcnt = 1; + obj->task = task; obj->type = omapi_type_connection; - omapi_object_reference(&c->outer, (omapi_object_t *)obj, - "omapi_protocol_connect"); - - omapi_object_reference(&obj->inner, c, "omapi_protocol_connect"); + ISC_LIST_INIT(obj->input_buffers); + ISC_LIST_APPEND(obj->input_buffers, ibuffer, link); + ISC_LIST_INIT(obj->output_buffers); + ISC_LIST_APPEND(obj->output_buffers, obuffer, link); /* - * Set up all the constants in the address. + * Tie the new connection object to the protocol object. */ - obj->remote_addr.sin_port = htons(port); - - /* - * First try for a numeric address, since that's easier to check. - */ - if (inet_aton(server_name, &obj->remote_addr.sin_addr) == 0) { - /* - * If we didn't get a numeric address, try for a domain - * name. It's okay for this call to block. - */ - he = gethostbyname(server_name); - if (he == NULL) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_connect"); - return (ISC_R_NOTFOUND); - } - hix = 1; - memcpy (&obj->remote_addr.sin_addr, - he->h_addr_list[0], - sizeof(obj->remote_addr.sin_addr)); - } else - he = NULL; - -#ifdef ISC_NET_HAVESALEN - obj->remote_addr.sin_len = sizeof(struct sockaddr_in); -#endif - obj->remote_addr.sin_family = AF_INET; - memset(&(obj->remote_addr.sin_zero), 0, - sizeof(obj->remote_addr.sin_zero)); + OBJECT_REF(&c->outer, obj, "omapi_connection_toserver"); + OBJECT_REF(&obj->inner, c, "omapi_connection_toserver"); /* * Create a socket on which to communicate. */ - obj->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (obj->socket < 0) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_connect"); - if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS) - return (ISC_R_NORESOURCES); - return (ISC_R_UNEXPECTED); + result = isc_socket_create(omapi_socketmgr, isc_sockaddr_pf(&sockaddr), + isc_sockettype_tcp, &obj->socket); + if (result != ISC_R_SUCCESS) { + /* XXXDCL this call and later will not free the connection obj + * because it has two refcnts, one for existing plus one + * for the tie to h->outer. This does not seem right to me. + */ + OBJECT_DEREF(&obj, "omapi_connection_toserver"); + return (result); } +#if 0 /*XXXDCL*/ /* * Set the SO_REUSEADDR flag (this should not fail). */ flag = 1; if (setsockopt(obj->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)) < 0) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_connect"); + OBJECT_DEREF(&obj, "omapi_connect"); return (ISC_R_UNEXPECTED); } +#endif - /* - * Try to connect to the one IP address we were given, or any of - * the IP addresses listed in the host's A RR. - */ - while (connect(obj->socket, ((struct sockaddr *)&obj->remote_addr), - sizeof(obj->remote_addr)) < 0) { - if (he == NULL || he->h_addr_list[hix] == NULL) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_connect"); - if (errno == ECONNREFUSED) - return (ISC_R_CONNREFUSED); - if (errno == ENETUNREACH) - return (ISC_R_NETUNREACH); - return (ISC_R_UNEXPECTED); - } - memcpy(&obj->remote_addr.sin_addr, he->h_addr_list[hix++], - sizeof(obj->remote_addr.sin_addr)); - } - - obj->state = omapi_connection_connected; - - /* - * I don't know why this would fail, so I'm tempted not to test - * the return value. - */ - hix = sizeof(obj->local_addr); - if (getsockname(obj->socket, (struct sockaddr *)&obj->local_addr, - &hix) < 0) - result = ISC_R_UNEXPECTED; - else - result = ISC_R_SUCCESS; - - if (result == ISC_R_SUCCESS) - if (fcntl(obj->socket, F_SETFL, O_NONBLOCK) < 0) - result = ISC_R_UNEXPECTED; - - if (result == ISC_R_SUCCESS) - result = omapi_register_io_object((omapi_object_t *)obj, - omapi_connection_readfd, - omapi_connection_writefd, - omapi_connection_reader, - omapi_connection_writer, - omapi_connection_reaper); - + result = isc_socket_connect(obj->socket, &sockaddr, task, + omapi_connection_connect, obj); if (result != ISC_R_SUCCESS) - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_connect"); - + OBJECT_DEREF(&obj, "omapi_connection_toserver"); return (result); } @@ -168,21 +219,21 @@ omapi_connect(omapi_object_t *c, const char *server_name, int port) { */ void -omapi_disconnect(omapi_object_t *h, isc_boolean_t force) { - omapi_connection_object_t *c; +omapi_disconnect(omapi_object_t *generic, isc_boolean_t force) { + omapi_connection_object_t *connection; - REQUIRE(h != NULL); + REQUIRE(generic != NULL); - c = (omapi_connection_object_t *)h; + connection = (omapi_connection_object_t *)generic; - REQUIRE(c->type == omapi_type_connection); + REQUIRE(connection->type == omapi_type_connection); if (! force) { /* * If we're already disconnecting, we don't have to do * anything. */ - if (c->state == omapi_connection_disconnecting) + if (connection->state == omapi_connection_disconnecting) return; /* @@ -191,86 +242,50 @@ omapi_disconnect(omapi_object_t *h, isc_boolean_t force) { * the shutdown succeeds, and we still have bytes left to * write, defer closing the socket until that's done. */ - if (shutdown(c->socket, SHUT_RD) == 0) { - if (c->out_bytes > 0) { - c->state = omapi_connection_disconnecting; - return; - } + if (connection->out_bytes > 0) { +#if 0 /*XXXDCL*/ + isc_socket_shutdown(connection->socket, + ISC_SOCKSHUT_RECV); +#else + isc_socket_cancel(connection->socket, NULL, + ISC_SOCKCANCEL_RECV); +#endif + connection->state = omapi_connection_disconnecting; + return; } } - close(c->socket); - c->state = omapi_connection_closed; + isc_task_shutdown(connection->task); + connection->state = omapi_connection_closed; /* * Disconnect from I/O object, if any. */ - if (h->outer != NULL) - omapi_object_dereference(&h->outer, "omapi_disconnect"); + if (connection->outer != NULL) + OBJECT_DEREF(&connection->outer, "omapi_disconnect"); /* * If whatever created us registered a signal handler, send it * a disconnect signal. */ - omapi_signal(h, "disconnect", h); + omapi_signal(generic, "disconnect", generic); } isc_result_t -omapi_connection_require(omapi_object_t *h, unsigned int bytes) { - omapi_connection_object_t *c; +omapi_connection_require(omapi_object_t *generic, unsigned int bytes) { + omapi_connection_object_t *connection; - REQUIRE(h != NULL && h->type == omapi_type_connection); + REQUIRE(generic != NULL && generic->type == omapi_type_connection); - c = (omapi_connection_object_t *)h; + connection = (omapi_connection_object_t *)generic; - c->bytes_needed = bytes; - if (c->bytes_needed <= c->in_bytes) + connection->bytes_needed = bytes; + if (connection->bytes_needed <= connection->in_bytes) return (ISC_R_SUCCESS); return (ISC_R_NOTYET); } -/* - * Return the socket on which the dispatcher should wait for readiness - * to read, for a connection object. If we already have more bytes than - * we need to do the next thing, and we have at least a single full input - * buffer, then don't indicate that we're ready to read. - */ -int -omapi_connection_readfd(omapi_object_t *h) { - omapi_connection_object_t *c; - - REQUIRE(h != NULL && h->type == omapi_type_connection); - - c = (omapi_connection_object_t *)h; - - if (c->state != omapi_connection_connected) - return (-1); - if (c->in_bytes >= OMAPI_BUFFER_SIZE - 1 && - c->in_bytes > c->bytes_needed) - return (-1); - return (c->socket); -} - -/* - * Return the socket on which the dispatcher should wait for readiness - * to write, for a connection object. If there are no bytes buffered - * for writing, then don't indicate that we're ready to write. - */ -int -omapi_connection_writefd(omapi_object_t *h) { - omapi_connection_object_t *c; - - REQUIRE(h != NULL && h->type == omapi_type_connection); - - c = (omapi_connection_object_t *)h; - - if (c->out_bytes) - return (c->socket); - else - return (-1); -} - /* * Reaper function for connection - if the connection is completely closed, * reap it. If it's in the disconnecting state, there were bytes left @@ -329,7 +344,7 @@ omapi_connection_destroy(omapi_object_t *h, const char *name) { omapi_disconnect(h, OMAPI_FORCE_DISCONNECT); if (c->listener != NULL) - omapi_object_dereference(&c->listener, name); + OBJECT_DEREF(&c->listener, name); } isc_result_t diff --git a/lib/omapi/data.c b/lib/omapi/data.c new file mode 100644 index 0000000000..bdb5b30821 --- /dev/null +++ b/lib/omapi/data.c @@ -0,0 +1,227 @@ +/* + * Copyright (C) 1996, 1997, 1998, 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* $Id: data.c,v 1.1 2000/01/04 20:04:37 tale Exp $ */ + +/* Principal Author: Ted Lemon */ + +/* + * Functions supporting memory allocation for the object management protocol. + */ +#include /* memset */ + +#include +#include + +#include + +isc_result_t +omapi_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) { + va_list l; + omapi_typed_data_t *new; + unsigned int len; + unsigned int val; + int intval; + char *s; + + REQUIRE(type == omapi_datatype_int || + type == omapi_datatype_string || + type == omapi_datatype_data || + type == omapi_datatype_object); + + va_start(l, type); + + /* + * Quiet bogus "might be used uninitialized in this function" warnings. + */ + val = 0; + intval = 0; + s = NULL; + + switch (type) { + case omapi_datatype_int: + len = OMAPI_TYPED_DATA_INT_LEN; + intval = va_arg(l, int); + break; + case omapi_datatype_string: + s = va_arg(l, char *); + val = strlen(s); + len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val; + break; + case omapi_datatype_data: + val = va_arg(l, unsigned int); + len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val; + break; + case omapi_datatype_object: + len = OMAPI_TYPED_DATA_OBJECT_LEN; + break; + default: + UNEXPECTED_ERROR(__FILE__, __LINE__, + "unknown type in omapi_data_new: %d\n", + type); + return (ISC_R_UNEXPECTED); + } + + new = isc_mem_get(omapi_mctx, len); + if (new == NULL) + return (ISC_R_NOMEMORY); + memset(new, 0, len); + + switch (type) { + case omapi_datatype_int: + new->u.integer = intval; + break; + case omapi_datatype_string: + memcpy(new->u.buffer.value, s, val); + new->u.buffer.len = val; + break; + case omapi_datatype_data: + new->u.buffer.len = val; + break; + case omapi_datatype_object: + OBJECT_REF(&new->u.object, va_arg(l, omapi_object_t *), + "omapi_datatype_new"); + break; + } + new->type = type; + omapi_data_reference(t, new, "omapi_data_new"); + + return (ISC_R_SUCCESS); +} + +void +omapi_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h, + const char *name) +{ + REQUIRE(r != NULL && h != NULL); + REQUIRE(*r != NULL); + + (void)name; /* Unused. */ + + *r = h; + h->refcnt++; +} + +void +omapi_data_dereference(omapi_typed_data_t **h, const char *name) { + REQUIRE(h != NULL && *h != NULL); + REQUIRE((*h)->refcnt > 0); + + if (--((*h)->refcnt) <= 0) { + switch ((*h)->type) { + case omapi_datatype_int: + case omapi_datatype_string: + case omapi_datatype_data: + default: + break; + case omapi_datatype_object: + OBJECT_DEREF(&(*h)->u.object, name); + break; + } + isc_mem_put(omapi_mctx, *h, sizeof(*h)); + } + *h = NULL; +} + +isc_result_t +omapi_data_newstring(omapi_data_string_t **d, unsigned int len, + const char *name) +{ + omapi_data_string_t *new; + + new = isc_mem_get(omapi_mctx, OMAPI_DATA_STRING_EMPTY_SIZE + len); + if (new != NULL) + return (ISC_R_NOMEMORY); + memset(new, 0, OMAPI_DATA_STRING_EMPTY_SIZE); + new->len = len; + + omapi_data_stringreference(d, new, name); + + return (ISC_R_SUCCESS); +} + +void +omapi_data_stringreference(omapi_data_string_t **r, omapi_data_string_t *h, + const char *name) +{ + REQUIRE(r != NULL && h != NULL); + REQUIRE(*r == NULL); + + (void)name; /* Unused. */ + + *r = h; + h->refcnt++; +} + +void +omapi_data_stringdereference(omapi_data_string_t **h, const char *name) { + REQUIRE(h != NULL && *h != NULL); + REQUIRE((*h)->refcnt > 0); + + (void)name; /* Unused. */ + + if (--((*h)->refcnt) <= 0) + isc_mem_put(omapi_mctx, *h, + OMAPI_DATA_STRING_EMPTY_SIZE + (*h)->len); + + *h = NULL; +} + +isc_result_t +omapi_data_newvalue(omapi_value_t **d, const char *name) { + omapi_value_t *new; + + new = isc_mem_get(omapi_mctx, sizeof(*new)); + if (new != NULL) + return (ISC_R_NOMEMORY); + memset(new, 0, sizeof *new); + + omapi_data_valuereference(d, new, name); + + return (ISC_R_SUCCESS); +} + +void +omapi_data_valuereference(omapi_value_t **r, omapi_value_t *h, + const char *name) +{ + REQUIRE(r != NULL && h != NULL); + REQUIRE(*r == NULL); + + (void)name; /* Unused. */ + + *r = h; + h->refcnt++; +} + +void +omapi_data_valuedereference(omapi_value_t **h, const char *name) { + REQUIRE(h != NULL && *h != NULL); + REQUIRE((*h)->refcnt > 0); + + (void)name; /* Unused. */ + + if (--((*h)->refcnt) <= 0) { + if ((*h)->name != NULL) + omapi_data_stringdereference(&(*h)->name, name); + if ((*h)->value != NULL) + omapi_data_dereference(&(*h)->value, name); + isc_mem_put(omapi_mctx, *h, sizeof(*h)); + } + *h = NULL; +} + diff --git a/lib/omapi/dispatch.c b/lib/omapi/dispatch.c index 908a94c0f8..a43f992f59 100644 --- a/lib/omapi/dispatch.c +++ b/lib/omapi/dispatch.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: dispatch.c,v 1.2 1999/11/02 04:01:32 tale Exp $ */ +/* $Id: dispatch.c,v 1.3 2000/01/04 20:04:38 tale Exp $ */ /* Principal Author: Ted Lemon */ @@ -23,13 +23,12 @@ * I/O dispatcher. */ #include /* NULL */ -#include /* malloc, free */ #include /* memset */ #include #include -#include +#include typedef struct omapi_io_object { OMAPI_OBJECT_PREAMBLE; @@ -50,80 +49,32 @@ typedef struct omapi_waiter_object { static omapi_io_object_t omapi_io_states; isc_uint32_t cur_time; -/* - * Register an I/O handle so that we can do asynchronous I/O on it. - */ - isc_result_t -omapi_register_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, *p; - +omapi_dispatch(struct timeval *t) { +#if 0 /*XXXDCL*/ + return (omapi_wait_for_completion((omapi_object_t *)&omapi_io_states, + t)); +#endif /* - * omapi_io_states is a static object. If its reference count - * is zero, this is the first I/O handle to be registered, so - * we need to initialize it. Because there is no inner or outer - * pointer on this object, and we're setting its refcnt to 1, it - * will never be freed. + * XXXDCL sleep forever? The socket thread will be doing all the work. */ - if (omapi_io_states.refcnt == 0) { - omapi_io_states.refcnt = 1; - omapi_io_states.type = omapi_type_io_object; - } - - obj = (omapi_io_object_t *)malloc(sizeof(*obj)); - if (obj == NULL) - return (ISC_R_NOMEMORY); - memset(obj, 0, sizeof(*obj)); - - obj->refcnt = 1; - obj->type = omapi_type_io_object; - - omapi_object_reference(&obj->inner, h, "omapi_register_io_object"); - omapi_object_reference(&h->outer, (omapi_object_t *)obj, - "omapi_register_io_object"); - - /* - * Find the last I/O state, if there are any. - */ - for (p = omapi_io_states.next; p != NULL && p->next; p = p->next) - ; - if (p != NULL) - p->next = obj; - else - omapi_io_states.next = obj; - - obj->readfd = readfd; - obj->writefd = writefd; - obj->reader = reader; - obj->writer = writer; - obj->reaper = reaper; + select(0, NULL, NULL, NULL, t ? t : NULL); return (ISC_R_SUCCESS); } -isc_result_t -omapi_dispatch(struct timeval *t) { - return (omapi_wait_for_completion((omapi_object_t *)&omapi_io_states, - t)); -} isc_result_t -omapi_wait_for_completion (omapi_object_t *object, struct timeval *t) { +omapi_wait_for_completion(omapi_object_t *object, struct timeval *t) { isc_result_t result; omapi_waiter_object_t *waiter; omapi_object_t *inner; if (object != NULL) { - waiter = malloc(sizeof(*waiter)); + waiter = isc_mem_get(omapi_mctx, sizeof(*waiter)); if (waiter == NULL) return (ISC_R_NOMEMORY); - memset (waiter, 0, sizeof(*waiter)); + memset(waiter, 0, sizeof(*waiter)); waiter->refcnt = 1; waiter->type = omapi_type_waiter; @@ -135,10 +86,8 @@ omapi_wait_for_completion (omapi_object_t *object, struct timeval *t) { inner = inner->inner) ; - omapi_object_reference(&waiter->outer, inner, - "omapi_wait_for_completion"); - omapi_object_reference(&inner->inner, (omapi_object_t *)waiter, - "omapi_wait_for_completion"); + OBJECT_REF(&waiter->outer, inner, "omapi_wait_for_completion"); + OBJECT_REF(&inner->inner, waiter, "omapi_wait_for_completion"); } else waiter = NULL; @@ -150,22 +99,18 @@ omapi_wait_for_completion (omapi_object_t *object, struct timeval *t) { if (waiter->outer != NULL) { if (waiter->outer->inner != NULL) { - omapi_object_dereference(&waiter->outer->inner, - "omapi_wait_for_completion"); + OBJECT_DEREF(&waiter->outer->inner, + "omapi_wait_for_completion"); if (waiter->inner != NULL) - omapi_object_reference(&waiter->outer->inner, - waiter->inner, - "omapi_wait_for_completion"); + OBJECT_REF(&waiter->outer->inner, waiter->inner, + "omapi_wait_for_completion"); } - omapi_object_dereference(&waiter->outer, - "omapi_wait_for_completion"); + OBJECT_DEREF(&waiter->outer, "omapi_wait_for_completion"); } if (waiter->inner != NULL) - omapi_object_dereference(&waiter->inner, - "omapi_wait_for_completion"); + OBJECT_DEREF(&waiter->inner, "omapi_wait_for_completion"); - omapi_object_dereference((omapi_object_t **)&waiter, - "omapi_wait_for_completion"); + OBJECT_DEREF(&waiter, "omapi_wait_for_completion"); return (ISC_R_SUCCESS); } @@ -173,9 +118,9 @@ omapi_wait_for_completion (omapi_object_t *object, struct timeval *t) { isc_result_t omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) { fd_set r, w, x; - int max = 0; int count; int desc; + int max = 0; struct timeval now, to; omapi_io_object_t *io, *prev; isc_result_t result; @@ -234,8 +179,8 @@ omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) { * trying to read for this I/O object, either there * won't be a readfd function, or it'll return -1. */ - if (io->readfd != NULL && - (desc = (*(io->readfd))(io->inner)) >= 0) { + if (io->readfd != NULL) { + desc = (*(io->readfd))(io->inner); FD_SET(desc, &r); if (desc > max) max = desc; @@ -244,8 +189,8 @@ omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) { /* * Same deal for write fdsets. */ - if (io->writefd != NULL && - (desc = (*(io->writefd))(io->inner)) >= 0) { + if (io->writefd != NULL) { + desc = (*(io->writefd))(io->inner); FD_SET(desc, &w); if (desc > max) max = desc; @@ -307,31 +252,18 @@ omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) { * pointer, if there is one. */ if (io->next != NULL) - omapi_object_reference - ((omapi_object_t **)&tmp, - (omapi_object_t *)io->next, - "omapi_wfc"); + OBJECT_REF(&tmp, io->next, "omapi_wfc"); if (prev != NULL) { - omapi_object_dereference - ((omapi_object_t **)&prev->next, - "omapi_wfc"); + OBJECT_DEREF(&prev->next, "omapi_wfc"); if (tmp != NULL) - omapi_object_reference - (((omapi_object_t **) - &prev->next), - (omapi_object_t *)tmp, - "omapi_wfc"); + OBJECT_REF(&prev->next, tmp, + "omapi_wfc"); } else { - omapi_object_dereference - (((omapi_object_t **) - &omapi_io_states.next), - "omapi_wfc"); + OBJECT_DEREF(&omapi_io_states.next, + "omapi_wfc"); if (tmp != NULL) - omapi_object_reference - (((omapi_object_t **) - &omapi_io_states.next), - (omapi_object_t *)tmp, - "omapi_wfc"); + OBJECT_REF(&omapi_io_states.next, + tmp, "omapi_wfc"); else omapi_signal_in ((omapi_object_t *) @@ -339,9 +271,7 @@ omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) { "ready"); } if (tmp != NULL) - omapi_object_dereference - ((omapi_object_t **)&tmp, - "omapi_wfc"); + OBJECT_DEREF(&tmp, "omapi_wfc"); } } prev = io; diff --git a/lib/omapi/generic.c b/lib/omapi/generic.c index 8df88e0284..4416521c33 100644 --- a/lib/omapi/generic.c +++ b/lib/omapi/generic.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: generic.c,v 1.2 1999/11/02 04:01:32 tale Exp $ */ +/* $Id: generic.c,v 1.3 2000/01/04 20:04:38 tale Exp $ */ /* Principal Author: Ted Lemon */ @@ -23,25 +23,24 @@ * Subroutines that support the generic object. */ #include /* NULL */ -#include /* malloc, free */ #include /* memset */ #include -#include +#include isc_result_t omapi_generic_new(omapi_object_t **gen, const char *name) { omapi_generic_object_t *obj; - obj = malloc(sizeof(*obj)); + obj = isc_mem_get(omapi_mctx, sizeof(*obj)); if (obj == NULL) return (ISC_R_NOMEMORY); memset(obj, 0, sizeof(*obj)); obj->refcnt = 0; obj->type = omapi_type_generic; - omapi_object_reference(gen, (omapi_object_t *)obj, name); + OBJECT_REF(gen, obj, name); return (ISC_R_SUCCESS); } @@ -67,7 +66,7 @@ omapi_generic_set_value(omapi_object_t *h, omapi_object_t *id, * with the new one. */ for (i = 0; i < g->nvalues; i++) { - if (omapi_data_string_cmp(name, g->values [i]->name) == 0) { + if (omapi_data_string_cmp(name, g->values[i]->name) == 0) { /* * There's an inconsistency here: the standard * behaviour of a set_values method when @@ -84,22 +83,22 @@ omapi_generic_set_value(omapi_object_t *h, omapi_object_t *id, * returned. */ new = NULL; - result = omapi_value_new(&new, - "omapi_message_get_value"); + result = omapi_data_newvalue(&new, + "omapi_message_get_value"); if (result != ISC_R_SUCCESS) return (result); - omapi_data_string_reference(&new->name, name, + omapi_data_stringreference(&new->name, name, "omapi_message_get_value"); if (value != NULL) - omapi_typed_data_reference(&new->value, value, + omapi_data_reference(&new->value, value, "omapi_generic_set_value"); - omapi_value_dereference(&(g->values [i]), + omapi_data_valuedereference(&(g->values[i]), "omapi_message_set_value"); - omapi_value_reference(&(g->values [i]), new, - "omapi_message_set_value"); - omapi_value_dereference(&new, + omapi_data_valuereference(&(g->values[i]), new, + "omapi_message_set_value"); + omapi_data_valuedereference(&new, "omapi_message_set_value"); return (ISC_R_SUCCESS); @@ -134,26 +133,29 @@ omapi_generic_set_value(omapi_object_t *h, omapi_object_t *id, vm_new = 2 * g->va_max; else vm_new = 10; - va = malloc(vm_new * sizeof(*va)); + va = isc_mem_get(omapi_mctx, vm_new * sizeof(*va)); if (va != NULL) return (ISC_R_NOMEMORY); - if (g->va_max != 0) + if (g->va_max != 0) { memcpy(va, g->values, g->va_max * sizeof(*va)); + isc_mem_put(omapi_mctx, g->values, + g->va_max * sizeof(*va)); + } + memset(va + g->va_max, 0, (vm_new - g->va_max) * sizeof(*va)); - free(g->values); g->values = va; g->va_max = vm_new; } - result = omapi_value_new(&g->values[g->nvalues], - "omapi_generic_set_value"); + result = omapi_data_newvalue(&g->values[g->nvalues], + "omapi_generic_set_value"); if (result != ISC_R_SUCCESS) return (result); - omapi_data_string_reference(&g->values[g->nvalues]->name, name, - "omapi_generic_set_value"); + omapi_data_stringreference(&g->values[g->nvalues]->name, name, + "omapi_generic_set_value"); if (value != NULL) - omapi_typed_data_reference(&g->values [g->nvalues]->value, - value, "omapi_generic_set_value"); + omapi_data_reference(&g->values[g->nvalues]->value, value, + "omapi_generic_set_value"); g->nvalues++; return (ISC_R_SUCCESS); } @@ -173,7 +175,7 @@ omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id, * Look up the specified name in our list of objects. */ for (i = 0; i < g->nvalues; i++) { - if (omapi_data_string_cmp (name, g->values [i]->name) == 0) { + if (omapi_data_string_cmp(name, g->values[i]->name) == 0) { /* * If this is a name/null value pair, this is the * same as if there were no value that matched @@ -184,8 +186,8 @@ omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id, /* * Otherwise, return the name/value pair. */ - omapi_value_reference(value, g->values[i], - "omapi_message_get_value"); + omapi_data_valuereference(value, g->values[i], + "omapi_message_get_value"); return (ISC_R_SUCCESS); } } @@ -208,9 +210,11 @@ omapi_generic_destroy(omapi_object_t *h, const char *name) { if (g->values != NULL) { for (i = 0; i < g->nvalues; i++) if (g->values[i] != NULL) - omapi_value_dereference(&g->values[i], name); + omapi_data_valuedereference(&g->values[i], + name); - free(g->values); + isc_mem_put(omapi_mctx, g->values, + g->va_max * sizeof(*g->values)); g->values = NULL; g->va_max = 0; } diff --git a/lib/omapi/handle.c b/lib/omapi/handle.c index e51b0c1536..e635b43afb 100644 --- a/lib/omapi/handle.c +++ b/lib/omapi/handle.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: handle.c,v 1.2 1999/11/02 04:01:33 tale Exp $ */ +/* $Id: handle.c,v 1.3 2000/01/04 20:04:39 tale Exp $ */ /* Principal Author: Ted Lemon */ @@ -23,12 +23,12 @@ * Functions for maintaining handles on objects. */ #include /* NULL */ -#include /* malloc, free */ #include /* memset */ #include +#include -#include +#include /* * The handle table is a hierarchical tree designed for quick mapping @@ -49,6 +49,7 @@ * the tree to contain the new handle. The pointer to the object is * then stored in the correct position. * + * XXXTL * Theoretically, we could have some code here to free up handle * tables as they go out of use, but by and large handle tables won't * go out of use, so this is being skipped for now. It shouldn't be @@ -62,7 +63,7 @@ typedef struct omapi_handle_table { omapi_handle_t first; omapi_handle_t limit; omapi_handle_t next; - int leafp; + isc_boolean_t leaf; union { omapi_object_t * object; struct omapi_handle_table * table; @@ -95,13 +96,14 @@ omapi_object_handle(omapi_handle_t *h, omapi_object_t *o) { } if (omapi_handle_table == NULL) { - omapi_handle_table = malloc(sizeof(*omapi_handle_table)); + omapi_handle_table = isc_mem_get(omapi_mctx, + sizeof(*omapi_handle_table)); if (omapi_handle_table == NULL) return (ISC_R_NOMEMORY); memset(omapi_handle_table, 0, sizeof(*omapi_handle_table)); omapi_handle_table->first = 0; omapi_handle_table->limit = OMAPI_HANDLE_TABLE_SIZE; - omapi_handle_table->leafp = 1; + omapi_handle_table->leaf = ISC_TRUE; } /* @@ -115,14 +117,14 @@ omapi_object_handle(omapi_handle_t *h, omapi_object_t *o) { while (omapi_next_handle >= omapi_handle_table->limit) { omapi_handle_table_t *new; - new = malloc(sizeof(*new)); + new = isc_mem_get(omapi_mctx, sizeof(*new)); if (new == NULL) return (ISC_R_NOMEMORY); memset(new, 0, sizeof(*new)); new->first = 0; new->limit = (omapi_handle_table->limit * OMAPI_HANDLE_TABLE_SIZE); - new->leafp = 0; + new->leaf = ISC_FALSE; new->children[0].table = omapi_handle_table; omapi_handle_table = new; } @@ -173,10 +175,9 @@ omapi_object_handle_in_table(omapi_handle_t h, omapi_handle_table_t *table, * If this is a leaf table, just stash the object in the * appropriate place. */ - if (table->leafp != NULL) { - omapi_object_reference(&table-> - children[h - table->first].object, - o, "omapi_object_handle_in_table"); + if (table->leaf) { + OBJECT_REF(&table->children[h - table->first].object, o, + "omapi_object_handle_in_table"); o->handle = h; return (ISC_R_SUCCESS); } @@ -201,14 +202,14 @@ omapi_object_handle_in_table(omapi_handle_t h, omapi_handle_table_t *table, * we came up with, make one. */ if (inner == NULL) { - inner = malloc(sizeof(*inner)); + inner = isc_mem_get(omapi_mctx, sizeof(*inner)); if (inner == NULL) return (ISC_R_NOMEMORY); memset(inner, 0, sizeof(*inner)); inner->first = index * scale + table->first; inner->limit = inner->first + scale; if (scale == OMAPI_HANDLE_TABLE_SIZE) - inner->leafp = 1; + inner->leaf = ISC_TRUE; table->children[index].table = inner; } @@ -257,21 +258,21 @@ omapi_handle_table_enclose(omapi_handle_table_t **table) { */ index = (base - inner->first) / OMAPI_HANDLE_TABLE_SIZE; - new = malloc(sizeof(*new)); + new = isc_mem_get(omapi_mctx, sizeof(*new)); if (new == NULL) return (ISC_R_NOMEMORY); memset(new, 0, sizeof *new); new->first = base; new->limit = base + scale; if (scale == OMAPI_HANDLE_TABLE_SIZE) - new->leafp = 0; + new->leaf = ISC_FALSE; new->children[index].table = inner; *table = new; return (ISC_R_SUCCESS); } isc_result_t -omapi_handle_lookup (omapi_object_t **o, omapi_handle_t h) { +omapi_handle_lookup(omapi_object_t **o, omapi_handle_t h) { return (omapi_handle_lookup_in(o, h, omapi_handle_table)); } @@ -288,16 +289,15 @@ omapi_handle_lookup_in(omapi_object_t **o, omapi_handle_t h, /* * If this is a leaf table, just grab the object. */ - if (table->leafp != NULL) { + if (table->leaf) { /* * Not there? */ if (table->children[h - table->first].object == NULL) return (ISC_R_NOTFOUND); - omapi_object_reference(o, - table->children[h - table->first].object, - "omapi_handle_lookup_in"); + OBJECT_REF(o, table->children[h - table->first].object, + "omapi_handle_lookup_in"); return (ISC_R_SUCCESS); } diff --git a/lib/omapi/include/omapi/buffer.h b/lib/omapi/include/omapi/buffer.h index c7df528604..bc9ba70827 100644 --- a/lib/omapi/include/omapi/buffer.h +++ b/lib/omapi/include/omapi/buffer.h @@ -78,7 +78,7 @@ omapi_connection_copyout(unsigned char *data, omapi_object_t *connection, unsigned int length); isc_result_t -omapi_connection_copyin(omapi_object_t *connection, const unsigned char *data, +omapi_connection_copyin(omapi_object_t *connection, unsigned char *data, unsigned int length); isc_result_t diff --git a/lib/omapi/include/omapi/omapip.h b/lib/omapi/include/omapi/omapip.h index 2079858272..3b07ea7ef6 100644 --- a/lib/omapi/include/omapi/omapip.h +++ b/lib/omapi/include/omapi/omapip.h @@ -46,6 +46,7 @@ typedef struct omapi_value omapi_value_t; #define OMAPI_OBJECT_PREAMBLE \ omapi_object_type_t * type; \ + size_t object_size; \ int refcnt; \ omapi_handle_t handle; \ omapi_object_t *outer, *inner @@ -256,6 +257,10 @@ omapi_protocol_send_update(omapi_object_t *protocl, omapi_object_t *id, isc_result_t omapi_connect(omapi_object_t *connection, const char *server, int port); +isc_result_t +omapi_connection_toserver(omapi_object_t *connection, const char *server, + int port); + void omapi_disconnect(omapi_object_t *connection, isc_boolean_t force); @@ -265,6 +270,9 @@ omapi_connection_readfd(omapi_object_t *connection); int omapi_connection_writefd(omapi_object_t *connection); +void +omapi_connection_read(isc_task_t *task, isc_event_t *event); + isc_result_t omapi_connection_reader(omapi_object_t *connection); @@ -312,32 +320,26 @@ omapi_connection_put_handle(omapi_object_t *connection, * listen.c */ isc_result_t -omapi_listen(omapi_object_t *listener, int port, int backlog); - -int -omapi_listener_readfd(omapi_object_t *listener); +omapi_listener_listen(omapi_object_t *listener, int port, int backlog); isc_result_t -omapi_accept(omapi_object_t *listener); +omapi_listener_setvalue(omapi_object_t *listener, omapi_object_t *id, + omapi_data_string_t *name, omapi_typed_data_t *value); isc_result_t -omapi_listener_set_value(omapi_object_t *listener, omapi_object_t *id, - omapi_data_string_t *name, omapi_typed_data_t *value); - -isc_result_t -omapi_listener_get_value(omapi_object_t *listener, omapi_object_t *id, - omapi_data_string_t *name, omapi_value_t **value); +omapi_listener_getvalue(omapi_object_t *listener, omapi_object_t *id, + omapi_data_string_t *name, omapi_value_t **value); void omapi_listener_destroy(omapi_object_t *listener, const char *name); isc_result_t -omapi_listener_signal_handler(omapi_object_t *listener, const char *name, - va_list args); +omapi_listener_signalhandler(omapi_object_t *listener, const char *name, + va_list args); isc_result_t -omapi_listener_stuff_values(omapi_object_t *listener, omapi_object_t *id, - omapi_object_t *object); +omapi_listener_stuffvalues(omapi_object_t *listener, omapi_object_t *id, + omapi_object_t *object); /* * dispatch.c @@ -387,8 +389,8 @@ isc_result_t omapi_generic_new(omapi_object_t **generic, const char *name); isc_result_t -omapi_generic_set_value (omapi_object_t *generic, omapi_object_t *id, - omapi_data_string_t *name, omapi_typed_data_t *value); +omapi_generic_set_value(omapi_object_t *generic, omapi_object_t *id, + omapi_data_string_t *name, omapi_typed_data_t *value); isc_result_t omapi_generic_get_value(omapi_object_t *generic, omapi_object_t *id, @@ -440,7 +442,7 @@ omapi_message_process(omapi_object_t *message, omapi_object_t *protocol); * support.c */ isc_result_t -omapi_init(void); +omapi_init(isc_mem_t *mctx); isc_result_t omapi_object_type_register(omapi_object_type_t **type, @@ -581,7 +583,7 @@ isc_result_t omapi_handle_td_lookup(omapi_object_t **object, omapi_typed_data_t *data); /* - * alloc.c + * object.c */ void omapi_object_reference(omapi_object_t **reference, omapi_object_t *object, @@ -590,38 +592,41 @@ omapi_object_reference(omapi_object_t **reference, omapi_object_t *object, void omapi_object_dereference(omapi_object_t **reference, const char *name); +/* + * data.c + */ + isc_result_t -omapi_typed_data_new(omapi_typed_data_t **data, omapi_datatype_t type, ...); +omapi_data_new(omapi_typed_data_t **data, omapi_datatype_t type, ...); void -omapi_typed_data_reference(omapi_typed_data_t **reference, - omapi_typed_data_t *data, +omapi_data_reference(omapi_typed_data_t **reference, omapi_typed_data_t *data, + const char *name); + +void +omapi_data_dereference(omapi_typed_data_t **reference, const char *name); + +isc_result_t +omapi_data_newstring(omapi_data_string_t **string, unsigned int length, + const char *name); + +void +omapi_data_stringreference(omapi_data_string_t **reference, + omapi_data_string_t *string, const char *name); void -omapi_typed_data_dereference(omapi_typed_data_t **reference, const char *name); - -isc_result_t -omapi_data_string_new(omapi_data_string_t **string, unsigned int length, - const char *name); - -void -omapi_data_string_reference(omapi_data_string_t **reference, - omapi_data_string_t *string, - const char *name); - -void -omapi_data_string_dereference(omapi_data_string_t **, const char *); +omapi_data_stringdereference(omapi_data_string_t **, const char *); isc_result_t -omapi_value_new(omapi_value_t **value, const char *name); +omapi_data_newvalue(omapi_value_t **value, const char *name); void -omapi_value_reference(omapi_value_t **reference, omapi_value_t *value, - const char *name); +omapi_data_valuereference(omapi_value_t **reference, omapi_value_t *value, + const char *name); void -omapi_value_dereference(omapi_value_t **reference, const char *name); +omapi_data_valuedereference(omapi_value_t **reference, const char *name); ISC_LANG_ENDDECLS diff --git a/lib/omapi/include/omapi/omapip_p.h b/lib/omapi/include/omapi/omapip_p.h deleted file mode 100644 index 820779d789..0000000000 --- a/lib/omapi/include/omapi/omapip_p.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 1996, 1997, 1998, 1999 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/***** - ***** Private master include file for the OMAPI library. - *****/ - -#ifndef OMAPI_OMAPIP_P_H -#define OMAPI_OMAPIP_P_H - -#include -#include -#include - -#include -#include -#include - -ISC_LANG_BEGINDECLS - -#define OMAPI_OP_OPEN 1 -#define OMAPI_OP_REFRESH 2 -#define OMAPI_OP_UPDATE 3 -#define OMAPI_OP_NOTIFY 4 -#define OMAPI_OP_STATUS 5 -#define OMAPI_OP_DELETE 6 - -typedef enum { - omapi_connection_unconnected, - omapi_connection_connecting, - omapi_connection_connected, - omapi_connection_disconnecting, - omapi_connection_closed -} omapi_connection_state_t; - -typedef struct omapi_message_object { - OMAPI_OBJECT_PREAMBLE; - struct omapi_message_object * next; - struct omapi_message_object * prev; - omapi_object_t * object; - omapi_object_t * notify_object; - unsigned int authlen; - omapi_typed_data_t * authenticator; - unsigned int authid; - omapi_object_t * id_object; - unsigned int op; - omapi_handle_t h; - unsigned int id; - unsigned int rid; -} omapi_message_object_t; - -typedef struct omapi_connection_object { - OMAPI_OBJECT_PREAMBLE; - int socket; /* Connection socket. */ - omapi_connection_state_t state; - struct sockaddr_in remote_addr; - struct sockaddr_in local_addr; - /* - * Bytes of input needed before wakeup. - */ - isc_uint32_t bytes_needed; - /* - * Bytes of input already buffered. - */ - isc_uint32_t in_bytes; - omapi_buffer_t * inbufs; - /* - * Bytes of output in buffers. - */ - isc_uint32_t out_bytes; - omapi_buffer_t * outbufs; - /* - * Listener that accepted this connection. - */ - omapi_object_t * listener; -} omapi_connection_object_t; - -typedef struct omapi_generic_object { - OMAPI_OBJECT_PREAMBLE; - omapi_value_t ** values; - int nvalues; - int va_max; -} omapi_generic_object_t; - -ISC_LANG_ENDDECLS - -#endif /* OMAPIP_OMAPIP_P_H */ diff --git a/lib/omapi/listener.c b/lib/omapi/listener.c index dd2f4b2b87..0ebbfcd73c 100644 --- a/lib/omapi/listener.c +++ b/lib/omapi/listener.c @@ -18,253 +18,313 @@ /* * Subroutines that support the generic listener object. */ -#include -#include /* fcntl, F_SETFL, O_NONBLOCK */ #include /* NULL */ -#include /* malloc, free */ #include /* memset */ #include /* close */ #include +#include +#include -#include +#include typedef struct omapi_listener_object { OMAPI_OBJECT_PREAMBLE; - /* - * Connection socket. - */ - int socket; - struct sockaddr_in address; + isc_task_t *task; + isc_socket_t *socket; /* Connection socket. */ + isc_sockaddr_t address; } omapi_listener_object_t; -isc_result_t -omapi_listen(omapi_object_t *h, int port, int max) { +/* + * Reader callback for a listener object. Accept an incoming connection. + */ +static void +omapi_listener_accept(isc_task_t *task, isc_event_t *event) { isc_result_t result; - omapi_listener_object_t *obj; + isc_buffer_t *ibuffer, *obuffer; + isc_task_t *recv_task; + isc_socket_newconnev_t *incoming; + omapi_connection_object_t *connection; + omapi_object_t *listener; + + /* + * XXXDCL What are the meaningful things the listen/accept function + * can do if it fails to process an incoming connection because one + * of the functions it calls fails? + */ + + /* + * Set up another listen task for the socket. + */ + isc_socket_accept(event->sender, task, omapi_listener_accept, + event->arg); + + /* + * Check for the validity of new connection event. + */ + incoming = (isc_socket_newconnev_t *)event; + if (incoming->result != ISC_R_SUCCESS) + /* + * The result is probably ISC_R_UNEXPECTED; what can really be + * done about this other than just flunking out of here? + */ + return; + + /* + * The new connection is good to go. Allocate the buffers for it and + * prepare the receive task. + */ + recv_task = NULL; + if (isc_task_create(omapi_taskmgr, NULL, 0, &recv_task) != + ISC_R_SUCCESS) + return; + + ibuffer = NULL; + result = isc_buffer_allocate(omapi_mctx, &ibuffer, OMAPI_BUFFER_SIZE, + ISC_BUFFERTYPE_BINARY); + if (result != ISC_R_SUCCESS) + return; + + obuffer = NULL; + result = isc_buffer_allocate(omapi_mctx, &obuffer, OMAPI_BUFFER_SIZE, + ISC_BUFFERTYPE_BINARY); + if (result != ISC_R_SUCCESS) + return; + + /* + * Create a new connection object. + */ + connection = isc_mem_get(omapi_mctx, sizeof(*connection)); + if (connection == NULL) { + /* + * XXXDCL at the moment, I am not confident this is + * the right way to forget all about this connection. + */ + isc_task_shutdown(recv_task); +#if 0 /*XXXDCL */ + isc_socket_cancel(incoming->newsocket, recv_task, + ISC_SOCKCANCEL_RECV); + isc_socket_shutdown(incoming->newsocket, ISC_SOCKSHUT_ALL); +#endif + isc_buffer_free(&ibuffer); + isc_buffer_free(&obuffer); + return; + } + + memset(connection, 0, sizeof(*connection)); + connection->object_size = sizeof(*connection); + connection->refcnt = 1; + connection->task = task; + connection->type = omapi_type_connection; + connection->state = omapi_connection_connected; + + connection->socket = incoming->newsocket; + + ISC_LIST_INIT(connection->input_buffers); + ISC_LIST_APPEND(connection->input_buffers, ibuffer, link); + ISC_LIST_INIT(connection->output_buffers); + ISC_LIST_APPEND(connection->output_buffers, obuffer, link); + + connection->output_buffer = obuffer; + + /* + * Queue the receive task. + */ + isc_socket_recvv(incoming->newsocket, &connection->input_buffers, 1, + recv_task, omapi_connection_read, connection); + isc_task_detach(&recv_task); + + /* + * Point the connection's listener member at the listener object. + * XXXDCL but why is this needed? + */ + listener = event->arg; + OBJECT_REF(&connection->listener, listener, "omapi_listener_accept"); + + /* + * Notify the listener object that a connection was made. + */ + result = omapi_signal(listener, "connect", connection); + if (result != ISC_R_SUCCESS) + /*XXXDCL then what?!*/ + ; + + /* + * Lose our reference to the connection, so it'll be gc'd when it's + * reaped. + * XXXDCL ... um, hmm? this object only has one reference, so it + * is going to be reaped right here! unless omapi_signal added + * a reference ... + */ + OBJECT_DEREF(&connection, "omapi_listener_accept"); + + return; +} + +isc_result_t +omapi_listener_listen(omapi_object_t *caller, int port, int max) { + isc_result_t result; + isc_task_t *task; + omapi_listener_object_t *listener; + struct in_addr inaddr; + + task = NULL; + result = isc_task_create(omapi_taskmgr, NULL, 0, &task); + if (result != ISC_R_SUCCESS) + return (result); + +#if 0 /*XXXDCL*/ + result = isc_task_onshutdown(task, omapi_listener_shutdown, NULL); + if (result != ISC_R_SUCCESS) + return (result); +#endif /* * Get the handle. */ - obj = (omapi_listener_object_t *)malloc(sizeof(*obj)); - if (obj == NULL) + listener = isc_mem_get(omapi_mctx, sizeof(*listener)); + if (listener == NULL) return (ISC_R_NOMEMORY); - memset(obj, 0, sizeof(*obj)); - obj->refcnt = 1; - obj->type = omapi_type_listener; + memset(listener, 0, sizeof(*listener)); + listener->object_size = sizeof(*listener); + listener->refcnt = 1; + listener->task = task; + listener->type = omapi_type_listener; /* - * Connect this object to the inner object. + * Tie the listener object to the calling object. */ - omapi_object_reference(&h->outer, (omapi_object_t *)obj, - "omapi_protocol_listen"); - omapi_object_reference(&obj->inner, h, "omapi_protocol_listen"); - - /* - * Set up the address on which we will listen. - */ - obj->address.sin_port = htons(port); - obj->address.sin_addr.s_addr = htonl(INADDR_ANY); + OBJECT_REF(&caller->outer, listener, "omapi_protocol_listen"); + OBJECT_REF(&listener->inner, caller, "omapi_protocol_listen"); /* * Create a socket on which to listen. */ - obj->socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (obj->socket < 0) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_listen"); - if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS) - return (ISC_R_NORESOURCES); - return (ISC_R_UNEXPECTED); + listener->socket = NULL; + result = isc_socket_create(omapi_socketmgr, PF_INET, + isc_sockettype_tcp, &listener->socket); + if (result != ISC_R_SUCCESS) { + /* XXXDCL this call and later will not free the listener + * because it has two refcnts, one for existing plus one + * for the tie to h->outer. This does not seem right to me. + */ + OBJECT_DEREF(&listener, "omapi_listen"); + return (result); } + /* + * Set up the address on which we will listen. + */ + inaddr.s_addr = INADDR_ANY; + isc_sockaddr_fromin(&listener->address, &inaddr, port); + /* * Try to bind to the wildcard address using the port number * we were given. */ - if (bind(obj->socket, - (struct sockaddr *)&obj->address, sizeof(obj->address)) < 0) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_listen"); - if (errno == EADDRINUSE) - return (ISC_R_ADDRNOTAVAIL); - if (errno == EPERM) - return (ISC_R_NOPERM); - return (ISC_R_UNEXPECTED); + result = isc_socket_bind(listener->socket, &listener->address); + if (result != ISC_R_SUCCESS) { + OBJECT_DEREF(&listener, "omapi_listen"); + return (result); } /* * Now tell the kernel to listen for connections. */ - if (listen(obj->socket, max) < 0) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_listen"); - return (ISC_R_UNEXPECTED); - } - - if (fcntl(obj->socket, F_SETFL, O_NONBLOCK) < 0) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_connect"); - return (ISC_R_UNEXPECTED); - } - - result = omapi_register_io_object((omapi_object_t *)obj, - omapi_listener_readfd, 0, - omapi_accept, 0, 0); + result = isc_socket_listen(listener->socket, max); if (result != ISC_R_SUCCESS) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_listen"); + OBJECT_DEREF(&listener, "omapi_listen"); return (result); } - return (ISC_R_SUCCESS); -} - -/* - * Return the socket on which the dispatcher should wait for readiness - * to read, for a listener object. - */ -int -omapi_listener_readfd (omapi_object_t *h) { - omapi_listener_object_t *l; - - REQUIRE(h != NULL && h->type == omapi_type_listener); - - l = (omapi_listener_object_t *)h; - - return (l->socket); -} - -/* - * Reader callback for a listener object. Accept an incoming connection. - */ -isc_result_t -omapi_accept (omapi_object_t *h) { - isc_result_t result; - int len; - omapi_connection_object_t *obj; - omapi_listener_object_t *listener; - - REQUIRE(h != NULL && h->type == omapi_type_listener); - - listener = (omapi_listener_object_t *)h; - /* - * Get the handle. + * Queue up the first accept event. The listener object + * will be passed to omapi_listener_accept() when it is called. */ - obj = (omapi_connection_object_t *)malloc(sizeof(*obj)); - if (obj == NULL) - return (ISC_R_NOMEMORY); - memset(obj, 0, sizeof(*obj)); - obj->refcnt = 1; - obj->type = omapi_type_connection; + result = isc_socket_accept(listener->socket, task, + omapi_listener_accept, listener); + if (result != ISC_R_SUCCESS) + OBJECT_DEREF(&listener, "omapi_listen"); - /* - * Accept the connection. - */ - len = sizeof(obj->remote_addr); - obj->socket = accept(listener->socket, - ((struct sockaddr *)&(obj->remote_addr)), &len); - if (obj->socket < 0) { - omapi_object_dereference ((omapi_object_t **)&obj, - "omapi_accept"); - if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS) - return (ISC_R_NORESOURCES); - return (ISC_R_UNEXPECTED); - } - - obj->state = omapi_connection_connected; - - result = omapi_register_io_object((omapi_object_t *)obj, - omapi_connection_readfd, - omapi_connection_writefd, - omapi_connection_reader, - omapi_connection_writer, - omapi_connection_reaper); - if (result != ISC_R_SUCCESS) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_accept"); - return (result); - } - - omapi_object_reference(&obj->listener, (omapi_object_t *)listener, - "omapi_accept"); - - result = omapi_signal(h, "connect", obj); - - /* - * Lose our reference to the connection, so it'll be gc'd when it's - * reaped. - */ - omapi_object_dereference ((omapi_object_t **)&obj, "omapi_accept"); return (result); } isc_result_t -omapi_listener_set_value(omapi_object_t *h, omapi_object_t *id, - omapi_data_string_t *name, - omapi_typed_data_t *value) +omapi_listener_setvalue(omapi_object_t *listener, omapi_object_t *id, + omapi_data_string_t *name, omapi_typed_data_t *value) { - REQUIRE(h != NULL && h->type == omapi_type_listener); - - if (h->inner != NULL && h->inner->type->set_value != NULL) - return (*(h->inner->type->set_value))(h->inner, id, - name, value); - return (ISC_R_NOTFOUND); + /* + * Nothing meaningful can be set in a listener object; just + * continue the call through the object chain. + */ + REQUIRE(listener != NULL && listener->type == omapi_type_listener); + + PASS_SETVALUE(listener); } isc_result_t -omapi_listener_get_value(omapi_object_t *h, omapi_object_t *id, - omapi_data_string_t *name, - omapi_value_t **value) +omapi_listener_getvalue(omapi_object_t *listener, omapi_object_t *id, + omapi_data_string_t *name, omapi_value_t **value) { - REQUIRE(h != NULL && h->type == omapi_type_listener); + /* + * Nothing meaningful can be fetched from a listener object; just + * continue the call through the object chain. + */ + REQUIRE(listener != NULL && listener->type == omapi_type_listener); - if (h->inner != NULL && h->inner->type->get_value != NULL) - return (*(h->inner->type->get_value))(h->inner, id, - name, value); - return (ISC_R_NOTFOUND); + PASS_GETVALUE(listener); } void -omapi_listener_destroy(omapi_object_t *h, const char *name) { - omapi_listener_object_t *l; +omapi_listener_destroy(omapi_object_t *object, const char *name) { + omapi_listener_object_t *listener; - REQUIRE(h != NULL && h->type == omapi_type_listener); + REQUIRE(object != NULL && object->type == omapi_type_listener); (void)name; /* Unused. */ - l = (omapi_listener_object_t *)h; - - if (l->socket != -1) { - close(l->socket); - l->socket = -1; + listener = (omapi_listener_object_t *)object; + + if (listener->socket != NULL) { +#if 0 /*XXXDCL*/ + isc_socket_cancel(listener->socket, NULL, ISC_SOCKCANCEL_ALL); + isc_socket_shutdown(listener->socket, ISC_SOCKSHUT_ALL); +#else + isc_task_shutdown(listener->task); +#endif + listener->socket = NULL; } } isc_result_t -omapi_listener_signal_handler(omapi_object_t *h, const char *name, va_list ap) +omapi_listener_signalhandler(omapi_object_t *listener, const char *name, + va_list ap) { - REQUIRE(h != NULL && h->type == omapi_type_listener); + REQUIRE(listener != NULL && listener->type == omapi_type_listener); - if (h->inner != NULL && h->inner->type->signal_handler != NULL) - return (*(h->inner->type->signal_handler))(h->inner, name, ap); - return (ISC_R_NOTFOUND); + /* + * This function is reached when omapi_listener_accept does + * an omapi_signal of "connect" on the listener object. Nothing + * need be done here, but the object that originally requested + * the listen needs to signalled that a connection was made. + * + * In the normal instance, the pass-through is to an object of type + * omapi_type_protocol_listener, so the signal_handler that + * is getting called is omapi_protocol_listener_signal. + */ + PASS_SIGNAL(listener); } /* * Write all the published values associated with the object through the * specified connection. */ - isc_result_t -omapi_listener_stuff_values(omapi_object_t *c, omapi_object_t *id, - omapi_object_t *h) +omapi_listener_stuffvalues(omapi_object_t *connection, omapi_object_t *id, + omapi_object_t *listener) { - REQUIRE(h != NULL && h->type == omapi_type_listener); + REQUIRE(listener != NULL && listener->type == omapi_type_listener); - if (h->inner != NULL && h->inner->type->stuff_values != NULL) - return (*(h->inner->type->stuff_values))(c, id, h->inner); - return (ISC_R_SUCCESS); + PASS_STUFFVALUES(listener); } diff --git a/lib/omapi/message.c b/lib/omapi/message.c index 4bd96245ab..b4fc9b5bb8 100644 --- a/lib/omapi/message.c +++ b/lib/omapi/message.c @@ -19,12 +19,11 @@ * Subroutines for dealing with message objects. */ #include /* NULL */ -#include /* malloc, free */ #include /* memset */ #include -#include +#include omapi_message_object_t *omapi_registered_messages; @@ -34,26 +33,27 @@ omapi_message_new(omapi_object_t **o, const char *name) { omapi_object_t *g; isc_result_t result; - m = malloc(sizeof(*m)); + m = isc_mem_get(omapi_mctx, sizeof(*m)); if (m == NULL) return (ISC_R_NOMEMORY); memset(m, 0, sizeof(*m)); - m->type = omapi_type_message; + m->object_size = sizeof(*m); m->refcnt = 1; + m->type = omapi_type_message; g = NULL; result = omapi_generic_new(&g, name); if (result != ISC_R_SUCCESS) { - free (m); + isc_mem_put(omapi_mctx, m, sizeof(*m)); return (result); } - omapi_object_reference(&m->inner, g, name); - omapi_object_reference(&g->outer, (omapi_object_t *)m, name); - omapi_object_reference(o, (omapi_object_t *)m, name); + OBJECT_REF(&m->inner, g, name); + OBJECT_REF(&g->outer, m, name); + OBJECT_REF(o, m, name); - omapi_object_dereference((omapi_object_t **)&m, name); - omapi_object_dereference(&g, name); + OBJECT_DEREF(&m, name); + OBJECT_DEREF(&g, name); return (result); } @@ -79,30 +79,29 @@ omapi_message_set_value(omapi_object_t *h, omapi_object_t *id, */ if (omapi_ds_strcmp(name, "authenticator") == 0) { if (m->authenticator != NULL) - omapi_typed_data_dereference(&m->authenticator, - "omapi_message_set_value"); - omapi_typed_data_reference(&m->authenticator, value, - "omapi_message_set_value"); + omapi_data_dereference(&m->authenticator, + "omapi_message_set_value"); + omapi_data_reference(&m->authenticator, value, + "omapi_message_set_value"); return (ISC_R_SUCCESS); } else if (omapi_ds_strcmp(name, "object") == 0) { INSIST(value != NULL && value->type == omapi_datatype_object); if (m->object != NULL) - omapi_object_dereference(&m->object, - "omapi_message_set_value"); - omapi_object_reference(&m->object, value->u.object, - "omapi_message_set_value"); + OBJECT_DEREF(&m->object, "omapi_message_set_value"); + OBJECT_REF(&m->object, value->u.object, + "omapi_message_set_value"); return (ISC_R_SUCCESS); - } else if (omapi_ds_strcmp (name, "notify-object") == 0) { + } else if (omapi_ds_strcmp(name, "notify-object") == 0) { INSIST(value != NULL && value->type == omapi_datatype_object); if (m->notify_object != NULL) - omapi_object_dereference(&m->notify_object, - "omapi_message_set_value"); - omapi_object_reference(&m->notify_object, value->u.object, - "omapi_message_set_value"); + OBJECT_DEREF(&m->notify_object, + "omapi_message_set_value"); + OBJECT_REF(&m->notify_object, value->u.object, + "omapi_message_set_value"); return (ISC_R_SUCCESS); /* @@ -222,19 +221,18 @@ omapi_message_destroy(omapi_object_t *h, const char *name) { m = (omapi_message_object_t *)h; if (m->authenticator != NULL) - omapi_typed_data_dereference(&m->authenticator, name); + omapi_data_dereference(&m->authenticator, name); if (m->prev == NULL && omapi_registered_messages != m) omapi_message_unregister(h); if (m->prev != NULL) - omapi_object_dereference((omapi_object_t **)&m->prev, name); + OBJECT_DEREF(&m->prev, name); if (m->next != NULL) - omapi_object_dereference((omapi_object_t **)&m->next, name); + OBJECT_DEREF(&m->next, name); if (m->id_object != NULL) - omapi_object_dereference((omapi_object_t **)&m->id_object, - name); + OBJECT_DEREF(&m->id_object, name); if (m->object != NULL) - omapi_object_dereference((omapi_object_t **)&m->object, name); + OBJECT_DEREF(&m->object, name); } isc_result_t @@ -290,20 +288,16 @@ omapi_message_register(omapi_object_t *h) { omapi_registered_messages != m); if (omapi_registered_messages != NULL) { - omapi_object_reference - ((omapi_object_t **)&m->next, - (omapi_object_t *)omapi_registered_messages, - "omapi_message_register"); - omapi_object_reference - ((omapi_object_t **)&omapi_registered_messages->prev, - (omapi_object_t *)m, "omapi_message_register"); - omapi_object_dereference - ((omapi_object_t **)&omapi_registered_messages, - "omapi_message_register"); + OBJECT_REF(&m->next, omapi_registered_messages, + "omapi_message_register"); + OBJECT_REF(&omapi_registered_messages->prev, m, + "omapi_message_register"); + OBJECT_DEREF(&omapi_registered_messages, + "omapi_message_register"); } - omapi_object_reference - ((omapi_object_t **)&omapi_registered_messages, - (omapi_object_t *)m, "omapi_message_register"); + + OBJECT_REF(&omapi_registered_messages, m, + "omapi_message_register"); return (ISC_R_SUCCESS); } @@ -323,41 +317,34 @@ omapi_message_unregister(omapi_object_t *h) { n = NULL; if (m->next != NULL) { - omapi_object_reference((omapi_object_t **)&n, - (omapi_object_t *)m->next, - "omapi_message_unregister"); - omapi_object_dereference((omapi_object_t **)&m->next, - "omapi_message_unregister"); + OBJECT_REF(&n, m->next, "omapi_message_unregister"); + OBJECT_DEREF(&m->next, "omapi_message_unregister"); } + if (m->prev != NULL) { omapi_message_object_t *tmp = NULL; - omapi_object_reference((omapi_object_t **)&tmp, - (omapi_object_t *)m->prev, - "omapi_message_register"); - omapi_object_dereference((omapi_object_t **)&m->prev, - "omapi_message_unregister"); + OBJECT_REF(&tmp, m->prev, "omapi_message_register"); + OBJECT_DEREF(&m->prev, "omapi_message_unregister"); + if (tmp->next != NULL) - omapi_object_dereference((omapi_object_t **)&tmp->next, - "omapi_message_unregister"); + OBJECT_DEREF(&tmp->next, "omapi_message_unregister"); + if (n != NULL) - omapi_object_reference((omapi_object_t **)&tmp->next, - (omapi_object_t *)n, - "omapi_message_unregister"); - omapi_object_dereference((omapi_object_t **)&tmp, - "omapi_message_unregister"); + OBJECT_REF(&tmp->next, n, "omapi_message_unregister"); + + OBJECT_DEREF(&tmp, "omapi_message_unregister"); + } else { - omapi_object_dereference - ((omapi_object_t **)&omapi_registered_messages, - "omapi_unregister_message"); + OBJECT_DEREF(&omapi_registered_messages, + "omapi_message_unregister"); if (n != NULL) - omapi_object_reference - ((omapi_object_t **)&omapi_registered_messages, - (omapi_object_t *)n, - "omapi_message_unregister"); + OBJECT_REF(&omapi_registered_messages, n, + "omapi_message_unregister"); } + if (n != NULL) - omapi_object_dereference ((omapi_object_t **)&n, - "omapi_message_unregister"); + OBJECT_DEREF(&n, "omapi_message_unregister"); + return (ISC_R_SUCCESS); } @@ -415,7 +402,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { } else type = NULL; if (tv != NULL) - omapi_value_dereference(&tv, "omapi_message_process"); + omapi_data_valuedereference(&tv, + "omapi_message_process"); /* * Get the create flag. @@ -423,7 +411,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { result = omapi_get_value_str(mo, NULL, "create", &tv); if (result == ISC_R_SUCCESS) { result = omapi_get_int_value(&create, tv->value); - omapi_value_dereference (&tv, "omapi_message_process"); + omapi_data_valuedereference(&tv, + "omapi_message_process"); if (result != ISC_R_SUCCESS) { return (omapi_protocol_send_status(po, NULL, result, message->id, @@ -438,7 +427,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { result = omapi_get_value_str(mo, NULL, "update", &tv); if (result == ISC_R_SUCCESS) { result = omapi_get_int_value(&update, tv->value); - omapi_value_dereference (&tv, "omapi_message_process"); + omapi_data_valuedereference(&tv, + "omapi_message_process"); if (result != ISC_R_SUCCESS) { return (omapi_protocol_send_status(po, NULL, result, message->id, @@ -453,7 +443,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { result = omapi_get_value_str(mo, NULL, "exclusive", &tv); if (result == ISC_R_SUCCESS) { result = omapi_get_int_value(&exclusive, tv->value); - omapi_value_dereference(&tv, "omapi_message_process"); + omapi_data_valuedereference(&tv, + "omapi_message_process"); if (result != ISC_R_SUCCESS) { return (omapi_protocol_send_status(po, NULL, result, message->id, @@ -516,8 +507,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { * return an error. */ if (result == ISC_R_SUCCESS && create != 0 && exclusive != 0) { - omapi_object_dereference(&object, - "omapi_message_process"); + OBJECT_DEREF(&object, "omapi_message_process"); return (omapi_protocol_send_status(po, NULL, ISC_R_EXISTS, message->id, "specified object already exists")); @@ -543,8 +533,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { message->object, message->handle); if (result != ISC_R_SUCCESS) { - omapi_object_dereference(&object, - "omapi_message_process"); + OBJECT_DEREF(&object, "omapi_message_process"); return (omapi_protocol_send_status(po, NULL, result, message->id, "can't update object")); @@ -567,13 +556,12 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { send: result = omapi_protocol_send_update(po, NULL, message->id, object); - omapi_object_dereference (&object, "omapi_message_process"); + OBJECT_DEREF(&object, "omapi_message_process"); return (result); case OMAPI_OP_UPDATE: if (m->object != NULL) { - omapi_object_reference(&object, m->object, - "omapi_message_process"); + OBJECT_REF(&object, m->object, "omapi_message_process"); } else { result = omapi_handle_lookup(&object, message->handle); if (result != ISC_R_SUCCESS) { @@ -586,8 +574,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { result = omapi_object_update(object, NULL, message->object, message->handle); if (result != ISC_R_SUCCESS) { - omapi_object_dereference(&object, - "omapi_message_process"); + OBJECT_DEREF(&object, "omapi_message_process"); if (message->rid == 0) return (omapi_protocol_send_status(po, NULL, result, message->id, @@ -626,7 +613,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { if (result == ISC_R_SUCCESS) { result = omapi_get_int_value(&wsi, tv->value); waitstatus = wsi; - omapi_value_dereference(&tv, "omapi_message_process"); + omapi_data_valuedereference(&tv, + "omapi_message_process"); if (result != ISC_R_SUCCESS) waitstatus = ISC_R_UNEXPECTED; } else @@ -635,7 +623,8 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { result = omapi_get_value_str(mo, NULL, "message", &tv); omapi_signal((omapi_object_t *)m, "status", waitstatus, tv); if (result == ISC_R_SUCCESS) - omapi_value_dereference(&tv, "omapi_message_process"); + omapi_data_valuedereference(&tv, + "omapi_message_process"); return (ISC_R_SUCCESS); case OMAPI_OP_DELETE: @@ -652,7 +641,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) { "no remove method for object")); result = (*(object->type->remove))(object, NULL); - omapi_object_dereference(&object, "omapi_message_process"); + OBJECT_DEREF(&object, "omapi_message_process"); return (omapi_protocol_send_status(po, NULL, result, message->id, NULL)); diff --git a/lib/omapi/object.c b/lib/omapi/object.c new file mode 100644 index 0000000000..4f4c262b65 --- /dev/null +++ b/lib/omapi/object.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 1996, 1997, 1998, 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* $Id: object.c,v 1.1 2000/01/04 20:04:40 tale Exp $ */ + +/* Principal Author: Ted Lemon */ + +/* + * Functions supporting memory allocation for the object management protocol. + */ +#include /* memset */ + +#include +#include + +#include + +void +omapi_object_reference(omapi_object_t **r, omapi_object_t *h, + const char *name) +{ + REQUIRE(r != NULL && *r == NULL); + REQUIRE(h != NULL); + + (void)name; /* Unused. */ + + *r = h; + h->refcnt++; +} + +void +omapi_object_dereference(omapi_object_t **h, const char *name) { + int outer_reference = 0; + int inner_reference = 0; + int handle_reference = 0; + int extra_references; + omapi_object_t *p; + + REQUIRE(h != NULL && *h != NULL); + REQUIRE((*h)->refcnt > 0); + + /* + * See if this object's inner object refers to it, but don't + * count this as a reference if we're being asked to free the + * reference from the inner object. + */ + if ((*h)->inner != NULL && (*h)->inner->outer != NULL && + h != &((*h)->inner->outer)) + inner_reference = 1; + + /* + * Ditto for the outer object. + */ + if ((*h)->outer != NULL && (*h)->outer->inner != NULL && + h != &((*h)->outer->inner)) + outer_reference = 1; + + /* + * Ditto for the handle object. The code below assumes that + * the only reason we'd get a dereference from the handle + * table is if this function does it - otherwise we'd have to + * traverse the handle table to find the address where the + * reference is stored and compare against that, and we don't + * want to do that if we can avoid it. + */ + if ((*h)->handle != 0) + handle_reference = 1; + + /* + * If we are getting rid of the last reference other than + * references to inner and outer objects, or from the handle + * table, then we must examine all the objects in either + * direction to see if they hold any non-inner, non-outer, + * non-handle-table references. If not, we need to free the + * entire chain of objects. + */ + if ((*h)->refcnt == + inner_reference + outer_reference + handle_reference + 1) { + if (inner_reference != 0 || + outer_reference != 0 || + handle_reference != 0) { + /* + * XXXTL we could check for a reference from the + * handle table here. + */ + extra_references = 0; + for (p = (*h)->inner; + p != NULL && extra_references == 0; + p = p->inner) { + extra_references += p->refcnt - 1; + if (p->inner != NULL) + --extra_references; + if (p->handle != 0) + --extra_references; + } + for (p = (*h)->outer; + p != NULL && extra_references == 0; + p = p->outer) { + extra_references += p->refcnt - 1; + if (p->outer != NULL) + --extra_references; + if (p->handle != 0) + --extra_references; + } + } else + extra_references = 0; + + if (extra_references == 0) { + if (inner_reference != 0) + OBJECT_DEREF(&(*h)->inner->outer, name); + if (outer_reference != 0) + OBJECT_DEREF(&(*h)->outer->inner, name); + if ((*h)->type->destroy != NULL) + (*((*h)->type->destroy))(*h, name); + isc_mem_put(omapi_mctx, *h, (*h)->object_size); + } + } + *h = NULL; +} diff --git a/lib/omapi/protocol.c b/lib/omapi/protocol.c index 4de73f86af..e477ff6b75 100644 --- a/lib/omapi/protocol.c +++ b/lib/omapi/protocol.c @@ -19,13 +19,13 @@ * Functions supporting the object management protocol. */ #include /* NULL */ -#include /* malloc, free */ +#include /* random */ #include /* memset */ #include #include -#include +#include typedef enum { omapi_protocol_intro_wait, @@ -78,22 +78,22 @@ omapi_protocol_connect(omapi_object_t *h, const char *server_name, isc_result_t result; omapi_protocol_object_t *obj; - obj = (omapi_protocol_object_t *)malloc(sizeof(*obj)); + obj = isc_mem_get(omapi_mctx, sizeof(*obj)); if (obj == NULL) return (ISC_R_NOMEMORY); memset(obj, 0, sizeof(*obj)); + obj->object_size = sizeof(*obj); obj->refcnt = 1; obj->type = omapi_type_protocol; - result = omapi_connect((omapi_object_t *)obj, server_name, port); + result = omapi_connection_toserver((omapi_object_t *)obj, + server_name, port); if (result != ISC_R_SUCCESS) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_protocol_connect"); + OBJECT_DEREF(&obj, "omapi_protocol_connect"); return (result); } - omapi_object_reference(&h->outer, (omapi_object_t *)obj, - "omapi_protocol_connect"); - omapi_object_reference(&obj->inner, h, "omapi_protocol_connect"); + OBJECT_REF(&h->outer, obj, "omapi_protocol_connect"); + OBJECT_REF(&obj->inner, h, "omapi_protocol_connect"); /* * Send the introductory message. @@ -102,16 +102,13 @@ omapi_protocol_connect(omapi_object_t *h, const char *server_name, OMAPI_PROTOCOL_VERSION, sizeof(omapi_protocol_header_t)); if (result != ISC_R_SUCCESS) { - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_protocol_connect"); + OBJECT_DEREF(&obj, "omapi_protocol_connect"); return (result); } if (authinfo) - omapi_object_reference(&obj->authinfo, authinfo, - "omapi_protocol_connect"); - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_protocol_accept"); + OBJECT_REF(&obj->authinfo, authinfo, "omapi_protocol_connect"); + OBJECT_DEREF(&obj, "omapi_protocol_accept"); return (ISC_R_SUCCESS); } @@ -123,20 +120,25 @@ omapi_protocol_send_intro(omapi_object_t *h, unsigned int ver, unsigned int hsize) { isc_result_t result; + isc_task_t *task; omapi_protocol_object_t *p; + omapi_connection_object_t *connection; REQUIRE(h != NULL && h->type == omapi_type_protocol); p = (omapi_protocol_object_t *)h; + connection = (omapi_connection_object_t *)h->outer; if (h->outer == NULL || h->outer->type != omapi_type_connection) return (ISC_R_NOTCONNECTED); - result = omapi_connection_put_uint32(h->outer, ver); + result = omapi_connection_put_uint32((omapi_object_t *)connection, + ver); if (result != ISC_R_SUCCESS) return (result); - result = omapi_connection_put_uint32(h->outer, hsize); + result = omapi_connection_put_uint32((omapi_object_t *)connection, + hsize); if (result != ISC_R_SUCCESS) return (result); @@ -146,7 +148,7 @@ omapi_protocol_send_intro(omapi_object_t *h, unsigned int ver, * protocol input state machine. */ p->state = omapi_protocol_intro_wait; - result = omapi_connection_require(h->outer, 8); + result = omapi_connection_require((omapi_object_t *)connection, 8); if (result != ISC_R_SUCCESS && result != ISC_R_NOTYET) return (result); @@ -155,6 +157,18 @@ omapi_protocol_send_intro(omapi_object_t *h, unsigned int ver, * XXXDCL better generator than random()? */ p->next_xid = random(); + + /* + * Send the intro. + */ + task = NULL; + result = isc_task_create(omapi_taskmgr, NULL, 0, &task); + if (result != ISC_R_SUCCESS) + return (result); + + isc_socket_sendv(connection->socket, &connection->output_buffers, + task, omapi_connection_written, connection); + return (ISC_R_SUCCESS); } @@ -166,6 +180,7 @@ omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id, omapi_object_t *c; omapi_message_object_t *m; omapi_message_object_t *om; + isc_task_t *task; isc_result_t result; REQUIRE(po != NULL && po->type == omapi_type_protocol && @@ -277,6 +292,16 @@ omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id, /* XXXTL Write the authenticator... */ + + task = NULL; + result = isc_task_create(omapi_taskmgr, NULL, 0, &task); + if (result != ISC_R_SUCCESS) + return (result); + + isc_socket_sendv(((omapi_connection_object_t *)c)->socket, + &((omapi_connection_object_t *)c)->output_buffers, + task, omapi_connection_written, c); + return (ISC_R_SUCCESS); } @@ -285,7 +310,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) { isc_result_t result; omapi_protocol_object_t *p; - omapi_object_t *c; + omapi_object_t *connection; isc_uint16_t nlen; isc_uint32_t vlen; @@ -296,16 +321,12 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) /* * Not a signal we recognize? */ - if (strcmp(name, "ready") != 0) { - if (p->inner != NULL && p->inner->type->signal_handler != NULL) - return (*(p->inner->type->signal_handler))(h, name, - ap); - return (ISC_R_NOTFOUND); - } + if (strcmp(name, "ready") != 0) + PASS_SIGNAL(h); INSIST(p->outer != NULL && p->outer->type == omapi_type_connection); - c = p->outer; + connection = p->outer; /* * We get here because we requested that we be woken up after @@ -318,30 +339,29 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) * Get protocol version and header size in network * byte order. */ - omapi_connection_get_uint32(c, + omapi_connection_get_uint32(connection, (isc_uint32_t *) &p->protocol_version); - omapi_connection_get_uint32(c, + omapi_connection_get_uint32(connection, (isc_uint32_t *)&p->header_size); /* * We currently only support the current protocol version. */ if (p->protocol_version != OMAPI_PROTOCOL_VERSION) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (ISC_R_VERSIONMISMATCH); } if (p->header_size < sizeof(omapi_protocol_header_t)) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (ISC_R_PROTOCOLERROR); } result = omapi_signal_in(h->inner, "ready"); - if (result != NULL) { + if (result != ISC_R_SUCCESS) /* XXXDCL disconnect? */ return (result); - } to_header_wait: /* @@ -354,7 +374,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) * header, and if we already have that many, process * them immediately. */ - if ((omapi_connection_require(c, p->header_size)) + if ((omapi_connection_require(connection, p->header_size)) != ISC_R_SUCCESS) break; /* @@ -365,33 +385,34 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) result = omapi_message_new((omapi_object_t **)&p->message, "omapi_protocol_signal_handler"); if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } /* * Swap in the header. */ - omapi_connection_get_uint32(c, + omapi_connection_get_uint32(connection, (isc_uint32_t *)&p->message->authid); /* XXXTL bind the authenticator here! */ - omapi_connection_get_uint32(c, + omapi_connection_get_uint32(connection, (isc_uint32_t *)&p->message->authlen); - omapi_connection_get_uint32(c, + omapi_connection_get_uint32(connection, (isc_uint32_t *)&p->message->op); - omapi_connection_get_uint32(c, + omapi_connection_get_uint32(connection, (isc_uint32_t *)&p->message->handle); - omapi_connection_get_uint32(c, + omapi_connection_get_uint32(connection, (isc_uint32_t *)&p->message->id); - omapi_connection_get_uint32(c, + omapi_connection_get_uint32(connection, (isc_uint32_t *)&p->message->rid); /* * If there was any extra header data, skip over it. */ if (p->header_size > sizeof(omapi_protocol_header_t)) { - omapi_connection_copyout(0, c, (p->header_size - + omapi_connection_copyout(0, connection, + (p->header_size - sizeof(omapi_protocol_header_t))); } @@ -417,16 +438,16 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) /* * Wait for a 16-bit length. */ - if (omapi_connection_require(c, 2) != ISC_R_SUCCESS) + if (omapi_connection_require(connection, 2) != ISC_R_SUCCESS) break; /* * If it's already here, fall through. */ case omapi_protocol_name_length_wait: - result = omapi_connection_get_uint16(c, &nlen); + result = omapi_connection_get_uint16(connection, &nlen); if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } @@ -466,7 +487,8 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) * the authenticator. If we already have it, * go read it in. */ - if (omapi_connection_require(c, p->message->authlen) + if (omapi_connection_require(connection, + p->message->authlen) == ISC_R_SUCCESS) goto signature_wait; break; @@ -475,14 +497,15 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) /* * Allocate a buffer for the name. */ - result = omapi_data_string_new(&p->name, nlen, + result = omapi_data_newstring(&p->name, nlen, "omapi_protocol_signal_handler"); if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } p->state = omapi_protocol_name_wait; - if (omapi_connection_require(c, nlen) != ISC_R_SUCCESS) + if (omapi_connection_require(connection, nlen) != + ISC_R_SUCCESS) break; /* @@ -490,10 +513,10 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) * */ case omapi_protocol_name_wait: - result = omapi_connection_copyout(p->name->value, c, + result = omapi_connection_copyout(p->name->value, connection, p->name->len); if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } @@ -501,7 +524,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) * Wait for a 32-bit length. */ p->state = omapi_protocol_value_length_wait; - if (omapi_connection_require(c, 4) != ISC_R_SUCCESS) + if (omapi_connection_require(connection, 4) != ISC_R_SUCCESS) break; /* @@ -509,7 +532,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) */ case omapi_protocol_value_length_wait: - omapi_connection_get_uint32(c, &vlen); + omapi_connection_get_uint32(connection, &vlen); /* * Zero-length values are allowed - if we get one, we @@ -519,26 +542,27 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) if (vlen == 0) goto insert_new_value; - result = omapi_typed_data_new(&p->value, + result = omapi_data_new(&p->value, omapi_datatype_data, vlen, "omapi_protocol_signal_handler"); if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } p->state = omapi_protocol_value_wait; - if (omapi_connection_require(c, vlen) != ISC_R_SUCCESS) + if (omapi_connection_require(connection, vlen) != ISC_R_SUCCESS) break; /* * If it's already here, fall through. */ case omapi_protocol_value_wait: - result = omapi_connection_copyout(p->value->u.buffer.value, c, + result = omapi_connection_copyout(p->value->u.buffer.value, + connection, p->value->u.buffer.len); if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } @@ -556,7 +580,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) result = omapi_generic_new(&p->message->object, "omapi_protocol_signal_handler"); if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } @@ -567,30 +591,30 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) p->name, p->value)); } if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } - omapi_data_string_dereference(&p->name, + omapi_data_stringdereference(&p->name, "omapi_protocol_signal_handler"); - omapi_typed_data_dereference(&p->value, - "omapi_protocol_signal_handler"); + omapi_data_dereference(&p->value, + "omapi_protocol_signal_handler"); goto need_name_length; signature_wait: case omapi_protocol_signature_wait: - result = omapi_typed_data_new(&p->message->authenticator, - omapi_datatype_data, - p->message->authlen); - + result = omapi_data_new(&p->message->authenticator, + omapi_datatype_data, + p->message->authlen); + if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } result = (omapi_connection_copyout - (p->message->authenticator->u.buffer.value, c, - p->message->authlen)); + (p->message->authenticator->u.buffer.value, + connection, p->message->authlen)); if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } @@ -603,13 +627,12 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap) result = omapi_message_process((omapi_object_t *)p->message, h); if (result != ISC_R_SUCCESS) { - omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); + omapi_disconnect(connection, OMAPI_FORCE_DISCONNECT); return (result); } /* XXXTL unbind the authenticator. */ - omapi_object_dereference((omapi_object_t **)&p->message, - "omapi_protocol_signal_handler"); + OBJECT_DEREF(&p->message, "omapi_protocol_signal_handler"); /* * Now wait for the next message. @@ -662,10 +685,10 @@ omapi_protocol_destroy(omapi_object_t *h, const char *name) { p = (omapi_protocol_object_t *)h; if (p->message != NULL) - omapi_object_dereference((omapi_object_t **)&p->message, name); + OBJECT_DEREF(&p->message, name); if (p->authinfo != NULL) - omapi_object_dereference(&p->authinfo, name); + OBJECT_DEREF(&p->authinfo, name); } /* @@ -694,21 +717,20 @@ omapi_protocol_listen(omapi_object_t *h, int port, int max) { isc_result_t result; omapi_protocol_listener_object_t *obj; - obj = (omapi_protocol_listener_object_t *)malloc(sizeof(*obj)); + obj = isc_mem_get(omapi_mctx, sizeof(*obj)); if (obj == NULL) return (ISC_R_NOMEMORY); memset(obj, 0, sizeof(*obj)); + obj->object_size = sizeof(*obj); obj->refcnt = 1; obj->type = omapi_type_protocol_listener; - omapi_object_reference(&h->outer, (omapi_object_t *)obj, - "omapi_protocol_listen"); - omapi_object_reference(&obj->inner, h, "omapi_protocol_listen"); + OBJECT_REF(&h->outer, obj, "omapi_protocol_listen"); + OBJECT_REF(&obj->inner, h, "omapi_protocol_listen"); - result = omapi_listen((omapi_object_t *)obj, port, max); + result = omapi_listener_listen((omapi_object_t *)obj, port, max); - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_protocol_listen"); + OBJECT_DEREF(&obj, "omapi_protocol_listen"); return (result); } @@ -743,17 +765,16 @@ omapi_protocol_listener_signal(omapi_object_t *h, const char *name, va_list ap) INSIST(c != NULL && c->type == omapi_type_connection); - obj = (omapi_protocol_object_t *)malloc(sizeof(*obj)); + obj = isc_mem_get(omapi_mctx, sizeof(*obj)); if (obj == NULL) return (ISC_R_NOMEMORY); - memset(obj, 0, sizeof(*obj)); + obj->object_size = sizeof(*obj); obj->refcnt = 1; obj->type = omapi_type_protocol; - omapi_object_reference(&obj->outer, c, "omapi_protocol_accept"); - omapi_object_reference(&c->inner, (omapi_object_t *)obj, - "omapi_protocol_accept"); + OBJECT_REF(&obj->outer, c, "omapi_protocol_accept"); + OBJECT_REF(&c->inner, obj, "omapi_protocol_accept"); /* * Send the introductory message. @@ -765,8 +786,7 @@ omapi_protocol_listener_signal(omapi_object_t *h, const char *name, va_list ap) if (result != ISC_R_SUCCESS) omapi_disconnect(c, OMAPI_FORCE_DISCONNECT); - omapi_object_dereference((omapi_object_t **)&obj, - "omapi_protocol_accept"); + OBJECT_DEREF(&obj, "omapi_protocol_accept"); return (result); } @@ -847,12 +867,10 @@ omapi_protocol_send_status(omapi_object_t *po, omapi_object_t *id, * If a message has been provided, send it. */ if (result == ISC_R_SUCCESS && msg != NULL) - result = omapi_set_string_value (message, NULL, - "message", msg); + result = omapi_set_string_value(message, NULL, "message", msg); if (result != ISC_R_SUCCESS) { - omapi_object_dereference(&message, - "omapi_protocol_send_status"); + OBJECT_DEREF(&message, "omapi_protocol_send_status"); return (result); } @@ -872,7 +890,7 @@ omapi_protocol_send_update(omapi_object_t *po, omapi_object_t *id, if (result != ISC_R_SUCCESS) return (result); - result = omapi_set_int_value (message, NULL, "op", OMAPI_OP_UPDATE); + result = omapi_set_int_value(message, NULL, "op", OMAPI_OP_UPDATE); if (result == ISC_R_SUCCESS && rid != 0) { omapi_handle_t handle; @@ -892,7 +910,7 @@ omapi_protocol_send_update(omapi_object_t *po, omapi_object_t *id, "object", object); if (result != ISC_R_SUCCESS) { - omapi_object_dereference (&message, "dhcpctl_open_object"); + OBJECT_DEREF(&message, "dhcpctl_open_object"); return (result); } diff --git a/lib/omapi/support.c b/lib/omapi/support.c index e95fdce520..ef8dcd0103 100644 --- a/lib/omapi/support.c +++ b/lib/omapi/support.c @@ -19,12 +19,11 @@ * Subroutines providing general support for objects. */ #include /* NULL */ -#include /* malloc, free */ #include /* memset */ #include -#include +#include omapi_object_type_t *omapi_type_connection; omapi_object_type_t *omapi_type_listener; @@ -40,10 +39,51 @@ omapi_object_type_t *omapi_type_message; omapi_object_type_t *omapi_object_types; int omapi_object_type_count; +isc_mem_t *omapi_mctx; +isc_taskmgr_t *omapi_taskmgr; +isc_timermgr_t *omapi_timermgr; +isc_socketmgr_t *omapi_socketmgr; + +isc_boolean_t omapi_ipv6 = ISC_FALSE; + isc_result_t -omapi_init(void) { +omapi_init(isc_mem_t *mctx) { isc_result_t result; + /* + * XXXDCL probeipv6? + */ + + if (mctx != NULL) + omapi_mctx = mctx; + + else { + omapi_mctx = NULL; + result = isc_mem_create(0, 0, &omapi_mctx); + if (result != ISC_R_SUCCESS) + return (result); + } + + omapi_socketmgr = NULL; + result = isc_socketmgr_create(omapi_mctx, &omapi_socketmgr); + if (result != ISC_R_SUCCESS) + return (result); + + omapi_taskmgr = NULL; + result = isc_taskmgr_create(omapi_mctx, 1, 0, &omapi_taskmgr); + if (result != ISC_R_SUCCESS) + return (result); + + omapi_timermgr = NULL; + result = isc_timermgr_create(omapi_mctx, &omapi_timermgr); + if (result != ISC_R_SUCCESS) + return (result); + + if (isc_net_probeipv6() == ISC_R_SUCCESS) + omapi_ipv6 = ISC_TRUE; + else + omapi_ipv6 = ISC_FALSE; + /* * Register all the standard object types. */ @@ -60,11 +100,11 @@ omapi_init(void) { result = omapi_object_type_register(&omapi_type_listener, "listener", - omapi_listener_set_value, - omapi_listener_get_value, + omapi_listener_setvalue, + omapi_listener_getvalue, omapi_listener_destroy, - omapi_listener_signal_handler, - omapi_listener_stuff_values, + omapi_listener_signalhandler, + omapi_listener_stuffvalues, 0, 0, 0); if (result != ISC_R_SUCCESS) return (result); @@ -177,7 +217,7 @@ omapi_object_type_register(omapi_object_type_t **type, const char *name, { omapi_object_type_t *t; - t = malloc(sizeof(*t)); + t = isc_mem_get(omapi_mctx, sizeof(*t)); if (t == NULL) return (ISC_R_NOMEMORY); memset(t, 0, sizeof(*t)); @@ -252,11 +292,11 @@ omapi_set_value_str(omapi_object_t *h, omapi_object_t *id, isc_result_t result; nds = NULL; - result = omapi_data_string_new(&nds, strlen (name), - "omapi_set_value_str"); + result = omapi_data_newstring(&nds, strlen(name), + "omapi_set_value_str"); if (result != ISC_R_SUCCESS) return (result); - memcpy(nds->value, name, strlen (name)); + memcpy(nds->value, name, strlen(name)); return (omapi_set_value(h, id, nds, value)); } @@ -269,21 +309,21 @@ omapi_set_boolean_value(omapi_object_t *h, omapi_object_t *id, omapi_typed_data_t *tv = NULL; omapi_data_string_t *n = NULL; - result = omapi_data_string_new(&n, strlen (name), - "omapi_set_boolean_value"); + result = omapi_data_newstring(&n, strlen(name), + "omapi_set_boolean_value"); if (result != ISC_R_SUCCESS) return (result); - memcpy(n->value, name, strlen (name)); + memcpy(n->value, name, strlen(name)); - result = omapi_typed_data_new(&tv, omapi_datatype_int, value); + result = omapi_data_new(&tv, omapi_datatype_int, value); if (result != ISC_R_SUCCESS) { - omapi_data_string_dereference(&n, "omapi_set_boolean_value"); + omapi_data_stringdereference(&n, "omapi_set_boolean_value"); return (result); } result = omapi_set_value(h, id, n, tv); - omapi_data_string_dereference(&n, "omapi_set_boolean_value"); - omapi_typed_data_dereference(&tv, "omapi_set_boolean_value"); + omapi_data_stringdereference(&n, "omapi_set_boolean_value"); + omapi_data_dereference(&tv, "omapi_set_boolean_value"); return (result); } @@ -295,21 +335,21 @@ omapi_set_int_value(omapi_object_t *h, omapi_object_t *id, omapi_typed_data_t *tv = NULL; omapi_data_string_t *n = NULL; - result = omapi_data_string_new(&n, strlen (name), - "omapi_set_int_value"); + result = omapi_data_newstring(&n, strlen(name), + "omapi_set_int_value"); if (result != ISC_R_SUCCESS) return (result); memcpy(n->value, name, strlen(name)); - result = omapi_typed_data_new(&tv, omapi_datatype_int, value); + result = omapi_data_new(&tv, omapi_datatype_int, value); if (result != ISC_R_SUCCESS) { - omapi_data_string_dereference(&n, "omapi_set_int_value"); + omapi_data_stringdereference(&n, "omapi_set_int_value"); return (result); } result = omapi_set_value(h, id, n, tv); - omapi_data_string_dereference(&n, "omapi_set_int_value"); - omapi_typed_data_dereference(&tv, "omapi_set_int_value"); + omapi_data_stringdereference(&n, "omapi_set_int_value"); + omapi_data_dereference(&tv, "omapi_set_int_value"); return (result); } @@ -321,21 +361,21 @@ omapi_set_object_value(omapi_object_t *h, omapi_object_t *id, omapi_typed_data_t *tv = NULL; omapi_data_string_t *n = NULL; - result = omapi_data_string_new (&n, strlen (name), - "omapi_set_object_value"); + result = omapi_data_newstring(&n, strlen(name), + "omapi_set_object_value"); if (result != ISC_R_SUCCESS) return (result); - memcpy(n->value, name, strlen (name)); + memcpy(n->value, name, strlen(name)); - result = omapi_typed_data_new(&tv, omapi_datatype_object, value); + result = omapi_data_new(&tv, omapi_datatype_object, value); if (result != ISC_R_SUCCESS) { - omapi_data_string_dereference(&n, "omapi_set_object_value"); + omapi_data_stringdereference(&n, "omapi_set_object_value"); return (result); } result = omapi_set_value(h, id, n, tv); - omapi_data_string_dereference(&n, "omapi_set_object_value"); - omapi_typed_data_dereference(&tv, "omapi_set_object_value"); + omapi_data_stringdereference(&n, "omapi_set_object_value"); + omapi_data_dereference(&tv, "omapi_set_object_value"); return (result); } @@ -347,21 +387,21 @@ omapi_set_string_value(omapi_object_t *h, omapi_object_t *id, omapi_typed_data_t *tv = NULL; omapi_data_string_t *n = NULL; - result = omapi_data_string_new(&n, strlen (name), - "omapi_set_string_value"); + result = omapi_data_newstring(&n, strlen(name), + "omapi_set_string_value"); if (result != ISC_R_SUCCESS) return (result); - memcpy(n->value, name, strlen (name)); + memcpy(n->value, name, strlen(name)); - result = omapi_typed_data_new(&tv, omapi_datatype_string, value); + result = omapi_data_new(&tv, omapi_datatype_string, value); if (result != ISC_R_SUCCESS) { - omapi_data_string_dereference(&n, "omapi_set_string_value"); + omapi_data_stringdereference(&n, "omapi_set_string_value"); return (result); } result = omapi_set_value(h, id, n, tv); - omapi_data_string_dereference(&n, "omapi_set_string_value"); - omapi_typed_data_dereference(&tv, "omapi_set_string_value"); + omapi_data_stringdereference(&n, "omapi_set_string_value"); + omapi_data_dereference(&tv, "omapi_set_string_value"); return (result); } @@ -387,11 +427,11 @@ omapi_get_value_str(omapi_object_t *h, omapi_object_t *id, isc_result_t result; nds = NULL; - result = omapi_data_string_new(&nds, strlen (name), - "omapi_get_value_str"); + result = omapi_data_newstring(&nds, strlen(name), + "omapi_get_value_str"); if (result != ISC_R_SUCCESS) return (result); - memcpy(nds->value, name, strlen (name)); + memcpy(nds->value, name, strlen(name)); for (outer = h; outer->outer != NULL; outer = outer->outer) ; @@ -479,7 +519,7 @@ omapi_ds_strcmp(omapi_data_string_t *s1, const char *s2) { unsigned int len, slen; int rv; - slen = strlen (s2); + slen = strlen(s2); if (slen > s1->len) len = s1->len; else @@ -523,14 +563,14 @@ omapi_make_value(omapi_value_t **vp, omapi_data_string_t *name, { isc_result_t result; - result = omapi_value_new(vp, caller); + result = omapi_data_newvalue(vp, caller); if (result != ISC_R_SUCCESS) return (result); - omapi_data_string_reference(&(*vp)->name, name, caller); + omapi_data_stringreference(&(*vp)->name, name, caller); if (value != NULL) - omapi_typed_data_reference(&(*vp)->value, value, caller); + omapi_data_reference(&(*vp)->value, value, caller); return (result); @@ -543,21 +583,21 @@ omapi_make_const_value(omapi_value_t **vp, omapi_data_string_t *name, { isc_result_t result; - result = omapi_value_new(vp, caller); + result = omapi_data_newvalue(vp, caller); if (result != ISC_R_SUCCESS) return (result); - omapi_data_string_reference(&(*vp)->name, name, caller); + omapi_data_stringreference(&(*vp)->name, name, caller); if (value != NULL) { - result = omapi_typed_data_new(&(*vp)->value, - omapi_datatype_data, len); + result = omapi_data_new(&(*vp)->value, omapi_datatype_data, + len); if (result == ISC_R_SUCCESS) memcpy((*vp)->value->u.buffer.value, value, len); } if (result != ISC_R_SUCCESS) - omapi_value_dereference(vp, caller); + omapi_data_valuedereference(vp, caller); return (result); } @@ -568,22 +608,21 @@ omapi_make_int_value(omapi_value_t **vp, omapi_data_string_t *name, { isc_result_t result; - result = omapi_value_new (vp, caller); + result = omapi_data_newvalue(vp, caller); if (result != ISC_R_SUCCESS) return (result); - omapi_data_string_reference(&(*vp)->name, name, caller); + omapi_data_stringreference(&(*vp)->name, name, caller); - if (value != NULL) { - result = omapi_typed_data_new(&(*vp)->value, - omapi_datatype_int); + if (value != 0) { + result = omapi_data_new(&(*vp)->value, omapi_datatype_int); if (result == ISC_R_SUCCESS) (*vp)->value->u.integer = value; } if (result != ISC_R_SUCCESS) - omapi_value_dereference(vp, caller); + omapi_data_valuedereference(vp, caller); return (result); } @@ -594,15 +633,14 @@ omapi_make_handle_value(omapi_value_t **vp, omapi_data_string_t *name, { isc_result_t result; - result = omapi_value_new(vp, caller); + result = omapi_data_newvalue(vp, caller); if (result != ISC_R_SUCCESS) return (result); - omapi_data_string_reference(&(*vp)->name, name, caller); + omapi_data_stringreference(&(*vp)->name, name, caller); if (value != NULL) { - result = omapi_typed_data_new(&(*vp)->value, - omapi_datatype_int); + result = omapi_data_new(&(*vp)->value, omapi_datatype_int); if (result == ISC_R_SUCCESS) result = (omapi_object_handle @@ -611,7 +649,7 @@ omapi_make_handle_value(omapi_value_t **vp, omapi_data_string_t *name, } if (result != ISC_R_SUCCESS) - omapi_value_dereference(vp, caller); + omapi_data_valuedereference(vp, caller); return (result); } @@ -622,18 +660,18 @@ omapi_make_string_value(omapi_value_t **vp, omapi_data_string_t *name, { isc_result_t result; - result = omapi_value_new(vp, caller); + result = omapi_data_newvalue(vp, caller); if (result != ISC_R_SUCCESS) return (result); - omapi_data_string_reference(&(*vp)->name, name, caller); + omapi_data_stringreference(&(*vp)->name, name, caller); if (value != NULL) - result = omapi_typed_data_new(&(*vp)->value, - omapi_datatype_string, value); + result = omapi_data_new(&(*vp)->value, omapi_datatype_string, + value); if (result != ISC_R_SUCCESS) - omapi_value_dereference(vp, caller); + omapi_data_valuedereference(vp, caller); return (result); }