Line 0
Link Here
|
|
|
1 |
Index: dnswriter.hh |
2 |
=================================================================== |
3 |
--- dnswriter.hh (revision 962) |
4 |
+++ dnswriter.hh (revision 996) |
5 |
@@ -84,5 +84,5 @@ |
6 |
|
7 |
void xfrLabel(const string& label, bool compress=false); |
8 |
- void xfrText(const string& text); |
9 |
+ void xfrText(const string& text, bool multi=false); |
10 |
void xfrBlob(const string& blob); |
11 |
void xfrHexBlob(const string& blob); |
12 |
Index: dnsparser.hh |
13 |
=================================================================== |
14 |
--- dnsparser.hh (revision 972) |
15 |
+++ dnsparser.hh (revision 996) |
16 |
@@ -110,7 +110,7 @@ |
17 |
} |
18 |
|
19 |
- void xfrText(string &text) |
20 |
- { |
21 |
- text=getText(); |
22 |
+ void xfrText(string &text, bool multi=false) |
23 |
+ { |
24 |
+ text=getText(multi); |
25 |
} |
26 |
|
27 |
@@ -126,5 +126,5 @@ |
28 |
|
29 |
string getLabel(unsigned int recurs=0); |
30 |
- string getText(); |
31 |
+ string getText(bool multi); |
32 |
|
33 |
uint16_t d_pos; |
34 |
Index: zoneparser-tng.cc |
35 |
=================================================================== |
36 |
--- zoneparser-tng.cc (revision 989) |
37 |
+++ zoneparser-tng.cc (revision 996) |
38 |
@@ -281,6 +281,5 @@ |
39 |
} |
40 |
catch(...) { |
41 |
- cerr<<"Oops, this doesn't look like a qtype, stopping loop\n"; |
42 |
- break; |
43 |
+ throw runtime_error("Parsing zone content line: '"+nextpart+"' doesn't look like a qtype, stopping loop"); |
44 |
} |
45 |
} |
46 |
Index: dnswriter.cc |
47 |
=================================================================== |
48 |
--- dnswriter.cc (revision 962) |
49 |
+++ dnswriter.cc (revision 996) |
50 |
@@ -2,4 +2,5 @@ |
51 |
#include "misc.hh" |
52 |
#include "dnsparser.hh" |
53 |
+#include <boost/tokenizer.hpp> |
54 |
|
55 |
DNSPacketWriter::DNSPacketWriter(vector<uint8_t>& content, const string& qname, uint16_t qtype, uint16_t qclass, uint8_t opcode) |
56 |
@@ -116,9 +117,20 @@ |
57 |
} |
58 |
|
59 |
-void DNSPacketWriter::xfrText(const string& text) |
60 |
-{ |
61 |
- d_record.push_back(text.length()); |
62 |
- const uint8_t* ptr=(uint8_t*)(text.c_str()); |
63 |
- d_record.insert(d_record.end(), ptr, ptr+text.size()); |
64 |
+void DNSPacketWriter::xfrText(const string& text, bool) |
65 |
+{ |
66 |
+ escaped_list_separator<char> sep('\\', ' ' , '"'); |
67 |
+ tokenizer<escaped_list_separator<char> > tok(text, sep); |
68 |
+ |
69 |
+ tokenizer<escaped_list_separator<char> >::iterator beg=tok.begin(); |
70 |
+ |
71 |
+ if(beg==tok.end()) { |
72 |
+ d_record.push_back(0); |
73 |
+ } |
74 |
+ else |
75 |
+ for(; beg!=tok.end(); ++beg){ |
76 |
+ d_record.push_back(beg->length()); |
77 |
+ const uint8_t* ptr=(uint8_t*)(beg->c_str()); |
78 |
+ d_record.insert(d_record.end(), ptr, ptr+beg->length()); |
79 |
+ } |
80 |
} |
81 |
|
82 |
Index: dnsparser.cc |
83 |
=================================================================== |
84 |
--- dnsparser.cc (revision 972) |
85 |
+++ dnsparser.cc (revision 996) |
86 |
@@ -359,14 +359,42 @@ |
87 |
} |
88 |
|
89 |
-string PacketReader::getText() |
90 |
+static string txtEscape(const string &name) |
91 |
+{ |
92 |
+ string ret; |
93 |
+ |
94 |
+ for(string::const_iterator i=name.begin();i!=name.end();++i) |
95 |
+ if(*i=='"' || *i=='\\'){ |
96 |
+ ret += '\\'; |
97 |
+ ret += *i; |
98 |
+ } |
99 |
+ else |
100 |
+ ret += *i; |
101 |
+ return ret; |
102 |
+} |
103 |
+ |
104 |
+// exceptions thrown here do not result in logging in the main pdns auth server - just so you know! |
105 |
+string PacketReader::getText(bool multi) |
106 |
{ |
107 |
string ret; |
108 |
ret.reserve(40); |
109 |
- |
110 |
- unsigned char labellen=d_content.at(d_pos++); |
111 |
- ret.append(&d_content.at(d_pos), &d_content.at(d_pos+labellen-1)+1); // the end is one beyond the packet |
112 |
- d_pos+=labellen; |
113 |
- return ret; |
114 |
-} |
115 |
+ while(d_pos < d_startrecordpos + d_recordlen ) { |
116 |
+ if(!ret.empty()) { |
117 |
+ ret.append(1,' '); |
118 |
+ } |
119 |
+ unsigned char labellen=d_content.at(d_pos++); |
120 |
+ |
121 |
+ ret.append(1,'"'); |
122 |
+ string val(&d_content.at(d_pos), &d_content.at(d_pos+labellen-1)+1); |
123 |
+ |
124 |
+ ret.append(txtEscape(val)); // the end is one beyond the packet |
125 |
+ ret.append(1,'"'); |
126 |
+ d_pos+=labellen; |
127 |
+ if(!multi) |
128 |
+ break; |
129 |
+ } |
130 |
+ |
131 |
+ return ret; |
132 |
+} |
133 |
+ |
134 |
|
135 |
void PacketReader::getLabelFromContent(const vector<uint8_t>& content, uint16_t& frompos, string& ret, int recurs) |
136 |
Index: rcpgenerator.hh |
137 |
=================================================================== |
138 |
--- rcpgenerator.hh (revision 802) |
139 |
+++ rcpgenerator.hh (revision 996) |
140 |
@@ -51,5 +51,5 @@ |
141 |
|
142 |
void xfrLabel(string& val, bool compress=false); |
143 |
- void xfrText(string& val); |
144 |
+ void xfrText(string& val, bool multi=false); |
145 |
void xfrHexBlob(string& val); |
146 |
void xfrBlob(string& val); |
147 |
@@ -76,5 +76,5 @@ |
148 |
void xfrType(const uint16_t& val); |
149 |
void xfrLabel(const string& val, bool compress=false); |
150 |
- void xfrText(const string& val); |
151 |
+ void xfrText(const string& val, bool multi=false); |
152 |
void xfrBlob(const string& val); |
153 |
void xfrHexBlob(const string& val); |
154 |
Index: dnsrecords.cc |
155 |
=================================================================== |
156 |
--- dnsrecords.cc (revision 823) |
157 |
+++ dnsrecords.cc (revision 996) |
158 |
@@ -1,5 +1,5 @@ |
159 |
/* |
160 |
PowerDNS Versatile Database Driven Nameserver |
161 |
- Copyright (C) 2005 - 2006 PowerDNS.COM BV |
162 |
+ Copyright (C) 2005 - 2007 PowerDNS.COM BV |
163 |
|
164 |
This program is free software; you can redistribute it and/or modify |
165 |
@@ -178,6 +178,6 @@ |
166 |
boilerplate_conv(PTR, ns_t_ptr, conv.xfrLabel(d_content, true)); |
167 |
boilerplate_conv(CNAME, ns_t_cname, conv.xfrLabel(d_content, true)); |
168 |
-boilerplate_conv(TXT, ns_t_txt, conv.xfrText(d_text)); |
169 |
-boilerplate_conv(SPF, 99, conv.xfrText(d_text)); |
170 |
+boilerplate_conv(TXT, ns_t_txt, conv.xfrText(d_text, true)); |
171 |
+boilerplate_conv(SPF, 99, conv.xfrText(d_text, true)); |
172 |
boilerplate_conv(HINFO, ns_t_hinfo, conv.xfrText(d_cpu); conv.xfrText(d_host)); |
173 |
|
174 |
@@ -199,4 +199,9 @@ |
175 |
conv.xfr16BitInt(d_preference); |
176 |
conv.xfrLabel(d_mxname, true); |
177 |
+ ) |
178 |
+ |
179 |
+boilerplate_conv(AFSDB, ns_t_afsdb, |
180 |
+ conv.xfr16BitInt(d_subtype); |
181 |
+ conv.xfrLabel(d_hostname); |
182 |
) |
183 |
|
184 |
@@ -235,4 +240,11 @@ |
185 |
conv.xfr32BitInt(d_st.expire); |
186 |
conv.xfr32BitInt(d_st.minimum); |
187 |
+ ); |
188 |
+#undef KEY |
189 |
+boilerplate_conv(KEY, ns_t_key, |
190 |
+ conv.xfr16BitInt(d_flags); |
191 |
+ conv.xfr8BitInt(d_protocol); |
192 |
+ conv.xfr8BitInt(d_algorithm); |
193 |
+ conv.xfrBlob(d_certificate); |
194 |
); |
195 |
|
196 |
@@ -294,7 +306,9 @@ |
197 |
void reportOtherTypes() |
198 |
{ |
199 |
+ AFSDBRecordContent::report(); |
200 |
SPFRecordContent::report(); |
201 |
NAPTRRecordContent::report(); |
202 |
RPRecordContent::report(); |
203 |
+ KEYRecordContent::report(); |
204 |
DNSKEYRecordContent::report(); |
205 |
RRSIGRecordContent::report(); |
206 |
Index: dnsrecords.hh |
207 |
=================================================================== |
208 |
--- dnsrecords.hh (revision 823) |
209 |
+++ dnsrecords.hh (revision 978) |
210 |
@@ -196,4 +196,26 @@ |
211 |
string d_fingerprint; |
212 |
}; |
213 |
+ |
214 |
+class KEYRecordContent : public DNSRecordContent |
215 |
+{ |
216 |
+public: |
217 |
+ includeboilerplate(KEY) |
218 |
+ |
219 |
+private: |
220 |
+ uint16_t d_flags; |
221 |
+ uint8_t d_protocol, d_algorithm; |
222 |
+ string d_certificate; |
223 |
+}; |
224 |
+ |
225 |
+class AFSDBRecordContent : public DNSRecordContent |
226 |
+{ |
227 |
+public: |
228 |
+ includeboilerplate(AFSDB) |
229 |
+ |
230 |
+private: |
231 |
+ uint16_t d_subtype; |
232 |
+ string d_hostname; |
233 |
+}; |
234 |
+ |
235 |
|
236 |
class CERTRecordContent : public DNSRecordContent |
237 |
Index: rcpgenerator.cc |
238 |
=================================================================== |
239 |
--- rcpgenerator.cc (revision 850) |
240 |
+++ rcpgenerator.cc (revision 996) |
241 |
@@ -67,9 +67,38 @@ |
242 |
if(!isdigit(d_string.at(d_pos))) |
243 |
throw RecordTextException("while parsing IP address, expected digits at position "+lexical_cast<string>(d_pos)+" in '"+d_string+"'"); |
244 |
- |
245 |
- string ip; |
246 |
- xfrLabel(ip); |
247 |
- if(!IpToU32(ip, &val)) |
248 |
- throw RecordTextException("unable to parse IP address '"+ip+"'"); |
249 |
+ |
250 |
+ uint32_t octet=0; |
251 |
+ val=0; |
252 |
+ char count=0; |
253 |
+ |
254 |
+ for(;;) { |
255 |
+ if(d_string.at(d_pos)=='.') { |
256 |
+ val<<=8; |
257 |
+ val+=octet; |
258 |
+ octet=0; |
259 |
+ count++; |
260 |
+ if(count > 3) |
261 |
+ break; |
262 |
+ } |
263 |
+ else if(isdigit(d_string.at(d_pos))) { |
264 |
+ octet*=10; |
265 |
+ octet+=d_string.at(d_pos) - '0'; |
266 |
+ if(octet > 255) |
267 |
+ throw RecordTextException("unable to parse IP address"); |
268 |
+ } |
269 |
+ else if(dns_isspace(d_string.at(d_pos))) |
270 |
+ break; |
271 |
+ else |
272 |
+ throw RecordTextException("unable to parse IP address, strange character: "+d_string.at(d_pos)); |
273 |
+ |
274 |
+ d_pos++; |
275 |
+ if(d_pos == d_string.length()) |
276 |
+ break; |
277 |
+ } |
278 |
+ if(count<=3) { |
279 |
+ val<<=8; |
280 |
+ val+=octet; |
281 |
+ } |
282 |
+ val=ntohl(val); |
283 |
} |
284 |
|
285 |
@@ -178,23 +207,31 @@ |
286 |
} |
287 |
|
288 |
- |
289 |
-void RecordTextReader::xfrText(string& val) |
290 |
-{ |
291 |
- skipSpaces(); |
292 |
- if(d_string[d_pos]!='"') |
293 |
- throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'"); |
294 |
- |
295 |
+void RecordTextReader::xfrText(string& val, bool multi) |
296 |
+{ |
297 |
val.clear(); |
298 |
val.reserve(d_end - d_pos); |
299 |
- |
300 |
- while(++d_pos < d_end && d_string[d_pos]!='"') { |
301 |
- if(d_string[d_pos]=='\\' && d_pos+1!=d_end) { |
302 |
- ++d_pos; |
303 |
+ |
304 |
+ while(d_pos != d_end) { |
305 |
+ if(!val.empty()) |
306 |
+ val.append(1, ' '); |
307 |
+ |
308 |
+ skipSpaces(); |
309 |
+ if(d_string[d_pos]!='"') |
310 |
+ throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'"); |
311 |
+ |
312 |
+ val.append(1, '"'); |
313 |
+ while(++d_pos < d_end && d_string[d_pos]!='"') { |
314 |
+ if(d_string[d_pos]=='\\' && d_pos+1!=d_end) { |
315 |
+ val.append(1, d_string[d_pos++]); |
316 |
+ } |
317 |
+ val.append(1, d_string[d_pos]); |
318 |
} |
319 |
- val.append(1, d_string[d_pos]); |
320 |
- } |
321 |
- if(d_pos == d_end) |
322 |
- throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'"); |
323 |
- d_pos++; |
324 |
+ val.append(1,'"'); |
325 |
+ if(d_pos == d_end) |
326 |
+ throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'"); |
327 |
+ d_pos++; |
328 |
+ if(!multi) |
329 |
+ break; |
330 |
+ } |
331 |
} |
332 |
|
333 |
@@ -251,11 +288,28 @@ |
334 |
|
335 |
char tmp[17]; |
336 |
- snprintf(tmp, sizeof(tmp)-1, "%u.%u.%u.%u", |
337 |
- (val >> 24)&0xff, |
338 |
- (val >> 16)&0xff, |
339 |
- (val >> 8)&0xff, |
340 |
- (val )&0xff); |
341 |
- |
342 |
- d_string+=tmp; |
343 |
+ uint32_t ip=htonl(val); |
344 |
+ uint8_t vals[4]; |
345 |
+ |
346 |
+ memcpy(&vals[0], &ip, sizeof(ip)); |
347 |
+ |
348 |
+ char *pos=tmp; |
349 |
+ |
350 |
+ for(int n=0; n < 4; ++n) { |
351 |
+ if(vals[n]<10) { |
352 |
+ *(pos++)=vals[n]+'0'; |
353 |
+ } else if(vals[n] < 100) { |
354 |
+ *(pos++)=(vals[n]/10) +'0'; |
355 |
+ *(pos++)=(vals[n]%10) +'0'; |
356 |
+ } else { |
357 |
+ *(pos++)=(vals[n]/100) +'0'; |
358 |
+ vals[n]%=100; |
359 |
+ *(pos++)=(vals[n]/10) +'0'; |
360 |
+ *(pos++)=(vals[n]%10) +'0'; |
361 |
+ } |
362 |
+ if(n!=3) |
363 |
+ *(pos++)='.'; |
364 |
+ } |
365 |
+ *pos=0; |
366 |
+ d_string.append(tmp, pos); |
367 |
} |
368 |
|
369 |
@@ -338,23 +392,10 @@ |
370 |
} |
371 |
|
372 |
-void RecordTextWriter::xfrText(const string& val) |
373 |
-{ |
374 |
- if(!d_string.empty()) |
375 |
- d_string.append(1,' '); |
376 |
- d_string.append(1,'"'); |
377 |
- |
378 |
- if(val.find_first_of("\\\"") == string::npos) |
379 |
- d_string+=val; |
380 |
- else { |
381 |
- string::size_type end=val.size(); |
382 |
- |
383 |
- for(string::size_type pos=0; pos < end; ++pos) { |
384 |
- if(val[pos]=='\'' || val[pos]=='"') |
385 |
- d_string.append(1,'\\'); |
386 |
- d_string.append(1, val[pos]); |
387 |
- } |
388 |
- } |
389 |
- |
390 |
- d_string.append(1,'"'); |
391 |
+void RecordTextWriter::xfrText(const string& val, bool multi) |
392 |
+{ |
393 |
+ if(!d_string.empty()) |
394 |
+ d_string.append(1,' '); |
395 |
+ |
396 |
+ d_string.append(val); |
397 |
} |
398 |
|