00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include <isc/buffer.h>
00025 #include <isc/util.h>
00026
00027 #include <dns/db.h>
00028 #include <dns/message.h>
00029 #include <dns/ncache.h>
00030 #include <dns/rdata.h>
00031 #include <dns/rdatalist.h>
00032 #include <dns/rdataset.h>
00033 #include <dns/rdatastruct.h>
00034
00035 #define DNS_NCACHE_RDATA 20U
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 static isc_result_t
00051 addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
00052 dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
00053 isc_boolean_t optout, isc_boolean_t secure,
00054 dns_rdataset_t *addedrdataset);
00055
00056 static inline isc_result_t
00057 copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
00058 isc_result_t result;
00059 unsigned int count;
00060 isc_region_t ar, r;
00061 dns_rdata_t rdata = DNS_RDATA_INIT;
00062
00063
00064
00065
00066 isc_buffer_availableregion(buffer, &ar);
00067 if (ar.length < 2)
00068 return (ISC_R_NOSPACE);
00069 count = dns_rdataset_count(rdataset);
00070 INSIST(count <= 65535);
00071 isc_buffer_putuint16(buffer, (isc_uint16_t)count);
00072
00073 result = dns_rdataset_first(rdataset);
00074 while (result == ISC_R_SUCCESS) {
00075 dns_rdataset_current(rdataset, &rdata);
00076 dns_rdata_toregion(&rdata, &r);
00077 INSIST(r.length <= 65535);
00078 isc_buffer_availableregion(buffer, &ar);
00079 if (ar.length < 2)
00080 return (ISC_R_NOSPACE);
00081
00082
00083
00084 isc_buffer_putuint16(buffer, (isc_uint16_t)r.length);
00085
00086
00087
00088 result = isc_buffer_copyregion(buffer, &r);
00089 if (result != ISC_R_SUCCESS)
00090 return (result);
00091 dns_rdata_reset(&rdata);
00092 result = dns_rdataset_next(rdataset);
00093 }
00094 if (result != ISC_R_NOMORE)
00095 return (result);
00096
00097 return (ISC_R_SUCCESS);
00098 }
00099
00100 isc_result_t
00101 dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
00102 dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
00103 dns_rdataset_t *addedrdataset)
00104 {
00105 return (addoptout(message, cache, node, covers, now, maxttl,
00106 ISC_FALSE, ISC_FALSE, addedrdataset));
00107 }
00108
00109 isc_result_t
00110 dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
00111 dns_dbnode_t *node, dns_rdatatype_t covers,
00112 isc_stdtime_t now, dns_ttl_t maxttl,
00113 isc_boolean_t optout, dns_rdataset_t *addedrdataset)
00114 {
00115 return (addoptout(message, cache, node, covers, now, maxttl,
00116 optout, ISC_TRUE, addedrdataset));
00117 }
00118
00119 static isc_result_t
00120 addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
00121 dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
00122 isc_boolean_t optout, isc_boolean_t secure,
00123 dns_rdataset_t *addedrdataset)
00124 {
00125 isc_result_t result;
00126 isc_buffer_t buffer;
00127 isc_region_t r;
00128 dns_rdataset_t *rdataset;
00129 dns_rdatatype_t type;
00130 dns_name_t *name;
00131 dns_ttl_t ttl;
00132 dns_trust_t trust;
00133 dns_rdata_t rdata[DNS_NCACHE_RDATA];
00134 dns_rdataset_t ncrdataset;
00135 dns_rdatalist_t ncrdatalist;
00136 unsigned char data[4096];
00137 unsigned int next = 0;
00138
00139
00140
00141
00142
00143
00144 REQUIRE(message != NULL);
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 dns_rdatalist_init(&ncrdatalist);
00155 ncrdatalist.rdclass = dns_db_class(cache);
00156 ncrdatalist.covers = covers;
00157 ncrdatalist.ttl = maxttl;
00158
00159
00160
00161
00162 ttl = maxttl;
00163 trust = 0xffff;
00164 isc_buffer_init(&buffer, data, sizeof(data));
00165 if (message->counts[DNS_SECTION_AUTHORITY])
00166 result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
00167 else
00168 result = ISC_R_NOMORE;
00169 while (result == ISC_R_SUCCESS) {
00170 name = NULL;
00171 dns_message_currentname(message, DNS_SECTION_AUTHORITY,
00172 &name);
00173 if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) {
00174 for (rdataset = ISC_LIST_HEAD(name->list);
00175 rdataset != NULL;
00176 rdataset = ISC_LIST_NEXT(rdataset, link)) {
00177 if ((rdataset->attributes &
00178 DNS_RDATASETATTR_NCACHE) == 0)
00179 continue;
00180 type = rdataset->type;
00181 if (type == dns_rdatatype_rrsig)
00182 type = rdataset->covers;
00183 if (type == dns_rdatatype_soa ||
00184 type == dns_rdatatype_nsec ||
00185 type == dns_rdatatype_nsec3) {
00186 if (ttl > rdataset->ttl)
00187 ttl = rdataset->ttl;
00188 if (trust > rdataset->trust)
00189 trust = rdataset->trust;
00190
00191
00192
00193 dns_name_toregion(name, &r);
00194 result = isc_buffer_copyregion(&buffer,
00195 &r);
00196 if (result != ISC_R_SUCCESS)
00197 return (result);
00198
00199
00200
00201 isc_buffer_availableregion(&buffer,
00202 &r);
00203 if (r.length < 3)
00204 return (ISC_R_NOSPACE);
00205 isc_buffer_putuint16(&buffer,
00206 rdataset->type);
00207 isc_buffer_putuint8(&buffer,
00208 (unsigned char)rdataset->trust);
00209
00210
00211
00212 result = copy_rdataset(rdataset,
00213 &buffer);
00214 if (result != ISC_R_SUCCESS)
00215 return (result);
00216
00217 if (next >= DNS_NCACHE_RDATA)
00218 return (ISC_R_NOSPACE);
00219 dns_rdata_init(&rdata[next]);
00220 isc_buffer_remainingregion(&buffer, &r);
00221 rdata[next].data = r.base;
00222 rdata[next].length = r.length;
00223 rdata[next].rdclass =
00224 ncrdatalist.rdclass;
00225 rdata[next].type = 0;
00226 rdata[next].flags = 0;
00227 ISC_LIST_APPEND(ncrdatalist.rdata,
00228 &rdata[next], link);
00229 isc_buffer_forward(&buffer, r.length);
00230 next++;
00231 }
00232 }
00233 }
00234 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
00235 }
00236 if (result != ISC_R_NOMORE)
00237 return (result);
00238
00239 if (trust == 0xffff) {
00240 if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 &&
00241 message->counts[DNS_SECTION_ANSWER] == 0) {
00242
00243
00244
00245
00246 trust = dns_trust_authauthority;
00247 } else
00248 trust = dns_trust_additional;
00249 ttl = 0;
00250 }
00251
00252 INSIST(trust != 0xffff);
00253
00254 ncrdatalist.ttl = ttl;
00255
00256 dns_rdataset_init(&ncrdataset);
00257 RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
00258 == ISC_R_SUCCESS);
00259 if (!secure && trust > dns_trust_answer)
00260 trust = dns_trust_answer;
00261 ncrdataset.trust = trust;
00262 ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
00263 if (message->rcode == dns_rcode_nxdomain)
00264 ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
00265 if (optout)
00266 ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT;
00267
00268 return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset,
00269 0, addedrdataset));
00270 }
00271
00272 isc_result_t
00273 dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
00274 isc_buffer_t *target, unsigned int options,
00275 unsigned int *countp)
00276 {
00277 dns_rdata_t rdata = DNS_RDATA_INIT;
00278 isc_result_t result;
00279 isc_region_t remaining, tavailable;
00280 isc_buffer_t source, savedbuffer, rdlen;
00281 dns_name_t name;
00282 dns_rdatatype_t type;
00283 unsigned int i, rcount, count;
00284
00285
00286
00287
00288
00289
00290
00291 REQUIRE(rdataset != NULL);
00292 REQUIRE(rdataset->type == 0);
00293 REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
00294
00295 savedbuffer = *target;
00296 count = 0;
00297
00298 result = dns_rdataset_first(rdataset);
00299 while (result == ISC_R_SUCCESS) {
00300 dns_rdataset_current(rdataset, &rdata);
00301 isc_buffer_init(&source, rdata.data, rdata.length);
00302 isc_buffer_add(&source, rdata.length);
00303 dns_name_init(&name, NULL);
00304 isc_buffer_remainingregion(&source, &remaining);
00305 dns_name_fromregion(&name, &remaining);
00306 INSIST(remaining.length >= name.length);
00307 isc_buffer_forward(&source, name.length);
00308 remaining.length -= name.length;
00309
00310 INSIST(remaining.length >= 5);
00311 type = isc_buffer_getuint16(&source);
00312 isc_buffer_forward(&source, 1);
00313 rcount = isc_buffer_getuint16(&source);
00314
00315 for (i = 0; i < rcount; i++) {
00316
00317
00318
00319
00320 isc_buffer_remainingregion(&source, &remaining);
00321 INSIST(remaining.length >= 2);
00322 dns_rdata_reset(&rdata);
00323 rdata.length = isc_buffer_getuint16(&source);
00324 isc_buffer_remainingregion(&source, &remaining);
00325 rdata.data = remaining.base;
00326 rdata.type = type;
00327 rdata.rdclass = rdataset->rdclass;
00328 INSIST(remaining.length >= rdata.length);
00329 isc_buffer_forward(&source, rdata.length);
00330
00331 if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 &&
00332 dns_rdatatype_isdnssec(type))
00333 continue;
00334
00335
00336
00337
00338 dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
00339 result = dns_name_towire(&name, cctx, target);
00340 if (result != ISC_R_SUCCESS)
00341 goto rollback;
00342
00343
00344
00345
00346
00347 isc_buffer_availableregion(target, &tavailable);
00348 if (tavailable.length < 10) {
00349 result = ISC_R_NOSPACE;
00350 goto rollback;
00351 }
00352 isc_buffer_putuint16(target, type);
00353 isc_buffer_putuint16(target, rdataset->rdclass);
00354 isc_buffer_putuint32(target, rdataset->ttl);
00355
00356
00357
00358
00359 rdlen = *target;
00360 isc_buffer_add(target, 2);
00361
00362
00363
00364
00365 result = dns_rdata_towire(&rdata, cctx, target);
00366 if (result != ISC_R_SUCCESS)
00367 goto rollback;
00368
00369
00370
00371
00372
00373 INSIST((target->used >= rdlen.used + 2) &&
00374 (target->used - rdlen.used - 2 < 65536));
00375 isc_buffer_putuint16(&rdlen,
00376 (isc_uint16_t)(target->used -
00377 rdlen.used - 2));
00378
00379 count++;
00380 }
00381 INSIST(isc_buffer_remaininglength(&source) == 0);
00382 result = dns_rdataset_next(rdataset);
00383 dns_rdata_reset(&rdata);
00384 }
00385 if (result != ISC_R_NOMORE)
00386 goto rollback;
00387
00388 *countp = count;
00389
00390 return (ISC_R_SUCCESS);
00391
00392 rollback:
00393 INSIST(savedbuffer.used < 65536);
00394 dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
00395 *countp = 0;
00396 *target = savedbuffer;
00397
00398 return (result);
00399 }
00400
00401 static void
00402 rdataset_disassociate(dns_rdataset_t *rdataset) {
00403 UNUSED(rdataset);
00404 }
00405
00406 static isc_result_t
00407 rdataset_first(dns_rdataset_t *rdataset) {
00408 unsigned char *raw = rdataset->private3;
00409 unsigned int count;
00410
00411 count = raw[0] * 256 + raw[1];
00412 if (count == 0) {
00413 rdataset->private5 = NULL;
00414 return (ISC_R_NOMORE);
00415 }
00416 raw += 2;
00417
00418
00419
00420
00421
00422 count--;
00423 rdataset->privateuint4 = count;
00424 rdataset->private5 = raw;
00425
00426 return (ISC_R_SUCCESS);
00427 }
00428
00429 static isc_result_t
00430 rdataset_next(dns_rdataset_t *rdataset) {
00431 unsigned int count;
00432 unsigned int length;
00433 unsigned char *raw;
00434
00435 count = rdataset->privateuint4;
00436 if (count == 0)
00437 return (ISC_R_NOMORE);
00438 count--;
00439 rdataset->privateuint4 = count;
00440 raw = rdataset->private5;
00441 length = raw[0] * 256 + raw[1];
00442 raw += length + 2;
00443 rdataset->private5 = raw;
00444
00445 return (ISC_R_SUCCESS);
00446 }
00447
00448 static void
00449 rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
00450 unsigned char *raw = rdataset->private5;
00451 isc_region_t r;
00452
00453 REQUIRE(raw != NULL);
00454
00455 r.length = raw[0] * 256 + raw[1];
00456 raw += 2;
00457 r.base = raw;
00458 dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
00459 }
00460
00461 static void
00462 rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
00463 *target = *source;
00464
00465
00466
00467
00468 target->privateuint4 = 0;
00469 target->private5 = NULL;
00470 }
00471
00472 static unsigned int
00473 rdataset_count(dns_rdataset_t *rdataset) {
00474 unsigned char *raw = rdataset->private3;
00475 unsigned int count;
00476
00477 count = raw[0] * 256 + raw[1];
00478
00479 return (count);
00480 }
00481
00482 static void
00483 rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
00484 unsigned char *raw = rdataset->private3;
00485
00486 raw[-1] = (unsigned char)trust;
00487 }
00488
00489 static dns_rdatasetmethods_t rdataset_methods = {
00490 rdataset_disassociate,
00491 rdataset_first,
00492 rdataset_next,
00493 rdataset_current,
00494 rdataset_clone,
00495 rdataset_count,
00496 NULL,
00497 NULL,
00498 NULL,
00499 NULL,
00500 NULL,
00501 NULL,
00502 NULL,
00503 rdataset_settrust,
00504 NULL,
00505 NULL,
00506 NULL,
00507 NULL
00508 };
00509
00510 isc_result_t
00511 dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
00512 dns_rdatatype_t type, dns_rdataset_t *rdataset)
00513 {
00514 isc_result_t result;
00515 dns_rdata_t rdata = DNS_RDATA_INIT;
00516 isc_region_t remaining;
00517 isc_buffer_t source;
00518 dns_name_t tname;
00519 dns_rdatatype_t ttype;
00520 dns_trust_t trust = dns_trust_none;
00521 dns_rdataset_t clone;
00522
00523 REQUIRE(ncacherdataset != NULL);
00524 REQUIRE(ncacherdataset->type == 0);
00525 REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
00526 REQUIRE(name != NULL);
00527 REQUIRE(!dns_rdataset_isassociated(rdataset));
00528 REQUIRE(type != dns_rdatatype_rrsig);
00529
00530 dns_rdataset_init(&clone);
00531 dns_rdataset_clone(ncacherdataset, &clone);
00532 result = dns_rdataset_first(&clone);
00533 while (result == ISC_R_SUCCESS) {
00534 dns_rdataset_current(&clone, &rdata);
00535 isc_buffer_init(&source, rdata.data, rdata.length);
00536 isc_buffer_add(&source, rdata.length);
00537 dns_name_init(&tname, NULL);
00538 isc_buffer_remainingregion(&source, &remaining);
00539 dns_name_fromregion(&tname, &remaining);
00540 INSIST(remaining.length >= tname.length);
00541 isc_buffer_forward(&source, tname.length);
00542 remaining.length -= tname.length;
00543
00544 INSIST(remaining.length >= 3);
00545 ttype = isc_buffer_getuint16(&source);
00546
00547 if (ttype == type && dns_name_equal(&tname, name)) {
00548 trust = isc_buffer_getuint8(&source);
00549 INSIST(trust <= dns_trust_ultimate);
00550 isc_buffer_remainingregion(&source, &remaining);
00551 break;
00552 }
00553 result = dns_rdataset_next(&clone);
00554 dns_rdata_reset(&rdata);
00555 }
00556 dns_rdataset_disassociate(&clone);
00557 if (result == ISC_R_NOMORE)
00558 return (ISC_R_NOTFOUND);
00559 if (result != ISC_R_SUCCESS)
00560 return (result);
00561
00562 INSIST(remaining.length != 0);
00563
00564 rdataset->methods = &rdataset_methods;
00565 rdataset->rdclass = ncacherdataset->rdclass;
00566 rdataset->type = type;
00567 rdataset->covers = 0;
00568 rdataset->ttl = ncacherdataset->ttl;
00569 rdataset->trust = trust;
00570 rdataset->private1 = NULL;
00571 rdataset->private2 = NULL;
00572
00573 rdataset->private3 = remaining.base;
00574
00575
00576
00577
00578 rdataset->privateuint4 = 0;
00579 rdataset->private5 = NULL;
00580 rdataset->private6 = NULL;
00581 return (ISC_R_SUCCESS);
00582 }
00583
00584 isc_result_t
00585 dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
00586 dns_rdatatype_t covers, dns_rdataset_t *rdataset)
00587 {
00588 dns_name_t tname;
00589 dns_rdata_rrsig_t rrsig;
00590 dns_rdata_t rdata = DNS_RDATA_INIT;
00591 dns_rdataset_t clone;
00592 dns_rdatatype_t type;
00593 dns_trust_t trust = dns_trust_none;
00594 isc_buffer_t source;
00595 isc_region_t remaining, sigregion;
00596 isc_result_t result;
00597 unsigned char *raw;
00598 unsigned int count;
00599
00600 REQUIRE(ncacherdataset != NULL);
00601 REQUIRE(ncacherdataset->type == 0);
00602 REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
00603 REQUIRE(name != NULL);
00604 REQUIRE(!dns_rdataset_isassociated(rdataset));
00605
00606 dns_rdataset_init(&clone);
00607 dns_rdataset_clone(ncacherdataset, &clone);
00608 result = dns_rdataset_first(&clone);
00609 while (result == ISC_R_SUCCESS) {
00610 dns_rdataset_current(&clone, &rdata);
00611 isc_buffer_init(&source, rdata.data, rdata.length);
00612 isc_buffer_add(&source, rdata.length);
00613 dns_name_init(&tname, NULL);
00614 isc_buffer_remainingregion(&source, &remaining);
00615 dns_name_fromregion(&tname, &remaining);
00616 INSIST(remaining.length >= tname.length);
00617 isc_buffer_forward(&source, tname.length);
00618 remaining.length -= tname.length;
00619 remaining.base += tname.length;
00620
00621 INSIST(remaining.length >= 2);
00622 type = isc_buffer_getuint16(&source);
00623 remaining.length -= 2;
00624 remaining.base += 2;
00625
00626 if (type != dns_rdatatype_rrsig ||
00627 !dns_name_equal(&tname, name)) {
00628 result = dns_rdataset_next(&clone);
00629 dns_rdata_reset(&rdata);
00630 continue;
00631 }
00632
00633 INSIST(remaining.length >= 1);
00634 trust = isc_buffer_getuint8(&source);
00635 INSIST(trust <= dns_trust_ultimate);
00636 remaining.length -= 1;
00637 remaining.base += 1;
00638
00639 raw = remaining.base;
00640 count = raw[0] * 256 + raw[1];
00641 INSIST(count > 0);
00642 raw += 2;
00643 sigregion.length = raw[0] * 256 + raw[1];
00644 raw += 2;
00645 sigregion.base = raw;
00646 dns_rdata_reset(&rdata);
00647 dns_rdata_fromregion(&rdata, rdataset->rdclass,
00648 dns_rdatatype_rrsig, &sigregion);
00649 (void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
00650 if (rrsig.covered == covers) {
00651 isc_buffer_remainingregion(&source, &remaining);
00652 break;
00653 }
00654
00655 result = dns_rdataset_next(&clone);
00656 dns_rdata_reset(&rdata);
00657 }
00658 dns_rdataset_disassociate(&clone);
00659 if (result == ISC_R_NOMORE)
00660 return (ISC_R_NOTFOUND);
00661 if (result != ISC_R_SUCCESS)
00662 return (result);
00663
00664 INSIST(remaining.length != 0);
00665
00666 rdataset->methods = &rdataset_methods;
00667 rdataset->rdclass = ncacherdataset->rdclass;
00668 rdataset->type = dns_rdatatype_rrsig;
00669 rdataset->covers = covers;
00670 rdataset->ttl = ncacherdataset->ttl;
00671 rdataset->trust = trust;
00672 rdataset->private1 = NULL;
00673 rdataset->private2 = NULL;
00674
00675 rdataset->private3 = remaining.base;
00676
00677
00678
00679
00680 rdataset->privateuint4 = 0;
00681 rdataset->private5 = NULL;
00682 rdataset->private6 = NULL;
00683 return (ISC_R_SUCCESS);
00684 }
00685
00686 void
00687 dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
00688 dns_rdataset_t *rdataset)
00689 {
00690 dns_rdata_t rdata = DNS_RDATA_INIT;
00691 dns_trust_t trust;
00692 isc_region_t remaining, sigregion;
00693 isc_buffer_t source;
00694 dns_name_t tname;
00695 dns_rdatatype_t type;
00696 unsigned int count;
00697 dns_rdata_rrsig_t rrsig;
00698 unsigned char *raw;
00699
00700 REQUIRE(ncacherdataset != NULL);
00701 REQUIRE(ncacherdataset->type == 0);
00702 REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
00703 REQUIRE(found != NULL);
00704 REQUIRE(!dns_rdataset_isassociated(rdataset));
00705
00706 dns_rdataset_current(ncacherdataset, &rdata);
00707 isc_buffer_init(&source, rdata.data, rdata.length);
00708 isc_buffer_add(&source, rdata.length);
00709
00710 dns_name_init(&tname, NULL);
00711 isc_buffer_remainingregion(&source, &remaining);
00712 dns_name_fromregion(found, &remaining);
00713 INSIST(remaining.length >= found->length);
00714 isc_buffer_forward(&source, found->length);
00715 remaining.length -= found->length;
00716
00717 INSIST(remaining.length >= 5);
00718 type = isc_buffer_getuint16(&source);
00719 trust = isc_buffer_getuint8(&source);
00720 INSIST(trust <= dns_trust_ultimate);
00721 isc_buffer_remainingregion(&source, &remaining);
00722
00723 rdataset->methods = &rdataset_methods;
00724 rdataset->rdclass = ncacherdataset->rdclass;
00725 rdataset->type = type;
00726 if (type == dns_rdatatype_rrsig) {
00727
00728
00729
00730 raw = remaining.base;
00731 count = raw[0] * 256 + raw[1];
00732 INSIST(count > 0);
00733 raw += 2;
00734 sigregion.length = raw[0] * 256 + raw[1];
00735 raw += 2;
00736 sigregion.base = raw;
00737 dns_rdata_reset(&rdata);
00738 dns_rdata_fromregion(&rdata, rdataset->rdclass,
00739 rdataset->type, &sigregion);
00740 (void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
00741 rdataset->covers = rrsig.covered;
00742 } else
00743 rdataset->covers = 0;
00744 rdataset->ttl = ncacherdataset->ttl;
00745 rdataset->trust = trust;
00746 rdataset->private1 = NULL;
00747 rdataset->private2 = NULL;
00748
00749 rdataset->private3 = remaining.base;
00750
00751
00752
00753
00754 rdataset->privateuint4 = 0;
00755 rdataset->private5 = NULL;
00756 rdataset->private6 = NULL;
00757 }