]>
Commit | Line | Data |
---|---|---|
12c86877 | 1 | /* |
12471842 PL |
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 | */ | |
ea76bac0 | 22 | #pragma once |
5f8fcf64 BH |
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> | |
12c86877 | 28 | #include "qtype.hh" |
675fa24c | 29 | #include "dnsname.hh" |
12c86877 BH |
30 | #include <time.h> |
31 | #include <sys/types.h> | |
d83feb68 CH |
32 | |
33 | #undef BADSIG // signal.h SIG_ERR | |
34 | ||
12c86877 | 35 | class DNSBackend; |
4950b140 | 36 | struct DNSRecord; |
12c86877 BH |
37 | |
38 | struct SOAData | |
39 | { | |
d29fbc0c | 40 | SOAData() : ttl(0), serial(0), refresh(0), retry(0), expire(0), default_ttl(0), db(0), domain_id(-1) {}; |
998a2450 | 41 | |
675fa24c PD |
42 | DNSName qname; |
43 | DNSName nameserver; | |
44 | DNSName hostmaster; | |
092f210a BH |
45 | uint32_t ttl; |
46 | uint32_t serial; | |
47 | uint32_t refresh; | |
48 | uint32_t retry; | |
49 | uint32_t expire; | |
50 | uint32_t default_ttl; | |
12c86877 | 51 | DNSBackend *db; |
9c81922d | 52 | int domain_id; |
12c86877 BH |
53 | }; |
54 | ||
12c86877 BH |
55 | class RCode |
56 | { | |
57 | public: | |
751ccfff | 58 | enum rcodes_ { NoError=0, FormErr=1, ServFail=2, NXDomain=3, NotImp=4, Refused=5, YXDomain=6, YXRRSet=7, NXRRSet=8, NotAuth=9, NotZone=10}; |
f6007449 | 59 | static std::string to_s(uint8_t rcode); |
6ab9bec7 | 60 | static std::vector<std::string> rcodes_s; |
12c86877 BH |
61 | }; |
62 | ||
d83feb68 CH |
63 | class ERCode |
64 | { | |
65 | public: | |
66 | enum rcodes_ { BADVERS=16, BADSIG=16, BADKEY=17, BADTIME=18, BADMODE=19, BADNAME=20, BADALG=21, BADTRUNC=22, BADCOOKIE=23 }; | |
f6007449 | 67 | static std::string to_s(uint8_t rcode); |
d83feb68 CH |
68 | }; |
69 | ||
12c86877 BH |
70 | class Opcode |
71 | { | |
72 | public: | |
73 | enum { Query=0, IQuery=1, Status=2, Notify=4, Update=5 }; | |
f3c9f421 | 74 | static std::string to_s(uint8_t opcode); |
12c86877 BH |
75 | }; |
76 | ||
f3d6a5c5 | 77 | // enum for policy decisions, used by both auth and recursor. Not all values supported everywhere. |
78 | namespace PolicyDecision { enum returnTypes { PASS=-1, DROP=-2, TRUNCATE=-3 }; }; | |
79 | ||
12c86877 BH |
80 | //! This class represents a resource record |
81 | class DNSResourceRecord | |
82 | { | |
83 | public: | |
4950b140 | 84 | DNSResourceRecord() : last_modified(0), ttl(0), signttl(0), domain_id(-1), qclass(1), scopeMask(0), auth(1), disabled(0) {}; |
12c86877 | 85 | ~DNSResourceRecord(){}; |
4950b140 | 86 | static DNSResourceRecord fromWire(const DNSRecord& d); |
12c86877 | 87 | |
4950b140 | 88 | enum Place : uint8_t {QUESTION=0, ANSWER=1, AUTHORITY=2, ADDITIONAL=3}; //!< Type describing the positioning within, say, a DNSPacket |
e693ff5a | 89 | |
f7a69a4c | 90 | void setContent(const string& content); |
f21fc0aa | 91 | string getZoneRepresentation(bool noDot=false) const; |
f7a69a4c | 92 | |
12c86877 | 93 | // data |
675fa24c PD |
94 | DNSName qname; //!< the name of this record, for example: www.powerdns.com |
95 | DNSName wildcardname; | |
12c86877 | 96 | string content; //!< what this record points to. Example: 10.1.2.3 |
7c2faec9 PL |
97 | |
98 | // Aligned on 8-byte boundries on systems where time_t is 8 bytes and int | |
99 | // is 4 bytes, aka modern linux on x86_64 | |
100 | time_t last_modified; //!< For autocalculating SOA serial numbers - the backend needs to fill this in | |
101 | ||
092f210a | 102 | uint32_t ttl; //!< Time To Live of this record |
794c2f92 | 103 | uint32_t signttl; //!< If non-zero, use this TTL as original TTL in the RRSIG |
7c2faec9 | 104 | |
12c86877 | 105 | int domain_id; //!< If a backend implements this, the domain_id of the zone this record is in |
7c2faec9 PL |
106 | QType qtype; //!< qtype of this record, ie A, CNAME, MX etc |
107 | uint16_t qclass; //!< class of this record | |
12c86877 | 108 | |
7c2faec9 | 109 | uint8_t scopeMask; |
702b226d | 110 | bool auth; |
cea26350 | 111 | bool disabled; |
702b226d | 112 | |
f7a69a4c | 113 | bool operator==(const DNSResourceRecord& rhs); |
cb433f9c | 114 | |
728485ca BH |
115 | bool operator<(const DNSResourceRecord &b) const |
116 | { | |
c536ca8d | 117 | if(qname < b.qname) |
728485ca | 118 | return true; |
c536ca8d BH |
119 | if(qname == b.qname) |
120 | return(content < b.content); | |
728485ca BH |
121 | return false; |
122 | } | |
12c86877 BH |
123 | }; |
124 | ||
76473b92 KM |
125 | #define GCCPACKATTRIBUTE __attribute__((packed)) |
126 | ||
5a57d2ea BH |
127 | struct dnsrecordheader |
128 | { | |
129 | uint16_t d_type; | |
130 | uint16_t d_class; | |
131 | uint32_t d_ttl; | |
132 | uint16_t d_clen; | |
009f9f55 BH |
133 | } GCCPACKATTRIBUTE; |
134 | ||
d6c335ab PL |
135 | struct EDNS0Record |
136 | { | |
0e55cc96 RG |
137 | uint8_t extRCode, version; |
138 | uint16_t extFlags; | |
009f9f55 | 139 | } GCCPACKATTRIBUTE; |
009f9f55 | 140 | |
a683e8bd RG |
141 | static_assert(sizeof(EDNS0Record) == 4, "EDNS0Record size must be 4"); |
142 | ||
4d39d7f3 | 143 | #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) |
009f9f55 | 144 | #include <machine/endian.h> |
8348048f | 145 | #elif __linux__ || __GNU__ |
a1a344bf BH |
146 | # include <endian.h> |
147 | ||
148 | #else // with thanks to <arpa/nameser.h> | |
149 | ||
150 | # define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */ | |
151 | # define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ | |
152 | # define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */ | |
153 | ||
154 | #if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \ | |
155 | defined(__i386) || defined(__ia64) || defined(__amd64) || \ | |
156 | defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \ | |
157 | defined(__alpha__) || defined(__alpha) || \ | |
158 | (defined(__Lynx__) && defined(__x86__)) | |
159 | # define BYTE_ORDER LITTLE_ENDIAN | |
160 | #endif | |
161 | ||
162 | #if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ | |
163 | defined(__sparc) || \ | |
164 | defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ | |
165 | defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\ | |
166 | defined(apollo) || defined(__convex__) || defined(_CRAY) || \ | |
167 | defined(__hppa) || defined(__hp9000) || \ | |
168 | defined(__hp9000s300) || defined(__hp9000s700) || \ | |
169 | defined(__hp3000s900) || defined(MPE) || \ | |
170 | defined(BIT_ZERO_ON_LEFT) || defined(m68k) || \ | |
171 | (defined(__Lynx__) && \ | |
172 | (defined(__68k__) || defined(__sparc__) || defined(__powerpc__))) | |
173 | # define BYTE_ORDER BIG_ENDIAN | |
174 | #endif | |
175 | ||
5a57d2ea BH |
176 | #endif |
177 | ||
178 | struct dnsheader { | |
179 | unsigned id :16; /* query identification number */ | |
180 | #if BYTE_ORDER == BIG_ENDIAN | |
181 | /* fields in third byte */ | |
182 | unsigned qr: 1; /* response flag */ | |
183 | unsigned opcode: 4; /* purpose of message */ | |
7c696097 | 184 | unsigned aa: 1; /* authoritative answer */ |
5a57d2ea BH |
185 | unsigned tc: 1; /* truncated message */ |
186 | unsigned rd: 1; /* recursion desired */ | |
187 | /* fields in fourth byte */ | |
188 | unsigned ra: 1; /* recursion available */ | |
189 | unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ | |
190 | unsigned ad: 1; /* authentic data from named */ | |
191 | unsigned cd: 1; /* checking disabled by resolver */ | |
192 | unsigned rcode :4; /* response code */ | |
9cf8d46a | 193 | #elif BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN |
5a57d2ea BH |
194 | /* fields in third byte */ |
195 | unsigned rd :1; /* recursion desired */ | |
196 | unsigned tc :1; /* truncated message */ | |
7c696097 | 197 | unsigned aa :1; /* authoritative answer */ |
5a57d2ea BH |
198 | unsigned opcode :4; /* purpose of message */ |
199 | unsigned qr :1; /* response flag */ | |
200 | /* fields in fourth byte */ | |
201 | unsigned rcode :4; /* response code */ | |
202 | unsigned cd: 1; /* checking disabled by resolver */ | |
203 | unsigned ad: 1; /* authentic data from named */ | |
204 | unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ | |
205 | unsigned ra :1; /* recursion available */ | |
206 | #endif | |
207 | /* remaining bytes */ | |
208 | unsigned qdcount :16; /* number of question entries */ | |
209 | unsigned ancount :16; /* number of answer entries */ | |
210 | unsigned nscount :16; /* number of authority entries */ | |
211 | unsigned arcount :16; /* number of resource entries */ | |
212 | }; | |
213 | ||
ca404e94 RG |
214 | static_assert(sizeof(dnsheader) == 12, "dnsheader size must be 12"); |
215 | ||
aeb36780 RG |
216 | inline uint16_t * getFlagsFromDNSHeader(struct dnsheader * dh) |
217 | { | |
218 | return (uint16_t*) (((char *) dh) + sizeof(uint16_t)); | |
219 | } | |
220 | ||
ca404e94 RG |
221 | #define DNS_TYPE_SIZE (2) |
222 | #define DNS_CLASS_SIZE (2) | |
223 | #define DNS_TTL_SIZE (4) | |
224 | #define DNS_RDLENGTH_SIZE (2) | |
225 | #define EDNS_EXTENDED_RCODE_SIZE (1) | |
226 | #define EDNS_VERSION_SIZE (1) | |
227 | #define EDNS_OPTION_CODE_SIZE (2) | |
228 | #define EDNS_OPTION_LENGTH_SIZE (2) | |
229 | ||
aeb36780 RG |
230 | #if BYTE_ORDER == BIG_ENDIAN |
231 | #define FLAGS_RD_OFFSET (8) | |
232 | #define FLAGS_CD_OFFSET (12) | |
233 | #elif BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN | |
234 | #define FLAGS_RD_OFFSET (0) | |
235 | #define FLAGS_CD_OFFSET (12) | |
236 | #endif | |
5a57d2ea | 237 | |
12c86877 | 238 | extern time_t s_starttime; |
8171ab83 | 239 | |
06ea9015 | 240 | uint32_t hashQuestion(const char* packet, uint16_t len, uint32_t init); |
65a60c2c | 241 | |
98c9ec39 | 242 | struct TSIGTriplet |
243 | { | |
244 | DNSName name, algo; | |
245 | string secret; | |
246 | }; | |
247 | ||
213cc78f | 248 | string &attodot(string &str); //!< for when you need to insert an email address in the SOA |