data_source.cc 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <dns/buffer.h>
  2. #include <dns/name.h>
  3. #include <dns/rrset.h>
  4. #include <dns/message.h>
  5. #include <cc/data.h>
  6. #include "data_source.h"
  7. namespace isc {
  8. namespace dns {
  9. DSResult
  10. DataSrc::runQuery(Query q) {
  11. DSResult result;
  12. Name container(".");
  13. Message& m = q.message();
  14. while (!q.tasks().empty()) {
  15. RRsetList data, sigs;
  16. bool found = false;
  17. QueryTaskPtr task = q.tasks().front();
  18. q.tasks().pop();
  19. const DataSrc* ds = findClosestEnclosure(task->qname, container, found);
  20. if (ds == NULL) {
  21. result = ZONE_NOT_FOUND;
  22. } else if (q.wantDnssec()) {
  23. result = ds->findRRset(task->qname, task->qclass, task->qtype,
  24. data, sigs);
  25. // XXX validity check:
  26. // for now, there must only be exactly one RRset in data
  27. // and no more than one RRset in sigs. the rrtype of data
  28. // must match the sigtype of sigs, if any
  29. } else {
  30. result = ds->findRRset(task->qname, task->qclass, task->qtype,
  31. data);
  32. }
  33. switch (result) {
  34. case SUCCESS:
  35. // XXX: what if 'data' contains more than one RRset?
  36. m.addRRset(task->section, data[0]);
  37. if (q.wantDnssec() && sigs.size() == 1) {
  38. m.addRRset(Section(task->section), sigs[0]);
  39. }
  40. if (q.status() == QUERY_FINISHING) {
  41. q.setStatus(QUERY_DONE);
  42. return (SUCCESS);
  43. }
  44. // if there are no more work items, add the authority section
  45. if (q.tasks().empty() && q.status() == QUERY_INCOMPLETE) {
  46. QueryTask *qt = new QueryTask(container, task->qclass,
  47. RRType::NS(),
  48. Section::AUTHORITY());
  49. q.tasks().push(QueryTaskPtr(qt));
  50. q.setStatus(QUERY_FINISHING);
  51. }
  52. continue;
  53. case CNAME:
  54. m.addRRset(task->section, data[0]);
  55. if (q.wantDnssec() && sigs.size() == 1) {
  56. m.addRRset(Section(task->section), sigs[0]);
  57. }
  58. // if (data[0].getType() == RRType::CNAME()) {
  59. // // take apart the CNAME rdata and re-query HERE
  60. // }
  61. continue;
  62. case NAME_NOT_FOUND:
  63. q.setStatus(QUERY_NODATA);
  64. if (q.wantDnssec()) {
  65. result = ds->findRRset(container, task->qclass,
  66. RRType::SOA(), data, sigs);
  67. } else {
  68. result = ds->findRRset(container, task->qclass,
  69. RRType::SOA(), data);
  70. }
  71. if (result != SUCCESS) {
  72. m.setRcode(Rcode::SERVFAIL());
  73. return (ERROR);
  74. }
  75. m.setRcode(Rcode::NXDOMAIN());
  76. m.addRRset(Section::AUTHORITY(), data[0]);
  77. if (q.wantDnssec() && sigs.size() == 1) {
  78. m.addRRset(Section::AUTHORITY(), sigs[0]);
  79. }
  80. break;
  81. case TYPE_NOT_FOUND:
  82. m.setRcode(Rcode::NOERROR());
  83. q.setStatus(QUERY_NODATA);
  84. return (result);
  85. case ZONE_NOT_FOUND:
  86. m.setRcode(Rcode::REFUSED());
  87. q.setStatus(QUERY_NODATA);
  88. return (result);
  89. default:
  90. m.setRcode(Rcode::SERVFAIL());
  91. q.setStatus(QUERY_NODATA);
  92. return (result);
  93. }
  94. }
  95. return (result);
  96. };
  97. }
  98. }