2
0

python_msgobj.c 14 KB

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