1 // Copyright (C) 2010-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 #ifndef RRTTL_H 8 #define RRTTL_H 1 9 10 #include <dns/exceptions.h> 11 12 #include <boost/optional.hpp> 13 14 #include <stdint.h> 15 16 namespace isc { 17 namespace util { 18 class InputBuffer; 19 class OutputBuffer; 20 } 21 22 namespace dns { 23 24 // forward declarations 25 class AbstractMessageRenderer; 26 27 /// 28 /// \brief A standard DNS module exception that is thrown if an RRTTL object 29 /// is being constructed from an unrecognized string. 30 /// 31 class InvalidRRTTL : public DNSTextError { 32 public: InvalidRRTTL(const char * file,size_t line,const char * what)33 InvalidRRTTL(const char* file, size_t line, const char* what) : 34 DNSTextError(file, line, what) {} 35 }; 36 37 /// 38 /// \brief A standard DNS module exception that is thrown if an RRTTL object 39 /// is being constructed from a incomplete (too short) wire-format data. 40 /// 41 class IncompleteRRTTL : public isc::dns::Exception { 42 public: IncompleteRRTTL(const char * file,size_t line,const char * what)43 IncompleteRRTTL(const char* file, size_t line, const char* what) : 44 isc::dns::Exception(file, line, what) {} 45 }; 46 47 /// 48 /// The \c RRTTL class encapsulates TTLs used in DNS resource records. 49 /// 50 /// This is a straightforward class; an \c RRTTL object simply maintains a 51 /// 32-bit unsigned integer corresponding to the TTL value. The main purpose 52 /// of this class is to provide convenient interfaces to convert a textual 53 /// representation into the integer TTL value and vice versa, and to handle 54 /// wire-format representations. 55 class RRTTL { 56 public: 57 /// 58 /// \name Constructors, Factory and Destructor 59 /// 60 /// Note: We use the default copy constructor and the default copy 61 /// assignment operator intentionally. 62 //@{ 63 /// Constructor from an integer TTL value. 64 /// 65 /// This constructor never throws an exception. 66 /// 67 /// \param ttlval An 32-bit integer of the RRTTL. RRTTL(uint32_t ttlval)68 explicit RRTTL(uint32_t ttlval) : ttlval_(ttlval) {} 69 70 /// Constructor from a string. 71 /// 72 /// It accepts either a decimal number, specifying number of seconds. Or, 73 /// it can be given a sequence of numbers and units, like "2H" (meaning 74 /// two hours), "1W3D" (one week and 3 days). The allowed units are W 75 /// (week), D (day), H (hour), M (minute) and S (second). They can be also 76 /// specified in lower-case. No further restrictions are checked (so they 77 /// can be specified in arbitrary order and even things like "1D1D" can 78 /// be used to specify two days). 79 /// 80 /// \param ttlstr A string representation of the \c RRTTL. 81 /// 82 /// \throw InvalidRRTTL in case the string is not recognized as valid 83 /// TTL representation. 84 explicit RRTTL(const std::string& ttlstr); 85 86 /// Constructor from wire-format data. 87 /// 88 /// The \c buffer parameter normally stores a complete DNS message 89 /// containing the RRTTL to be constructed. The current read position of 90 /// the buffer points to the head of the type. 91 /// 92 /// If the given data does not large enough to contain a 16-bit integer, 93 /// an exception of class \c IncompleteRRTTL will be thrown. 94 /// 95 /// \param buffer A buffer storing the wire format data. 96 explicit RRTTL(isc::util::InputBuffer& buffer); 97 98 /// A separate factory of RRTTL from text. 99 /// 100 /// This static method is similar to the constructor that takes a string 101 /// object, but works as a factory and reports parsing failure in the 102 /// form of the return value. Normally the constructor version should 103 /// suffice, but in some cases the caller may have to expect mixture of 104 /// valid and invalid input, and may want to minimize the overhead of 105 /// possible exception handling. This version is provided for such 106 /// purpose. 107 /// 108 /// If the given text represents a valid RRTTL, it returns a pointer 109 /// to a new RRTTL object. If the given text does not represent a 110 /// valid RRTTL, it returns \c NULL.. 111 /// 112 /// One main purpose of this function is to minimize the overhead 113 /// when the given text does not represent a valid RR TTL. For this 114 /// reason this function intentionally omits the capability of delivering 115 /// a detailed reason for the parse failure, such as in the \c want() 116 /// string when exception is thrown from the constructor (it will 117 /// internally require a creation of string object, which is relatively 118 /// expensive). If such detailed information is necessary, the constructor 119 /// version should be used to catch the resulting exception. 120 /// 121 /// This function never throws the \c InvalidRRTTL exception. 122 /// 123 /// \param ttlstr A string representation of the \c RRTTL. 124 /// \return A new RRTTL object for the given text or a \c NULL value. 125 static RRTTL* createFromText(const std::string& ttlstr); 126 /// 127 //@} 128 129 /// 130 /// \name Converter methods 131 /// 132 //@{ 133 /// \brief Convert the \c RRTTL to a string. 134 /// 135 /// This version of implementation simply converts the TTL value into the 136 /// numeric textual representation. We may introduce more human-readable 137 /// format depending on the context in future versions. 138 /// 139 /// If resource allocation in rendering process fails, a corresponding 140 /// standard exception will be thrown. 141 /// 142 /// \return A string representation of the \c RRTTL. 143 const std::string toText() const; 144 /// \brief Render the \c RRTTL in the wire format. 145 /// 146 /// This method renders the TTL value in network byte order via \c renderer, 147 /// which encapsulates output buffer and other rendering contexts. 148 /// 149 /// If resource allocation in rendering process fails, a corresponding 150 /// standard exception will be thrown. 151 /// 152 /// \param renderer DNS message rendering context that encapsulates the 153 /// output buffer in which the RRTTL is to be stored. 154 void toWire(AbstractMessageRenderer& renderer) const; 155 /// \brief Render the \c RRTTL in the wire format. 156 /// 157 /// This method renders the TTL value in network byte order into the 158 /// \c buffer. 159 /// 160 /// If resource allocation in rendering process fails, a corresponding 161 /// standard exception will be thrown. 162 /// 163 /// \param buffer An output buffer to store the wire data. 164 void toWire(isc::util::OutputBuffer& buffer) const; 165 //@} 166 167 /// 168 /// \name Getter Methods 169 /// 170 //@{ 171 /// \brief Returns the TTL value as a 32-bit unsigned integer. 172 /// 173 /// This method never throws an exception. 174 /// 175 /// \return An 32-bit integer corresponding to the RRTTL. getValue()176 uint32_t getValue() const { return (ttlval_); } 177 //@} 178 179 /// 180 /// \name Comparison methods 181 /// 182 /// Comparison between two \c RRTTL objects is performed in a 183 /// straightforward way, that is, comparing the corresponding TTL values 184 /// (which is the result of the \c getValue() method) as 32-bit unsigned 185 /// integers. 186 //@{ 187 /// \brief Return true iff two RRTTLs are equal. 188 /// 189 /// This method never throws an exception. 190 /// 191 /// \param other the \c RRTTL object to compare against. equals(const RRTTL & other)192 bool equals(const RRTTL& other) const 193 { return (ttlval_ == other.ttlval_); } 194 /// \brief Same as \c equals(). 195 bool operator==(const RRTTL& other) const 196 { return (ttlval_ == other.ttlval_); } 197 /// \brief Return true iff two RRTTLs are not equal. 198 /// 199 /// This method never throws an exception. 200 /// 201 /// \param other the \c RRTTL object to compare against. nequals(const RRTTL & other)202 bool nequals(const RRTTL& other) const 203 { return (ttlval_ != other.ttlval_); } 204 /// \brief Same as \c nequals(). 205 bool operator!=(const RRTTL& other) const 206 { return (ttlval_ != other.ttlval_); } 207 /// \brief Less-than or equal comparison for RRTTL against \c other. 208 /// 209 /// This method never throws an exception. 210 /// 211 /// \param other the \c RRTTL object to compare against. 212 /// \return true if \c this RRTTL is less than or equal to the \c other; 213 /// otherwise false. leq(const RRTTL & other)214 bool leq(const RRTTL& other) const 215 { return (ttlval_ <= other.ttlval_); } 216 217 /// Same as \c leq() 218 bool operator<=(const RRTTL& other) const 219 { return (ttlval_ <= other.ttlval_); } 220 221 /// \brief Greater-than or equal comparison for RRTTL against \c other. 222 /// 223 /// This method never throws an exception. 224 /// 225 /// \param other the \c RRTTL object to compare against. 226 /// \return true if \c this RRTTL is greater than or equal to the \c other; 227 /// otherwise false. geq(const RRTTL & other)228 bool geq(const RRTTL& other) const 229 { return (ttlval_ >= other.ttlval_); } 230 231 /// Same as \c geq() 232 bool operator>=(const RRTTL& other) const 233 { return (ttlval_ >= other.ttlval_); } 234 235 /// \brief Less-than comparison for RRTTL against \c other. 236 /// 237 /// This method never throws an exception. 238 /// 239 /// \param other the \c RRTTL object to compare against. 240 /// \return true if \c this RRTTL is less than the \c other; 241 /// otherwise false. lthan(const RRTTL & other)242 bool lthan(const RRTTL& other) const 243 { return (ttlval_ < other.ttlval_); } 244 245 /// Same as \c lthan() 246 bool operator<(const RRTTL& other) const 247 { return (ttlval_ < other.ttlval_); } 248 249 /// \brief Greater-than comparison for RRTTL against \c other. 250 /// 251 /// This method never throws an exception. 252 /// 253 /// \param other the \c RRTTL object to compare against. 254 /// \return true if \c this RRTTL is greater than the \c other; 255 /// otherwise false. gthan(const RRTTL & other)256 bool gthan(const RRTTL& other) const 257 { return (ttlval_ > other.ttlval_); } 258 259 /// Same as \c gthan() 260 bool operator>(const RRTTL& other) const 261 { return (ttlval_ > other.ttlval_); } 262 //@} 263 264 /// 265 /// \name Protocol constants 266 /// 267 //@{ 268 /// \brief The TTL of the max allowable value, per RFC2181 Section 8. 269 /// 270 /// The max value is the largest unsigned 31 bit integer, 2^31-1. 271 /// 272 /// \note At the moment an RRTTL object can have a value larger than 273 /// this limit. We may revisit it in a future version. MAX_TTL()274 static const RRTTL& MAX_TTL() { 275 static const RRTTL max_ttl(0x7fffffff); 276 return (max_ttl); 277 } 278 //@} 279 280 private: 281 uint32_t ttlval_; 282 }; 283 284 /// 285 /// \brief Insert the \c RRTTL as a string into stream. 286 /// 287 /// This method convert the \c rrttl into a string and inserts it into the 288 /// output stream \c os. 289 /// 290 /// This function overloads the global operator<< to behave as described in 291 /// ostream::operator<< but applied to \c RRTTL objects. 292 /// 293 /// \param os A \c std::ostream object on which the insertion operation is 294 /// performed. 295 /// \param rrttl The \c RRTTL object output by the operation. 296 /// \return A reference to the same \c std::ostream object referenced by 297 /// parameter \c os after the insertion operation. 298 std::ostream& 299 operator<<(std::ostream& os, const RRTTL& rrttl); 300 } 301 } 302 #endif // RRTTL_H 303 304 // Local Variables: 305 // mode: c++ 306 // End: 307