Commit f0f818b2 authored by Evan Hunt's avatar Evan Hunt

Addressed some review comments, including:

 - added diagrams to asiolink documentation
 - eliminated improper error return in TCPServer operator()
 - moved UDPEndpoint, TCPEndpoint, UDPSOcket, TCPSOcket implementation
   code into internal/udpdns.h and internal/tcpdns.h
 - RecursiveQuery ns_addr_ member now an IOAddress rather than asio address
 - add method headers in recursor.h and auth_srv.h
 - change asio_link unittest name to asiolink


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac327@3177 e5f2f494-b856-4b98-b285-d166d9295462
parent ad55ea2d
...@@ -174,8 +174,8 @@ class ConfigChecker : public SimpleCallback { ...@@ -174,8 +174,8 @@ class ConfigChecker : public SimpleCallback {
public: public:
ConfigChecker(AuthSrv* srv) : server_(srv) {} ConfigChecker(AuthSrv* srv) : server_(srv) {}
virtual void operator()(const IOMessage& io_message UNUSED_PARAM) const { virtual void operator()(const IOMessage& io_message UNUSED_PARAM) const {
if (server_->configSession()->hasQueuedMsgs()) { if (server_->getConfigSession()->hasQueuedMsgs()) {
server_->configSession()->checkCommand(); server_->getConfigSession()->checkCommand();
} }
} }
private: private:
...@@ -270,7 +270,7 @@ AuthSrv::setConfigSession(ModuleCCSession* config_session) { ...@@ -270,7 +270,7 @@ AuthSrv::setConfigSession(ModuleCCSession* config_session) {
} }
ModuleCCSession* ModuleCCSession*
AuthSrv::configSession() const { AuthSrv::getConfigSession() const {
return (impl_->config_session_); return (impl_->config_session_);
} }
......
...@@ -30,10 +30,6 @@ class AbstractXfroutClient; ...@@ -30,10 +30,6 @@ class AbstractXfroutClient;
} }
} }
namespace asiolink {
class IOMessage;
}
class AuthSrvImpl; class AuthSrvImpl;
class AuthSrv { class AuthSrv {
...@@ -58,30 +54,37 @@ public: ...@@ -58,30 +54,37 @@ public:
isc::xfr::AbstractXfroutClient& xfrout_client); isc::xfr::AbstractXfroutClient& xfrout_client);
~AuthSrv(); ~AuthSrv();
//@} //@}
/// \return \c true if the \message contains a response to be returned;
/// otherwise \c false. /// \brief Process an incoming DNS message, then signal 'server' to resume
void processMessage(const asiolink::IOMessage& io_message, void processMessage(const asiolink::IOMessage& io_message,
isc::dns::MessagePtr message, isc::dns::MessagePtr message,
isc::dns::OutputBufferPtr buffer, isc::dns::OutputBufferPtr buffer,
asiolink::DNSServer* server); asiolink::DNSServer* server);
// \brief Set and get verbose mode
void setVerbose(bool on); void setVerbose(bool on);
bool getVerbose() const; bool getVerbose() const;
isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
isc::config::ModuleCCSession* configSession() const; /// \brief Set and get the config session
void setConfigSession(isc::config::ModuleCCSession* config_session); void setConfigSession(isc::config::ModuleCCSession* config_session);
isc::config::ModuleCCSession* getConfigSession() const;
/// \brief Handle commands from the config session
isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
/// \brief Assign an ASIO IO Service queue to this Recursor object
void setIOService(asiolink::IOService& ios) { io_service_ = &ios; } void setIOService(asiolink::IOService& ios) { io_service_ = &ios; }
/// \brief Return this object's ASIO IO Service queue
asiolink::IOService& getIOService() const { return (*io_service_); } asiolink::IOService& getIOService() const { return (*io_service_); }
asiolink::DNSLookup* getDNSLookupProvider() const { /// \brief Return pointer to the DNS Lookup callback function
return (dns_lookup_); asiolink::DNSLookup* getDNSLookupProvider() const { return (dns_lookup_); }
}
asiolink::DNSAnswer* getDNSAnswerProvider() const { /// \brief Return pointer to the DNS Answer callback function
return (dns_answer_); asiolink::DNSAnswer* getDNSAnswerProvider() const { return (dns_answer_); }
}
asiolink::SimpleCallback* getCheckinProvider() const { /// \brief Return pointer to the Checkin callback function
return (checkin_); asiolink::SimpleCallback* getCheckinProvider() const { return (checkin_); }
}
/// ///
/// Note: this interface is tentative. We'll revisit the ASIO and session /// Note: this interface is tentative. We'll revisit the ASIO and session
......
...@@ -55,17 +55,17 @@ using namespace asiolink; ...@@ -55,17 +55,17 @@ using namespace asiolink;
namespace { namespace {
bool verbose_mode = false; static bool verbose_mode = false;
const string PROGRAM = "Auth"; static const string PROGRAM = "Auth";
const char* DNSPORT = "5300"; static const char* DNSPORT = "5300";
/* need global var for config/command handlers. /* need global var for config/command handlers.
* todo: turn this around, and put handlers in the authserver * todo: turn this around, and put handlers in the authserver
* class itself? */ * class itself? */
AuthSrv *auth_server; static AuthSrv *auth_server;
IOService* io_service; static IOService* io_service;
ConstElementPtr ConstElementPtr
my_config_handler(ConstElementPtr new_config) { my_config_handler(ConstElementPtr new_config) {
...@@ -89,7 +89,14 @@ my_command_handler(const string& command, ConstElementPtr args) { ...@@ -89,7 +89,14 @@ my_command_handler(const string& command, ConstElementPtr args) {
void void
usage() { usage() {
cerr << "Usage: b10-auth [-a address] [-p port] [-4|-6] [-nv]" << endl; cerr << "Usage: b10-auth [-a address] [-p port] [-4|-6] [-nv]" << endl;
cerr << "\t-a: specify the address to listen on (default: all) " << endl;
cerr << "\t-p: specify the port to listen on (default: 5300)" << endl;
cerr << "\t-4: listen on all IPv4 addresses (incompatible with -a)" << endl;
cerr << "\t-4: listen on all IPv6 addresses (incompatible with -a)" << endl;
cerr << "\t-n: do not cache answers in memory" << endl;
cerr << "\t-u: change process UID to the specified user" << endl;
cerr << "\t-v: verbose output" << endl;
exit(1); exit(1);
} }
} // end of anonymous namespace } // end of anonymous namespace
...@@ -141,12 +148,14 @@ main(int argc, char* argv[]) { ...@@ -141,12 +148,14 @@ main(int argc, char* argv[]) {
} }
if (!use_ipv4 && !use_ipv6) { if (!use_ipv4 && !use_ipv6) {
cerr << "[b10-auth] Error: -4 and -6 can't coexist" << endl; cerr << "[b10-auth] Error: Cannot specify both -4 and -6 "
<< "at the same time" << endl;
usage(); usage();
} }
if ((!use_ipv4 || !use_ipv6) && address != NULL) { if ((!use_ipv4 || !use_ipv6) && address != NULL) {
cerr << "[b10-auth] Error: -4|-6 and -a can't coexist" << endl; cerr << "[b10-auth] Error: Cannot specify -4 or -6 "
<< "at the same time as -a" << endl;
usage(); usage();
} }
......
...@@ -56,13 +56,13 @@ using namespace asiolink; ...@@ -56,13 +56,13 @@ using namespace asiolink;
namespace { namespace {
bool verbose_mode = false; static bool verbose_mode = false;
const string PROGRAM = "Recurse"; static const string PROGRAM = "Recurse";
const char* DNSPORT = "5300"; static const char* DNSPORT = "5300";
IOService* io_service; static IOService* io_service;
Recursor *recursor; static Recursor *recursor;
ConstElementPtr ConstElementPtr
my_config_handler(ConstElementPtr new_config) { my_config_handler(ConstElementPtr new_config) {
...@@ -86,8 +86,16 @@ my_command_handler(const string& command, ConstElementPtr args) { ...@@ -86,8 +86,16 @@ my_command_handler(const string& command, ConstElementPtr args) {
void void
usage() { usage() {
cerr << "Usage: b10-recurse -f nameserver [-a address] [-p port] " cerr << "Usage: b10-recurse -f nameserver [-a address] [-p port] "
"[-4|-6] [-nv]" << endl; "[-4|-6] [-v]" << endl;
cerr << "\t-f: specify the nameserver to which queries should be forwarded"
<< endl;
cerr << "\t-a: specify the address to listen on (default: all)" << endl;
cerr << "\t-p: specify the port to listen on (default: 5300)" << endl;
cerr << "\t-4: listen on all IPv4 addresses (incompatible with -a)" << endl;
cerr << "\t-4: listen on all IPv6 addresses (incompatible with -a)" << endl;
cerr << "\t-u: change process UID to the specified user" << endl;
cerr << "\t-v: verbose output" << endl;
exit(1); exit(1);
} }
} // end of anonymous namespace } // end of anonymous namespace
...@@ -99,9 +107,9 @@ main(int argc, char* argv[]) { ...@@ -99,9 +107,9 @@ main(int argc, char* argv[]) {
const char* address = NULL; const char* address = NULL;
const char* forward = NULL; const char* forward = NULL;
const char* uid = NULL; const char* uid = NULL;
bool use_ipv4 = true, use_ipv6 = true, cache = true; bool use_ipv4 = true, use_ipv6 = true;
while ((ch = getopt(argc, argv, "46a:f:np:u:v")) != -1) { while ((ch = getopt(argc, argv, "46a:f:p:u:v")) != -1) {
switch (ch) { switch (ch) {
case '4': case '4':
// Note that -4 means "ipv4 only", we need to set "use_ipv6" here, // Note that -4 means "ipv4 only", we need to set "use_ipv6" here,
...@@ -114,9 +122,6 @@ main(int argc, char* argv[]) { ...@@ -114,9 +122,6 @@ main(int argc, char* argv[]) {
// The same note as -4 applies. // The same note as -4 applies.
use_ipv4 = false; use_ipv4 = false;
break; break;
case 'n':
cache = false;
break;
case 'a': case 'a':
address = optarg; address = optarg;
break; break;
...@@ -143,12 +148,14 @@ main(int argc, char* argv[]) { ...@@ -143,12 +148,14 @@ main(int argc, char* argv[]) {
} }
if (!use_ipv4 && !use_ipv6) { if (!use_ipv4 && !use_ipv6) {
cerr << "[b10-recurse] Error: -4 and -6 can't coexist" << endl; cerr << "[b10-auth] Error: Cannot specify both -4 and -6 "
<< "at the same time" << endl;
usage(); usage();
} }
if ((!use_ipv4 || !use_ipv6) && address != NULL) { if ((!use_ipv4 || !use_ipv6) && address != NULL) {
cerr << "[b10-recurse] Error: -4|-6 and -a can't coexist" << endl; cerr << "[b10-auth] Error: Cannot specify -4 or -6 "
<< "at the same time as -a" << endl;
usage(); usage();
} }
...@@ -172,7 +179,7 @@ main(int argc, char* argv[]) { ...@@ -172,7 +179,7 @@ main(int argc, char* argv[]) {
} }
recursor = new Recursor(*forward); recursor = new Recursor(*forward);
recursor ->setVerbose(verbose_mode); recursor->setVerbose(verbose_mode);
cout << "[b10-recurse] Server created." << endl; cout << "[b10-recurse] Server created." << endl;
SimpleCallback* checkin = recursor->getCheckinProvider(); SimpleCallback* checkin = recursor->getCheckinProvider();
......
...@@ -85,6 +85,7 @@ public: ...@@ -85,6 +85,7 @@ public:
void processNormalQuery(const Question& question, MessagePtr message, void processNormalQuery(const Question& question, MessagePtr message,
OutputBufferPtr buffer, OutputBufferPtr buffer,
DNSServer* server); DNSServer* server);
ModuleCCSession* config_session_; ModuleCCSession* config_session_;
bool verbose_mode_; bool verbose_mode_;
...@@ -271,8 +272,8 @@ class ConfigCheck : public SimpleCallback { ...@@ -271,8 +272,8 @@ class ConfigCheck : public SimpleCallback {
public: public:
ConfigCheck(Recursor* srv) : server_(srv) {} ConfigCheck(Recursor* srv) : server_(srv) {}
virtual void operator()(const IOMessage& io_message UNUSED_PARAM) const { virtual void operator()(const IOMessage& io_message UNUSED_PARAM) const {
if (server_->configSession()->hasQueuedMsgs()) { if (server_->getConfigSession()->hasQueuedMsgs()) {
server_->configSession()->checkCommand(); server_->getConfigSession()->checkCommand();
} }
} }
private: private:
...@@ -316,7 +317,7 @@ Recursor::setConfigSession(ModuleCCSession* config_session) { ...@@ -316,7 +317,7 @@ Recursor::setConfigSession(ModuleCCSession* config_session) {
} }
ModuleCCSession* ModuleCCSession*
Recursor::configSession() const { Recursor::getConfigSession() const {
return (impl_->config_session_); return (impl_->config_session_);
} }
......
...@@ -24,16 +24,6 @@ ...@@ -24,16 +24,6 @@
#include <asiolink/asiolink.h> #include <asiolink/asiolink.h>
namespace isc {
namespace dns {
class InputBuffer;
}
}
namespace asiolink {
class IOMessage;
}
class RecursorImpl; class RecursorImpl;
class Recursor { class Recursor {
...@@ -56,30 +46,38 @@ public: ...@@ -56,30 +46,38 @@ public:
Recursor(const char& forward); Recursor(const char& forward);
~Recursor(); ~Recursor();
//@} //@}
/// \return \c true if the \message contains a response to be returned;
/// otherwise \c false. /// \brief Process an incoming DNS message, then signal 'server' to resume
void processMessage(const asiolink::IOMessage& io_message, void processMessage(const asiolink::IOMessage& io_message,
isc::dns::MessagePtr message, isc::dns::MessagePtr message,
isc::dns::OutputBufferPtr buffer, isc::dns::OutputBufferPtr buffer,
asiolink::DNSServer* server); asiolink::DNSServer* server);
// \brief Set and get verbose mode
void setVerbose(bool on); void setVerbose(bool on);
bool getVerbose() const; bool getVerbose() const;
isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
isc::config::ModuleCCSession* configSession() const; /// \brief Set and get the config session
isc::config::ModuleCCSession* getConfigSession() const;
void setConfigSession(isc::config::ModuleCCSession* config_session); void setConfigSession(isc::config::ModuleCCSession* config_session);
/// \brief Handle commands from the config session
isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
/// \brief Assign an ASIO IO Service queue to this Recursor object
void setIOService(asiolink::IOService& ios); void setIOService(asiolink::IOService& ios);
/// \brief Return this object's ASIO IO Service queue
asiolink::IOService& getIOService() const { return (*io_); } asiolink::IOService& getIOService() const { return (*io_); }
asiolink::DNSLookup* getDNSLookupProvider() { /// \brief Return pointer to the DNS Lookup callback function
return (dns_lookup_); asiolink::DNSLookup* getDNSLookupProvider() { return (dns_lookup_); }
}
asiolink::DNSAnswer* getDNSAnswerProvider() { /// \brief Return pointer to the DNS Answer callback function
return (dns_answer_); asiolink::DNSAnswer* getDNSAnswerProvider() { return (dns_answer_); }
}
asiolink::SimpleCallback* getCheckinProvider() { /// \brief Return pointer to the Checkin callback function
return (checkin_); asiolink::SimpleCallback* getCheckinProvider() { return (checkin_); }
}
private: private:
RecursorImpl* impl_; RecursorImpl* impl_;
......
...@@ -457,19 +457,4 @@ TEST_F(RecursorTest, notifyFail) { ...@@ -457,19 +457,4 @@ TEST_F(RecursorTest, notifyFail) {
Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0); Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
} }
void
updateConfig(Recursor* server, const char* const dbfile,
const bool expect_success)
{
ConstElementPtr config_answer =
server->updateConfig(Element::fromJSON(dbfile));
EXPECT_EQ(Element::map, config_answer->getType());
EXPECT_TRUE(config_answer->contains("result"));
ConstElementPtr result = config_answer->get("result");
EXPECT_EQ(Element::list, result->getType());
EXPECT_EQ(expect_success ? 0 : 1, result->get(0)->intValue());
}
} }
...@@ -67,14 +67,17 @@ used by a DNS Server to communicate with the module that called it. ...@@ -67,14 +67,17 @@ used by a DNS Server to communicate with the module that called it.
They are abstract-only classes whose concrete implementations They are abstract-only classes whose concrete implementations
are supplied by the calling module. are supplied by the calling module.
Note that the DNSLookup callback runs asynchronously. A concrete The DNSLookup callback always runs asynchronously. Concrete
implementation must be sure to call the server's "resume" method when implementations must be sure to call the server's "resume" method when
it is finished. it is finished.
In an authoritative server, the DNSLookup implementation would examine In an authoritative server, the DNSLookup implementation would examine
the query, look up the answer, then call "resume". In a recursive server, the query, look up the answer, then call "resume". (See the diagram
it would initiate a DNSQuery, which in turn would be responsible for in doc/auth_process.jpg.)
calling the server's "resume" method.
In a recursive server, the DNSLookup impelemtation would initiate a
DNSQuery, which in turn would be responsible for calling the server's
"resume" method. (See the diagram in doc/recursive_process.jpg.)
A DNSQuery object is intended to handle resolution of a query over A DNSQuery object is intended to handle resolution of a query over
the network when the local authoritative data sources or cache are not the network when the local authoritative data sources or cache are not
......
...@@ -172,15 +172,8 @@ IOService::get_io_service() { ...@@ -172,15 +172,8 @@ IOService::get_io_service() {
RecursiveQuery::RecursiveQuery(IOService& io_service, const char& forward, RecursiveQuery::RecursiveQuery(IOService& io_service, const char& forward,
uint16_t port) : uint16_t port) :
io_service_(io_service), port_(port) io_service_(io_service), ns_addr_(&forward), port_(port)
{ {}
error_code err;
ns_addr_ = ip::address::from_string(&forward, err);
if (err) {
isc_throw(IOError, "Invalid IP address '" << &ns_addr_ << "': "
<< err.message());
}
}
void void
RecursiveQuery::sendQuery(const Question& question, OutputBufferPtr buffer, RecursiveQuery::sendQuery(const Question& question, OutputBufferPtr buffer,
......
...@@ -222,8 +222,10 @@ public: ...@@ -222,8 +222,10 @@ public:
/// ///
/// These methods all make their calls indirectly via the "self_" /// These methods all make their calls indirectly via the "self_"
/// pointer, ensuring that the functions ultimately invoked will be /// pointer, ensuring that the functions ultimately invoked will be
/// the ones in the derived class. /// the ones in the derived class. This makes it possible to pass
/// /// instances of derived classes as references to this base class
/// without losing access to derived class data.
///
//@{ //@{
/// \brief The funtion operator /// \brief The funtion operator
virtual void operator()(asio::error_code ec = asio::error_code(), virtual void operator()(asio::error_code ec = asio::error_code(),
...@@ -464,7 +466,7 @@ public: ...@@ -464,7 +466,7 @@ public:
DNSServer* server); DNSServer* server);
private: private:
IOService& io_service_; IOService& io_service_;
asio::ip::address ns_addr_; IOAddress ns_addr_;
uint16_t port_; uint16_t port_;
}; };
......
...@@ -54,10 +54,29 @@ public: ...@@ -54,10 +54,29 @@ public:
{} {}
~TCPEndpoint() { delete asio_endpoint_placeholder_; } ~TCPEndpoint() { delete asio_endpoint_placeholder_; }
virtual IOAddress getAddress() const;
virtual uint16_t getPort() const; inline IOAddress getAddress() const {
virtual short getProtocol() const; return (asio_endpoint_.address());
virtual short getFamily() const; }
inline uint16_t getPort() const {
return (asio_endpoint_.port());
}
inline short getProtocol() const {
return (asio_endpoint_.protocol().protocol());
}
inline short getFamily() const {
return (asio_endpoint_.protocol().family());
}
// This is not part of the exosed IOEndpoint API but allows
// direct access to the ASIO implementation of the endpoint
inline const asio::ip::tcp::endpoint& getASIOEndpoint() const {
return (asio_endpoint_);
}
private: private:
const asio::ip::tcp::endpoint* asio_endpoint_placeholder_; const asio::ip::tcp::endpoint* asio_endpoint_placeholder_;
const asio::ip::tcp::endpoint& asio_endpoint_; const asio::ip::tcp::endpoint& asio_endpoint_;
...@@ -70,8 +89,10 @@ private: ...@@ -70,8 +89,10 @@ private:
TCPSocket& operator=(const TCPSocket& source); TCPSocket& operator=(const TCPSocket& source);
public: public:
TCPSocket(asio::ip::tcp::socket& socket) : socket_(socket) {} TCPSocket(asio::ip::tcp::socket& socket) : socket_(socket) {}
virtual int getNative() const;
virtual int getProtocol() const; inline int getNative() const { return (socket_.native()); }
inline int getProtocol() const { return (IPPROTO_TCP); }
private: private:
asio::ip::tcp::socket& socket_; asio::ip::tcp::socket& socket_;
}; };
......
...@@ -52,10 +52,29 @@ public: ...@@ -52,10 +52,29 @@ public:
{} {}
~UDPEndpoint() { delete asio_endpoint_placeholder_; } ~UDPEndpoint() { delete asio_endpoint_placeholder_; }
virtual IOAddress getAddress() const;
virtual uint16_t getPort() const; inline IOAddress getAddress() const {
virtual short getProtocol() const; return (asio_endpoint_.address());
virtual short getFamily() const; }
inline uint16_t getPort() const {
return (asio_endpoint_.port());
}