isc_result_t omapi_connection_copyin (omapi_object_t *h, const unsigned char *bufp, unsigned len) { omapi_buffer_t *buffer; isc_result_t status; int bytes_copied = 0; unsigned copy_len; int sig_flags = SIG_MODE_UPDATE; omapi_connection_object_t *c; /* Make sure len is valid. */ //if (len < 0) //return ISC_R_INVALIDARG; if (!h || h -> type != omapi_type_connection) return ISC_R_INVALIDARG; c = (omapi_connection_object_t *)h; /* If the connection is closed, return an error if the caller tries to copy in. */ if (c -> state == omapi_connection_disconnecting || c -> state == omapi_connection_closed) return ISC_R_NOTCONNECTED; if (c -> outbufs) { for (buffer = c -> outbufs; buffer -> next; buffer = buffer -> next) ; } else { status = omapi_buffer_new (&c -> outbufs, MDL); if (status != ISC_R_SUCCESS) return status; buffer = c -> outbufs; } while (bytes_copied < len) { /* If there is no space available in this buffer, allocate a new one. */ if (!BUFFER_BYTES_FREE (buffer)) { status = (omapi_buffer_new (&buffer -> next, MDL)); if (status != ISC_R_SUCCESS) return status; buffer = buffer -> next; } if (buffer -> tail > buffer -> head) copy_len = sizeof (buffer -> buf) - buffer -> tail; else copy_len = buffer -> head - buffer -> tail; if (copy_len > (len - bytes_copied)) copy_len = len - bytes_copied; if (c -> out_key) { if (!c -> out_context) sig_flags |= SIG_MODE_INIT; status = omapi_connection_sign_data (sig_flags, c -> out_key, &c -> out_context, &bufp [bytes_copied], copy_len, (omapi_typed_data_t **)0); if (status != ISC_R_SUCCESS) return status; } memcpy (&buffer -> buf [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 -> buf) buffer -> tail = 0; } return ISC_R_SUCCESS; }
isc_result_t omapi_connection_copyout (unsigned char *buf, omapi_object_t *h, unsigned size) { unsigned bytes_remaining; unsigned bytes_this_copy; unsigned first_byte; omapi_buffer_t *buffer; unsigned char *bufp; int sig_flags = SIG_MODE_UPDATE; omapi_connection_object_t *c; isc_result_t status; if (!h || h -> type != omapi_type_connection) return ISC_R_INVALIDARG; c = (omapi_connection_object_t *)h; if (size > c -> in_bytes) return ISC_R_NOMORE; bufp = buf; bytes_remaining = size; buffer = c -> inbufs; while (bytes_remaining) { if (!buffer) return ISC_R_UNEXPECTED; if (BYTES_IN_BUFFER (buffer)) { if (buffer -> head == (sizeof buffer -> buf) - 1) first_byte = 0; else first_byte = buffer -> head + 1; if (first_byte > buffer -> tail) { bytes_this_copy = (sizeof buffer -> buf - first_byte); } else { bytes_this_copy = buffer -> tail - first_byte; } if (bytes_this_copy > bytes_remaining) bytes_this_copy = bytes_remaining; if (bufp) { if (c -> in_key) { if (!c -> in_context) sig_flags |= SIG_MODE_INIT; status = omapi_connection_sign_data (sig_flags, c -> in_key, &c -> in_context, (unsigned char *) &buffer -> buf [first_byte], bytes_this_copy, (omapi_typed_data_t **)0); if (status != ISC_R_SUCCESS) return status; } memcpy (bufp, &buffer -> buf [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)) buffer = buffer -> next; } /* Get rid of any input buffers that we emptied. */ buffer = (omapi_buffer_t *)0; while (c -> inbufs && !BYTES_IN_BUFFER (c -> inbufs)) { if (c -> inbufs -> next) { omapi_buffer_reference (&buffer, c -> inbufs -> next, MDL); omapi_buffer_dereference (&c -> inbufs -> next, MDL); } omapi_buffer_dereference (&c -> inbufs, MDL); if (buffer) { omapi_buffer_reference (&c -> inbufs, buffer, MDL); omapi_buffer_dereference (&buffer, MDL); } } return ISC_R_SUCCESS; }
isc_result_t omapi_connection_copyin (omapi_object_t *h, const unsigned char *bufp, unsigned len) { omapi_buffer_t *buffer; isc_result_t status; int bytes_copied = 0; unsigned copy_len; int sig_flags = SIG_MODE_UPDATE; omapi_connection_object_t *c; /* no need to verify len as it's unsigned */ if (!h || h -> type != omapi_type_connection) return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; /* If the connection is closed, return an error if the caller tries to copy in. */ if (c -> state == omapi_connection_disconnecting || c -> state == omapi_connection_closed) return ISC_R_NOTCONNECTED; if (c -> outbufs) { for (buffer = c -> outbufs; buffer -> next; buffer = buffer -> next) ; } else { status = omapi_buffer_new (&c -> outbufs, MDL); if (status != ISC_R_SUCCESS) goto leave; buffer = c -> outbufs; } while (bytes_copied < len) { /* If there is no space available in this buffer, allocate a new one. */ if (!BUFFER_BYTES_FREE (buffer)) { status = (omapi_buffer_new (&buffer -> next, MDL)); if (status != ISC_R_SUCCESS) goto leave; buffer = buffer -> next; } if (buffer -> tail > buffer -> head) copy_len = sizeof (buffer -> buf) - buffer -> tail; else copy_len = buffer -> head - buffer -> tail; if (copy_len > (len - bytes_copied)) copy_len = len - bytes_copied; if (c -> out_key) { if (!c -> out_context) sig_flags |= SIG_MODE_INIT; status = omapi_connection_sign_data (sig_flags, c -> out_key, &c -> out_context, &bufp [bytes_copied], copy_len, (omapi_typed_data_t **)0); if (status != ISC_R_SUCCESS) goto leave; } memcpy (&buffer -> buf [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 -> buf) buffer -> tail = 0; } status = ISC_R_SUCCESS; leave: /* * If we have any bytes to send and we have a proper io object * inform the socket code that we would like to know when we * can send more bytes. */ if (c->out_bytes != 0) { if ((c->outer != NULL) && (c->outer->type == omapi_type_io_object)) { omapi_io_object_t *io = (omapi_io_object_t *)c->outer; isc_socket_fdwatchpoke(io->fd, ISC_SOCKFDWATCH_WRITE); } } return (status); }