Kea  2.1.7-git
tsigrecord.cc
Go to the documentation of this file.
1 // Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #include <ostream>
10 #include <string>
11 
12 #include <util/buffer.h>
13 
14 #include <dns/exceptions.h>
15 #include <dns/messagerenderer.h>
16 #include <dns/rrclass.h>
17 #include <dns/rrttl.h>
18 #include <dns/tsigrecord.h>
19 
20 using namespace isc::util;
21 using namespace isc::dns::rdata;
22 
23 namespace {
24 // Internally used constants:
25 
26 // Size in octets for the RR type, class TTL, RDLEN fields.
27 const size_t RR_COMMON_LEN = 10;
28 
29 // Size in octets for the fixed part of TSIG RDATAs.
30 // - Time Signed (6)
31 // - Fudge (2)
32 // - MAC Size (2)
33 // - Original ID (2)
34 // - Error (2)
35 // - Other Len (2)
36 const size_t RDATA_COMMON_LEN = 16;
37 }
38 
39 namespace isc {
40 namespace dns {
41 TSIGRecord::TSIGRecord(const Name& key_name,
42  const rdata::any::TSIG& tsig_rdata) :
43  key_name_(key_name), rdata_(tsig_rdata),
44  length_(RR_COMMON_LEN + RDATA_COMMON_LEN + key_name_.getLength() +
45  rdata_.getAlgorithm().getLength() +
46  rdata_.getMACSize() + rdata_.getOtherLen())
47 {}
48 
49 namespace {
50 // This is a straightforward wrapper of dynamic_cast<const any::TSIG&>.
51 // We use this so that we can throw the DNSMessageFORMERR exception when
52 // unexpected type of RDATA is detected in the member initialization list
53 // of the constructor below.
54 const any::TSIG&
55 castToTSIGRdata(const rdata::Rdata& rdata) {
56  const any::TSIG* tsig_rdata =
57  dynamic_cast<const any::TSIG*>(&rdata);
58  if (!tsig_rdata) {
60  "TSIG record is being constructed from "
61  "incompatible RDATA: " << rdata.toText());
62  }
63  return (*tsig_rdata);
64 }
65 }
66 
67 TSIGRecord::TSIGRecord(const Name& name, const RRClass& rrclass,
68  const RRTTL& ttl, const rdata::Rdata& rdata,
69  size_t length) :
70  key_name_(name), rdata_(castToTSIGRdata(rdata)), length_(length)
71 {
72  if (rrclass != getClass()) {
73  isc_throw(DNSMessageFORMERR, "Unexpected TSIG RR class: " << rrclass);
74  }
75  if (ttl != RRTTL(TSIG_TTL)) {
76  isc_throw(DNSMessageFORMERR, "Unexpected TSIG TTL: " << ttl);
77  }
78 }
79 
80 const RRClass&
82  return (RRClass::ANY());
83 }
84 
85 const RRTTL&
87  static RRTTL ttl(TSIG_TTL);
88  return (ttl);
89 }
90 
91 namespace {
92 template <typename OUTPUT>
93 void
94 toWireCommon(OUTPUT& output, const rdata::any::TSIG& rdata) {
95  // RR type, class, TTL are fixed constants.
96  RRType::TSIG().toWire(output);
97  TSIGRecord::getClass().toWire(output);
98  output.writeUint32(TSIGRecord::TSIG_TTL);
99 
100  // RDLEN
101  output.writeUint16(RDATA_COMMON_LEN + rdata.getAlgorithm().getLength() +
102  rdata.getMACSize() + rdata.getOtherLen());
103 
104  // TSIG RDATA
105  rdata.toWire(output);
106 }
107 }
108 
109 int
111  // If adding the TSIG would exceed the size limit, don't do it.
112  if (renderer.getLength() + length_ > renderer.getLengthLimit()) {
113  renderer.setTruncated();
114  return (0);
115  }
116 
117  // key name = owner. note that we disable compression.
118  renderer.writeName(key_name_, false);
119  toWireCommon(renderer, rdata_);
120  return (1);
121 }
122 
123 int
125  key_name_.toWire(buffer);
126  toWireCommon(buffer, rdata_);
127  return (1);
128 }
129 
130 std::string
132  return (key_name_.toText() + " " + RRTTL(TSIG_TTL).toText() + " " +
133  getClass().toText() + " " + RRType::TSIG().toText() + " " +
134  rdata_.toText() + "\n");
135 }
136 
137 std::ostream&
138 operator<<(std::ostream& os, const TSIGRecord& record) {
139  return (os << record.toText());
140 }
141 } // namespace dns
142 } // namespace isc
rdata::TSIG class represents the TSIG RDATA as defined in RFC2845.
Definition: rdataclass.h:63
The Name class encapsulates DNS names.
Definition: name.h:223
static const uint32_t TSIG_TTL
The TTL value to be used in TSIG RRs.
Definition: tsigrecord.h:267
uint16_t getOtherLen() const
Return the value of the Other Len field.
ostream & operator<<(std::ostream &os, const EDNS &edns)
Insert the EDNS as a string into stream.
Definition: edns.cc:172
static const RRType & TSIG()
Definition: rrtype.h:335
const std::string toText() const
Convert the RRType to a string.
Definition: rrtype.cc:45
virtual void writeName(const Name &name, bool compress=true)=0
Write a Name object into the internal buffer in wire format, with or without name compression...
void toWire(AbstractMessageRenderer &renderer) const
Render the RRClass in the wire format.
Definition: rrclass.cc:54
The Rdata class is an abstract base class that provides a set of common interfaces to manipulate conc...
Definition: rdata.h:123
TSIG resource record.
Definition: tsigrecord.h:54
The RRClass class encapsulates DNS resource record classes.
Definition: rrclass.h:98
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: edns.h:19
static const RRClass & getClass()
Return the RR class of TSIG.
Definition: tsigrecord.cc:81
The AbstractMessageRenderer class is an abstract base class that provides common interfaces for rende...
TSIGRecord(const Name &key_name, const rdata::any::TSIG &tsig_rdata)
Constructor from TSIG key name and RDATA.
Definition: tsigrecord.cc:41
std::string toText() const
Convert the TSIG record to a string.
Definition: tsigrecord.cc:131
virtual void setTruncated()=0
Mark the renderer to indicate truncation has occurred while rendering.
The RRTTL class encapsulates TTLs used in DNS resource records.
Definition: rrttl.h:55
void toWire(AbstractMessageRenderer &renderer) const
Render the RRType in the wire format.
Definition: rrtype.cc:55
std::string toText(bool omit_final_dot=false) const
Convert the Name to a string.
Definition: name.cc:507
static const RRClass & ANY()
Definition: rrclass.h:301
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
size_t getLength() const
Gets the length of the Name in its wire format.
Definition: name.h:360
void toWire(AbstractMessageRenderer &renderer) const
Render the Name in the wire format with compression.
Definition: name.cc:502
uint16_t getMACSize() const
Return the value of the MAC Size field.
static const RRTTL & getTTL()
Return the TTL value of TSIG.
Definition: tsigrecord.cc:86
Defines the logger used by the top-level component of kea-lfc.
const std::string toText() const
Convert the RRClass to a string.
Definition: rrclass.cc:44
const std::string toText() const
Convert the RRTTL to a string.
Definition: rrttl.cc:192
virtual std::string toText() const
Convert an Rdata to a string.
size_t getLength() const
Return the length of data written in the internal buffer.
virtual size_t getLengthLimit() const =0
Return the maximum length of rendered data that can fit in the corresponding DNS message without trun...
const Name & getAlgorithm() const
Return the algorithm name.
int toWire(AbstractMessageRenderer &renderer) const
Render the TSIG RR in the wire format.
Definition: tsigrecord.cc:110
virtual std::string toText() const =0
Convert an Rdata to a string.
virtual void toWire(isc::util::OutputBuffer &buffer) const
Render the Rdata in the wire format into a buffer.