"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/bin/named/client.c" (7 Sep 2020, 115895 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "client.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.11.21_vs_9.11.22.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 #include <config.h>
   13 
   14 #include <inttypes.h>
   15 #include <stdbool.h>
   16 
   17 #include <isc/aes.h>
   18 #include <isc/formatcheck.h>
   19 #include <isc/hmacsha.h>
   20 #include <isc/mutex.h>
   21 #include <isc/once.h>
   22 #include <isc/platform.h>
   23 #include <isc/print.h>
   24 #include <isc/queue.h>
   25 #include <isc/random.h>
   26 #include <isc/safe.h>
   27 #include <isc/serial.h>
   28 #include <isc/siphash.h>
   29 #include <isc/stats.h>
   30 #include <isc/stdio.h>
   31 #include <isc/string.h>
   32 #include <isc/task.h>
   33 #include <isc/timer.h>
   34 #include <isc/util.h>
   35 
   36 #include <dns/adb.h>
   37 #include <dns/badcache.h>
   38 #include <dns/db.h>
   39 #include <dns/dispatch.h>
   40 #include <dns/dnstap.h>
   41 #include <dns/cache.h>
   42 #include <dns/edns.h>
   43 #include <dns/events.h>
   44 #include <dns/message.h>
   45 #include <dns/peer.h>
   46 #include <dns/rcode.h>
   47 #include <dns/rdata.h>
   48 #include <dns/rdataclass.h>
   49 #include <dns/rdatalist.h>
   50 #include <dns/rdataset.h>
   51 #include <dns/resolver.h>
   52 #include <dns/stats.h>
   53 #include <dns/tsig.h>
   54 #include <dns/view.h>
   55 #include <dns/zone.h>
   56 
   57 #include <named/fuzz.h>
   58 #include <named/interfacemgr.h>
   59 #include <named/log.h>
   60 #include <named/notify.h>
   61 #include <named/os.h>
   62 #include <named/server.h>
   63 #include <named/update.h>
   64 
   65 /***
   66  *** Client
   67  ***/
   68 
   69 /*! \file
   70  * Client Routines
   71  *
   72  * Important note!
   73  *
   74  * All client state changes, other than that from idle to listening, occur
   75  * as a result of events.  This guarantees serialization and avoids the
   76  * need for locking.
   77  *
   78  * If a routine is ever created that allows someone other than the client's
   79  * task to change the client, then the client will have to be locked.
   80  */
   81 
   82 #define NS_CLIENT_TRACE
   83 #ifdef NS_CLIENT_TRACE
   84 #define CTRACE(m)   ns_client_log(client, \
   85                       NS_LOGCATEGORY_CLIENT, \
   86                       NS_LOGMODULE_CLIENT, \
   87                       ISC_LOG_DEBUG(3), \
   88                       "%s", (m))
   89 #define MTRACE(m)   isc_log_write(ns_g_lctx, \
   90                       NS_LOGCATEGORY_GENERAL, \
   91                       NS_LOGMODULE_CLIENT, \
   92                       ISC_LOG_DEBUG(3), \
   93                       "clientmgr @%p: %s", manager, (m))
   94 #else
   95 #define CTRACE(m)   ((void)(m))
   96 #define MTRACE(m)   ((void)(m))
   97 #endif
   98 
   99 #define TCP_CLIENT(c)   (((c)->attributes & NS_CLIENTATTR_TCP) != 0)
  100 
  101 #define TCP_BUFFER_SIZE         (65535 + 2)
  102 #define SEND_BUFFER_SIZE        4096
  103 #define RECV_BUFFER_SIZE        4096
  104 
  105 #define TCP_CLIENTS_PER_CONN        23
  106 /*%<
  107  * Number of simultaneous ns_clients_t (queries in flight) for one
  108  * TCP connection.  The number was arbitrarily picked and might be
  109  * changed in the future.
  110  */
  111 
  112 #ifdef ISC_PLATFORM_USETHREADS
  113 
  114 #define NMCTXS              100
  115 /*%<
  116  * Number of 'mctx pools' for clients. (Should this be configurable?)
  117  * When enabling threads, we use a pool of memory contexts shared by
  118  * client objects, since concurrent access to a shared context would cause
  119  * heavy contentions.  The above constant is expected to be enough for
  120  * completely avoiding contentions among threads for an authoritative-only
  121  * server.
  122  */
  123 #else
  124 #define NMCTXS              0
  125 /*%<
  126  * If named with built without thread, simply share manager's context.  Using
  127  * a separate context in this case would simply waste memory.
  128  */
  129 #endif
  130 
  131 #define COOKIE_SIZE 24U /* 8 + 4 + 4 + 8 */
  132 #define ECS_SIZE 20U /* 2 + 1 + 1 + [0..16] */
  133 
  134 #define WANTNSID(x) (((x)->attributes & NS_CLIENTATTR_WANTNSID) != 0)
  135 #define WANTEXPIRE(x) (((x)->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0)
  136 
  137 /*% nameserver client manager structure */
  138 struct ns_clientmgr {
  139     /* Unlocked. */
  140     unsigned int            magic;
  141 
  142     /* The queue object has its own locks */
  143     client_queue_t          inactive;     /*%< To be recycled */
  144 
  145     isc_mem_t *         mctx;
  146     isc_taskmgr_t *         taskmgr;
  147     isc_timermgr_t *        timermgr;
  148 
  149     /* Lock covers manager state. */
  150     isc_mutex_t         lock;
  151     bool            exiting;
  152 
  153     /* Lock covers the clients list */
  154     isc_mutex_t         listlock;
  155     client_list_t           clients;      /*%< All active clients */
  156 
  157     /* Lock covers the recursing list */
  158     isc_mutex_t         reclock;
  159     client_list_t           recursing;    /*%< Recursing clients */
  160 
  161 #if NMCTXS > 0
  162     /*%< mctx pool for clients. */
  163     unsigned int            nextmctx;
  164     isc_mem_t *         mctxpool[NMCTXS];
  165 #endif
  166 };
  167 
  168 #define MANAGER_MAGIC           ISC_MAGIC('N', 'S', 'C', 'm')
  169 #define VALID_MANAGER(m)        ISC_MAGIC_VALID(m, MANAGER_MAGIC)
  170 
  171 /*!
  172  * Client object states.  Ordering is significant: higher-numbered
  173  * states are generally "more active", meaning that the client can
  174  * have more dynamically allocated data, outstanding events, etc.
  175  * In the list below, any such properties listed for state N
  176  * also apply to any state > N.
  177  *
  178  * To force the client into a less active state, set client->newstate
  179  * to that state and call exit_check().  This will cause any
  180  * activities defined for higher-numbered states to be aborted.
  181  */
  182 
  183 #define NS_CLIENTSTATE_FREED    0
  184 /*%<
  185  * The client object no longer exists.
  186  */
  187 
  188 #define NS_CLIENTSTATE_INACTIVE 1
  189 /*%<
  190  * The client object exists and has a task and timer.
  191  * Its "query" struct and sendbuf are initialized.
  192  * It is on the client manager's list of inactive clients.
  193  * It has a message and OPT, both in the reset state.
  194  */
  195 
  196 #define NS_CLIENTSTATE_READY    2
  197 /*%<
  198  * The client object is either a TCP or a UDP one, and
  199  * it is associated with a network interface.  It is on the
  200  * client manager's list of active clients.
  201  *
  202  * If it is a TCP client object, it has a TCP listener socket
  203  * and an outstanding TCP listen request.
  204  *
  205  * If it is a UDP client object, it has a UDP listener socket
  206  * and an outstanding UDP receive request.
  207  */
  208 
  209 #define NS_CLIENTSTATE_READING  3
  210 /*%<
  211  * The client object is a TCP client object that has received
  212  * a connection.  It has a tcpsocket, tcpmsg, TCP quota, and an
  213  * outstanding TCP read request.  This state is not used for
  214  * UDP client objects.
  215  */
  216 
  217 #define NS_CLIENTSTATE_WORKING  4
  218 /*%<
  219  * The client object has received a request and is working
  220  * on it.  It has a view, and it may have any of a non-reset OPT,
  221  * recursion quota, and an outstanding write request.
  222  */
  223 
  224 #define NS_CLIENTSTATE_RECURSING  5
  225 /*%<
  226  * The client object is recursing.  It will be on the 'recursing'
  227  * list.
  228  */
  229 
  230 #define NS_CLIENTSTATE_MAX      9
  231 /*%<
  232  * Sentinel value used to indicate "no state".  When client->newstate
  233  * has this value, we are not attempting to exit the current state.
  234  * Must be greater than any valid state.
  235  */
  236 
  237 /*
  238  * Enable ns_client_dropport() by default.
  239  */
  240 #ifndef NS_CLIENT_DROPPORT
  241 #define NS_CLIENT_DROPPORT 1
  242 #endif
  243 
  244 unsigned int ns_client_requests;
  245 
  246 static void client_read(ns_client_t *client);
  247 static void client_accept(ns_client_t *client);
  248 static void client_udprecv(ns_client_t *client);
  249 static void clientmgr_destroy(ns_clientmgr_t *manager);
  250 static bool exit_check(ns_client_t *client);
  251 static void ns_client_endrequest(ns_client_t *client);
  252 static void client_start(isc_task_t *task, isc_event_t *event);
  253 static void client_request(isc_task_t *task, isc_event_t *event);
  254 static void ns_client_dumpmessage(ns_client_t *client, const char *reason);
  255 static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
  256                    dns_dispatch_t *disp, bool tcp);
  257 static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp,
  258                    isc_socket_t *sock, ns_client_t *oldclient);
  259 static inline bool
  260 allowed(isc_netaddr_t *addr, const dns_name_t *signer,
  261     isc_netaddr_t *ecs_addr, uint8_t ecs_addrlen,
  262     uint8_t *ecs_scope, dns_acl_t *acl);
  263 static void compute_cookie(ns_client_t *client, uint32_t when,
  264                uint32_t nonce, const unsigned char *secret,
  265                isc_buffer_t *buf);
  266 
  267 void
  268 ns_client_recursing(ns_client_t *client) {
  269     REQUIRE(NS_CLIENT_VALID(client));
  270     REQUIRE(client->state == NS_CLIENTSTATE_WORKING);
  271 
  272     LOCK(&client->manager->reclock);
  273     client->newstate = client->state = NS_CLIENTSTATE_RECURSING;
  274     ISC_LIST_APPEND(client->manager->recursing, client, rlink);
  275     UNLOCK(&client->manager->reclock);
  276 }
  277 
  278 void
  279 ns_client_killoldestquery(ns_client_t *client) {
  280     ns_client_t *oldest;
  281     REQUIRE(NS_CLIENT_VALID(client));
  282 
  283     LOCK(&client->manager->reclock);
  284     oldest = ISC_LIST_HEAD(client->manager->recursing);
  285     if (oldest != NULL) {
  286         ISC_LIST_UNLINK(client->manager->recursing, oldest, rlink);
  287         UNLOCK(&client->manager->reclock);
  288         ns_query_cancel(oldest);
  289         isc_stats_increment(ns_g_server->nsstats,
  290                     dns_nsstatscounter_reclimitdropped);
  291     } else {
  292         UNLOCK(&client->manager->reclock);
  293     }
  294 }
  295 
  296 void
  297 ns_client_settimeout(ns_client_t *client, unsigned int seconds) {
  298     isc_result_t result;
  299     isc_interval_t interval;
  300 
  301     isc_interval_set(&interval, seconds, 0);
  302     result = isc_timer_reset(client->timer, isc_timertype_once, NULL,
  303                  &interval, false);
  304     client->timerset = true;
  305     if (result != ISC_R_SUCCESS) {
  306         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
  307                   NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
  308                   "setting timeout: %s",
  309                   isc_result_totext(result));
  310         /* Continue anyway. */
  311     }
  312 }
  313 
  314 /*%
  315  * Allocate a reference-counted object that will maintain a single pointer to
  316  * the (also reference-counted) TCP client quota, shared between all the
  317  * clients processing queries on a single TCP connection, so that all
  318  * clients sharing the one socket will together consume only one slot in
  319  * the 'tcp-clients' quota.
  320  */
  321 static isc_result_t
  322 tcpconn_init(ns_client_t *client, bool force) {
  323     isc_result_t result;
  324     isc_quota_t *quota = NULL;
  325     ns_tcpconn_t *tconn = NULL;
  326 
  327     REQUIRE(client->tcpconn == NULL);
  328 
  329     /*
  330      * Try to attach to the quota first, so we won't pointlessly
  331      * allocate memory for a tcpconn object if we can't get one.
  332      */
  333     if (force) {
  334         result = isc_quota_force(&ns_g_server->tcpquota, &quota);
  335     } else {
  336         result = isc_quota_attach(&ns_g_server->tcpquota, &quota);
  337     }
  338     if (result != ISC_R_SUCCESS) {
  339         return (result);
  340     }
  341 
  342     /*
  343      * A global memory context is used for the allocation as different
  344      * client structures may have different memory contexts assigned and a
  345      * reference counter allocated here might need to be freed by a
  346      * different client.  The performance impact caused by memory context
  347      * contention here is expected to be negligible, given that this code
  348      * is only executed for TCP connections.
  349      */
  350     tconn = isc_mem_allocate(ns_g_mctx, sizeof(*tconn));
  351     if (tconn == NULL) {
  352         isc_quota_detach(&quota);
  353         return (ISC_R_NOMEMORY);
  354     }
  355 
  356     isc_refcount_init(&tconn->clients, 1);  /* Current client */
  357     tconn->tcpquota = quota;
  358     quota = NULL;
  359     tconn->pipelined = false;
  360 
  361     client->tcpconn = tconn;
  362 
  363     return (ISC_R_SUCCESS);
  364 }
  365 
  366 /*%
  367  * Increase the count of client structures sharing the TCP connection
  368  * that 'source' is associated with; add a pointer to the same tcpconn
  369  * to 'target', thus associating it with the same TCP connection.
  370  */
  371 static void
  372 tcpconn_attach(ns_client_t *source, ns_client_t *target) {
  373     int old_clients;
  374 
  375     REQUIRE(source->tcpconn != NULL);
  376     REQUIRE(target->tcpconn == NULL);
  377     REQUIRE(source->tcpconn->pipelined);
  378 
  379     isc_refcount_increment(&source->tcpconn->clients, &old_clients);
  380     INSIST(old_clients > 1);
  381     target->tcpconn = source->tcpconn;
  382 }
  383 
  384 /*%
  385  * Decrease the count of client structures sharing the TCP connection that
  386  * 'client' is associated with.  If this is the last client using this TCP
  387  * connection, we detach from the TCP quota and free the tcpconn
  388  * object. Either way, client->tcpconn is set to NULL.
  389  */
  390 static void
  391 tcpconn_detach(ns_client_t *client) {
  392     ns_tcpconn_t *tconn = NULL;
  393     int old_clients;
  394 
  395     REQUIRE(client->tcpconn != NULL);
  396 
  397     tconn = client->tcpconn;
  398     client->tcpconn = NULL;
  399 
  400     isc_refcount_decrement(&tconn->clients, &old_clients);
  401     if (old_clients == 0) {
  402         isc_quota_detach(&tconn->tcpquota);
  403         isc_mem_free(ns_g_mctx, tconn);
  404     }
  405 }
  406 
  407 /*%
  408  * Mark a client as active and increment the interface's 'ntcpactive'
  409  * counter, as a signal that there is at least one client servicing
  410  * TCP queries for the interface. If we reach the TCP client quota at
  411  * some point, this will be used to determine whether a quota overrun
  412  * should be permitted.
  413  *
  414  * Marking the client active with the 'tcpactive' flag ensures proper
  415  * accounting, by preventing us from incrementing or decrementing
  416  * 'ntcpactive' more than once per client.
  417  */
  418 static void
  419 mark_tcp_active(ns_client_t *client, bool active) {
  420     if (active && !client->tcpactive) {
  421         isc_refcount_increment0(&client->interface->ntcpactive, NULL);
  422         client->tcpactive = active;
  423     } else if (!active && client->tcpactive) {
  424         isc_refcount_decrement(&client->interface->ntcpactive, NULL);
  425         client->tcpactive = active;
  426     }
  427 }
  428 
  429 /*%
  430  * Check for a deactivation or shutdown request and take appropriate
  431  * action.  Returns true if either is in progress; in this case
  432  * the caller must no longer use the client object as it may have been
  433  * freed.
  434  */
  435 static bool
  436 exit_check(ns_client_t *client) {
  437     bool destroy_manager = false;
  438     ns_clientmgr_t *manager = NULL;
  439 
  440     REQUIRE(NS_CLIENT_VALID(client));
  441     manager = client->manager;
  442 
  443     if (client->state <= client->newstate)
  444         return (false); /* Business as usual. */
  445 
  446     INSIST(client->newstate < NS_CLIENTSTATE_RECURSING);
  447 
  448     /*
  449      * We need to detach from the view early when shutting down
  450      * the server to break the following vicious circle:
  451      *
  452      *  - The resolver will not shut down until the view refcount is zero
  453      *  - The view refcount does not go to zero until all clients detach
  454      *  - The client does not detach from the view until references is zero
  455      *  - references does not go to zero until the resolver has shut down
  456      *
  457      * Keep the view attached until any outstanding updates complete.
  458      */
  459     if (client->nupdates == 0 &&
  460         client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL)
  461         dns_view_detach(&client->view);
  462 
  463     if (client->state == NS_CLIENTSTATE_WORKING ||
  464         client->state == NS_CLIENTSTATE_RECURSING)
  465     {
  466         INSIST(client->newstate <= NS_CLIENTSTATE_READING);
  467         /*
  468          * Let the update processing complete.
  469          */
  470         if (client->nupdates > 0)
  471             return (true);
  472 
  473         /*
  474          * We are trying to abort request processing.
  475          */
  476         if (client->nsends > 0) {
  477             isc_socket_t *sock;
  478             if (TCP_CLIENT(client))
  479                 sock = client->tcpsocket;
  480             else
  481                 sock = client->udpsocket;
  482             isc_socket_cancel(sock, client->task,
  483                       ISC_SOCKCANCEL_SEND);
  484         }
  485 
  486         if (! (client->nsends == 0 && client->nrecvs == 0 &&
  487                client->references == 0))
  488         {
  489             /*
  490              * Still waiting for I/O cancel completion.
  491              * or lingering references.
  492              */
  493             return (true);
  494         }
  495 
  496         /*
  497          * I/O cancel is complete.  Burn down all state
  498          * related to the current request.  Ensure that
  499          * the client is no longer on the recursing list.
  500          *
  501          * We need to check whether the client is still linked,
  502          * because it may already have been removed from the
  503          * recursing list by ns_client_killoldestquery()
  504          */
  505         if (client->state == NS_CLIENTSTATE_RECURSING) {
  506             LOCK(&manager->reclock);
  507             if (ISC_LINK_LINKED(client, rlink))
  508                 ISC_LIST_UNLINK(manager->recursing,
  509                         client, rlink);
  510             UNLOCK(&manager->reclock);
  511         }
  512         ns_client_endrequest(client);
  513 
  514         client->state = NS_CLIENTSTATE_READING;
  515         INSIST(client->recursionquota == NULL);
  516 
  517         if (NS_CLIENTSTATE_READING == client->newstate) {
  518             INSIST(client->tcpconn != NULL);
  519             if (!client->tcpconn->pipelined) {
  520                 client_read(client);
  521                 client->newstate = NS_CLIENTSTATE_MAX;
  522                 return (true); /* We're done. */
  523             } else if (client->mortal) {
  524                 client->newstate = NS_CLIENTSTATE_INACTIVE;
  525             } else
  526                 return (false);
  527         }
  528     }
  529 
  530     if (client->state == NS_CLIENTSTATE_READING) {
  531         /*
  532          * We are trying to abort the current TCP connection,
  533          * if any.
  534          */
  535         INSIST(client->recursionquota == NULL);
  536         INSIST(client->newstate <= NS_CLIENTSTATE_READY);
  537 
  538         if (client->nreads > 0) {
  539             dns_tcpmsg_cancelread(&client->tcpmsg);
  540             /* Still waiting for read cancel completion? */
  541             if (client->nreads > 0) {
  542                 return (true);
  543             }
  544         }
  545 
  546         if (client->tcpmsg_valid) {
  547             dns_tcpmsg_invalidate(&client->tcpmsg);
  548             client->tcpmsg_valid = false;
  549         }
  550 
  551         /*
  552          * Soon the client will be ready to accept a new TCP
  553          * connection or UDP request, but we may have enough
  554          * clients doing that already.  Check whether this client
  555          * needs to remain active and allow it go inactive if
  556          * not.
  557          *
  558          * UDP clients always go inactive at this point, but a TCP
  559          * client may need to stay active and return to READY
  560          * state if no other clients are available to listen
  561          * for TCP requests on this interface.
  562          *
  563          * Regardless, if we're going to FREED state, that means
  564          * the system is shutting down and we don't need to
  565          * retain clients.
  566          */
  567         if (client->mortal && TCP_CLIENT(client) &&
  568             client->newstate != NS_CLIENTSTATE_FREED &&
  569             !ns_g_clienttest &&
  570             isc_refcount_current(&client->interface->ntcpaccepting) == 0)
  571         {
  572             /* Nobody else is accepting */
  573             client->mortal = false;
  574             client->newstate = NS_CLIENTSTATE_READY;
  575         }
  576 
  577         /*
  578          * Detach from TCP connection and TCP client quota,
  579          * if appropriate. If this is the last reference to
  580          * the TCP connection in our pipeline group, the
  581          * TCP quota slot will be released.
  582          */
  583         if (client->tcpconn) {
  584             tcpconn_detach(client);
  585         }
  586 
  587         if (client->tcpsocket != NULL) {
  588             CTRACE("closetcp");
  589             isc_socket_detach(&client->tcpsocket);
  590             mark_tcp_active(client, false);
  591         }
  592 
  593         if (client->timerset) {
  594             (void)isc_timer_reset(client->timer,
  595                           isc_timertype_inactive,
  596                           NULL, NULL, true);
  597             client->timerset = false;
  598         }
  599 
  600         client->peeraddr_valid = false;
  601 
  602         client->state = NS_CLIENTSTATE_READY;
  603 
  604         /*
  605          * We don't need the client; send it to the inactive
  606          * queue for recycling.
  607          */
  608         if (client->mortal) {
  609             if (client->newstate > NS_CLIENTSTATE_INACTIVE) {
  610                 client->newstate = NS_CLIENTSTATE_INACTIVE;
  611             }
  612         }
  613 
  614         if (NS_CLIENTSTATE_READY == client->newstate) {
  615             if (TCP_CLIENT(client)) {
  616                 client_accept(client);
  617             } else {
  618                 client_udprecv(client);
  619             }
  620             client->newstate = NS_CLIENTSTATE_MAX;
  621             return (true);
  622         }
  623     }
  624 
  625     if (client->state == NS_CLIENTSTATE_READY) {
  626         INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE);
  627 
  628         /*
  629          * We are trying to enter the inactive state.
  630          */
  631         if (client->naccepts > 0) {
  632             isc_socket_cancel(client->tcplistener, client->task,
  633                       ISC_SOCKCANCEL_ACCEPT);
  634             /* Still waiting for accept cancel completion? */
  635             if (client->naccepts > 0) {
  636                 return (true);
  637             }
  638         }
  639 
  640         /* Accept cancel is complete. */
  641         if (client->nrecvs > 0) {
  642             isc_socket_cancel(client->udpsocket, client->task,
  643                       ISC_SOCKCANCEL_RECV);
  644             /* Still waiting for recv cancel completion? */
  645             if (client->nrecvs > 0) {
  646                 return (true);
  647             }
  648         }
  649 
  650         /* Still waiting for control event to be delivered */
  651         if (client->nctls > 0) {
  652             return (true);
  653         }
  654 
  655         INSIST(client->naccepts == 0);
  656         INSIST(client->recursionquota == NULL);
  657         if (client->tcplistener != NULL) {
  658             isc_socket_detach(&client->tcplistener);
  659             mark_tcp_active(client, false);
  660         }
  661         if (client->udpsocket != NULL) {
  662             isc_socket_detach(&client->udpsocket);
  663         }
  664 
  665         /* Deactivate the client. */
  666         if (client->interface != NULL) {
  667             ns_interface_detach(&client->interface);
  668         }
  669 
  670         if (client->dispatch != NULL) {
  671             dns_dispatch_detach(&client->dispatch);
  672         }
  673 
  674         client->attributes = 0;
  675         client->mortal = false;
  676 
  677         if (client->keytag != NULL) {
  678             isc_mem_put(client->mctx, client->keytag,
  679                     client->keytag_len);
  680             client->keytag_len = 0;
  681         }
  682 
  683         /*
  684          * Put the client on the inactive list.  If we are aiming for
  685          * the "freed" state, it will be removed from the inactive
  686          * list shortly, and we need to keep the manager locked until
  687          * that has been done, lest the manager decide to reactivate
  688          * the dying client in between.
  689          */
  690         client->state = NS_CLIENTSTATE_INACTIVE;
  691         INSIST(client->recursionquota == NULL);
  692 
  693         if (client->state == client->newstate) {
  694             client->newstate = NS_CLIENTSTATE_MAX;
  695             if (!ns_g_clienttest && manager != NULL &&
  696                 !manager->exiting)
  697             {
  698                 ISC_QUEUE_PUSH(manager->inactive, client,
  699                            ilink);
  700             }
  701             if (client->needshutdown) {
  702                 isc_task_shutdown(client->task);
  703             }
  704             return (true);
  705         }
  706     }
  707 
  708     if (client->state == NS_CLIENTSTATE_INACTIVE) {
  709         INSIST(client->newstate == NS_CLIENTSTATE_FREED);
  710         /*
  711          * We are trying to free the client.
  712          *
  713          * When "shuttingdown" is true, either the task has received
  714          * its shutdown event or no shutdown event has ever been
  715          * set up.  Thus, we have no outstanding shutdown
  716          * event at this point.
  717          */
  718         REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE);
  719 
  720         INSIST(client->recursionquota == NULL);
  721         INSIST(!ISC_QLINK_LINKED(client, ilink));
  722 
  723         if (manager != NULL) {
  724             LOCK(&manager->listlock);
  725             ISC_LIST_UNLINK(manager->clients, client, link);
  726             LOCK(&manager->lock);
  727             if (manager->exiting &&
  728                 ISC_LIST_EMPTY(manager->clients))
  729                 destroy_manager = true;
  730             UNLOCK(&manager->lock);
  731             UNLOCK(&manager->listlock);
  732         }
  733 
  734         ns_query_free(client);
  735         isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE);
  736         isc_event_free((isc_event_t **)&client->sendevent);
  737         isc_event_free((isc_event_t **)&client->recvevent);
  738         isc_timer_detach(&client->timer);
  739         if (client->delaytimer != NULL)
  740             isc_timer_detach(&client->delaytimer);
  741 
  742         if (client->tcpbuf != NULL)
  743             isc_mem_put(client->mctx, client->tcpbuf,
  744                     TCP_BUFFER_SIZE);
  745         if (client->opt != NULL) {
  746             INSIST(dns_rdataset_isassociated(client->opt));
  747             dns_rdataset_disassociate(client->opt);
  748             dns_message_puttemprdataset(client->message,
  749                             &client->opt);
  750         }
  751         if (client->keytag != NULL) {
  752             isc_mem_put(client->mctx, client->keytag,
  753                     client->keytag_len);
  754             client->keytag_len = 0;
  755         }
  756 
  757         dns_message_destroy(&client->message);
  758 
  759         /*
  760          * Detaching the task must be done after unlinking from
  761          * the manager's lists because the manager accesses
  762          * client->task.
  763          */
  764         if (client->task != NULL)
  765             isc_task_detach(&client->task);
  766 
  767         CTRACE("free");
  768         client->magic = 0;
  769 
  770         /*
  771          * Check that there are no other external references to
  772          * the memory context.
  773          */
  774         if (ns_g_clienttest && isc_mem_references(client->mctx) != 1) {
  775             isc_mem_stats(client->mctx, stderr);
  776             INSIST(0);
  777             ISC_UNREACHABLE();
  778         }
  779 
  780         /*
  781          * Destroy the fetchlock mutex that was created in
  782          * ns_query_init().
  783          */
  784         DESTROYLOCK(&client->query.fetchlock);
  785 
  786         isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
  787     }
  788 
  789     if (destroy_manager && manager != NULL)
  790         clientmgr_destroy(manager);
  791 
  792     return (true);
  793 }
  794 
  795 /*%
  796  * The client's task has received the client's control event
  797  * as part of the startup process.
  798  */
  799 static void
  800 client_start(isc_task_t *task, isc_event_t *event) {
  801     ns_client_t *client = (ns_client_t *) event->ev_arg;
  802 
  803     INSIST(task == client->task);
  804 
  805     UNUSED(task);
  806 
  807     INSIST(client->nctls == 1);
  808     client->nctls--;
  809 
  810     if (exit_check(client))
  811         return;
  812 
  813     if (TCP_CLIENT(client)) {
  814         if (client->tcpconn != NULL) {
  815             client_read(client);
  816         } else {
  817             client_accept(client);
  818         }
  819     } else {
  820         client_udprecv(client);
  821     }
  822 }
  823 
  824 /*%
  825  * The client's task has received a shutdown event.
  826  */
  827 static void
  828 client_shutdown(isc_task_t *task, isc_event_t *event) {
  829     ns_client_t *client;
  830 
  831     REQUIRE(event != NULL);
  832     REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN);
  833     client = event->ev_arg;
  834     REQUIRE(NS_CLIENT_VALID(client));
  835     REQUIRE(task == client->task);
  836 
  837     UNUSED(task);
  838 
  839     CTRACE("shutdown");
  840 
  841     isc_event_free(&event);
  842 
  843     if (client->shutdown != NULL) {
  844         (client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN);
  845         client->shutdown = NULL;
  846         client->shutdown_arg = NULL;
  847     }
  848 
  849     if (ISC_QLINK_LINKED(client, ilink))
  850         ISC_QUEUE_UNLINK(client->manager->inactive, client, ilink);
  851 
  852     client->newstate = NS_CLIENTSTATE_FREED;
  853     client->needshutdown = false;
  854     (void)exit_check(client);
  855 }
  856 
  857 static void
  858 ns_client_endrequest(ns_client_t *client) {
  859     INSIST(client->naccepts == 0);
  860     INSIST(client->nreads == 0);
  861     INSIST(client->nsends == 0);
  862     INSIST(client->nrecvs == 0);
  863     INSIST(client->nupdates == 0);
  864     INSIST(client->state == NS_CLIENTSTATE_WORKING ||
  865            client->state == NS_CLIENTSTATE_RECURSING);
  866 
  867     CTRACE("endrequest");
  868 
  869     if (client->next != NULL) {
  870         (client->next)(client);
  871         client->next = NULL;
  872     }
  873 
  874     if (client->view != NULL) {
  875 #ifdef ENABLE_AFL
  876         if (ns_g_fuzz_type == ns_fuzz_resolver) {
  877             dns_cache_clean(client->view->cache, INT_MAX);
  878             dns_adb_flush(client->view->adb);
  879         }
  880 #endif
  881         dns_view_detach(&client->view);
  882     }
  883     if (client->opt != NULL) {
  884         INSIST(dns_rdataset_isassociated(client->opt));
  885         dns_rdataset_disassociate(client->opt);
  886         dns_message_puttemprdataset(client->message, &client->opt);
  887     }
  888 
  889     client->signer = NULL;
  890     client->udpsize = 512;
  891     client->extflags = 0;
  892     client->ednsversion = -1;
  893     dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
  894 
  895     if (client->recursionquota != NULL) {
  896         isc_quota_detach(&client->recursionquota);
  897         isc_stats_decrement(ns_g_server->nsstats,
  898                     dns_nsstatscounter_recursclients);
  899     }
  900 
  901     /*
  902      * Clear all client attributes that are specific to
  903      * the request; that's all except the TCP flag.
  904      */
  905     client->attributes &= NS_CLIENTATTR_TCP;
  906 #ifdef ENABLE_AFL
  907     if (ns_g_fuzz_type == ns_fuzz_client ||
  908         ns_g_fuzz_type == ns_fuzz_tcpclient ||
  909         ns_g_fuzz_type == ns_fuzz_resolver) {
  910         named_fuzz_notify();
  911     }
  912 #endif /* ENABLE_AFL */
  913 
  914 }
  915 
  916 void
  917 ns_client_next(ns_client_t *client, isc_result_t result) {
  918     int newstate;
  919 
  920     REQUIRE(NS_CLIENT_VALID(client));
  921     REQUIRE(client->state == NS_CLIENTSTATE_WORKING ||
  922         client->state == NS_CLIENTSTATE_RECURSING ||
  923         client->state == NS_CLIENTSTATE_READING);
  924 
  925     CTRACE("next");
  926 
  927     if (result != ISC_R_SUCCESS)
  928         ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
  929                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
  930                   "request failed: %s", isc_result_totext(result));
  931 
  932     /*
  933      * An error processing a TCP request may have left
  934      * the connection out of sync.  To be safe, we always
  935      * sever the connection when result != ISC_R_SUCCESS.
  936      */
  937     if (result == ISC_R_SUCCESS && TCP_CLIENT(client))
  938         newstate = NS_CLIENTSTATE_READING;
  939     else
  940         newstate = NS_CLIENTSTATE_READY;
  941 
  942     if (client->newstate > newstate)
  943         client->newstate = newstate;
  944     (void)exit_check(client);
  945 }
  946 
  947 
  948 static void
  949 client_senddone(isc_task_t *task, isc_event_t *event) {
  950     ns_client_t *client;
  951     isc_socketevent_t *sevent = (isc_socketevent_t *) event;
  952 
  953     REQUIRE(sevent != NULL);
  954     REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE);
  955     client = sevent->ev_arg;
  956     REQUIRE(NS_CLIENT_VALID(client));
  957     REQUIRE(task == client->task);
  958     REQUIRE(sevent == client->sendevent);
  959 
  960     UNUSED(task);
  961 
  962     CTRACE("senddone");
  963 
  964     if (sevent->result != ISC_R_SUCCESS)
  965         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
  966                   NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
  967                   "error sending response: %s",
  968                   isc_result_totext(sevent->result));
  969 
  970     INSIST(client->nsends > 0);
  971     client->nsends--;
  972 
  973     if (client->tcpbuf != NULL) {
  974         INSIST(TCP_CLIENT(client));
  975         isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
  976         client->tcpbuf = NULL;
  977     }
  978 
  979     ns_client_next(client, ISC_R_SUCCESS);
  980 }
  981 
  982 /*%
  983  * We only want to fail with ISC_R_NOSPACE when called from
  984  * ns_client_sendraw() and not when called from ns_client_send(),
  985  * tcpbuffer is NULL when called from ns_client_sendraw() and
  986  * length != 0.  tcpbuffer != NULL when called from ns_client_send()
  987  * and length == 0.
  988  */
  989 
  990 static isc_result_t
  991 client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,
  992             isc_buffer_t *tcpbuffer, uint32_t length,
  993             unsigned char *sendbuf, unsigned char **datap)
  994 {
  995     unsigned char *data;
  996     uint32_t bufsize;
  997     isc_result_t result;
  998 
  999     INSIST(datap != NULL);
 1000     INSIST((tcpbuffer == NULL && length != 0) ||
 1001            (tcpbuffer != NULL && length == 0));
 1002 
 1003     if (TCP_CLIENT(client)) {
 1004         INSIST(client->tcpbuf == NULL);
 1005         if (length + 2 > TCP_BUFFER_SIZE) {
 1006             result = ISC_R_NOSPACE;
 1007             goto done;
 1008         }
 1009         client->tcpbuf = isc_mem_get(client->mctx, TCP_BUFFER_SIZE);
 1010         if (client->tcpbuf == NULL) {
 1011             result = ISC_R_NOMEMORY;
 1012             goto done;
 1013         }
 1014         data = client->tcpbuf;
 1015         if (tcpbuffer != NULL) {
 1016             isc_buffer_init(tcpbuffer, data, TCP_BUFFER_SIZE);
 1017             isc_buffer_init(buffer, data + 2, TCP_BUFFER_SIZE - 2);
 1018         } else {
 1019             isc_buffer_init(buffer, data, TCP_BUFFER_SIZE);
 1020             INSIST(length <= 0xffff);
 1021             isc_buffer_putuint16(buffer, (uint16_t)length);
 1022         }
 1023     } else {
 1024         data = sendbuf;
 1025         if ((client->attributes & NS_CLIENTATTR_HAVECOOKIE) == 0) {
 1026             if (client->view != NULL)
 1027                 bufsize = client->view->nocookieudp;
 1028             else
 1029                 bufsize = 512;
 1030         } else
 1031             bufsize = client->udpsize;
 1032         if (bufsize > client->udpsize)
 1033             bufsize = client->udpsize;
 1034         if (bufsize > SEND_BUFFER_SIZE)
 1035             bufsize = SEND_BUFFER_SIZE;
 1036         if (length > bufsize) {
 1037             result = ISC_R_NOSPACE;
 1038             goto done;
 1039         }
 1040         isc_buffer_init(buffer, data, bufsize);
 1041     }
 1042     *datap = data;
 1043     result = ISC_R_SUCCESS;
 1044 
 1045  done:
 1046     return (result);
 1047 }
 1048 
 1049 static isc_result_t
 1050 client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
 1051     struct in6_pktinfo *pktinfo;
 1052     isc_result_t result;
 1053     isc_region_t r;
 1054     isc_sockaddr_t *address;
 1055     isc_socket_t *sock;
 1056     isc_netaddr_t netaddr;
 1057     int match;
 1058     unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE;
 1059 
 1060     if (TCP_CLIENT(client)) {
 1061         sock = client->tcpsocket;
 1062         address = NULL;
 1063     } else {
 1064         sock = client->udpsocket;
 1065         address = &client->peeraddr;
 1066 
 1067         isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
 1068         if (ns_g_server->blackholeacl != NULL &&
 1069             dns_acl_match(&netaddr, NULL,
 1070                   ns_g_server->blackholeacl,
 1071                   &ns_g_server->aclenv,
 1072                   &match, NULL) == ISC_R_SUCCESS &&
 1073             match > 0)
 1074             return (DNS_R_BLACKHOLED);
 1075         sockflags |= ISC_SOCKFLAG_NORETRY;
 1076     }
 1077 
 1078     if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0 &&
 1079         (client->attributes & NS_CLIENTATTR_MULTICAST) == 0)
 1080         pktinfo = &client->pktinfo;
 1081     else
 1082         pktinfo = NULL;
 1083 
 1084     if (client->dispatch != NULL) {
 1085         isc_dscp_t dscp = dns_dispatch_getdscp(client->dispatch);
 1086         if (dscp != -1) {
 1087             client->dscp = dscp;
 1088         }
 1089     }
 1090 
 1091     if (client->dscp == -1) {
 1092         client->sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP;
 1093         client->sendevent->dscp = 0;
 1094     } else {
 1095         client->sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP;
 1096         client->sendevent->dscp = client->dscp;
 1097     }
 1098 
 1099     isc_buffer_usedregion(buffer, &r);
 1100 
 1101     /*
 1102      * If this is a UDP client and the IPv6 packet can't be
 1103      * encapsulated without generating a PTB on a 1500 octet
 1104      * MTU link force fragmentation at 1280 if it is a IPv6
 1105      * response.
 1106      */
 1107     client->sendevent->attributes &= ~ISC_SOCKEVENTATTR_USEMINMTU;
 1108     if (!TCP_CLIENT(client) && r.length > 1432)
 1109         client->sendevent->attributes |= ISC_SOCKEVENTATTR_USEMINMTU;
 1110 
 1111     CTRACE("sendto");
 1112 
 1113     result = isc_socket_sendto2(sock, &r, client->task,
 1114                     address, pktinfo,
 1115                     client->sendevent, sockflags);
 1116     if (result == ISC_R_SUCCESS || result == ISC_R_INPROGRESS) {
 1117         client->nsends++;
 1118         if (result == ISC_R_SUCCESS)
 1119             client_senddone(client->task,
 1120                     (isc_event_t *)client->sendevent);
 1121         result = ISC_R_SUCCESS;
 1122     }
 1123     return (result);
 1124 }
 1125 
 1126 void
 1127 ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
 1128     isc_result_t result;
 1129     unsigned char *data;
 1130     isc_buffer_t buffer;
 1131     isc_region_t r;
 1132     isc_region_t *mr;
 1133     unsigned char sendbuf[SEND_BUFFER_SIZE];
 1134 
 1135     REQUIRE(NS_CLIENT_VALID(client));
 1136 
 1137     CTRACE("sendraw");
 1138 
 1139     mr = dns_message_getrawmessage(message);
 1140     if (mr == NULL) {
 1141         result = ISC_R_UNEXPECTEDEND;
 1142         goto done;
 1143     }
 1144 
 1145     result = client_allocsendbuf(client, &buffer, NULL, mr->length,
 1146                      sendbuf, &data);
 1147     if (result != ISC_R_SUCCESS)
 1148         goto done;
 1149 
 1150     /*
 1151      * Copy message to buffer and fixup id.
 1152      */
 1153     isc_buffer_availableregion(&buffer, &r);
 1154     result = isc_buffer_copyregion(&buffer, mr);
 1155     if (result != ISC_R_SUCCESS)
 1156         goto done;
 1157     r.base[0] = (client->message->id >> 8) & 0xff;
 1158     r.base[1] = client->message->id & 0xff;
 1159 
 1160     result = client_sendpkg(client, &buffer);
 1161     if (result == ISC_R_SUCCESS)
 1162         return;
 1163 
 1164  done:
 1165     if (client->tcpbuf != NULL) {
 1166         isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
 1167         client->tcpbuf = NULL;
 1168     }
 1169     ns_client_next(client, result);
 1170 }
 1171 
 1172 static void
 1173 client_send(ns_client_t *client) {
 1174     isc_result_t result;
 1175     unsigned char *data;
 1176     isc_buffer_t buffer;
 1177     isc_buffer_t tcpbuffer;
 1178     isc_region_t r;
 1179     dns_compress_t cctx;
 1180     bool cleanup_cctx = false;
 1181     unsigned char sendbuf[SEND_BUFFER_SIZE];
 1182     unsigned int render_opts;
 1183     unsigned int preferred_glue;
 1184     bool opt_included = false;
 1185     size_t respsize;
 1186 #ifdef HAVE_DNSTAP
 1187     unsigned char zone[DNS_NAME_MAXWIRE];
 1188     dns_dtmsgtype_t dtmsgtype;
 1189     isc_region_t zr;
 1190 #endif /* HAVE_DNSTAP */
 1191 
 1192     REQUIRE(NS_CLIENT_VALID(client));
 1193 
 1194     CTRACE("send");
 1195 
 1196     if (client->message->opcode == dns_opcode_query &&
 1197         (client->attributes & NS_CLIENTATTR_RA) != 0)
 1198         client->message->flags |= DNS_MESSAGEFLAG_RA;
 1199 
 1200     if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0)
 1201         render_opts = 0;
 1202     else
 1203         render_opts = DNS_MESSAGERENDER_OMITDNSSEC;
 1204 
 1205     preferred_glue = 0;
 1206     if (client->view != NULL) {
 1207         if (client->view->preferred_glue == dns_rdatatype_a)
 1208             preferred_glue = DNS_MESSAGERENDER_PREFER_A;
 1209         else if (client->view->preferred_glue == dns_rdatatype_aaaa)
 1210             preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA;
 1211     }
 1212     if (preferred_glue == 0) {
 1213         if (isc_sockaddr_pf(&client->peeraddr) == AF_INET)
 1214             preferred_glue = DNS_MESSAGERENDER_PREFER_A;
 1215         else
 1216             preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA;
 1217     }
 1218 
 1219 #ifdef ALLOW_FILTER_AAAA
 1220     /*
 1221      * filter-aaaa-on-v4 yes or break-dnssec option to suppress
 1222      * AAAA records.
 1223      *
 1224      * We already know that request came via IPv4,
 1225      * that we have both AAAA and A records,
 1226      * and that we either have no signatures that the client wants
 1227      * or we are supposed to break DNSSEC.
 1228      *
 1229      * Override preferred glue if necessary.
 1230      */
 1231     if ((client->attributes & NS_CLIENTATTR_FILTER_AAAA) != 0) {
 1232         render_opts |= DNS_MESSAGERENDER_FILTER_AAAA;
 1233         if (preferred_glue == DNS_MESSAGERENDER_PREFER_AAAA)
 1234             preferred_glue = DNS_MESSAGERENDER_PREFER_A;
 1235     }
 1236 #endif
 1237 
 1238     /*
 1239      * Create an OPT for our reply.
 1240      */
 1241     if ((client->attributes & NS_CLIENTATTR_WANTOPT) != 0) {
 1242         result = ns_client_addopt(client, client->message,
 1243                       &client->opt);
 1244         if (result != ISC_R_SUCCESS)
 1245             goto done;
 1246     }
 1247 
 1248     /*
 1249      * XXXRTH  The following doesn't deal with TCP buffer resizing.
 1250      */
 1251     result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0,
 1252                      sendbuf, &data);
 1253     if (result != ISC_R_SUCCESS)
 1254         goto done;
 1255 
 1256     result = dns_compress_init(&cctx, -1, client->mctx);
 1257     if (result != ISC_R_SUCCESS)
 1258         goto done;
 1259     if (client->peeraddr_valid && client->view != NULL) {
 1260         isc_netaddr_t netaddr;
 1261         dns_name_t *name = NULL;
 1262 
 1263         isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
 1264         if (client->message->tsigkey != NULL)
 1265             name = &client->message->tsigkey->name;
 1266 
 1267         if (client->view->nocasecompress == NULL ||
 1268             !allowed(&netaddr, name, NULL, 0, NULL,
 1269                  client->view->nocasecompress))
 1270         {
 1271             dns_compress_setsensitive(&cctx, true);
 1272         }
 1273 
 1274         if (client->view->msgcompression == false) {
 1275             dns_compress_disable(&cctx);
 1276         }
 1277     }
 1278     cleanup_cctx = true;
 1279 
 1280     result = dns_message_renderbegin(client->message, &cctx, &buffer);
 1281     if (result != ISC_R_SUCCESS)
 1282         goto done;
 1283 
 1284     if (client->opt != NULL) {
 1285         result = dns_message_setopt(client->message, client->opt);
 1286         opt_included = true;
 1287         client->opt = NULL;
 1288         if (result != ISC_R_SUCCESS)
 1289             goto done;
 1290     }
 1291     result = dns_message_rendersection(client->message,
 1292                        DNS_SECTION_QUESTION, 0);
 1293     if (result == ISC_R_NOSPACE) {
 1294         client->message->flags |= DNS_MESSAGEFLAG_TC;
 1295         goto renderend;
 1296     }
 1297     if (result != ISC_R_SUCCESS)
 1298         goto done;
 1299     /*
 1300      * Stop after the question if TC was set for rate limiting.
 1301      */
 1302     if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0)
 1303         goto renderend;
 1304     result = dns_message_rendersection(client->message,
 1305                        DNS_SECTION_ANSWER,
 1306                        DNS_MESSAGERENDER_PARTIAL |
 1307                        render_opts);
 1308     if (result == ISC_R_NOSPACE) {
 1309         client->message->flags |= DNS_MESSAGEFLAG_TC;
 1310         goto renderend;
 1311     }
 1312     if (result != ISC_R_SUCCESS)
 1313         goto done;
 1314     result = dns_message_rendersection(client->message,
 1315                        DNS_SECTION_AUTHORITY,
 1316                        DNS_MESSAGERENDER_PARTIAL |
 1317                        render_opts);
 1318     if (result == ISC_R_NOSPACE) {
 1319         client->message->flags |= DNS_MESSAGEFLAG_TC;
 1320         goto renderend;
 1321     }
 1322     if (result != ISC_R_SUCCESS)
 1323         goto done;
 1324     result = dns_message_rendersection(client->message,
 1325                        DNS_SECTION_ADDITIONAL,
 1326                        preferred_glue | render_opts);
 1327     if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
 1328         goto done;
 1329  renderend:
 1330     result = dns_message_renderend(client->message);
 1331 
 1332     if (result != ISC_R_SUCCESS)
 1333         goto done;
 1334 
 1335 #ifdef HAVE_DNSTAP
 1336     memset(&zr, 0, sizeof(zr));
 1337     if (((client->message->flags & DNS_MESSAGEFLAG_AA) != 0) &&
 1338         (client->query.authzone != NULL))
 1339     {
 1340         isc_buffer_t b;
 1341         dns_name_t *zo =
 1342             dns_zone_getorigin(client->query.authzone);
 1343 
 1344         isc_buffer_init(&b, zone, sizeof(zone));
 1345         dns_compress_setmethods(&cctx, DNS_COMPRESS_NONE);
 1346         result = dns_name_towire(zo, &cctx, &b);
 1347         if (result == ISC_R_SUCCESS)
 1348             isc_buffer_usedregion(&b, &zr);
 1349     }
 1350 
 1351     if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0)
 1352         dtmsgtype = DNS_DTTYPE_CR;
 1353     else
 1354         dtmsgtype = DNS_DTTYPE_AR;
 1355 #endif /* HAVE_DNSTAP */
 1356 
 1357     if (cleanup_cctx) {
 1358         dns_compress_invalidate(&cctx);
 1359         cleanup_cctx = false;
 1360     }
 1361 
 1362     if (TCP_CLIENT(client)) {
 1363         isc_buffer_usedregion(&buffer, &r);
 1364         isc_buffer_putuint16(&tcpbuffer, (uint16_t) r.length);
 1365         isc_buffer_add(&tcpbuffer, r.length);
 1366 #ifdef HAVE_DNSTAP
 1367         if (client->view != NULL) {
 1368             dns_dt_send(client->view, dtmsgtype,
 1369                     &client->peeraddr, &client->destsockaddr,
 1370                     true, &zr, &client->requesttime, NULL,
 1371                     &buffer);
 1372         }
 1373 #endif /* HAVE_DNSTAP */
 1374 
 1375         /* don't count the 2-octet length header */
 1376         respsize = isc_buffer_usedlength(&tcpbuffer) - 2;
 1377         result = client_sendpkg(client, &tcpbuffer);
 1378 
 1379         switch (isc_sockaddr_pf(&client->peeraddr)) {
 1380         case AF_INET:
 1381             isc_stats_increment(ns_g_server->tcpoutstats4,
 1382                         ISC_MIN((int)respsize / 16, 256));
 1383             break;
 1384         case AF_INET6:
 1385             isc_stats_increment(ns_g_server->tcpoutstats6,
 1386                         ISC_MIN((int)respsize / 16, 256));
 1387             break;
 1388         default:
 1389             INSIST(0);
 1390             ISC_UNREACHABLE();
 1391         }
 1392     } else {
 1393         respsize = isc_buffer_usedlength(&buffer);
 1394         result = client_sendpkg(client, &buffer);
 1395 #ifdef HAVE_DNSTAP
 1396         if (client->view != NULL) {
 1397             dns_dt_send(client->view, dtmsgtype,
 1398                     &client->peeraddr,
 1399                     &client->destsockaddr,
 1400                     false, &zr,
 1401                     &client->requesttime, NULL, &buffer);
 1402         }
 1403 #endif /* HAVE_DNSTAP */
 1404 
 1405         switch (isc_sockaddr_pf(&client->peeraddr)) {
 1406         case AF_INET:
 1407             isc_stats_increment(ns_g_server->udpoutstats4,
 1408                         ISC_MIN((int)respsize / 16, 256));
 1409             break;
 1410         case AF_INET6:
 1411             isc_stats_increment(ns_g_server->udpoutstats6,
 1412                         ISC_MIN((int)respsize / 16, 256));
 1413             break;
 1414         default:
 1415             INSIST(0);
 1416             ISC_UNREACHABLE();
 1417         }
 1418     }
 1419 
 1420     /* update statistics (XXXJT: is it okay to access message->xxxkey?) */
 1421     isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_response);
 1422 
 1423     dns_rcodestats_increment(ns_g_server->rcodestats,
 1424                  client->message->rcode);
 1425     if (opt_included) {
 1426         isc_stats_increment(ns_g_server->nsstats,
 1427                     dns_nsstatscounter_edns0out);
 1428     }
 1429     if (client->message->tsigkey != NULL) {
 1430         isc_stats_increment(ns_g_server->nsstats,
 1431                     dns_nsstatscounter_tsigout);
 1432     }
 1433     if (client->message->sig0key != NULL) {
 1434         isc_stats_increment(ns_g_server->nsstats,
 1435                     dns_nsstatscounter_sig0out);
 1436     }
 1437     if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0)
 1438         isc_stats_increment(ns_g_server->nsstats,
 1439                     dns_nsstatscounter_truncatedresp);
 1440 
 1441     if (result == ISC_R_SUCCESS)
 1442         return;
 1443 
 1444  done:
 1445     if (client->tcpbuf != NULL) {
 1446         isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
 1447         client->tcpbuf = NULL;
 1448     }
 1449 
 1450     if (cleanup_cctx)
 1451         dns_compress_invalidate(&cctx);
 1452 
 1453     ns_client_next(client, result);
 1454 }
 1455 
 1456 /*
 1457  * Completes the sending of a delayed client response.
 1458  */
 1459 static void
 1460 client_delay(isc_task_t *task, isc_event_t *event) {
 1461     ns_client_t *client;
 1462 
 1463     REQUIRE(event != NULL);
 1464     REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE ||
 1465         event->ev_type == ISC_TIMEREVENT_IDLE);
 1466     client = event->ev_arg;
 1467     REQUIRE(NS_CLIENT_VALID(client));
 1468     REQUIRE(task == client->task);
 1469     REQUIRE(client->delaytimer != NULL);
 1470 
 1471     UNUSED(task);
 1472 
 1473     CTRACE("client_delay");
 1474 
 1475     isc_event_free(&event);
 1476     isc_timer_detach(&client->delaytimer);
 1477 
 1478     client_send(client);
 1479     ns_client_detach(&client);
 1480 }
 1481 
 1482 void
 1483 ns_client_send(ns_client_t *client) {
 1484 
 1485     /*
 1486      * Delay the response by ns_g_delay ms.
 1487      */
 1488     if (ns_g_delay != 0) {
 1489         ns_client_t *dummy = NULL;
 1490         isc_result_t result;
 1491         isc_interval_t interval;
 1492 
 1493         /*
 1494          * Replace ourselves if we have not already been replaced.
 1495          */
 1496         if (!client->mortal) {
 1497             result = ns_client_replace(client);
 1498             if (result != ISC_R_SUCCESS)
 1499                 goto nodelay;
 1500         }
 1501 
 1502         ns_client_attach(client, &dummy);
 1503         if (ns_g_delay >= 1000)
 1504             isc_interval_set(&interval, ns_g_delay / 1000,
 1505                      (ns_g_delay % 1000) * 1000000);
 1506         else
 1507             isc_interval_set(&interval, 0, ns_g_delay * 1000000);
 1508         result = isc_timer_create(client->manager->timermgr,
 1509                       isc_timertype_once, NULL, &interval,
 1510                       client->task, client_delay,
 1511                       client, &client->delaytimer);
 1512         if (result == ISC_R_SUCCESS)
 1513             return;
 1514 
 1515         ns_client_detach(&dummy);
 1516     }
 1517 
 1518  nodelay:
 1519     client_send(client);
 1520 }
 1521 
 1522 #if NS_CLIENT_DROPPORT
 1523 #define DROPPORT_NO     0
 1524 #define DROPPORT_REQUEST    1
 1525 #define DROPPORT_RESPONSE   2
 1526 /*%
 1527  * ns_client_dropport determines if certain requests / responses
 1528  * should be dropped based on the port number.
 1529  *
 1530  * Returns:
 1531  * \li  0:  Don't drop.
 1532  * \li  1:  Drop request.
 1533  * \li  2:  Drop (error) response.
 1534  */
 1535 static int
 1536 ns_client_dropport(in_port_t port) {
 1537     switch (port) {
 1538     case 7: /* echo */
 1539     case 13: /* daytime */
 1540     case 19: /* chargen */
 1541     case 37: /* time */
 1542         return (DROPPORT_REQUEST);
 1543     case 464: /* kpasswd */
 1544         return (DROPPORT_RESPONSE);
 1545     }
 1546     return (DROPPORT_NO);
 1547 }
 1548 #endif
 1549 
 1550 void
 1551 ns_client_error(ns_client_t *client, isc_result_t result) {
 1552     dns_rcode_t rcode;
 1553     dns_message_t *message;
 1554 
 1555     REQUIRE(NS_CLIENT_VALID(client));
 1556 
 1557     CTRACE("error");
 1558 
 1559     message = client->message;
 1560     rcode = dns_result_torcode(result);
 1561 
 1562 #if NS_CLIENT_DROPPORT
 1563     /*
 1564      * Don't send FORMERR to ports on the drop port list.
 1565      */
 1566     if (rcode == dns_rcode_formerr &&
 1567         ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) !=
 1568         DROPPORT_NO) {
 1569         char buf[64];
 1570         isc_buffer_t b;
 1571 
 1572         isc_buffer_init(&b, buf, sizeof(buf) - 1);
 1573         if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS)
 1574             isc_buffer_putstr(&b, "UNKNOWN RCODE");
 1575         ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 1576                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
 1577                   "dropped error (%.*s) response: suspicious port",
 1578                   (int)isc_buffer_usedlength(&b), buf);
 1579         ns_client_next(client, ISC_R_SUCCESS);
 1580         return;
 1581     }
 1582 #endif
 1583 
 1584     /*
 1585      * Try to rate limit error responses.
 1586      */
 1587     if (client->view != NULL && client->view->rrl != NULL) {
 1588         bool wouldlog;
 1589         char log_buf[DNS_RRL_LOG_BUF_LEN];
 1590         dns_rrl_result_t rrl_result;
 1591         int loglevel;
 1592 
 1593         INSIST(rcode != dns_rcode_noerror &&
 1594                rcode != dns_rcode_nxdomain);
 1595         if (ns_g_server->log_queries)
 1596             loglevel = DNS_RRL_LOG_DROP;
 1597         else
 1598             loglevel = ISC_LOG_DEBUG(1);
 1599         wouldlog = isc_log_wouldlog(ns_g_lctx, loglevel);
 1600         rrl_result = dns_rrl(client->view, &client->peeraddr,
 1601                      TCP_CLIENT(client),
 1602                      dns_rdataclass_in, dns_rdatatype_none,
 1603                      NULL, result, client->now,
 1604                      wouldlog, log_buf, sizeof(log_buf));
 1605         if (rrl_result != DNS_RRL_RESULT_OK) {
 1606             /*
 1607              * Log dropped errors in the query category
 1608              * so that they are not lost in silence.
 1609              * Starts of rate-limited bursts are logged in
 1610              * NS_LOGCATEGORY_RRL.
 1611              */
 1612             if (wouldlog) {
 1613                 ns_client_log(client,
 1614                           NS_LOGCATEGORY_QUERY_ERRORS,
 1615                           NS_LOGMODULE_CLIENT,
 1616                           loglevel,
 1617                           "%s", log_buf);
 1618             }
 1619             /*
 1620              * Some error responses cannot be 'slipped',
 1621              * so don't try to slip any error responses.
 1622              */
 1623             if (!client->view->rrl->log_only) {
 1624                 isc_stats_increment(ns_g_server->nsstats,
 1625                         dns_nsstatscounter_ratedropped);
 1626                 isc_stats_increment(ns_g_server->nsstats,
 1627                         dns_nsstatscounter_dropped);
 1628                 ns_client_next(client, DNS_R_DROP);
 1629                 return;
 1630             }
 1631         }
 1632     }
 1633 
 1634     /*
 1635      * Message may be an in-progress reply that we had trouble
 1636      * with, in which case QR will be set.  We need to clear QR before
 1637      * calling dns_message_reply() to avoid triggering an assertion.
 1638      */
 1639     message->flags &= ~DNS_MESSAGEFLAG_QR;
 1640     /*
 1641      * AA and AD shouldn't be set.
 1642      */
 1643     message->flags &= ~(DNS_MESSAGEFLAG_AA | DNS_MESSAGEFLAG_AD);
 1644     result = dns_message_reply(message, true);
 1645     if (result != ISC_R_SUCCESS) {
 1646         /*
 1647          * It could be that we've got a query with a good header,
 1648          * but a bad question section, so we try again with
 1649          * want_question_section set to false.
 1650          */
 1651         result = dns_message_reply(message, false);
 1652         if (result != ISC_R_SUCCESS) {
 1653             ns_client_next(client, result);
 1654             return;
 1655         }
 1656     }
 1657     message->rcode = rcode;
 1658 
 1659     if (rcode == dns_rcode_formerr) {
 1660         /*
 1661          * FORMERR loop avoidance:  If we sent a FORMERR message
 1662          * with the same ID to the same client less than two
 1663          * seconds ago, assume that we are in an infinite error
 1664          * packet dialog with a server for some protocol whose
 1665          * error responses look enough like DNS queries to
 1666          * elicit a FORMERR response.  Drop a packet to break
 1667          * the loop.
 1668          */
 1669         if (isc_sockaddr_equal(&client->peeraddr,
 1670                        &client->formerrcache.addr) &&
 1671             message->id == client->formerrcache.id &&
 1672             (isc_time_seconds(&client->requesttime) -
 1673              client->formerrcache.time) < 2)
 1674         {
 1675             /* Drop packet. */
 1676             ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 1677                       NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
 1678                       "possible error packet loop, "
 1679                       "FORMERR dropped");
 1680             ns_client_next(client, result);
 1681             return;
 1682         }
 1683         client->formerrcache.addr = client->peeraddr;
 1684         client->formerrcache.time =
 1685             isc_time_seconds(&client->requesttime);
 1686         client->formerrcache.id = message->id;
 1687     } else if (rcode == dns_rcode_servfail && client->query.qname != NULL &&
 1688            client->view != NULL && client->view->fail_ttl != 0 &&
 1689            ((client->attributes & NS_CLIENTATTR_NOSETFC) == 0))
 1690     {
 1691         /*
 1692          * SERVFAIL caching: store qname/qtype of failed queries
 1693          */
 1694         isc_time_t expire;
 1695         isc_interval_t i;
 1696         uint32_t flags = 0;
 1697 
 1698         if ((message->flags & DNS_MESSAGEFLAG_CD) != 0)
 1699             flags = NS_FAILCACHE_CD;
 1700 
 1701         isc_interval_set(&i, client->view->fail_ttl, 0);
 1702         result = isc_time_nowplusinterval(&expire, &i);
 1703         if (result == ISC_R_SUCCESS)
 1704             dns_badcache_add(client->view->failcache,
 1705                      client->query.qname,
 1706                      client->query.qtype,
 1707                      true, flags, &expire);
 1708     }
 1709     ns_client_send(client);
 1710 }
 1711 
 1712 isc_result_t
 1713 ns_client_addopt(ns_client_t *client, dns_message_t *message,
 1714          dns_rdataset_t **opt)
 1715 {
 1716     unsigned char ecs[ECS_SIZE];
 1717     char nsid[BUFSIZ], *nsidp;
 1718     unsigned char cookie[COOKIE_SIZE];
 1719     isc_result_t result;
 1720     dns_view_t *view;
 1721     dns_resolver_t *resolver;
 1722     uint16_t udpsize;
 1723     dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
 1724     int count = 0;
 1725     unsigned int flags;
 1726     unsigned char expire[4];
 1727 
 1728     REQUIRE(NS_CLIENT_VALID(client));
 1729     REQUIRE(opt != NULL && *opt == NULL);
 1730     REQUIRE(message != NULL);
 1731 
 1732     view = client->view;
 1733     resolver = (view != NULL) ? view->resolver : NULL;
 1734     if (resolver != NULL)
 1735         udpsize = dns_resolver_getudpsize(resolver);
 1736     else
 1737         udpsize = ns_g_udpsize;
 1738 
 1739     flags = client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE;
 1740 
 1741     /* Set EDNS options if applicable */
 1742     if (WANTNSID(client) &&
 1743         (ns_g_server->server_id != NULL ||
 1744          ns_g_server->server_usehostname)) {
 1745         if (ns_g_server->server_usehostname) {
 1746             result = ns_os_gethostname(nsid, sizeof(nsid));
 1747             if (result != ISC_R_SUCCESS) {
 1748                 goto no_nsid;
 1749             }
 1750             nsidp = nsid;
 1751         } else
 1752             nsidp = ns_g_server->server_id;
 1753 
 1754         INSIST(count < DNS_EDNSOPTIONS);
 1755         ednsopts[count].code = DNS_OPT_NSID;
 1756         ednsopts[count].length = (uint16_t)strlen(nsidp);
 1757         ednsopts[count].value = (unsigned char *)nsidp;
 1758         count++;
 1759     }
 1760  no_nsid:
 1761     if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0) {
 1762         isc_buffer_t buf;
 1763         isc_stdtime_t now;
 1764         uint32_t nonce;
 1765 
 1766         isc_buffer_init(&buf, cookie, sizeof(cookie));
 1767         isc_stdtime_get(&now);
 1768         isc_random_get(&nonce);
 1769 
 1770         compute_cookie(client, now, nonce, ns_g_server->secret, &buf);
 1771 
 1772         INSIST(count < DNS_EDNSOPTIONS);
 1773         ednsopts[count].code = DNS_OPT_COOKIE;
 1774         ednsopts[count].length = COOKIE_SIZE;
 1775         ednsopts[count].value = cookie;
 1776         count++;
 1777     }
 1778     if ((client->attributes & NS_CLIENTATTR_HAVEEXPIRE) != 0) {
 1779         isc_buffer_t buf;
 1780 
 1781         INSIST(count < DNS_EDNSOPTIONS);
 1782 
 1783         isc_buffer_init(&buf, expire, sizeof(expire));
 1784         isc_buffer_putuint32(&buf, client->expire);
 1785         ednsopts[count].code = DNS_OPT_EXPIRE;
 1786         ednsopts[count].length = 4;
 1787         ednsopts[count].value = expire;
 1788         count++;
 1789     }
 1790     if (((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) &&
 1791         (client->ecs_addr.family == AF_INET ||
 1792          client->ecs_addr.family == AF_INET6 ||
 1793          client->ecs_addr.family == AF_UNSPEC))
 1794     {
 1795         isc_buffer_t buf;
 1796         uint8_t addr[16];
 1797         uint32_t plen, addrl;
 1798         uint16_t family = 0;
 1799 
 1800         /* Add CLIENT-SUBNET option. */
 1801 
 1802         plen = client->ecs_addrlen;
 1803 
 1804         /* Round up prefix len to a multiple of 8 */
 1805         addrl = (plen + 7) / 8;
 1806 
 1807         switch (client->ecs_addr.family) {
 1808         case AF_UNSPEC:
 1809             INSIST(plen == 0);
 1810             family = 0;
 1811             break;
 1812         case AF_INET:
 1813             INSIST(plen <= 32);
 1814             family = 1;
 1815             memmove(addr, &client->ecs_addr.type, addrl);
 1816             break;
 1817         case AF_INET6:
 1818             INSIST(plen <= 128);
 1819             family = 2;
 1820             memmove(addr, &client->ecs_addr.type, addrl);
 1821             break;
 1822         default:
 1823             INSIST(0);
 1824             ISC_UNREACHABLE();
 1825         }
 1826 
 1827         isc_buffer_init(&buf, ecs, sizeof(ecs));
 1828         /* family */
 1829         isc_buffer_putuint16(&buf, family);
 1830         /* source prefix-length */
 1831         isc_buffer_putuint8(&buf, client->ecs_addrlen);
 1832         /* scope prefix-length */
 1833         isc_buffer_putuint8(&buf, client->ecs_scope);
 1834 
 1835         /* address */
 1836         if (addrl > 0) {
 1837             /* Mask off last address byte */
 1838             if ((plen % 8) != 0)
 1839                 addr[addrl - 1] &=
 1840                     ~0U << (8 - (plen % 8));
 1841             isc_buffer_putmem(&buf, addr,
 1842                       (unsigned) addrl);
 1843         }
 1844 
 1845         ednsopts[count].code = DNS_OPT_CLIENT_SUBNET;
 1846         ednsopts[count].length = addrl + 4;
 1847         ednsopts[count].value = ecs;
 1848         count++;
 1849     }
 1850 
 1851     result = dns_message_buildopt(message, opt, 0, udpsize, flags,
 1852                       ednsopts, count);
 1853     return (result);
 1854 }
 1855 
 1856 static inline bool
 1857 allowed(isc_netaddr_t *addr, const dns_name_t *signer,
 1858     isc_netaddr_t *ecs_addr, uint8_t ecs_addrlen,
 1859     uint8_t *ecs_scope, dns_acl_t *acl)
 1860 {
 1861     int match;
 1862     isc_result_t result;
 1863 
 1864     if (acl == NULL)
 1865         return (true);
 1866     result = dns_acl_match2(addr, signer, ecs_addr, ecs_addrlen, ecs_scope,
 1867                 acl, &ns_g_server->aclenv, &match, NULL);
 1868     if (result == ISC_R_SUCCESS && match > 0)
 1869         return (true);
 1870     return (false);
 1871 }
 1872 
 1873 /*
 1874  * Callback to see if a non-recursive query coming from 'srcaddr' to
 1875  * 'destaddr', with optional key 'mykey' for class 'rdclass' would be
 1876  * delivered to 'myview'.
 1877  *
 1878  * We run this unlocked as both the view list and the interface list
 1879  * are updated when the appropriate task has exclusivity.
 1880  */
 1881 bool
 1882 ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
 1883          isc_sockaddr_t *srcaddr, isc_sockaddr_t *dstaddr,
 1884          dns_rdataclass_t rdclass, void *arg)
 1885 {
 1886     dns_view_t *view;
 1887     dns_tsigkey_t *key = NULL;
 1888     isc_netaddr_t netsrc;
 1889     isc_netaddr_t netdst;
 1890 
 1891     UNUSED(arg);
 1892 
 1893     /*
 1894      * ns_g_server->interfacemgr is task exclusive locked.
 1895      */
 1896     if (ns_g_server->interfacemgr == NULL)
 1897         return (true);
 1898 
 1899     if (!ns_interfacemgr_listeningon(ns_g_server->interfacemgr, dstaddr))
 1900         return (false);
 1901 
 1902     isc_netaddr_fromsockaddr(&netsrc, srcaddr);
 1903     isc_netaddr_fromsockaddr(&netdst, dstaddr);
 1904 
 1905     for (view = ISC_LIST_HEAD(ns_g_server->viewlist);
 1906          view != NULL;
 1907          view = ISC_LIST_NEXT(view, link))
 1908     {
 1909         const dns_name_t *tsig = NULL;
 1910 
 1911         if (view->matchrecursiveonly)
 1912             continue;
 1913 
 1914         if (rdclass != view->rdclass)
 1915             continue;
 1916 
 1917         if (mykey != NULL) {
 1918             bool match;
 1919             isc_result_t result;
 1920 
 1921             result = dns_view_gettsig(view, &mykey->name, &key);
 1922             if (result != ISC_R_SUCCESS)
 1923                 continue;
 1924             match = dst_key_compare(mykey->key, key->key);
 1925             dns_tsigkey_detach(&key);
 1926             if (!match)
 1927                 continue;
 1928             tsig = dns_tsigkey_identity(mykey);
 1929         }
 1930 
 1931         if (allowed(&netsrc, tsig, NULL, 0, NULL,
 1932                 view->matchclients) &&
 1933             allowed(&netdst, tsig, NULL, 0, NULL,
 1934                 view->matchdestinations))
 1935             break;
 1936     }
 1937     return (view == myview);
 1938 }
 1939 
 1940 static void
 1941 compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce,
 1942            const unsigned char *secret, isc_buffer_t *buf)
 1943 {
 1944     switch (ns_g_server->cookiealg) {
 1945     case ns_cookiealg_siphash24: {
 1946         unsigned char digest[ISC_SIPHASH24_TAG_LENGTH] = { 0 };
 1947         unsigned char input[16 + 16] = { 0 };
 1948         size_t inputlen = 0;
 1949         isc_netaddr_t netaddr;
 1950         unsigned char *cp;
 1951 
 1952         cp = isc_buffer_used(buf);
 1953         isc_buffer_putmem(buf, client->cookie, 8);
 1954         isc_buffer_putuint8(buf, NS_COOKIE_VERSION_1);
 1955         isc_buffer_putuint24(buf, 0); /* Reserved */
 1956         isc_buffer_putuint32(buf, when);
 1957 
 1958         memmove(input, cp, 16);
 1959 
 1960         isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
 1961         switch (netaddr.family) {
 1962         case AF_INET:
 1963             cp = (unsigned char *)&netaddr.type.in;
 1964             memmove(input + 16, cp, 4);
 1965             inputlen = 20;
 1966             break;
 1967         case AF_INET6:
 1968             cp = (unsigned char *)&netaddr.type.in6;
 1969             memmove(input + 16, cp, 16);
 1970             inputlen = 32;
 1971             break;
 1972         default:
 1973             INSIST(0);
 1974             ISC_UNREACHABLE();
 1975         }
 1976 
 1977         isc_siphash24(secret, input, inputlen, digest);
 1978         isc_buffer_putmem(buf, digest, 8);
 1979         break;
 1980     }
 1981 #if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES)
 1982     case ns_cookiealg_aes: {
 1983         unsigned char digest[ISC_AES_BLOCK_LENGTH];
 1984         unsigned char input[4 + 4 + 16];
 1985         isc_netaddr_t netaddr;
 1986         unsigned char *cp;
 1987         unsigned int i;
 1988 
 1989         cp = isc_buffer_used(buf);
 1990         isc_buffer_putmem(buf, client->cookie, 8);
 1991         isc_buffer_putuint32(buf, nonce);
 1992         isc_buffer_putuint32(buf, when);
 1993         memmove(input, cp, 16);
 1994         isc_aes128_crypt(secret, input, digest);
 1995         for (i = 0; i < 8; i++) {
 1996             input[i] = digest[i] ^ digest[i + 8];
 1997         }
 1998         isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
 1999         switch (netaddr.family) {
 2000         case AF_INET:
 2001             cp = (unsigned char *)&netaddr.type.in;
 2002             memmove(input + 8, cp, 4);
 2003             memset(input + 12, 0, 4);
 2004             isc_aes128_crypt(secret, input, digest);
 2005             break;
 2006         case AF_INET6:
 2007             cp = (unsigned char *)&netaddr.type.in6;
 2008             memmove(input + 8, cp, 16);
 2009             isc_aes128_crypt(secret, input, digest);
 2010             for (i = 0; i < 8; i++) {
 2011                 input[i + 8] = digest[i] ^ digest[i + 8];
 2012             }
 2013             isc_aes128_crypt(ns_g_server->secret, input + 8,
 2014                      digest);
 2015             break;
 2016         default:
 2017             INSIST(0);
 2018             ISC_UNREACHABLE();
 2019         }
 2020         for (i = 0; i < 8; i++) {
 2021             digest[i] ^= digest[i + 8];
 2022         }
 2023         isc_buffer_putmem(buf, digest, 8);
 2024         break;
 2025     }
 2026 #endif
 2027 
 2028     case ns_cookiealg_sha1: {
 2029         unsigned char digest[ISC_SHA1_DIGESTLENGTH];
 2030         isc_netaddr_t netaddr;
 2031         unsigned char *cp;
 2032         isc_hmacsha1_t hmacsha1;
 2033         unsigned int length;
 2034 
 2035         cp = isc_buffer_used(buf);
 2036         isc_buffer_putmem(buf, client->cookie, 8);
 2037         isc_buffer_putuint32(buf, nonce);
 2038         isc_buffer_putuint32(buf, when);
 2039 
 2040         isc_hmacsha1_init(&hmacsha1, secret, ISC_SHA1_DIGESTLENGTH);
 2041         isc_hmacsha1_update(&hmacsha1, cp, 16);
 2042         isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
 2043         switch (netaddr.family) {
 2044         case AF_INET:
 2045             cp = (unsigned char *)&netaddr.type.in;
 2046             length = 4;
 2047             break;
 2048         case AF_INET6:
 2049             cp = (unsigned char *)&netaddr.type.in6;
 2050             length = 16;
 2051             break;
 2052         default:
 2053             INSIST(0);
 2054             ISC_UNREACHABLE();
 2055         }
 2056         isc_hmacsha1_update(&hmacsha1, cp, length);
 2057         isc_hmacsha1_sign(&hmacsha1, digest, sizeof(digest));
 2058         isc_buffer_putmem(buf, digest, 8);
 2059         isc_hmacsha1_invalidate(&hmacsha1);
 2060         break;
 2061     }
 2062 
 2063     case ns_cookiealg_sha256: {
 2064         unsigned char digest[ISC_SHA256_DIGESTLENGTH];
 2065         isc_netaddr_t netaddr;
 2066         unsigned char *cp;
 2067         isc_hmacsha256_t hmacsha256;
 2068         unsigned int length;
 2069 
 2070         cp = isc_buffer_used(buf);
 2071         isc_buffer_putmem(buf, client->cookie, 8);
 2072         isc_buffer_putuint32(buf, nonce);
 2073         isc_buffer_putuint32(buf, when);
 2074 
 2075         isc_hmacsha256_init(&hmacsha256, secret,
 2076                     ISC_SHA256_DIGESTLENGTH);
 2077         isc_hmacsha256_update(&hmacsha256, cp, 16);
 2078         isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
 2079         switch (netaddr.family) {
 2080         case AF_INET:
 2081             cp = (unsigned char *)&netaddr.type.in;
 2082             length = 4;
 2083             break;
 2084         case AF_INET6:
 2085             cp = (unsigned char *)&netaddr.type.in6;
 2086             length = 16;
 2087             break;
 2088         default:
 2089             INSIST(0);
 2090             ISC_UNREACHABLE();
 2091         }
 2092         isc_hmacsha256_update(&hmacsha256, cp, length);
 2093         isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest));
 2094         isc_buffer_putmem(buf, digest, 8);
 2095         isc_hmacsha256_invalidate(&hmacsha256);
 2096         break;
 2097     }
 2098     default:
 2099         INSIST(0);
 2100         ISC_UNREACHABLE();
 2101     }
 2102 }
 2103 
 2104 static void
 2105 process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
 2106     ns_altsecret_t *altsecret;
 2107     unsigned char dbuf[COOKIE_SIZE];
 2108     unsigned char *old;
 2109     isc_stdtime_t now;
 2110     uint32_t when;
 2111     uint32_t nonce;
 2112     isc_buffer_t db;
 2113 
 2114     /*
 2115      * If we have already seen a cookie option skip this cookie option.
 2116      */
 2117     if ((!ns_g_server->answercookie) ||
 2118         (client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0)
 2119     {
 2120         isc_buffer_forward(buf, (unsigned int)optlen);
 2121         return;
 2122     }
 2123 
 2124     client->attributes |= NS_CLIENTATTR_WANTCOOKIE;
 2125 
 2126     isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_cookiein);
 2127 
 2128     if (optlen != COOKIE_SIZE) {
 2129         /*
 2130          * Not our token.
 2131          */
 2132         INSIST(optlen >= 8U);
 2133         memmove(client->cookie, isc_buffer_current(buf), 8);
 2134         isc_buffer_forward(buf, (unsigned int)optlen);
 2135 
 2136         if (optlen == 8U)
 2137             isc_stats_increment(ns_g_server->nsstats,
 2138                         dns_nsstatscounter_cookienew);
 2139         else
 2140             isc_stats_increment(ns_g_server->nsstats,
 2141                         dns_nsstatscounter_cookiebadsize);
 2142         return;
 2143     }
 2144 
 2145     /*
 2146      * Process all of the incoming buffer.
 2147      */
 2148     old = isc_buffer_current(buf);
 2149     memmove(client->cookie, old, 8);
 2150     isc_buffer_forward(buf, 8);
 2151     nonce = isc_buffer_getuint32(buf);
 2152     when = isc_buffer_getuint32(buf);
 2153     isc_buffer_forward(buf, 8);
 2154 
 2155     /*
 2156      * Allow for a 5 minute clock skew between servers sharing a secret.
 2157      * Only accept COOKIE if we have talked to the client in the last hour.
 2158      */
 2159     isc_stdtime_get(&now);
 2160     if (isc_serial_gt(when, (now + 300)) ||     /* In the future. */
 2161         isc_serial_lt(when, (now - 3600))) {    /* In the past. */
 2162         isc_stats_increment(ns_g_server->nsstats,
 2163                     dns_nsstatscounter_cookiebadtime);
 2164         return;
 2165     }
 2166 
 2167     isc_buffer_init(&db, dbuf, sizeof(dbuf));
 2168     compute_cookie(client, when, nonce, ns_g_server->secret, &db);
 2169 
 2170     if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) {
 2171         isc_stats_increment(ns_g_server->nsstats,
 2172                     dns_nsstatscounter_cookiematch);
 2173         client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
 2174         return;
 2175     }
 2176 
 2177     for (altsecret = ISC_LIST_HEAD(ns_g_server->altsecrets);
 2178          altsecret != NULL;
 2179          altsecret = ISC_LIST_NEXT(altsecret, link))
 2180     {
 2181         isc_buffer_init(&db, dbuf, sizeof(dbuf));
 2182         compute_cookie(client, when, nonce, altsecret->secret, &db);
 2183         if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) {
 2184             isc_stats_increment(ns_g_server->nsstats,
 2185                         dns_nsstatscounter_cookiematch);
 2186             client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
 2187             return;
 2188         }
 2189     }
 2190 
 2191     isc_stats_increment(ns_g_server->nsstats,
 2192                 dns_nsstatscounter_cookienomatch);
 2193 }
 2194 
 2195 static isc_result_t
 2196 process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
 2197     uint16_t family;
 2198     uint8_t addrlen, addrbytes, scope, *paddr;
 2199     isc_netaddr_t caddr;
 2200 
 2201     /*
 2202      * If we have already seen a ECS option skip this ECS option.
 2203      */
 2204     if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) {
 2205         isc_buffer_forward(buf, (unsigned int)optlen);
 2206         return (ISC_R_SUCCESS);
 2207     }
 2208 
 2209     /*
 2210      * XXXMUKS: Is there any need to repeat these checks here
 2211      * (except query's scope length) when they are done in the OPT
 2212      * RDATA fromwire code?
 2213      */
 2214 
 2215     if (optlen < 4U) {
 2216         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2217                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
 2218                   "EDNS client-subnet option too short");
 2219         return (DNS_R_FORMERR);
 2220     }
 2221 
 2222     family = isc_buffer_getuint16(buf);
 2223     addrlen = isc_buffer_getuint8(buf);
 2224     scope = isc_buffer_getuint8(buf);
 2225     optlen -= 4;
 2226 
 2227     if (scope != 0U) {
 2228         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2229                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
 2230                   "EDNS client-subnet option: invalid scope");
 2231         return (DNS_R_OPTERR);
 2232     }
 2233 
 2234     memset(&caddr, 0, sizeof(caddr));
 2235     switch (family) {
 2236     case 0:
 2237         /*
 2238          * XXXMUKS: In queries, if FAMILY is set to 0, SOURCE
 2239          * PREFIX-LENGTH must be 0 and ADDRESS should not be
 2240          * present as the address and prefix lengths don't make
 2241          * sense because the family is unknown.
 2242          */
 2243         if (addrlen != 0U) {
 2244             ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2245                       NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
 2246                       "EDNS client-subnet option: invalid "
 2247                       "address length (%u) for FAMILY=0",
 2248                       addrlen);
 2249             return (DNS_R_OPTERR);
 2250         }
 2251         caddr.family = AF_UNSPEC;
 2252         break;
 2253     case 1:
 2254         if (addrlen > 32U) {
 2255             ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2256                       NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
 2257                       "EDNS client-subnet option: invalid "
 2258                       "address length (%u) for IPv4",
 2259                       addrlen);
 2260             return (DNS_R_OPTERR);
 2261         }
 2262         caddr.family = AF_INET;
 2263         break;
 2264     case 2:
 2265         if (addrlen > 128U) {
 2266             ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2267                       NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
 2268                       "EDNS client-subnet option: invalid "
 2269                       "address length (%u) for IPv6",
 2270                       addrlen);
 2271             return (DNS_R_OPTERR);
 2272         }
 2273         caddr.family = AF_INET6;
 2274         break;
 2275     default:
 2276         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2277                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
 2278                   "EDNS client-subnet option: invalid family");
 2279         return (DNS_R_OPTERR);
 2280     }
 2281 
 2282     addrbytes = (addrlen + 7) / 8;
 2283     if (isc_buffer_remaininglength(buf) < addrbytes) {
 2284         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2285                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
 2286                   "EDNS client-subnet option: address too short");
 2287         return (DNS_R_OPTERR);
 2288     }
 2289 
 2290     paddr = (uint8_t *) &caddr.type;
 2291     if (addrbytes != 0U) {
 2292         memmove(paddr, isc_buffer_current(buf), addrbytes);
 2293         isc_buffer_forward(buf, addrbytes);
 2294         optlen -= addrbytes;
 2295 
 2296         if ((addrlen % 8) != 0) {
 2297             uint8_t bits = ~0U << (8 - (addrlen % 8));
 2298             bits &= paddr[addrbytes - 1];
 2299             if (bits != paddr[addrbytes - 1])
 2300                 return (DNS_R_OPTERR);
 2301         }
 2302     }
 2303 
 2304     memmove(&client->ecs_addr, &caddr, sizeof(caddr));
 2305     client->ecs_addrlen = addrlen;
 2306     client->ecs_scope = 0;
 2307     client->attributes |= NS_CLIENTATTR_HAVEECS;
 2308 
 2309     isc_buffer_forward(buf, (unsigned int)optlen);
 2310     return (ISC_R_SUCCESS);
 2311 }
 2312 
 2313 static isc_result_t
 2314 process_keytag(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
 2315 
 2316     if (optlen == 0 || (optlen % 2) != 0) {
 2317         isc_buffer_forward(buf, (unsigned int)optlen);
 2318         return (DNS_R_OPTERR);
 2319     }
 2320 
 2321     /* Silently drop additional keytag options. */
 2322     if (client->keytag != NULL) {
 2323         isc_buffer_forward(buf, (unsigned int)optlen);
 2324         return (ISC_R_SUCCESS);
 2325     }
 2326 
 2327     client->keytag = isc_mem_get(client->mctx, optlen);
 2328     if (client->keytag != NULL) {
 2329         client->keytag_len = (uint16_t)optlen;
 2330         memmove(client->keytag, isc_buffer_current(buf), optlen);
 2331     }
 2332     isc_buffer_forward(buf, (unsigned int)optlen);
 2333     return (ISC_R_SUCCESS);
 2334 }
 2335 
 2336 static isc_result_t
 2337 process_opt(ns_client_t *client, dns_rdataset_t *opt) {
 2338     dns_rdata_t rdata;
 2339     isc_buffer_t optbuf;
 2340     isc_result_t result;
 2341     uint16_t optcode;
 2342     uint16_t optlen;
 2343 
 2344     /*
 2345      * Set the client's UDP buffer size.
 2346      */
 2347     client->udpsize = opt->rdclass;
 2348 
 2349     /*
 2350      * If the requested UDP buffer size is less than 512,
 2351      * ignore it and use 512.
 2352      */
 2353     if (client->udpsize < 512)
 2354         client->udpsize = 512;
 2355 
 2356     /*
 2357      * Get the flags out of the OPT record.
 2358      */
 2359     client->extflags = (uint16_t)(opt->ttl & 0xFFFF);
 2360 
 2361     /*
 2362      * Do we understand this version of EDNS?
 2363      *
 2364      * XXXRTH need library support for this!
 2365      */
 2366     client->ednsversion = (opt->ttl & 0x00FF0000) >> 16;
 2367     if (client->ednsversion > DNS_EDNS_VERSION) {
 2368         isc_stats_increment(ns_g_server->nsstats,
 2369                     dns_nsstatscounter_badednsver);
 2370         result = ns_client_addopt(client, client->message,
 2371                       &client->opt);
 2372         if (result == ISC_R_SUCCESS)
 2373             result = DNS_R_BADVERS;
 2374         ns_client_error(client, result);
 2375         goto cleanup;
 2376     }
 2377 
 2378     /* Check for NSID request */
 2379     result = dns_rdataset_first(opt);
 2380     if (result == ISC_R_SUCCESS) {
 2381         dns_rdata_init(&rdata);
 2382         dns_rdataset_current(opt, &rdata);
 2383         isc_buffer_init(&optbuf, rdata.data, rdata.length);
 2384         isc_buffer_add(&optbuf, rdata.length);
 2385         while (isc_buffer_remaininglength(&optbuf) >= 4) {
 2386             optcode = isc_buffer_getuint16(&optbuf);
 2387             optlen = isc_buffer_getuint16(&optbuf);
 2388             switch (optcode) {
 2389             case DNS_OPT_NSID:
 2390                 if (!WANTNSID(client))
 2391                     isc_stats_increment(
 2392                             ns_g_server->nsstats,
 2393                             dns_nsstatscounter_nsidopt);
 2394                 client->attributes |= NS_CLIENTATTR_WANTNSID;
 2395                 isc_buffer_forward(&optbuf, optlen);
 2396                 break;
 2397             case DNS_OPT_COOKIE:
 2398                 process_cookie(client, &optbuf, optlen);
 2399                 break;
 2400             case DNS_OPT_EXPIRE:
 2401                 if (!WANTEXPIRE(client))
 2402                     isc_stats_increment(
 2403                           ns_g_server->nsstats,
 2404                           dns_nsstatscounter_expireopt);
 2405                 client->attributes |= NS_CLIENTATTR_WANTEXPIRE;
 2406                 isc_buffer_forward(&optbuf, optlen);
 2407                 break;
 2408             case DNS_OPT_CLIENT_SUBNET:
 2409                 result = process_ecs(client, &optbuf, optlen);
 2410                 if (result != ISC_R_SUCCESS) {
 2411                     ns_client_error(client, result);
 2412                     goto cleanup;
 2413                 }
 2414                 isc_stats_increment(ns_g_server->nsstats,
 2415                           dns_nsstatscounter_ecsopt);
 2416                 break;
 2417             case DNS_OPT_KEY_TAG:
 2418                 result = process_keytag(client, &optbuf,
 2419                             optlen);
 2420                 if (result != ISC_R_SUCCESS) {
 2421                     ns_client_error(client, result);
 2422                     return (result);
 2423                 }
 2424                 isc_stats_increment(ns_g_server->nsstats,
 2425                            dns_nsstatscounter_keytagopt);
 2426                 break;
 2427             default:
 2428                 isc_stats_increment(ns_g_server->nsstats,
 2429                           dns_nsstatscounter_otheropt);
 2430                 isc_buffer_forward(&optbuf, optlen);
 2431                 break;
 2432             }
 2433         }
 2434     }
 2435 
 2436     isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_edns0in);
 2437     client->attributes |= NS_CLIENTATTR_WANTOPT;
 2438 
 2439  cleanup:
 2440     return (result);
 2441 }
 2442 
 2443 /*
 2444  * Handle an incoming request event from the socket (UDP case)
 2445  * or tcpmsg (TCP case).
 2446  */
 2447 static void
 2448 client_request(isc_task_t *task, isc_event_t *event) {
 2449     ns_client_t *client;
 2450     isc_socketevent_t *sevent;
 2451     isc_result_t result;
 2452     isc_result_t sigresult = ISC_R_SUCCESS;
 2453     isc_buffer_t *buffer;
 2454     isc_buffer_t tbuffer;
 2455     dns_view_t *view;
 2456     dns_rdataset_t *opt;
 2457     dns_name_t *signame;
 2458     bool ra;    /* Recursion available. */
 2459     isc_netaddr_t netaddr;
 2460     int match;
 2461     dns_messageid_t id;
 2462     unsigned int flags;
 2463     bool notimp;
 2464     size_t reqsize;
 2465 #ifdef HAVE_DNSTAP
 2466     dns_dtmsgtype_t dtmsgtype;
 2467 #endif
 2468 
 2469     REQUIRE(event != NULL);
 2470     client = event->ev_arg;
 2471     REQUIRE(NS_CLIENT_VALID(client));
 2472     REQUIRE(task == client->task);
 2473 
 2474     INSIST(client->recursionquota == NULL);
 2475 
 2476     INSIST(client->state == (TCP_CLIENT(client) ?
 2477                        NS_CLIENTSTATE_READING :
 2478                        NS_CLIENTSTATE_READY));
 2479 
 2480     ns_client_requests++;
 2481 
 2482     if (event->ev_type == ISC_SOCKEVENT_RECVDONE) {
 2483         INSIST(!TCP_CLIENT(client));
 2484         sevent = (isc_socketevent_t *)event;
 2485         REQUIRE(sevent == client->recvevent);
 2486         isc_buffer_init(&tbuffer, sevent->region.base, sevent->n);
 2487         isc_buffer_add(&tbuffer, sevent->n);
 2488         buffer = &tbuffer;
 2489         result = sevent->result;
 2490         if (result == ISC_R_SUCCESS) {
 2491             client->peeraddr = sevent->address;
 2492             client->peeraddr_valid = true;
 2493         }
 2494         if ((sevent->attributes & ISC_SOCKEVENTATTR_DSCP) != 0) {
 2495             ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2496                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(90),
 2497                   "received DSCP %d", sevent->dscp);
 2498             if (client->dscp == -1)
 2499                 client->dscp = sevent->dscp;
 2500         }
 2501         if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) {
 2502             client->attributes |= NS_CLIENTATTR_PKTINFO;
 2503             client->pktinfo = sevent->pktinfo;
 2504         }
 2505         if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0)
 2506             client->attributes |= NS_CLIENTATTR_MULTICAST;
 2507         client->nrecvs--;
 2508     } else {
 2509         INSIST(TCP_CLIENT(client));
 2510         INSIST(client->tcpconn != NULL);
 2511         REQUIRE(event->ev_type == DNS_EVENT_TCPMSG);
 2512         REQUIRE(event->ev_sender == &client->tcpmsg);
 2513         buffer = &client->tcpmsg.buffer;
 2514         result = client->tcpmsg.result;
 2515         INSIST(client->nreads == 1);
 2516         /*
 2517          * client->peeraddr was set when the connection was accepted.
 2518          */
 2519         client->nreads--;
 2520     }
 2521 
 2522     reqsize = isc_buffer_usedlength(buffer);
 2523     /* don't count the length header */
 2524     if (TCP_CLIENT(client))
 2525         reqsize -= 2;
 2526 
 2527     if (exit_check(client))
 2528         goto cleanup;
 2529     client->state = client->newstate = NS_CLIENTSTATE_WORKING;
 2530 
 2531     isc_task_getcurrenttimex(task, &client->requesttime);
 2532     client->tnow = client->requesttime;
 2533     client->now = isc_time_seconds(&client->tnow);
 2534 
 2535     if (result != ISC_R_SUCCESS) {
 2536         if (TCP_CLIENT(client)) {
 2537             ns_client_next(client, result);
 2538         } else {
 2539             if  (result != ISC_R_CANCELED)
 2540                 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT,
 2541                           NS_LOGMODULE_CLIENT,
 2542                           ISC_LOG_ERROR,
 2543                           "UDP client handler shutting "
 2544                           "down due to fatal receive "
 2545                           "error: %s",
 2546                           isc_result_totext(result));
 2547             isc_task_shutdown(client->task);
 2548         }
 2549         goto cleanup;
 2550     }
 2551 
 2552     isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
 2553 
 2554 #if NS_CLIENT_DROPPORT
 2555     if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) ==
 2556         DROPPORT_REQUEST) {
 2557         ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 2558                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
 2559                   "dropped request: suspicious port");
 2560         ns_client_next(client, ISC_R_SUCCESS);
 2561         goto cleanup;
 2562     }
 2563 #endif
 2564 
 2565     ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2566               NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
 2567               "%s request",
 2568               TCP_CLIENT(client) ? "TCP" : "UDP");
 2569 
 2570     /*
 2571      * Check the blackhole ACL for UDP only, since TCP is done in
 2572      * client_newconn.
 2573      */
 2574     if (!TCP_CLIENT(client)) {
 2575         if (ns_g_server->blackholeacl != NULL &&
 2576             dns_acl_match(&netaddr, NULL, ns_g_server->blackholeacl,
 2577                   &ns_g_server->aclenv,
 2578                   &match, NULL) == ISC_R_SUCCESS &&
 2579             match > 0)
 2580         {
 2581             ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 2582                       NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
 2583                       "blackholed UDP datagram");
 2584             ns_client_next(client, ISC_R_SUCCESS);
 2585             goto cleanup;
 2586         }
 2587     }
 2588 
 2589     /*
 2590      * Silently drop multicast requests for the present.
 2591      * XXXMPA revisit this as mDNS spec was published.
 2592      */
 2593     if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) {
 2594         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2595                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
 2596                   "dropping multicast request");
 2597         ns_client_next(client, DNS_R_REFUSED);
 2598         goto cleanup;
 2599     }
 2600 
 2601     result = dns_message_peekheader(buffer, &id, &flags);
 2602     if (result != ISC_R_SUCCESS) {
 2603         /*
 2604          * There isn't enough header to determine whether
 2605          * this was a request or a response.  Drop it.
 2606          */
 2607         ns_client_next(client, result);
 2608         goto cleanup;
 2609     }
 2610 
 2611     /*
 2612      * The client object handles requests, not responses.
 2613      * If this is a UDP response, forward it to the dispatcher.
 2614      * If it's a TCP response, discard it here.
 2615      */
 2616     if ((flags & DNS_MESSAGEFLAG_QR) != 0) {
 2617         if (TCP_CLIENT(client)) {
 2618             CTRACE("unexpected response");
 2619             ns_client_next(client, DNS_R_FORMERR);
 2620             goto cleanup;
 2621         } else {
 2622             dns_dispatch_importrecv(client->dispatch, event);
 2623             ns_client_next(client, ISC_R_SUCCESS);
 2624             goto cleanup;
 2625         }
 2626     }
 2627 
 2628     /*
 2629      * Update some statistics counters.  Don't count responses.
 2630      */
 2631     if (isc_sockaddr_pf(&client->peeraddr) == PF_INET) {
 2632         isc_stats_increment(ns_g_server->nsstats,
 2633                     dns_nsstatscounter_requestv4);
 2634     } else {
 2635         isc_stats_increment(ns_g_server->nsstats,
 2636                     dns_nsstatscounter_requestv6);
 2637     }
 2638     if (TCP_CLIENT(client)) {
 2639         isc_stats_increment(ns_g_server->nsstats,
 2640                     dns_nsstatscounter_requesttcp);
 2641         switch (isc_sockaddr_pf(&client->peeraddr)) {
 2642         case AF_INET:
 2643             isc_stats_increment(ns_g_server->tcpinstats4,
 2644                         ISC_MIN((int)reqsize / 16, 18));
 2645             break;
 2646         case AF_INET6:
 2647             isc_stats_increment(ns_g_server->tcpinstats6,
 2648                         ISC_MIN((int)reqsize / 16, 18));
 2649             break;
 2650         default:
 2651             INSIST(0);
 2652             ISC_UNREACHABLE();
 2653         }
 2654     } else {
 2655         switch (isc_sockaddr_pf(&client->peeraddr)) {
 2656         case AF_INET:
 2657             isc_stats_increment(ns_g_server->udpinstats4,
 2658                         ISC_MIN((int)reqsize / 16, 18));
 2659             break;
 2660         case AF_INET6:
 2661             isc_stats_increment(ns_g_server->udpinstats6,
 2662                         ISC_MIN((int)reqsize / 16, 18));
 2663             break;
 2664         default:
 2665             INSIST(0);
 2666             ISC_UNREACHABLE();
 2667         }
 2668     }
 2669 
 2670     /*
 2671      * It's a request.  Parse it.
 2672      */
 2673     result = dns_message_parse(client->message, buffer, 0);
 2674     if (result != ISC_R_SUCCESS) {
 2675         /*
 2676          * Parsing the request failed.  Send a response
 2677          * (typically FORMERR or SERVFAIL).
 2678          */
 2679         if (result == DNS_R_OPTERR) {
 2680             (void)ns_client_addopt(client, client->message,
 2681                            &client->opt);
 2682         }
 2683 
 2684         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2685                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
 2686                   "message parsing failed: %s",
 2687                   isc_result_totext(result));
 2688         if (result == ISC_R_NOSPACE || result == DNS_R_BADTSIG) {
 2689             result = DNS_R_FORMERR;
 2690         }
 2691         ns_client_error(client, result);
 2692         goto cleanup;
 2693     }
 2694 
 2695     /*
 2696      * Pipeline TCP query processing.
 2697      */
 2698     if (TCP_CLIENT(client)) {
 2699         if (client->message->opcode != dns_opcode_query) {
 2700             client->tcpconn->pipelined = false;
 2701         }
 2702 
 2703         /*
 2704          * Limit the maximum number of simultaneous pipelined
 2705          * queries on TCP connection to TCP_CLIENTS_PER_CONN.
 2706          */
 2707         if ((isc_refcount_current(&client->tcpconn->clients)
 2708                 > TCP_CLIENTS_PER_CONN))
 2709         {
 2710             client->tcpconn->pipelined = false;
 2711         }
 2712 
 2713         if (client->tcpconn->pipelined) {
 2714             /*
 2715              * We're pipelining. Replace the client; the
 2716              * replacement can read the TCP socket looking
 2717              * for new messages and this one can process the
 2718              * current message asynchronously.
 2719              *
 2720              * There will now be at least three clients using this
 2721              * TCP socket - one accepting new connections,
 2722              * one reading an existing connection to get new
 2723              * messages, and one answering the message already
 2724              * received.
 2725              */
 2726             result = ns_client_replace(client);
 2727             if (result != ISC_R_SUCCESS) {
 2728                 client->tcpconn->pipelined = false;
 2729             }
 2730         }
 2731     }
 2732 
 2733     dns_opcodestats_increment(ns_g_server->opcodestats,
 2734                   client->message->opcode);
 2735     switch (client->message->opcode) {
 2736     case dns_opcode_query:
 2737     case dns_opcode_update:
 2738     case dns_opcode_notify:
 2739         notimp = false;
 2740         break;
 2741     case dns_opcode_iquery:
 2742     default:
 2743         notimp = true;
 2744         break;
 2745     }
 2746 
 2747     client->message->rcode = dns_rcode_noerror;
 2748 
 2749     /* RFC1123 section 6.1.3.2 */
 2750     if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0)
 2751         client->message->flags &= ~DNS_MESSAGEFLAG_RD;
 2752 
 2753     /*
 2754      * Deal with EDNS.
 2755      */
 2756     if (ns_g_noedns)
 2757         opt = NULL;
 2758     else
 2759         opt = dns_message_getopt(client->message);
 2760 
 2761     client->ecs_addrlen = 0;
 2762     client->ecs_scope = 0;
 2763 
 2764     if (opt != NULL) {
 2765         /*
 2766          * Are returning FORMERR to all EDNS queries?
 2767          * Simulate a STD13 compliant server.
 2768          */
 2769         if (ns_g_ednsformerr) {
 2770             ns_client_error(client, DNS_R_FORMERR);
 2771             return;
 2772         }
 2773 
 2774         /*
 2775          * Are returning NOTIMP to all EDNS queries?
 2776          */
 2777         if (ns_g_ednsnotimp) {
 2778             ns_client_error(client, DNS_R_NOTIMP);
 2779             return;
 2780         }
 2781 
 2782         /*
 2783          * Are returning REFUSED to all EDNS queries?
 2784          */
 2785         if (ns_g_ednsrefused) {
 2786             ns_client_error(client, DNS_R_REFUSED);
 2787             return;
 2788         }
 2789 
 2790         /*
 2791          * Are we dropping all EDNS queries?
 2792          */
 2793         if (ns_g_dropedns) {
 2794             ns_client_next(client, ISC_R_SUCCESS);
 2795             goto cleanup;
 2796         }
 2797 
 2798         result = process_opt(client, opt);
 2799         if (result != ISC_R_SUCCESS)
 2800             goto cleanup;
 2801     }
 2802 
 2803     if (client->message->rdclass == 0) {
 2804         if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0 &&
 2805             client->message->opcode == dns_opcode_query &&
 2806             client->message->counts[DNS_SECTION_QUESTION] == 0U)
 2807         {
 2808             result = dns_message_reply(client->message, true);
 2809             if (result != ISC_R_SUCCESS) {
 2810                 ns_client_error(client, result);
 2811                 return;
 2812             }
 2813             if (notimp)
 2814                 client->message->rcode = dns_rcode_notimp;
 2815             ns_client_send(client);
 2816             return;
 2817         }
 2818         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2819                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
 2820                   "message class could not be determined");
 2821         ns_client_dumpmessage(client,
 2822                       "message class could not be determined");
 2823         ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR);
 2824         goto cleanup;
 2825     }
 2826 
 2827     /*
 2828      * Determine the destination address.  If the receiving interface is
 2829      * bound to a specific address, we simply use it regardless of the
 2830      * address family.  All IPv4 queries should fall into this case.
 2831      * Otherwise, if this is a TCP query, get the address from the
 2832      * receiving socket (this needs a system call and can be heavy).
 2833      * For IPv6 UDP queries, we get this from the pktinfo structure (if
 2834      * supported).
 2835      * If all the attempts fail (this can happen due to memory shortage,
 2836      * etc), we regard this as an error for safety.
 2837      */
 2838     if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0)
 2839         isc_netaddr_fromsockaddr(&client->destaddr,
 2840                      &client->interface->addr);
 2841     else {
 2842         isc_sockaddr_t sockaddr;
 2843         result = ISC_R_FAILURE;
 2844 
 2845         if (TCP_CLIENT(client))
 2846             result = isc_socket_getsockname(client->tcpsocket,
 2847                             &sockaddr);
 2848         if (result == ISC_R_SUCCESS)
 2849             isc_netaddr_fromsockaddr(&client->destaddr, &sockaddr);
 2850         if (result != ISC_R_SUCCESS &&
 2851             client->interface->addr.type.sa.sa_family == AF_INET6 &&
 2852             (client->attributes & NS_CLIENTATTR_PKTINFO) != 0) {
 2853             /*
 2854              * XXXJT technically, we should convert the receiving
 2855              * interface ID to a proper scope zone ID.  However,
 2856              * due to the fact there is no standard API for this,
 2857              * we only handle link-local addresses and use the
 2858              * interface index as link ID.  Despite the assumption,
 2859              * it should cover most typical cases.
 2860              */
 2861             isc_netaddr_fromin6(&client->destaddr,
 2862                         &client->pktinfo.ipi6_addr);
 2863             if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr))
 2864                 isc_netaddr_setzone(&client->destaddr,
 2865                         client->pktinfo.ipi6_ifindex);
 2866             result = ISC_R_SUCCESS;
 2867         }
 2868         if (result != ISC_R_SUCCESS) {
 2869             UNEXPECTED_ERROR(__FILE__, __LINE__,
 2870                      "failed to get request's "
 2871                      "destination: %s",
 2872                      isc_result_totext(result));
 2873             ns_client_next(client, ISC_R_SUCCESS);
 2874             goto cleanup;
 2875         }
 2876     }
 2877 
 2878     isc_sockaddr_fromnetaddr(&client->destsockaddr, &client->destaddr, 0);
 2879 
 2880     /*
 2881      * Find a view that matches the client's source address.
 2882      */
 2883     for (view = ISC_LIST_HEAD(ns_g_server->viewlist);
 2884          view != NULL;
 2885          view = ISC_LIST_NEXT(view, link)) {
 2886         if (client->message->rdclass == view->rdclass ||
 2887             client->message->rdclass == dns_rdataclass_any)
 2888         {
 2889             const dns_name_t *tsig = NULL;
 2890             isc_netaddr_t *addr = NULL;
 2891             uint8_t *scope = NULL;
 2892 
 2893             sigresult = dns_message_rechecksig(client->message,
 2894                                view);
 2895             if (sigresult == ISC_R_SUCCESS) {
 2896                 dns_tsigkey_t *tsigkey;
 2897 
 2898                 tsigkey = client->message->tsigkey;
 2899                 tsig = dns_tsigkey_identity(tsigkey);
 2900             }
 2901 
 2902             if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) {
 2903                 addr = &client->ecs_addr;
 2904                 scope = &client->ecs_scope;
 2905             }
 2906 
 2907             if (allowed(&netaddr, tsig, addr, client->ecs_addrlen,
 2908                     scope, view->matchclients) &&
 2909                 allowed(&client->destaddr, tsig, NULL,
 2910                     0, NULL, view->matchdestinations) &&
 2911                 !(view->matchrecursiveonly &&
 2912                 (client->message->flags & DNS_MESSAGEFLAG_RD) == 0))
 2913             {
 2914                 dns_view_attach(view, &client->view);
 2915                 break;
 2916             }
 2917         }
 2918     }
 2919 
 2920     if (view == NULL) {
 2921         char classname[DNS_RDATACLASS_FORMATSIZE];
 2922 
 2923         /*
 2924          * Do a dummy TSIG verification attempt so that the
 2925          * response will have a TSIG if the query did, as
 2926          * required by RFC2845.
 2927          */
 2928         isc_buffer_t b;
 2929         isc_region_t *r;
 2930 
 2931         dns_message_resetsig(client->message);
 2932 
 2933         r = dns_message_getrawmessage(client->message);
 2934         isc_buffer_init(&b, r->base, r->length);
 2935         isc_buffer_add(&b, r->length);
 2936         (void)dns_tsig_verify(&b, client->message, NULL, NULL);
 2937 
 2938         dns_rdataclass_format(client->message->rdclass, classname,
 2939                       sizeof(classname));
 2940         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2941                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
 2942                   "no matching view in class '%s'", classname);
 2943         ns_client_dumpmessage(client, "no matching view in class");
 2944         ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED);
 2945         goto cleanup;
 2946     }
 2947 
 2948     ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 2949               NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5),
 2950               "using view '%s'", view->name);
 2951 
 2952     /*
 2953      * Check for a signature.  We log bad signatures regardless of
 2954      * whether they ultimately cause the request to be rejected or
 2955      * not.  We do not log the lack of a signature unless we are
 2956      * debugging.
 2957      */
 2958     client->signer = NULL;
 2959     dns_name_init(&client->signername, NULL);
 2960     result = dns_message_signer(client->message, &client->signername);
 2961     if (result != ISC_R_NOTFOUND) {
 2962         signame = NULL;
 2963         if (dns_message_gettsig(client->message, &signame) != NULL) {
 2964             isc_stats_increment(ns_g_server->nsstats,
 2965                         dns_nsstatscounter_tsigin);
 2966         } else {
 2967             isc_stats_increment(ns_g_server->nsstats,
 2968                         dns_nsstatscounter_sig0in);
 2969         }
 2970 
 2971     }
 2972     if (result == ISC_R_SUCCESS) {
 2973         char namebuf[DNS_NAME_FORMATSIZE];
 2974         dns_name_format(&client->signername, namebuf, sizeof(namebuf));
 2975         ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 2976                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
 2977                   "request has valid signature: %s", namebuf);
 2978         client->signer = &client->signername;
 2979     } else if (result == ISC_R_NOTFOUND) {
 2980         ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 2981                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
 2982                   "request is not signed");
 2983     } else if (result == DNS_R_NOIDENTITY) {
 2984         ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 2985                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
 2986                   "request is signed by a nonauthoritative key");
 2987     } else {
 2988         char tsigrcode[64];
 2989         isc_buffer_t b;
 2990         dns_rcode_t status;
 2991         isc_result_t tresult;
 2992 
 2993         /* There is a signature, but it is bad. */
 2994         isc_stats_increment(ns_g_server->nsstats,
 2995                     dns_nsstatscounter_invalidsig);
 2996         signame = NULL;
 2997         if (dns_message_gettsig(client->message, &signame) != NULL) {
 2998             char namebuf[DNS_NAME_FORMATSIZE];
 2999             char cnamebuf[DNS_NAME_FORMATSIZE];
 3000             dns_name_format(signame, namebuf, sizeof(namebuf));
 3001             status = client->message->tsigstatus;
 3002             isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1);
 3003             tresult = dns_tsigrcode_totext(status, &b);
 3004             INSIST(tresult == ISC_R_SUCCESS);
 3005             tsigrcode[isc_buffer_usedlength(&b)] = '\0';
 3006             if (client->message->tsigkey->generated) {
 3007                 dns_name_format(client->message->tsigkey->creator,
 3008                         cnamebuf, sizeof(cnamebuf));
 3009                 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 3010                           NS_LOGMODULE_CLIENT,
 3011                           ISC_LOG_ERROR,
 3012                           "request has invalid signature: "
 3013                           "TSIG %s (%s): %s (%s)", namebuf,
 3014                           cnamebuf,
 3015                           isc_result_totext(result),
 3016                           tsigrcode);
 3017             } else {
 3018                 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 3019                           NS_LOGMODULE_CLIENT,
 3020                           ISC_LOG_ERROR,
 3021                           "request has invalid signature: "
 3022                           "TSIG %s: %s (%s)", namebuf,
 3023                           isc_result_totext(result),
 3024                           tsigrcode);
 3025             }
 3026         } else {
 3027             status = client->message->sig0status;
 3028             isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1);
 3029             tresult = dns_tsigrcode_totext(status, &b);
 3030             INSIST(tresult == ISC_R_SUCCESS);
 3031             tsigrcode[isc_buffer_usedlength(&b)] = '\0';
 3032             ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 3033                       NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
 3034                       "request has invalid signature: %s (%s)",
 3035                       isc_result_totext(result), tsigrcode);
 3036         }
 3037         /*
 3038          * Accept update messages signed by unknown keys so that
 3039          * update forwarding works transparently through slaves
 3040          * that don't have all the same keys as the master.
 3041          */
 3042         if (!(client->message->tsigstatus == dns_tsigerror_badkey &&
 3043               client->message->opcode == dns_opcode_update)) {
 3044             ns_client_error(client, sigresult);
 3045             goto cleanup;
 3046         }
 3047     }
 3048 
 3049     /*
 3050      * Decide whether recursive service is available to this client.
 3051      * We do this here rather than in the query code so that we can
 3052      * set the RA bit correctly on all kinds of responses, not just
 3053      * responses to ordinary queries.  Note if you can't query the
 3054      * cache there is no point in setting RA.
 3055      */
 3056     ra = false;
 3057     if (client->view->resolver != NULL &&
 3058         client->view->recursion == true &&
 3059         ns_client_checkaclsilent(client, NULL,
 3060                      client->view->recursionacl,
 3061                      true) == ISC_R_SUCCESS &&
 3062         ns_client_checkaclsilent(client, NULL,
 3063                      client->view->cacheacl,
 3064                      true) == ISC_R_SUCCESS &&
 3065         ns_client_checkaclsilent(client, &client->destaddr,
 3066                      client->view->recursiononacl,
 3067                      true) == ISC_R_SUCCESS &&
 3068         ns_client_checkaclsilent(client, &client->destaddr,
 3069                      client->view->cacheonacl,
 3070                      true) == ISC_R_SUCCESS)
 3071         ra = true;
 3072 
 3073     if (ra == true) {
 3074         client->attributes |= NS_CLIENTATTR_RA;
 3075     }
 3076 
 3077     ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT,
 3078               ISC_LOG_DEBUG(3), ra ? "recursion available" :
 3079                          "recursion not available");
 3080 
 3081     /*
 3082      * Adjust maximum UDP response size for this client.
 3083      */
 3084     if (client->udpsize > 512) {
 3085         dns_peer_t *peer = NULL;
 3086         uint16_t udpsize = view->maxudp;
 3087         (void) dns_peerlist_peerbyaddr(view->peers, &netaddr, &peer);
 3088         if (peer != NULL)
 3089             dns_peer_getmaxudp(peer, &udpsize);
 3090         if (client->udpsize > udpsize)
 3091             client->udpsize = udpsize;
 3092     }
 3093 
 3094     /*
 3095      * Dispatch the request.
 3096      */
 3097     switch (client->message->opcode) {
 3098     case dns_opcode_query:
 3099         CTRACE("query");
 3100 #ifdef HAVE_DNSTAP
 3101         if (ra && (client->message->flags & DNS_MESSAGEFLAG_RD) != 0) {
 3102             dtmsgtype = DNS_DTTYPE_CQ;
 3103         } else {
 3104             dtmsgtype = DNS_DTTYPE_AQ;
 3105         }
 3106 
 3107         dns_dt_send(view, dtmsgtype, &client->peeraddr,
 3108                 &client->destsockaddr, TCP_CLIENT(client), NULL,
 3109                 &client->requesttime, NULL, buffer);
 3110 #endif /* HAVE_DNSTAP */
 3111 
 3112         ns_query_start(client);
 3113         break;
 3114     case dns_opcode_update:
 3115         CTRACE("update");
 3116         ns_client_settimeout(client, 60);
 3117         ns_update_start(client, sigresult);
 3118         break;
 3119     case dns_opcode_notify:
 3120         CTRACE("notify");
 3121         ns_client_settimeout(client, 60);
 3122         ns_notify_start(client);
 3123         break;
 3124     case dns_opcode_iquery:
 3125         CTRACE("iquery");
 3126         ns_client_error(client, DNS_R_NOTIMP);
 3127         break;
 3128     default:
 3129         CTRACE("unknown opcode");
 3130         ns_client_error(client, DNS_R_NOTIMP);
 3131     }
 3132 
 3133  cleanup:
 3134     return;
 3135 }
 3136 
 3137 static void
 3138 client_timeout(isc_task_t *task, isc_event_t *event) {
 3139     ns_client_t *client;
 3140 
 3141     REQUIRE(event != NULL);
 3142     REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE ||
 3143         event->ev_type == ISC_TIMEREVENT_IDLE);
 3144     client = event->ev_arg;
 3145     REQUIRE(NS_CLIENT_VALID(client));
 3146     REQUIRE(task == client->task);
 3147     REQUIRE(client->timer != NULL);
 3148 
 3149     UNUSED(task);
 3150 
 3151     CTRACE("timeout");
 3152 
 3153     isc_event_free(&event);
 3154 
 3155     if (client->shutdown != NULL) {
 3156         (client->shutdown)(client->shutdown_arg, ISC_R_TIMEDOUT);
 3157         client->shutdown = NULL;
 3158         client->shutdown_arg = NULL;
 3159     }
 3160 
 3161     if (client->newstate > NS_CLIENTSTATE_READY)
 3162         client->newstate = NS_CLIENTSTATE_READY;
 3163     (void)exit_check(client);
 3164 }
 3165 
 3166 static isc_result_t
 3167 get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) {
 3168     isc_mem_t *clientmctx;
 3169     isc_result_t result;
 3170 #if NMCTXS > 0
 3171     unsigned int nextmctx;
 3172 #endif
 3173 
 3174     MTRACE("clientmctx");
 3175 
 3176     /*
 3177      * Caller must be holding the manager lock.
 3178      */
 3179     if (ns_g_clienttest) {
 3180         result = isc_mem_create(0, 0, mctxp);
 3181         if (result == ISC_R_SUCCESS)
 3182             isc_mem_setname(*mctxp, "client", NULL);
 3183         return (result);
 3184     }
 3185 #if NMCTXS > 0
 3186     nextmctx = manager->nextmctx++;
 3187     if (manager->nextmctx == NMCTXS)
 3188         manager->nextmctx = 0;
 3189 
 3190     INSIST(nextmctx < NMCTXS);
 3191 
 3192     clientmctx = manager->mctxpool[nextmctx];
 3193     if (clientmctx == NULL) {
 3194         result = isc_mem_create(0, 0, &clientmctx);
 3195         if (result != ISC_R_SUCCESS)
 3196             return (result);
 3197         isc_mem_setname(clientmctx, "client", NULL);
 3198 
 3199         manager->mctxpool[nextmctx] = clientmctx;
 3200     }
 3201 #else
 3202     clientmctx = manager->mctx;
 3203 #endif
 3204 
 3205     isc_mem_attach(clientmctx, mctxp);
 3206 
 3207     return (ISC_R_SUCCESS);
 3208 }
 3209 
 3210 static isc_result_t
 3211 client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
 3212     ns_client_t *client;
 3213     isc_result_t result;
 3214     isc_mem_t *mctx = NULL;
 3215 
 3216     /*
 3217      * Caller must be holding the manager lock.
 3218      *
 3219      * Note: creating a client does not add the client to the
 3220      * manager's client list or set the client's manager pointer.
 3221      * The caller is responsible for that.
 3222      */
 3223 
 3224     REQUIRE(clientp != NULL && *clientp == NULL);
 3225 
 3226     result = get_clientmctx(manager, &mctx);
 3227     if (result != ISC_R_SUCCESS)
 3228         return (result);
 3229 
 3230     client = isc_mem_get(mctx, sizeof(*client));
 3231     if (client == NULL) {
 3232         isc_mem_detach(&mctx);
 3233         return (ISC_R_NOMEMORY);
 3234     }
 3235     client->mctx = mctx;
 3236 
 3237     client->task = NULL;
 3238     result = isc_task_create(manager->taskmgr, 0, &client->task);
 3239     if (result != ISC_R_SUCCESS)
 3240         goto cleanup_client;
 3241     isc_task_setname(client->task, "client", client);
 3242 
 3243     client->timer = NULL;
 3244     result = isc_timer_create(manager->timermgr, isc_timertype_inactive,
 3245                   NULL, NULL, client->task, client_timeout,
 3246                   client, &client->timer);
 3247     if (result != ISC_R_SUCCESS)
 3248         goto cleanup_task;
 3249     client->timerset = false;
 3250 
 3251     client->delaytimer = NULL;
 3252 
 3253     client->message = NULL;
 3254     result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE,
 3255                     &client->message);
 3256     if (result != ISC_R_SUCCESS)
 3257         goto cleanup_timer;
 3258 
 3259     /* XXXRTH  Hardwired constants */
 3260 
 3261     client->sendevent = isc_socket_socketevent(client->mctx, client,
 3262                            ISC_SOCKEVENT_SENDDONE,
 3263                            client_senddone, client);
 3264     if (client->sendevent == NULL) {
 3265         result = ISC_R_NOMEMORY;
 3266         goto cleanup_message;
 3267     }
 3268 
 3269     client->recvbuf = isc_mem_get(client->mctx, RECV_BUFFER_SIZE);
 3270     if  (client->recvbuf == NULL) {
 3271         result = ISC_R_NOMEMORY;
 3272         goto cleanup_sendevent;
 3273     }
 3274 
 3275     client->recvevent = isc_socket_socketevent(client->mctx, client,
 3276                            ISC_SOCKEVENT_RECVDONE,
 3277                            client_request, client);
 3278     if (client->recvevent == NULL) {
 3279         result = ISC_R_NOMEMORY;
 3280         goto cleanup_recvbuf;
 3281     }
 3282 
 3283     client->magic = NS_CLIENT_MAGIC;
 3284     client->manager = NULL;
 3285     client->state = NS_CLIENTSTATE_INACTIVE;
 3286     client->newstate = NS_CLIENTSTATE_MAX;
 3287     client->naccepts = 0;
 3288     client->nreads = 0;
 3289     client->nsends = 0;
 3290     client->nrecvs = 0;
 3291     client->nupdates = 0;
 3292     client->nctls = 0;
 3293     client->references = 0;
 3294     client->attributes = 0;
 3295     client->view = NULL;
 3296     client->dispatch = NULL;
 3297     client->udpsocket = NULL;
 3298     client->tcplistener = NULL;
 3299     client->tcpsocket = NULL;
 3300     client->tcpmsg_valid = false;
 3301     client->tcpbuf = NULL;
 3302     client->opt = NULL;
 3303     client->udpsize = 512;
 3304     client->dscp = -1;
 3305     client->extflags = 0;
 3306     client->ednsversion = -1;
 3307     client->next = NULL;
 3308     client->shutdown = NULL;
 3309     client->shutdown_arg = NULL;
 3310     client->signer = NULL;
 3311     dns_name_init(&client->signername, NULL);
 3312     client->mortal = false;
 3313     client->tcpconn = NULL;
 3314     client->recursionquota = NULL;
 3315     client->interface = NULL;
 3316     client->peeraddr_valid = false;
 3317     client->ecs_addrlen = 0;
 3318     client->ecs_scope = 0;
 3319 #ifdef ALLOW_FILTER_AAAA
 3320     client->filter_aaaa = dns_aaaa_ok;
 3321 #endif
 3322     client->needshutdown = ns_g_clienttest;
 3323     client->tcpactive = false;
 3324 
 3325     ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL,
 3326                NS_EVENT_CLIENTCONTROL, client_start, client, client,
 3327                NULL, NULL);
 3328     /*
 3329      * Initialize FORMERR cache to sentinel value that will not match
 3330      * any actual FORMERR response.
 3331      */
 3332     isc_sockaddr_any(&client->formerrcache.addr);
 3333     client->formerrcache.time = 0;
 3334     client->formerrcache.id = 0;
 3335     ISC_LINK_INIT(client, link);
 3336     ISC_LINK_INIT(client, rlink);
 3337     ISC_QLINK_INIT(client, ilink);
 3338     client->keytag = NULL;
 3339     client->keytag_len = 0;
 3340 
 3341     /*
 3342      * We call the init routines for the various kinds of client here,
 3343      * after we have created an otherwise valid client, because some
 3344      * of them call routines that REQUIRE(NS_CLIENT_VALID(client)).
 3345      */
 3346     result = ns_query_init(client);
 3347     if (result != ISC_R_SUCCESS)
 3348         goto cleanup_recvevent;
 3349 
 3350     result = isc_task_onshutdown(client->task, client_shutdown, client);
 3351     if (result != ISC_R_SUCCESS)
 3352         goto cleanup_query;
 3353 
 3354     CTRACE("create");
 3355 
 3356     *clientp = client;
 3357 
 3358     return (ISC_R_SUCCESS);
 3359 
 3360  cleanup_query:
 3361     ns_query_free(client);
 3362 
 3363  cleanup_recvevent:
 3364     isc_event_free((isc_event_t **)&client->recvevent);
 3365 
 3366  cleanup_recvbuf:
 3367     isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE);
 3368 
 3369  cleanup_sendevent:
 3370     isc_event_free((isc_event_t **)&client->sendevent);
 3371 
 3372     client->magic = 0;
 3373 
 3374  cleanup_message:
 3375     dns_message_destroy(&client->message);
 3376 
 3377  cleanup_timer:
 3378     isc_timer_detach(&client->timer);
 3379 
 3380  cleanup_task:
 3381     isc_task_detach(&client->task);
 3382 
 3383  cleanup_client:
 3384     isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
 3385 
 3386     return (result);
 3387 }
 3388 
 3389 static void
 3390 client_read(ns_client_t *client) {
 3391     isc_result_t result;
 3392 
 3393     CTRACE("read");
 3394 
 3395     result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task,
 3396                     client_request, client);
 3397     if (result != ISC_R_SUCCESS)
 3398         goto fail;
 3399 
 3400     /*
 3401      * Set a timeout to limit the amount of time we will wait
 3402      * for a request on this TCP connection.
 3403      */
 3404     ns_client_settimeout(client, 30);
 3405 
 3406     client->state = client->newstate = NS_CLIENTSTATE_READING;
 3407     INSIST(client->nreads == 0);
 3408     INSIST(client->recursionquota == NULL);
 3409     client->nreads++;
 3410 
 3411     return;
 3412  fail:
 3413     ns_client_next(client, result);
 3414 }
 3415 
 3416 static void
 3417 client_newconn(isc_task_t *task, isc_event_t *event) {
 3418     isc_result_t result;
 3419     ns_client_t *client = event->ev_arg;
 3420     isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;
 3421 
 3422     REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN);
 3423     REQUIRE(NS_CLIENT_VALID(client));
 3424     REQUIRE(client->task == task);
 3425 
 3426     UNUSED(task);
 3427 
 3428     INSIST(client->state == NS_CLIENTSTATE_READY);
 3429 
 3430     /*
 3431      * The accept() was successful and we're now establishing a new
 3432      * connection. We need to make note of it in the client and
 3433      * interface objects so client objects can do the right thing
 3434      * when going inactive in exit_check() (see comments in
 3435      * client_accept() for details).
 3436      */
 3437     INSIST(client->naccepts == 1);
 3438     client->naccepts--;
 3439 
 3440     isc_refcount_decrement(&client->interface->ntcpaccepting, NULL);
 3441 
 3442     /*
 3443      * We must take ownership of the new socket before the exit
 3444      * check to make sure it gets destroyed if we decide to exit.
 3445      */
 3446     if (nevent->result == ISC_R_SUCCESS) {
 3447         client->tcpsocket = nevent->newsocket;
 3448         isc_socket_setname(client->tcpsocket, "client-tcp", NULL);
 3449         client->state = NS_CLIENTSTATE_READING;
 3450         INSIST(client->recursionquota == NULL);
 3451 
 3452         (void)isc_socket_getpeername(client->tcpsocket,
 3453                          &client->peeraddr);
 3454         client->peeraddr_valid = true;
 3455         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 3456                NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
 3457                "new TCP connection");
 3458     } else {
 3459         /*
 3460          * XXXRTH  What should we do?  We're trying to accept but
 3461          *     it didn't work.  If we just give up, then TCP
 3462          *     service may eventually stop.
 3463          *
 3464          *     For now, we just go idle.
 3465          *
 3466          *     Going idle is probably the right thing if the
 3467          *     I/O was canceled.
 3468          */
 3469         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 3470                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
 3471                   "accept failed: %s",
 3472                   isc_result_totext(nevent->result));
 3473         tcpconn_detach(client);
 3474     }
 3475 
 3476     if (exit_check(client))
 3477         goto freeevent;
 3478 
 3479     if (nevent->result == ISC_R_SUCCESS) {
 3480         int match;
 3481         isc_netaddr_t netaddr;
 3482 
 3483         isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
 3484 
 3485         if (ns_g_server->blackholeacl != NULL &&
 3486             dns_acl_match(&netaddr, NULL,
 3487                   ns_g_server->blackholeacl,
 3488                   &ns_g_server->aclenv,
 3489                   &match, NULL) == ISC_R_SUCCESS &&
 3490             match > 0)
 3491         {
 3492             ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 3493                       NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
 3494                       "blackholed connection attempt");
 3495             client->newstate = NS_CLIENTSTATE_READY;
 3496             (void)exit_check(client);
 3497             goto freeevent;
 3498         }
 3499 
 3500         INSIST(client->tcpmsg_valid == false);
 3501         dns_tcpmsg_init(client->mctx, client->tcpsocket,
 3502                 &client->tcpmsg);
 3503         client->tcpmsg_valid = true;
 3504 
 3505         /*
 3506          * Let a new client take our place immediately, before
 3507          * we wait for a request packet.  If we don't,
 3508          * telnetting to port 53 (once per CPU) will
 3509          * deny service to legitimate TCP clients.
 3510          */
 3511         result = ns_client_replace(client);
 3512         if (result == ISC_R_SUCCESS &&
 3513             (ns_g_server->keepresporder == NULL ||
 3514              !allowed(&netaddr, NULL, NULL, 0, NULL,
 3515                   ns_g_server->keepresporder)))
 3516         {
 3517             client->tcpconn->pipelined = true;
 3518         }
 3519 
 3520         client_read(client);
 3521     }
 3522 
 3523  freeevent:
 3524     isc_event_free(&event);
 3525 }
 3526 
 3527 static void
 3528 client_accept(ns_client_t *client) {
 3529     isc_result_t result;
 3530 
 3531     CTRACE("accept");
 3532     /*
 3533      * Set up a new TCP connection. This means try to attach to the
 3534      * TCP client quota (tcp-clients), but fail if we're over quota.
 3535      */
 3536     result = tcpconn_init(client, false);
 3537     if (result != ISC_R_SUCCESS) {
 3538         bool exit;
 3539 
 3540         ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 3541                   NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
 3542                   "TCP client quota reached: %s",
 3543                   isc_result_totext(result));
 3544 
 3545         /*
 3546          * We have exceeded the system-wide TCP client quota.  But,
 3547          * we can't just block this accept in all cases, because if
 3548          * we did, a heavy TCP load on other interfaces might cause
 3549          * this interface to be starved, with no clients able to
 3550          * accept new connections.
 3551          *
 3552          * So, we check here to see if any other clients are
 3553          * already servicing TCP queries on this interface (whether
 3554          * accepting, reading, or processing). If we find that at
 3555          * least one client other than this one is active, then
 3556          * it's okay *not* to call accept - we can let this
 3557          * client go inactive and another will take over when it's
 3558          * done.
 3559          *
 3560          * If there aren't enough active clients on the interface,
 3561          * then we can be a little bit flexible about the quota.
 3562          * We'll allow *one* extra client through to ensure we're
 3563          * listening on every interface; we do this by setting the
 3564          * 'force' option to tcpconn_init().
 3565          *
 3566          * (Note: In practice this means that the real TCP client
 3567          * quota is tcp-clients plus the number of listening
 3568          * interfaces plus 1.)
 3569          */
 3570         exit = (isc_refcount_current(&client->interface->ntcpactive) >
 3571             (client->tcpactive ? 1U : 0U));
 3572         if (exit) {
 3573             client->newstate = NS_CLIENTSTATE_INACTIVE;
 3574             (void)exit_check(client);
 3575             return;
 3576         }
 3577 
 3578         result = tcpconn_init(client, true);
 3579         RUNTIME_CHECK(result == ISC_R_SUCCESS);
 3580     }
 3581 
 3582     /* TCP high-water stats update. */
 3583     unsigned int curr_tcpquota = isc_quota_getused(&ns_g_server->tcpquota);
 3584     isc_stats_update_if_greater(ns_g_server->nsstats,
 3585                     dns_nsstatscounter_tcphighwater,
 3586                     curr_tcpquota);
 3587 
 3588     /*
 3589      * If this client was set up using get_client() or get_worker(),
 3590      * then TCP is already marked active. However, if it was restarted
 3591      * from exit_check(), it might not be, so we take care of it now.
 3592      */
 3593     mark_tcp_active(client, true);
 3594 
 3595     result = isc_socket_accept(client->tcplistener, client->task,
 3596                    client_newconn, client);
 3597     if (result != ISC_R_SUCCESS) {
 3598         /*
 3599          * XXXRTH  What should we do?  We're trying to accept but
 3600          *     it didn't work.  If we just give up, then TCP
 3601          *     service may eventually stop.
 3602          *
 3603          *     For now, we just go idle.
 3604          */
 3605         UNEXPECTED_ERROR(__FILE__, __LINE__,
 3606                  "isc_socket_accept() failed: %s",
 3607                  isc_result_totext(result));
 3608 
 3609         tcpconn_detach(client);
 3610         mark_tcp_active(client, false);
 3611         return;
 3612     }
 3613 
 3614     /*
 3615      * The client's 'naccepts' counter indicates that this client has
 3616      * called accept() and is waiting for a new connection. It should
 3617      * never exceed 1.
 3618      */
 3619     INSIST(client->naccepts == 0);
 3620     client->naccepts++;
 3621 
 3622     /*
 3623      * The interface's 'ntcpaccepting' counter is incremented when
 3624      * any client calls accept(), and decremented in client_newconn()
 3625      * once the connection is established.
 3626      *
 3627      * When the client object is shutting down after handling a TCP
 3628      * request (see exit_check()), if this value is at least one, that
 3629      * means another client has called accept() and is waiting to
 3630      * establish the next connection. That means the client may be
 3631      * be free to become inactive; otherwise it may need to start
 3632      * listening for connections itself to prevent the interface
 3633      * going dead.
 3634      */
 3635     isc_refcount_increment0(&client->interface->ntcpaccepting, NULL);
 3636 }
 3637 
 3638 static void
 3639 client_udprecv(ns_client_t *client) {
 3640     isc_result_t result;
 3641     isc_region_t r;
 3642 
 3643     CTRACE("udprecv");
 3644 
 3645     r.base = client->recvbuf;
 3646     r.length = RECV_BUFFER_SIZE;
 3647     result = isc_socket_recv2(client->udpsocket, &r, 1,
 3648                   client->task, client->recvevent, 0);
 3649     if (result != ISC_R_SUCCESS) {
 3650         UNEXPECTED_ERROR(__FILE__, __LINE__,
 3651                  "isc_socket_recv2() failed: %s",
 3652                  isc_result_totext(result));
 3653         /*
 3654          * This cannot happen in the current implementation, since
 3655          * isc_socket_recv2() cannot fail if flags == 0.
 3656          *
 3657          * If this does fail, we just go idle.
 3658          */
 3659         return;
 3660     }
 3661     INSIST(client->nrecvs == 0);
 3662     client->nrecvs++;
 3663 }
 3664 
 3665 void
 3666 ns_client_attach(ns_client_t *source, ns_client_t **targetp) {
 3667     REQUIRE(NS_CLIENT_VALID(source));
 3668     REQUIRE(targetp != NULL && *targetp == NULL);
 3669 
 3670     source->references++;
 3671     ns_client_log(source, NS_LOGCATEGORY_CLIENT,
 3672               NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
 3673               "ns_client_attach: ref = %d", source->references);
 3674     *targetp = source;
 3675 }
 3676 
 3677 void
 3678 ns_client_detach(ns_client_t **clientp) {
 3679     ns_client_t *client = *clientp;
 3680 
 3681     client->references--;
 3682     INSIST(client->references >= 0);
 3683     *clientp = NULL;
 3684     ns_client_log(client, NS_LOGCATEGORY_CLIENT,
 3685               NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
 3686               "ns_client_detach: ref = %d", client->references);
 3687     (void)exit_check(client);
 3688 }
 3689 
 3690 bool
 3691 ns_client_shuttingdown(ns_client_t *client) {
 3692     return (client->newstate == NS_CLIENTSTATE_FREED);
 3693 }
 3694 
 3695 isc_result_t
 3696 ns_client_replace(ns_client_t *client) {
 3697     isc_result_t result;
 3698     bool tcp;
 3699 
 3700     CTRACE("replace");
 3701 
 3702     REQUIRE(client != NULL);
 3703     REQUIRE(client->manager != NULL);
 3704 
 3705     tcp = TCP_CLIENT(client);
 3706     if (tcp && client->tcpconn != NULL && client->tcpconn->pipelined) {
 3707         result = get_worker(client->manager, client->interface,
 3708                     client->tcpsocket, client);
 3709     } else {
 3710         result = get_client(client->manager, client->interface,
 3711                     client->dispatch, tcp);
 3712 
 3713     }
 3714     if (result != ISC_R_SUCCESS) {
 3715         return (result);
 3716     }
 3717 
 3718     /*
 3719      * The responsibility for listening for new requests is hereby
 3720      * transferred to the new client.  Therefore, the old client
 3721      * should refrain from listening for any more requests.
 3722      */
 3723     client->mortal = true;
 3724 
 3725     return (ISC_R_SUCCESS);
 3726 }
 3727 
 3728 /***
 3729  *** Client Manager
 3730  ***/
 3731 
 3732 static void
 3733 clientmgr_destroy(ns_clientmgr_t *manager) {
 3734 #if NMCTXS > 0
 3735     int i;
 3736 #endif
 3737 
 3738     REQUIRE(ISC_LIST_EMPTY(manager->clients));
 3739 
 3740     MTRACE("clientmgr_destroy");
 3741 
 3742 #if NMCTXS > 0
 3743     for (i = 0; i < NMCTXS; i++) {
 3744         if (manager->mctxpool[i] != NULL)
 3745             isc_mem_detach(&manager->mctxpool[i]);
 3746     }
 3747 #endif
 3748 
 3749     ISC_QUEUE_DESTROY(manager->inactive);
 3750     DESTROYLOCK(&manager->lock);
 3751     DESTROYLOCK(&manager->listlock);
 3752     DESTROYLOCK(&manager->reclock);
 3753     manager->magic = 0;
 3754     isc_mem_put(manager->mctx, manager, sizeof(*manager));
 3755 }
 3756 
 3757 isc_result_t
 3758 ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
 3759             isc_timermgr_t *timermgr, ns_clientmgr_t **managerp)
 3760 {
 3761     ns_clientmgr_t *manager;
 3762     isc_result_t result;
 3763 #if NMCTXS > 0
 3764     int i;
 3765 #endif
 3766 
 3767     manager = isc_mem_get(mctx, sizeof(*manager));
 3768     if (manager == NULL)
 3769         return (ISC_R_NOMEMORY);
 3770 
 3771     result = isc_mutex_init(&manager->lock);
 3772     if (result != ISC_R_SUCCESS)
 3773         goto cleanup_manager;
 3774 
 3775     result = isc_mutex_init(&manager->listlock);
 3776     if (result != ISC_R_SUCCESS)
 3777         goto cleanup_lock;
 3778 
 3779     result = isc_mutex_init(&manager->reclock);
 3780     if (result != ISC_R_SUCCESS)
 3781         goto cleanup_listlock;
 3782 
 3783     manager->mctx = mctx;
 3784     manager->taskmgr = taskmgr;
 3785     manager->timermgr = timermgr;
 3786     manager->exiting = false;
 3787     ISC_LIST_INIT(manager->clients);
 3788     ISC_LIST_INIT(manager->recursing);
 3789     ISC_QUEUE_INIT(manager->inactive, ilink);
 3790 #if NMCTXS > 0
 3791     manager->nextmctx = 0;
 3792     for (i = 0; i < NMCTXS; i++)
 3793         manager->mctxpool[i] = NULL; /* will be created on-demand */
 3794 #endif
 3795     manager->magic = MANAGER_MAGIC;
 3796 
 3797     MTRACE("create");
 3798 
 3799     *managerp = manager;
 3800 
 3801     return (ISC_R_SUCCESS);
 3802 
 3803  cleanup_listlock:
 3804     (void) isc_mutex_destroy(&manager->listlock);
 3805 
 3806  cleanup_lock:
 3807     (void) isc_mutex_destroy(&manager->lock);
 3808 
 3809  cleanup_manager:
 3810     isc_mem_put(manager->mctx, manager, sizeof(*manager));
 3811 
 3812     return (result);
 3813 }
 3814 
 3815 void
 3816 ns_clientmgr_destroy(ns_clientmgr_t **managerp) {
 3817     isc_result_t result;
 3818     ns_clientmgr_t *manager;
 3819     ns_client_t *client;
 3820     bool need_destroy = false, unlock = false;
 3821 
 3822     REQUIRE(managerp != NULL);
 3823     manager = *managerp;
 3824     REQUIRE(VALID_MANAGER(manager));
 3825 
 3826     MTRACE("destroy");
 3827 
 3828     /*
 3829      * Check for success because we may already be task-exclusive
 3830      * at this point.  Only if we succeed at obtaining an exclusive
 3831      * lock now will we need to relinquish it later.
 3832      */
 3833     result = isc_task_beginexclusive(ns_g_server->task);
 3834     if (result == ISC_R_SUCCESS)
 3835         unlock = true;
 3836 
 3837     manager->exiting = true;
 3838 
 3839     for (client = ISC_LIST_HEAD(manager->clients);
 3840          client != NULL;
 3841          client = ISC_LIST_NEXT(client, link))
 3842         isc_task_shutdown(client->task);
 3843 
 3844     if (ISC_LIST_EMPTY(manager->clients))
 3845         need_destroy = true;
 3846 
 3847     if (unlock)
 3848         isc_task_endexclusive(ns_g_server->task);
 3849 
 3850     if (need_destroy)
 3851         clientmgr_destroy(manager);
 3852 
 3853     *managerp = NULL;
 3854 }
 3855 
 3856 static isc_result_t
 3857 get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
 3858        dns_dispatch_t *disp, bool tcp)
 3859 {
 3860     isc_result_t result = ISC_R_SUCCESS;
 3861     isc_event_t *ev;
 3862     ns_client_t *client;
 3863     MTRACE("get client");
 3864 
 3865     REQUIRE(manager != NULL);
 3866 
 3867     if (manager->exiting)
 3868         return (ISC_R_SHUTTINGDOWN);
 3869 
 3870     /*
 3871      * Allocate a client.  First try to get a recycled one;
 3872      * if that fails, make a new one.
 3873      */
 3874     client = NULL;
 3875     if (!ns_g_clienttest)
 3876         ISC_QUEUE_POP(manager->inactive, ilink, client);
 3877 
 3878     if (client != NULL)
 3879         MTRACE("recycle");
 3880     else {
 3881         MTRACE("create new");
 3882 
 3883         LOCK(&manager->lock);
 3884         result = client_create(manager, &client);
 3885         UNLOCK(&manager->lock);
 3886         if (result != ISC_R_SUCCESS)
 3887             return (result);
 3888 
 3889         LOCK(&manager->listlock);
 3890         ISC_LIST_APPEND(manager->clients, client, link);
 3891         UNLOCK(&manager->listlock);
 3892     }
 3893 
 3894     client->manager = manager;
 3895     ns_interface_attach(ifp, &client->interface);
 3896     client->state = NS_CLIENTSTATE_READY;
 3897     INSIST(client->recursionquota == NULL);
 3898 
 3899     client->dscp = ifp->dscp;
 3900 
 3901     if (tcp) {
 3902         mark_tcp_active(client, true);
 3903 
 3904         client->attributes |= NS_CLIENTATTR_TCP;
 3905         isc_socket_attach(ifp->tcpsocket,
 3906                   &client->tcplistener);
 3907 
 3908     } else {
 3909         isc_socket_t *sock;
 3910 
 3911         dns_dispatch_attach(disp, &client->dispatch);
 3912         sock = dns_dispatch_getsocket(client->dispatch);
 3913         isc_socket_attach(sock, &client->udpsocket);
 3914     }
 3915 
 3916     INSIST(client->nctls == 0);
 3917     client->nctls++;
 3918     ev = &client->ctlevent;
 3919     isc_task_send(client->task, &ev);
 3920 
 3921     return (result);
 3922 }
 3923 
 3924 static isc_result_t
 3925 get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock,
 3926        ns_client_t *oldclient)
 3927 {
 3928     isc_result_t result = ISC_R_SUCCESS;
 3929     isc_event_t *ev;
 3930     ns_client_t *client;
 3931     MTRACE("get worker");
 3932 
 3933     REQUIRE(manager != NULL);
 3934     REQUIRE(oldclient != NULL);
 3935 
 3936     if (manager->exiting)
 3937         return (ISC_R_SHUTTINGDOWN);
 3938 
 3939     /*
 3940      * Allocate a client.  First try to get a recycled one;
 3941      * if that fails, make a new one.
 3942      */
 3943     client = NULL;
 3944     if (!ns_g_clienttest)
 3945         ISC_QUEUE_POP(manager->inactive, ilink, client);
 3946 
 3947     if (client != NULL)
 3948         MTRACE("recycle");
 3949     else {
 3950         MTRACE("create new");
 3951 
 3952         LOCK(&manager->lock);
 3953         result = client_create(manager, &client);
 3954         UNLOCK(&manager->lock);
 3955         if (result != ISC_R_SUCCESS)
 3956             return (result);
 3957 
 3958         LOCK(&manager->listlock);
 3959         ISC_LIST_APPEND(manager->clients, client, link);
 3960         UNLOCK(&manager->listlock);
 3961     }
 3962 
 3963     client->manager = manager;
 3964     ns_interface_attach(ifp, &client->interface);
 3965     client->newstate = client->state = NS_CLIENTSTATE_WORKING;
 3966     INSIST(client->recursionquota == NULL);
 3967 
 3968     client->dscp = ifp->dscp;
 3969 
 3970     client->attributes |= NS_CLIENTATTR_TCP;
 3971     client->mortal = true;
 3972 
 3973     tcpconn_attach(oldclient, client);
 3974     mark_tcp_active(client, true);
 3975 
 3976     isc_socket_attach(ifp->tcpsocket, &client->tcplistener);
 3977     isc_socket_attach(sock, &client->tcpsocket);
 3978     isc_socket_setname(client->tcpsocket, "worker-tcp", NULL);
 3979     (void)isc_socket_getpeername(client->tcpsocket, &client->peeraddr);
 3980     client->peeraddr_valid = true;
 3981 
 3982     INSIST(client->tcpmsg_valid == false);
 3983     dns_tcpmsg_init(client->mctx, client->tcpsocket, &client->tcpmsg);
 3984     client->tcpmsg_valid = true;
 3985 
 3986     INSIST(client->nctls == 0);
 3987     client->nctls++;
 3988     ev = &client->ctlevent;
 3989     isc_task_send(client->task, &ev);
 3990 
 3991     return (result);
 3992 }
 3993 
 3994 isc_result_t
 3995 ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
 3996                ns_interface_t *ifp, bool tcp)
 3997 {
 3998     isc_result_t result = ISC_R_SUCCESS;
 3999     unsigned int disp;
 4000 
 4001     REQUIRE(VALID_MANAGER(manager));
 4002     REQUIRE(n > 0);
 4003 
 4004     MTRACE("createclients");
 4005 
 4006     for (disp = 0; disp < n; disp++) {
 4007         result = get_client(manager, ifp, ifp->udpdispatch[disp], tcp);
 4008         if (result != ISC_R_SUCCESS)
 4009             break;
 4010     }
 4011 
 4012     return (result);
 4013 }
 4014 
 4015 isc_sockaddr_t *
 4016 ns_client_getsockaddr(ns_client_t *client) {
 4017     return (&client->peeraddr);
 4018 }
 4019 
 4020 isc_sockaddr_t *
 4021 ns_client_getdestaddr(ns_client_t *client) {
 4022     return (&client->destsockaddr);
 4023 }
 4024 
 4025 isc_result_t
 4026 ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
 4027              dns_acl_t *acl, bool default_allow)
 4028 {
 4029     isc_result_t result;
 4030     isc_netaddr_t tmpnetaddr;
 4031     isc_netaddr_t *ecs_addr = NULL;
 4032     uint8_t ecs_addrlen = 0;
 4033     int match;
 4034 
 4035     if (acl == NULL) {
 4036         if (default_allow)
 4037             goto allow;
 4038         else
 4039             goto deny;
 4040     }
 4041 
 4042     if (netaddr == NULL) {
 4043         isc_netaddr_fromsockaddr(&tmpnetaddr, &client->peeraddr);
 4044         netaddr = &tmpnetaddr;
 4045     }
 4046 
 4047     if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) {
 4048         ecs_addr = &client->ecs_addr;
 4049         ecs_addrlen = client->ecs_addrlen;
 4050     }
 4051 
 4052     result = dns_acl_match2(netaddr, client->signer,
 4053                 ecs_addr, ecs_addrlen, NULL, acl,
 4054                 &ns_g_server->aclenv, &match, NULL);
 4055 
 4056     if (result != ISC_R_SUCCESS)
 4057         goto deny; /* Internal error, already logged. */
 4058 
 4059     if (match > 0)
 4060         goto allow;
 4061     goto deny; /* Negative match or no match. */
 4062 
 4063  allow:
 4064     return (ISC_R_SUCCESS);
 4065 
 4066  deny:
 4067     return (DNS_R_REFUSED);
 4068 }
 4069 
 4070 isc_result_t
 4071 ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr,
 4072            const char *opname, dns_acl_t *acl,
 4073            bool default_allow, int log_level)
 4074 {
 4075     isc_result_t result;
 4076     isc_netaddr_t netaddr;
 4077 
 4078     if (sockaddr != NULL)
 4079         isc_netaddr_fromsockaddr(&netaddr, sockaddr);
 4080 
 4081     result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL,
 4082                       acl, default_allow);
 4083 
 4084     if (result == ISC_R_SUCCESS)
 4085         ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 4086                   NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
 4087                   "%s approved", opname);
 4088     else
 4089         ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
 4090                   NS_LOGMODULE_CLIENT,
 4091                   log_level, "%s denied", opname);
 4092     return (result);
 4093 }
 4094 
 4095 static void
 4096 ns_client_name(ns_client_t *client, char *peerbuf, size_t len) {
 4097     if (client->peeraddr_valid)
 4098         isc_sockaddr_format(&client->peeraddr, peerbuf,
 4099                     (unsigned int)len);
 4100     else
 4101         snprintf(peerbuf, len, "@%p", client);
 4102 }
 4103 
 4104 void
 4105 ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
 4106            isc_logmodule_t *module, int level, const char *fmt, va_list ap)
 4107 {
 4108     char msgbuf[4096];
 4109     char signerbuf[DNS_NAME_FORMATSIZE], qnamebuf[DNS_NAME_FORMATSIZE];
 4110     char peerbuf[ISC_SOCKADDR_FORMATSIZE];
 4111     const char *viewname = "";
 4112     const char *sep1 = "", *sep2 = "", *sep3 = "", *sep4 = "";
 4113     const char *signer = "", *qname = "";
 4114     dns_name_t *q = NULL;
 4115 
 4116     REQUIRE(client != NULL);
 4117 
 4118     vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
 4119 
 4120     if (client->signer != NULL) {
 4121         dns_name_format(client->signer, signerbuf, sizeof(signerbuf));
 4122         sep1 = "/key ";
 4123         signer = signerbuf;
 4124     }
 4125 
 4126     q = client->query.origqname != NULL
 4127         ? client->query.origqname : client->query.qname;
 4128     if (q != NULL) {
 4129         dns_name_format(q, qnamebuf, sizeof(qnamebuf));
 4130         sep2 = " (";
 4131         sep3 = ")";
 4132         qname = qnamebuf;
 4133     }
 4134 
 4135     if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 &&
 4136         strcmp(client->view->name, "_default") != 0) {
 4137         sep4 = ": view ";
 4138         viewname = client->view->name;
 4139     }
 4140 
 4141     if (client->peeraddr_valid) {
 4142         isc_sockaddr_format(&client->peeraddr,
 4143                     peerbuf, sizeof(peerbuf));
 4144     } else {
 4145         snprintf(peerbuf, sizeof(peerbuf), "(no-peer)");
 4146     }
 4147 
 4148     isc_log_write(ns_g_lctx, category, module, level,
 4149               "client @%p %s%s%s%s%s%s%s%s: %s",
 4150               client, peerbuf, sep1, signer, sep2, qname, sep3,
 4151               sep4, viewname, msgbuf);
 4152 }
 4153 
 4154 void
 4155 ns_client_log(ns_client_t *client, isc_logcategory_t *category,
 4156        isc_logmodule_t *module, int level, const char *fmt, ...)
 4157 {
 4158     va_list ap;
 4159 
 4160     if (! isc_log_wouldlog(ns_g_lctx, level))
 4161         return;
 4162 
 4163     va_start(ap, fmt);
 4164     ns_client_logv(client, category, module, level, fmt, ap);
 4165     va_end(ap);
 4166 }
 4167 
 4168 void
 4169 ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type,
 4170          dns_rdataclass_t rdclass, char *buf, size_t len)
 4171 {
 4172     char namebuf[DNS_NAME_FORMATSIZE];
 4173     char typebuf[DNS_RDATATYPE_FORMATSIZE];
 4174     char classbuf[DNS_RDATACLASS_FORMATSIZE];
 4175 
 4176     dns_name_format(name, namebuf, sizeof(namebuf));
 4177     dns_rdatatype_format(type, typebuf, sizeof(typebuf));
 4178     dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf));
 4179     (void)snprintf(buf, len, "%s '%s/%s/%s'", msg, namebuf, typebuf,
 4180                classbuf);
 4181 }
 4182 
 4183 static void
 4184 ns_client_dumpmessage(ns_client_t *client, const char *reason) {
 4185     isc_buffer_t buffer;
 4186     char *buf = NULL;
 4187     int len = 1024;
 4188     isc_result_t result;
 4189 
 4190     if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(1)))
 4191         return;
 4192 
 4193     /*
 4194      * Note that these are multiline debug messages.  We want a newline
 4195      * to appear in the log after each message.
 4196      */
 4197 
 4198     do {
 4199         buf = isc_mem_get(client->mctx, len);
 4200         if (buf == NULL)
 4201             break;
 4202         isc_buffer_init(&buffer, buf, len);
 4203         result = dns_message_totext(client->message,
 4204                         &dns_master_style_debug,
 4205                         0, &buffer);
 4206         if (result == ISC_R_NOSPACE) {
 4207             isc_mem_put(client->mctx, buf, len);
 4208             len += 1024;
 4209         } else if (result == ISC_R_SUCCESS)
 4210             ns_client_log(client, NS_LOGCATEGORY_UNMATCHED,
 4211                       NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
 4212                       "%s\n%.*s", reason,
 4213                        (int)isc_buffer_usedlength(&buffer),
 4214                        buf);
 4215     } while (result == ISC_R_NOSPACE);
 4216 
 4217     if (buf != NULL)
 4218         isc_mem_put(client->mctx, buf, len);
 4219 }
 4220 
 4221 void
 4222 ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {
 4223     ns_client_t *client;
 4224     char namebuf[DNS_NAME_FORMATSIZE];
 4225     char original[DNS_NAME_FORMATSIZE];
 4226     char peerbuf[ISC_SOCKADDR_FORMATSIZE];
 4227     char typebuf[DNS_RDATATYPE_FORMATSIZE];
 4228     char classbuf[DNS_RDATACLASS_FORMATSIZE];
 4229     const char *name;
 4230     const char *sep;
 4231     const char *origfor;
 4232     dns_rdataset_t *rdataset;
 4233 
 4234     REQUIRE(VALID_MANAGER(manager));
 4235 
 4236     LOCK(&manager->reclock);
 4237     client = ISC_LIST_HEAD(manager->recursing);
 4238     while (client != NULL) {
 4239         INSIST(client->state == NS_CLIENTSTATE_RECURSING);
 4240 
 4241         ns_client_name(client, peerbuf, sizeof(peerbuf));
 4242         if (client->view != NULL &&
 4243             strcmp(client->view->name, "_bind") != 0 &&
 4244             strcmp(client->view->name, "_default") != 0) {
 4245             name = client->view->name;
 4246             sep = ": view ";
 4247         } else {
 4248             name = "";
 4249             sep = "";
 4250         }
 4251 
 4252         LOCK(&client->query.fetchlock);
 4253         INSIST(client->query.qname != NULL);
 4254         dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
 4255         if (client->query.qname != client->query.origqname &&
 4256             client->query.origqname != NULL) {
 4257             origfor = " for ";
 4258             dns_name_format(client->query.origqname, original,
 4259                     sizeof(original));
 4260         } else {
 4261             origfor = "";
 4262             original[0] = '\0';
 4263         }
 4264         rdataset = ISC_LIST_HEAD(client->query.qname->list);
 4265         if (rdataset == NULL && client->query.origqname != NULL)
 4266             rdataset = ISC_LIST_HEAD(client->query.origqname->list);
 4267         if (rdataset != NULL) {
 4268             dns_rdatatype_format(rdataset->type, typebuf,
 4269                          sizeof(typebuf));
 4270             dns_rdataclass_format(rdataset->rdclass, classbuf,
 4271                           sizeof(classbuf));
 4272         } else {
 4273             strlcpy(typebuf, "-", sizeof(typebuf));
 4274             strlcpy(classbuf, "-", sizeof(classbuf));
 4275         }
 4276         UNLOCK(&client->query.fetchlock);
 4277         fprintf(f, "; client %s%s%s: id %u '%s/%s/%s'%s%s "
 4278             "requesttime %u\n", peerbuf, sep, name,
 4279             client->message->id, namebuf, typebuf, classbuf,
 4280             origfor, original,
 4281             isc_time_seconds(&client->requesttime));
 4282         client = ISC_LIST_NEXT(client, rlink);
 4283     }
 4284     UNLOCK(&manager->reclock);
 4285 }
 4286 
 4287 void
 4288 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) {
 4289     LOCK(&client->query.fetchlock);
 4290     if (client->query.restarts > 0) {
 4291         /*
 4292          * client->query.qname was dynamically allocated.
 4293          */
 4294         dns_message_puttempname(client->message,
 4295                     &client->query.qname);
 4296     }
 4297     client->query.qname = name;
 4298     client->query.attributes &= ~NS_QUERYATTR_REDIRECT;
 4299     UNLOCK(&client->query.fetchlock);
 4300 }
 4301 
 4302 isc_result_t
 4303 ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp) {
 4304     ns_client_t *client = (ns_client_t *) ci->data;
 4305 
 4306     REQUIRE(NS_CLIENT_VALID(client));
 4307     REQUIRE(addrp != NULL);
 4308 
 4309     *addrp = &client->peeraddr;
 4310     return (ISC_R_SUCCESS);
 4311 }