message_python.cc 27 KB

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