pydnspp.cc 31 KB

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