Home | History | Annotate | Download | only in ns

Lines Matching refs:client

1 /*	$NetBSD: client.c,v 1.29 2026/05/20 16:53:47 christos Exp $	*/
62 #include <ns/client.h>
73 *** Client
77 * Client Routines
81 * All client state changes, other than that from idle to listening, occur
85 * If a routine is ever created that allows someone other than the client's
86 * loop to change the client, then the client will have to be locked.
91 ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, \
147 ns_client_dumpmessage(ns_client_t *client, const char *reason);
151 compute_cookie(ns_client_t *client, uint32_t when, const unsigned char *secret,
156 ns_client_transport_type(const ns_client_t *client) {
162 if (!TCP_CLIENT(client)) {
166 INSIST(client->handle != NULL);
168 switch (isc_nm_socket_type(client->handle)) {
185 if (isc_nm_has_encryption(client->handle)) {
202 ns_client_recursing(ns_client_t *client) {
203 REQUIRE(NS_CLIENT_VALID(client));
204 REQUIRE(client->state == NS_CLIENTSTATE_WORKING);
206 LOCK(&client->manager->reclock);
207 client->state = NS_CLIENTSTATE_RECURSING;
208 ISC_LIST_APPEND(client->manager->recursing, client, rlink);
209 UNLOCK(&client->manager->reclock);
213 ns_client_killoldestquery(ns_client_t *client) {
215 REQUIRE(NS_CLIENT_VALID(client));
217 LOCK(&client->manager->reclock);
218 oldest = ISC_LIST_HEAD(client->manager->recursing);
220 ISC_LIST_UNLINK(client->manager->recursing, oldest, rlink);
222 ns_stats_increment(client->manager->sctx->nsstats,
225 UNLOCK(&client->manager->reclock);
229 ns_client_settimeout(ns_client_t *client, unsigned int seconds) {
230 UNUSED(client);
236 ns_client_endrequest(ns_client_t *client) {
237 INSIST(client->state == NS_CLIENTSTATE_WORKING ||
238 client->state == NS_CLIENTSTATE_RECURSING);
242 if (client->state == NS_CLIENTSTATE_RECURSING) {
243 LOCK(&client->manager->reclock);
244 if (ISC_LINK_LINKED(client, rlink)) {
245 ISC_LIST_UNLINK(client->manager->recursing, client,
248 UNLOCK(&client->manager->reclock);
251 if (client->cleanup != NULL) {
252 (client->cleanup)(client);
253 client->cleanup = NULL;
256 if (client->view != NULL) {
258 if (client->manager->sctx->fuzztype == isc_fuzz_resolver) {
260 dns_view_getadb(client->view, &adb);
267 dns_view_detach(&client->view);
269 if (client->opt != NULL) {
270 INSIST(dns_rdataset_isassociated(client->opt));
271 dns_rdataset_disassociate(client->opt);
272 dns_message_puttemprdataset(client->message, &client->opt);
275 client->signer = NULL;
276 client->udpsize = 512;
277 client->extflags = 0;
278 client->ednsversion = -1;
279 client->additionaldepth = 0;
280 dns_ecs_init(&client->ecs);
281 dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
284 * Clear all client attributes that are specific to the request
286 client->attributes = 0;
288 if (client->manager->sctx->fuzznotify != NULL &&
289 (client->manager->sctx->fuzztype == isc_fuzz_client ||
290 client->manager->sctx->fuzztype == isc_fuzz_tcpclient ||
291 client->manager->sctx->fuzztype == isc_fuzz_resolver))
293 client->manager->sctx->fuzznotify();
299 ns_client_drop(ns_client_t *client, isc_result_t result) {
300 REQUIRE(NS_CLIENT_VALID(client));
301 REQUIRE(client->state == NS_CLIENTSTATE_WORKING ||
302 client->state == NS_CLIENTSTATE_RECURSING);
306 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
314 ns_client_t *client = cbarg;
316 REQUIRE(client->sendhandle == handle);
327 client->sendhandle = NULL;
330 if (!TCP_CLIENT(client) && result == ISC_R_MAXSIZE) {
331 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
334 client->query.attributes &= ~NS_QUERYATTR_ANSWERED;
335 client->rcode_override = dns_rcode_noerror;
336 ns_client_error(client, ISC_R_MAXSIZE);
338 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
350 client_setup_tcp_buffer(ns_client_t *client) {
351 REQUIRE(client->tcpbuf == NULL);
353 client->tcpbuf = client->manager->tcp_buffer;
354 client->tcpbuf_size = NS_CLIENT_TCP_BUFFER_SIZE;
358 client_put_tcp_buffer(ns_client_t *client) {
359 if (client->tcpbuf == NULL) {
363 if (client->tcpbuf != client->manager->tcp_buffer) {
364 isc_mem_put(client->manager->mctx, client->tcpbuf,
365 client->tcpbuf_size);
368 client->tcpbuf = NULL;
369 client->tcpbuf_size = 0;
373 client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,
380 if (TCP_CLIENT(client)) {
381 client_setup_tcp_buffer(client);
382 data = client->tcpbuf;
383 isc_buffer_init(buffer, data, client->tcpbuf_size);
385 data = client->sendbuf;
386 if ((client->attributes & NS_CLIENTATTR_HAVECOOKIE) == 0) {
387 if (client->view != NULL) {
388 bufsize = client->view->nocookieudp;
393 bufsize = client->udpsize;
395 if (bufsize > client->udpsize) {
396 bufsize = client->udpsize;
407 client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
412 REQUIRE(client->sendhandle == NULL);
414 if (isc_buffer_base(buffer) == client->tcpbuf) {
416 INSIST(client->tcpbuf_size == NS_CLIENT_TCP_BUFFER_SIZE);
429 isc_mem_get(client->manager->mctx, used);
436 client_put_tcp_buffer(client);
441 client->tcpbuf = new_tcpbuf;
442 client->tcpbuf_size = used;
450 memmove(client->sendbuf, buffer->base, used);
455 client_put_tcp_buffer(client);
457 r.base = client->sendbuf;
463 isc_nmhandle_attach(client->handle, &client->sendhandle);
465 if (isc_nm_is_http_handle(client->handle)) {
466 result = dns_message_response_minttl(client->message, &min_ttl);
468 isc_nm_set_maxage(client->handle, min_ttl);
471 isc_nm_send(client->handle, &r, client_senddone, client);
475 ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
486 REQUIRE(NS_CLIENT_VALID(client));
496 client_allocsendbuf(client, &buffer, &data);
511 r.base[0] = (client->message->id >> 8) & 0xff;
512 r.base[1] = client->message->id & 0xff;
515 if (client->view != NULL) {
516 transport_type = ns_client_transport_type(client);
518 if (client->message->opcode == dns_opcode_update) {
520 } else if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) {
525 dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
526 &client->destsockaddr, transport_type, NULL,
527 &client->requesttime, NULL, &buffer);
531 client_sendpkg(client, &buffer);
535 if (client->tcpbuf != NULL) {
536 client_put_tcp_buffer(client);
539 ns_client_drop(client, result);
543 ns_client_send(ns_client_t *client) {
563 REQUIRE(NS_CLIENT_VALID(client));
565 if ((client->query.attributes & NS_QUERYATTR_ANSWERED) != 0) {
574 env = client->manager->aclenv;
578 if (client->message->opcode == dns_opcode_query &&
579 (client->attributes & NS_CLIENTATTR_RA) != 0)
581 client->message->flags |= DNS_MESSAGEFLAG_RA;
584 if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0) {
591 if (client->view != NULL) {
592 if (client->view->preferred_glue == dns_rdatatype_a) {
594 } else if (client->view->preferred_glue == dns_rdatatype_aaaa) {
599 if (isc_sockaddr_pf(&client->peeraddr) == AF_INET) {
609 if ((client->attributes & NS_CLIENTATTR_WANTOPT) != 0) {
610 result = ns_client_addopt(client, client->message,
611 &client->opt);
617 client_allocsendbuf(client, &buffer, &data);
619 if (client->peeraddr_valid && client->view != NULL) {
623 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
624 if (client->message->tsigkey != NULL) {
625 name = client->message->tsigkey->name;
628 if (client->view->nocasecompress == NULL ||
630 client->view->nocasecompress, env))
635 if (!client->view->msgcompression) {
639 dns_compress_init(&cctx, client->manager->mctx, compflags);
642 client->message, &cctx, &buffer);
647 if (client->opt != NULL) {
648 result = dns_message_setopt(client->message, client->opt);
650 client->opt = NULL;
655 result = dns_message_rendersection(client->message,
658 client->message->flags |= DNS_MESSAGEFLAG_TC;
667 if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0) {
670 result = dns_message_rendersection(client->message, DNS_SECTION_ANSWER,
674 client->message->flags |= DNS_MESSAGEFLAG_TC;
681 client->message, DNS_SECTION_AUTHORITY,
684 client->message->flags |= DNS_MESSAGEFLAG_TC;
690 result = dns_message_rendersection(client->message,
697 result = dns_message_renderend(client->message);
704 if (((client->message->flags & DNS_MESSAGEFLAG_AA) != 0) &&
705 (client->query.authzone != NULL))
709 dns_name_t *zo = dns_zone_getorigin(client->query.authzone);
719 if (client->message->opcode == dns_opcode_update) {
721 } else if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) {
727 transport_type = ns_client_transport_type(client);
734 if (client->sendcb != NULL) {
735 client->sendcb(&buffer);
736 } else if (TCP_CLIENT(client)) {
739 if (client->view != NULL) {
740 dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
741 &client->destsockaddr, transport_type, &zr,
742 &client->requesttime, NULL, &buffer);
748 client_sendpkg(client, &buffer);
750 switch (isc_sockaddr_pf(&client->peeraddr)) {
752 isc_histomulti_inc(client->manager->sctx->tcpoutstats4,
756 isc_histomulti_inc(client->manager->sctx->tcpoutstats6,
766 * leave client->view set to NULL.
768 if (client->view != NULL) {
769 dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
770 &client->destsockaddr, transport_type, &zr,
771 &client->requesttime, NULL, &buffer);
777 client_sendpkg(client, &buffer);
779 switch (isc_sockaddr_pf(&client->peeraddr)) {
781 isc_histomulti_inc(client->manager->sctx->udpoutstats4,
785 isc_histomulti_inc(client->manager->sctx->udpoutstats6,
794 ns_stats_increment(client->manager->sctx->nsstats,
797 dns_rcodestats_increment(client->manager->sctx->rcodestats,
798 client->message->rcode);
800 ns_stats_increment(client->manager->sctx->nsstats,
803 if (client->message->tsigkey != NULL) {
804 ns_stats_increment(client->manager->sctx->nsstats,
807 if (client->message->sig0key != NULL) {
808 ns_stats_increment(client->manager->sctx->nsstats,
811 if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0) {
812 ns_stats_increment(client->manager->sctx->nsstats,
816 client->query.attributes |= NS_QUERYATTR_ANSWERED;
821 if (client->tcpbuf != NULL) {
822 client_put_tcp_buffer(client);
859 ns_client_error(ns_client_t *client, isc_result_t result) {
864 REQUIRE(NS_CLIENT_VALID(client));
868 message = client->message;
870 if (client->rcode_override == -1) {
873 rcode = (dns_rcode_t)(client->rcode_override & 0xfff);
885 ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) !=
895 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
899 ns_client_drop(client, ISC_R_SUCCESS);
907 if (client->view != NULL && client->view->rrl != NULL) {
913 if ((client->manager->sctx->options & NS_SERVER_LOGQUERIES) !=
921 rrl_result = dns_rrl(client->view, NULL, &client->peeraddr,
922 TCP_CLIENT(client), dns_rdataclass_in,
924 client->now, wouldlog, log_buf,
934 ns_client_log(client,
943 if (!client->view->rrl->log_only) {
945 client->manager->sctx->nsstats,
948 client->manager->sctx->nsstats,
950 ns_client_drop(client, DNS_R_DROP);
975 ns_client_drop(client, result);
988 * with the same ID to the same client less than two
995 if (isc_sockaddr_equal(&client->peeraddr,
996 &client->formerrcache.addr) &&
997 message->id == client->formerrcache.id &&
998 (isc_time_seconds(&client->requesttime) -
999 client->formerrcache.time) < 2)
1002 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1006 ns_client_drop(client, result);
1009 client->formerrcache.addr = client->peeraddr;
1010 client->formerrcache.time =
1011 isc_time_seconds(&client->requesttime);
1012 client->formerrcache.id = message->id;
1013 } else if (rcode == dns_rcode_servfail && client->query.qname != NULL &&
1014 client->view != NULL && client->view->fail_ttl != 0 &&
1015 ((client->attributes & NS_CLIENTATTR_NOSETFC) == 0))
1028 isc_interval_set(&i, client->view->fail_ttl, 0);
1031 dns_badcache_add(client->view->failcache,
1032 client->query.qname,
1033 client->query.qtype, flags,
1038 ns_client_send(client);
1042 ns_client_addopt(ns_client_t *client, dns_message_t *message,
1057 REQUIRE(NS_CLIENT_VALID(client));
1061 env = client->manager->aclenv;
1062 view = client->view;
1066 udpsize = client->manager->sctx->udpsize;
1069 flags = client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE;
1072 if (WANTNSID(client)) {
1073 if (client->manager->sctx->server_id != NULL) {
1074 nsidp = client->manager->sctx->server_id;
1075 } else if (client->manager->sctx->usehostname) {
1091 if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0) {
1097 compute_cookie(client, now, client->manager->sctx->secret,
1106 if ((client->attributes & NS_CLIENTATTR_HAVEEXPIRE) != 0) {
1112 isc_buffer_putuint32(&buf, client->expire);
1118 if (((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) &&
1119 (client->ecs.addr.family == AF_INET ||
1120 client->ecs.addr.family == AF_INET6))
1127 /* Add CLIENT-SUBNET option. */
1129 plen = client->ecs.source;
1134 switch (client->ecs.addr.family) {
1138 memmove(addr, &client->ecs.addr.type, addrl);
1143 memmove(addr, &client->ecs.addr.type, addrl);
1153 isc_buffer_putuint8(&buf, client->ecs.source);
1155 isc_buffer_putuint8(&buf, client->ecs.scope);
1171 if (TCP_CLIENT(client) && USEKEEPALIVE(client)) {
1177 isc_nm_gettimeouts(isc_nmhandle_netmgr(client->handle), NULL,
1189 dns_ednsopt_t *ede = client->edectx.ede[i];
1203 if ((view != NULL) && (view->padding > 0) && WANTPAD(client) &&
1204 (TCP_CLIENT(client) ||
1205 ((client->attributes & NS_CLIENTATTR_HAVECOOKIE) != 0)))
1210 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
1231 compute_cookie(ns_client_t *client, uint32_t when, const unsigned char *secret,
1237 switch (client->manager->sctx->cookiealg) {
1244 isc_buffer_putmem(buf, client->cookie, 8);
1252 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
1278 process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
1290 if ((!client->manager->sctx->answercookie) ||
1291 (client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0)
1297 client->attributes |= NS_CLIENTATTR_WANTCOOKIE;
1299 ns_stats_increment(client->manager->sctx->nsstats,
1307 memmove(client->cookie, isc_buffer_current(buf), 8);
1311 ns_stats_increment(client->manager->sctx->nsstats,
1314 ns_stats_increment(client->manager->sctx->nsstats,
1316 client->attributes |= NS_CLIENTATTR_BADCOOKIE;
1325 memmove(client->cookie, old, 8);
1336 alwaysvalid = ns_server_getoption(client->manager->sctx,
1341 * Only accept COOKIE if we have talked to the client in the last hour.
1350 client->attributes |= NS_CLIENTATTR_BADCOOKIE;
1351 ns_stats_increment(client->manager->sctx->nsstats,
1357 compute_cookie(client, when, client->manager->sctx->secret, &db);
1360 ns_stats_increment(client->manager->sctx->nsstats,
1362 client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
1366 for (altsecret = ISC_LIST_HEAD(client->manager->sctx->altsecrets);
1370 compute_cookie(client, when, altsecret->secret, &db);
1372 ns_stats_increment(client->manager->sctx->nsstats,
1374 client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
1379 client->attributes |= NS_CLIENTATTR_BADCOOKIE;
1380 ns_stats_increment(client->manager->sctx->nsstats,
1385 process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
1393 if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) {
1405 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1407 "EDNS client-subnet option too short");
1417 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1419 "EDNS client-subnet option: invalid scope");
1427 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1429 "EDNS client-subnet option: invalid "
1438 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1440 "EDNS client-subnet option: invalid "
1448 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1450 "EDNS client-subnet option: invalid family");
1456 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1458 "EDNS client-subnet option: address too short");
1477 memmove(&client->ecs.addr, &caddr, sizeof(caddr));
1478 client->ecs.source = addrlen;
1479 client->ecs.scope = 0;
1480 client->attributes |= NS_CLIENTATTR_HAVEECS;
1487 process_keytag(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
1494 if (client->keytag != NULL) {
1499 client->keytag = isc_mem_get(client->manager->mctx, optlen);
1501 client->keytag_len = (uint16_t)optlen;
1502 memmove(client->keytag, isc_buffer_current(buf), optlen);
1509 process_opt(ns_client_t *client, dns_rdataset_t *opt) {
1517 * Set the client's UDP buffer size.
1519 client->udpsize = opt->rdclass;
1525 if (client->udpsize < 512) {
1526 client->udpsize = 512;
1532 client->extflags = (uint16_t)(opt->ttl & 0xFFFF);
1539 client->ednsversion = (opt->ttl & 0x00FF0000) >> 16;
1558 if (client->ednsversion > DNS_EDNS_VERSION &&
1567 if (!WANTNSID(client)) {
1569 client->manager->sctx->nsstats,
1572 client->attributes |= NS_CLIENTATTR_WANTNSID;
1576 process_cookie(client, &optbuf, optlen);
1579 if (!WANTEXPIRE(client)) {
1581 client->manager->sctx->nsstats,
1584 client->attributes |= NS_CLIENTATTR_WANTEXPIRE;
1588 result = process_ecs(client, &optbuf, optlen);
1590 ns_client_error(client, result);
1594 client->manager->sctx->nsstats,
1598 if (!USEKEEPALIVE(client)) {
1600 client->manager->sctx->nsstats,
1603 client->attributes |=
1605 isc_nmhandle_keepalive(client->handle, true);
1609 client->attributes |= NS_CLIENTATTR_WANTPAD;
1611 client->manager->sctx->nsstats,
1616 result = process_keytag(client, &optbuf,
1619 ns_client_error(client, result);
1623 client->manager->sctx->nsstats,
1628 client->manager->sctx->nsstats,
1636 if (client->ednsversion > DNS_EDNS_VERSION) {
1637 ns_stats_increment(client->manager->sctx->nsstats,
1639 result = ns_client_addopt(client, client->message,
1640 &client->opt);
1644 ns_client_error(client, result);
1648 ns_stats_increment(client->manager->sctx->nsstats,
1650 client->attributes |= NS_CLIENTATTR_WANTOPT;
1656 ns_client_async_reset(ns_client_t *client) {
1657 if (client->async) {
1658 client->async = false;
1659 if (client->handle != NULL) {
1660 isc_nmhandle_unref(client->handle);
1667 ns_client_t *client = client0;
1669 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT,
1670 ISC_LOG_DEBUG(3), "reset client");
1673 * We never started processing this client, possible if we're
1676 if (client->state == NS_CLIENTSTATE_READY) {
1680 ns_client_endrequest(client);
1681 if (client->tcpbuf != NULL) {
1682 client_put_tcp_buffer(client);
1685 if (client->keytag != NULL) {
1686 isc_mem_put(client->manager->mctx, client->keytag,
1687 client->keytag_len);
1688 client->keytag_len = 0;
1691 ns_client_async_reset(client);
1693 client->state = NS_CLIENTSTATE_READY;
1702 ns_client_t *client = client0;
1705 REQUIRE(NS_CLIENT_VALID(client));
1707 manager = client->manager;
1709 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT,
1710 ISC_LOG_DEBUG(3), "freeing client");
1713 * Call this first because it requires a valid client.
1715 ns_query_free(client);
1716 dns_ede_invalidate(&client->edectx);
1718 client->magic = 0;
1720 if (client->opt != NULL) {
1721 INSIST(dns_rdataset_isassociated(client->opt));
1722 dns_rdataset_disassociate(client->opt);
1723 dns_message_puttemprdataset(client->message, &client->opt);
1726 ns_client_async_reset(client);
1728 dns_message_detach(&client->message);
1734 isc_mutex_destroy(&client->query.fetchlock);
1736 isc_mem_put(manager->mctx, client, sizeof(*client));
1742 ns_client_setup_view(ns_client_t *client, isc_netaddr_t *netaddr) {
1745 client->sigresult = client->viewmatchresult = ISC_R_UNSET;
1747 if (client->async) {
1748 isc_nmhandle_ref(client->handle);
1751 result = client->manager->sctx->matchingview(
1752 netaddr, &client->destaddr, client->message,
1753 client->manager->aclenv, client->manager->sctx,
1754 client->async ? client->manager->loop : NULL,
1755 ns_client_request_continue, client, &client->sigresult,
1756 &client->viewmatchresult, &client->view);
1760 INSIST(client->async == true);
1767 * 'client->viewmatchresult'.
1769 INSIST(result == client->viewmatchresult);
1772 ns_client_async_reset(client);
1784 ns_client_t *client = NULL;
1799 client = isc_nmhandle_getdata(handle);
1800 if (client == NULL) {
1808 client = isc_mem_get(clientmgr->mctx, sizeof(*client));
1810 ns__client_setup(client, clientmgr, true);
1812 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1814 "allocate new client");
1816 ns__client_setup(client, NULL, false);
1819 client->state = NS_CLIENTSTATE_READY;
1821 if (client->handle == NULL) {
1822 isc_nmhandle_setdata(handle, client, ns__client_reset_cb,
1824 client->handle = handle;
1828 client->attributes |= NS_CLIENTATTR_TCP;
1831 INSIST(client->state == NS_CLIENTSTATE_READY);
1835 isc_buffer_init(&client->tbuffer, region->base, region->length);
1836 isc_buffer_add(&client->tbuffer, region->length);
1837 client->buffer = &client->tbuffer;
1839 client->peeraddr = isc_nmhandle_peeraddr(handle);
1840 client->peeraddr_valid = true;
1842 reqsize = isc_buffer_usedlength(client->buffer);
1844 client->state = NS_CLIENTSTATE_WORKING;
1846 client->requesttime = isc_time_now();
1847 client->tnow = client->requesttime;
1848 client->now = isc_time_seconds(&client->tnow);
1850 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
1853 if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) ==
1856 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1864 env = client->manager->aclenv;
1865 if (client->manager->sctx->blackholeacl != NULL &&
1866 (dns_acl_match(&netaddr, NULL, client->manager->sctx->blackholeacl,
1870 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1877 ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT,
1879 TCP_CLIENT(client) ? "TCP" : "UDP");
1881 result = dns_message_peekheader(client->buffer, &id, &flags);
1887 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1901 * The client object handles requests, not responses.
1906 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1916 if (isc_sockaddr_pf(&client->peeraddr) == PF_INET) {
1917 ns_stats_increment(client->manager->sctx->nsstats,
1920 ns_stats_increment(client->manager->sctx->nsstats,
1923 if (TCP_CLIENT(client)) {
1924 ns_stats_increment(client->manager->sctx->nsstats,
1926 switch (isc_sockaddr_pf(&client->peeraddr)) {
1928 isc_histomulti_inc(client->manager->sctx->tcpinstats4,
1932 isc_histomulti_inc(client->manager->sctx->tcpinstats6,
1939 switch (isc_sockaddr_pf(&client->peeraddr)) {
1941 isc_histomulti_inc(client->manager->sctx->udpinstats4,
1945 isc_histomulti_inc(client->manager->sctx->udpinstats6,
1956 result = dns_message_parse(client->message, client->buffer, 0);
1963 (void)ns_client_addopt(client, client->message,
1964 &client->opt);
1967 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1974 ns_client_error(client, result);
1978 dns_opcodestats_increment(client->manager->sctx->opcodestats,
1979 client->message->opcode);
1980 switch (client->message->opcode) {
1992 client->message->rcode = dns_rcode_noerror;
1997 if ((client->manager->sctx->options & NS_SERVER_NOEDNS) != 0) {
2000 opt = dns_message_getopt(client->message);
2003 client->ecs.source = 0;
2004 client->ecs.scope = 0;
2011 if ((client->manager->sctx->options & NS_SERVER_EDNSFORMERR) !=
2014 ns_client_error(client, DNS_R_FORMERR);
2021 if ((client->manager->sctx->options & NS_SERVER_EDNSNOTIMP) !=
2024 ns_client_error(client, DNS_R_NOTIMP);
2031 if ((client->manager->sctx->options & NS_SERVER_EDNSREFUSED) !=
2034 ns_client_error(client, DNS_R_REFUSED);
2041 if ((client->manager->sctx->options & NS_SERVER_DROPEDNS) != 0)
2043 ns_client_drop(client, ISC_R_SUCCESS);
2047 result = process_opt(client, opt);
2054 switch (client->message->rdclass) {
2056 if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0 &&
2057 client->message->opcode == dns_opcode_query &&
2058 client->message->counts[DNS_SECTION_QUESTION] == 0U)
2060 result = dns_message_reply(client->message, true);
2062 ns_client_error(client, result);
2067 client->message->rcode = dns_rcode_notimp;
2070 ns_client_send(client);
2074 ns_client_dumpmessage(client,
2076 ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR);
2085 if (client->message->opcode != dns_opcode_update) {
2086 ns_client_dumpmessage(client,
2089 ns_client_error(client, DNS_R_FORMERR);
2097 if (client->message->tkey == 0) {
2098 ns_client_dumpmessage(client,
2101 ns_client_error(client, DNS_R_FORMERR);
2106 dns_rdataclass_format(client->message->rdclass, classbuf,
2108 ns_client_dumpmessage(client, "");
2109 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
2113 ns_client_error(client, DNS_R_NOTIMP);
2117 client->destsockaddr = isc_nmhandle_localaddr(handle);
2118 isc_netaddr_fromsockaddr(&client->destaddr, &client->destsockaddr);
2124 client->async = (client->message->tsigkey == NULL &&
2125 client->message->tsig == NULL &&
2126 client->message->sig0 != NULL);
2128 result = ns_client_setup_view(client, &netaddr);
2133 ns_client_request_continue(client);
2138 ns_client_t *client = arg;
2165 INSIST(client->viewmatchresult != ISC_R_UNSET);
2171 if (client->async) {
2172 client->tnow = isc_time_now();
2173 client->now = isc_time_seconds(&client->tnow);
2176 if (client->viewmatchresult != ISC_R_SUCCESS) {
2185 dns_message_resetsig(client->message);
2186 r = dns_message_getrawmessage(client->message);
2189 (void)dns_tsig_verify(&b, client->message, NULL, NULL);
2191 if (client->viewmatchresult == ISC_R_QUOTA) {
2192 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
2198 client, "SIG(0) checks quota reached");
2203 dns_rdataclass_format(client->message->rdclass,
2206 ns_client_dumpmessage(client, "");
2207 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
2213 dns_ede_add(&client->edectx, DNS_EDE_PROHIBITED, NULL);
2214 ns_client_error(client, DNS_R_REFUSED);
2219 if (isc_nm_is_proxy_handle(client->handle)) {
2225 real_peer = isc_nmhandle_real_peeraddr(client->handle);
2227 real_local = isc_nmhandle_real_localaddr(client->handle);
2231 if (ns_client_checkaclsilent(client, &real_peer_addr,
2232 client->view->proxyacl,
2239 client, DNS_LOGCATEGORY_SECURITY,
2242 "for that client (real client address: "
2247 isc_nm_bad_request(client->handle);
2252 if (ns_client_checkaclsilent(client, &real_local_addr,
2253 client->view->proxyonacl,
2260 client, DNS_LOGCATEGORY_SECURITY,
2268 isc_nm_bad_request(client->handle);
2273 ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT,
2274 ISC_LOG_DEBUG(5), "using view '%s'", client->view->name);
2282 client->signer = NULL;
2283 dns_name_init(&client->signername, NULL);
2284 result = dns_message_signer(client->message, &client->signername);
2287 if (dns_message_gettsig(client->message, &signame) != NULL) {
2288 ns_stats_increment(client->manager->sctx->nsstats,
2291 ns_stats_increment(client->manager->sctx->nsstats,
2297 dns_name_format(&client->signername, namebuf, sizeof(namebuf));
2298 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2301 client->signer = &client->signername;
2303 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2307 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2317 ns_stats_increment(client->manager->sctx->nsstats,
2320 if (dns_message_gettsig(client->message, &signame) != NULL) {
2323 status = client->message->tsigstatus;
2328 if (client->message->tsigkey->generated) {
2330 client->message->tsigkey->creator,
2336 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2343 status = client->message->sig0status;
2348 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2359 if (!(client->message->tsigstatus == dns_tsigerror_badkey &&
2360 client->message->opcode == dns_opcode_update))
2362 ns_client_error(client, client->sigresult);
2368 * Decide whether recursive service is available to this client.
2377 if (client->view->resolver == NULL) {
2379 } else if (!client->view->recursion) {
2381 } else if (ns_client_checkaclsilent(client, NULL,
2382 client->view->recursionacl,
2386 } else if (ns_client_checkaclsilent(client, NULL,
2387 client->view->cacheacl,
2391 } else if (ns_client_checkaclsilent(client, &client->destaddr,
2392 client->view->recursiononacl,
2396 } else if (ns_client_checkaclsilent(client, &client->destaddr,
2397 client->view->cacheonacl,
2403 client->attributes |= NS_CLIENTATTR_RA;
2406 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT,
2413 * Adjust maximum UDP response size for this client.
2415 if (client->udpsize > 512) {
2417 uint16_t udpsize = client->view->maxudp;
2420 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
2421 (void)dns_peerlist_peerbyaddr(client->view->peers, &netaddr,
2426 if (client->udpsize > udpsize) {
2427 client->udpsize = udpsize;
2432 transport_type = ns_client_transport_type(client);
2438 switch (client->message->opcode) {
2442 if (ra && (client->message->flags & DNS_MESSAGEFLAG_RD) != 0) {
2448 dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
2449 &client->destsockaddr, transport_type, NULL,
2450 &client->requesttime, NULL, client->buffer);
2453 ns_query_start(client, client->handle);
2457 if (client->view->rdclass != dns_rdataclass_in) {
2458 ns_client_error(client, DNS_R_NOTIMP);
2462 dns_dt_send(client->view, DNS_DTTYPE_UQ, &client->peeraddr,
2463 &client
2464 &client->requesttime, NULL, client->buffer);
2466 ns_client_settimeout(client, 60);
2467 ns_update_start(client, client->handle, client->sigresult);
2471 if (client->view->rdclass != dns_rdataclass_in) {
2472 ns_client_error(client, DNS_R_NOTIMP);
2475 ns_client_settimeout(client, 60);
2476 ns_notify_start(client, client->handle);
2480 ns_client_error(client, DNS_R_NOTIMP);
2484 ns_client_error(client, DNS_R_NOTIMP);
2488 ns_client_async_reset(client);
2526 ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) {
2528 * Note: creating a client does not add the client to the
2529 * manager's client list, the caller is responsible for that.
2534 REQUIRE(client != NULL);
2537 *client = (ns_client_t){ .magic = 0 };
2539 ns_clientmgr_attach(mgr, &client->manager);
2541 dns_message_create(client->manager->mctx,
2542 client->manager->namepool,
2543 client->manager->rdspool,
2544 DNS_MESSAGE_INTENTPARSE, &client->message);
2550 client->magic = NS_CLIENT_MAGIC;
2551 ns_query_init(client);
2553 dns_ede_init(client->manager->mctx, &client->edectx);
2555 REQUIRE(NS_CLIENT_VALID(client));
2556 REQUIRE(client->manager->tid == isc_tid());
2559 * Retain these values from the existing client, but
2562 *client = (ns_client_t){
2564 .manager = client->manager,
2565 .message = client->message,
2566 .edectx = client->edectx,
2567 .query = client->query,
2570 dns_ede_reset(&client->edectx);
2573 client->query.attributes &= ~NS_QUERYATTR_ANSWERED;
2574 client->state = NS_CLIENTSTATE_INACTIVE;
2575 client->udpsize = 512;
2576 client->ednsversion = -1;
2577 dns_name_init(&client->signername, NULL);
2578 dns_ecs_init(&client->ecs);
2579 isc_sockaddr_any(&client->formerrcache.addr);
2580 client->formerrcache.time = 0;
2581 client->formerrcache.id = 0;
2582 ISC_LINK_INIT(client, rlink);
2583 client->rcode_override = -1; /* not set */
2585 client->magic = NS_CLIENT_MAGIC;
2591 *** Client Manager
2656 ns_client_t *client;
2663 for (client = ISC_LIST_HEAD(manager->recursing); client != NULL;
2664 client = ISC_LIST_NEXT(client, rlink))
2666 ns_query_cancel(client);
2672 ns_client_getsockaddr(ns_client_t *client) {
2673 return &client->peeraddr;
2677 ns_client_getdestaddr(ns_client_t *client) {
2678 return &client->destsockaddr;
2682 ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
2685 dns_aclenv_t *env = client->manager->aclenv;
2699 isc_netaddr_fromsockaddr(&tmpnetaddr, &client->peeraddr);
2703 local = isc_nmhandle_localaddr(client->handle);
2706 isc_nm_socket_type(client->handle),
2707 isc_nm_has_encryption(client->handle), client->signer, acl, env,
2727 ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr,
2737 result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL,
2741 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2745 dns_ede_add(&client->edectx, DNS_EDE_PROHIBITED, NULL);
2746 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2749 pfilter_notify(result, client, opname);
2755 ns_client_name(ns_client_t *client, char *peerbuf, size_t len) {
2756 if (client->peeraddr_valid) {
2757 isc_sockaddr_format(&client->peeraddr, peerbuf,
2760 snprintf(peerbuf, len, "@%p", client);
2765 ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
2776 REQUIRE(client != NULL);
2780 if (client->signer != NULL) {
2781 dns_name_format(client->signer, signerbuf, sizeof(signerbuf));
2786 q = client->query.origqname != NULL ? client->query.origqname
2787 : client->query.qname;
2795 if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 &&
2796 strcmp(client->view->name, "_default") != 0)
2799 viewname = client->view->name;
2802 if (client->peeraddr_valid) {
2803 isc_sockaddr_format(&client->peeraddr, peerbuf,
2810 "client @%p %s%s%s%s%s%s%s%s: %s", client, peerbuf, sep1,
2815 ns_client_log(ns_client_t *client, isc_logcategory_t *category,
2824 ns_client_logv(client, category, module, level, fmt, ap);
2843 ns_client_dumpmessage(ns_client_t *client, const char *reason) {
2859 buf = isc_mem_get(client->manager->mctx, len);
2862 client->message, &dns_master_style_debug, 0, &buffer);
2864 isc_mem_put(client->manager->mctx, buf, len);
2867 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
2875 isc_mem_put(client->manager->mctx, buf, len);
2881 ns_client_t *client;
2895 client = ISC_LIST_HEAD(manager->recursing);
2896 while (client != NULL) {
2897 INSIST(client->state == NS_CLIENTSTATE_RECURSING);
2899 ns_client_name(client, peerbuf, sizeof(peerbuf));
2900 if (client->view != NULL &&
2901 strcmp(client->view->name, "_bind") != 0 &&
2902 strcmp(client->view->name, "_default") != 0)
2904 name = client->view->name;
2911 LOCK(&client->query.fetchlock);
2912 INSIST(client->query.qname != NULL);
2913 dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
2914 if (client->query.qname != client->query.origqname &&
2915 client->query.origqname != NULL)
2918 dns_name_format(client->query.origqname, original,
2924 rdataset = ISC_LIST_HEAD(client->query.qname->list);
2925 if (rdataset == NULL && client->query.origqname != NULL) {
2926 rdataset = ISC_LIST_HEAD(client->query.origqname->list);
2937 UNLOCK(&client->query.fetchlock);
2939 "; client %s%s%s: id %u '%s/%s/%s'%s%s "
2941 peerbuf, sep, name, client->message->id, namebuf,
2943 isc_time_seconds(&client->requesttime));
2944 client = ISC_LIST_NEXT(client, rlink);
2950 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) {
2951 LOCK(&client->query.fetchlock);
2952 if (client->query.restarts > 0) {
2954 * client->query.qname was dynamically allocated.
2956 dns_message_puttempname(client->message, &client->query.qname);
2958 client->query.qname = name;
2959 client->query.attributes &= ~NS_QUERYATTR_REDIRECT;
2960 UNLOCK(&client->query.fetchlock);
2965 ns_client_t *client = (ns_client_t *)ci->data;
2967 REQUIRE(NS_CLIENT_VALID(client));
2970 *addrp = &client->peeraddr;
2975 ns_client_newrdataset(ns_client_t *client) {
2978 REQUIRE(NS_CLIENT_VALID(client));
2981 dns_message_gettemprdataset(client->message, &rdataset);
2987 ns_client_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
2990 REQUIRE(NS_CLIENT_VALID(client));
2999 dns_message_puttemprdataset(client->message, rdatasetp);
3004 ns_client_newnamebuf(ns_client_t *client) {
3009 isc_buffer_allocate(client->manager->mctx, &dbuf, 1024);
3010 ISC_LIST_APPEND(client->query.namebufs, dbuf, link);
3017 ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) {
3021 REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0);
3025 dns_message_gettempname(client->message, &name);
3030 client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED;
3037 ns_client_getnamebuf(ns_client_t *client) {
3047 if (ISC_LIST_EMPTY(client->query.namebufs)) {
3048 ns_client_newnamebuf(client);
3051 dbuf = ISC_LIST_TAIL(client->query.namebufs);
3055 ns_client_newnamebuf(client);
3056 dbuf = ISC_LIST_TAIL(client->query.namebufs);
3065 ns_client_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) {
3074 REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0);
3079 client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
3083 ns_client_releasename(ns_client_t *client, dns_name_t **namep) {
3091 client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
3092 dns_message_puttempname(client->message, namep);
3097 ns_client_newdbversion(ns_client_t *client, unsigned int n) {
3102 dbversion = isc_mem_get(client->manager->mctx,
3105 ISC_LIST_INITANDAPPEND(client->query.freeversions, dbversion,
3113 client_getdbversion(ns_client_t *client) {
3116 if (ISC_LIST_EMPTY(client->query.freeversions)) {
3117 ns_client_newdbversion(client, 1);
3119 dbversion = ISC_LIST_HEAD(client->query.freeversions);
3121 ISC_LIST_UNLINK(client->query.freeversions, dbversion, link);
3127 ns_client_findversion(ns_client_t *client, dns_db_t *db) {
3130 for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
3143 dbversion = client_getdbversion(client);
3151 ISC_LIST_APPEND(client->query.activeversions, dbversion, link);