]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dns.hh
limit compression pointers to 14 bits
[thirdparty/pdns.git] / pdns / dns.hh
CommitLineData
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 35class DNSBackend;
4950b140 36struct DNSRecord;
12c86877
BH
37
38struct 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
55class RCode
56{
57public:
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
63class ERCode
64{
65public:
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
70class Opcode
71{
72public:
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.
78namespace PolicyDecision { enum returnTypes { PASS=-1, DROP=-2, TRUNCATE=-3 }; };
79
12c86877
BH
80//! This class represents a resource record
81class DNSResourceRecord
82{
83public:
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
127struct 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
135struct EDNS0Record
136{
0e55cc96
RG
137 uint8_t extRCode, version;
138 uint16_t extFlags;
009f9f55 139} GCCPACKATTRIBUTE;
009f9f55 140
a683e8bd
RG
141static_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
178struct 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
214static_assert(sizeof(dnsheader) == 12, "dnsheader size must be 12");
215
aeb36780
RG
216inline 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 238extern time_t s_starttime;
8171ab83 239
06ea9015 240uint32_t hashQuestion(const char* packet, uint16_t len, uint32_t init);
65a60c2c 241
98c9ec39 242struct TSIGTriplet
243{
244 DNSName name, algo;
245 string secret;
246};
247
213cc78f 248string &attodot(string &str); //!< for when you need to insert an email address in the SOA