diff --git a/bin/named/client.c b/bin/named/client.c index 125ef4cabd..0935024f7f 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.c,v 1.141 2001/01/23 18:47:33 gson Exp $ */ +/* $Id: client.c,v 1.142 2001/01/27 02:07:59 bwelling Exp $ */ #include @@ -134,10 +134,10 @@ struct ns_clientmgr { * client manager's list of active clients. * * If it is a TCP client object, it has a TCP listener socket - * and an outstading TCP listen request. + * and an outstanding TCP listen request. * - * If it is a UDP client object, it is associated with a - * dispatch and has an outstanding dispatch request. + * If it is a UDP client object, it has a UDP listener socket + * and an outstanding UDP receive request. */ #define NS_CLIENTSTATE_READING 3 @@ -152,8 +152,7 @@ struct ns_clientmgr { /* * The client object has received a request and is working * on it. It has a view, and it may have any of a non-reset OPT, - * recursion quota, and an outstanding write request. If it - * is a UDP client object, it has a dispatch event. + * recursion quota, and an outstanding write request. */ #define NS_CLIENTSTATE_MAX 9 @@ -166,6 +165,7 @@ struct ns_clientmgr { static void client_read(ns_client_t *client); static void client_accept(ns_client_t *client); +static void client_udprecv(ns_client_t *client); static void clientmgr_destroy(ns_clientmgr_t *manager); static isc_boolean_t exit_check(ns_client_t *client); static void ns_client_endrequest(ns_client_t *client); @@ -191,14 +191,9 @@ client_deactivate(ns_client_t *client) { if (client->tcplistener != NULL) isc_socket_detach(&client->tcplistener); - if (client->dispentry != NULL) { - dns_dispatchevent_t **deventp; - if (client->dispevent != NULL) - deventp = &client->dispevent; - else - deventp = NULL; - dns_dispatch_removerequest(&client->dispentry, deventp); - } + if (client->udpsocket != NULL) + isc_socket_detach(&client->udpsocket); + if (client->dispatch != NULL) dns_dispatch_detach(&client->dispatch); @@ -237,6 +232,7 @@ client_free(ns_client_t *client) { ns_query_free(client); isc_mem_put(client->mctx, client->sendbuf, SEND_BUFFER_SIZE); + isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); isc_timer_detach(&client->timer); if (client->tcpbuf != NULL) @@ -338,13 +334,14 @@ exit_check(ns_client_t *client) { if (TCP_CLIENT(client)) socket = client->tcpsocket; else - socket = - dns_dispatch_getsocket(client->dispatch); + socket = client->udpsocket; isc_socket_cancel(socket, client->task, ISC_SOCKCANCEL_SEND); } - if (! (client->nsends == 0 && client->references == 0)) { + if (! (client->nsends == 0 && client->nrecvs == 0 && + client->references == 0)) + { /* * Still waiting for I/O cancel completion. * or lingering references. @@ -411,16 +408,8 @@ exit_check(ns_client_t *client) { if (NS_CLIENTSTATE_READY == client->newstate) { if (TCP_CLIENT(client)) { client_accept(client); - } else { - /* - * Give the processed dispatch event back to - * the dispatch. This tells the dispatch - * that we are ready to receive the next event. - */ - dns_dispatch_freeevent(client->dispatch, - client->dispentry, - &client->dispevent); - } + } else + client_udprecv(client); client->newstate = NS_CLIENTSTATE_MAX; return (ISC_TRUE); } @@ -440,6 +429,16 @@ exit_check(ns_client_t *client) { return (ISC_TRUE); } /* Accept cancel is complete. */ + + if (client->nrecvs > 0) + isc_socket_cancel(client->udpsocket, client->task, + ISC_SOCKCANCEL_RECV); + if (! (client->nrecvs == 0)) { + /* Still waiting for recv cancel completion. */ + return (ISC_TRUE); + } + /* Recv cancel is complete. */ + client_deactivate(client); client->state = NS_CLIENTSTATE_INACTIVE; INSIST(client->recursionquota == NULL); @@ -468,7 +467,6 @@ exit_check(ns_client_t *client) { static void client_start(isc_task_t *task, isc_event_t *event) { ns_client_t *client = (ns_client_t *) event->ev_arg; - isc_result_t result; INSIST(task == client->task); @@ -477,25 +475,7 @@ client_start(isc_task_t *task, isc_event_t *event) { if (TCP_CLIENT(client)) { client_accept(client); } else { - result = dns_dispatch_addrequest(client->dispatch, - client->task, - client_request, - client, - &client->dispentry); - - if (result != ISC_R_SUCCESS) { - ns_client_log(client, - DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, - ISC_LOG_DEBUG(3), - "dns_dispatch_addrequest() " - "failed: %s", - isc_result_totext(result)); - /* - * Not much we can do here but log the failure; - * the client will effectively go idle. - */ - } + client_udprecv(client); } } @@ -535,6 +515,7 @@ ns_client_endrequest(ns_client_t *client) { INSIST(client->naccepts == 0); INSIST(client->nreads == 0); INSIST(client->nsends == 0); + INSIST(client->nrecvs == 0); INSIST(client->state == NS_CLIENTSTATE_WORKING); CTRACE("endrequest"); @@ -731,8 +712,8 @@ client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) { socket = client->tcpsocket; address = NULL; } else { - socket = dns_dispatch_getsocket(client->dispatch); - address = &client->dispevent->addr; + socket = client->udpsocket; + address = &client->peeraddr; isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); if (ns_g_server->blackholeacl != NULL && @@ -1135,16 +1116,17 @@ client_getoptattrs(ns_client_t *client, dns_rdataset_t *opt) { /* - * Handle an incoming request event from the dispatch (UDP case) + * Handle an incoming request event from the socket (UDP case) * or tcpmsg (TCP case). */ static void client_request(isc_task_t *task, isc_event_t *event) { ns_client_t *client; - dns_dispatchevent_t *devent; + isc_socketevent_t *sevent; isc_result_t result; isc_result_t sigresult; isc_buffer_t *buffer; + isc_buffer_t tbuffer; dns_view_t *view; dns_rdataset_t *opt; isc_boolean_t ra; /* Recursion available. */ @@ -1166,21 +1148,22 @@ client_request(isc_task_t *task, isc_event_t *event) { RWLOCK(&ns_g_server->conflock, isc_rwlocktype_read); dns_zonemgr_lockconf(ns_g_server->zonemgr, isc_rwlocktype_read); - if (event->ev_type == DNS_EVENT_DISPATCH) { + if (event->ev_type == ISC_SOCKEVENT_RECVDONE) { INSIST(!TCP_CLIENT(client)); - devent = (dns_dispatchevent_t *)event; - REQUIRE(client->dispentry != NULL); - client->dispevent = devent; - buffer = &devent->buffer; - result = devent->result; - client->peeraddr = devent->addr; + sevent = (isc_socketevent_t *)event; + isc_buffer_init(&tbuffer, sevent->region.base, sevent->n); + isc_buffer_add(&tbuffer, sevent->n); + buffer = &tbuffer; + result = sevent->result; + client->peeraddr = sevent->address; client->peeraddr_valid = ISC_TRUE; - if ((devent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { + if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { client->attributes |= NS_CLIENTATTR_PKTINFO; - client->pktinfo = devent->pktinfo; + client->pktinfo = sevent->pktinfo; } - if ((devent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0) + if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0) client->attributes |= NS_CLIENTATTR_MULTICAST; + client->nrecvs--; } else { INSIST(TCP_CLIENT(client)); REQUIRE(event->ev_type == DNS_EVENT_TCPMSG); @@ -1232,14 +1215,20 @@ client_request(isc_task_t *task, isc_event_t *event) { } /* - * We expect a query, not a response. Unexpected UDP responses - * are discarded early by the dispatcher, but TCP responses - * bypass the dispatcher and must be discarded here. + * We expect a query, not a response. If this is a UDP response, + * forward it to the dispatcher. If it's a TCP response, + * discarded it here. */ if ((client->message->flags & DNS_MESSAGEFLAG_QR) != 0) { - CTRACE("unexpected response"); - ns_client_next(client, DNS_R_FORMERR); - goto cleanup_serverlock; + if (TCP_CLIENT(client)) { + CTRACE("unexpected response"); + ns_client_next(client, DNS_R_FORMERR); + goto cleanup_serverlock; + } else { + dns_dispatch_importrecv(client->dispatch, &event); + ns_client_next(client, ISC_R_SUCCESS); + goto cleanup_serverlock; + } } /* @@ -1546,6 +1535,10 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) if (client->sendbuf == NULL) goto cleanup_message; + client->recvbuf = isc_mem_get(manager->mctx, RECV_BUFFER_SIZE); + if (client->recvbuf == NULL) + goto cleanup_sendbuf; + client->magic = NS_CLIENT_MAGIC; client->mctx = manager->mctx; client->manager = NULL; @@ -1554,13 +1547,13 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) client->naccepts = 0; client->nreads = 0; client->nsends = 0; + client->nrecvs = 0; client->references = 0; client->attributes = 0; client->view = NULL; client->lockview = NULL; client->dispatch = NULL; - client->dispentry = NULL; - client->dispevent = NULL; + client->udpsocket = NULL; client->tcplistener = NULL; client->tcpsocket = NULL; client->tcpmsg_valid = ISC_FALSE; @@ -1594,7 +1587,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) */ result = ns_query_init(client); if (result != ISC_R_SUCCESS) - goto cleanup_sendbuf; + goto cleanup_recvbuf; CTRACE("create"); @@ -1602,6 +1595,9 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) return (ISC_R_SUCCESS); + cleanup_recvbuf: + isc_mem_put(manager->mctx, client->recvbuf, RECV_BUFFER_SIZE); + cleanup_sendbuf: isc_mem_put(manager->mctx, client->sendbuf, SEND_BUFFER_SIZE); @@ -1782,6 +1778,34 @@ client_accept(ns_client_t *client) { UNLOCK(&client->interface->lock); } +static void +client_udprecv(ns_client_t *client) { + isc_result_t result; + isc_region_t r; + + CTRACE("udprecv"); + + r.base = client->recvbuf; + r.length = RECV_BUFFER_SIZE; + result = isc_socket_recv(client->udpsocket, &r, 1, + client->task, client_request, client); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_socket_recv() failed: %s", + isc_result_totext(result)); + /* + * XXXBEW What should we do? We're trying to accept but + * it didn't work. If we just give up, then UDP + * service may eventually stop. + * + * For now, we just go idle. + */ + return; + } + INSIST(client->nrecvs == 0); + client->nrecvs++; +} + void ns_client_attach(ns_client_t *source, ns_client_t **targetp) { REQUIRE(NS_CLIENT_VALID(source)); @@ -1972,8 +1996,12 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, isc_socket_attach(ifp->tcpsocket, &client->tcplistener); } else { + isc_socket_t *sock; + dns_dispatch_attach(ifp->udpdispatch, &client->dispatch); + sock = dns_dispatch_getsocket(client->dispatch); + isc_socket_attach(sock, &client->udpsocket); } client->manager = manager; ISC_LIST_APPEND(manager->active, client, link); diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h index c1ba4c0485..62ba9ffbe9 100644 --- a/bin/named/include/named/client.h +++ b/bin/named/include/named/client.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.h,v 1.49 2001/01/09 21:40:12 bwelling Exp $ */ +/* $Id: client.h,v 1.50 2001/01/27 02:08:03 bwelling Exp $ */ #ifndef NAMED_CLIENT_H #define NAMED_CLIENT_H 1 @@ -93,14 +93,14 @@ struct ns_client { int naccepts; int nreads; int nsends; + int nrecvs; int references; unsigned int attributes; isc_task_t * task; dns_view_t * view; dns_view_t * lockview; dns_dispatch_t * dispatch; - dns_dispentry_t * dispentry; - dns_dispatchevent_t * dispevent; + isc_socket_t * udpsocket; isc_socket_t * tcplistener; isc_socket_t * tcpsocket; unsigned char * tcpbuf; @@ -109,6 +109,7 @@ struct ns_client { isc_timer_t * timer; dns_message_t * message; unsigned char * sendbuf; + unsigned char * recvbuf; dns_rdataset_t * opt; isc_uint16_t udpsize; isc_uint16_t extflags; diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c index 233c47c598..e6c6168028 100644 --- a/bin/named/interfacemgr.c +++ b/bin/named/interfacemgr.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: interfacemgr.c,v 1.55 2001/01/09 21:39:42 bwelling Exp $ */ +/* $Id: interfacemgr.c,v 1.56 2001/01/27 02:08:01 bwelling Exp $ */ #include @@ -244,6 +244,7 @@ ns_interface_listenudp(ns_interface_t *ifp) { attrs |= DNS_DISPATCHATTR_IPV4; else attrs |= DNS_DISPATCHATTR_IPV6; + attrs |= DNS_DISPATCHATTR_NOLISTEN; attrmask = 0; attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; @@ -269,6 +270,8 @@ ns_interface_listenudp(ns_interface_t *ifp) { return (ISC_R_SUCCESS); addtodispatch_failure: + dns_dispatch_changeattributes(ifp->udpdispatch, 0, + DNS_DISPATCHATTR_NOLISTEN); dns_dispatch_detach(&ifp->udpdispatch); udp_dispatch_failure: return (result); @@ -373,8 +376,11 @@ ns_interface_destroy(ns_interface_t *ifp) { ns_interface_shutdown(ifp); - if (ifp->udpdispatch != NULL) + if (ifp->udpdispatch != NULL) { + dns_dispatch_changeattributes(ifp->udpdispatch, 0, + DNS_DISPATCHATTR_NOLISTEN); dns_dispatch_detach(&ifp->udpdispatch); + } if (ifp->tcpsocket != NULL) isc_socket_detach(&ifp->tcpsocket); diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index bc661b8bb2..904501e3df 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dispatch.c,v 1.85 2001/01/25 13:52:32 gson Exp $ */ +/* $Id: dispatch.c,v 1.86 2001/01/27 02:08:04 bwelling Exp $ */ #include @@ -109,6 +109,7 @@ struct dns_dispatch { isc_sockaddr_t local; /* local address */ unsigned int maxrequests; /* max requests */ dns_acl_t *blackhole; + isc_event_t *ctlevent; /* Locked by mgr->lock. */ ISC_LINK(dns_dispatch_t) link; @@ -156,7 +157,7 @@ struct dns_dispatch { static dns_dispentry_t *bucket_search(dns_qid_t *, isc_sockaddr_t *, dns_messageid_t, unsigned int); static isc_boolean_t destroy_disp_ok(dns_dispatch_t *); -static void destroy_disp(dns_dispatch_t **); +static void destroy_disp(isc_task_t *task, isc_event_t *event); static void udp_recv(isc_task_t *, isc_event_t *); static void tcp_recv(isc_task_t *, isc_event_t *); static inline void startrecv(dns_dispatch_t *); @@ -376,14 +377,19 @@ destroy_disp_ok(dns_dispatch_t *disp) * The manager must be locked. */ static void -destroy_disp(dns_dispatch_t **dispp) { - dns_dispatchmgr_t *mgr; +destroy_disp(isc_task_t *task, isc_event_t *event) { dns_dispatch_t *disp; + dns_dispatchmgr_t *mgr; + isc_boolean_t killmgr; - disp = *dispp; - *dispp = NULL; + INSIST(event->ev_type == DNS_EVENT_DISPATCHCONTROL); + + UNUSED(task); + + disp = event->ev_arg; mgr = disp->mgr; + LOCK(&mgr->lock); ISC_LIST_UNLINK(mgr->list, disp, link); dispatch_log(disp, LVL(90), @@ -392,8 +398,14 @@ destroy_disp(dns_dispatch_t **dispp) { isc_socket_detach(&disp->socket); isc_task_detach(&disp->task); + isc_event_free(&event); dispatch_free(&disp); + + killmgr = destroy_mgr_ok(mgr); + UNLOCK(&mgr->lock); + if (killmgr) + destroy_mgr(&mgr); } @@ -537,8 +549,10 @@ udp_recv(isc_task_t *task, isc_event_t *ev_in) { "got packet: requests %d, buffers %d, recvs %d", disp->requests, disp->mgr->buffers, disp->recv_pending); - INSIST(disp->recv_pending != 0); - disp->recv_pending = 0; + if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0) { + INSIST(disp->recv_pending != 0); + disp->recv_pending = 0; + } if (disp->shutting_down) { /* @@ -551,14 +565,8 @@ udp_recv(isc_task_t *task, isc_event_t *ev_in) { killit = destroy_disp_ok(disp); UNLOCK(&disp->lock); - if (killit) { - LOCK(&mgr->lock); - destroy_disp(&disp); - killit = destroy_mgr_ok(mgr); - UNLOCK(&mgr->lock); - if (killit) - destroy_mgr(&mgr); - } + if (killit) + isc_task_send(disp->task, &disp->ctlevent); return; } @@ -800,14 +808,8 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) { */ killit = destroy_disp_ok(disp); UNLOCK(&disp->lock); - if (killit) { - LOCK(&mgr->lock); - destroy_disp(&disp); - killit = destroy_mgr_ok(mgr); - UNLOCK(&mgr->lock); - if (killit) - destroy_mgr(&mgr); - } + if (killit) + isc_task_send(disp->task, &disp->ctlevent); return; } @@ -921,6 +923,9 @@ startrecv(dns_dispatch_t *disp) { if (disp->shutting_down == 1) return; + if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) + return; + if (disp->recv_pending != 0) return; @@ -1560,6 +1565,13 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, if (result != ISC_R_SUCCESS) goto kill_socket; + disp->ctlevent = isc_event_allocate(mgr->mctx, disp, + DNS_EVENT_DISPATCHCONTROL, + destroy_disp, disp, + sizeof(isc_event_t)); + if (disp->ctlevent == NULL) + goto kill_task; + isc_task_setname(disp->task, "tcpdispatch", disp); dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg); @@ -1583,6 +1595,8 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, /* * Error returns. */ + kill_task: + isc_task_detach(&disp->task); kill_socket: isc_socket_detach(&disp->socket); deallocate_dispatch: @@ -1634,6 +1648,13 @@ dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, if (disp->maxrequests < maxrequests) disp->maxrequests = maxrequests; + if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0 && + (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) + disp->attributes |= DNS_DISPATCHATTR_NOLISTEN; + if (disp->recv_pending > 0) + isc_socket_cancel(disp->socket, NULL, + ISC_SOCKCANCEL_RECV); + UNLOCK(&disp->lock); UNLOCK(&mgr->lock); @@ -1693,6 +1714,13 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, if (result != ISC_R_SUCCESS) goto kill_socket; + disp->ctlevent = isc_event_allocate(mgr->mctx, disp, + DNS_EVENT_DISPATCHCONTROL, + destroy_disp, disp, + sizeof(isc_event_t)); + if (disp->ctlevent == NULL) + goto kill_task; + isc_task_setname(disp->task, "udpdispatch", disp); attributes &= ~DNS_DISPATCHATTR_TCP; @@ -1715,6 +1743,8 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, /* * Error returns. */ + kill_task: + isc_task_detach(&disp->task); kill_socket: isc_socket_detach(&disp->socket); deallocate_dispatch: @@ -1771,14 +1801,8 @@ dns_dispatch_detach(dns_dispatch_t **dispp) { killit = destroy_disp_ok(disp); UNLOCK(&disp->lock); - if (killit) { - LOCK(&mgr->lock); - destroy_disp(&disp); - killit = destroy_mgr_ok(mgr); - UNLOCK(&mgr->lock); - if (killit) - destroy_mgr(&mgr); - } + if (killit) + isc_task_send(disp->task, &disp->ctlevent); } isc_result_t @@ -1988,13 +2012,8 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp, killit = destroy_disp_ok(disp); UNLOCK(&disp->lock); - if (killit) { - destroy_disp(&disp); - killit = destroy_mgr_ok(mgr); - UNLOCK(&mgr->lock); - if (killit) - destroy_mgr(&mgr); - } + if (killit) + isc_task_send(disp->task, &disp->ctlevent); } isc_result_t @@ -2138,13 +2157,8 @@ dns_dispatch_removerequest(dns_dispentry_t **resp, killit = destroy_disp_ok(disp); UNLOCK(&disp->lock); - if (killit) { - destroy_disp(&disp); - killit = destroy_mgr_ok(mgr); - UNLOCK(&mgr->lock); - if (killit) - destroy_mgr(&mgr); - } + if (killit) + isc_task_send(disp->task, &disp->ctlevent); } void @@ -2344,11 +2358,45 @@ dns_dispatch_changeattributes(dns_dispatch_t *disp, */ LOCK(&disp->lock); + + if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0 && + (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0) + { + disp->attributes &= ~DNS_DISPATCHATTR_NOLISTEN; + startrecv(disp); + } + disp->attributes &= ~mask; disp->attributes |= (attributes & mask); UNLOCK(&disp->lock); } +void +dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t **eventp) { + void *buf; + isc_socketevent_t *sevent; + + REQUIRE(VALID_DISPATCH(disp)); + REQUIRE((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0); + REQUIRE(eventp != NULL && *eventp != NULL); + + sevent = (isc_socketevent_t *)*eventp; + + INSIST(sevent->n <= disp->mgr->buffersize); + buf = allocate_udp_buffer(disp); + if (buf == NULL) { + isc_event_free(eventp); + return; + } + memcpy(buf, sevent->region.base, sevent->n); + sevent->region.base = buf; + sevent->region.length = disp->mgr->buffersize; + sevent->ev_action = udp_recv; + sevent->ev_arg = disp; + sevent->ev_sender = NULL; + isc_task_send(disp->task, eventp); +} + #if 0 void dns_dispatchmgr_dump(dns_dispatchmgr_t *mgr) { diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h index 90706b8478..1f26167db2 100644 --- a/lib/dns/include/dns/dispatch.h +++ b/lib/dns/include/dns/dispatch.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dispatch.h,v 1.38 2001/01/09 21:52:47 bwelling Exp $ */ +/* $Id: dispatch.h,v 1.39 2001/01/27 02:08:06 bwelling Exp $ */ #ifndef DNS_DISPATCH_H #define DNS_DISPATCH_H 1 @@ -105,8 +105,8 @@ struct dns_dispatchevent { * _IPV4, _IPV6 * The dispatcher uses an ipv4 or ipv6 socket. * - * _ACCEPTREQUEST - * The dispatcher can be used to accept requests. + * _NOLISTEN + * The dispatcher should not listen on the socket. * * _MAKEQUERY * The dispatcher can be used to issue queries to other servers, and @@ -117,7 +117,7 @@ struct dns_dispatchevent { #define DNS_DISPATCHATTR_UDP 0x00000004U #define DNS_DISPATCHATTR_IPV4 0x00000008U #define DNS_DISPATCHATTR_IPV6 0x00000010U -#define DNS_DISPATCHATTR_ACCEPTREQUEST 0x00000020U +#define DNS_DISPATCHATTR_NOLISTEN 0x00000020U #define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U #define DNS_DISPATCHATTR_CONNECTED 0x00000080U @@ -462,6 +462,18 @@ dns_dispatch_changeattributes(dns_dispatch_t *disp, * attribute on a TCP socket isn't reasonable. */ +void +dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t **eventp); +/* + * Give a socket receive event to the dispatcher. This is used for sockets + * shared between dispatchers and clients. If the dispatcher fails to send + * the event, it frees it. + * + * Requires: + * disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set. + * eventp != NULL && *eventp != NULL + */ + ISC_LANG_ENDDECLS #endif /* DNS_DISPATCH_H */ diff --git a/lib/dns/include/dns/events.h b/lib/dns/include/dns/events.h index 8747e810d9..5886de7a26 100644 --- a/lib/dns/include/dns/events.h +++ b/lib/dns/include/dns/events.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: events.h,v 1.35 2001/01/19 22:22:17 bwelling Exp $ */ +/* $Id: events.h,v 1.36 2001/01/27 02:08:07 bwelling Exp $ */ #ifndef DNS_EVENTS_H #define DNS_EVENTS_H 1 @@ -58,6 +58,7 @@ #define DNS_EVENT_IOREADY (ISC_EVENTCLASS_DNS + 29) #define DNS_EVENT_LOOKUPDONE (ISC_EVENTCLASS_DNS + 30) #define DNS_EVENT_QUERYABORTED (ISC_EVENTCLASS_DNS + 31) +#define DNS_EVENT_DISPATCHCONTROL (ISC_EVENTCLASS_DNS + 32) #define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0) #define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535)