message_python.cc 27 KB

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