BIND 10 jinmei-l1cache, updated. d50629199527eadba57ac1f942ce7860e08bfcea [jinmei-l1cache] Merge branch 'jinmei-l1cache' of ssh://git.bind10.isc.org/var/bind10/git/bind10 into jinmei-l1cache
BIND 10 source code commits
bind10-changes at lists.isc.org
Sun Feb 24 01:14:20 UTC 2013
The branch, jinmei-l1cache has been updated
via d50629199527eadba57ac1f942ce7860e08bfcea (commit)
via 0a9f692b2445a19fa500b49923b7e76d83294f6e (commit)
via a2c332f61a556303f529e4f030b8eb408561aab9 (commit)
via 35ee9722b76603915786e026e8db8cc5648b8a43 (commit)
from afc6223cd09f2ce4823589b236c8cf758ec7df33 (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 d50629199527eadba57ac1f942ce7860e08bfcea
Merge: 0a9f692 afc6223
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Sat Feb 23 17:14:02 2013 -0800
[jinmei-l1cache] Merge branch 'jinmei-l1cache' of ssh://git.bind10.isc.org/var/bind10/git/bind10 into jinmei-l1cache
commit 0a9f692b2445a19fa500b49923b7e76d83294f6e
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Sat Feb 23 17:13:22 2013 -0800
[jinmei-l1cache] some more detailed logs
commit a2c332f61a556303f529e4f030b8eb408561aab9
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Sat Feb 23 17:12:22 2013 -0800
[jinmei-l1cache] supported measuring network IO overhead
commit 35ee9722b76603915786e026e8db8cc5648b8a43
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Sat Feb 23 17:11:58 2013 -0800
[jinmei-l1cache] some more simplification
-----------------------------------------------------------------------
Summary of changes:
src/bin/dnsl1cache/dnsl1cache_messages.mes | 2 +-
.../dnsl1cache/l1cache/benchmarks/query_bench.cc | 158 ++++++++++++++++++--
src/bin/dnsl1cache/l1cache/l1hash.cc | 15 +-
src/bin/dnsl1cache/l1cache/message_handler.cc | 27 ++--
4 files changed, 179 insertions(+), 23 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/dnsl1cache/dnsl1cache_messages.mes b/src/bin/dnsl1cache/dnsl1cache_messages.mes
index 912d49e..c34191d 100644
--- a/src/bin/dnsl1cache/dnsl1cache_messages.mes
+++ b/src/bin/dnsl1cache/dnsl1cache_messages.mes
@@ -32,7 +32,7 @@ $NAMESPACE isc::dnsl1cache
% DNSL1CACHE_CACHE_INSTALLED DNS cache installation completed
-% DNSL1CACHE_CACHE_TABLE_CREATED DNS cache table created with %1 entries
+% DNSL1CACHE_CACHE_TABLE_CREATED DNS cache table created with %1 entries, average message size=%2, max bucket size=%3
% DNSL1CACHE_RESPONSE_RECEIVED received response message, ignoring
diff --git a/src/bin/dnsl1cache/l1cache/benchmarks/query_bench.cc b/src/bin/dnsl1cache/l1cache/benchmarks/query_bench.cc
index 978dd88..4e53355 100644
--- a/src/bin/dnsl1cache/l1cache/benchmarks/query_bench.cc
+++ b/src/bin/dnsl1cache/l1cache/benchmarks/query_bench.cc
@@ -17,6 +17,8 @@
#include <bench/benchmark.h>
#include <bench/benchmark_util.h>
+#include <exceptions/exceptions.h>
+
#include <dnsl1cache/l1cache/message_handler.h>
#include <dnsl1cache/l1cache/l1hash.h>
@@ -38,11 +40,19 @@
#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
+#include <cassert>
+#include <cerrno>
#include <cstdlib>
+#include <cstring>
#include <ctime>
#include <iostream>
#include <vector>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+
using namespace isc::dnsl1cache;
using namespace isc::dns;
using namespace isc::bench;
@@ -76,7 +86,8 @@ public:
QueryBenchMark(DNSL1HashTable* cache_table, const BenchQueries& queries,
Message& query_message, OutputBuffer& buffer,
bool debug, size_t expected_rate, bool do_rotate,
- bool use_scatter_send) :
+ bool use_scatter_send, int sock, const sockaddr* sa,
+ socklen_t salen) :
msg_handler_(new MessageHandler),
queries_(queries),
query_message_(query_message),
@@ -88,10 +99,13 @@ public:
53210))),
debug_(debug), now_(std::time(NULL)), total_count_(0),
expected_rate_(expected_rate),
- buffers_(use_scatter_send ? &buffers_storage_ : NULL)
+ buffers_(use_scatter_send ? &buffers_storage_ : NULL),
+ sock_(sock), sa_(sa), salen_(salen)
{
msg_handler_->setCache(cache_table);
msg_handler_->setRRRotation(do_rotate);
+ std::memset(&mh_, 0, sizeof(mh_));
+ mh_.msg_iov = iov_;
}
public:
unsigned int run() {
@@ -110,9 +124,31 @@ public:
if (buffers_) {
buffers_->clear();
}
+ if (sock_ != -1) {
+ socklen_t salen = sizeof(ss_);
+ recvfrom(sock_, buf_, sizeof(buf_), 0,
+ static_cast<sockaddr*>(static_cast<void*>(&ss_)),
+ &salen);
+ }
msg_handler_->process(io_message, query_message_, buffer_,
&server, now_, buffers_);
-
+ if (sock_ != -1) {
+ if (buffers_) {
+ mh_.msg_name = const_cast<sockaddr*>(sa_);
+ mh_.msg_namelen = salen_;
+ mh_.msg_iovlen = buffers_->size();
+ Buffers::iterator iter = buffers_->begin();
+ Buffers::iterator const iter_end = buffers_->end();
+ for (int i = 0; iter != iter_end; ++iter, ++i) {
+ iov_[i].iov_base = const_cast<void*>(iter->first);
+ iov_[i].iov_len = iter->second;
+ }
+ sendmsg(sock_, &mh_, 0);
+ } else {
+ sendto(sock_, buffer_.getData(), buffer_.getLength(), 0,
+ sa_, salen_);
+ }
+ }
if (debug_) {
response_message_->clear(Message::PARSE);
InputBuffer ib(buffer_.getData(), buffer_.getLength());
@@ -136,20 +172,97 @@ private:
std::time_t now_;
size_t total_count_;
const size_t expected_rate_;
- std::vector<isc::asiodns::DNSLookup::Buffer> buffers_storage_;
- std::vector<isc::asiodns::DNSLookup::Buffer>* buffers_;
+ typedef std::vector<isc::asiodns::DNSLookup::Buffer> Buffers;
+ Buffers buffers_storage_;
+ Buffers* buffers_;
+ char buf_[512]; // dummy buffer for recvfrom
+ msghdr mh_;
+ iovec iov_[64];
+ const int sock_;
+ struct sockaddr_storage ss_;
+ const sockaddr* const sa_;
+ const socklen_t salen_;
};
+class BenchmarkError : public isc::Exception {
+public:
+ BenchmarkError(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
+int
+networkSetup(const char* addr, const char* port, const char* local_port,
+ void* sa_storage, size_t salen)
+{
+ addrinfo hints;
+ std::memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+
+ addrinfo *res;
+ const int error = getaddrinfo(addr, port, &hints, &res);
+ if (error != 0) {
+ isc_throw(BenchmarkError, "getaddrinfo failed: "
+ << gai_strerror(error));
+ }
+ assert(res->ai_addrlen <= salen);
+ std::memcpy(sa_storage, res->ai_addr, res->ai_addrlen);
+ salen = res->ai_addrlen;
+ freeaddrinfo(res);
+
+ hints.ai_flags |= AI_PASSIVE;
+ const int error2 = getaddrinfo(NULL, local_port, &hints, &res);
+ if (error2 != 0) {
+ isc_throw(BenchmarkError, "getaddrinfo for passive failed: "
+ << gai_strerror(error2));
+ }
+ int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s < 0) {
+ freeaddrinfo(res);
+ isc_throw(BenchmarkError, "failed to open socket: "
+ << std::strerror(errno));
+ }
+ if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
+ freeaddrinfo(res);
+ close(s);
+ isc_throw(BenchmarkError, "failed to bind socket: "
+ << std::strerror(errno));
+ }
+ freeaddrinfo(res);
+
+ const int on = 1;
+ if (ioctl(s, FIONBIO, &on) < 0) {
+ close(s);
+ isc_throw(BenchmarkError, "failed to make socket non-blocking: "
+ << std::strerror(errno));
+ }
+
+ return (s);
+}
+
const int ITERATION_DEFAULT = 1;
const size_t EXPECTED_RATE_DEFAULT = 50000;
+const char* const CLIENT_ADDRESS_DEFAULT = "127.0.0.1";
+const char* const CLIENT_PORT_DEFAULT = "5301";
+const char* const SERVER_PORT_DEFAULT = "5300";
void
usage() {
- std::cerr << "Usage: query_bench [-d] [-n iterations] [-r expected rate] "
- "[-R] cache_file query_datafile\n"
+ std::cerr << "Usage: query_bench [-a address] [-d] [-n iterations] [-N] "
+ "[-r expected rate] [-p port] [-P port] [-R] "
+ "cache_file query_datafile\n"
+ " -a Specify the 'client' address when -N is specified (default: "
+ << CLIENT_ADDRESS_DEFAULT << ")\n"
" -d Enable debug logging to stdout\n"
" -n Number of iterations per test case (default: "
<< ITERATION_DEFAULT << ")\n"
+ " -N Include network I/O\n"
+ " -p Specify the 'client' port when -N is specified (default: "
+ << CLIENT_PORT_DEFAULT << ")\n"
+ " -P Specify the 'server' port when -N is specified (default: "
+ << SERVER_PORT_DEFAULT << ")\n"
" -r Expected query rate/s, adjust TTL update frequency (default: "
<< EXPECTED_RATE_DEFAULT << ")\n"
" -R rotate answers\n"
@@ -169,14 +282,30 @@ main(int argc, char* argv[]) {
bool debug_log = false;
bool use_scatter_send = false;
bool do_rotate = false;
- while ((ch = getopt(argc, argv, "dn:r:Rs")) != -1) {
+ bool use_netio = false;
+ const char* client_addr = CLIENT_ADDRESS_DEFAULT;
+ const char* client_port = CLIENT_PORT_DEFAULT;
+ const char* server_port = SERVER_PORT_DEFAULT;
+ while ((ch = getopt(argc, argv, "a:dn:Nr:p:P:Rs")) != -1) {
switch (ch) {
+ case 'a':
+ client_addr = optarg;
+ break;
case 'n':
iteration = atoi(optarg);
break;
+ case 'N':
+ use_netio = true;
+ break;
case 'd':
debug_log = true;
break;
+ case 'p':
+ client_port = optarg;
+ break;
+ case 'P':
+ server_port = optarg;
+ break;
case 'r':
expected_rate = boost::lexical_cast<size_t>(optarg);
break;
@@ -204,6 +333,16 @@ main(int argc, char* argv[]) {
isc::log::MAX_DEBUG_LEVEL, NULL);
try {
+ int s = -1;
+ sockaddr_storage ss;
+ socklen_t salen = sizeof(ss);
+ const sockaddr* sa = NULL;
+ if (use_netio) {
+ s = networkSetup(client_addr, client_port, server_port, &ss,
+ salen);
+ sa = static_cast<const sockaddr*>(static_cast<const void*>(&ss));
+ }
+
BenchQueries queries;
loadQueryData(query_data_file, queries, RRClass::IN());
OutputBuffer buffer(4096);
@@ -220,7 +359,8 @@ main(int argc, char* argv[]) {
QueryBenchMark(&cache_table, queries,
message, buffer, debug_log,
expected_rate, do_rotate,
- use_scatter_send));
+ use_scatter_send, s, sa,
+ salen));
} catch (const std::exception& ex) {
cout << "Test unexpectedly failed: " << ex.what() << endl;
return (1);
diff --git a/src/bin/dnsl1cache/l1cache/l1hash.cc b/src/bin/dnsl1cache/l1cache/l1hash.cc
index 9a0f01a..363e309 100644
--- a/src/bin/dnsl1cache/l1cache/l1hash.cc
+++ b/src/bin/dnsl1cache/l1cache/l1hash.cc
@@ -72,7 +72,9 @@ namespace {
class CacheDataCreater {
public:
CacheDataCreater(const RRTTL& min_ttl) :
- rotatable_(false), min_ttl_(min_ttl), obuffer_(0) {}
+ rotatable_(false), total_msg_size_(0), min_ttl_(min_ttl), obuffer_(0)
+ {}
+
void start(const Name& qname, const RRType& qtype, const RRClass& qclass,
size_t ans_count, size_t soa_count)
{
@@ -94,6 +96,7 @@ public:
if (ans_count_ != 0 || soa_count_ != 0) {
isc_throw(DNSL1HashError, "broken cache data");
}
+ total_msg_size_ += renderer_.getLength();
}
ConstRRsetPtr adjustTTL(const RRsetPtr& rrset) {
if (rrset->getTTL() < min_ttl_) {
@@ -172,6 +175,7 @@ public:
std::vector<uint16_t> offsets_;
size_t offset0_; // offset to the pointer immediately after question
bool rotatable_;
+ size_t total_msg_size_;
private:
const RRTTL min_ttl_;
util::OutputBuffer obuffer_;
@@ -196,6 +200,7 @@ DNSL1HashTable::DNSL1HashTable(const char* cache_file, const RRTTL& min_ttl) {
std::string line, qname_str, qclass_str, qtype_str;
size_t rcode_code, ans_count, soa_count;
size_t entry_count = 0;
+ size_t max_bucket_size = 0;
while (ifs.good()) {
line.clear();
std::getline(ifs, line);
@@ -251,6 +256,9 @@ DNSL1HashTable::DNSL1HashTable(const char* cache_file, const RRTTL& min_ttl) {
std::time(NULL));
entry_buckets_[getQueryHash(labels, qtype) % N_BUCKETS].
push_back(entry);
+ max_bucket_size = std::max(
+ entry_buckets_[getQueryHash(labels, qtype) % N_BUCKETS].size(),
+ max_bucket_size);
labels.serialize(entry->getNameBuf(), name_buflen);
void* offsetp = entry->getOffsetBuf(name_buflen);
std::memcpy(offsetp, &creator.offsets_[0],
@@ -262,8 +270,9 @@ DNSL1HashTable::DNSL1HashTable(const char* cache_file, const RRTTL& min_ttl) {
assert(labels == LabelSequence(entry->getNameBuf()));
++entry_count;
}
-
- LOG_INFO(logger, DNSL1CACHE_CACHE_TABLE_CREATED).arg(entry_count);
+ LOG_INFO(logger, DNSL1CACHE_CACHE_TABLE_CREATED).arg(entry_count).
+ arg(entry_count > 0 ? creator.total_msg_size_ / entry_count : 0).
+ arg(max_bucket_size);
}
DNSL1HashEntry*
diff --git a/src/bin/dnsl1cache/l1cache/message_handler.cc b/src/bin/dnsl1cache/l1cache/message_handler.cc
index 0f186c3..9580488 100644
--- a/src/bin/dnsl1cache/l1cache/message_handler.cc
+++ b/src/bin/dnsl1cache/l1cache/message_handler.cc
@@ -49,7 +49,8 @@ namespace dnsl1cache {
class MessageHandler::MessageHandlerImpl {
public:
MessageHandlerImpl() :
- cache_table_(NULL), rotate_rr_(false), rotate_count_(0)
+ cache_table_(NULL), rotate_rr_(false), rotate_count_(0),
+ enable_query_log_(logger.isDebugEnabled(DBGLVL_TRACE_DETAIL))
{}
void process(const IOMessage& io_message, Message& message,
OutputBuffer& buffer, DNSServer* server, std::time_t now,
@@ -57,9 +58,16 @@ public:
DNSL1HashTable* cache_table_;
bool rotate_rr_;
+ void queryLog(const LabelSequence& qry_labels, const RRClass& qclass,
+ const RRType& qtype)
+ {
+ LOG_DEBUG(logger, DBGLVL_TRACE_DETAIL, DNSL1CACHE_RECEIVED_QUERY).
+ arg(qry_labels).arg(qclass).arg(qtype);
+ }
private:
uint8_t labels_buf_[LabelSequence::MAX_SERIALIZED_LENGTH];
size_t rotate_count_; // for RR rotation
+ const bool enable_query_log_;
};
inline uint32_t
@@ -106,12 +114,13 @@ MessageHandler::MessageHandlerImpl::process(
}
const LabelSequence qry_labels(request_buffer, labels_buf_);
- const RRType qtype(request_buffer);
- const RRClass qclass(request_buffer);
- LOG_DEBUG(logger, DBGLVL_TRACE_DETAIL, DNSL1CACHE_RECEIVED_QUERY).
- arg(qry_labels).arg(qclass).arg(qtype);
+ const RRType qtype(request_buffer.readUint16());
+ const RRClass qclass(request_buffer.readUint16());
+ if (enable_query_log_) {
+ queryLog(qry_labels, qclass, qtype);
+ }
if (qclass != RRClass::IN()) {
- isc_throw(Unexpected, "experimental assumption failure");
+ throw std::runtime_error("experimental assumption failure");
}
if (cache_table_ == NULL) {
@@ -122,8 +131,8 @@ MessageHandler::MessageHandlerImpl::process(
DNSL1HashEntry* entry = cache_table_->find(qry_labels, qtype);
if (entry == NULL) {
- isc_throw(Unexpected, "cache entry not found: experimental assumption "
- "failure: " << qry_labels << "/" << qtype);
+ throw std::runtime_error(
+ "cache entry not found: experimental assumption");
}
// Copy the part of DNS header (we know qdcount is 1 here)
@@ -294,8 +303,6 @@ MessageHandler::MessageHandlerImpl::process(
buffer.writeData(dp_beg, data_len);
}
}
-
- server->resume(true);
}
MessageHandler::MessageHandler() : impl_(new MessageHandlerImpl)
More information about the bind10-changes
mailing list