summaryrefslogtreecommitdiffstats
path: root/src/lib/dns/serial.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dns/serial.h')
-rw-r--r--src/lib/dns/serial.h150
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