summaryrefslogtreecommitdiffstats
path: root/src/lib/asiolink
diff options
context:
space:
mode:
authorJelte Jansen <jelte@isc.org>2011-03-03 18:00:53 +0100
committerJelte Jansen <jelte@isc.org>2011-03-03 18:00:53 +0100
commitb723719cdad0da4db9b2099596c09f407dbdb135 (patch)
tree444fa34fd6572b5bab0cd0706b0c552a5943de20 /src/lib/asiolink
parent[master] add asterisk for operation change; fix typo (diff)
downloadkea-b723719cdad0da4db9b2099596c09f407dbdb135.tar.xz
kea-b723719cdad0da4db9b2099596c09f407dbdb135.zip
[trac583] Added a qid_gen for random qids
Simple uniform random number generator using boost. At this moment, it is in asiolink, because that is where it is used. It should be moved to a lib/util (or something), together with the non-uniform nsas rng. Also note that IOFetch now *sets* a random qid, but does not actually check it when it receives an answer.
Diffstat (limited to 'src/lib/asiolink')
-rw-r--r--src/lib/asiolink/Makefile.am1
-rw-r--r--src/lib/asiolink/io_fetch.cc7
-rw-r--r--src/lib/asiolink/qid_gen.cc62
-rw-r--r--src/lib/asiolink/qid_gen.h74
-rw-r--r--src/lib/asiolink/tests/Makefile.am1
-rw-r--r--src/lib/asiolink/tests/qid_gen_unittest.cc63
6 files changed, 206 insertions, 2 deletions
diff --git a/src/lib/asiolink/Makefile.am b/src/lib/asiolink/Makefile.am
index b3968f0661..b0ce027ee2 100644
--- a/src/lib/asiolink/Makefile.am
+++ b/src/lib/asiolink/Makefile.am
@@ -35,6 +35,7 @@ libasiolink_la_SOURCES += tcp_socket.h
libasiolink_la_SOURCES += udp_endpoint.h
libasiolink_la_SOURCES += udp_server.h udp_server.cc
libasiolink_la_SOURCES += udp_socket.h
+libasiolink_la_SOURCES += qid_gen.cc qid_gen.h
# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
# B10_CXXFLAGS)
libasiolink_la_CXXFLAGS = $(AM_CXXFLAGS)
diff --git a/src/lib/asiolink/io_fetch.cc b/src/lib/asiolink/io_fetch.cc
index d1f722cf86..0711bb939d 100644
--- a/src/lib/asiolink/io_fetch.cc
+++ b/src/lib/asiolink/io_fetch.cc
@@ -26,6 +26,8 @@
#include <dns/rcode.h>
#include <log/dummylog.h>
+#include <asiolink/qid_gen.h>
+
#include <asio.hpp>
#include <asiolink/io_fetch.h>
@@ -34,8 +36,9 @@ using namespace isc::dns;
using namespace isc::log;
using namespace std;
-namespace asiolink {
+
+namespace asiolink {
/// IOFetch Constructor - just initialize the private data
IOFetch::IOFetch(int protocol, IOService& service,
@@ -65,7 +68,7 @@ IOFetch::operator()(error_code ec, size_t length) {
Message msg(Message::RENDER);
// TODO: replace with boost::random or some other suitable PRNG
- msg.setQid(0);
+ msg.setQid(QidGenerator::getInstance()->generateQid());
msg.setOpcode(Opcode::QUERY());
msg.setRcode(Rcode::NOERROR());
msg.setHeaderFlag(Message::HEADERFLAG_RD);
diff --git a/src/lib/asiolink/qid_gen.cc b/src/lib/asiolink/qid_gen.cc
new file mode 100644
index 0000000000..c570ee14dd
--- /dev/null
+++ b/src/lib/asiolink/qid_gen.cc
@@ -0,0 +1,62 @@
+// 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 {
+ asiolink::QidGenerator* qid_generator_instance = NULL;
+}
+
+namespace asiolink {
+QidGenerator*
+QidGenerator::getInstance() {
+ if (!qid_generator_instance) {
+ qid_generator_instance = new QidGenerator();
+ qid_generator_instance->seed();
+ }
+
+ return qid_generator_instance;
+}
+
+void
+QidGenerator::cleanInstance() {
+ delete qid_generator_instance;
+ qid_generator_instance = NULL;
+}
+
+QidGenerator::QidGenerator() : dist(0, 65535), vgen(generator, dist) {}
+
+void
+QidGenerator::seed() {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ long int seed;
+ seed = (tv.tv_sec * 1000000) + tv.tv_usec;
+ generator.seed(seed);
+}
+
+isc::dns::qid_t
+QidGenerator::generateQid() {
+ return vgen();
+}
+
+} // namespace asiolink
diff --git a/src/lib/asiolink/qid_gen.h b/src/lib/asiolink/qid_gen.h
new file mode 100644
index 0000000000..89fd506554
--- /dev/null
+++ b/src/lib/asiolink/qid_gen.h
@@ -0,0 +1,74 @@
+// 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_
+#define __QID_GEN_
+
+#include <dns/message.h>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/variate_generator.hpp>
+
+
+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
+ ///
+ /// Initializes a new instance if there is none.
+ static QidGenerator* getInstance();
+
+ /// \brief Cleans up the singleton instance.
+ ///
+ /// This is added so that we can run memory checkers and
+ /// not get complaints about leaking data. If getInstance()
+ /// is called after cleanInstance, a new one would be created.
+ static void cleanInstance();
+
+ /// 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 when getInstance() is called
+ /// the first time.
+ void seed();
+
+private:
+ QidGenerator();
+ boost::mt19937 generator;
+ boost::uniform_int<> dist;
+ boost::variate_generator<boost::mt19937&, boost::uniform_int<> > vgen;
+};
+
+
+} // namespace asiolink
+
+#endif // __QID_GEN_
diff --git a/src/lib/asiolink/tests/Makefile.am b/src/lib/asiolink/tests/Makefile.am
index b4f0a87739..ba5d962e98 100644
--- a/src/lib/asiolink/tests/Makefile.am
+++ b/src/lib/asiolink/tests/Makefile.am
@@ -27,6 +27,7 @@ run_unittests_SOURCES += interval_timer_unittest.cc
run_unittests_SOURCES += recursive_query_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
new file mode 100644
index 0000000000..aa315828f7
--- /dev/null
+++ b/src/lib/asiolink/tests/qid_gen_unittest.cc
@@ -0,0 +1,63 @@
+// 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) {
+ asiolink::QidGenerator* g1 = asiolink::QidGenerator::getInstance();
+ asiolink::QidGenerator* g2 = asiolink::QidGenerator::getInstance();
+
+ EXPECT_TRUE(g1 == g2);
+
+ asiolink::QidGenerator::cleanInstance();
+ // Is there any way to make sure a newly allocated one gets
+ // a new address?
+}
+
+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;
+ asiolink::QidGenerator* gen = asiolink::QidGenerator::getInstance();
+ one = gen->generateQid();
+ two = gen->generateQid();
+ three = gen->generateQid();
+ ASSERT_FALSE((one == two) && (one == three));
+}