2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-29 13:28:14 +00:00

- Fix buffer head/tail code.

- Correctly handle no more data and remote disconnect.
This commit is contained in:
Ted Lemon 1999-10-19 15:36:16 +00:00
parent abf550084b
commit c936e8c172

View File

@ -51,7 +51,7 @@ isc_result_t omapi_connection_reader (omapi_object_t *h)
for (buffer = c -> inbufs; buffer -> next; for (buffer = c -> inbufs; buffer -> next;
buffer = buffer -> next) buffer = buffer -> next)
; ;
if (!BUFFER_BYTES_AVAIL (buffer)) { if (!BUFFER_BYTES_FREE (buffer)) {
status = omapi_buffer_new (&buffer -> next, status = omapi_buffer_new (&buffer -> next,
"omapi_private_read"); "omapi_private_read");
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
@ -66,19 +66,19 @@ isc_result_t omapi_connection_reader (omapi_object_t *h)
buffer = c -> inbufs; buffer = c -> inbufs;
} }
bytes_to_read = BUFFER_BYTES_AVAIL (buffer); bytes_to_read = BUFFER_BYTES_FREE (buffer);
while (bytes_to_read) { while (bytes_to_read) {
if (buffer -> tail >= buffer -> head) if (buffer -> tail > buffer -> head)
read_len = sizeof (buffer -> buf) - buffer -> tail - 1; read_len = sizeof (buffer -> buf) - buffer -> tail;
else else
read_len = buffer -> tail - buffer -> head - 1; read_len = buffer -> head - buffer -> tail;
read_status = read (c -> socket, read_status = read (c -> socket,
&buffer -> buf [buffer -> tail], read_len); &buffer -> buf [buffer -> tail], read_len);
if (read_status < 0) { if (read_status < 0) {
if (errno == EWOULDBLOCK) if (errno == EWOULDBLOCK)
return ISC_R_NOMORE; break;
else if (errno == EIO) else if (errno == EIO)
return ISC_R_IOERROR; return ISC_R_IOERROR;
else if (errno == EINVAL) else if (errno == EINVAL)
@ -89,6 +89,8 @@ isc_result_t omapi_connection_reader (omapi_object_t *h)
} else } else
return ISC_R_UNEXPECTED; 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) { if (read_status == 0) {
omapi_disconnect (h, 0); omapi_disconnect (h, 0);
return ISC_R_SHUTTINGDOWN; return ISC_R_SHUTTINGDOWN;
@ -142,7 +144,7 @@ isc_result_t omapi_connection_copyin (omapi_object_t *h,
while (bytes_copied < len) { while (bytes_copied < len) {
/* If there is no space available in this buffer, /* If there is no space available in this buffer,
allocate a new one. */ allocate a new one. */
if (!BUFFER_BYTES_AVAIL (buffer)) { if (!BUFFER_BYTES_FREE (buffer)) {
status = (omapi_buffer_new status = (omapi_buffer_new
(&buffer -> next, (&buffer -> next,
"omapi_private_buffer_copyin")); "omapi_private_buffer_copyin"));
@ -151,10 +153,11 @@ isc_result_t omapi_connection_copyin (omapi_object_t *h,
buffer = buffer -> next; buffer = buffer -> next;
} }
if (buffer -> tail < buffer -> head) if (buffer -> tail > buffer -> head)
copy_len = buffer -> tail - buffer -> head - 1; copy_len = sizeof (buffer -> buf) - buffer -> tail;
else else
copy_len = sizeof (buffer -> buf) - buffer -> tail - 1; copy_len = buffer -> head - buffer -> tail;
if (copy_len > (len - bytes_copied)) if (copy_len > (len - bytes_copied))
copy_len = len - bytes_copied; copy_len = len - bytes_copied;
@ -178,6 +181,7 @@ isc_result_t omapi_connection_copyout (unsigned char *buf,
{ {
unsigned bytes_remaining; unsigned bytes_remaining;
unsigned bytes_this_copy; unsigned bytes_this_copy;
unsigned first_byte;
omapi_buffer_t *buffer; omapi_buffer_t *buffer;
unsigned char *bufp; unsigned char *bufp;
omapi_connection_object_t *c; omapi_connection_object_t *c;
@ -195,36 +199,39 @@ isc_result_t omapi_connection_copyout (unsigned char *buf,
while (bytes_remaining) { while (bytes_remaining) {
if (!buffer) if (!buffer)
return ISC_R_UNEXPECTED; return ISC_R_UNEXPECTED;
if (buffer -> head != buffer -> tail) { if (BYTES_IN_BUFFER (buffer)) {
if (buffer -> head > buffer -> tail) { 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 - bytes_this_copy = (sizeof buffer -> buf -
buffer -> head); first_byte);
} else { } else {
bytes_this_copy = bytes_this_copy =
buffer -> tail - buffer -> head; buffer -> tail - first_byte;
} }
if (bytes_this_copy > bytes_remaining) if (bytes_this_copy > bytes_remaining)
bytes_this_copy = bytes_remaining; bytes_this_copy = bytes_remaining;
if (bufp) { if (bufp) {
memcpy (bufp, &buffer -> buf [buffer -> head], memcpy (bufp, &buffer -> buf [first_byte],
bytes_this_copy); bytes_this_copy);
bufp += bytes_this_copy; bufp += bytes_this_copy;
} }
bytes_remaining -= bytes_this_copy; bytes_remaining -= bytes_this_copy;
buffer -> head += bytes_this_copy; buffer -> head = first_byte + bytes_this_copy - 1;
if (buffer -> head == sizeof buffer -> buf)
buffer -> head = 0;
c -> in_bytes -= bytes_this_copy; c -> in_bytes -= bytes_this_copy;
} }
if (buffer -> head == buffer -> tail) if (!BYTES_IN_BUFFER (buffer))
buffer = buffer -> next; buffer = buffer -> next;
} }
/* Get rid of any input buffers that we emptied. */ /* Get rid of any input buffers that we emptied. */
buffer = (omapi_buffer_t *)0; buffer = (omapi_buffer_t *)0;
while (c -> inbufs && while (c -> inbufs &&
c -> inbufs -> head == c -> inbufs -> tail) { !BYTES_IN_BUFFER (c -> inbufs)) {
if (c -> inbufs -> next) { if (c -> inbufs -> next) {
omapi_buffer_reference omapi_buffer_reference
(&buffer, (&buffer,
@ -236,11 +243,13 @@ isc_result_t omapi_connection_copyout (unsigned char *buf,
} }
omapi_buffer_dereference (&c -> inbufs, omapi_buffer_dereference (&c -> inbufs,
"omapi_private_buffer_copyout"); "omapi_private_buffer_copyout");
omapi_buffer_reference (&c -> inbufs, if (buffer) {
buffer, omapi_buffer_reference
"omapi_private_buffer_copyout"); (&c -> inbufs, buffer,
omapi_buffer_dereference (&buffer, "omapi_private_buffer_copyout");
"omapi_private_buffer_copyout"); omapi_buffer_dereference
(&buffer, "omapi_private_buffer_copyout");
}
} }
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }
@ -249,6 +258,7 @@ isc_result_t omapi_connection_writer (omapi_object_t *h)
{ {
unsigned bytes_this_write; unsigned bytes_this_write;
unsigned bytes_written; unsigned bytes_written;
unsigned first_byte;
omapi_buffer_t *buffer; omapi_buffer_t *buffer;
unsigned char *bufp; unsigned char *bufp;
omapi_connection_object_t *c; omapi_connection_object_t *c;
@ -266,16 +276,21 @@ isc_result_t omapi_connection_writer (omapi_object_t *h)
while (c -> out_bytes) { while (c -> out_bytes) {
if (!buffer) if (!buffer)
return ISC_R_UNEXPECTED; return ISC_R_UNEXPECTED;
if (buffer -> head != buffer -> tail) { if (BYTES_IN_BUFFER (buffer)) {
if (buffer -> head > buffer -> tail) { if (buffer -> head == (sizeof buffer -> buf) - 1)
first_byte = 0;
else
first_byte = buffer -> head + 1;
if (first_byte > buffer -> tail) {
bytes_this_write = (sizeof buffer -> buf - bytes_this_write = (sizeof buffer -> buf -
buffer -> head); first_byte);
} else { } else {
bytes_this_write = bytes_this_write =
(buffer -> tail - buffer -> head); buffer -> tail - first_byte;
} }
bytes_written = write (c -> socket, bytes_written = write (c -> socket,
&buffer -> buf [buffer -> head], &buffer -> buf [first_byte],
bytes_this_write); bytes_this_write);
/* If the write failed with EWOULDBLOCK or we wrote /* If the write failed with EWOULDBLOCK or we wrote
zero bytes, a further write would block, so we have zero bytes, a further write would block, so we have
@ -302,9 +317,7 @@ isc_result_t omapi_connection_writer (omapi_object_t *h)
if (bytes_written == 0) if (bytes_written == 0)
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
buffer -> head += bytes_written; buffer -> head = first_byte + bytes_written - 1;
if (buffer -> head == sizeof buffer -> buf)
buffer -> head = 0;
c -> out_bytes -= bytes_written; c -> out_bytes -= bytes_written;
/* If we didn't finish out the write, we filled the /* If we didn't finish out the write, we filled the
@ -314,14 +327,14 @@ isc_result_t omapi_connection_writer (omapi_object_t *h)
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }
if (buffer -> head == buffer -> tail) if (!BYTES_IN_BUFFER (buffer))
buffer = buffer -> next; buffer = buffer -> next;
} }
/* Get rid of any output buffers we emptied. */ /* Get rid of any output buffers we emptied. */
buffer = (omapi_buffer_t *)0; buffer = (omapi_buffer_t *)0;
while (c -> outbufs && while (c -> outbufs &&
c -> outbufs -> head == c -> outbufs -> tail) { !BYTES_IN_BUFFER (c -> outbufs)) {
if (c -> outbufs -> next) { if (c -> outbufs -> next) {
omapi_buffer_reference omapi_buffer_reference
(&buffer, c -> outbufs -> next, (&buffer, c -> outbufs -> next,