message_python.cc 28 KB

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