BIND 10 trac751, updated. 7bc6ee513da806b25cab12a32465122f33232128 [trac751] Move some files from asiolink library to asiodns library

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Apr 13 07:13:43 UTC 2011


The branch, trac751 has been updated
       via  7bc6ee513da806b25cab12a32465122f33232128 (commit)
      from  0eacaf1a394d3674ca73c6531aca60dd952e0e3b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 7bc6ee513da806b25cab12a32465122f33232128
Author: Ocean Wang <wanghaidong at cnnic.cn>
Date:   Wed Apr 13 15:12:33 2011 +0800

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

-----------------------------------------------------------------------

Summary of changes:
 src/lib/asiodns/Makefile.am                        |    4 +
 src/lib/{asiolink => asiodns}/README               |   29 +----
 src/lib/{asiolink => asiodns}/asiodef.cc           |   24 ++--
 src/lib/asiodns/asiodef.h                          |   23 +++
 src/lib/{asiolink => asiodns}/asiodef.msg          |    4 +-
 src/lib/asiodns/io_fetch.cc                        |   38 ++---
 src/lib/{asiolink => asiodns}/qid_gen.cc           |    8 +-
 src/lib/{asiolink => asiodns}/qid_gen.h            |    4 +-
 src/lib/asiodns/tests/Makefile.am                  |    1 +
 .../tests/qid_gen_unittest.cc                      |    8 +-
 src/lib/asiolink/Makefile.am                       |    4 -
 src/lib/asiolink/README                            |  160 --------------------
 src/lib/asiolink/asiodef.h                         |   23 ---
 src/lib/asiolink/tests/Makefile.am                 |    1 -
 14 files changed, 71 insertions(+), 260 deletions(-)
 copy src/lib/{asiolink => asiodns}/README (84%)
 rename src/lib/{asiolink => asiodns}/asiodef.cc (60%)
 create mode 100644 src/lib/asiodns/asiodef.h
 rename src/lib/{asiolink => asiodns}/asiodef.msg (98%)
 rename src/lib/{asiolink => asiodns}/qid_gen.cc (91%)
 rename src/lib/{asiolink => asiodns}/qid_gen.h (98%)
 rename src/lib/{asiolink => asiodns}/tests/qid_gen_unittest.cc (89%)
 delete mode 100644 src/lib/asiolink/asiodef.h

-----------------------------------------------------------------------
diff --git a/src/lib/asiodns/Makefile.am b/src/lib/asiodns/Makefile.am
index 04f190e..03b2bb5 100644
--- a/src/lib/asiodns/Makefile.am
+++ b/src/lib/asiodns/Makefile.am
@@ -11,12 +11,16 @@ CLEANFILES = *.gcno *.gcda
 
 lib_LTLIBRARIES = libasiodns.la
 libasiodns_la_SOURCES = dns_answer.h
+libasiodns_la_SOURCES += asiodef.cc asiodef.h
 libasiodns_la_SOURCES += dns_lookup.h
 libasiodns_la_SOURCES += dns_server.h
 libasiodns_la_SOURCES += dns_service.cc dns_service.h
 libasiodns_la_SOURCES += tcp_server.cc tcp_server.h
 libasiodns_la_SOURCES += udp_server.cc udp_server.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
 # B10_CXXFLAGS)
diff --git a/src/lib/asiodns/README b/src/lib/asiodns/README
new file mode 100644
index 0000000..596d1df
--- /dev/null
+++ b/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.
diff --git a/src/lib/asiodns/asiodef.cc b/src/lib/asiodns/asiodef.cc
new file mode 100644
index 0000000..127e848
--- /dev/null
+++ b/src/lib/asiodns/asiodef.cc
@@ -0,0 +1,39 @@
+// File created from asiodef.msg on Mon Feb 28 17:15:30 2011
+
+#include <cstddef>
+#include <log/message_types.h>
+#include <log/message_initializer.h>
+
+namespace isc {
+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 {
+
+const char* values[] = {
+    "FETCHCOMP", "upstream fetch to %s(%d) has now completed",
+    "FETCHSTOP", "upstream fetch to %s(%d) has been stopped",
+    "OPENSOCK", "error %d opening %s socket to %s(%d)",
+    "RECVSOCK", "error %d reading %s data from %s(%d)",
+    "RECVTMO", "receive timeout while waiting for data from %s(%d)",
+    "SENDSOCK", "error %d sending data using %s to %s(%d)",
+    "UNKORIGIN", "unknown origin for ASIO error code %d (protocol: %s, address %s)",
+    "UNKRESULT", "unknown result (%d) when IOFetch::stop() was executed for I/O to %s(%d)",
+    NULL
+};
+
+const isc::log::MessageInitializer initializer(values);
+
+} // Anonymous namespace
+
diff --git a/src/lib/asiodns/asiodef.h b/src/lib/asiodns/asiodef.h
new file mode 100644
index 0000000..50aa8a9
--- /dev/null
+++ b/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
diff --git a/src/lib/asiodns/asiodef.msg b/src/lib/asiodns/asiodef.msg
new file mode 100644
index 0000000..e38e6b8
--- /dev/null
+++ b/src/lib/asiodns/asiodef.msg
@@ -0,0 +1,56 @@
+# Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+$PREFIX ASIODNS_
+$NAMESPACE asiodns
+
+FETCHCOMP   upstream fetch to %s(%d) has now completed
++ A debug message, this records the the upstream fetch (a query made by the
++ resolver on behalf of its client) to the specified address has completed.
+
+FETCHSTOP   upstream fetch to %s(%d) has been stopped
++ An external component has requested the halting of an upstream fetch.  This
++ is an allowed operation, and the message should only appear if debug is
++ enabled.
+
+OPENSOCK    error %d opening %s socket to %s(%d)
++ The asynchronous I/O code encountered an error when trying to open a socket
++ of the specified protocol in order to send a message to the target address.
++ The the number of the system error that cause the problem is given in the
++ message.
+
+RECVSOCK    error %d reading %s data from %s(%d)
++ The asynchronous I/O code encountered an error when trying read data from
++ the specified address on the given protocol.  The the number of the system
++ error that cause the problem is given in the message.
+
+SENDSOCK    error %d sending data using %s to %s(%d)
++ The asynchronous I/O code encountered an error when trying send data to
++ the specified address on the given protocol.  The the number of the system
++ error that cause the problem is given in the message.
+
+RECVTMO     receive timeout while waiting for data from %s(%d)
++ An upstream fetch from the specified address timed out.  This may happen for
++ any number of reasons and is most probably a problem at the remote server
++ or a problem on the network.  The message will only appear if debug is
++ enabled.
+
+UNKORIGIN  unknown origin for ASIO error code %d (protocol: %s, address %s)
++ This message should not appear and indicates an internal error if it does.
++ Please enter a bug report.
+
+UNKRESULT  unknown result (%d) when IOFetch::stop() was executed for I/O to %s(%d)
++ The termination method of the resolver's upstream fetch class was called with
++ an unknown result code (which is given in the message).  This message should
++ not appear and may indicate an internal error.  Please enter a bug report.
diff --git a/src/lib/asiodns/io_fetch.cc b/src/lib/asiodns/io_fetch.cc
index a51d115..7a5cf2d 100644
--- a/src/lib/asiodns/io_fetch.cc
+++ b/src/lib/asiodns/io_fetch.cc
@@ -27,13 +27,10 @@
 #include <dns/opcode.h>
 #include <dns/rcode.h>
 #include <log/logger.h>
-
-#include <asiolink/qid_gen.h>
-
 #include <asio.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_asio_socket.h>
 #include <asiolink/io_endpoint.h>
@@ -42,7 +39,6 @@
 #include <asiolink/tcp_socket.h>
 #include <asiolink/udp_endpoint.h>
 #include <asiolink/udp_socket.h>
-#include <asiolink/qid_gen.h>
 
 #include "io_fetch.h"
 
@@ -149,7 +145,7 @@ struct IOFetchData {
         offset(0),
         stopped(false),
         timeout(wait),
-        origin(ASIO_UNKORIGIN),
+        origin(ASIODNS_UNKORIGIN),
         staging(),
         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
         // is synchronous (i.e. UDP operation) we bypass the yield.
-        data_->origin = ASIO_OPENSOCK;
+        data_->origin = ASIODNS_OPENSOCK;
         if (data_->socket->isOpenSynchronous()) {
             data_->socket->open(data_->remote_snd.get(), *this);
         } else {
@@ -235,10 +231,10 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
         do {
             // Begin an asynchronous send, and then yield.  When the send completes,
             // we will resume immediately after this point.
-            data_->origin = ASIO_SENDSOCK;
+            data_->origin = ASIODNS_SENDSOCK;
             CORO_YIELD data_->socket->asyncSend(data_->msgbuf->getData(),
                 data_->msgbuf->getLength(), data_->remote_snd.get(), *this);
-    
+
             // Now receive the response.  Since TCP may not receive the entire
             // message in one operation, we need to loop until we have received
             // 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
             // received all the data before copying it back to the user's buffer.
             // 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_->offset = 0;              // First data into start of 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
         // 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();
 
         /// We are done
@@ -317,7 +313,7 @@ IOFetch::stop(Result result) {
         switch (result) {
             case TIME_OUT:
                 if (logger.isDebugEnabled(1)) {
-                    logger.debug(20, ASIO_RECVTMO,
+                    logger.debug(20, ASIODNS_RECVTMO,
                                  data_->remote_snd->getAddress().toText().c_str(),
                                  static_cast<int>(data_->remote_snd->getPort()));
                 }
@@ -325,7 +321,7 @@ IOFetch::stop(Result result) {
 
             case SUCCESS:
                 if (logger.isDebugEnabled(50)) {
-                    logger.debug(30, ASIO_FETCHCOMP,
+                    logger.debug(30, ASIODNS_FETCHCOMP,
                                  data_->remote_rcv->getAddress().toText().c_str(),
                                  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
                 // allowed but as it is unusual it is logged, but with a lower
                 // 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(),
                              static_cast<int>(data_->remote_snd->getPort()));
                 break;
 
             default:
-                logger.error(ASIO_UNKRESULT, static_cast<int>(result),
+                logger.error(ASIODNS_UNKRESULT, static_cast<int>(result),
                              data_->remote_snd->getAddress().toText().c_str(),
                              static_cast<int>(data_->remote_snd->getPort()));
         }
@@ -365,10 +361,10 @@ IOFetch::stop(Result result) {
 void IOFetch::logIOFailure(asio::error_code ec) {
 
     // 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"};
     logger.error(data_->origin,
diff --git a/src/lib/asiodns/qid_gen.cc b/src/lib/asiodns/qid_gen.cc
new file mode 100644
index 0000000..f200364
--- /dev/null
+++ b/src/lib/asiodns/qid_gen.cc
@@ -0,0 +1,56 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// qid_gen defines a generator for query id's
+//
+// We probably want to merge this with the weighted random in the nsas
+// (and other parts where we need randomness, perhaps another thing
+// for a general libutil?)
+
+#include <asiodns/qid_gen.h>
+
+#include <sys/time.h>
+
+namespace {
+    isc::asiodns::QidGenerator qid_generator_instance;
+}
+
+namespace isc {
+namespace asiodns {
+
+QidGenerator&
+QidGenerator::getInstance() {
+    return (qid_generator_instance);
+}
+
+QidGenerator::QidGenerator() : dist_(0, 65535),
+                               vgen_(generator_, dist_)
+{
+    seed();
+}
+
+void
+QidGenerator::seed() {
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    generator_.seed((tv.tv_sec * 1000000) + tv.tv_usec);
+}
+
+isc::dns::qid_t
+QidGenerator::generateQid() {
+    return (vgen_());
+}
+
+} // namespace asiodns
+} // namespace isc
diff --git a/src/lib/asiodns/qid_gen.h b/src/lib/asiodns/qid_gen.h
new file mode 100644
index 0000000..bc6e2ad
--- /dev/null
+++ b/src/lib/asiodns/qid_gen.h
@@ -0,0 +1,87 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// qid_gen defines a generator for query id's
+//
+// We probably want to merge this with the weighted random in the nsas
+// (and other parts where we need randomness, perhaps another thing
+// for a general libutil?)
+
+#ifndef __QID_GEN_H
+#define __QID_GEN_H
+
+#include <dns/message.h>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/variate_generator.hpp>
+
+
+namespace isc {
+namespace asiodns {
+
+/// This class generates Qids for outgoing queries
+///
+/// It is implemented as a singleton; the public way to access it
+/// is to call getInstance()->generateQid().
+///
+/// It automatically seeds it with the current time when it is first
+/// used.
+class QidGenerator {
+public:
+    /// \brief Returns the singleton instance of the QidGenerator
+    ///
+    /// Returns a reference to the singleton instance of the generator
+    static QidGenerator& getInstance();
+
+    /// \brief Default constructor
+    ///
+    /// It is recommended that getInstance is used rather than creating
+    /// separate instances of this class.
+    ///
+    /// The constructor automatically seeds the generator with the
+    /// current time.
+    QidGenerator();
+
+    /// Generate a Qid
+    ///
+    /// \return A random Qid
+    isc::dns::qid_t generateQid();
+
+    /// \brief Seeds the QidGenerator (based on the current time)
+    ///
+    /// This is automatically called by the constructor
+    void seed();
+
+private:
+    // "Mersenne Twister: A 623-dimensionally equidistributed
+    // uniform pseudo-random number generator", Makoto Matsumoto and
+    // Takuji Nishimura, ACM Transactions on Modeling and Computer
+    // Simulation: Special Issue on Uniform Random Number Generation,
+    // Vol. 8, No. 1, January 1998, pp. 3-30.
+    //
+    // mt19937 is an implementation of one of the pseudo random
+    // generators described in this paper.
+    boost::mt19937 generator_;
+
+    // For qid's we want a uniform distribution
+    boost::uniform_int<> dist_;
+
+    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > vgen_;
+};
+
+
+} // namespace asiodns
+} // namespace isc
+
+#endif // __QID_GEN_H
diff --git a/src/lib/asiodns/tests/Makefile.am b/src/lib/asiodns/tests/Makefile.am
index 2153755..e319604 100644
--- a/src/lib/asiodns/tests/Makefile.am
+++ b/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 += dns_server_unittest.cc
 run_unittests_SOURCES += io_fetch_unittest.cc
+run_unittests_SOURCES += qid_gen_unittest.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 
diff --git a/src/lib/asiodns/tests/qid_gen_unittest.cc b/src/lib/asiodns/tests/qid_gen_unittest.cc
new file mode 100644
index 0000000..878d9a2
--- /dev/null
+++ b/src/lib/asiodns/tests/qid_gen_unittest.cc
@@ -0,0 +1,59 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+
+/// \brief Test of QidGenerator
+///
+
+#include <gtest/gtest.h>
+
+#include <asiodns/qid_gen.h>
+#include <dns/message.h>
+
+// Tests the operation of the Qid generator
+
+// Check that getInstance returns a singleton
+TEST(QidGenerator, singleton) {
+    isc::asiodns::QidGenerator& g1 = isc::asiodns::QidGenerator::getInstance();
+    isc::asiodns::QidGenerator& g2 = isc::asiodns::QidGenerator::getInstance();
+
+    EXPECT_TRUE(&g1 == &g2);
+}
+
+TEST(QidGenerator, generate) {
+    // We'll assume that boost's generator is 'good enough', and won't
+    // do full statistical checking here. Let's just call it the xkcd
+    // test (http://xkcd.com/221/), and check if three consecutive
+    // generates are not all the same.
+    isc::dns::qid_t one, two, three;
+    isc::asiodns::QidGenerator& gen = isc::asiodns::QidGenerator::getInstance();
+    one = gen.generateQid();
+    two = gen.generateQid();
+    three = gen.generateQid();
+    ASSERT_FALSE((one == two) && (one == three));
+}
diff --git a/src/lib/asiolink/Makefile.am b/src/lib/asiolink/Makefile.am
index f1afe69..07dec89 100644
--- a/src/lib/asiolink/Makefile.am
+++ b/src/lib/asiolink/Makefile.am
@@ -14,7 +14,6 @@ CLEANFILES = *.gcno *.gcda
 lib_LTLIBRARIES = libasiolink.la
 libasiolink_la_SOURCES  = asiolink.h
 libasiolink_la_SOURCES += asiolink_utilities.h
-libasiolink_la_SOURCES += asiodef.cc asiodef.h
 libasiolink_la_SOURCES += dummy_io_cb.h
 libasiolink_la_SOURCES += interval_timer.cc interval_timer.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_error.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_socket.h io_socket.cc
 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_socket.h
 
-EXTRA_DIST = asiodef.msg
-
 # Note: the ordering matters: -Wno-... must follow -Wextra (defined in
 # B10_CXXFLAGS)
 libasiolink_la_CXXFLAGS = $(AM_CXXFLAGS)
diff --git a/src/lib/asiolink/README b/src/lib/asiolink/README
index 6bd1a73..66091b1 100644
--- a/src/lib/asiolink/README
+++ b/src/lib/asiolink/README
@@ -16,167 +16,7 @@ including:
     them in only one place allows us to relax strictness here, while
     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,
 and IOAddress--are to be used by BIND 10 modules as wrappers around
 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.
diff --git a/src/lib/asiolink/asiodef.cc b/src/lib/asiolink/asiodef.cc
deleted file mode 100644
index 8e105c2..0000000
--- a/src/lib/asiolink/asiodef.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// File created from asiodef.msg on Mon Feb 28 17:15:30 2011
-
-#include <cstddef>
-#include <log/message_types.h>
-#include <log/message_initializer.h>
-
-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 isc
-
-namespace {
-
-const char* values[] = {
-    "FETCHCOMP", "upstream fetch to %s(%d) has now completed",
-    "FETCHSTOP", "upstream fetch to %s(%d) has been stopped",
-    "OPENSOCK", "error %d opening %s socket to %s(%d)",
-    "RECVSOCK", "error %d reading %s data from %s(%d)",
-    "RECVTMO", "receive timeout while waiting for data from %s(%d)",
-    "SENDSOCK", "error %d sending data using %s to %s(%d)",
-    "UNKORIGIN", "unknown origin for ASIO error code %d (protocol: %s, address %s)",
-    "UNKRESULT", "unknown result (%d) when IOFetch::stop() was executed for I/O to %s(%d)",
-    NULL
-};
-
-const isc::log::MessageInitializer initializer(values);
-
-} // Anonymous namespace
-
diff --git a/src/lib/asiolink/asiodef.h b/src/lib/asiolink/asiodef.h
deleted file mode 100644
index fdac741..0000000
--- a/src/lib/asiolink/asiodef.h
+++ /dev/null
@@ -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
diff --git a/src/lib/asiolink/asiodef.msg b/src/lib/asiolink/asiodef.msg
deleted file mode 100644
index 2fcadd1..0000000
--- a/src/lib/asiolink/asiodef.msg
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-$PREFIX ASIO_
-$NAMESPACE asiolink
-
-FETCHCOMP   upstream fetch to %s(%d) has now completed
-+ A debug message, this records the the upstream fetch (a query made by the
-+ resolver on behalf of its client) to the specified address has completed.
-
-FETCHSTOP   upstream fetch to %s(%d) has been stopped
-+ An external component has requested the halting of an upstream fetch.  This
-+ is an allowed operation, and the message should only appear if debug is
-+ enabled.
-
-OPENSOCK    error %d opening %s socket to %s(%d)
-+ The asynchronous I/O code encountered an error when trying to open a socket
-+ of the specified protocol in order to send a message to the target address.
-+ The the number of the system error that cause the problem is given in the
-+ message.
-
-RECVSOCK    error %d reading %s data from %s(%d)
-+ The asynchronous I/O code encountered an error when trying read data from
-+ the specified address on the given protocol.  The the number of the system
-+ error that cause the problem is given in the message.
-
-SENDSOCK    error %d sending data using %s to %s(%d)
-+ The asynchronous I/O code encountered an error when trying send data to
-+ the specified address on the given protocol.  The the number of the system
-+ error that cause the problem is given in the message.
-
-RECVTMO     receive timeout while waiting for data from %s(%d)
-+ An upstream fetch from the specified address timed out.  This may happen for
-+ any number of reasons and is most probably a problem at the remote server
-+ or a problem on the network.  The message will only appear if debug is
-+ enabled.
-
-UNKORIGIN  unknown origin for ASIO error code %d (protocol: %s, address %s)
-+ This message should not appear and indicates an internal error if it does.
-+ Please enter a bug report.
-
-UNKRESULT  unknown result (%d) when IOFetch::stop() was executed for I/O to %s(%d)
-+ The termination method of the resolver's upstream fetch class was called with
-+ an unknown result code (which is given in the message).  This message should
-+ not appear and may indicate an internal error.  Please enter a bug report.
diff --git a/src/lib/asiolink/qid_gen.cc b/src/lib/asiolink/qid_gen.cc
deleted file mode 100644
index 7088a11..0000000
--- a/src/lib/asiolink/qid_gen.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-// qid_gen defines a generator for query id's
-//
-// We probably want to merge this with the weighted random in the nsas
-// (and other parts where we need randomness, perhaps another thing
-// for a general libutil?)
-
-#include <asiolink/qid_gen.h>
-
-#include <sys/time.h>
-
-namespace {
-    isc::asiolink::QidGenerator qid_generator_instance;
-}
-
-namespace isc {
-namespace asiolink {
-
-QidGenerator&
-QidGenerator::getInstance() {
-    return (qid_generator_instance);
-}
-
-QidGenerator::QidGenerator() : dist_(0, 65535),
-                               vgen_(generator_, dist_)
-{
-    seed();
-}
-
-void
-QidGenerator::seed() {
-    struct timeval tv;
-    gettimeofday(&tv, 0);
-    generator_.seed((tv.tv_sec * 1000000) + tv.tv_usec);
-}
-
-isc::dns::qid_t
-QidGenerator::generateQid() {
-    return (vgen_());
-}
-
-} // namespace asiolink
-} // namespace isc
diff --git a/src/lib/asiolink/qid_gen.h b/src/lib/asiolink/qid_gen.h
deleted file mode 100644
index 466e78f..0000000
--- a/src/lib/asiolink/qid_gen.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-// qid_gen defines a generator for query id's
-//
-// We probably want to merge this with the weighted random in the nsas
-// (and other parts where we need randomness, perhaps another thing
-// for a general libutil?)
-
-#ifndef __QID_GEN_H
-#define __QID_GEN_H
-
-#include <dns/message.h>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/variate_generator.hpp>
-
-
-namespace isc {
-namespace asiolink {
-
-/// This class generates Qids for outgoing queries
-///
-/// It is implemented as a singleton; the public way to access it
-/// is to call getInstance()->generateQid().
-///
-/// It automatically seeds it with the current time when it is first
-/// used.
-class QidGenerator {
-public:
-    /// \brief Returns the singleton instance of the QidGenerator
-    ///
-    /// Returns a reference to the singleton instance of the generator
-    static QidGenerator& getInstance();
-
-    /// \brief Default constructor
-    ///
-    /// It is recommended that getInstance is used rather than creating
-    /// separate instances of this class.
-    ///
-    /// The constructor automatically seeds the generator with the
-    /// current time.
-    QidGenerator();
-
-    /// Generate a Qid
-    ///
-    /// \return A random Qid
-    isc::dns::qid_t generateQid();
-
-    /// \brief Seeds the QidGenerator (based on the current time)
-    ///
-    /// This is automatically called by the constructor
-    void seed();
-
-private:
-    // "Mersenne Twister: A 623-dimensionally equidistributed
-    // uniform pseudo-random number generator", Makoto Matsumoto and
-    // Takuji Nishimura, ACM Transactions on Modeling and Computer
-    // Simulation: Special Issue on Uniform Random Number Generation,
-    // Vol. 8, No. 1, January 1998, pp. 3-30.
-    //
-    // mt19937 is an implementation of one of the pseudo random
-    // generators described in this paper.
-    boost::mt19937 generator_;
-
-    // For qid's we want a uniform distribution
-    boost::uniform_int<> dist_;
-
-    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > vgen_;
-};
-
-
-} // namespace asiolink
-} // namespace isc
-
-#endif // __QID_GEN_H
diff --git a/src/lib/asiolink/tests/Makefile.am b/src/lib/asiolink/tests/Makefile.am
index cec9d4d..dfbd47c 100644
--- a/src/lib/asiolink/tests/Makefile.am
+++ b/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 += udp_endpoint_unittest.cc
 run_unittests_SOURCES += udp_socket_unittest.cc
-run_unittests_SOURCES += qid_gen_unittest.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 
diff --git a/src/lib/asiolink/tests/qid_gen_unittest.cc b/src/lib/asiolink/tests/qid_gen_unittest.cc
deleted file mode 100644
index 346e6f4..0000000
--- a/src/lib/asiolink/tests/qid_gen_unittest.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-
-/// \brief Test of QidGenerator
-///
-
-#include <gtest/gtest.h>
-
-#include <asiolink/qid_gen.h>
-#include <dns/message.h>
-
-// Tests the operation of the Qid generator
-
-// Check that getInstance returns a singleton
-TEST(QidGenerator, singleton) {
-    isc::asiolink::QidGenerator& g1 = isc::asiolink::QidGenerator::getInstance();
-    isc::asiolink::QidGenerator& g2 = isc::asiolink::QidGenerator::getInstance();
-
-    EXPECT_TRUE(&g1 == &g2);
-}
-
-TEST(QidGenerator, generate) {
-    // We'll assume that boost's generator is 'good enough', and won't
-    // do full statistical checking here. Let's just call it the xkcd
-    // test (http://xkcd.com/221/), and check if three consecutive
-    // generates are not all the same.
-    isc::dns::qid_t one, two, three;
-    isc::asiolink::QidGenerator& gen = isc::asiolink::QidGenerator::getInstance();
-    one = gen.generateQid();
-    two = gen.generateQid();
-    three = gen.generateQid();
-    ASSERT_FALSE((one == two) && (one == three));
-}




More information about the bind10-changes mailing list