message_python.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  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. #include <exceptions/exceptions.h>
  15. #include <dns/message.h>
  16. #include <dns/rcode.h>
  17. #include <dns/tsig.h>
  18. using namespace isc::dns;
  19. using namespace isc::util;
  20. namespace {
  21. //
  22. // Declaration of the custom exceptions
  23. // Initialization and addition of these go in the initModulePart
  24. // function at the end of this file
  25. //
  26. PyObject* po_MessageTooShort;
  27. PyObject* po_InvalidMessageSection;
  28. PyObject* po_InvalidMessageOperation;
  29. PyObject* po_InvalidMessageUDPSize;
  30. //
  31. // Definition of the classes
  32. //
  33. // For each class, we need a struct, a helper functions (init, destroy,
  34. // and static wrappers around the methods we export), a list of methods,
  35. // and a type description
  36. //
  37. // Message
  38. //
  39. // The s_* Class simply coverst one instantiation of the object
  40. class s_Message : public PyObject {
  41. public:
  42. Message* message;
  43. };
  44. //
  45. // We declare the functions here, the definitions are below
  46. // the type definition of the object, since both can use the other
  47. //
  48. // General creation and destruction
  49. int Message_init(s_Message* self, PyObject* args);
  50. void Message_destroy(s_Message* self);
  51. PyObject* Message_getHeaderFlag(s_Message* self, PyObject* args);
  52. PyObject* Message_setHeaderFlag(s_Message* self, PyObject* args);
  53. PyObject* Message_getQid(s_Message* self);
  54. PyObject* Message_setQid(s_Message* self, PyObject* args);
  55. PyObject* Message_getRcode(s_Message* self);
  56. PyObject* Message_setRcode(s_Message* self, PyObject* args);
  57. PyObject* Message_getOpcode(s_Message* self);
  58. PyObject* Message_setOpcode(s_Message* self, PyObject* args);
  59. PyObject* Message_getEDNS(s_Message* self);
  60. PyObject* Message_setEDNS(s_Message* self, PyObject* args);
  61. PyObject* Message_getTSIGRecord(s_Message* self);
  62. PyObject* Message_getRRCount(s_Message* self, PyObject* args);
  63. // use direct iterators for these? (or simply lists for now?)
  64. PyObject* Message_getQuestion(s_Message* self);
  65. PyObject* Message_getSection(s_Message* self, PyObject* args);
  66. //static PyObject* Message_beginQuestion(s_Message* self, PyObject* args);
  67. //static PyObject* Message_endQuestion(s_Message* self, PyObject* args);
  68. //static PyObject* Message_beginSection(s_Message* self, PyObject* args);
  69. //static PyObject* Message_endSection(s_Message* self, PyObject* args);
  70. PyObject* Message_addQuestion(s_Message* self, PyObject* args);
  71. PyObject* Message_addRRset(s_Message* self, PyObject* args);
  72. PyObject* Message_clear(s_Message* self, PyObject* args);
  73. PyObject* Message_makeResponse(s_Message* self);
  74. PyObject* Message_toText(s_Message* self);
  75. PyObject* Message_str(PyObject* self);
  76. PyObject* Message_toWire(s_Message* self, PyObject* args);
  77. PyObject* Message_fromWire(s_Message* self, PyObject* args);
  78. // This list contains the actual set of functions we have in
  79. // python. Each entry has
  80. // 1. Python method name
  81. // 2. Our static function here
  82. // 3. Argument type
  83. // 4. Documentation
  84. PyMethodDef Message_methods[] = {
  85. { "get_header_flag", reinterpret_cast<PyCFunction>(Message_getHeaderFlag),
  86. METH_VARARGS,
  87. "Return whether the specified header flag bit is set in the "
  88. "header section. Takes a MessageFlag object as the only argument." },
  89. { "set_header_flag",
  90. reinterpret_cast<PyCFunction>(Message_setHeaderFlag), METH_VARARGS,
  91. "Sets the specified header flag bit to 1. The message must be in "
  92. "RENDER mode. If not, an InvalidMessageOperation is raised. "
  93. "Takes a MessageFlag object as the only argument." },
  94. { "get_qid", reinterpret_cast<PyCFunction>(Message_getQid), METH_NOARGS,
  95. "Returns the query id" },
  96. { "set_qid", reinterpret_cast<PyCFunction>(Message_setQid), METH_VARARGS,
  97. "Sets the query id. If the message is not in RENDER mode, an "
  98. "InvalidMessageOperation is raised.\n"
  99. "The argument must be an integer" },
  100. { "get_rcode", reinterpret_cast<PyCFunction>(Message_getRcode), METH_NOARGS,
  101. "Returns the message Response code (an Rcode object)" },
  102. { "set_rcode", reinterpret_cast<PyCFunction>(Message_setRcode), METH_VARARGS,
  103. "Sets the message Response code (an Rcode object).\n"
  104. "If the message is not in RENDER mode, an "
  105. "InvalidMessageOperation is raised."},
  106. { "get_opcode", reinterpret_cast<PyCFunction>(Message_getOpcode), METH_NOARGS,
  107. "Returns the message opcode (an Opcode object)" },
  108. { "set_opcode", reinterpret_cast<PyCFunction>(Message_setOpcode), METH_VARARGS,
  109. "Sets the message opcode (an Opcode object).\n"
  110. "If the message is not in RENDER mode, an "
  111. "InvalidMessageOperation is raised."},
  112. { "get_edns", reinterpret_cast<PyCFunction>(Message_getEDNS), METH_NOARGS,
  113. "Return, if any, the EDNS associated with the message."
  114. },
  115. { "set_edns", reinterpret_cast<PyCFunction>(Message_setEDNS), METH_VARARGS,
  116. "Set EDNS for the message."
  117. },
  118. { "get_tsig_record",
  119. reinterpret_cast<PyCFunction>(Message_getTSIGRecord), METH_NOARGS,
  120. "Return, if any, the TSIG record contained in the received message. "
  121. "If no TSIG RR is set in the message, None will be returned."
  122. },
  123. { "get_rr_count", reinterpret_cast<PyCFunction>(Message_getRRCount), METH_VARARGS,
  124. "Returns the number of RRs contained in the given section." },
  125. { "get_question", reinterpret_cast<PyCFunction>(Message_getQuestion), METH_NOARGS,
  126. "Returns a list of all Question objects in the message "
  127. "(should be either 0 or 1)" },
  128. { "get_section", reinterpret_cast<PyCFunction>(Message_getSection), METH_VARARGS,
  129. "Returns a list of all RRset objects in the given section of the message\n"
  130. "The argument must be of type Section" },
  131. { "add_question", reinterpret_cast<PyCFunction>(Message_addQuestion), METH_VARARGS,
  132. "Add a Question to the message."
  133. "If the message is not in RENDER mode, an "
  134. "InvalidMessageOperation is raised."},
  135. { "add_rrset", reinterpret_cast<PyCFunction>(Message_addRRset), METH_VARARGS,
  136. "Add an RRset to the given section of the message.\n"
  137. "The first argument is of type Section\n"
  138. "The second is of type RRset\n"
  139. "The third argument is an optional Boolean specifying whether "
  140. "the RRset is signed"},
  141. { "clear", reinterpret_cast<PyCFunction>(Message_clear), METH_VARARGS,
  142. "Clears the message content (if any) and reinitialize the "
  143. "message in the given mode\n"
  144. "The argument must be either Message.PARSE or Message.RENDER"},
  145. { "make_response", reinterpret_cast<PyCFunction>(Message_makeResponse), METH_NOARGS,
  146. "Prepare for making a response from a request.\n"
  147. "This will clear the DNS header except those fields that should be kept "
  148. "for the response, and clear answer and the following sections. "
  149. "See also dns_message_reply() of BIND9."},
  150. { "to_text", reinterpret_cast<PyCFunction>(Message_toText), METH_NOARGS,
  151. "Returns the string representation of the message" },
  152. { "to_wire", reinterpret_cast<PyCFunction>(Message_toWire), METH_VARARGS,
  153. "Render the message in wire format.\n"
  154. "The argument must be a MessageRenderer.\n"
  155. "If the given message is not in RENDER mode, an "
  156. "InvalidMessageOperation is raised.\n"
  157. },
  158. { "from_wire", reinterpret_cast<PyCFunction>(Message_fromWire), METH_VARARGS,
  159. "Parses the given wire format to a Message object.\n"
  160. "The first argument is a Message to parse the data into.\n"
  161. "The second argument must implement the buffer interface.\n"
  162. "If the given message is not in PARSE mode, an "
  163. "InvalidMessageOperation is raised.\n"
  164. "Raises MessageTooShort, DNSMessageFORMERR or DNSMessageBADVERS "
  165. " if there is a problem parsing the message." },
  166. { NULL, NULL, 0, NULL }
  167. };
  168. // This defines the complete type for reflection in python and
  169. // parsing of PyObject* to s_Message
  170. // Most of the functions are not actually implemented and NULL here.
  171. PyTypeObject message_type = {
  172. PyVarObject_HEAD_INIT(NULL, 0)
  173. "pydnspp.Message",
  174. sizeof(s_Message), // tp_basicsize
  175. 0, // tp_itemsize
  176. (destructor)Message_destroy, // tp_dealloc
  177. NULL, // tp_print
  178. NULL, // tp_getattr
  179. NULL, // tp_setattr
  180. NULL, // tp_reserved
  181. NULL, // tp_repr
  182. NULL, // tp_as_number
  183. NULL, // tp_as_sequence
  184. NULL, // tp_as_mapping
  185. NULL, // tp_hash
  186. NULL, // tp_call
  187. Message_str, // tp_str
  188. NULL, // tp_getattro
  189. NULL, // tp_setattro
  190. NULL, // tp_as_buffer
  191. Py_TPFLAGS_DEFAULT, // tp_flags
  192. "The Message class encapsulates a standard DNS message.",
  193. NULL, // tp_traverse
  194. NULL, // tp_clear
  195. NULL, // tp_richcompare
  196. 0, // tp_weaklistoffset
  197. NULL, // tp_iter
  198. NULL, // tp_iternext
  199. Message_methods, // tp_methods
  200. NULL, // tp_members
  201. NULL, // tp_getset
  202. NULL, // tp_base
  203. NULL, // tp_dict
  204. NULL, // tp_descr_get
  205. NULL, // tp_descr_set
  206. 0, // tp_dictoffset
  207. (initproc)Message_init, // tp_init
  208. NULL, // tp_alloc
  209. PyType_GenericNew, // tp_new
  210. NULL, // tp_free
  211. NULL, // tp_is_gc
  212. NULL, // tp_bases
  213. NULL, // tp_mro
  214. NULL, // tp_cache
  215. NULL, // tp_subclasses
  216. NULL, // tp_weaklist
  217. NULL, // tp_del
  218. 0 // tp_version_tag
  219. };
  220. int
  221. Message_init(s_Message* self, PyObject* args) {
  222. int i;
  223. if (PyArg_ParseTuple(args, "i", &i)) {
  224. PyErr_Clear();
  225. if (i == Message::PARSE) {
  226. self->message = new Message(Message::PARSE);
  227. return (0);
  228. } else if (i == Message::RENDER) {
  229. self->message = new Message(Message::RENDER);
  230. return (0);
  231. } else {
  232. PyErr_SetString(PyExc_TypeError, "Message mode must be Message.PARSE or Message.RENDER");
  233. return (-1);
  234. }
  235. }
  236. PyErr_Clear();
  237. PyErr_SetString(PyExc_TypeError,
  238. "no valid type in constructor argument");
  239. return (-1);
  240. }
  241. void
  242. Message_destroy(s_Message* self) {
  243. delete self->message;
  244. self->message = NULL;
  245. Py_TYPE(self)->tp_free(self);
  246. }
  247. PyObject*
  248. Message_getHeaderFlag(s_Message* self, PyObject* args) {
  249. unsigned int messageflag;
  250. if (!PyArg_ParseTuple(args, "I", &messageflag)) {
  251. PyErr_Clear();
  252. PyErr_SetString(PyExc_TypeError,
  253. "no valid type in get_header_flag argument");
  254. return (NULL);
  255. }
  256. if (self->message->getHeaderFlag(
  257. static_cast<Message::HeaderFlag>(messageflag))) {
  258. Py_RETURN_TRUE;
  259. } else {
  260. Py_RETURN_FALSE;
  261. }
  262. }
  263. PyObject*
  264. Message_setHeaderFlag(s_Message* self, PyObject* args) {
  265. long messageflag;
  266. PyObject *on = Py_True;
  267. if (!PyArg_ParseTuple(args, "l|O!", &messageflag, &PyBool_Type, &on)) {
  268. PyErr_Clear();
  269. PyErr_SetString(PyExc_TypeError,
  270. "no valid type in set_header_flag argument");
  271. return (NULL);
  272. }
  273. if (messageflag < 0 || messageflag > 0xffff) {
  274. PyErr_SetString(PyExc_ValueError, "Message header flag out of range");
  275. return (NULL);
  276. }
  277. try {
  278. self->message->setHeaderFlag(
  279. static_cast<Message::HeaderFlag>(messageflag), on == Py_True);
  280. Py_RETURN_NONE;
  281. } catch (const InvalidMessageOperation& imo) {
  282. PyErr_Clear();
  283. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  284. return (NULL);
  285. } catch (const isc::InvalidParameter& ip) {
  286. PyErr_Clear();
  287. PyErr_SetString(po_InvalidParameter, ip.what());
  288. return (NULL);
  289. }
  290. }
  291. PyObject*
  292. Message_getQid(s_Message* self) {
  293. return (Py_BuildValue("I", self->message->getQid()));
  294. }
  295. PyObject*
  296. Message_setQid(s_Message* self, PyObject* args) {
  297. long id;
  298. if (!PyArg_ParseTuple(args, "l", &id)) {
  299. PyErr_Clear();
  300. PyErr_SetString(PyExc_TypeError,
  301. "no valid type in set_qid argument");
  302. return (NULL);
  303. }
  304. if (id < 0 || id > 0xffff) {
  305. PyErr_SetString(PyExc_ValueError,
  306. "Message id out of range");
  307. return (NULL);
  308. }
  309. try {
  310. self->message->setQid(id);
  311. Py_RETURN_NONE;
  312. } catch (const InvalidMessageOperation& imo) {
  313. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  314. return (NULL);
  315. }
  316. }
  317. PyObject*
  318. Message_getRcode(s_Message* self) {
  319. s_Rcode* rcode;
  320. rcode = static_cast<s_Rcode*>(rcode_type.tp_alloc(&rcode_type, 0));
  321. if (rcode != NULL) {
  322. rcode->cppobj = NULL;
  323. try {
  324. rcode->cppobj = new Rcode(self->message->getRcode());
  325. } catch (const InvalidMessageOperation& imo) {
  326. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  327. } catch (...) {
  328. PyErr_SetString(po_IscException, "Unexpected exception");
  329. }
  330. if (rcode->cppobj == NULL) {
  331. Py_DECREF(rcode);
  332. return (NULL);
  333. }
  334. }
  335. return (rcode);
  336. }
  337. PyObject*
  338. Message_setRcode(s_Message* self, PyObject* args) {
  339. s_Rcode* rcode;
  340. if (!PyArg_ParseTuple(args, "O!", &rcode_type, &rcode)) {
  341. return (NULL);
  342. }
  343. try {
  344. self->message->setRcode(*rcode->cppobj);
  345. Py_RETURN_NONE;
  346. } catch (const InvalidMessageOperation& imo) {
  347. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  348. return (NULL);
  349. }
  350. }
  351. PyObject*
  352. Message_getOpcode(s_Message* self) {
  353. s_Opcode* opcode;
  354. opcode = static_cast<s_Opcode*>(opcode_type.tp_alloc(&opcode_type, 0));
  355. if (opcode != NULL) {
  356. opcode->opcode = NULL;
  357. try {
  358. opcode->opcode = new Opcode(self->message->getOpcode());
  359. } catch (const InvalidMessageOperation& imo) {
  360. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  361. } catch (...) {
  362. PyErr_SetString(po_IscException, "Unexpected exception");
  363. }
  364. if (opcode->opcode == NULL) {
  365. Py_DECREF(opcode);
  366. return (NULL);
  367. }
  368. }
  369. return (opcode);
  370. }
  371. PyObject*
  372. Message_setOpcode(s_Message* self, PyObject* args) {
  373. s_Opcode* opcode;
  374. if (!PyArg_ParseTuple(args, "O!", &opcode_type, &opcode)) {
  375. return (NULL);
  376. }
  377. try {
  378. self->message->setOpcode(*opcode->opcode);
  379. Py_RETURN_NONE;
  380. } catch (const InvalidMessageOperation& imo) {
  381. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  382. return (NULL);
  383. }
  384. }
  385. PyObject*
  386. Message_getEDNS(s_Message* self) {
  387. s_EDNS* edns;
  388. EDNS* edns_body;
  389. ConstEDNSPtr src = self->message->getEDNS();
  390. if (!src) {
  391. Py_RETURN_NONE;
  392. }
  393. if ((edns_body = new(nothrow) EDNS(*src)) == NULL) {
  394. return (PyErr_NoMemory());
  395. }
  396. edns = static_cast<s_EDNS*>(opcode_type.tp_alloc(&edns_type, 0));
  397. if (edns != NULL) {
  398. edns->edns = edns_body;
  399. }
  400. return (edns);
  401. }
  402. PyObject*
  403. Message_setEDNS(s_Message* self, PyObject* args) {
  404. s_EDNS* edns;
  405. if (!PyArg_ParseTuple(args, "O!", &edns_type, &edns)) {
  406. return (NULL);
  407. }
  408. try {
  409. self->message->setEDNS(EDNSPtr(new EDNS(*edns->edns)));
  410. Py_RETURN_NONE;
  411. } catch (const InvalidMessageOperation& imo) {
  412. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  413. return (NULL);
  414. }
  415. }
  416. PyObject*
  417. Message_getTSIGRecord(s_Message* self) {
  418. try {
  419. const TSIGRecord* tsig_record = self->message->getTSIGRecord();
  420. if (tsig_record == NULL) {
  421. Py_RETURN_NONE;
  422. }
  423. return (createTSIGRecordObject(*tsig_record));
  424. } catch (const InvalidMessageOperation& ex) {
  425. PyErr_SetString(po_InvalidMessageOperation, ex.what());
  426. } catch (const exception& ex) {
  427. const string ex_what =
  428. "Unexpected failure in getting TSIGRecord from message: " +
  429. string(ex.what());
  430. PyErr_SetString(po_IscException, ex_what.c_str());
  431. } catch (...) {
  432. PyErr_SetString(PyExc_SystemError, "Unexpected failure in "
  433. "getting TSIGRecord from message");
  434. }
  435. return (NULL);
  436. }
  437. PyObject*
  438. Message_getRRCount(s_Message* self, PyObject* args) {
  439. unsigned int section;
  440. if (!PyArg_ParseTuple(args, "I", &section)) {
  441. PyErr_Clear();
  442. PyErr_SetString(PyExc_TypeError,
  443. "no valid type in get_rr_count argument");
  444. return (NULL);
  445. }
  446. try {
  447. return (Py_BuildValue("I", self->message->getRRCount(
  448. static_cast<Message::Section>(section))));
  449. } catch (const isc::OutOfRange& ex) {
  450. PyErr_SetString(PyExc_OverflowError, ex.what());
  451. return (NULL);
  452. }
  453. }
  454. // TODO use direct iterators for these? (or simply lists for now?)
  455. PyObject*
  456. Message_getQuestion(s_Message* self) {
  457. QuestionIterator qi, qi_end;
  458. try {
  459. qi = self->message->beginQuestion();
  460. qi_end = self->message->endQuestion();
  461. } catch (const InvalidMessageSection& ex) {
  462. PyErr_SetString(po_InvalidMessageSection, ex.what());
  463. return (NULL);
  464. } catch (...) {
  465. PyErr_SetString(po_IscException,
  466. "Unexpected exception in getting section iterators");
  467. return (NULL);
  468. }
  469. PyObject* list = PyList_New(0);
  470. if (list == NULL) {
  471. return (NULL);
  472. }
  473. for (; qi != qi_end; ++qi) {
  474. s_Question *question = static_cast<s_Question*>(
  475. question_type.tp_alloc(&question_type, 0));
  476. if (question == NULL) {
  477. Py_DECREF(question);
  478. Py_DECREF(list);
  479. return (NULL);
  480. }
  481. question->question = *qi;
  482. if (PyList_Append(list, question) == -1) {
  483. Py_DECREF(question);
  484. Py_DECREF(list);
  485. return (NULL);
  486. }
  487. Py_DECREF(question);
  488. }
  489. return (list);
  490. }
  491. PyObject*
  492. Message_getSection(s_Message* self, PyObject* args) {
  493. unsigned int section;
  494. if (!PyArg_ParseTuple(args, "I", &section)) {
  495. PyErr_Clear();
  496. PyErr_SetString(PyExc_TypeError,
  497. "no valid type in get_section argument");
  498. return (NULL);
  499. }
  500. RRsetIterator rrsi, rrsi_end;
  501. try {
  502. rrsi = self->message->beginSection(
  503. static_cast<Message::Section>(section));
  504. rrsi_end = self->message->endSection(
  505. static_cast<Message::Section>(section));
  506. } catch (const isc::OutOfRange& ex) {
  507. PyErr_SetString(PyExc_OverflowError, ex.what());
  508. return (NULL);
  509. } catch (const InvalidMessageSection& ex) {
  510. PyErr_SetString(po_InvalidMessageSection, ex.what());
  511. return (NULL);
  512. } catch (...) {
  513. PyErr_SetString(po_IscException,
  514. "Unexpected exception in getting section iterators");
  515. return (NULL);
  516. }
  517. PyObject* list = PyList_New(0);
  518. if (list == NULL) {
  519. return (NULL);
  520. }
  521. for (; rrsi != rrsi_end; ++rrsi) {
  522. s_RRset *rrset = static_cast<s_RRset*>(
  523. rrset_type.tp_alloc(&rrset_type, 0));
  524. if (rrset == NULL) {
  525. Py_DECREF(rrset);
  526. Py_DECREF(list);
  527. return (NULL);
  528. }
  529. rrset->rrset = *rrsi;
  530. if (PyList_Append(list, rrset) == -1) {
  531. Py_DECREF(rrset);
  532. Py_DECREF(list);
  533. return (NULL);
  534. }
  535. // PyList_Append increases refcount, so we remove ours since
  536. // we don't need it anymore
  537. Py_DECREF(rrset);
  538. }
  539. return (list);
  540. }
  541. //static PyObject* Message_beginQuestion(s_Message* self, PyObject* args);
  542. //static PyObject* Message_endQuestion(s_Message* self, PyObject* args);
  543. //static PyObject* Message_beginSection(s_Message* self, PyObject* args);
  544. //static PyObject* Message_endSection(s_Message* self, PyObject* args);
  545. //static PyObject* Message_addQuestion(s_Message* self, PyObject* args);
  546. PyObject*
  547. Message_addQuestion(s_Message* self, PyObject* args) {
  548. s_Question *question;
  549. if (!PyArg_ParseTuple(args, "O!", &question_type, &question)) {
  550. return (NULL);
  551. }
  552. self->message->addQuestion(question->question);
  553. Py_RETURN_NONE;
  554. }
  555. PyObject*
  556. Message_addRRset(s_Message* self, PyObject* args) {
  557. PyObject *sign = Py_False;
  558. int section;
  559. s_RRset* rrset;
  560. if (!PyArg_ParseTuple(args, "iO!|O!", &section, &rrset_type, &rrset,
  561. &PyBool_Type, &sign)) {
  562. return (NULL);
  563. }
  564. try {
  565. self->message->addRRset(static_cast<Message::Section>(section),
  566. rrset->rrset, sign == Py_True);
  567. Py_RETURN_NONE;
  568. } catch (const InvalidMessageOperation& imo) {
  569. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  570. return (NULL);
  571. } catch (const isc::OutOfRange& ex) {
  572. PyErr_SetString(PyExc_OverflowError, ex.what());
  573. return (NULL);
  574. } catch (...) {
  575. PyErr_SetString(po_IscException,
  576. "Unexpected exception in adding RRset");
  577. return (NULL);
  578. }
  579. }
  580. PyObject*
  581. Message_clear(s_Message* self, PyObject* args) {
  582. int i;
  583. if (PyArg_ParseTuple(args, "i", &i)) {
  584. PyErr_Clear();
  585. if (i == Message::PARSE) {
  586. self->message->clear(Message::PARSE);
  587. Py_RETURN_NONE;
  588. } else if (i == Message::RENDER) {
  589. self->message->clear(Message::RENDER);
  590. Py_RETURN_NONE;
  591. } else {
  592. PyErr_SetString(PyExc_TypeError,
  593. "Message mode must be Message.PARSE or Message.RENDER");
  594. return (NULL);
  595. }
  596. } else {
  597. return (NULL);
  598. }
  599. }
  600. PyObject*
  601. Message_makeResponse(s_Message* self) {
  602. self->message->makeResponse();
  603. Py_RETURN_NONE;
  604. }
  605. PyObject*
  606. Message_toText(s_Message* self) {
  607. // Py_BuildValue makes python objects from native data
  608. try {
  609. return (Py_BuildValue("s", self->message->toText().c_str()));
  610. } catch (const InvalidMessageOperation& imo) {
  611. PyErr_Clear();
  612. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  613. return (NULL);
  614. } catch (...) {
  615. PyErr_SetString(po_IscException, "Unexpected exception");
  616. return (NULL);
  617. }
  618. }
  619. PyObject*
  620. Message_str(PyObject* self) {
  621. // Simply call the to_text method we already defined
  622. return (PyObject_CallMethod(self,
  623. const_cast<char*>("to_text"),
  624. const_cast<char*>("")));
  625. }
  626. PyObject*
  627. Message_toWire(s_Message* self, PyObject* args) {
  628. s_MessageRenderer* mr;
  629. s_TSIGContext* tsig_ctx = NULL;
  630. if (PyArg_ParseTuple(args, "O!|O!", &messagerenderer_type, &mr,
  631. &tsigcontext_type, &tsig_ctx)) {
  632. try {
  633. if (tsig_ctx == NULL) {
  634. self->message->toWire(*mr->messagerenderer);
  635. } else {
  636. self->message->toWire(*mr->messagerenderer, *tsig_ctx->cppobj);
  637. }
  638. // If we return NULL it is seen as an error, so use this for
  639. // None returns
  640. Py_RETURN_NONE;
  641. } catch (const InvalidMessageOperation& imo) {
  642. PyErr_Clear();
  643. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  644. return (NULL);
  645. } catch (const TSIGContextError& ex) {
  646. // toWire() with a TSIG context can fail due to this if the
  647. // python program has a bug.
  648. PyErr_SetString(po_TSIGContextError, ex.what());
  649. return (NULL);
  650. }
  651. }
  652. PyErr_Clear();
  653. PyErr_SetString(PyExc_TypeError,
  654. "toWire argument must be a MessageRenderer");
  655. return (NULL);
  656. }
  657. PyObject*
  658. Message_fromWire(s_Message* self, PyObject* args) {
  659. const char* b;
  660. Py_ssize_t len;
  661. if (!PyArg_ParseTuple(args, "y#", &b, &len)) {
  662. return (NULL);
  663. }
  664. InputBuffer inbuf(b, len);
  665. try {
  666. self->message->fromWire(inbuf);
  667. Py_RETURN_NONE;
  668. } catch (const InvalidMessageOperation& imo) {
  669. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  670. return (NULL);
  671. } catch (const DNSMessageFORMERR& dmfe) {
  672. PyErr_SetString(po_DNSMessageFORMERR, dmfe.what());
  673. return (NULL);
  674. } catch (const DNSMessageBADVERS& dmfe) {
  675. PyErr_SetString(po_DNSMessageBADVERS, dmfe.what());
  676. return (NULL);
  677. } catch (const MessageTooShort& mts) {
  678. PyErr_SetString(po_MessageTooShort, mts.what());
  679. return (NULL);
  680. }
  681. }
  682. // Module Initialization, all statics are initialized here
  683. bool
  684. initModulePart_Message(PyObject* mod) {
  685. if (PyType_Ready(&message_type) < 0) {
  686. return (false);
  687. }
  688. Py_INCREF(&message_type);
  689. // Class variables
  690. // These are added to the tp_dict of the type object
  691. //
  692. addClassVariable(message_type, "PARSE",
  693. Py_BuildValue("I", Message::PARSE));
  694. addClassVariable(message_type, "RENDER",
  695. Py_BuildValue("I", Message::RENDER));
  696. addClassVariable(message_type, "HEADERFLAG_QR",
  697. Py_BuildValue("I", Message::HEADERFLAG_QR));
  698. addClassVariable(message_type, "HEADERFLAG_AA",
  699. Py_BuildValue("I", Message::HEADERFLAG_AA));
  700. addClassVariable(message_type, "HEADERFLAG_TC",
  701. Py_BuildValue("I", Message::HEADERFLAG_TC));
  702. addClassVariable(message_type, "HEADERFLAG_RD",
  703. Py_BuildValue("I", Message::HEADERFLAG_RD));
  704. addClassVariable(message_type, "HEADERFLAG_RA",
  705. Py_BuildValue("I", Message::HEADERFLAG_RA));
  706. addClassVariable(message_type, "HEADERFLAG_AD",
  707. Py_BuildValue("I", Message::HEADERFLAG_AD));
  708. addClassVariable(message_type, "HEADERFLAG_CD",
  709. Py_BuildValue("I", Message::HEADERFLAG_CD));
  710. addClassVariable(message_type, "SECTION_QUESTION",
  711. Py_BuildValue("I", Message::SECTION_QUESTION));
  712. addClassVariable(message_type, "SECTION_ANSWER",
  713. Py_BuildValue("I", Message::SECTION_ANSWER));
  714. addClassVariable(message_type, "SECTION_AUTHORITY",
  715. Py_BuildValue("I", Message::SECTION_AUTHORITY));
  716. addClassVariable(message_type, "SECTION_ADDITIONAL",
  717. Py_BuildValue("I", Message::SECTION_ADDITIONAL));
  718. addClassVariable(message_type, "DEFAULT_MAX_UDPSIZE",
  719. Py_BuildValue("I", Message::DEFAULT_MAX_UDPSIZE));
  720. /* Class-specific exceptions */
  721. po_MessageTooShort = PyErr_NewException("pydnspp.MessageTooShort", NULL,
  722. NULL);
  723. PyModule_AddObject(mod, "MessageTooShort", po_MessageTooShort);
  724. po_InvalidMessageSection =
  725. PyErr_NewException("pydnspp.InvalidMessageSection", NULL, NULL);
  726. PyModule_AddObject(mod, "InvalidMessageSection", po_InvalidMessageSection);
  727. po_InvalidMessageOperation =
  728. PyErr_NewException("pydnspp.InvalidMessageOperation", NULL, NULL);
  729. PyModule_AddObject(mod, "InvalidMessageOperation",
  730. po_InvalidMessageOperation);
  731. po_InvalidMessageUDPSize =
  732. PyErr_NewException("pydnspp.InvalidMessageUDPSize", NULL, NULL);
  733. PyModule_AddObject(mod, "InvalidMessageUDPSize", po_InvalidMessageUDPSize);
  734. po_DNSMessageBADVERS = PyErr_NewException("pydnspp.DNSMessageBADVERS",
  735. NULL, NULL);
  736. PyModule_AddObject(mod, "DNSMessageBADVERS", po_DNSMessageBADVERS);
  737. PyModule_AddObject(mod, "Message",
  738. reinterpret_cast<PyObject*>(&message_type));
  739. return (true);
  740. }
  741. } // end of unnamed namespace