diff options
Diffstat (limited to 'src/lib/dns/serial.h')
-rw-r--r-- | src/lib/dns/serial.h | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/lib/dns/serial.h b/src/lib/dns/serial.h new file mode 100644 index 0000000..7c7e338 --- /dev/null +++ b/src/lib/dns/serial.h @@ -0,0 +1,150 @@ +// Copyright (C) 2011-2015,2017 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef SERIAL_H +#define SERIAL_H 1 + +#include <stdint.h> +#include <iostream> + +namespace isc { +namespace dns { + +/// The maximum difference between two serial numbers. If the (plain uint32_t) +/// difference between two serials is greater than this number, the smaller one +/// is considered greater. +const uint32_t MAX_SERIAL_INCREMENT = 2147483647; + +/// Maximum value a serial can have, used in + operator. +const uint64_t MAX_SERIAL_VALUE = 4294967296ull; + +/// \brief This class defines DNS serial numbers and serial arithmetic. +/// +/// DNS Serial number are in essence unsigned 32-bits numbers, with one +/// catch; they should be compared using sequence space arithmetic. +/// So given that they are 32-bits; as soon as the difference between two +/// serial numbers is greater than 2147483647 (2^31 - 1), the lower number +/// (in plain comparison) is considered the higher one. +/// +/// In order to do this as transparently as possible, these numbers are +/// stored in the Serial class, which overrides the basic comparison operators. +/// +/// In this specific context, these operations are called 'serial number +/// arithmetic', and they are defined in RFC 1982. +/// +/// \note RFC 1982 defines everything based on the value SERIAL_BITS. Since +/// the serial number has a fixed length of 32 bits, the values we use are +/// hard-coded, and not computed based on variable bit lengths. +class Serial { +public: + /// \brief Constructor with value + /// + /// \param value The uint32_t value of the serial + explicit Serial(uint32_t value) : value_(value) {} + + /// \brief Copy constructor + Serial(const Serial& other) : value_(other.getValue()) {} + + /// \brief Direct assignment from other Serial + /// + /// \param other The Serial to assign the value from + Serial& operator=(const Serial& other) { + value_ = other.getValue(); + return (*this); + } + + /// \brief Direct assignment from value + /// + /// \param value the uint32_t value to assign + void operator=(uint32_t value) { value_ = value; } + + /// \brief Returns the uint32_t representation of this serial value + /// + /// \return The uint32_t value of this Serial + uint32_t getValue() const { return (value_); } + + /// \brief Returns true if the serial values are equal + /// + /// \return True if the values are equal + bool operator==(const Serial& other) const; + + /// \brief Returns true if the serial values are not equal + /// + /// \return True if the values are not equal + bool operator!=(const Serial& other) const; + + /// \brief Returns true if the serial value of this serial is smaller than + /// the other, according to serial arithmetic as described in RFC 1982 + /// + /// \param other The Serial to compare to + /// + /// \return True if this is smaller than the given value + bool operator<(const Serial& other) const; + + /// \brief Returns true if the serial value of this serial is equal to or + /// smaller than the other, according to serial arithmetic as described + /// in RFC 1982 + /// + /// \param other The Serial to compare to + /// + /// \return True if this is smaller than or equal to the given value + bool operator<=(const Serial& other) const; + + /// \brief Returns true if the serial value of this serial is greater than + /// the other, according to serial arithmetic as described in RFC 1982 + /// + /// \param other The Serial to compare to + /// + /// \return True if this is greater than the given value + bool operator>(const Serial& other) const; + + /// \brief Returns true if the serial value of this serial is equal to or + /// greater than the other, according to serial arithmetic as described in + /// RFC 1982 + /// + /// \param other The Serial to compare to + /// + /// \return True if this is greater than or equal to the given value + bool operator>=(const Serial& other) const; + + /// \brief Adds the given value to the serial number. If this would make + /// the number greater than 2^32-1, it is 'wrapped'. + /// \note According to the specification, an addition greater than + /// MAX_SERIAL_INCREMENT is undefined. We do NOT catch this error (so as not + /// to raise exceptions), but this behaviour remains undefined. + /// + /// \param other The Serial to add + /// + /// \return The result of the addition + Serial operator+(const Serial& other) const; + + /// \brief Adds the given value to the serial number. If this would make + /// the number greater than 2^32-1, it is 'wrapped'. + /// + /// \note According to the specification, an addition greater than + /// MAX_SERIAL_INCREMENT is undefined. We do NOT catch this error (so as not + /// to raise exceptions), but this behaviour remains undefined. + /// + /// \param other_val The uint32_t value to add + /// + /// \return The result of the addition + Serial operator+(uint32_t other_val) const; + +private: + uint32_t value_; +}; + +/// \brief Helper operator for output streams, writes the value to the stream +/// +/// \param os The ostream to write to +/// \param serial The Serial to write +/// \return the output stream +std::ostream& operator<<(std::ostream& os, const Serial& serial); + +} // end namespace dns +} // end namespace isc + +#endif // SERIAL_H |