Browse Source

[trac812] added mostly trivial TSIGError class.

JINMEI Tatuya 14 years ago
parent
commit
f099c11348
3 changed files with 456 additions and 0 deletions
  1. 102 0
      src/lib/dns/tests/tsigerror_unittest.cc
  2. 26 0
      src/lib/dns/tsigerror.cc
  3. 328 0
      src/lib/dns/tsigerror.h

+ 102 - 0
src/lib/dns/tests/tsigerror_unittest.cc

@@ -0,0 +1,102 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <string>
+#include <ostream>
+
+#include <gtest/gtest.h>
+
+#include <exceptions/exceptions.h>
+
+#include <dns/rcode.h>
+#include <dns/tsigerror.h>
+
+using namespace std;
+using namespace isc;
+using namespace isc::dns;
+
+namespace {
+TEST(TSIGErrorTest, constructFromErrorCode) {
+    // These are pretty trivial, and also test getCode();
+    EXPECT_EQ(0, TSIGError(0).getCode());
+    EXPECT_EQ(18, TSIGError(18).getCode());
+    EXPECT_EQ(65535, TSIGError(65535).getCode());
+}
+
+TEST(TSIGErrorTest, constructFromRcode) {
+    // We use RCODE for code values from 0-15.
+    EXPECT_EQ(0, TSIGError(Rcode::NOERROR()).getCode());
+    EXPECT_EQ(15, TSIGError(Rcode(15)).getCode());
+
+    // From error code 16 TSIG errors define a separate space, so passing
+    // corresponding RCODE for such code values should be prohibited.
+    EXPECT_THROW(TSIGError(Rcode(16)).getCode(), OutOfRange);
+}
+
+TEST(TSIGErrorTest, constants) {
+    // We'll only test arbitrarily chosen subsets of the codes.
+    // This class is quite simple, so it should be suffice.
+
+    EXPECT_EQ(TSIGError::BAD_SIG_CODE, TSIGError(16).getCode());
+    EXPECT_EQ(TSIGError::BAD_KEY_CODE, TSIGError(17).getCode());
+    EXPECT_EQ(TSIGError::BAD_TIME_CODE, TSIGError(18).getCode());
+
+    EXPECT_EQ(0, TSIGError::NOERROR().getCode());
+    EXPECT_EQ(9, TSIGError::NOTAUTH().getCode());
+    EXPECT_EQ(14, TSIGError::RESERVED14().getCode());
+    EXPECT_EQ(TSIGError::BAD_SIG_CODE, TSIGError::BAD_SIG().getCode());
+    EXPECT_EQ(TSIGError::BAD_KEY_CODE, TSIGError::BAD_KEY().getCode());
+    EXPECT_EQ(TSIGError::BAD_TIME_CODE, TSIGError::BAD_TIME().getCode());
+}
+
+TEST(TSIGErrorTest, equal) {
+    EXPECT_TRUE(TSIGError::NOERROR() == TSIGError(Rcode::NOERROR()));
+    EXPECT_TRUE(TSIGError(Rcode::NOERROR()) == TSIGError::NOERROR());
+    EXPECT_TRUE(TSIGError::NOERROR().equals(TSIGError(Rcode::NOERROR())));
+    EXPECT_TRUE(TSIGError::NOERROR().equals(TSIGError(Rcode::NOERROR())));
+
+    EXPECT_TRUE(TSIGError::BAD_SIG() == TSIGError(16));
+    EXPECT_TRUE(TSIGError(16) == TSIGError::BAD_SIG());
+    EXPECT_TRUE(TSIGError::BAD_SIG().equals(TSIGError(16)));
+    EXPECT_TRUE(TSIGError(16).equals(TSIGError::BAD_SIG()));
+}
+
+TEST(TSIGErrorTest, nequal) {
+    EXPECT_TRUE(TSIGError::BAD_KEY() != TSIGError(Rcode::NOERROR()));
+    EXPECT_TRUE(TSIGError(Rcode::NOERROR()) != TSIGError::BAD_KEY());
+    EXPECT_TRUE(TSIGError::BAD_KEY().nequals(TSIGError(Rcode::NOERROR())));
+    EXPECT_TRUE(TSIGError(Rcode::NOERROR()).nequals(TSIGError::BAD_KEY()));
+}
+
+TEST(TSIGErrorTest, toText) {
+    // TSIGError derived from the standard Rcode
+    EXPECT_EQ("NOERROR", TSIGError(Rcode::NOERROR()).toText());
+
+    // Well known TSIG errors
+    EXPECT_EQ("BADSIG", TSIGError::BAD_SIG().toText());
+    EXPECT_EQ("BADKEY", TSIGError::BAD_KEY().toText());
+    EXPECT_EQ("BADTIME", TSIGError::BAD_TIME().toText());
+
+    // Unknown (or not yet supported) codes.  Simply converted as numeric.
+    EXPECT_EQ("19", TSIGError(19).toText());
+    EXPECT_EQ("65535", TSIGError(65535).toText());
+}
+
+// test operator<<.  We simply confirm it appends the result of toText().
+TEST(TSIGErrorTest, LeftShiftOperator) {
+    ostringstream oss;
+    oss << TSIGError::BAD_KEY();
+    EXPECT_EQ(TSIGError::BAD_KEY().toText(), oss.str());
+}
+} // end namespace

+ 26 - 0
src/lib/dns/tsigerror.cc

@@ -0,0 +1,26 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <ostream>
+
+#include <dns/tsigerror.h>
+
+namespace isc {
+namespace dns {
+std::ostream&
+operator<<(std::ostream& os, const TSIGError& error) {
+    return (os << error.toText());
+}
+} // namespace dns
+} // namespace isc

+ 328 - 0
src/lib/dns/tsigerror.h

@@ -0,0 +1,328 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __TSIGERROR_H
+#define __TSIGERROR_H 1
+
+#include <ostream>
+#include <string>
+
+#include <dns/rcode.h>
+
+namespace isc {
+namespace dns {
+
+class RRClass;
+
+/// TSIG errors
+///
+/// The \c TSIGError class objects represent standard errors related to
+/// TSIG protocol operations as defined in related specifications, mainly
+/// in RFC2845.
+///
+/// (RCODEs) of the header section of DNS messages, and extended response
+/// codes as defined in the EDNS specification.
+class TSIGError {
+public:
+    /// Constants for pre-defined TSIG error values.
+    ///
+    /// Code values from 0 through 15 (inclusive) are derived from those of
+    /// RCODE and are not defined here.  See the \c Rcode class.
+    ///
+    /// \note Unfortunately some systems define "BADSIG" as a macro in a public
+    /// header file.  To avoid conflict with it we add an underscore to our
+    /// definitions.
+    enum CodeValue {
+        BAD_SIG_CODE = 16, ///< 16: TSIG verification failure
+        BAD_KEY_CODE = 17, ///< 17: TSIG key is not recognized
+        BAD_TIME_CODE = 18 ///< 18: Current time and time signed are too different
+    };
+
+    /// \name Constructors
+    ///
+    /// We use the default versions of destructor, copy constructor,
+    /// and assignment operator.
+    //@{
+    /// Constructor from the code value.
+    ///
+    /// \exception None
+    ///
+    /// \param code The underlying 16-bit error code value of the \c TSIGError.
+    explicit TSIGError(uint16_t error_code) : code_(error_code) {}
+
+    /// Constructor from \c Rcode.
+    ///
+    /// As defined in RFC2845, error code values from 0 to 15 (inclusive) are
+    /// derived from the DNS RCODEs, which are represented via the \c Rcode
+    /// class in this library.  This constructor works as a converter from
+    /// these RCODEs to corresponding TSIGError objects.
+    ///
+    /// \exception isc::OutOfRange Given rcode is not convertible to
+    /// TSIGErrors.
+    ///
+    /// \param rcode the \c Rcode from which the TSIGError should be derived.
+    explicit TSIGError(Rcode rcode);
+    //@}
+
+    /// \brief Returns the \c TSIGCode error code value.
+    ///
+    /// \exception None
+    ///
+    /// \return The underlying code value corresponding to the \c TSIGError.
+    uint16_t getCode() const { return (code_); }
+
+    /// \brief Return true iff two \c TSIGError objects are equal.
+    ///
+    /// Two TSIGError objects are equal iff their error codes are equal.
+    ///
+    /// \exception None
+    ///
+    /// \param other the \c TSIGError object to compare against.
+    /// \return true if the two TSIGError are equal; otherwise false.
+    bool equals(const TSIGError& other) const
+    { return (code_ == other.code_); }
+
+    /// \brief Same as \c equals().
+    bool operator==(const TSIGError& other) const { return (equals(other)); }
+
+    /// \brief Return true iff two \c TSIGError objects are not equal.
+    ///
+    /// \exception None
+    ///
+    /// \param other the \c TSIGError object to compare against.
+    /// \return true if the two TSIGError objects are not equal;
+    /// otherwise false.
+    bool nequals(const TSIGError& other) const
+    { return (code_ != other.code_); }
+
+    /// \brief Same as \c nequals().
+    bool operator!=(const TSIGError& other) const { return (nequals(other)); }
+
+    /// \brief Convert the \c TSIGError to a string.
+    ///
+    /// For codes derived from RCODEs up to 15, this method returns the
+    /// same string as \c Rcode::toText() for the corresponding code.
+    /// For other pre-defined code values (see TSIGError::CodeValue),
+    /// this method returns a string representation of the "mnemonic' used
+    /// for the enum and constant objects as defined in RFC2845.
+    /// For example, the string for code value 16 is "BADSIG", etc.
+    /// For other code values it returns a string representation of the decimal
+    /// number of the value, e.g. "32", "100", etc.
+    ///
+    /// \exception std::bad_alloc Resource allocation for the string fails
+    ///
+    /// \return A string representation of the \c TSIGError.
+    std::string toText() const;
+
+    /// A constant TSIG error object derived from \c Rcode::NOERROR()
+    static const TSIGError& NOERROR();
+
+    /// A constant TSIG error object derived from \c Rcode::FORMERR()
+    static const TSIGError& FORMERR();
+
+    /// A constant TSIG error object derived from \c Rcode::SERVFAIL()
+    static const TSIGError& SERVFAIL();
+
+    /// A constant TSIG error object derived from \c Rcode::NXDOMAIN()
+    static const TSIGError& NXDOMAIN();
+
+    /// A constant TSIG error object derived from \c Rcode::NOTIMP()
+    static const TSIGError& NOTIMP();
+
+    /// A constant TSIG error object derived from \c Rcode::REFUSED()
+    static const TSIGError& REFUSED();
+
+    /// A constant TSIG error object derived from \c Rcode::YXDOMAIN()
+    static const TSIGError& YXDOMAIN();
+
+    /// A constant TSIG error object derived from \c Rcode::YXRRSET()
+    static const TSIGError& YXRRSET();
+
+    /// A constant TSIG error object derived from \c Rcode::NXRRSET()
+    static const TSIGError& NXRRSET();
+
+    /// A constant TSIG error object derived from \c Rcode::NOTAUTH()
+    static const TSIGError& NOTAUTH();
+
+    /// A constant TSIG error object derived from \c Rcode::NOTZONE()
+    static const TSIGError& NOTZONE();
+
+    /// A constant TSIG error object derived from \c Rcode::RESERVED11()
+    static const TSIGError& RESERVED11();
+
+    /// A constant TSIG error object derived from \c Rcode::RESERVED12()
+    static const TSIGError& RESERVED12();
+
+    /// A constant TSIG error object derived from \c Rcode::RESERVED13()
+    static const TSIGError& RESERVED13();
+
+    /// A constant TSIG error object derived from \c Rcode::RESERVED14()
+    static const TSIGError& RESERVED14();
+
+    /// A constant TSIG error object derived from \c Rcode::RESERVED15()
+    static const TSIGError& RESERVED15();
+
+    /// A constant TSIG error object for the BADSIG code
+    /// (see \c TSIGError::BAD_SIG_CODE).
+    static const TSIGError& BAD_SIG();
+
+    /// A constant TSIG error object for the BADKEY code
+    /// (see \c TSIGError::BAD_KEY_CODE).
+    static const TSIGError& BAD_KEY();
+
+    /// A constant TSIG error object for the BADTIME code
+    /// (see \c TSIGError::BAD_TIME_CODE).
+    static const TSIGError& BAD_TIME();
+
+private:
+    // This is internally used to specify the maximum possible RCODE value
+    // that can be convertible to TSIGErrors.
+    static const int MAX_RCODE_FOR_TSIGERROR = 15;
+
+    uint16_t code_;
+};
+
+inline const TSIGError&
+TSIGError::NOERROR() {
+    static TSIGError e(Rcode::NOERROR());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::FORMERR() {
+    static TSIGError e(Rcode::FORMERR());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::SERVFAIL() {
+    static TSIGError e(Rcode::SERVFAIL());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::NXDOMAIN() {
+    static TSIGError e(Rcode::NXDOMAIN());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::NOTIMP() {
+    static TSIGError e(Rcode::NOTIMP());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::REFUSED() {
+    static TSIGError e(Rcode::REFUSED());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::YXDOMAIN() {
+    static TSIGError e(Rcode::YXDOMAIN());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::YXRRSET() {
+    static TSIGError e(Rcode::YXRRSET());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::NXRRSET() {
+    static TSIGError e(Rcode::NXRRSET());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::NOTAUTH() {
+    static TSIGError e(Rcode::NOTAUTH());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::NOTZONE() {
+    static TSIGError e(Rcode::NOTZONE());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::RESERVED11() {
+    static TSIGError e(Rcode::RESERVED11());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::RESERVED12() {
+    static TSIGError e(Rcode::RESERVED12());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::RESERVED13() {
+    static TSIGError e(Rcode::RESERVED13());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::RESERVED14() {
+    static TSIGError e(Rcode::RESERVED14());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::RESERVED15() {
+    static TSIGError e(Rcode::RESERVED15());
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::BAD_SIG() {
+    static TSIGError e(BAD_SIG_CODE);
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::BAD_KEY() {
+    static TSIGError e(BAD_KEY_CODE);
+    return (e);
+}
+
+inline const TSIGError&
+TSIGError::BAD_TIME() {
+    static TSIGError e(BAD_TIME_CODE);
+    return (e);
+}
+
+/// Insert the \c TSIGError as a string into stream.
+///
+/// This method convert \c tsig_error into a string and inserts it into the
+/// output stream \c os.
+///
+/// \param os A \c std::ostream object on which the insertion operation is
+/// performed.
+/// \param tsig_error An \c TSIGError object output by the operation.
+/// \return A reference to the same \c std::ostream object referenced by
+/// parameter \c os after the insertion operation.
+std::ostream& operator<<(std::ostream& os, const TSIGError& tsig_error);
+}
+}
+
+#endif  // __TSIGERROR_H
+
+// Local Variables:
+// mode: c++
+// End: