[svn] commit: r2177 - in /branches/trac221/src/bin/auth: asio_link.cc auth_srv.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Sun Jun 20 06:31:46 UTC 2010
Author: jinmei
Date: Sun Jun 20 06:31:45 2010
New Revision: 2177
Log:
refactoring: moved XFR logic from asio_link to auth_srv.
Modified:
branches/trac221/src/bin/auth/asio_link.cc
branches/trac221/src/bin/auth/auth_srv.cc
Modified: branches/trac221/src/bin/auth/asio_link.cc
==============================================================================
--- branches/trac221/src/bin/auth/asio_link.cc (original)
+++ branches/trac221/src/bin/auth/asio_link.cc Sun Jun 20 06:31:45 2010
@@ -26,15 +26,9 @@
#include <dns/message.h>
#include <dns/messagerenderer.h>
-#if defined(HAVE_BOOST_PYTHON)
-#define USE_XFROUT
-#include <xfr/xfrout_client.h>
-#endif
-
#include <asio_link.h>
-#include "spec_config.h" // for XFROUT. should not be here.
-#include "auth_srv.h"
+#include <auth/auth_srv.h>
using namespace asio;
using asio::ip::udp;
@@ -42,56 +36,6 @@
using namespace std;
using namespace isc::dns;
-#ifdef USE_XFROUT
-using namespace isc::xfr;
-#endif
-
-namespace {
-// As a short term workaround, we have XFROUT specific code. We should soon
-// refactor the code with some abstraction so that we can separate this level
-// details from the (AS)IO module.
-#ifdef USE_XFROUT
-//TODO. The sample way for checking axfr query, the code should be merged to auth server class
-bool
-check_axfr_query(char* const msg_data, const uint16_t msg_len) {
- if (msg_len < 15) {
- return false;
- }
-
- const 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
-void
-dispatch_axfr_query(const int tcp_sock, char const axfr_query[],
- const uint16_t query_len)
-{
- string path;
- if (getenv("B10_FROM_BUILD")) {
- path = string(getenv("B10_FROM_BUILD")) + "/auth_xfrout_conn";
- } else {
- path = 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 exception & err) {
- //if (verbose_mode)
- cerr << "error handle xfr query:" << err.what() << endl;
- }
-}
-#endif
-}
namespace asio_link {
IOAddress::IOAddress(const string& address_str) :
@@ -243,29 +187,19 @@
return;
}
-#ifdef USE_XFROUT
- if (check_axfr_query(data_, bytes_transferred)) {
- dispatch_axfr_query(socket_.native(), data_, bytes_transferred);
- // start to get new query ?
- start();
+ if (auth_server_->processMessage(io_message, dns_message_,
+ response_renderer_)) {
+ responselen_buffer_.writeUint16(
+ response_buffer_.getLength());
+ async_write(socket_,
+ asio::buffer(
+ responselen_buffer_.getData(),
+ responselen_buffer_.getLength()),
+ boost::bind(&TCPClient::responseWrite, this,
+ placeholders::error));
} else {
-#endif
- if (auth_server_->processMessage(io_message, dns_message_,
- response_renderer_)) {
- responselen_buffer_.writeUint16(
- response_buffer_.getLength());
- async_write(socket_,
- asio::buffer(
- responselen_buffer_.getData(),
- responselen_buffer_.getLength()),
- boost::bind(&TCPClient::responseWrite, this,
- placeholders::error));
- } else {
- delete this;
- }
-#ifdef USE_XFROUT
+ delete this;
}
-#endif
} else {
delete this;
}
Modified: branches/trac221/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac221/src/bin/auth/auth_srv.cc (original)
+++ branches/trac221/src/bin/auth/auth_srv.cc Sun Jun 20 06:31:45 2010
@@ -14,6 +14,8 @@
// $Id$
+#include <config.h> // for UNUSED_PARAM
+
#include <netinet/in.h>
#include <algorithm>
@@ -42,9 +44,15 @@
#include <cc/data.h>
+#if defined(HAVE_BOOST_PYTHON)
+#define USE_XFROUT
+#include <xfr/xfrout_client.h>
+#endif
+
#include <auth/common.h>
#include <auth/auth_srv.h>
#include <auth/asio_link.h>
+#include <auth/spec_config.h>
#include <boost/lexical_cast.hpp>
@@ -56,6 +64,9 @@
using namespace isc::dns::rdata;
using namespace isc::data;
using namespace isc::config;
+#ifdef USE_XFROUT
+using namespace isc::xfr;
+#endif
using namespace asio_link;
class AuthSrvImpl {
@@ -65,9 +76,13 @@
AuthSrvImpl& operator=(const AuthSrvImpl& source);
public:
AuthSrvImpl();
-
isc::data::ElementPtr setDbFile(const isc::data::ElementPtr config);
+ bool processNormalQuery(const IOMessage& io_message, Message& message,
+ MessageRenderer& response_renderer);
+ bool processAxfrQuery(const IOMessage& io_message) const;
+ bool processIxfrQuery(const IOMessage& io_message,
+ const ConstQuestionPtr question) const;
std::string db_file_;
ModuleCCSession* cs_;
MetaDataSrc data_sources_;
@@ -78,11 +93,14 @@
bool verbose_mode_;
+ const string xfr_path_; // currently non configurable
+
/// Currently non-configurable, but will be.
static const uint16_t DEFAULT_LOCAL_UDPSIZE = 4096;
};
-AuthSrvImpl::AuthSrvImpl() : cs_(NULL), verbose_mode_(false)
+AuthSrvImpl::AuthSrvImpl() : cs_(NULL), verbose_mode_(false),
+ xfr_path_(UNIX_SOCKET_FILE)
{
// cur_datasrc_ is automatically initialized by the default constructor,
// effectively being an empty (sqlite) data source. once ccsession is up
@@ -234,6 +252,22 @@
return (true);
}
+ ConstQuestionPtr question = *message.beginQuestion();
+ const RRType &qtype = question->getType();
+ if (qtype == RRType::AXFR()) {
+ return (impl_->processAxfrQuery(io_message));
+ } else if (qtype == RRType::IXFR()) {
+ return (impl_->processIxfrQuery(io_message, question));
+ } else {
+ return (impl_->processNormalQuery(io_message, message,
+ response_renderer));
+ }
+}
+
+bool
+AuthSrvImpl::processNormalQuery(const IOMessage& io_message, Message& message,
+ MessageRenderer& response_renderer)
+{
const bool dnssec_ok = message.isDNSSECSupported();
const uint16_t remote_bufsize = message.getUDPSize();
@@ -245,13 +279,14 @@
try {
Query query(message, dnssec_ok);
- impl_->data_sources_.doQuery(query);
+ data_sources_.doQuery(query);
} catch (const Exception& ex) {
- if (impl_->verbose_mode_) {
- cerr << "[b10-auth] Internal error, returning SERVFAIL: " << ex.what() << endl;
+ if (verbose_mode_) {
+ cerr << "[b10-auth] Internal error, returning SERVFAIL: " <<
+ ex.what() << endl;
}
makeErrorMessage(message, response_renderer, Rcode::SERVFAIL(),
- impl_->verbose_mode_);
+ verbose_mode_);
return (true);
}
@@ -259,13 +294,85 @@
(io_message.getSocket().getProtocol() == IPPROTO_UDP);
response_renderer.setLengthLimit(udp_buffer ? remote_bufsize : 65535);
message.toWire(response_renderer);
- if (impl_->verbose_mode_) {
+ if (verbose_mode_) {
cerr << "[b10-auth] sending a response (" <<
boost::lexical_cast<string>(response_renderer.getLength())
<< " bytes):\n" << message.toText() << endl;
}
return (true);
+}
+
+#ifdef USE_XFROUT
+bool
+AuthSrvImpl::processAxfrQuery(const IOMessage& io_message) const {
+ XfroutClient xfr_client(xfr_path_);
+
+ // XXX: should reject AXFR/UDP here.
+
+ try {
+ xfr_client.connect();
+ xfr_client.sendXfroutRequestInfo(io_message.getSocket().getNative(),
+ io_message.getData(),
+ io_message.getDataSize());
+ xfr_client.disconnect();
+ } catch (const exception& err) { // XXX: avoid catch-all catch!!
+ if (verbose_mode_) {
+ cerr << "[b10-auth] Error in handling XFR request:" << err.what()
+ << endl;
+ }
+ // XXX: should return an error (SERVFAIL?)
+ }
+
+ return (false);
+}
+#else
+bool
+AuthSrvImpl::processAxfrQuery(const IOMessage& io_message UNUSED_PARAM) const {
+ // should better to return an error message, but hopefully this case
+ // is short term workaround.
+ return (false);
+}
+#endif
+
+bool
+AuthSrvImpl::processIxfrQuery(const IOMessage& io_message,
+ const ConstQuestionPtr question) const
+{
+ // XXX: this function seems unacceptably expensive. Also, error cases
+ // aren't handled at all, which is bad.
+
+ // TODO check with the conf-mgr whether current server is the auth of the
+ // zone
+ isc::cc::Session tmp_session_with_xfr;
+ // this can block, expensive, and may throw exception. all bad.
+ tmp_session_with_xfr.establish();
+
+ // XXX: the following is super expensive.
+ const string remote_ip_address = io_message.getRemoteAddress().toText();
+ ElementPtr notify_command = Element::createFromString(
+ "{\"command\": [\"notify\", {\"zone_name\" : \"" +
+ question->getName().toText() + "\", \"master_ip\" : \"" +
+ remote_ip_address + "\"}]}");
+ // what if this fails?
+
+ const unsigned int seq =
+ tmp_session_with_xfr.group_sendmsg(notify_command, "Xfrin");
+ // this can trigger an exception. handle it.
+
+ ElementPtr env, answer;
+ tmp_session_with_xfr.group_recvmsg(env, answer, false, seq);
+ int rcode;
+ ElementPtr err = parseAnswer(rcode, answer);
+ if (rcode != 0) {
+ if (verbose_mode_) {
+ // XXX: should add the reason for the error
+ cerr << "[b10=auth] notify send failed" << endl;
+ }
+ // XXX: should return an error (SERVFAIL?)
+ }
+
+ return (false);
}
ElementPtr
More information about the bind10-changes
mailing list