]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dns.cc
make all caches that can be cleaned in the recursor canonical ordered so we can do...
[thirdparty/pdns.git] / pdns / dns.cc
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 #include "dns.hh"
5 #include "misc.hh"
6 #include "arguments.hh"
7 #include <stdexcept>
8 #include <iostream>
9 #include <boost/algorithm/string.hpp>
10 #include <boost/lexical_cast.hpp>
11 #include <boost/assign/list_of.hpp>
12 #include "dnsparser.hh"
13
14 std::vector<std::string> RCode::rcodes_s = boost::assign::list_of
15 ("No Error")
16 ("Form Error")
17 ("Server Failure")
18 ("Non-Existent domain")
19 ("Not Implemented")
20 ("Query Refused")
21 ("Name Exists when it should not")
22 ("RR Set Exists when it should not")
23 ("RR Set that should exist does not")
24 ("Server Not Authoritative for zone / Not Authorized")
25 ("Name not contained in zone")
26 ("Err#11")
27 ("Err#12")
28 ("Err#13")
29 ("Err#14")
30 ("Err#15")
31 ("Bad OPT Version / TSIG Signature Failure")
32 ("Key not recognized")
33 ("Signature out of time window")
34 ("Bad TKEY Mode")
35 ("Duplicate key name")
36 ("Algorithm not supported")
37 ("Bad Truncation")
38 ;
39
40 std::string RCode::to_s(unsigned short rcode) {
41 if (rcode > RCode::rcodes_s.size()-1 )
42 return std::string("Err#")+boost::lexical_cast<std::string>(rcode);
43 return RCode::rcodes_s[rcode];
44 }
45
46 class BoundsCheckingPointer
47 {
48 public:
49 explicit BoundsCheckingPointer(const char* a, unsigned int length)
50 : d_ptr(a), d_length(length)
51 {}
52
53 explicit BoundsCheckingPointer(const std::string& str)
54 : d_ptr(str.c_str()), d_length(str.size())
55 {}
56
57
58 char operator[](unsigned int offset) const
59 {
60 if(offset < d_length)
61 return d_ptr[offset];
62 throw runtime_error("out of bounds: "+boost::lexical_cast<string>(offset)+" >= " + boost::lexical_cast<string>(d_length));
63 }
64 private:
65 const char* d_ptr;
66 const unsigned int d_length;
67 };
68
69
70 // goal is to hash based purely on the question name, and turn error into 'default'
71 uint32_t hashQuestion(const char* packet, uint16_t len, uint32_t init)
72 {
73 if(len < 12)
74 return init;
75
76 uint32_t ret=init;
77 const unsigned char* end = (const unsigned char*)packet+len;
78 const unsigned char* pos = (const unsigned char*)packet+12;
79
80 unsigned char labellen;
81 while((labellen=*pos++) && pos < end) {
82 if(pos + labellen + 1 > end) // include length field in hash
83 return 0;
84 ret=burtleCI(pos, labellen+1, ret);
85 pos += labellen;
86 }
87 return ret;
88 }
89
90
91 string& attodot(string &str)
92 {
93 if(str.find_first_of("@")==string::npos)
94 return str;
95
96 for (unsigned int i = 0; i < str.length(); i++)
97 {
98 if (str[i] == '@') {
99 str[i] = '.';
100 break;
101 } else if (str[i] == '.') {
102 str.insert(i++, "\\");
103 }
104 }
105 return str;
106 }
107
108 vector<DNSResourceRecord> convertRRS(const vector<DNSRecord>& in)
109 {
110 vector<DNSResourceRecord> out;
111 for(const auto& d : in) {
112 DNSResourceRecord rr;
113 rr.qname = d.d_name;
114 rr.qtype = QType(d.d_type);
115 rr.ttl = d.d_ttl;
116 rr.content = d.d_content->getZoneRepresentation();
117 rr.auth = false;
118 rr.qclass = d.d_class;
119 out.push_back(rr);
120 }
121 return out;
122 }