[svn] commit: r2109 - in /branches/feng-authnotify/src/bin/auth: Makefile.am asio_link.cc asio_link.h auth_srv.cc auth_srv.h auth_util.cc auth_util.h main.cc tests/Makefile.am tests/auth_srv_unittest.cc

BIND 10 source code commits bind10-changes at lists.isc.org
Sun Jun 13 05:59:14 UTC 2010


Author: hanfeng
Date: Sun Jun 13 05:59:13 2010
New Revision: 2109

Log:
refactoring auth server code

Added:
    branches/feng-authnotify/src/bin/auth/asio_link.cc
      - copied, changed from r2034, trunk/src/bin/auth/asio_link.cc
    branches/feng-authnotify/src/bin/auth/asio_link.h
      - copied, changed from r2034, trunk/src/bin/auth/asio_link.h
    branches/feng-authnotify/src/bin/auth/auth_util.cc
    branches/feng-authnotify/src/bin/auth/auth_util.h
Modified:
    branches/feng-authnotify/src/bin/auth/Makefile.am
    branches/feng-authnotify/src/bin/auth/auth_srv.cc
    branches/feng-authnotify/src/bin/auth/auth_srv.h
    branches/feng-authnotify/src/bin/auth/main.cc
    branches/feng-authnotify/src/bin/auth/tests/Makefile.am
    branches/feng-authnotify/src/bin/auth/tests/auth_srv_unittest.cc

Modified: branches/feng-authnotify/src/bin/auth/Makefile.am
==============================================================================
--- branches/feng-authnotify/src/bin/auth/Makefile.am (original)
+++ branches/feng-authnotify/src/bin/auth/Makefile.am Sun Jun 13 05:59:13 2010
@@ -1,10 +1,9 @@
 SUBDIRS = . tests
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
-if GCC_WERROR_OK
-AM_CPPFLAGS += -Werror
-endif
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns -lsqlit3
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
@@ -26,9 +25,22 @@
 spec_config.h: spec_config.h.pre
 	$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
 
+# This is a wrapper library solely used for b10-auth.  The ASIO header files
+# have some code fragments that would hit gcc's unused-parameter warning,
+# which would make the build fail with -Werror (our default setting).
+# We don't want to lower the warning level for our own code just for ASIO,
+# so as a workaround we extract the ASIO related code into a separate library,
+# only for which we accept the unused-parameter warning.
+lib_LIBRARIES = libasio_link.a
+libasio_link_a_SOURCES = asio_link.cc asio_link.h
+# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
+# B10_CXXFLAGS)
+libasio_link_a_CXXFLAGS = $(AM_CXXFLAGS) -Wno-unused-parameter
+libasio_link_a_CPPFLAGS = $(AM_CPPFLAGS)
+
 BUILT_SOURCES = spec_config.h 
 pkglibexec_PROGRAMS = b10-auth
-b10_auth_SOURCES = auth_srv.cc auth_srv.h
+b10_auth_SOURCES = auth_srv.cc auth_srv.h auth_util.cc auth_util.h
 b10_auth_SOURCES += common.h
 b10_auth_SOURCES += main.cc
 b10_auth_LDADD =  $(top_builddir)/src/lib/datasrc/.libs/libdatasrc.a
@@ -36,13 +48,10 @@
 b10_auth_LDADD += $(top_builddir)/src/lib/config/.libs/libcfgclient.a
 b10_auth_LDADD += $(top_builddir)/src/lib/cc/libcc.a
 b10_auth_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
+b10_auth_LDADD += $(top_builddir)/src/bin/auth/libasio_link.a
 b10_auth_LDADD += $(SQLITE_LIBS)
-if HAVE_BOOST_SYSTEM
 if HAVE_BOOST_PYTHON
 b10_auth_LDADD += $(top_builddir)/src/lib/xfr/.libs/libxfr.a
-endif
-b10_auth_LDFLAGS = $(AM_LDFLAGS) $(BOOST_LDFLAGS)
-b10_auth_LDADD += $(BOOST_SYSTEM_LIB)
 endif
 
 # TODO: config.h.in is wrong because doesn't honor pkgdatadir

Modified: branches/feng-authnotify/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/feng-authnotify/src/bin/auth/auth_srv.cc (original)
+++ branches/feng-authnotify/src/bin/auth/auth_srv.cc Sun Jun 13 05:59:13 2010
@@ -18,6 +18,7 @@
 #include <cassert>
 #include <iostream>
 #include <vector>
+#include <boost/utility.hpp>
 
 #include <exceptions/exceptions.h>
 
@@ -32,6 +33,7 @@
 #include <config/ccsession.h>
 #include <cc/data.h>
 #include <exceptions/exceptions.h>
+#include <xfr/xfrout_client.h>
 
 #include <datasrc/query.h>
 #include <datasrc/data_source.h>
@@ -42,6 +44,9 @@
 
 #include "common.h"
 #include "auth_srv.h"
+#include "asio_link.h"
+#include "auth_util.h"
+#include "spec_config.h"
 
 #include <boost/lexical_cast.hpp>
 
@@ -53,16 +58,28 @@
 using namespace isc::dns::rdata;
 using namespace isc::data;
 using namespace isc::config;
-
-class AuthSrvImpl {
+using namespace isc::xfr;
+
+class AuthSrvImpl : private boost::noncopyable{
+public:
+    enum {DEFAULT_LOCAL_UDPSIZE = 4096};
+    AuthSrvImpl();
+
+    isc::data::ElementPtr setDbFile(const isc::data::ElementPtr config);
+    void setVerbose(bool on) { verbose_mode_ = on;}
+    bool getVerbose()const { return verbose_mode_;}
+    void setConfigSession(ModuleCCSession *cs) { cs_ = cs;}
+    ModuleCCSession *getConfigSession() { return cs_;}
+    void nag(const string &info){
+        if (verbose_mode_)
+            cerr << info;
+    }
+    void processQuery(asio_link::UserInfo &userInfo);
+
 private:
-    // prohibit copy
-    AuthSrvImpl(const AuthSrvImpl& source);
-    AuthSrvImpl& operator=(const AuthSrvImpl& source);
-public:
-    AuthSrvImpl();
-
-    isc::data::ElementPtr setDbFile(const isc::data::ElementPtr config);
+    void processNormalQuery(asio_link::UserInfo &userInfo);
+    void processAxfrQuery(asio_link::UserInfo &uerInfo);
+    void processIxfrQuery(asio_link::UserInfo &userInfo, const std::string &queryZoneName);
 
     std::string db_file_;
     ModuleCCSession* cs_;
@@ -71,11 +88,7 @@
     /// so that we can specifically remove that one should the database
     /// file change
     ConstDataSrcPtr cur_datasrc_;
-
     bool verbose_mode_;
-
-    /// Currently non-configurable, but will be.
-    static const uint16_t DEFAULT_LOCAL_UDPSIZE = 4096;
 };
 
 AuthSrvImpl::AuthSrvImpl() : cs_(NULL), verbose_mode_(false)
@@ -83,183 +96,107 @@
     // cur_datasrc_ is automatically initialized by the default constructor,
     // effectively being an empty (sqlite) data source.  once ccsession is up
     // the datasource will be set by the configuration setting
-
     // add static data source
     data_sources_.addDataSrc(ConstDataSrcPtr(new StaticDataSrc));
 }
 
-AuthSrv::AuthSrv() : impl_(new AuthSrvImpl) {
-}
-
-AuthSrv::~AuthSrv() {
-    delete impl_;
-}
-
-namespace {
-class QuestionInserter {
-public:
-    QuestionInserter(Message* message) : message_(message) {}
-    void operator()(const QuestionPtr question) {
-        message_->addQuestion(question);
-    }
-    Message* message_;
-};
-
-void
-makeErrorMessage(Message& message, MessageRenderer& renderer,
-                 const Rcode& rcode, const bool verbose_mode)
-{
-    // extract the parameters that should be kept.
-    // XXX: with the current implementation, it's not easy to set EDNS0
-    // depending on whether the query had it.  So we'll simply omit it.
-    const qid_t qid = message.getQid();
-    const bool rd = message.getHeaderFlag(MessageFlag::RD());
-    const bool cd = message.getHeaderFlag(MessageFlag::CD());
-    const Opcode& opcode = message.getOpcode();
-    vector<QuestionPtr> questions;
-
-    // If this is an error to a query, we should also copy the question section.
-    if (opcode == Opcode::QUERY()) {
-        questions.assign(message.beginQuestion(), message.endQuestion());
-    }
-
-    message.clear(Message::RENDER);
-    message.setQid(qid);
-    message.setOpcode(opcode);
-    message.setHeaderFlag(MessageFlag::QR());
-    message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
-    if (rd) {
-        message.setHeaderFlag(MessageFlag::RD());
-    }
-    if (cd) {
-        message.setHeaderFlag(MessageFlag::CD());
-    }
-    for_each(questions.begin(), questions.end(), QuestionInserter(&message));
-    message.setRcode(rcode);
-    message.toWire(renderer);
-
-    if (verbose_mode) {
-        cerr << "sending an error response (" <<
-            boost::lexical_cast<string>(renderer.getLength())
-             << " bytes):\n" << message.toText() << endl;
-    }
-}
-}
-
-void
-AuthSrv::setVerbose(const bool on) {
-    impl_->verbose_mode_ = on;
-}
-
-bool
-AuthSrv::getVerbose() const {
-    return (impl_->verbose_mode_);
-}
-
-void
-AuthSrv::setConfigSession(ModuleCCSession* cs) {
-    impl_->cs_ = cs;
-}
-
-ModuleCCSession*
-AuthSrv::configSession() const {
-    return (impl_->cs_);
-}
-
-bool
-AuthSrv::processMessage(InputBuffer& request_buffer, Message& message,
-                        MessageRenderer& response_renderer,
-                        const bool udp_buffer)
-{
-    // First, check the header part.  If we fail even for the base header,
-    // just drop the message.
+
+void
+AuthSrvImpl::processQuery(asio_link::UserInfo &userInfo)
+{
+    assert(userInfo.isMessageValid());
+    Message &message = userInfo.getMessage();
+    nag("[AuthSrv] received a message :\n" + message.toText() + "\n");
+    const Opcode &opcode = message.getOpcode();
+    if (opcode == Opcode::QUERY()){
+        QuestionPtr question = *message.beginQuestion();
+        const RRType &qtype = question->getType();
+        if (qtype == RRType::AXFR())
+            processAxfrQuery(userInfo);
+        else if (qtype == RRType::IXFR())
+            processIxfrQuery(userInfo, question->getName().toText());
+        else 
+            processNormalQuery(userInfo);
+    }else{
+        nag("unsupported opcode\n");
+        auth_util::makeErrorMessage(message, Rcode::NOTIMP());
+    }
+}
+
+
+
+void
+AuthSrvImpl::processNormalQuery(asio_link::UserInfo &userInfo)
+{
+    Message &message = userInfo.getMessage();
+    if (message.getRRCount(Section::QUESTION()) != 1) {
+        auth_util::makeErrorMessage(message, Rcode::FORMERR());
+    }
+    else{
+        const bool dnssec_ok = message.isDNSSECSupported();
+        //const uint16_t remote_bufsize = message.getUDPSize();
+
+        message.makeResponse();
+        message.setHeaderFlag(MessageFlag::AA());
+        message.setRcode(Rcode::NOERROR());
+        message.setDNSSECSupported(dnssec_ok);
+        message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+
+        try {
+            Query query(message, dnssec_ok);
+            data_sources_.doQuery(query);
+        } catch (const Exception& ex) {
+            nag(std::string("Internal error, returning SERVFAIL: ") + ex.what() + "\n");
+            auth_util::makeErrorMessage(message, Rcode::SERVFAIL());
+        }
+        //response_renderer.setLengthLimit(userInfo.getProtocolType() == asio_link::UserInfo::QueryThroughUDP ? remote_bufsize : 65535);
+    }
+
+    //message.toWire(response_renderer);
+    //nag(std::string("sending a response (") + boost::lexical_cast<string>(response_renderer.getLength()) 
+    //        + " bytes):\n" + message.toText() + "\n");
+}
+
+void 
+AuthSrvImpl::processAxfrQuery(asio_link::UserInfo &userInfo)
+{
+    string path(UNIX_SOCKET_FILE);
+    XfroutClient xfr_client(path);
     try {
-        message.parseHeader(request_buffer);
-
-        // Ignore all responses.
-        if (message.getHeaderFlag(MessageFlag::QR())) {
-            if (impl_->verbose_mode_) {
-                cerr << "received unexpected response, ignoring" << endl;
-            }
-            return (false);
-        }
-    } catch (const Exception& ex) {
-        return (false);
-    }
-
-    // Parse the message.  On failure, return an appropriate error.
-    try {
-        message.fromWire(request_buffer);
-    } catch (const DNSProtocolError& error) {
-        if (impl_->verbose_mode_) {
-            cerr << "returning " <<  error.getRcode().toText() << ": "
-                 << error.what() << endl;
-        }
-        makeErrorMessage(message, response_renderer, error.getRcode(),
-                         impl_->verbose_mode_);
-        return (true);
-    } catch (const Exception& ex) {
-        if (impl_->verbose_mode_) {
-            cerr << "returning SERVFAIL: " << ex.what() << endl;
-        }
-        makeErrorMessage(message, response_renderer, Rcode::SERVFAIL(),
-                         impl_->verbose_mode_);
-        return (true);
-    } // other exceptions will be handled at a higher layer.
-
-    if (impl_->verbose_mode_) {
-        cerr << "[AuthSrv] received a message:\n" << message.toText() << endl;
-    }
-
-    // Perform further protocol-level validation.
-
-    // In this implementation, we only support normal queries
-    if (message.getOpcode() != Opcode::QUERY()) {
-        if (impl_->verbose_mode_) {
-            cerr << "unsupported opcode" << endl;
-        }
-        makeErrorMessage(message, response_renderer, Rcode::NOTIMP(),
-                         impl_->verbose_mode_);
-        return (true);
-    }
-
-    if (message.getRRCount(Section::QUESTION()) != 1) {
-        makeErrorMessage(message, response_renderer, Rcode::FORMERR(),
-                         impl_->verbose_mode_);
-        return (true);
-    }
-
-    const bool dnssec_ok = message.isDNSSECSupported();
-    const uint16_t remote_bufsize = message.getUDPSize();
-
-    message.makeResponse();
-    message.setHeaderFlag(MessageFlag::AA());
-    message.setRcode(Rcode::NOERROR());
-    message.setDNSSECSupported(dnssec_ok);
-    message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
-
-    try {
-        Query query(message, dnssec_ok);
-        impl_->data_sources_.doQuery(query);
-    } catch (const Exception& ex) {
-        if (impl_->verbose_mode_) {
-            cerr << "Internal error, returning SERVFAIL: " << ex.what() << endl;
-        }
-        makeErrorMessage(message, response_renderer, Rcode::SERVFAIL(),
-                         impl_->verbose_mode_);
-        return (true);
-    }
-
-    response_renderer.setLengthLimit(udp_buffer ? remote_bufsize : 65535);
-    message.toWire(response_renderer);
-    if (impl_->verbose_mode_) {
-        cerr << "sending a response (" <<
-            boost::lexical_cast<string>(response_renderer.getLength())
-             << " bytes):\n" << message.toText() << endl;
-    }
-
-    return (true);
-}
+        xfr_client.connect();
+        OutputBuffer rawData(0);
+        auth_util::messageToWire(userInfo.getMessage(), rawData);
+        xfr_client.sendXfroutRequestInfo(userInfo.getSocket(), (uint8_t *)rawData.getData(),
+                rawData.getLength());
+        xfr_client.disconnect();
+    }   
+    catch (const exception & err) {
+        nag(std::string("error handle xfr query:") + err.what() + "\n");
+    }
+}
+
+void 
+AuthSrvImpl::processIxfrQuery(asio_link::UserInfo &userInfo, const std::string &queryZoneName)
+{
+    //TODO check with the conf-mgr whether current server is the auth of the zone
+    isc::cc::Session tmp_session_with_xfr;
+    tmp_session_with_xfr.establish();
+    const string remote_ip_address = userInfo.getIPAddress();
+    ElementPtr notify_command = Element::createFromString("{\"command\": [\"notify\", {\"zone_name\" : \""
+                                                            + queryZoneName 
+                                                            + "\", \"master_ip\" : \""
+                                                            + remote_ip_address
+                                                            + "\"}]}");
+    unsigned int seq = tmp_session_with_xfr.group_sendmsg(notify_command, "Xfrin");
+    ElementPtr env, answer;
+    tmp_session_with_xfr.group_recvmsg(env, answer, false, seq);
+    int rcode;
+    ElementPtr err = parseAnswer(rcode, answer);
+    if (rcode != 0) 
+        nag("notify send failed\n");
+    
+}
+
 
 ElementPtr
 AuthSrvImpl::setDbFile(const isc::data::ElementPtr config) {
@@ -289,7 +226,7 @@
     // exception guarantee: We first need to perform all operations that can
     // fail, while acquiring resources in the RAII manner.  We then perform
     // delete and swap operations which should not fail.
-    DataSrcPtr datasrc_ptr(DataSrcPtr(new Sqlite3DataSrc));
+    DataSrcPtr datasrc_ptr(new Sqlite3DataSrc);
     datasrc_ptr->init(final);
     data_sources_.addDataSrc(datasrc_ptr);
 
@@ -302,6 +239,42 @@
     return (answer);
 }
 
+
+AuthSrv::AuthSrv() : impl_(new AuthSrvImpl) {
+}
+
+AuthSrv::~AuthSrv() {
+    delete impl_;
+}
+
+
+void
+AuthSrv::setVerbose(const bool on) {
+    impl_->setVerbose(on);
+}
+
+bool
+AuthSrv::getVerbose() const {
+    return (impl_->getVerbose());
+}
+
+void
+AuthSrv::setConfigSession(ModuleCCSession* cs) {
+    impl_->setConfigSession(cs);
+}
+
+ModuleCCSession*
+AuthSrv::configSession() const {
+    return (impl_->getConfigSession());
+}
+    
+void
+AuthSrv::processQuery(asio_link::UserInfo &userInfo)
+{
+    impl_->processQuery(userInfo);
+}
+
+    
 ElementPtr
 AuthSrv::updateConfig(isc::data::ElementPtr new_config) {
     try {
@@ -312,9 +285,7 @@
 
         return answer;
     } catch (const isc::Exception& error) {
-        if (impl_->verbose_mode_) {
-            cerr << "[AuthSrv] error: " << error.what() << endl;
-        }
+        impl_->nag(std::string("[AuthSrv] error: ") + error.what() + "\n");
         return isc::config::createAnswer(1, error.what());
     }
 }

Modified: branches/feng-authnotify/src/bin/auth/auth_srv.h
==============================================================================
--- branches/feng-authnotify/src/bin/auth/auth_srv.h (original)
+++ branches/feng-authnotify/src/bin/auth/auth_srv.h Sun Jun 13 05:59:13 2010
@@ -21,45 +21,35 @@
 
 #include <cc/data.h>
 #include <config/ccsession.h>
+#include <boost/utility.hpp>
 
-namespace isc {
-namespace dns {
-class InputBuffer;
-class Message;
-class MessageRenderer;
-}
+
+class AuthSrvImpl;
+namespace asio_link
+{
+    class UserInfo;
 }
 
-class AuthSrvImpl;
-
-class AuthSrv {
+class AuthSrv : private boost::noncopyable{
     ///
     /// \name Constructors, Assignment Operator and Destructor.
     ///
     /// Note: The copy constructor and the assignment operator are intentionally
     /// defined as private.
     //@{
-private:
-    AuthSrv(const AuthSrv& source);
-    AuthSrv& operator=(const AuthSrv& source);
 public:
-    explicit AuthSrv();
+    AuthSrv();
     ~AuthSrv();
-    //@}
-    /// \return \c true if the \message contains a response to be returned;
-    /// otherwise \c false.
-    bool processMessage(isc::dns::InputBuffer& request_buffer,
-                        isc::dns::Message& message,
-                        isc::dns::MessageRenderer& response_renderer,
-                        bool udp_buffer);
+    void processQuery(asio_link::UserInfo &userInfo);
     void setVerbose(bool on);
     bool getVerbose() const;
     void serve(std::string zone_name);
     isc::data::ElementPtr updateConfig(isc::data::ElementPtr config);
     isc::config::ModuleCCSession* configSession() const;
     void setConfigSession(isc::config::ModuleCCSession* cs);
+
 private:
-    AuthSrvImpl* impl_;
+   AuthSrvImpl* impl_;
 };
 
 #endif // __AUTH_SRV_H

Modified: branches/feng-authnotify/src/bin/auth/main.cc
==============================================================================
--- branches/feng-authnotify/src/bin/auth/main.cc (original)
+++ branches/feng-authnotify/src/bin/auth/main.cc Sun Jun 13 05:59:13 2010
@@ -28,10 +28,6 @@
 #include <iostream>
 
 #include <boost/foreach.hpp>
-#ifdef HAVE_BOOST_SYSTEM
-#include <boost/bind.hpp>
-#include <boost/asio.hpp>
-#endif  // HAVE_BOOST_SYSTEM
 
 #include <exceptions/exceptions.h>
 
@@ -43,26 +39,12 @@
 #include <cc/data.h>
 #include <config/ccsession.h>
 
-#if defined(HAVE_BOOST_SYSTEM) && defined(HAVE_BOOST_PYTHON)
-#define USE_XFROUT
-#include <xfr/xfrout_client.h>
-#endif
-
 #include "spec_config.h"
 #include "common.h"
 #include "auth_srv.h"
+#include "asio_link.h"
 
 using namespace std;
-#ifdef USE_XFROUT
-using namespace isc::xfr;
-#endif
-
-#ifdef HAVE_BOOST_SYSTEM
-using namespace boost::asio;
-using ip::udp;
-using ip::tcp;
-#endif  // HAVE_BOOST_SYSTEM
-
 using namespace isc::data;
 using namespace isc::cc;
 using namespace isc::config;
@@ -79,13 +61,8 @@
  * todo: turn this around, and put handlers in the authserver
  * class itself? */
 AuthSrv *auth_server;
-#ifdef HAVE_BOOST_SYSTEM
-// TODO: this should be a property of AuthSrv, and AuthSrv needs
-// a stop() method (so the shutdown command can be handled)
-boost::asio::io_service io_service_;
-#else
-bool running;
-#endif  // HAVE_BOOST_SYSTEM
+
+asio_link::IOService* io_service;
 
 ElementPtr
 my_config_handler(ElementPtr new_config) {
@@ -101,660 +78,11 @@
         /* let's add that message to our answer as well */
         answer->get("result")->add(args);
     } else if (command == "shutdown") {
-#ifdef HAVE_BOOST_SYSTEM
-        io_service_.stop();
-#else
-        running = false;
-#endif  // HAVE_BOOST_SYSTEM
+        io_service->stop();
     }
     
     return answer;
 }
-
-#ifdef USE_XFROUT
-//TODO. The sample way for checking axfr query, the code should be merged to auth server class
-static bool
-check_axfr_query(char *msg_data, uint16_t msg_len)
-{
-    if (msg_len < 15)
-        return false;
-
-    uint16_t query_type = *(uint16_t *)(msg_data + (msg_len - 4));
-    if ( query_type == 0xFC00)
-        return true;
-    
-    return false;
-}
-
-//TODO. Send the xfr query to xfrout module, the code should be merged to auth server class
-static void
-dispatch_axfr_query(int tcp_sock, char axfr_query[], uint16_t query_len)
-{
-    std::string path = string(UNIX_SOCKET_FILE);
-    XfroutClient xfr_client(path);
-    try {
-        xfr_client.connect();
-        xfr_client.sendXfroutRequestInfo(tcp_sock, (uint8_t *)axfr_query, query_len);
-        xfr_client.disconnect();
-    }
-    catch (const std::exception & err) {
-        //if (verbose_mode)
-            cerr << "error handle xfr query:" << err.what() << endl;
-    }
-}
-#endif
-
-bool isNotifyMessage(const uint8_t *data)
-{
-    int opcode = (*(data + 2) & 0x78) >> 3;
-    return opcode == 4;
-}
-
-void handleNotify(udp::endpoint &sender, uint8_t *data, size_t data_len)
-{
-#define MIN_NOTIFY_HEAD_LEN 12
-    if (data_len < MIN_NOTIFY_HEAD_LEN)
-        return;
-    //get updated zone name and remote master's ip address and send to xfrin module
-    InputBuffer name_buffer(data + MIN_NOTIFY_HEAD_LEN, data_len - MIN_NOTIFY_HEAD_LEN);
-    try
-    {
-        Name name(name_buffer);
-        //TODO check with the conf-mgr whether current server is the auth of the zone
-        Session tmp_session_with_xfr;
-        tmp_session_with_xfr.establish();
-        const string remote_ip_address = sender.address().to_string();
-        ElementPtr notify_command = Element::createFromString("{\"command\": [\"notify\", {\"zone_name\" : \""
-                                                            + name.toText() 
-                                                            + "\", \"master_ip\" : \""
-                                                            + remote_ip_address
-                                                            + "\"}]}");
-        unsigned int seq = tmp_session_with_xfr.group_sendmsg(notify_command, "Xfrin");
-        ElementPtr env, answer;
-        tmp_session_with_xfr.group_recvmsg(env, answer, false, seq);
-        int rcode;
-        ElementPtr err = parseAnswer(rcode, answer);
-        if (rcode != 0) 
-        {
-            cerr << "notify send failed" << std::endl;
-        }
-    } 
-    catch (const std::exception& ex) 
-    {
-        cerr << "error handle notify query:" << ex.what() << endl;
-    }
-    
-    //set the qr bit
-    uint8_t *qr_start_byte = data + 2;
-    *qr_start_byte |= 0x80;
-}
-
-
-#ifdef HAVE_BOOST_SYSTEM
-//
-// Helper classes for asynchronous I/O using boost::asio
-//
-class TCPClient {
-public:
-    TCPClient(io_service& io_service) :
-        socket_(io_service),
-        response_buffer_(0),
-        responselen_buffer_(TCP_MESSAGE_LENGTHSIZE),
-        response_renderer_(response_buffer_),
-        dns_message_(Message::PARSE)
-    {}
-
-    void start() {
-        async_read(socket_, boost::asio::buffer(data_, TCP_MESSAGE_LENGTHSIZE),
-                   boost::bind(&TCPClient::headerRead, this,
-                               placeholders::error,
-                               placeholders::bytes_transferred));
-    }
-
-    tcp::socket& getSocket() { return (socket_); }
-
-    void headerRead(const boost::system::error_code& error,
-                    size_t bytes_transferred)
-    {
-        if (!error) {
-            InputBuffer dnsbuffer(data_, bytes_transferred);
-
-            uint16_t msglen = dnsbuffer.readUint16();
-            async_read(socket_, boost::asio::buffer(data_, msglen),
-
-                       boost::bind(&TCPClient::requestRead, this,
-                                   placeholders::error,
-                                   placeholders::bytes_transferred));
-        } else {
-            delete this;
-        }
-    }
-
-    void requestRead(const boost::system::error_code& error,
-                     size_t bytes_transferred)
-    {
-        if (!error) {
-            InputBuffer dnsbuffer(data_, bytes_transferred);
-#ifdef USE_XFROUT
-            if (check_axfr_query(data_, bytes_transferred)) {
-                dispatch_axfr_query(socket_.native(), data_, bytes_transferred); 
-                // start to get new query ?
-                start();
-            } else {
-#endif          
-                if (auth_server->processMessage(dnsbuffer, dns_message_,
-                                                response_renderer_, false)) {
-                    responselen_buffer_.writeUint16(response_buffer_.getLength());
-                    async_write(socket_,
-                                boost::asio::buffer(
-                                    responselen_buffer_.getData(),
-                                    responselen_buffer_.getLength()),
-                                boost::bind(&TCPClient::responseWrite, this,
-                                            placeholders::error));
-                } else {
-                    delete this;
-                }
-#ifdef USE_XFROUT
-            }
-#endif
-        } else {
-            delete this;
-        }
-    }
-
-    void responseWrite(const boost::system::error_code& error) {
-        if (!error) {
-                async_write(socket_,
-                            boost::asio::buffer(response_buffer_.getData(),
-                                                response_buffer_.getLength()),
-                        boost::bind(&TCPClient::handleWrite, this,
-                                    placeholders::error));
-        } else {
-            delete this;
-        }
-    }
-
-    void handleWrite(const boost::system::error_code& error) {
-        if (!error) {
-            start();            // handle next request, if any.
-      } else {
-            delete this;
-      }
-    }
-
-private:
-    tcp::socket socket_;
-    OutputBuffer response_buffer_;
-    OutputBuffer responselen_buffer_;
-    MessageRenderer response_renderer_;
-    Message dns_message_;
-    enum { MAX_LENGTH = 65535 };
-    static const size_t TCP_MESSAGE_LENGTHSIZE = 2;
-    char data_[MAX_LENGTH];
-};
-
-class TCPServer {
-public:
-    TCPServer(io_service& io_service, int af, short port) :
-        io_service_(io_service), acceptor_(io_service_),
-        listening_(new TCPClient(io_service_))
-    {
-        tcp::endpoint endpoint(af == AF_INET6 ? tcp::v6() : tcp::v4(), port);
-        acceptor_.open(endpoint.protocol());
-        // Set v6-only (we use a different instantiation for v4,
-        // otherwise asio will bind to both v4 and v6
-        if (af == AF_INET6) {
-            acceptor_.set_option(ip::v6_only(true));
-        }
-        acceptor_.set_option(tcp::acceptor::reuse_address(true));
-        acceptor_.bind(endpoint);
-        acceptor_.listen();
-        acceptor_.async_accept(listening_->getSocket(),
-                               boost::bind(&TCPServer::handleAccept, this,
-                                           listening_, placeholders::error));
-    }
-
-    ~TCPServer() { delete listening_; }
-
-    void handleAccept(TCPClient* new_client,
-                      const boost::system::error_code& error)
-    {
-        if (!error) {
-            assert(new_client == listening_);
-            new_client->start();
-            listening_ = new TCPClient(io_service_);
-            acceptor_.async_accept(listening_->getSocket(),
-                                   boost::bind(&TCPServer::handleAccept,
-                                               this, listening_,
-                                               placeholders::error));
-        } else {
-            delete new_client;
-        }
-    }
-
-private:
-    io_service& io_service_;
-    tcp::acceptor acceptor_;
-    TCPClient* listening_;
-};
-
-class UDPServer {
-public:
-    UDPServer(io_service& io_service, int af, short port) :
-        io_service_(io_service),
-        socket_(io_service, af == AF_INET6 ? udp::v6() : udp::v4()),
-        response_buffer_(0),
-        response_renderer_(response_buffer_),
-        dns_message_(Message::PARSE)
-    {
-        // Set v6-only (we use a different instantiation for v4,
-        // otherwise asio will bind to both v4 and v6
-        if (af == AF_INET6) {
-            socket_.set_option(boost::asio::ip::v6_only(true));
-            socket_.bind(udp::endpoint(udp::v6(), port));
-        } else {
-            socket_.bind(udp::endpoint(udp::v4(), port));
-        }
-        startReceive();
-    }
-
-    void handleRequest(const boost::system::error_code& error,
-                       size_t bytes_recvd)
-    {
-        if (!error && bytes_recvd > 0) {
-            InputBuffer request_buffer(data_, bytes_recvd);
-
-            if (isNotifyMessage((const uint8_t *)data_))
-            {
-                handleNotify(sender_endpoint_, (uint8_t *)data_, bytes_recvd);
-                socket_.async_send_to(
-                        boost::asio::buffer(data_, bytes_recvd),
-                        sender_endpoint_,
-                        boost::bind(&UDPServer::sendCompleted,
-                            this,
-                            placeholders::error,
-                            placeholders::bytes_transferred));
-
-            }
-            else
-            {
-
-                dns_message_.clear(Message::PARSE);
-                response_renderer_.clear();
-                if (auth_server->processMessage(request_buffer, dns_message_,
-                            response_renderer_, true)) {
-                    socket_.async_send_to(
-                            boost::asio::buffer(response_buffer_.getData(),
-                                response_buffer_.getLength()),
-                            sender_endpoint_,
-                            boost::bind(&UDPServer::sendCompleted,
-                                this,
-                                placeholders::error,
-                                placeholders::bytes_transferred));
-                } else {
-                    startReceive();
-                }
-            }
-        } else {
-            startReceive();
-        }
-    }
-
-    void sendCompleted(const boost::system::error_code& error UNUSED_PARAM,
-                       size_t bytes_sent UNUSED_PARAM)
-    {
-        // Even if error occurred there's nothing to do.  Simply handle
-        // the next request.
-        startReceive();
-    }
-private:
-    void startReceive() {
-        socket_.async_receive_from(
-            boost::asio::buffer(data_, MAX_LENGTH), sender_endpoint_,
-            boost::bind(&UDPServer::handleRequest, this,
-                        placeholders::error,
-                        placeholders::bytes_transferred));
-    }
-
-private:
-    io_service& io_service_;
-    udp::socket socket_;
-    OutputBuffer response_buffer_;
-    MessageRenderer response_renderer_;
-    Message dns_message_;
-    udp::endpoint sender_endpoint_;
-    enum { MAX_LENGTH = 4096 };
-    char data_[MAX_LENGTH];
-};
-
-struct ServerSet {
-    ServerSet() : udp4_server(NULL), udp6_server(NULL),
-                  tcp4_server(NULL), tcp6_server(NULL)
-    {}
-    ~ServerSet() {
-        delete udp4_server;
-        delete udp6_server;
-        delete tcp4_server;
-        delete tcp6_server;
-    }
-    UDPServer* udp4_server;
-    UDPServer* udp6_server;
-    TCPServer* tcp4_server;
-    TCPServer* tcp6_server;
-};
-
-void
-run_server(const char* port, const bool use_ipv4, const bool use_ipv6,
-           AuthSrv* srv UNUSED_PARAM)
-{
-    ServerSet servers;
-    short portnum = atoi(port);
-
-    if (use_ipv4) {
-        servers.udp4_server = new UDPServer(io_service_, AF_INET, portnum);
-        servers.tcp4_server = new TCPServer(io_service_, AF_INET, portnum);
-    }
-    if (use_ipv6) {
-        servers.udp6_server = new UDPServer(io_service_, AF_INET6, portnum);
-        servers.tcp6_server = new TCPServer(io_service_, AF_INET6, portnum);
-    }
-
-    cout << "Server started." << endl;
-    io_service_.run();
-}
-#else  // !HAVE_BOOST_SYSTEM
-struct SocketSet {
-    SocketSet() : ups4(-1), tps4(-1), ups6(-1), tps6(-1) {}
-    ~SocketSet() {
-        if (ups4 >= 0) {
-            close(ups4);
-        }
-        if (tps4 >= 0) {
-            close(tps4);
-        }
-        if (ups6 >= 0) {
-            close(ups6);
-        }
-        if (tps4 >= 0) {
-            close(tps6);
-        }
-    }
-    int ups4, tps4, ups6, tps6;
-};
-
-int
-getUDPSocket(int af, const char* port) {
-    struct addrinfo hints, *res;
-
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = af;
-    hints.ai_socktype = SOCK_DGRAM;
-    hints.ai_flags = AI_PASSIVE;
-    hints.ai_protocol = IPPROTO_UDP;
-
-    int error = getaddrinfo(NULL, port, &hints, &res);
-    if (error != 0) {
-        isc_throw(FatalError, "getaddrinfo failed: " << gai_strerror(error));
-    }
-
-    int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
-    if (s < 0) {
-        isc_throw(FatalError, "failed to open socket");
-    }
-
-    if (af == AF_INET6) {
-        int on = 1;
-        if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
-            cerr << "couldn't set IPV6_V6ONLY socket option" << endl;
-            // proceed anyway
-        }
-    }
-
-    if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
-        isc_throw(FatalError, "binding socket failure");
-    }
-
-    return (s);
-}
-
-int
-getTCPSocket(int af, const char* port) {
-    struct addrinfo hints, *res;
-
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = af;
-    hints.ai_socktype = SOCK_STREAM;
-    hints.ai_flags = AI_PASSIVE;
-    hints.ai_protocol = IPPROTO_TCP;
-
-    int error = getaddrinfo(NULL, port, &hints, &res);
-    if (error != 0) {
-        isc_throw(FatalError, "getaddrinfo failed: " << gai_strerror(error));
-    }
-
-    int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
-    if (s < 0) {
-        isc_throw(FatalError, "failed to open socket");
-    }
-
-    int on = 1;
-    if (af == AF_INET6) {
-        if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
-            cerr << "couldn't set IPV6_V6ONLY socket option" << endl;
-        }
-        // proceed anyway
-    }
-
-    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
-        cerr << "couldn't set SO_REUSEADDR socket option" << endl;
-    }
-
-    if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
-        isc_throw(FatalError, "binding socket failure");
-    }
-
-    if (listen(s, 100) < 0) {
-        isc_throw(FatalError, "failed to listen on a TCP socket");
-    }
-    return (s);
-}
-
-void
-processMessageUDP(const int fd, Message& dns_message,
-                  MessageRenderer& response_renderer)
-{
-    struct sockaddr_storage ss;
-    socklen_t sa_len = sizeof(ss);
-    struct sockaddr* sa = static_cast<struct sockaddr*>((void*)&ss);
-    char recvbuf[4096];
-    int cc;
-
-    dns_message.clear(Message::PARSE);
-    response_renderer.clear();
-    if ((cc = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, sa, &sa_len)) > 0) {
-        InputBuffer buffer(recvbuf, cc);
-        if (auth_server->processMessage(buffer, dns_message, response_renderer,
-                                        true)) {
-            cc = sendto(fd, response_renderer.getData(),
-                        response_renderer.getLength(), 0, sa, sa_len);
-            if (cc != response_renderer.getLength()) {
-                cerr << "UDP send error" << endl;
-            }
-        }
-    } else if (verbose_mode) {
-        cerr << "UDP receive error" << endl;
-    }
-}
-
-// XXX: this function does not handle partial reads or partial writes,
-//      and is VERY UNSAFE - will probably be removed or rewritten
-void
-processMessageTCP(const int fd, Message& dns_message,
-                  MessageRenderer& response_renderer)
-{
-    struct sockaddr_storage ss;
-    socklen_t sa_len = sizeof(ss);
-    struct sockaddr* sa = static_cast<struct sockaddr*>((void*)&ss);
-    char sizebuf[2];
-    int cc;
-
-    int ts = accept(fd, sa, &sa_len);
-    if (ts < 0) {
-        if (verbose_mode) {
-            cerr << "[XX] TCP accept failure:" << endl;
-            return;
-        }
-    }
-
-    if (verbose_mode) {
-        cerr << "[XX] process TCP" << endl;
-    }
-    cc = recv(ts, sizebuf, 2, 0);
-    if (cc < 0) {
-        if (verbose_mode) {
-            cerr << "[XX] TCP recv failure:" << endl;
-        }
-        close(ts);
-        return;
-    }
-    if (verbose_mode) {
-        cerr << "[XX] got: " << cc << endl;
-    }
-    uint16_t size, size_n;
-    memcpy(&size_n, sizebuf, 2);
-    size = ntohs(size_n);
-    if (verbose_mode) {
-        cerr << "[XX] got: " << size << endl;
-    }
-
-    vector<char> message_buffer;
-    message_buffer.reserve(size);
-    cc = 0;
-    while (cc < size) {
-        if (verbose_mode) {
-            cerr << "[XX] cc now: " << cc << " of " << size << endl;
-        }
-        const int cc0 = recv(ts, &message_buffer[0] + cc, size - cc, 0);
-        if (cc0 < 0) {
-            if (verbose_mode) {
-                cerr << "TCP receive error" << endl;
-                close(ts);
-                return;
-            }
-        }
-        if (cc0 == 0) {
-            // client closed connection
-            close(ts);
-            return;
-        }
-        cc += cc0;
-    }
-
-    InputBuffer buffer(&message_buffer[0], size);
-    dns_message.clear(Message::PARSE);
-    response_renderer.clear();
-    if (auth_server->processMessage(buffer, dns_message, response_renderer,
-                                    false)) {
-        size = response_renderer.getLength();
-        size_n = htons(size);
-        if (send(ts, &size_n, 2, 0) == 2) {
-            cc = send(ts, response_renderer.getData(),
-                      response_renderer.getLength(), 0);
-            if (cc == -1) {
-                if (verbose_mode) {
-                    cerr << "[AuthSrv] error in sending TCP response message" <<
-                        endl;
-                }
-            } else {
-                if (verbose_mode) {
-                    cerr << "[XX] sent TCP response: " << cc << " bytes"
-                         << endl;
-                }
-            }
-        } else {
-            if (verbose_mode) {
-                cerr << "TCP send error" << endl;
-            }
-        }
-    }
- 
-   // TODO: we don't check for more queries on the stream atm
-    close(ts);
-}
-
-void
-run_server(const char* port, const bool use_ipv4, const bool use_ipv6,
-           AuthSrv* srv)
-{
-    SocketSet socket_set;
-    fd_set fds_base;
-    int nfds = -1;
-
-    FD_ZERO(&fds_base);
-    if (use_ipv4) {
-        socket_set.ups4 = getUDPSocket(AF_INET, port);
-        FD_SET(socket_set.ups4, &fds_base);
-        nfds = max(nfds, socket_set.ups4);
-        socket_set.tps4 = getTCPSocket(AF_INET, port);
-        FD_SET(socket_set.tps4, &fds_base);
-        nfds = max(nfds, socket_set.tps4);
-    }
-    if (use_ipv6) {
-        socket_set.ups6 = getUDPSocket(AF_INET6, port);
-        FD_SET(socket_set.ups6, &fds_base);
-        nfds = max(nfds, socket_set.ups6);
-        socket_set.tps6 = getTCPSocket(AF_INET6, port);
-        FD_SET(socket_set.tps6, &fds_base);
-        nfds = max(nfds, socket_set.tps6);
-    }
-    ++nfds;
-
-    cout << "Server started." << endl;
-    
-    if (srv->configSession() == NULL) {
-        isc_throw(FatalError, "Config session not initalized");
-    }
-
-    int ss = srv->configSession()->getSocket();
-    Message dns_message(Message::PARSE);
-    OutputBuffer resonse_buffer(0);
-    MessageRenderer response_renderer(resonse_buffer);
-
-    running = true;
-    while (running) {
-        fd_set fds = fds_base;
-        FD_SET(ss, &fds);
-        ++nfds;
-
-        if (srv->configSession()->hasQueuedMsgs()) {
-            srv->configSession()->checkCommand();
-        }
-        int n = select(nfds, &fds, NULL, NULL, NULL);
-        if (n < 0) {
-            if (errno != EINTR) {
-                isc_throw(FatalError, "select error");
-            }
-            continue;
-        }
-
-        if (socket_set.ups4 >= 0 && FD_ISSET(socket_set.ups4, &fds)) {
-            processMessageUDP(socket_set.ups4, dns_message, response_renderer);
-        }
-        if (socket_set.ups6 >= 0 && FD_ISSET(socket_set.ups6, &fds)) {
-            processMessageUDP(socket_set.ups6, dns_message, response_renderer);
-        }
-        if (socket_set.tps4 >= 0 && FD_ISSET(socket_set.tps4, &fds)) {
-            processMessageTCP(socket_set.tps4, dns_message, response_renderer);
-        }
-        if (socket_set.tps6 >= 0 && FD_ISSET(socket_set.tps6, &fds)) {
-            processMessageTCP(socket_set.tps6, dns_message, response_renderer);
-        }
-        if (FD_ISSET(ss, &fds)) {
-            srv->configSession()->checkCommand();
-        }
-    }
-}
-#endif // HAVE_BOOST_SYSTEM
 
 void
 usage() {
@@ -799,7 +127,7 @@
     }
 
     if (!use_ipv4 && !use_ipv6) {
-        cerr << "-4 and -6 can't coexist" << endl;
+        cerr << "[b10-auth] Error: -4 and -6 can't coexist" << endl;
         usage();
     }
 
@@ -817,22 +145,23 @@
         auth_server = new AuthSrv;
         auth_server->setVerbose(verbose_mode);
 
-#ifdef HAVE_BOOST_SYSTEM
-        ModuleCCSession cs(specfile, io_service_, my_config_handler,
-                           my_command_handler);
-#else
-        ModuleCCSession cs(specfile, my_config_handler, my_command_handler);
-#endif
+        io_service = new asio_link::IOService(auth_server, port, use_ipv4,
+                                              use_ipv6);
+
+        ModuleCCSession cs(specfile, io_service->get_io_service(), my_config_handler, my_command_handler);
 
         auth_server->setConfigSession(&cs);
         auth_server->updateConfig(ElementPtr());
 
-        run_server(port, use_ipv4, use_ipv6, auth_server);
+        
+        cout << "[b10-auth] Server started." << endl;
+        io_service->run();
     } catch (const std::exception& ex) {
         cerr << ex.what() << endl;
         ret = 1;
     }
 
+    delete io_service;
     delete auth_server;
     return (ret);
 }

Modified: branches/feng-authnotify/src/bin/auth/tests/Makefile.am
==============================================================================
--- branches/feng-authnotify/src/bin/auth/tests/Makefile.am (original)
+++ branches/feng-authnotify/src/bin/auth/tests/Makefile.am Sun Jun 13 05:59:13 2010
@@ -1,6 +1,8 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/bin
 AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda
 
@@ -9,7 +11,7 @@
 TESTS += run_unittests
 run_unittests_SOURCES = $(top_srcdir)/src/lib/dns/tests/unittest_util.h
 run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
-run_unittests_SOURCES += ../auth_srv.h ../auth_srv.cc
+run_unittests_SOURCES += ../auth_srv.h ../auth_srv.cc ../asio_link.cc ../asio_link.h ../auth_util.h ../auth_util.cc
 run_unittests_SOURCES += auth_srv_unittest.cc
 run_unittests_SOURCES += run_unittests.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
@@ -20,11 +22,8 @@
 run_unittests_LDADD +=  $(top_builddir)/src/lib/dns/.libs/libdns.a
 run_unittests_LDADD += $(top_builddir)/src/lib/config/.libs/libcfgclient.a
 run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.a
-run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
-if HAVE_BOOST_SYSTEM
-run_unittests_LDFLAGS += $(BOOST_LDFLAGS)
-run_unittests_LDADD += $(BOOST_SYSTEM_LIB)
-endif
+run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a 
+run_unittests_LDADD += $(top_builddir)/src/lib/xfr/.libs/libxfr.a
 endif
 
 noinst_PROGRAMS = $(TESTS)

Modified: branches/feng-authnotify/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/feng-authnotify/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/feng-authnotify/src/bin/auth/tests/auth_srv_unittest.cc Sun Jun 13 05:59:13 2010
@@ -26,8 +26,9 @@
 #include <cc/data.h>
 
 #include <auth/auth_srv.h>
-
+#include <auth/asio_link.h>
 #include <dns/tests/unittest_util.h>
+#include <iostream>
 
 using isc::UnitTestUtil;
 using namespace std;
@@ -44,27 +45,19 @@
 
 class AuthSrvTest : public ::testing::Test {
 protected:
-    AuthSrvTest() : request_message(Message::RENDER),
-                    parse_message(Message::PARSE), default_qid(0x1035),
+    AuthSrvTest() : default_qid(0x1035),
                     opcode(Opcode(Opcode::QUERY())), qname("www.example.com"),
-                    qclass(RRClass::IN()), qtype(RRType::A()), ibuffer(NULL),
-                    request_obuffer(0), request_renderer(request_obuffer),
-                    response_obuffer(0), response_renderer(response_obuffer)
+                    qclass(RRClass::IN()), qtype(RRType::A()), 
+                    userInfo(asio_link::UserInfo::QueryThroughUDP)
     {}
     AuthSrv server;
-    Message request_message;
-    Message parse_message;
     const qid_t default_qid;
     const Opcode opcode;
     const Name qname;
     const RRClass qclass;
     const RRType qtype;
-    InputBuffer* ibuffer;
-    OutputBuffer request_obuffer;
-    MessageRenderer request_renderer;
-    OutputBuffer response_obuffer;
-    MessageRenderer response_renderer;
     vector<uint8_t> data;
+    asio_link::UserInfo userInfo;
 
     void createDataFromFile(const char* const datafile);
 };
@@ -82,20 +75,20 @@
 
 void
 AuthSrvTest::createDataFromFile(const char* const datafile) {
-    delete ibuffer;
     data.clear();
 
     UnitTestUtil::readWireData(datafile, data);
-    ibuffer = new InputBuffer(&data[0], data.size());
+    userInfo.setQueryRawData((char *)&data[0], data.size());
 }
 
 void
-headerCheck(const Message& message, const qid_t qid, const Rcode& rcode,
+responseHeaderCheck(const asio_link::UserInfo &userInfo, const qid_t qid, const Rcode& rcode,
             const uint16_t opcodeval, const unsigned int flags,
             const unsigned int qdcount,
             const unsigned int ancount, const unsigned int nscount,
             const unsigned int arcount)
 {
+    const Message &message = userInfo.getMessage();
     EXPECT_EQ(qid, message.getQid());
     EXPECT_EQ(rcode, message.getRcode());
     EXPECT_EQ(opcodeval, message.getOpcode().getCode());
@@ -118,13 +111,15 @@
     for (unsigned int i = 1; i < 16; ++i) {
         // set Opcode to 'i', which iterators over all possible codes except
         // the standard query (0)
+        if (i == 4 || i == 5)
+            continue;
         createDataFromFile("simplequery_fromWire");
         data[2] = ((i << 3) & 0xff);
-
-        parse_message.clear(Message::PARSE);
-        EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
-                                              response_renderer, true));
-        headerCheck(parse_message, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
+        userInfo.setQueryRawData((char *)&data[0], data.size());
+
+        EXPECT_EQ(true, userInfo.isMessageValid());
+        server.processQuery(userInfo);
+        responseHeaderCheck(userInfo, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
                     0, 0, 0, 0);
     }
 }
@@ -141,11 +136,13 @@
 // Multiple questions.  Should result in FORMERR.
 TEST_F(AuthSrvTest, multiQuestion) {
     createDataFromFile("multiquestion_fromWire");
-    EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
-                                          response_renderer, true));
-    headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
+    EXPECT_EQ(true, userInfo.isMessageValid());
+    EXPECT_EQ(true, userInfo.needsReply());
+    server.processQuery(userInfo);
+    responseHeaderCheck(userInfo, default_qid, Rcode::FORMERR(), opcode.getCode(),
                 QR_FLAG, 2, 0, 0, 0);
 
+    Message &parse_message = userInfo.getMessage();
     QuestionIterator qit = parse_message.beginQuestion();
     EXPECT_EQ(Name("example.com"), (*qit)->getName());
     EXPECT_EQ(RRClass::IN(), (*qit)->getClass());
@@ -162,8 +159,8 @@
 // dropped.
 TEST_F(AuthSrvTest, shortMessage) {
     createDataFromFile("shortmessage_fromWire");
-    EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
-                                           response_renderer, true));
+    EXPECT_EQ(false, userInfo.isMessageValid());
+    EXPECT_EQ(false, userInfo.needsReply());
 }
 
 // Response messages.  Must be silently dropped, whether it's a valid response
@@ -171,43 +168,41 @@
 TEST_F(AuthSrvTest, response) {
     // A valid (although unusual) response
     createDataFromFile("simpleresponse_fromWire");
-    EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
-                                           response_renderer, true));
+    EXPECT_EQ(false, userInfo.isMessageValid());
+    EXPECT_EQ(false, userInfo.needsReply());
 
     // A response with a broken question section.  must be dropped rather than
     // returning FORMERR.
     createDataFromFile("shortresponse_fromWire");
-    EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
-                                           response_renderer, true));
+    EXPECT_EQ(false, userInfo.isMessageValid());
+    EXPECT_EQ(false, userInfo.needsReply());
 
     // A response to iquery.  must be dropped rather than returning NOTIMP.
     createDataFromFile("iqueryresponse_fromWire");
-    EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
-                                           response_renderer, true));
+    EXPECT_EQ(false, userInfo.isMessageValid());
+    EXPECT_EQ(false, userInfo.needsReply());
 }
 
 // Query with a broken question
 TEST_F(AuthSrvTest, shortQuestion) {
     createDataFromFile("shortquestion_fromWire");
-    EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
-                                          response_renderer, true));
-    // Since the query's question is broken, the question section of the
-    // response should be empty.
-    headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
-                QR_FLAG, 0, 0, 0, 0);
+    EXPECT_EQ(false, userInfo.isMessageValid());
+    EXPECT_EQ(true, userInfo.needsReply());
+
+    responseHeaderCheck(userInfo, default_qid, Rcode::FORMERR(), opcode.getCode(),
+            QR_FLAG, 0, 0, 0, 0);
 }
 
 // Query with a broken answer section
 TEST_F(AuthSrvTest, shortAnswer) {
     createDataFromFile("shortanswer_fromWire");
-    EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
-                                          response_renderer, true));
-
-    // This is a bogus query, but question section is valid.  So the response
-    // should copy the question section.
-    headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
-                QR_FLAG, 1, 0, 0, 0);
-
+    EXPECT_EQ(false, userInfo.isMessageValid());
+    EXPECT_EQ(true, userInfo.needsReply());
+
+    responseHeaderCheck(userInfo, default_qid, Rcode::FORMERR(), opcode.getCode(),
+            QR_FLAG, 1, 0, 0, 0);
+    
+    Message &parse_message = userInfo.getMessage();
     QuestionIterator qit = parse_message.beginQuestion();
     EXPECT_EQ(Name("example.com"), (*qit)->getName());
     EXPECT_EQ(RRClass::IN(), (*qit)->getClass());
@@ -216,17 +211,21 @@
     EXPECT_TRUE(qit == parse_message.endQuestion());
 }
 
+
+
 // Query with unsupported version of EDNS.
 TEST_F(AuthSrvTest, ednsBadVers) {
     createDataFromFile("queryBadEDNS_fromWire");
-    EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
-                                          response_renderer, true));
+    EXPECT_EQ(false, userInfo.isMessageValid());
+    EXPECT_EQ(true, userInfo.needsReply());
 
     // The response must have an EDNS OPT RR in the additional section.
     // Note that the DNSSEC DO bit is cleared even if this bit in the query
     // is set.  This is a limitation of the current implementation.
-    headerCheck(parse_message, default_qid, Rcode::BADVERS(), opcode.getCode(),
+    responseHeaderCheck(userInfo, default_qid, Rcode::BADVERS(), opcode.getCode(),
                 QR_FLAG, 1, 0, 0, 1);
+
+    Message &parse_message = userInfo.getMessage();
     EXPECT_EQ(4096, parse_message.getUDPSize());
     EXPECT_FALSE(parse_message.isDNSSECSupported());
 }
@@ -253,9 +252,9 @@
     // response should have the AA flag on, and have an RR in each answer
     // and authority section.
     createDataFromFile("examplequery_fromWire");
-    EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
-                                          response_renderer, true));
-    headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
+    EXPECT_EQ(true, userInfo.isMessageValid());
+    server.processQuery(userInfo);
+    responseHeaderCheck(userInfo, default_qid, Rcode::NOERROR(), opcode.getCode(),
                 QR_FLAG | AA_FLAG, 1, 1, 1, 0);
 }
 
@@ -267,9 +266,9 @@
     // in a SERVFAIL response, and the answer and authority sections should
     // be empty.
     createDataFromFile("badExampleQuery_fromWire");
-    EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
-                                          response_renderer, true));
-    headerCheck(parse_message, default_qid, Rcode::SERVFAIL(), opcode.getCode(),
+    EXPECT_EQ(true, userInfo.isMessageValid());
+    server.processQuery(userInfo);
+    responseHeaderCheck(userInfo, default_qid, Rcode::SERVFAIL(), opcode.getCode(),
                 QR_FLAG, 1, 0, 0, 0);
 }
 
@@ -282,9 +281,9 @@
 
     // The original data source should still exist.
     createDataFromFile("examplequery_fromWire");
-    EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
-                                          response_renderer, true));
-    headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
+    EXPECT_EQ(true, userInfo.isMessageValid());
+    server.processQuery(userInfo);
+    responseHeaderCheck(userInfo, default_qid, Rcode::NOERROR(), opcode.getCode(),
                 QR_FLAG | AA_FLAG, 1, 1, 1, 0);
 }
 }




More information about the bind10-changes mailing list