123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- #include <dns/buffer.h>
- #include <dns/name.h>
- #include <dns/rrset.h>
- #include <dns/message.h>
- #include <cc/data.h>
- #include "data_source.h"
- namespace isc {
- namespace dns {
- DSResult
- DataSrc::runQuery(Query q) {
- DSResult result;
- Name container(".");
- Message& m = q.message();
- while (!q.tasks().empty()) {
- RRsetList data, sigs;
- bool found = false;
- QueryTaskPtr task = q.tasks().front();
- q.tasks().pop();
- const DataSrc* ds = findClosestEnclosure(task->qname, container, found);
- if (ds == NULL) {
- result = ZONE_NOT_FOUND;
- } else if (q.wantDnssec()) {
- result = ds->findRRset(task->qname, task->qclass, task->qtype,
- data, sigs);
- // XXX validity check:
- // for now, there must only be exactly one RRset in data
- // and no more than one RRset in sigs. the rrtype of data
- // must match the sigtype of sigs, if any
- } else {
- result = ds->findRRset(task->qname, task->qclass, task->qtype,
- data);
- }
- switch (result) {
- case SUCCESS:
- // XXX: what if 'data' contains more than one RRset?
- m.addRRset(task->section, data[0]);
- if (q.wantDnssec() && sigs.size() == 1) {
- m.addRRset(Section(task->section), sigs[0]);
- }
- if (q.status() == QUERY_FINISHING) {
- q.setStatus(QUERY_DONE);
- return (SUCCESS);
- }
- // if there are no more work items, add the authority section
- if (q.tasks().empty() && q.status() == QUERY_INCOMPLETE) {
- QueryTask *qt = new QueryTask(container, task->qclass,
- RRType::NS(),
- Section::AUTHORITY());
- q.tasks().push(QueryTaskPtr(qt));
- q.setStatus(QUERY_FINISHING);
- }
- continue;
- case CNAME:
- m.addRRset(task->section, data[0]);
- if (q.wantDnssec() && sigs.size() == 1) {
- m.addRRset(Section(task->section), sigs[0]);
- }
- // if (data[0].getType() == RRType::CNAME()) {
- // // take apart the CNAME rdata and re-query HERE
- // }
- continue;
- case NAME_NOT_FOUND:
- q.setStatus(QUERY_NODATA);
- if (q.wantDnssec()) {
- result = ds->findRRset(container, task->qclass,
- RRType::SOA(), data, sigs);
- } else {
- result = ds->findRRset(container, task->qclass,
- RRType::SOA(), data);
- }
- if (result != SUCCESS) {
- m.setRcode(Rcode::SERVFAIL());
- return (ERROR);
- }
- m.setRcode(Rcode::NXDOMAIN());
- m.addRRset(Section::AUTHORITY(), data[0]);
- if (q.wantDnssec() && sigs.size() == 1) {
- m.addRRset(Section::AUTHORITY(), sigs[0]);
- }
- break;
- case TYPE_NOT_FOUND:
- m.setRcode(Rcode::NOERROR());
- q.setStatus(QUERY_NODATA);
- return (result);
- case ZONE_NOT_FOUND:
- m.setRcode(Rcode::REFUSED());
- q.setStatus(QUERY_NODATA);
- return (result);
- default:
- m.setRcode(Rcode::SERVFAIL());
- q.setStatus(QUERY_NODATA);
- return (result);
- }
- }
- return (result);
- };
- }
- }
|