Parcourir la source

move code around a little
moved the current skeleton logic up into runningquery, where we do have context

Jelte Jansen il y a 14 ans
Parent
commit
d2a4816b05
3 fichiers modifiés avec 87 ajouts et 69 suppressions
  1. 2 0
      src/bin/resolver/resolver.cc
  2. 85 2
      src/lib/asiolink/asiolink.cc
  3. 0 67
      src/lib/asiolink/udpdns.cc

+ 2 - 0
src/bin/resolver/resolver.cc

@@ -438,7 +438,9 @@ ResolverImpl::processNormalQuery(const Question& question, MessagePtr message,
         edns_response->setUDPSize(ResolverImpl::DEFAULT_LOCAL_UDPSIZE);
         message->setEDNS(edns_response);
     }
+    dlog("[XX] calling sendQuery()");
     rec_query_->sendQuery(question, buffer, server);
+    dlog("[XX] done processing normal query");
 }
 
 namespace {

+ 85 - 2
src/lib/asiolink/asiolink.cc

@@ -32,6 +32,7 @@
 
 #include <dns/buffer.h>
 #include <dns/message.h>
+#include <dns/rcode.h>
 
 #include <asiolink/asiolink.h>
 #include <asiolink/internal/tcpdns.h>
@@ -39,6 +40,7 @@
 
 #include <log/dummylog.h>
 
+
 using namespace asio;
 using asio::ip::udp;
 using asio::ip::tcp;
@@ -50,6 +52,8 @@ using namespace boost;
 
 namespace asiolink {
 
+typedef pair<string, uint16_t> addr_t;
+
 class IOServiceImpl {
 private:
     IOServiceImpl(const IOService& source);
@@ -298,6 +302,8 @@ private:
 
     // Info for (re)sending the query (the question and destination)
     Question question_;
+    // currently we use upstream as the current list of NS records
+    // we should differentiate between forwarding and resolving
     shared_ptr<AddressVector> upstream_;
 
     // Buffer to store the result.
@@ -314,6 +320,15 @@ private:
     int timeout_;
     unsigned retries_;
 
+    // normal query state
+    // XXX hold CNAME info here
+
+    // if we change this to running and add a sent, we can do
+    // decoupled timeouts i think
+    bool done;
+    
+
+
     // (re)send the query to the server.
     void send() {
         const int uc = upstream_->size();
@@ -343,18 +358,86 @@ public:
         timeout_(timeout),
         retries_(retries)
     {
+        done = false;
         send();
     }
 
     // This function is used as callback from DNSQuery.
     virtual void operator()(UDPQuery::Result result) {
+        dlog("[XX] RunningQuery operator() called with result: " + result);
+        // XXX is this the place for TCP retry?
         if (result == UDPQuery::TIME_OUT && retries_ --) {
             dlog("Resending query");
             // We timed out, but we have some retries, so send again
             send();
         } else {
-            server_->resume(result == UDPQuery::SUCCESS);
-            delete this;
+            // we got an answer
+            std::cout << "[XX] for question: " << question_.toText() << std::endl;
+            Message incoming(Message::PARSE);
+            InputBuffer ibuf(buffer_->getData(), buffer_->getLength());
+            incoming.fromWire(ibuf);
+            std::cout << "[XX] i received answer: " << incoming.toText() << std::endl;
+            //
+
+            if (incoming.getRcode() == Rcode::NOERROR()) {
+                if (incoming.getRRCount(Message::SECTION_ANSWER) > 0) {
+                    dlog("[XX] this looks like the final result");
+                    done = true;
+                } else {
+                    dlog("[XX] this looks like a delegation");
+                    // ok we need to do some more processing.
+                    // the ns list should contain all nameservers
+                    // while the additional may contain addresses for
+                    // them.
+                    // this needs to tie into NSAS of course
+                    // for this very first mockup, hope there is an
+                    // address in additional and just use that
+    
+                    // send query to the addresses in the delegation
+                    bool found_address = false;
+                    upstream_->clear();
+
+                    for (RRsetIterator rrsi = incoming.beginSection(Message::SECTION_ADDITIONAL);
+                         rrsi != incoming.endSection(Message::SECTION_ADDITIONAL) && !found_address;
+                         rrsi++) {
+                        ConstRRsetPtr rrs = *rrsi;
+                        if (rrs->getType() == RRType::A()) {
+                            // found address
+                            RdataIteratorPtr rdi = rrs->getRdataIterator();
+                            // just use the first for now
+                            if (!rdi->isLast()) {
+                                std::string addr_str = rdi->getCurrent().toText();
+                                dlog("[XX] first address found: " + addr_str);
+                                // now we have one address, simply
+                                // resend that exact same query
+                                // to that address and yield, when it
+                                // returns, loop again.
+                                //ip::address addr =
+                                
+                                upstream_->push_back(addr_t(addr_str, 53));
+                                found_address = true;
+                            }
+                        }
+                    }
+                    if (found_address) {
+                        // next resolver round
+                        buffer_->clear();
+                        send();
+                    } else {
+                        dlog("[XX] no ready-made addresses in additional. need nsas.");
+                        // this will result in answering with the delegation. oh well
+                        done = true;
+                    }
+                }
+            } else {
+                done = true;
+            }
+            
+            if (done) {
+                std::cerr << "[XX] Done or error, returning to server" << std::endl;
+                server_->resume(result == UDPQuery::SUCCESS);
+                delete this;
+            }
         }
     }
 };

+ 0 - 67
src/lib/asiolink/udpdns.cc

@@ -235,7 +235,6 @@ UDPQuery::operator()(error_code ec, size_t length) {
     if (ec || data_->stopped) {
         return;
     }
-    bool done = false;
 
     CORO_REENTER (this) {
         /// Generate the upstream query and render it to wire format
@@ -266,7 +265,6 @@ UDPQuery::operator()(error_code ec, size_t length) {
                 TIME_OUT));
         }
 
-    while (!done) {
         // Begin an asynchronous send, and then yield.  When the
         // send completes, we will resume immediately after this point.
         CORO_YIELD data_->socket.async_send_to(buffer(data_->msgbuf->getData(),
@@ -283,71 +281,6 @@ UDPQuery::operator()(error_code ec, size_t length) {
         // The message is not rendered yet, so we can't print it easilly
         dlog("Received response from " + data_->remote.address().to_string());
 
-        // Initial naive resolver:
-        // The answer may be one of
-        // - the final result
-        // - a delegation
-        // - an error
-        // (there are more options but this is a start)
-        Message incoming(Message::PARSE);
-        InputBuffer ibuf(data_->data.get(), length);
-        incoming.fromWire(ibuf);
-        if (incoming.getRcode() == Rcode::NOERROR()) {
-            if (incoming.getRRCount(Message::SECTION_ANSWER) > 0) {
-                dlog("[XX] this looks like the final result");
-                // stop and copy the full data (with the code we
-                // already had, by providing the current buffer to
-                // the answerprovider (we should revisit that part)
-                done = true;
-            } else {
-                dlog("[XX] this looks like a delegation");
-                // ok we need to do some more processing.
-                // the ns list should contain all nameservers
-                // while the additional may contain addresses for
-                // them.
-                // this needs to tie into NSAS of course
-                // for this very first mockup, hope there is an
-                // address in additional and just use that
-
-                // send query to the first address
-                bool found_address = false;
-                for (RRsetIterator rrsi = incoming.beginSection(Message::SECTION_ADDITIONAL);
-                     rrsi != incoming.endSection(Message::SECTION_ADDITIONAL) && !found_address;
-                     rrsi++) {
-                    ConstRRsetPtr rrs = *rrsi;
-                    if (rrs->getType() == RRType::A()) {
-                        // found address
-                        RdataIteratorPtr rdi = rrs->getRdataIterator();
-                        // just use the first
-                        if (!rdi->isLast()) {
-                            std::string addr_str = rdi->getCurrent().toText();
-                            dlog("[XX] first address found: " + addr_str);
-                            // now we have one address, simply
-                            // resend that exact same query
-                            // to that address and yield, when it
-                            // returns, loop again.
-                            //ip::address addr = 
-                            data_->remote.address(ip::address::from_string(addr_str));
-                            found_address = true;
-                        }
-                    }
-                }
-                if (found_address) {
-                    // restart loop
-                } else {
-                    dlog("[XX] no ready-made addresses in additional. need nsas.");
-                    // this will result in answering with the delegation. oh well
-                    done = true;
-                }
-            }
-        } else if (false) {
-            dlog("[XX] this looks like an error");
-            // like for a final answer, stop and pass on the
-            // last buffer for now.
-            done = true;
-        }
-    }
-
         /// Copy the answer into the response buffer.  (XXX: If the
         /// OutputBuffer object were made to meet the requirements of
         /// a MutableBufferSequence, then it could be written to directly