Branch data Line data Source code
1 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #include <ostream>
16 : : #include <string>
17 : :
18 : : #include <util/buffer.h>
19 : :
20 : : #include <dns/exceptions.h>
21 : : #include <dns/messagerenderer.h>
22 : : #include <dns/rrclass.h>
23 : : #include <dns/rrttl.h>
24 : : #include <dns/tsigrecord.h>
25 : :
26 : : using namespace isc::util;
27 : : using namespace isc::dns::rdata;
28 : :
29 : : namespace {
30 : : // Internally used constants:
31 : :
32 : : // Size in octets for the RR type, class TTL, RDLEN fields.
33 : : const size_t RR_COMMON_LEN = 10;
34 : :
35 : : // Size in octets for the fixed part of TSIG RDATAs.
36 : : // - Time Signed (6)
37 : : // - Fudge (2)
38 : : // - MAC Size (2)
39 : : // - Original ID (2)
40 : : // - Error (2)
41 : : // - Other Len (2)
42 : : const size_t RDATA_COMMON_LEN = 16;
43 : : }
44 : :
45 : : namespace isc {
46 : : namespace dns {
47 : 279 : TSIGRecord::TSIGRecord(const Name& key_name,
48 : : const rdata::any::TSIG& tsig_rdata) :
49 : : key_name_(key_name), rdata_(tsig_rdata),
50 : : length_(RR_COMMON_LEN + RDATA_COMMON_LEN + key_name_.getLength() +
51 [ + - ]: 279 : rdata_.getAlgorithm().getLength() +
52 [ + - ][ + - ]: 558 : rdata_.getMACSize() + rdata_.getOtherLen())
[ + - ]
53 : 279 : {}
54 : :
55 : : namespace {
56 : : // This is a straightforward wrapper of dynamic_cast<const any::TSIG&>.
57 : : // We use this so that we can throw the DNSMessageFORMERR exception when
58 : : // unexpected type of RDATA is detected in the member initialization list
59 : : // of the constructor below.
60 : : const any::TSIG&
61 : 212 : castToTSIGRdata(const rdata::Rdata& rdata) {
62 : : try {
63 [ + + ]: 212 : return (dynamic_cast<const any::TSIG&>(rdata));
64 [ - + ]: 6 : } catch (std::bad_cast&) {
65 [ - + ][ - + ]: 6 : isc_throw(DNSMessageFORMERR,
[ - + ][ - + ]
[ - + ]
66 : : "TSIG record is being constructed from "
67 : : "incompatible RDATA:" << rdata.toText());
68 : : }
69 : : }
70 : : }
71 : :
72 : 212 : TSIGRecord::TSIGRecord(const Name& name, const RRClass& rrclass,
73 : : const RRTTL& ttl, const rdata::Rdata& rdata,
74 : : size_t length) :
75 [ + + ][ + - ]: 214 : key_name_(name), rdata_(castToTSIGRdata(rdata)), length_(length)
76 : : {
77 [ + - ][ + + ]: 209 : if (rrclass != getClass()) {
78 [ + - ][ + - ]: 2 : isc_throw(DNSMessageFORMERR, "Unexpected TSIG RR class: " << rrclass);
[ + - ][ + - ]
79 : : }
80 [ + + ]: 208 : if (ttl != RRTTL(TSIG_TTL)) {
81 [ + - ][ + - ]: 2 : isc_throw(DNSMessageFORMERR, "Unexpected TSIG TTL: " << ttl);
[ + - ][ + - ]
82 : : }
83 : 207 : }
84 : :
85 : : const RRClass&
86 : 655 : TSIGRecord::getClass() {
87 : 655 : return (RRClass::ANY());
88 : : }
89 : :
90 : : const RRTTL&
91 : 6 : TSIGRecord::getTTL() {
92 [ + + ][ + - ]: 6 : static RRTTL ttl(TSIG_TTL);
93 : 6 : return (ttl);
94 : : }
95 : :
96 : : namespace {
97 : : template <typename OUTPUT>
98 : : void
99 : : toWireCommon(OUTPUT& output, const rdata::any::TSIG& rdata) {
100 : : // RR type, class, TTL are fixed constants.
101 : 177 : RRType::TSIG().toWire(output);
102 : 177 : TSIGRecord::getClass().toWire(output);
103 : 20 : output.writeUint32(TSIGRecord::TSIG_TTL);
104 : :
105 : : // RDLEN
106 : 177 : output.writeUint16(RDATA_COMMON_LEN + rdata.getAlgorithm().getLength() +
107 : : rdata.getMACSize() + rdata.getOtherLen());
108 : :
109 : : // TSIG RDATA
110 : 177 : rdata.toWire(output);
111 : : }
112 : : }
113 : :
114 : : int
115 : 159 : TSIGRecord::toWire(AbstractMessageRenderer& renderer) const {
116 : : // If adding the TSIG would exceed the size limit, don't do it.
117 [ + + ]: 159 : if (renderer.getLength() + length_ > renderer.getLengthLimit()) {
118 : 2 : renderer.setTruncated();
119 : 2 : return (0);
120 : : }
121 : :
122 : : // key name = owner. note that we disable compression.
123 : 157 : renderer.writeName(key_name_, false);
124 : 157 : toWireCommon(renderer, rdata_);
125 : 159 : return (1);
126 : : }
127 : :
128 : : int
129 : 20 : TSIGRecord::toWire(OutputBuffer& buffer) const {
130 : 20 : key_name_.toWire(buffer);
131 : 20 : toWireCommon(buffer, rdata_);
132 : 20 : return (1);
133 : : }
134 : :
135 : : std::string
136 : 11 : TSIGRecord::toText() const {
137 : 11 : return (key_name_.toText() + " " + RRTTL(TSIG_TTL).toText() + " " +
138 [ + - ]: 44 : getClass().toText() + " " + RRType::TSIG().toText() + " " +
139 [ + - ][ + - ]: 44 : rdata_.toText() + "\n");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
140 : : }
141 : :
142 : : std::ostream&
143 : 1 : operator<<(std::ostream& os, const TSIGRecord& record) {
144 [ + - ]: 1 : return (os << record.toText());
145 : : }
146 : : } // namespace dns
147 : 137 : } // namespace isc
|