data_source.cc 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <dns/cpp/buffer.h>
  2. #include <dns/cpp/name.h>
  3. #include <dns/cpp/rrset.h>
  4. #include <dns/cpp/message.h>
  5. #include <cc/cpp/data.h>
  6. #include "data_source.h"
  7. namespace isc {
  8. namespace dns {
  9. DSResult
  10. DataSrc::runQuery(Query q) {
  11. DSResult result;
  12. RRsetList data, sigs;
  13. Name container(".");
  14. Message& m = q.message();
  15. while (!q.tasks().empty()) {
  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. m.addRRset(task->section, data[0]);
  36. if (q.wantDnssec() && sigs.size() == 1) {
  37. m.addRRset(Section(task->section), sigs[0]);
  38. }
  39. if (q.status() == QUERY_FINISHING) {
  40. q.setStatus(QUERY_DONE);
  41. return (SUCCESS);
  42. }
  43. // if there are no more work items, add the authority section
  44. if (q.tasks().empty() && q.status() == QUERY_INCOMPLETE) {
  45. QueryTask *qt = new QueryTask(container, task->qclass,
  46. RRType::NS(),
  47. Section::AUTHORITY());
  48. q.tasks().push(QueryTaskPtr(qt));
  49. q.setStatus(QUERY_FINISHING);
  50. }
  51. continue;
  52. case CNAME:
  53. m.addRRset(task->section, data[0]);
  54. if (q.wantDnssec() && sigs.size() == 1) {
  55. m.addRRset(Section(task->section), sigs[0]);
  56. }
  57. // if (data[0].getType() == RRType::CNAME()) {
  58. // // take apart the CNAME rdata and re-query HERE
  59. // }
  60. continue;
  61. case NAME_NOT_FOUND:
  62. q.setStatus(QUERY_NODATA);
  63. if (q.wantDnssec()) {
  64. result = ds->findRRset(container, task->qclass,
  65. RRType::SOA(), data, sigs);
  66. } else {
  67. result = ds->findRRset(container, task->qclass,
  68. RRType::SOA(), data);
  69. }
  70. if (result != SUCCESS) {
  71. m.setRcode(Rcode::SERVFAIL());
  72. return (ERROR);
  73. }
  74. m.setRcode(Rcode::NXDOMAIN());
  75. m.addRRset(Section::AUTHORITY(), data[0]);
  76. if (q.wantDnssec() && sigs.size() == 1) {
  77. m.addRRset(Section::AUTHORITY(), sigs[0]);
  78. }
  79. break;
  80. case TYPE_NOT_FOUND:
  81. m.setRcode(Rcode::NOERROR());
  82. q.setStatus(QUERY_NODATA);
  83. return (result);
  84. case ZONE_NOT_FOUND:
  85. m.setRcode(Rcode::REFUSED());
  86. q.setStatus(QUERY_NODATA);
  87. return (result);
  88. default:
  89. m.setRcode(Rcode::SERVFAIL());
  90. q.setStatus(QUERY_NODATA);
  91. return (result);
  92. }
  93. }
  94. return (result);
  95. };
  96. }
  97. }