diff --git a/ChangeLog b/ChangeLog index c59c9ec34d..6fb15b6c20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,35 @@ +347. [bug] jelte + Fixed a bug where adding Zonemgr/secondary_zones without explicitely + setting the class value of the added zone resulted in a cryptic + error in bindctl ("Error: class"). It will now correctly default to + IN if not set. This also adds better checks on the name and class + values, and better errors if they are bad. + (Trac #1414, git 7b122af8489acf0f28f935a19eca2c5509a3677f) + +346. [build]* jreed + Renamed libdhcp to libdhcp++. + (Trac #1446, git d394e64f4c44f16027b1e62b4ac34e054b49221d) + +345. [func] tomek + dhcp4: Dummy DHCPv4 component implemented. Currently it does + nothing useful, except providing skeleton implementation that can + be expanded in the future. + (Trac #992, git d6e33479365c8f8f62ef2b9aa5548efe6b194601) + +344. [func] y-aharen + src/lib/statistics: Added statistics counter library for entire server + items and per zone items. Also, modified b10-auth to use it. It is + also intended to use in the other modules such as b10-resolver. + (Trac #510, git afddaf4c5718c2a0cc31f2eee79c4e0cc625499f) + +343. [func] jelte + Added IXFR-out system tests, based on the first two test sets of + http://bind10.isc.org/wiki/IxfrSystemTests. + (Trac #1314, git 1655bed624866a766311a01214597db01b4c7cec) + 342. [bug] stephen In the resolver, a FORMERR received from an upstream nameserver - now rsults in a SERVFAIL being returned as a response to the original + now results in a SERVFAIL being returned as a response to the original query. Additional debug messages added to distinguish between different errors in packets received from upstream nameservers. (Trac #1383, git 9b2b249d23576c999a65d8c338e008cabe45f0c9) @@ -69,12 +98,12 @@ potential problems and were fixed. (Trac #1389, git 3fdce88046bdad392bd89ea656ec4ac3c858ca2f) -333. [bug] dvv - Solaris needs "-z now" to force non-lazy binding and prevent g++ static - initialization code from deadlocking. +333. [bug] dvv + Solaris needs "-z now" to force non-lazy binding and prevent + g++ static initialization code from deadlocking. (Trac #1439, git c789138250b33b6b08262425a08a2a0469d90433) -332. [bug] vorner +332. [bug] vorner C++ exceptions in the isc.dns.Rdata wrapper are now converted to python ones instead of just aborting the interpretter. (Trac #1407, git 5b64e839be2906b8950f5b1e42a3fadd72fca033) @@ -109,7 +138,7 @@ bind10-devel-20111128 released on November 28, 2011 always respond to IXFR requests according to RFC1995). (Trac #1371 and #1372, git 80c131f5b0763753d199b0fb9b51f10990bcd92b) -326. [build]* jinmei +326. [build]* jinmei Added a check script for the SQLite3 schema version. It will be run at the beginning of 'make install', and if it detects an old version of schema, installation will stop. You'll then need to diff --git a/configure.ac b/configure.ac index e370e21171..671a9b6769 100644 --- a/configure.ac +++ b/configure.ac @@ -730,7 +730,7 @@ then GTEST_FOUND="true" # There is no gtest-config script on this # system, which is supposed to inform us - # whether we need pthreads as well (a + # whether we need pthreads as well (a # gtest compile-time option). So we still # need to test that manually. CPPFLAGS_SAVED="$CPPFLAGS" @@ -892,6 +892,8 @@ AC_CONFIG_FILES([Makefile src/bin/auth/benchmarks/Makefile src/bin/dhcp6/Makefile src/bin/dhcp6/tests/Makefile + src/bin/dhcp4/Makefile + src/bin/dhcp4/tests/Makefile src/bin/resolver/Makefile src/bin/resolver/tests/Makefile src/bin/sockcreator/Makefile @@ -984,6 +986,8 @@ AC_CONFIG_FILES([Makefile src/lib/util/tests/Makefile src/lib/acl/Makefile src/lib/acl/tests/Makefile + src/lib/statistics/Makefile + src/lib/statistics/tests/Makefile tests/Makefile tests/system/Makefile tests/tools/Makefile @@ -1031,6 +1035,7 @@ AC_OUTPUT([doc/version.ent src/bin/msgq/run_msgq.sh src/bin/auth/auth.spec.pre src/bin/auth/spec_config.h.pre + src/bin/dhcp4/spec_config.h.pre src/bin/dhcp6/spec_config.h.pre src/bin/tests/process_rename_test.py src/lib/config/tests/data_def_unittests_config.h diff --git a/doc/guide/bind10-guide.xml b/doc/guide/bind10-guide.xml index e61725f9e8..b1861111fd 100644 --- a/doc/guide/bind10-guide.xml +++ b/doc/guide/bind10-guide.xml @@ -1502,6 +1502,49 @@ what if a NOTIFY is sent? --> +
+ Secondary Manager + + + The b10-zonemgr process is started by + bind10. + It keeps track of SOA refresh, retry, and expire timers + and other details for BIND 10 to perform as a slave. + When the b10-auth authoritative DNS server + receives a NOTIFY message, b10-zonemgr + may tell b10-xfrin to do a refresh + to start an inbound zone transfer. + The secondary manager resets its counters when a new zone is + transferred in. + + + + Access control (such as allowing notifies) is not yet provided. + The primary/secondary service is not yet complete. + + + + The following example shows using bindctl + to configure the server to be a secondary for the example zone: + + > config add Zonemgr/secondary_zones +> config set Zonemgr/secondary_zones[0]/name "" +> config set Zonemgr/secondary_zones[0]/class "" +> config commit + + + + + + + If the zone does not exist in the data source already + (i.e. no SOA record for it), b10-zonemgr + will automatically tell b10-xfrin + to transfer the zone in. + + +
+
Trigger an Incoming Zone Transfer Manually @@ -1514,7 +1557,6 @@ what if a NOTIFY is sent?
- @@ -1606,31 +1648,6 @@ what is XfroutClient xfr_client?? - - Secondary Manager - - - The b10-zonemgr process is started by - bind10. - It keeps track of SOA refresh, retry, and expire timers - and other details for BIND 10 to perform as a slave. - When the b10-auth authoritative DNS server - receives a NOTIFY message, b10-zonemgr - may tell b10-xfrin to do a refresh - to start an inbound zone transfer. - The secondary manager resets its counters when a new zone is - transferred in. - - - - Access control (such as allowing notifies) is not yet provided. - The primary/secondary service is not yet complete. - - - - - - Recursive Name Server diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 06d8df2e76..ba7ae812aa 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -1,4 +1,4 @@ SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \ - usermgr zonemgr stats tests resolver sockcreator dhcp6 + usermgr zonemgr stats tests resolver sockcreator dhcp6 dhcp4 check-recursive: all-recursive diff --git a/src/bin/auth/Makefile.am b/src/bin/auth/Makefile.am index 4d8ec833bd..3d604321dd 100644 --- a/src/bin/auth/Makefile.am +++ b/src/bin/auth/Makefile.am @@ -71,6 +71,7 @@ b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la b10_auth_LDADD += $(top_builddir)/src/lib/log/liblog.la b10_auth_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la b10_auth_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la +b10_auth_LDADD += $(top_builddir)/src/lib/statistics/libstatistics.la b10_auth_LDADD += $(SQLITE_LIBS) # TODO: config.h.in is wrong because doesn't honor pkgdatadir diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc index caf69b9a7c..da05e484c8 100644 --- a/src/bin/auth/auth_srv.cc +++ b/src/bin/auth/auth_srv.cc @@ -671,9 +671,9 @@ void AuthSrvImpl::incCounter(const int protocol) { // Increment query counter. if (protocol == IPPROTO_UDP) { - counters_.inc(AuthCounters::COUNTER_UDP_QUERY); + counters_.inc(AuthCounters::SERVER_UDP_QUERY); } else if (protocol == IPPROTO_TCP) { - counters_.inc(AuthCounters::COUNTER_TCP_QUERY); + counters_.inc(AuthCounters::SERVER_TCP_QUERY); } else { // unknown protocol isc_throw(Unexpected, "Unknown protocol: " << protocol); @@ -766,7 +766,7 @@ bool AuthSrv::submitStatistics() const { } uint64_t -AuthSrv::getCounter(const AuthCounters::CounterType type) const { +AuthSrv::getCounter(const AuthCounters::ServerCounterType type) const { return (impl_->counters_.getCounter(type)); } diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h index f2259a2994..a50e42759e 100644 --- a/src/bin/auth/auth_srv.h +++ b/src/bin/auth/auth_srv.h @@ -343,7 +343,7 @@ public: /// \param type Type of a counter to get the value of /// /// \return the value of the counter. - uint64_t getCounter(const AuthCounters::CounterType type) const; + uint64_t getCounter(const AuthCounters::ServerCounterType type) const; /** * \brief Set and get the addresses we listen on. diff --git a/src/bin/auth/benchmarks/Makefile.am b/src/bin/auth/benchmarks/Makefile.am index dd00ea53d5..da6a5c83a8 100644 --- a/src/bin/auth/benchmarks/Makefile.am +++ b/src/bin/auth/benchmarks/Makefile.am @@ -35,5 +35,6 @@ query_bench_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la query_bench_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la query_bench_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la +query_bench_LDADD += $(top_builddir)/src/lib/statistics/libstatistics.la query_bench_LDADD += $(SQLITE_LIBS) diff --git a/src/bin/auth/statistics.cc b/src/bin/auth/statistics.cc index e62719f7e2..7397a50f09 100644 --- a/src/bin/auth/statistics.cc +++ b/src/bin/auth/statistics.cc @@ -18,48 +18,67 @@ #include #include +#include +#include + #include #include +#include + using namespace isc::auth; +using namespace isc::statistics; // TODO: We need a namespace ("auth_server"?) to hold // AuthSrv and AuthCounters. -class AuthCountersImpl { -private: - // prohibit copy - AuthCountersImpl(const AuthCountersImpl& source); - AuthCountersImpl& operator=(const AuthCountersImpl& source); +// TODO: Make use of wrappers like isc::dns::Opcode +// for counter item type. + +class AuthCountersImpl : boost::noncopyable { public: AuthCountersImpl(); ~AuthCountersImpl(); - void inc(const AuthCounters::CounterType type); + void inc(const AuthCounters::ServerCounterType type); + void inc(const std::string& zone, + const AuthCounters::PerZoneCounterType type); bool submitStatistics() const; void setStatisticsSession(isc::cc::AbstractSession* statistics_session); void registerStatisticsValidator (AuthCounters::validator_type validator); // Currently for testing purpose only - uint64_t getCounter(const AuthCounters::CounterType type) const; + uint64_t getCounter(const AuthCounters::ServerCounterType type) const; private: - std::vector counters_; + Counter server_counter_; + CounterDictionary per_zone_counter_; isc::cc::AbstractSession* statistics_session_; AuthCounters::validator_type validator_; }; AuthCountersImpl::AuthCountersImpl() : // initialize counter - // size: AuthCounters::COUNTER_TYPES, initial value: 0 - counters_(AuthCounters::COUNTER_TYPES, 0), + // size of server_counter_: AuthCounters::SERVER_COUNTER_TYPES + // size of per_zone_counter_: AuthCounters::PER_ZONE_COUNTER_TYPES + server_counter_(AuthCounters::SERVER_COUNTER_TYPES), + per_zone_counter_(AuthCounters::PER_ZONE_COUNTER_TYPES), statistics_session_(NULL) -{} +{ + per_zone_counter_.addElement("_SERVER_"); +} AuthCountersImpl::~AuthCountersImpl() {} void -AuthCountersImpl::inc(const AuthCounters::CounterType type) { - ++counters_.at(type); +AuthCountersImpl::inc(const AuthCounters::ServerCounterType type) { + server_counter_.inc(type); +} + +void +AuthCountersImpl::inc(const std::string& zone, + const AuthCounters::PerZoneCounterType type) +{ + per_zone_counter_[zone].inc(type); } bool @@ -73,9 +92,9 @@ AuthCountersImpl::submitStatistics() const { << "{ \"owner\": \"Auth\"," << " \"data\":" << "{ \"queries.udp\": " - << counters_.at(AuthCounters::COUNTER_UDP_QUERY) + << server_counter_.get(AuthCounters::SERVER_UDP_QUERY) << ", \"queries.tcp\": " - << counters_.at(AuthCounters::COUNTER_TCP_QUERY) + << server_counter_.get(AuthCounters::SERVER_TCP_QUERY) << " }" << "}" << "]}"; @@ -126,19 +145,17 @@ AuthCountersImpl::registerStatisticsValidator // Currently for testing purpose only uint64_t -AuthCountersImpl::getCounter(const AuthCounters::CounterType type) const { - return (counters_.at(type)); +AuthCountersImpl::getCounter(const AuthCounters::ServerCounterType type) const { + return (server_counter_.get(type)); } AuthCounters::AuthCounters() : impl_(new AuthCountersImpl()) {} -AuthCounters::~AuthCounters() { - delete impl_; -} +AuthCounters::~AuthCounters() {} void -AuthCounters::inc(const AuthCounters::CounterType type) { +AuthCounters::inc(const AuthCounters::ServerCounterType type) { impl_->inc(type); } @@ -155,7 +172,7 @@ AuthCounters::setStatisticsSession } uint64_t -AuthCounters::getCounter(const AuthCounters::CounterType type) const { +AuthCounters::getCounter(const AuthCounters::ServerCounterType type) const { return (impl_->getCounter(type)); } diff --git a/src/bin/auth/statistics.h b/src/bin/auth/statistics.h index c930414c65..280b4a5d8f 100644 --- a/src/bin/auth/statistics.h +++ b/src/bin/auth/statistics.h @@ -17,6 +17,7 @@ #include #include +#include class AuthCountersImpl; @@ -51,13 +52,18 @@ class AuthCountersImpl; /// \todo Consider overhead of \c AuthCounters::inc() class AuthCounters { private: - AuthCountersImpl* impl_; + boost::scoped_ptr impl_; public: // Enum for the type of counter - enum CounterType { - COUNTER_UDP_QUERY = 0, ///< COUNTER_UDP_QUERY: counter for UDP queries - COUNTER_TCP_QUERY = 1, ///< COUNTER_TCP_QUERY: counter for TCP queries - COUNTER_TYPES = 2 ///< The number of defined counters + enum ServerCounterType { + SERVER_UDP_QUERY, ///< SERVER_UDP_QUERY: counter for UDP queries + SERVER_TCP_QUERY, ///< SERVER_TCP_QUERY: counter for TCP queries + SERVER_COUNTER_TYPES ///< The number of defined counters + }; + enum PerZoneCounterType { + ZONE_UDP_QUERY, ///< ZONE_UDP_QUERY: counter for UDP queries + ZONE_TCP_QUERY, ///< ZONE_TCP_QUERY: counter for TCP queries + PER_ZONE_COUNTER_TYPES ///< The number of defined counters }; /// The constructor. /// @@ -77,9 +83,9 @@ public: /// /// \throw std::out_of_range \a type is unknown. /// - /// usage: counter.inc(CounterType::COUNTER_UDP_QUERY); + /// usage: counter.inc(AuthCounters::SERVER_UDP_QUERY); /// - void inc(const CounterType type); + void inc(const ServerCounterType type); /// \brief Submit statistics counters to statistics module. /// @@ -130,7 +136,7 @@ public: /// /// \return the value of the counter specified by \a type. /// - uint64_t getCounter(const AuthCounters::CounterType type) const; + uint64_t getCounter(const AuthCounters::ServerCounterType type) const; /// \brief A type of validation function for the specification in /// isc::config::ModuleSpec. diff --git a/src/bin/auth/tests/Makefile.am b/src/bin/auth/tests/Makefile.am index d27386e62e..b5b96d7b24 100644 --- a/src/bin/auth/tests/Makefile.am +++ b/src/bin/auth/tests/Makefile.am @@ -65,6 +65,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la run_unittests_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la +run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libstatistics.la endif noinst_PROGRAMS = $(TESTS) diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc index ac25cd60d9..d90006a88d 100644 --- a/src/bin/auth/tests/auth_srv_unittest.cc +++ b/src/bin/auth/tests/auth_srv_unittest.cc @@ -779,7 +779,7 @@ TEST_F(AuthSrvTest, cacheSlots) { // Submit UDP normal query and check query counter TEST_F(AuthSrvTest, queryCounterUDPNormal) { // The counter should be initialized to 0. - EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_UDP_QUERY)); + EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_UDP_QUERY)); // Create UDP message and process. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(), default_qid, Name("example.com"), @@ -788,13 +788,13 @@ TEST_F(AuthSrvTest, queryCounterUDPNormal) { server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv); // After processing UDP query, the counter should be 1. - EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_UDP_QUERY)); + EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_UDP_QUERY)); } // Submit TCP normal query and check query counter TEST_F(AuthSrvTest, queryCounterTCPNormal) { // The counter should be initialized to 0. - EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY)); + EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY)); // Create TCP message and process. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(), default_qid, Name("example.com"), @@ -803,13 +803,13 @@ TEST_F(AuthSrvTest, queryCounterTCPNormal) { server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv); // After processing TCP query, the counter should be 1. - EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY)); + EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY)); } // Submit TCP AXFR query and check query counter TEST_F(AuthSrvTest, queryCounterTCPAXFR) { // The counter should be initialized to 0. - EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY)); + EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY)); UnitTestUtil::createRequestMessage(request_message, opcode, default_qid, Name("example.com"), RRClass::IN(), RRType::AXFR()); createRequestPacket(request_message, IPPROTO_TCP); @@ -818,13 +818,13 @@ TEST_F(AuthSrvTest, queryCounterTCPAXFR) { server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv); EXPECT_FALSE(dnsserv.hasAnswer()); // After processing TCP AXFR query, the counter should be 1. - EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY)); + EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY)); } // Submit TCP IXFR query and check query counter TEST_F(AuthSrvTest, queryCounterTCPIXFR) { // The counter should be initialized to 0. - EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY)); + EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY)); UnitTestUtil::createRequestMessage(request_message, opcode, default_qid, Name("example.com"), RRClass::IN(), RRType::IXFR()); createRequestPacket(request_message, IPPROTO_TCP); @@ -833,7 +833,7 @@ TEST_F(AuthSrvTest, queryCounterTCPIXFR) { server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv); EXPECT_FALSE(dnsserv.hasAnswer()); // After processing TCP IXFR query, the counter should be 1. - EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY)); + EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY)); } // class for queryCounterUnexpected test diff --git a/src/bin/auth/tests/statistics_unittest.cc b/src/bin/auth/tests/statistics_unittest.cc index 98e573b495..3f19f911f6 100644 --- a/src/bin/auth/tests/statistics_unittest.cc +++ b/src/bin/auth/tests/statistics_unittest.cc @@ -150,25 +150,24 @@ AuthCountersTest::MockSession::setThrowSessionTimeout(bool flag) { TEST_F(AuthCountersTest, incrementUDPCounter) { // The counter should be initialized to 0. - EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_UDP_QUERY)); - EXPECT_NO_THROW(counters.inc(AuthCounters::COUNTER_UDP_QUERY)); + EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY)); + EXPECT_NO_THROW(counters.inc(AuthCounters::SERVER_UDP_QUERY)); // After increment, the counter should be 1. - EXPECT_EQ(1, counters.getCounter(AuthCounters::COUNTER_UDP_QUERY)); + EXPECT_EQ(1, counters.getCounter(AuthCounters::SERVER_UDP_QUERY)); } TEST_F(AuthCountersTest, incrementTCPCounter) { // The counter should be initialized to 0. - EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_TCP_QUERY)); - EXPECT_NO_THROW(counters.inc(AuthCounters::COUNTER_TCP_QUERY)); + EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY)); + EXPECT_NO_THROW(counters.inc(AuthCounters::SERVER_TCP_QUERY)); // After increment, the counter should be 1. - EXPECT_EQ(1, counters.getCounter(AuthCounters::COUNTER_TCP_QUERY)); + EXPECT_EQ(1, counters.getCounter(AuthCounters::SERVER_TCP_QUERY)); } TEST_F(AuthCountersTest, incrementInvalidCounter) { - // Expect to throw isc::InvalidParameter if the type of the counter is - // invalid. - EXPECT_THROW(counters.inc(AuthCounters::COUNTER_TYPES), - std::out_of_range); + // Expect to throw an isc::OutOfRange + EXPECT_THROW(counters.inc(AuthCounters::SERVER_COUNTER_TYPES), + isc::OutOfRange); } TEST_F(AuthCountersTest, submitStatisticsWithoutSession) { @@ -195,14 +194,14 @@ TEST_F(AuthCountersTest, submitStatisticsWithoutValidator) { // Validate if it submits correct data. // Counters should be initialized to 0. - EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_UDP_QUERY)); - EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_TCP_QUERY)); + EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY)); + EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY)); // UDP query counter is set to 2. - counters.inc(AuthCounters::COUNTER_UDP_QUERY); - counters.inc(AuthCounters::COUNTER_UDP_QUERY); + counters.inc(AuthCounters::SERVER_UDP_QUERY); + counters.inc(AuthCounters::SERVER_UDP_QUERY); // TCP query counter is set to 1. - counters.inc(AuthCounters::COUNTER_TCP_QUERY); + counters.inc(AuthCounters::SERVER_TCP_QUERY); counters.submitStatistics(); // Destination is "Stats". @@ -237,14 +236,14 @@ TEST_F(AuthCountersTest, submitStatisticsWithValidator) { counters.registerStatisticsValidator(validator); // Counters should be initialized to 0. - EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_UDP_QUERY)); - EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_TCP_QUERY)); + EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY)); + EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY)); // UDP query counter is set to 2. - counters.inc(AuthCounters::COUNTER_UDP_QUERY); - counters.inc(AuthCounters::COUNTER_UDP_QUERY); + counters.inc(AuthCounters::SERVER_UDP_QUERY); + counters.inc(AuthCounters::SERVER_UDP_QUERY); // TCP query counter is set to 1. - counters.inc(AuthCounters::COUNTER_TCP_QUERY); + counters.inc(AuthCounters::SERVER_TCP_QUERY); // checks the value returned by submitStatistics EXPECT_TRUE(counters.submitStatistics()); diff --git a/src/bin/dhcp4/Makefile.am b/src/bin/dhcp4/Makefile.am new file mode 100644 index 0000000000..513ae1cca2 --- /dev/null +++ b/src/bin/dhcp4/Makefile.am @@ -0,0 +1,43 @@ +SUBDIRS = . tests + +AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib +AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin +AM_CPPFLAGS += $(BOOST_INCLUDES) + +AM_CXXFLAGS = $(B10_CXXFLAGS) + +if USE_STATIC_LINK +AM_LDFLAGS = -static +endif + +pkglibexecdir = $(libexecdir)/@PACKAGE@ + +CLEANFILES = spec_config.h + +man_MANS = b10-dhcp4.8 +EXTRA_DIST = $(man_MANS) dhcp4.spec + +if ENABLE_MAN + +b10-dhcp4.8: b10-dhcp4.xml + xsltproc --novalid --xinclude --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $(srcdir)/b10-dhcp4.xml + +endif + +spec_config.h: spec_config.h.pre + $(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@ + +BUILT_SOURCES = spec_config.h +pkglibexec_PROGRAMS = b10-dhcp4 + +b10_dhcp4_SOURCES = main.cc dhcp4_srv.cc dhcp4_srv.h + +b10_dhcp4_LDADD = $(top_builddir)/src/lib/dhcp/libdhcp++.la +b10_dhcp4_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la +b10_dhcp4_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la +b10_dhcp4_LDADD += $(top_builddir)/src/lib/log/liblog.la + +# TODO: config.h.in is wrong because doesn't honor pkgdatadir +# and can't use @datadir@ because doesn't expand default ${prefix} +b10_dhcp4dir = $(pkgdatadir) +b10_dhcp4_DATA = dhcp4.spec diff --git a/src/bin/dhcp4/b10-dhcp4.8 b/src/bin/dhcp4/b10-dhcp4.8 new file mode 100644 index 0000000000..97bdeb8b73 --- /dev/null +++ b/src/bin/dhcp4/b10-dhcp4.8 @@ -0,0 +1,60 @@ +'\" t +.\" Title: b10-dhcp4 +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: October 27, 2011 +.\" Manual: BIND10 +.\" Source: BIND10 +.\" Language: English +.\" +.TH "B10\-DHCP4" "8" "October 27, 2011" "BIND10" "BIND10" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +b10-dhcp4 \- DHCPv4 server in BIND 10 architecture +.SH "SYNOPSIS" +.HP \w'\fBb10\-dhcp4\fR\ 'u +\fBb10\-dhcp4\fR [\fB\-v\fR] +.SH "DESCRIPTION" +.PP +The +\fBb10\-dhcp4\fR +daemon will provide the DHCPv4 server implementation when it becomes functional\&. +.SH "ARGUMENTS" +.PP +The arguments are as follows: +.PP +\fB\-v\fR +.RS 4 +Enable verbose mode\&. +.RE +.SH "SEE ALSO" +.PP + +\fBbind10\fR(8)\&. +.SH "HISTORY" +.PP +The +\fBb10\-dhcp4\fR +daemon was first coded in November 2011 by Tomek Mrugalski\&. +.SH "COPYRIGHT" +.br +Copyright \(co 2011 Internet Systems Consortium, Inc. ("ISC") +.br diff --git a/src/bin/dhcp4/b10-dhcp4.xml b/src/bin/dhcp4/b10-dhcp4.xml new file mode 100644 index 0000000000..370fa046cc --- /dev/null +++ b/src/bin/dhcp4/b10-dhcp4.xml @@ -0,0 +1,98 @@ +]> + + + + + + October 27, 2011 + + + + b10-dhcp4 + 8 + BIND10 + + + + b10-dhcp4 + DHCPv4 server in BIND 10 architecture + + + + + 2011 + Internet Systems Consortium, Inc. ("ISC") + + + + + + b10-dhcp4 + + + + + + DESCRIPTION + + The b10-dhcp4 daemon will provide the + DHCPv4 server implementation when it becomes functional. + + + + + + ARGUMENTS + + The arguments are as follows: + + + + + + + Enable verbose mode. + + + + + + + + + SEE ALSO + + + bind108 + . + + + + + HISTORY + + The b10-dhcp4 daemon was first coded in + November 2011 by Tomek Mrugalski. + + + diff --git a/src/bin/dhcp4/dhcp4.spec b/src/bin/dhcp4/dhcp4.spec new file mode 100644 index 0000000000..8061fd2261 --- /dev/null +++ b/src/bin/dhcp4/dhcp4.spec @@ -0,0 +1,14 @@ +{ + "module_spec": { + "module_name": "dhcp4", + "module_description": "DHCPv4 server daemon", + "config_data": [ + { "item_name": "interface", + "item_type": "string", + "item_optional": false, + "item_default": "eth0" + } + ], + "commands": [] + } +} diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc new file mode 100644 index 0000000000..9686a35499 --- /dev/null +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -0,0 +1,154 @@ +// 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. + +#include +#include +#include +#include +#include + +using namespace std; +using namespace isc; +using namespace isc::dhcp; +using namespace isc::asiolink; + +Dhcpv4Srv::Dhcpv4Srv(uint16_t port) { + cout << "Initialization: opening sockets on port " << port << endl; + + // first call to instance() will create IfaceMgr (it's a singleton) + // it may throw something if things go wrong + IfaceMgr::instance(); + + /// @todo: instantiate LeaseMgr here once it is imlpemented. + + setServerID(); + + shutdown_ = false; +} + +Dhcpv4Srv::~Dhcpv4Srv() { + cout << "DHCPv4 server shutdown." << endl; +} + +bool +Dhcpv4Srv::run() { + while (!shutdown_) { + boost::shared_ptr query; // client's message + boost::shared_ptr rsp; // server's response + +#if 0 + // uncomment this once ticket 1239 is merged. + query = IfaceMgr::instance().receive4(); +#endif + + if (query) { + if (!query->unpack()) { + cout << "Failed to parse incoming packet" << endl; + continue; + } + switch (query->getType()) { + case DHCPDISCOVER: + rsp = processDiscover(query); + break; + case DHCPREQUEST: + rsp = processRequest(query); + break; + case DHCPRELEASE: + processRelease(query); + break; + case DHCPDECLINE: + processDecline(query); + break; + case DHCPINFORM: + processInform(query); + break; + default: + cout << "Unknown pkt type received:" + << query->getType() << endl; + } + + cout << "Received " << query->len() << " bytes packet type=" + << query->getType() << endl; + + // TODO: print out received packets only if verbose (or debug) + // mode is enabled + cout << query->toText(); + + if (rsp) { + rsp->setRemoteAddr(query->getRemoteAddr()); + rsp->setLocalAddr(query->getLocalAddr()); + rsp->setRemotePort(DHCP4_CLIENT_PORT); + rsp->setLocalPort(DHCP4_SERVER_PORT); + rsp->setIface(query->getIface()); + rsp->setIndex(query->getIndex()); + + cout << "Replying with:" << rsp->getType() << endl; + cout << rsp->toText(); + cout << "----" << endl; + if (rsp->pack()) { + cout << "Packet assembled correctly." << endl; + } +#if 0 + // uncomment this once ticket 1240 is merged. + IfaceMgr::instance().send4(rsp); +#endif + } + } + + // TODO add support for config session (see src/bin/auth/main.cc) + // so this daemon can be controlled from bob + } + + return (true); +} + +void +Dhcpv4Srv::setServerID() { + /// TODO implement this for real once interface detection (ticket 1237) + /// is done. Use hardcoded server-id for now. + +#if 0 + // uncomment this once ticket 1350 is merged. + IOAddress srvId("127.0.0.1"); + serverid_ = boost::shared_ptr