Parcourir la source

ends0 fix and message argument rename

renamed the original MessaPtr message argument in the various process()
calls to query_message, to better reflect the content
Also fixed EDNS0 responses; fill in our own value (currently hardcoded
to 4096, we should make this configurable at some point)
added a new constant DEFAULT_MAX_EDNS0_UDPSIZE to lib/dns/message.h for
that purpose
Jelte Jansen il y a 14 ans
Parent
commit
6e4c7c07b7

+ 48 - 51
src/bin/resolver/resolver.cc

@@ -106,7 +106,6 @@ public:
     }
 
     void processNormalQuery(const Question& question,
-                            MessagePtr message,
                             MessagePtr answer_message,
                             OutputBufferPtr buffer,
                             DNSServer* server);
@@ -211,13 +210,13 @@ public:
 
     // \brief Handle the DNS Lookup
     virtual void operator()(const IOMessage& io_message,
-                            MessagePtr message,
+                            MessagePtr query_message,
                             MessagePtr answer_message,
                             OutputBufferPtr buffer,
                             DNSServer* server) const
     {
-        server_->processMessage(io_message, message, answer_message,
-                                buffer, server);
+        server_->processMessage(io_message, query_message,
+                                answer_message, buffer, server);
     }
 private:
     Resolver* server_;
@@ -230,17 +229,17 @@ private:
 class MessageAnswer : public DNSAnswer {
 public:
     virtual void operator()(const IOMessage& io_message,
-                            MessagePtr message,
+                            MessagePtr query_message,
                             MessagePtr answer_message,
                             OutputBufferPtr buffer) const
     {
-        const qid_t qid = message->getQid();
-        const bool rd = message->getHeaderFlag(Message::HEADERFLAG_RD);
-        const bool cd = message->getHeaderFlag(Message::HEADERFLAG_CD);
-        const Opcode& opcode = message->getOpcode();
-        const Rcode& rcode = message->getRcode();
+        const qid_t qid = query_message->getQid();
+        const bool rd = query_message->getHeaderFlag(Message::HEADERFLAG_RD);
+        const bool cd = query_message->getHeaderFlag(Message::HEADERFLAG_CD);
+        const Opcode& opcode = query_message->getOpcode();
+        const Rcode& rcode = query_message->getRcode();
         vector<QuestionPtr> questions;
-        questions.assign(message->beginQuestion(), message->endQuestion());
+        questions.assign(query_message->beginQuestion(), query_message->endQuestion());
 
         // Fill in the final details of the answer message
         //message->clear(Message::RENDER);
@@ -261,10 +260,23 @@ public:
         buffer->clear();
         MessageRenderer renderer(*buffer);
 
+        ConstEDNSPtr edns(query_message->getEDNS());
+        const bool dnssec_ok = edns && edns->getDNSSECAwareness();
+        if (edns) {
+            EDNSPtr edns_response(new EDNS());
+            edns_response->setDNSSECAwareness(dnssec_ok);
+
+            // TODO: We should make our own edns bufsize length configurable
+            edns_response->setUDPSize(Message::DEFAULT_MAX_EDNS0_UDPSIZE);
+            answer_message->setEDNS(edns_response);
+        }
+        
         if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
-            ConstEDNSPtr edns(message->getEDNS());
-            renderer.setLengthLimit(edns ? edns->getUDPSize() :
-                Message::DEFAULT_MAX_UDPSIZE);
+            if (edns) {
+                renderer.setLengthLimit(edns->getUDPSize());
+            } else {
+                renderer.setLengthLimit(Message::DEFAULT_MAX_UDPSIZE);
+            }
         } else {
             renderer.setLengthLimit(65535);
         }
@@ -273,7 +285,7 @@ public:
 
         dlog(string("sending a response (") +
             boost::lexical_cast<string>(renderer.getLength()) + "bytes): \n" +
-            message->toText());
+            answer_message->toText());
     }
 };
 
@@ -326,7 +338,7 @@ Resolver::getConfigSession() const {
 
 void
 Resolver::processMessage(const IOMessage& io_message,
-                         MessagePtr message,
+                         MessagePtr query_message,
                          MessagePtr answer_message,
                          OutputBufferPtr buffer,
                          DNSServer* server)
@@ -336,10 +348,10 @@ Resolver::processMessage(const IOMessage& io_message,
     // First, check the header part.  If we fail even for the base header,
     // just drop the message.
     try {
-        message->parseHeader(request_buffer);
+        query_message->parseHeader(request_buffer);
 
         // Ignore all responses.
-        if (message->getHeaderFlag(Message::HEADERFLAG_QR)) {
+        if (query_message->getHeaderFlag(Message::HEADERFLAG_QR)) {
             dlog("Received unexpected response, ignoring");
             server->resume(false);
             return;
@@ -352,53 +364,53 @@ Resolver::processMessage(const IOMessage& io_message,
 
     // Parse the message.  On failure, return an appropriate error.
     try {
-        message->fromWire(request_buffer);
+        query_message->fromWire(request_buffer);
     } catch (const DNSProtocolError& error) {
         dlog(string("returning ") + error.getRcode().toText() + ": " + 
             error.what());
-        makeErrorMessage(message, buffer, error.getRcode());
+        makeErrorMessage(query_message, buffer, error.getRcode());
         server->resume(true);
         return;
     } catch (const Exception& ex) {
         dlog(string("returning SERVFAIL: ") + ex.what());
-        makeErrorMessage(message, buffer, Rcode::SERVFAIL());
+        makeErrorMessage(query_message, buffer, Rcode::SERVFAIL());
         server->resume(true);
         return;
     } // other exceptions will be handled at a higher layer.
 
-    dlog("received a message:\n" + message->toText());
+    dlog("received a message:\n" + query_message->toText());
 
     // Perform further protocol-level validation.
     bool sendAnswer = true;
-    if (message->getOpcode() == Opcode::NOTIFY()) {
-        makeErrorMessage(message, buffer, Rcode::NOTAUTH());
+    if (query_message->getOpcode() == Opcode::NOTIFY()) {
+        makeErrorMessage(query_message, buffer, Rcode::NOTAUTH());
         dlog("Notify arrived, but we are not authoritative");
-    } else if (message->getOpcode() != Opcode::QUERY()) {
-        dlog("Unsupported opcode (got: " + message->getOpcode().toText() +
+    } else if (query_message->getOpcode() != Opcode::QUERY()) {
+        dlog("Unsupported opcode (got: " + query_message->getOpcode().toText() +
             ", expected: " + Opcode::QUERY().toText());
-        makeErrorMessage(message, buffer, Rcode::NOTIMP());
-    } else if (message->getRRCount(Message::SECTION_QUESTION) != 1) {
+        makeErrorMessage(query_message, buffer, Rcode::NOTIMP());
+    } else if (query_message->getRRCount(Message::SECTION_QUESTION) != 1) {
         dlog("The query contained " +
-            boost::lexical_cast<string>(message->getRRCount(
+            boost::lexical_cast<string>(query_message->getRRCount(
             Message::SECTION_QUESTION) + " questions, exactly one expected"));
-        makeErrorMessage(message, buffer, Rcode::FORMERR());
+        makeErrorMessage(query_message, buffer, Rcode::FORMERR());
     } else {
-        ConstQuestionPtr question = *message->beginQuestion();
+        ConstQuestionPtr question = *query_message->beginQuestion();
         const RRType &qtype = question->getType();
         if (qtype == RRType::AXFR()) {
             if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
-                makeErrorMessage(message, buffer, Rcode::FORMERR());
+                makeErrorMessage(query_message, buffer, Rcode::FORMERR());
             } else {
-                makeErrorMessage(message, buffer, Rcode::NOTIMP());
+                makeErrorMessage(query_message, buffer, Rcode::NOTIMP());
             }
         } else if (qtype == RRType::IXFR()) {
-            makeErrorMessage(message, buffer, Rcode::NOTIMP());
+            makeErrorMessage(query_message, buffer, Rcode::NOTIMP());
         } else {
             // The RecursiveQuery object will post the "resume" event to the
             // DNSServer when an answer arrives, so we don't have to do it now.
             sendAnswer = false;
-            impl_->processNormalQuery(*question, message,
-                                      answer_message, buffer, server);
+            impl_->processNormalQuery(*question, answer_message,
+                                      buffer, server);
         }
     }
 
@@ -409,27 +421,12 @@ Resolver::processMessage(const IOMessage& io_message,
 
 void
 ResolverImpl::processNormalQuery(const Question& question,
-                                 MessagePtr message,
                                  MessagePtr answer_message,
                                  OutputBufferPtr buffer,
                                  DNSServer* server)
 {
     dlog("Processing normal query");
-    ConstEDNSPtr edns(message->getEDNS());
-    const bool dnssec_ok = edns && edns->getDNSSECAwareness();
-
-    message->makeResponse();
-    message->setHeaderFlag(Message::HEADERFLAG_RA);
-    message->setRcode(Rcode::NOERROR());
-    if (edns) {
-        EDNSPtr edns_response(new EDNS());
-        edns_response->setDNSSECAwareness(dnssec_ok);
-        edns_response->setUDPSize(ResolverImpl::DEFAULT_LOCAL_UDPSIZE);
-        message->setEDNS(edns_response);
-    }
-    dlog("[XX] calling sendQuery()");
     rec_query_->sendQuery(question, answer_message, buffer, server);
-    dlog("[XX] done processing normal query");
 }
 
 namespace {

+ 1 - 1
src/bin/resolver/resolver.h

@@ -65,7 +65,7 @@ public:
     /// \param buffer Pointer to an \c OutputBuffer for the resposne
     /// \param server Pointer to the \c DNSServer
     void processMessage(const asiolink::IOMessage& io_message,
-                        isc::dns::MessagePtr message,
+                        isc::dns::MessagePtr query_message,
                         isc::dns::MessagePtr answer_message,
                         isc::dns::OutputBufferPtr buffer,
                         asiolink::DNSServer* server);

+ 0 - 1
src/lib/asiolink/asiolink.cc

@@ -428,7 +428,6 @@ public:
             InputBuffer ibuf(buffer_->getData(), buffer_->getLength());
             incoming.fromWire(ibuf);
             std::cout << "[XX] received answer: " << incoming.toText() << std::endl;
-            //
 
             if (incoming.getRcode() == Rcode::NOERROR()) {
                 if (incoming.getRRCount(Message::SECTION_ANSWER) > 0) {

+ 1 - 1
src/lib/asiolink/internal/tcpdns.h

@@ -197,7 +197,7 @@ private:
     // \c IOMessage and \c Message objects to be passed to the
     // DNS lookup and answer providers
     boost::shared_ptr<asiolink::IOMessage> io_message_;
-    isc::dns::MessagePtr message_;
+    isc::dns::MessagePtr query_message_;
     isc::dns::MessagePtr answer_message_;
 
     // The buffer into which the query packet is written

+ 5 - 1
src/lib/asiolink/internal/udpdns.h

@@ -210,7 +210,11 @@ private:
     // \c IOMessage and \c Message objects to be passed to the
     // DNS lookup and answer providers
     boost::shared_ptr<asiolink::IOMessage> io_message_;
-    isc::dns::MessagePtr message_;
+
+    // The original query as sent by the client
+    isc::dns::MessagePtr query_message_;
+
+    // The response message we are building
     isc::dns::MessagePtr answer_message_;
 
     // The buffer into which the response is written

+ 5 - 3
src/lib/asiolink/tcpdns.cc

@@ -144,7 +144,7 @@ TCPServer::operator()(error_code ec, size_t length) {
         // Reset or instantiate objects that will be needed by the
         // DNS lookup and the write call.
         respbuf_.reset(new OutputBuffer(0));
-        message_.reset(new Message(Message::PARSE));
+        query_message_.reset(new Message(Message::PARSE));
         answer_message_.reset(new Message(Message::RENDER));
 
         // Schedule a DNS lookup, and yield.  When the lookup is
@@ -160,7 +160,8 @@ TCPServer::operator()(error_code ec, size_t length) {
 
         // Call the DNS answer provider to render the answer into
         // wire format
-        (*answer_callback_)(*io_message_, message_, answer_message_, respbuf_);
+        (*answer_callback_)(*io_message_, query_message_,
+                            answer_message_, respbuf_);
 
         // Set up the response, beginning with two length bytes.
         lenbuf.writeUint16(respbuf_->getLength());
@@ -179,7 +180,8 @@ TCPServer::operator()(error_code ec, size_t length) {
 /// AsyncLookup<TCPServer> handler.)
 void
 TCPServer::asyncLookup() {
-    (*lookup_callback_)(*io_message_, message_, answer_message_, respbuf_, this);
+    (*lookup_callback_)(*io_message_, query_message_,
+                        answer_message_, respbuf_, this);
 }
 
 /// Post this coroutine on the ASIO service queue so that it will

+ 5 - 3
src/lib/asiolink/udpdns.cc

@@ -132,7 +132,7 @@ UDPServer::operator()(error_code ec, size_t length) {
         // Instantiate objects that will be needed by the
         // asynchronous DNS lookup and/or by the send call.
         respbuf_.reset(new OutputBuffer(0));
-        message_.reset(new Message(Message::PARSE));
+        query_message_.reset(new Message(Message::PARSE));
         answer_message_.reset(new Message(Message::RENDER));
 
         // Schedule a DNS lookup, and yield.  When the lookup is
@@ -150,7 +150,8 @@ UDPServer::operator()(error_code ec, size_t length) {
 
         // Call the DNS answer provider to render the answer into
         // wire format
-        (*answer_callback_)(*io_message_, message_, answer_message_, respbuf_);
+        (*answer_callback_)(*io_message_, query_message_,
+                            answer_message_, respbuf_);
 
         // Begin an asynchronous send, and then yield.  When the
         // send completes, we will resume immediately after this point
@@ -166,7 +167,8 @@ UDPServer::operator()(error_code ec, size_t length) {
 /// AsyncLookup<UDPServer> handler.)
 void
 UDPServer::asyncLookup() {
-    (*lookup_callback_)(*io_message_, message_, answer_message_, respbuf_, this);
+    (*lookup_callback_)(*io_message_, query_message_, answer_message_,
+                        respbuf_, this);
 }
 
 /// Post this coroutine on the ASIO service queue so that it will

+ 1 - 0
src/lib/dns/message.h

@@ -511,6 +511,7 @@ public:
     ///
     /// With EDNS the maximum size can be increased per message.
     static const uint16_t DEFAULT_MAX_UDPSIZE = 512;
+    static const uint16_t DEFAULT_MAX_EDNS0_UDPSIZE = 4096;
     //@}
 
 private: