]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnspacket.hh
Avoid throwing an exception in Logger::log().
[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
12c86877
BH
23#include <cstdio>
24#include <cstring>
25#include <cstdlib>
1258abe0 26#include <sys/types.h>
809fe23f 27#include "iputils.hh"
af7d3ea6 28#include "ednssubnet.hh"
55b524a0 29#include <unordered_set>
12c86877
BH
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <sys/time.h>
1258abe0
BH
33#include <unistd.h>
34#include <arpa/inet.h>
35
12c86877
BH
36#include <iostream>
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
78bcb858 61 const string& getString(); //!< for serialization - just passes the whole packet
12c86877 62
34b37bbb 63 // address & socket manipulation
b8e0f341 64 void setRemote(const ComboAddress*);
b9b4da23 65 ComboAddress getRemote() const;
af7d3ea6 66 Netmask getRealRemote() const;
b9b4da23 67 ComboAddress getLocal() const
88c1bc50
BH
68 {
69 ComboAddress ca;
70 socklen_t len=sizeof(ca);
71 getsockname(d_socket, (sockaddr*)&ca, &len);
b9b4da23 72 return ca;
88c1bc50 73 }
092f210a 74 uint16_t getRemotePort() const;
2b6f1436
BH
75
76 boost::optional<ComboAddress> d_anyLocal;
12c86877 77
34b37bbb
BH
78 Utility::sock_t getSocket() const
79 {
80 return d_socket;
81 }
b8e0f341 82 void setSocket(Utility::sock_t sock);
34b37bbb
BH
83
84
85 // these manipulate 'd'
86 void setA(bool); //!< make this packet authoritative - manipulates 'd'
87 void setID(uint16_t); //!< set the DNS id of this packet - manipulates 'd'
88 void setRA(bool); //!< set the Recursion Available flag - manipulates 'd'
89 void setRD(bool); //!< set the Recursion Desired flag - manipulates 'd'
90 void setAnswer(bool); //!< Make this packet an answer - clears the 'stringbuffer' first, if passed 'true', does nothing otherwise, manipulates 'd'
12c86877 91
34b37bbb
BH
92 void setOpcode(uint16_t); //!< set the Opcode of this packet - manipulates 'd'
93 void setRcode(int v); //!< set the Rcode of this packet - manipulates 'd'
94
95 void clearRecords(); //!< when building a packet, wipe all previously added records (clears 'rrs')
77235722 96
90ba52e0 97 /** Add a DNSZoneRecord to this packet. A DNSPacket (as does a DNS Packet) has 4 kinds of resource records. Questions,
12c86877 98 Answers, Authority and Additional. See RFC 1034 and 1035 for details. You can specify where a record needs to go in the
90ba52e0 99 DNSZoneRecord d_place field */
9bbcf03a 100 void addRecord(DNSZoneRecord&&); // adds to 'rrs'
34b37bbb 101
c2f3be9d 102 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
103
104 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
e02d0a59 105 void wrapup(); // writes out queued rrs, and generates the binary packet. also shuffles. also rectifies dnsheader 'd', and copies it to the stringbuffer
c2826d2e 106 void spoofQuestion(const DNSPacket& qd); //!< paste in the exact right case of the question. Useful for PacketCache
b35ea8ec 107 unsigned int getMinTTL(); //!< returns lowest TTL of any record in the packet
9951e2d0 108 bool isEmpty(); //!< returns true if there are no rrs in the packet
34b37bbb 109
90ba52e0 110 vector<DNSZoneRecord*> getAPRecords(); //!< get a vector with DNSZoneRecords that need additional processing
111 vector<DNSZoneRecord*> getAnswerRecords(); //!< get a vector with DNSZoneRecords that are answers
34b37bbb
BH
112 void setCompress(bool compress);
113
c2826d2e 114 std::unique_ptr<DNSPacket> replyPacket() const; //!< convenience function that creates a virgin answer packet to this question
34b37bbb 115
b8e0f341 116 void commitD(); //!< copies 'd' into the stringbuffer
78bcb858 117 unsigned int getMaxReplyLen(); //!< retrieve the maximum length of the packet we should send in response
80397312 118 void setMaxReplyLen(int bytes); //!< set the max reply len (used when retrieving from the packet cache, and this changed)
7f7b8d55 119
c2826d2e 120 bool couldBeCached() const; //!< returns 0 if this query should bypass the packet cache
02980dc2 121 bool hasEDNSSubnet() const;
c2826d2e 122 bool hasEDNS() const;
298fabc3
AT
123 uint8_t getEDNSVersion() const { return d_ednsversion; };
124 void setEDNSRcode(uint16_t extRCode)
125 {
126 // WARNING: this is really 12 bits
127 d_ednsrcode=extRCode;
128 };
129 uint8_t getEDNSRCode() const { return d_ednsrcode; };
bf269e28
RG
130 uint32_t getHash() const { return d_hash; };
131 void setHash(uint32_t hash) { d_hash = hash; };
132
34b37bbb 133 //////// DATA !
12c86877 134
c2f3be9d
PD
135 DNSName qdomain; //!< qname of the question 4 - unsure how this is used
136 DNSName qdomainwild; //!< wildcard matched by qname, used by LuaPolicyEngine
137 DNSName qdomainzone; //!< zone name for the answer (as reflected in SOA for negative responses), used by LuaPolicyEngine
921d0747 138 string d_peer_principal;
1a5ac5d7
AT
139 const DNSName& getTSIGKeyname() const;
140
921d0747
PL
141 struct dnsheader d; //!< dnsheader at the start of the databuffer 12
142
921d0747
PL
143 TSIGRecordContent d_trc; //72
144
145 ComboAddress d_remote; //28
eace2c24 146 TSIGHashEnum d_tsig_algo{TSIG_MD5}; //4
921d0747 147
f93ad391 148 int d_ednsRawPacketSizeLimit{-1}; // only used for Lua record
eace2c24
RG
149 uint16_t qclass{QClass::IN}; //!< class of the question - should always be INternet 2
150 QType qtype; //!< type of the question 2
151
152 bool d_tcp{false};
153 bool d_dnssecOk{false};
154 bool d_havetsig{false};
78bcb858 155
ea3816cf 156 bool getTSIGDetails(TSIGRecordContent* tr, DNSName* keyname, uint16_t* tsigPos=nullptr) const;
675fa24c
PD
157 void setTSIGDetails(const TSIGRecordContent& tr, const DNSName& keyname, const string& secret, const string& previous, bool timersonly=false);
158 bool getTKEYRecord(TKEYRecordContent* tr, DNSName* keyname) const;
4429ed62 159
90ba52e0 160 vector<DNSZoneRecord>& getRRS() { return d_rrs; }
ea3816cf
RG
161 bool checkForCorrectTSIG(UeberBackend* B, DNSName* keyname, string* secret, TSIGRecordContent* trc) const;
162
779b8a25 163 static uint16_t s_udpTruncationThreshold;
eace2c24
RG
164 static bool s_doEDNSSubnetProcessing;
165
12c86877 166private:
34b37bbb
BH
167 void pasteQ(const char *question, int length); //!< set the question of this packet, useful for crafting replies
168
78bcb858 169 string d_tsigsecret;
675fa24c 170 DNSName d_tsigkeyname;
78bcb858 171 string d_tsigprevious;
78bcb858 172
90ba52e0 173 vector<DNSZoneRecord> d_rrs; // 8
9d40dd1f 174 std::unordered_set<size_t> d_dedup;
921d0747 175 string d_rawpacket; // this is where everything lives 8
921d0747
PL
176 EDNSSubnetOpts d_eso;
177
eace2c24
RG
178 int d_maxreplylen{0};
179 int d_socket{-1}; // 4
bf269e28 180 uint32_t d_hash{0};
eace2c24
RG
181 // WARNING! This is really 12 bits
182 uint16_t d_ednsrcode{0};
183 uint8_t d_ednsversion{0};
184
185 bool d_wrapped{false}; // 1
186 bool d_compress{true}; // 1
187 bool d_tsigtimersonly{false};
188 bool d_wantsnsid{false};
189 bool d_haveednssubnet{false};
190 bool d_haveednssection{false};
27c0050c 191 bool d_isQuery;
12c86877 192};