Branch data Line data Source code
1 : : ///////////////
2 : : ///////////////
3 : : /////////////// THIS FILE IS AUTOMATICALLY GENERATED BY gen-rdatacode.py.
4 : : /////////////// DO NOT EDIT!
5 : : ///////////////
6 : : ///////////////
7 : :
8 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
9 : : //
10 : : // Permission to use, copy, modify, and/or distribute this software for any
11 : : // purpose with or without fee is hereby granted, provided that the above
12 : : // copyright notice and this permission notice appear in all copies.
13 : : //
14 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
15 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
16 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
17 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
18 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
19 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 : : // PERFORMANCE OF THIS SOFTWARE.
21 : :
22 : : #include <string>
23 : : #include <sstream>
24 : : #include <vector>
25 : :
26 : : #include <boost/lexical_cast.hpp>
27 : :
28 : : #include <util/buffer.h>
29 : : #include <util/strutil.h>
30 : : #include <util/encode/base64.h>
31 : :
32 : : #include <dns/messagerenderer.h>
33 : : #include <dns/name.h>
34 : : #include <dns/rdata.h>
35 : : #include <dns/rdataclass.h>
36 : : #include <dns/tsigerror.h>
37 : :
38 : : using namespace std;
39 : : using namespace boost;
40 : : using namespace isc::util;
41 : : using namespace isc::util::encode;
42 : : using namespace isc::util::str;
43 : :
44 : : namespace isc {
45 : : namespace dns {
46 : : namespace rdata {
47 : : namespace any {
48 : :
49 : : /// This is a straightforward representation of TSIG RDATA fields.
50 [ + - ][ + - ]: 1985 : struct TSIG::TSIGImpl {
51 : 275 : TSIGImpl(const Name& algorithm, uint64_t time_signed, uint16_t fudge,
52 : : vector<uint8_t>& mac, uint16_t original_id, uint16_t error,
53 : : vector<uint8_t>& other_data) :
54 : : algorithm_(algorithm), time_signed_(time_signed), fudge_(fudge),
55 : : mac_(mac), original_id_(original_id), error_(error),
56 [ + - ][ + - ]: 275 : other_data_(other_data)
57 : 275 : {}
58 : : TSIGImpl(const Name& algorithm, uint64_t time_signed, uint16_t fudge,
59 : : size_t macsize, const void* mac, uint16_t original_id,
60 : : uint16_t error, size_t other_len, const void* other_data) :
61 : : algorithm_(algorithm), time_signed_(time_signed), fudge_(fudge),
62 : : mac_(static_cast<const uint8_t*>(mac),
63 : : static_cast<const uint8_t*>(mac) + macsize),
64 : : original_id_(original_id), error_(error),
65 : : other_data_(static_cast<const uint8_t*>(other_data),
66 [ + - ][ + - ]: 246 : static_cast<const uint8_t*>(other_data) + other_len)
[ - + ]
67 : : {}
68 : : template <typename Output>
69 : : void toWireCommon(Output& output) const;
70 : :
71 : : const Name algorithm_;
72 : : const uint64_t time_signed_;
73 : : const uint16_t fudge_;
74 : : const vector<uint8_t> mac_;
75 : : const uint16_t original_id_;
76 : : const uint16_t error_;
77 : : const vector<uint8_t> other_data_;
78 : : };
79 : :
80 : : /// \brief Constructor from string.
81 : : ///
82 : : /// \c tsig_str must be formatted as follows:
83 : : /// \code <Alg> <Time> <Fudge> <MACsize> [<MAC>] <OrigID> <Error> <OtherLen> [<OtherData>]
84 : : /// \endcode
85 : : /// where
86 : : /// - <Alg> is a valid textual representation of domain name.
87 : : /// - <Time> is an unsigned 48-bit decimal integer.
88 : : /// - <MACSize>, <OrigID>, and <OtherLen> are an unsigned 16-bit decimal
89 : : /// integer.
90 : : /// - <Error> is an unsigned 16-bit decimal integer or a valid mnemonic for
91 : : /// the Error field specified in RFC2845. Currently, "BADSIG", "BADKEY",
92 : : /// and "BADTIME" are supported (case sensitive). In future versions
93 : : /// other representations that are compatible with the DNS RCODE will be
94 : : /// supported.
95 : : /// - <MAC> and <OtherData> is a BASE-64 encoded string that does not contain
96 : : /// space characters.
97 : : /// When <MACSize> and <OtherLen> is 0, <MAC> and <OtherData> must not
98 : : /// appear in \c tsgi_str, respectively.
99 : : /// - The decoded data of <MAC> is <MACSize> bytes of binary stream.
100 : : /// - The decoded data of <OtherData> is <OtherLen> bytes of binary stream.
101 : : ///
102 : : /// An example of valid string is:
103 : : /// \code "hmac-sha256. 853804800 300 3 AAAA 2845 0 0" \endcode
104 : : /// In this example <OtherData> is missing because <OtherLen> is 0.
105 : : ///
106 : : /// Note that RFC2845 does not define the standard presentation format
107 : : /// of %TSIG RR, so the above syntax is implementation specific.
108 : : /// This is, however, compatible with the format acceptable to BIND 9's
109 : : /// RDATA parser.
110 : : ///
111 : : /// <b>Exceptions</b>
112 : : ///
113 : : /// If <Alg> is not a valid domain name, a corresponding exception from
114 : : /// the \c Name class will be thrown;
115 : : /// if <MAC> or <OtherData> is not validly encoded in BASE-64, an exception
116 : : /// of class \c isc::BadValue will be thrown;
117 : : /// if %any of the other bullet points above is not met, an exception of
118 : : /// class \c InvalidRdataText will be thrown.
119 : : /// This constructor internally involves resource allocation, and if it fails
120 : : /// a corresponding standard exception will be thrown.
121 : 152 : TSIG::TSIG(const std::string& tsig_str) : impl_(NULL) {
122 [ + - + - ]: 152 : istringstream iss(tsig_str);
123 : :
124 : : try {
125 [ + - ][ + + ]: 151 : const Name algorithm(getToken(iss));
126 [ + - ][ + + ]: 75 : const int64_t time_signed = tokenToNum<int64_t, 48>(getToken(iss));
127 [ + - ][ + + ]: 73 : const int32_t fudge = tokenToNum<int32_t, 16>(getToken(iss));
128 [ + - ][ + + ]: 71 : const int32_t macsize = tokenToNum<int32_t, 16>(getToken(iss));
129 : :
130 [ + + ][ + - ]: 140 : const string mac_txt = (macsize > 0) ? getToken(iss) : "";
[ + - ]
131 : : vector<uint8_t> mac;
132 [ + + ]: 70 : decodeBase64(mac_txt, mac);
133 [ + + ]: 69 : if (mac.size() != macsize) {
134 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "TSIG MAC size and data are inconsistent");
[ + - ]
135 : : }
136 : :
137 [ + - ][ + + ]: 68 : const int32_t orig_id = tokenToNum<int32_t, 16>(getToken(iss));
138 : :
139 [ + - ]: 134 : const string error_txt = getToken(iss);
140 : 67 : int32_t error = 0;
141 : : // XXX: In the initial implementation we hardcode the mnemonics.
142 : : // We'll soon generalize this.
143 [ + + ]: 67 : if (error_txt == "BADSIG") {
144 : : error = 16;
145 [ + + ]: 59 : } else if (error_txt == "BADKEY") {
146 : : error = 17;
147 [ + + ]: 55 : } else if (error_txt == "BADTIME") {
148 : : error = 18;
149 : : } else {
150 [ + + ]: 50 : error = tokenToNum<int32_t, 16>(error_txt);
151 : : }
152 : :
153 [ + + ][ + - ]: 62 : const int32_t otherlen = tokenToNum<int32_t, 16>(getToken(iss));
154 [ + + ][ + - ]: 122 : const string otherdata_txt = (otherlen > 0) ? getToken(iss) : "";
[ + - ]
155 : : vector<uint8_t> other_data;
156 [ + - ]: 61 : decodeBase64(otherdata_txt, other_data);
157 : :
158 [ + + ]: 61 : if (!iss.eof()) {
159 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "Unexpected input for TSIG RDATA: " <<
[ + - ][ + - ]
160 : : tsig_str);
161 : : }
162 : :
163 : : impl_ = new TSIGImpl(algorithm, time_signed, fudge, mac, orig_id,
164 [ + - ][ + - ]: 60 : error, other_data);
165 : :
166 [ + + ]: 28 : } catch (const StringTokenError& ste) {
167 [ - + ][ - + ]: 24 : isc_throw(InvalidRdataText, "Invalid TSIG text: " << ste.what() <<
[ - + ][ - + ]
[ - + ][ - + ]
168 : : ": " << tsig_str);
169 : : }
170 : 60 : }
171 : :
172 : : /// \brief Constructor from wire-format data.
173 : : ///
174 : : /// When a read operation on \c buffer fails (e.g., due to a corrupted
175 : : /// message) a corresponding exception from the \c InputBuffer class will
176 : : /// be thrown.
177 : : /// If the wire-format data does not begin with a valid domain name,
178 : : /// a corresponding exception from the \c Name class will be thrown.
179 : : /// In addition, this constructor internally involves resource allocation,
180 : : /// and if it fails a corresponding standard exception will be thrown.
181 : : ///
182 : : /// According to RFC3597, the Algorithm field must be a non compressed form
183 : : /// of domain name. But this implementation accepts a %TSIG RR even if that
184 : : /// field is compressed.
185 : : ///
186 : : /// \param buffer A buffer storing the wire format data.
187 : : /// \param rdata_len The length of the RDATA in bytes, normally expected
188 : : /// to be the value of the RDLENGTH field of the corresponding RR.
189 : : /// But this constructor does not use this parameter; if necessary, the caller
190 : : /// must check consistency between the length parameter and the actual
191 : : /// RDATA length.
192 : 436 : TSIG::TSIG(InputBuffer& buffer, size_t) : impl_(NULL) {
193 [ + + ]: 435 : Name algorithm(buffer);
194 : :
195 : : uint8_t time_signed_buf[6];
196 [ + - ]: 217 : buffer.readData(time_signed_buf, sizeof(time_signed_buf));
197 : : const uint64_t time_signed =
198 : 217 : (static_cast<uint64_t>(time_signed_buf[0]) << 40 |
199 : 217 : static_cast<uint64_t>(time_signed_buf[1]) << 32 |
200 : 217 : static_cast<uint64_t>(time_signed_buf[2]) << 24 |
201 : 217 : static_cast<uint64_t>(time_signed_buf[3]) << 16 |
202 : 217 : static_cast<uint64_t>(time_signed_buf[4]) << 8 |
203 : 1085 : static_cast<uint64_t>(time_signed_buf[5]));
204 : :
205 [ + - ]: 217 : const uint16_t fudge = buffer.readUint16();
206 : :
207 [ + - ]: 217 : const uint16_t mac_size = buffer.readUint16();
208 [ + - ]: 217 : vector<uint8_t> mac(mac_size);
209 [ + + ]: 217 : if (mac_size > 0) {
210 [ + + ]: 208 : buffer.readData(&mac[0], mac_size);
211 : : }
212 : :
213 [ + - ]: 216 : const uint16_t original_id = buffer.readUint16();
214 [ + - ]: 216 : const uint16_t error = buffer.readUint16();
215 : :
216 [ + - ]: 216 : const uint16_t other_len = buffer.readUint16();
217 [ + - ]: 216 : vector<uint8_t> other_data(other_len);
218 [ + + ]: 216 : if (other_len > 0) {
219 [ + + ]: 2 : buffer.readData(&other_data[0], other_len);
220 : : }
221 : :
222 : : impl_ = new TSIGImpl(algorithm, time_signed, fudge, mac, original_id,
223 [ + - ][ + - ]: 215 : error, other_data);
224 : 215 : }
225 : :
226 : 251 : TSIG::TSIG(const Name& algorithm, uint64_t time_signed, uint16_t fudge,
227 : : uint16_t mac_size, const void* mac, uint16_t original_id,
228 : : uint16_t error, uint16_t other_len, const void* other_data) :
229 : 502 : impl_(NULL)
230 : : {
231 : : // Time Signed is a 48-bit value.
232 [ + + ]: 251 : if ((time_signed >> 48) != 0) {
233 [ + - ][ + - ]: 3 : isc_throw(OutOfRange, "TSIG Time Signed is too large: " <<
234 : : time_signed);
235 : : }
236 [ + + ][ + + ]: 250 : if ((mac_size == 0 && mac != NULL) || (mac_size > 0 && mac == NULL)) {
237 [ + - ][ + - ]: 4 : isc_throw(InvalidParameter, "TSIG MAC size and data inconsistent");
238 : : }
239 [ + + ][ + + ]: 248 : if ((other_len == 0 && other_data != NULL) ||
240 : : (other_len > 0 && other_data == NULL)) {
241 [ + - ][ + - ]: 4 : isc_throw(InvalidParameter,
242 : : "TSIG Other data length and data inconsistent");
243 : : }
244 : : impl_ = new TSIGImpl(algorithm, time_signed, fudge, mac_size, mac,
245 [ + - ]: 246 : original_id, error, other_len, other_data);
246 : 246 : }
247 : :
248 : : /// \brief The copy constructor.
249 : : ///
250 : : /// It internally allocates a resource, and if it fails a corresponding
251 : : /// standard exception will be thrown.
252 : : /// This constructor never throws an exception otherwise.
253 [ + - ][ + - ]: 730 : TSIG::TSIG(const TSIG& source) : Rdata(), impl_(new TSIGImpl(*source.impl_))
254 : 730 : {}
255 : :
256 : : TSIG&
257 : 3 : TSIG::operator=(const TSIG& source) {
258 [ + + ]: 3 : if (impl_ == source.impl_) {
259 : : return (*this);
260 : : }
261 : :
262 [ + - ]: 2 : TSIGImpl* newimpl = new TSIGImpl(*source.impl_);
263 [ + - ]: 4 : delete impl_;
264 : 2 : impl_ = newimpl;
265 : :
266 : 3 : return (*this);
267 : : }
268 : :
269 : 1533 : TSIG::~TSIG() {
270 [ + - ]: 2502 : delete impl_;
271 : 1533 : }
272 : :
273 : : /// \brief Convert the \c TSIG to a string.
274 : : ///
275 : : /// The output of this method is formatted as described in the "from string"
276 : : /// constructor (\c TSIG(const std::string&))).
277 : : ///
278 : : /// If internal resource allocation fails, a corresponding
279 : : /// standard exception will be thrown.
280 : : ///
281 : : /// \return A \c string object that represents the \c TSIG object.
282 : : std::string
283 : 15 : TSIG::toText() const {
284 : 0 : string result;
285 : :
286 : 15 : result += impl_->algorithm_.toText() + " " +
287 : 30 : lexical_cast<string>(impl_->time_signed_) + " " +
288 : 30 : lexical_cast<string>(impl_->fudge_) + " " +
289 [ + - ][ + - ]: 45 : lexical_cast<string>(impl_->mac_.size()) + " ";
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
290 [ + + ]: 15 : if (impl_->mac_.size() > 0) {
291 [ + - ][ + - ]: 28 : result += encodeBase64(impl_->mac_) + " ";
292 : : }
293 [ + - ][ + - ]: 30 : result += lexical_cast<string>(impl_->original_id_) + " ";
294 [ + - ][ + - ]: 30 : result += TSIGError(impl_->error_).toText() + " ";
295 [ + - ]: 30 : result += lexical_cast<string>(impl_->other_data_.size());
296 [ + + ]: 15 : if (impl_->other_data_.size() > 0) {
297 [ + - ]: 2 : result += " " + encodeBase64(impl_->other_data_);
298 : : }
299 : :
300 : 15 : return (result);
301 : : }
302 : :
303 : : // Common sequence of toWire() operations used for the two versions of
304 : : // toWire().
305 : : template <typename Output>
306 : : void
307 : 185 : TSIG::TSIGImpl::toWireCommon(Output& output) const {
308 : 23 : output.writeUint16(time_signed_ >> 32);
309 : 23 : output.writeUint32(time_signed_ & 0xffffffff);
310 : 23 : output.writeUint16(fudge_);
311 : 185 : const uint16_t mac_size = mac_.size();
312 : 23 : output.writeUint16(mac_size);
313 [ + + + + ]: 185 : if (mac_size > 0) {
314 : 22 : output.writeData(&mac_[0], mac_size);
315 : : }
316 : 23 : output.writeUint16(original_id_);
317 : 23 : output.writeUint16(error_);
318 : 185 : const uint16_t other_len = other_data_.size();
319 : 23 : output.writeUint16(other_len);
320 [ + + + + ]: 185 : if (other_len > 0) {
321 : 1 : output.writeData(&other_data_[0], other_len);
322 : : }
323 : 185 : }
324 : :
325 : : /// \brief Render the \c TSIG in the wire format without name compression.
326 : : ///
327 : : /// If internal resource allocation fails, a corresponding
328 : : /// standard exception will be thrown.
329 : : /// This method never throws an exception otherwise.
330 : : ///
331 : : /// \param buffer An output buffer to store the wire data.
332 : : void
333 : 23 : TSIG::toWire(OutputBuffer& buffer) const {
334 : 23 : impl_->algorithm_.toWire(buffer);
335 : 23 : impl_->toWireCommon<OutputBuffer>(buffer);
336 : 23 : }
337 : :
338 : : /// \brief Render the \c TSIG in the wire format with taking into account
339 : : /// compression.
340 : : ///
341 : : /// As specified in RFC3597, the Algorithm field (a domain name) will not
342 : : /// be compressed. However, the domain name could be a target of compression
343 : : /// of other compressible names (though pretty unlikely), the offset
344 : : /// information of the algorithm name may be recorded in \c renderer.
345 : : ///
346 : : /// If internal resource allocation fails, a corresponding
347 : : /// standard exception will be thrown.
348 : : /// This method never throws an exception otherwise.
349 : : ///
350 : : /// \param renderer DNS message rendering context that encapsulates the
351 : : /// output buffer and name compression information.
352 : : void
353 : 162 : TSIG::toWire(AbstractMessageRenderer& renderer) const {
354 : 162 : renderer.writeName(impl_->algorithm_, false);
355 : 162 : impl_->toWireCommon<AbstractMessageRenderer>(renderer);
356 : 162 : }
357 : :
358 : : // A helper function commonly used for TSIG::compare().
359 : : int
360 : 36 : vectorComp(const vector<uint8_t>& v1, const vector<uint8_t>& v2) {
361 : 36 : const size_t this_size = v1.size();
362 : 36 : const size_t other_size = v2.size();
363 [ + + ]: 36 : if (this_size != other_size) {
364 [ + + ]: 4 : return (this_size < other_size ? -1 : 1);
365 : : }
366 [ + + ]: 32 : if (this_size > 0) {
367 : 36 : return (memcmp(&v1[0], &v2[0], this_size));
368 : : }
369 : : return (0);
370 : : }
371 : :
372 : : /// \brief Compare two instances of \c TSIG RDATA.
373 : : ///
374 : : /// This method compares \c this and the \c other \c TSIG objects
375 : : /// in terms of the DNSSEC sorting order as defined in RFC4034, and returns
376 : : /// the result as an integer.
377 : : ///
378 : : /// This method is expected to be used in a polymorphic way, and the
379 : : /// parameter to compare against is therefore of the abstract \c Rdata class.
380 : : /// However, comparing two \c Rdata objects of different RR types
381 : : /// is meaningless, and \c other must point to a \c TSIG object;
382 : : /// otherwise, the standard \c bad_cast exception will be thrown.
383 : : /// This method never throws an exception otherwise.
384 : : ///
385 : : /// \param other the right-hand operand to compare against.
386 : : /// \return < 0 if \c this would be sorted before \c other.
387 : : /// \return 0 if \c this is identical to \c other in terms of sorting order.
388 : : /// \return > 0 if \c this would be sorted after \c other.
389 : : int
390 : 29 : TSIG::compare(const Rdata& other) const {
391 [ + + ]: 29 : const TSIG& other_tsig = dynamic_cast<const TSIG&>(other);
392 : :
393 : : const int ncmp = compareNames(impl_->algorithm_,
394 : 28 : other_tsig.impl_->algorithm_);
395 [ + + ]: 28 : if (ncmp != 0) {
396 : : return (ncmp);
397 : : }
398 : :
399 [ + + ]: 26 : if (impl_->time_signed_ != other_tsig.impl_->time_signed_) {
400 [ + + ]: 2 : return (impl_->time_signed_ < other_tsig.impl_->time_signed_ ? -1 : 1);
401 : : }
402 [ + + ]: 24 : if (impl_->fudge_ != other_tsig.impl_->fudge_) {
403 [ + + ]: 2 : return (impl_->fudge_ < other_tsig.impl_->fudge_ ? -1 : 1);
404 : : }
405 : 22 : const int vcmp = vectorComp(impl_->mac_, other_tsig.impl_->mac_);
406 [ + + ]: 22 : if (vcmp != 0) {
407 : : return (vcmp);
408 : : }
409 [ + + ]: 18 : if (impl_->original_id_ != other_tsig.impl_->original_id_) {
410 [ + + ]: 2 : return (impl_->original_id_ < other_tsig.impl_->original_id_ ? -1 : 1);
411 : : }
412 [ + + ]: 16 : if (impl_->error_ != other_tsig.impl_->error_) {
413 [ + + ]: 2 : return (impl_->error_ < other_tsig.impl_->error_ ? -1 : 1);
414 : : }
415 : 28 : return (vectorComp(impl_->other_data_, other_tsig.impl_->other_data_));
416 : : }
417 : :
418 : : const Name&
419 : 580 : TSIG::getAlgorithm() const {
420 : 580 : return (impl_->algorithm_);
421 : : }
422 : :
423 : : uint64_t
424 : 238 : TSIG::getTimeSigned() const {
425 : 238 : return (impl_->time_signed_);
426 : : }
427 : :
428 : : uint16_t
429 : 81 : TSIG::getFudge() const {
430 : 81 : return (impl_->fudge_);
431 : : }
432 : :
433 : : uint16_t
434 : 668 : TSIG::getMACSize() const {
435 : 668 : return (impl_->mac_.size());
436 : : }
437 : :
438 : : const void*
439 : 136 : TSIG::getMAC() const {
440 [ + + ]: 136 : if (impl_->mac_.size() > 0) {
441 : 136 : return (&impl_->mac_[0]);
442 : : } else {
443 : : return (NULL);
444 : : }
445 : : }
446 : :
447 : : uint16_t
448 : 80 : TSIG::getOriginalID() const {
449 : 80 : return (impl_->original_id_);
450 : : }
451 : :
452 : : uint16_t
453 : 90 : TSIG::getError() const {
454 : 90 : return (impl_->error_);
455 : : }
456 : :
457 : : uint16_t
458 : 549 : TSIG::getOtherLen() const {
459 : 549 : return (impl_->other_data_.size());
460 : : }
461 : :
462 : : const void*
463 : 82 : TSIG::getOtherData() const {
464 [ + + ]: 82 : if (impl_->other_data_.size() > 0) {
465 : 82 : return (&impl_->other_data_[0]);
466 : : } else {
467 : : return (NULL);
468 : : }
469 : : }
470 : :
471 : : } // end of namespace "any"
472 : : } // end of namespace "rdata"
473 : : } // end of namespace "dns"
474 : : } // end of namespace "isc"
475 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
476 : : //
477 : : // Permission to use, copy, modify, and/or distribute this software for any
478 : : // purpose with or without fee is hereby granted, provided that the above
479 : : // copyright notice and this permission notice appear in all copies.
480 : : //
481 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
482 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
483 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
484 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
485 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
486 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
487 : : // PERFORMANCE OF THIS SOFTWARE.
488 : :
489 : : #include <string>
490 : :
491 : : #include <exceptions/exceptions.h>
492 : :
493 : : #include <util/buffer.h>
494 : : #include <dns/messagerenderer.h>
495 : : #include <dns/rdata.h>
496 : : #include <dns/rdataclass.h>
497 : :
498 : : using namespace std;
499 : : using namespace isc::util;
500 : :
501 : : namespace isc {
502 : : namespace dns {
503 : : namespace rdata {
504 : : namespace ch {
505 : :
506 : 0 : A::A(const string&) {
507 : : // TBD
508 : 0 : }
509 : :
510 : 0 : A::A(InputBuffer&, size_t) {
511 : : // TBD
512 : 0 : }
513 : :
514 : 0 : A::A(const A&) : Rdata() {
515 : : // TBD
516 : 0 : }
517 : :
518 : : void
519 : 0 : A::toWire(OutputBuffer&) const {
520 : : // TBD
521 : 0 : }
522 : :
523 : : void
524 : 0 : A::toWire(AbstractMessageRenderer&) const {
525 : : // TBD
526 : 0 : }
527 : :
528 : : string
529 : 0 : A::toText() const {
530 : : // TBD
531 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "Not implemented yet");
532 : : }
533 : :
534 : : int
535 : 0 : A::compare(const Rdata&) const {
536 : 0 : return (0); // dummy. TBD
537 : : }
538 : :
539 : : } // end of namespace "ch"
540 : : } // end of namespace "rdata"
541 : : } // end of namespace "dns"
542 : : } // end of namespace "isc"
543 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
544 : : //
545 : : // Permission to use, copy, modify, and/or distribute this software for any
546 : : // purpose with or without fee is hereby granted, provided that the above
547 : : // copyright notice and this permission notice appear in all copies.
548 : : //
549 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
550 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
551 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
552 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
553 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
554 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
555 : : // PERFORMANCE OF THIS SOFTWARE.
556 : :
557 : : #include <string>
558 : : #include <sstream>
559 : :
560 : : #include <util/buffer.h>
561 : : #include <util/strutil.h>
562 : :
563 : : #include <dns/name.h>
564 : : #include <dns/messagerenderer.h>
565 : : #include <dns/rdata.h>
566 : : #include <dns/rdataclass.h>
567 : :
568 : : #include <boost/lexical_cast.hpp>
569 : :
570 : : using namespace std;
571 : : using namespace isc::util;
572 : : using namespace isc::util::str;
573 : :
574 : : namespace isc {
575 : : namespace dns {
576 : : namespace rdata {
577 : : namespace generic {
578 : :
579 : : /// \brief Constructor from string.
580 : : ///
581 : : /// \c afsdb_str must be formatted as follows:
582 : : /// \code <subtype> <server name>
583 : : /// \endcode
584 : : /// where server name field must represent a valid domain name.
585 : : ///
586 : : /// An example of valid string is:
587 : : /// \code "1 server.example.com." \endcode
588 : : ///
589 : : /// <b>Exceptions</b>
590 : : ///
591 : : /// \exception InvalidRdataText The number of RDATA fields (must be 2) is
592 : : /// incorrect.
593 : : /// \exception std::bad_alloc Memory allocation fails.
594 : : /// \exception Other The constructor of the \c Name class will throw if the
595 : : /// names in the string is invalid.
596 : 29 : AFSDB::AFSDB(const std::string& afsdb_str) :
597 [ + - ][ + - ]: 35 : subtype_(0), server_(Name::ROOT_NAME())
598 : : {
599 [ + - + - ]: 58 : istringstream iss(afsdb_str);
600 : :
601 : : try {
602 [ + - ][ + + ]: 29 : const uint32_t subtype = tokenToNum<int32_t, 16>(getToken(iss));
603 [ + + ][ + + ]: 50 : const Name servername(getToken(iss));
604 : 24 : string server;
605 : :
606 [ + + ]: 24 : if (!iss.eof()) {
607 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "Unexpected input for AFSDB"
[ + - ][ + - ]
608 : : "RDATA: " << afsdb_str);
609 : : }
610 : :
611 : 23 : subtype_ = subtype;
612 [ + - ]: 23 : server_ = servername;
613 : :
614 [ + + ]: 10 : } catch (const StringTokenError& ste) {
615 [ - + ][ - + ]: 8 : isc_throw(InvalidRdataText, "Invalid AFSDB text: " <<
[ - + ][ - + ]
[ - + ][ - + ]
616 : : ste.what() << ": " << afsdb_str);
617 : : }
618 : 23 : }
619 : :
620 : : /// \brief Constructor from wire-format data.
621 : : ///
622 : : /// This constructor doesn't check the validity of the second parameter (rdata
623 : : /// length) for parsing.
624 : : /// If necessary, the caller will check consistency.
625 : : ///
626 : : /// \exception std::bad_alloc Memory allocation fails.
627 : : /// \exception Other The constructor of the \c Name class will throw if the
628 : : /// names in the wire is invalid.
629 : 5 : AFSDB::AFSDB(InputBuffer& buffer, size_t) :
630 [ + - ][ + + ]: 5 : subtype_(buffer.readUint16()), server_(buffer)
631 : 4 : {}
632 : :
633 : : /// \brief Copy constructor.
634 : : ///
635 : : /// \exception std::bad_alloc Memory allocation fails in copying internal
636 : : /// member variables (this should be very rare).
637 : 1 : AFSDB::AFSDB(const AFSDB& other) :
638 [ + - ]: 1 : Rdata(), subtype_(other.subtype_), server_(other.server_)
639 : 1 : {}
640 : :
641 : : AFSDB&
642 : 3 : AFSDB::operator=(const AFSDB& source) {
643 : 3 : subtype_ = source.subtype_;
644 : 3 : server_ = source.server_;
645 : :
646 : 3 : return (*this);
647 : : }
648 : :
649 : : /// \brief Convert the \c AFSDB to a string.
650 : : ///
651 : : /// The output of this method is formatted as described in the "from string"
652 : : /// constructor (\c AFSDB(const std::string&))).
653 : : ///
654 : : /// \exception std::bad_alloc Internal resource allocation fails.
655 : : ///
656 : : /// \return A \c string object that represents the \c AFSDB object.
657 : : string
658 : 2 : AFSDB::toText() const {
659 [ + - ][ + - ]: 2 : return (boost::lexical_cast<string>(subtype_) + " " + server_.toText());
[ + - ]
660 : : }
661 : :
662 : : /// \brief Render the \c AFSDB in the wire format without name compression.
663 : : ///
664 : : /// \exception std::bad_alloc Internal resource allocation fails.
665 : : ///
666 : : /// \param buffer An output buffer to store the wire data.
667 : : void
668 : 2 : AFSDB::toWire(OutputBuffer& buffer) const {
669 : 2 : buffer.writeUint16(subtype_);
670 : 2 : server_.toWire(buffer);
671 : 2 : }
672 : :
673 : : /// \brief Render the \c AFSDB in the wire format with taking into account
674 : : /// compression.
675 : : ///
676 : : /// As specified in RFC3597, TYPE AFSDB is not "well-known", the server
677 : : /// field (domain name) will not be compressed.
678 : : ///
679 : : /// \exception std::bad_alloc Internal resource allocation fails.
680 : : ///
681 : : /// \param renderer DNS message rendering context that encapsulates the
682 : : /// output buffer and name compression information.
683 : : void
684 : 2 : AFSDB::toWire(AbstractMessageRenderer& renderer) const {
685 : 2 : renderer.writeUint16(subtype_);
686 : 2 : renderer.writeName(server_, false);
687 : 2 : }
688 : :
689 : : /// \brief Compare two instances of \c AFSDB RDATA.
690 : : ///
691 : : /// See documentation in \c Rdata.
692 : : int
693 : 14 : AFSDB::compare(const Rdata& other) const {
694 [ + + ]: 14 : const AFSDB& other_afsdb = dynamic_cast<const AFSDB&>(other);
695 [ + + ]: 13 : if (subtype_ < other_afsdb.subtype_) {
696 : : return (-1);
697 [ + + ]: 11 : } else if (subtype_ > other_afsdb.subtype_) {
698 : : return (1);
699 : : }
700 : :
701 : 13 : return (compareNames(server_, other_afsdb.server_));
702 : : }
703 : :
704 : : const Name&
705 : 2 : AFSDB::getServer() const {
706 : 2 : return (server_);
707 : : }
708 : :
709 : : uint16_t
710 : 2 : AFSDB::getSubtype() const {
711 : 2 : return (subtype_);
712 : : }
713 : :
714 : : } // end of namespace "generic"
715 : : } // end of namespace "rdata"
716 : : } // end of namespace "dns"
717 : : } // end of namespace "isc"
718 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
719 : : //
720 : : // Permission to use, copy, modify, and/or distribute this software for any
721 : : // purpose with or without fee is hereby granted, provided that the above
722 : : // copyright notice and this permission notice appear in all copies.
723 : : //
724 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
725 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
726 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
727 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
728 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
729 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
730 : : // PERFORMANCE OF THIS SOFTWARE.
731 : :
732 : : #include <config.h>
733 : :
734 : : #include <string>
735 : :
736 : : #include <util/buffer.h>
737 : : #include <dns/name.h>
738 : : #include <dns/messagerenderer.h>
739 : : #include <dns/rdata.h>
740 : : #include <dns/rdataclass.h>
741 : :
742 : : using namespace std;
743 : : using namespace isc::util;
744 : :
745 : : namespace isc {
746 : : namespace dns {
747 : : namespace rdata {
748 : : namespace generic {
749 : :
750 : 756 : CNAME::CNAME(const std::string& namestr) :
751 [ + + ]: 756 : cname_(namestr)
752 : 755 : {}
753 : :
754 : 18 : CNAME::CNAME(InputBuffer& buffer, size_t) :
755 [ + + ]: 18 : Rdata(), cname_(buffer)
756 : : {
757 : : // we don't need rdata_len for parsing. if necessary, the caller will
758 : : // check consistency.
759 : 17 : }
760 : :
761 : 56 : CNAME::CNAME(const CNAME& other) :
762 [ + - ]: 56 : Rdata(), cname_(other.cname_)
763 : 56 : {}
764 : :
765 : 5 : CNAME::CNAME(const Name& cname) :
766 [ + - ]: 5 : cname_(cname)
767 : 5 : {}
768 : :
769 : : void
770 : 1 : CNAME::toWire(OutputBuffer& buffer) const {
771 : 1 : cname_.toWire(buffer);
772 : 1 : }
773 : :
774 : : void
775 : 3 : CNAME::toWire(AbstractMessageRenderer& renderer) const {
776 : 3 : renderer.writeName(cname_);
777 : 3 : }
778 : :
779 : : string
780 : 164 : CNAME::toText() const {
781 : 164 : return (cname_.toText());
782 : : }
783 : :
784 : : int
785 : 40 : CNAME::compare(const Rdata& other) const {
786 [ + - ]: 40 : const CNAME& other_cname = dynamic_cast<const CNAME&>(other);
787 : :
788 : 40 : return (compareNames(cname_, other_cname.cname_));
789 : : }
790 : :
791 : : const Name&
792 : 28 : CNAME::getCname() const {
793 : 28 : return (cname_);
794 : : }
795 : :
796 : : } // end of namespace "generic"
797 : : } // end of namespace "rdata"
798 : : } // end of namespace "dns"
799 : : } // end of namespace "isc"
800 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
801 : : //
802 : : // Permission to use, copy, modify, and/or distribute this software for any
803 : : // purpose with or without fee is hereby granted, provided that the above
804 : : // copyright notice and this permission notice appear in all copies.
805 : : //
806 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
807 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
808 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
809 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
810 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
811 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
812 : : // PERFORMANCE OF THIS SOFTWARE.
813 : :
814 : : #include <string>
815 : :
816 : : #include <util/buffer.h>
817 : : #include <util/encode/hex.h>
818 : :
819 : : #include <dns/messagerenderer.h>
820 : : #include <dns/rdata.h>
821 : : #include <dns/rdataclass.h>
822 : :
823 : : #include <dns/rdata/generic/detail/ds_like.h>
824 : :
825 : : using namespace std;
826 : : using namespace isc::util;
827 : : using namespace isc::util::encode;
828 : : using namespace isc::dns::rdata::generic::detail;
829 : :
830 : : namespace isc {
831 : : namespace dns {
832 : : namespace rdata {
833 : : namespace generic {
834 : :
835 : : /// \brief Constructor from string.
836 : : ///
837 : : /// A copy of the implementation object is allocated and constructed.
838 : 33 : DLV::DLV(const string& ds_str) :
839 [ + - ][ + + ]: 33 : impl_(new DLVImpl(ds_str))
840 : 27 : {}
841 : :
842 : : /// \brief Constructor from wire-format data.
843 : : ///
844 : : /// A copy of the implementation object is allocated and constructed.
845 : 1 : DLV::DLV(InputBuffer& buffer, size_t rdata_len) :
846 [ + - ][ + - ]: 1 : impl_(new DLVImpl(buffer, rdata_len))
847 : 1 : {}
848 : :
849 : : /// \brief Copy constructor
850 : : ///
851 : : /// A copy of the implementation object is allocated and constructed.
852 : 1 : DLV::DLV(const DLV& source) :
853 [ + - ][ + - ]: 1 : Rdata(), impl_(new DLVImpl(*source.impl_))
854 : 1 : {}
855 : :
856 : : /// \brief Assignment operator
857 : : ///
858 : : /// PIMPL-induced logic
859 : : DLV&
860 : 3 : DLV::operator=(const DLV& source) {
861 [ + + ]: 3 : if (impl_ == source.impl_) {
862 : : return (*this);
863 : : }
864 : :
865 [ + - ]: 2 : DLVImpl* newimpl = new DLVImpl(*source.impl_);
866 [ + - ]: 4 : delete impl_;
867 : 2 : impl_ = newimpl;
868 : :
869 : 3 : return (*this);
870 : : }
871 : :
872 : : /// \brief Destructor
873 : : ///
874 : : /// Deallocates an internal resource.
875 : 31 : DLV::~DLV() {
876 [ + - ]: 58 : delete impl_;
877 : 31 : }
878 : :
879 : : /// \brief Convert the \c DLV to a string.
880 : : ///
881 : : /// A pass-thru to the corresponding implementation method.
882 : : string
883 : 1 : DLV::toText() const {
884 : 1 : return (impl_->toText());
885 : : }
886 : :
887 : : /// \brief Render the \c DLV in the wire format to a OutputBuffer object
888 : : ///
889 : : /// A pass-thru to the corresponding implementation method.
890 : : void
891 : 1 : DLV::toWire(OutputBuffer& buffer) const {
892 : 1 : impl_->toWire(buffer);
893 : 1 : }
894 : :
895 : : /// \brief Render the \c DLV in the wire format to a AbstractMessageRenderer
896 : : /// object
897 : : ///
898 : : /// A pass-thru to the corresponding implementation method.
899 : : void
900 : 1 : DLV::toWire(AbstractMessageRenderer& renderer) const {
901 : 1 : impl_->toWire(renderer);
902 : 1 : }
903 : :
904 : : /// \brief Compare two instances of \c DLV RDATA.
905 : : ///
906 : : /// The type check is performed here. Otherwise, a pass-thru to the
907 : : /// corresponding implementation method.
908 : : int
909 : 16 : DLV::compare(const Rdata& other) const {
910 [ + + ]: 16 : const DLV& other_ds = dynamic_cast<const DLV&>(other);
911 : :
912 : 15 : return (impl_->compare(*other_ds.impl_));
913 : : }
914 : :
915 : : /// \brief Tag accessor
916 : : uint16_t
917 : 1 : DLV::getTag() const {
918 : 1 : return (impl_->getTag());
919 : : }
920 : :
921 : : } // end of namespace "generic"
922 : : } // end of namespace "rdata"
923 : : } // end of namespace "dns"
924 : : } // end of namespace "isc"
925 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
926 : : //
927 : : // Permission to use, copy, modify, and/or distribute this software for any
928 : : // purpose with or without fee is hereby granted, provided that the above
929 : : // copyright notice and this permission notice appear in all copies.
930 : : //
931 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
932 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
933 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
934 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
935 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
936 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
937 : : // PERFORMANCE OF THIS SOFTWARE.
938 : :
939 : : #include <config.h>
940 : :
941 : : #include <string>
942 : :
943 : : #include <util/buffer.h>
944 : : #include <dns/name.h>
945 : : #include <dns/messagerenderer.h>
946 : : #include <dns/rdata.h>
947 : : #include <dns/rdataclass.h>
948 : :
949 : : using namespace std;
950 : : using namespace isc::util;
951 : :
952 : : namespace isc {
953 : : namespace dns {
954 : : namespace rdata {
955 : : namespace generic {
956 : :
957 : 495 : DNAME::DNAME(const std::string& namestr) :
958 [ + - ]: 495 : dname_(namestr)
959 : 495 : {}
960 : :
961 : 11 : DNAME::DNAME(InputBuffer& buffer, size_t) :
962 [ + + ]: 11 : dname_(buffer)
963 : : {
964 : : // we don't need rdata_len for parsing. if necessary, the caller will
965 : : // check consistency.
966 : 10 : }
967 : :
968 : 15 : DNAME::DNAME(const DNAME& other) :
969 [ + - ]: 15 : Rdata(), dname_(other.dname_)
970 : 15 : {}
971 : :
972 : 0 : DNAME::DNAME(const Name& dname) :
973 [ # # ]: 0 : dname_(dname)
974 : 0 : {}
975 : :
976 : : void
977 : 1 : DNAME::toWire(OutputBuffer& buffer) const {
978 : 1 : dname_.toWire(buffer);
979 : 1 : }
980 : :
981 : : void
982 : 2 : DNAME::toWire(AbstractMessageRenderer& renderer) const {
983 : 2 : renderer.writeName(dname_);
984 : 2 : }
985 : :
986 : : string
987 : 98 : DNAME::toText() const {
988 : 98 : return (dname_.toText());
989 : : }
990 : :
991 : : int
992 : 29 : DNAME::compare(const Rdata& other) const {
993 [ + - ]: 29 : const DNAME& other_dname = dynamic_cast<const DNAME&>(other);
994 : :
995 : 29 : return (compareNames(dname_, other_dname.dname_));
996 : : }
997 : :
998 : : const Name&
999 : 10 : DNAME::getDname() const {
1000 : 10 : return (dname_);
1001 : : }
1002 : :
1003 : : } // end of namespace "generic"
1004 : : } // end of namespace "rdata"
1005 : : } // end of namespace "dns"
1006 : : } // end of namespace "isc"
1007 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
1008 : : //
1009 : : // Permission to use, copy, modify, and/or distribute this software for any
1010 : : // purpose with or without fee is hereby granted, provided that the above
1011 : : // copyright notice and this permission notice appear in all copies.
1012 : : //
1013 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
1014 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1015 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
1016 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1017 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
1018 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1019 : : // PERFORMANCE OF THIS SOFTWARE.
1020 : :
1021 : : #include <iostream>
1022 : : #include <string>
1023 : : #include <sstream>
1024 : : #include <vector>
1025 : :
1026 : : #include <boost/lexical_cast.hpp>
1027 : : #include <boost/foreach.hpp>
1028 : :
1029 : : #include <util/encode/base64.h>
1030 : : #include <util/buffer.h>
1031 : : #include <dns/messagerenderer.h>
1032 : : #include <dns/name.h>
1033 : : #include <dns/rdata.h>
1034 : : #include <dns/rdataclass.h>
1035 : :
1036 : : #include <stdio.h>
1037 : : #include <time.h>
1038 : :
1039 : : using namespace std;
1040 : : using namespace isc::util;
1041 : : using namespace isc::util::encode;
1042 : :
1043 : : namespace isc {
1044 : : namespace dns {
1045 : : namespace rdata {
1046 : : namespace generic {
1047 : :
1048 [ # # ][ + - ]: 19 : struct DNSKEYImpl {
1049 : : // straightforward representation of DNSKEY RDATA fields
1050 : : DNSKEYImpl(uint16_t flags, uint8_t protocol, uint8_t algorithm,
1051 : : const vector<uint8_t>& keydata) :
1052 : : flags_(flags), protocol_(protocol), algorithm_(algorithm),
1053 [ + - ][ + - ]: 69 : keydata_(keydata)
1054 : : {}
1055 : :
1056 : : uint16_t flags_;
1057 : : uint8_t protocol_;
1058 : : uint8_t algorithm_;
1059 : : const vector<uint8_t> keydata_;
1060 : : };
1061 : :
1062 : 105 : DNSKEY::DNSKEY(const string& dnskey_str) :
1063 : 210 : impl_(NULL)
1064 : : {
1065 [ + - + - ]: 210 : istringstream iss(dnskey_str);
1066 : : unsigned int flags, protocol, algorithm;
1067 : 210 : stringbuf keydatabuf;
1068 : :
1069 [ + - ]: 105 : iss >> flags >> protocol >> algorithm >> &keydatabuf;
1070 [ + - ][ + + ]: 105 : if (iss.bad() || iss.fail()) {
[ + + ]
1071 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "Invalid DNSKEY text");
[ + - ]
1072 : : }
1073 [ + + ]: 104 : if (flags > 0xffff) {
1074 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "DNSKEY flags out of range");
[ + - ]
1075 : : }
1076 [ + + ]: 103 : if (protocol > 0xff) {
1077 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "DNSKEY protocol out of range");
[ + - ]
1078 : : }
1079 [ + + ]: 102 : if (algorithm > 0xff) {
1080 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "DNSKEY algorithm out of range");
[ + - ]
1081 : : }
1082 : :
1083 : : vector<uint8_t> keydata;
1084 [ + - ][ + + ]: 101 : decodeBase64(keydatabuf.str(), keydata);
1085 : :
1086 [ - + ][ # # ]: 68 : if (algorithm == 1 && keydata.size() < 3) {
[ - + ]
1087 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataLength, "DNSKEY keydata too short");
[ # # ]
1088 : : }
1089 : :
1090 [ + - ]: 68 : impl_ = new DNSKEYImpl(flags, protocol, algorithm, keydata);
1091 : 68 : }
1092 : :
1093 : 2 : DNSKEY::DNSKEY(InputBuffer& buffer, size_t rdata_len) {
1094 [ - + ]: 1 : if (rdata_len < 4) {
1095 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataLength, "DNSKEY too short: " << rdata_len);
[ # # ]
1096 : : }
1097 : :
1098 [ + - ]: 1 : uint16_t flags = buffer.readUint16();
1099 [ + - ]: 1 : uint16_t protocol = buffer.readUint8();
1100 [ + - ]: 1 : uint16_t algorithm = buffer.readUint8();
1101 : :
1102 : 1 : rdata_len -= 4;
1103 [ + - ]: 1 : vector<uint8_t> keydata(rdata_len);
1104 [ + - ]: 1 : buffer.readData(&keydata[0], rdata_len);
1105 : :
1106 [ + - ]: 1 : impl_ = new DNSKEYImpl(flags, protocol, algorithm, keydata);
1107 : 1 : }
1108 : :
1109 : 19 : DNSKEY::DNSKEY(const DNSKEY& source) :
1110 [ + - ]: 19 : Rdata(), impl_(new DNSKEYImpl(*source.impl_))
1111 : 19 : {}
1112 : :
1113 : : DNSKEY&
1114 : 0 : DNSKEY::operator=(const DNSKEY& source) {
1115 [ # # ]: 0 : if (impl_ == source.impl_) {
1116 : : return (*this);
1117 : : }
1118 : :
1119 : 0 : DNSKEYImpl* newimpl = new DNSKEYImpl(*source.impl_);
1120 [ # # ]: 0 : delete impl_;
1121 : 0 : impl_ = newimpl;
1122 : :
1123 : 0 : return (*this);
1124 : : }
1125 : :
1126 : 167 : DNSKEY::~DNSKEY() {
1127 [ + - ]: 176 : delete impl_;
1128 : 167 : }
1129 : :
1130 : : string
1131 : 11 : DNSKEY::toText() const {
1132 : 11 : return (boost::lexical_cast<string>(static_cast<int>(impl_->flags_)) +
1133 : 22 : " " + boost::lexical_cast<string>(static_cast<int>(impl_->protocol_)) +
1134 : 22 : " " + boost::lexical_cast<string>(static_cast<int>(impl_->algorithm_)) +
1135 [ + - ][ + - ]: 22 : " " + encodeBase64(impl_->keydata_));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
1136 : : }
1137 : :
1138 : : void
1139 : 1 : DNSKEY::toWire(OutputBuffer& buffer) const {
1140 : 1 : buffer.writeUint16(impl_->flags_);
1141 : 1 : buffer.writeUint8(impl_->protocol_);
1142 : 1 : buffer.writeUint8(impl_->algorithm_);
1143 : 1 : buffer.writeData(&impl_->keydata_[0], impl_->keydata_.size());
1144 : 1 : }
1145 : :
1146 : : void
1147 : 1 : DNSKEY::toWire(AbstractMessageRenderer& renderer) const {
1148 : 1 : renderer.writeUint16(impl_->flags_);
1149 : 1 : renderer.writeUint8(impl_->protocol_);
1150 : 1 : renderer.writeUint8(impl_->algorithm_);
1151 : 2 : renderer.writeData(&impl_->keydata_[0], impl_->keydata_.size());
1152 : 1 : }
1153 : :
1154 : : int
1155 : 8 : DNSKEY::compare(const Rdata& other) const {
1156 [ + - ]: 8 : const DNSKEY& other_dnskey = dynamic_cast<const DNSKEY&>(other);
1157 : :
1158 [ - + ]: 8 : if (impl_->flags_ != other_dnskey.impl_->flags_) {
1159 [ # # ]: 0 : return (impl_->flags_ < other_dnskey.impl_->flags_ ? -1 : 1);
1160 : : }
1161 [ - + ]: 8 : if (impl_->protocol_ != other_dnskey.impl_->protocol_) {
1162 [ # # ]: 0 : return (impl_->protocol_ < other_dnskey.impl_->protocol_ ? -1 : 1);
1163 : : }
1164 [ - + ]: 8 : if (impl_->algorithm_ != other_dnskey.impl_->algorithm_) {
1165 [ # # ]: 0 : return (impl_->algorithm_ < other_dnskey.impl_->algorithm_ ? -1 : 1);
1166 : : }
1167 : :
1168 : 16 : size_t this_len = impl_->keydata_.size();
1169 : 16 : size_t other_len = other_dnskey.impl_->keydata_.size();
1170 : 8 : size_t cmplen = min(this_len, other_len);
1171 : 16 : int cmp = memcmp(&impl_->keydata_[0], &other_dnskey.impl_->keydata_[0],
1172 : 8 : cmplen);
1173 [ + - ]: 8 : if (cmp != 0) {
1174 : : return (cmp);
1175 : : } else {
1176 [ - + ][ # # ]: 8 : return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1);
1177 : : }
1178 : : }
1179 : :
1180 : : uint16_t
1181 : 1 : DNSKEY::getTag() const {
1182 [ - + ]: 1 : if (impl_->algorithm_ == 1) {
1183 : 0 : int len = impl_->keydata_.size();
1184 : 0 : return ((impl_->keydata_[len - 3] << 8) + impl_->keydata_[len - 2]);
1185 : : }
1186 : :
1187 : 1 : uint32_t ac = impl_->flags_;
1188 : 1 : ac += (impl_->protocol_ << 8);
1189 : 1 : ac += impl_->algorithm_;
1190 : :
1191 : 2 : size_t size = impl_->keydata_.size();
1192 [ + + ]: 262 : for (size_t i = 0; i < size; i ++) {
1193 [ + + ]: 261 : ac += (i & 1) ? impl_->keydata_[i] : (impl_->keydata_[i] << 8);
1194 : : }
1195 : 1 : ac += (ac >> 16) & 0xffff;
1196 : 1 : return (ac & 0xffff);
1197 : : }
1198 : :
1199 : : uint16_t
1200 : 1 : DNSKEY::getFlags() const {
1201 : 1 : return (impl_->flags_);
1202 : : }
1203 : :
1204 : : uint8_t
1205 : 1 : DNSKEY::getAlgorithm() const {
1206 : 1 : return (impl_->algorithm_);
1207 : : }
1208 : :
1209 : : } // end of namespace "generic"
1210 : : } // end of namespace "rdata"
1211 : : } // end of namespace "dns"
1212 : : } // end of namespace "isc"
1213 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
1214 : : //
1215 : : // Permission to use, copy, modify, and/or distribute this software for any
1216 : : // purpose with or without fee is hereby granted, provided that the above
1217 : : // copyright notice and this permission notice appear in all copies.
1218 : : //
1219 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
1220 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1221 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
1222 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1223 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
1224 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1225 : : // PERFORMANCE OF THIS SOFTWARE.
1226 : :
1227 : : #include <string>
1228 : :
1229 : : #include <util/buffer.h>
1230 : : #include <util/encode/hex.h>
1231 : :
1232 : : #include <dns/messagerenderer.h>
1233 : : #include <dns/rdata.h>
1234 : : #include <dns/rdataclass.h>
1235 : :
1236 : : #include <dns/rdata/generic/detail/ds_like.h>
1237 : :
1238 : : using namespace std;
1239 : : using namespace isc::util;
1240 : : using namespace isc::util::encode;
1241 : : using namespace isc::dns::rdata::generic::detail;
1242 : :
1243 : : namespace isc {
1244 : : namespace dns {
1245 : : namespace rdata {
1246 : : namespace generic {
1247 : :
1248 : 341 : DS::DS(const string& ds_str) :
1249 [ + - ][ + + ]: 341 : impl_(new DSImpl(ds_str))
1250 : 335 : {}
1251 : :
1252 : 1 : DS::DS(InputBuffer& buffer, size_t rdata_len) :
1253 [ + - ][ + - ]: 1 : impl_(new DSImpl(buffer, rdata_len))
1254 : 1 : {}
1255 : :
1256 : 25 : DS::DS(const DS& source) :
1257 [ + - ][ + - ]: 25 : Rdata(), impl_(new DSImpl(*source.impl_))
1258 : 25 : {}
1259 : :
1260 : : DS&
1261 : 3 : DS::operator=(const DS& source) {
1262 [ + + ]: 3 : if (impl_ == source.impl_) {
1263 : : return (*this);
1264 : : }
1265 : :
1266 [ + - ]: 2 : DSImpl* newimpl = new DSImpl(*source.impl_);
1267 [ + - ]: 4 : delete impl_;
1268 : 2 : impl_ = newimpl;
1269 : :
1270 : 3 : return (*this);
1271 : : }
1272 : :
1273 : 695 : DS::~DS() {
1274 [ + - ]: 722 : delete impl_;
1275 : 695 : }
1276 : :
1277 : : string
1278 : 35 : DS::toText() const {
1279 : 35 : return (impl_->toText());
1280 : : }
1281 : :
1282 : : void
1283 : 1 : DS::toWire(OutputBuffer& buffer) const {
1284 : 1 : impl_->toWire(buffer);
1285 : 1 : }
1286 : :
1287 : : void
1288 : 1 : DS::toWire(AbstractMessageRenderer& renderer) const {
1289 : 1 : impl_->toWire(renderer);
1290 : 1 : }
1291 : :
1292 : : int
1293 : 21 : DS::compare(const Rdata& other) const {
1294 [ + + ]: 21 : const DS& other_ds = dynamic_cast<const DS&>(other);
1295 : :
1296 : 20 : return (impl_->compare(*other_ds.impl_));
1297 : : }
1298 : :
1299 : : uint16_t
1300 : 1 : DS::getTag() const {
1301 : 1 : return (impl_->getTag());
1302 : : }
1303 : :
1304 : : } // end of namespace "generic"
1305 : : } // end of namespace "rdata"
1306 : : } // end of namespace "dns"
1307 : : } // end of namespace "isc"
1308 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
1309 : : //
1310 : : // Permission to use, copy, modify, and/or distribute this software for any
1311 : : // purpose with or without fee is hereby granted, provided that the above
1312 : : // copyright notice and this permission notice appear in all copies.
1313 : : //
1314 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
1315 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1316 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
1317 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1318 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
1319 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1320 : : // PERFORMANCE OF THIS SOFTWARE.
1321 : :
1322 : : #include <config.h>
1323 : :
1324 : : #include <string>
1325 : :
1326 : : #include <boost/lexical_cast.hpp>
1327 : :
1328 : : #include <exceptions/exceptions.h>
1329 : :
1330 : : #include <dns/name.h>
1331 : : #include <dns/messagerenderer.h>
1332 : : #include <dns/rdata.h>
1333 : : #include <dns/rdataclass.h>
1334 : : #include <dns/character_string.h>
1335 : : #include <util/strutil.h>
1336 : :
1337 : : using namespace std;
1338 : : using namespace boost;
1339 : : using namespace isc::util;
1340 : : using namespace isc::dns;
1341 : : using namespace isc::dns::characterstr;
1342 : :
1343 : : namespace isc {
1344 : : namespace dns {
1345 : : namespace rdata {
1346 : : namespace generic {
1347 : :
1348 : :
1349 : 3 : HINFO::HINFO(const string& hinfo_str) {
1350 : 46 : string::const_iterator input_iterator = hinfo_str.begin();
1351 [ + + ]: 91 : cpu_ = getNextCharacterString(hinfo_str, input_iterator);
1352 : :
1353 [ + + ]: 45 : skipLeftSpaces(hinfo_str, input_iterator);
1354 : :
1355 [ + - ]: 86 : os_ = getNextCharacterString(hinfo_str, input_iterator);
1356 : 43 : }
1357 : :
1358 : 0 : HINFO::HINFO(InputBuffer& buffer, size_t rdata_len) {
1359 [ + - ]: 2 : cpu_ = getNextCharacterString(buffer, rdata_len);
1360 [ + - ]: 2 : os_ = getNextCharacterString(buffer, rdata_len);
1361 : 1 : }
1362 : :
1363 : 0 : HINFO::HINFO(const HINFO& source):
1364 [ # # ][ # # ]: 0 : Rdata(), cpu_(source.cpu_), os_(source.os_)
1365 : : {
1366 : 0 : }
1367 : :
1368 : : std::string
1369 : 1 : HINFO::toText() const {
1370 : 0 : string result;
1371 : : result += "\"";
1372 : 1 : result += cpu_;
1373 : : result += "\" \"";
1374 : 1 : result += os_;
1375 : : result += "\"";
1376 : 1 : return (result);
1377 : : }
1378 : :
1379 : : void
1380 : 1 : HINFO::toWire(OutputBuffer& buffer) const {
1381 : : toWireHelper(buffer);
1382 : 1 : }
1383 : :
1384 : : void
1385 : 1 : HINFO::toWire(AbstractMessageRenderer& renderer) const {
1386 : : toWireHelper(renderer);
1387 : 1 : }
1388 : :
1389 : : int
1390 : 5 : HINFO::compare(const Rdata& other) const {
1391 [ + - ]: 5 : const HINFO& other_hinfo = dynamic_cast<const HINFO&>(other);
1392 : :
1393 [ + + ]: 5 : if (cpu_ < other_hinfo.cpu_) {
1394 : : return (-1);
1395 [ + + ]: 4 : } else if (cpu_ > other_hinfo.cpu_) {
1396 : : return (1);
1397 : : }
1398 : :
1399 [ + + ]: 3 : if (os_ < other_hinfo.os_) {
1400 : : return (-1);
1401 [ + + ]: 2 : } else if (os_ > other_hinfo.os_) {
1402 : : return (1);
1403 : : }
1404 : :
1405 : 5 : return (0);
1406 : : }
1407 : :
1408 : : const std::string&
1409 : 3 : HINFO::getCPU() const {
1410 : 3 : return (cpu_);
1411 : : }
1412 : :
1413 : : const std::string&
1414 : 2 : HINFO::getOS() const {
1415 : 2 : return (os_);
1416 : : }
1417 : :
1418 : : void
1419 : 45 : HINFO::skipLeftSpaces(const std::string& input_str,
1420 : : std::string::const_iterator& input_iterator)
1421 : : {
1422 [ + + ]: 45 : if (input_iterator >= input_str.end()) {
1423 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText,
1424 : : "Invalid HINFO text format, field is missing.");
1425 : : }
1426 : :
1427 [ + + ]: 44 : if (!isspace(*input_iterator)) {
1428 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText,
1429 : : "Invalid HINFO text format, fields are not separated by space.");
1430 : : }
1431 : : // Skip white spaces
1432 [ + - ][ + + ]: 86 : while (input_iterator < input_str.end() && isspace(*input_iterator)) {
[ + + ]
1433 : : ++input_iterator;
1434 : : }
1435 : 43 : }
1436 : :
1437 : : } // end of namespace "generic"
1438 : : } // end of namespace "rdata"
1439 : : } // end of namespace "dns"
1440 : : } // end of namespace "isc"
1441 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
1442 : : //
1443 : : // Permission to use, copy, modify, and/or distribute this software for any
1444 : : // purpose with or without fee is hereby granted, provided that the above
1445 : : // copyright notice and this permission notice appear in all copies.
1446 : : //
1447 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
1448 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1449 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
1450 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1451 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
1452 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1453 : : // PERFORMANCE OF THIS SOFTWARE.
1454 : :
1455 : : #include <string>
1456 : : #include <sstream>
1457 : :
1458 : : #include <util/buffer.h>
1459 : :
1460 : : #include <dns/messagerenderer.h>
1461 : : #include <dns/name.h>
1462 : : #include <dns/rdata.h>
1463 : : #include <dns/rdataclass.h>
1464 : :
1465 : : using namespace std;
1466 : : using namespace isc::dns;
1467 : : using namespace isc::util;
1468 : :
1469 : : namespace isc {
1470 : : namespace dns {
1471 : : namespace rdata {
1472 : : namespace generic {
1473 : :
1474 : : /// \brief Constructor from string.
1475 : : ///
1476 : : /// \c minfo_str must be formatted as follows:
1477 : : /// \code <rmailbox name> <emailbox name>
1478 : : /// \endcode
1479 : : /// where both fields must represent a valid domain name.
1480 : : ///
1481 : : /// An example of valid string is:
1482 : : /// \code "rmail.example.com. email.example.com." \endcode
1483 : : ///
1484 : : /// <b>Exceptions</b>
1485 : : ///
1486 : : /// \exception InvalidRdataText The number of RDATA fields (must be 2) is
1487 : : /// incorrect.
1488 : : /// \exception std::bad_alloc Memory allocation for names fails.
1489 : : /// \exception Other The constructor of the \c Name class will throw if the
1490 : : /// names in the string is invalid.
1491 : 25 : MINFO::MINFO(const std::string& minfo_str) :
1492 : : // We cannot construct both names in the initialization list due to the
1493 : : // necessary text processing, so we have to initialize them with a dummy
1494 : : // name and replace them later.
1495 [ + - ][ + - ]: 29 : rmailbox_(Name::ROOT_NAME()), emailbox_(Name::ROOT_NAME())
[ + - ][ + - ]
1496 : : {
1497 [ + - + - ]: 50 : istringstream iss(minfo_str);
1498 : 25 : string rmailbox_str, emailbox_str;
1499 [ + - ][ + - ]: 25 : iss >> rmailbox_str >> emailbox_str;
1500 : :
1501 : : // Validation: A valid MINFO RR must have exactly two fields.
1502 [ + - ][ + + ]: 25 : if (iss.bad() || iss.fail()) {
[ + + ]
1503 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "Invalid MINFO text: " << minfo_str);
[ + - ][ + - ]
1504 : : }
1505 [ + + ]: 24 : if (!iss.eof()) {
1506 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "Invalid MINFO text (redundant field): "
[ + - ][ + - ]
1507 : : << minfo_str);
1508 : : }
1509 : :
1510 [ + + ][ + - ]: 23 : rmailbox_ = Name(rmailbox_str);
1511 [ + + ][ + - ]: 22 : emailbox_ = Name(emailbox_str);
1512 : 21 : }
1513 : :
1514 : : /// \brief Constructor from wire-format data.
1515 : : ///
1516 : : /// This constructor doesn't check the validity of the second parameter (rdata
1517 : : /// length) for parsing.
1518 : : /// If necessary, the caller will check consistency.
1519 : : ///
1520 : : /// \exception std::bad_alloc Memory allocation for names fails.
1521 : : /// \exception Other The constructor of the \c Name class will throw if the
1522 : : /// names in the wire is invalid.
1523 : 6 : MINFO::MINFO(InputBuffer& buffer, size_t) :
1524 [ + + ][ + + ]: 6 : rmailbox_(buffer), emailbox_(buffer)
1525 : 4 : {}
1526 : :
1527 : : /// \brief Copy constructor.
1528 : : ///
1529 : : /// \exception std::bad_alloc Memory allocation fails in copying internal
1530 : : /// member variables (this should be very rare).
1531 : 1 : MINFO::MINFO(const MINFO& other) :
1532 [ + - ][ + - ]: 1 : Rdata(), rmailbox_(other.rmailbox_), emailbox_(other.emailbox_)
1533 : 1 : {}
1534 : :
1535 : : /// \brief Convert the \c MINFO to a string.
1536 : : ///
1537 : : /// The output of this method is formatted as described in the "from string"
1538 : : /// constructor (\c MINFO(const std::string&))).
1539 : : ///
1540 : : /// \exception std::bad_alloc Internal resource allocation fails.
1541 : : ///
1542 : : /// \return A \c string object that represents the \c MINFO object.
1543 : : std::string
1544 : 2 : MINFO::toText() const {
1545 [ + - ][ + - ]: 2 : return (rmailbox_.toText() + " " + emailbox_.toText());
[ + - ]
1546 : : }
1547 : :
1548 : : /// \brief Render the \c MINFO in the wire format without name compression.
1549 : : ///
1550 : : /// \exception std::bad_alloc Internal resource allocation fails.
1551 : : ///
1552 : : /// \param buffer An output buffer to store the wire data.
1553 : : void
1554 : 2 : MINFO::toWire(OutputBuffer& buffer) const {
1555 : 2 : rmailbox_.toWire(buffer);
1556 : 2 : emailbox_.toWire(buffer);
1557 : 2 : }
1558 : :
1559 : : MINFO&
1560 : 3 : MINFO::operator=(const MINFO& source) {
1561 : 3 : rmailbox_ = source.rmailbox_;
1562 : 3 : emailbox_ = source.emailbox_;
1563 : :
1564 : 3 : return (*this);
1565 : : }
1566 : :
1567 : : /// \brief Render the \c MINFO in the wire format with taking into account
1568 : : /// compression.
1569 : : ///
1570 : : /// As specified in RFC3597, TYPE MINFO is "well-known", the rmailbox and
1571 : : /// emailbox fields (domain names) will be compressed.
1572 : : ///
1573 : : /// \exception std::bad_alloc Internal resource allocation fails.
1574 : : ///
1575 : : /// \param renderer DNS message rendering context that encapsulates the
1576 : : /// output buffer and name compression information.
1577 : : void
1578 : 2 : MINFO::toWire(AbstractMessageRenderer& renderer) const {
1579 : 2 : renderer.writeName(rmailbox_);
1580 : 2 : renderer.writeName(emailbox_);
1581 : 2 : }
1582 : :
1583 : : /// \brief Compare two instances of \c MINFO RDATA.
1584 : : ///
1585 : : /// See documentation in \c Rdata.
1586 : : int
1587 : 12 : MINFO::compare(const Rdata& other) const {
1588 [ + + ]: 12 : const MINFO& other_minfo = dynamic_cast<const MINFO&>(other);
1589 : :
1590 : 11 : const int cmp = compareNames(rmailbox_, other_minfo.rmailbox_);
1591 [ + + ]: 11 : if (cmp != 0) {
1592 : : return (cmp);
1593 : : }
1594 : 11 : return (compareNames(emailbox_, other_minfo.emailbox_));
1595 : : }
1596 : :
1597 : : } // end of namespace "generic"
1598 : : } // end of namespace "rdata"
1599 : : } // end of namespace "dns"
1600 : : } // end of namespace "isc"
1601 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
1602 : : //
1603 : : // Permission to use, copy, modify, and/or distribute this software for any
1604 : : // purpose with or without fee is hereby granted, provided that the above
1605 : : // copyright notice and this permission notice appear in all copies.
1606 : : //
1607 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
1608 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1609 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
1610 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1611 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
1612 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1613 : : // PERFORMANCE OF THIS SOFTWARE.
1614 : :
1615 : : #include <config.h>
1616 : :
1617 : : #include <string>
1618 : :
1619 : : #include <boost/lexical_cast.hpp>
1620 : :
1621 : : #include <exceptions/exceptions.h>
1622 : :
1623 : : #include <util/buffer.h>
1624 : : #include <dns/name.h>
1625 : : #include <dns/messagerenderer.h>
1626 : : #include <dns/rdata.h>
1627 : : #include <dns/rdataclass.h>
1628 : :
1629 : : using namespace std;
1630 : : using namespace boost;
1631 : : using namespace isc::util;
1632 : :
1633 : : namespace isc {
1634 : : namespace dns {
1635 : : namespace rdata {
1636 : : namespace generic {
1637 : :
1638 : 1 : MX::MX(InputBuffer& buffer, size_t) :
1639 [ + - ][ + - ]: 1 : preference_(buffer.readUint16()), mxname_(buffer)
1640 : : {
1641 : : // we don't need rdata_len for parsing. if necessary, the caller will
1642 : : // check consistency.
1643 : 1 : }
1644 : :
1645 : 587 : MX::MX(const std::string& mx_str) :
1646 [ + - ][ + - ]: 591 : preference_(0), mxname_(".")
1647 : : {
1648 [ + - + - ]: 1174 : istringstream iss(mx_str);
1649 : : uint16_t pref;
1650 : 587 : string mxname;
1651 : :
1652 [ + - ]: 587 : iss >> pref >> mxname;
1653 : :
1654 [ + - ][ + + ]: 587 : if (iss.bad() || iss.fail() || !iss.eof()) {
[ + + ][ + + ]
1655 [ + - ][ + - ]: 8 : isc_throw(InvalidRdataText, "Invalid MX text format");
[ + - ]
1656 : : }
1657 : :
1658 : 583 : preference_ = pref;
1659 [ + - ][ + - ]: 583 : mxname_ = Name(mxname);
1660 : 583 : }
1661 : :
1662 : 5 : MX::MX(uint16_t preference, const Name& mxname) :
1663 [ + - ]: 5 : preference_(preference), mxname_(mxname)
1664 : 5 : {}
1665 : :
1666 : 12 : MX::MX(const MX& other) :
1667 [ + - ]: 12 : Rdata(), preference_(other.preference_), mxname_(other.mxname_)
1668 : 12 : {}
1669 : :
1670 : : void
1671 : 1 : MX::toWire(OutputBuffer& buffer) const {
1672 : 1 : buffer.writeUint16(preference_);
1673 : 1 : mxname_.toWire(buffer);
1674 : 1 : }
1675 : :
1676 : : void
1677 : 1 : MX::toWire(AbstractMessageRenderer& renderer) const {
1678 : 1 : renderer.writeUint16(preference_);
1679 : 1 : renderer.writeName(mxname_);
1680 : 1 : }
1681 : :
1682 : : string
1683 : 102 : MX::toText() const {
1684 [ + - ][ + - ]: 102 : return (lexical_cast<string>(preference_) + " " + mxname_.toText());
[ + - ]
1685 : : }
1686 : :
1687 : : int
1688 : 15 : MX::compare(const Rdata& other) const {
1689 [ + + ]: 15 : const MX& other_mx = dynamic_cast<const MX&>(other);
1690 : :
1691 [ + + ]: 14 : if (preference_ < other_mx.preference_) {
1692 : : return (-1);
1693 [ + + ]: 12 : } else if (preference_ > other_mx.preference_) {
1694 : : return (1);
1695 : : }
1696 : :
1697 : 14 : return (compareNames(mxname_, other_mx.mxname_));
1698 : : }
1699 : :
1700 : : const Name&
1701 : 142 : MX::getMXName() const {
1702 : 142 : return (mxname_);
1703 : : }
1704 : :
1705 : : uint16_t
1706 : 1 : MX::getMXPref() const {
1707 : 1 : return (preference_);
1708 : : }
1709 : :
1710 : : } // end of namespace "generic"
1711 : : } // end of namespace "rdata"
1712 : : } // end of namespace "dns"
1713 : : } // end of namespace "isc"
1714 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
1715 : : //
1716 : : // Permission to use, copy, modify, and/or distribute this software for any
1717 : : // purpose with or without fee is hereby granted, provided that the above
1718 : : // copyright notice and this permission notice appear in all copies.
1719 : : //
1720 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
1721 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1722 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
1723 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1724 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
1725 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1726 : : // PERFORMANCE OF THIS SOFTWARE.
1727 : :
1728 : : #include <config.h>
1729 : :
1730 : : #include <string>
1731 : :
1732 : : #include <boost/lexical_cast.hpp>
1733 : :
1734 : : #include <exceptions/exceptions.h>
1735 : :
1736 : : #include <dns/character_string.h>
1737 : : #include <dns/name.h>
1738 : : #include <dns/messagerenderer.h>
1739 : : #include <dns/rdata.h>
1740 : : #include <dns/rdataclass.h>
1741 : :
1742 : : using namespace std;
1743 : : using namespace boost;
1744 : : using namespace isc::util;
1745 : : using namespace isc::dns;
1746 : : using namespace isc::dns::characterstr;
1747 : :
1748 : : namespace isc {
1749 : : namespace dns {
1750 : : namespace rdata {
1751 : : namespace generic {
1752 : :
1753 : : namespace {
1754 : : /// Skip the left whitespaces of the input string
1755 : : ///
1756 : : /// \param input_str The input string
1757 : : /// \param input_iterator From which the skipping started
1758 : : void
1759 : 120 : skipLeftSpaces(const std::string& input_str,
1760 : : std::string::const_iterator& input_iterator)
1761 : : {
1762 [ + + ]: 120 : if (input_iterator >= input_str.end()) {
1763 [ + - ][ + - ]: 4 : isc_throw(InvalidRdataText,
1764 : : "Invalid NAPTR text format, field is missing.");
1765 : : }
1766 : :
1767 [ + + ]: 118 : if (!isspace(*input_iterator)) {
1768 [ + - ][ + - ]: 6 : isc_throw(InvalidRdataText,
1769 : : "Invalid NAPTR text format, fields are not separated by space.");
1770 : : }
1771 : : // Skip white spaces
1772 [ + - ][ + + ]: 230 : while (input_iterator < input_str.end() && isspace(*input_iterator)) {
[ + + ]
1773 : : ++input_iterator;
1774 : : }
1775 : 115 : }
1776 : :
1777 : : } // Anonymous namespace
1778 : :
1779 : 1 : NAPTR::NAPTR(InputBuffer& buffer, size_t len):
1780 [ + - ][ + - ]: 1 : replacement_(".")
1781 : : {
1782 [ + - ]: 1 : order_ = buffer.readUint16();
1783 [ + - ]: 1 : preference_ = buffer.readUint16();
1784 : :
1785 [ + - ]: 2 : flags_ = getNextCharacterString(buffer, len);
1786 [ + - ]: 2 : services_ = getNextCharacterString(buffer, len);
1787 [ + - ]: 2 : regexp_ = getNextCharacterString(buffer, len);
1788 [ + - ][ + - ]: 1 : replacement_ = Name(buffer);
1789 : 1 : }
1790 : :
1791 : 36 : NAPTR::NAPTR(const std::string& naptr_str):
1792 [ + - ][ + - ]: 45 : replacement_(".")
1793 : : {
1794 [ + - + - ]: 72 : istringstream iss(naptr_str);
1795 : : uint16_t order;
1796 : : uint16_t preference;
1797 : :
1798 : 36 : iss >> order >> preference;
1799 : :
1800 [ + - ][ + + ]: 36 : if (iss.bad() || iss.fail()) {
[ + + ]
1801 [ + - ][ + - ]: 6 : isc_throw(InvalidRdataText, "Invalid NAPTR text format");
[ + - ]
1802 : : }
1803 : :
1804 : 33 : order_ = order;
1805 : 33 : preference_ = preference;
1806 : :
1807 [ + - ]: 33 : string::const_iterator input_iterator = naptr_str.begin() + iss.tellg();
1808 : :
1809 [ + + ]: 33 : skipLeftSpaces(naptr_str, input_iterator);
1810 : :
1811 [ + + ]: 63 : flags_ = getNextCharacterString(naptr_str, input_iterator);
1812 : :
1813 [ + + ]: 31 : skipLeftSpaces(naptr_str, input_iterator);
1814 : :
1815 [ + - ]: 56 : services_ = getNextCharacterString(naptr_str, input_iterator);
1816 : :
1817 [ + - ]: 28 : skipLeftSpaces(naptr_str, input_iterator);
1818 : :
1819 [ + - ]: 56 : regexp_ = getNextCharacterString(naptr_str, input_iterator);
1820 : :
1821 [ + + ]: 28 : skipLeftSpaces(naptr_str, input_iterator);
1822 : :
1823 [ + - ]: 27 : if (input_iterator < naptr_str.end()) {
1824 : 27 : string replacementStr(input_iterator, naptr_str.end());
1825 : :
1826 [ + - ][ + - ]: 27 : replacement_ = Name(replacementStr);
1827 : : } else {
1828 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText,
[ # # ]
1829 : : "Invalid NAPTR text format, replacement field is missing");
1830 : : }
1831 : 27 : }
1832 : :
1833 : 11 : NAPTR::NAPTR(const NAPTR& naptr):
1834 : : Rdata(), order_(naptr.order_), preference_(naptr.preference_),
1835 : : flags_(naptr.flags_), services_(naptr.services_), regexp_(naptr.regexp_),
1836 [ + - ][ + - ]: 11 : replacement_(naptr.replacement_)
[ + - ][ + - ]
1837 : : {
1838 : 11 : }
1839 : :
1840 : : void
1841 : 1 : NAPTR::toWire(OutputBuffer& buffer) const {
1842 : : toWireHelper(buffer);
1843 : 1 : }
1844 : :
1845 : : void
1846 : 1 : NAPTR::toWire(AbstractMessageRenderer& renderer) const {
1847 : : toWireHelper(renderer);
1848 : 1 : }
1849 : :
1850 : : string
1851 : 1 : NAPTR::toText() const {
1852 : 0 : string result;
1853 [ + - ]: 2 : result += lexical_cast<string>(order_);
1854 : : result += " ";
1855 [ + - ]: 2 : result += lexical_cast<string>(preference_);
1856 : : result += " \"";
1857 : 1 : result += flags_;
1858 : : result += "\" \"";
1859 : 1 : result += services_;
1860 : : result += "\" \"";
1861 : 1 : result += regexp_;
1862 : : result += "\" ";
1863 [ + - ]: 2 : result += replacement_.toText();
1864 : 1 : return (result);
1865 : : }
1866 : :
1867 : : int
1868 : 11 : NAPTR::compare(const Rdata& other) const {
1869 [ + - ]: 22 : const NAPTR other_naptr = dynamic_cast<const NAPTR&>(other);
1870 : :
1871 [ + + ]: 11 : if (order_ < other_naptr.order_) {
1872 : : return (-1);
1873 [ + + ]: 10 : } else if (order_ > other_naptr.order_) {
1874 : : return (1);
1875 : : }
1876 : :
1877 [ + + ]: 9 : if (preference_ < other_naptr.preference_) {
1878 : : return (-1);
1879 [ + + ]: 8 : } else if (preference_ > other_naptr.preference_) {
1880 : : return (1);
1881 : : }
1882 : :
1883 [ + + ]: 7 : if (flags_ < other_naptr.flags_) {
1884 : : return (-1);
1885 [ + + ]: 6 : } else if (flags_ > other_naptr.flags_) {
1886 : : return (1);
1887 : : }
1888 : :
1889 [ + + ]: 5 : if (services_ < other_naptr.services_) {
1890 : : return (-1);
1891 [ + + ]: 4 : } else if (services_ > other_naptr.services_) {
1892 : : return (1);
1893 : : }
1894 : :
1895 [ + - ]: 3 : if (regexp_ < other_naptr.regexp_) {
1896 : : return (-1);
1897 [ + - ]: 3 : } else if (regexp_ > other_naptr.regexp_) {
1898 : : return (1);
1899 : : }
1900 : :
1901 [ + - ]: 3 : return (compareNames(replacement_, other_naptr.replacement_));
1902 : : }
1903 : :
1904 : : uint16_t
1905 : 2 : NAPTR::getOrder() const {
1906 : 2 : return (order_);
1907 : : }
1908 : :
1909 : : uint16_t
1910 : 2 : NAPTR::getPreference() const {
1911 : 2 : return (preference_);
1912 : : }
1913 : :
1914 : : const std::string&
1915 : 3 : NAPTR::getFlags() const {
1916 : 3 : return (flags_);
1917 : : }
1918 : :
1919 : : const std::string&
1920 : 3 : NAPTR::getServices() const {
1921 : 3 : return (services_);
1922 : : }
1923 : :
1924 : : const std::string&
1925 : 2 : NAPTR::getRegexp() const {
1926 : 2 : return (regexp_);
1927 : : }
1928 : :
1929 : : const Name&
1930 : 2 : NAPTR::getReplacement() const {
1931 : 2 : return (replacement_);
1932 : : }
1933 : :
1934 : : } // end of namespace "generic"
1935 : : } // end of namespace "rdata"
1936 : : } // end of namespace "dns"
1937 : : } // end of namespace "isc"
1938 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
1939 : : //
1940 : : // Permission to use, copy, modify, and/or distribute this software for any
1941 : : // purpose with or without fee is hereby granted, provided that the above
1942 : : // copyright notice and this permission notice appear in all copies.
1943 : : //
1944 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
1945 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1946 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
1947 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1948 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
1949 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1950 : : // PERFORMANCE OF THIS SOFTWARE.
1951 : :
1952 : : #include <config.h>
1953 : :
1954 : : #include <string>
1955 : :
1956 : : #include <util/buffer.h>
1957 : : #include <dns/name.h>
1958 : : #include <dns/messagerenderer.h>
1959 : : #include <dns/rdata.h>
1960 : : #include <dns/rdataclass.h>
1961 : :
1962 : : using namespace std;
1963 : : using namespace isc::util;
1964 : :
1965 : : namespace isc {
1966 : : namespace dns {
1967 : : namespace rdata {
1968 : : namespace generic {
1969 : :
1970 : 3998 : NS::NS(const std::string& namestr) :
1971 [ + - ]: 3998 : nsname_(namestr)
1972 : 3998 : {}
1973 : :
1974 : 148 : NS::NS(InputBuffer& buffer, size_t) :
1975 [ + + ]: 148 : nsname_(buffer)
1976 : : {
1977 : : // we don't need rdata_len for parsing. if necessary, the caller will
1978 : : // check consistency.
1979 : 147 : }
1980 : :
1981 : 1245 : NS::NS(const NS& other) :
1982 [ + - ]: 1245 : Rdata(), nsname_(other.nsname_)
1983 : 1245 : {}
1984 : :
1985 : : void
1986 : 3 : NS::toWire(OutputBuffer& buffer) const {
1987 : 3 : nsname_.toWire(buffer);
1988 : 3 : }
1989 : :
1990 : : void
1991 : 63 : NS::toWire(AbstractMessageRenderer& renderer) const {
1992 : 63 : renderer.writeName(nsname_);
1993 : 63 : }
1994 : :
1995 : : string
1996 : 1040 : NS::toText() const {
1997 : 1040 : return (nsname_.toText());
1998 : : }
1999 : :
2000 : : int
2001 : 182 : NS::compare(const Rdata& other) const {
2002 [ + - ]: 182 : const NS& other_ns = dynamic_cast<const NS&>(other);
2003 : :
2004 : 182 : return (compareNames(nsname_, other_ns.nsname_));
2005 : : }
2006 : :
2007 : : const Name&
2008 : 705 : NS::getNSName() const {
2009 : 705 : return (nsname_);
2010 : : }
2011 : :
2012 : : } // end of namespace "generic"
2013 : : } // end of namespace "rdata"
2014 : : } // end of namespace "dns"
2015 : : } // end of namespace "isc"
2016 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
2017 : : //
2018 : : // Permission to use, copy, modify, and/or distribute this software for any
2019 : : // purpose with or without fee is hereby granted, provided that the above
2020 : : // copyright notice and this permission notice appear in all copies.
2021 : : //
2022 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
2023 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2024 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
2025 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2026 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2027 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2028 : : // PERFORMANCE OF THIS SOFTWARE.
2029 : :
2030 : : #include <iostream>
2031 : : #include <iomanip>
2032 : : #include <string>
2033 : : #include <sstream>
2034 : : #include <vector>
2035 : : #include <cassert>
2036 : :
2037 : : #include <boost/lexical_cast.hpp>
2038 : :
2039 : : #include <util/encode/base32hex.h>
2040 : : #include <util/encode/hex.h>
2041 : : #include <util/buffer.h>
2042 : :
2043 : : #include <dns/exceptions.h>
2044 : : #include <dns/messagerenderer.h>
2045 : : #include <dns/name.h>
2046 : : #include <dns/rrtype.h>
2047 : : #include <dns/rrttl.h>
2048 : : #include <dns/rdata.h>
2049 : : #include <dns/rdataclass.h>
2050 : : #include <dns/rdata/generic/detail/nsec_bitmap.h>
2051 : : #include <dns/rdata/generic/detail/nsec3param_common.h>
2052 : :
2053 : : #include <stdio.h>
2054 : : #include <time.h>
2055 : :
2056 : : using namespace std;
2057 : : using namespace isc::dns::rdata::generic::detail::nsec;
2058 : : using namespace isc::dns::rdata::generic::detail::nsec3;
2059 : : using namespace isc::util::encode;
2060 : : using namespace isc::util;
2061 : :
2062 : : namespace isc {
2063 : : namespace dns {
2064 : : namespace rdata {
2065 : : namespace generic {
2066 : :
2067 [ + - ][ + - ]: 37 : struct NSEC3Impl {
2068 : : // straightforward representation of NSEC3 RDATA fields
2069 : 664 : NSEC3Impl(uint8_t hashalg, uint8_t flags, uint16_t iterations,
2070 : : vector<uint8_t>salt, vector<uint8_t>next,
2071 : : vector<uint8_t> typebits) :
2072 : : hashalg_(hashalg), flags_(flags), iterations_(iterations),
2073 [ + - ][ + - ]: 664 : salt_(salt), next_(next), typebits_(typebits)
2074 : 664 : {}
2075 : :
2076 : : const uint8_t hashalg_;
2077 : : const uint8_t flags_;
2078 : : const uint16_t iterations_;
2079 : : const vector<uint8_t> salt_;
2080 : : const vector<uint8_t> next_;
2081 : : const vector<uint8_t> typebits_;
2082 : : };
2083 : :
2084 : 670 : NSEC3::NSEC3(const string& nsec3_str) :
2085 : 1340 : impl_(NULL)
2086 : : {
2087 [ + - + - : 1340 : istringstream iss(nsec3_str);
+ - ]
2088 : : vector<uint8_t> salt;
2089 : : const ParseNSEC3ParamResult params =
2090 [ + + ]: 670 : parseNSEC3ParamText("NSEC3", nsec3_str, iss, salt);
2091 : :
2092 : : // Extract Next hash. It must be an unpadded base32hex string.
2093 : 661 : string nexthash;
2094 [ + - ]: 661 : iss >> nexthash;
2095 [ + - ][ + - ]: 661 : if (iss.bad() || iss.fail()) {
[ - + ]
2096 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "Invalid NSEC3 text: " << nsec3_str);
[ # # ][ # # ]
2097 : : }
2098 [ - + ]: 661 : assert(!nexthash.empty());
2099 [ + - ][ + + ]: 661 : if (*nexthash.rbegin() == '=') {
2100 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "NSEC3 hash has padding: " << nsec3_str);
[ + - ][ + - ]
2101 : : }
2102 : : vector<uint8_t> next;
2103 [ + + ]: 660 : decodeBase32Hex(nexthash, next);
2104 [ + + ]: 659 : if (next.size() > 255) {
2105 [ + - ][ + - ]: 3 : isc_throw(InvalidRdataText, "NSEC3 hash is too long: "
[ + - ][ + - ]
2106 : : << next.size() << " bytes");
2107 : : }
2108 : :
2109 : : // For NSEC3 empty bitmap is possible and allowed.
2110 [ + + ]: 658 : if (iss.eof()) {
2111 : : impl_ = new NSEC3Impl(params.algorithm, params.flags,
2112 : : params.iterations, salt, next,
2113 [ + - ][ + - ]: 36 : vector<uint8_t>());
[ + - ][ + - ]
2114 : 655 : return;
2115 : : }
2116 : :
2117 : : vector<uint8_t> typebits;
2118 [ + + ]: 622 : buildBitmapsFromText("NSEC3", iss, typebits);
2119 : :
2120 : : impl_ = new NSEC3Impl(params.algorithm, params.flags, params.iterations,
2121 [ + - ][ + - ]: 619 : salt, next, typebits);
[ + - ][ + - ]
[ + - ]
2122 : : }
2123 : :
2124 : 120 : NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len) {
2125 : : vector<uint8_t> salt;
2126 : : const ParseNSEC3ParamResult params =
2127 [ + + ]: 60 : parseNSEC3ParamWire("NSEC3", buffer, rdata_len, salt);
2128 : :
2129 [ + + ]: 49 : if (rdata_len < 1) {
2130 [ + - ][ + - ]: 3 : isc_throw(DNSMessageFORMERR, "NSEC3 too short to contain hash length, "
[ + - ]
2131 : : "length: " << rdata_len + salt.size() + 5);
2132 : : }
2133 [ + + ]: 48 : const uint8_t nextlen = buffer.readUint8();
2134 : 47 : --rdata_len;
2135 [ + + ][ + + ]: 47 : if (nextlen == 0 || rdata_len < nextlen) {
2136 [ + - ][ + - ]: 6 : isc_throw(DNSMessageFORMERR, "NSEC3 invalid hash length: " <<
[ + - ]
2137 : : static_cast<unsigned int>(nextlen));
2138 : : }
2139 : :
2140 [ + - ]: 45 : vector<uint8_t> next(nextlen);
2141 [ + + ]: 45 : buffer.readData(&next[0], nextlen);
2142 : 25 : rdata_len -= nextlen;
2143 : :
2144 [ + - ]: 25 : vector<uint8_t> typebits(rdata_len);
2145 [ + + ]: 25 : if (rdata_len > 0) {
2146 : : // Read and parse the bitmaps only when they exist; empty bitmap
2147 : : // is possible for NSEC3.
2148 [ + + ]: 23 : buffer.readData(&typebits[0], rdata_len);
2149 [ + + ]: 14 : checkRRTypeBitmaps("NSEC3", typebits);
2150 : : }
2151 : :
2152 : : impl_ = new NSEC3Impl(params.algorithm, params.flags, params.iterations,
2153 [ + - ][ + - ]: 9 : salt, next, typebits);
[ + - ][ + - ]
[ + - ]
2154 : 9 : }
2155 : :
2156 : 37 : NSEC3::NSEC3(const NSEC3& source) :
2157 [ + - ][ + - ]: 37 : Rdata(), impl_(new NSEC3Impl(*source.impl_))
2158 : 37 : {}
2159 : :
2160 : : NSEC3&
2161 : 0 : NSEC3::operator=(const NSEC3& source) {
2162 [ # # ]: 0 : if (impl_ == source.impl_) {
2163 : : return (*this);
2164 : : }
2165 : :
2166 [ # # ]: 0 : NSEC3Impl* newimpl = new NSEC3Impl(*source.impl_);
2167 [ # # ]: 0 : delete impl_;
2168 : 0 : impl_ = newimpl;
2169 : :
2170 : 0 : return (*this);
2171 : : }
2172 : :
2173 : 1274 : NSEC3::~NSEC3() {
2174 [ + - ]: 1402 : delete impl_;
2175 : 1274 : }
2176 : :
2177 : : string
2178 : 328 : NSEC3::toText() const {
2179 : 656 : ostringstream s;
2180 [ + - ]: 328 : bitmapsToText(impl_->typebits_, s);
2181 : :
2182 : : using namespace boost;
2183 : 328 : return (lexical_cast<string>(static_cast<int>(impl_->hashalg_)) +
2184 : 656 : " " + lexical_cast<string>(static_cast<int>(impl_->flags_)) +
2185 : 656 : " " + lexical_cast<string>(static_cast<int>(impl_->iterations_)) +
2186 : 656 : " " + (impl_->salt_.empty() ? "-" : encodeHex(impl_->salt_)) +
2187 [ + - ][ + + ]: 984 : " " + encodeBase32Hex(impl_->next_) + s.str());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
2188 : : }
2189 : :
2190 : : template <typename OUTPUT_TYPE>
2191 : : void
2192 : 6 : toWireHelper(const NSEC3Impl& impl, OUTPUT_TYPE& output) {
2193 : 3 : output.writeUint8(impl.hashalg_);
2194 : 3 : output.writeUint8(impl.flags_);
2195 : 3 : output.writeUint16(impl.iterations_);
2196 : 3 : output.writeUint8(impl.salt_.size());
2197 [ + + + + ]: 6 : if (!impl.salt_.empty()) {
2198 : 2 : output.writeData(&impl.salt_[0], impl.salt_.size());
2199 : : }
2200 [ - + ][ - + ]: 6 : assert(!impl.next_.empty());
2201 : 3 : output.writeUint8(impl.next_.size());
2202 : 3 : output.writeData(&impl.next_[0], impl.next_.size());
2203 [ + + + + ]: 6 : if (!impl.typebits_.empty()) {
2204 : 2 : output.writeData(&impl.typebits_[0], impl.typebits_.size());
2205 : : }
2206 : 6 : }
2207 : :
2208 : : void
2209 : 3 : NSEC3::toWire(OutputBuffer& buffer) const {
2210 : 3 : toWireHelper(*impl_, buffer);
2211 : 3 : }
2212 : :
2213 : : void
2214 : 3 : NSEC3::toWire(AbstractMessageRenderer& renderer) const {
2215 : 3 : toWireHelper(*impl_, renderer);
2216 : 3 : }
2217 : :
2218 : : namespace {
2219 : : // This is a helper subroutine for compare(). It compares two binary
2220 : : // data stored in vector<uint8_t> objects based on the "Canonical RR Ordering"
2221 : : // as defined in Section 6.3 of RFC4034, that is, the data are treated
2222 : : // "as a left-justified unsigned octet sequence in which the absence of an
2223 : : // octet sorts before a zero octet."
2224 : : //
2225 : : // If check_length_first is true, it treats the compared data as if they
2226 : : // began with a single-octet "length" field whose value is the size of the
2227 : : // corresponding vector. In this case, if the sizes of the two vectors are
2228 : : // different the shorter one is always considered the "smaller"; the contents
2229 : : // of the vector don't matter.
2230 : : //
2231 : : // This function returns:
2232 : : // -1 if v1 is considered smaller than v2
2233 : : // 1 if v1 is considered larger than v2
2234 : : // 0 otherwise
2235 : : int
2236 : 218 : compareVectors(const vector<uint8_t>& v1, const vector<uint8_t>& v2,
2237 : : bool check_length_first = true)
2238 : : {
2239 : 218 : const size_t len1 = v1.size();
2240 : 218 : const size_t len2 = v2.size();
2241 [ + + ][ + + ]: 218 : if (check_length_first && len1 != len2) {
2242 : 6 : return (len1 - len2);
2243 : : }
2244 : 212 : const size_t cmplen = min(len1, len2);
2245 [ + - ]: 212 : const int cmp = cmplen == 0 ? 0 : memcmp(&v1.at(0), &v2.at(0), cmplen);
2246 [ + + ]: 212 : if (cmp != 0) {
2247 : : return (cmp);
2248 : : } else {
2249 : 218 : return (len1 - len2);
2250 : : }
2251 : : }
2252 : : }
2253 : :
2254 : : int
2255 : 85 : NSEC3::compare(const Rdata& other) const {
2256 [ + + ]: 85 : const NSEC3& other_nsec3 = dynamic_cast<const NSEC3&>(other);
2257 : :
2258 [ + + ]: 84 : if (impl_->hashalg_ != other_nsec3.impl_->hashalg_) {
2259 [ + + ]: 2 : return (impl_->hashalg_ < other_nsec3.impl_->hashalg_ ? -1 : 1);
2260 : : }
2261 [ + + ]: 82 : if (impl_->flags_ != other_nsec3.impl_->flags_) {
2262 [ + + ]: 2 : return (impl_->flags_ < other_nsec3.impl_->flags_ ? -1 : 1);
2263 : : }
2264 [ + + ]: 80 : if (impl_->iterations_ != other_nsec3.impl_->iterations_) {
2265 [ + + ]: 2 : return (impl_->iterations_ < other_nsec3.impl_->iterations_ ? -1 : 1);
2266 : : }
2267 : :
2268 : 78 : int cmp = compareVectors(impl_->salt_, other_nsec3.impl_->salt_);
2269 [ + + ]: 78 : if (cmp != 0) {
2270 : : return (cmp);
2271 : : }
2272 : 72 : cmp = compareVectors(impl_->next_, other_nsec3.impl_->next_);
2273 [ + + ]: 72 : if (cmp != 0) {
2274 : : return (cmp);
2275 : : }
2276 : : // Note that bitmap doesn't have a dedicated length field, so we shouldn't
2277 : : // terminate the comparison just because the lengths are different.
2278 : : return (compareVectors(impl_->typebits_, other_nsec3.impl_->typebits_,
2279 : 84 : false));
2280 : : }
2281 : :
2282 : : uint8_t
2283 : 223 : NSEC3::getHashalg() const {
2284 : 223 : return (impl_->hashalg_);
2285 : : }
2286 : :
2287 : : uint8_t
2288 : 2 : NSEC3::getFlags() const {
2289 : 2 : return (impl_->flags_);
2290 : : }
2291 : :
2292 : : uint16_t
2293 : 223 : NSEC3::getIterations() const {
2294 : 223 : return (impl_->iterations_);
2295 : : }
2296 : :
2297 : : const vector<uint8_t>&
2298 : 226 : NSEC3::getSalt() const {
2299 : 226 : return (impl_->salt_);
2300 : : }
2301 : :
2302 : : const vector<uint8_t>&
2303 : 1 : NSEC3::getNext() const {
2304 : 1 : return (impl_->next_);
2305 : : }
2306 : :
2307 : : } // end of namespace "generic"
2308 : : } // end of namespace "rdata"
2309 : : } // end of namespace "dns"
2310 : : } // end of namespace "isc"
2311 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
2312 : : //
2313 : : // Permission to use, copy, modify, and/or distribute this software for any
2314 : : // purpose with or without fee is hereby granted, provided that the above
2315 : : // copyright notice and this permission notice appear in all copies.
2316 : : //
2317 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
2318 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2319 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
2320 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2321 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2322 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2323 : : // PERFORMANCE OF THIS SOFTWARE.
2324 : :
2325 : : #include <util/buffer.h>
2326 : : #include <util/encode/hex.h>
2327 : :
2328 : : #include <dns/messagerenderer.h>
2329 : : #include <dns/rdata.h>
2330 : : #include <dns/rdataclass.h>
2331 : : #include <dns/rdata/generic/detail/nsec3param_common.h>
2332 : :
2333 : : #include <boost/lexical_cast.hpp>
2334 : :
2335 : : #include <string>
2336 : : #include <sstream>
2337 : : #include <vector>
2338 : :
2339 : : using namespace std;
2340 : : using namespace isc::util;
2341 : : using namespace isc::util::encode;
2342 : :
2343 : : namespace isc {
2344 : : namespace dns {
2345 : : namespace rdata {
2346 : : namespace generic {
2347 : :
2348 [ # # ][ + - ]: 17 : struct NSEC3PARAMImpl {
2349 : : // straightforward representation of NSEC3PARAM RDATA fields
2350 : : NSEC3PARAMImpl(uint8_t hashalg, uint8_t flags, uint16_t iterations,
2351 : : const vector<uint8_t>& salt) :
2352 [ + - ][ + - ]: 154 : hashalg_(hashalg), flags_(flags), iterations_(iterations), salt_(salt)
2353 : : {}
2354 : :
2355 : : const uint8_t hashalg_;
2356 : : const uint8_t flags_;
2357 : : const uint16_t iterations_;
2358 : : const vector<uint8_t> salt_;
2359 : : };
2360 : :
2361 : 159 : NSEC3PARAM::NSEC3PARAM(const string& nsec3param_str) :
2362 : 318 : impl_(NULL)
2363 : : {
2364 [ + - + - ]: 318 : istringstream iss(nsec3param_str);
2365 : : vector<uint8_t> salt;
2366 : : const ParseNSEC3ParamResult params =
2367 [ + + ]: 159 : parseNSEC3ParamText("NSEC3PARAM", nsec3param_str, iss, salt);
2368 : :
2369 [ + + ]: 151 : if (!iss.eof()) {
2370 [ + - ][ + - ]: 8 : isc_throw(InvalidRdataText, "Invalid NSEC3PARAM (redundant text): "
[ + - ][ + - ]
2371 : : << nsec3param_str);
2372 : : }
2373 : :
2374 : : impl_ = new NSEC3PARAMImpl(params.algorithm, params.flags,
2375 [ + - ]: 147 : params.iterations, salt);
2376 : 147 : }
2377 : :
2378 : 36 : NSEC3PARAM::NSEC3PARAM(InputBuffer& buffer, size_t rdata_len) {
2379 : : vector<uint8_t> salt;
2380 : : const ParseNSEC3ParamResult params =
2381 [ + + ]: 18 : parseNSEC3ParamWire("NSEC3PARAM", buffer, rdata_len, salt);
2382 : :
2383 : : impl_ = new NSEC3PARAMImpl(params.algorithm, params.flags,
2384 [ + - ]: 7 : params.iterations, salt);
2385 : 7 : }
2386 : :
2387 : 17 : NSEC3PARAM::NSEC3PARAM(const NSEC3PARAM& source) :
2388 [ + - ]: 17 : Rdata(), impl_(new NSEC3PARAMImpl(*source.impl_))
2389 : 17 : {}
2390 : :
2391 : : NSEC3PARAM&
2392 : 0 : NSEC3PARAM::operator=(const NSEC3PARAM& source) {
2393 [ # # ]: 0 : if (impl_ == source.impl_) {
2394 : : return (*this);
2395 : : }
2396 : :
2397 : 0 : NSEC3PARAMImpl* newimpl = new NSEC3PARAMImpl(*source.impl_);
2398 [ # # ]: 0 : delete impl_;
2399 : 0 : impl_ = newimpl;
2400 : :
2401 : 0 : return (*this);
2402 : : }
2403 : :
2404 : 276 : NSEC3PARAM::~NSEC3PARAM() {
2405 [ + - ]: 342 : delete impl_;
2406 : 276 : }
2407 : :
2408 : : string
2409 : 20 : NSEC3PARAM::toText() const {
2410 : : using namespace boost;
2411 : 20 : return (lexical_cast<string>(static_cast<int>(impl_->hashalg_)) +
2412 : 40 : " " + lexical_cast<string>(static_cast<int>(impl_->flags_)) +
2413 : 40 : " " + lexical_cast<string>(static_cast<int>(impl_->iterations_)) +
2414 [ + + ][ + - ]: 40 : " " + (impl_->salt_.empty() ? "-" : encodeHex(impl_->salt_)));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
2415 : : }
2416 : :
2417 : : template <typename OUTPUT_TYPE>
2418 : : void
2419 : : toWireHelper(const NSEC3PARAMImpl& impl, OUTPUT_TYPE& output) {
2420 : 3 : output.writeUint8(impl.hashalg_);
2421 : 3 : output.writeUint8(impl.flags_);
2422 : 3 : output.writeUint16(impl.iterations_);
2423 : 3 : output.writeUint8(impl.salt_.size());
2424 [ + + + + ]: 6 : if (!impl.salt_.empty()) {
2425 : 2 : output.writeData(&impl.salt_[0], impl.salt_.size());
2426 : : }
2427 : : }
2428 : :
2429 : : void
2430 : 3 : NSEC3PARAM::toWire(OutputBuffer& buffer) const {
2431 : 3 : toWireHelper(*impl_, buffer);
2432 : 3 : }
2433 : :
2434 : : void
2435 : 3 : NSEC3PARAM::toWire(AbstractMessageRenderer& renderer) const {
2436 : 3 : toWireHelper(*impl_, renderer);
2437 : 3 : }
2438 : :
2439 : : int
2440 : 20 : NSEC3PARAM::compare(const Rdata& other) const {
2441 [ + + ]: 20 : const NSEC3PARAM& other_param = dynamic_cast<const NSEC3PARAM&>(other);
2442 : :
2443 [ + + ]: 19 : if (impl_->hashalg_ != other_param.impl_->hashalg_) {
2444 [ + + ]: 2 : return (impl_->hashalg_ < other_param.impl_->hashalg_ ? -1 : 1);
2445 : : }
2446 [ + + ]: 17 : if (impl_->flags_ != other_param.impl_->flags_) {
2447 [ + + ]: 2 : return (impl_->flags_ < other_param.impl_->flags_ ? -1 : 1);
2448 : : }
2449 [ + + ]: 15 : if (impl_->iterations_ != other_param.impl_->iterations_) {
2450 [ + + ]: 2 : return (impl_->iterations_ < other_param.impl_->iterations_ ? -1 : 1);
2451 : : }
2452 : :
2453 : 26 : const size_t this_len = impl_->salt_.size();
2454 : 26 : const size_t other_len = other_param.impl_->salt_.size();
2455 [ + + ]: 13 : if (this_len != other_len) {
2456 : 4 : return (this_len - other_len);
2457 : : }
2458 : 9 : const size_t cmplen = min(this_len, other_len);
2459 : : const int cmp = (cmplen == 0) ? 0 :
2460 [ + + ]: 9 : memcmp(&impl_->salt_.at(0), &other_param.impl_->salt_.at(0), cmplen);
2461 [ + + ]: 9 : if (cmp != 0) {
2462 : : return (cmp);
2463 : : } else {
2464 : 19 : return (this_len - other_len);
2465 : : }
2466 : : }
2467 : :
2468 : : uint8_t
2469 : 63 : NSEC3PARAM::getHashalg() const {
2470 : 63 : return (impl_->hashalg_);
2471 : : }
2472 : :
2473 : : uint8_t
2474 : 3 : NSEC3PARAM::getFlags() const {
2475 : 3 : return (impl_->flags_);
2476 : : }
2477 : :
2478 : : uint16_t
2479 : 62 : NSEC3PARAM::getIterations() const {
2480 : 62 : return (impl_->iterations_);
2481 : : }
2482 : :
2483 : : const vector<uint8_t>&
2484 : 66 : NSEC3PARAM::getSalt() const {
2485 : 66 : return (impl_->salt_);
2486 : : }
2487 : :
2488 : : } // end of namespace "generic"
2489 : : } // end of namespace "rdata"
2490 : : } // end of namespace "dns"
2491 : : } // end of namespace "isc"
2492 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
2493 : : //
2494 : : // Permission to use, copy, modify, and/or distribute this software for any
2495 : : // purpose with or without fee is hereby granted, provided that the above
2496 : : // copyright notice and this permission notice appear in all copies.
2497 : : //
2498 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
2499 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2500 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
2501 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2502 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2503 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2504 : : // PERFORMANCE OF THIS SOFTWARE.
2505 : :
2506 : : #include <iostream>
2507 : : #include <string>
2508 : : #include <sstream>
2509 : : #include <vector>
2510 : :
2511 : : #include <util/encode/base64.h>
2512 : : #include <util/buffer.h>
2513 : : #include <dns/exceptions.h>
2514 : : #include <dns/messagerenderer.h>
2515 : : #include <dns/name.h>
2516 : : #include <dns/rrtype.h>
2517 : : #include <dns/rrttl.h>
2518 : : #include <dns/rdata.h>
2519 : : #include <dns/rdataclass.h>
2520 : : #include <dns/rdata/generic/detail/nsec_bitmap.h>
2521 : :
2522 : : #include <stdio.h>
2523 : : #include <time.h>
2524 : :
2525 : : using namespace std;
2526 : : using namespace isc::util;
2527 : : using namespace isc::util::encode;
2528 : : using namespace isc::dns::rdata::generic::detail::nsec;
2529 : :
2530 : : namespace isc {
2531 : : namespace dns {
2532 : : namespace rdata {
2533 : : namespace generic {
2534 : :
2535 [ + - ]: 2308 : struct NSECImpl {
2536 : : // straightforward representation of NSEC RDATA fields
2537 : 2140 : NSECImpl(const Name& next, vector<uint8_t> typebits) :
2538 [ + - ]: 2140 : nextname_(next), typebits_(typebits)
2539 : 2140 : {}
2540 : :
2541 : : Name nextname_;
2542 : : vector<uint8_t> typebits_;
2543 : : };
2544 : :
2545 : 2142 : NSEC::NSEC(const string& nsec_str) :
2546 : 4284 : impl_(NULL)
2547 : : {
2548 [ + - + - ]: 4284 : istringstream iss(nsec_str);
2549 : 2142 : string nextname;
2550 : :
2551 [ + - ]: 2142 : iss >> nextname;
2552 [ + - ][ + - ]: 2142 : if (iss.bad() || iss.fail()) {
[ - + ]
2553 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "Invalid NSEC name");
[ # # ]
2554 : : }
2555 [ + + ]: 2142 : if (iss.eof()) {
2556 [ + - ][ + - ]: 4 : isc_throw(InvalidRdataText, "NSEC bitmap is missing");
[ + - ]
2557 : : }
2558 : :
2559 : : vector<uint8_t> typebits;
2560 [ + + ]: 2140 : buildBitmapsFromText("NSEC", iss, typebits);
2561 : :
2562 [ + - ][ + - ]: 4276 : impl_ = new NSECImpl(Name(nextname), typebits);
[ + - ][ + - ]
2563 : 2138 : }
2564 : :
2565 : 22 : NSEC::NSEC(InputBuffer& buffer, size_t rdata_len) {
2566 : 11 : const size_t pos = buffer.getPosition();
2567 [ + - ]: 22 : const Name nextname(buffer);
2568 : :
2569 : : // rdata_len must be sufficiently large to hold non empty bitmap.
2570 [ + + ]: 11 : if (rdata_len <= buffer.getPosition() - pos) {
2571 [ + - ][ + - ]: 6 : isc_throw(DNSMessageFORMERR,
[ + - ][ + - ]
2572 : : "NSEC RDATA from wire too short: " << rdata_len << "bytes");
2573 : : }
2574 : 9 : rdata_len -= (buffer.getPosition() - pos);
2575 : :
2576 [ + - ]: 9 : vector<uint8_t> typebits(rdata_len);
2577 [ + - ]: 9 : buffer.readData(&typebits[0], rdata_len);
2578 [ + + ]: 9 : checkRRTypeBitmaps("NSEC", typebits);
2579 : :
2580 [ + - ][ + - ]: 2 : impl_ = new NSECImpl(nextname, typebits);
[ + - ]
2581 : 2 : }
2582 : :
2583 : 84 : NSEC::NSEC(const NSEC& source) :
2584 [ + - ][ + - ]: 84 : Rdata(), impl_(new NSECImpl(*source.impl_))
2585 : 84 : {}
2586 : :
2587 : : NSEC&
2588 : 0 : NSEC::operator=(const NSEC& source) {
2589 [ # # ]: 0 : if (impl_ == source.impl_) {
2590 : : return (*this);
2591 : : }
2592 : :
2593 [ # # ]: 0 : NSECImpl* newimpl = new NSECImpl(*source.impl_);
2594 [ # # ]: 0 : delete impl_;
2595 : 0 : impl_ = newimpl;
2596 : :
2597 : 0 : return (*this);
2598 : : }
2599 : :
2600 : 4369 : NSEC::~NSEC() {
2601 [ + - ]: 4448 : delete impl_;
2602 : 4369 : }
2603 : :
2604 : : string
2605 : 280 : NSEC::toText() const {
2606 : 560 : ostringstream s;
2607 [ + - ]: 280 : s << impl_->nextname_;
2608 [ + - ]: 280 : bitmapsToText(impl_->typebits_, s);
2609 : 280 : return (s.str());
2610 : : }
2611 : :
2612 : : void
2613 : 1 : NSEC::toWire(OutputBuffer& buffer) const {
2614 : 1 : impl_->nextname_.toWire(buffer);
2615 : 1 : buffer.writeData(&impl_->typebits_[0], impl_->typebits_.size());
2616 : 1 : }
2617 : :
2618 : : void
2619 : 1 : NSEC::toWire(AbstractMessageRenderer& renderer) const {
2620 : 1 : impl_->nextname_.toWire(renderer);
2621 : 2 : renderer.writeData(&impl_->typebits_[0], impl_->typebits_.size());
2622 : 1 : }
2623 : :
2624 : : const Name&
2625 : 8 : NSEC::getNextName() const {
2626 : 8 : return (impl_->nextname_);
2627 : : }
2628 : :
2629 : : int
2630 : 91 : NSEC::compare(const Rdata& other) const {
2631 [ + + ]: 91 : const NSEC& other_nsec = dynamic_cast<const NSEC&>(other);
2632 : :
2633 : 90 : int cmp = compareNames(impl_->nextname_, other_nsec.impl_->nextname_);
2634 [ + + ]: 90 : if (cmp != 0) {
2635 : : return (cmp);
2636 : : }
2637 : :
2638 : 176 : const size_t this_len = impl_->typebits_.size();
2639 : 176 : const size_t other_len = other_nsec.impl_->typebits_.size();
2640 : 88 : const size_t cmplen = min(this_len, other_len);
2641 : 176 : cmp = memcmp(&impl_->typebits_[0], &other_nsec.impl_->typebits_[0],
2642 : 88 : cmplen);
2643 [ + + ]: 88 : if (cmp != 0) {
2644 : : return (cmp);
2645 : : } else {
2646 [ + + ][ + + ]: 90 : return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1);
2647 : : }
2648 : : }
2649 : :
2650 : : } // end of namespace "generic"
2651 : : } // end of namespace "rdata"
2652 : : } // end of namespace "dns"
2653 : : } // end of namespace "isc"
2654 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
2655 : : //
2656 : : // Permission to use, copy, modify, and/or distribute this software for any
2657 : : // purpose with or without fee is hereby granted, provided that the above
2658 : : // copyright notice and this permission notice appear in all copies.
2659 : : //
2660 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
2661 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2662 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
2663 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2664 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2665 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2666 : : // PERFORMANCE OF THIS SOFTWARE.
2667 : :
2668 : : #include <config.h>
2669 : :
2670 : : #include <string>
2671 : :
2672 : : #include <util/buffer.h>
2673 : : #include <dns/messagerenderer.h>
2674 : : #include <dns/rdata.h>
2675 : : #include <dns/rdataclass.h>
2676 : :
2677 : : using namespace std;
2678 : : using namespace isc::util;
2679 : :
2680 : : namespace isc {
2681 : : namespace dns {
2682 : : namespace rdata {
2683 : : namespace generic {
2684 : :
2685 : 2 : OPT::OPT(const string&) {
2686 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "OPT RR cannot be constructed from text");
[ + - ]
2687 : : }
2688 : :
2689 : 108 : OPT::OPT(InputBuffer& buffer, size_t rdata_len) {
2690 : : // setPosition() will throw against a short buffer anyway, but it's safer
2691 : : // to check it explicitly here.
2692 [ + + ]: 54 : if (buffer.getLength() - buffer.getPosition() < rdata_len) {
2693 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataLength, "RDLEN of OPT is too large");
[ + - ]
2694 : : }
2695 : :
2696 : : // This simple implementation ignores any options
2697 : 53 : buffer.setPosition(buffer.getPosition() + rdata_len);
2698 : 53 : }
2699 : :
2700 : 0 : OPT::OPT(const OPT&) : Rdata() {
2701 : : // there's nothing to copy in this simple implementation.
2702 : 0 : }
2703 : :
2704 : : std::string
2705 : 1 : OPT::toText() const {
2706 : 1 : return ("");
2707 : : }
2708 : :
2709 : : void
2710 : 3 : OPT::toWire(OutputBuffer&) const {
2711 : : // nothing to do, as this simple version doesn't support any options.
2712 : 3 : }
2713 : :
2714 : : void
2715 : 143 : OPT::toWire(AbstractMessageRenderer&) const {
2716 : : // nothing to do, as this simple version doesn't support any options.
2717 : 143 : }
2718 : :
2719 : : int
2720 : 2 : OPT::compare(const Rdata& other) const {
2721 : : //const OPT& other_opt = dynamic_cast<const OPT&>(other);
2722 : : // right now we don't need other_opt:
2723 [ + + ]: 2 : static_cast<void>(dynamic_cast<const OPT&>(other));
2724 : :
2725 : 1 : return (0);
2726 : : }
2727 : :
2728 : : } // end of namespace "generic"
2729 : : } // end of namespace "rdata"
2730 : : } // end of namespace "dns"
2731 : : } // end of namespace "isc"
2732 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
2733 : : //
2734 : : // Permission to use, copy, modify, and/or distribute this software for any
2735 : : // purpose with or without fee is hereby granted, provided that the above
2736 : : // copyright notice and this permission notice appear in all copies.
2737 : : //
2738 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
2739 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2740 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
2741 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2742 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2743 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2744 : : // PERFORMANCE OF THIS SOFTWARE.
2745 : :
2746 : : #include <config.h>
2747 : :
2748 : : #include <string>
2749 : :
2750 : : #include <util/buffer.h>
2751 : : #include <dns/name.h>
2752 : : #include <dns/messagerenderer.h>
2753 : : #include <dns/rdata.h>
2754 : : #include <dns/rdataclass.h>
2755 : :
2756 : : using namespace std;
2757 : : using namespace isc::util;
2758 : :
2759 : : namespace isc {
2760 : : namespace dns {
2761 : : namespace rdata {
2762 : : namespace generic {
2763 : :
2764 : 9 : PTR::PTR(const string& type_str) :
2765 [ + - ]: 9 : ptr_name_(type_str)
2766 : 9 : {}
2767 : :
2768 : 6 : PTR::PTR(InputBuffer& buffer, size_t) :
2769 [ + + ]: 6 : ptr_name_(buffer)
2770 : : {
2771 : : // we don't need rdata_len for parsing. if necessary, the caller will
2772 : : // check consistency.
2773 : 5 : }
2774 : :
2775 : 0 : PTR::PTR(const PTR& source) :
2776 [ # # ]: 0 : Rdata(), ptr_name_(source.ptr_name_)
2777 : 0 : {}
2778 : :
2779 : : std::string
2780 : 1 : PTR::toText() const {
2781 : 1 : return (ptr_name_.toText());
2782 : : }
2783 : :
2784 : : void
2785 : 1 : PTR::toWire(OutputBuffer& buffer) const {
2786 : 1 : ptr_name_.toWire(buffer);
2787 : 1 : }
2788 : :
2789 : : void
2790 : 2 : PTR::toWire(AbstractMessageRenderer& renderer) const {
2791 : 2 : renderer.writeName(ptr_name_);
2792 : 2 : }
2793 : :
2794 : : int
2795 : 7 : PTR::compare(const Rdata& other) const {
2796 : : // The compare method normally begins with this dynamic cast.
2797 [ + - ]: 7 : const PTR& other_ptr = dynamic_cast<const PTR&>(other);
2798 : :
2799 : 7 : return (compareNames(ptr_name_, other_ptr.ptr_name_));
2800 : :
2801 : : }
2802 : :
2803 : : const Name&
2804 : 1 : PTR::getPTRName() const {
2805 : 1 : return (ptr_name_);
2806 : : }
2807 : :
2808 : : } // end of namespace "generic"
2809 : : } // end of namespace "rdata"
2810 : : } // end of namespace "dns"
2811 : : } // end of namespace "isc"
2812 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
2813 : : //
2814 : : // Permission to use, copy, modify, and/or distribute this software for any
2815 : : // purpose with or without fee is hereby granted, provided that the above
2816 : : // copyright notice and this permission notice appear in all copies.
2817 : : //
2818 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
2819 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2820 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
2821 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2822 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2823 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2824 : : // PERFORMANCE OF THIS SOFTWARE.
2825 : :
2826 : : #include <string>
2827 : : #include <sstream>
2828 : :
2829 : : #include <util/buffer.h>
2830 : :
2831 : : #include <dns/messagerenderer.h>
2832 : : #include <dns/name.h>
2833 : : #include <dns/rdata.h>
2834 : : #include <dns/rdataclass.h>
2835 : :
2836 : : using namespace std;
2837 : : using namespace isc::dns;
2838 : : using namespace isc::util;
2839 : :
2840 : : namespace isc {
2841 : : namespace dns {
2842 : : namespace rdata {
2843 : : namespace generic {
2844 : :
2845 : : /// \brief Constructor from string.
2846 : : ///
2847 : : /// \c rp_str must be formatted as follows:
2848 : : /// \code <mailbox name> <text name>
2849 : : /// \endcode
2850 : : /// where both fields must represent a valid domain name.
2851 : : ///
2852 : : /// \exception InvalidRdataText The number of RDATA fields (must be 2) is
2853 : : /// incorrect.
2854 : : /// \exception Other The constructor of the \c Name class will throw if the
2855 : : /// given name is invalid.
2856 : : /// \exception std::bad_alloc Memory allocation for names fails.
2857 : 15 : RP::RP(const std::string& rp_str) :
2858 : : // We cannot construct both names in the initialization list due to the
2859 : : // necessary text processing, so we have to initialize them with a dummy
2860 : : // name and replace them later.
2861 [ + - ][ + - ]: 19 : mailbox_(Name::ROOT_NAME()), text_(Name::ROOT_NAME())
[ + - ][ + - ]
2862 : : {
2863 [ + - + - ]: 30 : istringstream iss(rp_str);
2864 : 15 : string mailbox_str, text_str;
2865 [ + - ][ + - ]: 15 : iss >> mailbox_str >> text_str;
2866 : :
2867 : : // Validation: A valid RP RR must have exactly two fields.
2868 [ + - ][ + + ]: 15 : if (iss.bad() || iss.fail()) {
[ + + ]
2869 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "Invalid RP text: " << rp_str);
[ + - ][ + - ]
2870 : : }
2871 [ + + ]: 14 : if (!iss.eof()) {
2872 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "Invalid RP text (redundant field): "
[ + - ][ + - ]
2873 : : << rp_str);
2874 : : }
2875 : :
2876 [ + + ][ + - ]: 13 : mailbox_ = Name(mailbox_str);
2877 [ + + ][ + - ]: 12 : text_ = Name(text_str);
2878 : 11 : }
2879 : :
2880 : : /// \brief Constructor from wire-format data.
2881 : : ///
2882 : : /// This constructor doesn't check the validity of the second parameter (rdata
2883 : : /// length) for parsing.
2884 : : /// If necessary, the caller will check consistency.
2885 : : ///
2886 : : /// \exception std::bad_alloc Memory allocation for names fails.
2887 : : /// \exception Other The constructor of the \c Name class will throw if the
2888 : : /// names in the wire is invalid.
2889 [ + + ][ + + ]: 6 : RP::RP(InputBuffer& buffer, size_t) : mailbox_(buffer), text_(buffer) {
2890 : 4 : }
2891 : :
2892 : : /// \brief Copy constructor.
2893 : : ///
2894 : : /// \exception std::bad_alloc Memory allocation fails in copying internal
2895 : : /// member variables (this should be very rare).
2896 : 0 : RP::RP(const RP& other) :
2897 [ # # ][ # # ]: 0 : Rdata(), mailbox_(other.mailbox_), text_(other.text_)
2898 : 0 : {}
2899 : :
2900 : : /// \brief Convert the \c RP to a string.
2901 : : ///
2902 : : /// The output of this method is formatted as described in the "from string"
2903 : : /// constructor (\c RP(const std::string&))).
2904 : : ///
2905 : : /// \exception std::bad_alloc Internal resource allocation fails.
2906 : : ///
2907 : : /// \return A \c string object that represents the \c RP object.
2908 : : std::string
2909 : 1 : RP::toText() const {
2910 [ + - ][ + - ]: 1 : return (mailbox_.toText() + " " + text_.toText());
[ + - ]
2911 : : }
2912 : :
2913 : : void
2914 : 1 : RP::toWire(OutputBuffer& buffer) const {
2915 : 1 : mailbox_.toWire(buffer);
2916 : 1 : text_.toWire(buffer);
2917 : 1 : }
2918 : :
2919 : : void
2920 : 1 : RP::toWire(AbstractMessageRenderer& renderer) const {
2921 : : // Type RP is not "well-known", and name compression must be disabled
2922 : : // per RFC3597.
2923 : 1 : renderer.writeName(mailbox_, false);
2924 : 1 : renderer.writeName(text_, false);
2925 : 1 : }
2926 : :
2927 : : int
2928 : 7 : RP::compare(const Rdata& other) const {
2929 [ + + ]: 7 : const RP& other_rp = dynamic_cast<const RP&>(other);
2930 : :
2931 : 6 : const int cmp = compareNames(mailbox_, other_rp.mailbox_);
2932 [ + + ]: 6 : if (cmp != 0) {
2933 : : return (cmp);
2934 : : }
2935 : 6 : return (compareNames(text_, other_rp.text_));
2936 : : }
2937 : :
2938 : : } // end of namespace "generic"
2939 : : } // end of namespace "rdata"
2940 : : } // end of namespace "dns"
2941 : : } // end of namespace "isc"
2942 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
2943 : : //
2944 : : // Permission to use, copy, modify, and/or distribute this software for any
2945 : : // purpose with or without fee is hereby granted, provided that the above
2946 : : // copyright notice and this permission notice appear in all copies.
2947 : : //
2948 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
2949 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2950 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
2951 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2952 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2953 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2954 : : // PERFORMANCE OF THIS SOFTWARE.
2955 : :
2956 : : #include <string>
2957 : : #include <iomanip>
2958 : : #include <iostream>
2959 : : #include <sstream>
2960 : : #include <vector>
2961 : :
2962 : : #include <boost/lexical_cast.hpp>
2963 : :
2964 : : #include <util/encode/base64.h>
2965 : : #include <util/buffer.h>
2966 : : #include <util/time_utilities.h>
2967 : : #include <dns/messagerenderer.h>
2968 : : #include <dns/name.h>
2969 : : #include <dns/rrtype.h>
2970 : : #include <dns/rrttl.h>
2971 : : #include <dns/rdata.h>
2972 : : #include <dns/rdataclass.h>
2973 : :
2974 : : #include <stdio.h>
2975 : : #include <time.h>
2976 : :
2977 : : using namespace std;
2978 : : using namespace isc::util;
2979 : : using namespace isc::util::encode;
2980 : :
2981 : : namespace isc {
2982 : : namespace dns {
2983 : : namespace rdata {
2984 : : namespace generic {
2985 : :
2986 : : namespace {
2987 : : // This is the minimum necessary length of all wire-format RRSIG RDATA:
2988 : : // - two 8-bit fields (algorithm and labels)
2989 : : // - two 16-bit fields (covered and tag)
2990 : : // - three 32-bit fields (original TTL, expire and inception)
2991 : : const size_t RRSIG_MINIMUM_LEN = 2 * sizeof(uint8_t) + 2 * sizeof(uint16_t) +
2992 : : 3 * sizeof(uint32_t);
2993 : : }
2994 : :
2995 [ + - ]: 9385 : struct RRSIGImpl {
2996 : : // straightforward representation of RRSIG RDATA fields
2997 : : RRSIGImpl(const RRType& covered, uint8_t algorithm, uint8_t labels,
2998 : : uint32_t originalttl, uint32_t timeexpire, uint32_t timeinception,
2999 : : uint16_t tag, const Name& signer,
3000 : : const vector<uint8_t>& signature) :
3001 : : covered_(covered), algorithm_(algorithm), labels_(labels),
3002 : : originalttl_(originalttl), timeexpire_(timeexpire),
3003 : : timeinception_(timeinception), tag_(tag), signer_(signer),
3004 [ + - ][ - + ]: 7159 : signature_(signature)
[ + - ][ - + ]
3005 : : {}
3006 : :
3007 : : const RRType covered_;
3008 : : uint8_t algorithm_;
3009 : : uint8_t labels_;
3010 : : uint32_t originalttl_;
3011 : : uint32_t timeexpire_;
3012 : : uint32_t timeinception_;
3013 : : uint16_t tag_;
3014 : : const Name signer_;
3015 : : const vector<uint8_t> signature_;
3016 : : };
3017 : :
3018 : 7164 : RRSIG::RRSIG(const string& rrsig_str) :
3019 : 14328 : impl_(NULL)
3020 : : {
3021 [ + - + - ]: 14328 : istringstream iss(rrsig_str);
3022 : 7164 : string covered_txt, signer_txt, expire_txt, inception_txt;
3023 : : unsigned int algorithm, labels;
3024 : : uint32_t originalttl;
3025 : : uint16_t tag;
3026 : 14328 : stringbuf signaturebuf;
3027 : :
3028 [ + - ]: 7164 : iss >> covered_txt >> algorithm >> labels >> originalttl
3029 [ + - ][ + - ]: 14328 : >> expire_txt >> inception_txt >> tag >> signer_txt
[ + - ]
3030 [ + - ]: 7164 : >> &signaturebuf;
3031 [ + - ][ + + ]: 7164 : if (iss.bad() || iss.fail()) {
[ + + ]
3032 [ + - ][ + - ]: 10 : isc_throw(InvalidRdataText, "Invalid RRSIG text");
[ + - ]
3033 : : }
3034 [ + + ]: 7159 : if (algorithm > 0xff) {
3035 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "RRSIG algorithm out of range");
[ + - ]
3036 : : }
3037 [ + + ]: 7158 : if (labels > 0xff) {
3038 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "RRSIG labels out of range");
[ + - ]
3039 : : }
3040 : :
3041 [ + + ]: 7157 : const uint32_t timeexpire = timeFromText32(expire_txt);
3042 [ + - ]: 7156 : const uint32_t timeinception = timeFromText32(inception_txt);
3043 : :
3044 : : vector<uint8_t> signature;
3045 [ + - ][ + + ]: 7156 : decodeBase64(signaturebuf.str(), signature);
3046 : :
3047 : : impl_ = new RRSIGImpl(RRType(covered_txt), algorithm, labels,
3048 : : originalttl, timeexpire, timeinception, tag,
3049 [ + - ][ + - ]: 14310 : Name(signer_txt), signature);
[ + - ]
3050 : 7155 : }
3051 : :
3052 : 10 : RRSIG::RRSIG(InputBuffer& buffer, size_t rdata_len) {
3053 : 5 : size_t pos = buffer.getPosition();
3054 : :
3055 [ - + ]: 5 : if (rdata_len < RRSIG_MINIMUM_LEN) {
3056 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataLength, "RRSIG too short");
[ # # ]
3057 : : }
3058 : :
3059 [ + - ]: 5 : RRType covered(buffer);
3060 [ + - ]: 5 : uint8_t algorithm = buffer.readUint8();
3061 [ + - ]: 5 : uint8_t labels = buffer.readUint8();
3062 [ + - ]: 5 : uint32_t originalttl = buffer.readUint32();
3063 [ + - ]: 5 : uint32_t timeexpire = buffer.readUint32();
3064 [ + - ]: 5 : uint32_t timeinception = buffer.readUint32();
3065 [ + - ]: 5 : uint16_t tag = buffer.readUint16();
3066 [ + - ]: 10 : Name signer(buffer);
3067 : :
3068 : : // rdata_len must be sufficiently large to hold non empty signature data.
3069 [ + + ]: 5 : if (rdata_len <= buffer.getPosition() - pos) {
3070 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataLength, "RRSIG too short");
[ + - ]
3071 : : }
3072 : 4 : rdata_len -= (buffer.getPosition() - pos);
3073 : :
3074 [ + - ]: 4 : vector<uint8_t> signature(rdata_len);
3075 [ + - ]: 4 : buffer.readData(&signature[0], rdata_len);
3076 : :
3077 : : impl_ = new RRSIGImpl(covered, algorithm, labels,
3078 : : originalttl, timeexpire, timeinception, tag,
3079 [ + - ]: 4 : signer, signature);
3080 : 4 : }
3081 : :
3082 : 1113 : RRSIG::RRSIG(const RRSIG& source) :
3083 [ + - ][ + - ]: 1113 : Rdata(), impl_(new RRSIGImpl(*source.impl_))
3084 : 1113 : {}
3085 : :
3086 : : RRSIG&
3087 : 0 : RRSIG::operator=(const RRSIG& source) {
3088 [ # # ]: 0 : if (impl_ == source.impl_) {
3089 : : return (*this);
3090 : : }
3091 : :
3092 [ # # ]: 0 : RRSIGImpl* newimpl = new RRSIGImpl(*source.impl_);
3093 [ # # ]: 0 : delete impl_;
3094 : 0 : impl_ = newimpl;
3095 : :
3096 : 0 : return (*this);
3097 : : }
3098 : :
3099 : 16473 : RRSIG::~RRSIG() {
3100 [ + - ]: 16544 : delete impl_;
3101 : 16473 : }
3102 : :
3103 : : string
3104 : 746 : RRSIG::toText() const {
3105 : 746 : return (impl_->covered_.toText() +
3106 : 1492 : " " + boost::lexical_cast<string>(static_cast<int>(impl_->algorithm_))
3107 : 1492 : + " " + boost::lexical_cast<string>(static_cast<int>(impl_->labels_))
3108 : 1492 : + " " + boost::lexical_cast<string>(impl_->originalttl_)
3109 : 1492 : + " " + timeToText32(impl_->timeexpire_)
3110 : 1492 : + " " + timeToText32(impl_->timeinception_)
3111 : 1492 : + " " + boost::lexical_cast<string>(impl_->tag_)
3112 : 1492 : + " " + impl_->signer_.toText()
3113 [ + - ][ + - ]: 1492 : + " " + encodeBase64(impl_->signature_));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3114 : : }
3115 : :
3116 : : void
3117 : 1 : RRSIG::toWire(OutputBuffer& buffer) const {
3118 : 1 : impl_->covered_.toWire(buffer);
3119 : 1 : buffer.writeUint8(impl_->algorithm_);
3120 : 1 : buffer.writeUint8(impl_->labels_);
3121 : 1 : buffer.writeUint32(impl_->originalttl_);
3122 : 1 : buffer.writeUint32(impl_->timeexpire_);
3123 : 1 : buffer.writeUint32(impl_->timeinception_);
3124 : 1 : buffer.writeUint16(impl_->tag_);
3125 : 1 : impl_->signer_.toWire(buffer);
3126 : 1 : buffer.writeData(&impl_->signature_[0], impl_->signature_.size());
3127 : 1 : }
3128 : :
3129 : : void
3130 : 6 : RRSIG::toWire(AbstractMessageRenderer& renderer) const {
3131 : 6 : impl_->covered_.toWire(renderer);
3132 : 6 : renderer.writeUint8(impl_->algorithm_);
3133 : 6 : renderer.writeUint8(impl_->labels_);
3134 : 6 : renderer.writeUint32(impl_->originalttl_);
3135 : 6 : renderer.writeUint32(impl_->timeexpire_);
3136 : 6 : renderer.writeUint32(impl_->timeinception_);
3137 : 6 : renderer.writeUint16(impl_->tag_);
3138 : 6 : renderer.writeName(impl_->signer_, false);
3139 : 12 : renderer.writeData(&impl_->signature_[0], impl_->signature_.size());
3140 : 6 : }
3141 : :
3142 : : int
3143 : 195 : RRSIG::compare(const Rdata& other) const {
3144 [ + - ]: 195 : const RRSIG& other_rrsig = dynamic_cast<const RRSIG&>(other);
3145 : :
3146 [ - + ]: 195 : if (impl_->covered_.getCode() != other_rrsig.impl_->covered_.getCode()) {
3147 : 0 : return (impl_->covered_.getCode() <
3148 [ # # ]: 0 : other_rrsig.impl_->covered_.getCode() ? -1 : 1);
3149 : : }
3150 [ - + ]: 195 : if (impl_->algorithm_ != other_rrsig.impl_->algorithm_) {
3151 [ # # ]: 0 : return (impl_->algorithm_ < other_rrsig.impl_->algorithm_ ? -1 : 1);
3152 : : }
3153 [ - + ]: 195 : if (impl_->labels_ != other_rrsig.impl_->labels_) {
3154 [ # # ]: 0 : return (impl_->labels_ < other_rrsig.impl_->labels_ ? -1 : 1);
3155 : : }
3156 [ - + ]: 195 : if (impl_->originalttl_ != other_rrsig.impl_->originalttl_) {
3157 : : return (impl_->originalttl_ < other_rrsig.impl_->originalttl_ ?
3158 [ # # ]: 0 : -1 : 1);
3159 : : }
3160 [ - + ]: 195 : if (impl_->timeexpire_ != other_rrsig.impl_->timeexpire_) {
3161 : : return (impl_->timeexpire_ < other_rrsig.impl_->timeexpire_ ?
3162 [ # # ]: 0 : -1 : 1);
3163 : : }
3164 [ - + ]: 195 : if (impl_->timeinception_ != other_rrsig.impl_->timeinception_) {
3165 : : return (impl_->timeinception_ < other_rrsig.impl_->timeinception_ ?
3166 [ # # ]: 0 : -1 : 1);
3167 : : }
3168 [ - + ]: 195 : if (impl_->tag_ != other_rrsig.impl_->tag_) {
3169 [ # # ]: 0 : return (impl_->tag_ < other_rrsig.impl_->tag_ ? -1 : 1);
3170 : : }
3171 : :
3172 : 195 : int cmp = compareNames(impl_->signer_, other_rrsig.impl_->signer_);
3173 [ + - ]: 195 : if (cmp != 0) {
3174 : : return (cmp);
3175 : : }
3176 : :
3177 : 390 : size_t this_len = impl_->signature_.size();
3178 : 390 : size_t other_len = other_rrsig.impl_->signature_.size();
3179 : 195 : size_t cmplen = min(this_len, other_len);
3180 : 390 : cmp = memcmp(&impl_->signature_[0], &other_rrsig.impl_->signature_[0],
3181 : 195 : cmplen);
3182 [ + - ]: 195 : if (cmp != 0) {
3183 : : return (cmp);
3184 : : } else {
3185 [ - + ][ # # ]: 195 : return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1);
3186 : : }
3187 : : }
3188 : :
3189 : : const RRType&
3190 : 2976 : RRSIG::typeCovered() const {
3191 : 2976 : return (impl_->covered_);
3192 : : }
3193 : :
3194 : : } // end of namespace "generic"
3195 : : } // end of namespace "rdata"
3196 : : } // end of namespace "dns"
3197 : : } // end of namespace "isc"
3198 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
3199 : : //
3200 : : // Permission to use, copy, modify, and/or distribute this software for any
3201 : : // purpose with or without fee is hereby granted, provided that the above
3202 : : // copyright notice and this permission notice appear in all copies.
3203 : : //
3204 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
3205 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
3206 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
3207 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
3208 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
3209 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3210 : : // PERFORMANCE OF THIS SOFTWARE.
3211 : :
3212 : : #include <config.h>
3213 : :
3214 : : #include <string>
3215 : :
3216 : : #include <boost/lexical_cast.hpp>
3217 : :
3218 : : #include <exceptions/exceptions.h>
3219 : :
3220 : : #include <util/buffer.h>
3221 : : #include <dns/name.h>
3222 : : #include <dns/messagerenderer.h>
3223 : : #include <dns/rdata.h>
3224 : : #include <dns/rdataclass.h>
3225 : :
3226 : : using namespace std;
3227 : : using namespace boost;
3228 : : using namespace isc::util;
3229 : :
3230 : : namespace isc {
3231 : : namespace dns {
3232 : : namespace rdata {
3233 : : namespace generic {
3234 : :
3235 : 224 : SOA::SOA(InputBuffer& buffer, size_t) :
3236 [ + - ][ + - ]: 226 : mname_(buffer), rname_(buffer)
3237 : : {
3238 : : // we don't need rdata_len for parsing. if necessary, the caller will
3239 : : // check consistency.
3240 [ + + ]: 224 : buffer.readData(numdata_, sizeof(numdata_));
3241 : 222 : }
3242 : :
3243 : 2980 : SOA::SOA(const string& soastr) :
3244 [ + - ][ + - ]: 2981 : mname_("."), rname_(".") // quick hack workaround
[ + - ][ + - ]
3245 : : {
3246 [ + - + - ]: 5960 : istringstream iss(soastr);
3247 : 2980 : string token;
3248 : :
3249 [ + - ]: 2980 : iss >> token;
3250 [ + - ][ + - ]: 2980 : if (iss.bad() || iss.fail()) {
[ - + ]
3251 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "Invalid SOA MNAME");
[ # # ]
3252 : : }
3253 [ + - ][ + - ]: 2980 : mname_ = Name(token);
3254 [ + - ]: 2980 : iss >> token;
3255 [ + - ][ + - ]: 2980 : if (iss.bad() || iss.fail()) {
[ - + ]
3256 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "Invalid SOA RNAME");
[ # # ]
3257 : : }
3258 [ + - ][ + - ]: 2980 : rname_ = Name(token);
3259 : :
3260 : : uint32_t serial, refresh, retry, expire, minimum;
3261 : 11920 : iss >> serial >> refresh >> retry >> expire >> minimum;
3262 [ + + ]: 2980 : if (iss.rdstate() != ios::eofbit) {
3263 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "Invalid SOA format");
[ + - ]
3264 : : }
3265 [ + - ]: 2979 : OutputBuffer buffer(20);
3266 [ + - ]: 2979 : buffer.writeUint32(serial);
3267 [ + - ]: 2979 : buffer.writeUint32(refresh);
3268 [ + - ]: 2979 : buffer.writeUint32(retry);
3269 [ + - ]: 2979 : buffer.writeUint32(expire);
3270 [ + - ]: 2979 : buffer.writeUint32(minimum);
3271 : 2979 : memcpy(numdata_, buffer.getData(), buffer.getLength());
3272 : 2979 : }
3273 : :
3274 : 16 : SOA::SOA(const Name& mname, const Name& rname, uint32_t serial,
3275 : : uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum) :
3276 [ + - ][ + - ]: 16 : mname_(mname), rname_(rname)
3277 : : {
3278 [ + - ]: 16 : OutputBuffer b(20);
3279 [ + - ]: 16 : b.writeUint32(serial);
3280 [ + - ]: 16 : b.writeUint32(refresh);
3281 [ + - ]: 16 : b.writeUint32(retry);
3282 [ + - ]: 16 : b.writeUint32(expire);
3283 [ + - ]: 16 : b.writeUint32(minimum);
3284 [ - + ]: 16 : assert(b.getLength() == sizeof(numdata_));
3285 : 16 : memcpy(numdata_, b.getData(), sizeof(numdata_));
3286 : 16 : }
3287 : :
3288 : 2215 : SOA::SOA(const SOA& other) :
3289 [ + - ][ + - ]: 2215 : Rdata(), mname_(other.mname_), rname_(other.rname_)
3290 : : {
3291 : 2215 : memcpy(numdata_, other.numdata_, sizeof(numdata_));
3292 : 2215 : }
3293 : :
3294 : : void
3295 : 43 : SOA::toWire(OutputBuffer& buffer) const {
3296 : 43 : mname_.toWire(buffer);
3297 : 43 : rname_.toWire(buffer);
3298 : 43 : buffer.writeData(numdata_, sizeof(numdata_));
3299 : 43 : }
3300 : :
3301 : : void
3302 : 219 : SOA::toWire(AbstractMessageRenderer& renderer) const {
3303 : 219 : renderer.writeName(mname_);
3304 : 219 : renderer.writeName(rname_);
3305 : 219 : renderer.writeData(numdata_, sizeof(numdata_));
3306 : 219 : }
3307 : :
3308 : : Serial
3309 : 1234 : SOA::getSerial() const {
3310 : 1234 : InputBuffer b(numdata_, sizeof(numdata_));
3311 : 1234 : return (Serial(b.readUint32()));
3312 : : }
3313 : :
3314 : : string
3315 : 2944 : SOA::toText() const {
3316 : 2944 : InputBuffer b(numdata_, sizeof(numdata_));
3317 : 2944 : uint32_t serial = b.readUint32();
3318 : 2944 : uint32_t refresh = b.readUint32();
3319 : 2944 : uint32_t retry = b.readUint32();
3320 : 2944 : uint32_t expire = b.readUint32();
3321 : 2944 : uint32_t minimum = b.readUint32();
3322 : :
3323 : 2944 : return (mname_.toText() + " " + rname_.toText() + " " +
3324 : 5888 : lexical_cast<string>(serial) + " " +
3325 : 5888 : lexical_cast<string>(refresh) + " " +
3326 : 5888 : lexical_cast<string>(retry) + " " +
3327 : 5888 : lexical_cast<string>(expire) + " " +
3328 [ + - ][ + - ]: 5888 : lexical_cast<string>(minimum));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3329 : : }
3330 : :
3331 : : int
3332 : 909 : SOA::compare(const Rdata& other) const {
3333 [ + - ]: 909 : const SOA& other_soa = dynamic_cast<const SOA&>(other);
3334 : :
3335 : 909 : int order = compareNames(mname_, other_soa.mname_);
3336 [ + - ]: 909 : if (order != 0) {
3337 : : return (order);
3338 : : }
3339 : :
3340 : 909 : order = compareNames(rname_, other_soa.rname_);
3341 [ + - ]: 909 : if (order != 0) {
3342 : : return (order);
3343 : : }
3344 : :
3345 : 909 : return (memcmp(numdata_, other_soa.numdata_, sizeof(numdata_)));
3346 : : }
3347 : :
3348 : : } // end of namespace "generic"
3349 : : } // end of namespace "rdata"
3350 : : } // end of namespace "dns"
3351 : : } // end of namespace "isc"
3352 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
3353 : : //
3354 : : // Permission to use, copy, modify, and/or distribute this software for any
3355 : : // purpose with or without fee is hereby granted, provided that the above
3356 : : // copyright notice and this permission notice appear in all copies.
3357 : : //
3358 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
3359 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
3360 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
3361 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
3362 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
3363 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3364 : : // PERFORMANCE OF THIS SOFTWARE.
3365 : :
3366 : : #include <stdint.h>
3367 : : #include <string.h>
3368 : :
3369 : : #include <string>
3370 : : #include <vector>
3371 : :
3372 : : #include <util/buffer.h>
3373 : : #include <dns/exceptions.h>
3374 : : #include <dns/messagerenderer.h>
3375 : : #include <dns/rdata.h>
3376 : : #include <dns/rdataclass.h>
3377 : :
3378 : : using namespace std;
3379 : : using namespace isc::util;
3380 : :
3381 : : namespace isc {
3382 : : namespace dns {
3383 : : namespace rdata {
3384 : : namespace generic {
3385 : :
3386 : : /// This class implements the basic interfaces inherited from the abstract
3387 : : /// \c rdata::Rdata class. The semantics of the class is provided by
3388 : : /// a copy of instantiated TXTLikeImpl class common to both TXT and SPF.
3389 : :
3390 : : #include <dns/rdata/generic/detail/txt_like.h>
3391 : :
3392 : : /// \brief The assignment operator
3393 : : ///
3394 : : /// It internally allocates a resource, and if it fails a corresponding
3395 : : /// standard exception will be thrown.
3396 : : /// This method never throws an exception otherwise.
3397 : : SPF&
3398 : 3 : SPF::operator=(const SPF& source) {
3399 [ + + ]: 3 : if (impl_ == source.impl_) {
3400 : : return (*this);
3401 : : }
3402 : :
3403 : 2 : SPFImpl* newimpl = new SPFImpl(*source.impl_);
3404 [ + - ]: 4 : delete impl_;
3405 : 2 : impl_ = newimpl;
3406 : :
3407 : 3 : return (*this);
3408 : : }
3409 : :
3410 : : /// \brief The destructor
3411 : 44 : SPF::~SPF() {
3412 [ + - ]: 80 : delete impl_;
3413 : 44 : }
3414 : :
3415 : : /// \brief Constructor from wire-format data.
3416 : : ///
3417 : : /// It internally allocates a resource, and if it fails a corresponding
3418 : : /// standard exception will be thrown.
3419 : 7 : SPF::SPF(InputBuffer& buffer, size_t rdata_len) :
3420 [ + - ][ + + ]: 7 : impl_(new SPFImpl(buffer, rdata_len))
3421 : 4 : {}
3422 : :
3423 : : /// \brief Constructor from string.
3424 : : ///
3425 : : /// It internally allocates a resource, and if it fails a corresponding
3426 : : /// standard exception will be thrown.
3427 : 38 : SPF::SPF(const std::string& txtstr) :
3428 [ + - ][ + + ]: 38 : impl_(new SPFImpl(txtstr))
3429 : 35 : {}
3430 : :
3431 : : /// \brief Copy constructor
3432 : : ///
3433 : : /// It internally allocates a resource, and if it fails a corresponding
3434 : : /// standard exception will be thrown.
3435 : 1 : SPF::SPF(const SPF& other) :
3436 [ + - ]: 1 : Rdata(), impl_(new SPFImpl(*other.impl_))
3437 : 1 : {}
3438 : :
3439 : : /// \brief Render the \c SPF in the wire format to a OutputBuffer object
3440 : : ///
3441 : : /// \return is the return of the corresponding implementation method.
3442 : : void
3443 : 5 : SPF::toWire(OutputBuffer& buffer) const {
3444 : 5 : impl_->toWire(buffer);
3445 : 5 : }
3446 : :
3447 : : /// \brief Render the \c SPF in the wire format to an AbstractMessageRenderer
3448 : : /// object
3449 : : ///
3450 : : /// \return is the return of the corresponding implementation method.
3451 : : void
3452 : 1 : SPF::toWire(AbstractMessageRenderer& renderer) const {
3453 : 1 : impl_->toWire(renderer);
3454 : 1 : }
3455 : :
3456 : : /// \brief Convert the \c SPF to a string.
3457 : : ///
3458 : : /// \return is the return of the corresponding implementation method.
3459 : : string
3460 : 1 : SPF::toText() const {
3461 : 1 : return (impl_->toText());
3462 : : }
3463 : :
3464 : : /// \brief Compare two instances of \c SPF RDATA.
3465 : : ///
3466 : : /// This method compares \c this and the \c other \c SPF objects.
3467 : : ///
3468 : : /// This method is expected to be used in a polymorphic way, and the
3469 : : /// parameter to compare against is therefore of the abstract \c Rdata class.
3470 : : /// However, comparing two \c Rdata objects of different RR types
3471 : : /// is meaningless, and \c other must point to a \c SPF object;
3472 : : /// otherwise, the standard \c bad_cast exception will be thrown.
3473 : : ///
3474 : : /// \param other the right-hand operand to compare against.
3475 : : /// \return is the return of the corresponding implementation method.
3476 : : int
3477 : 20 : SPF::compare(const Rdata& other) const {
3478 [ + + ]: 20 : const SPF& other_txt = dynamic_cast<const SPF&>(other);
3479 : :
3480 : 19 : return (impl_->compare(*other_txt.impl_));
3481 : : }
3482 : :
3483 : : } // end of namespace "generic"
3484 : : } // end of namespace "rdata"
3485 : : } // end of namespace "dns"
3486 : : } // end of namespace "isc"
3487 : : // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
3488 : : //
3489 : : // Permission to use, copy, modify, and/or distribute this software for any
3490 : : // purpose with or without fee is hereby granted, provided that the above
3491 : : // copyright notice and this permission notice appear in all copies.
3492 : : //
3493 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
3494 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
3495 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
3496 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
3497 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
3498 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3499 : : // PERFORMANCE OF THIS SOFTWARE.
3500 : :
3501 : : #include <config.h>
3502 : :
3503 : : #include <string>
3504 : :
3505 : : #include <boost/lexical_cast.hpp>
3506 : :
3507 : : #include <exceptions/exceptions.h>
3508 : :
3509 : : #include <util/buffer.h>
3510 : : #include <util/encode/hex.h>
3511 : : #include <dns/name.h>
3512 : : #include <dns/messagerenderer.h>
3513 : : #include <dns/rdata.h>
3514 : : #include <dns/rdataclass.h>
3515 : :
3516 : : using namespace std;
3517 : : using namespace boost;
3518 : : using namespace isc::util;
3519 : : using namespace isc::util::encode;
3520 : :
3521 : : namespace isc {
3522 : : namespace dns {
3523 : : namespace rdata {
3524 : : namespace generic {
3525 : :
3526 : 4 : SSHFP::SSHFP(InputBuffer& buffer, size_t rdata_len)
3527 : : {
3528 [ - + ]: 2 : if (rdata_len < 2) {
3529 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataLength, "SSHFP record too short");
[ # # ]
3530 : : }
3531 : :
3532 [ + - ]: 2 : algorithm_ = buffer.readUint8();
3533 [ + - ]: 2 : fingerprint_type_ = buffer.readUint8();
3534 : :
3535 : 2 : rdata_len -= 2;
3536 [ + - ]: 2 : fingerprint_.resize(rdata_len);
3537 [ + - ]: 2 : buffer.readData(&fingerprint_[0], rdata_len);
3538 : 2 : }
3539 : :
3540 : 18 : SSHFP::SSHFP(const std::string& sshfp_str)
3541 : : {
3542 [ + - + - ]: 14 : std::istringstream iss(sshfp_str);
3543 : : // peekc should be of iss's char_type for isspace to work
3544 : : std::istringstream::char_type peekc;
3545 : 14 : std::stringbuf fingerprintbuf;
3546 : : uint32_t algorithm, fingerprint_type;
3547 : :
3548 : 7 : iss >> algorithm >> fingerprint_type;
3549 [ + - ][ + + ]: 7 : if (iss.bad() || iss.fail()) {
[ + + ]
3550 [ + - ][ + - ]: 4 : isc_throw(InvalidRdataText, "Invalid SSHFP text");
[ + - ]
3551 : : }
3552 [ - + ]: 5 : if ((algorithm < 1) || (algorithm > 2)) {
3553 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "SSHFP algorithm number out of range");
[ # # ]
3554 : : }
3555 [ + + ]: 5 : if (fingerprint_type != 1) {
3556 [ + - ][ + - ]: 4 : isc_throw(InvalidRdataText, "SSHFP fingerprint type out of range");
[ + - ]
3557 : : }
3558 : :
3559 [ + - ]: 3 : iss.read(&peekc, 1);
3560 [ + - + - ]: 6 : if (!iss.good() || !isspace(peekc, iss.getloc())) {
[ - + ][ + - ]
[ - + ]
3561 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "SSHFP presentation format error");
[ # # ]
3562 : : }
3563 : :
3564 [ + - ]: 3 : iss >> &fingerprintbuf;
3565 : :
3566 : 3 : algorithm_ = algorithm;
3567 : 3 : fingerprint_type_ = fingerprint_type;
3568 [ + - ][ + - ]: 3 : decodeHex(fingerprintbuf.str(), fingerprint_);
3569 : 3 : }
3570 : :
3571 : 2 : SSHFP::SSHFP(uint8_t algorithm, uint8_t fingerprint_type, const string& fingerprint)
3572 : : {
3573 [ - + ]: 1 : if ((algorithm < 1) || (algorithm > 2)) {
3574 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "SSHFP algorithm number out of range");
[ # # ]
3575 : : }
3576 [ - + ]: 1 : if (fingerprint_type != 1) {
3577 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "SSHFP fingerprint type out of range");
[ # # ]
3578 : : }
3579 : :
3580 : 1 : algorithm_ = algorithm;
3581 : 1 : fingerprint_type_ = fingerprint_type;
3582 [ + - ]: 1 : decodeHex(fingerprint, fingerprint_);
3583 : 1 : }
3584 : :
3585 : 1 : SSHFP::SSHFP(const SSHFP& other) :
3586 [ + - ]: 1 : Rdata(), algorithm_(other.algorithm_), fingerprint_type_(other.fingerprint_type_), fingerprint_(other.fingerprint_)
3587 : 1 : {}
3588 : :
3589 : : void
3590 : 0 : SSHFP::toWire(OutputBuffer& buffer) const {
3591 : 0 : buffer.writeUint8(algorithm_);
3592 : 0 : buffer.writeUint8(fingerprint_type_);
3593 : 0 : buffer.writeData(&fingerprint_[0], fingerprint_.size());
3594 : 0 : }
3595 : :
3596 : : void
3597 : 0 : SSHFP::toWire(AbstractMessageRenderer& renderer) const {
3598 : 0 : renderer.writeUint8(algorithm_);
3599 : 0 : renderer.writeUint8(fingerprint_type_);
3600 : : renderer.writeData(&fingerprint_[0], fingerprint_.size());
3601 : 0 : }
3602 : :
3603 : : string
3604 : 1 : SSHFP::toText() const {
3605 : 1 : return (lexical_cast<string>(static_cast<int>(algorithm_)) +
3606 : 2 : " " + lexical_cast<string>(static_cast<int>(fingerprint_type_)) +
3607 [ + - ][ + - ]: 2 : " " + encodeHex(fingerprint_));
[ + - ][ + - ]
[ + - ][ + - ]
3608 : : }
3609 : :
3610 : : int
3611 : 6 : SSHFP::compare(const Rdata& other) const {
3612 [ + - ]: 6 : const SSHFP& other_sshfp = dynamic_cast<const SSHFP&>(other);
3613 : :
3614 : : /* This doesn't really make any sort of sense, but in the name of
3615 : : consistency... */
3616 : :
3617 [ + - ]: 6 : if (algorithm_ < other_sshfp.algorithm_) {
3618 : : return (-1);
3619 [ + - ]: 6 : } else if (algorithm_ > other_sshfp.algorithm_) {
3620 : : return (1);
3621 : : }
3622 : :
3623 [ + - ]: 6 : if (fingerprint_type_ < other_sshfp.fingerprint_type_) {
3624 : : return (-1);
3625 [ + - ]: 6 : } else if (fingerprint_type_ > other_sshfp.fingerprint_type_) {
3626 : : return (1);
3627 : : }
3628 : :
3629 : 6 : size_t this_len = fingerprint_.size();
3630 : 6 : size_t other_len = other_sshfp.fingerprint_.size();
3631 : 6 : size_t cmplen = min(this_len, other_len);
3632 : 6 : int cmp = memcmp(&fingerprint_[0], &other_sshfp.fingerprint_[0], cmplen);
3633 [ + - ]: 6 : if (cmp != 0) {
3634 : : return (cmp);
3635 : : } else {
3636 : : return ((this_len == other_len)
3637 [ - + ][ # # ]: 6 : ? 0 : (this_len < other_len) ? -1 : 1);
3638 : : }
3639 : : }
3640 : :
3641 : : uint8_t
3642 : 1 : SSHFP::getSSHFPAlgorithmNumber() const {
3643 : 1 : return (algorithm_);
3644 : : }
3645 : :
3646 : : uint8_t
3647 : 1 : SSHFP::getSSHFPFingerprintType() const {
3648 : 1 : return (fingerprint_type_);
3649 : : }
3650 : :
3651 : : } // end of namespace "generic"
3652 : : } // end of namespace "rdata"
3653 : : } // end of namespace "dns"
3654 : : } // end of namespace "isc"
3655 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
3656 : : //
3657 : : // Permission to use, copy, modify, and/or distribute this software for any
3658 : : // purpose with or without fee is hereby granted, provided that the above
3659 : : // copyright notice and this permission notice appear in all copies.
3660 : : //
3661 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
3662 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
3663 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
3664 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
3665 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
3666 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3667 : : // PERFORMANCE OF THIS SOFTWARE.
3668 : :
3669 : : #include <stdint.h>
3670 : : #include <string.h>
3671 : :
3672 : : #include <string>
3673 : : #include <vector>
3674 : :
3675 : : #include <util/buffer.h>
3676 : : #include <dns/exceptions.h>
3677 : : #include <dns/messagerenderer.h>
3678 : : #include <dns/rdata.h>
3679 : : #include <dns/rdataclass.h>
3680 : :
3681 : : using namespace std;
3682 : : using namespace isc::util;
3683 : :
3684 : : namespace isc {
3685 : : namespace dns {
3686 : : namespace rdata {
3687 : : namespace generic {
3688 : :
3689 : : #include <dns/rdata/generic/detail/txt_like.h>
3690 : :
3691 : : TXT&
3692 : 3 : TXT::operator=(const TXT& source) {
3693 [ + + ]: 3 : if (impl_ == source.impl_) {
3694 : : return (*this);
3695 : : }
3696 : :
3697 : 2 : TXTImpl* newimpl = new TXTImpl(*source.impl_);
3698 [ + - ]: 4 : delete impl_;
3699 : 2 : impl_ = newimpl;
3700 : :
3701 : 3 : return (*this);
3702 : : }
3703 : :
3704 : 11270 : TXT::~TXT() {
3705 [ + - ]: 14912 : delete impl_;
3706 : 11270 : }
3707 : :
3708 : 10 : TXT::TXT(InputBuffer& buffer, size_t rdata_len) :
3709 [ + - ][ + + ]: 10 : impl_(new TXTImpl(buffer, rdata_len))
3710 : 6 : {}
3711 : :
3712 : 3839 : TXT::TXT(const std::string& txtstr) :
3713 [ + - ][ + + ]: 3839 : impl_(new TXTImpl(txtstr))
3714 : 3835 : {}
3715 : :
3716 : 3615 : TXT::TXT(const TXT& other) :
3717 [ + - ]: 3615 : Rdata(), impl_(new TXTImpl(*other.impl_))
3718 : 3615 : {}
3719 : :
3720 : : void
3721 : 7 : TXT::toWire(OutputBuffer& buffer) const {
3722 : 7 : impl_->toWire(buffer);
3723 : 7 : }
3724 : :
3725 : : void
3726 : 21 : TXT::toWire(AbstractMessageRenderer& renderer) const {
3727 : 21 : impl_->toWire(renderer);
3728 : 21 : }
3729 : :
3730 : : string
3731 : 39 : TXT::toText() const {
3732 : 39 : return (impl_->toText());
3733 : : }
3734 : :
3735 : : int
3736 : 117 : TXT::compare(const Rdata& other) const {
3737 [ + + ]: 117 : const TXT& other_txt = dynamic_cast<const TXT&>(other);
3738 : :
3739 : 116 : return (impl_->compare(*other_txt.impl_));
3740 : : }
3741 : :
3742 : : } // end of namespace "generic"
3743 : : } // end of namespace "rdata"
3744 : : } // end of namespace "dns"
3745 : : } // end of namespace "isc"
3746 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
3747 : : //
3748 : : // Permission to use, copy, modify, and/or distribute this software for any
3749 : : // purpose with or without fee is hereby granted, provided that the above
3750 : : // copyright notice and this permission notice appear in all copies.
3751 : : //
3752 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
3753 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
3754 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
3755 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
3756 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
3757 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3758 : : // PERFORMANCE OF THIS SOFTWARE.
3759 : :
3760 : : #include <string>
3761 : :
3762 : : #include <exceptions/exceptions.h>
3763 : :
3764 : : #include <util/buffer.h>
3765 : : #include <dns/messagerenderer.h>
3766 : : #include <dns/rdata.h>
3767 : : #include <dns/rdataclass.h>
3768 : :
3769 : : using namespace std;
3770 : : using namespace isc::util;
3771 : :
3772 : : namespace isc {
3773 : : namespace dns {
3774 : : namespace rdata {
3775 : : namespace hs {
3776 : :
3777 : 0 : A::A(const string&) {
3778 : : // TBD
3779 : 0 : }
3780 : :
3781 : 0 : A::A(InputBuffer&, size_t) {
3782 : : // TBD
3783 : 0 : }
3784 : :
3785 : 0 : A::A(const A&) : Rdata() {
3786 : : // TBD
3787 : 0 : }
3788 : :
3789 : : void
3790 : 0 : A::toWire(OutputBuffer&) const {
3791 : : // TBD
3792 : 0 : }
3793 : :
3794 : : void
3795 : 0 : A::toWire(AbstractMessageRenderer&) const {
3796 : : // TBD
3797 : 0 : }
3798 : :
3799 : : string
3800 : 0 : A::toText() const {
3801 : : // TBD
3802 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "Not implemented yet");
3803 : : }
3804 : :
3805 : : int
3806 : 0 : A::compare(const Rdata&) const {
3807 : 0 : return (0); // dummy. TBD
3808 : : }
3809 : :
3810 : : } // end of namespace "hs"
3811 : : } // end of namespace "rdata"
3812 : : } // end of namespace "dns"
3813 : : } // end of namespace "isc"
3814 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
3815 : : //
3816 : : // Permission to use, copy, modify, and/or distribute this software for any
3817 : : // purpose with or without fee is hereby granted, provided that the above
3818 : : // copyright notice and this permission notice appear in all copies.
3819 : : //
3820 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
3821 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
3822 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
3823 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
3824 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
3825 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3826 : : // PERFORMANCE OF THIS SOFTWARE.
3827 : :
3828 : : #include <stdint.h>
3829 : : #include <string.h>
3830 : :
3831 : : #include <string>
3832 : :
3833 : : #include <arpa/inet.h> // XXX: for inet_pton/ntop(), not exist in C++ standards
3834 : : #include <sys/socket.h> // for AF_INET/AF_INET6
3835 : :
3836 : : #include <exceptions/exceptions.h>
3837 : :
3838 : : #include <util/buffer.h>
3839 : : #include <dns/exceptions.h>
3840 : : #include <dns/messagerenderer.h>
3841 : : #include <dns/rdata.h>
3842 : : #include <dns/rdataclass.h>
3843 : :
3844 : : using namespace std;
3845 : : using namespace isc::util;
3846 : :
3847 : : namespace isc {
3848 : : namespace dns {
3849 : : namespace rdata {
3850 : : namespace in {
3851 : :
3852 : 8012 : A::A(const string& addrstr) {
3853 : : // RFC1035 states textual representation of IN/A RDATA is
3854 : : // "four decimal numbers separated by dots without any embedded spaces".
3855 : : // This is exactly what inet_pton() accepts for AF_INET. In particular,
3856 : : // it rejects an abbreviated form such as "10.1" meaning "10.0.0.1".
3857 [ + + ]: 4006 : if (inet_pton(AF_INET, addrstr.c_str(), &addr_) != 1) {
3858 [ + - ][ + - ]: 22 : isc_throw(InvalidRdataText,
[ + - ][ + - ]
3859 : : "IN/A RDATA construction from text failed: Address cannot be "
3860 : : "converted: " << addrstr);
3861 : : }
3862 : 3995 : }
3863 : :
3864 : 592 : A::A(InputBuffer& buffer, size_t rdata_len) {
3865 [ + + ]: 296 : if (rdata_len != sizeof(addr_)) {
3866 [ + - ][ + - ]: 6 : isc_throw(DNSMessageFORMERR,
[ + - ]
3867 : : "IN/A RDATA construction from wire failed: Invalid length: "
3868 : : << rdata_len);
3869 : : }
3870 [ + + ]: 294 : if (buffer.getLength() - buffer.getPosition() < sizeof(addr_)) {
3871 [ + - ][ + - ]: 3 : isc_throw(DNSMessageFORMERR,
[ + - ]
3872 : : "IN/A RDATA construction from wire failed: "
3873 : : "insufficient buffer length: "
3874 : : << buffer.getLength() - buffer.getPosition());
3875 : : }
3876 [ + - ]: 293 : buffer.readData(&addr_, sizeof(addr_));
3877 : 293 : }
3878 : :
3879 : 3180 : A::A(const A& other) : Rdata(), addr_(other.addr_)
3880 : 1590 : {}
3881 : :
3882 : : void
3883 : 17 : A::toWire(OutputBuffer& buffer) const {
3884 : 17 : buffer.writeData(&addr_, sizeof(addr_));
3885 : 17 : }
3886 : :
3887 : : void
3888 : 196 : A::toWire(AbstractMessageRenderer& renderer) const {
3889 : 196 : renderer.writeData(&addr_, sizeof(addr_));
3890 : 196 : }
3891 : :
3892 : : string
3893 : 1547 : A::toText() const {
3894 : : char addr_string[sizeof("255.255.255.255")];
3895 : :
3896 [ - + ]: 1547 : if (inet_ntop(AF_INET, &addr_, addr_string, sizeof(addr_string)) == NULL) {
3897 [ # # ]: 0 : isc_throw(Unexpected,
3898 : : "Failed to convert IN/A RDATA to textual IPv4 address");
3899 : : }
3900 : :
3901 : 1547 : return (addr_string);
3902 : : }
3903 : :
3904 : : int
3905 : 354 : A::compare(const Rdata& other) const {
3906 [ + + ]: 354 : const A& other_a = dynamic_cast<const A&>(other);
3907 : 353 : return (memcmp(&addr_, &other_a.addr_, sizeof(addr_)));
3908 : : }
3909 : : } // end of namespace "in"
3910 : : } // end of namespace "rdata"
3911 : : } // end of namespace "dns"
3912 : : } // end of namespace "isc"
3913 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
3914 : : //
3915 : : // Permission to use, copy, modify, and/or distribute this software for any
3916 : : // purpose with or without fee is hereby granted, provided that the above
3917 : : // copyright notice and this permission notice appear in all copies.
3918 : : //
3919 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
3920 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
3921 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
3922 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
3923 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
3924 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3925 : : // PERFORMANCE OF THIS SOFTWARE.
3926 : :
3927 : : #include <stdint.h>
3928 : : #include <string.h>
3929 : :
3930 : : #include <string>
3931 : :
3932 : : #include <arpa/inet.h> // XXX: for inet_pton/ntop(), not exist in C++ standards
3933 : : #include <sys/socket.h> // for AF_INET/AF_INET6
3934 : :
3935 : : #include <exceptions/exceptions.h>
3936 : :
3937 : : #include <util/buffer.h>
3938 : : #include <dns/exceptions.h>
3939 : : #include <dns/messagerenderer.h>
3940 : : #include <dns/rdata.h>
3941 : : #include <dns/rdataclass.h>
3942 : :
3943 : : using namespace std;
3944 : : using namespace isc::util;
3945 : :
3946 : : namespace isc {
3947 : : namespace dns {
3948 : : namespace rdata {
3949 : : namespace in {
3950 : :
3951 : 1998 : AAAA::AAAA(const string& addrstr) {
3952 [ + + ]: 999 : if (inet_pton(AF_INET6, addrstr.c_str(), &addr_) != 1) {
3953 [ + - ][ + - ]: 4 : isc_throw(InvalidRdataText,
[ + - ][ + - ]
3954 : : "IN/AAAA RDATA construction from text failed: "
3955 : : "Address cannot be converted: " << addrstr);
3956 : : }
3957 : 997 : }
3958 : :
3959 : 28 : AAAA::AAAA(InputBuffer& buffer, size_t rdata_len) {
3960 [ + + ]: 14 : if (rdata_len != sizeof(addr_)) {
3961 [ + - ][ + - ]: 6 : isc_throw(DNSMessageFORMERR,
[ + - ]
3962 : : "IN/AAAA RDATA construction from wire failed: "
3963 : : "Invalid length: " << rdata_len);
3964 : : }
3965 [ + + ]: 12 : if (buffer.getLength() - buffer.getPosition() < sizeof(addr_)) {
3966 [ + - ][ + - ]: 3 : isc_throw(DNSMessageFORMERR,
[ + - ]
3967 : : "IN/AAAA RDATA construction from wire failed: "
3968 : : "insufficient buffer length: "
3969 : : << buffer.getLength() - buffer.getPosition());
3970 : : }
3971 [ + - ]: 11 : buffer.readData(&addr_, sizeof(addr_));
3972 : 11 : }
3973 : :
3974 : 734 : AAAA::AAAA(const AAAA& other) : Rdata() {
3975 : 367 : memcpy(addr_, other.addr_, sizeof(addr_));
3976 : 367 : }
3977 : :
3978 : : void
3979 : 3 : AAAA::toWire(OutputBuffer& buffer) const {
3980 : 3 : buffer.writeData(&addr_, sizeof(addr_));
3981 : 3 : }
3982 : :
3983 : : void
3984 : 3 : AAAA::toWire(AbstractMessageRenderer& renderer) const {
3985 : 3 : renderer.writeData(&addr_, sizeof(addr_));
3986 : 3 : }
3987 : :
3988 : : string
3989 : 609 : AAAA::toText() const {
3990 : : char addr_string[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
3991 : :
3992 [ - + ]: 609 : if (inet_ntop(AF_INET6, &addr_, addr_string, sizeof(addr_string)) == NULL) {
3993 [ # # ]: 0 : isc_throw(Unexpected,
3994 : : "Failed to convert IN/AAAA RDATA to textual IPv6 address");
3995 : : }
3996 : :
3997 : 609 : return (string(addr_string));
3998 : : }
3999 : :
4000 : : int
4001 : 103 : AAAA::compare(const Rdata& other) const {
4002 [ + + ]: 103 : const AAAA& other_a = dynamic_cast<const AAAA&>(other);
4003 : 102 : return (memcmp(&addr_, &other_a.addr_, sizeof(addr_)));
4004 : : }
4005 : :
4006 : : } // end of namespace "in"
4007 : : } // end of namespace "rdata"
4008 : : } // end of namespace "dns"
4009 : : } // end of namespace "isc"
4010 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
4011 : : //
4012 : : // Permission to use, copy, modify, and/or distribute this software for any
4013 : : // purpose with or without fee is hereby granted, provided that the above
4014 : : // copyright notice and this permission notice appear in all copies.
4015 : : //
4016 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
4017 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
4018 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
4019 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
4020 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
4021 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
4022 : : // PERFORMANCE OF THIS SOFTWARE.
4023 : :
4024 : : #include <stdint.h>
4025 : : #include <string.h>
4026 : :
4027 : : #include <string>
4028 : :
4029 : : #include <exceptions/exceptions.h>
4030 : :
4031 : : #include <util/buffer.h>
4032 : : #include <util/encode/base64.h>
4033 : : #include <dns/exceptions.h>
4034 : : #include <dns/messagerenderer.h>
4035 : : #include <dns/rdata.h>
4036 : : #include <dns/rdataclass.h>
4037 : :
4038 : : using namespace std;
4039 : : using namespace isc::util;
4040 : :
4041 : : namespace isc {
4042 : : namespace dns {
4043 : : namespace rdata {
4044 : : namespace in {
4045 : :
4046 : : /// \brief Constructor from string.
4047 : : ///
4048 : : /// \param dhcid_str A base-64 representation of the DHCID binary data.
4049 : : /// The data is considered to be opaque, but a sanity check is performed.
4050 : : ///
4051 : : /// <b>Exceptions</b>
4052 : : ///
4053 : : /// \c dhcid_str must be a valid BASE-64 string, otherwise an exception
4054 : : /// of class \c isc::BadValue will be thrown;
4055 : : /// the binary data should consist of at leat of 3 octets as per RFC4701:
4056 : : /// < 2 octets > Identifier type code
4057 : : /// < 1 octet > Digest type code
4058 : : /// < n octets > Digest (length depends on digest type)
4059 : : /// If the data is less than 3 octets (i.e. it cannot contain id type code and
4060 : : /// digest type code), an exception of class \c InvalidRdataLength is thrown.
4061 : 16 : DHCID::DHCID(const string& dhcid_str) {
4062 [ + - + - ]: 14 : istringstream iss(dhcid_str);
4063 : 14 : stringbuf digestbuf;
4064 : :
4065 [ + - ]: 7 : iss >> &digestbuf;
4066 [ + - ][ + + ]: 7 : isc::util::encode::decodeBase64(digestbuf.str(), digest_);
4067 : :
4068 : : // RFC4701 states DNS software should consider the RDATA section to
4069 : : // be opaque, but there must be at least three bytes in the data:
4070 : : // < 2 octets > Identifier type code
4071 : : // < 1 octet > Digest type code
4072 [ + + ]: 6 : if (digest_.size() < 3) {
4073 [ + - ][ + - ]: 3 : isc_throw(InvalidRdataLength, "DHCID length " << digest_.size() <<
[ + - ][ + - ]
4074 : : " too short, need at least 3 bytes");
4075 : : }
4076 : 5 : }
4077 : :
4078 : : /// \brief Constructor from wire-format data.
4079 : : ///
4080 : : /// \param buffer A buffer storing the wire format data.
4081 : : /// \param rdata_len The length of the RDATA in bytes
4082 : : ///
4083 : : /// <b>Exceptions</b>
4084 : : /// \c InvalidRdataLength is thrown if \c rdata_len is than minimum of 3 octets
4085 : 2 : DHCID::DHCID(InputBuffer& buffer, size_t rdata_len) {
4086 [ - + ]: 1 : if (rdata_len < 3) {
4087 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataLength, "DHCID length " << rdata_len <<
[ # # ][ # # ]
4088 : : " too short, need at least 3 bytes");
4089 : : }
4090 : :
4091 [ + - ]: 1 : digest_.resize(rdata_len);
4092 [ + - ]: 1 : buffer.readData(&digest_[0], rdata_len);
4093 : 1 : }
4094 : :
4095 : : /// \brief The copy constructor.
4096 : : ///
4097 : : /// This trivial copy constructor never throws an exception.
4098 [ + - ]: 1 : DHCID::DHCID(const DHCID& other) : Rdata(), digest_(other.digest_)
4099 : 1 : {}
4100 : :
4101 : : /// \brief Render the \c DHCID in the wire format.
4102 : : ///
4103 : : /// \param buffer An output buffer to store the wire data.
4104 : : void
4105 : 1 : DHCID::toWire(OutputBuffer& buffer) const {
4106 : 1 : buffer.writeData(&digest_[0], digest_.size());
4107 : 1 : }
4108 : :
4109 : : /// \brief Render the \c DHCID in the wire format into a
4110 : : /// \c MessageRenderer object.
4111 : : ///
4112 : : /// \param renderer DNS message rendering context that encapsulates the
4113 : : /// output buffer in which the \c DHCID is to be stored.
4114 : : void
4115 : 1 : DHCID::toWire(AbstractMessageRenderer& renderer) const {
4116 : : renderer.writeData(&digest_[0], digest_.size());
4117 : 1 : }
4118 : :
4119 : : /// \brief Convert the \c DHCID to a string.
4120 : : ///
4121 : : /// This method returns a \c std::string object representing the \c DHCID.
4122 : : ///
4123 : : /// \return A string representation of \c DHCID.
4124 : : string
4125 : 1 : DHCID::toText() const {
4126 : 1 : return (isc::util::encode::encodeBase64(digest_));
4127 : : }
4128 : :
4129 : : /// \brief Compare two instances of \c DHCID RDATA.
4130 : : ///
4131 : : /// See documentation in \c Rdata.
4132 : : int
4133 : 9 : DHCID::compare(const Rdata& other) const {
4134 [ + + ]: 9 : const DHCID& other_dhcid = dynamic_cast<const DHCID&>(other);
4135 : :
4136 : 8 : size_t this_len = digest_.size();
4137 : 8 : size_t other_len = other_dhcid.digest_.size();
4138 : 8 : size_t cmplen = min(this_len, other_len);
4139 : 8 : int cmp = memcmp(&digest_[0], &other_dhcid.digest_[0], cmplen);
4140 [ + + ]: 8 : if (cmp != 0) {
4141 : : return (cmp);
4142 : : } else {
4143 [ - + ][ # # ]: 8 : return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1);
4144 : : }
4145 : : }
4146 : :
4147 : : /// \brief Accessor method to get the DHCID digest
4148 : : ///
4149 : : /// \return A reference to the binary DHCID data
4150 : : const std::vector<uint8_t>&
4151 : 1 : DHCID::getDigest() const {
4152 : 1 : return (digest_);
4153 : : }
4154 : :
4155 : : } // end of namespace "in"
4156 : : } // end of namespace "rdata"
4157 : : } // end of namespace "dns"
4158 : : } // end of namespace "isc"
4159 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
4160 : : //
4161 : : // Permission to use, copy, modify, and/or distribute this software for any
4162 : : // purpose with or without fee is hereby granted, provided that the above
4163 : : // copyright notice and this permission notice appear in all copies.
4164 : : //
4165 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
4166 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
4167 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
4168 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
4169 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
4170 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
4171 : : // PERFORMANCE OF THIS SOFTWARE.
4172 : :
4173 : : #include <iostream>
4174 : : #include <sstream>
4175 : :
4176 : : #include <boost/lexical_cast.hpp>
4177 : :
4178 : : #include <util/buffer.h>
4179 : : #include <util/strutil.h>
4180 : :
4181 : : #include <dns/messagerenderer.h>
4182 : : #include <dns/name.h>
4183 : : #include <dns/rdata.h>
4184 : : #include <dns/rdataclass.h>
4185 : :
4186 : : using namespace std;
4187 : : using namespace isc::util;
4188 : : using namespace isc::util::str;
4189 : :
4190 : : namespace isc {
4191 : : namespace dns {
4192 : : namespace rdata {
4193 : : namespace in {
4194 : :
4195 [ + - ][ + - ]: 44 : struct SRVImpl {
4196 : : // straightforward representation of SRV RDATA fields
4197 : : SRVImpl(uint16_t priority, uint16_t weight, uint16_t port,
4198 : : const Name& target) :
4199 : : priority_(priority), weight_(weight), port_(port),
4200 [ + - ][ + - ]: 14 : target_(target)
4201 : : {}
4202 : :
4203 : : uint16_t priority_;
4204 : : uint16_t weight_;
4205 : : uint16_t port_;
4206 : : Name target_;
4207 : : };
4208 : :
4209 : : /// \brief Constructor from string.
4210 : : ///
4211 : : /// \c srv_str must be formatted as follows:
4212 : : /// \code <Priority> <Weight> <Port> <Target>
4213 : : /// \endcode
4214 : : /// where
4215 : : /// - <Priority>, <Weight>, and <Port> are an unsigned 16-bit decimal
4216 : : /// integer.
4217 : : /// - <Target> is a valid textual representation of domain name.
4218 : : ///
4219 : : /// An example of valid string is:
4220 : : /// \code "1 5 1500 example.com." \endcode
4221 : : ///
4222 : : /// <b>Exceptions</b>
4223 : : ///
4224 : : /// If <Target> is not a valid domain name, a corresponding exception from
4225 : : /// the \c Name class will be thrown;
4226 : : /// if %any of the other bullet points above is not met, an exception of
4227 : : /// class \c InvalidRdataText will be thrown.
4228 : : /// This constructor internally involves resource allocation, and if it fails
4229 : : /// a corresponding standard exception will be thrown.
4230 : 16 : SRV::SRV(const string& srv_str) :
4231 : 32 : impl_(NULL)
4232 : : {
4233 [ + - + - ]: 32 : istringstream iss(srv_str);
4234 : :
4235 : : try {
4236 [ + - ][ + + ]: 16 : const int32_t priority = tokenToNum<int32_t, 16>(getToken(iss));
4237 [ + - ][ + + ]: 15 : const int32_t weight = tokenToNum<int32_t, 16>(getToken(iss));
4238 [ + - ][ + + ]: 14 : const int32_t port = tokenToNum<int32_t, 16>(getToken(iss));
4239 [ + - ][ + + ]: 21 : const Name targetname(getToken(iss));
4240 : :
4241 [ - + ]: 10 : if (!iss.eof()) {
4242 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "Unexpected input for SRV RDATA: " <<
[ # # ][ # # ]
4243 : : srv_str);
4244 : : }
4245 : :
4246 [ + - ]: 10 : impl_ = new SRVImpl(priority, weight, port, targetname);
4247 [ + + ]: 11 : } catch (const StringTokenError& ste) {
4248 [ - + ][ - + ]: 10 : isc_throw(InvalidRdataText, "Invalid SRV text: " <<
[ - + ][ - + ]
[ - + ][ - + ]
4249 : : ste.what() << ": " << srv_str);
4250 : : }
4251 : 10 : }
4252 : :
4253 : : /// \brief Constructor from wire-format data.
4254 : : ///
4255 : : /// When a read operation on \c buffer fails (e.g., due to a corrupted
4256 : : /// message) a corresponding exception from the \c InputBuffer class will
4257 : : /// be thrown.
4258 : : /// If the wire-format data does not end with a valid domain name,
4259 : : /// a corresponding exception from the \c Name class will be thrown.
4260 : : /// In addition, this constructor internally involves resource allocation,
4261 : : /// and if it fails a corresponding standard exception will be thrown.
4262 : : ///
4263 : : /// According to RFC2782, the Target field must be a non compressed form
4264 : : /// of domain name. But this implementation accepts a %SRV RR even if that
4265 : : /// field is compressed as suggested in RFC3597.
4266 : : ///
4267 : : /// \param buffer A buffer storing the wire format data.
4268 : : /// \param rdata_len The length of the RDATA in bytes, normally expected
4269 : : /// to be the value of the RDLENGTH field of the corresponding RR.
4270 : 10 : SRV::SRV(InputBuffer& buffer, size_t rdata_len) {
4271 [ - + ]: 5 : if (rdata_len < 6) {
4272 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataLength, "SRV too short");
[ # # ]
4273 : : }
4274 : :
4275 [ + - ]: 5 : uint16_t priority = buffer.readUint16();
4276 [ + - ]: 5 : uint16_t weight = buffer.readUint16();
4277 [ + - ]: 5 : uint16_t port = buffer.readUint16();
4278 [ + + ]: 9 : const Name targetname(buffer);
4279 : :
4280 [ + - ]: 4 : impl_ = new SRVImpl(priority, weight, port, targetname);
4281 : 4 : }
4282 : :
4283 : : /// \brief The copy constructor.
4284 : : ///
4285 : : /// It internally allocates a resource, and if it fails a corresponding
4286 : : /// standard exception will be thrown.
4287 : : /// This constructor never throws an exception otherwise.
4288 : 13 : SRV::SRV(const SRV& source) :
4289 [ + - ]: 13 : Rdata(), impl_(new SRVImpl(*source.impl_))
4290 : 13 : {}
4291 : :
4292 : : SRV&
4293 : 3 : SRV::operator=(const SRV& source) {
4294 [ + + ]: 3 : if (impl_ == source.impl_) {
4295 : : return (*this);
4296 : : }
4297 : :
4298 : 2 : SRVImpl* newimpl = new SRVImpl(*source.impl_);
4299 [ + - ]: 4 : delete impl_;
4300 : 2 : impl_ = newimpl;
4301 : :
4302 : 3 : return (*this);
4303 : : }
4304 : :
4305 : 32 : SRV::~SRV() {
4306 [ + - ]: 54 : delete impl_;
4307 : 32 : }
4308 : :
4309 : : /// \brief Convert the \c SRV to a string.
4310 : : ///
4311 : : /// The output of this method is formatted as described in the "from string"
4312 : : /// constructor (\c SRV(const std::string&))).
4313 : : ///
4314 : : /// If internal resource allocation fails, a corresponding
4315 : : /// standard exception will be thrown.
4316 : : ///
4317 : : /// \return A \c string object that represents the \c SRV object.
4318 : : string
4319 : 2 : SRV::toText() const {
4320 : : using namespace boost;
4321 : 2 : return (lexical_cast<string>(impl_->priority_) +
4322 : 4 : " " + lexical_cast<string>(impl_->weight_) +
4323 : 4 : " " + lexical_cast<string>(impl_->port_) +
4324 [ + - ][ + - ]: 4 : " " + impl_->target_.toText());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
4325 : : }
4326 : :
4327 : : /// \brief Render the \c SRV in the wire format without name compression.
4328 : : ///
4329 : : /// If internal resource allocation fails, a corresponding
4330 : : /// standard exception will be thrown.
4331 : : /// This method never throws an exception otherwise.
4332 : : ///
4333 : : /// \param buffer An output buffer to store the wire data.
4334 : : void
4335 : 2 : SRV::toWire(OutputBuffer& buffer) const {
4336 : 2 : buffer.writeUint16(impl_->priority_);
4337 : 2 : buffer.writeUint16(impl_->weight_);
4338 : 2 : buffer.writeUint16(impl_->port_);
4339 : 2 : impl_->target_.toWire(buffer);
4340 : 2 : }
4341 : :
4342 : : /// \brief Render the \c SRV in the wire format with taking into account
4343 : : /// compression.
4344 : : ///
4345 : : /// As specified in RFC2782, the Target field (a domain name) will not be
4346 : : /// compressed. However, the domain name could be a target of compression
4347 : : /// of other compressible names (though pretty unlikely), the offset
4348 : : /// information of the algorithm name may be recorded in \c renderer.
4349 : : ///
4350 : : /// If internal resource allocation fails, a corresponding
4351 : : /// standard exception will be thrown.
4352 : : /// This method never throws an exception otherwise.
4353 : : ///
4354 : : /// \param renderer DNS message rendering context that encapsulates the
4355 : : /// output buffer and name compression information.
4356 : : void
4357 : 2 : SRV::toWire(AbstractMessageRenderer& renderer) const {
4358 : 2 : renderer.writeUint16(impl_->priority_);
4359 : 2 : renderer.writeUint16(impl_->weight_);
4360 : 2 : renderer.writeUint16(impl_->port_);
4361 : 2 : renderer.writeName(impl_->target_, false);
4362 : 2 : }
4363 : :
4364 : : /// \brief Compare two instances of \c SRV RDATA.
4365 : : ///
4366 : : /// See documentation in \c Rdata.
4367 : : int
4368 : 15 : SRV::compare(const Rdata& other) const {
4369 [ + + ]: 15 : const SRV& other_srv = dynamic_cast<const SRV&>(other);
4370 : :
4371 [ + + ]: 14 : if (impl_->priority_ != other_srv.impl_->priority_) {
4372 [ + + ]: 2 : return (impl_->priority_ < other_srv.impl_->priority_ ? -1 : 1);
4373 : : }
4374 [ + + ]: 12 : if (impl_->weight_ != other_srv.impl_->weight_) {
4375 [ + + ]: 2 : return (impl_->weight_ < other_srv.impl_->weight_ ? -1 : 1);
4376 : : }
4377 [ + + ]: 10 : if (impl_->port_ != other_srv.impl_->port_) {
4378 [ + + ]: 2 : return (impl_->port_ < other_srv.impl_->port_ ? -1 : 1);
4379 : : }
4380 : :
4381 : 14 : return (compareNames(impl_->target_, other_srv.impl_->target_));
4382 : : }
4383 : :
4384 : : uint16_t
4385 : 1 : SRV::getPriority() const {
4386 : 1 : return (impl_->priority_);
4387 : : }
4388 : :
4389 : : uint16_t
4390 : 1 : SRV::getWeight() const {
4391 : 1 : return (impl_->weight_);
4392 : : }
4393 : :
4394 : : uint16_t
4395 : 1 : SRV::getPort() const {
4396 : 1 : return (impl_->port_);
4397 : : }
4398 : :
4399 : : const Name&
4400 : 1 : SRV::getTarget() const {
4401 : 1 : return (impl_->target_);
4402 : : }
4403 : :
4404 : : } // end of namespace "in"
4405 : : } // end of namespace "rdata"
4406 : : } // end of namespace "dns"
4407 : 137 : } // end of namespace "isc"
|