00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <string.h>
00023
00024 #include <isc/hex.h>
00025 #include <isc/mem.h>
00026 #include <isc/print.h>
00027 #include <isc/serial.h>
00028 #include <isc/stats.h>
00029 #include <isc/util.h>
00030
00031 #include <dns/adb.h>
00032 #include <dns/badcache.h>
00033 #include <dns/byaddr.h>
00034 #include <dns/cache.h>
00035 #include <dns/db.h>
00036 #include <dns/dlz.h>
00037 #include <dns/dns64.h>
00038 #include <dns/dnssec.h>
00039 #include <dns/events.h>
00040 #include <dns/message.h>
00041 #include <dns/ncache.h>
00042 #include <dns/nsec3.h>
00043 #include <dns/order.h>
00044 #include <dns/rdata.h>
00045 #include <dns/rdataclass.h>
00046 #include <dns/rdatalist.h>
00047 #include <dns/rdataset.h>
00048 #include <dns/rdatasetiter.h>
00049 #include <dns/rdatastruct.h>
00050 #include <dns/rdatatype.h>
00051 #include <dns/resolver.h>
00052 #include <dns/result.h>
00053 #include <dns/stats.h>
00054 #include <dns/tkey.h>
00055 #include <dns/view.h>
00056 #include <dns/zone.h>
00057 #include <dns/zt.h>
00058
00059 #include <named/client.h>
00060 #include <named/globals.h>
00061 #include <named/log.h>
00062 #include <named/server.h>
00063 #include <named/sortlist.h>
00064 #include <named/xfrout.h>
00065
00066 #if 0
00067
00068
00069
00070
00071
00072
00073
00074 #define dns64_bis_return_excluded_addresses 1
00075 #endif
00076
00077
00078 #define PARTIALANSWER(c) (((c)->query.attributes & \
00079 NS_QUERYATTR_PARTIALANSWER) != 0)
00080
00081 #define USECACHE(c) (((c)->query.attributes & \
00082 NS_QUERYATTR_CACHEOK) != 0)
00083
00084 #define RECURSIONOK(c) (((c)->query.attributes & \
00085 NS_QUERYATTR_RECURSIONOK) != 0)
00086
00087 #define RECURSING(c) (((c)->query.attributes & \
00088 NS_QUERYATTR_RECURSING) != 0)
00089
00090 #define CACHEGLUEOK(c) (((c)->query.attributes & \
00091 NS_QUERYATTR_CACHEGLUEOK) != 0)
00092
00093 #define WANTRECURSION(c) (((c)->query.attributes & \
00094 NS_QUERYATTR_WANTRECURSION) != 0)
00095
00096 #define WANTDNSSEC(c) (((c)->attributes & \
00097 NS_CLIENTATTR_WANTDNSSEC) != 0)
00098
00099 #define WANTAD(c) (((c)->attributes & \
00100 NS_CLIENTATTR_WANTAD) != 0)
00101 #ifdef ISC_PLATFORM_USESIT
00102
00103 #define HAVESIT(c) (((c)->attributes & \
00104 NS_CLIENTATTR_HAVESIT) != 0)
00105 #else
00106 #define HAVESIT(c) (0)
00107 #endif
00108
00109
00110 #define NOAUTHORITY(c) (((c)->query.attributes & \
00111 NS_QUERYATTR_NOAUTHORITY) != 0)
00112
00113 #define NOADDITIONAL(c) (((c)->query.attributes & \
00114 NS_QUERYATTR_NOADDITIONAL) != 0)
00115
00116 #define SECURE(c) (((c)->query.attributes & \
00117 NS_QUERYATTR_SECURE) != 0)
00118
00119 #define DNS64(c) (((c)->query.attributes & \
00120 NS_QUERYATTR_DNS64) != 0)
00121
00122 #define DNS64EXCLUDE(c) (((c)->query.attributes & \
00123 NS_QUERYATTR_DNS64EXCLUDE) != 0)
00124
00125 #define REDIRECT(c) (((c)->query.attributes & \
00126 NS_QUERYATTR_REDIRECT) != 0)
00127
00128
00129 #define NOQNAME(r) (((r)->attributes & \
00130 DNS_RDATASETATTR_NOQNAME) != 0)
00131
00132 #ifdef WANT_QUERYTRACE
00133 #define CTRACE(l,m) do { \
00134 if (client != NULL && client->query.qname != NULL) { \
00135 if (isc_log_wouldlog(ns_g_lctx, l)) { \
00136 char qbuf[DNS_NAME_FORMATSIZE]; \
00137 dns_name_format(client->query.qname, \
00138 qbuf, sizeof(qbuf)); \
00139 isc_log_write(ns_g_lctx, \
00140 NS_LOGCATEGORY_CLIENT, \
00141 NS_LOGMODULE_QUERY, \
00142 l, "client %p (%s): %s", \
00143 client, qbuf, (m)); \
00144 } \
00145 } else { \
00146 isc_log_write(ns_g_lctx, \
00147 NS_LOGCATEGORY_CLIENT, \
00148 NS_LOGMODULE_QUERY, \
00149 l, "client %p (<unknown-name>): %s", \
00150 client, (m)); \
00151 } \
00152 } while(0)
00153 #else
00154 #define CTRACE(l,m) ((void)m)
00155 #endif
00156
00157
00158 #define DNS_GETDB_NOEXACT 0x01U
00159 #define DNS_GETDB_NOLOG 0x02U
00160 #define DNS_GETDB_PARTIAL 0x04U
00161 #define DNS_GETDB_IGNOREACL 0x08U
00162
00163 #define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0)
00164
00165 #define SFCACHE_CDFLAG 0x1
00166
00167 typedef struct client_additionalctx {
00168 ns_client_t *client;
00169 dns_rdataset_t *rdataset;
00170 } client_additionalctx_t;
00171
00172 static isc_result_t
00173 query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype);
00174
00175 static isc_boolean_t
00176 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
00177 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
00178
00179 static void
00180 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
00181 dns_dbversion_t *version, ns_client_t *client,
00182 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
00183 dns_name_t *fname, isc_boolean_t exact,
00184 dns_name_t *found);
00185
00186 static inline void
00187 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level);
00188
00189 static void
00190 rpz_st_clear(ns_client_t *client);
00191
00192
00193
00194
00195 static inline void
00196 inc_stats(ns_client_t *client, isc_statscounter_t counter) {
00197 dns_zone_t *zone = client->query.authzone;
00198 dns_rdatatype_t qtype;
00199 dns_rdataset_t *rdataset;
00200 isc_stats_t *zonestats;
00201 dns_stats_t *querystats = NULL;
00202
00203 isc_stats_increment(ns_g_server->nsstats, counter);
00204
00205 if (zone == NULL)
00206 return;
00207
00208
00209 zonestats = dns_zone_getrequeststats(zone);
00210
00211 if (zonestats != NULL)
00212 isc_stats_increment(zonestats, counter);
00213
00214
00215
00216
00217
00218
00219 if (counter == dns_nsstatscounter_authans) {
00220 querystats = dns_zone_getrcvquerystats(zone);
00221 if (querystats != NULL) {
00222 rdataset = ISC_LIST_HEAD(client->query.qname->list);
00223 if (rdataset != NULL) {
00224 qtype = rdataset->type;
00225 dns_rdatatypestats_increment(querystats, qtype);
00226 }
00227 }
00228 }
00229 }
00230
00231 static void
00232 query_send(ns_client_t *client) {
00233 isc_statscounter_t counter;
00234
00235 if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0)
00236 inc_stats(client, dns_nsstatscounter_nonauthans);
00237 else
00238 inc_stats(client, dns_nsstatscounter_authans);
00239
00240 if (client->message->rcode == dns_rcode_noerror) {
00241 dns_section_t answer = DNS_SECTION_ANSWER;
00242 if (ISC_LIST_EMPTY(client->message->sections[answer])) {
00243 if (client->query.isreferral)
00244 counter = dns_nsstatscounter_referral;
00245 else
00246 counter = dns_nsstatscounter_nxrrset;
00247 } else
00248 counter = dns_nsstatscounter_success;
00249 } else if (client->message->rcode == dns_rcode_nxdomain)
00250 counter = dns_nsstatscounter_nxdomain;
00251 else
00252 counter = dns_nsstatscounter_failure;
00253
00254 inc_stats(client, counter);
00255 ns_client_send(client);
00256 }
00257
00258 static void
00259 query_error(ns_client_t *client, isc_result_t result, int line) {
00260 int loglevel = ISC_LOG_DEBUG(3);
00261
00262 switch (result) {
00263 case DNS_R_SERVFAIL:
00264 loglevel = ISC_LOG_DEBUG(1);
00265 inc_stats(client, dns_nsstatscounter_servfail);
00266 break;
00267 case DNS_R_FORMERR:
00268 inc_stats(client, dns_nsstatscounter_formerr);
00269 break;
00270 default:
00271 inc_stats(client, dns_nsstatscounter_failure);
00272 break;
00273 }
00274
00275 if (ns_g_server->log_queries)
00276 loglevel = ISC_LOG_INFO;
00277
00278 log_queryerror(client, result, line, loglevel);
00279
00280 ns_client_error(client, result);
00281 }
00282
00283 static void
00284 query_next(ns_client_t *client, isc_result_t result) {
00285 if (result == DNS_R_DUPLICATE)
00286 inc_stats(client, dns_nsstatscounter_duplicate);
00287 else if (result == DNS_R_DROP)
00288 inc_stats(client, dns_nsstatscounter_dropped);
00289 else
00290 inc_stats(client, dns_nsstatscounter_failure);
00291 ns_client_next(client, result);
00292 }
00293
00294 static inline void
00295 query_freefreeversions(ns_client_t *client, isc_boolean_t everything) {
00296 ns_dbversion_t *dbversion, *dbversion_next;
00297 unsigned int i;
00298
00299 for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0;
00300 dbversion != NULL;
00301 dbversion = dbversion_next, i++)
00302 {
00303 dbversion_next = ISC_LIST_NEXT(dbversion, link);
00304
00305
00306
00307
00308 if (i > 3 || everything) {
00309 ISC_LIST_UNLINK(client->query.freeversions, dbversion,
00310 link);
00311 isc_mem_put(client->mctx, dbversion,
00312 sizeof(*dbversion));
00313 }
00314 }
00315 }
00316
00317 void
00318 ns_query_cancel(ns_client_t *client) {
00319 LOCK(&client->query.fetchlock);
00320 if (client->query.fetch != NULL) {
00321 dns_resolver_cancelfetch(client->query.fetch);
00322
00323 client->query.fetch = NULL;
00324 }
00325 UNLOCK(&client->query.fetchlock);
00326 }
00327
00328 static inline void
00329 query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
00330 dns_rdataset_t *rdataset = *rdatasetp;
00331
00332 CTRACE(ISC_LOG_DEBUG(3), "query_putrdataset");
00333 if (rdataset != NULL) {
00334 if (dns_rdataset_isassociated(rdataset))
00335 dns_rdataset_disassociate(rdataset);
00336 dns_message_puttemprdataset(client->message, rdatasetp);
00337 }
00338 CTRACE(ISC_LOG_DEBUG(3), "query_putrdataset: done");
00339 }
00340
00341 static inline void
00342 query_reset(ns_client_t *client, isc_boolean_t everything) {
00343 isc_buffer_t *dbuf, *dbuf_next;
00344 ns_dbversion_t *dbversion, *dbversion_next;
00345
00346
00347
00348
00349
00350
00351
00352
00353 ns_query_cancel(client);
00354
00355
00356
00357
00358 for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
00359 dbversion != NULL;
00360 dbversion = dbversion_next) {
00361 dbversion_next = ISC_LIST_NEXT(dbversion, link);
00362 dns_db_closeversion(dbversion->db, &dbversion->version,
00363 ISC_FALSE);
00364 dns_db_detach(&dbversion->db);
00365 ISC_LIST_INITANDAPPEND(client->query.freeversions,
00366 dbversion, link);
00367 }
00368 ISC_LIST_INIT(client->query.activeversions);
00369
00370 if (client->query.authdb != NULL)
00371 dns_db_detach(&client->query.authdb);
00372 if (client->query.authzone != NULL)
00373 dns_zone_detach(&client->query.authzone);
00374
00375 if (client->query.dns64_aaaa != NULL)
00376 query_putrdataset(client, &client->query.dns64_aaaa);
00377 if (client->query.dns64_sigaaaa != NULL)
00378 query_putrdataset(client, &client->query.dns64_sigaaaa);
00379 if (client->query.dns64_aaaaok != NULL) {
00380 isc_mem_put(client->mctx, client->query.dns64_aaaaok,
00381 client->query.dns64_aaaaoklen *
00382 sizeof(isc_boolean_t));
00383 client->query.dns64_aaaaok = NULL;
00384 client->query.dns64_aaaaoklen = 0;
00385 }
00386
00387 query_putrdataset(client, &client->query.redirect.rdataset);
00388 query_putrdataset(client, &client->query.redirect.sigrdataset);
00389 if (client->query.redirect.db != NULL) {
00390 if (client->query.redirect.node != NULL)
00391 dns_db_detachnode(client->query.redirect.db,
00392 &client->query.redirect.node);
00393 dns_db_detach(&client->query.redirect.db);
00394 }
00395 if (client->query.redirect.zone != NULL)
00396 dns_zone_detach(&client->query.redirect.zone);
00397
00398 query_freefreeversions(client, everything);
00399
00400 for (dbuf = ISC_LIST_HEAD(client->query.namebufs);
00401 dbuf != NULL;
00402 dbuf = dbuf_next) {
00403 dbuf_next = ISC_LIST_NEXT(dbuf, link);
00404 if (dbuf_next != NULL || everything) {
00405 ISC_LIST_UNLINK(client->query.namebufs, dbuf, link);
00406 isc_buffer_free(&dbuf);
00407 }
00408 }
00409
00410 if (client->query.restarts > 0) {
00411
00412
00413
00414 dns_message_puttempname(client->message,
00415 &client->query.qname);
00416 }
00417 client->query.qname = NULL;
00418 client->query.attributes = (NS_QUERYATTR_RECURSIONOK |
00419 NS_QUERYATTR_CACHEOK |
00420 NS_QUERYATTR_SECURE);
00421 client->query.restarts = 0;
00422 client->query.timerset = ISC_FALSE;
00423 if (client->query.rpz_st != NULL) {
00424 rpz_st_clear(client);
00425 if (everything) {
00426 isc_mem_put(client->mctx, client->query.rpz_st,
00427 sizeof(*client->query.rpz_st));
00428 client->query.rpz_st = NULL;
00429 }
00430 }
00431 client->query.origqname = NULL;
00432 client->query.dboptions = 0;
00433 client->query.fetchoptions = 0;
00434 client->query.gluedb = NULL;
00435 client->query.authdbset = ISC_FALSE;
00436 client->query.isreferral = ISC_FALSE;
00437 client->query.dns64_options = 0;
00438 client->query.dns64_ttl = ISC_UINT32_MAX;
00439 }
00440
00441 static void
00442 query_next_callback(ns_client_t *client) {
00443 query_reset(client, ISC_FALSE);
00444 }
00445
00446 void
00447 ns_query_free(ns_client_t *client) {
00448 query_reset(client, ISC_TRUE);
00449 }
00450
00451 static inline isc_result_t
00452 query_newnamebuf(ns_client_t *client) {
00453 isc_buffer_t *dbuf;
00454 isc_result_t result;
00455
00456 CTRACE(ISC_LOG_DEBUG(3), "query_newnamebuf");
00457
00458
00459
00460
00461 dbuf = NULL;
00462 result = isc_buffer_allocate(client->mctx, &dbuf, 1024);
00463 if (result != ISC_R_SUCCESS) {
00464 CTRACE(ISC_LOG_DEBUG(3),
00465 "query_newnamebuf: isc_buffer_allocate failed: done");
00466 return (result);
00467 }
00468 ISC_LIST_APPEND(client->query.namebufs, dbuf, link);
00469
00470 CTRACE(ISC_LOG_DEBUG(3), "query_newnamebuf: done");
00471 return (ISC_R_SUCCESS);
00472 }
00473
00474 static inline isc_buffer_t *
00475 query_getnamebuf(ns_client_t *client) {
00476 isc_buffer_t *dbuf;
00477 isc_result_t result;
00478 isc_region_t r;
00479
00480 CTRACE(ISC_LOG_DEBUG(3), "query_getnamebuf");
00481
00482
00483
00484
00485
00486 if (ISC_LIST_EMPTY(client->query.namebufs)) {
00487 result = query_newnamebuf(client);
00488 if (result != ISC_R_SUCCESS) {
00489 CTRACE(ISC_LOG_DEBUG(3),
00490 "query_getnamebuf: query_newnamebuf failed: done");
00491 return (NULL);
00492 }
00493 }
00494
00495 dbuf = ISC_LIST_TAIL(client->query.namebufs);
00496 INSIST(dbuf != NULL);
00497 isc_buffer_availableregion(dbuf, &r);
00498 if (r.length < 255) {
00499 result = query_newnamebuf(client);
00500 if (result != ISC_R_SUCCESS) {
00501 CTRACE(ISC_LOG_DEBUG(3),
00502 "query_getnamebuf: query_newnamebuf failed: done");
00503 return (NULL);
00504
00505 }
00506 dbuf = ISC_LIST_TAIL(client->query.namebufs);
00507 isc_buffer_availableregion(dbuf, &r);
00508 INSIST(r.length >= 255);
00509 }
00510 CTRACE(ISC_LOG_DEBUG(3), "query_getnamebuf: done");
00511 return (dbuf);
00512 }
00513
00514 static inline void
00515 query_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) {
00516 isc_region_t r;
00517
00518 CTRACE(ISC_LOG_DEBUG(3), "query_keepname");
00519
00520
00521
00522
00523
00524 REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0);
00525
00526 dns_name_toregion(name, &r);
00527 isc_buffer_add(dbuf, r.length);
00528 dns_name_setbuffer(name, NULL);
00529 client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
00530 }
00531
00532 static inline void
00533 query_releasename(ns_client_t *client, dns_name_t **namep) {
00534 dns_name_t *name = *namep;
00535
00536
00537
00538
00539
00540
00541
00542 CTRACE(ISC_LOG_DEBUG(3), "query_releasename");
00543 if (dns_name_hasbuffer(name)) {
00544 INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED)
00545 != 0);
00546 client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
00547 }
00548 dns_message_puttempname(client->message, namep);
00549 CTRACE(ISC_LOG_DEBUG(3), "query_releasename: done");
00550 }
00551
00552 static inline dns_name_t *
00553 query_newname(ns_client_t *client, isc_buffer_t *dbuf,
00554 isc_buffer_t *nbuf)
00555 {
00556 dns_name_t *name;
00557 isc_region_t r;
00558 isc_result_t result;
00559
00560 REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0);
00561
00562 CTRACE(ISC_LOG_DEBUG(3), "query_newname");
00563 name = NULL;
00564 result = dns_message_gettempname(client->message, &name);
00565 if (result != ISC_R_SUCCESS) {
00566 CTRACE(ISC_LOG_DEBUG(3),
00567 "query_newname: dns_message_gettempname failed: done");
00568 return (NULL);
00569 }
00570 isc_buffer_availableregion(dbuf, &r);
00571 isc_buffer_init(nbuf, r.base, r.length);
00572 dns_name_init(name, NULL);
00573 dns_name_setbuffer(name, nbuf);
00574 client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED;
00575
00576 CTRACE(ISC_LOG_DEBUG(3), "query_newname: done");
00577 return (name);
00578 }
00579
00580 static inline dns_rdataset_t *
00581 query_newrdataset(ns_client_t *client) {
00582 dns_rdataset_t *rdataset;
00583 isc_result_t result;
00584
00585 CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset");
00586 rdataset = NULL;
00587 result = dns_message_gettemprdataset(client->message, &rdataset);
00588 if (result != ISC_R_SUCCESS) {
00589 CTRACE(ISC_LOG_DEBUG(3),
00590 "query_newrdataset: "
00591 "dns_message_gettemprdataset failed: done");
00592 return (NULL);
00593 }
00594 dns_rdataset_init(rdataset);
00595
00596 CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset: done");
00597 return (rdataset);
00598 }
00599
00600 static inline isc_result_t
00601 query_newdbversion(ns_client_t *client, unsigned int n) {
00602 unsigned int i;
00603 ns_dbversion_t *dbversion;
00604
00605 for (i = 0; i < n; i++) {
00606 dbversion = isc_mem_get(client->mctx, sizeof(*dbversion));
00607 if (dbversion != NULL) {
00608 dbversion->db = NULL;
00609 dbversion->version = NULL;
00610 ISC_LIST_INITANDAPPEND(client->query.freeversions,
00611 dbversion, link);
00612 } else {
00613
00614
00615
00616
00617 if (i == 0)
00618 return (ISC_R_NOMEMORY);
00619 else
00620 return (ISC_R_SUCCESS);
00621 }
00622 }
00623
00624 return (ISC_R_SUCCESS);
00625 }
00626
00627 static inline ns_dbversion_t *
00628 query_getdbversion(ns_client_t *client) {
00629 isc_result_t result;
00630 ns_dbversion_t *dbversion;
00631
00632 if (ISC_LIST_EMPTY(client->query.freeversions)) {
00633 result = query_newdbversion(client, 1);
00634 if (result != ISC_R_SUCCESS)
00635 return (NULL);
00636 }
00637 dbversion = ISC_LIST_HEAD(client->query.freeversions);
00638 INSIST(dbversion != NULL);
00639 ISC_LIST_UNLINK(client->query.freeversions, dbversion, link);
00640
00641 return (dbversion);
00642 }
00643
00644 isc_result_t
00645 ns_query_init(ns_client_t *client) {
00646 isc_result_t result;
00647
00648 ISC_LIST_INIT(client->query.namebufs);
00649 ISC_LIST_INIT(client->query.activeversions);
00650 ISC_LIST_INIT(client->query.freeversions);
00651 client->query.restarts = 0;
00652 client->query.timerset = ISC_FALSE;
00653 client->query.rpz_st = NULL;
00654 client->query.qname = NULL;
00655
00656
00657
00658
00659 result = isc_mutex_init(&client->query.fetchlock);
00660 if (result != ISC_R_SUCCESS)
00661 return (result);
00662 client->query.fetch = NULL;
00663 client->query.prefetch = NULL;
00664 client->query.authdb = NULL;
00665 client->query.authzone = NULL;
00666 client->query.authdbset = ISC_FALSE;
00667 client->query.isreferral = ISC_FALSE;
00668 client->query.dns64_aaaa = NULL;
00669 client->query.dns64_sigaaaa = NULL;
00670 client->query.dns64_aaaaok = NULL;
00671 client->query.dns64_aaaaoklen = 0;
00672 client->query.redirect.db = NULL;
00673 client->query.redirect.node = NULL;
00674 client->query.redirect.zone = NULL;
00675 client->query.redirect.qtype = dns_rdatatype_none;
00676 client->query.redirect.result = ISC_R_SUCCESS;
00677 client->query.redirect.rdataset = NULL;
00678 client->query.redirect.sigrdataset = NULL;
00679 dns_fixedname_init(&client->query.redirect.fixed);
00680 client->query.redirect.fname =
00681 dns_fixedname_name(&client->query.redirect.fixed);
00682 query_reset(client, ISC_FALSE);
00683 result = query_newdbversion(client, 3);
00684 if (result != ISC_R_SUCCESS) {
00685 DESTROYLOCK(&client->query.fetchlock);
00686 return (result);
00687 }
00688 result = query_newnamebuf(client);
00689 if (result != ISC_R_SUCCESS) {
00690 query_freefreeversions(client, ISC_TRUE);
00691 DESTROYLOCK(&client->query.fetchlock);
00692 }
00693
00694 return (result);
00695 }
00696
00697 static inline ns_dbversion_t *
00698 query_findversion(ns_client_t *client, dns_db_t *db)
00699 {
00700 ns_dbversion_t *dbversion;
00701
00702
00703
00704
00705
00706
00707 for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
00708 dbversion != NULL;
00709 dbversion = ISC_LIST_NEXT(dbversion, link)) {
00710 if (dbversion->db == db)
00711 break;
00712 }
00713
00714 if (dbversion == NULL) {
00715
00716
00717
00718
00719 dbversion = query_getdbversion(client);
00720 if (dbversion == NULL)
00721 return (NULL);
00722 dns_db_attach(db, &dbversion->db);
00723 dns_db_currentversion(db, &dbversion->version);
00724 dbversion->acl_checked = ISC_FALSE;
00725 dbversion->queryok = ISC_FALSE;
00726 ISC_LIST_APPEND(client->query.activeversions,
00727 dbversion, link);
00728 }
00729
00730 return (dbversion);
00731 }
00732
00733 static inline isc_result_t
00734 query_validatezonedb(ns_client_t *client, dns_name_t *name,
00735 dns_rdatatype_t qtype, unsigned int options,
00736 dns_zone_t *zone, dns_db_t *db,
00737 dns_dbversion_t **versionp)
00738 {
00739 isc_result_t result;
00740 dns_acl_t *queryacl, *queryonacl;
00741 ns_dbversion_t *dbversion;
00742
00743 REQUIRE(zone != NULL);
00744 REQUIRE(db != NULL);
00745
00746
00747
00748
00749
00750
00751
00752 if (!client->view->additionalfromauth &&
00753 client->query.authdbset &&
00754 db != client->query.authdb)
00755 return (DNS_R_REFUSED);
00756
00757
00758
00759
00760
00761
00762 if (dns_zone_gettype(zone) == dns_zone_staticstub &&
00763 !RECURSIONOK(client)) {
00764 return (DNS_R_REFUSED);
00765 }
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 dbversion = query_findversion(client, db);
00779 if (dbversion == NULL) {
00780 CTRACE(ISC_LOG_ERROR, "unable to get db version");
00781 return (DNS_R_SERVFAIL);
00782 }
00783
00784 if ((options & DNS_GETDB_IGNOREACL) != 0)
00785 goto approved;
00786 if (dbversion->acl_checked) {
00787 if (!dbversion->queryok)
00788 return (DNS_R_REFUSED);
00789 goto approved;
00790 }
00791
00792 queryacl = dns_zone_getqueryacl(zone);
00793 if (queryacl == NULL) {
00794 queryacl = client->view->queryacl;
00795 if ((client->query.attributes &
00796 NS_QUERYATTR_QUERYOKVALID) != 0) {
00797
00798
00799
00800
00801
00802
00803 dbversion->acl_checked = ISC_TRUE;
00804 if ((client->query.attributes &
00805 NS_QUERYATTR_QUERYOK) == 0) {
00806 dbversion->queryok = ISC_FALSE;
00807 return (DNS_R_REFUSED);
00808 }
00809 dbversion->queryok = ISC_TRUE;
00810 goto approved;
00811 }
00812 }
00813
00814 result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE);
00815 if ((options & DNS_GETDB_NOLOG) == 0) {
00816 char msg[NS_CLIENT_ACLMSGSIZE("query")];
00817 if (result == ISC_R_SUCCESS) {
00818 if (isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(3))) {
00819 ns_client_aclmsg("query", name, qtype,
00820 client->view->rdclass,
00821 msg, sizeof(msg));
00822 ns_client_log(client,
00823 DNS_LOGCATEGORY_SECURITY,
00824 NS_LOGMODULE_QUERY,
00825 ISC_LOG_DEBUG(3),
00826 "%s approved", msg);
00827 }
00828 } else {
00829 ns_client_aclmsg("query", name, qtype,
00830 client->view->rdclass,
00831 msg, sizeof(msg));
00832 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
00833 NS_LOGMODULE_QUERY, ISC_LOG_INFO,
00834 "%s denied", msg);
00835 }
00836 }
00837
00838 if (queryacl == client->view->queryacl) {
00839 if (result == ISC_R_SUCCESS) {
00840
00841
00842
00843
00844
00845 client->query.attributes |= NS_QUERYATTR_QUERYOK;
00846 }
00847
00848
00849
00850
00851 client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
00852 }
00853
00854
00855 if (result == ISC_R_SUCCESS) {
00856 queryonacl = dns_zone_getqueryonacl(zone);
00857 if (queryonacl == NULL)
00858 queryonacl = client->view->queryonacl;
00859
00860 result = ns_client_checkaclsilent(client, &client->destaddr,
00861 queryonacl, ISC_TRUE);
00862 if ((options & DNS_GETDB_NOLOG) == 0 &&
00863 result != ISC_R_SUCCESS)
00864 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
00865 NS_LOGMODULE_QUERY, ISC_LOG_INFO,
00866 "query-on denied");
00867 }
00868
00869 dbversion->acl_checked = ISC_TRUE;
00870 if (result != ISC_R_SUCCESS) {
00871 dbversion->queryok = ISC_FALSE;
00872 return (DNS_R_REFUSED);
00873 }
00874 dbversion->queryok = ISC_TRUE;
00875
00876 approved:
00877
00878 if (versionp != NULL)
00879 *versionp = dbversion->version;
00880 return (ISC_R_SUCCESS);
00881 }
00882
00883 static inline isc_result_t
00884 query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
00885 unsigned int options, dns_zone_t **zonep, dns_db_t **dbp,
00886 dns_dbversion_t **versionp)
00887 {
00888 isc_result_t result;
00889 unsigned int ztoptions;
00890 dns_zone_t *zone = NULL;
00891 dns_db_t *db = NULL;
00892 isc_boolean_t partial = ISC_FALSE;
00893
00894 REQUIRE(zonep != NULL && *zonep == NULL);
00895 REQUIRE(dbp != NULL && *dbp == NULL);
00896
00897
00898
00899
00900 ztoptions = ((options & DNS_GETDB_NOEXACT) != 0) ?
00901 DNS_ZTFIND_NOEXACT : 0;
00902
00903 result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL,
00904 &zone);
00905
00906 if (result == DNS_R_PARTIALMATCH)
00907 partial = ISC_TRUE;
00908 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
00909 result = dns_zone_getdb(zone, &db);
00910
00911 if (result != ISC_R_SUCCESS)
00912 goto fail;
00913
00914 result = query_validatezonedb(client, name, qtype, options, zone, db,
00915 versionp);
00916
00917 if (result != ISC_R_SUCCESS)
00918 goto fail;
00919
00920
00921 *zonep = zone;
00922 *dbp = db;
00923
00924 if (partial && (options & DNS_GETDB_PARTIAL) != 0)
00925 return (DNS_R_PARTIALMATCH);
00926 return (ISC_R_SUCCESS);
00927
00928 fail:
00929 if (zone != NULL)
00930 dns_zone_detach(&zone);
00931 if (db != NULL)
00932 dns_db_detach(&db);
00933
00934 return (result);
00935 }
00936
00937 static void
00938 rpz_log_rewrite(ns_client_t *client, isc_boolean_t disabled,
00939 dns_rpz_policy_t policy, dns_rpz_type_t type,
00940 dns_zone_t *p_zone, dns_name_t *p_name,
00941 dns_name_t *cname)
00942 {
00943 isc_stats_t *zonestats;
00944 char qname_buf[DNS_NAME_FORMATSIZE];
00945 char p_name_buf[DNS_NAME_FORMATSIZE];
00946 char cname_buf[DNS_NAME_FORMATSIZE] = { 0 };
00947 const char *s1 = cname_buf, *s2 = cname_buf;
00948
00949
00950
00951
00952
00953 if (!disabled && policy != DNS_RPZ_POLICY_PASSTHRU) {
00954 isc_stats_increment(ns_g_server->nsstats,
00955 dns_nsstatscounter_rpz_rewrites);
00956 }
00957 if (p_zone != NULL) {
00958 zonestats = dns_zone_getrequeststats(p_zone);
00959 if (zonestats != NULL)
00960 isc_stats_increment(zonestats,
00961 dns_nsstatscounter_rpz_rewrites);
00962 }
00963
00964 if (!isc_log_wouldlog(ns_g_lctx, DNS_RPZ_INFO_LEVEL))
00965 return;
00966
00967 dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf));
00968 dns_name_format(p_name, p_name_buf, sizeof(p_name_buf));
00969 if (cname != NULL) {
00970 s1 = " (CNAME to: ";
00971 dns_name_format(cname, cname_buf, sizeof(cname_buf));
00972 s2 = ")";
00973 }
00974
00975 ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY,
00976 DNS_RPZ_INFO_LEVEL, "%srpz %s %s rewrite %s via %s%s%s%s",
00977 disabled ? "disabled " : "",
00978 dns_rpz_type2str(type), dns_rpz_policy2str(policy),
00979 qname_buf, p_name_buf, s1, cname_buf, s2);
00980 }
00981
00982 static void
00983 rpz_log_fail(ns_client_t *client, int level, dns_name_t *p_name,
00984 dns_rpz_type_t rpz_type, const char *str, isc_result_t result)
00985 {
00986 char qnamebuf[DNS_NAME_FORMATSIZE];
00987 char p_namebuf[DNS_NAME_FORMATSIZE];
00988 const char *failed;
00989
00990 if (!isc_log_wouldlog(ns_g_lctx, level))
00991 return;
00992
00993
00994
00995
00996 if (level <= DNS_RPZ_DEBUG_LEVEL1)
00997 failed = "failed: ";
00998 else
00999 failed = ": ";
01000 dns_name_format(client->query.qname, qnamebuf, sizeof(qnamebuf));
01001 dns_name_format(p_name, p_namebuf, sizeof(p_namebuf));
01002 ns_client_log(client, NS_LOGCATEGORY_QUERY_EERRORS,
01003 NS_LOGMODULE_QUERY, level,
01004 "rpz %s rewrite %s via %s%s%s%s",
01005 dns_rpz_type2str(rpz_type),
01006 qnamebuf, p_namebuf,
01007 str, failed, isc_result_totext(result));
01008 }
01009
01010
01011
01012
01013 static isc_result_t
01014 rpz_getdb(ns_client_t *client, dns_name_t *p_name, dns_rpz_type_t rpz_type,
01015 dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp)
01016 {
01017 char qnamebuf[DNS_NAME_FORMATSIZE];
01018 char p_namebuf[DNS_NAME_FORMATSIZE];
01019 dns_dbversion_t *rpz_version = NULL;
01020 isc_result_t result;
01021
01022 result = query_getzonedb(client, p_name, dns_rdatatype_any,
01023 DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version);
01024 if (result == ISC_R_SUCCESS) {
01025 if (isc_log_wouldlog(ns_g_lctx, DNS_RPZ_DEBUG_LEVEL2)) {
01026 dns_name_format(client->query.qname, qnamebuf,
01027 sizeof(qnamebuf));
01028 dns_name_format(p_name, p_namebuf, sizeof(p_namebuf));
01029 ns_client_log(client, DNS_LOGCATEGORY_RPZ,
01030 NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2,
01031 "try rpz %s rewrite %s via %s",
01032 dns_rpz_type2str(rpz_type),
01033 qnamebuf, p_namebuf);
01034 }
01035 *versionp = rpz_version;
01036 return (ISC_R_SUCCESS);
01037 }
01038 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type,
01039 " query_getzonedb()", result);
01040 return (result);
01041 }
01042
01043 static inline isc_result_t
01044 query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
01045 dns_db_t **dbp, unsigned int options)
01046 {
01047 isc_result_t result;
01048 isc_boolean_t check_acl;
01049 dns_db_t *db = NULL;
01050
01051 REQUIRE(dbp != NULL && *dbp == NULL);
01052
01053
01054
01055
01056
01057
01058
01059 if (!USECACHE(client))
01060 return (DNS_R_REFUSED);
01061 dns_db_attach(client->view->cachedb, &db);
01062
01063 if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) != 0) {
01064
01065
01066
01067
01068
01069
01070 check_acl = ISC_FALSE;
01071 if ((client->query.attributes & NS_QUERYATTR_CACHEACLOK) == 0)
01072 goto refuse;
01073 } else {
01074
01075
01076
01077 check_acl = ISC_TRUE;
01078 }
01079
01080 if (check_acl) {
01081 isc_boolean_t log = ISC_TF((options & DNS_GETDB_NOLOG) == 0);
01082 char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")];
01083
01084 result = ns_client_checkaclsilent(client, NULL,
01085 client->view->cacheacl,
01086 ISC_TRUE);
01087 if (result == ISC_R_SUCCESS) {
01088
01089
01090
01091
01092 client->query.attributes |=
01093 NS_QUERYATTR_CACHEACLOK;
01094 if (log && isc_log_wouldlog(ns_g_lctx,
01095 ISC_LOG_DEBUG(3)))
01096 {
01097 ns_client_aclmsg("query (cache)", name, qtype,
01098 client->view->rdclass,
01099 msg, sizeof(msg));
01100 ns_client_log(client,
01101 DNS_LOGCATEGORY_SECURITY,
01102 NS_LOGMODULE_QUERY,
01103 ISC_LOG_DEBUG(3),
01104 "%s approved", msg);
01105 }
01106 } else if (log) {
01107 ns_client_aclmsg("query (cache)", name, qtype,
01108 client->view->rdclass, msg,
01109 sizeof(msg));
01110 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
01111 NS_LOGMODULE_QUERY, ISC_LOG_INFO,
01112 "%s denied", msg);
01113 }
01114
01115
01116
01117
01118 client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID;
01119
01120 if (result != ISC_R_SUCCESS)
01121 goto refuse;
01122 }
01123
01124
01125
01126
01127 *dbp = db;
01128
01129 return (ISC_R_SUCCESS);
01130
01131 refuse:
01132 result = DNS_R_REFUSED;
01133
01134 if (db != NULL)
01135 dns_db_detach(&db);
01136
01137 return (result);
01138 }
01139
01140
01141 static inline isc_result_t
01142 query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
01143 unsigned int options, dns_zone_t **zonep, dns_db_t **dbp,
01144 dns_dbversion_t **versionp, isc_boolean_t *is_zonep)
01145 {
01146 isc_result_t result;
01147
01148 isc_result_t tresult;
01149 unsigned int namelabels;
01150 unsigned int zonelabels;
01151 dns_zone_t *zone = NULL;
01152 dns_db_t *tdbp;
01153
01154 REQUIRE(zonep != NULL && *zonep == NULL);
01155
01156 tdbp = NULL;
01157
01158
01159 namelabels = dns_name_countlabels(name);
01160 zonelabels = 0;
01161
01162
01163 result = query_getzonedb(client, name, qtype, options, &zone,
01164 dbp, versionp);
01165
01166
01167 if (result == ISC_R_SUCCESS && zone != NULL)
01168 zonelabels = dns_name_countlabels(dns_zone_getorigin(zone));
01169
01170
01171
01172
01173
01174 if (zonelabels < namelabels &&
01175 !ISC_LIST_EMPTY(client->view->dlz_searched))
01176 {
01177 dns_clientinfomethods_t cm;
01178 dns_clientinfo_t ci;
01179
01180 dns_clientinfomethods_init(&cm, ns_client_sourceip);
01181 dns_clientinfo_init(&ci, client, NULL);
01182
01183 tresult = dns_view_searchdlz(client->view, name,
01184 zonelabels, &cm, &ci, &tdbp);
01185
01186 if (tresult == ISC_R_SUCCESS) {
01187
01188
01189
01190 if (zone != NULL)
01191 dns_zone_detach(&zone);
01192
01193
01194
01195
01196
01197 if (*dbp != NULL)
01198 dns_db_detach(dbp);
01199
01200
01201
01202
01203 *versionp = NULL;
01204
01205
01206
01207
01208 dns_db_currentversion(tdbp, versionp);
01209
01210
01211
01212
01213 *dbp = tdbp;
01214
01215
01216
01217
01218 zone = NULL;
01219 result = tresult;
01220 }
01221 }
01222
01223
01224 if (result == ISC_R_SUCCESS) {
01225 *zonep = zone;
01226
01227
01228
01229 *is_zonep = ISC_TRUE;
01230 } else if (result == ISC_R_NOTFOUND) {
01231 result = query_getcachedb(client, name, qtype, dbp, options);
01232 *is_zonep = ISC_FALSE;
01233 }
01234 return (result);
01235 }
01236
01237 static inline isc_boolean_t
01238 query_isduplicate(ns_client_t *client, dns_name_t *name,
01239 dns_rdatatype_t type, dns_name_t **mnamep)
01240 {
01241 dns_section_t section;
01242 dns_name_t *mname = NULL;
01243 isc_result_t result;
01244
01245 CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate");
01246
01247 for (section = DNS_SECTION_ANSWER;
01248 section <= DNS_SECTION_ADDITIONAL;
01249 section++) {
01250 result = dns_message_findname(client->message, section,
01251 name, type, 0, &mname, NULL);
01252 if (result == ISC_R_SUCCESS) {
01253
01254
01255
01256 CTRACE(ISC_LOG_DEBUG(3),
01257 "query_isduplicate: true: done");
01258 return (ISC_TRUE);
01259 } else if (result == DNS_R_NXRRSET) {
01260
01261
01262
01263 if (section == DNS_SECTION_ADDITIONAL)
01264 break;
01265 } else
01266 RUNTIME_CHECK(result == DNS_R_NXDOMAIN);
01267 mname = NULL;
01268 }
01269
01270 if (mnamep != NULL)
01271 *mnamep = mname;
01272
01273 CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate: false: done");
01274 return (ISC_FALSE);
01275 }
01276
01277 static isc_result_t
01278 query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
01279 ns_client_t *client = arg;
01280 isc_result_t result, eresult;
01281 dns_dbnode_t *node;
01282 dns_db_t *db;
01283 dns_name_t *fname, *mname;
01284 dns_rdataset_t *rdataset, *sigrdataset, *trdataset;
01285 isc_buffer_t *dbuf;
01286 isc_buffer_t b;
01287 dns_dbversion_t *version;
01288 isc_boolean_t added_something, need_addname;
01289 dns_zone_t *zone;
01290 dns_rdatatype_t type;
01291 dns_clientinfomethods_t cm;
01292 dns_clientinfo_t ci;
01293
01294 REQUIRE(NS_CLIENT_VALID(client));
01295 REQUIRE(qtype != dns_rdatatype_any);
01296
01297 if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype))
01298 return (ISC_R_SUCCESS);
01299
01300 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional");
01301
01302
01303
01304
01305 eresult = ISC_R_SUCCESS;
01306 fname = NULL;
01307 rdataset = NULL;
01308 sigrdataset = NULL;
01309 trdataset = NULL;
01310 db = NULL;
01311 version = NULL;
01312 node = NULL;
01313 added_something = ISC_FALSE;
01314 need_addname = ISC_FALSE;
01315 zone = NULL;
01316
01317 dns_clientinfomethods_init(&cm, ns_client_sourceip);
01318 dns_clientinfo_init(&ci, client, NULL);
01319
01320
01321
01322
01323
01324
01325
01326 if (qtype == dns_rdatatype_a)
01327 type = dns_rdatatype_any;
01328 else
01329 type = qtype;
01330
01331
01332
01333
01334 dbuf = query_getnamebuf(client);
01335 if (dbuf == NULL)
01336 goto cleanup;
01337 fname = query_newname(client, dbuf, &b);
01338 rdataset = query_newrdataset(client);
01339 if (fname == NULL || rdataset == NULL)
01340 goto cleanup;
01341 if (WANTDNSSEC(client)) {
01342 sigrdataset = query_newrdataset(client);
01343 if (sigrdataset == NULL)
01344 goto cleanup;
01345 }
01346
01347
01348
01349
01350
01351 result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG,
01352 &zone, &db, &version);
01353 if (result != ISC_R_SUCCESS)
01354 goto try_cache;
01355
01356 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: db_find");
01357
01358
01359
01360
01361
01362
01363 node = NULL;
01364 result = dns_db_findext(db, name, version, type,
01365 client->query.dboptions,
01366 client->now, &node, fname, &cm, &ci,
01367 rdataset, sigrdataset);
01368 if (result == ISC_R_SUCCESS) {
01369 if (sigrdataset != NULL && !dns_db_issecure(db) &&
01370 dns_rdataset_isassociated(sigrdataset))
01371 dns_rdataset_disassociate(sigrdataset);
01372 goto found;
01373 }
01374
01375 if (dns_rdataset_isassociated(rdataset))
01376 dns_rdataset_disassociate(rdataset);
01377 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
01378 dns_rdataset_disassociate(sigrdataset);
01379 if (node != NULL)
01380 dns_db_detachnode(db, &node);
01381 version = NULL;
01382 dns_db_detach(&db);
01383
01384
01385
01386
01387
01388 try_cache:
01389 result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG);
01390 if (result != ISC_R_SUCCESS)
01391
01392
01393
01394 goto try_glue;
01395
01396
01397
01398 if (sigrdataset == NULL) {
01399 sigrdataset = query_newrdataset(client);
01400 if (sigrdataset == NULL)
01401 goto cleanup;
01402 }
01403 result = dns_db_findext(db, name, version, type,
01404 client->query.dboptions |
01405 DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
01406 client->now, &node, fname, &cm, &ci,
01407 rdataset, sigrdataset);
01408
01409 dns_cache_updatestats(client->view->cache, result);
01410 if (result == DNS_R_GLUE &&
01411 validate(client, db, fname, rdataset, sigrdataset))
01412 result = ISC_R_SUCCESS;
01413 if (!WANTDNSSEC(client))
01414 query_putrdataset(client, &sigrdataset);
01415 if (result == ISC_R_SUCCESS)
01416 goto found;
01417
01418
01419 if (dns_rdataset_isassociated(rdataset))
01420 dns_rdataset_disassociate(rdataset);
01421 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
01422 dns_rdataset_disassociate(sigrdataset);
01423 if (node != NULL)
01424 dns_db_detachnode(db, &node);
01425 dns_db_detach(&db);
01426
01427 try_glue:
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443 if (client->query.gluedb == NULL)
01444 goto cleanup;
01445
01446
01447
01448
01449 if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb)))
01450 goto cleanup;
01451
01452 dns_db_attach(client->query.gluedb, &db);
01453 result = dns_db_findext(db, name, version, type,
01454 client->query.dboptions | DNS_DBFIND_GLUEOK,
01455 client->now, &node, fname, &cm, &ci,
01456 rdataset, sigrdataset);
01457 if (!(result == ISC_R_SUCCESS ||
01458 result == DNS_R_ZONECUT ||
01459 result == DNS_R_GLUE))
01460 goto cleanup;
01461
01462 found:
01463
01464
01465
01466
01467 query_keepname(client, fname, dbuf);
01468
01469
01470
01471
01472
01473 mname = NULL;
01474 if (dns_rdataset_isassociated(rdataset) &&
01475 !query_isduplicate(client, fname, type, &mname)) {
01476 if (mname != NULL) {
01477 INSIST(mname != fname);
01478 query_releasename(client, &fname);
01479 fname = mname;
01480 } else
01481 need_addname = ISC_TRUE;
01482 ISC_LIST_APPEND(fname->list, rdataset, link);
01483 trdataset = rdataset;
01484 rdataset = NULL;
01485 added_something = ISC_TRUE;
01486
01487
01488
01489
01490
01491 if (sigrdataset != NULL &&
01492 dns_rdataset_isassociated(sigrdataset))
01493 {
01494 ISC_LIST_APPEND(fname->list, sigrdataset, link);
01495 sigrdataset = NULL;
01496 }
01497 }
01498
01499 if (qtype == dns_rdatatype_a) {
01500 #ifdef ALLOW_FILTER_AAAA
01501 isc_boolean_t have_a = ISC_FALSE;
01502 #endif
01503
01504
01505
01506
01507
01508
01509
01510 if (rdataset != NULL) {
01511 if (dns_rdataset_isassociated(rdataset))
01512 dns_rdataset_disassociate(rdataset);
01513 } else {
01514 rdataset = query_newrdataset(client);
01515 if (rdataset == NULL)
01516 goto addname;
01517 }
01518 if (sigrdataset != NULL) {
01519 if (dns_rdataset_isassociated(sigrdataset))
01520 dns_rdataset_disassociate(sigrdataset);
01521 } else if (WANTDNSSEC(client)) {
01522 sigrdataset = query_newrdataset(client);
01523 if (sigrdataset == NULL)
01524 goto addname;
01525 }
01526 if (query_isduplicate(client, fname, dns_rdatatype_a, NULL))
01527 goto aaaa_lookup;
01528 result = dns_db_findrdataset(db, node, version,
01529 dns_rdatatype_a, 0,
01530 client->now,
01531 rdataset, sigrdataset);
01532 if (result == DNS_R_NCACHENXDOMAIN)
01533 goto addname;
01534 if (result == DNS_R_NCACHENXRRSET) {
01535 dns_rdataset_disassociate(rdataset);
01536 if (sigrdataset != NULL &&
01537 dns_rdataset_isassociated(sigrdataset))
01538 dns_rdataset_disassociate(sigrdataset);
01539 }
01540 if (result == ISC_R_SUCCESS) {
01541 mname = NULL;
01542 #ifdef ALLOW_FILTER_AAAA
01543 have_a = ISC_TRUE;
01544 #endif
01545 if (!query_isduplicate(client, fname,
01546 dns_rdatatype_a, &mname)) {
01547 if (mname != fname) {
01548 if (mname != NULL) {
01549 query_releasename(client, &fname);
01550 fname = mname;
01551 } else
01552 need_addname = ISC_TRUE;
01553 }
01554 ISC_LIST_APPEND(fname->list, rdataset, link);
01555 added_something = ISC_TRUE;
01556 if (sigrdataset != NULL &&
01557 dns_rdataset_isassociated(sigrdataset))
01558 {
01559 ISC_LIST_APPEND(fname->list,
01560 sigrdataset, link);
01561 sigrdataset =
01562 query_newrdataset(client);
01563 }
01564 rdataset = query_newrdataset(client);
01565 if (rdataset == NULL)
01566 goto addname;
01567 if (WANTDNSSEC(client) && sigrdataset == NULL)
01568 goto addname;
01569 } else {
01570 dns_rdataset_disassociate(rdataset);
01571 if (sigrdataset != NULL &&
01572 dns_rdataset_isassociated(sigrdataset))
01573 dns_rdataset_disassociate(sigrdataset);
01574 }
01575 }
01576 aaaa_lookup:
01577 if (query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL))
01578 goto addname;
01579 result = dns_db_findrdataset(db, node, version,
01580 dns_rdatatype_aaaa, 0,
01581 client->now,
01582 rdataset, sigrdataset);
01583 if (result == DNS_R_NCACHENXDOMAIN)
01584 goto addname;
01585 if (result == DNS_R_NCACHENXRRSET) {
01586 dns_rdataset_disassociate(rdataset);
01587 if (sigrdataset != NULL &&
01588 dns_rdataset_isassociated(sigrdataset))
01589 dns_rdataset_disassociate(sigrdataset);
01590 }
01591 if (result == ISC_R_SUCCESS) {
01592 mname = NULL;
01593
01594
01595
01596 #ifdef ALLOW_FILTER_AAAA
01597 if (have_a &&
01598 (client->filter_aaaa == dns_aaaa_break_dnssec ||
01599 (client->filter_aaaa == dns_aaaa_filter &&
01600 (!WANTDNSSEC(client) || sigrdataset == NULL ||
01601 !dns_rdataset_isassociated(sigrdataset)))))
01602 goto addname;
01603 #endif
01604 if (!query_isduplicate(client, fname,
01605 dns_rdatatype_aaaa, &mname)) {
01606 if (mname != fname) {
01607 if (mname != NULL) {
01608 query_releasename(client, &fname);
01609 fname = mname;
01610 } else
01611 need_addname = ISC_TRUE;
01612 }
01613 ISC_LIST_APPEND(fname->list, rdataset, link);
01614 added_something = ISC_TRUE;
01615 if (sigrdataset != NULL &&
01616 dns_rdataset_isassociated(sigrdataset))
01617 {
01618 ISC_LIST_APPEND(fname->list,
01619 sigrdataset, link);
01620 sigrdataset = NULL;
01621 }
01622 rdataset = NULL;
01623 }
01624 }
01625 }
01626
01627 addname:
01628 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: addname");
01629
01630
01631
01632 if (!added_something)
01633 goto cleanup;
01634
01635
01636
01637
01638
01639
01640 if (need_addname)
01641 dns_message_addname(client->message, fname,
01642 DNS_SECTION_ADDITIONAL);
01643 fname = NULL;
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656 if (type == dns_rdatatype_srv && trdataset != NULL) {
01657
01658
01659
01660
01661
01662 eresult = dns_rdataset_additionaldata(trdataset,
01663 query_addadditional,
01664 client);
01665 }
01666
01667 cleanup:
01668 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: cleanup");
01669 query_putrdataset(client, &rdataset);
01670 if (sigrdataset != NULL)
01671 query_putrdataset(client, &sigrdataset);
01672 if (fname != NULL)
01673 query_releasename(client, &fname);
01674 if (node != NULL)
01675 dns_db_detachnode(db, &node);
01676 if (db != NULL)
01677 dns_db_detach(&db);
01678 if (zone != NULL)
01679 dns_zone_detach(&zone);
01680
01681 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: done");
01682 return (eresult);
01683 }
01684
01685 static inline void
01686 query_discardcache(ns_client_t *client, dns_rdataset_t *rdataset_base,
01687 dns_rdatasetadditional_t additionaltype,
01688 dns_rdatatype_t type, dns_zone_t **zonep, dns_db_t **dbp,
01689 dns_dbversion_t **versionp, dns_dbnode_t **nodep,
01690 dns_name_t *fname)
01691 {
01692 dns_rdataset_t *rdataset;
01693
01694 while ((rdataset = ISC_LIST_HEAD(fname->list)) != NULL) {
01695 ISC_LIST_UNLINK(fname->list, rdataset, link);
01696 query_putrdataset(client, &rdataset);
01697 }
01698 if (*versionp != NULL)
01699 dns_db_closeversion(*dbp, versionp, ISC_FALSE);
01700 if (*nodep != NULL)
01701 dns_db_detachnode(*dbp, nodep);
01702 if (*dbp != NULL)
01703 dns_db_detach(dbp);
01704 if (*zonep != NULL)
01705 dns_zone_detach(zonep);
01706 (void)dns_rdataset_putadditional(client->view->acache, rdataset_base,
01707 additionaltype, type);
01708 }
01709
01710 static inline isc_result_t
01711 query_iscachevalid(dns_zone_t *zone, dns_db_t *db, dns_db_t *db0,
01712 dns_dbversion_t *version)
01713 {
01714 isc_result_t result = ISC_R_SUCCESS;
01715 dns_dbversion_t *version_current = NULL;
01716 dns_db_t *db_current = db0;
01717
01718 if (db_current == NULL) {
01719 result = dns_zone_getdb(zone, &db_current);
01720 if (result != ISC_R_SUCCESS)
01721 return (result);
01722 }
01723 dns_db_currentversion(db_current, &version_current);
01724 if (db_current != db || version_current != version) {
01725 result = ISC_R_FAILURE;
01726 goto cleanup;
01727 }
01728
01729 cleanup:
01730 dns_db_closeversion(db_current, &version_current, ISC_FALSE);
01731 if (db0 == NULL && db_current != NULL)
01732 dns_db_detach(&db_current);
01733
01734 return (result);
01735 }
01736
01737 static isc_result_t
01738 query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
01739 client_additionalctx_t *additionalctx = arg;
01740 dns_rdataset_t *rdataset_base;
01741 ns_client_t *client;
01742 isc_result_t result, eresult;
01743 dns_dbnode_t *node, *cnode;
01744 dns_db_t *db, *cdb;
01745 dns_name_t *fname, *mname0, cfname;
01746 dns_rdataset_t *rdataset, *sigrdataset;
01747 dns_rdataset_t *crdataset, *crdataset_next;
01748 isc_buffer_t *dbuf;
01749 isc_buffer_t b;
01750 dns_dbversion_t *version, *cversion;
01751 isc_boolean_t added_something, need_addname, needadditionalcache;
01752 isc_boolean_t need_sigrrset;
01753 dns_zone_t *zone;
01754 dns_rdatatype_t type;
01755 dns_rdatasetadditional_t additionaltype;
01756 dns_clientinfomethods_t cm;
01757 dns_clientinfo_t ci;
01758
01759
01760
01761
01762 client = additionalctx->client;
01763 REQUIRE(NS_CLIENT_VALID(client));
01764
01765 if (qtype != dns_rdatatype_a || client->view->acache == NULL) {
01766
01767
01768
01769
01770
01771 return (query_addadditional(additionalctx->client,
01772 name, qtype));
01773 }
01774
01775
01776
01777
01778 rdataset_base = additionalctx->rdataset;
01779 eresult = ISC_R_SUCCESS;
01780 fname = NULL;
01781 rdataset = NULL;
01782 sigrdataset = NULL;
01783 db = NULL;
01784 cdb = NULL;
01785 version = NULL;
01786 cversion = NULL;
01787 node = NULL;
01788 cnode = NULL;
01789 added_something = ISC_FALSE;
01790 need_addname = ISC_FALSE;
01791 zone = NULL;
01792 needadditionalcache = ISC_FALSE;
01793 POST(needadditionalcache);
01794 additionaltype = dns_rdatasetadditional_fromauth;
01795 dns_name_init(&cfname, NULL);
01796 dns_clientinfomethods_init(&cm, ns_client_sourceip);
01797 dns_clientinfo_init(&ci, client, NULL);
01798
01799 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2");
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810 type = dns_rdatatype_any;
01811
01812
01813
01814
01815 dbuf = query_getnamebuf(client);
01816 if (dbuf == NULL)
01817 goto cleanup;
01818 fname = query_newname(client, dbuf, &b);
01819 if (fname == NULL)
01820 goto cleanup;
01821 dns_name_setbuffer(&cfname, &b);
01822
01823
01824 result = dns_rdataset_getadditional(rdataset_base, additionaltype,
01825 type, client->view->acache, &zone,
01826 &cdb, &cversion, &cnode, &cfname,
01827 client->message, client->now);
01828 if (result != ISC_R_SUCCESS)
01829 goto findauthdb;
01830 if (zone == NULL) {
01831 CTRACE(ISC_LOG_DEBUG(3),
01832 "query_addadditional2: auth zone not found");
01833 goto try_cache;
01834 }
01835
01836
01837 result = query_iscachevalid(zone, cdb, NULL, cversion);
01838 if (result != ISC_R_SUCCESS) {
01839 CTRACE(ISC_LOG_DEBUG(3),
01840 "query_addadditional2: old auth additional cache");
01841 query_discardcache(client, rdataset_base, additionaltype,
01842 type, &zone, &cdb, &cversion, &cnode,
01843 &cfname);
01844 goto findauthdb;
01845 }
01846
01847 if (cnode == NULL) {
01848
01849
01850
01851
01852
01853 CTRACE(ISC_LOG_DEBUG(3),
01854 "query_addadditional2: negative auth additional cache");
01855 dns_db_closeversion(cdb, &cversion, ISC_FALSE);
01856 dns_db_detach(&cdb);
01857 dns_zone_detach(&zone);
01858 goto try_cache;
01859 }
01860
01861 result = query_validatezonedb(client, name, qtype, DNS_GETDB_NOLOG,
01862 zone, cdb, NULL);
01863 if (result != ISC_R_SUCCESS) {
01864 query_discardcache(client, rdataset_base, additionaltype,
01865 type, &zone, &cdb, &cversion, &cnode,
01866 &cfname);
01867 goto try_cache;
01868 }
01869
01870
01871 CTRACE(ISC_LOG_DEBUG(3),
01872 "query_addadditional2: auth additional cache");
01873 dns_db_closeversion(cdb, &cversion, ISC_FALSE);
01874 db = cdb;
01875 node = cnode;
01876 dns_name_clone(&cfname, fname);
01877 query_keepname(client, fname, dbuf);
01878 goto foundcache;
01879
01880
01881
01882
01883
01884 findauthdb:
01885 result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG,
01886 &zone, &db, &version);
01887 if (result != ISC_R_SUCCESS) {
01888
01889 (void)dns_rdataset_setadditional(rdataset_base, additionaltype,
01890 type, client->view->acache,
01891 NULL, NULL, NULL, NULL,
01892 NULL);
01893 goto try_cache;
01894 }
01895
01896 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: db_find");
01897
01898
01899
01900
01901
01902
01903 node = NULL;
01904 result = dns_db_findext(db, name, version, type,
01905 client->query.dboptions,
01906 client->now, &node, fname, &cm, &ci,
01907 NULL, NULL);
01908 if (result == ISC_R_SUCCESS)
01909 goto found;
01910
01911
01912 (void)dns_rdataset_setadditional(rdataset_base, additionaltype,
01913 type, client->view->acache, zone, db,
01914 version, NULL, fname);
01915
01916 if (node != NULL)
01917 dns_db_detachnode(db, &node);
01918 version = NULL;
01919 dns_db_detach(&db);
01920
01921
01922
01923
01924
01925 try_cache:
01926 additionaltype = dns_rdatasetadditional_fromcache;
01927 result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG);
01928 if (result != ISC_R_SUCCESS)
01929
01930
01931
01932 goto try_glue;
01933
01934 result = dns_db_findext(db, name, version, type,
01935 client->query.dboptions |
01936 DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
01937 client->now, &node, fname, &cm, &ci,
01938 NULL, NULL);
01939 if (result == ISC_R_SUCCESS)
01940 goto found;
01941
01942 if (node != NULL)
01943 dns_db_detachnode(db, &node);
01944 dns_db_detach(&db);
01945
01946 try_glue:
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961 if (client->query.gluedb == NULL)
01962 goto cleanup;
01963
01964
01965
01966
01967 if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb)))
01968 goto cleanup;
01969
01970
01971 additionaltype = dns_rdatasetadditional_fromglue;
01972 result = dns_rdataset_getadditional(rdataset_base, additionaltype,
01973 type, client->view->acache, NULL,
01974 &cdb, &cversion, &cnode, &cfname,
01975 client->message, client->now);
01976 if (result != ISC_R_SUCCESS)
01977 goto findglue;
01978
01979 result = query_iscachevalid(zone, cdb, client->query.gluedb, cversion);
01980 if (result != ISC_R_SUCCESS) {
01981 CTRACE(ISC_LOG_DEBUG(3),
01982 "query_addadditional2: old glue additional cache");
01983 query_discardcache(client, rdataset_base, additionaltype,
01984 type, &zone, &cdb, &cversion, &cnode,
01985 &cfname);
01986 goto findglue;
01987 }
01988
01989 if (cnode == NULL) {
01990
01991 CTRACE(ISC_LOG_DEBUG(3),
01992 "query_addadditional2: negative glue additional cache");
01993 dns_db_closeversion(cdb, &cversion, ISC_FALSE);
01994 dns_db_detach(&cdb);
01995 goto cleanup;
01996 }
01997
01998
01999 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: glue additional cache");
02000 dns_db_closeversion(cdb, &cversion, ISC_FALSE);
02001 db = cdb;
02002 node = cnode;
02003 dns_name_clone(&cfname, fname);
02004 query_keepname(client, fname, dbuf);
02005 goto foundcache;
02006
02007 findglue:
02008 dns_db_attach(client->query.gluedb, &db);
02009 result = dns_db_findext(db, name, version, type,
02010 client->query.dboptions | DNS_DBFIND_GLUEOK,
02011 client->now, &node, fname, &cm, &ci,
02012 NULL, NULL);
02013 if (!(result == ISC_R_SUCCESS ||
02014 result == DNS_R_ZONECUT ||
02015 result == DNS_R_GLUE)) {
02016
02017 (void)dns_rdataset_setadditional(rdataset_base, additionaltype,
02018 type, client->view->acache,
02019 NULL, db, version, NULL,
02020 fname);
02021 goto cleanup;
02022 }
02023
02024 found:
02025
02026
02027
02028
02029
02030
02031 dns_name_clone(fname, &cfname);
02032 query_keepname(client, fname, dbuf);
02033 needadditionalcache = ISC_TRUE;
02034
02035 rdataset = query_newrdataset(client);
02036 if (rdataset == NULL)
02037 goto cleanup;
02038
02039 sigrdataset = query_newrdataset(client);
02040 if (sigrdataset == NULL)
02041 goto cleanup;
02042
02043 if (additionaltype == dns_rdatasetadditional_fromcache &&
02044 query_isduplicate(client, fname, dns_rdatatype_a, NULL))
02045 goto aaaa_lookup;
02046
02047
02048
02049
02050
02051
02052
02053 result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 0,
02054 client->now, rdataset, sigrdataset);
02055
02056
02057
02058
02059 if (result == ISC_R_SUCCESS &&
02060 additionaltype == dns_rdatasetadditional_fromcache &&
02061 (DNS_TRUST_PENDING(rdataset->trust) ||
02062 DNS_TRUST_GLUE(rdataset->trust)) &&
02063 !validate(client, db, fname, rdataset, sigrdataset)) {
02064 dns_rdataset_disassociate(rdataset);
02065 if (dns_rdataset_isassociated(sigrdataset))
02066 dns_rdataset_disassociate(sigrdataset);
02067 result = ISC_R_NOTFOUND;
02068 }
02069 if (result == DNS_R_NCACHENXDOMAIN)
02070 goto setcache;
02071 if (result == DNS_R_NCACHENXRRSET) {
02072 dns_rdataset_disassociate(rdataset);
02073 if (dns_rdataset_isassociated(sigrdataset))
02074 dns_rdataset_disassociate(sigrdataset);
02075 }
02076 if (result == ISC_R_SUCCESS) {
02077
02078 ISC_LIST_APPEND(cfname.list, rdataset, link);
02079 if (dns_rdataset_isassociated(sigrdataset)) {
02080 ISC_LIST_APPEND(cfname.list, sigrdataset, link);
02081 sigrdataset = query_newrdataset(client);
02082 }
02083 rdataset = query_newrdataset(client);
02084 if (sigrdataset == NULL || rdataset == NULL) {
02085
02086 goto foundcache;
02087 }
02088 }
02089
02090 aaaa_lookup:
02091 if (additionaltype == dns_rdatasetadditional_fromcache &&
02092 query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL))
02093 goto foundcache;
02094
02095 result = dns_db_findrdataset(db, node, version, dns_rdatatype_aaaa,
02096 0, client->now, rdataset, sigrdataset);
02097
02098
02099
02100
02101 if (result == ISC_R_SUCCESS &&
02102 additionaltype == dns_rdatasetadditional_fromcache &&
02103 (DNS_TRUST_PENDING(rdataset->trust) ||
02104 DNS_TRUST_GLUE(rdataset->trust)) &&
02105 !validate(client, db, fname, rdataset, sigrdataset)) {
02106 dns_rdataset_disassociate(rdataset);
02107 if (dns_rdataset_isassociated(sigrdataset))
02108 dns_rdataset_disassociate(sigrdataset);
02109 result = ISC_R_NOTFOUND;
02110 }
02111 if (result == ISC_R_SUCCESS) {
02112 ISC_LIST_APPEND(cfname.list, rdataset, link);
02113 rdataset = NULL;
02114 if (dns_rdataset_isassociated(sigrdataset)) {
02115 ISC_LIST_APPEND(cfname.list, sigrdataset, link);
02116 sigrdataset = NULL;
02117 }
02118 }
02119
02120 setcache:
02121
02122
02123
02124
02125 if (needadditionalcache == ISC_TRUE &&
02126 (additionaltype == dns_rdatasetadditional_fromauth ||
02127 additionaltype == dns_rdatasetadditional_fromglue)) {
02128 (void)dns_rdataset_setadditional(rdataset_base, additionaltype,
02129 type, client->view->acache,
02130 zone, db, version, node,
02131 &cfname);
02132 }
02133
02134 foundcache:
02135 need_sigrrset = ISC_FALSE;
02136 mname0 = NULL;
02137 for (crdataset = ISC_LIST_HEAD(cfname.list);
02138 crdataset != NULL;
02139 crdataset = crdataset_next) {
02140 dns_name_t *mname;
02141
02142 crdataset_next = ISC_LIST_NEXT(crdataset, link);
02143
02144 mname = NULL;
02145 if (crdataset->type == dns_rdatatype_a ||
02146 crdataset->type == dns_rdatatype_aaaa) {
02147 if (!query_isduplicate(client, fname, crdataset->type,
02148 &mname)) {
02149 if (mname != fname) {
02150 if (mname != NULL) {
02151
02152
02153
02154
02155
02156
02157
02158
02159 INSIST(mname0 == NULL);
02160
02161 query_releasename(client, &fname);
02162 fname = mname;
02163 mname0 = mname;
02164 } else
02165 need_addname = ISC_TRUE;
02166 }
02167 ISC_LIST_UNLINK(cfname.list, crdataset, link);
02168 ISC_LIST_APPEND(fname->list, crdataset, link);
02169 added_something = ISC_TRUE;
02170 need_sigrrset = ISC_TRUE;
02171 } else
02172 need_sigrrset = ISC_FALSE;
02173 } else if (crdataset->type == dns_rdatatype_rrsig &&
02174 need_sigrrset && WANTDNSSEC(client)) {
02175 ISC_LIST_UNLINK(cfname.list, crdataset, link);
02176 ISC_LIST_APPEND(fname->list, crdataset, link);
02177 added_something = ISC_TRUE;
02178 need_sigrrset = ISC_FALSE;
02179 }
02180 }
02181
02182 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: addname");
02183
02184
02185
02186
02187 if (!added_something)
02188 goto cleanup;
02189
02190
02191
02192
02193
02194
02195 if (need_addname)
02196 dns_message_addname(client->message, fname,
02197 DNS_SECTION_ADDITIONAL);
02198 fname = NULL;
02199
02200 cleanup:
02201 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: cleanup");
02202
02203 if (rdataset != NULL)
02204 query_putrdataset(client, &rdataset);
02205 if (sigrdataset != NULL)
02206 query_putrdataset(client, &sigrdataset);
02207 while ((crdataset = ISC_LIST_HEAD(cfname.list)) != NULL) {
02208 ISC_LIST_UNLINK(cfname.list, crdataset, link);
02209 query_putrdataset(client, &crdataset);
02210 }
02211 if (fname != NULL)
02212 query_releasename(client, &fname);
02213 if (node != NULL)
02214 dns_db_detachnode(db, &node);
02215 if (db != NULL)
02216 dns_db_detach(&db);
02217 if (zone != NULL)
02218 dns_zone_detach(&zone);
02219
02220 CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: done");
02221 return (eresult);
02222 }
02223
02224 static inline void
02225 query_addrdataset(ns_client_t *client, dns_name_t *fname,
02226 dns_rdataset_t *rdataset)
02227 {
02228 client_additionalctx_t additionalctx;
02229
02230
02231
02232
02233
02234
02235 CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset");
02236
02237 ISC_LIST_APPEND(fname->list, rdataset, link);
02238
02239 if (client->view->order != NULL)
02240 rdataset->attributes |= dns_order_find(client->view->order,
02241 fname, rdataset->type,
02242 rdataset->rdclass);
02243 rdataset->attributes |= DNS_RDATASETATTR_LOADORDER;
02244
02245 if (NOADDITIONAL(client))
02246 return;
02247
02248
02249
02250
02251
02252
02253 additionalctx.client = client;
02254 additionalctx.rdataset = rdataset;
02255 (void)dns_rdataset_additionaldata(rdataset, query_addadditional2,
02256 &additionalctx);
02257 CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset: done");
02258 }
02259
02260 static isc_result_t
02261 query_dns64(ns_client_t *client, dns_name_t **namep, dns_rdataset_t *rdataset,
02262 dns_rdataset_t *sigrdataset, isc_buffer_t *dbuf,
02263 dns_section_t section)
02264 {
02265 dns_name_t *name, *mname;
02266 dns_rdata_t *dns64_rdata;
02267 dns_rdata_t rdata = DNS_RDATA_INIT;
02268 dns_rdatalist_t *dns64_rdatalist;
02269 dns_rdataset_t *dns64_rdataset;
02270 dns_rdataset_t *mrdataset;
02271 isc_buffer_t *buffer;
02272 isc_region_t r;
02273 isc_result_t result;
02274 dns_view_t *view = client->view;
02275 isc_netaddr_t netaddr;
02276 dns_dns64_t *dns64;
02277 unsigned int flags = 0;
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289 CTRACE(ISC_LOG_DEBUG(3), "query_dns64");
02290 name = *namep;
02291 mname = NULL;
02292 mrdataset = NULL;
02293 buffer = NULL;
02294 dns64_rdata = NULL;
02295 dns64_rdataset = NULL;
02296 dns64_rdatalist = NULL;
02297 result = dns_message_findname(client->message, section,
02298 name, dns_rdatatype_aaaa,
02299 rdataset->covers,
02300 &mname, &mrdataset);
02301 if (result == ISC_R_SUCCESS) {
02302
02303
02304
02305
02306 CTRACE(ISC_LOG_DEBUG(3),
02307 "query_dns64: dns_message_findname succeeded: done");
02308 if (dbuf != NULL)
02309 query_releasename(client, namep);
02310 return (ISC_R_SUCCESS);
02311 } else if (result == DNS_R_NXDOMAIN) {
02312
02313
02314
02315 if (dbuf != NULL)
02316 query_keepname(client, name, dbuf);
02317 dns_message_addname(client->message, name, section);
02318 *namep = NULL;
02319 mname = name;
02320 } else {
02321 RUNTIME_CHECK(result == DNS_R_NXRRSET);
02322 if (dbuf != NULL)
02323 query_releasename(client, namep);
02324 }
02325
02326 if (rdataset->trust != dns_trust_secure &&
02327 (section == DNS_SECTION_ANSWER ||
02328 section == DNS_SECTION_AUTHORITY))
02329 client->query.attributes &= ~NS_QUERYATTR_SECURE;
02330
02331 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
02332
02333 result = isc_buffer_allocate(client->mctx, &buffer, view->dns64cnt *
02334 16 * dns_rdataset_count(rdataset));
02335 if (result != ISC_R_SUCCESS)
02336 goto cleanup;
02337 result = dns_message_gettemprdataset(client->message, &dns64_rdataset);
02338 if (result != ISC_R_SUCCESS)
02339 goto cleanup;
02340 result = dns_message_gettemprdatalist(client->message,
02341 &dns64_rdatalist);
02342 if (result != ISC_R_SUCCESS)
02343 goto cleanup;
02344
02345 dns_rdataset_init(dns64_rdataset);
02346 dns_rdatalist_init(dns64_rdatalist);
02347 dns64_rdatalist->rdclass = dns_rdataclass_in;
02348 dns64_rdatalist->type = dns_rdatatype_aaaa;
02349 if (client->query.dns64_ttl != ISC_UINT32_MAX)
02350 dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl,
02351 client->query.dns64_ttl);
02352 else
02353 dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, 600);
02354
02355 if (RECURSIONOK(client))
02356 flags |= DNS_DNS64_RECURSIVE;
02357
02358
02359
02360
02361
02362 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
02363 flags |= DNS_DNS64_DNSSEC;
02364
02365 for (result = dns_rdataset_first(rdataset);
02366 result == ISC_R_SUCCESS;
02367 result = dns_rdataset_next(rdataset)) {
02368 for (dns64 = ISC_LIST_HEAD(client->view->dns64);
02369 dns64 != NULL; dns64 = dns_dns64_next(dns64)) {
02370
02371 dns_rdataset_current(rdataset, &rdata);
02372 isc_buffer_availableregion(buffer, &r);
02373 INSIST(r.length >= 16);
02374 result = dns_dns64_aaaafroma(dns64, &netaddr,
02375 client->signer,
02376 &ns_g_server->aclenv,
02377 flags, rdata.data, r.base);
02378 if (result != ISC_R_SUCCESS) {
02379 dns_rdata_reset(&rdata);
02380 continue;
02381 }
02382 isc_buffer_add(buffer, 16);
02383 isc_buffer_remainingregion(buffer, &r);
02384 isc_buffer_forward(buffer, 16);
02385 result = dns_message_gettemprdata(client->message,
02386 &dns64_rdata);
02387 if (result != ISC_R_SUCCESS)
02388 goto cleanup;
02389 dns_rdata_init(dns64_rdata);
02390 dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in,
02391 dns_rdatatype_aaaa, &r);
02392 ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata,
02393 link);
02394 dns64_rdata = NULL;
02395 dns_rdata_reset(&rdata);
02396 }
02397 }
02398 if (result != ISC_R_NOMORE)
02399 goto cleanup;
02400
02401 if (ISC_LIST_EMPTY(dns64_rdatalist->rdata))
02402 goto cleanup;
02403
02404 result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset);
02405 if (result != ISC_R_SUCCESS)
02406 goto cleanup;
02407 dns_rdataset_setownercase(dns64_rdataset, mname);
02408 client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
02409 dns64_rdataset->trust = rdataset->trust;
02410 query_addrdataset(client, mname, dns64_rdataset);
02411 dns64_rdataset = NULL;
02412 dns64_rdatalist = NULL;
02413 dns_message_takebuffer(client->message, &buffer);
02414 inc_stats(client, dns_nsstatscounter_dns64);
02415 result = ISC_R_SUCCESS;
02416
02417 cleanup:
02418 if (buffer != NULL)
02419 isc_buffer_free(&buffer);
02420
02421 if (dns64_rdata != NULL)
02422 dns_message_puttemprdata(client->message, &dns64_rdata);
02423
02424 if (dns64_rdataset != NULL)
02425 dns_message_puttemprdataset(client->message, &dns64_rdataset);
02426
02427 if (dns64_rdatalist != NULL) {
02428 for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata);
02429 dns64_rdata != NULL;
02430 dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata))
02431 {
02432 ISC_LIST_UNLINK(dns64_rdatalist->rdata,
02433 dns64_rdata, link);
02434 dns_message_puttemprdata(client->message, &dns64_rdata);
02435 }
02436 dns_message_puttemprdatalist(client->message, &dns64_rdatalist);
02437 }
02438
02439 CTRACE(ISC_LOG_DEBUG(3), "query_dns64: done");
02440 return (result);
02441 }
02442
02443 static void
02444 query_filter64(ns_client_t *client, dns_name_t **namep,
02445 dns_rdataset_t *rdataset, isc_buffer_t *dbuf,
02446 dns_section_t section)
02447 {
02448 dns_name_t *name, *mname;
02449 dns_rdata_t *myrdata;
02450 dns_rdata_t rdata = DNS_RDATA_INIT;
02451 dns_rdatalist_t *myrdatalist;
02452 dns_rdataset_t *myrdataset;
02453 isc_buffer_t *buffer;
02454 isc_region_t r;
02455 isc_result_t result;
02456 unsigned int i;
02457
02458 CTRACE(ISC_LOG_DEBUG(3), "query_filter64");
02459
02460 INSIST(client->query.dns64_aaaaok != NULL);
02461 INSIST(client->query.dns64_aaaaoklen == dns_rdataset_count(rdataset));
02462
02463 name = *namep;
02464 mname = NULL;
02465 buffer = NULL;
02466 myrdata = NULL;
02467 myrdataset = NULL;
02468 myrdatalist = NULL;
02469 result = dns_message_findname(client->message, section,
02470 name, dns_rdatatype_aaaa,
02471 rdataset->covers,
02472 &mname, &myrdataset);
02473 if (result == ISC_R_SUCCESS) {
02474
02475
02476
02477
02478 CTRACE(ISC_LOG_DEBUG(3),
02479 "query_filter64: dns_message_findname succeeded: done");
02480 if (dbuf != NULL)
02481 query_releasename(client, namep);
02482 return;
02483 } else if (result == DNS_R_NXDOMAIN) {
02484 mname = name;
02485 *namep = NULL;
02486 } else {
02487 RUNTIME_CHECK(result == DNS_R_NXRRSET);
02488 if (dbuf != NULL)
02489 query_releasename(client, namep);
02490 dbuf = NULL;
02491 }
02492
02493 if (rdataset->trust != dns_trust_secure &&
02494 (section == DNS_SECTION_ANSWER ||
02495 section == DNS_SECTION_AUTHORITY))
02496 client->query.attributes &= ~NS_QUERYATTR_SECURE;
02497
02498 result = isc_buffer_allocate(client->mctx, &buffer,
02499 16 * dns_rdataset_count(rdataset));
02500 if (result != ISC_R_SUCCESS)
02501 goto cleanup;
02502 result = dns_message_gettemprdataset(client->message, &myrdataset);
02503 if (result != ISC_R_SUCCESS)
02504 goto cleanup;
02505 result = dns_message_gettemprdatalist(client->message, &myrdatalist);
02506 if (result != ISC_R_SUCCESS)
02507 goto cleanup;
02508
02509 dns_rdataset_init(myrdataset);
02510 dns_rdatalist_init(myrdatalist);
02511 myrdatalist->rdclass = dns_rdataclass_in;
02512 myrdatalist->type = dns_rdatatype_aaaa;
02513 myrdatalist->ttl = rdataset->ttl;
02514
02515 i = 0;
02516 for (result = dns_rdataset_first(rdataset);
02517 result == ISC_R_SUCCESS;
02518 result = dns_rdataset_next(rdataset)) {
02519 if (!client->query.dns64_aaaaok[i++])
02520 continue;
02521 dns_rdataset_current(rdataset, &rdata);
02522 INSIST(rdata.length == 16);
02523 isc_buffer_putmem(buffer, rdata.data, rdata.length);
02524 isc_buffer_remainingregion(buffer, &r);
02525 isc_buffer_forward(buffer, rdata.length);
02526 result = dns_message_gettemprdata(client->message, &myrdata);
02527 if (result != ISC_R_SUCCESS)
02528 goto cleanup;
02529 dns_rdata_init(myrdata);
02530 dns_rdata_fromregion(myrdata, dns_rdataclass_in,
02531 dns_rdatatype_aaaa, &r);
02532 ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link);
02533 myrdata = NULL;
02534 dns_rdata_reset(&rdata);
02535 }
02536 if (result != ISC_R_NOMORE)
02537 goto cleanup;
02538
02539 result = dns_rdatalist_tordataset(myrdatalist, myrdataset);
02540 if (result != ISC_R_SUCCESS)
02541 goto cleanup;
02542 dns_rdataset_setownercase(myrdataset, name);
02543 client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
02544 if (mname == name) {
02545 if (dbuf != NULL)
02546 query_keepname(client, name, dbuf);
02547 dns_message_addname(client->message, name, section);
02548 dbuf = NULL;
02549 }
02550 myrdataset->trust = rdataset->trust;
02551 query_addrdataset(client, mname, myrdataset);
02552 myrdataset = NULL;
02553 myrdatalist = NULL;
02554 dns_message_takebuffer(client->message, &buffer);
02555
02556 cleanup:
02557 if (buffer != NULL)
02558 isc_buffer_free(&buffer);
02559
02560 if (myrdata != NULL)
02561 dns_message_puttemprdata(client->message, &myrdata);
02562
02563 if (myrdataset != NULL)
02564 dns_message_puttemprdataset(client->message, &myrdataset);
02565
02566 if (myrdatalist != NULL) {
02567 for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata);
02568 myrdata != NULL;
02569 myrdata = ISC_LIST_HEAD(myrdatalist->rdata))
02570 {
02571 ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link);
02572 dns_message_puttemprdata(client->message, &myrdata);
02573 }
02574 dns_message_puttemprdatalist(client->message, &myrdatalist);
02575 }
02576 if (dbuf != NULL)
02577 query_releasename(client, &name);
02578
02579 CTRACE(ISC_LOG_DEBUG(3), "query_filter64: done");
02580 }
02581
02582 static void
02583 query_addrrset(ns_client_t *client, dns_name_t **namep,
02584 dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,
02585 isc_buffer_t *dbuf, dns_section_t section)
02586 {
02587 dns_name_t *name, *mname;
02588 dns_rdataset_t *rdataset, *mrdataset, *sigrdataset;
02589 isc_result_t result;
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601 CTRACE(ISC_LOG_DEBUG(3), "query_addrrset");
02602 name = *namep;
02603 rdataset = *rdatasetp;
02604 if (sigrdatasetp != NULL)
02605 sigrdataset = *sigrdatasetp;
02606 else
02607 sigrdataset = NULL;
02608 mname = NULL;
02609 mrdataset = NULL;
02610 result = dns_message_findname(client->message, section,
02611 name, rdataset->type, rdataset->covers,
02612 &mname, &mrdataset);
02613 if (result == ISC_R_SUCCESS) {
02614
02615
02616
02617 CTRACE(ISC_LOG_DEBUG(3),
02618 "query_addrrset: dns_message_findname succeeded: done");
02619 if (dbuf != NULL)
02620 query_releasename(client, namep);
02621 if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0)
02622 mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
02623 return;
02624 } else if (result == DNS_R_NXDOMAIN) {
02625
02626
02627
02628 if (dbuf != NULL)
02629 query_keepname(client, name, dbuf);
02630 dns_message_addname(client->message, name, section);
02631 *namep = NULL;
02632 mname = name;
02633 } else {
02634 RUNTIME_CHECK(result == DNS_R_NXRRSET);
02635 if (dbuf != NULL)
02636 query_releasename(client, namep);
02637 }
02638
02639 if (rdataset->trust != dns_trust_secure &&
02640 (section == DNS_SECTION_ANSWER ||
02641 section == DNS_SECTION_AUTHORITY))
02642 client->query.attributes &= ~NS_QUERYATTR_SECURE;
02643
02644
02645
02646
02647
02648 query_addrdataset(client, mname, rdataset);
02649 *rdatasetp = NULL;
02650 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) {
02651
02652
02653
02654 ISC_LIST_APPEND(mname->list, sigrdataset, link);
02655 *sigrdatasetp = NULL;
02656 }
02657 CTRACE(ISC_LOG_DEBUG(3), "query_addrrset: done");
02658 }
02659
02660 static inline isc_result_t
02661 query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
02662 unsigned int override_ttl, isc_boolean_t isassociated,
02663 dns_section_t section)
02664 {
02665 dns_name_t *name;
02666 dns_dbnode_t *node;
02667 isc_result_t result, eresult;
02668 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
02669 dns_rdataset_t **sigrdatasetp = NULL;
02670 dns_clientinfomethods_t cm;
02671 dns_clientinfo_t ci;
02672
02673 CTRACE(ISC_LOG_DEBUG(3), "query_addsoa");
02674
02675
02676
02677 eresult = ISC_R_SUCCESS;
02678 name = NULL;
02679 rdataset = NULL;
02680 node = NULL;
02681
02682 dns_clientinfomethods_init(&cm, ns_client_sourceip);
02683 dns_clientinfo_init(&ci, client, NULL);
02684
02685
02686
02687
02688 if (ns_g_nosoa && (!WANTDNSSEC(client) || !isassociated))
02689 return (ISC_R_SUCCESS);
02690
02691
02692
02693
02694 result = dns_message_gettempname(client->message, &name);
02695 if (result != ISC_R_SUCCESS)
02696 return (result);
02697 dns_name_init(name, NULL);
02698 dns_name_clone(dns_db_origin(db), name);
02699 rdataset = query_newrdataset(client);
02700 if (rdataset == NULL) {
02701 CTRACE(ISC_LOG_ERROR, "unable to allocate rdataset");
02702 eresult = DNS_R_SERVFAIL;
02703 goto cleanup;
02704 }
02705 if (WANTDNSSEC(client) && dns_db_issecure(db)) {
02706 sigrdataset = query_newrdataset(client);
02707 if (sigrdataset == NULL) {
02708 CTRACE(ISC_LOG_ERROR, "unable to allocate sigrdataset");
02709 eresult = DNS_R_SERVFAIL;
02710 goto cleanup;
02711 }
02712 }
02713
02714
02715
02716
02717 result = dns_db_getoriginnode(db, &node);
02718 if (result == ISC_R_SUCCESS) {
02719 result = dns_db_findrdataset(db, node, version,
02720 dns_rdatatype_soa, 0, client->now,
02721 rdataset, sigrdataset);
02722 } else {
02723 dns_fixedname_t foundname;
02724 dns_name_t *fname;
02725
02726 dns_fixedname_init(&foundname);
02727 fname = dns_fixedname_name(&foundname);
02728
02729 result = dns_db_findext(db, name, version, dns_rdatatype_soa,
02730 client->query.dboptions, 0, &node,
02731 fname, &cm, &ci, rdataset, sigrdataset);
02732 }
02733 if (result != ISC_R_SUCCESS) {
02734
02735
02736
02737
02738 CTRACE(ISC_LOG_ERROR, "unable to find SOA RR at zone apex");
02739 eresult = DNS_R_SERVFAIL;
02740 } else {
02741
02742
02743
02744 dns_rdata_soa_t soa;
02745 dns_rdata_t rdata = DNS_RDATA_INIT;
02746 result = dns_rdataset_first(rdataset);
02747 RUNTIME_CHECK(result == ISC_R_SUCCESS);
02748 dns_rdataset_current(rdataset, &rdata);
02749 result = dns_rdata_tostruct(&rdata, &soa, NULL);
02750 if (result != ISC_R_SUCCESS)
02751 goto cleanup;
02752
02753 if (override_ttl != ISC_UINT32_MAX &&
02754 override_ttl < rdataset->ttl) {
02755 rdataset->ttl = override_ttl;
02756 if (sigrdataset != NULL)
02757 sigrdataset->ttl = override_ttl;
02758 }
02759
02760
02761
02762
02763
02764 if (rdataset->ttl > soa.minimum)
02765 rdataset->ttl = soa.minimum;
02766 if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum)
02767 sigrdataset->ttl = soa.minimum;
02768
02769 if (sigrdataset != NULL)
02770 sigrdatasetp = &sigrdataset;
02771 else
02772 sigrdatasetp = NULL;
02773
02774 if (section == DNS_SECTION_ADDITIONAL)
02775 rdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
02776 query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL,
02777 section);
02778 }
02779
02780 cleanup:
02781 query_putrdataset(client, &rdataset);
02782 if (sigrdataset != NULL)
02783 query_putrdataset(client, &sigrdataset);
02784 if (name != NULL)
02785 query_releasename(client, &name);
02786 if (node != NULL)
02787 dns_db_detachnode(db, &node);
02788
02789 return (eresult);
02790 }
02791
02792 static inline isc_result_t
02793 query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
02794 dns_name_t *name, *fname;
02795 dns_dbnode_t *node;
02796 isc_result_t result, eresult;
02797 dns_fixedname_t foundname;
02798 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
02799 dns_rdataset_t **sigrdatasetp = NULL;
02800 dns_clientinfomethods_t cm;
02801 dns_clientinfo_t ci;
02802
02803 CTRACE(ISC_LOG_DEBUG(3), "query_addns");
02804
02805
02806
02807 eresult = ISC_R_SUCCESS;
02808 name = NULL;
02809 rdataset = NULL;
02810 node = NULL;
02811 dns_fixedname_init(&foundname);
02812 fname = dns_fixedname_name(&foundname);
02813 dns_clientinfomethods_init(&cm, ns_client_sourceip);
02814 dns_clientinfo_init(&ci, client, NULL);
02815
02816
02817
02818
02819 result = dns_message_gettempname(client->message, &name);
02820 if (result != ISC_R_SUCCESS) {
02821 CTRACE(ISC_LOG_DEBUG(3),
02822 "query_addns: dns_message_gettempname failed: done");
02823 return (result);
02824 }
02825 dns_name_init(name, NULL);
02826 dns_name_clone(dns_db_origin(db), name);
02827 rdataset = query_newrdataset(client);
02828 if (rdataset == NULL) {
02829 CTRACE(ISC_LOG_ERROR,
02830 "query_addns: query_newrdataset failed");
02831 eresult = DNS_R_SERVFAIL;
02832 goto cleanup;
02833 }
02834 if (WANTDNSSEC(client) && dns_db_issecure(db)) {
02835 sigrdataset = query_newrdataset(client);
02836 if (sigrdataset == NULL) {
02837 CTRACE(ISC_LOG_ERROR,
02838 "query_addns: query_newrdataset failed");
02839 eresult = DNS_R_SERVFAIL;
02840 goto cleanup;
02841 }
02842 }
02843
02844
02845
02846
02847 result = dns_db_getoriginnode(db, &node);
02848 if (result == ISC_R_SUCCESS) {
02849 result = dns_db_findrdataset(db, node, version,
02850 dns_rdatatype_ns, 0, client->now,
02851 rdataset, sigrdataset);
02852 } else {
02853 CTRACE(ISC_LOG_DEBUG(3), "query_addns: calling dns_db_find");
02854 result = dns_db_findext(db, name, NULL, dns_rdatatype_ns,
02855 client->query.dboptions, 0, &node,
02856 fname, &cm, &ci, rdataset, sigrdataset);
02857 CTRACE(ISC_LOG_DEBUG(3), "query_addns: dns_db_find complete");
02858 }
02859 if (result != ISC_R_SUCCESS) {
02860 CTRACE(ISC_LOG_ERROR,
02861 "query_addns: "
02862 "dns_db_findrdataset or dns_db_find failed");
02863
02864
02865
02866
02867 eresult = DNS_R_SERVFAIL;
02868 } else {
02869 if (sigrdataset != NULL)
02870 sigrdatasetp = &sigrdataset;
02871 else
02872 sigrdatasetp = NULL;
02873 query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL,
02874 DNS_SECTION_AUTHORITY);
02875 }
02876
02877 cleanup:
02878 CTRACE(ISC_LOG_DEBUG(3), "query_addns: cleanup");
02879 query_putrdataset(client, &rdataset);
02880 if (sigrdataset != NULL)
02881 query_putrdataset(client, &sigrdataset);
02882 if (name != NULL)
02883 query_releasename(client, &name);
02884 if (node != NULL)
02885 dns_db_detachnode(db, &node);
02886
02887 CTRACE(ISC_LOG_DEBUG(3), "query_addns: done");
02888 return (eresult);
02889 }
02890
02891 static isc_result_t
02892 query_add_cname(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,
02893 dns_trust_t trust, dns_ttl_t ttl)
02894 {
02895 dns_rdataset_t *rdataset;
02896 dns_rdatalist_t *rdatalist;
02897 dns_rdata_t *rdata;
02898 isc_region_t r;
02899 dns_name_t *aname;
02900 isc_result_t result;
02901
02902
02903
02904
02905
02906 aname = NULL;
02907 result = dns_message_gettempname(client->message, &aname);
02908 if (result != ISC_R_SUCCESS)
02909 return (result);
02910 result = dns_name_dup(qname, client->mctx, aname);
02911 if (result != ISC_R_SUCCESS) {
02912 dns_message_puttempname(client->message, &aname);
02913 return (result);
02914 }
02915
02916 rdatalist = NULL;
02917 result = dns_message_gettemprdatalist(client->message, &rdatalist);
02918 if (result != ISC_R_SUCCESS) {
02919 dns_message_puttempname(client->message, &aname);
02920 return (result);
02921 }
02922 rdata = NULL;
02923 result = dns_message_gettemprdata(client->message, &rdata);
02924 if (result != ISC_R_SUCCESS) {
02925 dns_message_puttempname(client->message, &aname);
02926 dns_message_puttemprdatalist(client->message, &rdatalist);
02927 return (result);
02928 }
02929 rdataset = NULL;
02930 result = dns_message_gettemprdataset(client->message, &rdataset);
02931 if (result != ISC_R_SUCCESS) {
02932 dns_message_puttempname(client->message, &aname);
02933 dns_message_puttemprdatalist(client->message, &rdatalist);
02934 dns_message_puttemprdata(client->message, &rdata);
02935 return (result);
02936 }
02937 dns_rdataset_init(rdataset);
02938 rdatalist->type = dns_rdatatype_cname;
02939 rdatalist->rdclass = client->message->rdclass;
02940 rdatalist->ttl = ttl;
02941
02942 dns_name_toregion(tname, &r);
02943 rdata->data = r.base;
02944 rdata->length = r.length;
02945 rdata->rdclass = client->message->rdclass;
02946 rdata->type = dns_rdatatype_cname;
02947
02948 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
02949 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
02950 == ISC_R_SUCCESS);
02951 rdataset->trust = trust;
02952 dns_rdataset_setownercase(rdataset, aname);
02953
02954 query_addrrset(client, &aname, &rdataset, NULL, NULL,
02955 DNS_SECTION_ANSWER);
02956 if (rdataset != NULL) {
02957 if (dns_rdataset_isassociated(rdataset))
02958 dns_rdataset_disassociate(rdataset);
02959 dns_message_puttemprdataset(client->message, &rdataset);
02960 }
02961 if (aname != NULL)
02962 dns_message_puttempname(client->message, &aname);
02963
02964 return (ISC_R_SUCCESS);
02965 }
02966
02967
02968
02969
02970
02971 static void
02972 mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name,
02973 dns_rdata_rrsig_t *rrsig, dns_rdataset_t *rdataset,
02974 dns_rdataset_t *sigrdataset)
02975 {
02976 isc_result_t result;
02977 dns_dbnode_t *node = NULL;
02978 dns_clientinfomethods_t cm;
02979 dns_clientinfo_t ci;
02980 isc_stdtime_t now;
02981
02982 rdataset->trust = dns_trust_secure;
02983 sigrdataset->trust = dns_trust_secure;
02984 dns_clientinfomethods_init(&cm, ns_client_sourceip);
02985 dns_clientinfo_init(&ci, client, NULL);
02986
02987
02988
02989
02990 result = dns_db_findnodeext(db, name, ISC_TRUE, &cm, &ci, &node);
02991 if (result != ISC_R_SUCCESS)
02992 return;
02993
02994 isc_stdtime_get(&now);
02995 dns_rdataset_trimttl(rdataset, sigrdataset, rrsig, now,
02996 client->view->acceptexpired);
02997
02998 (void)dns_db_addrdataset(db, node, NULL, client->now, rdataset,
02999 0, NULL);
03000 (void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset,
03001 0, NULL);
03002 dns_db_detachnode(db, &node);
03003 }
03004
03005
03006
03007
03008
03009
03010
03011 static isc_boolean_t
03012 get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig,
03013 dns_rdataset_t *keyrdataset, dst_key_t **keyp)
03014 {
03015 isc_result_t result;
03016 dns_dbnode_t *node = NULL;
03017 isc_boolean_t secure = ISC_FALSE;
03018 dns_clientinfomethods_t cm;
03019 dns_clientinfo_t ci;
03020
03021 dns_clientinfomethods_init(&cm, ns_client_sourceip);
03022 dns_clientinfo_init(&ci, client, NULL);
03023
03024 if (!dns_rdataset_isassociated(keyrdataset)) {
03025 result = dns_db_findnodeext(db, &rrsig->signer, ISC_FALSE,
03026 &cm, &ci, &node);
03027 if (result != ISC_R_SUCCESS)
03028 return (ISC_FALSE);
03029
03030 result = dns_db_findrdataset(db, node, NULL,
03031 dns_rdatatype_dnskey, 0,
03032 client->now, keyrdataset, NULL);
03033 dns_db_detachnode(db, &node);
03034 if (result != ISC_R_SUCCESS)
03035 return (ISC_FALSE);
03036
03037 if (keyrdataset->trust != dns_trust_secure)
03038 return (ISC_FALSE);
03039
03040 result = dns_rdataset_first(keyrdataset);
03041 } else
03042 result = dns_rdataset_next(keyrdataset);
03043
03044 for ( ; result == ISC_R_SUCCESS;
03045 result = dns_rdataset_next(keyrdataset)) {
03046 dns_rdata_t rdata = DNS_RDATA_INIT;
03047 isc_buffer_t b;
03048
03049 dns_rdataset_current(keyrdataset, &rdata);
03050 isc_buffer_init(&b, rdata.data, rdata.length);
03051 isc_buffer_add(&b, rdata.length);
03052 result = dst_key_fromdns(&rrsig->signer, rdata.rdclass, &b,
03053 client->mctx, keyp);
03054 if (result != ISC_R_SUCCESS)
03055 continue;
03056 if (rrsig->algorithm == (dns_secalg_t)dst_key_alg(*keyp) &&
03057 rrsig->keyid == (dns_keytag_t)dst_key_id(*keyp) &&
03058 dst_key_iszonekey(*keyp)) {
03059 secure = ISC_TRUE;
03060 break;
03061 }
03062 dst_key_free(keyp);
03063 }
03064 return (secure);
03065 }
03066
03067 static isc_boolean_t
03068 verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset,
03069 dns_rdata_t *rdata, ns_client_t *client)
03070 {
03071 isc_result_t result;
03072 dns_fixedname_t fixed;
03073 isc_boolean_t ignore = ISC_FALSE;
03074
03075 dns_fixedname_init(&fixed);
03076
03077 again:
03078 result = dns_dnssec_verify3(name, rdataset, key, ignore,
03079 client->view->maxbits, client->mctx,
03080 rdata, NULL);
03081 if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) {
03082 ignore = ISC_TRUE;
03083 goto again;
03084 }
03085 if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD)
03086 return (ISC_TRUE);
03087 return (ISC_FALSE);
03088 }
03089
03090
03091
03092
03093 static isc_boolean_t
03094 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
03095 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
03096 {
03097 isc_result_t result;
03098 dns_rdata_t rdata = DNS_RDATA_INIT;
03099 dns_rdata_rrsig_t rrsig;
03100 dst_key_t *key = NULL;
03101 dns_rdataset_t keyrdataset;
03102
03103 if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset))
03104 return (ISC_FALSE);
03105
03106 for (result = dns_rdataset_first(sigrdataset);
03107 result == ISC_R_SUCCESS;
03108 result = dns_rdataset_next(sigrdataset)) {
03109
03110 dns_rdata_reset(&rdata);
03111 dns_rdataset_current(sigrdataset, &rdata);
03112 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
03113 if (result != ISC_R_SUCCESS)
03114 return (ISC_FALSE);
03115 if (!dns_resolver_algorithm_supported(client->view->resolver,
03116 name, rrsig.algorithm))
03117 continue;
03118 if (!dns_name_issubdomain(name, &rrsig.signer))
03119 continue;
03120 dns_rdataset_init(&keyrdataset);
03121 do {
03122 if (!get_key(client, db, &rrsig, &keyrdataset, &key))
03123 break;
03124 if (verify(key, name, rdataset, &rdata, client)) {
03125 dst_key_free(&key);
03126 dns_rdataset_disassociate(&keyrdataset);
03127 mark_secure(client, db, name, &rrsig,
03128 rdataset, sigrdataset);
03129 return (ISC_TRUE);
03130 }
03131 dst_key_free(&key);
03132 } while (1);
03133 if (dns_rdataset_isassociated(&keyrdataset))
03134 dns_rdataset_disassociate(&keyrdataset);
03135 }
03136 return (ISC_FALSE);
03137 }
03138
03139 static void
03140 query_addbestns(ns_client_t *client) {
03141 dns_db_t *db, *zdb;
03142 dns_dbnode_t *node;
03143 dns_name_t *fname, *zfname;
03144 dns_rdataset_t *rdataset, *sigrdataset, *zrdataset, *zsigrdataset;
03145 isc_boolean_t is_zone, use_zone;
03146 isc_buffer_t *dbuf;
03147 isc_result_t result;
03148 dns_dbversion_t *version;
03149 dns_zone_t *zone;
03150 isc_buffer_t b;
03151 dns_clientinfomethods_t cm;
03152 dns_clientinfo_t ci;
03153
03154 CTRACE(ISC_LOG_DEBUG(3), "query_addbestns");
03155 fname = NULL;
03156 zfname = NULL;
03157 rdataset = NULL;
03158 zrdataset = NULL;
03159 sigrdataset = NULL;
03160 zsigrdataset = NULL;
03161 node = NULL;
03162 db = NULL;
03163 zdb = NULL;
03164 version = NULL;
03165 zone = NULL;
03166 is_zone = ISC_FALSE;
03167 use_zone = ISC_FALSE;
03168
03169 dns_clientinfomethods_init(&cm, ns_client_sourceip);
03170 dns_clientinfo_init(&ci, client, NULL);
03171
03172
03173
03174
03175 result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0,
03176 &zone, &db, &version, &is_zone);
03177 if (result != ISC_R_SUCCESS)
03178 goto cleanup;
03179
03180 db_find:
03181
03182
03183
03184 dbuf = query_getnamebuf(client);
03185 if (dbuf == NULL)
03186 goto cleanup;
03187 fname = query_newname(client, dbuf, &b);
03188 rdataset = query_newrdataset(client);
03189 if (fname == NULL || rdataset == NULL)
03190 goto cleanup;
03191
03192
03193
03194
03195 if (WANTDNSSEC(client) || !is_zone) {
03196 sigrdataset = query_newrdataset(client);
03197 if (sigrdataset == NULL)
03198 goto cleanup;
03199 }
03200
03201
03202
03203
03204 if (is_zone) {
03205 result = dns_db_findext(db, client->query.qname, version,
03206 dns_rdatatype_ns,
03207 client->query.dboptions,
03208 client->now, &node, fname,
03209 &cm, &ci, rdataset, sigrdataset);
03210 if (result != DNS_R_DELEGATION)
03211 goto cleanup;
03212 if (USECACHE(client)) {
03213 query_keepname(client, fname, dbuf);
03214 zdb = db;
03215 zfname = fname;
03216 fname = NULL;
03217 zrdataset = rdataset;
03218 rdataset = NULL;
03219 zsigrdataset = sigrdataset;
03220 sigrdataset = NULL;
03221 dns_db_detachnode(db, &node);
03222 version = NULL;
03223 db = NULL;
03224 dns_db_attach(client->view->cachedb, &db);
03225 is_zone = ISC_FALSE;
03226 goto db_find;
03227 }
03228 } else {
03229 result = dns_db_findzonecut(db, client->query.qname,
03230 client->query.dboptions,
03231 client->now, &node, fname,
03232 rdataset, sigrdataset);
03233 if (result == ISC_R_SUCCESS) {
03234 if (zfname != NULL &&
03235 !dns_name_issubdomain(fname, zfname)) {
03236
03237
03238
03239
03240 use_zone = ISC_TRUE;
03241 }
03242 } else if (result == ISC_R_NOTFOUND && zfname != NULL) {
03243
03244
03245
03246
03247 use_zone = ISC_TRUE;
03248 } else
03249 goto cleanup;
03250 }
03251
03252 if (use_zone) {
03253 query_releasename(client, &fname);
03254 fname = zfname;
03255 zfname = NULL;
03256
03257
03258
03259
03260
03261
03262 dbuf = NULL;
03263 query_putrdataset(client, &rdataset);
03264 if (sigrdataset != NULL)
03265 query_putrdataset(client, &sigrdataset);
03266 rdataset = zrdataset;
03267 zrdataset = NULL;
03268 sigrdataset = zsigrdataset;
03269 zsigrdataset = NULL;
03270 }
03271
03272
03273
03274
03275 if ((DNS_TRUST_PENDING(rdataset->trust) ||
03276 (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust)))
03277 && !validate(client, db, fname, rdataset, sigrdataset) &&
03278 !PENDINGOK(client->query.dboptions))
03279 goto cleanup;
03280
03281 if ((DNS_TRUST_GLUE(rdataset->trust) ||
03282 (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) &&
03283 !validate(client, db, fname, rdataset, sigrdataset) &&
03284 SECURE(client) && WANTDNSSEC(client))
03285 goto cleanup;
03286
03287
03288
03289
03290 if (SECURE(client) && (WANTDNSSEC(client) || WANTAD(client)) &&
03291 ((rdataset->trust != dns_trust_secure) ||
03292 (sigrdataset != NULL && sigrdataset->trust != dns_trust_secure)))
03293 goto cleanup;
03294
03295
03296
03297
03298
03299 if (!WANTDNSSEC(client))
03300 query_putrdataset(client, &sigrdataset);
03301 query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
03302 DNS_SECTION_AUTHORITY);
03303
03304 cleanup:
03305 if (rdataset != NULL)
03306 query_putrdataset(client, &rdataset);
03307 if (sigrdataset != NULL)
03308 query_putrdataset(client, &sigrdataset);
03309 if (fname != NULL)
03310 query_releasename(client, &fname);
03311 if (node != NULL)
03312 dns_db_detachnode(db, &node);
03313 if (db != NULL)
03314 dns_db_detach(&db);
03315 if (zone != NULL)
03316 dns_zone_detach(&zone);
03317 if (zdb != NULL) {
03318 query_putrdataset(client, &zrdataset);
03319 if (zsigrdataset != NULL)
03320 query_putrdataset(client, &zsigrdataset);
03321 if (zfname != NULL)
03322 query_releasename(client, &zfname);
03323 dns_db_detach(&zdb);
03324 }
03325 }
03326
03327 static void
03328 fixrdataset(ns_client_t *client, dns_rdataset_t **rdataset) {
03329 if (*rdataset == NULL)
03330 *rdataset = query_newrdataset(client);
03331 else if (dns_rdataset_isassociated(*rdataset))
03332 dns_rdataset_disassociate(*rdataset);
03333 }
03334
03335 static void
03336 fixfname(ns_client_t *client, dns_name_t **fname, isc_buffer_t **dbuf,
03337 isc_buffer_t *nbuf)
03338 {
03339 if (*fname == NULL) {
03340 *dbuf = query_getnamebuf(client);
03341 if (*dbuf == NULL)
03342 return;
03343 *fname = query_newname(client, *dbuf, nbuf);
03344 }
03345 }
03346
03347 static void
03348 query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node,
03349 dns_dbversion_t *version, dns_name_t *name)
03350 {
03351 dns_fixedname_t fixed;
03352 dns_name_t *fname = NULL;
03353 dns_name_t *rname;
03354 dns_rdataset_t *rdataset, *sigrdataset;
03355 isc_buffer_t *dbuf, b;
03356 isc_result_t result;
03357 unsigned int count;
03358
03359 CTRACE(ISC_LOG_DEBUG(3), "query_addds");
03360 rname = NULL;
03361 rdataset = NULL;
03362 sigrdataset = NULL;
03363
03364
03365
03366
03367 rdataset = query_newrdataset(client);
03368 sigrdataset = query_newrdataset(client);
03369 if (rdataset == NULL || sigrdataset == NULL)
03370 goto cleanup;
03371
03372
03373
03374
03375 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ds, 0,
03376 client->now, rdataset, sigrdataset);
03377
03378
03379
03380 if (result == ISC_R_NOTFOUND)
03381 result = dns_db_findrdataset(db, node, version,
03382 dns_rdatatype_nsec, 0, client->now,
03383 rdataset, sigrdataset);
03384 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
03385 goto addnsec3;
03386 if (!dns_rdataset_isassociated(rdataset) ||
03387 !dns_rdataset_isassociated(sigrdataset))
03388 goto addnsec3;
03389
03390
03391
03392
03393
03394
03395 result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY);
03396 if (result != ISC_R_SUCCESS)
03397 goto cleanup;
03398
03399 rname = NULL;
03400 dns_message_currentname(client->message, DNS_SECTION_AUTHORITY,
03401 &rname);
03402 result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL);
03403 if (result != ISC_R_SUCCESS)
03404 goto cleanup;
03405
03406 ISC_LIST_APPEND(rname->list, rdataset, link);
03407 ISC_LIST_APPEND(rname->list, sigrdataset, link);
03408 rdataset = NULL;
03409 sigrdataset = NULL;
03410 return;
03411
03412 addnsec3:
03413 if (!dns_db_iszone(db))
03414 goto cleanup;
03415
03416
03417
03418 dbuf = query_getnamebuf(client);
03419 if (dbuf == NULL)
03420 goto cleanup;
03421 fname = query_newname(client, dbuf, &b);
03422 dns_fixedname_init(&fixed);
03423 if (dns_rdataset_isassociated(rdataset))
03424 dns_rdataset_disassociate(rdataset);
03425 if (dns_rdataset_isassociated(sigrdataset))
03426 dns_rdataset_disassociate(sigrdataset);
03427 query_findclosestnsec3(name, db, version, client, rdataset,
03428 sigrdataset, fname, ISC_TRUE,
03429 dns_fixedname_name(&fixed));
03430 if (!dns_rdataset_isassociated(rdataset))
03431 goto cleanup;
03432 query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
03433 DNS_SECTION_AUTHORITY);
03434
03435
03436
03437
03438 if (!dns_name_equal(name, dns_fixedname_name(&fixed))) {
03439 count = dns_name_countlabels(dns_fixedname_name(&fixed)) + 1;
03440 dns_name_getlabelsequence(name,
03441 dns_name_countlabels(name) - count,
03442 count, dns_fixedname_name(&fixed));
03443 fixfname(client, &fname, &dbuf, &b);
03444 fixrdataset(client, &rdataset);
03445 fixrdataset(client, &sigrdataset);
03446 if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
03447 goto cleanup;
03448 query_findclosestnsec3(dns_fixedname_name(&fixed), db, version,
03449 client, rdataset, sigrdataset, fname,
03450 ISC_FALSE, NULL);
03451 if (!dns_rdataset_isassociated(rdataset))
03452 goto cleanup;
03453 query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
03454 DNS_SECTION_AUTHORITY);
03455 }
03456
03457 cleanup:
03458 if (rdataset != NULL)
03459 query_putrdataset(client, &rdataset);
03460 if (sigrdataset != NULL)
03461 query_putrdataset(client, &sigrdataset);
03462 if (fname != NULL)
03463 query_releasename(client, &fname);
03464 }
03465
03466 static void
03467 query_addwildcardproof(ns_client_t *client, dns_db_t *db,
03468 dns_dbversion_t *version, dns_name_t *name,
03469 isc_boolean_t ispositive, isc_boolean_t nodata)
03470 {
03471 isc_buffer_t *dbuf, b;
03472 dns_name_t *fname;
03473 dns_rdataset_t *rdataset, *sigrdataset;
03474 dns_fixedname_t wfixed;
03475 dns_name_t *wname;
03476 dns_dbnode_t *node;
03477 unsigned int options;
03478 unsigned int olabels, nlabels, labels;
03479 isc_result_t result;
03480 dns_rdata_t rdata = DNS_RDATA_INIT;
03481 dns_rdata_nsec_t nsec;
03482 isc_boolean_t have_wname;
03483 int order;
03484 dns_fixedname_t cfixed;
03485 dns_name_t *cname;
03486 dns_clientinfomethods_t cm;
03487 dns_clientinfo_t ci;
03488
03489 CTRACE(ISC_LOG_DEBUG(3), "query_addwildcardproof");
03490 fname = NULL;
03491 rdataset = NULL;
03492 sigrdataset = NULL;
03493 node = NULL;
03494
03495 dns_clientinfomethods_init(&cm, ns_client_sourceip);
03496 dns_clientinfo_init(&ci, client, NULL);
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540 options = client->query.dboptions | DNS_DBFIND_NOWILD;
03541 dns_fixedname_init(&wfixed);
03542 wname = dns_fixedname_name(&wfixed);
03543 again:
03544 have_wname = ISC_FALSE;
03545
03546
03547
03548 dbuf = query_getnamebuf(client);
03549 if (dbuf == NULL)
03550 goto cleanup;
03551 fname = query_newname(client, dbuf, &b);
03552 rdataset = query_newrdataset(client);
03553 sigrdataset = query_newrdataset(client);
03554 if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
03555 goto cleanup;
03556
03557 result = dns_db_findext(db, name, version, dns_rdatatype_nsec,
03558 options, 0, &node, fname, &cm, &ci,
03559 rdataset, sigrdataset);
03560 if (node != NULL)
03561 dns_db_detachnode(db, &node);
03562
03563 if (!dns_rdataset_isassociated(rdataset)) {
03564
03565
03566
03567 dns_fixedname_init(&cfixed);
03568 cname = dns_fixedname_name(&cfixed);
03569
03570
03571
03572 dns_name_copy(name, cname, NULL);
03573 while (result == DNS_R_NXDOMAIN) {
03574 labels = dns_name_countlabels(cname) - 1;
03575
03576
03577
03578 if (labels == 0U)
03579 goto cleanup;
03580 dns_name_split(cname, labels, NULL, cname);
03581 result = dns_db_findext(db, cname, version,
03582 dns_rdatatype_nsec,
03583 options, 0, NULL, fname,
03584 &cm, &ci, NULL, NULL);
03585 }
03586
03587
03588
03589 query_findclosestnsec3(cname, db, NULL, client, rdataset,
03590 sigrdataset, fname, ISC_TRUE, cname);
03591 if (!dns_rdataset_isassociated(rdataset))
03592 goto cleanup;
03593 if (!ispositive)
03594 query_addrrset(client, &fname, &rdataset, &sigrdataset,
03595 dbuf, DNS_SECTION_AUTHORITY);
03596
03597
03598
03599
03600 if (fname == NULL) {
03601 dbuf = query_getnamebuf(client);
03602 if (dbuf == NULL)
03603 goto cleanup;
03604 fname = query_newname(client, dbuf, &b);
03605 }
03606
03607 if (rdataset == NULL)
03608 rdataset = query_newrdataset(client);
03609 else if (dns_rdataset_isassociated(rdataset))
03610 dns_rdataset_disassociate(rdataset);
03611
03612 if (sigrdataset == NULL)
03613 sigrdataset = query_newrdataset(client);
03614 else if (dns_rdataset_isassociated(sigrdataset))
03615 dns_rdataset_disassociate(sigrdataset);
03616
03617 if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
03618 goto cleanup;
03619
03620
03621
03622 labels = dns_name_countlabels(cname) + 1;
03623 if (dns_name_countlabels(name) == labels)
03624 dns_name_copy(name, wname, NULL);
03625 else
03626 dns_name_split(name, labels, NULL, wname);
03627
03628 query_findclosestnsec3(wname, db, NULL, client, rdataset,
03629 sigrdataset, fname, ISC_FALSE, NULL);
03630 if (!dns_rdataset_isassociated(rdataset))
03631 goto cleanup;
03632 query_addrrset(client, &fname, &rdataset, &sigrdataset,
03633 dbuf, DNS_SECTION_AUTHORITY);
03634
03635 if (ispositive)
03636 goto cleanup;
03637
03638
03639
03640
03641 if (fname == NULL) {
03642 dbuf = query_getnamebuf(client);
03643 if (dbuf == NULL)
03644 goto cleanup;
03645 fname = query_newname(client, dbuf, &b);
03646 }
03647
03648 if (rdataset == NULL)
03649 rdataset = query_newrdataset(client);
03650 else if (dns_rdataset_isassociated(rdataset))
03651 dns_rdataset_disassociate(rdataset);
03652
03653 if (sigrdataset == NULL)
03654 sigrdataset = query_newrdataset(client);
03655 else if (dns_rdataset_isassociated(sigrdataset))
03656 dns_rdataset_disassociate(sigrdataset);
03657
03658 if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
03659 goto cleanup;
03660
03661
03662
03663 result = dns_name_concatenate(dns_wildcardname,
03664 cname, wname, NULL);
03665 if (result != ISC_R_SUCCESS)
03666 goto cleanup;
03667
03668 query_findclosestnsec3(wname, db, NULL, client, rdataset,
03669 sigrdataset, fname, nodata, NULL);
03670 if (!dns_rdataset_isassociated(rdataset))
03671 goto cleanup;
03672 query_addrrset(client, &fname, &rdataset, &sigrdataset,
03673 dbuf, DNS_SECTION_AUTHORITY);
03674
03675 goto cleanup;
03676 } else if (result == DNS_R_NXDOMAIN) {
03677 if (!ispositive)
03678 result = dns_rdataset_first(rdataset);
03679 if (result == ISC_R_SUCCESS) {
03680 dns_rdataset_current(rdataset, &rdata);
03681 result = dns_rdata_tostruct(&rdata, &nsec, NULL);
03682 }
03683 if (result == ISC_R_SUCCESS) {
03684 (void)dns_name_fullcompare(name, fname, &order,
03685 &olabels);
03686 (void)dns_name_fullcompare(name, &nsec.next, &order,
03687 &nlabels);
03688
03689
03690
03691
03692 if (dns_name_countlabels(name) == nlabels)
03693 goto cleanup;
03694
03695 if (olabels > nlabels)
03696 dns_name_split(name, olabels, NULL, wname);
03697 else
03698 dns_name_split(name, nlabels, NULL, wname);
03699 result = dns_name_concatenate(dns_wildcardname,
03700 wname, wname, NULL);
03701 if (result == ISC_R_SUCCESS)
03702 have_wname = ISC_TRUE;
03703 dns_rdata_freestruct(&nsec);
03704 }
03705 query_addrrset(client, &fname, &rdataset, &sigrdataset,
03706 dbuf, DNS_SECTION_AUTHORITY);
03707 }
03708 if (rdataset != NULL)
03709 query_putrdataset(client, &rdataset);
03710 if (sigrdataset != NULL)
03711 query_putrdataset(client, &sigrdataset);
03712 if (fname != NULL)
03713 query_releasename(client, &fname);
03714 if (have_wname) {
03715 ispositive = ISC_TRUE;
03716 if (!dns_name_equal(name, wname)) {
03717 name = wname;
03718 goto again;
03719 }
03720 }
03721 cleanup:
03722 if (rdataset != NULL)
03723 query_putrdataset(client, &rdataset);
03724 if (sigrdataset != NULL)
03725 query_putrdataset(client, &sigrdataset);
03726 if (fname != NULL)
03727 query_releasename(client, &fname);
03728 }
03729
03730 static void
03731 query_addnxrrsetnsec(ns_client_t *client, dns_db_t *db,
03732 dns_dbversion_t *version, dns_name_t **namep,
03733 dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp)
03734 {
03735 dns_name_t *name;
03736 dns_rdataset_t *sigrdataset;
03737 dns_rdata_t sigrdata;
03738 dns_rdata_rrsig_t sig;
03739 unsigned int labels;
03740 isc_buffer_t *dbuf, b;
03741 dns_name_t *fname;
03742 isc_result_t result;
03743
03744 name = *namep;
03745 if ((name->attributes & DNS_NAMEATTR_WILDCARD) == 0) {
03746 query_addrrset(client, namep, rdatasetp, sigrdatasetp,
03747 NULL, DNS_SECTION_AUTHORITY);
03748 return;
03749 }
03750
03751 if (sigrdatasetp == NULL)
03752 return;
03753
03754 sigrdataset = *sigrdatasetp;
03755 if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset))
03756 return;
03757 result = dns_rdataset_first(sigrdataset);
03758 if (result != ISC_R_SUCCESS)
03759 return;
03760 dns_rdata_init(&sigrdata);
03761 dns_rdataset_current(sigrdataset, &sigrdata);
03762 result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
03763 if (result != ISC_R_SUCCESS)
03764 return;
03765
03766 labels = dns_name_countlabels(name);
03767 if ((unsigned int)sig.labels + 1 >= labels)
03768 return;
03769
03770
03771 query_addwildcardproof(client, db, version, client->query.qname,
03772 ISC_TRUE, ISC_FALSE);
03773
03774
03775
03776
03777 dbuf = query_getnamebuf(client);
03778 if (dbuf == NULL)
03779 return;
03780 fname = query_newname(client, dbuf, &b);
03781 if (fname == NULL)
03782 return;
03783 dns_name_split(name, sig.labels + 1, NULL, fname);
03784
03785 RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, fname, fname,
03786 NULL) == ISC_R_SUCCESS);
03787 query_addrrset(client, &fname, rdatasetp, sigrdatasetp,
03788 dbuf, DNS_SECTION_AUTHORITY);
03789 }
03790
03791 static void
03792 query_resume(isc_task_t *task, isc_event_t *event) {
03793 dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
03794 dns_fetch_t *fetch;
03795 ns_client_t *client;
03796 isc_boolean_t fetch_canceled, client_shuttingdown;
03797 isc_result_t result;
03798 isc_logcategory_t *logcategory = NS_LOGCATEGORY_QUERY_EERRORS;
03799 int errorloglevel;
03800
03801
03802
03803
03804
03805 UNUSED(task);
03806
03807 REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
03808 client = devent->ev_arg;
03809 REQUIRE(NS_CLIENT_VALID(client));
03810 REQUIRE(task == client->task);
03811 REQUIRE(RECURSING(client));
03812
03813 LOCK(&client->query.fetchlock);
03814 if (client->query.fetch != NULL) {
03815
03816
03817
03818 INSIST(devent->fetch == client->query.fetch);
03819 client->query.fetch = NULL;
03820 fetch_canceled = ISC_FALSE;
03821
03822
03823
03824 isc_stdtime_get(&client->now);
03825 } else {
03826
03827
03828
03829
03830 fetch_canceled = ISC_TRUE;
03831 }
03832 UNLOCK(&client->query.fetchlock);
03833 INSIST(client->query.fetch == NULL);
03834
03835 client->query.attributes &= ~NS_QUERYATTR_RECURSING;
03836 fetch = devent->fetch;
03837 devent->fetch = NULL;
03838
03839
03840
03841
03842
03843 client_shuttingdown = ns_client_shuttingdown(client);
03844 if (fetch_canceled || client_shuttingdown) {
03845 if (devent->node != NULL)
03846 dns_db_detachnode(devent->db, &devent->node);
03847 if (devent->db != NULL)
03848 dns_db_detach(&devent->db);
03849 query_putrdataset(client, &devent->rdataset);
03850 if (devent->sigrdataset != NULL)
03851 query_putrdataset(client, &devent->sigrdataset);
03852 isc_event_free(&event);
03853 if (fetch_canceled) {
03854 CTRACE(ISC_LOG_ERROR, "fetch cancelled");
03855 query_error(client, DNS_R_SERVFAIL, __LINE__);
03856 } else
03857 query_next(client, ISC_R_CANCELED);
03858
03859
03860
03861 ns_client_detach(&client);
03862 } else {
03863 result = query_find(client, devent, 0);
03864 if (result != ISC_R_SUCCESS) {
03865 if (result == DNS_R_SERVFAIL)
03866 errorloglevel = ISC_LOG_DEBUG(2);
03867 else
03868 errorloglevel = ISC_LOG_DEBUG(4);
03869 if (isc_log_wouldlog(ns_g_lctx, errorloglevel)) {
03870 dns_resolver_logfetch(fetch, ns_g_lctx,
03871 logcategory,
03872 NS_LOGMODULE_QUERY,
03873 errorloglevel, ISC_FALSE);
03874 }
03875 }
03876 }
03877
03878 dns_resolver_destroyfetch(&fetch);
03879 }
03880
03881 static void
03882 prefetch_done(isc_task_t *task, isc_event_t *event) {
03883 dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
03884 ns_client_t *client;
03885
03886 UNUSED(task);
03887
03888 REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
03889 client = devent->ev_arg;
03890 REQUIRE(NS_CLIENT_VALID(client));
03891 REQUIRE(task == client->task);
03892
03893 LOCK(&client->query.fetchlock);
03894 if (client->query.prefetch != NULL) {
03895 INSIST(devent->fetch == client->query.prefetch);
03896 client->query.prefetch = NULL;
03897 }
03898 UNLOCK(&client->query.fetchlock);
03899 if (devent->fetch != NULL)
03900 dns_resolver_destroyfetch(&devent->fetch);
03901 if (devent->node != NULL)
03902 dns_db_detachnode(devent->db, &devent->node);
03903 if (devent->db != NULL)
03904 dns_db_detach(&devent->db);
03905 query_putrdataset(client, &devent->rdataset);
03906 isc_event_free(&event);
03907 ns_client_detach(&client);
03908 }
03909
03910 static void
03911 query_prefetch(ns_client_t *client, dns_name_t *qname,
03912 dns_rdataset_t *rdataset)
03913 {
03914 isc_result_t result;
03915 isc_sockaddr_t *peeraddr;
03916 dns_rdataset_t *tmprdataset;
03917 ns_client_t *dummy = NULL;
03918 unsigned int options;
03919
03920 if (client->query.prefetch != NULL ||
03921 client->view->prefetch_trigger == 0U ||
03922 rdataset->ttl > client->view->prefetch_trigger ||
03923 (rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0)
03924 return;
03925
03926 if (client->recursionquota == NULL) {
03927 result = isc_quota_attach(&ns_g_server->recursionquota,
03928 &client->recursionquota);
03929 if (result != ISC_R_SUCCESS)
03930 return;
03931 isc_stats_increment(ns_g_server->nsstats,
03932 dns_nsstatscounter_recursclients);
03933 }
03934
03935 tmprdataset = query_newrdataset(client);
03936 if (tmprdataset == NULL)
03937 return;
03938 if ((client->attributes & NS_CLIENTATTR_TCP) == 0)
03939 peeraddr = &client->peeraddr;
03940 else
03941 peeraddr = NULL;
03942 ns_client_attach(client, &dummy);
03943 options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH;
03944 result = dns_resolver_createfetch3(client->view->resolver,
03945 qname, rdataset->type, NULL, NULL,
03946 NULL, peeraddr, client->message->id,
03947 options, 0, NULL, client->task,
03948 prefetch_done, client,
03949 tmprdataset, NULL,
03950 &client->query.prefetch);
03951 if (result != ISC_R_SUCCESS) {
03952 query_putrdataset(client, &tmprdataset);
03953 ns_client_detach(&dummy);
03954 }
03955 dns_rdataset_clearprefetch(rdataset);
03956 }
03957
03958 static isc_result_t
03959 query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
03960 dns_name_t *qdomain, dns_rdataset_t *nameservers,
03961 isc_boolean_t resuming)
03962 {
03963 isc_result_t result;
03964 dns_rdataset_t *rdataset, *sigrdataset;
03965 isc_sockaddr_t *peeraddr;
03966
03967 if (!resuming)
03968 inc_stats(client, dns_nsstatscounter_recursion);
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980 if (client->recursionquota == NULL) {
03981 result = isc_quota_attach(&ns_g_server->recursionquota,
03982 &client->recursionquota);
03983
03984 isc_stats_increment(ns_g_server->nsstats,
03985 dns_nsstatscounter_recursclients);
03986
03987 if (result == ISC_R_SOFTQUOTA) {
03988 static isc_stdtime_t last = 0;
03989 isc_stdtime_t now;
03990 isc_stdtime_get(&now);
03991 if (now != last) {
03992 last = now;
03993 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
03994 NS_LOGMODULE_QUERY,
03995 ISC_LOG_WARNING,
03996 "recursive-clients soft limit "
03997 "exceeded (%d/%d/%d), "
03998 "aborting oldest query",
03999 client->recursionquota->used,
04000 client->recursionquota->soft,
04001 client->recursionquota->max);
04002 }
04003 ns_client_killoldestquery(client);
04004 result = ISC_R_SUCCESS;
04005 } else if (result == ISC_R_QUOTA) {
04006 static isc_stdtime_t last = 0;
04007 isc_stdtime_t now;
04008 isc_stdtime_get(&now);
04009 if (now != last) {
04010 last = now;
04011 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
04012 NS_LOGMODULE_QUERY,
04013 ISC_LOG_WARNING,
04014 "no more recursive clients "
04015 "(%d/%d/%d): %s",
04016 ns_g_server->recursionquota.used,
04017 ns_g_server->recursionquota.soft,
04018 ns_g_server->recursionquota.max,
04019 isc_result_totext(result));
04020 }
04021 ns_client_killoldestquery(client);
04022 }
04023 if (result == ISC_R_SUCCESS && !client->mortal &&
04024 (client->attributes & NS_CLIENTATTR_TCP) == 0) {
04025 result = ns_client_replace(client);
04026 if (result != ISC_R_SUCCESS) {
04027 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
04028 NS_LOGMODULE_QUERY,
04029 ISC_LOG_WARNING,
04030 "ns_client_replace() failed: %s",
04031 isc_result_totext(result));
04032 isc_quota_detach(&client->recursionquota);
04033 isc_stats_decrement(ns_g_server->nsstats,
04034 dns_nsstatscounter_recursclients);
04035 }
04036 }
04037 if (result != ISC_R_SUCCESS)
04038 return (result);
04039 ns_client_recursing(client);
04040 }
04041
04042
04043
04044
04045 REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns);
04046 REQUIRE(client->query.fetch == NULL);
04047
04048 rdataset = query_newrdataset(client);
04049 if (rdataset == NULL)
04050 return (ISC_R_NOMEMORY);
04051 if (WANTDNSSEC(client)) {
04052 sigrdataset = query_newrdataset(client);
04053 if (sigrdataset == NULL) {
04054 query_putrdataset(client, &rdataset);
04055 return (ISC_R_NOMEMORY);
04056 }
04057 } else
04058 sigrdataset = NULL;
04059
04060 if (client->query.timerset == ISC_FALSE)
04061 ns_client_settimeout(client, 60);
04062 if ((client->attributes & NS_CLIENTATTR_TCP) == 0)
04063 peeraddr = &client->peeraddr;
04064 else
04065 peeraddr = NULL;
04066 result = dns_resolver_createfetch3(client->view->resolver,
04067 qname, qtype, qdomain, nameservers,
04068 NULL, peeraddr, client->message->id,
04069 client->query.fetchoptions, 0, NULL,
04070 client->task, query_resume, client,
04071 rdataset, sigrdataset,
04072 &client->query.fetch);
04073
04074 if (result == ISC_R_SUCCESS) {
04075
04076
04077
04078
04079
04080 } else {
04081 query_putrdataset(client, &rdataset);
04082 if (sigrdataset != NULL)
04083 query_putrdataset(client, &sigrdataset);
04084 }
04085
04086 return (result);
04087 }
04088
04089 static inline void
04090 rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep,
04091 dns_rdataset_t **rdatasetp)
04092 {
04093 if (nodep != NULL && *nodep != NULL) {
04094 REQUIRE(dbp != NULL && *dbp != NULL);
04095 dns_db_detachnode(*dbp, nodep);
04096 }
04097 if (dbp != NULL && *dbp != NULL)
04098 dns_db_detach(dbp);
04099 if (zonep != NULL && *zonep != NULL)
04100 dns_zone_detach(zonep);
04101 if (rdatasetp != NULL && *rdatasetp != NULL &&
04102 dns_rdataset_isassociated(*rdatasetp))
04103 dns_rdataset_disassociate(*rdatasetp);
04104 }
04105
04106 static inline void
04107 rpz_match_clear(dns_rpz_st_t *st)
04108 {
04109 rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset);
04110 st->m.version = NULL;
04111 }
04112
04113 static inline isc_result_t
04114 rpz_ready(ns_client_t *client, dns_rdataset_t **rdatasetp)
04115 {
04116 REQUIRE(rdatasetp != NULL);
04117
04118 if (*rdatasetp == NULL) {
04119 *rdatasetp = query_newrdataset(client);
04120 if (*rdatasetp == NULL) {
04121 CTRACE(ISC_LOG_ERROR,
04122 "rpz_ready: query_newrdataset failed");
04123 return (DNS_R_SERVFAIL);
04124 }
04125 } else if (dns_rdataset_isassociated(*rdatasetp)) {
04126 dns_rdataset_disassociate(*rdatasetp);
04127 }
04128 return (ISC_R_SUCCESS);
04129 }
04130
04131 static void
04132 rpz_st_clear(ns_client_t *client) {
04133 dns_rpz_st_t *st = client->query.rpz_st;
04134
04135 if (st->m.rdataset != NULL)
04136 query_putrdataset(client, &st->m.rdataset);
04137 rpz_match_clear(st);
04138
04139 rpz_clean(NULL, &st->r.db, NULL, NULL);
04140 if (st->r.ns_rdataset != NULL)
04141 query_putrdataset(client, &st->r.ns_rdataset);
04142 if (st->r.r_rdataset != NULL)
04143 query_putrdataset(client, &st->r.r_rdataset);
04144
04145 rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL);
04146 if (st->q.rdataset != NULL)
04147 query_putrdataset(client, &st->q.rdataset);
04148 if (st->q.sigrdataset != NULL)
04149 query_putrdataset(client, &st->q.sigrdataset);
04150 st->state = 0;
04151 st->m.type = DNS_RPZ_TYPE_BAD;
04152 st->m.policy = DNS_RPZ_POLICY_MISS;
04153 }
04154
04155 static dns_rpz_zbits_t
04156 rpz_get_zbits(ns_client_t *client,
04157 dns_rdatatype_t ip_type, dns_rpz_type_t rpz_type)
04158 {
04159 dns_rpz_zones_t *rpzs;
04160 dns_rpz_st_t *st;
04161 dns_rpz_zbits_t zbits;
04162
04163 rpzs = client->view->rpzs;
04164
04165 switch (rpz_type) {
04166 case DNS_RPZ_TYPE_CLIENT_IP:
04167 zbits = rpzs->have.client_ip;
04168 break;
04169 case DNS_RPZ_TYPE_QNAME:
04170 zbits = rpzs->have.qname;
04171 break;
04172 case DNS_RPZ_TYPE_IP:
04173 if (ip_type == dns_rdatatype_a) {
04174 zbits = rpzs->have.ipv4;
04175 } else if (ip_type == dns_rdatatype_aaaa) {
04176 zbits = rpzs->have.ipv6;
04177 } else {
04178 zbits = rpzs->have.ip;
04179 }
04180 break;
04181 case DNS_RPZ_TYPE_NSDNAME:
04182 zbits = rpzs->have.nsdname;
04183 break;
04184 case DNS_RPZ_TYPE_NSIP:
04185 if (ip_type == dns_rdatatype_a) {
04186 zbits = rpzs->have.nsipv4;
04187 } else if (ip_type == dns_rdatatype_aaaa) {
04188 zbits = rpzs->have.nsipv6;
04189 } else {
04190 zbits = rpzs->have.nsip;
04191 }
04192 break;
04193 default:
04194 INSIST(0);
04195 break;
04196 }
04197
04198 st = client->query.rpz_st;
04199
04200
04201
04202
04203
04204
04205
04206
04207
04208 if (st->m.policy != DNS_RPZ_POLICY_MISS) {
04209 if (st->m.type >= rpz_type) {
04210 zbits &= DNS_RPZ_ZMASK(st->m.rpz->num);
04211 } else{
04212 zbits &= DNS_RPZ_ZMASK(st->m.rpz->num) >> 1;
04213 }
04214 }
04215
04216
04217
04218
04219 if (!RECURSIONOK(client))
04220 zbits &= rpzs->p.no_rd_ok;
04221
04222 return (zbits);
04223 }
04224
04225
04226
04227
04228
04229 static isc_result_t
04230 rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
04231 dns_rpz_type_t rpz_type, dns_db_t **dbp,
04232 dns_dbversion_t *version, dns_rdataset_t **rdatasetp,
04233 isc_boolean_t resuming)
04234 {
04235 dns_rpz_st_t *st;
04236 isc_boolean_t is_zone;
04237 dns_dbnode_t *node;
04238 dns_fixedname_t fixed;
04239 dns_name_t *found;
04240 isc_result_t result;
04241 dns_clientinfomethods_t cm;
04242 dns_clientinfo_t ci;
04243
04244 dns_clientinfomethods_init(&cm, ns_client_sourceip);
04245 dns_clientinfo_init(&ci, client, NULL);
04246
04247 st = client->query.rpz_st;
04248 if ((st->state & DNS_RPZ_RECURSING) != 0) {
04249 INSIST(st->r.r_type == type);
04250 INSIST(dns_name_equal(name, st->r_name));
04251 INSIST(*rdatasetp == NULL ||
04252 !dns_rdataset_isassociated(*rdatasetp));
04253 INSIST(*dbp == NULL);
04254 st->state &= ~DNS_RPZ_RECURSING;
04255 *dbp = st->r.db;
04256 st->r.db = NULL;
04257 if (*rdatasetp != NULL)
04258 query_putrdataset(client, rdatasetp);
04259 *rdatasetp = st->r.r_rdataset;
04260 st->r.r_rdataset = NULL;
04261 result = st->r.r_result;
04262 if (result == DNS_R_DELEGATION) {
04263 CTRACE(ISC_LOG_ERROR, "RPZ recursing");
04264 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
04265 rpz_type, " rpz_rrset_find(1)", result);
04266 st->m.policy = DNS_RPZ_POLICY_ERROR;
04267 result = DNS_R_SERVFAIL;
04268 }
04269 return (result);
04270 }
04271
04272 result = rpz_ready(client, rdatasetp);
04273 if (result != ISC_R_SUCCESS) {
04274 st->m.policy = DNS_RPZ_POLICY_ERROR;
04275 return (result);
04276 }
04277 if (*dbp != NULL) {
04278 is_zone = ISC_FALSE;
04279 } else {
04280 dns_zone_t *zone;
04281
04282 version = NULL;
04283 zone = NULL;
04284 result = query_getdb(client, name, type, 0, &zone, dbp,
04285 &version, &is_zone);
04286 if (result != ISC_R_SUCCESS) {
04287 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
04288 rpz_type, " rpz_rrset_find(2)", result);
04289 st->m.policy = DNS_RPZ_POLICY_ERROR;
04290 if (zone != NULL)
04291 dns_zone_detach(&zone);
04292 return (result);
04293 }
04294 if (zone != NULL)
04295 dns_zone_detach(&zone);
04296 }
04297
04298 node = NULL;
04299 dns_fixedname_init(&fixed);
04300 found = dns_fixedname_name(&fixed);
04301 dns_clientinfomethods_init(&cm, ns_client_sourceip);
04302 dns_clientinfo_init(&ci, client, NULL);
04303 result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK,
04304 client->now, &node, found,
04305 &cm, &ci, *rdatasetp, NULL);
04306 if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) {
04307
04308
04309
04310
04311 rpz_clean(NULL, dbp, &node, rdatasetp);
04312 version = NULL;
04313 dns_db_attach(client->view->cachedb, dbp);
04314 result = dns_db_findext(*dbp, name, version, dns_rdatatype_ns,
04315 0, client->now, &node, found,
04316 &cm, &ci, *rdatasetp, NULL);
04317 }
04318 rpz_clean(NULL, dbp, &node, NULL);
04319 if (result == DNS_R_DELEGATION) {
04320 rpz_clean(NULL, NULL, NULL, rdatasetp);
04321
04322
04323
04324
04325 if (rpz_type == DNS_RPZ_TYPE_IP) {
04326 result = DNS_R_NXRRSET;
04327 } else {
04328 dns_name_copy(name, st->r_name, NULL);
04329 result = query_recurse(client, type, st->r_name,
04330 NULL, NULL, resuming);
04331 if (result == ISC_R_SUCCESS) {
04332 st->state |= DNS_RPZ_RECURSING;
04333 result = DNS_R_DELEGATION;
04334 }
04335 }
04336 }
04337 return (result);
04338 }
04339
04340
04341
04342
04343
04344 static isc_result_t
04345 rpz_get_p_name(ns_client_t *client, dns_name_t *p_name,
04346 dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
04347 dns_name_t *trig_name)
04348 {
04349 dns_offsets_t prefix_offsets;
04350 dns_name_t prefix, *suffix;
04351 unsigned int first, labels;
04352 isc_result_t result;
04353
04354
04355
04356
04357
04358
04359
04360 switch (rpz_type) {
04361 case DNS_RPZ_TYPE_CLIENT_IP:
04362 suffix = &rpz->client_ip;
04363 break;
04364 case DNS_RPZ_TYPE_QNAME:
04365 suffix = &rpz->origin;
04366 break;
04367 case DNS_RPZ_TYPE_IP:
04368 suffix = &rpz->ip;
04369 break;
04370 case DNS_RPZ_TYPE_NSDNAME:
04371 suffix = &rpz->nsdname;
04372 break;
04373 case DNS_RPZ_TYPE_NSIP:
04374 suffix = &rpz->nsip;
04375 break;
04376 default:
04377 INSIST(0);
04378 }
04379
04380
04381
04382
04383
04384 dns_name_init(&prefix, prefix_offsets);
04385 labels = dns_name_countlabels(trig_name);
04386 first = 0;
04387 for (;;) {
04388 dns_name_getlabelsequence(trig_name, first, labels-first-1,
04389 &prefix);
04390 result = dns_name_concatenate(&prefix, suffix, p_name, NULL);
04391 if (result == ISC_R_SUCCESS)
04392 break;
04393 INSIST(result == DNS_R_NAMETOOLONG);
04394
04395
04396
04397 if (labels-first < 2) {
04398 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, suffix,
04399 rpz_type, " concatentate()", result);
04400 return (ISC_R_FAILURE);
04401 }
04402
04403
04404
04405 if (first == 0) {
04406 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, suffix,
04407 rpz_type, " concatentate()", result);
04408 }
04409 ++first;
04410 }
04411 return (ISC_R_SUCCESS);
04412 }
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425 static isc_result_t
04426 rpz_find_p(ns_client_t *client, dns_name_t *self_name, dns_rdatatype_t qtype,
04427 dns_name_t *p_name, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
04428 dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp,
04429 dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
04430 dns_rpz_policy_t *policyp)
04431 {
04432 dns_fixedname_t foundf;
04433 dns_name_t *found;
04434 isc_result_t result;
04435 dns_clientinfomethods_t cm;
04436 dns_clientinfo_t ci;
04437
04438 REQUIRE(nodep != NULL);
04439
04440 dns_clientinfomethods_init(&cm, ns_client_sourceip);
04441 dns_clientinfo_init(&ci, client, NULL);
04442
04443
04444
04445
04446
04447 rpz_clean(zonep, dbp, nodep, rdatasetp);
04448 result = rpz_ready(client, rdatasetp);
04449 if (result != ISC_R_SUCCESS) {
04450 CTRACE(ISC_LOG_ERROR, "rpz_ready() failed");
04451 return (DNS_R_SERVFAIL);
04452 }
04453 *versionp = NULL;
04454 result = rpz_getdb(client, p_name, rpz_type, zonep, dbp, versionp);
04455 if (result != ISC_R_SUCCESS)
04456 return (DNS_R_NXDOMAIN);
04457 dns_fixedname_init(&foundf);
04458 found = dns_fixedname_name(&foundf);
04459
04460 result = dns_db_findext(*dbp, p_name, *versionp, dns_rdatatype_any, 0,
04461 client->now, nodep, found, &cm, &ci,
04462 *rdatasetp, NULL);
04463
04464
04465
04466 if (result == ISC_R_SUCCESS) {
04467 dns_rdatasetiter_t *rdsiter;
04468
04469 rdsiter = NULL;
04470 result = dns_db_allrdatasets(*dbp, *nodep, *versionp, 0,
04471 &rdsiter);
04472 if (result != ISC_R_SUCCESS) {
04473 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name,
04474 rpz_type, " allrdatasets()", result);
04475 CTRACE(ISC_LOG_ERROR,
04476 "rpz_find_p: allrdatasets failed");
04477 return (DNS_R_SERVFAIL);
04478 }
04479 for (result = dns_rdatasetiter_first(rdsiter);
04480 result == ISC_R_SUCCESS;
04481 result = dns_rdatasetiter_next(rdsiter)) {
04482 dns_rdatasetiter_current(rdsiter, *rdatasetp);
04483 if ((*rdatasetp)->type == dns_rdatatype_cname ||
04484 (*rdatasetp)->type == qtype)
04485 break;
04486 dns_rdataset_disassociate(*rdatasetp);
04487 }
04488 dns_rdatasetiter_destroy(&rdsiter);
04489 if (result != ISC_R_SUCCESS) {
04490 if (result != ISC_R_NOMORE) {
04491 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
04492 p_name, rpz_type,
04493 " rdatasetiter", result);
04494 CTRACE(ISC_LOG_ERROR,
04495 "rpz_find_p: rdatasetiter_destroy "
04496 "failed");
04497 return (DNS_R_SERVFAIL);
04498 }
04499
04500
04501
04502
04503 if (dns_rdataset_isassociated(*rdatasetp))
04504 dns_rdataset_disassociate(*rdatasetp);
04505 dns_db_detachnode(*dbp, nodep);
04506
04507 if (qtype == dns_rdatatype_rrsig ||
04508 qtype == dns_rdatatype_sig)
04509 result = DNS_R_NXRRSET;
04510 else
04511 result = dns_db_findext(*dbp, p_name, *versionp,
04512 qtype, 0, client->now,
04513 nodep, found, &cm, &ci,
04514 *rdatasetp, NULL);
04515 }
04516 }
04517 switch (result) {
04518 case ISC_R_SUCCESS:
04519 if ((*rdatasetp)->type != dns_rdatatype_cname) {
04520 *policyp = DNS_RPZ_POLICY_RECORD;
04521 } else {
04522 *policyp = dns_rpz_decode_cname(rpz, *rdatasetp,
04523 self_name);
04524 if ((*policyp == DNS_RPZ_POLICY_RECORD ||
04525 *policyp == DNS_RPZ_POLICY_WILDCNAME) &&
04526 qtype != dns_rdatatype_cname &&
04527 qtype != dns_rdatatype_any)
04528 return (DNS_R_CNAME);
04529 }
04530 return (ISC_R_SUCCESS);
04531 case DNS_R_NXRRSET:
04532 *policyp = DNS_RPZ_POLICY_NODATA;
04533 return (result);
04534 case DNS_R_DNAME:
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544
04545 case DNS_R_NXDOMAIN:
04546 case DNS_R_EMPTYNAME:
04547 return (DNS_R_NXDOMAIN);
04548 default:
04549 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type,
04550 "", result);
04551 CTRACE(ISC_LOG_ERROR,
04552 "rpz_find_p: unexpected result");
04553 return (DNS_R_SERVFAIL);
04554 }
04555 }
04556
04557 static void
04558 rpz_save_p(dns_rpz_st_t *st, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
04559 dns_rpz_policy_t policy, dns_name_t *p_name, dns_rpz_prefix_t prefix,
04560 isc_result_t result, dns_zone_t **zonep, dns_db_t **dbp,
04561 dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
04562 dns_dbversion_t *version)
04563 {
04564 dns_rdataset_t *trdataset;
04565
04566 rpz_match_clear(st);
04567 st->m.rpz = rpz;
04568 st->m.type = rpz_type;
04569 st->m.policy = policy;
04570 dns_name_copy(p_name, st->p_name, NULL);
04571 st->m.prefix = prefix;
04572 st->m.result = result;
04573 st->m.zone = *zonep;
04574 *zonep = NULL;
04575 st->m.db = *dbp;
04576 *dbp = NULL;
04577 st->m.node = *nodep;
04578 *nodep = NULL;
04579 if (*rdatasetp != NULL && dns_rdataset_isassociated(*rdatasetp)) {
04580
04581
04582
04583
04584 trdataset = st->m.rdataset;
04585 st->m.rdataset = *rdatasetp;
04586 *rdatasetp = trdataset;
04587 st->m.ttl = ISC_MIN(st->m.rdataset->ttl, rpz->max_policy_ttl);
04588 } else {
04589 st->m.ttl = ISC_MIN(DNS_RPZ_TTL_DEFAULT, rpz->max_policy_ttl);
04590 }
04591 st->m.version = version;
04592 }
04593
04594
04595
04596
04597 static isc_result_t
04598 rpz_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr,
04599 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
04600 dns_rpz_zbits_t zbits, dns_rdataset_t **p_rdatasetp)
04601 {
04602 dns_rpz_zones_t *rpzs;
04603 dns_rpz_st_t *st;
04604 dns_rpz_zone_t *rpz;
04605 dns_rpz_prefix_t prefix;
04606 dns_rpz_num_t rpz_num;
04607 dns_fixedname_t ip_namef, p_namef;
04608 dns_name_t *ip_name, *p_name;
04609 dns_zone_t *p_zone;
04610 dns_db_t *p_db;
04611 dns_dbversion_t *p_version;
04612 dns_dbnode_t *p_node;
04613 dns_rpz_policy_t policy;
04614 isc_result_t result;
04615
04616 dns_fixedname_init(&ip_namef);
04617 ip_name = dns_fixedname_name(&ip_namef);
04618
04619 p_zone = NULL;
04620 p_db = NULL;
04621 p_node = NULL;
04622
04623 rpzs = client->view->rpzs;
04624 st = client->query.rpz_st;
04625 while (zbits != 0) {
04626 rpz_num = dns_rpz_find_ip(rpzs, rpz_type, zbits, netaddr,
04627 ip_name, &prefix);
04628 if (rpz_num == DNS_RPZ_INVALID_NUM)
04629 break;
04630 zbits &= (DNS_RPZ_ZMASK(rpz_num) >> 1);
04631
04632
04633
04634
04635
04636
04637
04638 rpz = rpzs->zones[rpz_num];
04639 if (st->m.policy != DNS_RPZ_POLICY_MISS) {
04640 if (st->m.rpz->num < rpz->num)
04641 break;
04642 if (st->m.rpz->num == rpz->num &&
04643 (st->m.type < rpz_type ||
04644 st->m.prefix > prefix))
04645 break;
04646 }
04647
04648
04649
04650
04651
04652 dns_fixedname_init(&p_namef);
04653 p_name = dns_fixedname_name(&p_namef);
04654 result = rpz_get_p_name(client, p_name, rpz, rpz_type, ip_name);
04655 if (result != ISC_R_SUCCESS)
04656 continue;
04657 result = rpz_find_p(client, ip_name, qtype,
04658 p_name, rpz, rpz_type,
04659 &p_zone, &p_db, &p_version, &p_node,
04660 p_rdatasetp, &policy);
04661 switch (result) {
04662 case DNS_R_NXDOMAIN:
04663
04664
04665
04666
04667
04668
04669 continue;
04670 case DNS_R_SERVFAIL:
04671 rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp);
04672 st->m.policy = DNS_RPZ_POLICY_ERROR;
04673 return (DNS_R_SERVFAIL);
04674 default:
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693 if (st->m.policy != DNS_RPZ_POLICY_MISS &&
04694 rpz->num == st->m.rpz->num &&
04695 (st->m.type == rpz_type &&
04696 st->m.prefix == prefix &&
04697 0 > dns_name_rdatacompare(st->p_name, p_name)))
04698 break;
04699
04700
04701
04702
04703
04704
04705 if (rpz->policy != DNS_RPZ_POLICY_DISABLED) {
04706 rpz_save_p(st, rpz, rpz_type,
04707 policy, p_name, prefix, result,
04708 &p_zone, &p_db, &p_node,
04709 p_rdatasetp, p_version);
04710 break;
04711 }
04712
04713
04714
04715
04716
04717 rpz_log_rewrite(client, ISC_TRUE, policy, rpz_type,
04718 p_zone, p_name, NULL);
04719 }
04720 }
04721
04722 rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp);
04723 return (ISC_R_SUCCESS);
04724 }
04725
04726
04727
04728
04729
04730 static isc_result_t
04731 rpz_rewrite_ip_rrset(ns_client_t *client,
04732 dns_name_t *name, dns_rdatatype_t qtype,
04733 dns_rpz_type_t rpz_type, dns_rdatatype_t ip_type,
04734 dns_db_t **ip_dbp, dns_dbversion_t *ip_version,
04735 dns_rdataset_t **ip_rdatasetp,
04736 dns_rdataset_t **p_rdatasetp, isc_boolean_t resuming)
04737 {
04738 dns_rpz_zbits_t zbits;
04739 isc_netaddr_t netaddr;
04740 struct in_addr ina;
04741 struct in6_addr in6a;
04742 isc_result_t result;
04743
04744 zbits = rpz_get_zbits(client, ip_type, rpz_type);
04745 if (zbits == 0)
04746 return (ISC_R_SUCCESS);
04747
04748
04749
04750
04751 result = rpz_rrset_find(client, name, ip_type, rpz_type, ip_dbp,
04752 ip_version, ip_rdatasetp, resuming);
04753 switch (result) {
04754 case ISC_R_SUCCESS:
04755 case DNS_R_GLUE:
04756 case DNS_R_ZONECUT:
04757 break;
04758 case DNS_R_EMPTYNAME:
04759 case DNS_R_EMPTYWILD:
04760 case DNS_R_NXDOMAIN:
04761 case DNS_R_NCACHENXDOMAIN:
04762 case DNS_R_NXRRSET:
04763 case DNS_R_NCACHENXRRSET:
04764 case ISC_R_NOTFOUND:
04765 return (ISC_R_SUCCESS);
04766 case DNS_R_DELEGATION:
04767 case DNS_R_DUPLICATE:
04768 case DNS_R_DROP:
04769 return (result);
04770 case DNS_R_CNAME:
04771 case DNS_R_DNAME:
04772 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, name, rpz_type,
04773 " NS address rewrite rrset", result);
04774 return (ISC_R_SUCCESS);
04775 default:
04776 if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) {
04777 client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR;
04778 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
04779 rpz_type, " NS address rewrite rrset",
04780 result);
04781 }
04782 CTRACE(ISC_LOG_ERROR,
04783 "rpz_rewrite_ip_rrset: unexpected result");
04784 return (DNS_R_SERVFAIL);
04785 }
04786
04787
04788
04789
04790 for (result = dns_rdataset_first(*ip_rdatasetp);
04791 result == ISC_R_SUCCESS;
04792 result = dns_rdataset_next(*ip_rdatasetp)) {
04793
04794 dns_rdata_t rdata = DNS_RDATA_INIT;
04795 dns_rdataset_current(*ip_rdatasetp, &rdata);
04796 switch (rdata.type) {
04797 case dns_rdatatype_a:
04798 INSIST(rdata.length == 4);
04799 memmove(&ina.s_addr, rdata.data, 4);
04800 isc_netaddr_fromin(&netaddr, &ina);
04801 break;
04802 case dns_rdatatype_aaaa:
04803 INSIST(rdata.length == 16);
04804 memmove(in6a.s6_addr, rdata.data, 16);
04805 isc_netaddr_fromin6(&netaddr, &in6a);
04806 break;
04807 default:
04808 continue;
04809 }
04810
04811 result = rpz_rewrite_ip(client, &netaddr, qtype, rpz_type,
04812 zbits, p_rdatasetp);
04813 if (result != ISC_R_SUCCESS)
04814 return (result);
04815 }
04816
04817 return (ISC_R_SUCCESS);
04818 }
04819
04820
04821
04822
04823
04824 static isc_result_t
04825 rpz_rewrite_ip_rrsets(ns_client_t *client, dns_name_t *name,
04826 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
04827 dns_rdataset_t **ip_rdatasetp, isc_boolean_t resuming)
04828 {
04829 dns_rpz_st_t *st;
04830 dns_dbversion_t *ip_version;
04831 dns_db_t *ip_db;
04832 dns_rdataset_t *p_rdataset;
04833 isc_result_t result;
04834
04835 st = client->query.rpz_st;
04836 ip_version = NULL;
04837 ip_db = NULL;
04838 p_rdataset = NULL;
04839 if ((st->state & DNS_RPZ_DONE_IPv4) == 0 &&
04840 (qtype == dns_rdatatype_a ||
04841 qtype == dns_rdatatype_any ||
04842 rpz_type == DNS_RPZ_TYPE_NSIP)) {
04843
04844
04845
04846
04847 result = rpz_rewrite_ip_rrset(client, name, qtype,
04848 rpz_type, dns_rdatatype_a,
04849 &ip_db, ip_version, ip_rdatasetp,
04850 &p_rdataset, resuming);
04851 if (result == ISC_R_SUCCESS)
04852 st->state |= DNS_RPZ_DONE_IPv4;
04853 } else {
04854 result = ISC_R_SUCCESS;
04855 }
04856 if (result == ISC_R_SUCCESS &&
04857 (qtype == dns_rdatatype_aaaa ||
04858 qtype == dns_rdatatype_any ||
04859 rpz_type == DNS_RPZ_TYPE_NSIP)) {
04860
04861
04862
04863
04864 result = rpz_rewrite_ip_rrset(client, name, qtype,
04865 rpz_type, dns_rdatatype_aaaa,
04866 &ip_db, ip_version, ip_rdatasetp,
04867 &p_rdataset, resuming);
04868 }
04869 if (ip_db != NULL)
04870 dns_db_detach(&ip_db);
04871 query_putrdataset(client, &p_rdataset);
04872 return (result);
04873 }
04874
04875
04876
04877
04878
04879
04880
04881
04882 static isc_result_t
04883 rpz_rewrite_name(ns_client_t *client, dns_name_t *trig_name,
04884 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
04885 dns_rpz_zbits_t allowed_zbits, dns_rdataset_t **rdatasetp)
04886 {
04887 dns_rpz_zone_t *rpz;
04888 dns_rpz_st_t *st;
04889 dns_fixedname_t p_namef;
04890 dns_name_t *p_name;
04891 dns_rpz_zbits_t zbits;
04892 dns_rpz_num_t rpz_num;
04893 dns_zone_t *p_zone;
04894 dns_db_t *p_db;
04895 dns_dbversion_t *p_version;
04896 dns_dbnode_t *p_node;
04897 dns_rpz_policy_t policy;
04898 isc_result_t result;
04899
04900 zbits = rpz_get_zbits(client, qtype, rpz_type);
04901 zbits &= allowed_zbits;
04902 if (zbits == 0)
04903 return (ISC_R_SUCCESS);
04904
04905
04906
04907
04908
04909
04910
04911 if (zbits != (zbits & (~zbits + 1))) {
04912 zbits = dns_rpz_find_name(client->view->rpzs,
04913 rpz_type, zbits, trig_name);
04914 if (zbits == 0)
04915 return (ISC_R_SUCCESS);
04916 }
04917
04918 dns_fixedname_init(&p_namef);
04919 p_name = dns_fixedname_name(&p_namef);
04920
04921 p_zone = NULL;
04922 p_db = NULL;
04923 p_node = NULL;
04924
04925 st = client->query.rpz_st;
04926
04927
04928
04929
04930
04931
04932
04933
04934
04935 for (rpz_num = 0;
04936 zbits != 0;
04937 ++rpz_num, zbits >>= 1) {
04938 if ((zbits & 1) == 0) {
04939 INSIST(rpz_num <= client->view->rpzs->p.num_zones);
04940 continue;
04941 }
04942
04943
04944
04945
04946
04947 rpz = client->view->rpzs->zones[rpz_num];
04948 if (st->m.policy != DNS_RPZ_POLICY_MISS) {
04949 if (st->m.rpz->num < rpz->num)
04950 break;
04951 if (st->m.rpz->num == rpz->num &&
04952 st->m.type < rpz_type)
04953 break;
04954 }
04955
04956
04957
04958
04959 result = rpz_get_p_name(client, p_name, rpz, rpz_type,
04960 trig_name);
04961 if (result != ISC_R_SUCCESS)
04962 continue;
04963 result = rpz_find_p(client, trig_name, qtype, p_name,
04964 rpz, rpz_type,
04965 &p_zone, &p_db, &p_version, &p_node,
04966 rdatasetp, &policy);
04967 switch (result) {
04968 case DNS_R_NXDOMAIN:
04969
04970
04971
04972
04973
04974
04975 continue;
04976 case DNS_R_SERVFAIL:
04977 rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
04978 st->m.policy = DNS_RPZ_POLICY_ERROR;
04979 return (DNS_R_SERVFAIL);
04980 default:
04981
04982
04983
04984
04985
04986
04987
04988
04989 if (st->m.policy != DNS_RPZ_POLICY_MISS &&
04990 rpz->num == st->m.rpz->num &&
04991 (st->m.type < rpz_type ||
04992 (st->m.type == rpz_type &&
04993 0 >= dns_name_compare(p_name, st->p_name))))
04994 continue;
04995 #if 0
04996
04997
04998
04999
05000
05001
05002
05003
05004
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015
05016 unsigned int labels;
05017 labels = dns_name_countlabels(trig_name);
05018 if (labels >= 2) {
05019 dns_label_t label;
05020
05021 dns_name_getlabel(trig_name, labels-2, &label);
05022 if (label.length >= sizeof(DNS_RPZ_PREFIX)-1 &&
05023 strncasecmp((const char *)label.base+1,
05024 DNS_RPZ_PREFIX,
05025 sizeof(DNS_RPZ_PREFIX)-1) == 0)
05026 continue;
05027 }
05028 #endif
05029 if (rpz->policy != DNS_RPZ_POLICY_DISABLED) {
05030 rpz_save_p(st, rpz, rpz_type,
05031 policy, p_name, 0, result,
05032 &p_zone, &p_db, &p_node,
05033 rdatasetp, p_version);
05034
05035
05036
05037
05038 rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
05039 return (ISC_R_SUCCESS);
05040 }
05041
05042
05043
05044
05045 rpz_log_rewrite(client, ISC_TRUE, policy, rpz_type,
05046 p_zone, p_name, NULL);
05047 break;
05048 }
05049 }
05050
05051 rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
05052 return (ISC_R_SUCCESS);
05053 }
05054
05055 static void
05056 rpz_rewrite_ns_skip(ns_client_t *client, dns_name_t *nsname,
05057 isc_result_t result, int level, const char *str)
05058 {
05059 dns_rpz_st_t *st;
05060
05061 st = client->query.rpz_st;
05062
05063 if (str != NULL)
05064 rpz_log_fail(client, level, nsname, DNS_RPZ_TYPE_NSIP,
05065 str, result);
05066 if (st->r.ns_rdataset != NULL &&
05067 dns_rdataset_isassociated(st->r.ns_rdataset))
05068 dns_rdataset_disassociate(st->r.ns_rdataset);
05069
05070 st->r.label--;
05071 }
05072
05073
05074
05075
05076 static isc_result_t
05077 rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult,
05078 isc_boolean_t resuming)
05079 {
05080 dns_rpz_st_t *st;
05081 dns_rdataset_t *rdataset;
05082 dns_fixedname_t nsnamef;
05083 dns_name_t *nsname;
05084 int qresult_type;
05085 dns_rpz_zbits_t zbits;
05086 isc_result_t result = ISC_R_SUCCESS;
05087
05088 st = client->query.rpz_st;
05089 if (st == NULL) {
05090 st = isc_mem_get(client->mctx, sizeof(*st));
05091 if (st == NULL)
05092 return (ISC_R_NOMEMORY);
05093 st->state = 0;
05094 memset(&st->m, 0, sizeof(st->m));
05095 st->m.type = DNS_RPZ_TYPE_BAD;
05096 st->m.policy = DNS_RPZ_POLICY_MISS;
05097 st->m.ttl = ~0;
05098 memset(&st->r, 0, sizeof(st->r));
05099 memset(&st->q, 0, sizeof(st->q));
05100 dns_fixedname_init(&st->_p_namef);
05101 dns_fixedname_init(&st->_r_namef);
05102 dns_fixedname_init(&st->_fnamef);
05103 st->p_name = dns_fixedname_name(&st->_p_namef);
05104 st->r_name = dns_fixedname_name(&st->_r_namef);
05105 st->fname = dns_fixedname_name(&st->_fnamef);
05106 client->query.rpz_st = st;
05107 }
05108
05109
05110
05111
05112 switch (qresult) {
05113 case ISC_R_SUCCESS:
05114 case DNS_R_GLUE:
05115 case DNS_R_ZONECUT:
05116 qresult_type = 0;
05117 break;
05118 case DNS_R_EMPTYNAME:
05119 case DNS_R_NXRRSET:
05120 case DNS_R_NXDOMAIN:
05121 case DNS_R_EMPTYWILD:
05122 case DNS_R_NCACHENXDOMAIN:
05123 case DNS_R_NCACHENXRRSET:
05124 case DNS_R_CNAME:
05125 case DNS_R_DNAME:
05126 qresult_type = 1;
05127 break;
05128 case DNS_R_DELEGATION:
05129 case ISC_R_NOTFOUND:
05130
05131
05132
05133
05134
05135 if (RECURSIONOK(client))
05136 qresult_type = 2;
05137 else
05138 qresult_type = 1;
05139 break;
05140 case ISC_R_FAILURE:
05141 case ISC_R_TIMEDOUT:
05142 case DNS_R_BROKENCHAIN:
05143 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, client->query.qname,
05144 DNS_RPZ_TYPE_QNAME,
05145 " stop on qresult in rpz_rewrite()", qresult);
05146 return (ISC_R_SUCCESS);
05147 default:
05148 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, client->query.qname,
05149 DNS_RPZ_TYPE_QNAME,
05150 " stop on unrecognized qresult in rpz_rewrite()",
05151 qresult);
05152 return (ISC_R_SUCCESS);
05153 }
05154
05155 rdataset = NULL;
05156
05157 if ((st->state & (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) !=
05158 (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) {
05159 isc_netaddr_t netaddr;
05160 dns_rpz_zbits_t allowed;
05161
05162 if (qresult_type == 2) {
05163
05164
05165
05166
05167
05168 allowed = client->view->rpzs->have.qname_skip_recurse;
05169 if (allowed == 0)
05170 return (ISC_R_SUCCESS);
05171 } else {
05172 allowed = DNS_RPZ_ALL_ZBITS;
05173 }
05174
05175
05176
05177
05178 if ((st->state & DNS_RPZ_DONE_CLIENT_IP) == 0) {
05179 zbits = rpz_get_zbits(client, dns_rdatatype_none,
05180 DNS_RPZ_TYPE_CLIENT_IP);
05181 zbits &= allowed;
05182 if (zbits != 0) {
05183 isc_netaddr_fromsockaddr(&netaddr,
05184 &client->peeraddr);
05185 result = rpz_rewrite_ip(client, &netaddr, qtype,
05186 DNS_RPZ_TYPE_CLIENT_IP,
05187 zbits, &rdataset);
05188 if (result != ISC_R_SUCCESS)
05189 goto cleanup;
05190 }
05191 }
05192
05193
05194
05195
05196
05197
05198 if ((st->state & DNS_RPZ_DONE_QNAME) == 0) {
05199 result = rpz_rewrite_name(client, client->query.qname,
05200 qtype, DNS_RPZ_TYPE_QNAME,
05201 allowed, &rdataset);
05202 if (result != ISC_R_SUCCESS)
05203 goto cleanup;
05204
05205
05206
05207
05208
05209 st->r.label = dns_name_countlabels(client->query.qname);
05210 st->state &= ~(DNS_RPZ_DONE_QNAME_IP |
05211 DNS_RPZ_DONE_IPv4);
05212
05213 }
05214
05215
05216
05217
05218
05219
05220
05221
05222
05223
05224
05225
05226
05227 if (qresult_type == 2)
05228 goto cleanup;
05229
05230
05231
05232
05233
05234 st->state |= (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME);
05235 }
05236
05237
05238
05239
05240
05241
05242
05243
05244 if ((st->state & DNS_RPZ_DONE_QNAME_IP) == 0 && qresult_type == 0 &&
05245 rpz_get_zbits(client, qtype, DNS_RPZ_TYPE_IP) != 0) {
05246 result = rpz_rewrite_ip_rrsets(client,
05247 client->query.qname, qtype,
05248 DNS_RPZ_TYPE_IP,
05249 &rdataset, resuming);
05250 if (result != ISC_R_SUCCESS)
05251 goto cleanup;
05252
05253
05254
05255
05256 st->state |= DNS_RPZ_DONE_QNAME_IP;
05257 st->state &= ~DNS_RPZ_DONE_IPv4;
05258 }
05259
05260
05261
05262
05263
05264 if (rpz_get_zbits(client, dns_rdatatype_any,
05265 DNS_RPZ_TYPE_NSDNAME) == 0 &&
05266 rpz_get_zbits(client, dns_rdatatype_any,
05267 DNS_RPZ_TYPE_NSIP) == 0) {
05268 result = ISC_R_SUCCESS;
05269 goto cleanup;
05270 }
05271
05272 dns_fixedname_init(&nsnamef);
05273 dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef));
05274 while (st->r.label > client->view->rpzs->p.min_ns_labels) {
05275
05276
05277
05278 if (st->r.label == dns_name_countlabels(client->query.qname)) {
05279 nsname = client->query.qname;
05280 } else {
05281 nsname = dns_fixedname_name(&nsnamef);
05282 dns_name_split(client->query.qname, st->r.label,
05283 NULL, nsname);
05284 }
05285 if (st->r.ns_rdataset == NULL ||
05286 !dns_rdataset_isassociated(st->r.ns_rdataset)) {
05287 dns_db_t *db = NULL;
05288 result = rpz_rrset_find(client, nsname,
05289 dns_rdatatype_ns,
05290 DNS_RPZ_TYPE_NSDNAME,
05291 &db, NULL, &st->r.ns_rdataset,
05292 resuming);
05293 if (db != NULL)
05294 dns_db_detach(&db);
05295 if (st->m.policy == DNS_RPZ_POLICY_ERROR)
05296 goto cleanup;
05297 switch (result) {
05298 case ISC_R_SUCCESS:
05299 result = dns_rdataset_first(st->r.ns_rdataset);
05300 if (result != ISC_R_SUCCESS)
05301 goto cleanup;
05302 st->state &= ~(DNS_RPZ_DONE_NSDNAME |
05303 DNS_RPZ_DONE_IPv4);
05304 break;
05305 case DNS_R_DELEGATION:
05306 case DNS_R_DUPLICATE:
05307 case DNS_R_DROP:
05308 goto cleanup;
05309 case DNS_R_EMPTYNAME:
05310 case DNS_R_NXRRSET:
05311 case DNS_R_EMPTYWILD:
05312 case DNS_R_NXDOMAIN:
05313 case DNS_R_NCACHENXDOMAIN:
05314 case DNS_R_NCACHENXRRSET:
05315 case ISC_R_NOTFOUND:
05316 case DNS_R_CNAME:
05317 case DNS_R_DNAME:
05318 rpz_rewrite_ns_skip(client, nsname, result,
05319 0, NULL);
05320 continue;
05321 case ISC_R_TIMEDOUT:
05322 case DNS_R_BROKENCHAIN:
05323 case ISC_R_FAILURE:
05324 rpz_rewrite_ns_skip(client, nsname, result,
05325 DNS_RPZ_DEBUG_LEVEL3,
05326 " NS rpz_rrset_find() ");
05327 continue;
05328 default:
05329 rpz_rewrite_ns_skip(client, nsname, result,
05330 DNS_RPZ_INFO_LEVEL,
05331 " unrecognized NS"
05332 " rpz_rrset_find() ");
05333 continue;
05334 }
05335 }
05336
05337
05338
05339 do {
05340 dns_rdata_ns_t ns;
05341 dns_rdata_t nsrdata = DNS_RDATA_INIT;
05342
05343 dns_rdataset_current(st->r.ns_rdataset, &nsrdata);
05344 result = dns_rdata_tostruct(&nsrdata, &ns, NULL);
05345 dns_rdata_reset(&nsrdata);
05346 if (result != ISC_R_SUCCESS) {
05347 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
05348 nsname, DNS_RPZ_TYPE_NSIP,
05349 " rdata_tostruct()", result);
05350 st->m.policy = DNS_RPZ_POLICY_ERROR;
05351 goto cleanup;
05352 }
05353
05354
05355
05356 if (dns_name_equal(&ns.name, dns_rootname)) {
05357 dns_rdata_freestruct(&ns);
05358 result = dns_rdataset_next(st->r.ns_rdataset);
05359 continue;
05360 }
05361
05362
05363
05364
05365 if ((st->state & DNS_RPZ_DONE_NSDNAME) == 0) {
05366 result = rpz_rewrite_name(client, &ns.name,
05367 qtype,
05368 DNS_RPZ_TYPE_NSDNAME,
05369 DNS_RPZ_ALL_ZBITS,
05370 &rdataset);
05371 if (result != ISC_R_SUCCESS) {
05372 dns_rdata_freestruct(&ns);
05373 goto cleanup;
05374 }
05375 st->state |= DNS_RPZ_DONE_NSDNAME;
05376 }
05377
05378
05379
05380 result = rpz_rewrite_ip_rrsets(client, &ns.name, qtype,
05381 DNS_RPZ_TYPE_NSIP,
05382 &rdataset, resuming);
05383 dns_rdata_freestruct(&ns);
05384 if (result != ISC_R_SUCCESS)
05385 goto cleanup;
05386 st->state &= ~(DNS_RPZ_DONE_NSDNAME |
05387 DNS_RPZ_DONE_IPv4);
05388 result = dns_rdataset_next(st->r.ns_rdataset);
05389 } while (result == ISC_R_SUCCESS);
05390 dns_rdataset_disassociate(st->r.ns_rdataset);
05391 st->r.label--;
05392
05393 if (rpz_get_zbits(client, dns_rdatatype_any,
05394 DNS_RPZ_TYPE_NSDNAME) == 0 &&
05395 rpz_get_zbits(client, dns_rdatatype_any,
05396 DNS_RPZ_TYPE_NSIP) == 0)
05397 break;
05398 }
05399
05400
05401
05402
05403 result = ISC_R_SUCCESS;
05404
05405 cleanup:
05406 if (st->m.policy != DNS_RPZ_POLICY_MISS &&
05407 st->m.policy != DNS_RPZ_POLICY_ERROR &&
05408 st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN)
05409 st->m.policy = st->m.rpz->policy;
05410 if (st->m.policy == DNS_RPZ_POLICY_MISS ||
05411 st->m.policy == DNS_RPZ_POLICY_PASSTHRU ||
05412 st->m.policy == DNS_RPZ_POLICY_ERROR) {
05413 if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU &&
05414 result != DNS_R_DELEGATION)
05415 rpz_log_rewrite(client, ISC_FALSE, st->m.policy,
05416 st->m.type, st->m.zone, st->p_name,
05417 NULL);
05418 rpz_match_clear(st);
05419 }
05420 if (st->m.policy == DNS_RPZ_POLICY_ERROR) {
05421 CTRACE(ISC_LOG_ERROR, "SERVFAIL due to RPZ policy");
05422 st->m.type = DNS_RPZ_TYPE_BAD;
05423 result = DNS_R_SERVFAIL;
05424 }
05425 query_putrdataset(client, &rdataset);
05426 if ((st->state & DNS_RPZ_RECURSING) == 0)
05427 rpz_clean(NULL, &st->r.db, NULL, &st->r.ns_rdataset);
05428
05429 return (result);
05430 }
05431
05432
05433
05434
05435
05436 static isc_boolean_t
05437 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult,
05438 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
05439 {
05440 dns_fixedname_t fixed;
05441 dns_name_t *found;
05442 dns_rdataset_t trdataset;
05443 dns_rdatatype_t type;
05444 isc_result_t result;
05445
05446 if (client->view->rpzs->p.break_dnssec || !WANTDNSSEC(client))
05447 return (ISC_TRUE);
05448
05449
05450
05451
05452
05453 if (qresult == DNS_R_DELEGATION || qresult == ISC_R_NOTFOUND)
05454 return (ISC_FALSE);
05455
05456 if (sigrdataset == NULL)
05457 return (ISC_TRUE);
05458 if (dns_rdataset_isassociated(sigrdataset))
05459 return (ISC_FALSE);
05460
05461
05462
05463
05464 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset))
05465 return (ISC_TRUE);
05466
05467
05468
05469 if (rdataset->type == dns_rdatatype_nsec ||
05470 rdataset->type == dns_rdatatype_nsec3 ||
05471 rdataset->type == dns_rdatatype_rrsig)
05472 return (ISC_FALSE);
05473
05474
05475
05476
05477 if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0)
05478 return (ISC_TRUE);
05479 dns_fixedname_init(&fixed);
05480 found = dns_fixedname_name(&fixed);
05481 dns_rdataset_init(&trdataset);
05482 for (result = dns_rdataset_first(rdataset);
05483 result == ISC_R_SUCCESS;
05484 result = dns_rdataset_next(rdataset)) {
05485 dns_ncache_current(rdataset, found, &trdataset);
05486 type = trdataset.type;
05487 dns_rdataset_disassociate(&trdataset);
05488 if (type == dns_rdatatype_nsec ||
05489 type == dns_rdatatype_nsec3 ||
05490 type == dns_rdatatype_rrsig)
05491 return (ISC_FALSE);
05492 }
05493 return (ISC_TRUE);
05494 }
05495
05496
05497
05498
05499
05500
05501
05502 static isc_result_t
05503 rpz_add_cname(ns_client_t *client, dns_rpz_st_t *st,
05504 dns_name_t *cname, dns_name_t *fname, isc_buffer_t *dbuf)
05505 {
05506 dns_fixedname_t prefix, suffix;
05507 unsigned int labels;
05508 isc_result_t result;
05509
05510 labels = dns_name_countlabels(cname);
05511 if (labels > 2 && dns_name_iswildcard(cname)) {
05512 dns_fixedname_init(&prefix);
05513 dns_name_split(client->query.qname, 1,
05514 dns_fixedname_name(&prefix), NULL);
05515 dns_fixedname_init(&suffix);
05516 dns_name_split(cname, labels-1,
05517 NULL, dns_fixedname_name(&suffix));
05518 result = dns_name_concatenate(dns_fixedname_name(&prefix),
05519 dns_fixedname_name(&suffix),
05520 fname, NULL);
05521 if (result == DNS_R_NAMETOOLONG)
05522 client->message->rcode = dns_rcode_yxdomain;
05523 } else {
05524 result = dns_name_copy(cname, fname, NULL);
05525 RUNTIME_CHECK(result == ISC_R_SUCCESS);
05526 }
05527 if (result != ISC_R_SUCCESS)
05528 return (result);
05529 query_keepname(client, fname, dbuf);
05530 result = query_add_cname(client, client->query.qname,
05531 fname, dns_trust_authanswer, st->m.ttl);
05532 if (result != ISC_R_SUCCESS)
05533 return (result);
05534 rpz_log_rewrite(client, ISC_FALSE, st->m.policy,
05535 st->m.type, st->m.zone, st->p_name, fname);
05536 ns_client_qnamereplace(client, fname);
05537
05538
05539
05540
05541 client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
05542 NS_CLIENTATTR_WANTAD);
05543 return (ISC_R_SUCCESS);
05544 }
05545
05546 #define MAX_RESTARTS 16
05547
05548 #define QUERY_ERROR(r) \
05549 do { \
05550 eresult = r; \
05551 want_restart = ISC_FALSE; \
05552 line = __LINE__; \
05553 } while (0)
05554
05555 #define RECURSE_ERROR(r) \
05556 do { \
05557 if ((r) == DNS_R_DUPLICATE || (r) == DNS_R_DROP) \
05558 QUERY_ERROR(r); \
05559 else \
05560 QUERY_ERROR(DNS_R_SERVFAIL); \
05561 } while (0)
05562
05563
05564
05565
05566
05567
05568
05569
05570
05571 static isc_result_t
05572 rdata_tonetaddr(const dns_rdata_t *rdata, isc_netaddr_t *netaddr) {
05573 struct in_addr ina;
05574 struct in6_addr in6a;
05575
05576 switch (rdata->type) {
05577 case dns_rdatatype_a:
05578 INSIST(rdata->length == 4);
05579 memmove(&ina.s_addr, rdata->data, 4);
05580 isc_netaddr_fromin(netaddr, &ina);
05581 return (ISC_R_SUCCESS);
05582 case dns_rdatatype_aaaa:
05583 INSIST(rdata->length == 16);
05584 memmove(in6a.s6_addr, rdata->data, 16);
05585 isc_netaddr_fromin6(netaddr, &in6a);
05586 return (ISC_R_SUCCESS);
05587 default:
05588 return (ISC_R_NOTIMPLEMENTED);
05589 }
05590 }
05591
05592
05593
05594
05595
05596
05597 static int
05598 query_sortlist_order_2element(const dns_rdata_t *rdata, const void *arg) {
05599 isc_netaddr_t netaddr;
05600
05601 if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS)
05602 return (INT_MAX);
05603 return (ns_sortlist_addrorder2(&netaddr, arg));
05604 }
05605
05606
05607
05608
05609
05610 static int
05611 query_sortlist_order_1element(const dns_rdata_t *rdata, const void *arg) {
05612 isc_netaddr_t netaddr;
05613
05614 if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS)
05615 return (INT_MAX);
05616 return (ns_sortlist_addrorder1(&netaddr, arg));
05617 }
05618
05619
05620
05621
05622
05623 static void
05624 setup_query_sortlist(ns_client_t *client) {
05625 isc_netaddr_t netaddr;
05626 dns_rdatasetorderfunc_t order = NULL;
05627 const void *order_arg = NULL;
05628
05629 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
05630 switch (ns_sortlist_setup(client->view->sortlist,
05631 &netaddr, &order_arg)) {
05632 case NS_SORTLISTTYPE_1ELEMENT:
05633 order = query_sortlist_order_1element;
05634 break;
05635 case NS_SORTLISTTYPE_2ELEMENT:
05636 order = query_sortlist_order_2element;
05637 break;
05638 case NS_SORTLISTTYPE_NONE:
05639 order = NULL;
05640 break;
05641 default:
05642 INSIST(0);
05643 break;
05644 }
05645 dns_message_setsortorder(client->message, order, order_arg);
05646 }
05647
05648 static void
05649 query_addnoqnameproof(ns_client_t *client, dns_rdataset_t *rdataset) {
05650 isc_buffer_t *dbuf, b;
05651 dns_name_t *fname;
05652 dns_rdataset_t *neg, *negsig;
05653 isc_result_t result = ISC_R_NOMEMORY;
05654
05655 CTRACE(ISC_LOG_DEBUG(3), "query_addnoqnameproof");
05656
05657 fname = NULL;
05658 neg = NULL;
05659 negsig = NULL;
05660
05661 dbuf = query_getnamebuf(client);
05662 if (dbuf == NULL)
05663 goto cleanup;
05664 fname = query_newname(client, dbuf, &b);
05665 neg = query_newrdataset(client);
05666 negsig = query_newrdataset(client);
05667 if (fname == NULL || neg == NULL || negsig == NULL)
05668 goto cleanup;
05669
05670 result = dns_rdataset_getnoqname(rdataset, fname, neg, negsig);
05671 RUNTIME_CHECK(result == ISC_R_SUCCESS);
05672
05673 query_addrrset(client, &fname, &neg, &negsig, dbuf,
05674 DNS_SECTION_AUTHORITY);
05675
05676 if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) == 0)
05677 goto cleanup;
05678
05679 if (fname == NULL) {
05680 dbuf = query_getnamebuf(client);
05681 if (dbuf == NULL)
05682 goto cleanup;
05683 fname = query_newname(client, dbuf, &b);
05684 }
05685 if (neg == NULL)
05686 neg = query_newrdataset(client);
05687 else if (dns_rdataset_isassociated(neg))
05688 dns_rdataset_disassociate(neg);
05689 if (negsig == NULL)
05690 negsig = query_newrdataset(client);
05691 else if (dns_rdataset_isassociated(negsig))
05692 dns_rdataset_disassociate(negsig);
05693 if (fname == NULL || neg == NULL || negsig == NULL)
05694 goto cleanup;
05695 result = dns_rdataset_getclosest(rdataset, fname, neg, negsig);
05696 RUNTIME_CHECK(result == ISC_R_SUCCESS);
05697
05698 query_addrrset(client, &fname, &neg, &negsig, dbuf,
05699 DNS_SECTION_AUTHORITY);
05700
05701 cleanup:
05702 if (neg != NULL)
05703 query_putrdataset(client, &neg);
05704 if (negsig != NULL)
05705 query_putrdataset(client, &negsig);
05706 if (fname != NULL)
05707 query_releasename(client, &fname);
05708 }
05709
05710 static inline void
05711 answer_in_glue(ns_client_t *client, dns_rdatatype_t qtype) {
05712 dns_name_t *name;
05713 dns_message_t *msg;
05714 dns_section_t section = DNS_SECTION_ADDITIONAL;
05715 dns_rdataset_t *rdataset = NULL;
05716
05717 msg = client->message;
05718 for (name = ISC_LIST_HEAD(msg->sections[section]);
05719 name != NULL;
05720 name = ISC_LIST_NEXT(name, link))
05721 if (dns_name_equal(name, client->query.qname)) {
05722 for (rdataset = ISC_LIST_HEAD(name->list);
05723 rdataset != NULL;
05724 rdataset = ISC_LIST_NEXT(rdataset, link))
05725 if (rdataset->type == qtype)
05726 break;
05727 break;
05728 }
05729 if (rdataset != NULL) {
05730 ISC_LIST_UNLINK(msg->sections[section], name, link);
05731 ISC_LIST_PREPEND(msg->sections[section], name, link);
05732 ISC_LIST_UNLINK(name->list, rdataset, link);
05733 ISC_LIST_PREPEND(name->list, rdataset, link);
05734 rdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
05735 }
05736 }
05737
05738 #define NS_NAME_INIT(A,B) \
05739 { \
05740 DNS_NAME_MAGIC, \
05741 A, sizeof(A), sizeof(B), \
05742 DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, \
05743 B, NULL, { (void *)-1, (void *)-1}, \
05744 {NULL, NULL} \
05745 }
05746
05747 static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 };
05748 static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 };
05749 static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 };
05750
05751 static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA";
05752
05753 static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA";
05754 static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA";
05755 static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA";
05756 static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA";
05757 static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA";
05758 static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA";
05759 static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA";
05760 static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA";
05761 static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA";
05762 static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA";
05763 static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA";
05764 static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA";
05765 static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA";
05766 static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA";
05767 static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA";
05768 static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA";
05769
05770 static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA";
05771
05772 static dns_name_t rfc1918names[] = {
05773 NS_NAME_INIT(inaddr10, inaddr10_offsets),
05774 NS_NAME_INIT(inaddr16172, inaddr172_offsets),
05775 NS_NAME_INIT(inaddr17172, inaddr172_offsets),
05776 NS_NAME_INIT(inaddr18172, inaddr172_offsets),
05777 NS_NAME_INIT(inaddr19172, inaddr172_offsets),
05778 NS_NAME_INIT(inaddr20172, inaddr172_offsets),
05779 NS_NAME_INIT(inaddr21172, inaddr172_offsets),
05780 NS_NAME_INIT(inaddr22172, inaddr172_offsets),
05781 NS_NAME_INIT(inaddr23172, inaddr172_offsets),
05782 NS_NAME_INIT(inaddr24172, inaddr172_offsets),
05783 NS_NAME_INIT(inaddr25172, inaddr172_offsets),
05784 NS_NAME_INIT(inaddr26172, inaddr172_offsets),
05785 NS_NAME_INIT(inaddr27172, inaddr172_offsets),
05786 NS_NAME_INIT(inaddr28172, inaddr172_offsets),
05787 NS_NAME_INIT(inaddr29172, inaddr172_offsets),
05788 NS_NAME_INIT(inaddr30172, inaddr172_offsets),
05789 NS_NAME_INIT(inaddr31172, inaddr172_offsets),
05790 NS_NAME_INIT(inaddr168192, inaddr192_offsets)
05791 };
05792
05793
05794 static unsigned char prisoner_data[] = "\010prisoner\004iana\003org";
05795 static unsigned char hostmaster_data[] = "\012hostmaster\014root-servers\003org";
05796
05797 static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 };
05798 static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 };
05799
05800 static dns_name_t prisoner = NS_NAME_INIT(prisoner_data, prisoner_offsets);
05801 static dns_name_t hostmaster = NS_NAME_INIT(hostmaster_data, hostmaster_offsets);
05802
05803 static void
05804 warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) {
05805 unsigned int i;
05806 dns_rdata_t rdata = DNS_RDATA_INIT;
05807 dns_rdata_soa_t soa;
05808 dns_rdataset_t found;
05809 isc_result_t result;
05810
05811 for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++) {
05812 if (dns_name_issubdomain(fname, &rfc1918names[i])) {
05813 dns_rdataset_init(&found);
05814 result = dns_ncache_getrdataset(rdataset,
05815 &rfc1918names[i],
05816 dns_rdatatype_soa,
05817 &found);
05818 if (result != ISC_R_SUCCESS)
05819 return;
05820
05821 result = dns_rdataset_first(&found);
05822 RUNTIME_CHECK(result == ISC_R_SUCCESS);
05823 dns_rdataset_current(&found, &rdata);
05824 result = dns_rdata_tostruct(&rdata, &soa, NULL);
05825 RUNTIME_CHECK(result == ISC_R_SUCCESS);
05826 if (dns_name_equal(&soa.origin, &prisoner) &&
05827 dns_name_equal(&soa.contact, &hostmaster)) {
05828 char buf[DNS_NAME_FORMATSIZE];
05829 dns_name_format(fname, buf, sizeof(buf));
05830 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
05831 NS_LOGMODULE_QUERY,
05832 ISC_LOG_WARNING,
05833 "RFC 1918 response from "
05834 "Internet for %s", buf);
05835 }
05836 dns_rdataset_disassociate(&found);
05837 return;
05838 }
05839 }
05840 }
05841
05842 static void
05843 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
05844 dns_dbversion_t *version, ns_client_t *client,
05845 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
05846 dns_name_t *fname, isc_boolean_t exact,
05847 dns_name_t *found)
05848 {
05849 unsigned char salt[256];
05850 size_t salt_length;
05851 isc_uint16_t iterations;
05852 isc_result_t result;
05853 unsigned int dboptions;
05854 dns_fixedname_t fixed;
05855 dns_hash_t hash;
05856 dns_name_t name;
05857 unsigned int skip = 0, labels;
05858 dns_rdata_nsec3_t nsec3;
05859 dns_rdata_t rdata = DNS_RDATA_INIT;
05860 isc_boolean_t optout;
05861 dns_clientinfomethods_t cm;
05862 dns_clientinfo_t ci;
05863
05864 salt_length = sizeof(salt);
05865 result = dns_db_getnsec3parameters(db, version, &hash, NULL,
05866 &iterations, salt, &salt_length);
05867 if (result != ISC_R_SUCCESS)
05868 return;
05869
05870 dns_name_init(&name, NULL);
05871 dns_name_clone(qname, &name);
05872 labels = dns_name_countlabels(&name);
05873 dns_clientinfomethods_init(&cm, ns_client_sourceip);
05874 dns_clientinfo_init(&ci, client, NULL);
05875
05876
05877
05878
05879 if (hash == DNS_NSEC3_UNKNOWNALG)
05880 hash = 1;
05881
05882 again:
05883 dns_fixedname_init(&fixed);
05884 result = dns_nsec3_hashname(&fixed, NULL, NULL, &name,
05885 dns_db_origin(db), hash,
05886 iterations, salt, salt_length);
05887 if (result != ISC_R_SUCCESS)
05888 return;
05889
05890 dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3;
05891 result = dns_db_findext(db, dns_fixedname_name(&fixed), version,
05892 dns_rdatatype_nsec3, dboptions, client->now,
05893 NULL, fname, &cm, &ci, rdataset, sigrdataset);
05894
05895 if (result == DNS_R_NXDOMAIN) {
05896 if (!dns_rdataset_isassociated(rdataset)) {
05897 return;
05898 }
05899 result = dns_rdataset_first(rdataset);
05900 INSIST(result == ISC_R_SUCCESS);
05901 dns_rdataset_current(rdataset, &rdata);
05902 dns_rdata_tostruct(&rdata, &nsec3, NULL);
05903 dns_rdata_reset(&rdata);
05904 optout = ISC_TF((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0);
05905 if (found != NULL && optout &&
05906 dns_name_issubdomain(&name, dns_db_origin(db)))
05907 {
05908 dns_rdataset_disassociate(rdataset);
05909 if (dns_rdataset_isassociated(sigrdataset))
05910 dns_rdataset_disassociate(sigrdataset);
05911 skip++;
05912 dns_name_getlabelsequence(qname, skip, labels - skip,
05913 &name);
05914 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
05915 NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(3),
05916 "looking for closest provable encloser");
05917 goto again;
05918 }
05919 if (exact)
05920 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
05921 NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
05922 "expected a exact match NSEC3, got "
05923 "a covering record");
05924
05925 } else if (result != ISC_R_SUCCESS) {
05926 return;
05927 } else if (!exact)
05928 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
05929 NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
05930 "expected covering NSEC3, got an exact match");
05931 if (found == qname) {
05932 if (skip != 0U)
05933 dns_name_getlabelsequence(qname, skip, labels - skip,
05934 found);
05935 } else if (found != NULL)
05936 dns_name_copy(&name, found, NULL);
05937 return;
05938 }
05939
05940 #ifdef ALLOW_FILTER_AAAA
05941 static isc_boolean_t
05942 is_v4_client(ns_client_t *client) {
05943 if (isc_sockaddr_pf(&client->peeraddr) == AF_INET)
05944 return (ISC_TRUE);
05945 if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 &&
05946 IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr))
05947 return (ISC_TRUE);
05948 return (ISC_FALSE);
05949 }
05950
05951 static isc_boolean_t
05952 is_v6_client(ns_client_t *client) {
05953 if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 &&
05954 !IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr))
05955 return (ISC_TRUE);
05956 return (ISC_FALSE);
05957 }
05958 #endif
05959
05960 static isc_uint32_t
05961 dns64_ttl(dns_db_t *db, dns_dbversion_t *version) {
05962 dns_dbnode_t *node = NULL;
05963 dns_rdata_soa_t soa;
05964 dns_rdata_t rdata = DNS_RDATA_INIT;
05965 dns_rdataset_t rdataset;
05966 isc_result_t result;
05967 isc_uint32_t ttl = ISC_UINT32_MAX;
05968
05969 dns_rdataset_init(&rdataset);
05970
05971 result = dns_db_getoriginnode(db, &node);
05972 if (result != ISC_R_SUCCESS)
05973 goto cleanup;
05974
05975 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
05976 0, 0, &rdataset, NULL);
05977 if (result != ISC_R_SUCCESS)
05978 goto cleanup;
05979 result = dns_rdataset_first(&rdataset);
05980 if (result != ISC_R_SUCCESS)
05981 goto cleanup;
05982
05983 dns_rdataset_current(&rdataset, &rdata);
05984 result = dns_rdata_tostruct(&rdata, &soa, NULL);
05985 RUNTIME_CHECK(result == ISC_R_SUCCESS);
05986 ttl = ISC_MIN(rdataset.ttl, soa.minimum);
05987
05988 cleanup:
05989 if (dns_rdataset_isassociated(&rdataset))
05990 dns_rdataset_disassociate(&rdataset);
05991 if (node != NULL)
05992 dns_db_detachnode(db, &node);
05993 return (ttl);
05994 }
05995
05996 static isc_boolean_t
05997 dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
05998 dns_rdataset_t *sigrdataset)
05999 {
06000 isc_netaddr_t netaddr;
06001 dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64);
06002 unsigned int flags = 0;
06003 unsigned int i, count;
06004 isc_boolean_t *aaaaok;
06005
06006 INSIST(client->query.dns64_aaaaok == NULL);
06007 INSIST(client->query.dns64_aaaaoklen == 0);
06008 INSIST(client->query.dns64_aaaa == NULL);
06009 INSIST(client->query.dns64_sigaaaa == NULL);
06010
06011 if (dns64 == NULL)
06012 return (ISC_TRUE);
06013
06014 if (RECURSIONOK(client))
06015 flags |= DNS_DNS64_RECURSIVE;
06016
06017 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
06018 flags |= DNS_DNS64_DNSSEC;
06019
06020 count = dns_rdataset_count(rdataset);
06021 aaaaok = isc_mem_get(client->mctx, sizeof(isc_boolean_t) * count);
06022
06023 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
06024 if (dns_dns64_aaaaok(dns64, &netaddr, client->signer,
06025 &ns_g_server->aclenv, flags, rdataset,
06026 aaaaok, count)) {
06027 for (i = 0; i < count; i++) {
06028 if (aaaaok != NULL && !aaaaok[i]) {
06029 client->query.dns64_aaaaok = aaaaok;
06030 client->query.dns64_aaaaoklen = count;
06031 break;
06032 }
06033 }
06034 if (i == count && aaaaok != NULL)
06035 isc_mem_put(client->mctx, aaaaok,
06036 sizeof(isc_boolean_t) * count);
06037 return (ISC_TRUE);
06038 }
06039 if (aaaaok != NULL)
06040 isc_mem_put(client->mctx, aaaaok,
06041 sizeof(isc_boolean_t) * count);
06042 return (ISC_FALSE);
06043 }
06044
06045
06046
06047
06048
06049
06050
06051
06052
06053 static isc_result_t
06054 redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
06055 dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
06056 dns_rdatatype_t qtype)
06057 {
06058 dns_db_t *db = NULL;
06059 dns_dbnode_t *node = NULL;
06060 dns_fixedname_t fixed;
06061 dns_name_t *found;
06062 dns_rdataset_t trdataset;
06063 isc_result_t result;
06064 dns_rdatatype_t type;
06065 dns_clientinfomethods_t cm;
06066 dns_clientinfo_t ci;
06067 ns_dbversion_t *dbversion;
06068
06069 CTRACE(ISC_LOG_DEBUG(3), "redirect");
06070
06071 if (client->view->redirect == NULL)
06072 return (ISC_R_NOTFOUND);
06073
06074 dns_fixedname_init(&fixed);
06075 found = dns_fixedname_name(&fixed);
06076 dns_rdataset_init(&trdataset);
06077
06078 dns_clientinfomethods_init(&cm, ns_client_sourceip);
06079 dns_clientinfo_init(&ci, client, NULL);
06080
06081 if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
06082 return (ISC_R_NOTFOUND);
06083
06084 if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
06085 if (rdataset->trust == dns_trust_secure)
06086 return (ISC_R_NOTFOUND);
06087 if (rdataset->trust == dns_trust_ultimate &&
06088 (rdataset->type == dns_rdatatype_nsec ||
06089 rdataset->type == dns_rdatatype_nsec3))
06090 return (ISC_R_NOTFOUND);
06091 if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
06092 for (result = dns_rdataset_first(rdataset);
06093 result == ISC_R_SUCCESS;
06094 result = dns_rdataset_next(rdataset)) {
06095 dns_ncache_current(rdataset, found, &trdataset);
06096 type = trdataset.type;
06097 dns_rdataset_disassociate(&trdataset);
06098 if (type == dns_rdatatype_nsec ||
06099 type == dns_rdatatype_nsec3 ||
06100 type == dns_rdatatype_rrsig)
06101 return (ISC_R_NOTFOUND);
06102 }
06103 }
06104 }
06105
06106 result = ns_client_checkaclsilent(client, NULL,
06107 dns_zone_getqueryacl(client->view->redirect),
06108 ISC_TRUE);
06109 if (result != ISC_R_SUCCESS)
06110 return (ISC_R_NOTFOUND);
06111
06112 result = dns_zone_getdb(client->view->redirect, &db);
06113 if (result != ISC_R_SUCCESS)
06114 return (ISC_R_NOTFOUND);
06115
06116 dbversion = query_findversion(client, db);
06117 if (dbversion == NULL) {
06118 dns_db_detach(&db);
06119 return (ISC_R_NOTFOUND);
06120 }
06121
06122
06123
06124
06125 result = dns_db_findext(db, client->query.qname, dbversion->version,
06126 qtype, DNS_DBFIND_NOZONECUT, client->now,
06127 &node, found, &cm, &ci, &trdataset, NULL);
06128 if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
06129 if (dns_rdataset_isassociated(rdataset))
06130 dns_rdataset_disassociate(rdataset);
06131 if (dns_rdataset_isassociated(&trdataset))
06132 dns_rdataset_disassociate(&trdataset);
06133 goto nxrrset;
06134 } else if (result != ISC_R_SUCCESS) {
06135 if (dns_rdataset_isassociated(&trdataset))
06136 dns_rdataset_disassociate(&trdataset);
06137 if (node != NULL)
06138 dns_db_detachnode(db, &node);
06139 dns_db_detach(&db);
06140 return (ISC_R_NOTFOUND);
06141 }
06142
06143 CTRACE(ISC_LOG_DEBUG(3), "redirect: found data: done");
06144 dns_name_copy(found, name, NULL);
06145 if (dns_rdataset_isassociated(rdataset))
06146 dns_rdataset_disassociate(rdataset);
06147 if (dns_rdataset_isassociated(&trdataset)) {
06148 dns_rdataset_clone(&trdataset, rdataset);
06149 dns_rdataset_disassociate(&trdataset);
06150 }
06151 nxrrset:
06152 if (*nodep != NULL)
06153 dns_db_detachnode(*dbp, nodep);
06154 dns_db_detach(dbp);
06155 dns_db_attachnode(db, node, nodep);
06156 dns_db_attach(db, dbp);
06157 dns_db_detachnode(db, &node);
06158 dns_db_detach(&db);
06159 *versionp = dbversion->version;
06160
06161 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
06162 NS_QUERYATTR_NOADDITIONAL);
06163
06164 return (result);
06165 }
06166
06167 static isc_result_t
06168 redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
06169 dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
06170 dns_rdatatype_t qtype)
06171 {
06172 dns_db_t *db = NULL;
06173 dns_dbnode_t *node = NULL;
06174 dns_fixedname_t fixed;
06175 dns_fixedname_t fixedredirect;
06176 dns_name_t *found, *redirectname;
06177 dns_rdataset_t trdataset;
06178 isc_result_t result;
06179 dns_rdatatype_t type;
06180 dns_clientinfomethods_t cm;
06181 dns_clientinfo_t ci;
06182 dns_dbversion_t *version = NULL;
06183 dns_zone_t *zone = NULL;
06184 unsigned int options;
06185 isc_boolean_t is_zonep = ISC_FALSE;
06186
06187 CTRACE(ISC_LOG_DEBUG(3), "redirect2");
06188
06189 if (client->view->redirectzone == NULL)
06190 return (ISC_R_NOTFOUND);
06191
06192 if (dns_name_issubdomain(name, client->view->redirectzone))
06193 return (ISC_R_NOTFOUND);
06194
06195 dns_fixedname_init(&fixed);
06196 found = dns_fixedname_name(&fixed);
06197 dns_rdataset_init(&trdataset);
06198
06199 dns_clientinfomethods_init(&cm, ns_client_sourceip);
06200 dns_clientinfo_init(&ci, client, NULL);
06201
06202 if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
06203 return (ISC_R_NOTFOUND);
06204
06205 if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
06206 if (rdataset->trust == dns_trust_secure)
06207 return (ISC_R_NOTFOUND);
06208 if (rdataset->trust == dns_trust_ultimate &&
06209 (rdataset->type == dns_rdatatype_nsec ||
06210 rdataset->type == dns_rdatatype_nsec3))
06211 return (ISC_R_NOTFOUND);
06212 if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
06213 for (result = dns_rdataset_first(rdataset);
06214 result == ISC_R_SUCCESS;
06215 result = dns_rdataset_next(rdataset)) {
06216 dns_ncache_current(rdataset, found, &trdataset);
06217 type = trdataset.type;
06218 dns_rdataset_disassociate(&trdataset);
06219 if (type == dns_rdatatype_nsec ||
06220 type == dns_rdatatype_nsec3 ||
06221 type == dns_rdatatype_rrsig)
06222 return (ISC_R_NOTFOUND);
06223 }
06224 }
06225 }
06226
06227 dns_fixedname_init(&fixedredirect);
06228 redirectname = dns_fixedname_name(&fixedredirect);
06229 if (dns_name_countlabels(name) > 1U) {
06230 dns_name_t prefix;
06231 unsigned int labels = dns_name_countlabels(name) - 1;
06232
06233 dns_name_init(&prefix, NULL);
06234 dns_name_getlabelsequence(name, 0, labels, &prefix);
06235 result = dns_name_concatenate(&prefix,
06236 client->view->redirectzone,
06237 redirectname, NULL);
06238 if (result != ISC_R_SUCCESS)
06239 return (ISC_R_NOTFOUND);
06240 } else
06241 dns_name_copy(redirectname, client->view->redirectzone, NULL);
06242
06243 options = 0;
06244 result = query_getdb(client, redirectname, qtype, options, &zone,
06245 &db, &version, &is_zonep);
06246 if (result != ISC_R_SUCCESS)
06247 return (ISC_R_NOTFOUND);
06248
06249
06250
06251
06252 result = dns_db_findext(db, redirectname, version,
06253 qtype, 0, client->now,
06254 &node, found, &cm, &ci, &trdataset, NULL);
06255 if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
06256 if (dns_rdataset_isassociated(rdataset))
06257 dns_rdataset_disassociate(rdataset);
06258 if (dns_rdataset_isassociated(&trdataset))
06259 dns_rdataset_disassociate(&trdataset);
06260 goto nxrrset;
06261 } else if (result == ISC_R_NOTFOUND || result == DNS_R_DELEGATION) {
06262
06263
06264
06265 if (dns_rdataset_isassociated(&trdataset))
06266 dns_rdataset_disassociate(&trdataset);
06267 if (node != NULL)
06268 dns_db_detachnode(db, &node);
06269 dns_db_detach(&db);
06270
06271
06272
06273 if (!REDIRECT(client)) {
06274 result = query_recurse(client, qtype, redirectname,
06275 NULL, NULL, ISC_TRUE);
06276 if (result == ISC_R_SUCCESS) {
06277 client->query.attributes |=
06278 NS_QUERYATTR_RECURSING;
06279 client->query.attributes |=
06280 NS_QUERYATTR_REDIRECT;
06281 return (DNS_R_CONTINUE);
06282 }
06283 }
06284 return (ISC_R_NOTFOUND);
06285 } else if (result != ISC_R_SUCCESS) {
06286 if (dns_rdataset_isassociated(&trdataset))
06287 dns_rdataset_disassociate(&trdataset);
06288 if (node != NULL)
06289 dns_db_detachnode(db, &node);
06290 dns_db_detach(&db);
06291 return (ISC_R_NOTFOUND);
06292 }
06293
06294 CTRACE(ISC_LOG_DEBUG(3), "redirect2: found data: done");
06295
06296
06297
06298 dns_name_split(found, dns_name_countlabels(client->view->redirectzone),
06299 found, NULL);
06300
06301
06302
06303 result = dns_name_concatenate(found, dns_rootname, found, NULL);
06304 RUNTIME_CHECK(result == ISC_R_SUCCESS);
06305
06306 dns_name_copy(found, name, NULL);
06307 if (dns_rdataset_isassociated(rdataset))
06308 dns_rdataset_disassociate(rdataset);
06309 if (dns_rdataset_isassociated(&trdataset)) {
06310 dns_rdataset_clone(&trdataset, rdataset);
06311 dns_rdataset_disassociate(&trdataset);
06312 }
06313 nxrrset:
06314 if (*nodep != NULL)
06315 dns_db_detachnode(*dbp, nodep);
06316 dns_db_detach(dbp);
06317 dns_db_attachnode(db, node, nodep);
06318 dns_db_attach(db, dbp);
06319 dns_db_detachnode(db, &node);
06320 dns_db_detach(&db);
06321 *versionp = version;
06322
06323 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
06324 NS_QUERYATTR_NOADDITIONAL);
06325
06326 return (result);
06327 }
06328
06329
06330
06331
06332
06333
06334 static isc_result_t
06335 query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
06336 {
06337 dns_db_t *db, *zdb;
06338 dns_dbnode_t *node;
06339 dns_rdatatype_t type = qtype;
06340 dns_name_t *fname, *zfname, *tname, *prefix;
06341 dns_rdataset_t *rdataset, *trdataset;
06342 dns_rdataset_t *sigrdataset, *zrdataset, *zsigrdataset;
06343 dns_rdataset_t **sigrdatasetp;
06344 dns_rdata_t rdata = DNS_RDATA_INIT;
06345 dns_rdatasetiter_t *rdsiter;
06346 isc_boolean_t want_restart, is_zone, need_wildcardproof;
06347 isc_boolean_t is_staticstub_zone;
06348 isc_boolean_t authoritative = ISC_FALSE;
06349 unsigned int n, nlabels;
06350 dns_namereln_t namereln;
06351 int order;
06352 isc_buffer_t *dbuf;
06353 isc_buffer_t b;
06354 isc_result_t result, eresult, tresult;
06355 dns_fixedname_t fixed;
06356 dns_fixedname_t wildcardname;
06357 dns_dbversion_t *version, *zversion;
06358 dns_zone_t *zone;
06359 dns_rdata_cname_t cname;
06360 dns_rdata_dname_t dname;
06361 unsigned int options;
06362 isc_boolean_t empty_wild;
06363 dns_rdataset_t *noqname;
06364 dns_rpz_st_t *rpz_st;
06365 isc_boolean_t resuming;
06366 int line = -1;
06367 isc_boolean_t dns64_exclude, dns64;
06368 isc_boolean_t nxrewrite = ISC_FALSE;
06369 isc_boolean_t redirected = ISC_FALSE;
06370 dns_clientinfomethods_t cm;
06371 dns_clientinfo_t ci;
06372 char errmsg[256];
06373 isc_boolean_t associated;
06374 dns_section_t section;
06375 dns_ttl_t ttl;
06376 isc_boolean_t failcache;
06377 isc_uint32_t flags;
06378
06379 CTRACE(ISC_LOG_DEBUG(3), "query_find");
06380
06381
06382
06383
06384
06385
06386
06387
06388 eresult = ISC_R_SUCCESS;
06389 fname = NULL;
06390 zfname = NULL;
06391 rdataset = NULL;
06392 zrdataset = NULL;
06393 sigrdataset = NULL;
06394 zsigrdataset = NULL;
06395 zversion = NULL;
06396 node = NULL;
06397 db = NULL;
06398 zdb = NULL;
06399 version = NULL;
06400 zone = NULL;
06401 need_wildcardproof = ISC_FALSE;
06402 empty_wild = ISC_FALSE;
06403 dns64_exclude = dns64 = ISC_FALSE;
06404 options = 0;
06405 resuming = ISC_FALSE;
06406 is_zone = ISC_FALSE;
06407 is_staticstub_zone = ISC_FALSE;
06408
06409 dns_clientinfomethods_init(&cm, ns_client_sourceip);
06410 dns_clientinfo_init(&ci, client, NULL);
06411
06412 if (event != NULL) {
06413
06414
06415
06416
06417 want_restart = ISC_FALSE;
06418
06419 rpz_st = client->query.rpz_st;
06420 if (rpz_st != NULL &&
06421 (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
06422 is_zone = rpz_st->q.is_zone;
06423 authoritative = rpz_st->q.authoritative;
06424 zone = rpz_st->q.zone;
06425 rpz_st->q.zone = NULL;
06426 node = rpz_st->q.node;
06427 rpz_st->q.node = NULL;
06428 db = rpz_st->q.db;
06429 rpz_st->q.db = NULL;
06430 rdataset = rpz_st->q.rdataset;
06431 rpz_st->q.rdataset = NULL;
06432 sigrdataset = rpz_st->q.sigrdataset;
06433 rpz_st->q.sigrdataset = NULL;
06434 qtype = rpz_st->q.qtype;
06435
06436 rpz_st->r.db = event->db;
06437 if (event->node != NULL)
06438 dns_db_detachnode(event->db, &event->node);
06439 rpz_st->r.r_type = event->qtype;
06440 rpz_st->r.r_rdataset = event->rdataset;
06441 query_putrdataset(client, &event->sigrdataset);
06442 } else if (REDIRECT(client)) {
06443
06444
06445
06446
06447 qtype = client->query.redirect.qtype;
06448 rdataset = client->query.redirect.rdataset;
06449 client->query.redirect.rdataset = NULL;
06450 sigrdataset = client->query.redirect.sigrdataset;
06451 client->query.redirect.sigrdataset = NULL;
06452 db = client->query.redirect.db;
06453 client->query.redirect.db = NULL;
06454 node = client->query.redirect.node;
06455 client->query.redirect.node = NULL;
06456 zone = client->query.redirect.zone;
06457 client->query.redirect.zone = NULL;
06458 authoritative = client->query.redirect.authoritative;
06459
06460
06461
06462
06463 query_putrdataset(client, &event->rdataset);
06464 query_putrdataset(client, &event->sigrdataset);
06465 if (event->node != NULL)
06466 dns_db_detachnode(event->db, &event->node);
06467 if (event->db != NULL)
06468 dns_db_detach(&event->db);
06469 } else {
06470 authoritative = ISC_FALSE;
06471
06472 qtype = event->qtype;
06473 db = event->db;
06474 node = event->node;
06475 rdataset = event->rdataset;
06476 sigrdataset = event->sigrdataset;
06477 }
06478
06479 if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig)
06480 type = dns_rdatatype_any;
06481 else
06482 type = qtype;
06483
06484 if (DNS64(client)) {
06485 client->query.attributes &= ~NS_QUERYATTR_DNS64;
06486 dns64 = ISC_TRUE;
06487 }
06488 if (DNS64EXCLUDE(client)) {
06489 client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE;
06490 dns64_exclude = ISC_TRUE;
06491 }
06492
06493
06494
06495
06496 dbuf = query_getnamebuf(client);
06497 if (dbuf == NULL) {
06498 CTRACE(ISC_LOG_ERROR,
06499 "query_find: query_getnamebuf failed (1)");
06500 QUERY_ERROR(DNS_R_SERVFAIL);
06501 goto cleanup;
06502 }
06503 fname = query_newname(client, dbuf, &b);
06504 if (fname == NULL) {
06505 CTRACE(ISC_LOG_ERROR,
06506 "query_find: query_newname failed (1)");
06507 QUERY_ERROR(DNS_R_SERVFAIL);
06508 goto cleanup;
06509 }
06510 if (rpz_st != NULL &&
06511 (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
06512 tname = rpz_st->fname;
06513 } else if (REDIRECT(client)) {
06514 tname = client->query.redirect.fname;
06515 } else {
06516 tname = dns_fixedname_name(&event->foundname);
06517 }
06518 result = dns_name_copy(tname, fname, NULL);
06519 if (result != ISC_R_SUCCESS) {
06520 CTRACE(ISC_LOG_ERROR,
06521 "query_find: dns_name_copy failed");
06522 QUERY_ERROR(DNS_R_SERVFAIL);
06523 goto cleanup;
06524 }
06525 if (rpz_st != NULL &&
06526 (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
06527 rpz_st->r.r_result = event->result;
06528 result = rpz_st->q.result;
06529 isc_event_free(ISC_EVENT_PTR(&event));
06530 } else if (REDIRECT(client)) {
06531 result = client->query.redirect.result;
06532 } else {
06533 result = event->result;
06534 }
06535 resuming = ISC_TRUE;
06536 goto resume;
06537 }
06538
06539
06540
06541
06542
06543
06544
06545
06546
06547 if (RECURSIONOK(client)) {
06548 flags = 0;
06549 failcache = dns_badcache_find(client->view->failcache,
06550 client->query.qname, qtype,
06551 &flags, &client->tnow);
06552 if (failcache &&
06553 (((flags & NS_FAILCACHE_CD) != 0) ||
06554 ((client->message->flags & DNS_MESSAGEFLAG_CD) == 0)))
06555 {
06556 if (isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(1))) {
06557 char namebuf[DNS_NAME_FORMATSIZE];
06558 char typename[DNS_RDATATYPE_FORMATSIZE];
06559
06560 dns_name_format(client->query.qname,
06561 namebuf, sizeof(namebuf));
06562 dns_rdatatype_format(qtype, typename,
06563 sizeof(typename));
06564 ns_client_log(client, NS_LOGCATEGORY_CLIENT,
06565 NS_LOGMODULE_QUERY,
06566 ISC_LOG_DEBUG(1),
06567 "servfail cache hit %s/%s (%s)",
06568 namebuf, typename,
06569 ((flags & NS_FAILCACHE_CD) != 0)
06570 ? "CD=1"
06571 : "CD=0");
06572 }
06573 client->attributes |= NS_CLIENTATTR_NOSETFC;
06574 QUERY_ERROR(DNS_R_SERVFAIL);
06575 goto cleanup;
06576 }
06577 }
06578
06579
06580
06581
06582 if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig)
06583 type = dns_rdatatype_any;
06584 else
06585 type = qtype;
06586
06587 restart:
06588 CTRACE(ISC_LOG_DEBUG(3), "query_find: restart");
06589 want_restart = ISC_FALSE;
06590 authoritative = ISC_FALSE;
06591 version = NULL;
06592 need_wildcardproof = ISC_FALSE;
06593
06594 if (client->view->checknames &&
06595 !dns_rdata_checkowner(client->query.qname,
06596 client->message->rdclass,
06597 qtype, ISC_FALSE)) {
06598 char namebuf[DNS_NAME_FORMATSIZE];
06599 char typename[DNS_RDATATYPE_FORMATSIZE];
06600 char classname[DNS_RDATACLASS_FORMATSIZE];
06601
06602 dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
06603 dns_rdatatype_format(qtype, typename, sizeof(typename));
06604 dns_rdataclass_format(client->message->rdclass, classname,
06605 sizeof(classname));
06606 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
06607 NS_LOGMODULE_QUERY, ISC_LOG_ERROR,
06608 "check-names failure %s/%s/%s", namebuf,
06609 typename, classname);
06610 QUERY_ERROR(DNS_R_REFUSED);
06611 goto cleanup;
06612 }
06613
06614
06615
06616
06617 options &= DNS_GETDB_NOLOG;
06618 if (dns_rdatatype_atparent(qtype) &&
06619 !dns_name_equal(client->query.qname, dns_rootname))
06620 options |= DNS_GETDB_NOEXACT;
06621 result = query_getdb(client, client->query.qname, qtype, options,
06622 &zone, &db, &version, &is_zone);
06623 if ((result != ISC_R_SUCCESS || !is_zone) && !RECURSIONOK(client) &&
06624 (options & DNS_GETDB_NOEXACT) != 0 && qtype == dns_rdatatype_ds) {
06625
06626
06627
06628
06629 dns_db_t *tdb = NULL;
06630 dns_zone_t *tzone = NULL;
06631 dns_dbversion_t *tversion = NULL;
06632
06633 tresult = query_getzonedb(client, client->query.qname, qtype,
06634 DNS_GETDB_PARTIAL, &tzone, &tdb,
06635 &tversion);
06636 if (tresult == ISC_R_SUCCESS) {
06637 options &= ~DNS_GETDB_NOEXACT;
06638 query_putrdataset(client, &rdataset);
06639 if (db != NULL)
06640 dns_db_detach(&db);
06641 if (zone != NULL)
06642 dns_zone_detach(&zone);
06643 version = tversion;
06644 db = tdb;
06645 zone = tzone;
06646 is_zone = ISC_TRUE;
06647 result = ISC_R_SUCCESS;
06648 } else {
06649 if (tdb != NULL)
06650 dns_db_detach(&tdb);
06651 if (tzone != NULL)
06652 dns_zone_detach(&tzone);
06653 }
06654 }
06655 if (result != ISC_R_SUCCESS) {
06656 if (result == DNS_R_REFUSED) {
06657 if (WANTRECURSION(client)) {
06658 inc_stats(client,
06659 dns_nsstatscounter_recurserej);
06660 } else
06661 inc_stats(client, dns_nsstatscounter_authrej);
06662 if (!PARTIALANSWER(client))
06663 QUERY_ERROR(DNS_R_REFUSED);
06664 } else {
06665 CTRACE(ISC_LOG_ERROR,
06666 "query_find: query_getdb failed");
06667 QUERY_ERROR(DNS_R_SERVFAIL);
06668 }
06669 goto cleanup;
06670 }
06671
06672 is_staticstub_zone = ISC_FALSE;
06673 if (is_zone) {
06674 authoritative = ISC_TRUE;
06675 if (zone != NULL &&
06676 dns_zone_gettype(zone) == dns_zone_staticstub)
06677 is_staticstub_zone = ISC_TRUE;
06678 }
06679
06680 if (event == NULL && client->query.restarts == 0) {
06681 if (is_zone) {
06682 if (zone != NULL) {
06683
06684
06685
06686
06687 dns_zone_attach(zone, &client->query.authzone);
06688 }
06689 dns_db_attach(db, &client->query.authdb);
06690 }
06691 client->query.authdbset = ISC_TRUE;
06692
06693
06694 if ((client->attributes & NS_CLIENTATTR_TCP) != 0)
06695 inc_stats(client, dns_nsstatscounter_tcp);
06696 else
06697 inc_stats(client, dns_nsstatscounter_udp);
06698 }
06699
06700 db_find:
06701 CTRACE(ISC_LOG_DEBUG(3), "query_find: db_find");
06702
06703
06704
06705 dbuf = query_getnamebuf(client);
06706 if (dbuf == NULL) {
06707 CTRACE(ISC_LOG_ERROR,
06708 "query_find: query_getnamebuf failed (2)");
06709 QUERY_ERROR(DNS_R_SERVFAIL);
06710 goto cleanup;
06711 }
06712 fname = query_newname(client, dbuf, &b);
06713 rdataset = query_newrdataset(client);
06714 if (fname == NULL || rdataset == NULL) {
06715 CTRACE(ISC_LOG_ERROR,
06716 "query_find: query_newname failed (2)");
06717 QUERY_ERROR(DNS_R_SERVFAIL);
06718 goto cleanup;
06719 }
06720 if (WANTDNSSEC(client) && (!is_zone || dns_db_issecure(db))) {
06721 sigrdataset = query_newrdataset(client);
06722 if (sigrdataset == NULL) {
06723 CTRACE(ISC_LOG_ERROR,
06724 "query_find: query_newrdataset failed (2)");
06725 QUERY_ERROR(DNS_R_SERVFAIL);
06726 goto cleanup;
06727 }
06728 }
06729
06730
06731
06732
06733 result = dns_db_findext(db, client->query.qname, version, type,
06734 client->query.dboptions, client->now,
06735 &node, fname, &cm, &ci, rdataset, sigrdataset);
06736
06737 if (db == client->view->cachedb)
06738 dns_cache_updatestats(client->view->cache, result);
06739
06740 resume:
06741 CTRACE(ISC_LOG_DEBUG(3), "query_find: resume");
06742
06743
06744
06745
06746
06747
06748
06749
06750
06751
06752
06753 if (client->view->rrl != NULL && !HAVESIT(client) &&
06754 ((fname != NULL && dns_name_isabsolute(fname)) ||
06755 (result == ISC_R_NOTFOUND && !RECURSIONOK(client))) &&
06756 !(result == DNS_R_DELEGATION && !is_zone && RECURSIONOK(client)) &&
06757 (client->query.rpz_st == NULL ||
06758 (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0)&&
06759 (client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0) {
06760 dns_rdataset_t nc_rdataset;
06761 isc_boolean_t wouldlog;
06762 char log_buf[DNS_RRL_LOG_BUF_LEN];
06763 isc_result_t nc_result, resp_result;
06764 dns_rrl_result_t rrl_result;
06765
06766 client->query.attributes |= NS_QUERYATTR_RRL_CHECKED;
06767
06768 wouldlog = isc_log_wouldlog(ns_g_lctx, DNS_RRL_LOG_DROP);
06769 tname = fname;
06770 if (result == DNS_R_NXDOMAIN) {
06771
06772
06773
06774 if (db != NULL)
06775 tname = dns_db_origin(db);
06776 resp_result = result;
06777 } else if (result == DNS_R_NCACHENXDOMAIN &&
06778 rdataset != NULL &&
06779 dns_rdataset_isassociated(rdataset) &&
06780 (rdataset->attributes &
06781 DNS_RDATASETATTR_NEGATIVE) != 0) {
06782
06783
06784
06785 dns_fixedname_init(&fixed);
06786 dns_rdataset_init(&nc_rdataset);
06787 for (nc_result = dns_rdataset_first(rdataset);
06788 nc_result == ISC_R_SUCCESS;
06789 nc_result = dns_rdataset_next(rdataset)) {
06790 dns_ncache_current(rdataset,
06791 dns_fixedname_name(&fixed),
06792 &nc_rdataset);
06793 if (nc_rdataset.type == dns_rdatatype_soa) {
06794 dns_rdataset_disassociate(&nc_rdataset);
06795 tname = dns_fixedname_name(&fixed);
06796 break;
06797 }
06798 dns_rdataset_disassociate(&nc_rdataset);
06799 }
06800 resp_result = DNS_R_NXDOMAIN;
06801 } else if (result == DNS_R_NXRRSET ||
06802 result == DNS_R_EMPTYNAME) {
06803 resp_result = DNS_R_NXRRSET;
06804 } else if (result == DNS_R_DELEGATION) {
06805 resp_result = result;
06806 } else if (result == ISC_R_NOTFOUND) {
06807
06808
06809
06810
06811
06812 tname = dns_rootname;
06813 resp_result = DNS_R_DELEGATION;
06814 } else {
06815 resp_result = ISC_R_SUCCESS;
06816 }
06817 rrl_result = dns_rrl(client->view, &client->peeraddr,
06818 ISC_TF((client->attributes
06819 & NS_CLIENTATTR_TCP) != 0),
06820 client->message->rdclass, qtype, tname,
06821 resp_result, client->now,
06822 wouldlog, log_buf, sizeof(log_buf));
06823 if (rrl_result != DNS_RRL_RESULT_OK) {
06824
06825
06826
06827
06828
06829
06830
06831
06832
06833
06834 if (wouldlog) {
06835 ns_client_log(client, DNS_LOGCATEGORY_RRL,
06836 NS_LOGMODULE_QUERY,
06837 DNS_RRL_LOG_DROP,
06838 "%s", log_buf);
06839 }
06840 if (!client->view->rrl->log_only) {
06841 if (rrl_result == DNS_RRL_RESULT_DROP) {
06842
06843
06844
06845
06846 inc_stats(client,
06847 dns_nsstatscounter_ratedropped);
06848 QUERY_ERROR(DNS_R_DROP);
06849 } else {
06850
06851
06852
06853
06854 inc_stats(client,
06855 dns_nsstatscounter_rateslipped);
06856 client->message->flags |=
06857 DNS_MESSAGEFLAG_TC;
06858 if (resp_result == DNS_R_NXDOMAIN)
06859 client->message->rcode =
06860 dns_rcode_nxdomain;
06861 }
06862 goto cleanup;
06863 }
06864 }
06865 }
06866
06867 if (client->view->rpzs != NULL &&
06868 client->view->rpzs->p.num_zones != 0 &&
06869 (RECURSIONOK(client) || client->view->rpzs->p.no_rd_ok != 0) &&
06870 rpz_ck_dnssec(client, result, rdataset, sigrdataset) &&
06871 !RECURSING(client) &&
06872 (client->query.rpz_st == NULL ||
06873 (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) &&
06874 !dns_name_equal(client->query.qname, dns_rootname))
06875 {
06876 isc_result_t rresult;
06877
06878 rresult = rpz_rewrite(client, qtype, result, resuming);
06879 rpz_st = client->query.rpz_st;
06880 switch (rresult) {
06881 case ISC_R_SUCCESS:
06882 break;
06883 case DNS_R_DELEGATION:
06884
06885
06886
06887
06888 rpz_st->q.qtype = qtype;
06889 rpz_st->q.is_zone = is_zone;
06890 rpz_st->q.authoritative = authoritative;
06891 rpz_st->q.zone = zone;
06892 zone = NULL;
06893 rpz_st->q.db = db;
06894 db = NULL;
06895 rpz_st->q.node = node;
06896 node = NULL;
06897 rpz_st->q.rdataset = rdataset;
06898 rdataset = NULL;
06899 rpz_st->q.sigrdataset = sigrdataset;
06900 sigrdataset = NULL;
06901 dns_name_copy(fname, rpz_st->fname, NULL);
06902 rpz_st->q.result = result;
06903 client->query.attributes |= NS_QUERYATTR_RECURSING;
06904 goto cleanup;
06905 default:
06906 RECURSE_ERROR(rresult);
06907 goto cleanup;
06908 }
06909 if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS)
06910 rpz_st->state |= DNS_RPZ_REWRITTEN;
06911 if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS &&
06912 rpz_st->m.policy != DNS_RPZ_POLICY_PASSTHRU &&
06913 (rpz_st->m.policy != DNS_RPZ_POLICY_TCP_ONLY ||
06914 (client->attributes & NS_CLIENTATTR_TCP) == 0) &&
06915 rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) {
06916
06917
06918
06919
06920
06921 rresult = dns_name_copy(client->query.qname,
06922 fname, NULL);
06923 RUNTIME_CHECK(rresult == ISC_R_SUCCESS);
06924 rpz_clean(&zone, &db, &node, NULL);
06925 if (rpz_st->m.rdataset != NULL) {
06926 query_putrdataset(client, &rdataset);
06927 rdataset = rpz_st->m.rdataset;
06928 rpz_st->m.rdataset = NULL;
06929 } else if (rdataset != NULL &&
06930 dns_rdataset_isassociated(rdataset)) {
06931 dns_rdataset_disassociate(rdataset);
06932 }
06933 node = rpz_st->m.node;
06934 rpz_st->m.node = NULL;
06935 db = rpz_st->m.db;
06936 rpz_st->m.db = NULL;
06937 version = rpz_st->m.version;
06938 rpz_st->m.version = NULL;
06939 zone = rpz_st->m.zone;
06940 rpz_st->m.zone = NULL;
06941
06942 switch (rpz_st->m.policy) {
06943 case DNS_RPZ_POLICY_TCP_ONLY:
06944 client->message->flags |= DNS_MESSAGEFLAG_TC;
06945 if (result == DNS_R_NXDOMAIN ||
06946 result == DNS_R_NCACHENXDOMAIN)
06947 client->message->rcode =
06948 dns_rcode_nxdomain;
06949 rpz_log_rewrite(client, ISC_FALSE,
06950 rpz_st->m.policy,
06951 rpz_st->m.type, zone,
06952 rpz_st->p_name, NULL);
06953 goto cleanup;
06954 case DNS_RPZ_POLICY_DROP:
06955 QUERY_ERROR(DNS_R_DROP);
06956 rpz_log_rewrite(client, ISC_FALSE,
06957 rpz_st->m.policy,
06958 rpz_st->m.type, zone,
06959 rpz_st->p_name, NULL);
06960 goto cleanup;
06961 case DNS_RPZ_POLICY_NXDOMAIN:
06962 result = DNS_R_NXDOMAIN;
06963 nxrewrite = ISC_TRUE;
06964 break;
06965 case DNS_RPZ_POLICY_NODATA:
06966 result = DNS_R_NXRRSET;
06967 nxrewrite = ISC_TRUE;
06968 break;
06969 case DNS_RPZ_POLICY_RECORD:
06970 result = rpz_st->m.result;
06971 if (qtype == dns_rdatatype_any &&
06972 result != DNS_R_CNAME) {
06973
06974
06975
06976
06977
06978 if (dns_rdataset_isassociated(rdataset))
06979 dns_rdataset_disassociate(rdataset);
06980 } else {
06981
06982
06983
06984 rdataset->ttl = ISC_MIN(rdataset->ttl,
06985 rpz_st->m.ttl);
06986 }
06987 break;
06988 case DNS_RPZ_POLICY_WILDCNAME:
06989 result = dns_rdataset_first(rdataset);
06990 RUNTIME_CHECK(result == ISC_R_SUCCESS);
06991 dns_rdataset_current(rdataset, &rdata);
06992 result = dns_rdata_tostruct(&rdata, &cname,
06993 NULL);
06994 RUNTIME_CHECK(result == ISC_R_SUCCESS);
06995 dns_rdata_reset(&rdata);
06996 result = rpz_add_cname(client, rpz_st,
06997 &cname.cname,
06998 fname, dbuf);
06999 if (result != ISC_R_SUCCESS)
07000 goto cleanup;
07001 fname = NULL;
07002 want_restart = ISC_TRUE;
07003 goto cleanup;
07004 case DNS_RPZ_POLICY_CNAME:
07005
07006
07007
07008
07009 result = rpz_add_cname(client, rpz_st,
07010 &rpz_st->m.rpz->cname,
07011 fname, dbuf);
07012 if (result != ISC_R_SUCCESS)
07013 goto cleanup;
07014 fname = NULL;
07015 want_restart = ISC_TRUE;
07016 goto cleanup;
07017 default:
07018 INSIST(0);
07019 }
07020
07021
07022
07023
07024
07025 client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
07026 NS_CLIENTATTR_WANTAD);
07027 client->message->flags &= ~DNS_MESSAGEFLAG_AD;
07028 query_putrdataset(client, &sigrdataset);
07029 rpz_st->q.is_zone = is_zone;
07030 is_zone = ISC_TRUE;
07031 rpz_log_rewrite(client, ISC_FALSE, rpz_st->m.policy,
07032 rpz_st->m.type, zone, rpz_st->p_name,
07033 NULL);
07034 }
07035 }
07036
07037 switch (result) {
07038 case ISC_R_SUCCESS:
07039
07040
07041
07042 break;
07043 case DNS_R_GLUE:
07044 case DNS_R_ZONECUT:
07045
07046
07047
07048 INSIST(is_zone);
07049 authoritative = ISC_FALSE;
07050 break;
07051 case ISC_R_NOTFOUND:
07052
07053
07054
07055
07056 INSIST(!is_zone);
07057 if (db != NULL)
07058 dns_db_detach(&db);
07059
07060 if (client->view->hints == NULL) {
07061
07062 result = ISC_R_FAILURE;
07063 } else {
07064 dns_db_attach(client->view->hints, &db);
07065 result = dns_db_findext(db, dns_rootname,
07066 NULL, dns_rdatatype_ns,
07067 0, client->now, &node,
07068 fname, &cm, &ci,
07069 rdataset, sigrdataset);
07070 }
07071 if (result != ISC_R_SUCCESS) {
07072
07073
07074
07075 if (dns_rdataset_isassociated(rdataset))
07076 dns_rdataset_disassociate(rdataset);
07077 if (sigrdataset != NULL &&
07078 dns_rdataset_isassociated(sigrdataset))
07079 dns_rdataset_disassociate(sigrdataset);
07080 if (node != NULL)
07081 dns_db_detachnode(db, &node);
07082
07083
07084
07085
07086
07087
07088 if (RECURSIONOK(client)) {
07089 result = query_recurse(client, qtype,
07090 client->query.qname,
07091 NULL, NULL, resuming);
07092 if (result == ISC_R_SUCCESS) {
07093 client->query.attributes |=
07094 NS_QUERYATTR_RECURSING;
07095 if (dns64)
07096 client->query.attributes |=
07097 NS_QUERYATTR_DNS64;
07098 if (dns64_exclude)
07099 client->query.attributes |=
07100 NS_QUERYATTR_DNS64EXCLUDE;
07101 } else
07102 RECURSE_ERROR(result);
07103 goto cleanup;
07104 } else {
07105
07106 CTRACE(ISC_LOG_ERROR,
07107 "unable to give root server referral");
07108 QUERY_ERROR(DNS_R_SERVFAIL);
07109 goto cleanup;
07110 }
07111 }
07112
07113
07114
07115
07116 case DNS_R_DELEGATION:
07117 authoritative = ISC_FALSE;
07118 if (is_zone) {
07119
07120
07121
07122
07123 if (!RECURSIONOK(client) &&
07124 (options & DNS_GETDB_NOEXACT) != 0 &&
07125 qtype == dns_rdatatype_ds) {
07126 dns_db_t *tdb = NULL;
07127 dns_zone_t *tzone = NULL;
07128 dns_dbversion_t *tversion = NULL;
07129 result = query_getzonedb(client,
07130 client->query.qname,
07131 qtype,
07132 DNS_GETDB_PARTIAL,
07133 &tzone, &tdb,
07134 &tversion);
07135 if (result == ISC_R_SUCCESS) {
07136 options &= ~DNS_GETDB_NOEXACT;
07137 query_putrdataset(client, &rdataset);
07138 if (sigrdataset != NULL)
07139 query_putrdataset(client,
07140 &sigrdataset);
07141 if (fname != NULL)
07142 query_releasename(client,
07143 &fname);
07144 if (node != NULL)
07145 dns_db_detachnode(db, &node);
07146 if (db != NULL)
07147 dns_db_detach(&db);
07148 if (zone != NULL)
07149 dns_zone_detach(&zone);
07150 version = tversion;
07151 db = tdb;
07152 zone = tzone;
07153 authoritative = ISC_TRUE;
07154 goto db_find;
07155 }
07156 if (tdb != NULL)
07157 dns_db_detach(&tdb);
07158 if (tzone != NULL)
07159 dns_zone_detach(&tzone);
07160 }
07161
07162
07163
07164 if (!USECACHE(client) || !RECURSIONOK(client)) {
07165 dns_fixedname_init(&fixed);
07166 dns_name_copy(fname,
07167 dns_fixedname_name(&fixed), NULL);
07168
07169
07170
07171
07172
07173
07174
07175
07176
07177
07178
07179
07180
07181
07182
07183
07184 client->query.gluedb = db;
07185 client->query.isreferral = ISC_TRUE;
07186
07187
07188
07189
07190
07191
07192 client->query.attributes &=
07193 ~NS_QUERYATTR_NOADDITIONAL;
07194 if (sigrdataset != NULL)
07195 sigrdatasetp = &sigrdataset;
07196 else
07197 sigrdatasetp = NULL;
07198 query_addrrset(client, &fname,
07199 &rdataset, sigrdatasetp,
07200 dbuf, DNS_SECTION_AUTHORITY);
07201 client->query.gluedb = NULL;
07202 if (WANTDNSSEC(client))
07203 query_addds(client, db, node, version,
07204 dns_fixedname_name(&fixed));
07205 } else {
07206
07207
07208
07209
07210
07211
07212
07213
07214 query_keepname(client, fname, dbuf);
07215 zdb = db;
07216 zfname = fname;
07217 fname = NULL;
07218 zrdataset = rdataset;
07219 rdataset = NULL;
07220 zsigrdataset = sigrdataset;
07221 sigrdataset = NULL;
07222 dns_db_detachnode(db, &node);
07223 zversion = version;
07224 version = NULL;
07225 db = NULL;
07226 dns_db_attach(client->view->cachedb, &db);
07227 is_zone = ISC_FALSE;
07228 goto db_find;
07229 }
07230 } else {
07231 if (zfname != NULL &&
07232 (!dns_name_issubdomain(fname, zfname) ||
07233 (is_staticstub_zone &&
07234 dns_name_equal(fname, zfname)))) {
07235
07236
07237
07238
07239
07240
07241
07242
07243
07244
07245
07246
07247
07248
07249 query_releasename(client, &fname);
07250 fname = zfname;
07251 zfname = NULL;
07252
07253
07254
07255
07256
07257
07258 dbuf = NULL;
07259 query_putrdataset(client, &rdataset);
07260 if (sigrdataset != NULL)
07261 query_putrdataset(client,
07262 &sigrdataset);
07263 rdataset = zrdataset;
07264 zrdataset = NULL;
07265 sigrdataset = zsigrdataset;
07266 zsigrdataset = NULL;
07267 version = zversion;
07268 zversion = NULL;
07269
07270
07271
07272
07273
07274 }
07275
07276 if (RECURSIONOK(client)) {
07277
07278
07279
07280 if (dns_rdatatype_atparent(type))
07281 result = query_recurse(client, qtype,
07282 client->query.qname,
07283 NULL, NULL, resuming);
07284 else if (dns64)
07285 result = query_recurse(client,
07286 dns_rdatatype_a,
07287 client->query.qname,
07288 NULL, NULL, resuming);
07289 else
07290 result = query_recurse(client, qtype,
07291 client->query.qname,
07292 fname, rdataset,
07293 resuming);
07294
07295 if (result == ISC_R_SUCCESS) {
07296 client->query.attributes |=
07297 NS_QUERYATTR_RECURSING;
07298 if (dns64)
07299 client->query.attributes |=
07300 NS_QUERYATTR_DNS64;
07301 if (dns64_exclude)
07302 client->query.attributes |=
07303 NS_QUERYATTR_DNS64EXCLUDE;
07304 } else if (result == DNS_R_DUPLICATE ||
07305 result == DNS_R_DROP)
07306 QUERY_ERROR(result);
07307 else
07308 RECURSE_ERROR(result);
07309 } else {
07310 dns_fixedname_init(&fixed);
07311 dns_name_copy(fname,
07312 dns_fixedname_name(&fixed), NULL);
07313
07314
07315
07316 client->query.attributes |=
07317 NS_QUERYATTR_CACHEGLUEOK;
07318 client->query.gluedb = zdb;
07319 client->query.isreferral = ISC_TRUE;
07320
07321
07322
07323
07324
07325
07326 client->query.attributes &=
07327 ~NS_QUERYATTR_NOADDITIONAL;
07328 if (sigrdataset != NULL)
07329 sigrdatasetp = &sigrdataset;
07330 else
07331 sigrdatasetp = NULL;
07332 query_addrrset(client, &fname,
07333 &rdataset, sigrdatasetp,
07334 dbuf, DNS_SECTION_AUTHORITY);
07335 client->query.gluedb = NULL;
07336 client->query.attributes &=
07337 ~NS_QUERYATTR_CACHEGLUEOK;
07338 if (WANTDNSSEC(client))
07339 query_addds(client, db, node, version,
07340 dns_fixedname_name(&fixed));
07341 }
07342 }
07343 goto cleanup;
07344
07345 case DNS_R_EMPTYNAME:
07346 case DNS_R_NXRRSET:
07347 iszone_nxrrset:
07348 INSIST(is_zone);
07349
07350 #ifdef dns64_bis_return_excluded_addresses
07351 if (dns64)
07352 #else
07353 if (dns64 && !dns64_exclude)
07354 #endif
07355 {
07356
07357
07358
07359 if (rdataset != NULL)
07360 query_putrdataset(client, &rdataset);
07361 if (sigrdataset != NULL)
07362 query_putrdataset(client, &sigrdataset);
07363 rdataset = client->query.dns64_aaaa;
07364 sigrdataset = client->query.dns64_sigaaaa;
07365 client->query.dns64_aaaa = NULL;
07366 client->query.dns64_sigaaaa = NULL;
07367 if (fname == NULL) {
07368 dbuf = query_getnamebuf(client);
07369 if (dbuf == NULL) {
07370 CTRACE(ISC_LOG_ERROR,
07371 "query_find: "
07372 "query_getnamebuf failed (3)");
07373 QUERY_ERROR(DNS_R_SERVFAIL);
07374 goto cleanup;
07375 }
07376 fname = query_newname(client, dbuf, &b);
07377 if (fname == NULL) {
07378 CTRACE(ISC_LOG_ERROR,
07379 "query_find: "
07380 "query_newname failed (3)");
07381 QUERY_ERROR(DNS_R_SERVFAIL);
07382 goto cleanup;
07383 }
07384 }
07385 dns_name_copy(client->query.qname, fname, NULL);
07386 dns64 = ISC_FALSE;
07387 #ifdef dns64_bis_return_excluded_addresses
07388
07389
07390
07391 if (dns64_excluded)
07392 break;
07393 #endif
07394 } else if (result == DNS_R_NXRRSET &&
07395 !ISC_LIST_EMPTY(client->view->dns64) &&
07396 client->message->rdclass == dns_rdataclass_in &&
07397 qtype == dns_rdatatype_aaaa)
07398 {
07399
07400
07401
07402
07403 INSIST(client->query.dns64_aaaa == NULL);
07404 INSIST(client->query.dns64_sigaaaa == NULL);
07405 client->query.dns64_aaaa = rdataset;
07406 client->query.dns64_sigaaaa = sigrdataset;
07407 client->query.dns64_ttl = dns64_ttl(db, version);
07408 query_releasename(client, &fname);
07409 dns_db_detachnode(db, &node);
07410 rdataset = NULL;
07411 sigrdataset = NULL;
07412 type = qtype = dns_rdatatype_a;
07413 rpz_st = client->query.rpz_st;
07414 if (rpz_st != NULL) {
07415
07416
07417
07418 if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0)
07419 is_zone = rpz_st->q.is_zone;
07420 rpz_st_clear(client);
07421 }
07422 dns64 = ISC_TRUE;
07423 goto db_find;
07424 }
07425
07426
07427
07428
07429 nxrrset_rrsig:
07430 if (redirected)
07431 goto cleanup;
07432 if (!dns_rdataset_isassociated(rdataset) &&
07433 WANTDNSSEC(client)) {
07434 if ((fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) {
07435 dns_name_t *found;
07436 dns_name_t *qname;
07437
07438 dns_fixedname_init(&fixed);
07439 found = dns_fixedname_name(&fixed);
07440 qname = client->query.qname;
07441
07442 query_findclosestnsec3(qname, db, version,
07443 client, rdataset,
07444 sigrdataset, fname,
07445 ISC_TRUE, found);
07446
07447
07448
07449
07450
07451 if (dns_rdataset_isassociated(rdataset) &&
07452 !dns_name_equal(qname, found) &&
07453 !(ns_g_nonearest &&
07454 qtype != dns_rdatatype_ds))
07455 {
07456 unsigned int count;
07457 unsigned int skip;
07458
07459
07460
07461
07462 query_addrrset(client, &fname,
07463 &rdataset, &sigrdataset,
07464 dbuf,
07465 DNS_SECTION_AUTHORITY);
07466
07467 count = dns_name_countlabels(found)
07468 + 1;
07469 skip = dns_name_countlabels(qname) -
07470 count;
07471 dns_name_getlabelsequence(qname, skip,
07472 count,
07473 found);
07474
07475 fixfname(client, &fname, &dbuf, &b);
07476 fixrdataset(client, &rdataset);
07477 fixrdataset(client, &sigrdataset);
07478 if (fname == NULL ||
07479 rdataset == NULL ||
07480 sigrdataset == NULL) {
07481 CTRACE(ISC_LOG_ERROR,
07482 "query_find: "
07483 "failure getting "
07484 "closest encloser");
07485 QUERY_ERROR(DNS_R_SERVFAIL);
07486 goto cleanup;
07487 }
07488
07489
07490
07491
07492 query_findclosestnsec3(found, db,
07493 version,
07494 client,
07495 rdataset,
07496 sigrdataset,
07497 fname,
07498 ISC_FALSE,
07499 NULL);
07500 }
07501 } else {
07502 query_releasename(client, &fname);
07503 query_addwildcardproof(client, db, version,
07504 client->query.qname,
07505 ISC_FALSE, ISC_TRUE);
07506 }
07507 }
07508 if (dns_rdataset_isassociated(rdataset)) {
07509
07510
07511
07512
07513
07514 query_keepname(client, fname, dbuf);
07515 } else if (fname != NULL) {
07516
07517
07518
07519
07520
07521 query_releasename(client, &fname);
07522 }
07523
07524
07525
07526
07527
07528 associated = dns_rdataset_isassociated(rdataset);
07529 section = nxrewrite ? DNS_SECTION_ADDITIONAL :
07530 DNS_SECTION_AUTHORITY;
07531
07532 result = query_addsoa(client, db, version, ISC_UINT32_MAX,
07533 associated, section);
07534 if (result != ISC_R_SUCCESS) {
07535 QUERY_ERROR(result);
07536 goto cleanup;
07537 }
07538
07539
07540
07541
07542 if (WANTDNSSEC(client)) {
07543 if (dns_rdataset_isassociated(rdataset))
07544 query_addnxrrsetnsec(client, db, version,
07545 &fname, &rdataset,
07546 &sigrdataset);
07547 }
07548 goto cleanup;
07549
07550 case DNS_R_EMPTYWILD:
07551 empty_wild = ISC_TRUE;
07552
07553
07554 case DNS_R_NXDOMAIN:
07555 INSIST(is_zone);
07556 if (!empty_wild) {
07557 tresult = redirect(client, fname, rdataset, &node,
07558 &db, &version, type);
07559 if (tresult == ISC_R_SUCCESS)
07560 break;
07561 if (tresult == DNS_R_NXRRSET) {
07562 redirected = ISC_TRUE;
07563 goto iszone_nxrrset;
07564 }
07565 if (tresult == DNS_R_NCACHENXRRSET) {
07566 redirected = ISC_TRUE;
07567 is_zone = ISC_FALSE;
07568 goto ncache_nxrrset;
07569 }
07570 tresult = redirect2(client, fname, rdataset, &node,
07571 &db, &version, type);
07572 if (tresult == DNS_R_CONTINUE) {
07573 client->query.redirect.qtype = qtype;
07574 client->query.redirect.rdataset = rdataset;
07575 client->query.redirect.sigrdataset =
07576 sigrdataset;
07577 client->query.redirect.db = db;
07578 client->query.redirect.node = node;
07579 client->query.redirect.zone = zone;
07580 client->query.redirect.result = DNS_R_NXDOMAIN;
07581 dns_name_copy(fname,
07582 client->query.redirect.fname,
07583 NULL);
07584 client->query.redirect.authoritative =
07585 authoritative;
07586 db = NULL;
07587 node = NULL;
07588 zone = NULL;
07589 rdataset = NULL;
07590 sigrdataset = NULL;
07591 goto cleanup;
07592 }
07593 if (tresult == ISC_R_SUCCESS)
07594 break;
07595 if (tresult == DNS_R_NXRRSET) {
07596 redirected = ISC_TRUE;
07597 goto iszone_nxrrset;
07598 }
07599 if (tresult == DNS_R_NCACHENXRRSET) {
07600 redirected = ISC_TRUE;
07601 is_zone = ISC_FALSE;
07602 goto ncache_nxrrset;
07603 }
07604 }
07605 if (dns_rdataset_isassociated(rdataset)) {
07606
07607
07608
07609
07610
07611 query_keepname(client, fname, dbuf);
07612 } else if (fname != NULL) {
07613
07614
07615
07616
07617
07618 query_releasename(client, &fname);
07619 }
07620
07621
07622
07623
07624
07625
07626
07627
07628
07629
07630 associated = dns_rdataset_isassociated(rdataset);
07631 section = nxrewrite ? DNS_SECTION_ADDITIONAL :
07632 DNS_SECTION_AUTHORITY;
07633 ttl = ISC_UINT32_MAX;
07634 if (!nxrewrite && qtype == dns_rdatatype_soa &&
07635 zone != NULL && dns_zone_getzeronosoattl(zone))
07636 ttl = 0;
07637 result = query_addsoa(client, db, version, ttl, associated,
07638 section);
07639 if (result != ISC_R_SUCCESS) {
07640 QUERY_ERROR(result);
07641 goto cleanup;
07642 }
07643
07644 if (WANTDNSSEC(client)) {
07645
07646
07647
07648 if (dns_rdataset_isassociated(rdataset))
07649 query_addrrset(client, &fname, &rdataset,
07650 &sigrdataset,
07651 NULL, DNS_SECTION_AUTHORITY);
07652 query_addwildcardproof(client, db, version,
07653 client->query.qname, ISC_FALSE,
07654 ISC_FALSE);
07655 }
07656
07657
07658
07659
07660 if (empty_wild)
07661 client->message->rcode = dns_rcode_noerror;
07662 else
07663 client->message->rcode = dns_rcode_nxdomain;
07664 goto cleanup;
07665
07666 case DNS_R_NCACHENXDOMAIN:
07667 tresult = redirect(client, fname, rdataset, &node,
07668 &db, &version, type);
07669 if (tresult == ISC_R_SUCCESS)
07670 break;
07671 if (tresult == DNS_R_NXRRSET) {
07672 redirected = ISC_TRUE;
07673 is_zone = ISC_TRUE;
07674 goto iszone_nxrrset;
07675 }
07676 if (tresult == DNS_R_NCACHENXRRSET) {
07677 redirected = ISC_TRUE;
07678 result = tresult;
07679 goto ncache_nxrrset;
07680 }
07681 tresult = redirect2(client, fname, rdataset, &node,
07682 &db, &version, type);
07683 if (tresult == DNS_R_CONTINUE) {
07684 client->query.redirect.db = db;
07685 client->query.redirect.node = node;
07686 client->query.redirect.zone = zone;
07687 client->query.redirect.qtype = qtype;
07688 client->query.redirect.rdataset = rdataset;
07689 client->query.redirect.sigrdataset = sigrdataset;
07690 client->query.redirect.result = DNS_R_NCACHENXDOMAIN;
07691 dns_name_copy(fname, client->query.redirect.fname,
07692 NULL);
07693 client->query.redirect.authoritative = authoritative;
07694 db = NULL;
07695 node = NULL;
07696 rdataset = NULL;
07697 sigrdataset = NULL;
07698 goto cleanup;
07699 }
07700 if (tresult == ISC_R_SUCCESS)
07701 break;
07702 if (tresult == DNS_R_NXRRSET) {
07703 redirected = ISC_TRUE;
07704 is_zone = ISC_TRUE;
07705 goto iszone_nxrrset;
07706 }
07707 if (tresult == DNS_R_NCACHENXRRSET) {
07708 redirected = ISC_TRUE;
07709 result = tresult;
07710 goto ncache_nxrrset;
07711 }
07712
07713
07714 case DNS_R_NCACHENXRRSET:
07715 ncache_nxrrset:
07716 INSIST(!is_zone);
07717 authoritative = ISC_FALSE;
07718
07719
07720
07721 if (result == DNS_R_NCACHENXDOMAIN)
07722 client->message->rcode = dns_rcode_nxdomain;
07723
07724
07725
07726 if (result == DNS_R_NCACHENXDOMAIN &&
07727 qtype == dns_rdatatype_ptr &&
07728 client->message->rdclass == dns_rdataclass_in &&
07729 dns_name_countlabels(fname) == 7)
07730 warn_rfc1918(client, fname, rdataset);
07731
07732 #ifdef dns64_bis_return_excluded_addresses
07733 if (dns64)
07734 #else
07735 if (dns64 && !dns64_exclude)
07736 #endif
07737 {
07738
07739
07740
07741 if (rdataset != NULL)
07742 query_putrdataset(client, &rdataset);
07743 if (sigrdataset != NULL)
07744 query_putrdataset(client, &sigrdataset);
07745 rdataset = client->query.dns64_aaaa;
07746 sigrdataset = client->query.dns64_sigaaaa;
07747 client->query.dns64_aaaa = NULL;
07748 client->query.dns64_sigaaaa = NULL;
07749 if (fname == NULL) {
07750 dbuf = query_getnamebuf(client);
07751 if (dbuf == NULL) {
07752 CTRACE(ISC_LOG_ERROR,
07753 "query_find: "
07754 "query_getnamebuf failed (4)");
07755 QUERY_ERROR(DNS_R_SERVFAIL);
07756 goto cleanup;
07757 }
07758 fname = query_newname(client, dbuf, &b);
07759 if (fname == NULL) {
07760 CTRACE(ISC_LOG_ERROR,
07761 "query_find: "
07762 "query_newname failed (4)");
07763 QUERY_ERROR(DNS_R_SERVFAIL);
07764 goto cleanup;
07765 }
07766 }
07767 dns_name_copy(client->query.qname, fname, NULL);
07768 dns64 = ISC_FALSE;
07769 #ifdef dns64_bis_return_excluded_addresses
07770 if (dns64_excluded)
07771 break;
07772 #endif
07773 } else if (result == DNS_R_NCACHENXRRSET &&
07774 !ISC_LIST_EMPTY(client->view->dns64) &&
07775 client->message->rdclass == dns_rdataclass_in &&
07776 qtype == dns_rdatatype_aaaa)
07777 {
07778
07779
07780
07781
07782 INSIST(client->query.dns64_aaaa == NULL);
07783 INSIST(client->query.dns64_sigaaaa == NULL);
07784 client->query.dns64_aaaa = rdataset;
07785 client->query.dns64_sigaaaa = sigrdataset;
07786
07787
07788
07789
07790
07791 if (rdataset->ttl != 0)
07792 client->query.dns64_ttl = rdataset->ttl;
07793 else if (dns_rdataset_first(rdataset) == ISC_R_SUCCESS)
07794 client->query.dns64_ttl = 0;
07795 query_releasename(client, &fname);
07796 dns_db_detachnode(db, &node);
07797 rdataset = NULL;
07798 sigrdataset = NULL;
07799 fname = NULL;
07800 type = qtype = dns_rdatatype_a;
07801 rpz_st = client->query.rpz_st;
07802 if (rpz_st != NULL) {
07803
07804
07805
07806 if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0)
07807 is_zone = rpz_st->q.is_zone;
07808 rpz_st_clear(client);
07809 }
07810 dns64 = ISC_TRUE;
07811 goto db_find;
07812 }
07813
07814
07815
07816
07817
07818 if (dns_rdataset_isassociated(rdataset)) {
07819 query_keepname(client, fname, dbuf);
07820 dns_message_addname(client->message, fname,
07821 DNS_SECTION_AUTHORITY);
07822 ISC_LIST_APPEND(fname->list, rdataset, link);
07823 fname = NULL;
07824 rdataset = NULL;
07825 }
07826 goto cleanup;
07827
07828 case DNS_R_CNAME:
07829
07830
07831
07832
07833
07834 trdataset = rdataset;
07835
07836
07837
07838 if (sigrdataset != NULL)
07839 sigrdatasetp = &sigrdataset;
07840 else
07841 sigrdatasetp = NULL;
07842 if (WANTDNSSEC(client) &&
07843 (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
07844 {
07845 dns_fixedname_init(&wildcardname);
07846 dns_name_copy(fname, dns_fixedname_name(&wildcardname),
07847 NULL);
07848 need_wildcardproof = ISC_TRUE;
07849 }
07850 if (NOQNAME(rdataset) && WANTDNSSEC(client))
07851 noqname = rdataset;
07852 else
07853 noqname = NULL;
07854 if (!is_zone && RECURSIONOK(client))
07855 query_prefetch(client, fname, rdataset);
07856 query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf,
07857 DNS_SECTION_ANSWER);
07858 if (noqname != NULL)
07859 query_addnoqnameproof(client, noqname);
07860
07861
07862
07863
07864 client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
07865
07866
07867
07868
07869 tname = NULL;
07870 result = dns_message_gettempname(client->message, &tname);
07871 if (result != ISC_R_SUCCESS)
07872 goto cleanup;
07873 result = dns_rdataset_first(trdataset);
07874 if (result != ISC_R_SUCCESS) {
07875 dns_message_puttempname(client->message, &tname);
07876 goto cleanup;
07877 }
07878 dns_rdataset_current(trdataset, &rdata);
07879 result = dns_rdata_tostruct(&rdata, &cname, NULL);
07880 dns_rdata_reset(&rdata);
07881 if (result != ISC_R_SUCCESS) {
07882 dns_message_puttempname(client->message, &tname);
07883 goto cleanup;
07884 }
07885 dns_name_init(tname, NULL);
07886 result = dns_name_dup(&cname.cname, client->mctx, tname);
07887 if (result != ISC_R_SUCCESS) {
07888 dns_message_puttempname(client->message, &tname);
07889 dns_rdata_freestruct(&cname);
07890 goto cleanup;
07891 }
07892 dns_rdata_freestruct(&cname);
07893 ns_client_qnamereplace(client, tname);
07894 want_restart = ISC_TRUE;
07895 if (!WANTRECURSION(client))
07896 options |= DNS_GETDB_NOLOG;
07897 goto addauth;
07898 case DNS_R_DNAME:
07899
07900
07901
07902
07903
07904 namereln = dns_name_fullcompare(client->query.qname, fname,
07905 &order, &nlabels);
07906 INSIST(namereln == dns_namereln_subdomain);
07907
07908
07909
07910
07911
07912 trdataset = rdataset;
07913
07914
07915
07916 if (sigrdataset != NULL)
07917 sigrdatasetp = &sigrdataset;
07918 else
07919 sigrdatasetp = NULL;
07920 if (WANTDNSSEC(client) &&
07921 (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
07922 {
07923 dns_fixedname_init(&wildcardname);
07924 dns_name_copy(fname, dns_fixedname_name(&wildcardname),
07925 NULL);
07926 need_wildcardproof = ISC_TRUE;
07927 }
07928 if (!is_zone && RECURSIONOK(client))
07929 query_prefetch(client, fname, rdataset);
07930 query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf,
07931 DNS_SECTION_ANSWER);
07932
07933
07934
07935
07936 client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
07937
07938
07939
07940 tname = NULL;
07941 result = dns_message_gettempname(client->message, &tname);
07942 if (result != ISC_R_SUCCESS)
07943 goto cleanup;
07944 result = dns_rdataset_first(trdataset);
07945 if (result != ISC_R_SUCCESS) {
07946 dns_message_puttempname(client->message, &tname);
07947 goto cleanup;
07948 }
07949 dns_rdataset_current(trdataset, &rdata);
07950 result = dns_rdata_tostruct(&rdata, &dname, NULL);
07951 dns_rdata_reset(&rdata);
07952 if (result != ISC_R_SUCCESS) {
07953 dns_message_puttempname(client->message, &tname);
07954 goto cleanup;
07955 }
07956 dns_name_clone(&dname.dname, tname);
07957 dns_rdata_freestruct(&dname);
07958
07959
07960
07961
07962 dns_fixedname_init(&fixed);
07963 prefix = dns_fixedname_name(&fixed);
07964 dns_name_split(client->query.qname, nlabels, prefix, NULL);
07965 INSIST(fname == NULL);
07966 dbuf = query_getnamebuf(client);
07967 if (dbuf == NULL) {
07968 dns_message_puttempname(client->message, &tname);
07969 goto cleanup;
07970 }
07971 fname = query_newname(client, dbuf, &b);
07972 if (fname == NULL) {
07973 dns_message_puttempname(client->message, &tname);
07974 goto cleanup;
07975 }
07976 result = dns_name_concatenate(prefix, tname, fname, NULL);
07977 dns_message_puttempname(client->message, &tname);
07978
07979
07980
07981
07982
07983
07984 if (result == DNS_R_NAMETOOLONG)
07985 client->message->rcode = dns_rcode_yxdomain;
07986 if (result != ISC_R_SUCCESS)
07987 goto cleanup;
07988
07989 query_keepname(client, fname, dbuf);
07990
07991
07992
07993
07994
07995
07996
07997
07998
07999
08000
08001
08002
08003
08004 result = query_add_cname(client, client->query.qname, fname,
08005 trdataset->trust, trdataset->ttl);
08006 if (result != ISC_R_SUCCESS)
08007 goto cleanup;
08008
08009
08010
08011 ns_client_qnamereplace(client, fname);
08012 fname = NULL;
08013 want_restart = ISC_TRUE;
08014 if (!WANTRECURSION(client))
08015 options |= DNS_GETDB_NOLOG;
08016 goto addauth;
08017 default:
08018
08019
08020
08021 snprintf(errmsg, sizeof(errmsg) - 1,
08022 "query_find: unexpected error after resuming: %s",
08023 isc_result_totext(result));
08024 CTRACE(ISC_LOG_ERROR, errmsg);
08025 QUERY_ERROR(DNS_R_SERVFAIL);
08026 goto cleanup;
08027 }
08028
08029 if (WANTDNSSEC(client) &&
08030 (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
08031 {
08032 dns_fixedname_init(&wildcardname);
08033 dns_name_copy(fname, dns_fixedname_name(&wildcardname), NULL);
08034 need_wildcardproof = ISC_TRUE;
08035 }
08036
08037 #ifdef ALLOW_FILTER_AAAA
08038
08039
08040
08041
08042
08043 client->filter_aaaa = dns_aaaa_ok;
08044 if (client->view->v4_aaaa != dns_aaaa_ok ||
08045 client->view->v6_aaaa != dns_aaaa_ok)
08046 {
08047 result = ns_client_checkaclsilent(client, NULL,
08048 client->view->aaaa_acl,
08049 ISC_TRUE);
08050 if (result == ISC_R_SUCCESS &&
08051 client->view->v4_aaaa != dns_aaaa_ok &&
08052 is_v4_client(client))
08053 client->filter_aaaa = client->view->v4_aaaa;
08054 else if (result == ISC_R_SUCCESS &&
08055 client->view->v6_aaaa != dns_aaaa_ok &&
08056 is_v6_client(client))
08057 client->filter_aaaa = client->view->v6_aaaa;
08058 }
08059
08060 #endif
08061
08062 if (type == dns_rdatatype_any) {
08063 #ifdef ALLOW_FILTER_AAAA
08064 isc_boolean_t have_aaaa, have_a, have_sig;
08065
08066
08067
08068
08069
08070
08071 have_aaaa = ISC_FALSE;
08072 have_a = !authoritative;
08073 have_sig = ISC_FALSE;
08074 #endif
08075
08076
08077
08078
08079 n = 0;
08080 rdsiter = NULL;
08081 result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
08082 if (result != ISC_R_SUCCESS) {
08083 CTRACE(ISC_LOG_ERROR,
08084 "query_find: type any; allrdatasets failed");
08085 QUERY_ERROR(DNS_R_SERVFAIL);
08086 goto cleanup;
08087 }
08088
08089
08090
08091
08092
08093
08094
08095
08096
08097
08098
08099
08100 query_keepname(client, fname, dbuf);
08101 tname = fname;
08102 result = dns_rdatasetiter_first(rdsiter);
08103 while (result == ISC_R_SUCCESS) {
08104 dns_rdatasetiter_current(rdsiter, rdataset);
08105 #ifdef ALLOW_FILTER_AAAA
08106
08107
08108
08109
08110 if (client->filter_aaaa != dns_aaaa_ok) {
08111 if (rdataset->type == dns_rdatatype_aaaa)
08112 have_aaaa = ISC_TRUE;
08113 else if (rdataset->type == dns_rdatatype_a)
08114 have_a = ISC_TRUE;
08115 }
08116 #endif
08117 if (is_zone && qtype == dns_rdatatype_any &&
08118 !dns_db_issecure(db) &&
08119 dns_rdatatype_isdnssec(rdataset->type)) {
08120
08121
08122
08123
08124
08125 dns_rdataset_disassociate(rdataset);
08126 } else if ((qtype == dns_rdatatype_any ||
08127 rdataset->type == qtype) && rdataset->type != 0) {
08128 #ifdef ALLOW_FILTER_AAAA
08129 if (dns_rdatatype_isdnssec(rdataset->type))
08130 have_sig = ISC_TRUE;
08131 #endif
08132 if (NOQNAME(rdataset) && WANTDNSSEC(client))
08133 noqname = rdataset;
08134 else
08135 noqname = NULL;
08136 rpz_st = client->query.rpz_st;
08137 if (rpz_st != NULL)
08138 rdataset->ttl = ISC_MIN(rdataset->ttl,
08139 rpz_st->m.ttl);
08140 if (!is_zone && RECURSIONOK(client)) {
08141 dns_name_t *name;
08142 name = (fname != NULL) ? fname : tname;
08143 query_prefetch(client, name, rdataset);
08144 }
08145 query_addrrset(client,
08146 fname != NULL ? &fname : &tname,
08147 &rdataset, NULL,
08148 NULL, DNS_SECTION_ANSWER);
08149 if (noqname != NULL)
08150 query_addnoqnameproof(client, noqname);
08151 n++;
08152 INSIST(tname != NULL);
08153
08154
08155
08156
08157 if (rdataset != NULL)
08158 query_putrdataset(client, &rdataset);
08159 rdataset = query_newrdataset(client);
08160 if (rdataset == NULL)
08161 break;
08162 } else {
08163
08164
08165
08166 dns_rdataset_disassociate(rdataset);
08167 }
08168 result = dns_rdatasetiter_next(rdsiter);
08169 }
08170
08171 #ifdef ALLOW_FILTER_AAAA
08172
08173
08174
08175
08176 if (client->filter_aaaa == dns_aaaa_break_dnssec)
08177 client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
08178 else if (client->filter_aaaa != dns_aaaa_ok &&
08179 have_aaaa && have_a &&
08180 (!have_sig || !WANTDNSSEC(client)))
08181 client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
08182 #endif
08183 if (fname != NULL)
08184 dns_message_puttempname(client->message, &fname);
08185
08186 if (n == 0) {
08187
08188
08189
08190
08191
08192 if ((qtype == dns_rdatatype_rrsig ||
08193 qtype == dns_rdatatype_sig) &&
08194 result == ISC_R_NOMORE) {
08195 if (!is_zone) {
08196 authoritative = ISC_FALSE;
08197 dns_rdatasetiter_destroy(&rdsiter);
08198 client->attributes &= ~NS_CLIENTATTR_RA;
08199 goto addauth;
08200 }
08201
08202 if (qtype == dns_rdatatype_rrsig &&
08203 dns_db_issecure(db)) {
08204 char namebuf[DNS_NAME_FORMATSIZE];
08205 dns_name_format(client->query.qname,
08206 namebuf,
08207 sizeof(namebuf));
08208 ns_client_log(client,
08209 DNS_LOGCATEGORY_DNSSEC,
08210 NS_LOGMODULE_QUERY,
08211 ISC_LOG_WARNING,
08212 "missing signature "
08213 "for %s", namebuf);
08214 }
08215
08216 dns_rdatasetiter_destroy(&rdsiter);
08217 fname = query_newname(client, dbuf, &b);
08218 goto nxrrset_rrsig;
08219 } else {
08220 CTRACE(ISC_LOG_ERROR,
08221 "query_find: no matching rdatasets "
08222 "in cache");
08223 result = DNS_R_SERVFAIL;
08224 }
08225 }
08226
08227 dns_rdatasetiter_destroy(&rdsiter);
08228 if (result != ISC_R_NOMORE) {
08229 CTRACE(ISC_LOG_ERROR,
08230 "query_find: dns_rdatasetiter_destroy failed");
08231 QUERY_ERROR(DNS_R_SERVFAIL);
08232 goto cleanup;
08233 }
08234 } else {
08235
08236
08237
08238
08239
08240 #ifdef ALLOW_FILTER_AAAA
08241
08242
08243
08244
08245
08246
08247
08248
08249 if (client->filter_aaaa == dns_aaaa_break_dnssec ||
08250 (client->filter_aaaa == dns_aaaa_filter &&
08251 (!WANTDNSSEC(client) || sigrdataset == NULL ||
08252 !dns_rdataset_isassociated(sigrdataset))))
08253 {
08254 if (qtype == dns_rdatatype_aaaa) {
08255 trdataset = query_newrdataset(client);
08256 result = dns_db_findrdataset(db, node, version,
08257 dns_rdatatype_a, 0,
08258 client->now,
08259 trdataset, NULL);
08260 if (dns_rdataset_isassociated(trdataset))
08261 dns_rdataset_disassociate(trdataset);
08262 query_putrdataset(client, &trdataset);
08263
08264
08265
08266
08267
08268
08269
08270
08271
08272
08273
08274
08275
08276
08277 if (result == ISC_R_SUCCESS) {
08278 client->attributes |=
08279 NS_CLIENTATTR_FILTER_AAAA;
08280
08281 } else if (authoritative ||
08282 !RECURSIONOK(client) ||
08283 (result != DNS_R_DELEGATION &&
08284 result != ISC_R_NOTFOUND)) {
08285 client->attributes &=
08286 ~NS_CLIENTATTR_FILTER_AAAA;
08287 } else {
08288
08289
08290
08291
08292
08293
08294
08295
08296 result = query_recurse(client,
08297 dns_rdatatype_a,
08298 client->query.qname,
08299 NULL, NULL, resuming);
08300 if (result == ISC_R_SUCCESS) {
08301 client->attributes |=
08302 NS_CLIENTATTR_FILTER_AAAA_RC;
08303 client->query.attributes |=
08304 NS_QUERYATTR_RECURSING;
08305 }
08306 }
08307
08308 } else if (qtype == dns_rdatatype_a &&
08309 (client->attributes &
08310 NS_CLIENTATTR_FILTER_AAAA_RC) != 0) {
08311 client->attributes &=
08312 ~NS_CLIENTATTR_FILTER_AAAA_RC;
08313 client->attributes |=
08314 NS_CLIENTATTR_FILTER_AAAA;
08315 dns_rdataset_disassociate(rdataset);
08316 if (sigrdataset != NULL &&
08317 dns_rdataset_isassociated(sigrdataset))
08318 dns_rdataset_disassociate(sigrdataset);
08319 goto cleanup;
08320 }
08321 }
08322 #endif
08323
08324
08325
08326
08327 INSIST(client->query.dns64_aaaaok == NULL);
08328
08329 if (qtype == dns_rdatatype_aaaa && !dns64_exclude &&
08330 !ISC_LIST_EMPTY(client->view->dns64) &&
08331 client->message->rdclass == dns_rdataclass_in &&
08332 !dns64_aaaaok(client, rdataset, sigrdataset)) {
08333
08334
08335
08336
08337 client->query.dns64_aaaa = rdataset;
08338 client->query.dns64_sigaaaa = sigrdataset;
08339 client->query.dns64_ttl = rdataset->ttl;
08340 query_releasename(client, &fname);
08341 dns_db_detachnode(db, &node);
08342 rdataset = NULL;
08343 sigrdataset = NULL;
08344 type = qtype = dns_rdatatype_a;
08345 rpz_st = client->query.rpz_st;
08346 if (rpz_st != NULL) {
08347
08348
08349
08350 if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0)
08351 is_zone = rpz_st->q.is_zone;
08352 rpz_st_clear(client);
08353 }
08354 dns64_exclude = dns64 = ISC_TRUE;
08355 goto db_find;
08356 }
08357
08358 if (sigrdataset != NULL)
08359 sigrdatasetp = &sigrdataset;
08360 else
08361 sigrdatasetp = NULL;
08362 if (NOQNAME(rdataset) && WANTDNSSEC(client))
08363 noqname = rdataset;
08364 else
08365 noqname = NULL;
08366
08367
08368
08369 if (is_zone && qtype == dns_rdatatype_ns &&
08370 dns_name_equal(client->query.qname, dns_rootname))
08371 client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL;
08372
08373
08374
08375
08376 if (zone != NULL) {
08377 dns_zone_t *raw = NULL, *mayberaw;
08378
08379 if (is_zone)
08380 dns_zone_getraw(zone, &raw);
08381 mayberaw = (raw != NULL) ? raw : zone;
08382
08383 if (is_zone && qtype == dns_rdatatype_soa &&
08384 ((client->attributes &
08385 NS_CLIENTATTR_WANTEXPIRE) != 0) &&
08386 client->query.restarts == 0 &&
08387 dns_zone_gettype(mayberaw) == dns_zone_slave)
08388 {
08389 isc_time_t expiretime;
08390 isc_uint32_t secs;
08391 dns_zone_getexpiretime(zone, &expiretime);
08392 secs = isc_time_seconds(&expiretime);
08393 if (secs >= client->now &&
08394 result == ISC_R_SUCCESS) {
08395 client->attributes |=
08396 NS_CLIENTATTR_HAVEEXPIRE;
08397 client->expire = secs - client->now;
08398 }
08399 }
08400 if (raw != NULL)
08401 dns_zone_detach(&raw);
08402 }
08403
08404 if (dns64) {
08405 qtype = type = dns_rdatatype_aaaa;
08406 result = query_dns64(client, &fname, rdataset,
08407 sigrdataset, dbuf,
08408 DNS_SECTION_ANSWER);
08409 dns_rdataset_disassociate(rdataset);
08410 dns_message_puttemprdataset(client->message, &rdataset);
08411 if (result == ISC_R_NOMORE) {
08412 #ifndef dns64_bis_return_excluded_addresses
08413 if (dns64_exclude) {
08414 if (!is_zone)
08415 goto cleanup;
08416
08417
08418
08419 (void)query_addsoa(client, db, version,
08420 600, ISC_FALSE,
08421 DNS_SECTION_AUTHORITY);
08422 goto cleanup;
08423 }
08424 #endif
08425 if (is_zone)
08426 goto iszone_nxrrset;
08427 else
08428 goto ncache_nxrrset;
08429 } else if (result != ISC_R_SUCCESS) {
08430 eresult = result;
08431 goto cleanup;
08432 }
08433 } else if (client->query.dns64_aaaaok != NULL) {
08434 query_filter64(client, &fname, rdataset, dbuf,
08435 DNS_SECTION_ANSWER);
08436 query_putrdataset(client, &rdataset);
08437 } else {
08438 if (!is_zone && RECURSIONOK(client))
08439 query_prefetch(client, fname, rdataset);
08440 query_addrrset(client, &fname, &rdataset,
08441 sigrdatasetp, dbuf, DNS_SECTION_ANSWER);
08442 }
08443
08444 if (noqname != NULL)
08445 query_addnoqnameproof(client, noqname);
08446
08447
08448
08449
08450 INSIST(rdataset == NULL);
08451 }
08452
08453 addauth:
08454 CTRACE(ISC_LOG_DEBUG(3), "query_find: addauth");
08455
08456
08457
08458
08459 if (!want_restart && !NOAUTHORITY(client)) {
08460 if (is_zone) {
08461 if (!((qtype == dns_rdatatype_ns ||
08462 qtype == dns_rdatatype_any) &&
08463 dns_name_equal(client->query.qname,
08464 dns_db_origin(db))))
08465 (void)query_addns(client, db, version);
08466 } else if (qtype != dns_rdatatype_ns) {
08467 if (fname != NULL)
08468 query_releasename(client, &fname);
08469 query_addbestns(client);
08470 }
08471 }
08472
08473
08474
08475
08476
08477 if (need_wildcardproof && dns_db_issecure(db))
08478 query_addwildcardproof(client, db, version,
08479 dns_fixedname_name(&wildcardname),
08480 ISC_TRUE, ISC_FALSE);
08481 cleanup:
08482 CTRACE(ISC_LOG_DEBUG(3), "query_find: cleanup");
08483
08484
08485
08486 rpz_st = client->query.rpz_st;
08487 if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0) {
08488 rpz_match_clear(rpz_st);
08489 rpz_st->state &= ~DNS_RPZ_DONE_QNAME;
08490 }
08491 if (rdataset != NULL)
08492 query_putrdataset(client, &rdataset);
08493 if (sigrdataset != NULL)
08494 query_putrdataset(client, &sigrdataset);
08495 if (fname != NULL)
08496 query_releasename(client, &fname);
08497 if (node != NULL)
08498 dns_db_detachnode(db, &node);
08499 if (db != NULL)
08500 dns_db_detach(&db);
08501 if (zone != NULL)
08502 dns_zone_detach(&zone);
08503 if (zdb != NULL) {
08504 query_putrdataset(client, &zrdataset);
08505 if (zsigrdataset != NULL)
08506 query_putrdataset(client, &zsigrdataset);
08507 if (zfname != NULL)
08508 query_releasename(client, &zfname);
08509 dns_db_detach(&zdb);
08510 }
08511 if (event != NULL)
08512 isc_event_free(ISC_EVENT_PTR(&event));
08513
08514
08515
08516
08517 if (client->query.restarts == 0 && !authoritative) {
08518
08519
08520
08521
08522 client->message->flags &= ~DNS_MESSAGEFLAG_AA;
08523 }
08524
08525
08526
08527
08528 if (want_restart && client->query.restarts < MAX_RESTARTS) {
08529 client->query.restarts++;
08530 goto restart;
08531 }
08532
08533 if (eresult != ISC_R_SUCCESS &&
08534 (!PARTIALANSWER(client) || WANTRECURSION(client)
08535 || eresult == DNS_R_DROP)) {
08536 if (eresult == DNS_R_DUPLICATE || eresult == DNS_R_DROP) {
08537
08538
08539
08540
08541
08542
08543 query_next(client, eresult);
08544 } else {
08545
08546
08547
08548
08549
08550 INSIST(line >= 0);
08551 query_error(client, eresult, line);
08552 }
08553 ns_client_detach(&client);
08554 } else if (!RECURSING(client)) {
08555
08556
08557
08558
08559
08560
08561 setup_query_sortlist(client);
08562
08563
08564
08565
08566
08567
08568 if (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER]) &&
08569 client->message->rcode == dns_rcode_noerror &&
08570 (qtype == dns_rdatatype_a || qtype == dns_rdatatype_aaaa))
08571 answer_in_glue(client, qtype);
08572
08573 if (client->message->rcode == dns_rcode_nxdomain &&
08574 client->view->auth_nxdomain == ISC_TRUE)
08575 client->message->flags |= DNS_MESSAGEFLAG_AA;
08576
08577
08578
08579
08580
08581
08582 if (resuming &&
08583 (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER]) ||
08584 client->message->rcode != dns_rcode_noerror))
08585 eresult = ISC_R_FAILURE;
08586
08587 query_send(client);
08588 ns_client_detach(&client);
08589 }
08590 CTRACE(ISC_LOG_DEBUG(3), "query_find: done");
08591
08592 return (eresult);
08593 }
08594
08595 static inline void
08596 log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
08597 char namebuf[DNS_NAME_FORMATSIZE];
08598 char typename[DNS_RDATATYPE_FORMATSIZE];
08599 char classname[DNS_RDATACLASS_FORMATSIZE];
08600 char onbuf[ISC_NETADDR_FORMATSIZE];
08601 char ednsbuf[sizeof("E(255)")] = { 0 };
08602 dns_rdataset_t *rdataset;
08603 int level = ISC_LOG_INFO;
08604
08605 if (! isc_log_wouldlog(ns_g_lctx, level))
08606 return;
08607
08608 rdataset = ISC_LIST_HEAD(client->query.qname->list);
08609 INSIST(rdataset != NULL);
08610 dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
08611 dns_rdataclass_format(rdataset->rdclass, classname, sizeof(classname));
08612 dns_rdatatype_format(rdataset->type, typename, sizeof(typename));
08613 isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf));
08614
08615 if (client->ednsversion >= 0)
08616 snprintf(ednsbuf, sizeof(ednsbuf), "E(%d)",
08617 client->ednsversion);
08618
08619 ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
08620 level, "query: %s %s %s %s%s%s%s%s%s (%s)", namebuf,
08621 classname, typename, WANTRECURSION(client) ? "+" : "-",
08622 (client->signer != NULL) ? "S" : "", ednsbuf,
08623 ((client->attributes & NS_CLIENTATTR_TCP) != 0) ?
08624 "T" : "",
08625 ((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "",
08626 ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "",
08627 onbuf);
08628 }
08629
08630 static inline void
08631 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) {
08632 char namebuf[DNS_NAME_FORMATSIZE];
08633 char typename[DNS_RDATATYPE_FORMATSIZE];
08634 char classname[DNS_RDATACLASS_FORMATSIZE];
08635 const char *namep, *typep, *classp, *sep1, *sep2;
08636 dns_rdataset_t *rdataset;
08637
08638 if (!isc_log_wouldlog(ns_g_lctx, level))
08639 return;
08640
08641 namep = typep = classp = sep1 = sep2 = "";
08642
08643
08644
08645
08646
08647
08648 if (client->query.origqname != NULL) {
08649 dns_name_format(client->query.origqname, namebuf,
08650 sizeof(namebuf));
08651 namep = namebuf;
08652 sep1 = " for ";
08653
08654 rdataset = ISC_LIST_HEAD(client->query.origqname->list);
08655 if (rdataset != NULL) {
08656 dns_rdataclass_format(rdataset->rdclass, classname,
08657 sizeof(classname));
08658 classp = classname;
08659 dns_rdatatype_format(rdataset->type, typename,
08660 sizeof(typename));
08661 typep = typename;
08662 sep2 = "/";
08663 }
08664 }
08665
08666 ns_client_log(client, NS_LOGCATEGORY_QUERY_EERRORS, NS_LOGMODULE_QUERY,
08667 level, "query failed (%s)%s%s%s%s%s%s at %s:%d",
08668 isc_result_totext(result), sep1, namep, sep2,
08669 classp, sep2, typep, __FILE__, line);
08670 }
08671
08672 void
08673 ns_query_start(ns_client_t *client) {
08674 isc_result_t result;
08675 dns_message_t *message = client->message;
08676 dns_rdataset_t *rdataset;
08677 ns_client_t *qclient;
08678 dns_rdatatype_t qtype;
08679 unsigned int saved_extflags = client->extflags;
08680 unsigned int saved_flags = client->message->flags;
08681
08682 CTRACE(ISC_LOG_DEBUG(3), "ns_query_start");
08683
08684
08685
08686
08687 if (ns_g_clienttest && (client->attributes & NS_CLIENTATTR_TCP) == 0)
08688 RUNTIME_CHECK(ns_client_replace(client) == ISC_R_SUCCESS);
08689
08690
08691
08692
08693 client->next = query_next_callback;
08694
08695
08696
08697
08698 if (!client->view->enablednssec) {
08699 message->flags &= ~DNS_MESSAGEFLAG_CD;
08700 client->extflags &= ~DNS_MESSAGEEXTFLAG_DO;
08701 }
08702
08703 if ((message->flags & DNS_MESSAGEFLAG_RD) != 0)
08704 client->query.attributes |= NS_QUERYATTR_WANTRECURSION;
08705
08706 if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0)
08707 client->attributes |= NS_CLIENTATTR_WANTDNSSEC;
08708
08709 if (client->view->minimalresponses)
08710 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
08711 NS_QUERYATTR_NOADDITIONAL);
08712
08713 if ((client->view->cachedb == NULL)
08714 || (!client->view->additionalfromcache)) {
08715
08716
08717
08718
08719 client->query.attributes &=
08720 ~(NS_QUERYATTR_RECURSIONOK|NS_QUERYATTR_CACHEOK);
08721 client->query.attributes |= NS_CLIENTATTR_NOSETFC;
08722 } else if ((client->attributes & NS_CLIENTATTR_RA) == 0 ||
08723 (message->flags & DNS_MESSAGEFLAG_RD) == 0) {
08724
08725
08726
08727
08728
08729
08730 client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
08731 client->query.attributes |= NS_CLIENTATTR_NOSETFC;
08732 }
08733
08734
08735
08736
08737 result = dns_message_firstname(message, DNS_SECTION_QUESTION);
08738 if (result != ISC_R_SUCCESS) {
08739 query_error(client, result, __LINE__);
08740 return;
08741 }
08742 dns_message_currentname(message, DNS_SECTION_QUESTION,
08743 &client->query.qname);
08744 client->query.origqname = client->query.qname;
08745 result = dns_message_nextname(message, DNS_SECTION_QUESTION);
08746 if (result != ISC_R_NOMORE) {
08747 if (result == ISC_R_SUCCESS) {
08748
08749
08750
08751
08752 query_error(client, DNS_R_FORMERR, __LINE__);
08753 } else
08754 query_error(client, result, __LINE__);
08755 return;
08756 }
08757
08758 if (ns_g_server->log_queries)
08759 log_query(client, saved_flags, saved_extflags);
08760
08761
08762
08763
08764 if (message->counts[DNS_SECTION_QUESTION] > 1) {
08765 query_error(client, DNS_R_FORMERR, __LINE__);
08766 return;
08767 }
08768
08769
08770
08771
08772 rdataset = ISC_LIST_HEAD(client->query.qname->list);
08773 INSIST(rdataset != NULL);
08774 client->query.qtype = qtype = rdataset->type;
08775 dns_rdatatypestats_increment(ns_g_server->rcvquerystats, qtype);
08776
08777 if (dns_rdatatype_ismeta(qtype)) {
08778 switch (qtype) {
08779 case dns_rdatatype_any:
08780 break;
08781 case dns_rdatatype_ixfr:
08782 case dns_rdatatype_axfr:
08783 ns_xfr_start(client, rdataset->type);
08784 return;
08785 case dns_rdatatype_maila:
08786 case dns_rdatatype_mailb:
08787 query_error(client, DNS_R_NOTIMP, __LINE__);
08788 return;
08789 case dns_rdatatype_tkey:
08790 result = dns_tkey_processquery(client->message,
08791 ns_g_server->tkeyctx,
08792 client->view->dynamickeys);
08793 if (result == ISC_R_SUCCESS)
08794 query_send(client);
08795 else
08796 query_error(client, result, __LINE__);
08797 return;
08798 default:
08799 query_error(client, DNS_R_FORMERR, __LINE__);
08800 return;
08801 }
08802 }
08803
08804
08805
08806
08807 if (qtype == dns_rdatatype_dnskey || qtype == dns_rdatatype_ds)
08808 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
08809 NS_QUERYATTR_NOADDITIONAL);
08810
08811
08812
08813
08814 if (client->ednsversion >= 0 && client->udpsize <= 512U &&
08815 (client->attributes & NS_CLIENTATTR_TCP) == 0)
08816 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
08817 NS_QUERYATTR_NOADDITIONAL);
08818
08819
08820
08821
08822
08823
08824
08825
08826
08827 if (message->flags & DNS_MESSAGEFLAG_CD ||
08828 qtype == dns_rdatatype_rrsig)
08829 {
08830 client->query.dboptions |= DNS_DBFIND_PENDINGOK;
08831 client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
08832 } else if (!client->view->enablevalidation)
08833 client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
08834
08835
08836
08837
08838
08839 if (message->flags & DNS_MESSAGEFLAG_CD)
08840 client->query.attributes &= ~NS_QUERYATTR_SECURE;
08841
08842
08843
08844
08845
08846 if ((message->flags & DNS_MESSAGEFLAG_AD) != 0)
08847 client->attributes |= NS_CLIENTATTR_WANTAD;
08848
08849
08850
08851
08852 result = dns_message_reply(message, ISC_TRUE);
08853 if (result != ISC_R_SUCCESS) {
08854 query_next(client, result);
08855 return;
08856 }
08857
08858
08859
08860
08861
08862
08863
08864
08865 if (!ns_g_noaa)
08866 message->flags |= DNS_MESSAGEFLAG_AA;
08867
08868
08869
08870
08871
08872 if (WANTDNSSEC(client) || WANTAD(client))
08873 message->flags |= DNS_MESSAGEFLAG_AD;
08874
08875 qclient = NULL;
08876 ns_client_attach(client, &qclient);
08877 (void)query_find(qclient, NULL, qtype);
08878 }