Browse Source

[trac905] other adjustment to support TSIGError. Rcode binding was also
decoupled from the main pydnspp so that it can be used from tsigerror_python
separately (there should be no behavior change to the Rcode binding itself)

JINMEI Tatuya 14 years ago
parent
commit
1ea71dc169

+ 2 - 0
src/lib/dns/python/Makefile.am

@@ -6,6 +6,8 @@ AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 
 pyexec_LTLIBRARIES = pydnspp.la
 pyexec_LTLIBRARIES = pydnspp.la
 pydnspp_la_SOURCES = pydnspp.cc pydnspp_common.cc
 pydnspp_la_SOURCES = pydnspp.cc pydnspp_common.cc
+pydnspp_la_SOURCES += rcode_python.cc rcode_python.h
+pydnspp_la_SOURCES += tsigerror_python.cc tsigerror_python.h
 pydnspp_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
 pydnspp_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
 pydnspp_la_LDFLAGS = $(PYTHON_LDFLAGS)
 pydnspp_la_LDFLAGS = $(PYTHON_LDFLAGS)
 
 

+ 4 - 4
src/lib/dns/python/message_python.cc

@@ -336,15 +336,15 @@ Message_getRcode(s_Message* self) {
 
 
     rcode = static_cast<s_Rcode*>(rcode_type.tp_alloc(&rcode_type, 0));
     rcode = static_cast<s_Rcode*>(rcode_type.tp_alloc(&rcode_type, 0));
     if (rcode != NULL) {
     if (rcode != NULL) {
-        rcode->rcode = NULL;
+        rcode->cppobj = NULL;
         try {
         try {
-            rcode->rcode = new Rcode(self->message->getRcode());
+            rcode->cppobj = new Rcode(self->message->getRcode());
         } catch (const InvalidMessageOperation& imo) {
         } catch (const InvalidMessageOperation& imo) {
             PyErr_SetString(po_InvalidMessageOperation, imo.what());
             PyErr_SetString(po_InvalidMessageOperation, imo.what());
         } catch (...) {
         } catch (...) {
             PyErr_SetString(po_IscException, "Unexpected exception");
             PyErr_SetString(po_IscException, "Unexpected exception");
         }
         }
-        if (rcode->rcode == NULL) {
+        if (rcode->cppobj == NULL) {
             Py_DECREF(rcode);
             Py_DECREF(rcode);
             return (NULL);
             return (NULL);
         }
         }
@@ -360,7 +360,7 @@ Message_setRcode(s_Message* self, PyObject* args) {
         return (NULL);
         return (NULL);
     }
     }
     try {
     try {
-        self->message->setRcode(*rcode->rcode);
+        self->message->setRcode(*rcode->cppobj);
         Py_RETURN_NONE;
         Py_RETURN_NONE;
     } catch (const InvalidMessageOperation& imo) {
     } catch (const InvalidMessageOperation& imo) {
         PyErr_SetString(po_InvalidMessageOperation, imo.what());
         PyErr_SetString(po_InvalidMessageOperation, imo.what());

+ 24 - 7
src/lib/dns/python/pydnspp.cc

@@ -32,20 +32,32 @@
 #include <exceptions/exceptions.h>
 #include <exceptions/exceptions.h>
 
 
 #include <util/buffer.h>
 #include <util/buffer.h>
+
 #include <dns/exceptions.h>
 #include <dns/exceptions.h>
 #include <dns/name.h>
 #include <dns/name.h>
 #include <dns/messagerenderer.h>
 #include <dns/messagerenderer.h>
 
 
-#include <dns/python/pydnspp_common.h>
+#include "pydnspp_common.h"
 
 
+namespace isc {
+namespace dns {
+namespace python {
 // For our 'general' isc::Exceptions
 // For our 'general' isc::Exceptions
-static PyObject* po_IscException;
-static PyObject* po_InvalidParameter;
+PyObject* po_IscException;
+PyObject* po_InvalidParameter;
 
 
 // For our own isc::dns::Exception
 // For our own isc::dns::Exception
-static PyObject* po_DNSMessageBADVERS;
+PyObject* po_DNSMessageBADVERS;
+}
+}
+}
+
+#include "rcode_python.h"
+#include "tsigerror_python.h"
 
 
 // order is important here!
 // order is important here!
+using namespace isc::dns::python;
+
 #include <dns/python/messagerenderer_python.cc>
 #include <dns/python/messagerenderer_python.cc>
 #include <dns/python/name_python.cc>           // needs Messagerenderer
 #include <dns/python/name_python.cc>           // needs Messagerenderer
 #include <dns/python/rrclass_python.cc>        // needs Messagerenderer
 #include <dns/python/rrclass_python.cc>        // needs Messagerenderer
@@ -58,14 +70,14 @@ static PyObject* po_DNSMessageBADVERS;
 #include <dns/python/tsigkey_python.cc>        // needs Name
 #include <dns/python/tsigkey_python.cc>        // needs Name
 #include <dns/python/tsig_python.cc>           // needs tsigkey
 #include <dns/python/tsig_python.cc>           // needs tsigkey
 #include <dns/python/opcode_python.cc>
 #include <dns/python/opcode_python.cc>
-#include <dns/python/rcode_python.cc>
 #include <dns/python/edns_python.cc>           // needs Messagerenderer, Rcode
 #include <dns/python/edns_python.cc>           // needs Messagerenderer, Rcode
 #include <dns/python/message_python.cc>        // needs RRset, Question
 #include <dns/python/message_python.cc>        // needs RRset, Question
 
 
 //
 //
 // Definition of the module
 // Definition of the module
 //
 //
-static PyModuleDef pydnspp = {
+namespace {
+PyModuleDef pydnspp = {
     { PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
     { PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
     "pydnspp",
     "pydnspp",
     "Python bindings for the classes in the isc::dns namespace.\n\n"
     "Python bindings for the classes in the isc::dns namespace.\n\n"
@@ -80,10 +92,11 @@ static PyModuleDef pydnspp = {
     NULL,
     NULL,
     NULL
     NULL
 };
 };
+}
 
 
 PyMODINIT_FUNC
 PyMODINIT_FUNC
 PyInit_pydnspp(void) {
 PyInit_pydnspp(void) {
-    PyObject *mod = PyModule_Create(&pydnspp);
+    PyObject* mod = PyModule_Create(&pydnspp);
     if (mod == NULL) {
     if (mod == NULL) {
         return (NULL);
         return (NULL);
     }
     }
@@ -154,6 +167,10 @@ PyInit_pydnspp(void) {
         return (NULL);
         return (NULL);
     }
     }
 
 
+    if (!initModulePart_TSIGError(mod)) {
+        return (NULL);
+    }
+
     if (!initModulePart_TSIGContext(mod)) {
     if (!initModulePart_TSIGContext(mod)) {
         return (NULL);
         return (NULL);
     }
     }

+ 14 - 4
src/lib/dns/python/pydnspp_common.cc

@@ -15,6 +15,9 @@
 #include <Python.h>
 #include <Python.h>
 #include <pydnspp_common.h>
 #include <pydnspp_common.h>
 
 
+namespace isc {
+namespace dns {
+namespace python {
 int
 int
 readDataFromSequence(uint8_t *data, size_t len, PyObject* sequence) {
 readDataFromSequence(uint8_t *data, size_t len, PyObject* sequence) {
     PyObject* el = NULL;
     PyObject* el = NULL;
@@ -44,8 +47,15 @@ readDataFromSequence(uint8_t *data, size_t len, PyObject* sequence) {
 }
 }
 
 
 
 
-void addClassVariable(PyTypeObject& c, const char* name,
-                      PyObject* obj)
-{
-    PyDict_SetItemString(c.tp_dict, name, obj);
+int
+addClassVariable(PyTypeObject& c, const char* name, PyObject* obj) {
+    if (obj == NULL) {
+        PyErr_SetString(PyExc_ValueError,
+                        "NULL object is specified for a class variable");
+        return (-1);
+    }
+    return (PyDict_SetItemString(c.tp_dict, name, obj));
+}
+}
+}
 }
 }

+ 24 - 5
src/lib/dns/python/pydnspp_common.h

@@ -15,9 +15,22 @@
 #ifndef __LIBDNS_PYTHON_COMMON_H
 #ifndef __LIBDNS_PYTHON_COMMON_H
 #define __LIBDNS_PYTHON_COMMON_H 1
 #define __LIBDNS_PYTHON_COMMON_H 1
 
 
-//
-// Shared functions for python/c API
-//
+#include <Python.h>
+
+#include <stdexcept>
+#include <string>
+
+#include <util/python/pycppwrapper_util.h>
+
+namespace isc {
+namespace dns {
+namespace python {
+// For our 'general' isc::Exceptions
+extern PyObject* po_IscException;
+extern PyObject* po_InvalidParameter;
+
+// For our own isc::dns::Exception
+extern PyObject* po_DNSMessageBADVERS;
 
 
 // This function reads 'bytes' from a sequence
 // This function reads 'bytes' from a sequence
 // This sequence can be anything that implements the Sequence interface,
 // This sequence can be anything that implements the Sequence interface,
@@ -31,6 +44,12 @@
 // case nothing is removed
 // case nothing is removed
 int readDataFromSequence(uint8_t *data, size_t len, PyObject* sequence);
 int readDataFromSequence(uint8_t *data, size_t len, PyObject* sequence);
 
 
-void addClassVariable(PyTypeObject& c, const char* name, PyObject* obj);
-
+int addClassVariable(PyTypeObject& c, const char* name, PyObject* obj);
+} // namespace python
+} // namespace dns
+} // namespace isc
 #endif // __LIBDNS_PYTHON_COMMON_H
 #endif // __LIBDNS_PYTHON_COMMON_H
+
+// Local Variables:
+// mode: c++
+// End:

+ 78 - 77
src/lib/dns/python/rcode_python.cc

@@ -12,9 +12,15 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 // PERFORMANCE OF THIS SOFTWARE.
 
 
+#include <exceptions/exceptions.h>
+
 #include <dns/rcode.h>
 #include <dns/rcode.h>
 
 
+#include "pydnspp_common.h"
+#include "rcode_python.h"
+
 using namespace isc::dns;
 using namespace isc::dns;
+using namespace isc::dns::python;
 
 
 //
 //
 // Declaration of the custom exceptions (None for this class)
 // Declaration of the custom exceptions (None for this class)
@@ -27,25 +33,14 @@ using namespace isc::dns;
 // and static wrappers around the methods we export), a list of methods,
 // and static wrappers around the methods we export), a list of methods,
 // and a type description
 // and a type description
 
 
-namespace {
 //
 //
 // Rcode
 // Rcode
 //
 //
 
 
-// We added a helper variable static_code here
-// Since we can create Rcodes dynamically with Rcode(int), but also
-// use the static globals (Rcode::NOERROR() etc), we use this
-// variable to see if the code came from one of the latter, in which
-// case Rcode_destroy should not free it (the other option is to
-// allocate new Rcodes for every use of the static ones, but this
-// seems more efficient).
-class s_Rcode : public PyObject {
-public:
-    s_Rcode() : rcode(NULL), static_code(false) {}
-    const Rcode* rcode;
-    bool static_code;
-};
+// Trivial constructor.
+s_Rcode::s_Rcode() : cppobj(NULL), static_code(false) {}
 
 
+namespace {
 int Rcode_init(s_Rcode* const self, PyObject* args);
 int Rcode_init(s_Rcode* const self, PyObject* args);
 void Rcode_destroy(s_Rcode* const self);
 void Rcode_destroy(s_Rcode* const self);
 
 
@@ -118,57 +113,6 @@ PyMethodDef Rcode_methods[] = {
     { NULL, NULL, 0, NULL }
     { NULL, NULL, 0, NULL }
 };
 };
 
 
-PyTypeObject rcode_type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "pydnspp.Rcode",
-    sizeof(s_Rcode),                    // tp_basicsize
-    0,                                  // tp_itemsize
-    (destructor)Rcode_destroy,          // tp_dealloc
-    NULL,                               // tp_print
-    NULL,                               // tp_getattr
-    NULL,                               // tp_setattr
-    NULL,                               // tp_reserved
-    NULL,                               // tp_repr
-    NULL,                               // tp_as_number
-    NULL,                               // tp_as_sequence
-    NULL,                               // tp_as_mapping
-    NULL,                               // tp_hash 
-    NULL,                               // tp_call
-    Rcode_str,                          // tp_str
-    NULL,                               // tp_getattro
-    NULL,                               // tp_setattro
-    NULL,                               // tp_as_buffer
-    Py_TPFLAGS_DEFAULT,                 // tp_flags
-    "The Rcode class objects represent standard RCODEs"
-    "of the header section of DNS messages.",
-    NULL,                               // tp_traverse
-    NULL,                               // tp_clear
-    (richcmpfunc)Rcode_richcmp,         // tp_richcompare
-    0,                                  // tp_weaklistoffset
-    NULL,                               // tp_iter
-    NULL,                               // tp_iternext
-    Rcode_methods,                      // tp_methods
-    NULL,                               // tp_members
-    NULL,                               // tp_getset
-    NULL,                               // tp_base
-    NULL,                               // tp_dict
-    NULL,                               // tp_descr_get
-    NULL,                               // tp_descr_set
-    0,                                  // tp_dictoffset
-    (initproc)Rcode_init,               // tp_init
-    NULL,                               // tp_alloc
-    PyType_GenericNew,                  // tp_new
-    NULL,                               // tp_free
-    NULL,                               // tp_is_gc
-    NULL,                               // tp_bases
-    NULL,                               // tp_mro
-    NULL,                               // tp_cache
-    NULL,                               // tp_subclasses
-    NULL,                               // tp_weaklist
-    NULL,                               // tp_del
-    0                                   // tp_version_tag
-};
-
 int
 int
 Rcode_init(s_Rcode* const self, PyObject* args) {
 Rcode_init(s_Rcode* const self, PyObject* args) {
     long code = 0;
     long code = 0;
@@ -193,9 +137,9 @@ Rcode_init(s_Rcode* const self, PyObject* args) {
     }
     }
     try {
     try {
         if (ext_code == -1) {
         if (ext_code == -1) {
-            self->rcode = new Rcode(code);
+            self->cppobj = new Rcode(code);
         } else {
         } else {
-            self->rcode = new Rcode(code, ext_code);
+            self->cppobj = new Rcode(code, ext_code);
         }
         }
         self->static_code = false;
         self->static_code = false;
     } catch (const isc::OutOfRange& ex) {
     } catch (const isc::OutOfRange& ex) {
@@ -211,27 +155,27 @@ Rcode_init(s_Rcode* const self, PyObject* args) {
 void
 void
 Rcode_destroy(s_Rcode* const self) {
 Rcode_destroy(s_Rcode* const self) {
     // Depending on whether we created the rcode or are referring
     // Depending on whether we created the rcode or are referring
-    // to a global one, we do or do not delete self->rcode here
+    // to a global one, we do or do not delete self->cppobj here
     if (!self->static_code) {
     if (!self->static_code) {
-        delete self->rcode;
+        delete self->cppobj;
     }
     }
-    self->rcode = NULL;
+    self->cppobj = NULL;
     Py_TYPE(self)->tp_free(self);
     Py_TYPE(self)->tp_free(self);
 }
 }
 
 
 PyObject*
 PyObject*
 Rcode_getCode(const s_Rcode* const self) {
 Rcode_getCode(const s_Rcode* const self) {
-    return (Py_BuildValue("I", self->rcode->getCode()));
+    return (Py_BuildValue("I", self->cppobj->getCode()));
 }
 }
 
 
 PyObject*
 PyObject*
 Rcode_getExtendedCode(const s_Rcode* const self) {
 Rcode_getExtendedCode(const s_Rcode* const self) {
-    return (Py_BuildValue("I", self->rcode->getExtendedCode()));
+    return (Py_BuildValue("I", self->cppobj->getExtendedCode()));
 }
 }
 
 
 PyObject*
 PyObject*
 Rcode_toText(const s_Rcode* const self) {
 Rcode_toText(const s_Rcode* const self) {
-    return (Py_BuildValue("s", self->rcode->toText().c_str()));
+    return (Py_BuildValue("s", self->cppobj->toText().c_str()));
 }
 }
 
 
 PyObject*
 PyObject*
@@ -245,7 +189,7 @@ PyObject*
 Rcode_createStatic(const Rcode& rcode) {
 Rcode_createStatic(const Rcode& rcode) {
     s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
     s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
     if (ret != NULL) {
     if (ret != NULL) {
-        ret->rcode = &rcode;
+        ret->cppobj = &rcode;
         ret->static_code = true;
         ret->static_code = true;
     }
     }
     return (ret);
     return (ret);
@@ -357,10 +301,10 @@ Rcode_richcmp(const s_Rcode* const self, const s_Rcode* const other,
         PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
         PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
         return (NULL);
         return (NULL);
     case Py_EQ:
     case Py_EQ:
-        c = (*self->rcode == *other->rcode);
+        c = (*self->cppobj == *other->cppobj);
         break;
         break;
     case Py_NE:
     case Py_NE:
-        c = (*self->rcode != *other->rcode);
+        c = (*self->cppobj != *other->cppobj);
         break;
         break;
     case Py_GT:
     case Py_GT:
         PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
         PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
@@ -374,6 +318,61 @@ Rcode_richcmp(const s_Rcode* const self, const s_Rcode* const other,
     else
     else
         Py_RETURN_FALSE;
         Py_RETURN_FALSE;
 }
 }
+} // end of unnamed namespace
+
+namespace isc {
+namespace dns {
+namespace python {
+PyTypeObject rcode_type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "pydnspp.Rcode",
+    sizeof(s_Rcode),                    // tp_basicsize
+    0,                                  // tp_itemsize
+    (destructor)Rcode_destroy,          // tp_dealloc
+    NULL,                               // tp_print
+    NULL,                               // tp_getattr
+    NULL,                               // tp_setattr
+    NULL,                               // tp_reserved
+    NULL,                               // tp_repr
+    NULL,                               // tp_as_number
+    NULL,                               // tp_as_sequence
+    NULL,                               // tp_as_mapping
+    NULL,                               // tp_hash
+    NULL,                               // tp_call
+    Rcode_str,                          // tp_str
+    NULL,                               // tp_getattro
+    NULL,                               // tp_setattro
+    NULL,                               // tp_as_buffer
+    Py_TPFLAGS_DEFAULT,                 // tp_flags
+    "The Rcode class objects represent standard RCODEs"
+    "of the header section of DNS messages.",
+    NULL,                               // tp_traverse
+    NULL,                               // tp_clear
+    reinterpret_cast<richcmpfunc>(Rcode_richcmp),         // tp_richcompare
+    0,                                  // tp_weaklistoffset
+    NULL,                               // tp_iter
+    NULL,                               // tp_iternext
+    Rcode_methods,                      // tp_methods
+    NULL,                               // tp_members
+    NULL,                               // tp_getset
+    NULL,                               // tp_base
+    NULL,                               // tp_dict
+    NULL,                               // tp_descr_get
+    NULL,                               // tp_descr_set
+    0,                                  // tp_dictoffset
+    (initproc)Rcode_init,               // tp_init
+    NULL,                               // tp_alloc
+    PyType_GenericNew,                  // tp_new
+    NULL,                               // tp_free
+    NULL,                               // tp_is_gc
+    NULL,                               // tp_bases
+    NULL,                               // tp_mro
+    NULL,                               // tp_cache
+    NULL,                               // tp_subclasses
+    NULL,                               // tp_weaklist
+    NULL,                               // tp_del
+    0                                   // tp_version_tag
+};
 
 
 // Module Initialization, all statics are initialized here
 // Module Initialization, all statics are initialized here
 bool
 bool
@@ -428,4 +427,6 @@ initModulePart_Rcode(PyObject* mod) {
 
 
     return (true);
     return (true);
 }
 }
-} // end of unnamed namespace
+} // namespace python
+} // namespace dns
+} // namespace isc

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

@@ -12,6 +12,7 @@ PYTESTS += rrset_python_test.py
 PYTESTS += rrttl_python_test.py
 PYTESTS += rrttl_python_test.py
 PYTESTS += rrtype_python_test.py
 PYTESTS += rrtype_python_test.py
 PYTESTS += tsig_python_test.py
 PYTESTS += tsig_python_test.py
+PYTESTS += tsigerror_python_test.py
 PYTESTS += tsigkey_python_test.py
 PYTESTS += tsigkey_python_test.py
 
 
 EXTRA_DIST = $(PYTESTS)
 EXTRA_DIST = $(PYTESTS)

+ 1 - 1
src/lib/dns/python/tests/tsigerror_python_test.py

@@ -1,4 +1,4 @@
-# Copyright (C) 2010  Internet Systems Consortium.
+# Copyright (C) 2011  Internet Systems Consortium.
 #
 #
 # Permission to use, copy, modify, and distribute this software for any
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
 # purpose with or without fee is hereby granted, provided that the above

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

@@ -26,7 +26,6 @@ using namespace isc::dns;
 
 
 namespace {
 namespace {
 // The s_* Class simply covers one instantiation of the object
 // The s_* Class simply covers one instantiation of the object
-
 class s_TSIGContext : public PyObject {
 class s_TSIGContext : public PyObject {
 public:
 public:
     TSIGContext* tsig_ctx;
     TSIGContext* tsig_ctx;