Browse Source

[trac751] Move some files from asiolink library to asiodns library

Ocean Wang 14 years ago
parent
commit
7bc6ee513d

+ 4 - 0
src/lib/asiodns/Makefile.am

@@ -11,12 +11,16 @@ CLEANFILES = *.gcno *.gcda
 
 
 lib_LTLIBRARIES = libasiodns.la
 lib_LTLIBRARIES = libasiodns.la
 libasiodns_la_SOURCES = dns_answer.h
 libasiodns_la_SOURCES = dns_answer.h
+libasiodns_la_SOURCES += asiodef.cc asiodef.h
 libasiodns_la_SOURCES += dns_lookup.h
 libasiodns_la_SOURCES += dns_lookup.h
 libasiodns_la_SOURCES += dns_server.h
 libasiodns_la_SOURCES += dns_server.h
 libasiodns_la_SOURCES += dns_service.cc dns_service.h
 libasiodns_la_SOURCES += dns_service.cc dns_service.h
 libasiodns_la_SOURCES += tcp_server.cc tcp_server.h
 libasiodns_la_SOURCES += tcp_server.cc tcp_server.h
 libasiodns_la_SOURCES += udp_server.cc udp_server.h
 libasiodns_la_SOURCES += udp_server.cc udp_server.h
 libasiodns_la_SOURCES += io_fetch.cc io_fetch.h
 libasiodns_la_SOURCES += io_fetch.cc io_fetch.h
+libasiodns_la_SOURCES += qid_gen.cc qid_gen.h
+
+EXTRA_DIST = asiodef.msg
 
 
 # Note: the ordering matters: -Wno-... must follow -Wextra (defined in
 # Note: the ordering matters: -Wno-... must follow -Wextra (defined in
 # B10_CXXFLAGS)
 # B10_CXXFLAGS)

+ 157 - 0
src/lib/asiodns/README

@@ -0,0 +1,157 @@
+The asiodns library is intended to provide an abstraction layer between
+BIND10 modules and asiolink library.
+
+These DNS server and client routines are written using the "stackless
+coroutine" pattern invented by Chris Kohlhoff and described at
+http://blog.think-async.com/2010/03/potted-guide-to-stackless-coroutines.html.
+This is intended to simplify development a bit, since it allows the
+routines to be written in a straightfowrard step-step-step fashion rather
+than as a complex chain of separate handler functions.
+
+Coroutine objects (i.e., UDPServer, TCPServer and IOFetch) are objects
+with reenterable operator() members.  When an instance of one of these
+classes is called as a function, it resumes at the position where it left
+off.  Thus, a UDPServer can issue an asynchronous I/O call and specify
+itself as the handler object; when the call completes, the UDPServer
+carries on at the same position.  As a result, the code can look as
+if it were using synchronous, not asynchronous, I/O, providing some of
+the benefit of threading but with minimal switching overhead.
+
+So, in simplified form, the behavior of a DNS Server is:
+
+  REENTER:
+    while true:
+      YIELD packet = read_packet
+      FORK
+      if not parent:
+        break
+
+    # This callback informs the caller that a packet has arrived, and
+    # gives it a chance to update configuration, etc
+    SimpleCallback(packet)
+    YIELD answer = DNSLookup(packet, this)
+    response = DNSAnswer(answer)
+    YIELD send(response)
+
+At each "YIELD" point, the coroutine initiates an asynchronous operation,
+then pauses and turns over control to some other task on the ASIO service
+queue.  When the operation completes, the coroutine resumes.
+
+DNSLookup, DNSAnswer and SimpleCallback define callback methods
+used by a DNS Server to communicate with the module that called it.
+They are abstract-only classes whose concrete implementations
+are supplied by the calling module.
+
+The DNSLookup callback always runs asynchronously.  Concrete
+implementations must be sure to call the server's "resume" method when
+it is finished.
+
+In an authoritative server, the DNSLookup implementation would examine
+the query, look up the answer, then call "resume".  (See the diagram
+in doc/auth_process.jpg.)
+
+In a recursive server, the DNSLookup impelemtation would initiate a
+DNSQuery, which in turn would be responsible for calling the server's
+"resume" method.  (See the diagram in doc/recursive_process.jpg.)
+
+A DNSQuery object is intended to handle resolution of a query over
+the network when the local authoritative data sources or cache are not
+sufficient.  The plan is that it will make use of subsidiary DNSFetch
+calls to get data from particular authoritative servers, and when it has
+gotten a complete answer, it calls "resume".
+
+In current form, however, DNSQuery is much simpler; it forwards queries
+to a single upstream resolver and passes the answers back to the client.
+It is constructed with the address of the forward server.  Queries are
+initiated with the question to ask the forward server, a buffer into
+which to write the answer, and a pointer to the coroutine to be resumed
+when the answer has arrived.  In simplified form, the DNSQuery routine is:
+
+  REENTER:
+    render the question into a wire-format query packet
+    YIELD send(query)
+    YIELD response = read_packet
+    server->resume
+
+Currently, DNSQuery is only implemented for UDP queries.  In future work
+it will be necessary to write code to fall back to TCP when circumstances
+require it.
+
+
+Upstream Fetches
+================
+Upstream fetches (queries by the resolver on behalf of a client) are made
+using a slightly-modified version of the pattern described above.
+
+Sockets
+-------
+First, it will be useful to understand the class hierarchy used in the
+fetch logic:
+
+        IOSocket
+           |
+      IOAsioSocket
+           |
+     +-----+-----+                
+     |           |
+UDPSocket    TCPSocket
+
+IOSocket is a wrapper class for a socket and is used by the authoritative
+server code.  It is an abstract base class, providing little more that the ability to hold the socket and to return the protocol in use.
+
+Built on this is IOAsioSocket, which adds the open, close, asyncSend and
+asyncReceive methods.  This is a template class, which takes as template
+argument the class of the object that will be used as the callback when the
+asynchronous operation completes. This object can be of any type, but must
+include an operator() method with the signature:
+
+   operator()(asio::error_code ec, size_t length)
+
+... the two arguments being the status of the completed I/O operation and
+the number of bytes transferred. (In the case of the open method, the second
+argument will be zero.)
+
+Finally, the TCPSocket and UDPSocket classes provide the body of the
+asynchronous operations.
+
+Fetch Sequence
+--------------
+The fetch is implemented by the IOFetch class, which takes as argument the
+protocol to use.  The sequence is:
+
+  REENTER:
+    render the question into a wire-format query packet
+    open()                           // Open socket and optionally connect
+    if (! synchronous) {
+        YIELD;
+    }
+    YIELD asyncSend(query)           // Send query 
+    do {
+        YIELD asyncReceive(response) // Read response
+    } while (! complete(response))
+    close()                          // Drop connection and close socket
+    server->resume
+
+The open() method opens a socket for use.  On TCP, it also makes a
+connection to the remote end.  So under UDP the operation will complete
+immediately, but under TCP it could take a long time.  One solution would be
+for the open operation to post an event to the I/O queue; then both cases
+could be regarded as being equivalent, with the completion being signalled
+by the posting of the completion event.  However UDP is the most common case
+and that would involve extra overhead.  So the open() returns a status
+indicating whether the operation completed asynchronously.  If it did, the
+code yields back to the coroutine; if not the yield is bypassed.
+
+The asynchronous send is straightforward, invoking the underlying ASIO
+function.  (Note that the address/port is supplied to both the open() and
+asyncSend() methods - it is used by the TCPSocket in open() and by the
+UDPSocket in asyncSend().)
+
+The asyncReceive() method issues an asynchronous read and waits for completion.
+The fetch object keeps track of the amount of data received so far and when
+the receive completes it calls a method on the socket to determine if the
+entire message has been received.  (This will always be the case for UDP.  On
+TCP though, the message is preceded by a count field as several reads may be
+required to read all the data.)  The fetch loops until all the data is read.
+
+Finally, the socket is closed and the server called to resume operation.

+ 12 - 12
src/lib/asiolink/asiodef.cc

@@ -5,18 +5,18 @@
 #include <log/message_initializer.h>
 #include <log/message_initializer.h>
 
 
 namespace isc {
 namespace isc {
-namespace asiolink {
-
-extern const isc::log::MessageID ASIO_FETCHCOMP = "FETCHCOMP";
-extern const isc::log::MessageID ASIO_FETCHSTOP = "FETCHSTOP";
-extern const isc::log::MessageID ASIO_OPENSOCK = "OPENSOCK";
-extern const isc::log::MessageID ASIO_RECVSOCK = "RECVSOCK";
-extern const isc::log::MessageID ASIO_RECVTMO = "RECVTMO";
-extern const isc::log::MessageID ASIO_SENDSOCK = "SENDSOCK";
-extern const isc::log::MessageID ASIO_UNKORIGIN = "UNKORIGIN";
-extern const isc::log::MessageID ASIO_UNKRESULT = "UNKRESULT";
-
-} // namespace asiolink
+namespace asiodns {
+
+extern const isc::log::MessageID ASIODNS_FETCHCOMP = "FETCHCOMP";
+extern const isc::log::MessageID ASIODNS_FETCHSTOP = "FETCHSTOP";
+extern const isc::log::MessageID ASIODNS_OPENSOCK = "OPENSOCK";
+extern const isc::log::MessageID ASIODNS_RECVSOCK = "RECVSOCK";
+extern const isc::log::MessageID ASIODNS_RECVTMO = "RECVTMO";
+extern const isc::log::MessageID ASIODNS_SENDSOCK = "SENDSOCK";
+extern const isc::log::MessageID ASIODNS_UNKORIGIN = "UNKORIGIN";
+extern const isc::log::MessageID ASIODNS_UNKRESULT = "UNKRESULT";
+
+} // namespace asiodns
 } // namespace isc
 } // namespace isc
 
 
 namespace {
 namespace {

+ 23 - 0
src/lib/asiodns/asiodef.h

@@ -0,0 +1,23 @@
+// File created from asiodef.msg on Mon Feb 28 17:15:30 2011
+
+#ifndef __ASIODEF_H
+#define __ASIODEF_H
+
+#include <log/message_types.h>
+
+namespace isc {
+namespace asiodns {
+
+extern const isc::log::MessageID ASIODNS_FETCHCOMP;
+extern const isc::log::MessageID ASIODNS_FETCHSTOP;
+extern const isc::log::MessageID ASIODNS_OPENSOCK;
+extern const isc::log::MessageID ASIODNS_RECVSOCK;
+extern const isc::log::MessageID ASIODNS_RECVTMO;
+extern const isc::log::MessageID ASIODNS_SENDSOCK;
+extern const isc::log::MessageID ASIODNS_UNKORIGIN;
+extern const isc::log::MessageID ASIODNS_UNKRESULT;
+
+} // namespace asiodns
+} // namespace isc
+
+#endif // __ASIODEF_H

+ 2 - 2
src/lib/asiolink/asiodef.msg

@@ -12,8 +12,8 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 # PERFORMANCE OF THIS SOFTWARE.
 
 
-$PREFIX ASIO_
-$NAMESPACE asiolink
+$PREFIX ASIODNS_
+$NAMESPACE asiodns
 
 
 FETCHCOMP   upstream fetch to %s(%d) has now completed
 FETCHCOMP   upstream fetch to %s(%d) has now completed
 + A debug message, this records the the upstream fetch (a query made by the
 + A debug message, this records the the upstream fetch (a query made by the

+ 17 - 21
src/lib/asiodns/io_fetch.cc

@@ -27,13 +27,10 @@
 #include <dns/opcode.h>
 #include <dns/opcode.h>
 #include <dns/rcode.h>
 #include <dns/rcode.h>
 #include <log/logger.h>
 #include <log/logger.h>
-
-#include <asiolink/qid_gen.h>
-
 #include <asio.hpp>
 #include <asio.hpp>
 #include <asio/deadline_timer.hpp>
 #include <asio/deadline_timer.hpp>
-
-#include <asiolink/asiodef.h>
+#include <asiodns/qid_gen.h>
+#include <asiodns/asiodef.h>
 #include <asiolink/io_address.h>
 #include <asiolink/io_address.h>
 #include <asiolink/io_asio_socket.h>
 #include <asiolink/io_asio_socket.h>
 #include <asiolink/io_endpoint.h>
 #include <asiolink/io_endpoint.h>
@@ -42,7 +39,6 @@
 #include <asiolink/tcp_socket.h>
 #include <asiolink/tcp_socket.h>
 #include <asiolink/udp_endpoint.h>
 #include <asiolink/udp_endpoint.h>
 #include <asiolink/udp_socket.h>
 #include <asiolink/udp_socket.h>
-#include <asiolink/qid_gen.h>
 
 
 #include "io_fetch.h"
 #include "io_fetch.h"
 
 
@@ -149,7 +145,7 @@ struct IOFetchData {
         offset(0),
         offset(0),
         stopped(false),
         stopped(false),
         timeout(wait),
         timeout(wait),
-        origin(ASIO_UNKORIGIN),
+        origin(ASIODNS_UNKORIGIN),
         staging(),
         staging(),
         qid(QidGenerator::getInstance().generateQid())
         qid(QidGenerator::getInstance().generateQid())
     {}
     {}
@@ -225,7 +221,7 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
 
 
         // Open a connection to the target system.  For speed, if the operation
         // Open a connection to the target system.  For speed, if the operation
         // is synchronous (i.e. UDP operation) we bypass the yield.
         // is synchronous (i.e. UDP operation) we bypass the yield.
-        data_->origin = ASIO_OPENSOCK;
+        data_->origin = ASIODNS_OPENSOCK;
         if (data_->socket->isOpenSynchronous()) {
         if (data_->socket->isOpenSynchronous()) {
             data_->socket->open(data_->remote_snd.get(), *this);
             data_->socket->open(data_->remote_snd.get(), *this);
         } else {
         } else {
@@ -235,10 +231,10 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
         do {
         do {
             // Begin an asynchronous send, and then yield.  When the send completes,
             // Begin an asynchronous send, and then yield.  When the send completes,
             // we will resume immediately after this point.
             // we will resume immediately after this point.
-            data_->origin = ASIO_SENDSOCK;
+            data_->origin = ASIODNS_SENDSOCK;
             CORO_YIELD data_->socket->asyncSend(data_->msgbuf->getData(),
             CORO_YIELD data_->socket->asyncSend(data_->msgbuf->getData(),
                 data_->msgbuf->getLength(), data_->remote_snd.get(), *this);
                 data_->msgbuf->getLength(), data_->remote_snd.get(), *this);
-    
+
             // Now receive the response.  Since TCP may not receive the entire
             // Now receive the response.  Since TCP may not receive the entire
             // message in one operation, we need to loop until we have received
             // message in one operation, we need to loop until we have received
             // it. (This can't be done within the asyncReceive() method because
             // it. (This can't be done within the asyncReceive() method because
@@ -257,8 +253,8 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
             // the expected amount of data.  Then we need to loop until we have
             // the expected amount of data.  Then we need to loop until we have
             // received all the data before copying it back to the user's buffer.
             // received all the data before copying it back to the user's buffer.
             // And we want to minimise the amount of copying...
             // And we want to minimise the amount of copying...
-    
-            data_->origin = ASIO_RECVSOCK;
+
+            data_->origin = ASIODNS_RECVSOCK;
             data_->cumulative = 0;          // No data yet received
             data_->cumulative = 0;          // No data yet received
             data_->offset = 0;              // First data into start of buffer
             data_->offset = 0;              // First data into start of buffer
             data_->received->clear();       // Clear the receive buffer
             data_->received->clear();       // Clear the receive buffer
@@ -274,7 +270,7 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
 
 
         // Finished with this socket, so close it.  This will not generate an
         // Finished with this socket, so close it.  This will not generate an
         // I/O error, but reset the origin to unknown in case we change this.
         // I/O error, but reset the origin to unknown in case we change this.
-        data_->origin = ASIO_UNKORIGIN;
+        data_->origin = ASIODNS_UNKORIGIN;
         data_->socket->close();
         data_->socket->close();
 
 
         /// We are done
         /// We are done
@@ -317,7 +313,7 @@ IOFetch::stop(Result result) {
         switch (result) {
         switch (result) {
             case TIME_OUT:
             case TIME_OUT:
                 if (logger.isDebugEnabled(1)) {
                 if (logger.isDebugEnabled(1)) {
-                    logger.debug(20, ASIO_RECVTMO,
+                    logger.debug(20, ASIODNS_RECVTMO,
                                  data_->remote_snd->getAddress().toText().c_str(),
                                  data_->remote_snd->getAddress().toText().c_str(),
                                  static_cast<int>(data_->remote_snd->getPort()));
                                  static_cast<int>(data_->remote_snd->getPort()));
                 }
                 }
@@ -325,7 +321,7 @@ IOFetch::stop(Result result) {
 
 
             case SUCCESS:
             case SUCCESS:
                 if (logger.isDebugEnabled(50)) {
                 if (logger.isDebugEnabled(50)) {
-                    logger.debug(30, ASIO_FETCHCOMP,
+                    logger.debug(30, ASIODNS_FETCHCOMP,
                                  data_->remote_rcv->getAddress().toText().c_str(),
                                  data_->remote_rcv->getAddress().toText().c_str(),
                                  static_cast<int>(data_->remote_rcv->getPort()));
                                  static_cast<int>(data_->remote_rcv->getPort()));
                 }
                 }
@@ -335,13 +331,13 @@ IOFetch::stop(Result result) {
                 // Fetch has been stopped for some other reason.  This is
                 // Fetch has been stopped for some other reason.  This is
                 // allowed but as it is unusual it is logged, but with a lower
                 // allowed but as it is unusual it is logged, but with a lower
                 // debug level than a timeout (which is totally normal).
                 // debug level than a timeout (which is totally normal).
-                logger.debug(1, ASIO_FETCHSTOP,
+                logger.debug(1, ASIODNS_FETCHSTOP,
                              data_->remote_snd->getAddress().toText().c_str(),
                              data_->remote_snd->getAddress().toText().c_str(),
                              static_cast<int>(data_->remote_snd->getPort()));
                              static_cast<int>(data_->remote_snd->getPort()));
                 break;
                 break;
 
 
             default:
             default:
-                logger.error(ASIO_UNKRESULT, static_cast<int>(result),
+                logger.error(ASIODNS_UNKRESULT, static_cast<int>(result),
                              data_->remote_snd->getAddress().toText().c_str(),
                              data_->remote_snd->getAddress().toText().c_str(),
                              static_cast<int>(data_->remote_snd->getPort()));
                              static_cast<int>(data_->remote_snd->getPort()));
         }
         }
@@ -365,10 +361,10 @@ IOFetch::stop(Result result) {
 void IOFetch::logIOFailure(asio::error_code ec) {
 void IOFetch::logIOFailure(asio::error_code ec) {
 
 
     // Should only get here with a known error code.
     // Should only get here with a known error code.
-    assert((data_->origin == ASIO_OPENSOCK) ||
-           (data_->origin == ASIO_SENDSOCK) ||
-           (data_->origin == ASIO_RECVSOCK) ||
-           (data_->origin == ASIO_UNKORIGIN));
+    assert((data_->origin == ASIODNS_OPENSOCK) ||
+           (data_->origin == ASIODNS_SENDSOCK) ||
+           (data_->origin == ASIODNS_RECVSOCK) ||
+           (data_->origin == ASIODNS_UNKORIGIN));
 
 
     static const char* PROTOCOL[2] = {"TCP", "UDP"};
     static const char* PROTOCOL[2] = {"TCP", "UDP"};
     logger.error(data_->origin,
     logger.error(data_->origin,

+ 4 - 4
src/lib/asiolink/qid_gen.cc

@@ -18,16 +18,16 @@
 // (and other parts where we need randomness, perhaps another thing
 // (and other parts where we need randomness, perhaps another thing
 // for a general libutil?)
 // for a general libutil?)
 
 
-#include <asiolink/qid_gen.h>
+#include <asiodns/qid_gen.h>
 
 
 #include <sys/time.h>
 #include <sys/time.h>
 
 
 namespace {
 namespace {
-    isc::asiolink::QidGenerator qid_generator_instance;
+    isc::asiodns::QidGenerator qid_generator_instance;
 }
 }
 
 
 namespace isc {
 namespace isc {
-namespace asiolink {
+namespace asiodns {
 
 
 QidGenerator&
 QidGenerator&
 QidGenerator::getInstance() {
 QidGenerator::getInstance() {
@@ -52,5 +52,5 @@ QidGenerator::generateQid() {
     return (vgen_());
     return (vgen_());
 }
 }
 
 
-} // namespace asiolink
+} // namespace asiodns
 } // namespace isc
 } // namespace isc

+ 2 - 2
src/lib/asiolink/qid_gen.h

@@ -28,7 +28,7 @@
 
 
 
 
 namespace isc {
 namespace isc {
-namespace asiolink {
+namespace asiodns {
 
 
 /// This class generates Qids for outgoing queries
 /// This class generates Qids for outgoing queries
 ///
 ///
@@ -81,7 +81,7 @@ private:
 };
 };
 
 
 
 
-} // namespace asiolink
+} // namespace asiodns
 } // namespace isc
 } // namespace isc
 
 
 #endif // __QID_GEN_H
 #endif // __QID_GEN_H

+ 1 - 0
src/lib/asiodns/tests/Makefile.am

@@ -21,6 +21,7 @@ run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
 run_unittests_SOURCES += io_service_unittest.cc
 run_unittests_SOURCES += io_service_unittest.cc
 run_unittests_SOURCES += dns_server_unittest.cc
 run_unittests_SOURCES += dns_server_unittest.cc
 run_unittests_SOURCES += io_fetch_unittest.cc
 run_unittests_SOURCES += io_fetch_unittest.cc
+run_unittests_SOURCES += qid_gen_unittest.cc
 
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 
 

+ 4 - 4
src/lib/asiolink/tests/qid_gen_unittest.cc

@@ -32,15 +32,15 @@
 
 
 #include <gtest/gtest.h>
 #include <gtest/gtest.h>
 
 
-#include <asiolink/qid_gen.h>
+#include <asiodns/qid_gen.h>
 #include <dns/message.h>
 #include <dns/message.h>
 
 
 // Tests the operation of the Qid generator
 // Tests the operation of the Qid generator
 
 
 // Check that getInstance returns a singleton
 // Check that getInstance returns a singleton
 TEST(QidGenerator, singleton) {
 TEST(QidGenerator, singleton) {
-    isc::asiolink::QidGenerator& g1 = isc::asiolink::QidGenerator::getInstance();
-    isc::asiolink::QidGenerator& g2 = isc::asiolink::QidGenerator::getInstance();
+    isc::asiodns::QidGenerator& g1 = isc::asiodns::QidGenerator::getInstance();
+    isc::asiodns::QidGenerator& g2 = isc::asiodns::QidGenerator::getInstance();
 
 
     EXPECT_TRUE(&g1 == &g2);
     EXPECT_TRUE(&g1 == &g2);
 }
 }
@@ -51,7 +51,7 @@ TEST(QidGenerator, generate) {
     // test (http://xkcd.com/221/), and check if three consecutive
     // test (http://xkcd.com/221/), and check if three consecutive
     // generates are not all the same.
     // generates are not all the same.
     isc::dns::qid_t one, two, three;
     isc::dns::qid_t one, two, three;
-    isc::asiolink::QidGenerator& gen = isc::asiolink::QidGenerator::getInstance();
+    isc::asiodns::QidGenerator& gen = isc::asiodns::QidGenerator::getInstance();
     one = gen.generateQid();
     one = gen.generateQid();
     two = gen.generateQid();
     two = gen.generateQid();
     three = gen.generateQid();
     three = gen.generateQid();

+ 0 - 4
src/lib/asiolink/Makefile.am

@@ -14,7 +14,6 @@ CLEANFILES = *.gcno *.gcda
 lib_LTLIBRARIES = libasiolink.la
 lib_LTLIBRARIES = libasiolink.la
 libasiolink_la_SOURCES  = asiolink.h
 libasiolink_la_SOURCES  = asiolink.h
 libasiolink_la_SOURCES += asiolink_utilities.h
 libasiolink_la_SOURCES += asiolink_utilities.h
-libasiolink_la_SOURCES += asiodef.cc asiodef.h
 libasiolink_la_SOURCES += dummy_io_cb.h
 libasiolink_la_SOURCES += dummy_io_cb.h
 libasiolink_la_SOURCES += interval_timer.cc interval_timer.h
 libasiolink_la_SOURCES += interval_timer.cc interval_timer.h
 libasiolink_la_SOURCES += io_address.cc io_address.h
 libasiolink_la_SOURCES += io_address.cc io_address.h
@@ -22,7 +21,6 @@ libasiolink_la_SOURCES += io_asio_socket.h
 libasiolink_la_SOURCES += io_endpoint.cc io_endpoint.h
 libasiolink_la_SOURCES += io_endpoint.cc io_endpoint.h
 libasiolink_la_SOURCES += io_error.h
 libasiolink_la_SOURCES += io_error.h
 libasiolink_la_SOURCES += io_message.h
 libasiolink_la_SOURCES += io_message.h
-libasiolink_la_SOURCES += qid_gen.cc qid_gen.h
 libasiolink_la_SOURCES += io_service.h io_service.cc
 libasiolink_la_SOURCES += io_service.h io_service.cc
 libasiolink_la_SOURCES += io_socket.h io_socket.cc
 libasiolink_la_SOURCES += io_socket.h io_socket.cc
 libasiolink_la_SOURCES += simple_callback.h
 libasiolink_la_SOURCES += simple_callback.h
@@ -31,8 +29,6 @@ libasiolink_la_SOURCES += tcp_socket.h
 libasiolink_la_SOURCES += udp_endpoint.h
 libasiolink_la_SOURCES += udp_endpoint.h
 libasiolink_la_SOURCES += udp_socket.h
 libasiolink_la_SOURCES += udp_socket.h
 
 
-EXTRA_DIST = asiodef.msg
-
 # Note: the ordering matters: -Wno-... must follow -Wextra (defined in
 # Note: the ordering matters: -Wno-... must follow -Wextra (defined in
 # B10_CXXFLAGS)
 # B10_CXXFLAGS)
 libasiolink_la_CXXFLAGS = $(AM_CXXFLAGS)
 libasiolink_la_CXXFLAGS = $(AM_CXXFLAGS)

+ 0 - 160
src/lib/asiolink/README

@@ -16,167 +16,7 @@ including:
     them in only one place allows us to relax strictness here, while
     them in only one place allows us to relax strictness here, while
     leaving it in place elsewhere.
     leaving it in place elsewhere.
 
 
-Currently, the asiolink library only supports DNS servers (i.e., b10-auth
-and b10-resolver).  The plan is to make it more generic and allow it to
-support other modules as well.
-
 Some of the classes defined here--for example, IOSocket, IOEndpoint,
 Some of the classes defined here--for example, IOSocket, IOEndpoint,
 and IOAddress--are to be used by BIND 10 modules as wrappers around
 and IOAddress--are to be used by BIND 10 modules as wrappers around
 ASIO-specific classes.
 ASIO-specific classes.
 
 
-Other classes implement the DNS protocol on behalf of BIND 10 modules.
-
-These DNS server and client routines are written using the "stackless
-coroutine" pattern invented by Chris Kohlhoff and described at
-http://blog.think-async.com/2010/03/potted-guide-to-stackless-coroutines.html.
-This is intended to simplify development a bit, since it allows the
-routines to be written in a straightfowrard step-step-step fashion rather
-than as a complex chain of separate handler functions.
-
-Coroutine objects (i.e., UDPServer, TCPServer and IOFetch) are objects
-with reenterable operator() members.  When an instance of one of these
-classes is called as a function, it resumes at the position where it left
-off.  Thus, a UDPServer can issue an asynchronous I/O call and specify
-itself as the handler object; when the call completes, the UDPServer
-carries on at the same position.  As a result, the code can look as
-if it were using synchronous, not asynchronous, I/O, providing some of
-the benefit of threading but with minimal switching overhead.
-
-So, in simplified form, the behavior of a DNS Server is:
-
-  REENTER:
-    while true:
-      YIELD packet = read_packet
-      FORK
-      if not parent:
-        break
-
-    # This callback informs the caller that a packet has arrived, and
-    # gives it a chance to update configuration, etc
-    SimpleCallback(packet)
-    YIELD answer = DNSLookup(packet, this)
-    response = DNSAnswer(answer)
-    YIELD send(response)
-
-At each "YIELD" point, the coroutine initiates an asynchronous operation,
-then pauses and turns over control to some other task on the ASIO service
-queue.  When the operation completes, the coroutine resumes.
-
-DNSLookup, DNSAnswer and SimpleCallback define callback methods
-used by a DNS Server to communicate with the module that called it.
-They are abstract-only classes whose concrete implementations
-are supplied by the calling module.
-
-The DNSLookup callback always runs asynchronously.  Concrete
-implementations must be sure to call the server's "resume" method when
-it is finished.
-
-In an authoritative server, the DNSLookup implementation would examine
-the query, look up the answer, then call "resume".  (See the diagram
-in doc/auth_process.jpg.)
-
-In a recursive server, the DNSLookup impelemtation would initiate a
-DNSQuery, which in turn would be responsible for calling the server's
-"resume" method.  (See the diagram in doc/recursive_process.jpg.)
-
-A DNSQuery object is intended to handle resolution of a query over
-the network when the local authoritative data sources or cache are not
-sufficient.  The plan is that it will make use of subsidiary DNSFetch
-calls to get data from particular authoritative servers, and when it has
-gotten a complete answer, it calls "resume".
-
-In current form, however, DNSQuery is much simpler; it forwards queries
-to a single upstream resolver and passes the answers back to the client.
-It is constructed with the address of the forward server.  Queries are
-initiated with the question to ask the forward server, a buffer into
-which to write the answer, and a pointer to the coroutine to be resumed
-when the answer has arrived.  In simplified form, the DNSQuery routine is:
-
-  REENTER:
-    render the question into a wire-format query packet
-    YIELD send(query)
-    YIELD response = read_packet
-    server->resume
-
-Currently, DNSQuery is only implemented for UDP queries.  In future work
-it will be necessary to write code to fall back to TCP when circumstances
-require it.
-
-
-Upstream Fetches
-================
-Upstream fetches (queries by the resolver on behalf of a client) are made
-using a slightly-modified version of the pattern described above.
-
-Sockets
--------
-First, it will be useful to understand the class hierarchy used in the
-fetch logic:
-
-        IOSocket
-           |
-      IOAsioSocket
-           |
-     +-----+-----+                
-     |           |
-UDPSocket    TCPSocket
-
-IOSocket is a wrapper class for a socket and is used by the authoritative
-server code.  It is an abstract base class, providing little more that the ability to hold the socket and to return the protocol in use.
-
-Built on this is IOAsioSocket, which adds the open, close, asyncSend and
-asyncReceive methods.  This is a template class, which takes as template
-argument the class of the object that will be used as the callback when the
-asynchronous operation completes. This object can be of any type, but must
-include an operator() method with the signature:
-
-   operator()(asio::error_code ec, size_t length)
-
-... the two arguments being the status of the completed I/O operation and
-the number of bytes transferred. (In the case of the open method, the second
-argument will be zero.)
-
-Finally, the TCPSocket and UDPSocket classes provide the body of the
-asynchronous operations.
-
-Fetch Sequence
---------------
-The fetch is implemented by the IOFetch class, which takes as argument the
-protocol to use.  The sequence is:
-
-  REENTER:
-    render the question into a wire-format query packet
-    open()                           // Open socket and optionally connect
-    if (! synchronous) {
-        YIELD;
-    }
-    YIELD asyncSend(query)           // Send query 
-    do {
-        YIELD asyncReceive(response) // Read response
-    } while (! complete(response))
-    close()                          // Drop connection and close socket
-    server->resume
-
-The open() method opens a socket for use.  On TCP, it also makes a
-connection to the remote end.  So under UDP the operation will complete
-immediately, but under TCP it could take a long time.  One solution would be
-for the open operation to post an event to the I/O queue; then both cases
-could be regarded as being equivalent, with the completion being signalled
-by the posting of the completion event.  However UDP is the most common case
-and that would involve extra overhead.  So the open() returns a status
-indicating whether the operation completed asynchronously.  If it did, the
-code yields back to the coroutine; if not the yield is bypassed.
-
-The asynchronous send is straightforward, invoking the underlying ASIO
-function.  (Note that the address/port is supplied to both the open() and
-asyncSend() methods - it is used by the TCPSocket in open() and by the
-UDPSocket in asyncSend().)
-
-The asyncReceive() method issues an asynchronous read and waits for completion.
-The fetch object keeps track of the amount of data received so far and when
-the receive completes it calls a method on the socket to determine if the
-entire message has been received.  (This will always be the case for UDP.  On
-TCP though, the message is preceded by a count field as several reads may be
-required to read all the data.)  The fetch loops until all the data is read.
-
-Finally, the socket is closed and the server called to resume operation.

+ 0 - 23
src/lib/asiolink/asiodef.h

@@ -1,23 +0,0 @@
-// File created from asiodef.msg on Mon Feb 28 17:15:30 2011
-
-#ifndef __ASIODEF_H
-#define __ASIODEF_H
-
-#include <log/message_types.h>
-
-namespace isc {
-namespace asiolink {
-
-extern const isc::log::MessageID ASIO_FETCHCOMP;
-extern const isc::log::MessageID ASIO_FETCHSTOP;
-extern const isc::log::MessageID ASIO_OPENSOCK;
-extern const isc::log::MessageID ASIO_RECVSOCK;
-extern const isc::log::MessageID ASIO_RECVTMO;
-extern const isc::log::MessageID ASIO_SENDSOCK;
-extern const isc::log::MessageID ASIO_UNKORIGIN;
-extern const isc::log::MessageID ASIO_UNKRESULT;
-
-} // namespace asiolink
-} // namespace isc
-
-#endif // __ASIODEF_H

+ 0 - 1
src/lib/asiolink/tests/Makefile.am

@@ -27,7 +27,6 @@ run_unittests_SOURCES += tcp_endpoint_unittest.cc
 run_unittests_SOURCES += tcp_socket_unittest.cc
 run_unittests_SOURCES += tcp_socket_unittest.cc
 run_unittests_SOURCES += udp_endpoint_unittest.cc
 run_unittests_SOURCES += udp_endpoint_unittest.cc
 run_unittests_SOURCES += udp_socket_unittest.cc
 run_unittests_SOURCES += udp_socket_unittest.cc
-run_unittests_SOURCES += qid_gen_unittest.cc
 
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)