python_msgobj.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /* $Id$
  2. *
  3. * Copyright (C) 2009 Sippy Software, Inc., http://www.sippysoft.com
  4. *
  5. * This file is part of SIP-Router, a free SIP server.
  6. *
  7. * SIP-Router is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version
  11. *
  12. * SIP-Router is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. */
  22. #include <Python.h>
  23. #include "../../action.h"
  24. #include "../../mem/mem.h"
  25. #include "../../sr_module.h"
  26. #include "../../dset.h"
  27. #include "../../parser/msg_parser.h"
  28. #include "structmember.h"
  29. typedef struct {
  30. PyObject_HEAD
  31. struct sip_msg *msg;
  32. } msgobject;
  33. static PyTypeObject MSGtype;
  34. #define is_msgobject(v) ((v)->ob_type == &MSGtype)
  35. msgobject *newmsgobject(struct sip_msg *msg)
  36. {
  37. msgobject *msgp;
  38. msgp = PyObject_New(msgobject, &MSGtype);
  39. if (msgp == NULL)
  40. return NULL;
  41. msgp->msg = msg;
  42. return msgp;
  43. }
  44. void msg_invalidate(msgobject *self)
  45. {
  46. self->msg = NULL;
  47. }
  48. static void msg_dealloc(msgobject *msgp)
  49. {
  50. PyObject_Del(msgp);
  51. }
  52. static PyObject *msg_copy(msgobject *self)
  53. {
  54. msgobject *msgp;
  55. if ((msgp = newmsgobject(self->msg)) == NULL)
  56. return NULL;
  57. return (PyObject *)msgp;
  58. }
  59. static PyObject *msg_rewrite_ruri(msgobject *self, PyObject *args)
  60. {
  61. char *ruri;
  62. struct action act;
  63. struct run_act_ctx ra_ctx;
  64. if (self->msg == NULL) {
  65. PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
  66. Py_INCREF(Py_None);
  67. return Py_None;
  68. }
  69. if ((self->msg->first_line).type != SIP_REQUEST) {
  70. PyErr_SetString(PyExc_RuntimeError, "Not a request message - rewrite is not possible.\n");
  71. Py_INCREF(Py_None);
  72. return Py_None;
  73. }
  74. if(!PyArg_ParseTuple(args, "s:rewrite_ruri", &ruri))
  75. return NULL;
  76. memset(&act, '\0', sizeof(act));
  77. act.type = SET_URI_T;
  78. act.val[0].type = STRING_ST;
  79. act.val[0].u.str.s = ruri;
  80. act.val[0].u.str.len = strlen(ruri);
  81. init_run_actions_ctx(&ra_ctx);
  82. if (do_action(&ra_ctx, &act, self->msg) < 0) {
  83. LM_ERR("Error in do_action\n");
  84. }
  85. Py_INCREF(Py_None);
  86. return Py_None;
  87. }
  88. static PyObject *msg_set_dst_uri(msgobject *self, PyObject *args)
  89. {
  90. str ruri;
  91. if (self->msg == NULL) {
  92. PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
  93. Py_INCREF(Py_None);
  94. return Py_None;
  95. }
  96. if ((self->msg->first_line).type != SIP_REQUEST) {
  97. PyErr_SetString(PyExc_RuntimeError, "Not a request message - set destination is not possible.\n");
  98. Py_INCREF(Py_None);
  99. return Py_None;
  100. }
  101. if(!PyArg_ParseTuple(args, "s:set_dst_uri", &ruri.s))
  102. return NULL;
  103. ruri.len = strlen(ruri.s);
  104. if (set_dst_uri(self->msg, &ruri) < 0) {
  105. LM_ERR("Error in set_dst_uri\n");
  106. PyErr_SetString(PyExc_RuntimeError, "Error in set_dst_uri\n");
  107. }
  108. /* dst_uri changes, so it makes sense to re-use the current uri for
  109. forking */
  110. ruri_mark_new(); /* re-use uri for serial forking */
  111. Py_INCREF(Py_None);
  112. return Py_None;
  113. }
  114. static PyObject *msg_getHeader(msgobject *self, PyObject *args)
  115. {
  116. struct hdr_field *hf;
  117. str hname, *hbody;
  118. if (self->msg == NULL) {
  119. PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
  120. Py_INCREF(Py_None);
  121. return Py_None;
  122. }
  123. if(!PyArg_ParseTuple(args, "s:getHeader", &hname.s))
  124. return NULL;
  125. hname.len = strlen(hname.s);
  126. parse_headers(self->msg, ~0, 0);
  127. hbody = NULL;
  128. for (hf = self->msg->headers; hf != NULL; hf = hf->next) {
  129. if (hname.len == hf->name.len &&
  130. strncasecmp(hname.s, hf->name.s, hname.len) == 0) {
  131. hbody = &(hf->body);
  132. break;
  133. }
  134. }
  135. if (hbody == NULL) {
  136. Py_INCREF(Py_None);
  137. return Py_None;
  138. }
  139. return PyString_FromStringAndSize(hbody->s, hbody->len);
  140. }
  141. static PyObject *msg_call_function(msgobject *self, PyObject *args)
  142. {
  143. int i, rval;
  144. char *fname, *arg1, *arg2;
  145. sr31_cmd_export_t* fexport;
  146. struct action *act;
  147. struct run_act_ctx ra_ctx;
  148. unsigned mod_ver;
  149. if (self->msg == NULL) {
  150. PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
  151. Py_INCREF(Py_None);
  152. return Py_None;
  153. }
  154. i = PySequence_Size(args);
  155. if (i < 1 || i > 3) {
  156. PyErr_SetString(PyExc_RuntimeError, "call_function() should " \
  157. "have from 1 to 3 arguments");
  158. Py_INCREF(Py_None);
  159. return Py_None;
  160. }
  161. if(!PyArg_ParseTuple(args, "s|ss:call_function", &fname, &arg1, &arg2))
  162. return NULL;
  163. fexport = find_export_record(fname, i - 1, 0, &mod_ver);
  164. if (fexport == NULL) {
  165. PyErr_SetString(PyExc_RuntimeError, "no such function");
  166. Py_INCREF(Py_None);
  167. return Py_None;
  168. }
  169. act = mk_action(MODULE2_T, 4 /* number of (type, value) pairs */,
  170. MODEXP_ST, fexport, /* function */
  171. NUMBER_ST, 2, /* parameter number */
  172. STRING_ST, arg1, /* param. 1 */
  173. STRING_ST, arg2 /* param. 2 */
  174. );
  175. if (act == NULL) {
  176. PyErr_SetString(PyExc_RuntimeError,
  177. "action structure could not be created");
  178. Py_INCREF(Py_None);
  179. return Py_None;
  180. }
  181. if (fexport->fixup != NULL) {
  182. if (i >= 3) {
  183. rval = fexport->fixup(&(act->val[3].u.data), 2);
  184. if (rval < 0) {
  185. PyErr_SetString(PyExc_RuntimeError, "Error in fixup (2)");
  186. Py_INCREF(Py_None);
  187. return Py_None;
  188. }
  189. act->val[3].type = MODFIXUP_ST;
  190. }
  191. if (i >= 2) {
  192. rval = fexport->fixup(&(act->val[2].u.data), 1);
  193. if (rval < 0) {
  194. PyErr_SetString(PyExc_RuntimeError, "Error in fixup (1)");
  195. Py_INCREF(Py_None);
  196. return Py_None;
  197. }
  198. act->val[2].type = MODFIXUP_ST;
  199. }
  200. if (i == 1) {
  201. rval = fexport->fixup(0, 0);
  202. if (rval < 0) {
  203. PyErr_SetString(PyExc_RuntimeError, "Error in fixup (0)");
  204. Py_INCREF(Py_None);
  205. return Py_None;
  206. }
  207. }
  208. }
  209. init_run_actions_ctx(&ra_ctx);
  210. rval = do_action(&ra_ctx, act, self->msg);
  211. if ((act->val[3].type == MODFIXUP_ST) && (act->val[3].u.data)) {
  212. pkg_free(act->val[3].u.data);
  213. }
  214. if ((act->val[2].type == MODFIXUP_ST) && (act->val[2].u.data)) {
  215. pkg_free(act->val[2].u.data);
  216. }
  217. pkg_free(act);
  218. return PyInt_FromLong(rval);
  219. }
  220. PyDoc_STRVAR(copy_doc,
  221. "copy() -> msg object\n\
  222. \n\
  223. Return a copy (``clone'') of the msg object.");
  224. static PyMethodDef msg_methods[] = {
  225. {"copy", (PyCFunction)msg_copy, METH_NOARGS, copy_doc},
  226. {"rewrite_ruri", (PyCFunction)msg_rewrite_ruri, METH_VARARGS, "Rewrite Request-URI."},
  227. {"set_dst_uri", (PyCFunction)msg_set_dst_uri, METH_VARARGS, "Set destination URI."},
  228. {"getHeader", (PyCFunction)msg_getHeader, METH_VARARGS, "Get SIP header field by name."},
  229. {"call_function", (PyCFunction)msg_call_function, METH_VARARGS, "Invoke function exported by the other module."},
  230. {NULL, NULL, 0, NULL} /* sentinel */
  231. };
  232. static PyObject *msg_getType(msgobject *self, PyObject *unused)
  233. {
  234. const char *rval;
  235. if (self->msg == NULL) {
  236. PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
  237. Py_INCREF(Py_None);
  238. return Py_None;
  239. }
  240. switch ((self->msg->first_line).type)
  241. {
  242. case SIP_REQUEST:
  243. rval = "SIP_REQUEST";
  244. break;
  245. case SIP_REPLY:
  246. rval = "SIP_REPLY";
  247. break;
  248. default:
  249. rval = "SIP_INVALID";
  250. break;
  251. }
  252. return PyString_FromString(rval);
  253. }
  254. static PyObject *msg_getMethod(msgobject *self, PyObject *unused)
  255. {
  256. str *rval;
  257. if (self->msg == NULL) {
  258. PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
  259. Py_INCREF(Py_None);
  260. return Py_None;
  261. }
  262. if ((self->msg->first_line).type != SIP_REQUEST) {
  263. PyErr_SetString(PyExc_RuntimeError, "Not a request message - no method available.\n");
  264. Py_INCREF(Py_None);
  265. return Py_None;
  266. }
  267. rval = &((self->msg->first_line).u.request.method);
  268. return PyString_FromStringAndSize(rval->s, rval->len);
  269. }
  270. static PyObject *msg_getStatus(msgobject *self, PyObject *unused)
  271. {
  272. str *rval;
  273. if (self->msg == NULL) {
  274. PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
  275. Py_INCREF(Py_None);
  276. return Py_None;
  277. }
  278. if ((self->msg->first_line).type != SIP_REPLY) {
  279. PyErr_SetString(PyExc_RuntimeError, "Not a non-reply message - no status available.\n");
  280. Py_INCREF(Py_None);
  281. return Py_None;
  282. }
  283. rval = &((self->msg->first_line).u.reply.status);
  284. return PyString_FromStringAndSize(rval->s, rval->len);
  285. }
  286. static PyObject *msg_getRURI(msgobject *self, PyObject *unused)
  287. {
  288. str *rval;
  289. if (self->msg == NULL) {
  290. PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
  291. Py_INCREF(Py_None);
  292. return Py_None;
  293. }
  294. if ((self->msg->first_line).type != SIP_REQUEST) {
  295. PyErr_SetString(PyExc_RuntimeError, "Not a request message - RURI is not available.\n");
  296. Py_INCREF(Py_None);
  297. return Py_None;
  298. }
  299. rval = &((self->msg->first_line).u.request.uri);
  300. return PyString_FromStringAndSize(rval->s, rval->len);
  301. }
  302. static PyObject *msg_get_src_address(msgobject *self, PyObject *unused)
  303. {
  304. PyObject *src_ip, *src_port, *pyRval;
  305. if (self->msg == NULL) {
  306. PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
  307. Py_INCREF(Py_None);
  308. return Py_None;
  309. }
  310. src_ip = PyString_FromString(ip_addr2a(&self->msg->rcv.src_ip));
  311. if (src_ip == NULL) {
  312. Py_INCREF(Py_None);
  313. return Py_None;
  314. }
  315. src_port = PyInt_FromLong(self->msg->rcv.src_port);
  316. if (src_port == NULL) {
  317. Py_DECREF(src_ip);
  318. Py_INCREF(Py_None);
  319. return Py_None;
  320. }
  321. pyRval = PyTuple_Pack(2, src_ip, src_port);
  322. Py_DECREF(src_ip);
  323. Py_DECREF(src_port);
  324. if (pyRval == NULL) {
  325. Py_INCREF(Py_None);
  326. return Py_None;
  327. }
  328. return pyRval;
  329. }
  330. static PyObject *msg_get_dst_address(msgobject *self, PyObject *unused)
  331. {
  332. PyObject *dst_ip, *dst_port, *pyRval;
  333. if (self->msg == NULL) {
  334. PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
  335. Py_INCREF(Py_None);
  336. return Py_None;
  337. }
  338. dst_ip = PyString_FromString(ip_addr2a(&self->msg->rcv.dst_ip));
  339. if (dst_ip == NULL) {
  340. Py_INCREF(Py_None);
  341. return Py_None;
  342. }
  343. dst_port = PyInt_FromLong(self->msg->rcv.dst_port);
  344. if (dst_port == NULL) {
  345. Py_DECREF(dst_ip);
  346. Py_INCREF(Py_None);
  347. return Py_None;
  348. }
  349. pyRval = PyTuple_Pack(2, dst_ip, dst_port);
  350. Py_DECREF(dst_ip);
  351. Py_DECREF(dst_port);
  352. if (pyRval == NULL) {
  353. Py_INCREF(Py_None);
  354. return Py_None;
  355. }
  356. return pyRval;
  357. }
  358. static PyGetSetDef msg_getseters[] = {
  359. {"Type", (getter)msg_getType, NULL, NULL, "Get message type - \"SIP_REQUEST\" or \"SIP_REPLY\"."},
  360. {"Method", (getter)msg_getMethod, NULL, NULL, "Get SIP method name."},
  361. {"Status", (getter)msg_getStatus, NULL, NULL, "Get SIP status code string."},
  362. {"RURI", (getter)msg_getRURI, NULL, NULL, "Get SIP Request-URI."},
  363. {"src_address", (getter)msg_get_src_address, NULL, NULL, "Get (IP, port) tuple representing source address of the message."},
  364. {"dst_address", (getter)msg_get_dst_address, NULL, NULL, "Get (IP, port) tuple representing destination address of the message."},
  365. {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
  366. };
  367. static PyTypeObject MSGtype = {
  368. #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6
  369. PyVarObject_HEAD_INIT(NULL, 0)
  370. #else
  371. PyObject_HEAD_INIT(NULL)
  372. 0, /*ob_size*/
  373. #endif
  374. "Router.msg", /*tp_name*/
  375. sizeof(msgobject), /*tp_size*/
  376. 0, /*tp_itemsize*/
  377. /* methods */
  378. (destructor)msg_dealloc, /*tp_dealloc*/
  379. 0, /*tp_print*/
  380. 0, /*tp_getattr*/
  381. 0, /*tp_setattr*/
  382. 0, /*tp_compare*/
  383. 0, /*tp_repr*/
  384. 0, /*tp_as_number*/
  385. 0, /*tp_as_sequence*/
  386. 0, /*tp_as_mapping*/
  387. 0, /*tp_hash*/
  388. 0, /*tp_call*/
  389. 0, /*tp_str*/
  390. 0, /*tp_getattro*/
  391. 0, /*tp_setattro*/
  392. 0, /*tp_as_buffer*/
  393. Py_TPFLAGS_DEFAULT, /*tp_flags*/
  394. 0, /*tp_doc*/
  395. 0, /*tp_traverse*/
  396. 0, /*tp_clear*/
  397. 0, /*tp_richcompare*/
  398. 0, /*tp_weaklistoffset*/
  399. 0, /*tp_iter*/
  400. 0, /*tp_iternext*/
  401. msg_methods, /*tp_methods*/
  402. 0, /*tp_members*/
  403. msg_getseters, /*tp_getset*/
  404. };
  405. int python_msgobj_init(void)
  406. {
  407. MSGtype.ob_type = &PyType_Type;
  408. if (PyType_Ready(&MSGtype) < 0)
  409. return -1;
  410. return 0;
  411. }