]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnspacket.hh
Merge pull request #11431 from jroessler-ox/docs-kskzskroll-update
[thirdparty/pdns.git] / pdns / dnspacket.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 */
e8c59f2d 22#pragma once
1258abe0 23#include <sys/types.h>
809fe23f 24#include "iputils.hh"
af7d3ea6 25#include "ednssubnet.hh"
37063755 26#include "ednscookies.hh"
3d92919d 27#include <optional>
55b524a0 28#include <unordered_set>
12c86877
BH
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <sys/time.h>
1258abe0
BH
32#include <unistd.h>
33#include <arpa/inet.h>
34
12c86877 35#include <iostream>
f28cf17b 36#include <optional>
12c86877 37#include <string>
12c86877
BH
38#include <vector>
39#include "qtype.hh"
40#include "dns.hh"
41#include "misc.hh"
42#include "utility.hh"
43#include "logger.hh"
5c409fa2 44#include "pdnsexception.hh"
78bcb858 45#include "dnsrecords.hh"
12c86877 46
3971cf53 47class UeberBackend;
e0d84497 48class DNSSECKeeper;
34b37bbb 49
90ba52e0 50
12c86877
BH
51//! This class represents DNS packets, either received or to be sent.
52class DNSPacket
53{
54public:
27c0050c 55 DNSPacket(bool isQuery);
f238ce64
OM
56 DNSPacket(const DNSPacket &orig) = default;
57 DNSPacket & operator=(const DNSPacket &) = default;
12c86877 58
a683e8bd
RG
59 int noparse(const char *mesg, size_t len); //!< just suck the data inward
60 int parse(const char *mesg, size_t len); //!< parse a raw UDP or TCP packet and suck the data inward
1f07a63f 61 const string& getString(bool throwsOnTruncation=false); //!< for serialization - just passes the whole packet. If throwsOnTruncation is set, an exception will be raised if the records are too large to fit inside a single DNS payload, instead of setting the TC bit
12c86877 62
34b37bbb 63 // address & socket manipulation
4172a5b2 64 void setRemote(const ComboAddress*, std::optional<ComboAddress> = std::nullopt);
b9b4da23 65 ComboAddress getRemote() const;
4172a5b2 66 ComboAddress getInnerRemote() const; // for proxy protocol
af7d3ea6 67 Netmask getRealRemote() const;
b9b4da23 68 ComboAddress getLocal() const
88c1bc50
BH
69 {
70 ComboAddress ca;
71 socklen_t len=sizeof(ca);
72 getsockname(d_socket, (sockaddr*)&ca, &len);
b9b4da23 73 return ca;
88c1bc50 74 }
092f210a 75 uint16_t getRemotePort() const;
2b6f1436 76
4172a5b2
PD
77 string getRemoteString() const;
78 string getRemoteStringWithPort() const;
79
2b6f1436 80 boost::optional<ComboAddress> d_anyLocal;
12c86877 81
34b37bbb
BH
82 Utility::sock_t getSocket() const
83 {
84 return d_socket;
85 }
b8e0f341 86 void setSocket(Utility::sock_t sock);
34b37bbb 87
34b37bbb
BH
88 // these manipulate 'd'
89 void setA(bool); //!< make this packet authoritative - manipulates 'd'
90 void setID(uint16_t); //!< set the DNS id of this packet - manipulates 'd'
91 void setRA(bool); //!< set the Recursion Available flag - manipulates 'd'
92 void setRD(bool); //!< set the Recursion Desired flag - manipulates 'd'
93 void setAnswer(bool); //!< Make this packet an answer - clears the 'stringbuffer' first, if passed 'true', does nothing otherwise, manipulates 'd'
12c86877 94
34b37bbb
BH
95 void setOpcode(uint16_t); //!< set the Opcode of this packet - manipulates 'd'
96 void setRcode(int v); //!< set the Rcode of this packet - manipulates 'd'
97
98 void clearRecords(); //!< when building a packet, wipe all previously added records (clears 'rrs')
77235722 99
90ba52e0 100 /** Add a DNSZoneRecord to this packet. A DNSPacket (as does a DNS Packet) has 4 kinds of resource records. Questions,
12c86877 101 Answers, Authority and Additional. See RFC 1034 and 1035 for details. You can specify where a record needs to go in the
90ba52e0 102 DNSZoneRecord d_place field */
9bbcf03a 103 void addRecord(DNSZoneRecord&&); // adds to 'rrs'
34b37bbb 104
c2f3be9d 105 void setQuestion(int op, const DNSName &qdomain, int qtype); // wipes 'd', sets a random id, creates start of packet (domain, type, class etc)
34b37bbb
BH
106
107 DTime d_dt; //!< the time this packet was created. replyPacket() copies this in for you, so d_dt becomes the time spent processing the question+answer
1f07a63f 108 void wrapup(bool throwsOnTruncation=false); // writes out queued rrs, and generates the binary packet. also shuffles. also rectifies dnsheader 'd', and copies it to the stringbuffer. If throwsOnTruncation is set, an exception will be raised if the records are too large to fit inside a single DNS payload, instead of setting the TC bit
c2826d2e 109 void spoofQuestion(const DNSPacket& qd); //!< paste in the exact right case of the question. Useful for PacketCache
b35ea8ec 110 unsigned int getMinTTL(); //!< returns lowest TTL of any record in the packet
9951e2d0 111 bool isEmpty(); //!< returns true if there are no rrs in the packet
34b37bbb 112
90ba52e0 113 vector<DNSZoneRecord*> getAPRecords(); //!< get a vector with DNSZoneRecords that need additional processing
114 vector<DNSZoneRecord*> getAnswerRecords(); //!< get a vector with DNSZoneRecords that are answers
bdbee377 115 vector<DNSZoneRecord*> getServiceRecords(); //!< Get a vector with all Service-style (SVCB) records
34b37bbb
BH
116 void setCompress(bool compress);
117
c2826d2e 118 std::unique_ptr<DNSPacket> replyPacket() const; //!< convenience function that creates a virgin answer packet to this question
34b37bbb 119
b8e0f341 120 void commitD(); //!< copies 'd' into the stringbuffer
78bcb858 121 unsigned int getMaxReplyLen(); //!< retrieve the maximum length of the packet we should send in response
80397312 122 void setMaxReplyLen(int bytes); //!< set the max reply len (used when retrieving from the packet cache, and this changed)
7f7b8d55 123
c2826d2e 124 bool couldBeCached() const; //!< returns 0 if this query should bypass the packet cache
02980dc2 125 bool hasEDNSSubnet() const;
c2826d2e 126 bool hasEDNS() const;
37063755
PL
127 bool hasEDNSCookie() const;
128 bool hasWellFormedEDNSCookie() const;
38118dcb 129 bool hasValidEDNSCookie() const;
298fabc3
AT
130 uint8_t getEDNSVersion() const { return d_ednsversion; };
131 void setEDNSRcode(uint16_t extRCode)
132 {
133 // WARNING: this is really 12 bits
134 d_ednsrcode=extRCode;
135 };
136 uint8_t getEDNSRCode() const { return d_ednsrcode; };
bf269e28
RG
137 uint32_t getHash() const { return d_hash; };
138 void setHash(uint32_t hash) { d_hash = hash; };
139
34b37bbb 140 //////// DATA !
12c86877 141
c2f3be9d
PD
142 DNSName qdomain; //!< qname of the question 4 - unsure how this is used
143 DNSName qdomainwild; //!< wildcard matched by qname, used by LuaPolicyEngine
144 DNSName qdomainzone; //!< zone name for the answer (as reflected in SOA for negative responses), used by LuaPolicyEngine
921d0747 145 string d_peer_principal;
1a5ac5d7
AT
146 const DNSName& getTSIGKeyname() const;
147
921d0747
PL
148 struct dnsheader d; //!< dnsheader at the start of the databuffer 12
149
921d0747
PL
150 TSIGRecordContent d_trc; //72
151
152 ComboAddress d_remote; //28
034768b4 153 std::optional<ComboAddress> d_inner_remote; // the 'outer' remote is the IP on the physical packet header. The 'inner' remote lives one layer deeper, in the PROXY header.
eace2c24 154 TSIGHashEnum d_tsig_algo{TSIG_MD5}; //4
921d0747 155
f93ad391 156 int d_ednsRawPacketSizeLimit{-1}; // only used for Lua record
eace2c24
RG
157 uint16_t qclass{QClass::IN}; //!< class of the question - should always be INternet 2
158 QType qtype; //!< type of the question 2
159
160 bool d_tcp{false};
161 bool d_dnssecOk{false};
162 bool d_havetsig{false};
78bcb858 163
ea3816cf 164 bool getTSIGDetails(TSIGRecordContent* tr, DNSName* keyname, uint16_t* tsigPos=nullptr) const;
675fa24c
PD
165 void setTSIGDetails(const TSIGRecordContent& tr, const DNSName& keyname, const string& secret, const string& previous, bool timersonly=false);
166 bool getTKEYRecord(TKEYRecordContent* tr, DNSName* keyname) const;
4429ed62 167
90ba52e0 168 vector<DNSZoneRecord>& getRRS() { return d_rrs; }
ea3816cf
RG
169 bool checkForCorrectTSIG(UeberBackend* B, DNSName* keyname, string* secret, TSIGRecordContent* trc) const;
170
779b8a25 171 static uint16_t s_udpTruncationThreshold;
eace2c24 172 static bool s_doEDNSSubnetProcessing;
37063755
PL
173 static bool s_doEDNSCookieProcessing;
174 static string s_EDNSCookieKey;
50e2abc0 175 EDNSSubnetOpts d_eso;
15e39ee4
OM
176
177#ifdef ENABLE_GSS_TSIG
dd0ef5ed 178 void cleanupGSS(int rcode);
15e39ee4 179#endif
eace2c24 180
12c86877 181private:
34b37bbb
BH
182 void pasteQ(const char *question, int length); //!< set the question of this packet, useful for crafting replies
183
78bcb858 184 string d_tsigsecret;
675fa24c 185 DNSName d_tsigkeyname;
78bcb858 186 string d_tsigprevious;
78bcb858 187
90ba52e0 188 vector<DNSZoneRecord> d_rrs; // 8
9d40dd1f 189 std::unordered_set<size_t> d_dedup;
921d0747 190 string d_rawpacket; // this is where everything lives 8
37063755 191 EDNSCookiesOpt d_eco;
921d0747 192
eace2c24
RG
193 int d_maxreplylen{0};
194 int d_socket{-1}; // 4
bf269e28 195 uint32_t d_hash{0};
eace2c24
RG
196 // WARNING! This is really 12 bits
197 uint16_t d_ednsrcode{0};
198 uint8_t d_ednsversion{0};
199
200 bool d_wrapped{false}; // 1
201 bool d_compress{true}; // 1
202 bool d_tsigtimersonly{false};
203 bool d_wantsnsid{false};
204 bool d_haveednssubnet{false};
37063755 205 bool d_haveednscookie{false};
29992caa 206 bool d_ednscookievalid{false};
eace2c24 207 bool d_haveednssection{false};
27c0050c 208 bool d_isQuery;
12c86877 209};