2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 16:15:27 +00:00

make the isc_socket_recv() partial flag be a byte count instead, which allows

us to say "read at least 2 bytes" for things like a DNS packet over TCP.
This commit is contained in:
Michael Graff
1999-07-28 21:30:37 +00:00
parent 9bde328d3b
commit d524cd03ec
7 changed files with 43 additions and 40 deletions

View File

@@ -219,7 +219,7 @@ tcp_recv_len(isc_task_t *task, isc_event_t *event)
region.base = ctx->buf;
region.length = ctx->buflen;
isc_socket_recv(sock, &region, ISC_FALSE,
isc_socket_recv(sock, &region, 0,
task, tcp_recv_req, event->arg);
isc_event_free(&event);
@@ -349,7 +349,7 @@ tcp_accept(isc_task_t *task, isc_event_t *event)
region.length = 2;
region.base = (unsigned char *)&ctx->buflen;
RUNTIME_CHECK(isc_socket_recv(ctx->csock, &region, ISC_FALSE, task,
RUNTIME_CHECK(isc_socket_recv(ctx->csock, &region, 0, task,
tcp_recv_len, ctx)
== ISC_R_SUCCESS);
@@ -399,7 +399,7 @@ tcp_send(isc_task_t *task, isc_event_t *event)
*/
region.base = (unsigned char *)&ctx->buflen;
region.length = 2;
isc_socket_recv(sock, &region, ISC_FALSE, task, tcp_recv_len, ctx);
isc_socket_recv(sock, &region, 0, task, tcp_recv_len, ctx);
isc_event_free(&event);
}

View File

@@ -177,7 +177,7 @@ udp_recv(isc_task_t *task, isc_event_t *event)
&dev->address);
} else {
/* Send no reply, just wait for the next request. */
isc_socket_recv(sock, &region, ISC_FALSE, task, udp_recv, ctx);
isc_socket_recv(sock, &region, 0, task, udp_recv, ctx);
}
isc_event_free(&event);
@@ -218,7 +218,7 @@ udp_send(isc_task_t *task, isc_event_t *event)
region.base = ctx->buf;
region.length = UDP_INPUT_BUFFER_SIZE;
isc_socket_recv(sock, &region, ISC_FALSE, task, udp_recv, ctx);
isc_socket_recv(sock, &region, 0, task, udp_recv, ctx);
isc_event_free(&event);
}
@@ -309,7 +309,7 @@ udp_listener_start(udp_listener_t *l,
region.base = l->ctxs[i]->buf;
RUNTIME_CHECK(isc_socket_recv(sock, &region,
ISC_FALSE, l->tasks[i],
0, l->tasks[i],
udp_recv, l->ctxs[i])
== ISC_R_SUCCESS);

View File

@@ -84,7 +84,7 @@ my_recv(isc_task_t *task, isc_event_t *event)
if (strcmp(event->arg, "so2") != 0) {
region = dev->region;
sprintf(buf, "\r\nReceived: %.*s\r\n\r\n",
(int)region.length, (char *)region.base);
(int)dev->n, (char *)region.base);
region.base = isc_mem_get(mctx, strlen(buf) + 1);
region.length = strlen(buf) + 1;
strcpy((char *)region.base, buf); /* strcpy is safe */
@@ -92,11 +92,10 @@ my_recv(isc_task_t *task, isc_event_t *event)
} else {
region = dev->region;
printf("\r\nReceived: %.*s\r\n\r\n",
(int)region.length, (char *)region.base);
(int)dev->n, (char *)region.base);
}
isc_socket_recv(sock, &dev->region, ISC_FALSE,
task, my_recv, event->arg);
isc_socket_recv(sock, &dev->region, 1, task, my_recv, event->arg);
isc_event_free(&event);
}
@@ -146,8 +145,7 @@ my_http_get(isc_task_t *task, isc_event_t *event)
return;
}
isc_socket_recv(sock, &dev->region, ISC_FALSE, task, my_recv,
event->arg);
isc_socket_recv(sock, &dev->region, 1, task, my_recv, event->arg);
isc_event_free(&event);
}
@@ -218,7 +216,7 @@ my_listen(isc_task_t *task, isc_event_t *event)
newtask = NULL;
RUNTIME_CHECK(isc_task_create(manager, NULL, 0, &newtask)
== ISC_R_SUCCESS);
isc_socket_recv(dev->newsocket, &region, ISC_FALSE,
isc_socket_recv(dev->newsocket, &region, 1,
newtask, my_recv, event->arg);
isc_task_detach(&newtask);
} else {

View File

@@ -761,7 +761,7 @@ startrecv(dns_dispatch_t *disp)
return;
XDEBUG(("Recv into %p, length %d\n", region.base,
region.length));
res = isc_socket_recv(disp->socket, &region, ISC_TRUE,
res = isc_socket_recv(disp->socket, &region, 1,
disp->task, udp_recv, disp);
if (res != ISC_R_SUCCESS) {
disp->shutdown_why = res;

View File

@@ -81,7 +81,7 @@ recv_length(isc_task_t *task, isc_event_t *ev_in)
isc_buffer_init(&tcpmsg->buffer, region.base, region.length,
ISC_BUFFERTYPE_BINARY);
result = isc_socket_recv(tcpmsg->sock, &region, ISC_FALSE,
result = isc_socket_recv(tcpmsg->sock, &region, 0,
task, recv_message, tcpmsg);
if (result != ISC_R_SUCCESS) {
tcpmsg->result = result;
@@ -188,7 +188,7 @@ dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg,
region.base = (unsigned char *)&tcpmsg->size;
region.length = 2; /* isc_uint16_t */
result = isc_socket_recv(tcpmsg->sock, &region, ISC_FALSE,
result = isc_socket_recv(tcpmsg->sock, &region, 0,
tcpmsg->task, recv_length, tcpmsg);
if (result != ISC_R_SUCCESS)

View File

@@ -82,7 +82,7 @@ typedef struct isc_socketevent isc_socketevent_t;
struct isc_socketevent {
ISC_EVENT_COMMON(isc_socketevent_t);
isc_result_t result; /* OK, EOF, whatever else */
isc_boolean_t partial; /* partial i/o ok */
unsigned int minimum; /* minimum i/o for event */
unsigned int n; /* bytes read or written */
isc_region_t region; /* the region info */
isc_sockaddr_t address; /* source address */
@@ -113,12 +113,8 @@ struct isc_socket_connev {
/*
* Internal events.
*/
#define ISC_SOCKEVENT_INTRECV (ISC_EVENTCLASS_SOCKET + 257)
#define ISC_SOCKEVENT_INTSEND (ISC_EVENTCLASS_SOCKET + 258)
#define ISC_SOCKEVENT_INTACCEPT (ISC_EVENTCLASS_SOCKET + 259)
#define ISC_SOCKEVENT_INTCONN (ISC_EVENTCLASS_SOCKET + 260)
#define ISC_SOCKEVENT_INTR (ISC_EVENTCLASS_SOCKET + 261)
#define ISC_SOCKEVENT_INTW (ISC_EVENTCLASS_SOCKET + 262)
#define ISC_SOCKEVENT_INTR (ISC_EVENTCLASS_SOCKET + 256)
#define ISC_SOCKEVENT_INTW (ISC_EVENTCLASS_SOCKET + 257)
typedef enum {
isc_sockettype_udp = 1,
@@ -413,7 +409,7 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp);
isc_result_t
isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
isc_boolean_t partial,
unsigned int minimum,
isc_task_t *task, isc_taskaction_t action, void *arg);
/*
* Receive from 'socket', storing the results in region.
@@ -422,17 +418,17 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
*
* Let 'length' refer to the length of 'region'.
*
* If 'partial' is true, then at most 'length' bytes will be read.
* Otherwise the read will not complete until exactly 'length' bytes
* have been read.
* If 'minimum' is non-zero and at least that many bytes are read,
* the completion event will be posted to the task 'task.' If minimum
* is zero, the exact number of bytes requested in the region must
* be read for an event to be posted. This only makes sense for TCP
* connections, and is always set to the full buffer for UDP.
*
* The read will complete when the desired number of bytes have been
* read, if end-of-input occurs, or if an error occurs. A read done
* event with the given 'action' and 'arg' will be posted to the
* event queue of 'task'.
*
* Partial reads are always turned on for UDP.
*
* The caller may neither read from nor write to 'region' until it
* has received the read completion event.
*

View File

@@ -359,7 +359,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTR,
NULL, sock, sock, NULL, NULL);
ISC_EVENT_INIT(&sock->writable_ev, sizeof(intev_t),
ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTR,
ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTW,
NULL, sock, sock, NULL, NULL);
sock->magic = SOCKET_MAGIC;
@@ -835,6 +835,8 @@ internal_recv(isc_task_t *me, isc_event_t *ev)
(void)me;
INSIST(ev->type == ISC_SOCKEVENT_INTR);
sock = ev->sender;
REQUIRE(VALID_SOCKET(sock));
@@ -965,7 +967,7 @@ internal_recv(isc_task_t *me, isc_event_t *ev)
* was read with a success result, and continue
* the loop.
*/
if (dev->partial) {
if (dev->minimum >= dev->n) {
send_recvdone_event(sock, &task, &dev,
ISC_R_SUCCESS, 1);
goto next;
@@ -1010,6 +1012,8 @@ internal_send(isc_task_t *me, isc_event_t *ev)
(void)me;
INSIST(ev->type == ISC_SOCKEVENT_INTW);
/*
* Find out what socket this is and lock it.
*/
@@ -1544,9 +1548,8 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp)
}
isc_result_t
isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
isc_boolean_t partial, isc_task_t *task,
isc_taskaction_t action, void *arg)
isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
isc_task_t *task, isc_taskaction_t action, void *arg)
{
isc_socketevent_t *dev;
isc_socketmgr_t *manager;
@@ -1557,6 +1560,7 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
REQUIRE(VALID_SOCKET(sock));
manager = sock->manager;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(region->length >= minimum);
LOCK(&sock->lock);
@@ -1574,12 +1578,17 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
* UDP sockets are always partial read
*/
if (sock->type == isc_sockettype_udp)
partial = ISC_TRUE;
dev->minimum = 1;
else {
if (minimum == 0)
dev->minimum = region->length;
else
dev->minimum = minimum;
}
dev->region = *region;
dev->n = 0;
dev->result = ISC_R_SUCCESS;
dev->partial = partial;
was_empty = ISC_LIST_EMPTY(sock->recv_list);
@@ -1666,7 +1675,7 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
/*
* Partial reads need to be queued
*/
if ((size_t)cc != dev->region.length && !partial)
if (((size_t)cc != dev->region.length) && (dev->n < dev->minimum))
goto queue;
/*
@@ -1742,7 +1751,7 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
dev->region = *region;
dev->n = 0;
dev->result = ISC_R_SUCCESS;
dev->partial = ISC_FALSE; /* doesn't matter */
dev->minimum = region->length;
was_empty = ISC_LIST_EMPTY(sock->send_list);
@@ -2424,7 +2433,7 @@ isc_socket_recvmark(isc_socket_t *sock,
isc_task_attach(task, &ntask);
dev->result = ISC_R_SUCCESS;
dev->partial = ISC_FALSE; /* doesn't matter */
dev->minimum = 0;
dev->sender = ntask;
ISC_LIST_ENQUEUE(sock->recv_list, dev, link);
@@ -2481,7 +2490,7 @@ isc_socket_sendmark(isc_socket_t *sock,
isc_task_attach(task, &ntask);
dev->result = ISC_R_SUCCESS;
dev->partial = ISC_FALSE; /* doesn't matter */
dev->minimum = 0;
dev->sender = ntask;
ISC_LIST_ENQUEUE(sock->send_list, dev, link);