Commit a07e078b authored by Jelte Jansen's avatar Jelte Jansen
Browse files

Merge branch 'trac483'

Conflicts:
	src/bin/resolver/resolver.cc
parents 748885cd a039907d
......@@ -76,7 +76,7 @@ public:
void querySetup(DNSService& dnss) {
assert(!rec_query_); // queryShutdown must be called first
dlog("Query setup");
rec_query_ = new RecursiveQuery(dnss, upstream_, timeout_, retries_);
rec_query_ = new RecursiveQuery(dnss, upstream_, upstream_root_, timeout_, retries_);
}
void queryShutdown() {
......@@ -107,6 +107,25 @@ public:
}
}
void setRootAddresses(const vector<addr_t>& upstream_root,
DNSService *dnss)
{
queryShutdown();
upstream_root_ = upstream_root;
if (dnss) {
if (!upstream_root_.empty()) {
dlog("Setting root addresses:");
BOOST_FOREACH(const addr_t& address, upstream_root) {
dlog(" " + address.first + ":" +
boost::lexical_cast<string>(address.second));
}
} else {
dlog("No root addresses");
}
querySetup(*dnss);
}
}
void processNormalQuery(const Question& question,
MessagePtr answer_message,
OutputBufferPtr buffer,
......@@ -117,6 +136,8 @@ public:
/// These members are public because Resolver accesses them directly.
ModuleCCSession* config_session_;
/// Addresses of the root nameserver(s)
vector<addr_t> upstream_root_;
/// Addresses of the forward nameserver
vector<addr_t> upstream_;
/// Addresses we listen on
......@@ -445,7 +466,7 @@ parseAddresses(ConstElementPtr addresses) {
}
} else if (addresses->getType() != Element::null) {
isc_throw(TypeError,
"forward_addresses config element must be a list");
"root_addresses, forward_addresses, and listen_on config element must be a list");
}
}
return (result);
......@@ -459,6 +480,8 @@ Resolver::updateConfig(ConstElementPtr config) {
try {
// Parse forward_addresses
ConstElementPtr rootAddressesE(config->get("root_addresses"));
vector<addr_t> rootAddresses(parseAddresses(rootAddressesE));
ConstElementPtr forwardAddressesE(config->get("forward_addresses"));
vector<addr_t> forwardAddresses(parseAddresses(forwardAddressesE));
ConstElementPtr listenAddressesE(config->get("listen_on"));
......@@ -496,6 +519,9 @@ Resolver::updateConfig(ConstElementPtr config) {
setForwardAddresses(forwardAddresses);
need_query_restart = true;
}
if (rootAddressesE) {
setRootAddresses(rootAddresses);
}
if (set_timeouts) {
setTimeouts(timeout, retries);
need_query_restart = true;
......@@ -518,6 +544,12 @@ Resolver::setForwardAddresses(const vector<addr_t>& addresses)
impl_->setForwardAddresses(addresses, dnss_);
}
void
Resolver::setRootAddresses(const vector<addr_t>& addresses)
{
impl_->setRootAddresses(addresses, dnss_);
}
bool
Resolver::isForwarding() const {
return (!impl_->upstream_.empty());
......@@ -528,6 +560,11 @@ Resolver::getForwardAddresses() const {
return (impl_->upstream_);
}
vector<addr_t>
Resolver::getRootAddresses() const {
return (impl_->upstream_root_);
}
namespace {
void
......
......@@ -111,6 +111,24 @@ public:
/// Return if we are in forwarding mode (if not, we are in fully recursive)
bool isForwarding() const;
/**
* \brief Specify the list of root nameservers.
*
* Specify the list of addresses of root nameservers
*
* @param addresses The list of addresses to use (each one is the address
* and port pair).
*/
void setRootAddresses(const std::vector<std::pair<std::string,
uint16_t> >& addresses);
/**
* \short Get list of root addresses.
*
* \see setRootAddresses.
*/
std::vector<std::pair<std::string, uint16_t> > getRootAddresses() const;
/**
* Set and get the addresses we listen on.
*/
......
......@@ -41,6 +41,32 @@
]
}
},
{
"item_name": "root_addresses",
"item_type": "list",
"item_optional": True,
"item_default": [],
"list_item_spec" : {
"item_name": "address",
"item_type": "map",
"item_optional": False,
"item_default": {},
"map_item_spec": [
{
"item_name": "address",
"item_type": "string",
"item_optional": False,
"item_default": "::1"
},
{
"item_name": "port",
"item_type": "integer",
"item_optional": False,
"item_default": 53
}
]
}
},
{
"item_name": "listen_on",
"item_type": "list",
......
......@@ -96,6 +96,31 @@ TEST_F(ResolverConfig, forwardAddressConfig) {
EXPECT_EQ(0, server.getForwardAddresses().size());
}
TEST_F(ResolverConfig, rootAddressConfig) {
// Try putting there some address
ElementPtr config(Element::fromJSON("{"
"\"root_addresses\": ["
" {"
" \"address\": \"192.0.2.1\","
" \"port\": 53"
" }"
"]"
"}"));
ConstElementPtr result(server.updateConfig(config));
EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
ASSERT_EQ(1, server.getRootAddresses().size());
EXPECT_EQ("192.0.2.1", server.getRootAddresses()[0].first);
EXPECT_EQ(53, server.getRootAddresses()[0].second);
// And then remove all addresses
config = Element::fromJSON("{"
"\"root_addresses\": null"
"}");
result = server.updateConfig(config);
EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
EXPECT_EQ(0, server.getRootAddresses().size());
}
void
ResolverConfig::invalidTest(const string &JOSN) {
ElementPtr config(Element::fromJSON(JOSN));
......
......@@ -283,8 +283,11 @@ typedef std::vector<std::pair<std::string, uint16_t> > AddressVector;
}
RecursiveQuery::RecursiveQuery(DNSService& dns_service,
const AddressVector& upstream, int timeout, unsigned retries) :
const AddressVector& upstream,
const AddressVector& upstream_root,
int timeout, unsigned retries) :
dns_service_(dns_service), upstream_(new AddressVector(upstream)),
upstream_root_(new AddressVector(upstream_root)),
timeout_(timeout), retries_(retries)
{}
......@@ -344,6 +347,9 @@ private:
// we should differentiate between forwarding and resolving
shared_ptr<AddressVector> upstream_;
// root servers...just copied over to the zone_servers_
shared_ptr<AddressVector> upstream_root_;
// Buffer to store the result.
OutputBufferPtr buffer_;
......@@ -468,12 +474,14 @@ private:
public:
RunningQuery(asio::io_service& io, const Question &question,
MessagePtr answer_message, shared_ptr<AddressVector> upstream,
shared_ptr<AddressVector> upstream_root,
OutputBufferPtr buffer, DNSServer* server, int timeout,
unsigned retries) :
io_(io),
question_(question),
answer_message_(answer_message),
upstream_(upstream),
upstream_root_(upstream_root),
buffer_(buffer),
server_(server->clone()),
timeout_(timeout),
......@@ -483,9 +491,25 @@ public:
dlog("Started a new RunningQuery");
done = false;
// hardcoded f.root-servers.net now, should use NSAS
// should use NSAS for root servers
// Adding root servers if not a forwarder
if (upstream_->empty()) {
zone_servers_.push_back(addr_t("192.5.5.241", 53));
if (upstream_root_->empty()) { //if no root ips given, use this
zone_servers_.push_back(addr_t("192.5.5.241", 53));
}
else
{
//copy the list
dlog("Size is " +
boost::lexical_cast<string>(upstream_root_->size()) +
"\n");
//Use BOOST_FOREACH here? Is it faster?
for(AddressVector::iterator it = upstream_root_->begin();
it < upstream_root_->end(); it++) {
zone_servers_.push_back(addr_t(it->first,it->second));
dlog("Put " + zone_servers_.back().first + "into root list\n");
}
}
}
send();
}
......@@ -538,8 +562,8 @@ RecursiveQuery::sendQuery(const Question& question,
// we're only going to handle UDP.
asio::io_service& io = dns_service_.get_io_service();
// It will delete itself when it is done
new RunningQuery(io, question, answer_message, upstream_, buffer,
server, timeout_, retries_);
new RunningQuery(io, question, answer_message, upstream_, upstream_root_,
buffer, server, timeout_, retries_);
}
class IntervalTimerImpl {
......
......@@ -538,6 +538,8 @@ public:
/// query on.
/// \param upstream Addresses and ports of the upstream servers
/// to forward queries to.
/// \param upstream_root Addresses and ports of the root servers
/// to use when resolving.
/// \param timeout How long to timeout the query, in ms
/// -1 means never timeout (but do not use that).
/// TODO: This should be computed somehow dynamically in future
......@@ -545,7 +547,10 @@ public:
/// and return if it returs).
RecursiveQuery(DNSService& dns_service,
const std::vector<std::pair<std::string, uint16_t> >&
upstream, int timeout = -1, unsigned retries = 0);
upstream,
const std::vector<std::pair<std::string, uint16_t> >&
upstream_root,
int timeout = -1, unsigned retries = 0);
//@}
/// \brief Initiates an upstream query in the \c RecursiveQuery object.
......@@ -566,6 +571,8 @@ private:
DNSService& dns_service_;
boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
upstream_;
boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
upstream_root_;
int timeout_;
unsigned retries_;
};
......
......@@ -645,15 +645,17 @@ singleAddress(const string &address, uint16_t port) {
TEST_F(ASIOLinkTest, recursiveSetupV4) {
setDNSService(true, false);
uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
EXPECT_NO_THROW(RecursiveQuery(*dns_service_, singleAddress(TEST_IPV6_ADDR,
port)));
EXPECT_NO_THROW(RecursiveQuery(*dns_service_,
singleAddress(TEST_IPV4_ADDR, port),
singleAddress(TEST_IPV4_ADDR, port)));
}
TEST_F(ASIOLinkTest, recursiveSetupV6) {
setDNSService(false, true);
uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
EXPECT_NO_THROW(RecursiveQuery(*dns_service_, singleAddress(TEST_IPV6_ADDR,
port)));
EXPECT_NO_THROW(RecursiveQuery(*dns_service_,
singleAddress(TEST_IPV6_ADDR, port),
singleAddress(TEST_IPV6_ADDR,port)));
}
// XXX:
......@@ -669,7 +671,9 @@ TEST_F(ASIOLinkTest, forwarderSend) {
uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
MockServer server(*io_service_);
RecursiveQuery rq(*dns_service_, singleAddress(TEST_IPV4_ADDR, port));
RecursiveQuery rq(*dns_service_,
singleAddress(TEST_IPV4_ADDR, port),
singleAddress(TEST_IPV4_ADDR, port));
Question q(Name("example.com"), RRClass::IN(), RRType::TXT());
OutputBufferPtr buffer(new OutputBuffer(0));
......@@ -715,8 +719,10 @@ TEST_F(ASIOLinkTest, recursiveTimeout) {
// Do the answer
const uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
RecursiveQuery query(*dns_service_, singleAddress(TEST_IPV4_ADDR, port),
10, 2);
RecursiveQuery query(*dns_service_,
singleAddress(TEST_IPV4_ADDR, port),
singleAddress(TEST_IPV4_ADDR, port),
10, 2);
Question question(Name("example.net"), RRClass::IN(), RRType::A());
OutputBufferPtr buffer(new OutputBuffer(0));
MessagePtr answer(new Message(Message::RENDER));
......@@ -762,7 +768,7 @@ TEST_F(ASIOLinkTest, DISABLED_recursiveSendOk) {
MockServerStop server(*io_service_, &done);
vector<pair<string, uint16_t> > empty_vector;
RecursiveQuery rq(*dns_service_, empty_vector, 10000, 0);
RecursiveQuery rq(*dns_service_, empty_vector, empty_vector, 10000, 0);
Question q(Name("www.isc.org"), RRClass::IN(), RRType::A());
OutputBufferPtr buffer(new OutputBuffer(0));
......@@ -787,7 +793,7 @@ TEST_F(ASIOLinkTest, DISABLED_recursiveSendNXDOMAIN) {
MockServerStop server(*io_service_, &done);
vector<pair<string, uint16_t> > empty_vector;
RecursiveQuery rq(*dns_service_, empty_vector, 10000, 0);
RecursiveQuery rq(*dns_service_, empty_vector, empty_vector, 10000, 0);
Question q(Name("wwwdoesnotexist.isc.org"), RRClass::IN(), RRType::A());
OutputBufferPtr buffer(new OutputBuffer(0));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment