Branch data Line data Source code
1 : : // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : // Enable this if you use s# variants with PyArg_ParseTuple(), see
16 : : // http://docs.python.org/py3k/c-api/arg.html#strings-and-buffers
17 : : //#define PY_SSIZE_T_CLEAN
18 : :
19 : : // Python.h needs to be placed at the head of the program file, see:
20 : : // http://docs.python.org/py3k/extending/extending.html#a-simple-example
21 : : #include <Python.h>
22 : :
23 : : #include <string>
24 : : #include <stdexcept>
25 : :
26 : : #include <util/python/pycppwrapper_util.h>
27 : :
28 : : #include <dns/nsec3hash.h>
29 : : #include <dns/rdataclass.h>
30 : :
31 : : #include "pydnspp_common.h"
32 : : #include "name_python.h"
33 : : #include "nsec3hash_python.h"
34 : : #include "rdata_python.h"
35 : :
36 : : using namespace std;
37 : : using namespace isc::util::python;
38 : : using namespace isc::dns;
39 : : using namespace isc::dns::rdata;
40 : : using namespace isc::dns::python;
41 : :
42 : : // Import pydoc text
43 : : #include "nsec3hash_python_inc.cc"
44 : :
45 : : // Trivial constructor.
46 : 0 : s_NSEC3Hash::s_NSEC3Hash() : cppobj(NULL) {
47 : 0 : }
48 : :
49 : : namespace {
50 : : int
51 : 18 : NSEC3Hash_init(PyObject* po_self, PyObject* args, PyObject*) {
52 : 18 : s_NSEC3Hash* const self = static_cast<s_NSEC3Hash*>(po_self);
53 : : try {
54 : : PyObject* po_rdata;
55 [ + - ][ + + ]: 18 : if (PyArg_ParseTuple(args, "O", &po_rdata)) {
56 [ + - ][ + + ]: 16 : if (!PyRdata_Check(po_rdata)) {
57 : : PyErr_Format(PyExc_TypeError,
58 : : "param must be an Rdata of type NSEC3/NSEC3PARAM,"
59 [ + - ]: 1 : " not %.200s", po_rdata->ob_type->tp_name);
60 : : return (-1);
61 : : }
62 [ + - ]: 15 : const Rdata& rdata = PyRdata_ToRdata(po_rdata);
63 : : const generic::NSEC3PARAM* nsec3param =
64 [ + - ]: 15 : dynamic_cast<const generic::NSEC3PARAM*>(&rdata);
65 : : const generic::NSEC3* nsec3 =
66 [ + - ]: 15 : dynamic_cast<const generic::NSEC3*>(&rdata);
67 [ + + ]: 15 : if (nsec3param != NULL) {
68 [ + + ]: 8 : self->cppobj = NSEC3Hash::create(*nsec3param);
69 [ + + ]: 7 : } else if (nsec3 != NULL) {
70 [ + + ]: 6 : self->cppobj = NSEC3Hash::create(*nsec3);
71 : : } else {
72 : : PyErr_Format(PyExc_TypeError,
73 [ + - ]: 18 : "param must be an Rdata of type NSEC3/NSEC3HASH");
74 : : return (-1);
75 : : }
76 : : return (0);
77 : : }
78 : 4 : } catch (const UnknownNSEC3HashAlgorithm& ex) {
79 [ - + ]: 2 : PyErr_SetString(po_UnknownNSEC3HashAlgorithm, ex.what());
80 : : return (-1);
81 : 0 : } catch (const exception& ex) {
82 : : const string ex_what = "Failed to construct NSEC3Hash object: " +
83 [ # # ][ # # ]: 0 : string(ex.what());
84 [ # # ]: 0 : PyErr_SetString(po_IscException, ex_what.c_str());
85 : : return (-1);
86 [ + - - ]: 2 : } catch (...) {
87 [ # # ]: 0 : PyErr_SetString(PyExc_SystemError, "Unexpected C++ exception");
88 : : return (-1);
89 : : }
90 : :
91 : : return (-1);
92 : : }
93 : :
94 : : void
95 : 18 : NSEC3Hash_destroy(PyObject* po_self) {
96 : 18 : s_NSEC3Hash* self = static_cast<s_NSEC3Hash*>(po_self);
97 [ + + ]: 18 : delete self->cppobj;
98 : 18 : self->cppobj = NULL;
99 : 18 : Py_TYPE(self)->tp_free(self);
100 : 18 : }
101 : :
102 : : PyObject*
103 : 11 : NSEC3Hash_calculate(PyObject* po_self, PyObject* args) {
104 : 11 : s_NSEC3Hash* const self = static_cast<s_NSEC3Hash*>(po_self);
105 : :
106 : : try {
107 : : PyObject* po_name;
108 [ + - ][ + + ]: 11 : if (PyArg_ParseTuple(args, "O", &po_name)) {
109 [ + - ][ + + ]: 9 : if (!PyName_Check(po_name)) {
110 : : PyErr_Format(PyExc_TypeError,
111 : : "name must be a Name, not %.200s",
112 [ + - ]: 1 : po_name->ob_type->tp_name);
113 : : return (NULL);
114 : : }
115 : : const string hash =
116 [ + - ][ + - ]: 19 : self->cppobj->calculate(PyName_ToName(po_name));
117 [ + - ]: 8 : return (Py_BuildValue("s", hash.c_str()));
118 : : }
119 : 0 : } catch (const exception& ex) {
120 : : const string ex_what = "Unexpected failure in NSEC3Hash.calculate: " +
121 [ # # ][ # # ]: 0 : string(ex.what());
122 [ # # ]: 0 : PyErr_SetString(po_IscException, ex_what.c_str());
123 : : return (NULL);
124 [ # # ]: 0 : } catch (...) {
125 [ # # ]: 0 : PyErr_SetString(PyExc_SystemError, "Unexpected C++ exception");
126 : : return (NULL);
127 : : }
128 : :
129 : : return (NULL);
130 : : }
131 : :
132 : : PyObject*
133 : 27 : NSEC3Hash_match(PyObject* po_self, PyObject* args) {
134 : 27 : s_NSEC3Hash* const self = static_cast<s_NSEC3Hash*>(po_self);
135 : :
136 : : try {
137 : : PyObject* po_rdata;
138 [ + - ][ + + ]: 27 : if (PyArg_ParseTuple(args, "O", &po_rdata)) {
139 [ + - ][ + + ]: 26 : if (!PyRdata_Check(po_rdata)) {
140 : : PyErr_Format(PyExc_TypeError,
141 : : "param must be an Rdata of type NSEC3/NSEC3PARAM,"
142 [ + - ]: 1 : " not %.200s", po_rdata->ob_type->tp_name);
143 : : return (NULL);
144 : : }
145 [ + - ]: 25 : const Rdata& rdata = PyRdata_ToRdata(po_rdata);
146 : : const generic::NSEC3PARAM* nsec3param =
147 [ + - ]: 25 : dynamic_cast<const generic::NSEC3PARAM*>(&rdata);
148 : : const generic::NSEC3* nsec3 =
149 [ + - ]: 25 : dynamic_cast<const generic::NSEC3*>(&rdata);
150 : : bool matched;
151 [ + + ]: 25 : if (nsec3param != NULL) {
152 [ + - ]: 12 : matched = self->cppobj->match(*nsec3param);
153 [ + + ]: 13 : } else if (nsec3 != NULL) {
154 [ + - ]: 12 : matched = self->cppobj->match(*nsec3);
155 : : } else {
156 : : PyErr_Format(PyExc_TypeError,
157 [ + - ]: 1 : "param must be an Rdata of type NSEC3/NSEC3HASH");
158 : : return (NULL);
159 : : }
160 [ + + ]: 24 : PyObject* ret = matched ? Py_True : Py_False;
161 : 24 : Py_INCREF(ret);
162 : 27 : return (ret);
163 : : }
164 : 0 : } catch (const exception& ex) {
165 : : const string ex_what = "Unexpected failure in NSEC3Hash.match: " +
166 [ # # ][ # # ]: 0 : string(ex.what());
167 [ # # ]: 0 : PyErr_SetString(po_IscException, ex_what.c_str());
168 : : return (NULL);
169 [ # # ]: 0 : } catch (...) {
170 [ # # ]: 0 : PyErr_SetString(PyExc_SystemError, "Unexpected C++ exception");
171 : : return (NULL);
172 : : }
173 : :
174 : : return (NULL);
175 : : }
176 : :
177 : : // This list contains the actual set of functions we have in
178 : : // python. Each entry has
179 : : // 1. Python method name
180 : : // 2. Our static function here
181 : : // 3. Argument type
182 : : // 4. Documentation
183 : : PyMethodDef NSEC3Hash_methods[] = {
184 : : { "calculate", NSEC3Hash_calculate, METH_VARARGS, NSEC3Hash_calculate_doc },
185 : : { "match", NSEC3Hash_match, METH_VARARGS, NSEC3Hash_match_doc },
186 : : { NULL, NULL, 0, NULL }
187 : : };
188 : : } // end of unnamed namespace
189 : :
190 : : namespace isc {
191 : : namespace dns {
192 : : namespace python {
193 : : //
194 : : // Declaration of the custom exceptions
195 : : // Initialization and addition of these go in pydnspp.cc
196 : : //
197 : : PyObject* po_UnknownNSEC3HashAlgorithm;
198 : :
199 : : // This defines the complete type for reflection in python and
200 : : // parsing of PyObject* to s_NSEC3Hash
201 : : // Most of the functions are not actually implemented and NULL here.
202 : : PyTypeObject nsec3hash_type = {
203 : : PyVarObject_HEAD_INIT(NULL, 0)
204 : : "dns.NSEC3Hash",
205 : : sizeof(s_NSEC3Hash), // tp_basicsize
206 : : 0, // tp_itemsize
207 : : NSEC3Hash_destroy, // tp_dealloc
208 : : NULL, // tp_print
209 : : NULL, // tp_getattr
210 : : NULL, // tp_setattr
211 : : NULL, // tp_reserved
212 : : NULL, // tp_repr
213 : : NULL, // tp_as_number
214 : : NULL, // tp_as_sequence
215 : : NULL, // tp_as_mapping
216 : : NULL, // tp_hash
217 : : NULL, // tp_call
218 : : NULL, // tp_str
219 : : NULL, // tp_getattro
220 : : NULL, // tp_setattro
221 : : NULL, // tp_as_buffer
222 : : Py_TPFLAGS_DEFAULT, // tp_flags
223 : : NSEC3Hash_doc,
224 : : NULL, // tp_traverse
225 : : NULL, // tp_clear
226 : : NULL, // tp_richcompare
227 : : 0, // tp_weaklistoffset
228 : : NULL, // tp_iter
229 : : NULL, // tp_iternext
230 : : NSEC3Hash_methods, // tp_methods
231 : : NULL, // tp_members
232 : : NULL, // tp_getset
233 : : NULL, // tp_base
234 : : NULL, // tp_dict
235 : : NULL, // tp_descr_get
236 : : NULL, // tp_descr_set
237 : : 0, // tp_dictoffset
238 : : NSEC3Hash_init, // tp_init
239 : : NULL, // tp_alloc
240 : : PyType_GenericNew, // tp_new
241 : : NULL, // tp_free
242 : : NULL, // tp_is_gc
243 : : NULL, // tp_bases
244 : : NULL, // tp_mro
245 : : NULL, // tp_cache
246 : : NULL, // tp_subclasses
247 : : NULL, // tp_weaklist
248 : : NULL, // tp_del
249 : : 0 // tp_version_tag
250 : : };
251 : :
252 : : // Module Initialization, all statics (nothing right now) are initialized here
253 : : bool
254 : 29 : initModulePart_NSEC3Hash(PyObject* mod) {
255 : : // We initialize the static description object with PyType_Ready(),
256 : : // then add it to the module. This is not just a check! (leaving
257 : : // this out results in segmentation faults)
258 [ + - ]: 29 : if (PyType_Ready(&nsec3hash_type) < 0) {
259 : : return (false);
260 : : }
261 : 29 : void* p = &nsec3hash_type;
262 [ + - ]: 29 : if (PyModule_AddObject(mod, "NSEC3Hash", static_cast<PyObject*>(p)) < 0) {
263 : : return (false);
264 : : }
265 : 29 : Py_INCREF(&nsec3hash_type);
266 : :
267 : 29 : return (true);
268 : : }
269 : : } // namespace python
270 : : } // namespace dns
271 : 123 : } // namespace isc
|