pydnspp.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  1. // Copyright (C) 2010 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. // We want a lot of different parts of the DNS API in the python
  15. // module, but not one big 10000-line file.
  16. // So we split it up in several 'mini-modules'
  17. // These would be the same as a single module, except for
  18. // the init function, which has to be modified to a unique
  19. // name initModulePart_<name>, and return true/false instead of
  20. // NULL/*mod
  21. //
  22. // The big init function is split up into a separate initModulePart function
  23. // for each class we add.
  24. #define PY_SSIZE_T_CLEAN
  25. #include <Python.h>
  26. #include <structmember.h>
  27. #include <dns/message.h>
  28. #include <dns/opcode.h>
  29. #include <dns/tsig.h>
  30. #include <util/python/pycppwrapper_util.h>
  31. #include "pydnspp_common.h"
  32. #include "edns_python.h"
  33. #include "message_python.h"
  34. #include "messagerenderer_python.h"
  35. #include "name_python.h"
  36. #include "opcode_python.h"
  37. #include "pydnspp_common.h"
  38. #include "pydnspp_towire.h"
  39. #include "question_python.h"
  40. #include "rcode_python.h"
  41. #include "rdata_python.h"
  42. #include "rrclass_python.h"
  43. #include "rrset_python.h"
  44. #include "rrttl_python.h"
  45. #include "rrtype_python.h"
  46. #include "tsigerror_python.h"
  47. #include "tsigkey_python.h"
  48. #include "tsig_python.h"
  49. #include "tsig_rdata_python.h"
  50. #include "tsigrecord_python.h"
  51. using namespace isc::dns;
  52. using namespace isc::dns::python;
  53. using namespace isc::util::python;
  54. namespace {
  55. bool
  56. initModulePart_EDNS(PyObject* mod) {
  57. // We initialize the static description object with PyType_Ready(),
  58. // then add it to the module. This is not just a check! (leaving
  59. // this out results in segmentation faults)
  60. //
  61. // After the type has been initialized, we initialize any exceptions
  62. // that are defined in the wrapper for this class, and add constants
  63. // to the type, if any
  64. if (PyType_Ready(&edns_type) < 0) {
  65. return (false);
  66. }
  67. Py_INCREF(&edns_type);
  68. void* p = &edns_type;
  69. PyModule_AddObject(mod, "EDNS", static_cast<PyObject*>(p));
  70. addClassVariable(edns_type, "SUPPORTED_VERSION",
  71. Py_BuildValue("B", EDNS::SUPPORTED_VERSION));
  72. return (true);
  73. }
  74. bool
  75. initModulePart_Message(PyObject* mod) {
  76. if (PyType_Ready(&message_type) < 0) {
  77. return (false);
  78. }
  79. void* p = &message_type;
  80. if (PyModule_AddObject(mod, "Message", static_cast<PyObject*>(p)) < 0) {
  81. return (false);
  82. }
  83. Py_INCREF(&message_type);
  84. try {
  85. //
  86. // Constant class variables
  87. //
  88. // Parse mode
  89. installClassVariable(message_type, "PARSE",
  90. Py_BuildValue("I", Message::PARSE));
  91. installClassVariable(message_type, "RENDER",
  92. Py_BuildValue("I", Message::RENDER));
  93. // Parse options
  94. installClassVariable(message_type, "PARSE_DEFAULT",
  95. Py_BuildValue("I", Message::PARSE_DEFAULT));
  96. installClassVariable(message_type, "PRESERVE_ORDER",
  97. Py_BuildValue("I", Message::PRESERVE_ORDER));
  98. // Header flags
  99. installClassVariable(message_type, "HEADERFLAG_QR",
  100. Py_BuildValue("I", Message::HEADERFLAG_QR));
  101. installClassVariable(message_type, "HEADERFLAG_AA",
  102. Py_BuildValue("I", Message::HEADERFLAG_AA));
  103. installClassVariable(message_type, "HEADERFLAG_TC",
  104. Py_BuildValue("I", Message::HEADERFLAG_TC));
  105. installClassVariable(message_type, "HEADERFLAG_RD",
  106. Py_BuildValue("I", Message::HEADERFLAG_RD));
  107. installClassVariable(message_type, "HEADERFLAG_RA",
  108. Py_BuildValue("I", Message::HEADERFLAG_RA));
  109. installClassVariable(message_type, "HEADERFLAG_AD",
  110. Py_BuildValue("I", Message::HEADERFLAG_AD));
  111. installClassVariable(message_type, "HEADERFLAG_CD",
  112. Py_BuildValue("I", Message::HEADERFLAG_CD));
  113. // Sections
  114. installClassVariable(message_type, "SECTION_QUESTION",
  115. Py_BuildValue("I", Message::SECTION_QUESTION));
  116. installClassVariable(message_type, "SECTION_ANSWER",
  117. Py_BuildValue("I", Message::SECTION_ANSWER));
  118. installClassVariable(message_type, "SECTION_AUTHORITY",
  119. Py_BuildValue("I", Message::SECTION_AUTHORITY));
  120. installClassVariable(message_type, "SECTION_ADDITIONAL",
  121. Py_BuildValue("I", Message::SECTION_ADDITIONAL));
  122. // Protocol constant
  123. installClassVariable(message_type, "DEFAULT_MAX_UDPSIZE",
  124. Py_BuildValue("I", Message::DEFAULT_MAX_UDPSIZE));
  125. /* Class-specific exceptions */
  126. po_MessageTooShort =
  127. PyErr_NewException("pydnspp.MessageTooShort", NULL, NULL);
  128. PyObjectContainer(po_MessageTooShort).installToModule(
  129. mod, "MessageTooShort");
  130. po_InvalidMessageSection =
  131. PyErr_NewException("pydnspp.InvalidMessageSection", NULL, NULL);
  132. PyObjectContainer(po_InvalidMessageSection).installToModule(
  133. mod, "InvalidMessageSection");
  134. po_InvalidMessageOperation =
  135. PyErr_NewException("pydnspp.InvalidMessageOperation", NULL, NULL);
  136. PyObjectContainer(po_InvalidMessageOperation).installToModule(
  137. mod, "InvalidMessageOperation");
  138. po_InvalidMessageUDPSize =
  139. PyErr_NewException("pydnspp.InvalidMessageUDPSize", NULL, NULL);
  140. PyObjectContainer(po_InvalidMessageUDPSize).installToModule(
  141. mod, "InvalidMessageUDPSize");
  142. po_DNSMessageBADVERS =
  143. PyErr_NewException("pydnspp.DNSMessageBADVERS", NULL, NULL);
  144. PyObjectContainer(po_DNSMessageBADVERS).installToModule(
  145. mod, "DNSMessageBADVERS");
  146. } catch (const std::exception& ex) {
  147. const std::string ex_what =
  148. "Unexpected failure in Message initialization: " +
  149. std::string(ex.what());
  150. PyErr_SetString(po_IscException, ex_what.c_str());
  151. return (false);
  152. } catch (...) {
  153. PyErr_SetString(PyExc_SystemError,
  154. "Unexpected failure in Message initialization");
  155. return (false);
  156. }
  157. return (true);
  158. }
  159. bool
  160. initModulePart_MessageRenderer(PyObject* mod) {
  161. if (PyType_Ready(&messagerenderer_type) < 0) {
  162. return (false);
  163. }
  164. Py_INCREF(&messagerenderer_type);
  165. addClassVariable(messagerenderer_type, "CASE_INSENSITIVE",
  166. Py_BuildValue("I", MessageRenderer::CASE_INSENSITIVE));
  167. addClassVariable(messagerenderer_type, "CASE_SENSITIVE",
  168. Py_BuildValue("I", MessageRenderer::CASE_SENSITIVE));
  169. PyModule_AddObject(mod, "MessageRenderer",
  170. reinterpret_cast<PyObject*>(&messagerenderer_type));
  171. return (true);
  172. }
  173. bool
  174. initModulePart_Name(PyObject* mod) {
  175. //
  176. // NameComparisonResult
  177. //
  178. if (PyType_Ready(&name_comparison_result_type) < 0) {
  179. return (false);
  180. }
  181. Py_INCREF(&name_comparison_result_type);
  182. // Add the enums to the module
  183. po_NameRelation = Py_BuildValue("{i:s,i:s,i:s,i:s}",
  184. NameComparisonResult::SUPERDOMAIN, "SUPERDOMAIN",
  185. NameComparisonResult::SUBDOMAIN, "SUBDOMAIN",
  186. NameComparisonResult::EQUAL, "EQUAL",
  187. NameComparisonResult::COMMONANCESTOR, "COMMONANCESTOR");
  188. addClassVariable(name_comparison_result_type, "NameRelation",
  189. po_NameRelation);
  190. PyModule_AddObject(mod, "NameComparisonResult",
  191. reinterpret_cast<PyObject*>(&name_comparison_result_type));
  192. //
  193. // Name
  194. //
  195. if (PyType_Ready(&name_type) < 0) {
  196. return (false);
  197. }
  198. Py_INCREF(&name_type);
  199. // Add the constants to the module
  200. addClassVariable(name_type, "MAX_WIRE",
  201. Py_BuildValue("I", Name::MAX_WIRE));
  202. addClassVariable(name_type, "MAX_LABELS",
  203. Py_BuildValue("I", Name::MAX_LABELS));
  204. addClassVariable(name_type, "MAX_LABELLEN",
  205. Py_BuildValue("I", Name::MAX_LABELLEN));
  206. addClassVariable(name_type, "MAX_COMPRESS_POINTER",
  207. Py_BuildValue("I", Name::MAX_COMPRESS_POINTER));
  208. addClassVariable(name_type, "COMPRESS_POINTER_MARK8",
  209. Py_BuildValue("I", Name::COMPRESS_POINTER_MARK8));
  210. addClassVariable(name_type, "COMPRESS_POINTER_MARK16",
  211. Py_BuildValue("I", Name::COMPRESS_POINTER_MARK16));
  212. addClassVariable(name_type, "ROOT_NAME",
  213. createNameObject(Name::ROOT_NAME()));
  214. PyModule_AddObject(mod, "Name",
  215. reinterpret_cast<PyObject*>(&name_type));
  216. // Add the exceptions to the module
  217. po_EmptyLabel = PyErr_NewException("pydnspp.EmptyLabel", NULL, NULL);
  218. PyModule_AddObject(mod, "EmptyLabel", po_EmptyLabel);
  219. po_TooLongName = PyErr_NewException("pydnspp.TooLongName", NULL, NULL);
  220. PyModule_AddObject(mod, "TooLongName", po_TooLongName);
  221. po_TooLongLabel = PyErr_NewException("pydnspp.TooLongLabel", NULL, NULL);
  222. PyModule_AddObject(mod, "TooLongLabel", po_TooLongLabel);
  223. po_BadLabelType = PyErr_NewException("pydnspp.BadLabelType", NULL, NULL);
  224. PyModule_AddObject(mod, "BadLabelType", po_BadLabelType);
  225. po_BadEscape = PyErr_NewException("pydnspp.BadEscape", NULL, NULL);
  226. PyModule_AddObject(mod, "BadEscape", po_BadEscape);
  227. po_IncompleteName = PyErr_NewException("pydnspp.IncompleteName", NULL, NULL);
  228. PyModule_AddObject(mod, "IncompleteName", po_IncompleteName);
  229. po_InvalidBufferPosition =
  230. PyErr_NewException("pydnspp.InvalidBufferPosition", NULL, NULL);
  231. PyModule_AddObject(mod, "InvalidBufferPosition", po_InvalidBufferPosition);
  232. // This one could have gone into the message_python.cc file, but is
  233. // already needed here.
  234. po_DNSMessageFORMERR = PyErr_NewException("pydnspp.DNSMessageFORMERR",
  235. NULL, NULL);
  236. PyModule_AddObject(mod, "DNSMessageFORMERR", po_DNSMessageFORMERR);
  237. return (true);
  238. }
  239. bool
  240. initModulePart_Opcode(PyObject* mod) {
  241. if (PyType_Ready(&opcode_type) < 0) {
  242. return (false);
  243. }
  244. Py_INCREF(&opcode_type);
  245. void* p = &opcode_type;
  246. if (PyModule_AddObject(mod, "Opcode", static_cast<PyObject*>(p)) != 0) {
  247. Py_DECREF(&opcode_type);
  248. return (false);
  249. }
  250. addClassVariable(opcode_type, "QUERY_CODE",
  251. Py_BuildValue("h", Opcode::QUERY_CODE));
  252. addClassVariable(opcode_type, "IQUERY_CODE",
  253. Py_BuildValue("h", Opcode::IQUERY_CODE));
  254. addClassVariable(opcode_type, "STATUS_CODE",
  255. Py_BuildValue("h", Opcode::STATUS_CODE));
  256. addClassVariable(opcode_type, "RESERVED3_CODE",
  257. Py_BuildValue("h", Opcode::RESERVED3_CODE));
  258. addClassVariable(opcode_type, "NOTIFY_CODE",
  259. Py_BuildValue("h", Opcode::NOTIFY_CODE));
  260. addClassVariable(opcode_type, "UPDATE_CODE",
  261. Py_BuildValue("h", Opcode::UPDATE_CODE));
  262. addClassVariable(opcode_type, "RESERVED6_CODE",
  263. Py_BuildValue("h", Opcode::RESERVED6_CODE));
  264. addClassVariable(opcode_type, "RESERVED7_CODE",
  265. Py_BuildValue("h", Opcode::RESERVED7_CODE));
  266. addClassVariable(opcode_type, "RESERVED8_CODE",
  267. Py_BuildValue("h", Opcode::RESERVED8_CODE));
  268. addClassVariable(opcode_type, "RESERVED9_CODE",
  269. Py_BuildValue("h", Opcode::RESERVED9_CODE));
  270. addClassVariable(opcode_type, "RESERVED10_CODE",
  271. Py_BuildValue("h", Opcode::RESERVED10_CODE));
  272. addClassVariable(opcode_type, "RESERVED11_CODE",
  273. Py_BuildValue("h", Opcode::RESERVED11_CODE));
  274. addClassVariable(opcode_type, "RESERVED12_CODE",
  275. Py_BuildValue("h", Opcode::RESERVED12_CODE));
  276. addClassVariable(opcode_type, "RESERVED13_CODE",
  277. Py_BuildValue("h", Opcode::RESERVED13_CODE));
  278. addClassVariable(opcode_type, "RESERVED14_CODE",
  279. Py_BuildValue("h", Opcode::RESERVED14_CODE));
  280. addClassVariable(opcode_type, "RESERVED15_CODE",
  281. Py_BuildValue("h", Opcode::RESERVED15_CODE));
  282. return (true);
  283. }
  284. bool
  285. initModulePart_Question(PyObject* mod) {
  286. if (PyType_Ready(&question_type) < 0) {
  287. return (false);
  288. }
  289. Py_INCREF(&question_type);
  290. PyModule_AddObject(mod, "Question",
  291. reinterpret_cast<PyObject*>(&question_type));
  292. return (true);
  293. }
  294. bool
  295. initModulePart_Rcode(PyObject* mod) {
  296. if (PyType_Ready(&rcode_type) < 0) {
  297. return (false);
  298. }
  299. Py_INCREF(&rcode_type);
  300. void* p = &rcode_type;
  301. if (PyModule_AddObject(mod, "Rcode", static_cast<PyObject*>(p)) != 0) {
  302. Py_DECREF(&rcode_type);
  303. return (false);
  304. }
  305. addClassVariable(rcode_type, "NOERROR_CODE",
  306. Py_BuildValue("h", Rcode::NOERROR_CODE));
  307. addClassVariable(rcode_type, "FORMERR_CODE",
  308. Py_BuildValue("h", Rcode::FORMERR_CODE));
  309. addClassVariable(rcode_type, "SERVFAIL_CODE",
  310. Py_BuildValue("h", Rcode::SERVFAIL_CODE));
  311. addClassVariable(rcode_type, "NXDOMAIN_CODE",
  312. Py_BuildValue("h", Rcode::NXDOMAIN_CODE));
  313. addClassVariable(rcode_type, "NOTIMP_CODE",
  314. Py_BuildValue("h", Rcode::NOTIMP_CODE));
  315. addClassVariable(rcode_type, "REFUSED_CODE",
  316. Py_BuildValue("h", Rcode::REFUSED_CODE));
  317. addClassVariable(rcode_type, "YXDOMAIN_CODE",
  318. Py_BuildValue("h", Rcode::YXDOMAIN_CODE));
  319. addClassVariable(rcode_type, "YXRRSET_CODE",
  320. Py_BuildValue("h", Rcode::YXRRSET_CODE));
  321. addClassVariable(rcode_type, "NXRRSET_CODE",
  322. Py_BuildValue("h", Rcode::NXRRSET_CODE));
  323. addClassVariable(rcode_type, "NOTAUTH_CODE",
  324. Py_BuildValue("h", Rcode::NOTAUTH_CODE));
  325. addClassVariable(rcode_type, "NOTZONE_CODE",
  326. Py_BuildValue("h", Rcode::NOTZONE_CODE));
  327. addClassVariable(rcode_type, "RESERVED11_CODE",
  328. Py_BuildValue("h", Rcode::RESERVED11_CODE));
  329. addClassVariable(rcode_type, "RESERVED12_CODE",
  330. Py_BuildValue("h", Rcode::RESERVED12_CODE));
  331. addClassVariable(rcode_type, "RESERVED13_CODE",
  332. Py_BuildValue("h", Rcode::RESERVED13_CODE));
  333. addClassVariable(rcode_type, "RESERVED14_CODE",
  334. Py_BuildValue("h", Rcode::RESERVED14_CODE));
  335. addClassVariable(rcode_type, "RESERVED15_CODE",
  336. Py_BuildValue("h", Rcode::RESERVED15_CODE));
  337. addClassVariable(rcode_type, "BADVERS_CODE",
  338. Py_BuildValue("h", Rcode::BADVERS_CODE));
  339. return (true);
  340. }
  341. bool
  342. initModulePart_Rdata(PyObject* mod) {
  343. if (PyType_Ready(&rdata_type) < 0) {
  344. return (false);
  345. }
  346. Py_INCREF(&rdata_type);
  347. PyModule_AddObject(mod, "Rdata",
  348. reinterpret_cast<PyObject*>(&rdata_type));
  349. // Add the exceptions to the class
  350. po_InvalidRdataLength = PyErr_NewException("pydnspp.InvalidRdataLength",
  351. NULL, NULL);
  352. PyModule_AddObject(mod, "InvalidRdataLength", po_InvalidRdataLength);
  353. po_InvalidRdataText = PyErr_NewException("pydnspp.InvalidRdataText",
  354. NULL, NULL);
  355. PyModule_AddObject(mod, "InvalidRdataText", po_InvalidRdataText);
  356. po_CharStringTooLong = PyErr_NewException("pydnspp.CharStringTooLong",
  357. NULL, NULL);
  358. PyModule_AddObject(mod, "CharStringTooLong", po_CharStringTooLong);
  359. return (true);
  360. }
  361. bool
  362. initModulePart_RRClass(PyObject* mod) {
  363. po_InvalidRRClass = PyErr_NewException("pydnspp.InvalidRRClass",
  364. NULL, NULL);
  365. Py_INCREF(po_InvalidRRClass);
  366. PyModule_AddObject(mod, "InvalidRRClass", po_InvalidRRClass);
  367. po_IncompleteRRClass = PyErr_NewException("pydnspp.IncompleteRRClass",
  368. NULL, NULL);
  369. Py_INCREF(po_IncompleteRRClass);
  370. PyModule_AddObject(mod, "IncompleteRRClass", po_IncompleteRRClass);
  371. if (PyType_Ready(&rrclass_type) < 0) {
  372. return (false);
  373. }
  374. Py_INCREF(&rrclass_type);
  375. PyModule_AddObject(mod, "RRClass",
  376. reinterpret_cast<PyObject*>(&rrclass_type));
  377. return (true);
  378. }
  379. bool
  380. initModulePart_RRset(PyObject* mod) {
  381. po_EmptyRRset = PyErr_NewException("pydnspp.EmptyRRset", NULL, NULL);
  382. PyModule_AddObject(mod, "EmptyRRset", po_EmptyRRset);
  383. // NameComparisonResult
  384. if (PyType_Ready(&rrset_type) < 0) {
  385. return (false);
  386. }
  387. Py_INCREF(&rrset_type);
  388. PyModule_AddObject(mod, "RRset",
  389. reinterpret_cast<PyObject*>(&rrset_type));
  390. return (true);
  391. }
  392. bool
  393. initModulePart_RRTTL(PyObject* mod) {
  394. po_InvalidRRTTL = PyErr_NewException("pydnspp.InvalidRRTTL", NULL, NULL);
  395. PyModule_AddObject(mod, "InvalidRRTTL", po_InvalidRRTTL);
  396. po_IncompleteRRTTL = PyErr_NewException("pydnspp.IncompleteRRTTL",
  397. NULL, NULL);
  398. PyModule_AddObject(mod, "IncompleteRRTTL", po_IncompleteRRTTL);
  399. if (PyType_Ready(&rrttl_type) < 0) {
  400. return (false);
  401. }
  402. Py_INCREF(&rrttl_type);
  403. PyModule_AddObject(mod, "RRTTL",
  404. reinterpret_cast<PyObject*>(&rrttl_type));
  405. return (true);
  406. }
  407. bool
  408. initModulePart_RRType(PyObject* mod) {
  409. // Add the exceptions to the module
  410. po_InvalidRRType = PyErr_NewException("pydnspp.InvalidRRType", NULL, NULL);
  411. PyModule_AddObject(mod, "InvalidRRType", po_InvalidRRType);
  412. po_IncompleteRRType = PyErr_NewException("pydnspp.IncompleteRRType",
  413. NULL, NULL);
  414. PyModule_AddObject(mod, "IncompleteRRType", po_IncompleteRRType);
  415. if (PyType_Ready(&rrtype_type) < 0) {
  416. return (false);
  417. }
  418. Py_INCREF(&rrtype_type);
  419. PyModule_AddObject(mod, "RRType",
  420. reinterpret_cast<PyObject*>(&rrtype_type));
  421. return (true);
  422. }
  423. bool
  424. initModulePart_TSIGError(PyObject* mod) {
  425. if (PyType_Ready(&tsigerror_type) < 0) {
  426. return (false);
  427. }
  428. void* p = &tsigerror_type;
  429. if (PyModule_AddObject(mod, "TSIGError", static_cast<PyObject*>(p)) < 0) {
  430. return (false);
  431. }
  432. Py_INCREF(&tsigerror_type);
  433. try {
  434. // Constant class variables
  435. // Error codes (bare values)
  436. installClassVariable(tsigerror_type, "BAD_SIG_CODE",
  437. Py_BuildValue("H", TSIGError::BAD_SIG_CODE));
  438. installClassVariable(tsigerror_type, "BAD_KEY_CODE",
  439. Py_BuildValue("H", TSIGError::BAD_KEY_CODE));
  440. installClassVariable(tsigerror_type, "BAD_TIME_CODE",
  441. Py_BuildValue("H", TSIGError::BAD_TIME_CODE));
  442. // Error codes (constant objects)
  443. installClassVariable(tsigerror_type, "NOERROR",
  444. createTSIGErrorObject(TSIGError::NOERROR()));
  445. installClassVariable(tsigerror_type, "FORMERR",
  446. createTSIGErrorObject(TSIGError::FORMERR()));
  447. installClassVariable(tsigerror_type, "SERVFAIL",
  448. createTSIGErrorObject(TSIGError::SERVFAIL()));
  449. installClassVariable(tsigerror_type, "NXDOMAIN",
  450. createTSIGErrorObject(TSIGError::NXDOMAIN()));
  451. installClassVariable(tsigerror_type, "NOTIMP",
  452. createTSIGErrorObject(TSIGError::NOTIMP()));
  453. installClassVariable(tsigerror_type, "REFUSED",
  454. createTSIGErrorObject(TSIGError::REFUSED()));
  455. installClassVariable(tsigerror_type, "YXDOMAIN",
  456. createTSIGErrorObject(TSIGError::YXDOMAIN()));
  457. installClassVariable(tsigerror_type, "YXRRSET",
  458. createTSIGErrorObject(TSIGError::YXRRSET()));
  459. installClassVariable(tsigerror_type, "NXRRSET",
  460. createTSIGErrorObject(TSIGError::NXRRSET()));
  461. installClassVariable(tsigerror_type, "NOTAUTH",
  462. createTSIGErrorObject(TSIGError::NOTAUTH()));
  463. installClassVariable(tsigerror_type, "NOTZONE",
  464. createTSIGErrorObject(TSIGError::NOTZONE()));
  465. installClassVariable(tsigerror_type, "RESERVED11",
  466. createTSIGErrorObject(TSIGError::RESERVED11()));
  467. installClassVariable(tsigerror_type, "RESERVED12",
  468. createTSIGErrorObject(TSIGError::RESERVED12()));
  469. installClassVariable(tsigerror_type, "RESERVED13",
  470. createTSIGErrorObject(TSIGError::RESERVED13()));
  471. installClassVariable(tsigerror_type, "RESERVED14",
  472. createTSIGErrorObject(TSIGError::RESERVED14()));
  473. installClassVariable(tsigerror_type, "RESERVED15",
  474. createTSIGErrorObject(TSIGError::RESERVED15()));
  475. installClassVariable(tsigerror_type, "BAD_SIG",
  476. createTSIGErrorObject(TSIGError::BAD_SIG()));
  477. installClassVariable(tsigerror_type, "BAD_KEY",
  478. createTSIGErrorObject(TSIGError::BAD_KEY()));
  479. installClassVariable(tsigerror_type, "BAD_TIME",
  480. createTSIGErrorObject(TSIGError::BAD_TIME()));
  481. } catch (const std::exception& ex) {
  482. const std::string ex_what =
  483. "Unexpected failure in TSIGError initialization: " +
  484. std::string(ex.what());
  485. PyErr_SetString(po_IscException, ex_what.c_str());
  486. return (false);
  487. } catch (...) {
  488. PyErr_SetString(PyExc_SystemError,
  489. "Unexpected failure in TSIGError initialization");
  490. return (false);
  491. }
  492. return (true);
  493. }
  494. bool
  495. initModulePart_TSIGKey(PyObject* mod) {
  496. if (PyType_Ready(&tsigkey_type) < 0) {
  497. return (false);
  498. }
  499. void* p = &tsigkey_type;
  500. if (PyModule_AddObject(mod, "TSIGKey", static_cast<PyObject*>(p)) != 0) {
  501. return (false);
  502. }
  503. Py_INCREF(&tsigkey_type);
  504. try {
  505. // Constant class variables
  506. installClassVariable(tsigkey_type, "HMACMD5_NAME",
  507. createNameObject(TSIGKey::HMACMD5_NAME()));
  508. installClassVariable(tsigkey_type, "HMACSHA1_NAME",
  509. createNameObject(TSIGKey::HMACSHA1_NAME()));
  510. installClassVariable(tsigkey_type, "HMACSHA256_NAME",
  511. createNameObject(TSIGKey::HMACSHA256_NAME()));
  512. installClassVariable(tsigkey_type, "HMACSHA224_NAME",
  513. createNameObject(TSIGKey::HMACSHA224_NAME()));
  514. installClassVariable(tsigkey_type, "HMACSHA384_NAME",
  515. createNameObject(TSIGKey::HMACSHA384_NAME()));
  516. installClassVariable(tsigkey_type, "HMACSHA512_NAME",
  517. createNameObject(TSIGKey::HMACSHA512_NAME()));
  518. } catch (const std::exception& ex) {
  519. const std::string ex_what =
  520. "Unexpected failure in TSIGKey initialization: " +
  521. std::string(ex.what());
  522. PyErr_SetString(po_IscException, ex_what.c_str());
  523. return (false);
  524. } catch (...) {
  525. PyErr_SetString(PyExc_SystemError,
  526. "Unexpected failure in TSIGKey initialization");
  527. return (false);
  528. }
  529. return (true);
  530. }
  531. bool
  532. initModulePart_TSIGKeyRing(PyObject* mod) {
  533. if (PyType_Ready(&tsigkeyring_type) < 0) {
  534. return (false);
  535. }
  536. Py_INCREF(&tsigkeyring_type);
  537. void* p = &tsigkeyring_type;
  538. if (PyModule_AddObject(mod, "TSIGKeyRing",
  539. static_cast<PyObject*>(p)) != 0) {
  540. Py_DECREF(&tsigkeyring_type);
  541. return (false);
  542. }
  543. addClassVariable(tsigkeyring_type, "SUCCESS",
  544. Py_BuildValue("I", TSIGKeyRing::SUCCESS));
  545. addClassVariable(tsigkeyring_type, "EXIST",
  546. Py_BuildValue("I", TSIGKeyRing::EXIST));
  547. addClassVariable(tsigkeyring_type, "NOTFOUND",
  548. Py_BuildValue("I", TSIGKeyRing::NOTFOUND));
  549. return (true);
  550. }
  551. bool
  552. initModulePart_TSIGContext(PyObject* mod) {
  553. if (PyType_Ready(&tsigcontext_type) < 0) {
  554. return (false);
  555. }
  556. void* p = &tsigcontext_type;
  557. if (PyModule_AddObject(mod, "TSIGContext",
  558. static_cast<PyObject*>(p)) < 0) {
  559. return (false);
  560. }
  561. Py_INCREF(&tsigcontext_type);
  562. try {
  563. // Class specific exceptions
  564. po_TSIGContextError = PyErr_NewException("pydnspp.TSIGContextError",
  565. po_IscException, NULL);
  566. PyObjectContainer(po_TSIGContextError).installToModule(
  567. mod, "TSIGContextError");
  568. // Constant class variables
  569. installClassVariable(tsigcontext_type, "STATE_INIT",
  570. Py_BuildValue("I", TSIGContext::INIT));
  571. installClassVariable(tsigcontext_type, "STATE_SENT_REQUEST",
  572. Py_BuildValue("I", TSIGContext::SENT_REQUEST));
  573. installClassVariable(tsigcontext_type, "STATE_RECEIVED_REQUEST",
  574. Py_BuildValue("I", TSIGContext::RECEIVED_REQUEST));
  575. installClassVariable(tsigcontext_type, "STATE_SENT_RESPONSE",
  576. Py_BuildValue("I", TSIGContext::SENT_RESPONSE));
  577. installClassVariable(tsigcontext_type, "STATE_VERIFIED_RESPONSE",
  578. Py_BuildValue("I",
  579. TSIGContext::VERIFIED_RESPONSE));
  580. installClassVariable(tsigcontext_type, "DEFAULT_FUDGE",
  581. Py_BuildValue("H", TSIGContext::DEFAULT_FUDGE));
  582. } catch (const std::exception& ex) {
  583. const std::string ex_what =
  584. "Unexpected failure in TSIGContext initialization: " +
  585. std::string(ex.what());
  586. PyErr_SetString(po_IscException, ex_what.c_str());
  587. return (false);
  588. } catch (...) {
  589. PyErr_SetString(PyExc_SystemError,
  590. "Unexpected failure in TSIGContext initialization");
  591. return (false);
  592. }
  593. return (true);
  594. }
  595. bool
  596. initModulePart_TSIG(PyObject* mod) {
  597. if (PyType_Ready(&tsig_type) < 0) {
  598. return (false);
  599. }
  600. void* p = &tsig_type;
  601. if (PyModule_AddObject(mod, "TSIG", static_cast<PyObject*>(p)) < 0) {
  602. return (false);
  603. }
  604. Py_INCREF(&tsig_type);
  605. return (true);
  606. }
  607. bool
  608. initModulePart_TSIGRecord(PyObject* mod) {
  609. if (PyType_Ready(&tsigrecord_type) < 0) {
  610. return (false);
  611. }
  612. void* p = &tsigrecord_type;
  613. if (PyModule_AddObject(mod, "TSIGRecord", static_cast<PyObject*>(p)) < 0) {
  614. return (false);
  615. }
  616. Py_INCREF(&tsigrecord_type);
  617. try {
  618. // Constant class variables
  619. installClassVariable(tsigrecord_type, "TSIG_TTL",
  620. Py_BuildValue("I", 0));
  621. } catch (const std::exception& ex) {
  622. const std::string ex_what =
  623. "Unexpected failure in TSIGRecord initialization: " +
  624. std::string(ex.what());
  625. PyErr_SetString(po_IscException, ex_what.c_str());
  626. return (false);
  627. } catch (...) {
  628. PyErr_SetString(PyExc_SystemError,
  629. "Unexpected failure in TSIGRecord initialization");
  630. return (false);
  631. }
  632. return (true);
  633. }
  634. PyModuleDef pydnspp = {
  635. { PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
  636. "pydnspp",
  637. "Python bindings for the classes in the isc::dns namespace.\n\n"
  638. "These bindings match the original C++ API as closely as possible, "
  639. "but are not complete. Some classes are unnecessary (InputBuffer "
  640. "and OutputBuffer for instance), and others may be necessary, but "
  641. "were not up to now.",
  642. -1,
  643. NULL,
  644. NULL,
  645. NULL,
  646. NULL,
  647. NULL
  648. };
  649. }
  650. PyMODINIT_FUNC
  651. PyInit_pydnspp(void) {
  652. PyObject* mod = PyModule_Create(&pydnspp);
  653. if (mod == NULL) {
  654. return (NULL);
  655. }
  656. // Add the exceptions to the class
  657. po_IscException = PyErr_NewException("pydnspp.IscException", NULL, NULL);
  658. PyModule_AddObject(mod, "IscException", po_IscException);
  659. po_InvalidParameter = PyErr_NewException("pydnspp.InvalidParameter",
  660. NULL, NULL);
  661. PyModule_AddObject(mod, "InvalidParameter", po_InvalidParameter);
  662. // for each part included above, we call its specific initializer
  663. if (!initModulePart_Name(mod)) {
  664. return (NULL);
  665. }
  666. if (!initModulePart_MessageRenderer(mod)) {
  667. return (NULL);
  668. }
  669. if (!initModulePart_RRClass(mod)) {
  670. return (NULL);
  671. }
  672. if (!initModulePart_RRType(mod)) {
  673. return (NULL);
  674. }
  675. if (!initModulePart_RRTTL(mod)) {
  676. return (NULL);
  677. }
  678. if (!initModulePart_Rdata(mod)) {
  679. return (NULL);
  680. }
  681. if (!initModulePart_RRset(mod)) {
  682. return (NULL);
  683. }
  684. if (!initModulePart_Question(mod)) {
  685. return (NULL);
  686. }
  687. if (!initModulePart_Opcode(mod)) {
  688. return (NULL);
  689. }
  690. if (!initModulePart_Rcode(mod)) {
  691. return (NULL);
  692. }
  693. if (!initModulePart_Message(mod)) {
  694. return (NULL);
  695. }
  696. if (!initModulePart_EDNS(mod)) {
  697. return (NULL);
  698. }
  699. if (!initModulePart_TSIGKey(mod)) {
  700. return (NULL);
  701. }
  702. if (!initModulePart_TSIGKeyRing(mod)) {
  703. return (NULL);
  704. }
  705. if (!initModulePart_TSIG(mod)) {
  706. return (NULL);
  707. }
  708. if (!initModulePart_TSIGError(mod)) {
  709. return (NULL);
  710. }
  711. if (!initModulePart_TSIGRecord(mod)) {
  712. return (NULL);
  713. }
  714. if (!initModulePart_TSIGContext(mod)) {
  715. return (NULL);
  716. }
  717. return (mod);
  718. }