]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/stubresolver.cc
6 #include "arguments.hh"
11 #include "dnswriter.hh"
12 #include "dns_random.hh"
13 #include "namespaces.hh"
15 #include "stubresolver.hh"
17 // s_resolversForStub contains the ComboAddresses that are used by
19 static vector
<ComboAddress
> s_resolversForStub
;
22 * Returns false if no resolvers are configured, while emitting a warning about this
24 bool resolversDefined()
26 if (s_resolversForStub
.empty()) {
27 L
<<Logger::Warning
<<"No upstream resolvers configured, stub resolving (including secpoll and ALIAS) impossible."<<endl
;
34 * Fill the s_resolversForStub vector with addresses for the upstream resolvers.
35 * First, parse the `resolver` configuration option for IP addresses to use.
36 * If that doesn't work, parse /etc/resolv.conf and add those nameservers to
39 void stubParseResolveConf()
41 if(::arg().mustDo("resolver")) {
43 stringtok(parts
, ::arg()["resolver"], " ,\t");
44 for (const auto& addr
: parts
)
45 s_resolversForStub
.push_back(ComboAddress(addr
, 53));
48 if (s_resolversForStub
.empty()) {
49 ifstream
ifs("/etc/resolv.conf");
54 while(std::getline(ifs
, line
)) {
55 boost::trim_right_if(line
, is_any_of(" \r\n\x1a"));
56 boost::trim_left(line
); // leading spaces, let's be nice
58 string::size_type tpos
= line
.find_first_of(";#");
59 if(tpos
!= string::npos
)
62 if(boost::starts_with(line
, "nameserver ") || boost::starts_with(line
, "nameserver\t")) {
64 stringtok(parts
, line
, " \t,"); // be REALLY nice
65 for(vector
<string
>::const_iterator iter
= parts
.begin()+1; iter
!= parts
.end(); ++iter
) {
67 s_resolversForStub
.push_back(ComboAddress(*iter
, 53));
76 // Emit a warning if there are no stubs.
80 // s_resolversForStub contains the ComboAddresses that are used to resolve the
81 int stubDoResolve(const DNSName
& qname
, uint16_t qtype
, vector
<DNSZoneRecord
>& ret
)
83 if (!resolversDefined())
84 return RCode::ServFail
;
86 vector
<uint8_t> packet
;
88 DNSPacketWriter
pw(packet
, qname
, qtype
);
89 pw
.getHeader()->id
=dns_random(0xffff);
92 string msg
="Doing stub resolving, using resolvers: ";
93 for (const auto& server
: s_resolversForStub
) {
94 msg
+= server
.toString() + ", ";
96 L
<<Logger::Debug
<<msg
.substr(0, msg
.length() - 2)<<endl
;
98 for(const ComboAddress
& dest
: s_resolversForStub
) {
99 Socket
sock(dest
.sin4
.sin_family
, SOCK_DGRAM
);
100 sock
.setNonBlocking();
102 sock
.send(string(packet
.begin(), packet
.end()));
106 waitForData(sock
.getHandle(), 2, 0);
109 sock
.read(reply
); // this calls recv
110 if(reply
.size() > sizeof(struct dnsheader
)) {
112 memcpy(&d
, reply
.c_str(), sizeof(d
));
113 if(d
.id
!= pw
.getHeader()->id
)
120 MOADNSParser
mdp(false, reply
);
121 if(mdp
.d_header
.rcode
== RCode::ServFail
)
124 for(MOADNSParser::answers_t::const_iterator i
=mdp
.d_answers
.begin(); i
!=mdp
.d_answers
.end(); ++i
) {
125 if(i
->first
.d_place
== 1 && i
->first
.d_type
==qtype
) {
132 L
<<Logger::Debug
<<"Question got answered by "<<dest
.toString()<<endl
;
133 return mdp
.d_header
.rcode
;
135 return RCode::ServFail
;