]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dns.hh
Merge pull request #5523 from rubenk/fix-typos-in-logmessage
[thirdparty/pdns.git] / pdns / dns.hh
1 /*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22 #pragma once
23 #include <boost/multi_index_container.hpp>
24 #include <boost/multi_index/ordered_index.hpp>
25 #include <boost/tuple/tuple_comparison.hpp>
26 #include <boost/multi_index/key_extractors.hpp>
27 #include <boost/multi_index/sequenced_index.hpp>
28 #include "qtype.hh"
29 #include "dnsname.hh"
30 #include <time.h>
31 #include <sys/types.h>
32 class DNSBackend;
33 struct DNSRecord;
34
35 struct SOAData
36 {
37 SOAData() : ttl(0), serial(0), refresh(0), retry(0), expire(0), default_ttl(0), db(0), domain_id(-1), scopeMask(0) {};
38
39 DNSName qname;
40 DNSName nameserver;
41 DNSName hostmaster;
42 uint32_t ttl;
43 uint32_t serial;
44 uint32_t refresh;
45 uint32_t retry;
46 uint32_t expire;
47 uint32_t default_ttl;
48 DNSBackend *db;
49 int domain_id;
50 uint8_t scopeMask;
51 };
52
53 class RCode
54 {
55 public:
56 enum rcodes_ { NoError=0, FormErr=1, ServFail=2, NXDomain=3, NotImp=4, Refused=5, YXDomain=6, YXRRSet=7, NXRRSet=8, NotAuth=9, NotZone=10};
57 static std::string to_s(unsigned short rcode);
58 static std::vector<std::string> rcodes_s;
59 };
60
61 class Opcode
62 {
63 public:
64 enum { Query=0, IQuery=1, Status=2, Notify=4, Update=5 };
65 };
66
67 // enum for policy decisions, used by both auth and recursor. Not all values supported everywhere.
68 namespace PolicyDecision { enum returnTypes { PASS=-1, DROP=-2, TRUNCATE=-3 }; };
69
70 //! This class represents a resource record
71 class DNSResourceRecord
72 {
73 public:
74 DNSResourceRecord() : last_modified(0), ttl(0), signttl(0), domain_id(-1), qclass(1), scopeMask(0), auth(1), disabled(0) {};
75 ~DNSResourceRecord(){};
76 static DNSResourceRecord fromWire(const DNSRecord& d);
77
78 enum Place : uint8_t {QUESTION=0, ANSWER=1, AUTHORITY=2, ADDITIONAL=3}; //!< Type describing the positioning within, say, a DNSPacket
79
80 void setContent(const string& content);
81 string getZoneRepresentation(bool noDot=false) const;
82
83 // data
84 DNSName qname; //!< the name of this record, for example: www.powerdns.com
85 DNSName wildcardname;
86 string content; //!< what this record points to. Example: 10.1.2.3
87
88 // Aligned on 8-byte boundries on systems where time_t is 8 bytes and int
89 // is 4 bytes, aka modern linux on x86_64
90 time_t last_modified; //!< For autocalculating SOA serial numbers - the backend needs to fill this in
91
92 uint32_t ttl; //!< Time To Live of this record
93 uint32_t signttl; //!< If non-zero, use this TTL as original TTL in the RRSIG
94
95 int domain_id; //!< If a backend implements this, the domain_id of the zone this record is in
96 QType qtype; //!< qtype of this record, ie A, CNAME, MX etc
97 uint16_t qclass; //!< class of this record
98
99 uint8_t scopeMask;
100 bool auth;
101 bool disabled;
102
103 bool operator==(const DNSResourceRecord& rhs);
104
105 bool operator<(const DNSResourceRecord &b) const
106 {
107 if(qname < b.qname)
108 return true;
109 if(qname == b.qname)
110 return(content < b.content);
111 return false;
112 }
113 };
114
115 #define GCCPACKATTRIBUTE __attribute__((packed))
116
117 struct dnsrecordheader
118 {
119 uint16_t d_type;
120 uint16_t d_class;
121 uint32_t d_ttl;
122 uint16_t d_clen;
123 } GCCPACKATTRIBUTE;
124
125 struct EDNS0Record
126 {
127 uint8_t extRCode, version;
128 uint16_t Z;
129 } GCCPACKATTRIBUTE;
130
131 static_assert(sizeof(EDNS0Record) == 4, "EDNS0Record size must be 4");
132
133 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
134 #include <machine/endian.h>
135 #elif __linux__ || __GNU__
136 # include <endian.h>
137
138 #else // with thanks to <arpa/nameser.h>
139
140 # define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */
141 # define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
142 # define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */
143
144 #if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
145 defined(__i386) || defined(__ia64) || defined(__amd64) || \
146 defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
147 defined(__alpha__) || defined(__alpha) || \
148 (defined(__Lynx__) && defined(__x86__))
149 # define BYTE_ORDER LITTLE_ENDIAN
150 #endif
151
152 #if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
153 defined(__sparc) || \
154 defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
155 defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
156 defined(apollo) || defined(__convex__) || defined(_CRAY) || \
157 defined(__hppa) || defined(__hp9000) || \
158 defined(__hp9000s300) || defined(__hp9000s700) || \
159 defined(__hp3000s900) || defined(MPE) || \
160 defined(BIT_ZERO_ON_LEFT) || defined(m68k) || \
161 (defined(__Lynx__) && \
162 (defined(__68k__) || defined(__sparc__) || defined(__powerpc__)))
163 # define BYTE_ORDER BIG_ENDIAN
164 #endif
165
166 #endif
167
168 struct dnsheader {
169 unsigned id :16; /* query identification number */
170 #if BYTE_ORDER == BIG_ENDIAN
171 /* fields in third byte */
172 unsigned qr: 1; /* response flag */
173 unsigned opcode: 4; /* purpose of message */
174 unsigned aa: 1; /* authoritative answer */
175 unsigned tc: 1; /* truncated message */
176 unsigned rd: 1; /* recursion desired */
177 /* fields in fourth byte */
178 unsigned ra: 1; /* recursion available */
179 unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
180 unsigned ad: 1; /* authentic data from named */
181 unsigned cd: 1; /* checking disabled by resolver */
182 unsigned rcode :4; /* response code */
183 #elif BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
184 /* fields in third byte */
185 unsigned rd :1; /* recursion desired */
186 unsigned tc :1; /* truncated message */
187 unsigned aa :1; /* authoritative answer */
188 unsigned opcode :4; /* purpose of message */
189 unsigned qr :1; /* response flag */
190 /* fields in fourth byte */
191 unsigned rcode :4; /* response code */
192 unsigned cd: 1; /* checking disabled by resolver */
193 unsigned ad: 1; /* authentic data from named */
194 unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
195 unsigned ra :1; /* recursion available */
196 #endif
197 /* remaining bytes */
198 unsigned qdcount :16; /* number of question entries */
199 unsigned ancount :16; /* number of answer entries */
200 unsigned nscount :16; /* number of authority entries */
201 unsigned arcount :16; /* number of resource entries */
202 };
203
204 static_assert(sizeof(dnsheader) == 12, "dnsheader size must be 12");
205
206 inline uint16_t * getFlagsFromDNSHeader(struct dnsheader * dh)
207 {
208 return (uint16_t*) (((char *) dh) + sizeof(uint16_t));
209 }
210
211 #define DNS_TYPE_SIZE (2)
212 #define DNS_CLASS_SIZE (2)
213 #define DNS_TTL_SIZE (4)
214 #define DNS_RDLENGTH_SIZE (2)
215 #define EDNS_EXTENDED_RCODE_SIZE (1)
216 #define EDNS_VERSION_SIZE (1)
217 #define EDNS_OPTION_CODE_SIZE (2)
218 #define EDNS_OPTION_LENGTH_SIZE (2)
219
220 #if BYTE_ORDER == BIG_ENDIAN
221 #define FLAGS_RD_OFFSET (8)
222 #define FLAGS_CD_OFFSET (12)
223 #elif BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
224 #define FLAGS_RD_OFFSET (0)
225 #define FLAGS_CD_OFFSET (12)
226 #endif
227
228 #define L theL()
229 extern time_t s_starttime;
230
231 uint32_t hashQuestion(const char* packet, uint16_t len, uint32_t init);
232
233 struct TSIGTriplet
234 {
235 DNSName name, algo;
236 string secret;
237 };
238
239 /** for use by DNSPacket, converts a SOAData class to a ascii line again */
240 string serializeSOAData(const SOAData &data);
241 string &attodot(string &str); //!< for when you need to insert an email address in the SOA