Browse Source

Merge branch 'trac2518'

Mukund Sivaraman 11 years ago
parent
commit
920f29296c

+ 4 - 4
src/bin/auth/auth_srv.cc

@@ -498,7 +498,7 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
             impl_->resumeServer(server, message, stats_attrs, false);
             return;
         }
-    } catch (const Exception& ex) {
+    } catch (const isc::Exception& ex) {
         LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_HEADER_PARSE_FAIL)
                   .arg(ex.what());
         impl_->resumeServer(server, message, stats_attrs, false);
@@ -522,7 +522,7 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
                          stats_attrs);
         impl_->resumeServer(server, message, stats_attrs, true);
         return;
-    } catch (const Exception& ex) {
+    } catch (const isc::Exception& ex) {
         LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_PACKET_PARSE_FAILED)
                   .arg(ex.what());
         makeErrorMessage(impl_->renderer_, message, buffer, Rcode::SERVFAIL(),
@@ -660,7 +660,7 @@ AuthSrvImpl::processNormalQuery(const IOMessage& io_message,
                              stats_attrs);
             return (true);
         }
-    } catch (const Exception& ex) {
+    } catch (const isc::Exception& ex) {
         LOG_ERROR(auth_logger, AUTH_PROCESS_FAIL).arg(ex.what());
         makeErrorMessage(renderer_, message, buffer, Rcode::SERVFAIL(),
                          stats_attrs);
@@ -820,7 +820,7 @@ AuthSrvImpl::processNotify(const IOMessage& io_message, Message& message,
                       .arg(parsed_answer->str());
             return (false);
         }
-    } catch (const Exception& ex) {
+    } catch (const isc::Exception& ex) {
         LOG_ERROR(auth_logger, AUTH_ZONEMGR_COMMS).arg(ex.what());
         return (false);
     }

+ 1 - 1
src/bin/d2/dns_client.cc

@@ -142,7 +142,7 @@ DNSClientImpl::operator()(asiodns::IOFetch::Result result) {
         try {
             response_->fromWire(response_buf);
 
-        } catch (const Exception& ex) {
+        } catch (const isc::Exception& ex) {
             status = DNSClient::INVALID_RESPONSE;
             LOG_DEBUG(dctl_logger, DBGLVL_TRACE_DETAIL,
                       DHCP_DDNS_INVALID_RESPONSE).arg(ex.what());

+ 2 - 2
src/bin/resolver/resolver.cc

@@ -418,7 +418,7 @@ Resolver::processMessage(const IOMessage& io_message,
             server->resume(false);
             return;
         }
-    } catch (const Exception& ex) {
+    } catch (const isc::Exception& ex) {
         LOG_DEBUG(resolver_logger, RESOLVER_DBG_IO,
                   RESOLVER_HEADER_PROCESSING_FAILED).arg(ex.what());
         server->resume(false);
@@ -436,7 +436,7 @@ Resolver::processMessage(const IOMessage& io_message,
                          buffer, error.getRcode());
         server->resume(true);
         return;
-    } catch (const Exception& ex) {
+    } catch (const isc::Exception& ex) {
         LOG_DEBUG(resolver_logger, RESOLVER_DBG_IO,
                   RESOLVER_MESSAGE_PROCESSING_FAILED)
                   .arg(ex.what()).arg(Rcode::SERVFAIL());

+ 27 - 2
src/lib/dns/exceptions.h

@@ -30,10 +30,34 @@ namespace dns {
 ///
 class Rcode;                    // forward declaration
 
-class DNSProtocolError : public isc::Exception {
+class Exception : public isc::Exception {
 public:
-    DNSProtocolError(const char* file, size_t line, const char* what) :
+    Exception(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
+};
+
+///
+/// \brief Base class for all sorts of text parse errors.
+///
+class DNSTextError : public isc::dns::Exception {
+public:
+    DNSTextError(const char* file, size_t line, const char* what) :
+        isc::dns::Exception(file, line, what) {}
+};
+
+///
+/// \brief Base class for name parser exceptions.
+///
+class NameParserException : public DNSTextError {
+public:
+    NameParserException(const char* file, size_t line, const char* what) :
+        DNSTextError(file, line, what) {}
+};
+
+class DNSProtocolError : public isc::dns::Exception {
+public:
+    DNSProtocolError(const char* file, size_t line, const char* what) :
+        isc::dns::Exception(file, line, what) {}
     virtual const Rcode& getRcode() const = 0;
 };
 
@@ -50,6 +74,7 @@ public:
         DNSProtocolError(file, line, what) {}
     virtual const Rcode& getRcode() const;
 };
+
 }
 }
 #endif  // DNS_EXCEPTIONS_H

+ 3 - 3
src/lib/dns/master_lexer.h

@@ -15,7 +15,7 @@
 #ifndef MASTER_LEXER_H
 #define MASTER_LEXER_H 1
 
-#include <exceptions/exceptions.h>
+#include <dns/exceptions.h>
 
 #include <istream>
 #include <string>
@@ -324,10 +324,10 @@ public:
     ///
     /// The \c token_ member variable (read-only) is set to a \c MasterToken
     /// object of type ERROR indicating the reason for the error.
-    class LexerError : public Exception {
+    class LexerError : public isc::dns::Exception {
     public:
         LexerError(const char* file, size_t line, MasterToken error_token) :
-            Exception(file, line, error_token.getErrorText().c_str()),
+            isc::dns::Exception(file, line, error_token.getErrorText().c_str()),
             token_(error_token)
         {}
         const MasterToken token_;

+ 13 - 9
src/lib/dns/master_loader.cc

@@ -995,15 +995,19 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) {
                     isc_throw(MasterLoaderError, "Invalid RR data");
                 }
             }
-        } catch (const MasterLoaderError&) {
-            // This is a hack. We exclude the MasterLoaderError from the
-            // below case. Once we restrict the below to some smaller
-            // exception, we should remove this.
-            throw;
-        } catch (const isc::Exception& e) {
-            // TODO: Once we do #2518, catch only the DNSTextError here,
-            // not isc::Exception. The rest should be just simply
-            // propagated.
+        } catch (const isc::dns::DNSTextError& e) {
+            reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
+                        e.what());
+            eatUntilEOL(false);
+        } catch (const MasterLexer::ReadError& e) {
+            reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
+                        e.what());
+            eatUntilEOL(false);
+        } catch (const MasterLexer::LexerError& e) {
+            reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
+                        e.what());
+            eatUntilEOL(false);
+        } catch (const InternalException& e) {
             reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
                         e.what());
             eatUntilEOL(false);

+ 9 - 9
src/lib/dns/message.h

@@ -21,7 +21,7 @@
 #include <string>
 #include <ostream>
 
-#include <exceptions/exceptions.h>
+#include <dns/exceptions.h>
 
 #include <dns/edns.h>
 #include <dns/question.h>
@@ -41,10 +41,10 @@ class TSIGRecord;
 /// message parser encounters a short length of data that don't even contain
 /// the full header section.
 ///
-class MessageTooShort : public Exception {
+class MessageTooShort : public isc::dns::Exception {
 public:
     MessageTooShort(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        isc::dns::Exception(file, line, what) {}
 };
 
 ///
@@ -52,10 +52,10 @@ public:
 /// is being constructed for an incompatible section.  Specifically, this
 /// happens RRset iterator is being constructed for a Question section.
 ///
-class InvalidMessageSection : public Exception {
+class InvalidMessageSection : public isc::dns::Exception {
 public:
     InvalidMessageSection(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        isc::dns::Exception(file, line, what) {}
 };
 
 ///
@@ -63,10 +63,10 @@ public:
 /// class method is called that is prohibited for the current mode of
 /// the message.
 ///
-class InvalidMessageOperation : public Exception {
+class InvalidMessageOperation : public isc::dns::Exception {
 public:
     InvalidMessageOperation(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        isc::dns::Exception(file, line, what) {}
 };
 
 ///
@@ -74,10 +74,10 @@ public:
 /// smaller than the standard default maximum (DEFAULT_MAX_UDPSIZE) is
 /// being specified for the message.
 ///
-class InvalidMessageUDPSize : public Exception {
+class InvalidMessageUDPSize : public isc::dns::Exception {
 public:
     InvalidMessageUDPSize(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        isc::dns::Exception(file, line, what) {}
 };
 
 typedef uint16_t qid_t;

+ 1 - 10
src/lib/dns/name.h

@@ -20,7 +20,7 @@
 #include <string>
 #include <vector>
 
-#include <exceptions/exceptions.h>
+#include <dns/exceptions.h>
 
 namespace isc {
 namespace util {
@@ -32,15 +32,6 @@ namespace dns {
 class AbstractMessageRenderer;
 
 ///
-/// \brief Base class for name parser exceptions.
-///
-class NameParserException : public Exception {
-public:
-    NameParserException(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
-///
 /// \brief A standard DNS module exception that is thrown if the name parser
 /// encounters an empty label in the middle of a name.
 ///

+ 1 - 1
src/lib/dns/python/name_python.cc

@@ -537,6 +537,7 @@ namespace python {
 // Initialization and addition of these go in the module init at the
 // end
 //
+PyObject* po_NameParserException;
 PyObject* po_EmptyLabel;
 PyObject* po_TooLongName;
 PyObject* po_TooLongLabel;
@@ -544,7 +545,6 @@ PyObject* po_BadLabelType;
 PyObject* po_BadEscape;
 PyObject* po_IncompleteName;
 PyObject* po_InvalidBufferPosition;
-PyObject* po_DNSMessageFORMERR;
 
 //
 // Definition of enums

+ 1 - 1
src/lib/dns/python/name_python.h

@@ -23,6 +23,7 @@ class Name;
 
 namespace python {
 
+extern PyObject* po_NameParserException;
 extern PyObject* po_EmptyLabel;
 extern PyObject* po_TooLongName;
 extern PyObject* po_TooLongLabel;
@@ -30,7 +31,6 @@ extern PyObject* po_BadLabelType;
 extern PyObject* po_BadEscape;
 extern PyObject* po_IncompleteName;
 extern PyObject* po_InvalidBufferPosition;
-extern PyObject* po_DNSMessageFORMERR;
 
 //
 // Declaration of enums

+ 49 - 21
src/lib/dns/python/pydnspp.cc

@@ -28,6 +28,7 @@
 #include <Python.h>
 #include <structmember.h>
 
+#include <dns/exceptions.h>
 #include <dns/message.h>
 #include <dns/opcode.h>
 #include <dns/tsig.h>
@@ -152,8 +153,14 @@ initModulePart_Message(PyObject* mod) {
             PyErr_NewException("pydnspp.InvalidMessageUDPSize", NULL, NULL);
         PyObjectContainer(po_InvalidMessageUDPSize).installToModule(
             mod, "InvalidMessageUDPSize");
+        po_DNSMessageFORMERR =
+            PyErr_NewException("pydnspp.DNSMessageFORMERR",
+                               po_DNSProtocolError, NULL);
+        PyObjectContainer(po_DNSMessageFORMERR).installToModule(
+            mod, "DNSMessageFORMERR");
         po_DNSMessageBADVERS =
-            PyErr_NewException("pydnspp.DNSMessageBADVERS", NULL, NULL);
+            PyErr_NewException("pydnspp.DNSMessageBADVERS",
+                               po_DNSProtocolError, NULL);
         PyObjectContainer(po_DNSMessageBADVERS).installToModule(
             mod, "DNSMessageBADVERS");
         po_UnknownNSEC3HashAlgorithm =
@@ -243,36 +250,40 @@ initModulePart_Name(PyObject* mod) {
 
     // Add the exceptions to the module
     try {
-        po_EmptyLabel = PyErr_NewException("pydnspp.EmptyLabel", NULL, NULL);
+        po_NameParserException =
+            PyErr_NewException("pydnspp.NameParserException",
+                               po_DNSTextError, NULL);
+        PyObjectContainer(po_NameParserException)
+            .installToModule(mod, "NameParserException");
+
+        po_EmptyLabel = PyErr_NewException("pydnspp.EmptyLabel",
+                                           po_NameParserException, NULL);
         PyObjectContainer(po_EmptyLabel).installToModule(mod, "EmptyLabel");
 
-        po_TooLongName = PyErr_NewException("pydnspp.TooLongName", NULL, NULL);
+        po_TooLongName = PyErr_NewException("pydnspp.TooLongName",
+                                            po_NameParserException, NULL);
         PyObjectContainer(po_TooLongName).installToModule(mod, "TooLongName");
 
-        po_TooLongLabel = PyErr_NewException("pydnspp.TooLongLabel", NULL, NULL);
+        po_TooLongLabel = PyErr_NewException("pydnspp.TooLongLabel",
+                                             po_NameParserException, NULL);
         PyObjectContainer(po_TooLongLabel).installToModule(mod, "TooLongLabel");
 
-        po_BadLabelType = PyErr_NewException("pydnspp.BadLabelType", NULL, NULL);
+        po_BadLabelType = PyErr_NewException("pydnspp.BadLabelType",
+                                             po_NameParserException, NULL);
         PyObjectContainer(po_BadLabelType).installToModule(mod, "BadLabelType");
 
-        po_BadEscape = PyErr_NewException("pydnspp.BadEscape", NULL, NULL);
+        po_BadEscape = PyErr_NewException("pydnspp.BadEscape",
+                                          po_NameParserException, NULL);
         PyObjectContainer(po_BadEscape).installToModule(mod, "BadEscape");
 
-        po_IncompleteName = PyErr_NewException("pydnspp.IncompleteName", NULL,
-                                               NULL);
+        po_IncompleteName = PyErr_NewException("pydnspp.IncompleteName",
+                                               po_NameParserException, NULL);
         PyObjectContainer(po_IncompleteName).installToModule(mod, "IncompleteName");
 
         po_InvalidBufferPosition =
             PyErr_NewException("pydnspp.InvalidBufferPosition", NULL, NULL);
         PyObjectContainer(po_InvalidBufferPosition).installToModule(
             mod, "InvalidBufferPosition");
-
-        // This one could have gone into the message_python.cc file, but is
-        // already needed here.
-        po_DNSMessageFORMERR = PyErr_NewException("pydnspp.DNSMessageFORMERR",
-                                                  NULL, NULL);
-        PyObjectContainer(po_DNSMessageFORMERR).installToModule(
-            mod, "DNSMessageFORMERR");
     } catch (const std::exception& ex) {
         const std::string ex_what =
             "Unexpected failure in Name initialization: " +
@@ -865,14 +876,31 @@ PyInit_pydnspp(void) {
         PyObjectContainer(po_IscException).installToModule(mod, "IscException");
 
         po_InvalidOperation = PyErr_NewException("pydnspp.InvalidOperation",
-                                                 NULL, NULL);
-        PyObjectContainer(po_InvalidOperation).installToModule(
-            mod, "InvalidOperation");
+                                                 po_IscException, NULL);
+        PyObjectContainer(po_InvalidOperation)
+            .installToModule(mod, "InvalidOperation");
 
         po_InvalidParameter = PyErr_NewException("pydnspp.InvalidParameter",
-                                                 NULL, NULL);
-        PyObjectContainer(po_InvalidParameter).installToModule(
-            mod, "InvalidParameter");
+                                                 po_IscException, NULL);
+        PyObjectContainer(po_InvalidParameter)
+            .installToModule(mod, "InvalidParameter");
+
+        // Add DNS exceptions
+        po_DNSException = PyErr_NewException("pydnspp.DNSException",
+                                             po_IscException, NULL);
+        PyObjectContainer(po_DNSException)
+            .installToModule(mod, "DNSException");
+
+        po_DNSTextError = PyErr_NewException("pydnspp.DNSTextError",
+                                             po_DNSException, NULL);
+        PyObjectContainer(po_DNSTextError)
+            .installToModule(mod, "DNSTextError");
+
+        po_DNSProtocolError = PyErr_NewException("pydnspp.DNSProtocolError",
+                                             po_DNSException, NULL);
+        PyObjectContainer(po_DNSProtocolError)
+            .installToModule(mod, "DNSProtocolError");
+
     } catch (const std::exception& ex) {
         const std::string ex_what =
             "Unexpected failure in pydnspp initialization: " +

+ 5 - 1
src/lib/dns/python/pydnspp_common.cc

@@ -50,7 +50,11 @@ PyObject* po_IscException;
 PyObject* po_InvalidOperation;
 PyObject* po_InvalidParameter;
 
-// For our own isc::dns::Exception
+// For DNS exceptions
+PyObject* po_DNSException;
+PyObject* po_DNSTextError;
+PyObject* po_DNSProtocolError;
+PyObject* po_DNSMessageFORMERR;
 PyObject* po_DNSMessageBADVERS;
 
 

+ 4 - 0
src/lib/dns/python/pydnspp_common.h

@@ -34,6 +34,10 @@ extern PyObject* po_InvalidOperation;
 extern PyObject* po_InvalidParameter;
 
 // For our own isc::dns::Exception
+extern PyObject* po_DNSException;
+extern PyObject* po_DNSTextError;
+extern PyObject* po_DNSProtocolError;
+extern PyObject* po_DNSMessageFORMERR;
 extern PyObject* po_DNSMessageBADVERS;
 
 // This function reads 'bytes' from a sequence

+ 1 - 0
src/lib/dns/python/rdata_python.cc

@@ -25,6 +25,7 @@
 #include "rrclass_python.h"
 #include "messagerenderer_python.h"
 #include "name_python.h"
+#include "pydnspp_common.h"
 
 using namespace isc::dns;
 using namespace isc::dns::python;

+ 1 - 0
src/lib/dns/python/tests/Makefile.am

@@ -6,6 +6,7 @@ PYTESTS += name_python_test.py
 PYTESTS += nsec3hash_python_test.py
 PYTESTS += question_python_test.py
 PYTESTS += opcode_python_test.py
+PYTESTS += pydnspp_python_test.py
 PYTESTS += rcode_python_test.py
 PYTESTS += rdata_python_test.py
 PYTESTS += rrclass_python_test.py

+ 11 - 1
src/lib/dns/python/tests/name_python_test.py

@@ -14,7 +14,7 @@
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Tests for the messagerenderer part of the pydnspp module
+# Tests for the name part of the pydnspp module
 #
 
 import unittest
@@ -97,6 +97,16 @@ class NameTest(unittest.TestCase):
         self.assertRaises(DNSMessageFORMERR, Name, b, 0)
         self.assertRaises(IndexError, Name, b, -1)
 
+    def test_exception_hierarchy(self):
+        self.assertTrue(isinstance(EmptyLabel(), NameParserException))
+        self.assertTrue(isinstance(TooLongLabel(), NameParserException))
+        self.assertTrue(isinstance(BadLabelType(), NameParserException))
+        self.assertTrue(isinstance(BadEscape(), NameParserException))
+        self.assertTrue(isinstance(TooLongName(), NameParserException))
+        self.assertTrue(isinstance(IncompleteName(), NameParserException))
+
+        self.assertTrue(isinstance(NameParserException(), DNSTextError))
+
     def test_at(self):
         self.assertEqual(7, self.name1.at(0))
         self.assertEqual(101, self.name1.at(1))

+ 34 - 0
src/lib/dns/python/tests/pydnspp_python_test.py

@@ -0,0 +1,34 @@
+# Copyright (C) 2014  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and 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 INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM 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.
+
+#
+# Tests for the common part of the pydnspp module
+#
+
+import unittest
+import os
+from pydnspp import *
+
+class CommonTest(unittest.TestCase):
+    def test_exception_hierarchy(self):
+        self.assertTrue(isinstance(InvalidOperation(), IscException))
+        self.assertTrue(isinstance(InvalidParameter(), IscException))
+
+        self.assertTrue(isinstance(DNSException(), IscException))
+        self.assertTrue(isinstance(DNSTextError(), DNSException))
+        self.assertTrue(isinstance(DNSProtocolError(), DNSException))
+
+if __name__ == '__main__':
+    unittest.main()

+ 7 - 7
src/lib/dns/rdata.h

@@ -19,7 +19,7 @@
 #include <dns/master_loader.h>
 #include <dns/master_loader_callbacks.h>
 
-#include <exceptions/exceptions.h>
+#include <dns/exceptions.h>
 
 #include <boost/shared_ptr.hpp>
 
@@ -42,20 +42,20 @@ namespace rdata {
 /// \brief A standard DNS module exception that is thrown if RDATA parser
 /// encounters an invalid or inconsistent data length.
 ///
-class InvalidRdataLength : public Exception {
+class InvalidRdataLength : public DNSTextError {
 public:
     InvalidRdataLength(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        DNSTextError(file, line, what) {}
 };
 
 ///
 /// \brief A standard DNS module exception that is thrown if RDATA parser
 /// fails to recognize a given textual representation.
 ///
-class InvalidRdataText : public Exception {
+class InvalidRdataText : public DNSTextError {
 public:
     InvalidRdataText(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        DNSTextError(file, line, what) {}
 };
 
 ///
@@ -63,10 +63,10 @@ public:
 /// encounters a character-string (as defined in RFC1035) exceeding
 /// the maximum allowable length (\c MAX_CHARSTRING_LEN).
 ///
-class CharStringTooLong : public Exception {
+class CharStringTooLong : public DNSTextError {
 public:
     CharStringTooLong(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        DNSTextError(file, line, what) {}
 };
 
 // Forward declaration to define RdataPtr.

+ 5 - 5
src/lib/dns/rrclass-placeholder.h

@@ -20,7 +20,7 @@
 #include <string>
 #include <ostream>
 
-#include <exceptions/exceptions.h>
+#include <dns/exceptions.h>
 
 #include <boost/optional.hpp>
 
@@ -39,20 +39,20 @@ class AbstractMessageRenderer;
 /// \brief A standard DNS module exception that is thrown if an RRClass object
 /// is being constructed from an unrecognized string.
 ///
-class InvalidRRClass : public Exception {
+class InvalidRRClass : public DNSTextError {
 public:
     InvalidRRClass(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        DNSTextError(file, line, what) {}
 };
 
 ///
 /// \brief A standard DNS module exception that is thrown if an RRClass object
 /// is being constructed from a incomplete (too short) wire-format data.
 ///
-class IncompleteRRClass : public Exception {
+class IncompleteRRClass : public isc::dns::Exception {
 public:
     IncompleteRRClass(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        isc::dns::Exception(file, line, what) {}
 };
 
 ///

+ 5 - 5
src/lib/dns/rrparamregistry.h

@@ -21,7 +21,7 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include <exceptions/exceptions.h>
+#include <dns/exceptions.h>
 
 #include <dns/rdata.h>
 
@@ -35,20 +35,20 @@ struct RRParamRegistryImpl;
 /// \brief A standard DNS module exception that is thrown if a new RR type is
 /// being registered with a different type string.
 ///
-class RRTypeExists : public Exception {
+class RRTypeExists : public isc::dns::Exception {
 public:
     RRTypeExists(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        isc::dns::Exception(file, line, what) {}
 };
 
 ///
 /// \brief A standard DNS module exception that is thrown if a new RR class is
 /// being registered with a different type string.
 ///
-class RRClassExists : public Exception {
+class RRClassExists : public isc::dns::Exception {
 public:
     RRClassExists(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        isc::dns::Exception(file, line, what) {}
 };
 
 namespace rdata {

+ 3 - 3
src/lib/dns/rrset.h

@@ -20,7 +20,7 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include <exceptions/exceptions.h>
+#include <dns/exceptions.h>
 
 #include <dns/rdata.h>
 #include <dns/rrtype.h>
@@ -36,10 +36,10 @@ namespace dns {
 /// \brief A standard DNS module exception that is thrown if an RRset object
 /// does not contain any RDATA where required.
 ///
-class EmptyRRset : public Exception {
+class EmptyRRset : public isc::dns::Exception {
 public:
     EmptyRRset(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        isc::dns::Exception(file, line, what) {}
 };
 
 // forward declarations

+ 5 - 5
src/lib/dns/rrttl.h

@@ -15,7 +15,7 @@
 #ifndef RRTTL_H
 #define RRTTL_H 1
 
-#include <exceptions/exceptions.h>
+#include <dns/exceptions.h>
 
 #include <boost/optional.hpp>
 
@@ -36,20 +36,20 @@ class AbstractMessageRenderer;
 /// \brief A standard DNS module exception that is thrown if an RRTTL object
 /// is being constructed from an unrecognized string.
 ///
-class InvalidRRTTL : public Exception {
+class InvalidRRTTL : public DNSTextError {
 public:
     InvalidRRTTL(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        DNSTextError(file, line, what) {}
 };
 
 ///
 /// \brief A standard DNS module exception that is thrown if an RRTTL object
 /// is being constructed from a incomplete (too short) wire-format data.
 ///
-class IncompleteRRTTL : public Exception {
+class IncompleteRRTTL : public isc::dns::Exception {
 public:
     IncompleteRRTTL(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        isc::dns::Exception(file, line, what) {}
 };
 
 ///

+ 5 - 5
src/lib/dns/rrtype-placeholder.h

@@ -20,7 +20,7 @@
 #include <string>
 #include <ostream>
 
-#include <exceptions/exceptions.h>
+#include <dns/exceptions.h>
 
 // Solaris x86 defines DS in <sys/regset.h>, which gets pulled in by Boost
 #if defined(__sun) && defined(DS)
@@ -42,20 +42,20 @@ class AbstractMessageRenderer;
 /// \brief A standard DNS module exception that is thrown if an RRType object
 /// is being constructed from an unrecognized string.
 ///
-class InvalidRRType : public Exception {
+class InvalidRRType : public DNSTextError {
 public:
     InvalidRRType(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        DNSTextError(file, line, what) {}
 };
 
 ///
 /// \brief A standard DNS module exception that is thrown if an RRType object
 /// is being constructed from a incomplete (too short) wire-format data.
 ///
-class IncompleteRRType : public Exception {
+class IncompleteRRType : public isc::dns::Exception {
 public:
     IncompleteRRType(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
+        isc::dns::Exception(file, line, what) {}
 };
 
 ///

+ 1 - 0
src/lib/dns/tests/Makefile.am

@@ -21,6 +21,7 @@ TESTS =
 if HAVE_GTEST
 TESTS += run_unittests
 run_unittests_SOURCES = unittest_util.h unittest_util.cc
+run_unittests_SOURCES += dns_exceptions_unittest.cc
 run_unittests_SOURCES += edns_unittest.cc
 run_unittests_SOURCES += master_lexer_inputsource_unittest.cc
 run_unittests_SOURCES += labelsequence_unittest.cc

+ 69 - 0
src/lib/dns/tests/dns_exceptions_unittest.cc

@@ -0,0 +1,69 @@
+// Copyright (C) 2014  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 <dns/exceptions.h>
+
+#include <gtest/gtest.h>
+
+namespace { // begin unnamed namespace
+
+TEST(DNSExceptionsTest, checkExceptionsHierarchy) {
+    EXPECT_NO_THROW({
+        const isc::dns::Exception exception("", 0, "");
+        const isc::Exception& exception_cast =
+          dynamic_cast<const isc::Exception&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+    });
+
+    EXPECT_NO_THROW({
+        const isc::dns::DNSTextError exception("", 0, "");
+        const isc::dns::Exception& exception_cast =
+          dynamic_cast<const isc::dns::Exception&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+    });
+
+    EXPECT_NO_THROW({
+        const isc::dns::NameParserException exception("", 0, "");
+        const isc::dns::DNSTextError& exception_cast =
+          dynamic_cast<const isc::dns::DNSTextError&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+    });
+
+    EXPECT_NO_THROW({
+        const isc::dns::DNSMessageFORMERR exception("", 0, "");
+        const isc::dns::DNSProtocolError& exception_cast =
+          dynamic_cast<const isc::dns::DNSProtocolError&>(exception);
+        const isc::dns::Exception& exception_cast2 =
+          dynamic_cast<const isc::dns::Exception&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+        exception_cast2.what();
+    });
+
+    EXPECT_NO_THROW({
+        const isc::dns::DNSMessageBADVERS exception("", 0, "");
+        const isc::dns::DNSProtocolError& exception_cast =
+          dynamic_cast<const isc::dns::DNSProtocolError&>(exception);
+        const isc::dns::Exception& exception_cast2 =
+          dynamic_cast<const isc::dns::Exception&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+        exception_cast2.what();
+    });
+}
+
+} // end unnamed namespace

+ 58 - 0
src/lib/dns/tests/name_unittest.cc

@@ -164,6 +164,64 @@ checkBadTextName(const string& txt) {
                  NameParserException);
 }
 
+TEST_F(NameTest, checkExceptionsHierarchy) {
+    EXPECT_NO_THROW({
+        const isc::dns::EmptyLabel exception("", 0, "");
+        const isc::dns::NameParserException& exception_cast =
+          dynamic_cast<const isc::dns::NameParserException&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+    });
+
+    EXPECT_NO_THROW({
+        const isc::dns::TooLongName exception("", 0, "");
+        const isc::dns::NameParserException& exception_cast =
+          dynamic_cast<const isc::dns::NameParserException&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+    });
+
+    EXPECT_NO_THROW({
+        const isc::dns::TooLongLabel exception("", 0, "");
+        const isc::dns::NameParserException& exception_cast =
+          dynamic_cast<const isc::dns::NameParserException&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+    });
+
+    EXPECT_NO_THROW({
+        const isc::dns::BadLabelType exception("", 0, "");
+        const isc::dns::NameParserException& exception_cast =
+          dynamic_cast<const isc::dns::NameParserException&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+    });
+
+    EXPECT_NO_THROW({
+        const isc::dns::BadEscape exception("", 0, "");
+        const isc::dns::NameParserException& exception_cast =
+          dynamic_cast<const isc::dns::NameParserException&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+    });
+
+    EXPECT_NO_THROW({
+        const isc::dns::IncompleteName exception("", 0, "");
+        const isc::dns::NameParserException& exception_cast =
+          dynamic_cast<const isc::dns::NameParserException&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+    });
+
+    EXPECT_NO_THROW({
+        const isc::dns::MissingNameOrigin exception("", 0, "");
+        const isc::dns::NameParserException& exception_cast =
+          dynamic_cast<const isc::dns::NameParserException&>(exception);
+        // to avoid compiler warning
+        exception_cast.what();
+    });
+}
+
 TEST_F(NameTest, fromText) {
     vector<string> strnames;
     strnames.push_back("www.example.com");

+ 15 - 15
src/lib/dns/tsig.cc

@@ -79,7 +79,7 @@ struct TSIGContext::TSIGContextImpl {
                                 key_.getSecret(), key_.getSecretLength(),
                                 key_.getAlgorithm()),
                             deleteHMAC);
-            } catch (const Exception&) {
+            } catch (const isc::Exception&) {
                 return;
             }
             digest_len_ = hmac_->getOutputLength();
@@ -289,20 +289,20 @@ TSIGContext::getTSIGLength() const {
     //
     // The space required for an TSIG record is:
     //
-    //	n1 bytes for the (key) name
-    //	2 bytes for the type
-    //	2 bytes for the class
-    //	4 bytes for the ttl
-    //	2 bytes for the rdlength
-    //	n2 bytes for the algorithm name
-    //	6 bytes for the time signed
-    //	2 bytes for the fudge
-    //	2 bytes for the MAC size
-    //	x bytes for the MAC
-    //	2 bytes for the original id
-    //	2 bytes for the error
-    //	2 bytes for the other data length
-    //	y bytes for the other data (at most)
+    //  n1 bytes for the (key) name
+    //  2 bytes for the type
+    //  2 bytes for the class
+    //  4 bytes for the ttl
+    //  2 bytes for the rdlength
+    //  n2 bytes for the algorithm name
+    //  6 bytes for the time signed
+    //  2 bytes for the fudge
+    //  2 bytes for the MAC size
+    //  x bytes for the MAC
+    //  2 bytes for the original id
+    //  2 bytes for the error
+    //  2 bytes for the other data length
+    //  y bytes for the other data (at most)
     // ---------------------------------
     //     26 + n1 + n2 + x + y bytes
     //

+ 1 - 1
src/lib/dns/tsigkey.cc

@@ -141,7 +141,7 @@ TSIGKey::TSIGKey(const std::string& str) : impl_(NULL) {
         impl_ = new TSIGKeyImpl(Name(keyname_str), algo_name, algorithm,
                                 secret.empty() ? NULL : &secret[0],
                                 secret.size());
-    } catch (const Exception& e) {
+    } catch (const isc::Exception& e) {
         // 'reduce' the several types of exceptions name parsing and
         // Base64 decoding can throw to just the InvalidParameter
         isc_throw(InvalidParameter, e.what());