00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <config.h>
00019
00020 #include <isc/formatcheck.h>
00021 #include <isc/mutex.h>
00022 #include <isc/once.h>
00023 #include <isc/platform.h>
00024 #include <isc/print.h>
00025 #include <isc/queue.h>
00026 #include <isc/random.h>
00027 #include <isc/serial.h>
00028 #include <isc/stats.h>
00029 #include <isc/stdio.h>
00030 #include <isc/string.h>
00031 #include <isc/task.h>
00032 #include <isc/timer.h>
00033 #include <isc/util.h>
00034
00035 #ifdef AES_SIT
00036 #include <isc/aes.h>
00037 #else
00038 #include <isc/hmacsha.h>
00039 #endif
00040
00041 #include <dns/badcache.h>
00042 #include <dns/db.h>
00043 #include <dns/dispatch.h>
00044 #include <dns/edns.h>
00045 #include <dns/events.h>
00046 #include <dns/message.h>
00047 #include <dns/peer.h>
00048 #include <dns/rcode.h>
00049 #include <dns/rdata.h>
00050 #include <dns/rdataclass.h>
00051 #include <dns/rdatalist.h>
00052 #include <dns/rdataset.h>
00053 #include <dns/resolver.h>
00054 #include <dns/stats.h>
00055 #include <dns/tsig.h>
00056 #include <dns/view.h>
00057 #include <dns/zone.h>
00058
00059 #include <named/interfacemgr.h>
00060 #include <named/log.h>
00061 #include <named/notify.h>
00062 #include <named/os.h>
00063 #include <named/server.h>
00064 #include <named/update.h>
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #define NS_CLIENT_TRACE
00084 #ifdef NS_CLIENT_TRACE
00085 #define CTRACE(m) ns_client_log(client, \
00086 NS_LOGCATEGORY_CLIENT, \
00087 NS_LOGMODULE_CLIENT, \
00088 ISC_LOG_DEBUG(3), \
00089 "%s", (m))
00090 #define MTRACE(m) isc_log_write(ns_g_lctx, \
00091 NS_LOGCATEGORY_GENERAL, \
00092 NS_LOGMODULE_CLIENT, \
00093 ISC_LOG_DEBUG(3), \
00094 "clientmgr @%p: %s", manager, (m))
00095 #else
00096 #define CTRACE(m) ((void)(m))
00097 #define MTRACE(m) ((void)(m))
00098 #endif
00099
00100 #define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0)
00101
00102 #define TCP_BUFFER_SIZE (65535 + 2)
00103 #define SEND_BUFFER_SIZE 4096
00104 #define RECV_BUFFER_SIZE 4096
00105
00106 #ifdef ISC_PLATFORM_USETHREADS
00107 #define NMCTXS 100
00108
00109
00110
00111
00112
00113
00114
00115
00116 #else
00117 #define NMCTXS 0
00118
00119
00120
00121
00122 #endif
00123
00124 #define SIT_SIZE 24U
00125 #define ECS_SIZE 20U
00126
00127
00128 struct ns_clientmgr {
00129
00130 unsigned int magic;
00131
00132
00133 client_queue_t inactive;
00134
00135 isc_mem_t * mctx;
00136 isc_taskmgr_t * taskmgr;
00137 isc_timermgr_t * timermgr;
00138
00139
00140 isc_mutex_t lock;
00141 isc_boolean_t exiting;
00142
00143
00144 isc_mutex_t listlock;
00145 client_list_t clients;
00146
00147
00148 isc_mutex_t reclock;
00149 client_list_t recursing;
00150
00151 #if NMCTXS > 0
00152
00153 unsigned int nextmctx;
00154 isc_mem_t * mctxpool[NMCTXS];
00155 #endif
00156 };
00157
00158 #define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm')
00159 #define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC)
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 #define NS_CLIENTSTATE_FREED 0
00174
00175
00176
00177
00178 #define NS_CLIENTSTATE_INACTIVE 1
00179
00180
00181
00182
00183
00184
00185
00186 #define NS_CLIENTSTATE_READY 2
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 #define NS_CLIENTSTATE_READING 3
00200
00201
00202
00203
00204
00205
00206
00207 #define NS_CLIENTSTATE_WORKING 4
00208
00209
00210
00211
00212
00213
00214 #define NS_CLIENTSTATE_RECURSING 5
00215
00216
00217
00218
00219
00220 #define NS_CLIENTSTATE_MAX 9
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 #ifndef NS_CLIENT_DROPPORT
00231 #define NS_CLIENT_DROPPORT 1
00232 #endif
00233
00234 unsigned int ns_client_requests;
00235
00236 static void client_read(ns_client_t *client);
00237 static void client_accept(ns_client_t *client);
00238 static void client_udprecv(ns_client_t *client);
00239 static void clientmgr_destroy(ns_clientmgr_t *manager);
00240 static isc_boolean_t exit_check(ns_client_t *client);
00241 static void ns_client_endrequest(ns_client_t *client);
00242 static void client_start(isc_task_t *task, isc_event_t *event);
00243 static void client_request(isc_task_t *task, isc_event_t *event);
00244 static void ns_client_dumpmessage(ns_client_t *client, const char *reason);
00245 static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
00246 dns_dispatch_t *disp, isc_boolean_t tcp);
00247 static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp,
00248 isc_socket_t *sock);
00249 static inline isc_boolean_t
00250 allowed(isc_netaddr_t *addr, dns_name_t *signer, isc_netaddr_t *ecs_addr,
00251 isc_uint8_t ecs_addrlen, isc_uint8_t *ecs_scope, dns_acl_t *acl);
00252 #ifdef ISC_PLATFORM_USESIT
00253 static void compute_sit(ns_client_t *client, isc_uint32_t when,
00254 isc_uint32_t nonce, isc_buffer_t *buf);
00255 #endif
00256
00257 void
00258 ns_client_recursing(ns_client_t *client) {
00259 REQUIRE(NS_CLIENT_VALID(client));
00260 REQUIRE(client->state == NS_CLIENTSTATE_WORKING);
00261
00262 LOCK(&client->manager->reclock);
00263 client->newstate = client->state = NS_CLIENTSTATE_RECURSING;
00264 ISC_LIST_APPEND(client->manager->recursing, client, rlink);
00265 UNLOCK(&client->manager->reclock);
00266 }
00267
00268 void
00269 ns_client_killoldestquery(ns_client_t *client) {
00270 ns_client_t *oldest;
00271 REQUIRE(NS_CLIENT_VALID(client));
00272
00273 LOCK(&client->manager->reclock);
00274 oldest = ISC_LIST_HEAD(client->manager->recursing);
00275 if (oldest != NULL) {
00276 ISC_LIST_UNLINK(client->manager->recursing, oldest, rlink);
00277 UNLOCK(&client->manager->reclock);
00278 ns_query_cancel(oldest);
00279 } else
00280 UNLOCK(&client->manager->reclock);
00281 }
00282
00283 void
00284 ns_client_settimeout(ns_client_t *client, unsigned int seconds) {
00285 isc_result_t result;
00286 isc_interval_t interval;
00287
00288 isc_interval_set(&interval, seconds, 0);
00289 result = isc_timer_reset(client->timer, isc_timertype_once, NULL,
00290 &interval, ISC_FALSE);
00291 client->timerset = ISC_TRUE;
00292 if (result != ISC_R_SUCCESS) {
00293 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
00294 NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
00295 "setting timeout: %s",
00296 isc_result_totext(result));
00297
00298 }
00299 }
00300
00301
00302
00303
00304
00305
00306
00307 static isc_boolean_t
00308 exit_check(ns_client_t *client) {
00309 isc_boolean_t destroy_manager = ISC_FALSE;
00310 ns_clientmgr_t *manager = NULL;
00311
00312 REQUIRE(NS_CLIENT_VALID(client));
00313 manager = client->manager;
00314
00315 if (client->state <= client->newstate)
00316 return (ISC_FALSE);
00317
00318 INSIST(client->newstate < NS_CLIENTSTATE_RECURSING);
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 if (client->nupdates == 0 &&
00332 client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL)
00333 dns_view_detach(&client->view);
00334
00335 if (client->state == NS_CLIENTSTATE_WORKING ||
00336 client->state == NS_CLIENTSTATE_RECURSING)
00337 {
00338 INSIST(client->newstate <= NS_CLIENTSTATE_READING);
00339
00340
00341
00342 if (client->nupdates > 0)
00343 return (ISC_TRUE);
00344
00345
00346
00347
00348 if (client->nsends > 0) {
00349 isc_socket_t *sock;
00350 if (TCP_CLIENT(client))
00351 sock = client->tcpsocket;
00352 else
00353 sock = client->udpsocket;
00354 isc_socket_cancel(sock, client->task,
00355 ISC_SOCKCANCEL_SEND);
00356 }
00357
00358 if (! (client->nsends == 0 && client->nrecvs == 0 &&
00359 client->references == 0))
00360 {
00361
00362
00363
00364
00365 return (ISC_TRUE);
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 if (client->state == NS_CLIENTSTATE_RECURSING) {
00378 LOCK(&manager->reclock);
00379 if (ISC_LINK_LINKED(client, rlink))
00380 ISC_LIST_UNLINK(manager->recursing,
00381 client, rlink);
00382 UNLOCK(&manager->reclock);
00383 }
00384 ns_client_endrequest(client);
00385
00386 client->state = NS_CLIENTSTATE_READING;
00387 INSIST(client->recursionquota == NULL);
00388
00389 if (NS_CLIENTSTATE_READING == client->newstate) {
00390 if (!client->pipelined) {
00391 client_read(client);
00392 client->newstate = NS_CLIENTSTATE_MAX;
00393 return (ISC_TRUE);
00394 } else if (client->mortal) {
00395 client->newstate = NS_CLIENTSTATE_INACTIVE;
00396 }
00397 }
00398 }
00399
00400 if (client->state == NS_CLIENTSTATE_READING) {
00401
00402
00403
00404
00405 INSIST(client->recursionquota == NULL);
00406 INSIST(client->newstate <= NS_CLIENTSTATE_READY);
00407 if (client->nreads > 0)
00408 dns_tcpmsg_cancelread(&client->tcpmsg);
00409 if (! client->nreads == 0) {
00410
00411 return (ISC_TRUE);
00412 }
00413
00414 if (client->tcpmsg_valid) {
00415 dns_tcpmsg_invalidate(&client->tcpmsg);
00416 client->tcpmsg_valid = ISC_FALSE;
00417 }
00418 if (client->tcpsocket != NULL) {
00419 CTRACE("closetcp");
00420 isc_socket_detach(&client->tcpsocket);
00421 }
00422
00423 if (client->tcpquota != NULL)
00424 isc_quota_detach(&client->tcpquota);
00425
00426 if (client->timerset) {
00427 (void)isc_timer_reset(client->timer,
00428 isc_timertype_inactive,
00429 NULL, NULL, ISC_TRUE);
00430 client->timerset = ISC_FALSE;
00431 }
00432
00433 client->pipelined = ISC_FALSE;
00434
00435 client->peeraddr_valid = ISC_FALSE;
00436
00437 client->state = NS_CLIENTSTATE_READY;
00438 INSIST(client->recursionquota == NULL);
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 if (client->mortal && TCP_CLIENT(client) && !ns_g_clienttest) {
00451 LOCK(&client->interface->lock);
00452 if (client->interface->ntcpcurrent <
00453 client->interface->ntcptarget)
00454 client->mortal = ISC_FALSE;
00455 UNLOCK(&client->interface->lock);
00456 }
00457
00458
00459
00460
00461
00462 if (client->mortal) {
00463 if (client->newstate > NS_CLIENTSTATE_INACTIVE)
00464 client->newstate = NS_CLIENTSTATE_INACTIVE;
00465 }
00466
00467 if (NS_CLIENTSTATE_READY == client->newstate) {
00468 if (TCP_CLIENT(client)) {
00469 client_accept(client);
00470 } else
00471 client_udprecv(client);
00472 client->newstate = NS_CLIENTSTATE_MAX;
00473 return (ISC_TRUE);
00474 }
00475 }
00476
00477 if (client->state == NS_CLIENTSTATE_READY) {
00478 INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE);
00479
00480
00481
00482
00483 if (client->naccepts > 0)
00484 isc_socket_cancel(client->tcplistener, client->task,
00485 ISC_SOCKCANCEL_ACCEPT);
00486
00487
00488 if (! (client->naccepts == 0))
00489 return (ISC_TRUE);
00490
00491
00492 if (client->nrecvs > 0)
00493 isc_socket_cancel(client->udpsocket, client->task,
00494 ISC_SOCKCANCEL_RECV);
00495
00496
00497 if (! (client->nrecvs == 0))
00498 return (ISC_TRUE);
00499
00500
00501 if (client->nctls > 0)
00502 return (ISC_TRUE);
00503
00504
00505 if (client->interface)
00506 ns_interface_detach(&client->interface);
00507
00508 INSIST(client->naccepts == 0);
00509 INSIST(client->recursionquota == NULL);
00510 if (client->tcplistener != NULL)
00511 isc_socket_detach(&client->tcplistener);
00512
00513 if (client->udpsocket != NULL)
00514 isc_socket_detach(&client->udpsocket);
00515
00516 if (client->dispatch != NULL)
00517 dns_dispatch_detach(&client->dispatch);
00518
00519 client->attributes = 0;
00520 client->mortal = ISC_FALSE;
00521
00522
00523
00524
00525
00526
00527
00528
00529 client->state = NS_CLIENTSTATE_INACTIVE;
00530 INSIST(client->recursionquota == NULL);
00531
00532 if (client->state == client->newstate) {
00533 client->newstate = NS_CLIENTSTATE_MAX;
00534 if (!ns_g_clienttest && manager != NULL &&
00535 !manager->exiting)
00536 ISC_QUEUE_PUSH(manager->inactive, client,
00537 ilink);
00538 if (client->needshutdown)
00539 isc_task_shutdown(client->task);
00540 return (ISC_TRUE);
00541 }
00542 }
00543
00544 if (client->state == NS_CLIENTSTATE_INACTIVE) {
00545 INSIST(client->newstate == NS_CLIENTSTATE_FREED);
00546
00547
00548
00549
00550
00551
00552
00553
00554 REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE);
00555
00556 INSIST(client->recursionquota == NULL);
00557 INSIST(!ISC_QLINK_LINKED(client, ilink));
00558
00559 if (manager != NULL) {
00560 LOCK(&manager->listlock);
00561 ISC_LIST_UNLINK(manager->clients, client, link);
00562 LOCK(&manager->lock);
00563 if (manager->exiting &&
00564 ISC_LIST_EMPTY(manager->clients))
00565 destroy_manager = ISC_TRUE;
00566 UNLOCK(&manager->lock);
00567 UNLOCK(&manager->listlock);
00568 }
00569
00570 ns_query_free(client);
00571 isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE);
00572 isc_event_free((isc_event_t **)&client->sendevent);
00573 isc_event_free((isc_event_t **)&client->recvevent);
00574 isc_timer_detach(&client->timer);
00575 if (client->delaytimer != NULL)
00576 isc_timer_detach(&client->delaytimer);
00577
00578 if (client->tcpbuf != NULL)
00579 isc_mem_put(client->mctx, client->tcpbuf,
00580 TCP_BUFFER_SIZE);
00581 if (client->opt != NULL) {
00582 INSIST(dns_rdataset_isassociated(client->opt));
00583 dns_rdataset_disassociate(client->opt);
00584 dns_message_puttemprdataset(client->message,
00585 &client->opt);
00586 }
00587
00588 dns_message_destroy(&client->message);
00589
00590
00591
00592
00593
00594
00595 if (client->task != NULL)
00596 isc_task_detach(&client->task);
00597
00598 CTRACE("free");
00599 client->magic = 0;
00600
00601
00602
00603
00604
00605 if (ns_g_clienttest && isc_mem_references(client->mctx) != 1) {
00606 isc_mem_stats(client->mctx, stderr);
00607 INSIST(0);
00608 }
00609
00610
00611
00612
00613
00614 DESTROYLOCK(&client->query.fetchlock);
00615
00616 isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
00617 }
00618
00619 if (destroy_manager && manager != NULL)
00620 clientmgr_destroy(manager);
00621
00622 return (ISC_TRUE);
00623 }
00624
00625
00626
00627
00628
00629 static void
00630 client_start(isc_task_t *task, isc_event_t *event) {
00631 ns_client_t *client = (ns_client_t *) event->ev_arg;
00632
00633 INSIST(task == client->task);
00634
00635 UNUSED(task);
00636
00637 INSIST(client->nctls == 1);
00638 client->nctls--;
00639
00640 if (exit_check(client))
00641 return;
00642
00643 if (TCP_CLIENT(client)) {
00644 if (client->pipelined) {
00645 client_read(client);
00646 } else {
00647 client_accept(client);
00648 }
00649 } else {
00650 client_udprecv(client);
00651 }
00652 }
00653
00654
00655
00656
00657
00658 static void
00659 client_shutdown(isc_task_t *task, isc_event_t *event) {
00660 ns_client_t *client;
00661
00662 REQUIRE(event != NULL);
00663 REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN);
00664 client = event->ev_arg;
00665 REQUIRE(NS_CLIENT_VALID(client));
00666 REQUIRE(task == client->task);
00667
00668 UNUSED(task);
00669
00670 CTRACE("shutdown");
00671
00672 isc_event_free(&event);
00673
00674 if (client->shutdown != NULL) {
00675 (client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN);
00676 client->shutdown = NULL;
00677 client->shutdown_arg = NULL;
00678 }
00679
00680 if (ISC_QLINK_LINKED(client, ilink))
00681 ISC_QUEUE_UNLINK(client->manager->inactive, client, ilink);
00682
00683 client->newstate = NS_CLIENTSTATE_FREED;
00684 client->needshutdown = ISC_FALSE;
00685 (void)exit_check(client);
00686 }
00687
00688 static void
00689 ns_client_endrequest(ns_client_t *client) {
00690 INSIST(client->naccepts == 0);
00691 INSIST(client->nreads == 0);
00692 INSIST(client->nsends == 0);
00693 INSIST(client->nrecvs == 0);
00694 INSIST(client->nupdates == 0);
00695 INSIST(client->state == NS_CLIENTSTATE_WORKING ||
00696 client->state == NS_CLIENTSTATE_RECURSING);
00697
00698 CTRACE("endrequest");
00699
00700 if (client->next != NULL) {
00701 (client->next)(client);
00702 client->next = NULL;
00703 }
00704
00705 if (client->view != NULL)
00706 dns_view_detach(&client->view);
00707 if (client->opt != NULL) {
00708 INSIST(dns_rdataset_isassociated(client->opt));
00709 dns_rdataset_disassociate(client->opt);
00710 dns_message_puttemprdataset(client->message, &client->opt);
00711 }
00712
00713 client->signer = NULL;
00714 client->udpsize = 512;
00715 client->extflags = 0;
00716 client->ednsversion = -1;
00717 dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
00718
00719 if (client->recursionquota != NULL) {
00720 isc_quota_detach(&client->recursionquota);
00721 isc_stats_decrement(ns_g_server->nsstats,
00722 dns_nsstatscounter_recursclients);
00723 }
00724
00725
00726
00727
00728
00729 client->attributes &= NS_CLIENTATTR_TCP;
00730 }
00731
00732 void
00733 ns_client_next(ns_client_t *client, isc_result_t result) {
00734 int newstate;
00735
00736 REQUIRE(NS_CLIENT_VALID(client));
00737 REQUIRE(client->state == NS_CLIENTSTATE_WORKING ||
00738 client->state == NS_CLIENTSTATE_RECURSING ||
00739 client->state == NS_CLIENTSTATE_READING);
00740
00741 CTRACE("next");
00742
00743 if (result != ISC_R_SUCCESS)
00744 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
00745 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
00746 "request failed: %s", isc_result_totext(result));
00747
00748
00749
00750
00751
00752
00753 if (result == ISC_R_SUCCESS && TCP_CLIENT(client))
00754 newstate = NS_CLIENTSTATE_READING;
00755 else
00756 newstate = NS_CLIENTSTATE_READY;
00757
00758 if (client->newstate > newstate)
00759 client->newstate = newstate;
00760 (void)exit_check(client);
00761 }
00762
00763
00764 static void
00765 client_senddone(isc_task_t *task, isc_event_t *event) {
00766 ns_client_t *client;
00767 isc_socketevent_t *sevent = (isc_socketevent_t *) event;
00768
00769 REQUIRE(sevent != NULL);
00770 REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE);
00771 client = sevent->ev_arg;
00772 REQUIRE(NS_CLIENT_VALID(client));
00773 REQUIRE(task == client->task);
00774 REQUIRE(sevent == client->sendevent);
00775
00776 UNUSED(task);
00777
00778 CTRACE("senddone");
00779
00780 if (sevent->result != ISC_R_SUCCESS)
00781 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
00782 NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
00783 "error sending response: %s",
00784 isc_result_totext(sevent->result));
00785
00786 INSIST(client->nsends > 0);
00787 client->nsends--;
00788
00789 if (client->tcpbuf != NULL) {
00790 INSIST(TCP_CLIENT(client));
00791 isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
00792 client->tcpbuf = NULL;
00793 }
00794
00795 ns_client_next(client, ISC_R_SUCCESS);
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 static isc_result_t
00807 client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,
00808 isc_buffer_t *tcpbuffer, isc_uint32_t length,
00809 unsigned char *sendbuf, unsigned char **datap)
00810 {
00811 unsigned char *data;
00812 isc_uint32_t bufsize;
00813 isc_result_t result;
00814
00815 INSIST(datap != NULL);
00816 INSIST((tcpbuffer == NULL && length != 0) ||
00817 (tcpbuffer != NULL && length == 0));
00818
00819 if (TCP_CLIENT(client)) {
00820 INSIST(client->tcpbuf == NULL);
00821 if (length + 2 > TCP_BUFFER_SIZE) {
00822 result = ISC_R_NOSPACE;
00823 goto done;
00824 }
00825 client->tcpbuf = isc_mem_get(client->mctx, TCP_BUFFER_SIZE);
00826 if (client->tcpbuf == NULL) {
00827 result = ISC_R_NOMEMORY;
00828 goto done;
00829 }
00830 data = client->tcpbuf;
00831 if (tcpbuffer != NULL) {
00832 isc_buffer_init(tcpbuffer, data, TCP_BUFFER_SIZE);
00833 isc_buffer_init(buffer, data + 2, TCP_BUFFER_SIZE - 2);
00834 } else {
00835 isc_buffer_init(buffer, data, TCP_BUFFER_SIZE);
00836 INSIST(length <= 0xffff);
00837 isc_buffer_putuint16(buffer, (isc_uint16_t)length);
00838 }
00839 } else {
00840 data = sendbuf;
00841 #ifdef ISC_PLATFORM_USESIT
00842 if ((client->attributes & NS_CLIENTATTR_HAVESIT) == 0) {
00843 if (client->view != NULL)
00844 bufsize = client->view->situdp;
00845 else
00846 bufsize = 512;
00847 } else
00848 bufsize = client->udpsize;
00849 if (bufsize > client->udpsize)
00850 bufsize = client->udpsize;
00851 if (bufsize > SEND_BUFFER_SIZE)
00852 bufsize = SEND_BUFFER_SIZE;
00853 #else
00854 if (client->udpsize < SEND_BUFFER_SIZE)
00855 bufsize = client->udpsize;
00856 else
00857 bufsize = SEND_BUFFER_SIZE;
00858 #endif
00859 if (length > bufsize) {
00860 result = ISC_R_NOSPACE;
00861 goto done;
00862 }
00863 isc_buffer_init(buffer, data, bufsize);
00864 }
00865 *datap = data;
00866 result = ISC_R_SUCCESS;
00867
00868 done:
00869 return (result);
00870 }
00871
00872 static isc_result_t
00873 client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
00874 struct in6_pktinfo *pktinfo;
00875 isc_result_t result;
00876 isc_region_t r;
00877 isc_sockaddr_t *address;
00878 isc_socket_t *sock;
00879 isc_netaddr_t netaddr;
00880 int match;
00881 unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE;
00882 isc_dscp_t dispdscp = -1;
00883
00884 if (TCP_CLIENT(client)) {
00885 sock = client->tcpsocket;
00886 address = NULL;
00887 } else {
00888 sock = client->udpsocket;
00889 address = &client->peeraddr;
00890
00891 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
00892 if (ns_g_server->blackholeacl != NULL &&
00893 dns_acl_match(&netaddr, NULL,
00894 ns_g_server->blackholeacl,
00895 &ns_g_server->aclenv,
00896 &match, NULL) == ISC_R_SUCCESS &&
00897 match > 0)
00898 return (DNS_R_BLACKHOLED);
00899 sockflags |= ISC_SOCKFLAG_NORETRY;
00900 }
00901
00902 if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0 &&
00903 (client->attributes & NS_CLIENTATTR_MULTICAST) == 0)
00904 pktinfo = &client->pktinfo;
00905 else
00906 pktinfo = NULL;
00907
00908 if (client->dispatch != NULL) {
00909 dispdscp = dns_dispatch_getdscp(client->dispatch);
00910 if (dispdscp != -1)
00911 client->dscp = dispdscp;
00912 }
00913
00914 if (client->dscp == -1) {
00915 client->sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP;
00916 client->sendevent->dscp = 0;
00917 } else {
00918 client->sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP;
00919 client->sendevent->dscp = client->dscp;
00920 }
00921
00922 isc_buffer_usedregion(buffer, &r);
00923
00924 CTRACE("sendto");
00925
00926 result = isc_socket_sendto2(sock, &r, client->task,
00927 address, pktinfo,
00928 client->sendevent, sockflags);
00929 if (result == ISC_R_SUCCESS || result == ISC_R_INPROGRESS) {
00930 client->nsends++;
00931 if (result == ISC_R_SUCCESS)
00932 client_senddone(client->task,
00933 (isc_event_t *)client->sendevent);
00934 result = ISC_R_SUCCESS;
00935 }
00936 return (result);
00937 }
00938
00939 void
00940 ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
00941 isc_result_t result;
00942 unsigned char *data;
00943 isc_buffer_t buffer;
00944 isc_region_t r;
00945 isc_region_t *mr;
00946 unsigned char sendbuf[SEND_BUFFER_SIZE];
00947
00948 REQUIRE(NS_CLIENT_VALID(client));
00949
00950 CTRACE("sendraw");
00951
00952 mr = dns_message_getrawmessage(message);
00953 if (mr == NULL) {
00954 result = ISC_R_UNEXPECTEDEND;
00955 goto done;
00956 }
00957
00958 result = client_allocsendbuf(client, &buffer, NULL, mr->length,
00959 sendbuf, &data);
00960 if (result != ISC_R_SUCCESS)
00961 goto done;
00962
00963
00964
00965
00966 isc_buffer_availableregion(&buffer, &r);
00967 result = isc_buffer_copyregion(&buffer, mr);
00968 if (result != ISC_R_SUCCESS)
00969 goto done;
00970 r.base[0] = (client->message->id >> 8) & 0xff;
00971 r.base[1] = client->message->id & 0xff;
00972
00973 result = client_sendpkg(client, &buffer);
00974 if (result == ISC_R_SUCCESS)
00975 return;
00976
00977 done:
00978 if (client->tcpbuf != NULL) {
00979 isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
00980 client->tcpbuf = NULL;
00981 }
00982 ns_client_next(client, result);
00983 }
00984
00985 static void
00986 client_send(ns_client_t *client) {
00987 isc_result_t result;
00988 unsigned char *data;
00989 isc_buffer_t buffer;
00990 isc_buffer_t tcpbuffer;
00991 isc_region_t r;
00992 dns_compress_t cctx;
00993 isc_boolean_t cleanup_cctx = ISC_FALSE;
00994 unsigned char sendbuf[SEND_BUFFER_SIZE];
00995 unsigned int render_opts;
00996 unsigned int preferred_glue;
00997 isc_boolean_t opt_included = ISC_FALSE;
00998
00999 REQUIRE(NS_CLIENT_VALID(client));
01000
01001 CTRACE("send");
01002
01003 if ((client->attributes & NS_CLIENTATTR_RA) != 0)
01004 client->message->flags |= DNS_MESSAGEFLAG_RA;
01005
01006 if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0)
01007 render_opts = 0;
01008 else
01009 render_opts = DNS_MESSAGERENDER_OMITDNSSEC;
01010
01011 preferred_glue = 0;
01012 if (client->view != NULL) {
01013 if (client->view->preferred_glue == dns_rdatatype_a)
01014 preferred_glue = DNS_MESSAGERENDER_PREFER_A;
01015 else if (client->view->preferred_glue == dns_rdatatype_aaaa)
01016 preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA;
01017 }
01018
01019 #ifdef ALLOW_FILTER_AAAA
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031 if ((client->attributes & NS_CLIENTATTR_FILTER_AAAA) != 0) {
01032 render_opts |= DNS_MESSAGERENDER_FILTER_AAAA;
01033 if (preferred_glue == DNS_MESSAGERENDER_PREFER_AAAA)
01034 preferred_glue = DNS_MESSAGERENDER_PREFER_A;
01035 }
01036 #endif
01037
01038
01039
01040
01041 if ((client->attributes & NS_CLIENTATTR_WANTOPT) != 0) {
01042 result = ns_client_addopt(client, client->message,
01043 &client->opt);
01044 if (result != ISC_R_SUCCESS)
01045 goto done;
01046 }
01047
01048
01049
01050
01051 result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0,
01052 sendbuf, &data);
01053 if (result != ISC_R_SUCCESS)
01054 goto done;
01055
01056 result = dns_compress_init(&cctx, -1, client->mctx);
01057 if (result != ISC_R_SUCCESS)
01058 goto done;
01059 if (client->peeraddr_valid && client->view != NULL) {
01060 isc_netaddr_t netaddr;
01061 dns_name_t *name = NULL;
01062
01063 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
01064 if (client->message->tsigkey != NULL)
01065 name = &client->message->tsigkey->name;
01066 if (client->view->nocasecompress == NULL ||
01067 !allowed(&netaddr, name, NULL, 0, NULL,
01068 client->view->nocasecompress))
01069 {
01070 dns_compress_setsensitive(&cctx, ISC_TRUE);
01071 }
01072 }
01073 cleanup_cctx = ISC_TRUE;
01074
01075 result = dns_message_renderbegin(client->message, &cctx, &buffer);
01076 if (result != ISC_R_SUCCESS)
01077 goto done;
01078
01079 if (client->opt != NULL) {
01080 result = dns_message_setopt(client->message, client->opt);
01081 opt_included = ISC_TRUE;
01082 client->opt = NULL;
01083 if (result != ISC_R_SUCCESS)
01084 goto done;
01085 }
01086 result = dns_message_rendersection(client->message,
01087 DNS_SECTION_QUESTION, 0);
01088 if (result == ISC_R_NOSPACE) {
01089 client->message->flags |= DNS_MESSAGEFLAG_TC;
01090 goto renderend;
01091 }
01092 if (result != ISC_R_SUCCESS)
01093 goto done;
01094
01095
01096
01097 if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0)
01098 goto renderend;
01099 result = dns_message_rendersection(client->message,
01100 DNS_SECTION_ANSWER,
01101 DNS_MESSAGERENDER_PARTIAL |
01102 render_opts);
01103 if (result == ISC_R_NOSPACE) {
01104 client->message->flags |= DNS_MESSAGEFLAG_TC;
01105 goto renderend;
01106 }
01107 if (result != ISC_R_SUCCESS)
01108 goto done;
01109 result = dns_message_rendersection(client->message,
01110 DNS_SECTION_AUTHORITY,
01111 DNS_MESSAGERENDER_PARTIAL |
01112 render_opts);
01113 if (result == ISC_R_NOSPACE) {
01114 client->message->flags |= DNS_MESSAGEFLAG_TC;
01115 goto renderend;
01116 }
01117 if (result != ISC_R_SUCCESS)
01118 goto done;
01119 result = dns_message_rendersection(client->message,
01120 DNS_SECTION_ADDITIONAL,
01121 preferred_glue | render_opts);
01122 if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
01123 goto done;
01124 renderend:
01125 result = dns_message_renderend(client->message);
01126
01127 if (result != ISC_R_SUCCESS)
01128 goto done;
01129
01130 if (cleanup_cctx) {
01131 dns_compress_invalidate(&cctx);
01132 cleanup_cctx = ISC_FALSE;
01133 }
01134
01135 if (TCP_CLIENT(client)) {
01136 isc_buffer_usedregion(&buffer, &r);
01137 isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t) r.length);
01138 isc_buffer_add(&tcpbuffer, r.length);
01139 result = client_sendpkg(client, &tcpbuffer);
01140 } else
01141 result = client_sendpkg(client, &buffer);
01142
01143
01144 isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_response);
01145 if (opt_included) {
01146 isc_stats_increment(ns_g_server->nsstats,
01147 dns_nsstatscounter_edns0out);
01148 }
01149 if (client->message->tsigkey != NULL) {
01150 isc_stats_increment(ns_g_server->nsstats,
01151 dns_nsstatscounter_tsigout);
01152 }
01153 if (client->message->sig0key != NULL) {
01154 isc_stats_increment(ns_g_server->nsstats,
01155 dns_nsstatscounter_sig0out);
01156 }
01157 if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0)
01158 isc_stats_increment(ns_g_server->nsstats,
01159 dns_nsstatscounter_truncatedresp);
01160
01161 if (result == ISC_R_SUCCESS)
01162 return;
01163
01164 done:
01165 if (client->tcpbuf != NULL) {
01166 isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
01167 client->tcpbuf = NULL;
01168 }
01169
01170 if (cleanup_cctx)
01171 dns_compress_invalidate(&cctx);
01172
01173 ns_client_next(client, result);
01174 }
01175
01176
01177
01178
01179 static void
01180 client_delay(isc_task_t *task, isc_event_t *event) {
01181 ns_client_t *client;
01182
01183 REQUIRE(event != NULL);
01184 REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE ||
01185 event->ev_type == ISC_TIMEREVENT_IDLE);
01186 client = event->ev_arg;
01187 REQUIRE(NS_CLIENT_VALID(client));
01188 REQUIRE(task == client->task);
01189 REQUIRE(client->delaytimer != NULL);
01190
01191 UNUSED(task);
01192
01193 CTRACE("client_delay");
01194
01195 isc_event_free(&event);
01196 isc_timer_detach(&client->delaytimer);
01197
01198 client_send(client);
01199 ns_client_detach(&client);
01200 }
01201
01202 void
01203 ns_client_send(ns_client_t *client) {
01204
01205
01206
01207
01208 if (ns_g_delay != 0) {
01209 ns_client_t *dummy = NULL;
01210 isc_result_t result;
01211 isc_interval_t interval;
01212
01213
01214
01215
01216 if (!client->mortal) {
01217 result = ns_client_replace(client);
01218 if (result != ISC_R_SUCCESS)
01219 goto nodelay;
01220 }
01221
01222 ns_client_attach(client, &dummy);
01223 if (ns_g_delay >= 1000)
01224 isc_interval_set(&interval, ns_g_delay / 1000,
01225 (ns_g_delay % 1000) * 1000000);
01226 else
01227 isc_interval_set(&interval, 0, ns_g_delay * 1000000);
01228 result = isc_timer_create(client->manager->timermgr,
01229 isc_timertype_once, NULL, &interval,
01230 client->task, client_delay,
01231 client, &client->delaytimer);
01232 if (result == ISC_R_SUCCESS)
01233 return;
01234
01235 ns_client_detach(&dummy);
01236 }
01237
01238 nodelay:
01239 client_send(client);
01240 }
01241
01242 #if NS_CLIENT_DROPPORT
01243 #define DROPPORT_NO 0
01244 #define DROPPORT_REQUEST 1
01245 #define DROPPORT_RESPONSE 2
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255 static int
01256 ns_client_dropport(in_port_t port) {
01257 switch (port) {
01258 case 7:
01259 case 13:
01260 case 19:
01261 case 37:
01262 return (DROPPORT_REQUEST);
01263 case 464:
01264 return (DROPPORT_RESPONSE);
01265 }
01266 return (DROPPORT_NO);
01267 }
01268 #endif
01269
01270 void
01271 ns_client_error(ns_client_t *client, isc_result_t result) {
01272 dns_rcode_t rcode;
01273 dns_message_t *message;
01274
01275 REQUIRE(NS_CLIENT_VALID(client));
01276
01277 CTRACE("error");
01278
01279 message = client->message;
01280 rcode = dns_result_torcode(result);
01281
01282 #if NS_CLIENT_DROPPORT
01283
01284
01285
01286 if (rcode == dns_rcode_formerr &&
01287 ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) !=
01288 DROPPORT_NO) {
01289 char buf[64];
01290 isc_buffer_t b;
01291
01292 isc_buffer_init(&b, buf, sizeof(buf) - 1);
01293 if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS)
01294 isc_buffer_putstr(&b, "UNKNOWN RCODE");
01295 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
01296 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
01297 "dropped error (%.*s) response: suspicious port",
01298 (int)isc_buffer_usedlength(&b), buf);
01299 ns_client_next(client, ISC_R_SUCCESS);
01300 return;
01301 }
01302 #endif
01303
01304
01305
01306
01307 if (client->view != NULL && client->view->rrl != NULL) {
01308 isc_boolean_t wouldlog;
01309 char log_buf[DNS_RRL_LOG_BUF_LEN];
01310 dns_rrl_result_t rrl_result;
01311 int loglevel;
01312
01313 INSIST(rcode != dns_rcode_noerror &&
01314 rcode != dns_rcode_nxdomain);
01315 if (ns_g_server->log_queries)
01316 loglevel = DNS_RRL_LOG_DROP;
01317 else
01318 loglevel = ISC_LOG_DEBUG(1);
01319 wouldlog = isc_log_wouldlog(ns_g_lctx, loglevel);
01320 rrl_result = dns_rrl(client->view, &client->peeraddr,
01321 TCP_CLIENT(client),
01322 dns_rdataclass_in, dns_rdatatype_none,
01323 NULL, result, client->now,
01324 wouldlog, log_buf, sizeof(log_buf));
01325 if (rrl_result != DNS_RRL_RESULT_OK) {
01326
01327
01328
01329
01330
01331
01332 if (wouldlog) {
01333 ns_client_log(client,
01334 NS_LOGCATEGORY_QUERY_EERRORS,
01335 NS_LOGMODULE_CLIENT,
01336 loglevel,
01337 "%s", log_buf);
01338 }
01339
01340
01341
01342
01343 if (!client->view->rrl->log_only) {
01344 isc_stats_increment(ns_g_server->nsstats,
01345 dns_nsstatscounter_ratedropped);
01346 isc_stats_increment(ns_g_server->nsstats,
01347 dns_nsstatscounter_dropped);
01348 ns_client_next(client, DNS_R_DROP);
01349 return;
01350 }
01351 }
01352 }
01353
01354
01355
01356
01357
01358
01359 message->flags &= ~DNS_MESSAGEFLAG_QR;
01360
01361
01362
01363 message->flags &= ~(DNS_MESSAGEFLAG_AA | DNS_MESSAGEFLAG_AD);
01364 result = dns_message_reply(message, ISC_TRUE);
01365 if (result != ISC_R_SUCCESS) {
01366
01367
01368
01369
01370
01371 result = dns_message_reply(message, ISC_FALSE);
01372 if (result != ISC_R_SUCCESS) {
01373 ns_client_next(client, result);
01374 return;
01375 }
01376 }
01377 message->rcode = rcode;
01378
01379 if (rcode == dns_rcode_formerr) {
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389 if (isc_sockaddr_equal(&client->peeraddr,
01390 &client->formerrcache.addr) &&
01391 message->id == client->formerrcache.id &&
01392 client->requesttime - client->formerrcache.time < 2) {
01393
01394 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
01395 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
01396 "possible error packet loop, "
01397 "FORMERR dropped");
01398 ns_client_next(client, result);
01399 return;
01400 }
01401 client->formerrcache.addr = client->peeraddr;
01402 client->formerrcache.time = client->requesttime;
01403 client->formerrcache.id = message->id;
01404 } else if (rcode == dns_rcode_servfail && client->query.qname != NULL &&
01405 client->view != NULL && client->view->fail_ttl != 0 &&
01406 ((client->attributes & NS_CLIENTATTR_NOSETFC) == 0))
01407 {
01408
01409
01410
01411 isc_time_t expire;
01412 isc_interval_t i;
01413 isc_uint32_t flags = 0;
01414
01415 if ((message->flags & DNS_MESSAGEFLAG_CD) != 0)
01416 flags = NS_FAILCACHE_CD;
01417
01418 isc_interval_set(&i, client->view->fail_ttl, 0);
01419 result = isc_time_nowplusinterval(&expire, &i);
01420 if (result == ISC_R_SUCCESS)
01421 dns_badcache_add(client->view->failcache,
01422 client->query.qname,
01423 client->query.qtype,
01424 ISC_TRUE, flags, &expire);
01425 }
01426 ns_client_send(client);
01427 }
01428
01429 isc_result_t
01430 ns_client_addopt(ns_client_t *client, dns_message_t *message,
01431 dns_rdataset_t **opt)
01432 {
01433 unsigned char ecs[ECS_SIZE];
01434 char nsid[BUFSIZ], *nsidp;
01435 #ifdef ISC_PLATFORM_USESIT
01436 unsigned char sit[SIT_SIZE];
01437 #endif
01438 isc_result_t result;
01439 dns_view_t *view;
01440 dns_resolver_t *resolver;
01441 isc_uint16_t udpsize;
01442 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
01443 int count = 0;
01444 unsigned int flags;
01445 unsigned char expire[4];
01446
01447 REQUIRE(NS_CLIENT_VALID(client));
01448 REQUIRE(opt != NULL && *opt == NULL);
01449 REQUIRE(message != NULL);
01450
01451 view = client->view;
01452 resolver = (view != NULL) ? view->resolver : NULL;
01453 if (resolver != NULL)
01454 udpsize = dns_resolver_getudpsize(resolver);
01455 else
01456 udpsize = ns_g_udpsize;
01457
01458 flags = client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE;
01459
01460
01461 if ((client->attributes & NS_CLIENTATTR_WANTNSID) != 0 &&
01462 (ns_g_server->server_id != NULL ||
01463 ns_g_server->server_usehostname)) {
01464 if (ns_g_server->server_usehostname) {
01465 result = ns_os_gethostname(nsid, sizeof(nsid));
01466 if (result != ISC_R_SUCCESS) {
01467 goto no_nsid;
01468 }
01469 nsidp = nsid;
01470 } else
01471 nsidp = ns_g_server->server_id;
01472
01473 INSIST(count < DNS_EDNSOPTIONS);
01474 ednsopts[count].code = DNS_OPT_NSID;
01475 ednsopts[count].length = (isc_uint16_t)strlen(nsidp);
01476 ednsopts[count].value = (unsigned char *)nsidp;
01477 count++;
01478 }
01479 no_nsid:
01480 #ifdef ISC_PLATFORM_USESIT
01481 if ((client->attributes & NS_CLIENTATTR_WANTSIT) != 0) {
01482 isc_buffer_t buf;
01483 isc_stdtime_t now;
01484 isc_uint32_t nonce;
01485
01486 isc_buffer_init(&buf, sit, sizeof(sit));
01487 isc_stdtime_get(&now);
01488 isc_random_get(&nonce);
01489
01490 compute_sit(client, now, nonce, &buf);
01491
01492 INSIST(count < DNS_EDNSOPTIONS);
01493 ednsopts[count].code = DNS_OPT_SIT;
01494 ednsopts[count].length = SIT_SIZE;
01495 ednsopts[count].value = sit;
01496 count++;
01497 }
01498 #endif
01499 if ((client->attributes & NS_CLIENTATTR_HAVEEXPIRE) != 0) {
01500 isc_buffer_t buf;
01501
01502 INSIST(count < DNS_EDNSOPTIONS);
01503
01504 isc_buffer_init(&buf, expire, sizeof(expire));
01505 isc_buffer_putuint32(&buf, client->expire);
01506 ednsopts[count].code = DNS_OPT_EXPIRE;
01507 ednsopts[count].length = 4;
01508 ednsopts[count].value = expire;
01509 count++;
01510 }
01511 if (((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) &&
01512 (client->ecs_addr.family == AF_INET ||
01513 client->ecs_addr.family == AF_INET6))
01514 {
01515 int i, addrbytes = (client->ecs_addrlen + 7) / 8;
01516 isc_uint8_t *paddr;
01517 isc_buffer_t buf;
01518
01519
01520 isc_buffer_init(&buf, ecs, sizeof(ecs));
01521 if (client->ecs_addr.family == AF_INET)
01522 isc_buffer_putuint16(&buf, 1);
01523 else
01524 isc_buffer_putuint16(&buf, 2);
01525 isc_buffer_putuint8(&buf, client->ecs_addrlen);
01526 isc_buffer_putuint8(&buf, client->ecs_scope);
01527
01528 paddr = (isc_uint8_t *) &client->ecs_addr.type;
01529 for (i = 0; i < addrbytes; i++) {
01530 unsigned char uc;
01531 uc = paddr[i];
01532 if (i == addrbytes - 1 &&
01533 ((client->ecs_addrlen % 8) != 0))
01534 uc &= (1U << (8 - (client->ecs_addrlen % 8)));
01535 isc_buffer_putuint8(&buf, uc);
01536 }
01537
01538 ednsopts[count].code = DNS_OPT_CLIENT_SUBNET;
01539 ednsopts[count].length = addrbytes + 4;
01540 ednsopts[count].value = ecs;
01541 count++;
01542 }
01543
01544 result = dns_message_buildopt(message, opt, 0, udpsize, flags,
01545 ednsopts, count);
01546 return (result);
01547 }
01548
01549 static inline isc_boolean_t
01550 allowed(isc_netaddr_t *addr, dns_name_t *signer,
01551 isc_netaddr_t *ecs_addr, isc_uint8_t ecs_addrlen,
01552 isc_uint8_t *ecs_scope, dns_acl_t *acl)
01553 {
01554 int match;
01555 isc_result_t result;
01556
01557 if (acl == NULL)
01558 return (ISC_TRUE);
01559 result = dns_acl_match2(addr, signer, ecs_addr, ecs_addrlen, ecs_scope,
01560 acl, &ns_g_server->aclenv, &match, NULL);
01561 if (result == ISC_R_SUCCESS && match > 0)
01562 return (ISC_TRUE);
01563 return (ISC_FALSE);
01564 }
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574 isc_boolean_t
01575 ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
01576 isc_sockaddr_t *srcaddr, isc_sockaddr_t *dstaddr,
01577 dns_rdataclass_t rdclass, void *arg)
01578 {
01579 dns_view_t *view;
01580 dns_tsigkey_t *key = NULL;
01581 dns_name_t *tsig = NULL;
01582 isc_netaddr_t netsrc;
01583 isc_netaddr_t netdst;
01584
01585 UNUSED(arg);
01586
01587
01588
01589
01590 if (ns_g_server->interfacemgr == NULL)
01591 return (ISC_TRUE);
01592
01593 if (!ns_interfacemgr_listeningon(ns_g_server->interfacemgr, dstaddr))
01594 return (ISC_FALSE);
01595
01596 isc_netaddr_fromsockaddr(&netsrc, srcaddr);
01597 isc_netaddr_fromsockaddr(&netdst, dstaddr);
01598
01599 for (view = ISC_LIST_HEAD(ns_g_server->viewlist);
01600 view != NULL;
01601 view = ISC_LIST_NEXT(view, link)) {
01602
01603 if (view->matchrecursiveonly)
01604 continue;
01605
01606 if (rdclass != view->rdclass)
01607 continue;
01608
01609 if (mykey != NULL) {
01610 isc_boolean_t match;
01611 isc_result_t result;
01612
01613 result = dns_view_gettsig(view, &mykey->name, &key);
01614 if (result != ISC_R_SUCCESS)
01615 continue;
01616 match = dst_key_compare(mykey->key, key->key);
01617 dns_tsigkey_detach(&key);
01618 if (!match)
01619 continue;
01620 tsig = dns_tsigkey_identity(mykey);
01621 }
01622
01623 if (allowed(&netsrc, tsig, NULL, 0, NULL,
01624 view->matchclients) &&
01625 allowed(&netdst, tsig, NULL, 0, NULL,
01626 view->matchdestinations))
01627 break;
01628 }
01629 return (ISC_TF(view == myview));
01630 }
01631
01632 #ifdef ISC_PLATFORM_USESIT
01633 static void
01634 compute_sit(ns_client_t *client, isc_uint32_t when, isc_uint32_t nonce,
01635 isc_buffer_t *buf)
01636 {
01637 #ifdef AES_SIT
01638 unsigned char digest[ISC_AES_BLOCK_LENGTH];
01639 unsigned char input[4 + 4 + 16];
01640 isc_netaddr_t netaddr;
01641 unsigned char *cp;
01642 unsigned int i;
01643
01644 memset(input, 0, sizeof(input));
01645 cp = isc_buffer_used(buf);
01646 isc_buffer_putmem(buf, client->cookie, 8);
01647 isc_buffer_putuint32(buf, nonce);
01648 isc_buffer_putuint32(buf, when);
01649 memmove(input, cp, 16);
01650 isc_aes128_crypt(ns_g_server->secret, input, digest);
01651 for (i = 0; i < 8; i++)
01652 input[i] = digest[i] ^ digest[i + 8];
01653 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
01654 switch (netaddr.family) {
01655 case AF_INET:
01656 memmove(input + 8, (unsigned char *)&netaddr.type.in, 4);
01657 memset(input + 12, 0, 4);
01658 isc_aes128_crypt(ns_g_server->secret, input, digest);
01659 break;
01660 case AF_INET6:
01661 memmove(input + 8, (unsigned char *)&netaddr.type.in6, 16);
01662 isc_aes128_crypt(ns_g_server->secret, input, digest);
01663 for (i = 0; i < 8; i++)
01664 input[i + 8] = digest[i] ^ digest[i + 8];
01665 isc_aes128_crypt(ns_g_server->secret, input + 8, digest);
01666 break;
01667 }
01668 for (i = 0; i < 8; i++)
01669 digest[i] ^= digest[i + 8];
01670 isc_buffer_putmem(buf, digest, 8);
01671 #endif
01672 #ifdef HMAC_SHA1_SIT
01673 unsigned char digest[ISC_SHA1_DIGESTLENGTH];
01674 isc_netaddr_t netaddr;
01675 unsigned char *cp;
01676 isc_hmacsha1_t hmacsha1;
01677
01678 cp = isc_buffer_used(buf);
01679 isc_buffer_putmem(buf, client->cookie, 8);
01680 isc_buffer_putuint32(buf, nonce);
01681 isc_buffer_putuint32(buf, when);
01682
01683 isc_hmacsha1_init(&hmacsha1,
01684 ns_g_server->secret,
01685 ISC_SHA1_DIGESTLENGTH);
01686 isc_hmacsha1_update(&hmacsha1, cp, 16);
01687 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
01688 switch (netaddr.family) {
01689 case AF_INET:
01690 isc_hmacsha1_update(&hmacsha1,
01691 (unsigned char *)&netaddr.type.in, 4);
01692 break;
01693 case AF_INET6:
01694 isc_hmacsha1_update(&hmacsha1,
01695 (unsigned char *)&netaddr.type.in6, 16);
01696 break;
01697 }
01698 isc_hmacsha1_update(&hmacsha1, client->cookie, sizeof(client->cookie));
01699 isc_hmacsha1_sign(&hmacsha1, digest, sizeof(digest));
01700 isc_buffer_putmem(buf, digest, 8);
01701 isc_hmacsha1_invalidate(&hmacsha1);
01702 #endif
01703 #ifdef HMAC_SHA256_SIT
01704 unsigned char digest[ISC_SHA256_DIGESTLENGTH];
01705 isc_netaddr_t netaddr;
01706 unsigned char *cp;
01707 isc_hmacsha256_t hmacsha256;
01708
01709 cp = isc_buffer_used(buf);
01710 isc_buffer_putmem(buf, client->cookie, 8);
01711 isc_buffer_putuint32(buf, nonce);
01712 isc_buffer_putuint32(buf, when);
01713
01714 isc_hmacsha256_init(&hmacsha256,
01715 ns_g_server->secret,
01716 ISC_SHA256_DIGESTLENGTH);
01717 isc_hmacsha256_update(&hmacsha256, cp, 16);
01718 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
01719 switch (netaddr.family) {
01720 case AF_INET:
01721 isc_hmacsha256_update(&hmacsha256,
01722 (unsigned char *)&netaddr.type.in, 4);
01723 break;
01724 case AF_INET6:
01725 isc_hmacsha256_update(&hmacsha256,
01726 (unsigned char *)&netaddr.type.in6, 16);
01727 break;
01728 }
01729 isc_hmacsha256_update(&hmacsha256, client->cookie,
01730 sizeof(client->cookie));
01731 isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest));
01732 isc_buffer_putmem(buf, digest, 8);
01733 isc_hmacsha256_invalidate(&hmacsha256);
01734 #endif
01735 }
01736
01737 static void
01738 process_sit(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
01739 unsigned char dbuf[SIT_SIZE];
01740 unsigned char *old;
01741 isc_stdtime_t now;
01742 isc_uint32_t when;
01743 isc_uint32_t nonce;
01744 isc_buffer_t db;
01745
01746 client->attributes |= NS_CLIENTATTR_WANTSIT;
01747
01748 isc_stats_increment(ns_g_server->nsstats,
01749 dns_nsstatscounter_sitopt);
01750
01751 if (optlen != SIT_SIZE) {
01752
01753
01754
01755 if (optlen >= 8U)
01756 memmove(client->cookie, isc_buffer_current(buf), 8);
01757 else
01758 memset(client->cookie, 0, 8);
01759 isc_buffer_forward(buf, (unsigned int)optlen);
01760
01761 if (optlen == 8U)
01762 isc_stats_increment(ns_g_server->nsstats,
01763 dns_nsstatscounter_sitnew);
01764 else
01765 isc_stats_increment(ns_g_server->nsstats,
01766 dns_nsstatscounter_sitbadsize);
01767 return;
01768 }
01769
01770
01771
01772
01773 old = isc_buffer_current(buf);
01774 memmove(client->cookie, old, 8);
01775 isc_buffer_forward(buf, 8);
01776 nonce = isc_buffer_getuint32(buf);
01777 when = isc_buffer_getuint32(buf);
01778 isc_buffer_forward(buf, 8);
01779
01780
01781
01782
01783
01784 isc_stdtime_get(&now);
01785 if (isc_serial_gt(when, (now + 300)) ||
01786 isc_serial_lt(when, (now - 3600))) {
01787 isc_stats_increment(ns_g_server->nsstats,
01788 dns_nsstatscounter_sitbadtime);
01789 return;
01790 }
01791
01792 isc_buffer_init(&db, dbuf, sizeof(dbuf));
01793 compute_sit(client, when, nonce, &db);
01794
01795 if (memcmp(old, dbuf, SIT_SIZE) != 0) {
01796 isc_stats_increment(ns_g_server->nsstats,
01797 dns_nsstatscounter_sitnomatch);
01798 return;
01799 }
01800 isc_stats_increment(ns_g_server->nsstats,
01801 dns_nsstatscounter_sitmatch);
01802
01803 client->attributes |= NS_CLIENTATTR_HAVESIT;
01804 }
01805 #endif
01806
01807 static isc_result_t
01808 process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
01809 isc_uint16_t family;
01810 isc_uint8_t addrlen, addrbytes, scope, *paddr;
01811 isc_netaddr_t caddr;
01812 int i;
01813
01814 if (optlen < 4U) {
01815 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
01816 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
01817 "EDNS client subnet option too short");
01818 return (DNS_R_FORMERR);
01819 }
01820
01821 family = isc_buffer_getuint16(buf);
01822 addrlen = isc_buffer_getuint8(buf);
01823 scope = isc_buffer_getuint8(buf);
01824 optlen -= 4;
01825
01826 if (scope != 0U) {
01827 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
01828 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
01829 "EDNS client subnet option: invalid scope");
01830 return (DNS_R_FORMERR);
01831 }
01832
01833 memset(&caddr, 0, sizeof(caddr));
01834 switch (family) {
01835 case 1:
01836 if (addrlen > 32U)
01837 goto invalid_length;
01838 caddr.family = AF_INET;
01839 break;
01840 case 2:
01841 if (addrlen > 128U) {
01842 invalid_length:
01843 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
01844 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
01845 "EDNS client subnet option: invalid "
01846 "address length (%u) for %s",
01847 addrlen, family == 1 ? "IPv4" : "IPv6");
01848 return (DNS_R_FORMERR);
01849 }
01850 caddr.family = AF_INET6;
01851 break;
01852 default:
01853 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
01854 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
01855 "EDNS client subnet option: invalid family");
01856 return (DNS_R_FORMERR);
01857 }
01858
01859 addrbytes = (addrlen + 7) / 8;
01860 if (isc_buffer_remaininglength(buf) < addrbytes) {
01861 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
01862 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
01863 "EDNS client subnet option: address too short");
01864 return (DNS_R_FORMERR);
01865 }
01866
01867 paddr = (isc_uint8_t *) &caddr.type;
01868 for (i = 0; i < addrbytes; i++) {
01869 paddr[i] = isc_buffer_getuint8(buf);
01870 optlen--;
01871 }
01872
01873 memmove(&client->ecs_addr, &caddr, sizeof(caddr));
01874 client->ecs_addrlen = addrlen;
01875 client->ecs_scope = 0;
01876 client->attributes |= NS_CLIENTATTR_HAVEECS;
01877
01878 isc_buffer_forward(buf, (unsigned int)optlen);
01879 return (ISC_R_SUCCESS);
01880 }
01881
01882 static isc_result_t
01883 process_opt(ns_client_t *client, dns_rdataset_t *opt) {
01884 dns_rdata_t rdata;
01885 isc_buffer_t optbuf;
01886 isc_result_t result;
01887 isc_uint16_t optcode;
01888 isc_uint16_t optlen;
01889
01890
01891
01892
01893 client->udpsize = opt->rdclass;
01894
01895
01896
01897
01898
01899 if (client->udpsize < 512)
01900 client->udpsize = 512;
01901
01902
01903
01904
01905 client->extflags = (isc_uint16_t)(opt->ttl & 0xFFFF);
01906
01907
01908
01909
01910
01911
01912 client->ednsversion = (opt->ttl & 0x00FF0000) >> 16;
01913 if (client->ednsversion > DNS_EDNS_VERSION) {
01914 isc_stats_increment(ns_g_server->nsstats,
01915 dns_nsstatscounter_badednsver);
01916 result = ns_client_addopt(client, client->message,
01917 &client->opt);
01918 if (result == ISC_R_SUCCESS)
01919 result = DNS_R_BADVERS;
01920 ns_client_error(client, result);
01921 goto cleanup;
01922 }
01923
01924
01925 result = dns_rdataset_first(opt);
01926 if (result == ISC_R_SUCCESS) {
01927 dns_rdata_init(&rdata);
01928 dns_rdataset_current(opt, &rdata);
01929 isc_buffer_init(&optbuf, rdata.data, rdata.length);
01930 isc_buffer_add(&optbuf, rdata.length);
01931 while (isc_buffer_remaininglength(&optbuf) >= 4) {
01932 optcode = isc_buffer_getuint16(&optbuf);
01933 optlen = isc_buffer_getuint16(&optbuf);
01934 switch (optcode) {
01935 case DNS_OPT_NSID:
01936 isc_stats_increment(ns_g_server->nsstats,
01937 dns_nsstatscounter_nsidopt);
01938 client->attributes |= NS_CLIENTATTR_WANTNSID;
01939 isc_buffer_forward(&optbuf, optlen);
01940 break;
01941 #ifdef ISC_PLATFORM_USESIT
01942 case DNS_OPT_SIT:
01943 process_sit(client, &optbuf, optlen);
01944 break;
01945 #endif
01946 case DNS_OPT_EXPIRE:
01947 isc_stats_increment(ns_g_server->nsstats,
01948 dns_nsstatscounter_expireopt);
01949 client->attributes |= NS_CLIENTATTR_WANTEXPIRE;
01950 isc_buffer_forward(&optbuf, optlen);
01951 break;
01952 case DNS_OPT_CLIENT_SUBNET:
01953 result = process_ecs(client, &optbuf, optlen);
01954 if (result != ISC_R_SUCCESS) {
01955 ns_client_error(client, result);
01956 goto cleanup;
01957 }
01958 isc_stats_increment(ns_g_server->nsstats,
01959 dns_nsstatscounter_ecsopt);
01960 break;
01961 default:
01962 isc_stats_increment(ns_g_server->nsstats,
01963 dns_nsstatscounter_otheropt);
01964 isc_buffer_forward(&optbuf, optlen);
01965 break;
01966 }
01967 }
01968 }
01969
01970 isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_edns0in);
01971 client->attributes |= NS_CLIENTATTR_WANTOPT;
01972
01973 cleanup:
01974 return (result);
01975 }
01976
01977
01978
01979
01980
01981 static void
01982 client_request(isc_task_t *task, isc_event_t *event) {
01983 ns_client_t *client;
01984 isc_socketevent_t *sevent;
01985 isc_result_t result;
01986 isc_result_t sigresult = ISC_R_SUCCESS;
01987 isc_buffer_t *buffer;
01988 isc_buffer_t tbuffer;
01989 dns_view_t *view;
01990 dns_rdataset_t *opt;
01991 dns_name_t *signame;
01992 isc_boolean_t ra;
01993 isc_netaddr_t netaddr;
01994 int match;
01995 dns_messageid_t id;
01996 unsigned int flags;
01997 isc_boolean_t notimp;
01998
01999 REQUIRE(event != NULL);
02000 client = event->ev_arg;
02001 REQUIRE(NS_CLIENT_VALID(client));
02002 REQUIRE(task == client->task);
02003
02004 INSIST(client->recursionquota == NULL);
02005
02006 INSIST(client->state == (TCP_CLIENT(client) ?
02007 NS_CLIENTSTATE_READING :
02008 NS_CLIENTSTATE_READY));
02009
02010 ns_client_requests++;
02011
02012 if (event->ev_type == ISC_SOCKEVENT_RECVDONE) {
02013 INSIST(!TCP_CLIENT(client));
02014 sevent = (isc_socketevent_t *)event;
02015 REQUIRE(sevent == client->recvevent);
02016 isc_buffer_init(&tbuffer, sevent->region.base, sevent->n);
02017 isc_buffer_add(&tbuffer, sevent->n);
02018 buffer = &tbuffer;
02019 result = sevent->result;
02020 if (result == ISC_R_SUCCESS) {
02021 client->peeraddr = sevent->address;
02022 client->peeraddr_valid = ISC_TRUE;
02023 }
02024 if ((sevent->attributes & ISC_SOCKEVENTATTR_DSCP) != 0) {
02025 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
02026 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(90),
02027 "received DSCP %d", sevent->dscp);
02028 if (client->dscp == -1)
02029 client->dscp = sevent->dscp;
02030 }
02031 if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) {
02032 client->attributes |= NS_CLIENTATTR_PKTINFO;
02033 client->pktinfo = sevent->pktinfo;
02034 }
02035 if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0)
02036 client->attributes |= NS_CLIENTATTR_MULTICAST;
02037 client->nrecvs--;
02038 } else {
02039 INSIST(TCP_CLIENT(client));
02040 REQUIRE(event->ev_type == DNS_EVENT_TCPMSG);
02041 REQUIRE(event->ev_sender == &client->tcpmsg);
02042 buffer = &client->tcpmsg.buffer;
02043 result = client->tcpmsg.result;
02044 INSIST(client->nreads == 1);
02045
02046
02047
02048 client->nreads--;
02049 }
02050
02051 if (exit_check(client))
02052 goto cleanup;
02053 client->state = client->newstate = NS_CLIENTSTATE_WORKING;
02054
02055 isc_task_getcurrenttime(task, &client->requesttime);
02056 client->now = client->requesttime;
02057 isc_time_set(&client->tnow, client->now, 0);
02058
02059 if (result != ISC_R_SUCCESS) {
02060 if (TCP_CLIENT(client)) {
02061 ns_client_next(client, result);
02062 } else {
02063 if (result != ISC_R_CANCELED)
02064 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT,
02065 NS_LOGMODULE_CLIENT,
02066 ISC_LOG_ERROR,
02067 "UDP client handler shutting "
02068 "down due to fatal receive "
02069 "error: %s",
02070 isc_result_totext(result));
02071 isc_task_shutdown(client->task);
02072 }
02073 goto cleanup;
02074 }
02075
02076 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
02077
02078 #if NS_CLIENT_DROPPORT
02079 if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) ==
02080 DROPPORT_REQUEST) {
02081 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
02082 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
02083 "dropped request: suspicious port");
02084 ns_client_next(client, ISC_R_SUCCESS);
02085 goto cleanup;
02086 }
02087 #endif
02088
02089 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
02090 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
02091 "%s request",
02092 TCP_CLIENT(client) ? "TCP" : "UDP");
02093
02094
02095
02096
02097
02098 if (!TCP_CLIENT(client)) {
02099 if (ns_g_server->blackholeacl != NULL &&
02100 dns_acl_match(&netaddr, NULL, ns_g_server->blackholeacl,
02101 &ns_g_server->aclenv,
02102 &match, NULL) == ISC_R_SUCCESS &&
02103 match > 0)
02104 {
02105 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
02106 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
02107 "blackholed UDP datagram");
02108 ns_client_next(client, ISC_R_SUCCESS);
02109 goto cleanup;
02110 }
02111 }
02112
02113
02114
02115
02116
02117 if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) {
02118 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
02119 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
02120 "dropping multicast request");
02121 ns_client_next(client, DNS_R_REFUSED);
02122 goto cleanup;
02123 }
02124
02125 result = dns_message_peekheader(buffer, &id, &flags);
02126 if (result != ISC_R_SUCCESS) {
02127
02128
02129
02130
02131 ns_client_next(client, result);
02132 goto cleanup;
02133 }
02134
02135
02136
02137
02138
02139
02140 if ((flags & DNS_MESSAGEFLAG_QR) != 0) {
02141 if (TCP_CLIENT(client)) {
02142 CTRACE("unexpected response");
02143 ns_client_next(client, DNS_R_FORMERR);
02144 goto cleanup;
02145 } else {
02146 dns_dispatch_importrecv(client->dispatch, event);
02147 ns_client_next(client, ISC_R_SUCCESS);
02148 goto cleanup;
02149 }
02150 }
02151
02152
02153
02154
02155 if (isc_sockaddr_pf(&client->peeraddr) == PF_INET) {
02156 isc_stats_increment(ns_g_server->nsstats,
02157 dns_nsstatscounter_requestv4);
02158 } else {
02159 isc_stats_increment(ns_g_server->nsstats,
02160 dns_nsstatscounter_requestv6);
02161 }
02162 if (TCP_CLIENT(client))
02163 isc_stats_increment(ns_g_server->nsstats,
02164 dns_nsstatscounter_requesttcp);
02165
02166
02167
02168
02169 result = dns_message_parse(client->message, buffer, 0);
02170 if (result != ISC_R_SUCCESS) {
02171
02172
02173
02174
02175 ns_client_error(client, result);
02176 goto cleanup;
02177 }
02178
02179
02180
02181
02182 if (client->message->opcode != dns_opcode_query)
02183 client->pipelined = ISC_FALSE;
02184 if (TCP_CLIENT(client) && client->pipelined) {
02185 result = isc_quota_reserve(&ns_g_server->tcpquota);
02186 if (result == ISC_R_SUCCESS)
02187 result = ns_client_replace(client);
02188 if (result != ISC_R_SUCCESS) {
02189 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
02190 NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
02191 "no more TCP clients(read): %s",
02192 isc_result_totext(result));
02193 client->pipelined = ISC_FALSE;
02194 }
02195 }
02196
02197 dns_opcodestats_increment(ns_g_server->opcodestats,
02198 client->message->opcode);
02199 switch (client->message->opcode) {
02200 case dns_opcode_query:
02201 case dns_opcode_update:
02202 case dns_opcode_notify:
02203 notimp = ISC_FALSE;
02204 break;
02205 case dns_opcode_iquery:
02206 default:
02207 notimp = ISC_TRUE;
02208 break;
02209 }
02210
02211 client->message->rcode = dns_rcode_noerror;
02212
02213
02214 if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0)
02215 client->message->flags &= ~DNS_MESSAGEFLAG_RD;
02216
02217
02218
02219
02220 if (ns_g_noedns)
02221 opt = NULL;
02222 else
02223 opt = dns_message_getopt(client->message);
02224
02225 client->ecs_addrlen = 0;
02226 client->ecs_scope = 0;
02227
02228 if (opt != NULL) {
02229
02230
02231
02232 if (ns_g_dropedns) {
02233 ns_client_next(client, ISC_R_SUCCESS);
02234 goto cleanup;
02235 }
02236 result = process_opt(client, opt);
02237 if (result != ISC_R_SUCCESS)
02238 goto cleanup;
02239 }
02240
02241 if (client->message->rdclass == 0) {
02242 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
02243 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
02244 "message class could not be determined");
02245 ns_client_dumpmessage(client,
02246 "message class could not be determined");
02247 ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR);
02248 goto cleanup;
02249 }
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262 if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0)
02263 isc_netaddr_fromsockaddr(&client->destaddr,
02264 &client->interface->addr);
02265 else {
02266 isc_sockaddr_t sockaddr;
02267 result = ISC_R_FAILURE;
02268
02269 if (TCP_CLIENT(client))
02270 result = isc_socket_getsockname(client->tcpsocket,
02271 &sockaddr);
02272 if (result == ISC_R_SUCCESS)
02273 isc_netaddr_fromsockaddr(&client->destaddr, &sockaddr);
02274 if (result != ISC_R_SUCCESS &&
02275 client->interface->addr.type.sa.sa_family == AF_INET6 &&
02276 (client->attributes & NS_CLIENTATTR_PKTINFO) != 0) {
02277
02278
02279
02280
02281
02282
02283
02284
02285 isc_netaddr_fromin6(&client->destaddr,
02286 &client->pktinfo.ipi6_addr);
02287 if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr))
02288 isc_netaddr_setzone(&client->destaddr,
02289 client->pktinfo.ipi6_ifindex);
02290 result = ISC_R_SUCCESS;
02291 }
02292 if (result != ISC_R_SUCCESS) {
02293 UNEXPECTED_ERROR(__FILE__, __LINE__,
02294 "failed to get request's "
02295 "destination: %s",
02296 isc_result_totext(result));
02297 ns_client_next(client, ISC_R_SUCCESS);
02298 goto cleanup;
02299 }
02300 }
02301
02302
02303
02304
02305 for (view = ISC_LIST_HEAD(ns_g_server->viewlist);
02306 view != NULL;
02307 view = ISC_LIST_NEXT(view, link)) {
02308 if (client->message->rdclass == view->rdclass ||
02309 client->message->rdclass == dns_rdataclass_any)
02310 {
02311 dns_name_t *tsig = NULL;
02312 isc_netaddr_t *addr = NULL;
02313 isc_uint8_t *scope = NULL;
02314
02315 sigresult = dns_message_rechecksig(client->message,
02316 view);
02317 if (sigresult == ISC_R_SUCCESS) {
02318 dns_tsigkey_t *tsigkey;
02319
02320 tsigkey = client->message->tsigkey;
02321 tsig = dns_tsigkey_identity(tsigkey);
02322 }
02323
02324 if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) {
02325 addr = &client->ecs_addr;
02326 scope = &client->ecs_scope;
02327 }
02328
02329 if (allowed(&netaddr, tsig, addr, client->ecs_addrlen,
02330 scope, view->matchclients) &&
02331 allowed(&client->destaddr, tsig, NULL,
02332 0, NULL, view->matchdestinations) &&
02333 !(view->matchrecursiveonly &&
02334 (client->message->flags & DNS_MESSAGEFLAG_RD) == 0))
02335 {
02336 dns_view_attach(view, &client->view);
02337 break;
02338 }
02339 }
02340 }
02341
02342 if (view == NULL) {
02343 char classname[DNS_RDATACLASS_FORMATSIZE];
02344
02345
02346
02347
02348
02349
02350 isc_buffer_t b;
02351 isc_region_t *r;
02352
02353 dns_message_resetsig(client->message);
02354
02355 r = dns_message_getrawmessage(client->message);
02356 isc_buffer_init(&b, r->base, r->length);
02357 isc_buffer_add(&b, r->length);
02358 (void)dns_tsig_verify(&b, client->message, NULL, NULL);
02359
02360 dns_rdataclass_format(client->message->rdclass, classname,
02361 sizeof(classname));
02362 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
02363 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
02364 "no matching view in class '%s'", classname);
02365 ns_client_dumpmessage(client, "no matching view in class");
02366 ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED);
02367 goto cleanup;
02368 }
02369
02370 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
02371 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5),
02372 "using view '%s'", view->name);
02373
02374
02375
02376
02377
02378
02379
02380 client->signer = NULL;
02381 dns_name_init(&client->signername, NULL);
02382 result = dns_message_signer(client->message, &client->signername);
02383 if (result != ISC_R_NOTFOUND) {
02384 signame = NULL;
02385 if (dns_message_gettsig(client->message, &signame) != NULL) {
02386 isc_stats_increment(ns_g_server->nsstats,
02387 dns_nsstatscounter_tsigin);
02388 } else {
02389 isc_stats_increment(ns_g_server->nsstats,
02390 dns_nsstatscounter_sig0in);
02391 }
02392
02393 }
02394 if (result == ISC_R_SUCCESS) {
02395 char namebuf[DNS_NAME_FORMATSIZE];
02396 dns_name_format(&client->signername, namebuf, sizeof(namebuf));
02397 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
02398 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
02399 "request has valid signature: %s", namebuf);
02400 client->signer = &client->signername;
02401 } else if (result == ISC_R_NOTFOUND) {
02402 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
02403 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
02404 "request is not signed");
02405 } else if (result == DNS_R_NOIDENTITY) {
02406 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
02407 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
02408 "request is signed by a nonauthoritative key");
02409 } else {
02410 char tsigrcode[64];
02411 isc_buffer_t b;
02412 dns_rcode_t status;
02413 isc_result_t tresult;
02414
02415
02416 isc_stats_increment(ns_g_server->nsstats,
02417 dns_nsstatscounter_invalidsig);
02418 signame = NULL;
02419 if (dns_message_gettsig(client->message, &signame) != NULL) {
02420 char namebuf[DNS_NAME_FORMATSIZE];
02421 char cnamebuf[DNS_NAME_FORMATSIZE];
02422 dns_name_format(signame, namebuf, sizeof(namebuf));
02423 status = client->message->tsigstatus;
02424 isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1);
02425 tresult = dns_tsigrcode_totext(status, &b);
02426 INSIST(tresult == ISC_R_SUCCESS);
02427 tsigrcode[isc_buffer_usedlength(&b)] = '\0';
02428 if (client->message->tsigkey->generated) {
02429 dns_name_format(client->message->tsigkey->creator,
02430 cnamebuf, sizeof(cnamebuf));
02431 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
02432 NS_LOGMODULE_CLIENT,
02433 ISC_LOG_ERROR,
02434 "request has invalid signature: "
02435 "TSIG %s (%s): %s (%s)", namebuf,
02436 cnamebuf,
02437 isc_result_totext(result),
02438 tsigrcode);
02439 } else {
02440 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
02441 NS_LOGMODULE_CLIENT,
02442 ISC_LOG_ERROR,
02443 "request has invalid signature: "
02444 "TSIG %s: %s (%s)", namebuf,
02445 isc_result_totext(result),
02446 tsigrcode);
02447 }
02448 } else {
02449 status = client->message->sig0status;
02450 isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1);
02451 tresult = dns_tsigrcode_totext(status, &b);
02452 INSIST(tresult == ISC_R_SUCCESS);
02453 tsigrcode[isc_buffer_usedlength(&b)] = '\0';
02454 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
02455 NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
02456 "request has invalid signature: %s (%s)",
02457 isc_result_totext(result), tsigrcode);
02458 }
02459
02460
02461
02462
02463
02464 if (!(client->message->tsigstatus == dns_tsigerror_badkey &&
02465 client->message->opcode == dns_opcode_update)) {
02466 ns_client_error(client, sigresult);
02467 goto cleanup;
02468 }
02469 }
02470
02471
02472
02473
02474
02475
02476
02477
02478 ra = ISC_FALSE;
02479 if (client->view->resolver != NULL &&
02480 client->view->recursion == ISC_TRUE &&
02481 ns_client_checkaclsilent(client, NULL,
02482 client->view->recursionacl,
02483 ISC_TRUE) == ISC_R_SUCCESS &&
02484 ns_client_checkaclsilent(client, NULL,
02485 client->view->cacheacl,
02486 ISC_TRUE) == ISC_R_SUCCESS &&
02487 ns_client_checkaclsilent(client, &client->destaddr,
02488 client->view->recursiononacl,
02489 ISC_TRUE) == ISC_R_SUCCESS &&
02490 ns_client_checkaclsilent(client, &client->destaddr,
02491 client->view->cacheonacl,
02492 ISC_TRUE) == ISC_R_SUCCESS)
02493 ra = ISC_TRUE;
02494
02495 if (ra == ISC_TRUE)
02496 client->attributes |= NS_CLIENTATTR_RA;
02497
02498 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT,
02499 ISC_LOG_DEBUG(3), ra ? "recursion available" :
02500 "recursion not available");
02501
02502
02503
02504
02505 if (client->udpsize > 512) {
02506 dns_peer_t *peer = NULL;
02507 isc_uint16_t udpsize = view->maxudp;
02508 (void) dns_peerlist_peerbyaddr(view->peers, &netaddr, &peer);
02509 if (peer != NULL)
02510 dns_peer_getmaxudp(peer, &udpsize);
02511 if (client->udpsize > udpsize)
02512 client->udpsize = udpsize;
02513 }
02514
02515
02516
02517
02518 switch (client->message->opcode) {
02519 case dns_opcode_query:
02520 CTRACE("query");
02521 ns_query_start(client);
02522 break;
02523 case dns_opcode_update:
02524 CTRACE("update");
02525 ns_client_settimeout(client, 60);
02526 ns_update_start(client, sigresult);
02527 break;
02528 case dns_opcode_notify:
02529 CTRACE("notify");
02530 ns_client_settimeout(client, 60);
02531 ns_notify_start(client);
02532 break;
02533 case dns_opcode_iquery:
02534 CTRACE("iquery");
02535 ns_client_error(client, DNS_R_NOTIMP);
02536 break;
02537 default:
02538 CTRACE("unknown opcode");
02539 ns_client_error(client, DNS_R_NOTIMP);
02540 }
02541
02542 cleanup:
02543 return;
02544 }
02545
02546 static void
02547 client_timeout(isc_task_t *task, isc_event_t *event) {
02548 ns_client_t *client;
02549
02550 REQUIRE(event != NULL);
02551 REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE ||
02552 event->ev_type == ISC_TIMEREVENT_IDLE);
02553 client = event->ev_arg;
02554 REQUIRE(NS_CLIENT_VALID(client));
02555 REQUIRE(task == client->task);
02556 REQUIRE(client->timer != NULL);
02557
02558 UNUSED(task);
02559
02560 CTRACE("timeout");
02561
02562 isc_event_free(&event);
02563
02564 if (client->shutdown != NULL) {
02565 (client->shutdown)(client->shutdown_arg, ISC_R_TIMEDOUT);
02566 client->shutdown = NULL;
02567 client->shutdown_arg = NULL;
02568 }
02569
02570 if (client->newstate > NS_CLIENTSTATE_READY)
02571 client->newstate = NS_CLIENTSTATE_READY;
02572 (void)exit_check(client);
02573 }
02574
02575 static isc_result_t
02576 get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) {
02577 isc_mem_t *clientmctx;
02578 isc_result_t result;
02579 #if NMCTXS > 0
02580 unsigned int nextmctx;
02581 #endif
02582
02583 MTRACE("clientmctx");
02584
02585
02586
02587
02588 if (ns_g_clienttest) {
02589 result = isc_mem_create(0, 0, mctxp);
02590 if (result == ISC_R_SUCCESS)
02591 isc_mem_setname(*mctxp, "client", NULL);
02592 return (result);
02593 }
02594 #if NMCTXS > 0
02595 nextmctx = manager->nextmctx++;
02596 if (manager->nextmctx == NMCTXS)
02597 manager->nextmctx = 0;
02598
02599 INSIST(nextmctx < NMCTXS);
02600
02601 clientmctx = manager->mctxpool[nextmctx];
02602 if (clientmctx == NULL) {
02603 result = isc_mem_create(0, 0, &clientmctx);
02604 if (result != ISC_R_SUCCESS)
02605 return (result);
02606 isc_mem_setname(clientmctx, "client", NULL);
02607
02608 manager->mctxpool[nextmctx] = clientmctx;
02609 }
02610 #else
02611 clientmctx = manager->mctx;
02612 #endif
02613
02614 isc_mem_attach(clientmctx, mctxp);
02615
02616 return (ISC_R_SUCCESS);
02617 }
02618
02619 static isc_result_t
02620 client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
02621 ns_client_t *client;
02622 isc_result_t result;
02623 isc_mem_t *mctx = NULL;
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633 REQUIRE(clientp != NULL && *clientp == NULL);
02634
02635 result = get_clientmctx(manager, &mctx);
02636 if (result != ISC_R_SUCCESS)
02637 return (result);
02638
02639 client = isc_mem_get(mctx, sizeof(*client));
02640 if (client == NULL) {
02641 isc_mem_detach(&mctx);
02642 return (ISC_R_NOMEMORY);
02643 }
02644 client->mctx = mctx;
02645
02646 client->task = NULL;
02647 result = isc_task_create(manager->taskmgr, 0, &client->task);
02648 if (result != ISC_R_SUCCESS)
02649 goto cleanup_client;
02650 isc_task_setname(client->task, "client", client);
02651
02652 client->timer = NULL;
02653 result = isc_timer_create(manager->timermgr, isc_timertype_inactive,
02654 NULL, NULL, client->task, client_timeout,
02655 client, &client->timer);
02656 if (result != ISC_R_SUCCESS)
02657 goto cleanup_task;
02658 client->timerset = ISC_FALSE;
02659
02660 client->delaytimer = NULL;
02661
02662 client->message = NULL;
02663 result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE,
02664 &client->message);
02665 if (result != ISC_R_SUCCESS)
02666 goto cleanup_timer;
02667
02668
02669
02670 client->sendevent = isc_socket_socketevent(client->mctx, client,
02671 ISC_SOCKEVENT_SENDDONE,
02672 client_senddone, client);
02673 if (client->sendevent == NULL) {
02674 result = ISC_R_NOMEMORY;
02675 goto cleanup_message;
02676 }
02677
02678 client->recvbuf = isc_mem_get(client->mctx, RECV_BUFFER_SIZE);
02679 if (client->recvbuf == NULL) {
02680 result = ISC_R_NOMEMORY;
02681 goto cleanup_sendevent;
02682 }
02683
02684 client->recvevent = isc_socket_socketevent(client->mctx, client,
02685 ISC_SOCKEVENT_RECVDONE,
02686 client_request, client);
02687 if (client->recvevent == NULL) {
02688 result = ISC_R_NOMEMORY;
02689 goto cleanup_recvbuf;
02690 }
02691
02692 client->magic = NS_CLIENT_MAGIC;
02693 client->manager = NULL;
02694 client->state = NS_CLIENTSTATE_INACTIVE;
02695 client->newstate = NS_CLIENTSTATE_MAX;
02696 client->naccepts = 0;
02697 client->nreads = 0;
02698 client->nsends = 0;
02699 client->nrecvs = 0;
02700 client->nupdates = 0;
02701 client->nctls = 0;
02702 client->references = 0;
02703 client->attributes = 0;
02704 client->view = NULL;
02705 client->dispatch = NULL;
02706 client->udpsocket = NULL;
02707 client->tcplistener = NULL;
02708 client->tcpsocket = NULL;
02709 client->tcpmsg_valid = ISC_FALSE;
02710 client->tcpbuf = NULL;
02711 client->opt = NULL;
02712 client->udpsize = 512;
02713 client->dscp = -1;
02714 client->extflags = 0;
02715 client->ednsversion = -1;
02716 client->next = NULL;
02717 client->shutdown = NULL;
02718 client->shutdown_arg = NULL;
02719 client->signer = NULL;
02720 dns_name_init(&client->signername, NULL);
02721 client->mortal = ISC_FALSE;
02722 client->pipelined = ISC_FALSE;
02723 client->tcpquota = NULL;
02724 client->recursionquota = NULL;
02725 client->interface = NULL;
02726 client->peeraddr_valid = ISC_FALSE;
02727 client->ecs_addrlen = 0;
02728 client->ecs_scope = 0;
02729 #ifdef ALLOW_FILTER_AAAA
02730 client->filter_aaaa = dns_aaaa_ok;
02731 #endif
02732 client->needshutdown = ns_g_clienttest;
02733
02734 ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL,
02735 NS_EVENT_CLIENTCONTROL, client_start, client, client,
02736 NULL, NULL);
02737
02738
02739
02740
02741 isc_sockaddr_any(&client->formerrcache.addr);
02742 client->formerrcache.time = 0;
02743 client->formerrcache.id = 0;
02744 ISC_LINK_INIT(client, link);
02745 ISC_LINK_INIT(client, rlink);
02746 ISC_QLINK_INIT(client, ilink);
02747
02748
02749
02750
02751
02752
02753 result = ns_query_init(client);
02754 if (result != ISC_R_SUCCESS)
02755 goto cleanup_recvevent;
02756
02757 result = isc_task_onshutdown(client->task, client_shutdown, client);
02758 if (result != ISC_R_SUCCESS)
02759 goto cleanup_query;
02760
02761 CTRACE("create");
02762
02763 *clientp = client;
02764
02765 return (ISC_R_SUCCESS);
02766
02767 cleanup_query:
02768 ns_query_free(client);
02769
02770 cleanup_recvevent:
02771 isc_event_free((isc_event_t **)&client->recvevent);
02772
02773 cleanup_recvbuf:
02774 isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE);
02775
02776 cleanup_sendevent:
02777 isc_event_free((isc_event_t **)&client->sendevent);
02778
02779 client->magic = 0;
02780
02781 cleanup_message:
02782 dns_message_destroy(&client->message);
02783
02784 cleanup_timer:
02785 isc_timer_detach(&client->timer);
02786
02787 cleanup_task:
02788 isc_task_detach(&client->task);
02789
02790 cleanup_client:
02791 isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
02792
02793 return (result);
02794 }
02795
02796 static void
02797 client_read(ns_client_t *client) {
02798 isc_result_t result;
02799
02800 CTRACE("read");
02801
02802 result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task,
02803 client_request, client);
02804 if (result != ISC_R_SUCCESS)
02805 goto fail;
02806
02807
02808
02809
02810
02811 ns_client_settimeout(client, 30);
02812
02813 client->state = client->newstate = NS_CLIENTSTATE_READING;
02814 INSIST(client->nreads == 0);
02815 INSIST(client->recursionquota == NULL);
02816 client->nreads++;
02817
02818 return;
02819 fail:
02820 ns_client_next(client, result);
02821 }
02822
02823 static void
02824 client_newconn(isc_task_t *task, isc_event_t *event) {
02825 ns_client_t *client = event->ev_arg;
02826 isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;
02827 isc_result_t result;
02828
02829 REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN);
02830 REQUIRE(NS_CLIENT_VALID(client));
02831 REQUIRE(client->task == task);
02832
02833 UNUSED(task);
02834
02835 INSIST(client->state == NS_CLIENTSTATE_READY);
02836
02837 INSIST(client->naccepts == 1);
02838 client->naccepts--;
02839
02840 LOCK(&client->interface->lock);
02841 INSIST(client->interface->ntcpcurrent > 0);
02842 client->interface->ntcpcurrent--;
02843 UNLOCK(&client->interface->lock);
02844
02845
02846
02847
02848
02849 if (nevent->result == ISC_R_SUCCESS) {
02850 client->tcpsocket = nevent->newsocket;
02851 isc_socket_setname(client->tcpsocket, "client-tcp", NULL);
02852 client->state = NS_CLIENTSTATE_READING;
02853 INSIST(client->recursionquota == NULL);
02854
02855 (void)isc_socket_getpeername(client->tcpsocket,
02856 &client->peeraddr);
02857 client->peeraddr_valid = ISC_TRUE;
02858 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
02859 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
02860 "new TCP connection");
02861 } else {
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
02873 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
02874 "accept failed: %s",
02875 isc_result_totext(nevent->result));
02876 }
02877
02878 if (exit_check(client))
02879 goto freeevent;
02880
02881 if (nevent->result == ISC_R_SUCCESS) {
02882 int match;
02883 isc_netaddr_t netaddr;
02884
02885 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
02886
02887 if (ns_g_server->blackholeacl != NULL &&
02888 dns_acl_match(&netaddr, NULL,
02889 ns_g_server->blackholeacl,
02890 &ns_g_server->aclenv,
02891 &match, NULL) == ISC_R_SUCCESS &&
02892 match > 0)
02893 {
02894 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
02895 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
02896 "blackholed connection attempt");
02897 client->newstate = NS_CLIENTSTATE_READY;
02898 (void)exit_check(client);
02899 goto freeevent;
02900 }
02901
02902 INSIST(client->tcpmsg_valid == ISC_FALSE);
02903 dns_tcpmsg_init(client->mctx, client->tcpsocket,
02904 &client->tcpmsg);
02905 client->tcpmsg_valid = ISC_TRUE;
02906
02907
02908
02909
02910
02911
02912
02913 client->pipelined = ISC_FALSE;
02914 result = isc_quota_attach(&ns_g_server->tcpquota,
02915 &client->tcpquota);
02916 if (result == ISC_R_SUCCESS)
02917 result = ns_client_replace(client);
02918 if (result != ISC_R_SUCCESS) {
02919 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
02920 NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
02921 "no more TCP clients(accept): %s",
02922 isc_result_totext(result));
02923 } else if (ns_g_server->keepresporder == NULL ||
02924 !allowed(&netaddr, NULL, NULL, 0, NULL,
02925 ns_g_server->keepresporder)) {
02926 client->pipelined = ISC_TRUE;
02927 }
02928
02929 client_read(client);
02930 }
02931
02932 freeevent:
02933 isc_event_free(&event);
02934 }
02935
02936 static void
02937 client_accept(ns_client_t *client) {
02938 isc_result_t result;
02939
02940 CTRACE("accept");
02941
02942 result = isc_socket_accept(client->tcplistener, client->task,
02943 client_newconn, client);
02944 if (result != ISC_R_SUCCESS) {
02945 UNEXPECTED_ERROR(__FILE__, __LINE__,
02946 "isc_socket_accept() failed: %s",
02947 isc_result_totext(result));
02948
02949
02950
02951
02952
02953
02954
02955 return;
02956 }
02957 INSIST(client->naccepts == 0);
02958 client->naccepts++;
02959 LOCK(&client->interface->lock);
02960 client->interface->ntcpcurrent++;
02961 UNLOCK(&client->interface->lock);
02962 }
02963
02964 static void
02965 client_udprecv(ns_client_t *client) {
02966 isc_result_t result;
02967 isc_region_t r;
02968
02969 CTRACE("udprecv");
02970
02971 r.base = client->recvbuf;
02972 r.length = RECV_BUFFER_SIZE;
02973 result = isc_socket_recv2(client->udpsocket, &r, 1,
02974 client->task, client->recvevent, 0);
02975 if (result != ISC_R_SUCCESS) {
02976 UNEXPECTED_ERROR(__FILE__, __LINE__,
02977 "isc_socket_recv2() failed: %s",
02978 isc_result_totext(result));
02979
02980
02981
02982
02983
02984
02985 return;
02986 }
02987 INSIST(client->nrecvs == 0);
02988 client->nrecvs++;
02989 }
02990
02991 void
02992 ns_client_attach(ns_client_t *source, ns_client_t **targetp) {
02993 REQUIRE(NS_CLIENT_VALID(source));
02994 REQUIRE(targetp != NULL && *targetp == NULL);
02995
02996 source->references++;
02997 ns_client_log(source, NS_LOGCATEGORY_CLIENT,
02998 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
02999 "ns_client_attach: ref = %d", source->references);
03000 *targetp = source;
03001 }
03002
03003 void
03004 ns_client_detach(ns_client_t **clientp) {
03005 ns_client_t *client = *clientp;
03006
03007 client->references--;
03008 INSIST(client->references >= 0);
03009 *clientp = NULL;
03010 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
03011 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
03012 "ns_client_detach: ref = %d", client->references);
03013 (void)exit_check(client);
03014 }
03015
03016 isc_boolean_t
03017 ns_client_shuttingdown(ns_client_t *client) {
03018 return (ISC_TF(client->newstate == NS_CLIENTSTATE_FREED));
03019 }
03020
03021 isc_result_t
03022 ns_client_replace(ns_client_t *client) {
03023 isc_result_t result;
03024 isc_boolean_t tcp;
03025
03026 CTRACE("replace");
03027
03028 REQUIRE(client != NULL);
03029 REQUIRE(client->manager != NULL);
03030
03031 tcp = TCP_CLIENT(client);
03032 if (tcp && client->pipelined) {
03033 result = get_worker(client->manager, client->interface,
03034 client->tcpsocket);
03035 } else {
03036 result = get_client(client->manager, client->interface,
03037 client->dispatch, tcp);
03038 }
03039 if (result != ISC_R_SUCCESS)
03040 return (result);
03041
03042
03043
03044
03045
03046
03047 client->mortal = ISC_TRUE;
03048
03049 return (ISC_R_SUCCESS);
03050 }
03051
03052
03053
03054
03055
03056 static void
03057 clientmgr_destroy(ns_clientmgr_t *manager) {
03058 #if NMCTXS > 0
03059 int i;
03060 #endif
03061
03062 REQUIRE(ISC_LIST_EMPTY(manager->clients));
03063
03064 MTRACE("clientmgr_destroy");
03065
03066 #if NMCTXS > 0
03067 for (i = 0; i < NMCTXS; i++) {
03068 if (manager->mctxpool[i] != NULL)
03069 isc_mem_detach(&manager->mctxpool[i]);
03070 }
03071 #endif
03072
03073 ISC_QUEUE_DESTROY(manager->inactive);
03074 DESTROYLOCK(&manager->lock);
03075 DESTROYLOCK(&manager->listlock);
03076 DESTROYLOCK(&manager->reclock);
03077 manager->magic = 0;
03078 isc_mem_put(manager->mctx, manager, sizeof(*manager));
03079 }
03080
03081 isc_result_t
03082 ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
03083 isc_timermgr_t *timermgr, ns_clientmgr_t **managerp)
03084 {
03085 ns_clientmgr_t *manager;
03086 isc_result_t result;
03087 #if NMCTXS > 0
03088 int i;
03089 #endif
03090
03091 manager = isc_mem_get(mctx, sizeof(*manager));
03092 if (manager == NULL)
03093 return (ISC_R_NOMEMORY);
03094
03095 result = isc_mutex_init(&manager->lock);
03096 if (result != ISC_R_SUCCESS)
03097 goto cleanup_manager;
03098
03099 result = isc_mutex_init(&manager->listlock);
03100 if (result != ISC_R_SUCCESS)
03101 goto cleanup_lock;
03102
03103 result = isc_mutex_init(&manager->reclock);
03104 if (result != ISC_R_SUCCESS)
03105 goto cleanup_listlock;
03106
03107 manager->mctx = mctx;
03108 manager->taskmgr = taskmgr;
03109 manager->timermgr = timermgr;
03110 manager->exiting = ISC_FALSE;
03111 ISC_LIST_INIT(manager->clients);
03112 ISC_LIST_INIT(manager->recursing);
03113 ISC_QUEUE_INIT(manager->inactive, ilink);
03114 #if NMCTXS > 0
03115 manager->nextmctx = 0;
03116 for (i = 0; i < NMCTXS; i++)
03117 manager->mctxpool[i] = NULL;
03118 #endif
03119 manager->magic = MANAGER_MAGIC;
03120
03121 MTRACE("create");
03122
03123 *managerp = manager;
03124
03125 return (ISC_R_SUCCESS);
03126
03127 cleanup_listlock:
03128 (void) isc_mutex_destroy(&manager->listlock);
03129
03130 cleanup_lock:
03131 (void) isc_mutex_destroy(&manager->lock);
03132
03133 cleanup_manager:
03134 isc_mem_put(manager->mctx, manager, sizeof(*manager));
03135
03136 return (result);
03137 }
03138
03139 void
03140 ns_clientmgr_destroy(ns_clientmgr_t **managerp) {
03141 isc_result_t result;
03142 ns_clientmgr_t *manager;
03143 ns_client_t *client;
03144 isc_boolean_t need_destroy = ISC_FALSE, unlock = ISC_FALSE;
03145
03146 REQUIRE(managerp != NULL);
03147 manager = *managerp;
03148 REQUIRE(VALID_MANAGER(manager));
03149
03150 MTRACE("destroy");
03151
03152
03153
03154
03155
03156
03157 result = isc_task_beginexclusive(ns_g_server->task);
03158 if (result == ISC_R_SUCCESS)
03159 unlock = ISC_TRUE;
03160
03161 manager->exiting = ISC_TRUE;
03162
03163 for (client = ISC_LIST_HEAD(manager->clients);
03164 client != NULL;
03165 client = ISC_LIST_NEXT(client, link))
03166 isc_task_shutdown(client->task);
03167
03168 if (ISC_LIST_EMPTY(manager->clients))
03169 need_destroy = ISC_TRUE;
03170
03171 if (unlock)
03172 isc_task_endexclusive(ns_g_server->task);
03173
03174 if (need_destroy)
03175 clientmgr_destroy(manager);
03176
03177 *managerp = NULL;
03178 }
03179
03180 static isc_result_t
03181 get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
03182 dns_dispatch_t *disp, isc_boolean_t tcp)
03183 {
03184 isc_result_t result = ISC_R_SUCCESS;
03185 isc_event_t *ev;
03186 ns_client_t *client;
03187 MTRACE("get client");
03188
03189 REQUIRE(manager != NULL);
03190
03191 if (manager->exiting)
03192 return (ISC_R_SHUTTINGDOWN);
03193
03194
03195
03196
03197
03198 client = NULL;
03199 if (!ns_g_clienttest)
03200 ISC_QUEUE_POP(manager->inactive, ilink, client);
03201
03202 if (client != NULL)
03203 MTRACE("recycle");
03204 else {
03205 MTRACE("create new");
03206
03207 LOCK(&manager->lock);
03208 result = client_create(manager, &client);
03209 UNLOCK(&manager->lock);
03210 if (result != ISC_R_SUCCESS)
03211 return (result);
03212
03213 LOCK(&manager->listlock);
03214 ISC_LIST_APPEND(manager->clients, client, link);
03215 UNLOCK(&manager->listlock);
03216 }
03217
03218 client->manager = manager;
03219 ns_interface_attach(ifp, &client->interface);
03220 client->state = NS_CLIENTSTATE_READY;
03221 INSIST(client->recursionquota == NULL);
03222
03223 client->dscp = ifp->dscp;
03224
03225 if (tcp) {
03226 client->attributes |= NS_CLIENTATTR_TCP;
03227 isc_socket_attach(ifp->tcpsocket,
03228 &client->tcplistener);
03229 } else {
03230 isc_socket_t *sock;
03231
03232 dns_dispatch_attach(disp, &client->dispatch);
03233 sock = dns_dispatch_getsocket(client->dispatch);
03234 isc_socket_attach(sock, &client->udpsocket);
03235 }
03236
03237 INSIST(client->nctls == 0);
03238 client->nctls++;
03239 ev = &client->ctlevent;
03240 isc_task_send(client->task, &ev);
03241
03242 return (ISC_R_SUCCESS);
03243 }
03244
03245 static isc_result_t
03246 get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock)
03247 {
03248 isc_result_t result = ISC_R_SUCCESS;
03249 isc_event_t *ev;
03250 ns_client_t *client;
03251 MTRACE("get worker");
03252
03253 REQUIRE(manager != NULL);
03254
03255 if (manager->exiting)
03256 return (ISC_R_SHUTTINGDOWN);
03257
03258
03259
03260
03261
03262 client = NULL;
03263 if (!ns_g_clienttest)
03264 ISC_QUEUE_POP(manager->inactive, ilink, client);
03265
03266 if (client != NULL)
03267 MTRACE("recycle");
03268 else {
03269 MTRACE("create new");
03270
03271 LOCK(&manager->lock);
03272 result = client_create(manager, &client);
03273 UNLOCK(&manager->lock);
03274 if (result != ISC_R_SUCCESS)
03275 return (result);
03276
03277 LOCK(&manager->listlock);
03278 ISC_LIST_APPEND(manager->clients, client, link);
03279 UNLOCK(&manager->listlock);
03280 }
03281
03282 client->manager = manager;
03283 ns_interface_attach(ifp, &client->interface);
03284 client->newstate = client->state = NS_CLIENTSTATE_WORKING;
03285 INSIST(client->recursionquota == NULL);
03286 client->tcpquota = &ns_g_server->tcpquota;
03287
03288 client->dscp = ifp->dscp;
03289
03290 client->attributes |= NS_CLIENTATTR_TCP;
03291 client->pipelined = ISC_TRUE;
03292
03293 isc_socket_attach(ifp->tcpsocket, &client->tcplistener);
03294 isc_socket_attach(sock, &client->tcpsocket);
03295 isc_socket_setname(client->tcpsocket, "worker-tcp", NULL);
03296 (void)isc_socket_getpeername(client->tcpsocket, &client->peeraddr);
03297 client->peeraddr_valid = ISC_TRUE;
03298
03299 INSIST(client->tcpmsg_valid == ISC_FALSE);
03300 dns_tcpmsg_init(client->mctx, client->tcpsocket, &client->tcpmsg);
03301 client->tcpmsg_valid = ISC_TRUE;
03302
03303 INSIST(client->nctls == 0);
03304 client->nctls++;
03305 ev = &client->ctlevent;
03306 isc_task_send(client->task, &ev);
03307
03308 return (ISC_R_SUCCESS);
03309 }
03310
03311 isc_result_t
03312 ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
03313 ns_interface_t *ifp, isc_boolean_t tcp)
03314 {
03315 isc_result_t result = ISC_R_SUCCESS;
03316 unsigned int disp;
03317
03318 REQUIRE(VALID_MANAGER(manager));
03319 REQUIRE(n > 0);
03320
03321 MTRACE("createclients");
03322
03323 for (disp = 0; disp < n; disp++) {
03324 result = get_client(manager, ifp, ifp->udpdispatch[disp], tcp);
03325 if (result != ISC_R_SUCCESS)
03326 break;
03327 }
03328
03329 return (result);
03330 }
03331
03332 isc_sockaddr_t *
03333 ns_client_getsockaddr(ns_client_t *client) {
03334 return (&client->peeraddr);
03335 }
03336
03337 isc_result_t
03338 ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
03339 dns_acl_t *acl, isc_boolean_t default_allow)
03340 {
03341 isc_result_t result;
03342 isc_netaddr_t tmpnetaddr;
03343 isc_netaddr_t *ecs_addr = NULL;
03344 isc_uint8_t ecs_addrlen = 0;
03345 int match;
03346
03347 if (acl == NULL) {
03348 if (default_allow)
03349 goto allow;
03350 else
03351 goto deny;
03352 }
03353
03354 if (netaddr == NULL) {
03355 isc_netaddr_fromsockaddr(&tmpnetaddr, &client->peeraddr);
03356 netaddr = &tmpnetaddr;
03357 }
03358
03359 if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) {
03360 ecs_addr = &client->ecs_addr;
03361 ecs_addrlen = client->ecs_addrlen;
03362 }
03363
03364 result = dns_acl_match2(netaddr, client->signer,
03365 ecs_addr, ecs_addrlen, NULL, acl,
03366 &ns_g_server->aclenv, &match, NULL);
03367
03368 if (result != ISC_R_SUCCESS)
03369 goto deny;
03370
03371 if (match > 0)
03372 goto allow;
03373 goto deny;
03374
03375 allow:
03376 return (ISC_R_SUCCESS);
03377
03378 deny:
03379 return (DNS_R_REFUSED);
03380 }
03381
03382 isc_result_t
03383 ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr,
03384 const char *opname, dns_acl_t *acl,
03385 isc_boolean_t default_allow, int log_level)
03386 {
03387 isc_result_t result;
03388 isc_netaddr_t netaddr;
03389
03390 if (sockaddr != NULL)
03391 isc_netaddr_fromsockaddr(&netaddr, sockaddr);
03392
03393 result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL,
03394 acl, default_allow);
03395
03396 if (result == ISC_R_SUCCESS)
03397 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
03398 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
03399 "%s approved", opname);
03400 else
03401 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
03402 NS_LOGMODULE_CLIENT,
03403 log_level, "%s denied", opname);
03404 return (result);
03405 }
03406
03407 static void
03408 ns_client_name(ns_client_t *client, char *peerbuf, size_t len) {
03409 if (client->peeraddr_valid)
03410 isc_sockaddr_format(&client->peeraddr, peerbuf,
03411 (unsigned int)len);
03412 else
03413 snprintf(peerbuf, len, "@%p", client);
03414 }
03415
03416 void
03417 ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
03418 isc_logmodule_t *module, int level, const char *fmt, va_list ap)
03419 {
03420 char msgbuf[4096];
03421 char peerbuf[ISC_SOCKADDR_FORMATSIZE];
03422 char signerbuf[DNS_NAME_FORMATSIZE], qnamebuf[DNS_NAME_FORMATSIZE];
03423 const char *viewname = "";
03424 const char *sep1 = "", *sep2 = "", *sep3 = "", *sep4 = "";
03425 const char *signer = "", *qname = "";
03426 dns_name_t *q = NULL;
03427
03428 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
03429
03430 ns_client_name(client, peerbuf, sizeof(peerbuf));
03431
03432 if (client->signer != NULL) {
03433 dns_name_format(client->signer, signerbuf, sizeof(signerbuf));
03434 sep1 = "/key ";
03435 signer = signerbuf;
03436 }
03437
03438 q = client->query.origqname != NULL
03439 ? client->query.origqname : client->query.qname;
03440 if (q != NULL) {
03441 dns_name_format(q, qnamebuf, sizeof(qnamebuf));
03442 sep2 = " (";
03443 sep3 = ")";
03444 qname = qnamebuf;
03445 }
03446
03447 if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 &&
03448 strcmp(client->view->name, "_default") != 0) {
03449 sep4 = ": view ";
03450 viewname = client->view->name;
03451 }
03452
03453 isc_log_write(ns_g_lctx, category, module, level,
03454 "client %s%s%s%s%s%s%s%s: %s",
03455 peerbuf, sep1, signer, sep2, qname, sep3,
03456 sep4, viewname, msgbuf);
03457 }
03458
03459 void
03460 ns_client_log(ns_client_t *client, isc_logcategory_t *category,
03461 isc_logmodule_t *module, int level, const char *fmt, ...)
03462 {
03463 va_list ap;
03464
03465 if (! isc_log_wouldlog(ns_g_lctx, level))
03466 return;
03467
03468 va_start(ap, fmt);
03469 ns_client_logv(client, category, module, level, fmt, ap);
03470 va_end(ap);
03471 }
03472
03473 void
03474 ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type,
03475 dns_rdataclass_t rdclass, char *buf, size_t len)
03476 {
03477 char namebuf[DNS_NAME_FORMATSIZE];
03478 char typebuf[DNS_RDATATYPE_FORMATSIZE];
03479 char classbuf[DNS_RDATACLASS_FORMATSIZE];
03480
03481 dns_name_format(name, namebuf, sizeof(namebuf));
03482 dns_rdatatype_format(type, typebuf, sizeof(typebuf));
03483 dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf));
03484 (void)snprintf(buf, len, "%s '%s/%s/%s'", msg, namebuf, typebuf,
03485 classbuf);
03486 }
03487
03488 static void
03489 ns_client_dumpmessage(ns_client_t *client, const char *reason) {
03490 isc_buffer_t buffer;
03491 char *buf = NULL;
03492 int len = 1024;
03493 isc_result_t result;
03494
03495 if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(1)))
03496 return;
03497
03498
03499
03500
03501
03502
03503 do {
03504 buf = isc_mem_get(client->mctx, len);
03505 if (buf == NULL)
03506 break;
03507 isc_buffer_init(&buffer, buf, len);
03508 result = dns_message_totext(client->message,
03509 &dns_master_style_debug,
03510 0, &buffer);
03511 if (result == ISC_R_NOSPACE) {
03512 isc_mem_put(client->mctx, buf, len);
03513 len += 1024;
03514 } else if (result == ISC_R_SUCCESS)
03515 ns_client_log(client, NS_LOGCATEGORY_UNMATCHED,
03516 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
03517 "%s\n%.*s", reason,
03518 (int)isc_buffer_usedlength(&buffer),
03519 buf);
03520 } while (result == ISC_R_NOSPACE);
03521
03522 if (buf != NULL)
03523 isc_mem_put(client->mctx, buf, len);
03524 }
03525
03526 void
03527 ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {
03528 ns_client_t *client;
03529 char namebuf[DNS_NAME_FORMATSIZE];
03530 char original[DNS_NAME_FORMATSIZE];
03531 char peerbuf[ISC_SOCKADDR_FORMATSIZE];
03532 char typebuf[DNS_RDATATYPE_FORMATSIZE];
03533 char classbuf[DNS_RDATACLASS_FORMATSIZE];
03534 const char *name;
03535 const char *sep;
03536 const char *origfor;
03537 dns_rdataset_t *rdataset;
03538
03539 REQUIRE(VALID_MANAGER(manager));
03540
03541 LOCK(&manager->reclock);
03542 client = ISC_LIST_HEAD(manager->recursing);
03543 while (client != NULL) {
03544 INSIST(client->state == NS_CLIENTSTATE_RECURSING);
03545
03546 ns_client_name(client, peerbuf, sizeof(peerbuf));
03547 if (client->view != NULL &&
03548 strcmp(client->view->name, "_bind") != 0 &&
03549 strcmp(client->view->name, "_default") != 0) {
03550 name = client->view->name;
03551 sep = ": view ";
03552 } else {
03553 name = "";
03554 sep = "";
03555 }
03556
03557 LOCK(&client->query.fetchlock);
03558 INSIST(client->query.qname != NULL);
03559 dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
03560 if (client->query.qname != client->query.origqname &&
03561 client->query.origqname != NULL) {
03562 origfor = " for ";
03563 dns_name_format(client->query.origqname, original,
03564 sizeof(original));
03565 } else {
03566 origfor = "";
03567 original[0] = '\0';
03568 }
03569 rdataset = ISC_LIST_HEAD(client->query.qname->list);
03570 if (rdataset == NULL && client->query.origqname != NULL)
03571 rdataset = ISC_LIST_HEAD(client->query.origqname->list);
03572 if (rdataset != NULL) {
03573 dns_rdatatype_format(rdataset->type, typebuf,
03574 sizeof(typebuf));
03575 dns_rdataclass_format(rdataset->rdclass, classbuf,
03576 sizeof(classbuf));
03577 } else {
03578 strcpy(typebuf, "-");
03579 strcpy(classbuf, "-");
03580 }
03581 UNLOCK(&client->query.fetchlock);
03582 fprintf(f, "; client %s%s%s: id %u '%s/%s/%s'%s%s "
03583 "requesttime %d\n", peerbuf, sep, name,
03584 client->message->id, namebuf, typebuf, classbuf,
03585 origfor, original, client->requesttime);
03586 client = ISC_LIST_NEXT(client, rlink);
03587 }
03588 UNLOCK(&manager->reclock);
03589 }
03590
03591 void
03592 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) {
03593 LOCK(&client->query.fetchlock);
03594 if (client->query.restarts > 0) {
03595
03596
03597
03598 dns_message_puttempname(client->message,
03599 &client->query.qname);
03600 }
03601 client->query.qname = name;
03602 client->query.attributes &= ~NS_QUERYATTR_REDIRECT;
03603 UNLOCK(&client->query.fetchlock);
03604 }
03605
03606 isc_result_t
03607 ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp) {
03608 ns_client_t *client = (ns_client_t *) ci->data;
03609
03610 REQUIRE(NS_CLIENT_VALID(client));
03611 REQUIRE(addrp != NULL);
03612
03613 *addrp = &client->peeraddr;
03614 return (ISC_R_SUCCESS);
03615 }