diff options
author | Jelte Jansen <jelte@isc.org> | 2011-03-03 18:00:53 +0100 |
---|---|---|
committer | Jelte Jansen <jelte@isc.org> | 2011-03-03 18:00:53 +0100 |
commit | b723719cdad0da4db9b2099596c09f407dbdb135 (patch) | |
tree | 444fa34fd6572b5bab0cd0706b0c552a5943de20 /src/lib/asiolink | |
parent | [master] add asterisk for operation change; fix typo (diff) | |
download | kea-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.am | 1 | ||||
-rw-r--r-- | src/lib/asiolink/io_fetch.cc | 7 | ||||
-rw-r--r-- | src/lib/asiolink/qid_gen.cc | 62 | ||||
-rw-r--r-- | src/lib/asiolink/qid_gen.h | 74 | ||||
-rw-r--r-- | src/lib/asiolink/tests/Makefile.am | 1 | ||||
-rw-r--r-- | src/lib/asiolink/tests/qid_gen_unittest.cc | 63 |
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)); +} |