Lines Matching refs:client

1 /*	$NetBSD: client.c,v 1.6 2012/12/04 23:38:38 spz Exp $	*/
69 * All client state changes, other than that from idle to listening, occur
73 * If a routine is ever created that allows someone other than the client's
74 * task to change the client, then the client will have to be locked.
79 #define CTRACE(m) ns_client_log(client, \
105 * client objects, since concurrent access to a shared context would cause
118 /*% nameserver client manager structure */
154 * states are generally "more active", meaning that the client can
159 * To force the client into a less active state, set client->newstate
166 * The client object no longer exists.
171 * The client object exists and has a task and timer.
173 * It is on the client manager's list of inactive clients.
179 * The client object is either a TCP or a UDP one, and
181 * client manager's list of active clients.
183 * If it is a TCP client object, it has a TCP listener socket
186 * If it is a UDP client object, it has a UDP listener socket
192 * The client object is a TCP client object that has received
195 * UDP client objects.
200 * The client object has received a request and is working
207 * The client object is recursing. It will be on the 'recursing'
213 * Sentinel value used to indicate "no state". When client->newstate
227 static void client_read(ns_client_t *client);
228 static void client_accept(ns_client_t *client);
229 static void client_udprecv(ns_client_t *client);
231 static isc_boolean_t exit_check(ns_client_t *client);
232 static void ns_client_endrequest(ns_client_t *client);
235 static void ns_client_dumpmessage(ns_client_t *client, const char *reason);
240 ns_client_recursing(ns_client_t *client) {
241 REQUIRE(NS_CLIENT_VALID(client));
242 REQUIRE(client->state == NS_CLIENTSTATE_WORKING);
244 LOCK(&client->manager->reclock);
245 client->newstate = client->state = NS_CLIENTSTATE_RECURSING;
246 ISC_LIST_APPEND(client->manager->recursing, client, rlink);
247 UNLOCK(&client->manager->reclock);
251 ns_client_killoldestquery(ns_client_t *client) {
253 REQUIRE(NS_CLIENT_VALID(client));
255 LOCK(&client->manager->reclock);
256 oldest = ISC_LIST_HEAD(client->manager->recursing);
258 ISC_LIST_UNLINK(client->manager->recursing, oldest, rlink);
259 UNLOCK(&client->manager->reclock);
262 UNLOCK(&client->manager->reclock);
266 ns_client_settimeout(ns_client_t *client, unsigned int seconds) {
271 result = isc_timer_reset(client->timer, isc_timertype_once, NULL,
273 client->timerset = ISC_TRUE;
275 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
286 * the caller must no longer use the client object as it may have been
290 exit_check(ns_client_t *client) {
294 REQUIRE(NS_CLIENT_VALID(client));
295 manager = client->manager;
297 if (client->state <= client->newstate)
300 INSIST(client->newstate < NS_CLIENTSTATE_RECURSING);
308 * - The client does not detach from the view until references is zero
313 if (client->nupdates == 0 &&
314 client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL)
315 dns_view_detach(&client->view);
317 if (client->state == NS_CLIENTSTATE_WORKING ||
318 client->state == NS_CLIENTSTATE_RECURSING)
320 INSIST(client->newstate <= NS_CLIENTSTATE_READING);
324 if (client->nupdates > 0)
330 if (client->nsends > 0) {
332 if (TCP_CLIENT(client))
333 socket = client->tcpsocket;
335 socket = client->udpsocket;
336 isc_socket_cancel(socket, client->task,
340 if (! (client->nsends == 0 && client->nrecvs == 0 &&
341 client->references == 0))
353 * the client is no longer on the recursing list.
355 * We need to check whether the client is still linked,
359 if (client->state == NS_CLIENTSTATE_RECURSING) {
361 if (ISC_LINK_LINKED(client, rlink))
363 client, rlink);
366 ns_client_endrequest(client);
368 client->state = NS_CLIENTSTATE_READING;
369 INSIST(client->recursionquota == NULL);
371 if (NS_CLIENTSTATE_READING == client->newstate) {
372 client_read(client);
373 client->newstate = NS_CLIENTSTATE_MAX;
378 if (client->state == NS_CLIENTSTATE_READING) {
383 INSIST(client->recursionquota == NULL);
384 INSIST(client->newstate <= NS_CLIENTSTATE_READY);
385 if (client->nreads > 0)
386 dns_tcpmsg_cancelread(&client->tcpmsg);
387 if (! client->nreads == 0) {
392 if (client->tcpmsg_valid) {
393 dns_tcpmsg_invalidate(&client->tcpmsg);
394 client->tcpmsg_valid = ISC_FALSE;
396 if (client->tcpsocket != NULL) {
398 isc_socket_detach(&client->tcpsocket);
401 if (client->tcpquota != NULL)
402 isc_quota_detach(&client->tcpquota);
404 if (client->timerset) {
405 (void)isc_timer_reset(client->timer,
408 client->timerset = ISC_FALSE;
411 client->peeraddr_valid = ISC_FALSE;
413 client->state = NS_CLIENTSTATE_READY;
414 INSIST(client->recursionquota == NULL);
417 * Now the client is ready to accept a new TCP connection
419 * that already. Check whether this client needs to remain
423 * may remain active if we have fewer active TCP client
426 if (client->mortal && TCP_CLIENT(client) && !ns_g_clienttest) {
427 LOCK(&client->interface->lock);
428 if (client->interface->ntcpcurrent <
429 client->interface->ntcptarget)
430 client->mortal = ISC_FALSE;
431 UNLOCK(&client->interface->lock);
435 * We don't need the client; send it to the inactive
438 if (client->mortal) {
439 if (client->newstate > NS_CLIENTSTATE_INACTIVE)
440 client->newstate = NS_CLIENTSTATE_INACTIVE;
443 if (NS_CLIENTSTATE_READY == client->newstate) {
444 if (TCP_CLIENT(client)) {
445 client_accept(client);
447 client_udprecv(client);
448 client->newstate = NS_CLIENTSTATE_MAX;
453 if (client->state == NS_CLIENTSTATE_READY) {
454 INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE);
459 if (client->naccepts > 0)
460 isc_socket_cancel(client->tcplistener, client->task,
464 if (! (client->naccepts == 0))
468 if (client->nrecvs > 0)
469 isc_socket_cancel(client->udpsocket, client->task,
473 if (! (client->nrecvs == 0))
477 if (client->nctls > 0)
480 /* Deactivate the client. */
481 if (client->interface)
482 ns_interface_detach(&client->interface);
484 INSIST(client->naccepts == 0);
485 INSIST(client->recursionquota == NULL);
486 if (client->tcplistener != NULL)
487 isc_socket_detach(&client->tcplistener);
489 if (client->udpsocket != NULL)
490 isc_socket_detach(&client->udpsocket);
492 if (client->dispatch != NULL)
493 dns_dispatch_detach(&client->dispatch);
495 client->attributes = 0;
496 client->mortal = ISC_FALSE;
499 * Put the client on the inactive list. If we are aiming for
503 * the dying client inbetween.
505 client->state = NS_CLIENTSTATE_INACTIVE;
506 INSIST(client->recursionquota == NULL);
508 if (client->state == client->newstate) {
509 client->newstate = NS_CLIENTSTATE_MAX;
512 ISC_QUEUE_PUSH(manager->inactive, client,
514 if (client->needshutdown)
515 isc_task_shutdown(client->task);
520 if (client->state == NS_CLIENTSTATE_INACTIVE) {
521 INSIST(client->newstate == NS_CLIENTSTATE_FREED);
523 * We are trying to free the client.
530 REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE);
532 INSIST(client->recursionquota == NULL);
533 INSIST(!ISC_QLINK_LINKED(client, ilink));
535 ns_query_free(client);
536 isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE);
537 isc_event_free((isc_event_t **)&client->sendevent);
538 isc_event_free((isc_event_t **)&client->recvevent);
539 isc_timer_detach(&client->timer);
541 if (client->tcpbuf != NULL)
542 isc_mem_put(client->mctx, client->tcpbuf,
544 if (client->opt != NULL) {
545 INSIST(dns_rdataset_isassociated(client->opt));
546 dns_rdataset_disassociate(client->opt);
547 dns_message_puttemprdataset(client->message,
548 &client->opt);
551 dns_message_destroy(&client->message);
554 ISC_LIST_UNLINK(manager->clients, client, link);
566 * client->task.
568 if (client->task != NULL)
569 isc_task_detach(&client->task);
572 client->magic = 0;
578 if (ns_g_clienttest && isc_mem_references(client->mctx) != 1) {
579 isc_mem_stats(client->mctx, stderr);
582 isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
592 * The client's task has received the client's control event
597 ns_client_t *client = (ns_client_t *) event->ev_arg;
599 INSIST(task == client->task);
603 INSIST(client->nctls == 1);
604 client->nctls--;
606 if (exit_check(client))
609 if (TCP_CLIENT(client)) {
610 client_accept(client);
612 client_udprecv(client);
618 * The client's task has received a shutdown event.
622 ns_client_t *client;
626 client = event->ev_arg;
627 REQUIRE(NS_CLIENT_VALID(client));
628 REQUIRE(task == client->task);
636 if (client->shutdown != NULL) {
637 (client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN);
638 client->shutdown = NULL;
639 client->shutdown_arg = NULL;
642 if (ISC_QLINK_LINKED(client, ilink))
643 ISC_QUEUE_UNLINK(client->manager->inactive, client, ilink);
645 client->newstate = NS_CLIENTSTATE_FREED;
646 client->needshutdown = ISC_FALSE;
647 (void)exit_check(client);
651 ns_client_endrequest(ns_client_t *client) {
652 INSIST(client->naccepts == 0);
653 INSIST(client->nreads == 0);
654 INSIST(client->nsends == 0);
655 INSIST(client->nrecvs == 0);
656 INSIST(client->nupdates == 0);
657 INSIST(client->state == NS_CLIENTSTATE_WORKING ||
658 client->state == NS_CLIENTSTATE_RECURSING);
662 if (client->next != NULL) {
663 (client->next)(client);
664 client->next = NULL;
667 if (client->view != NULL)
668 dns_view_detach(&client->view);
669 if (client->opt != NULL) {
670 INSIST(dns_rdataset_isassociated(client->opt));
671 dns_rdataset_disassociate(client->opt);
672 dns_message_puttemprdataset(client->message, &client->opt);
675 client->signer = NULL;
676 client->udpsize = 512;
677 client->extflags = 0;
678 client->ednsversion = -1;
679 dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
681 if (client->recursionquota != NULL)
682 isc_quota_detach(&client->recursionquota);
685 * Clear all client attributes that are specific to
688 client->attributes &= NS_CLIENTATTR_TCP;
692 ns_client_next(ns_client_t *client, isc_result_t result) {
695 REQUIRE(NS_CLIENT_VALID(client));
696 REQUIRE(client->state == NS_CLIENTSTATE_WORKING ||
697 client->state == NS_CLIENTSTATE_RECURSING ||
698 client->state == NS_CLIENTSTATE_READING);
703 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
712 if (result == ISC_R_SUCCESS && TCP_CLIENT(client))
717 if (client->newstate > newstate)
718 client->newstate = newstate;
719 (void)exit_check(client);
725 ns_client_t *client;
730 client = sevent->ev_arg;
731 REQUIRE(NS_CLIENT_VALID(client));
732 REQUIRE(task == client->task);
733 REQUIRE(sevent == client->sendevent);
740 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
745 INSIST(client->nsends > 0);
746 client->nsends--;
748 if (client->tcpbuf != NULL) {
749 INSIST(TCP_CLIENT(client));
750 isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
751 client->tcpbuf = NULL;
754 ns_client_next(client, ISC_R_SUCCESS);
766 client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,
778 if (TCP_CLIENT(client)) {
779 INSIST(client->tcpbuf == NULL);
784 client->tcpbuf = isc_mem_get(client->mctx, TCP_BUFFER_SIZE);
785 if (client->tcpbuf == NULL) {
789 data = client->tcpbuf;
800 if (client->udpsize < SEND_BUFFER_SIZE)
801 bufsize = client->udpsize;
818 client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
828 if (TCP_CLIENT(client)) {
829 socket = client->tcpsocket;
832 socket = client->udpsocket;
833 address = &client->peeraddr;
835 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
846 if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0 &&
847 (client->attributes & NS_CLIENTATTR_MULTICAST) == 0)
848 pktinfo = &client->pktinfo;
856 result = isc_socket_sendto2(socket, &r, client->task,
858 client->sendevent, sockflags);
860 client->nsends++;
862 client_senddone(client->task,
863 (isc_event_t *)client->sendevent);
870 ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
878 REQUIRE(NS_CLIENT_VALID(client));
888 result = client_allocsendbuf(client, &buffer, NULL, mr->length,
900 r.base[0] = (client->message->id >> 8) & 0xff;
901 r.base[1] = client->message->id & 0xff;
903 result = client_sendpkg(client, &buffer);
908 if (client->tcpbuf != NULL) {
909 isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
910 client->tcpbuf = NULL;
912 ns_client_next(client, result);
916 ns_client_send(ns_client_t *client) {
929 REQUIRE(NS_CLIENT_VALID(client));
933 if ((client->attributes & NS_CLIENTATTR_RA) != 0)
934 client->message->flags |= DNS_MESSAGEFLAG_RA;
936 if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0)
942 if (client->view != NULL) {
943 if (client->view->preferred_glue == dns_rdatatype_a)
945 else if (client->view->preferred_glue == dns_rdatatype_aaaa)
955 * and that we either have no signatures that the client wants
960 if ((client->attributes & NS_CLIENTATTR_FILTER_AAAA) != 0) {
970 result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0,
975 result = dns_compress_init(&cctx, -1, client->mctx);
980 result = dns_message_renderbegin(client->message, &cctx, &buffer);
984 if (client->opt != NULL) {
985 result = dns_message_setopt(client->message, client->opt);
987 client->opt = NULL;
991 result = dns_message_rendersection(client->message,
994 client->message->flags |= DNS_MESSAGEFLAG_TC;
999 result = dns_message_rendersection(client->message,
1004 client->message->flags |= DNS_MESSAGEFLAG_TC;
1009 result = dns_message_rendersection(client->message,
1014 client->message->flags |= DNS_MESSAGEFLAG_TC;
1019 result = dns_message_rendersection(client->message,
1025 result = dns_message_renderend(client->message);
1035 if (TCP_CLIENT(client)) {
1039 result = client_sendpkg(client, &tcpbuffer);
1041 result = client_sendpkg(client, &buffer);
1049 if (client->message->tsigkey != NULL) {
1053 if (client->message->sig0key != NULL) {
1057 if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0)
1065 if (client->tcpbuf != NULL) {
1066 isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
1067 client->tcpbuf = NULL;
1073 ns_client_next(client, result);
1105 ns_client_error(ns_client_t *client, isc_result_t result) {
1109 REQUIRE(NS_CLIENT_VALID(client));
1113 message = client->message;
1121 ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) !=
1129 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1133 ns_client_next(client, ISC_R_SUCCESS);
1157 ns_client_next(client, result);
1165 * with the same ID to the same client less than two
1173 if (isc_sockaddr_equal(&client->peeraddr,
1174 &client->formerrcache.addr) &&
1175 message->id == client->formerrcache.id &&
1176 client->requesttime - client->formerrcache.time < 2) {
1178 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1182 ns_client_next(client, result);
1185 client->formerrcache.addr = client->peeraddr;
1186 client->formerrcache.time = client->requesttime;
1187 client->formerrcache.id = message->id;
1189 ns_client_send(client);
1193 client_addopt(ns_client_t *client) {
1202 REQUIRE(client->opt == NULL); /* XXXRTH free old. */
1205 result = dns_message_gettemprdatalist(client->message, &rdatalist);
1209 result = dns_message_gettemprdata(client->message, &rdata);
1213 result = dns_message_gettemprdataset(client->message, &rdataset);
1224 view = client->view;
1235 rdatalist->ttl = (client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE);
1238 if (client->attributes & NS_CLIENTATTR_WANTNSID &&
1261 result = isc_buffer_allocate(client->mctx, &buffer,
1270 dns_message_takebuffer(client->message, &buffer);
1286 client->opt = rdataset;
1375 ns_client_t *client;
1394 client = event->ev_arg;
1395 REQUIRE(NS_CLIENT_VALID(client));
1396 REQUIRE(task == client->task);
1398 INSIST(client->recursionquota == NULL);
1400 INSIST(client->state == TCP_CLIENT(client) ?
1407 INSIST(!TCP_CLIENT(client));
1409 REQUIRE(sevent == client->recvevent);
1415 client->peeraddr = sevent->address;
1416 client->peeraddr_valid = ISC_TRUE;
1419 client->attributes |= NS_CLIENTATTR_PKTINFO;
1420 client->pktinfo = sevent->pktinfo;
1423 client->attributes |= NS_CLIENTATTR_MULTICAST;
1424 client->nrecvs--;
1426 INSIST(TCP_CLIENT(client));
1428 REQUIRE(event->ev_sender == &client->tcpmsg);
1429 buffer = &client->tcpmsg.buffer;
1430 result = client->tcpmsg.result;
1431 INSIST(client->nreads == 1);
1433 * client->peeraddr was set when the connection was accepted.
1435 client->nreads--;
1438 if (exit_check(client))
1440 client->state = client->newstate = NS_CLIENTSTATE_WORKING;
1442 isc_task_getcurrenttime(task, &client->requesttime);
1443 client->now = client->requesttime;
1446 if (TCP_CLIENT(client)) {
1447 ns_client_next(client, result);
1453 "UDP client handler shutting "
1457 isc_task_shutdown(client->task);
1462 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
1465 if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) ==
1467 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1470 ns_client_next(client, ISC_R_SUCCESS);
1475 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1478 TCP_CLIENT(client) ? "TCP" : "UDP");
1484 if (!TCP_CLIENT(client)) {
1492 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1495 ns_client_next(client, ISC_R_SUCCESS);
1504 if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) {
1505 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1508 ns_client_next(client, DNS_R_REFUSED);
1518 ns_client_next(client, result);
1523 * The client object handles requests, not responses.
1528 if (TCP_CLIENT(client)) {
1530 ns_client_next(client, DNS_R_FORMERR);
1533 dns_dispatch_importrecv(client->dispatch, event);
1534 ns_client_next(client, ISC_R_SUCCESS);
1542 if (isc_sockaddr_pf(&client->peeraddr) == PF_INET) {
1549 if (TCP_CLIENT(client))
1556 result = dns_message_parse(client->message, buffer, 0);
1562 ns_client_error(client, result);
1567 client->message->opcode);
1568 switch (client->message->opcode) {
1580 client->message->rcode = dns_rcode_noerror;
1583 if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0)
1584 client->message->flags &= ~DNS_MESSAGEFLAG_RD;
1589 opt = dns_message_getopt(client->message);
1592 * Set the client's UDP buffer size.
1594 client->udpsize = opt->rdclass;
1600 if (client->udpsize < 512)
1601 client->udpsize = 512;
1606 client->extflags = (isc_uint16_t)(opt->ttl & 0xFFFF);
1613 client->ednsversion = (opt->ttl & 0x00FF0000) >> 16;
1614 if (client->ednsversion > 0) {
1617 result = client_addopt(client);
1620 ns_client_error(client, result);
1636 client->attributes |=
1647 result = client_addopt(client);
1649 ns_client_error(client, result);
1654 if (client->message->rdclass == 0) {
1655 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1658 ns_client_dumpmessage(client,
1660 ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR);
1675 if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0)
1676 isc_netaddr_fromsockaddr(&client->destaddr,
1677 &client->interface->addr);
1682 if (TCP_CLIENT(client))
1683 result = isc_socket_getsockname(client->tcpsocket,
1686 isc_netaddr_fromsockaddr(&client->destaddr, &sockaddr);
1688 client->interface->addr.type.sa.sa_family == AF_INET6 &&
1689 (client->attributes & NS_CLIENTATTR_PKTINFO) != 0) {
1698 isc_netaddr_fromin6(&client->destaddr,
1699 &client->pktinfo.ipi6_addr);
1700 if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr))
1701 isc_netaddr_setzone(&client->destaddr,
1702 client->pktinfo.ipi6_ifindex);
1710 ns_client_next(client, ISC_R_SUCCESS);
1716 * Find a view that matches the client's source address.
1721 if (client->message->rdclass == view->rdclass ||
1722 client->message->rdclass == dns_rdataclass_any)
1726 sigresult = dns_message_rechecksig(client->message,
1729 tsig = dns_tsigkey_identity(client->message->tsigkey);
1732 allowed(&client->destaddr, tsig,
1734 !((client->message->flags & DNS_MESSAGEFLAG_RD)
1737 dns_view_attach(view, &client->view);
1754 dns_message_resetsig(client->message);
1756 r = dns_message_getrawmessage(client->message);
1759 (void)dns_tsig_verify(&b, client->message, NULL, NULL);
1761 dns_rdataclass_format(client->message->rdclass, classname,
1763 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1766 ns_client_dumpmessage(client, "no matching view in class");
1767 ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED);
1771 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1781 client->signer = NULL;
1782 dns_name_init(&client->signername, NULL);
1783 result = dns_message_signer(client->message, &client->signername);
1786 if (dns_message_gettsig(client->message, &signame) != NULL) {
1797 dns_name_format(&client->signername, namebuf, sizeof(namebuf));
1798 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1801 client->signer = &client->signername;
1803 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1807 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1820 if (dns_message_gettsig(client->message, &signame) != NULL) {
1824 status = client->message->tsigstatus;
1829 if (client->message->tsigkey->generated) {
1830 dns_name_format(client->message->tsigkey->creator,
1832 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1841 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1850 status = client->message->sig0status;
1855 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1865 if (!(client->message->tsigstatus == dns_tsigerror_badkey &&
1866 client->message->opcode == dns_opcode_update)) {
1867 ns_client_error(client, sigresult);
1873 * Decide whether recursive service is available to this client.
1880 if (client->view->resolver != NULL &&
1881 client->view->recursion == ISC_TRUE &&
1882 ns_client_checkaclsilent(client, NULL,
1883 client->view->recursionacl,
1885 ns_client_checkaclsilent(client, NULL,
1886 client->view->cacheacl,
1888 ns_client_checkaclsilent(client, &client->destaddr,
1889 client->view->recursiononacl,
1891 ns_client_checkaclsilent(client, &client->destaddr,
1892 client->view->cacheonacl,
1897 client->attributes |= NS_CLIENTATTR_RA;
1899 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT,
1904 * Adjust maximum UDP response size for this client.
1906 if (client->udpsize > 512) {
1912 if (client->udpsize > udpsize)
1913 client->udpsize = udpsize;
1919 switch (client->message->opcode) {
1922 ns_query_start(client);
1926 ns_client_settimeout(client, 60);
1927 ns_update_start(client, sigresult);
1931 ns_client_settimeout(client, 60);
1932 ns_notify_start(client);
1936 ns_client_error(client, DNS_R_NOTIMP);
1940 ns_client_error(client, DNS_R_NOTIMP);
1949 ns_client_t *client;
1954 client = event->ev_arg;
1955 REQUIRE(NS_CLIENT_VALID(client));
1956 REQUIRE(task == client->task);
1957 REQUIRE(client->timer != NULL);
1965 if (client->shutdown != NULL) {
1966 (client->shutdown)(client->shutdown_arg, ISC_R_TIMEDOUT);
1967 client->shutdown = NULL;
1968 client->shutdown_arg = NULL;
1971 if (client->newstate > NS_CLIENTSTATE_READY)
1972 client->newstate = NS_CLIENTSTATE_READY;
1973 (void)exit_check(client);
1992 isc_mem_setname(*mctxp, "client", NULL);
2007 isc_mem_setname(clientmctx, "client", NULL);
2022 ns_client_t *client;
2029 * Note: creating a client does not add the client to the
2030 * manager's client list or set the client's manager pointer.
2040 client = isc_mem_get(mctx, sizeof(*client));
2041 if (client == NULL) {
2045 client->mctx = mctx;
2047 client->task = NULL;
2048 result = isc_task_create(manager->taskmgr, 0, &client->task);
2051 isc_task_setname(client->task, "client", client);
2053 client->timer = NULL;
2055 NULL, NULL, client->task, client_timeout,
2056 client, &client->timer);
2059 client->timerset = ISC_FALSE;
2061 client->message = NULL;
2062 result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE,
2063 &client->message);
2069 client->sendevent = (isc_socketevent_t *)
2070 isc_event_allocate(client->mctx, client,
2072 client_senddone, client,
2074 if (client->sendevent == NULL) {
2079 client->recvbuf = isc_mem_get(client->mctx, RECV_BUFFER_SIZE);
2080 if (client->recvbuf == NULL) {
2085 client->recvevent = (isc_socketevent_t *)
2086 isc_event_allocate(client->mctx, client,
2088 client_request, client,
2090 if (client->recvevent == NULL) {
2095 client->magic = NS_CLIENT_MAGIC;
2096 client->manager = NULL;
2097 client->state = NS_CLIENTSTATE_INACTIVE;
2098 client->newstate = NS_CLIENTSTATE_MAX;
2099 client->naccepts = 0;
2100 client->nreads = 0;
2101 client->nsends = 0;
2102 client->nrecvs = 0;
2103 client->nupdates = 0;
2104 client->nctls = 0;
2105 client->references = 0;
2106 client->attributes = 0;
2107 client->view = NULL;
2108 client->dispatch = NULL;
2109 client->udpsocket = NULL;
2110 client->tcplistener = NULL;
2111 client->tcpsocket = NULL;
2112 client->tcpmsg_valid = ISC_FALSE;
2113 client->tcpbuf = NULL;
2114 client->opt = NULL;
2115 client->udpsize = 512;
2116 client->extflags = 0;
2117 client->ednsversion = -1;
2118 client->next = NULL;
2119 client->shutdown = NULL;
2120 client->shutdown_arg = NULL;
2121 client->signer = NULL;
2122 dns_name_init(&client->signername, NULL);
2123 client->mortal = ISC_FALSE;
2124 client->tcpquota = NULL;
2125 client->recursionquota = NULL;
2126 client->interface = NULL;
2127 client->peeraddr_valid = ISC_FALSE;
2129 client->filter_aaaa = dns_v4_aaaa_ok;
2131 client->needshutdown = ns_g_clienttest;
2133 ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL,
2134 NS_EVENT_CLIENTCONTROL, client_start, client, client,
2140 isc_sockaddr_any(&client->formerrcache.addr);
2141 client->formerrcache.time = 0;
2142 client->formerrcache.id = 0;
2143 ISC_LINK_INIT(client, link);
2144 ISC_LINK_INIT(client, rlink);
2145 ISC_QLINK_INIT(client, ilink);
2148 * We call the init routines for the various kinds of client here,
2149 * after we have created an otherwise valid client, because some
2150 * of them call routines that REQUIRE(NS_CLIENT_VALID(client)).
2152 result = ns_query_init(client);
2156 result = isc_task_onshutdown(client->task, client_shutdown, client);
2162 *clientp = client;
2167 ns_query_free(client);
2170 isc_event_free((isc_event_t **)&client->recvevent);
2173 isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE);
2176 isc_event_free((isc_event_t **)&client->sendevent);
2178 client->magic = 0;
2181 dns_message_destroy(&client->message);
2184 isc_timer_detach(&client->timer);
2187 isc_task_detach(&client->task);
2190 isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
2196 client_read(ns_client_t *client) {
2201 result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task,
2202 client_request, client);
2210 ns_client_settimeout(client, 30);
2212 client->state = client->newstate = NS_CLIENTSTATE_READING;
2213 INSIST(client->nreads == 0);
2214 INSIST(client->recursionquota == NULL);
2215 client->nreads++;
2219 ns_client_next(client, result);
2224 ns_client_t *client = event->ev_arg;
2229 REQUIRE(NS_CLIENT_VALID(client));
2230 REQUIRE(client->task == task);
2234 INSIST(client->state == NS_CLIENTSTATE_READY);
2236 INSIST(client->naccepts == 1);
2237 client->naccepts--;
2239 LOCK(&client->interface->lock);
2240 INSIST(client->interface->ntcpcurrent > 0);
2241 client->interface->ntcpcurrent--;
2242 UNLOCK(&client->interface->lock);
2249 client->tcpsocket = nevent->newsocket;
2250 isc_socket_setname(client->tcpsocket, "client-tcp", NULL);
2251 client->state = NS_CLIENTSTATE_READING;
2252 INSIST(client->recursionquota == NULL);
2254 (void)isc_socket_getpeername(client->tcpsocket,
2255 &client->peeraddr);
2256 client->peeraddr_valid = ISC_TRUE;
2257 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
2271 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
2277 if (exit_check(client))
2284 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
2293 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2296 client->newstate = NS_CLIENTSTATE_READY;
2297 (void)exit_check(client);
2301 INSIST(client->tcpmsg_valid == ISC_FALSE);
2302 dns_tcpmsg_init(client->mctx, client->tcpsocket,
2303 &client->tcpmsg);
2304 client->tcpmsg_valid = ISC_TRUE;
2307 * Let a new client take our place immediately, before
2313 &client->tcpquota);
2315 result = ns_client_replace(client);
2317 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
2323 client_read(client);
2331 client_accept(ns_client_t *client) {
2336 result = isc_socket_accept(client->tcplistener, client->task,
2337 client_newconn, client);
2351 INSIST(client->naccepts == 0);
2352 client->naccepts++;
2353 LOCK(&client->interface->lock);
2354 client->interface->ntcpcurrent++;
2355 UNLOCK(&client->interface->lock);
2359 client_udprecv(ns_client_t *client) {
2365 r.base = client->recvbuf;
2367 result = isc_socket_recv2(client->udpsocket, &r, 1,
2368 client->task, client->recvevent, 0);
2381 INSIST(client->nrecvs == 0);
2382 client->nrecvs++;
2399 ns_client_t *client = *clientp;
2401 client->references--;
2402 INSIST(client->references >= 0);
2404 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
2406 "ns_client_detach: ref = %d", client->references);
2407 (void)exit_check(client);
2411 ns_client_shuttingdown(ns_client_t *client) {
2412 return (ISC_TF(client->newstate == NS_CLIENTSTATE_FREED));
2416 ns_client_replace(ns_client_t *client) {
2421 result = get_client(client->manager, client->interface,
2422 client->dispatch, TCP_CLIENT(client));
2428 * transferred to the new client. Therefore, the old client
2431 client->mortal = ISC_TRUE;
2527 ns_client_t *client;
2547 for (client = ISC_LIST_HEAD(manager->clients);
2548 client != NULL;
2549 client = ISC_LIST_NEXT(client, link))
2550 isc_task_shutdown(client->task);
2570 ns_client_t *client;
2571 MTRACE("get client");
2577 * Allocate a client. First try to get a recycled one;
2580 client = NULL;
2582 ISC_QUEUE_POP(manager->inactive, ilink, client);
2584 if (client != NULL)
2590 result = client_create(manager, &client);
2596 ISC_LIST_APPEND(manager->clients, client, link);
2600 client->manager = manager;
2601 ns_interface_attach(ifp, &client->interface);
2602 client->state = NS_CLIENTSTATE_READY;
2603 INSIST(client->recursionquota == NULL);
2606 client->attributes |= NS_CLIENTATTR_TCP;
2608 &client->tcplistener);
2612 dns_dispatch_attach(disp, &client->dispatch);
2613 sock = dns_dispatch_getsocket(client->dispatch);
2614 isc_socket_attach(sock, &client->udpsocket);
2617 INSIST(client->nctls == 0);
2618 client->nctls++;
2619 ev = &client->ctlevent;
2620 isc_task_send(client->task, &ev);
2647 ns_client_getsockaddr(ns_client_t *client) {
2648 return (&client->peeraddr);
2652 ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
2667 isc_netaddr_fromsockaddr(&tmpnetaddr, &client->peeraddr);
2671 result = dns_acl_match(netaddr, client->signer, acl,
2688 ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr,
2698 result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL,
2702 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2706 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2713 ns_client_name(ns_client_t *client, char *peerbuf, size_t len) {
2714 if (client->peeraddr_valid)
2715 isc_sockaddr_format(&client->peeraddr, peerbuf, len);
2717 snprintf(peerbuf, len, "@%p", client);
2721 ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
2734 ns_client_name(client, peerbuf, sizeof(peerbuf));
2736 if (client->signer != NULL) {
2737 dns_name_format(client->signer, signerbuf, sizeof(signerbuf));
2742 q = client->query.origqname != NULL
2743 ? client->query.origqname : client->query.qname;
2751 if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 &&
2752 strcmp(client->view->name, "_default") != 0) {
2754 viewname = client->view->name;
2758 "client %s%s%s%s%s%s%s%s: %s",
2764 ns_client_log(ns_client_t *client, isc_logcategory_t *category,
2773 ns_client_logv(client, category, module, level, fmt, ap);
2793 ns_client_dumpmessage(ns_client_t *client, const char *reason) {
2805 buf = isc_mem_get(client->mctx, len);
2809 result = dns_message_totext(client->message,
2813 isc_mem_put(client->mctx, buf, len);
2816 ns_client_log(client, NS_LOGCATEGORY_UNMATCHED,
2824 isc_mem_put(client->mctx, buf, len);
2829 ns_client_t *client;
2843 client = ISC_LIST_HEAD(manager->recursing);
2844 while (client != NULL) {
2845 INSIST(client->state == NS_CLIENTSTATE_RECURSING);
2847 ns_client_name(client, peerbuf, sizeof(peerbuf));
2848 if (client->view != NULL &&
2849 strcmp(client->view->name, "_bind") != 0 &&
2850 strcmp(client->view->name, "_default") != 0) {
2851 name = client->view->name;
2858 LOCK(&client->query.fetchlock);
2859 INSIST(client->query.qname != NULL);
2860 dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
2861 if (client->query.qname != client->query.origqname &&
2862 client->query.origqname != NULL) {
2864 dns_name_format(client->query.origqname, original,
2870 rdataset = ISC_LIST_HEAD(client->query.qname->list);
2871 if (rdataset == NULL && client->query.origqname != NULL)
2872 rdataset = ISC_LIST_HEAD(client->query.origqname->list);
2882 UNLOCK(&client->query.fetchlock);
2883 fprintf(f, "; client %s%s%s: id %u '%s/%s/%s'%s%s "
2885 client->message->id, namebuf, typebuf, classbuf,
2886 origfor, original, client->requesttime);
2887 client = ISC_LIST_NEXT(client, rlink);
2893 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) {
2894 LOCK(&client->query.fetchlock);
2895 if (client->query.restarts > 0) {
2897 * client->query.qname was dynamically allocated.
2899 dns_message_puttempname(client->message,
2900 &client->query.qname);
2902 client->query.qname = name;
2903 UNLOCK(&client->query.fetchlock);
2908 ns_client_t *client = (ns_client_t *) ci->data;
2910 REQUIRE(NS_CLIENT_VALID(client));
2913 *addrp = &client->peeraddr;