mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
Merge branch 'wpk-get-rid-of-socket-v-functions' into 'master'
Get rid of socket *v functions See merge request isc-projects/bind9!932
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -1,3 +1,8 @@
|
||||
5074. [cleanup] Remove vector socket functions - isc_socket_recvv(),
|
||||
isc_socket_sendtov(), isc_socket_sendtov2(),
|
||||
isc_socket_sendv() - in order to simplify socket code.
|
||||
[GL #645]
|
||||
|
||||
5073. [bug] Destroy a task first when destroying rpzs and catzs.
|
||||
[GL #84]
|
||||
|
||||
|
@@ -1534,12 +1534,6 @@ clear_query(dig_query_t *query) {
|
||||
ISC_LIST_UNLINK(lookup->q, query, link);
|
||||
if (ISC_LINK_LINKED(query, clink))
|
||||
ISC_LIST_UNLINK(lookup->connecting, query, clink);
|
||||
if (ISC_LINK_LINKED(&query->recvbuf, link))
|
||||
ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf,
|
||||
link);
|
||||
if (ISC_LINK_LINKED(&query->lengthbuf, link))
|
||||
ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf,
|
||||
link);
|
||||
INSIST(query->recvspace != NULL);
|
||||
|
||||
if (query->sock != NULL) {
|
||||
@@ -1548,6 +1542,7 @@ clear_query(dig_query_t *query) {
|
||||
debug("sockcount=%d", sockcount);
|
||||
}
|
||||
isc_mempool_put(commctx, query->recvspace);
|
||||
isc_mempool_put(commctx, query->tmpsendspace);
|
||||
isc_buffer_invalidate(&query->recvbuf);
|
||||
isc_buffer_invalidate(&query->lengthbuf);
|
||||
if (query->waiting_senddone)
|
||||
@@ -2488,16 +2483,15 @@ setup_lookup(dig_lookup_t *lookup) {
|
||||
query->msg_count = 0;
|
||||
query->byte_count = 0;
|
||||
query->ixfr_axfr = false;
|
||||
ISC_LIST_INIT(query->recvlist);
|
||||
ISC_LIST_INIT(query->lengthlist);
|
||||
query->sock = NULL;
|
||||
query->recvspace = isc_mempool_get(commctx);
|
||||
query->tmpsendspace = isc_mempool_get(commctx);
|
||||
if (query->recvspace == NULL)
|
||||
fatal("memory allocation failure");
|
||||
|
||||
isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE);
|
||||
isc_buffer_init(&query->lengthbuf, query->lengthspace, 2);
|
||||
isc_buffer_init(&query->slbuf, query->slspace, 2);
|
||||
isc_buffer_init(&query->tmpsendbuf, query->tmpsendspace, COMMSIZE);
|
||||
query->sendbuf = lookup->renderbuf;
|
||||
|
||||
ISC_LINK_INIT(query, clink);
|
||||
@@ -2523,8 +2517,6 @@ setup_lookup(dig_lookup_t *lookup) {
|
||||
*/
|
||||
static void
|
||||
send_done(isc_task_t *_task, isc_event_t *event) {
|
||||
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
|
||||
isc_buffer_t *b = NULL;
|
||||
dig_query_t *query, *next;
|
||||
dig_lookup_t *l;
|
||||
|
||||
@@ -2539,13 +2531,6 @@ send_done(isc_task_t *_task, isc_event_t *event) {
|
||||
debug("sendcount=%d", sendcount);
|
||||
INSIST(sendcount >= 0);
|
||||
|
||||
for (b = ISC_LIST_HEAD(sevent->bufferlist);
|
||||
b != NULL;
|
||||
b = ISC_LIST_HEAD(sevent->bufferlist)) {
|
||||
ISC_LIST_DEQUEUE(sevent->bufferlist, b, link);
|
||||
isc_mem_free(mctx, b);
|
||||
}
|
||||
|
||||
query = event->ev_arg;
|
||||
query->waiting_senddone = false;
|
||||
l = query->lookup;
|
||||
@@ -2777,17 +2762,6 @@ send_tcp_connect(dig_query_t *query) {
|
||||
}
|
||||
}
|
||||
|
||||
static isc_buffer_t *
|
||||
clone_buffer(isc_buffer_t *source) {
|
||||
isc_buffer_t *buffer;
|
||||
buffer = isc_mem_allocate(mctx, sizeof(*buffer));
|
||||
if (buffer == NULL)
|
||||
fatal("memory allocation failure in %s:%d",
|
||||
__FILE__, __LINE__);
|
||||
*buffer = *source;
|
||||
return (buffer);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Send a UDP packet to the remote nameserver, possible starting the
|
||||
* recv action as well. Also make sure that the timer is running and
|
||||
@@ -2797,8 +2771,9 @@ static void
|
||||
send_udp(dig_query_t *query) {
|
||||
dig_lookup_t *l = NULL;
|
||||
isc_result_t result;
|
||||
isc_buffer_t *sendbuf;
|
||||
dig_query_t *next;
|
||||
isc_region_t r;
|
||||
isc_socketevent_t *sevent;
|
||||
|
||||
debug("send_udp(%p)", query);
|
||||
|
||||
@@ -2859,29 +2834,27 @@ send_udp(dig_query_t *query) {
|
||||
check_result(result, "isc_socket_bind");
|
||||
|
||||
query->recv_made = true;
|
||||
ISC_LINK_INIT(&query->recvbuf, link);
|
||||
ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf,
|
||||
link);
|
||||
isc_buffer_availableregion(&query->recvbuf, &r);
|
||||
debug("recving with lookup=%p, query=%p, sock=%p",
|
||||
query->lookup, query, query->sock);
|
||||
result = isc_socket_recvv(query->sock, &query->recvlist, 1,
|
||||
global_task, recv_done, query);
|
||||
check_result(result, "isc_socket_recvv");
|
||||
result = isc_socket_recv(query->sock, &r, 1,
|
||||
global_task, recv_done, query);
|
||||
check_result(result, "isc_socket_recv");
|
||||
recvcount++;
|
||||
debug("recvcount=%d", recvcount);
|
||||
}
|
||||
ISC_LIST_INIT(query->sendlist);
|
||||
sendbuf = clone_buffer(&query->sendbuf);
|
||||
ISC_LIST_ENQUEUE(query->sendlist, sendbuf, link);
|
||||
isc_buffer_usedregion(&query->sendbuf, &r);
|
||||
debug("sending a request");
|
||||
TIME_NOW(&query->time_sent);
|
||||
INSIST(query->sock != NULL);
|
||||
query->waiting_senddone = true;
|
||||
result = isc_socket_sendtov2(query->sock, &query->sendlist,
|
||||
global_task, send_done, query,
|
||||
&query->sockaddr, NULL,
|
||||
ISC_SOCKFLAG_NORETRY);
|
||||
check_result(result, "isc_socket_sendtov");
|
||||
sevent = isc_socket_socketevent(mctx, query->sock,
|
||||
ISC_SOCKEVENT_SENDDONE,
|
||||
send_done, query);
|
||||
result = isc_socket_sendto2(query->sock, &r,
|
||||
global_task, &query->sockaddr, NULL,
|
||||
sevent, ISC_SOCKFLAG_NORETRY);
|
||||
check_result(result, "isc_socket_sendto2");
|
||||
sendcount++;
|
||||
}
|
||||
|
||||
@@ -2971,7 +2944,8 @@ connect_timeout(isc_task_t *task, isc_event_t *event) {
|
||||
static void
|
||||
tcp_length_done(isc_task_t *task, isc_event_t *event) {
|
||||
isc_socketevent_t *sevent;
|
||||
isc_buffer_t *b = NULL;
|
||||
isc_buffer_t b;
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
dig_query_t *query = NULL;
|
||||
dig_lookup_t *l, *n;
|
||||
@@ -2991,10 +2965,6 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
|
||||
recvcount--;
|
||||
INSIST(recvcount >= 0);
|
||||
|
||||
b = ISC_LIST_HEAD(sevent->bufferlist);
|
||||
INSIST(b == &query->lengthbuf);
|
||||
ISC_LIST_DEQUEUE(sevent->bufferlist, b, link);
|
||||
|
||||
if (sevent->result == ISC_R_CANCELED) {
|
||||
isc_event_free(&event);
|
||||
l = query->lookup;
|
||||
@@ -3027,7 +2997,10 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
|
||||
UNLOCK_LOOKUP;
|
||||
return;
|
||||
}
|
||||
length = isc_buffer_getuint16(b);
|
||||
isc_buffer_init(&b, sevent->region.base, sevent->n);
|
||||
isc_buffer_add(&b, sevent->n);
|
||||
length = isc_buffer_getuint16(&b);
|
||||
|
||||
if (length == 0) {
|
||||
isc_event_free(&event);
|
||||
launch_next_query(query, false);
|
||||
@@ -3041,13 +3014,11 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
isc_buffer_invalidate(&query->recvbuf);
|
||||
isc_buffer_init(&query->recvbuf, query->recvspace, length);
|
||||
ENSURE(ISC_LIST_EMPTY(query->recvlist));
|
||||
ISC_LINK_INIT(&query->recvbuf, link);
|
||||
ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link);
|
||||
isc_buffer_availableregion(&query->recvbuf, &r);
|
||||
debug("recving with lookup=%p, query=%p", query->lookup, query);
|
||||
result = isc_socket_recvv(query->sock, &query->recvlist, length, task,
|
||||
recv_done, query);
|
||||
check_result(result, "isc_socket_recvv");
|
||||
result = isc_socket_recv(query->sock, &r, length, task,
|
||||
recv_done, query);
|
||||
check_result(result, "isc_socket_recv");
|
||||
recvcount++;
|
||||
debug("resubmitted recv request with length %d, recvcount=%d",
|
||||
length, recvcount);
|
||||
@@ -3063,7 +3034,7 @@ static void
|
||||
launch_next_query(dig_query_t *query, bool include_question) {
|
||||
isc_result_t result;
|
||||
dig_lookup_t *l;
|
||||
isc_buffer_t *buffer;
|
||||
isc_region_t r;
|
||||
|
||||
INSIST(!free_now);
|
||||
|
||||
@@ -3082,35 +3053,28 @@ launch_next_query(dig_query_t *query, bool include_question) {
|
||||
return;
|
||||
}
|
||||
|
||||
isc_buffer_clear(&query->slbuf);
|
||||
isc_buffer_clear(&query->lengthbuf);
|
||||
isc_buffer_putuint16(&query->slbuf, (uint16_t) query->sendbuf.used);
|
||||
ISC_LIST_INIT(query->sendlist);
|
||||
ISC_LINK_INIT(&query->slbuf, link);
|
||||
if (!query->first_soa_rcvd) {
|
||||
buffer = clone_buffer(&query->slbuf);
|
||||
ISC_LIST_ENQUEUE(query->sendlist, buffer, link);
|
||||
if (include_question) {
|
||||
buffer = clone_buffer(&query->sendbuf);
|
||||
ISC_LIST_ENQUEUE(query->sendlist, buffer, link);
|
||||
}
|
||||
}
|
||||
|
||||
ISC_LINK_INIT(&query->lengthbuf, link);
|
||||
ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link);
|
||||
|
||||
result = isc_socket_recvv(query->sock, &query->lengthlist, 0,
|
||||
global_task, tcp_length_done, query);
|
||||
check_result(result, "isc_socket_recvv");
|
||||
isc_buffer_availableregion(&query->lengthbuf, &r);
|
||||
result = isc_socket_recv(query->sock, &r, 0,
|
||||
global_task, tcp_length_done, query);
|
||||
check_result(result, "isc_socket_recv");
|
||||
recvcount++;
|
||||
debug("recvcount=%d", recvcount);
|
||||
if (!query->first_soa_rcvd) {
|
||||
debug("sending a request in launch_next_query");
|
||||
TIME_NOW(&query->time_sent);
|
||||
query->waiting_senddone = true;
|
||||
result = isc_socket_sendv(query->sock, &query->sendlist,
|
||||
global_task, send_done, query);
|
||||
check_result(result, "isc_socket_sendv");
|
||||
isc_buffer_clear(&query->tmpsendbuf);
|
||||
isc_buffer_putuint16(&query->tmpsendbuf,
|
||||
isc_buffer_usedlength(&query->sendbuf));
|
||||
if (include_question) {
|
||||
isc_buffer_usedregion(&query->sendbuf, &r);
|
||||
isc_buffer_copyregion(&query->tmpsendbuf, &r);
|
||||
}
|
||||
isc_buffer_usedregion(&query->tmpsendbuf, &r);
|
||||
result = isc_socket_send(query->sock, &r,
|
||||
global_task, send_done, query);
|
||||
check_result(result, "isc_socket_send");
|
||||
sendcount++;
|
||||
debug("sendcount=%d", sendcount);
|
||||
}
|
||||
@@ -3460,8 +3424,9 @@ ednsvers(dns_rdataset_t *opt) {
|
||||
static void
|
||||
recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
isc_socketevent_t *sevent = NULL;
|
||||
isc_region_t r;
|
||||
dig_query_t *query = NULL;
|
||||
isc_buffer_t *b = NULL;
|
||||
isc_buffer_t b;
|
||||
dns_message_t *msg = NULL;
|
||||
isc_result_t result;
|
||||
dig_lookup_t *n, *l;
|
||||
@@ -3491,9 +3456,8 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
|
||||
sevent = (isc_socketevent_t *)event;
|
||||
|
||||
b = ISC_LIST_HEAD(sevent->bufferlist);
|
||||
INSIST(b == &query->recvbuf);
|
||||
ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link);
|
||||
isc_buffer_init(&b, sevent->region.base, sevent->n);
|
||||
isc_buffer_add(&b, sevent->n);
|
||||
|
||||
if ((l->tcp_mode) && (query->timer != NULL))
|
||||
isc_timer_touch(query->timer);
|
||||
@@ -3569,7 +3533,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
}
|
||||
|
||||
result = dns_message_peekheader(b, &id, &msgflags);
|
||||
result = dns_message_peekheader(&b, &id, &msgflags);
|
||||
if (result != ISC_R_SUCCESS || l->sendmsg->id != id) {
|
||||
match = false;
|
||||
if (l->tcp_mode) {
|
||||
@@ -3638,7 +3602,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
parseflags |= DNS_MESSAGEPARSE_BESTEFFORT;
|
||||
parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION;
|
||||
}
|
||||
result = dns_message_parse(msg, b, parseflags);
|
||||
result = dns_message_parse(msg, &b, parseflags);
|
||||
if (result == DNS_R_RECOVERABLE) {
|
||||
printf(";; Warning: Message parser reports malformed "
|
||||
"message packet.\n");
|
||||
@@ -3646,7 +3610,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
printf(";; Got bad packet: %s\n", isc_result_totext(result));
|
||||
hex_dump(b);
|
||||
hex_dump(&b);
|
||||
query->waiting_connect = false;
|
||||
dns_message_destroy(&msg);
|
||||
isc_event_free(&event);
|
||||
@@ -3800,7 +3764,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
|
||||
if (tsigkey != NULL) {
|
||||
result = dns_tsig_verify(&query->recvbuf, msg, NULL, NULL);
|
||||
result = dns_tsig_verify(&b, msg, NULL, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
printf(";; Couldn't verify signature: %s\n",
|
||||
isc_result_totext(result));
|
||||
@@ -3816,7 +3780,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
check_result(result,"dns_message_getquerytsig");
|
||||
}
|
||||
|
||||
extrabytes = isc_buffer_remaininglength(b);
|
||||
extrabytes = isc_buffer_remaininglength(&b);
|
||||
|
||||
debug("after parse");
|
||||
if (l->doing_xfr && l->xfr_q == NULL) {
|
||||
@@ -3863,8 +3827,8 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
(l->origin != NULL || l->need_search)) {
|
||||
if (!next_origin(query->lookup) || showsearch) {
|
||||
dighost_printmessage(query, msg, true);
|
||||
dighost_received(b->used, &sevent->address,
|
||||
query);
|
||||
dighost_received(isc_buffer_usedlength(&b),
|
||||
&sevent->address, query);
|
||||
}
|
||||
} else if (!l->trace && !l->ns_search_only) {
|
||||
dighost_printmessage(query, msg, true);
|
||||
@@ -3931,7 +3895,8 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
} else {
|
||||
|
||||
if (msg->rcode == dns_rcode_noerror || l->origin == NULL) {
|
||||
dighost_received(b->used, &sevent->address, query);
|
||||
dighost_received(isc_buffer_usedlength(&b),
|
||||
&sevent->address, query);
|
||||
}
|
||||
|
||||
if (!query->lookup->ns_search_only)
|
||||
@@ -3954,11 +3919,10 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
udp_mismatch:
|
||||
isc_buffer_invalidate(&query->recvbuf);
|
||||
isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE);
|
||||
ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link);
|
||||
result = isc_socket_recvv(query->sock, &query->recvlist, 1,
|
||||
global_task, recv_done, query);
|
||||
check_result(result, "isc_socket_recvv");
|
||||
isc_buffer_availableregion(&query->recvbuf, &r);
|
||||
result = isc_socket_recv(query->sock, &r, 1,
|
||||
global_task, recv_done, query);
|
||||
check_result(result, "isc_socket_recv");
|
||||
recvcount++;
|
||||
isc_event_free(&event);
|
||||
UNLOCK_LOOKUP;
|
||||
|
@@ -203,15 +203,12 @@ struct dig_query {
|
||||
bool ixfr_axfr;
|
||||
char *servname;
|
||||
char *userarg;
|
||||
isc_bufferlist_t sendlist,
|
||||
recvlist,
|
||||
lengthlist;
|
||||
isc_buffer_t recvbuf,
|
||||
lengthbuf,
|
||||
slbuf;
|
||||
char *recvspace,
|
||||
lengthspace[4],
|
||||
slspace[4];
|
||||
tmpsendbuf,
|
||||
sendbuf;
|
||||
char *recvspace, *tmpsendspace,
|
||||
lengthspace[4];
|
||||
isc_socket_t *sock;
|
||||
ISC_LINK(dig_query_t) link;
|
||||
ISC_LINK(dig_query_t) clink;
|
||||
@@ -219,7 +216,6 @@ struct dig_query {
|
||||
isc_time_t time_sent;
|
||||
isc_time_t time_recv;
|
||||
uint64_t byte_count;
|
||||
isc_buffer_t sendbuf;
|
||||
isc_timer_t *timer;
|
||||
};
|
||||
|
||||
|
@@ -923,12 +923,6 @@ flush_lookup_list(void) {
|
||||
ISC_SOCKCANCEL_ALL);
|
||||
isc_socket_detach(&q->sock);
|
||||
}
|
||||
if (ISC_LINK_LINKED(&q->recvbuf, link))
|
||||
ISC_LIST_DEQUEUE(q->recvlist, &q->recvbuf,
|
||||
link);
|
||||
if (ISC_LINK_LINKED(&q->lengthbuf, link))
|
||||
ISC_LIST_DEQUEUE(q->lengthlist, &q->lengthbuf,
|
||||
link);
|
||||
isc_buffer_invalidate(&q->recvbuf);
|
||||
isc_buffer_invalidate(&q->lengthbuf);
|
||||
qp = q;
|
||||
|
@@ -956,7 +956,6 @@ allocate_sevent(dns_dispatch_t *disp, isc_socket_t *sock,
|
||||
free_sevent, disp->sepool);
|
||||
ev->result = ISC_R_UNSET;
|
||||
ISC_LINK_INIT(ev, ev_link);
|
||||
ISC_LIST_INIT(ev->bufferlist);
|
||||
ev->region.base = NULL;
|
||||
ev->n = 0;
|
||||
ev->offset = 0;
|
||||
|
@@ -114,9 +114,9 @@ struct isc_httpd {
|
||||
* compressed HTTP data, if compression is used.
|
||||
*
|
||||
*/
|
||||
isc_bufferlist_t bufflist;
|
||||
isc_buffer_t headerbuffer;
|
||||
isc_buffer_t compbuffer;
|
||||
isc_buffer_t *sendbuffer;
|
||||
|
||||
const char *mimetype;
|
||||
unsigned int retcode;
|
||||
@@ -667,10 +667,9 @@ isc_httpd_accept(isc_task_t *task, isc_event_t *ev) {
|
||||
}
|
||||
isc_buffer_init(&httpd->headerbuffer, headerdata, HTTP_SENDGROW);
|
||||
|
||||
ISC_LIST_INIT(httpd->bufflist);
|
||||
|
||||
isc_buffer_initnull(&httpd->compbuffer);
|
||||
isc_buffer_initnull(&httpd->bodybuffer);
|
||||
httpd->sendbuffer = NULL;
|
||||
reset_client(httpd);
|
||||
|
||||
r.base = (unsigned char *)httpd->recvbuf;
|
||||
@@ -840,12 +839,13 @@ isc_httpd_compress(isc_httpd_t *httpd) {
|
||||
|
||||
static void
|
||||
isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
isc_httpd_t *httpd = ev->ev_arg;
|
||||
isc_socketevent_t *sev = (isc_socketevent_t *)ev;
|
||||
isc_buffer_t *databuffer;
|
||||
isc_httpdurl_t *url;
|
||||
isc_time_t now;
|
||||
isc_region_t r;
|
||||
bool is_compressed = false;
|
||||
char datebuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
|
||||
|
||||
@@ -963,22 +963,24 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
|
||||
isc_httpd_endheaders(httpd); /* done */
|
||||
|
||||
ISC_LIST_APPEND(httpd->bufflist, &httpd->headerbuffer, link);
|
||||
/*
|
||||
* Link the data buffer into our send queue, should we have any data
|
||||
* rendered into it. If no data is present, we won't do anything
|
||||
* with the buffer.
|
||||
* Append either the compressed or the non-compressed response body to
|
||||
* the response headers and store the result in httpd->sendbuffer.
|
||||
*/
|
||||
if (is_compressed == true) {
|
||||
ISC_LIST_APPEND(httpd->bufflist, &httpd->compbuffer, link);
|
||||
} else {
|
||||
if (isc_buffer_length(&httpd->bodybuffer) > 0) {
|
||||
ISC_LIST_APPEND(httpd->bufflist, &httpd->bodybuffer, link);
|
||||
}
|
||||
}
|
||||
isc_buffer_dup(httpd->mgr->mctx,
|
||||
&httpd->sendbuffer, &httpd->headerbuffer);
|
||||
isc_buffer_setautorealloc(httpd->sendbuffer, true);
|
||||
databuffer = (is_compressed ? &httpd->compbuffer : &httpd->bodybuffer);
|
||||
isc_buffer_usedregion(databuffer, &r);
|
||||
result = isc_buffer_copyregion(httpd->sendbuffer, &r);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
/*
|
||||
* Determine total response size.
|
||||
*/
|
||||
isc_buffer_usedregion(httpd->sendbuffer, &r);
|
||||
|
||||
/* check return code? */
|
||||
(void)isc_socket_sendv(httpd->sock, &httpd->bufflist, task,
|
||||
(void)isc_socket_send(httpd->sock, &r, task,
|
||||
isc_httpd_senddone, httpd);
|
||||
|
||||
out:
|
||||
@@ -1126,13 +1128,7 @@ isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) {
|
||||
ENTER("senddone");
|
||||
INSIST(ISC_HTTPD_ISSEND(httpd));
|
||||
|
||||
/*
|
||||
* First, unlink our header buffer from the socket's bufflist. This
|
||||
* is sort of an evil hack, since we know our buffer will be there,
|
||||
* and we know it's address, so we can just remove it directly.
|
||||
*/
|
||||
NOTICE("senddone unlinked header");
|
||||
ISC_LIST_UNLINK(sev->bufferlist, &httpd->headerbuffer, link);
|
||||
isc_buffer_free(&httpd->sendbuffer);
|
||||
|
||||
/*
|
||||
* We will always want to clean up our receive buffer, even if we
|
||||
@@ -1149,13 +1145,6 @@ isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) {
|
||||
}
|
||||
NOTICE("senddone free callback performed");
|
||||
}
|
||||
if (ISC_LINK_LINKED(&httpd->bodybuffer, link)) {
|
||||
ISC_LIST_UNLINK(sev->bufferlist, &httpd->bodybuffer, link);
|
||||
NOTICE("senddone body buffer unlinked");
|
||||
} else if (ISC_LINK_LINKED(&httpd->compbuffer, link)) {
|
||||
ISC_LIST_UNLINK(sev->bufferlist, &httpd->compbuffer, link);
|
||||
NOTICE("senddone compressed data unlinked and freed");
|
||||
}
|
||||
|
||||
if (sev->result != ISC_R_SUCCESS) {
|
||||
destroy_client(&httpd);
|
||||
|
@@ -204,7 +204,6 @@ struct isc_socketevent {
|
||||
unsigned int n; /*%< bytes read or written */
|
||||
unsigned int offset; /*%< offset into buffer list */
|
||||
isc_region_t region; /*%< for single-buffer i/o */
|
||||
isc_bufferlist_t bufferlist; /*%< list of buffers */
|
||||
isc_sockaddr_t address; /*%< source address */
|
||||
isc_time_t timestamp; /*%< timestamp of packet recv */
|
||||
struct in6_pktinfo pktinfo; /*%< ipv6 pktinfo */
|
||||
@@ -742,10 +741,6 @@ isc_result_t
|
||||
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_result_t
|
||||
isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
unsigned int minimum,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg);
|
||||
|
||||
isc_result_t
|
||||
isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
|
||||
@@ -775,11 +770,6 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
|
||||
* into this function, or any data they refer to until the completion
|
||||
* event is received.
|
||||
*
|
||||
*\li For isc_socket_recvv():
|
||||
* On successful completion, '*buflist' will be empty, and the list of
|
||||
* all buffers will be returned in the done event's 'bufferlist'
|
||||
* member. On error return, '*buflist' will be unchanged.
|
||||
*
|
||||
*\li For isc_socket_recv2():
|
||||
* 'event' is not NULL, and the non-socket specific fields are
|
||||
* expected to be initialized.
|
||||
@@ -834,18 +824,6 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
|
||||
isc_result_t
|
||||
isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg);
|
||||
isc_result_t
|
||||
isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
|
||||
isc_result_t
|
||||
isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
|
||||
unsigned int flags);
|
||||
isc_result_t
|
||||
isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
|
||||
isc_task_t *task,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
|
||||
@@ -866,11 +844,6 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
|
||||
* into this function, or any data they refer to until the completion
|
||||
* event is received.
|
||||
*
|
||||
*\li For isc_socket_sendv() and isc_socket_sendtov():
|
||||
* On successful completion, '*buflist' will be empty, and the list of
|
||||
* all buffers will be returned in the done event's 'bufferlist'
|
||||
* member. On error return, '*buflist' will be unchanged.
|
||||
*
|
||||
*\li For isc_socket_sendto2():
|
||||
* 'event' is not NULL, and the non-socket specific fields are
|
||||
* expected to be initialized.
|
||||
|
@@ -39,7 +39,6 @@
|
||||
|
||||
#include <isc/app.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/bufferlist.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/formatcheck.h>
|
||||
#include <isc/json.h>
|
||||
@@ -1197,10 +1196,7 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev,
|
||||
struct msghdr *msg, struct iovec *iov, size_t *write_countp)
|
||||
{
|
||||
unsigned int iovcount;
|
||||
isc_buffer_t *buffer;
|
||||
isc_region_t used;
|
||||
size_t write_count;
|
||||
size_t skip_count;
|
||||
struct cmsghdr *cmsgp;
|
||||
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
@@ -1213,54 +1209,14 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev,
|
||||
msg->msg_namelen = 0;
|
||||
}
|
||||
|
||||
buffer = ISC_LIST_HEAD(dev->bufferlist);
|
||||
write_count = 0;
|
||||
iovcount = 0;
|
||||
|
||||
/*
|
||||
* Single buffer I/O? Skip what we've done so far in this region.
|
||||
*/
|
||||
if (buffer == NULL) {
|
||||
write_count = dev->region.length - dev->n;
|
||||
iov[0].iov_base = (void *)(dev->region.base + dev->n);
|
||||
iov[0].iov_len = write_count;
|
||||
iovcount = 1;
|
||||
write_count = dev->region.length - dev->n;
|
||||
iov[0].iov_base = (void *)(dev->region.base + dev->n);
|
||||
iov[0].iov_len = write_count;
|
||||
iovcount = 1;
|
||||
|
||||
goto config;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multibuffer I/O.
|
||||
* Skip the data in the buffer list that we have already written.
|
||||
*/
|
||||
skip_count = dev->n;
|
||||
while (buffer != NULL) {
|
||||
REQUIRE(ISC_BUFFER_VALID(buffer));
|
||||
if (skip_count < isc_buffer_usedlength(buffer))
|
||||
break;
|
||||
skip_count -= isc_buffer_usedlength(buffer);
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
}
|
||||
|
||||
while (buffer != NULL) {
|
||||
INSIST(iovcount < MAXSCATTERGATHER_SEND);
|
||||
|
||||
isc_buffer_usedregion(buffer, &used);
|
||||
|
||||
if (used.length > 0) {
|
||||
iov[iovcount].iov_base = (void *)(used.base
|
||||
+ skip_count);
|
||||
iov[iovcount].iov_len = used.length - skip_count;
|
||||
write_count += (used.length - skip_count);
|
||||
skip_count = 0;
|
||||
iovcount++;
|
||||
}
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
}
|
||||
|
||||
INSIST(skip_count == 0U);
|
||||
|
||||
config:
|
||||
msg->msg_iov = iov;
|
||||
msg->msg_iovlen = iovcount;
|
||||
msg->msg_control = NULL;
|
||||
@@ -1416,8 +1372,6 @@ build_msghdr_recv(isc__socket_t *sock, char *cmsgbuf, isc_socketevent_t *dev,
|
||||
struct msghdr *msg, struct iovec *iov, size_t *read_countp)
|
||||
{
|
||||
unsigned int iovcount;
|
||||
isc_buffer_t *buffer;
|
||||
isc_region_t available;
|
||||
size_t read_count;
|
||||
|
||||
memset(msg, 0, sizeof(struct msghdr));
|
||||
@@ -1432,48 +1386,12 @@ build_msghdr_recv(isc__socket_t *sock, char *cmsgbuf, isc_socketevent_t *dev,
|
||||
dev->address = sock->peer_address;
|
||||
}
|
||||
|
||||
buffer = ISC_LIST_HEAD(dev->bufferlist);
|
||||
read_count = 0;
|
||||
|
||||
/*
|
||||
* Single buffer I/O? Skip what we've done so far in this region.
|
||||
*/
|
||||
if (buffer == NULL) {
|
||||
read_count = dev->region.length - dev->n;
|
||||
iov[0].iov_base = (void *)(dev->region.base + dev->n);
|
||||
iov[0].iov_len = read_count;
|
||||
iovcount = 1;
|
||||
|
||||
goto config;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multibuffer I/O.
|
||||
* Skip empty buffers.
|
||||
*/
|
||||
while (buffer != NULL) {
|
||||
REQUIRE(ISC_BUFFER_VALID(buffer));
|
||||
if (isc_buffer_availablelength(buffer) != 0)
|
||||
break;
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
}
|
||||
|
||||
iovcount = 0;
|
||||
while (buffer != NULL) {
|
||||
INSIST(iovcount < MAXSCATTERGATHER_RECV);
|
||||
|
||||
isc_buffer_availableregion(buffer, &available);
|
||||
|
||||
if (available.length > 0) {
|
||||
iov[iovcount].iov_base = (void *)(available.base);
|
||||
iov[iovcount].iov_len = available.length;
|
||||
read_count += available.length;
|
||||
iovcount++;
|
||||
}
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
}
|
||||
|
||||
config:
|
||||
read_count = dev->region.length - dev->n;
|
||||
iov[0].iov_base = (void *)(dev->region.base + dev->n);
|
||||
iov[0].iov_len = read_count;
|
||||
iovcount = 1;
|
||||
|
||||
/*
|
||||
* If needed, set up to receive that one extra byte.
|
||||
@@ -1522,8 +1440,6 @@ static void
|
||||
destroy_socketevent(isc_event_t *event) {
|
||||
isc_socketevent_t *ev = (isc_socketevent_t *)event;
|
||||
|
||||
INSIST(ISC_LIST_EMPTY(ev->bufferlist));
|
||||
|
||||
(ev->destroy)(event);
|
||||
}
|
||||
|
||||
@@ -1543,7 +1459,6 @@ allocate_socketevent(isc_mem_t *mctx, void *sender,
|
||||
|
||||
ev->result = ISC_R_UNSET;
|
||||
ISC_LINK_INIT(ev, ev_link);
|
||||
ISC_LIST_INIT(ev->bufferlist);
|
||||
ev->region.base = NULL;
|
||||
ev->n = 0;
|
||||
ev->offset = 0;
|
||||
@@ -1584,9 +1499,7 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) {
|
||||
int cc;
|
||||
struct iovec iov[MAXSCATTERGATHER_RECV];
|
||||
size_t read_count;
|
||||
size_t actual_count;
|
||||
struct msghdr msghdr;
|
||||
isc_buffer_t *buffer;
|
||||
int recv_errno;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
char cmsgbuf[RECVCMSGBUFLEN] = {0};
|
||||
@@ -1719,25 +1632,6 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) {
|
||||
* update the buffers (if any) and the i/o count
|
||||
*/
|
||||
dev->n += cc;
|
||||
actual_count = cc;
|
||||
buffer = ISC_LIST_HEAD(dev->bufferlist);
|
||||
while (buffer != NULL && actual_count > 0U) {
|
||||
REQUIRE(ISC_BUFFER_VALID(buffer));
|
||||
if (isc_buffer_availablelength(buffer) <= actual_count) {
|
||||
actual_count -= isc_buffer_availablelength(buffer);
|
||||
isc_buffer_add(buffer,
|
||||
isc_buffer_availablelength(buffer));
|
||||
} else {
|
||||
isc_buffer_add(buffer, actual_count);
|
||||
actual_count = 0;
|
||||
POST(actual_count);
|
||||
break;
|
||||
}
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
if (buffer == NULL) {
|
||||
INSIST(actual_count == 0U);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we read less than we expected, update counters,
|
||||
@@ -4668,61 +4562,6 @@ socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_recvv(isc_socket_t *sock0, isc_bufferlist_t *buflist,
|
||||
unsigned int minimum, isc_task_t *task,
|
||||
isc_taskaction_t action, void *arg)
|
||||
{
|
||||
isc__socket_t *sock = (isc__socket_t *)sock0;
|
||||
isc_socketevent_t *dev;
|
||||
isc__socketmgr_t *manager;
|
||||
unsigned int iocount;
|
||||
isc_buffer_t *buffer;
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
REQUIRE(buflist != NULL);
|
||||
REQUIRE(!ISC_LIST_EMPTY(*buflist));
|
||||
REQUIRE(task != NULL);
|
||||
REQUIRE(action != NULL);
|
||||
|
||||
manager = sock->manager;
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
|
||||
iocount = isc_bufferlist_availablecount(buflist);
|
||||
REQUIRE(iocount > 0);
|
||||
|
||||
INSIST(sock->bound);
|
||||
|
||||
dev = allocate_socketevent(manager->mctx, sock,
|
||||
ISC_SOCKEVENT_RECVDONE, action, arg);
|
||||
if (dev == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
/*
|
||||
* UDP sockets are always partial read
|
||||
*/
|
||||
if (sock->type == isc_sockettype_udp)
|
||||
dev->minimum = 1;
|
||||
else {
|
||||
if (minimum == 0)
|
||||
dev->minimum = iocount;
|
||||
else
|
||||
dev->minimum = minimum;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move each buffer from the passed in list to our internal one.
|
||||
*/
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
while (buffer != NULL) {
|
||||
ISC_LIST_DEQUEUE(*buflist, buffer, link);
|
||||
ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link);
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
}
|
||||
|
||||
return (socket_recv(sock, dev, task, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_recv(isc_socket_t *sock0, isc_region_t *region,
|
||||
unsigned int minimum, isc_task_t *task,
|
||||
@@ -4757,7 +4596,6 @@ isc_socket_recv2(isc_socket_t *sock0, isc_region_t *region,
|
||||
|
||||
event->ev_sender = sock;
|
||||
event->result = ISC_R_UNSET;
|
||||
ISC_LIST_INIT(event->bufferlist);
|
||||
event->region = *region;
|
||||
event->n = 0;
|
||||
event->offset = 0;
|
||||
@@ -4912,65 +4750,6 @@ isc_socket_sendto(isc_socket_t *sock0, isc_region_t *region,
|
||||
return (socket_send(sock, dev, task, address, pktinfo, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg)
|
||||
{
|
||||
return (isc_socket_sendtov2(sock, buflist, task, action, arg, NULL,
|
||||
NULL, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
|
||||
{
|
||||
return (isc_socket_sendtov2(sock, buflist, task, action, arg, address,
|
||||
pktinfo, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendtov2(isc_socket_t *sock0, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
|
||||
unsigned int flags)
|
||||
{
|
||||
isc__socket_t *sock = (isc__socket_t *)sock0;
|
||||
isc_socketevent_t *dev;
|
||||
isc__socketmgr_t *manager;
|
||||
unsigned int iocount;
|
||||
isc_buffer_t *buffer;
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
REQUIRE(buflist != NULL);
|
||||
REQUIRE(!ISC_LIST_EMPTY(*buflist));
|
||||
REQUIRE(task != NULL);
|
||||
REQUIRE(action != NULL);
|
||||
|
||||
manager = sock->manager;
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
|
||||
iocount = isc_bufferlist_usedcount(buflist);
|
||||
REQUIRE(iocount > 0);
|
||||
|
||||
dev = allocate_socketevent(manager->mctx, sock,
|
||||
ISC_SOCKEVENT_SENDDONE, action, arg);
|
||||
if (dev == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
/*
|
||||
* Move each buffer from the passed in list to our internal one.
|
||||
*/
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
while (buffer != NULL) {
|
||||
ISC_LIST_DEQUEUE(*buflist, buffer, link);
|
||||
ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link);
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
}
|
||||
|
||||
return (socket_send(sock, dev, task, address, pktinfo, flags));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendto2(isc_socket_t *sock0, isc_region_t *region,
|
||||
isc_task_t *task,
|
||||
@@ -4985,7 +4764,6 @@ isc_socket_sendto2(isc_socket_t *sock0, isc_region_t *region,
|
||||
REQUIRE(sock->type == isc_sockettype_udp);
|
||||
event->ev_sender = sock;
|
||||
event->result = ISC_R_UNSET;
|
||||
ISC_LIST_INIT(event->bufferlist);
|
||||
event->region = *region;
|
||||
event->n = 0;
|
||||
event->offset = 0;
|
||||
|
@@ -84,13 +84,9 @@ isc_socket_open
|
||||
isc_socket_permunix
|
||||
isc_socket_recv
|
||||
isc_socket_recv2
|
||||
isc_socket_recvv
|
||||
isc_socket_send
|
||||
isc_socket_sendto
|
||||
isc_socket_sendto2
|
||||
isc_socket_sendtov
|
||||
isc_socket_sendtov2
|
||||
isc_socket_sendv
|
||||
isc_socket_setname
|
||||
isc_socketmgr_create
|
||||
isc_socketmgr_create2
|
||||
|
@@ -47,7 +47,6 @@
|
||||
|
||||
#include <isc/app.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/bufferlist.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/list.h>
|
||||
#include <isc/log.h>
|
||||
@@ -271,16 +270,6 @@ struct isc_socket {
|
||||
|
||||
#define _set_state(sock, _state) do { (sock)->state = (_state); (sock)->state_lineno = __LINE__; } while (0)
|
||||
|
||||
/*
|
||||
* Buffer structure
|
||||
*/
|
||||
typedef struct buflist buflist_t;
|
||||
|
||||
struct buflist {
|
||||
void *buf;
|
||||
unsigned int buflen;
|
||||
ISC_LINK(buflist_t) link;
|
||||
};
|
||||
|
||||
/*
|
||||
* I/O Completion ports Info structures
|
||||
@@ -296,7 +285,8 @@ typedef struct IoCompletionInfo {
|
||||
DWORD received_bytes;
|
||||
int request_type;
|
||||
struct msghdr messagehdr;
|
||||
ISC_LIST(buflist_t) bufferlist; /*%< list of buffers */
|
||||
void *buf;
|
||||
unsigned int buflen;
|
||||
} IoCompletionInfo;
|
||||
|
||||
/*
|
||||
@@ -950,91 +940,33 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
IoCompletionInfo *lpo)
|
||||
{
|
||||
unsigned int iovcount;
|
||||
isc_buffer_t *buffer;
|
||||
buflist_t *cpbuffer;
|
||||
isc_region_t used;
|
||||
size_t write_count;
|
||||
size_t skip_count;
|
||||
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
|
||||
memmove(&msg->to_addr, &dev->address.type, dev->address.length);
|
||||
msg->to_addr_len = dev->address.length;
|
||||
|
||||
buffer = ISC_LIST_HEAD(dev->bufferlist);
|
||||
write_count = 0;
|
||||
iovcount = 0;
|
||||
|
||||
/*
|
||||
* Single buffer I/O? Skip what we've done so far in this region.
|
||||
*/
|
||||
if (buffer == NULL) {
|
||||
write_count = dev->region.length - dev->n;
|
||||
cpbuffer = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(buflist_t));
|
||||
RUNTIME_CHECK(cpbuffer != NULL);
|
||||
cpbuffer->buf = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, write_count);
|
||||
RUNTIME_CHECK(cpbuffer->buf != NULL);
|
||||
write_count = dev->region.length - dev->n;
|
||||
lpo->buf = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, write_count);
|
||||
RUNTIME_CHECK(lpo->buf != NULL);
|
||||
|
||||
socket_log(__LINE__, sock, NULL, TRACE,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK,
|
||||
"alloc_buffer %p %d %p %d", cpbuffer, sizeof(buflist_t),
|
||||
cpbuffer->buf, write_count);
|
||||
socket_log(__LINE__, sock, NULL, TRACE,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK,
|
||||
"alloc_buffer %p %d", lpo->buf, write_count);
|
||||
|
||||
memmove(cpbuffer->buf,(dev->region.base + dev->n), write_count);
|
||||
cpbuffer->buflen = (unsigned int)write_count;
|
||||
ISC_LINK_INIT(cpbuffer, link);
|
||||
ISC_LIST_ENQUEUE(lpo->bufferlist, cpbuffer, link);
|
||||
iov[0].buf = cpbuffer->buf;
|
||||
iov[0].len = (u_long)write_count;
|
||||
iovcount = 1;
|
||||
memmove(lpo->buf,(dev->region.base + dev->n), write_count);
|
||||
lpo->buflen = (unsigned int)write_count;
|
||||
iov[0].buf = lpo->buf;
|
||||
iov[0].len = (u_long)write_count;
|
||||
iovcount = 1;
|
||||
|
||||
goto config;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multibuffer I/O.
|
||||
* Skip the data in the buffer list that we have already written.
|
||||
*/
|
||||
skip_count = dev->n;
|
||||
while (buffer != NULL) {
|
||||
REQUIRE(ISC_BUFFER_VALID(buffer));
|
||||
if (skip_count < isc_buffer_usedlength(buffer))
|
||||
break;
|
||||
skip_count -= isc_buffer_usedlength(buffer);
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
}
|
||||
|
||||
while (buffer != NULL) {
|
||||
INSIST(iovcount < MAXSCATTERGATHER_SEND);
|
||||
|
||||
isc_buffer_usedregion(buffer, &used);
|
||||
|
||||
if (used.length > 0) {
|
||||
int uselen = (int)(used.length - skip_count);
|
||||
cpbuffer = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(buflist_t));
|
||||
RUNTIME_CHECK(cpbuffer != NULL);
|
||||
cpbuffer->buf = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, uselen);
|
||||
RUNTIME_CHECK(cpbuffer->buf != NULL);
|
||||
|
||||
socket_log(__LINE__, sock, NULL, TRACE,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK,
|
||||
"alloc_buffer %p %d %p %d", cpbuffer, sizeof(buflist_t),
|
||||
cpbuffer->buf, write_count);
|
||||
|
||||
memmove(cpbuffer->buf,(used.base + skip_count), uselen);
|
||||
cpbuffer->buflen = uselen;
|
||||
iov[iovcount].buf = cpbuffer->buf;
|
||||
iov[iovcount].len = (u_long)(used.length - skip_count);
|
||||
write_count += uselen;
|
||||
skip_count = 0;
|
||||
iovcount++;
|
||||
}
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
}
|
||||
|
||||
INSIST(skip_count == 0);
|
||||
|
||||
config:
|
||||
msg->msg_iov = iov;
|
||||
msg->msg_iovlen = iovcount;
|
||||
msg->msg_totallen = (u_int)write_count;
|
||||
@@ -1059,8 +991,6 @@ static void
|
||||
destroy_socketevent(isc_event_t *event) {
|
||||
isc_socketevent_t *ev = (isc_socketevent_t *)event;
|
||||
|
||||
INSIST(ISC_LIST_EMPTY(ev->bufferlist));
|
||||
|
||||
(ev->destroy)(event);
|
||||
}
|
||||
|
||||
@@ -1079,7 +1009,6 @@ allocate_socketevent(isc_mem_t *mctx, isc_socket_t *sock,
|
||||
|
||||
ev->result = ISC_R_IOERROR; // XXXMLG temporary change to detect failure to set
|
||||
ISC_LINK_INIT(ev, ev_link);
|
||||
ISC_LIST_INIT(ev->bufferlist);
|
||||
ev->region.base = NULL;
|
||||
ev->n = 0;
|
||||
ev->offset = 0;
|
||||
@@ -1215,9 +1144,7 @@ map_socket_error(isc_socket_t *sock, int windows_errno, int *isc_errno,
|
||||
|
||||
static void
|
||||
fill_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
isc_region_t r;
|
||||
int copylen;
|
||||
isc_buffer_t *buffer;
|
||||
|
||||
INSIST(dev->n < dev->minimum);
|
||||
INSIST(sock->recvbuf.remaining > 0);
|
||||
@@ -1241,36 +1168,12 @@ fill_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
dev->address = sock->address;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run through the list of buffers we were given, and find the
|
||||
* first one with space. Once it is found, loop through, filling
|
||||
* the buffers as much as possible.
|
||||
*/
|
||||
buffer = ISC_LIST_HEAD(dev->bufferlist);
|
||||
if (buffer != NULL) { // Multi-buffer receive
|
||||
while (buffer != NULL && sock->recvbuf.remaining > 0) {
|
||||
REQUIRE(ISC_BUFFER_VALID(buffer));
|
||||
if (isc_buffer_availablelength(buffer) > 0) {
|
||||
isc_buffer_availableregion(buffer, &r);
|
||||
copylen = min(r.length,
|
||||
sock->recvbuf.remaining);
|
||||
memmove(r.base, sock->recvbuf.consume_position,
|
||||
copylen);
|
||||
sock->recvbuf.consume_position += copylen;
|
||||
sock->recvbuf.remaining -= copylen;
|
||||
isc_buffer_add(buffer, copylen);
|
||||
dev->n += copylen;
|
||||
}
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
}
|
||||
} else { // Single-buffer receive
|
||||
copylen = min(dev->region.length - dev->n, sock->recvbuf.remaining);
|
||||
memmove(dev->region.base + dev->n,
|
||||
sock->recvbuf.consume_position, copylen);
|
||||
sock->recvbuf.consume_position += copylen;
|
||||
sock->recvbuf.remaining -= copylen;
|
||||
dev->n += copylen;
|
||||
}
|
||||
copylen = min(dev->region.length - dev->n, sock->recvbuf.remaining);
|
||||
memmove(dev->region.base + dev->n,
|
||||
sock->recvbuf.consume_position, copylen);
|
||||
sock->recvbuf.consume_position += copylen;
|
||||
sock->recvbuf.remaining -= copylen;
|
||||
dev->n += copylen;
|
||||
|
||||
/*
|
||||
* UDP receives are all-consuming. That is, if we have 4k worth of
|
||||
@@ -1377,7 +1280,6 @@ startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,
|
||||
lpo->dev = dev;
|
||||
mh = &lpo->messagehdr;
|
||||
memset(mh, 0, sizeof(struct msghdr));
|
||||
ISC_LIST_INIT(lpo->bufferlist);
|
||||
|
||||
build_msghdr_send(sock, dev, mh, cmsg, sock->iov, lpo);
|
||||
|
||||
@@ -2301,8 +2203,6 @@ static void
|
||||
internal_send(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
struct msghdr *messagehdr, int nbytes, int send_errno, IoCompletionInfo *lpo)
|
||||
{
|
||||
buflist_t *buffer;
|
||||
|
||||
/*
|
||||
* Find out what socket this is and lock it.
|
||||
*/
|
||||
@@ -2315,17 +2215,14 @@ internal_send(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALSEND,
|
||||
"internal_send: task got socket event %p", dev);
|
||||
|
||||
buffer = ISC_LIST_HEAD(lpo->bufferlist);
|
||||
while (buffer != NULL) {
|
||||
ISC_LIST_DEQUEUE(lpo->bufferlist, buffer, link);
|
||||
|
||||
if (lpo->buf != NULL) {
|
||||
socket_log(__LINE__, sock, NULL, TRACE,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK,
|
||||
"free_buffer %p %p", buffer, buffer->buf);
|
||||
"free_buffer %p", lpo->buf);
|
||||
|
||||
HeapFree(hHeapHandle, 0, buffer->buf);
|
||||
HeapFree(hHeapHandle, 0, buffer);
|
||||
buffer = ISC_LIST_HEAD(lpo->bufferlist);
|
||||
HeapFree(hHeapHandle, 0, lpo->buf);
|
||||
lpo->buf = NULL;
|
||||
lpo->buflen = 0;
|
||||
}
|
||||
|
||||
INSIST(sock->pending_iocp > 0);
|
||||
@@ -2836,77 +2733,6 @@ socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
unsigned int minimum, isc_task_t *task,
|
||||
isc_taskaction_t action, void *arg)
|
||||
{
|
||||
isc_socketevent_t *dev;
|
||||
isc_socketmgr_t *manager;
|
||||
unsigned int iocount;
|
||||
isc_buffer_t *buffer;
|
||||
isc_result_t ret;
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
LOCK(&sock->lock);
|
||||
CONSISTENT(sock);
|
||||
|
||||
/*
|
||||
* Make sure that the socket is not closed. XXXMLG change error here?
|
||||
*/
|
||||
if (sock->fd == INVALID_SOCKET) {
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_CONNREFUSED);
|
||||
}
|
||||
|
||||
REQUIRE(buflist != NULL);
|
||||
REQUIRE(!ISC_LIST_EMPTY(*buflist));
|
||||
REQUIRE(task != NULL);
|
||||
REQUIRE(action != NULL);
|
||||
|
||||
manager = sock->manager;
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
|
||||
iocount = isc_bufferlist_availablecount(buflist);
|
||||
REQUIRE(iocount > 0);
|
||||
|
||||
INSIST(sock->bound);
|
||||
|
||||
dev = allocate_socketevent(manager->mctx, sock,
|
||||
ISC_SOCKEVENT_RECVDONE, action, arg);
|
||||
if (dev == NULL) {
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
* UDP sockets are always partial read
|
||||
*/
|
||||
if (sock->type == isc_sockettype_udp)
|
||||
dev->minimum = 1;
|
||||
else {
|
||||
if (minimum == 0)
|
||||
dev->minimum = iocount;
|
||||
else
|
||||
dev->minimum = minimum;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move each buffer from the passed in list to our internal one.
|
||||
*/
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
while (buffer != NULL) {
|
||||
ISC_LIST_DEQUEUE(*buflist, buffer, link);
|
||||
ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link);
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
}
|
||||
|
||||
ret = socket_recv(sock, dev, task, 0);
|
||||
|
||||
UNLOCK(&sock->lock);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
|
||||
unsigned int minimum, isc_task_t *task,
|
||||
@@ -2967,7 +2793,6 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
|
||||
return (ISC_R_CONNREFUSED);
|
||||
}
|
||||
|
||||
ISC_LIST_INIT(event->bufferlist);
|
||||
event->region = *region;
|
||||
event->n = 0;
|
||||
event->offset = 0;
|
||||
@@ -3112,80 +2937,6 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg)
|
||||
{
|
||||
return (isc_socket_sendtov2(sock, buflist, task, action, arg, NULL,
|
||||
NULL, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
|
||||
{
|
||||
return (isc_socket_sendtov2(sock, buflist, task, action, arg, address,
|
||||
pktinfo, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
|
||||
unsigned int flags)
|
||||
{
|
||||
isc_socketevent_t *dev;
|
||||
isc_socketmgr_t *manager;
|
||||
unsigned int iocount;
|
||||
isc_buffer_t *buffer;
|
||||
isc_result_t ret;
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
|
||||
LOCK(&sock->lock);
|
||||
CONSISTENT(sock);
|
||||
|
||||
/*
|
||||
* make sure that the socket's not closed
|
||||
*/
|
||||
if (sock->fd == INVALID_SOCKET) {
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_CONNREFUSED);
|
||||
}
|
||||
REQUIRE(buflist != NULL);
|
||||
REQUIRE(!ISC_LIST_EMPTY(*buflist));
|
||||
REQUIRE(task != NULL);
|
||||
REQUIRE(action != NULL);
|
||||
|
||||
manager = sock->manager;
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
|
||||
iocount = isc_bufferlist_usedcount(buflist);
|
||||
REQUIRE(iocount > 0);
|
||||
|
||||
dev = allocate_socketevent(manager->mctx, sock,
|
||||
ISC_SOCKEVENT_SENDDONE, action, arg);
|
||||
if (dev == NULL) {
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move each buffer from the passed in list to our internal one.
|
||||
*/
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
while (buffer != NULL) {
|
||||
ISC_LIST_DEQUEUE(*buflist, buffer, link);
|
||||
ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link);
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
}
|
||||
|
||||
ret = socket_send(sock, dev, task, address, pktinfo, flags);
|
||||
UNLOCK(&sock->lock);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
|
||||
@@ -3209,7 +2960,6 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task,
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_CONNREFUSED);
|
||||
}
|
||||
ISC_LIST_INIT(event->bufferlist);
|
||||
event->region = *region;
|
||||
event->n = 0;
|
||||
event->offset = 0;
|
||||
|
Reference in New Issue
Block a user