]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/resolver.hh
4089097a16149058d4cf68249eee76aa669f514f
[thirdparty/pdns.git] / pdns / resolver.hh
1 /*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 - 2011 PowerDNS.COM BV
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2
7 as published by the Free Software Foundation
8
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <string>
21 #include <vector>
22 #include <sys/types.h>
23 #include "iputils.hh"
24 #include <netdb.h>
25 #include <unistd.h>
26 #include <sys/time.h>
27 #include <sys/uio.h>
28 #include <fcntl.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #undef res_mkquery
33
34 #include "pdnsexception.hh"
35 #include "dns.hh"
36 #include "namespaces.hh"
37 #include "dnsbackend.hh"
38
39 class ResolverException : public PDNSException
40 {
41 public:
42 ResolverException(const string &reason) : PDNSException(reason){}
43 };
44
45 // make an IPv4 or IPv6 query socket
46 int makeQuerySocket(const ComboAddress& local, bool udpOrTCP);
47 //! Resolver class. Can be used synchronously and asynchronously, over IPv4 and over IPv6 (simultaneously)
48 class Resolver : public boost::noncopyable
49 {
50 public:
51 Resolver();
52 ~Resolver();
53
54 typedef vector<DNSResourceRecord> res_t;
55 //! synchronously resolve domain|type at IP, store result in result, rcode in ret
56 int resolve(const string &ip, const char *domain, int type, res_t* result);
57
58 //! only send out a resolution request
59 uint16_t sendResolve(const ComboAddress& remote, const char *domain, int type, bool dnssecOk=false,
60 const string& tsigkeyname="", const string& tsigalgorithm="", const string& tsigsecret="");
61
62 //! see if we got a SOA response from our sendResolve
63 bool tryGetSOASerial(string* theirDomain, uint32_t* theirSerial, uint32_t* theirInception, uint32_t* theirExpire, uint16_t* id);
64
65 //! convenience function that calls resolve above
66 void getSoaSerial(const string &, const string &, uint32_t *);
67
68 private:
69 int d_sock4, d_sock6;
70
71 int d_type;
72 int d_timeout;
73 string d_domain;
74 uint16_t d_randomid;
75
76 ComboAddress d_remote;
77 };
78
79 class AXFRRetriever : public boost::noncopyable
80 {
81 public:
82 AXFRRetriever(const ComboAddress& remote,
83 const string& zone,
84 const string& tsigkeyname=string(),
85 const string& tsigalgorithm=string(),
86 const string& tsigsecret=string(),
87 const ComboAddress* laddr = NULL);
88 ~AXFRRetriever();
89 int getChunk(Resolver::res_t &res);
90
91 private:
92 void connect();
93 int getLength();
94 void timeoutReadn(uint16_t bytes);
95
96 shared_array<char> d_buf;
97 string d_domain;
98 int d_sock;
99 int d_soacount;
100 ComboAddress d_remote;
101
102 string d_tsigkeyname;
103 string d_tsigsecret;
104 string d_prevMac; // RFC2845 4.4
105 string d_signData;
106 uint32_t d_tsigPos;
107 uint d_nonSignedMessages; // RFC2845 4.4
108 TSIGRecordContent d_trc;
109 };
110
111 // class that one day might be more than a function to help you get IP addresses for a nameserver
112 class FindNS
113 {
114 public:
115 vector<string> lookup(const string &name, DNSBackend *B)
116 {
117 vector<string> addresses;
118
119 struct addrinfo* res;
120 struct addrinfo hints;
121 memset(&hints, 0, sizeof(hints));
122
123 for(int n = 0; n < 2; ++n) {
124 hints.ai_family = n ? AF_INET : AF_INET6;
125 ComboAddress remote;
126 remote.sin4.sin_family = AF_INET6;
127 if(!getaddrinfo(name.c_str(), 0, &hints, &res)) {
128 struct addrinfo* address = res;
129 do {
130 memcpy(&remote, address->ai_addr, address->ai_addrlen);
131 addresses.push_back(remote.toString());
132 } while((address = address->ai_next));
133 freeaddrinfo(res);
134 }
135 }
136
137 B->lookup(QType(QType::ANY),name);
138 DNSResourceRecord rr;
139 while(B->get(rr))
140 if(rr.qtype.getCode() == QType::A || rr.qtype.getCode()==QType::AAAA)
141 addresses.push_back(rr.content); // SOL if you have a CNAME for an NS
142
143 return addresses;
144 }
145 };
146