0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-26 00:32:35 +01:00

ircd::net::dns: Move cache interfaces into cache class.

This commit is contained in:
Jason Volk 2018-04-14 16:39:13 -07:00
parent ee5c1f27f2
commit 1ad4d58e43
2 changed files with 104 additions and 56 deletions

View file

@ -42,7 +42,6 @@ struct ircd::net::dns
// (internal) generate strings for rfc1035 questions or dns::cache keys.
static string_view make_SRV_key(const mutable_buffer &out, const hostport &, const opts &);
bool query_cache(const hostport &, const opts &, const callback &);
public:
// Cache warming
@ -94,6 +93,11 @@ struct ircd::net::dns::cache
std::multimap<std::string, rfc1035::record::A, std::less<>> A;
std::multimap<std::string, rfc1035::record::SRV, std::less<>> SRV;
public:
bool get(const hostport &, const opts &, const callback &);
rfc1035::record *put(const rfc1035::question &, const rfc1035::answer &);
bool put_error(const rfc1035::question &, const uint &code);
};
template<class Callback>

View file

@ -2448,24 +2448,111 @@ ircd::net::dns::operator()(const hostport &hostport,
callback cb)
{
if(opts.cache_check)
if(query_cache(hostport, opts, cb))
if(cache.get(hostport, opts, cb))
return;
assert(bool(ircd::net::dns::resolver));
(*resolver)(hostport, opts, std::move(cb));
}
ircd::string_view
ircd::net::dns::make_SRV_key(const mutable_buffer &out,
const hostport &hp,
const opts &opts)
{
if(!opts.srv)
return fmt::sprintf
{
out, "_%s._%s.%s", service(hp), opts.proto, host(hp)
};
else
return fmt::sprintf
{
out, "%s%s", opts.srv, host(hp)
};
}
//
// cache
//
bool
ircd::net::dns::cache::put_error(const rfc1035::question &question,
const uint &code)
{
const auto &host
{
rstrip(question.name, '.')
};
switch(question.qtype)
{
case 1: // A
{
rfc1035::record::A record;
record.ttl = ircd::time() + seconds(cache::clear_nxdomain).count(); //TODO: code
A.emplace(host, record);
return true;
}
case 33: // SRV
{
rfc1035::record::SRV record;
record.ttl = ircd::time() + seconds(cache::clear_nxdomain).count(); //TODO: code
SRV.emplace(host, record);
return true;
}
}
return false;
}
ircd::rfc1035::record *
ircd::net::dns::cache::put(const rfc1035::question &question,
const rfc1035::answer &answer)
{
const auto &host
{
rstrip(question.name, '.')
};
switch(answer.qtype)
{
case 1: // A
{
const auto &it
{
A.emplace(host, answer)
};
return &it->second;
}
case 33: // SRV
{
const auto &it
{
SRV.emplace(host, answer)
};
return &it->second;
}
default:
return nullptr;
}
}
/// This function has an opportunity to respond from the DNS cache. If it
/// returns true, that indicates it responded by calling back the user and
/// nothing further should be done for them. If it returns false, that
/// indicates it did not respond and to proceed normally. The response can
/// be of a cached successful result, or a cached error. Both will return
/// true.
///
bool
ircd::net::dns::query_cache(const hostport &hp,
const opts &opts,
const callback &cb)
ircd::net::dns::cache::get(const hostport &hp,
const opts &opts,
const callback &cb)
{
// It's no use putting the result record array on the stack in case this
// function is either called from an ircd::ctx or calls back an ircd::ctx.
@ -2486,7 +2573,7 @@ ircd::net::dns::query_cache(const hostport &hp,
make_SRV_key(srvbuf, hp, opts)
};
auto &map{cache.SRV};
auto &map{SRV};
const auto pit{map.equal_range(srvhost)};
if(pit.first == pit.second)
return false;
@ -2523,7 +2610,7 @@ ircd::net::dns::query_cache(const hostport &hp,
}
else // Deduced A query (for now)
{
auto &map{cache.A};
auto &map{A};
const auto pit{map.equal_range(host(hp))};
if(pit.first == pit.second)
return false;
@ -2568,23 +2655,6 @@ ircd::net::dns::query_cache(const hostport &hp,
return count;
}
ircd::string_view
ircd::net::dns::make_SRV_key(const mutable_buffer &out,
const hostport &hp,
const opts &opts)
{
if(!opts.srv)
return fmt::sprintf
{
out, "_%s._%s.%s", service(hp), opts.proto, host(hp)
};
else
return fmt::sprintf
{
out, "%s%s", opts.srv, host(hp)
};
}
///////////////////////////////////////////////////////////////////////////////
//
// net/resolver.h
@ -3028,10 +3098,7 @@ try
continue;
}
const auto &name{qd.at(0).name};
const auto &host{rstrip(name, '.')};
const auto &it{cache.A.emplace(host, an[i])};
record[i] = &it->second;
record[i] = cache.put(qd.at(0), an[i]);
continue;
}
@ -3051,10 +3118,7 @@ try
continue;
}
const auto &name{qd.at(0).name};
const auto &host{rstrip(name, '.')};
const auto it{cache.SRV.emplace(host, an[i])};
record[i] = &it->second;
record[i] = cache.put(qd.at(0), an[i]);
continue;
}
@ -3085,7 +3149,7 @@ catch(const std::exception &e)
bool
ircd::net::dns::resolver::handle_error(const header &header,
const rfc1035::question &q,
const rfc1035::question &question,
const dns::opts &opts)
{
switch(header.rcode)
@ -3094,30 +3158,10 @@ ircd::net::dns::resolver::handle_error(const header &header,
return true;
case 3: // NXDomain; exception
{
if(opts.cache_result) switch(q.qtype)
{
case 1: // A
{
const auto &host{rstrip(q.name, '.')};
rfc1035::record::A record;
record.ttl = ircd::time() + seconds(cache::clear_nxdomain).count();
cache.A.emplace(host, record);
break;
}
case 33:
{
const auto &host{rstrip(q.name, '.')};
rfc1035::record::SRV record;
record.ttl = ircd::time() + seconds(cache::clear_nxdomain).count();
cache.SRV.emplace(host, record);
break;
}
}
if(opts.cache_result)
cache.put_error(question, header.rcode);
return false;
}
default: // Unhandled error; exception
return false;