action.c 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2001-2003 FhG Fokus
  5. *
  6. * This file is part of ser, a free SIP server.
  7. *
  8. * ser is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * For a license to use the ser software under conditions
  14. * other than those described here, or to purchase support for this
  15. * software, please contact iptel.org by e-mail at the following addresses:
  16. * [email protected]
  17. *
  18. * ser is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  26. *
  27. * History:
  28. * ---------
  29. * 2003-02-28 scratchpad compatibility abandoned (jiri)
  30. * 2003-01-29 removed scratchpad (jiri)
  31. * 2003-03-19 fixed set* len calculation bug & simplified a little the code
  32. * (should be a little faster now) (andrei)
  33. * replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
  34. * 2003-04-01 Added support for loose routing in forward (janakj)
  35. * 2003-04-12 FORCE_RPORT_T added (andrei)
  36. * 2003-04-22 strip_tail added (jiri)
  37. * 2003-10-02 added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei)
  38. * 2003-10-29 added FORCE_TCP_ALIAS_T (andrei)
  39. * 2004-11-30 added FORCE_SEND_SOCKET_T (andrei)
  40. * 2005-12-12 return & drop/exit differentiation (andrei)
  41. * 2005-12-19 select framework (mma)
  42. * 2006-04-12 updated *_send() calls to use a struct dest_info (andrei)
  43. * 2006-07-27 dns cache and dns based send address failover support (andrei)
  44. * 2006-12-06 on popular request last_retcode set also by module functions
  45. * (andrei)
  46. * 2007-06-14 run_actions & do_action need a ctx or handle now, no more
  47. * static vars (andrei)
  48. * 2008-11-18 support for variable parameter module functions (andrei)
  49. * 2008-12-03 use lvalues/rvalues for assignments (andrei)
  50. * 2008-12-17 added UDP_MTU_TRY_PROTO_T (andrei)
  51. * 2009-05-04 switched IF_T to rval_expr (andrei)
  52. * 2009-09-15 added SET_{FWD,RPL}_NO_CONNECT, SET_{FWD,RPL}_CLOSE (andrei)
  53. * 2010-06-01 special hack/support for fparam fixups so that they can handle
  54. * variable RVEs (andrei)
  55. */
  56. /*!
  57. * \file
  58. * \brief SIP-router core ::
  59. * \ingroup core
  60. * Module: \ref core
  61. */
  62. #include "comp_defs.h"
  63. #include "action.h"
  64. #include "config.h"
  65. #include "error.h"
  66. #include "dprint.h"
  67. #include "proxy.h"
  68. #include "forward.h"
  69. #include "udp_server.h"
  70. #include "route.h"
  71. #include "parser/msg_parser.h"
  72. #include "parser/parse_uri.h"
  73. #include "ut.h"
  74. #include "lvalue.h"
  75. #include "sr_module.h"
  76. #include "select_buf.h"
  77. #include "mem/mem.h"
  78. #include "globals.h"
  79. #include "dset.h"
  80. #include "onsend.h"
  81. #include "resolve.h"
  82. #ifdef USE_TCP
  83. #include "tcp_server.h"
  84. #endif
  85. #ifdef USE_SCTP
  86. #include "sctp_server.h"
  87. #endif
  88. #include "switch.h"
  89. #include "events.h"
  90. #include "cfg/cfg_struct.h"
  91. #include <sys/types.h>
  92. #include <sys/socket.h>
  93. #include <netdb.h>
  94. #include <stdlib.h>
  95. #include <netinet/in.h>
  96. #include <arpa/inet.h>
  97. #include <string.h>
  98. #ifdef DEBUG_DMALLOC
  99. #include <dmalloc.h>
  100. #endif
  101. int _last_returned_code = 0;
  102. struct onsend_info* p_onsend=0; /* onsend route send info */
  103. /* handle the exit code of a module function call.
  104. * (used internally in do_action())
  105. * @param h - script handle (h->last_retcode and h->run_flags will be set).
  106. * @param ret - module function (v0 or v2) retcode
  107. * Side-effects: sets _last_returned_code
  108. */
  109. #define MODF_HANDLE_RETCODE(h, ret) \
  110. do { \
  111. /* if (unlikely((ret)==0)) (h)->run_flags|=EXIT_R_F; */ \
  112. (h)->run_flags |= EXIT_R_F & (((ret) != 0) -1); \
  113. (h)->last_retcode=(ret); \
  114. _last_returned_code = (h)->last_retcode; \
  115. } while(0)
  116. /* frees parameters converted using MODF_RVE_PARAM_CONVERT() from dst.
  117. * (used internally in do_action())
  118. * Assumes src is unchanged.
  119. * Side-effects: clobbers i (int).
  120. */
  121. #define MODF_RVE_PARAM_FREE(cmd, src, dst) \
  122. for (i=0; i < (dst)[1].u.number; i++) { \
  123. if ((src)[i+2].type == RVE_ST && (dst)[i+2].u.data) { \
  124. if ((dst)[i+2].type == RVE_FREE_FIXUP_ST) {\
  125. /* call free_fixup (which should restore the original
  126. string) */ \
  127. call_fixup((cmd)->free_fixup, &(dst)[i+2].u.data, i+1); \
  128. } else if ((dst)[i+2].type == FPARAM_DYN_ST) {\
  129. /* completely frees fparam and restore original string */\
  130. fparam_free_restore(&(dst)[i+2].u.data); \
  131. } \
  132. /* free allocated string */ \
  133. pkg_free((dst)[i+2].u.data); \
  134. (dst)[i+2].u.data = 0; \
  135. } \
  136. }
  137. /* fills dst from src, converting RVE_ST params to STRING_ST.
  138. * (used internally in do_action())
  139. * @param src - source action_u_t array, as in the action structure
  140. * @param dst - destination action_u_t array, will be filled from src.
  141. * WARNING: dst must be cleaned when done, use MODULE_RVE_PARAM_FREE()
  142. * Side-effects: clobbers i (int), s (str), rv (rvalue*), might jump to error.
  143. */
  144. #define MODF_RVE_PARAM_CONVERT(h, msg, cmd, src, dst) \
  145. do { \
  146. (dst)[1]=(src)[1]; \
  147. for (i=0; i < (src)[1].u.number; i++) { \
  148. if ((src)[2+i].type == RVE_ST) { \
  149. rv=rval_expr_eval((h), (msg), (src)[i+2].u.data); \
  150. if (unlikely(rv == 0 || \
  151. rval_get_str((h), (msg), &s, rv, 0) < 0)) { \
  152. rval_destroy(rv); \
  153. ERR("failed to convert RVE to string\n"); \
  154. (dst)[1].u.number = i; \
  155. MODF_RVE_PARAM_FREE(cmd, src, dst); \
  156. goto error; \
  157. } \
  158. (dst)[i+2].type = STRING_RVE_ST; \
  159. (dst)[i+2].u.string = s.s; \
  160. (dst)[i+2].u.str.len = s.len; \
  161. rval_destroy(rv); \
  162. if ((cmd)->fixup) {\
  163. if ((cmd)->free_fixup) {\
  164. if (likely( call_fixup((cmd)->fixup, \
  165. &(dst)[i+2].u.data, i+1) >= 0) ) { \
  166. /* success => mark it for calling free fixup */ \
  167. if (likely((dst)[i+2].u.data != s.s)) \
  168. (dst)[i+2].type = RVE_FREE_FIXUP_ST; \
  169. } else { \
  170. /* error calling fixup => mark conv. parameter \
  171. and return error */ \
  172. (dst)[1].u.number = i; \
  173. ERR("runtime fixup failed for %s param %d\n", \
  174. (cmd)->name, i+1); \
  175. MODF_RVE_PARAM_FREE(cmd, src, dst); \
  176. goto error; \
  177. } \
  178. } else if ((cmd)->fixup_flags & FIXUP_F_FPARAM_RVE) { \
  179. if (likely( call_fixup((cmd)->fixup, \
  180. &(dst)[i+2].u.data, i+1) >= 0)) { \
  181. if ((dst)[i+2].u.data != s.s) \
  182. (dst)[i+2].type = FPARAM_DYN_ST; \
  183. } else { \
  184. /* error calling fixup => mark conv. parameter \
  185. and return error */ \
  186. (dst)[1].u.number = i; \
  187. ERR("runtime fixup failed for %s param %d\n", \
  188. (cmd)->name, i+1); \
  189. MODF_RVE_PARAM_FREE(cmd, src, dst); \
  190. goto error; \
  191. }\
  192. } \
  193. } \
  194. } else \
  195. (dst)[i+2]=(src)[i+2]; \
  196. } \
  197. } while(0)
  198. /* call a module function with normal STRING_ST params.
  199. * (used internally in do_action())
  200. * @param f_type - cmd_function type
  201. * @param h
  202. * @param msg
  203. * @param src - source action_u_t array (e.g. action->val)
  204. * @param params... - variable list of parameters, passed to the module
  205. * function
  206. * Side-effects: sets ret, clobbers i (int), s (str), rv (rvalue*), cmd,
  207. * might jump to error.
  208. *
  209. */
  210. #ifdef __SUNPRO_C
  211. #define MODF_CALL(f_type, h, msg, src, ...) \
  212. do { \
  213. cmd=(src)[0].u.data; \
  214. ret=((f_type)cmd->function)((msg), __VAR_ARGS__); \
  215. MODF_HANDLE_RETCODE(h, ret); \
  216. } while (0)
  217. #else /* ! __SUNPRO_C (gcc, icc a.s.o) */
  218. #define MODF_CALL(f_type, h, msg, src, params...) \
  219. do { \
  220. cmd=(src)[0].u.data; \
  221. ret=((f_type)cmd->function)((msg), ## params ); \
  222. MODF_HANDLE_RETCODE(h, ret); \
  223. } while (0)
  224. #endif /* __SUNPRO_C */
  225. /* call a module function with possible RVE params.
  226. * (used internally in do_action())
  227. * @param f_type - cmd_function type
  228. * @param h
  229. * @param msg
  230. * @param src - source action_u_t array (e.g. action->val)
  231. * @param dst - temporary action_u_t array used for conversions. It can be
  232. * used for the function parameters. It's contents it's not
  233. * valid after the call.
  234. * @param params... - variable list of parameters, passed to the module
  235. * function
  236. * Side-effects: sets ret, clobbers i (int), s (str), rv (rvalue*), f, dst,
  237. * might jump to error.
  238. *
  239. */
  240. #ifdef __SUNPRO_C
  241. #define MODF_RVE_CALL(f_type, h, msg, src, dst, ...) \
  242. do { \
  243. cmd=(src)[0].u.data; \
  244. MODF_RVE_PARAM_CONVERT(h, msg, cmd, src, dst); \
  245. ret=((f_type)cmd->function)((msg), __VAR_ARGS__); \
  246. MODF_HANDLE_RETCODE(h, ret); \
  247. /* free strings allocated by us or fixups */ \
  248. MODF_RVE_PARAM_FREE(cmd, src, dst); \
  249. } while (0)
  250. #else /* ! __SUNPRO_C (gcc, icc a.s.o) */
  251. #define MODF_RVE_CALL(f_type, h, msg, src, dst, params...) \
  252. do { \
  253. cmd=(src)[0].u.data; \
  254. MODF_RVE_PARAM_CONVERT(h, msg, cmd, src, dst); \
  255. ret=((f_type)cmd->function)((msg), ## params ); \
  256. MODF_HANDLE_RETCODE(h, ret); \
  257. /* free strings allocated by us or fixups */ \
  258. MODF_RVE_PARAM_FREE(cmd, src, dst); \
  259. } while (0)
  260. #endif /* __SUNPRO_C */
  261. /* ret= 0! if action -> end of list(e.g DROP),
  262. > 0 to continue processing next actions
  263. and <0 on error */
  264. int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
  265. {
  266. int ret;
  267. int v;
  268. struct dest_info dst;
  269. char* tmp;
  270. char *new_uri, *end, *crt;
  271. sr31_cmd_export_t* cmd;
  272. int len;
  273. int user;
  274. struct sip_uri uri, next_hop;
  275. struct sip_uri *u;
  276. unsigned short port;
  277. str* dst_host;
  278. int i, flags;
  279. avp_t* avp;
  280. struct search_state st;
  281. struct switch_cond_table* sct;
  282. struct switch_jmp_table* sjt;
  283. struct rval_expr* rve;
  284. struct match_cond_table* mct;
  285. struct rvalue* rv;
  286. struct rvalue* rv1;
  287. struct rval_cache c1;
  288. str s;
  289. void *srevp[2];
  290. /* temporary storage space for a struct action.val[] working copy
  291. (needed to transform RVE intro STRING before calling module
  292. functions). [0] is not used (corresp. to the module export pointer),
  293. [1] contains the number of params, and [2..] the param values.
  294. We need [1], because some fixup function use it
  295. (see fixup_get_param_count()). */
  296. static action_u_t mod_f_params[MAX_ACTIONS];
  297. /* reset the value of error to E_UNSPEC so avoid unknowledgable
  298. functions to return with error (status<0) and not setting it
  299. leaving there previous error; cache the previous value though
  300. for functions which want to process it */
  301. prev_ser_error=ser_error;
  302. ser_error=E_UNSPEC;
  303. /* hook for every executed action (in use by cfg debugger) */
  304. if(unlikely(sr_event_enabled(SREV_CFG_RUN_ACTION)))
  305. {
  306. srevp[0] = (void*)a;
  307. srevp[1] = (void*)msg;
  308. sr_event_exec(SREV_CFG_RUN_ACTION, (void*)srevp);
  309. }
  310. ret=E_BUG;
  311. switch ((unsigned char)a->type){
  312. case DROP_T:
  313. switch(a->val[0].type){
  314. case NUMBER_ST:
  315. ret=(int) a->val[0].u.number;
  316. break;
  317. case RVE_ST:
  318. rve=(struct rval_expr*)a->val[0].u.data;
  319. rval_expr_eval_int(h, msg, &ret, rve);
  320. break;
  321. case RETCODE_ST:
  322. ret=h->last_retcode;
  323. break;
  324. default:
  325. BUG("unexpected subtype %d in DROP_T\n",
  326. a->val[0].type);
  327. ret=0;
  328. goto error;
  329. }
  330. h->run_flags|=(unsigned int)a->val[1].u.number;
  331. break;
  332. case FORWARD_T:
  333. #ifdef USE_TCP
  334. case FORWARD_TCP_T:
  335. #endif
  336. #ifdef USE_TLS
  337. case FORWARD_TLS_T:
  338. #endif
  339. #ifdef USE_SCTP
  340. case FORWARD_SCTP_T:
  341. #endif
  342. case FORWARD_UDP_T:
  343. /* init dst */
  344. init_dest_info(&dst);
  345. if (a->type==FORWARD_UDP_T) dst.proto=PROTO_UDP;
  346. #ifdef USE_TCP
  347. else if (a->type==FORWARD_TCP_T) dst.proto= PROTO_TCP;
  348. #endif
  349. #ifdef USE_TLS
  350. else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
  351. #endif
  352. #ifdef USE_SCTP
  353. else if (a->type==FORWARD_SCTP_T) dst.proto=PROTO_SCTP;
  354. #endif
  355. else dst.proto=PROTO_NONE;
  356. if (a->val[0].type==URIHOST_ST){
  357. /*parse uri*/
  358. if (msg->dst_uri.len) {
  359. ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
  360. &next_hop);
  361. u = &next_hop;
  362. } else {
  363. ret = parse_sip_msg_uri(msg);
  364. u = &msg->parsed_uri;
  365. }
  366. if (ret<0) {
  367. LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
  368. " dropping packet\n");
  369. goto error;
  370. }
  371. switch (a->val[1].type){
  372. case URIPORT_ST:
  373. port=u->port_no;
  374. break;
  375. case NUMBER_ST:
  376. port=a->val[1].u.number;
  377. break;
  378. default:
  379. LOG(L_CRIT, "BUG: do_action bad forward 2nd"
  380. " param type (%d)\n", a->val[1].type);
  381. ret=E_UNSPEC;
  382. goto error_fwd_uri;
  383. }
  384. if (dst.proto == PROTO_NONE){ /* only if proto not set get it
  385. from the uri */
  386. switch(u->proto){
  387. case PROTO_NONE:
  388. /*dst.proto=PROTO_UDP; */
  389. /* no proto, try to get it from the dns */
  390. break;
  391. case PROTO_UDP:
  392. #ifdef USE_TCP
  393. case PROTO_TCP:
  394. #endif
  395. #ifdef USE_TLS
  396. case PROTO_TLS:
  397. #endif
  398. #ifdef USE_SCTP
  399. case PROTO_SCTP:
  400. #endif
  401. dst.proto=u->proto;
  402. break;
  403. default:
  404. LOG(L_ERR,"ERROR: do action: forward: bad uri"
  405. " transport %d\n", u->proto);
  406. ret=E_BAD_PROTO;
  407. goto error_fwd_uri;
  408. }
  409. #ifdef USE_TLS
  410. if (u->type==SIPS_URI_T){
  411. if (u->proto==PROTO_UDP){
  412. LOG(L_ERR, "ERROR: do_action: forward: secure uri"
  413. " incompatible with transport %d\n",
  414. u->proto);
  415. ret=E_BAD_PROTO;
  416. goto error_fwd_uri;
  417. }
  418. dst.proto=PROTO_TLS;
  419. }
  420. #endif
  421. }
  422. #ifdef HONOR_MADDR
  423. if (u->maddr_val.s && u->maddr_val.len)
  424. dst_host=&u->maddr_val;
  425. else
  426. #endif
  427. dst_host=&u->host;
  428. #ifdef USE_COMP
  429. dst.comp=u->comp;
  430. #endif
  431. ret=forward_request(msg, dst_host, port, &dst);
  432. if (ret>=0){
  433. ret=1;
  434. }
  435. }else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
  436. if (dst.proto==PROTO_NONE)
  437. dst.proto=msg->rcv.proto;
  438. proxy2su(&dst.to, (struct proxy_l*)a->val[0].u.data);
  439. ret=forward_request(msg, 0, 0, &dst);
  440. if (ret>=0){
  441. ret=1;
  442. proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
  443. }else if (ser_error!=E_OK){
  444. proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
  445. }
  446. }else{
  447. LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
  448. a->val[0].type, a->val[1].type);
  449. ret=E_BUG;
  450. goto error;
  451. }
  452. break;
  453. case SEND_T:
  454. case SEND_TCP_T:
  455. if (a->val[0].type==URIHOST_ST){
  456. /*get next hop uri uri*/
  457. if (msg->dst_uri.len) {
  458. ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
  459. &next_hop);
  460. u = &next_hop;
  461. } else {
  462. ret = parse_sip_msg_uri(msg);
  463. u = &msg->parsed_uri;
  464. }
  465. if (ret<0) {
  466. LM_ERR("send() - bad_uri dropping packet\n");
  467. ret=E_BUG;
  468. goto error;
  469. }
  470. /* init dst */
  471. init_dest_info(&dst);
  472. ret = sip_hostport2su(&dst.to, &u->host, u->port_no,
  473. &dst.proto);
  474. if(ret!=0) {
  475. LM_ERR("failed to resolve [%.*s]\n", u->host.len,
  476. ZSW(u->host.s));
  477. ret=E_BUG;
  478. goto error;
  479. }
  480. } else {
  481. if ((a->val[0].type!= PROXY_ST)|(a->val[1].type!=NUMBER_ST)){
  482. LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
  483. a->val[0].type, a->val[1].type);
  484. ret=E_BUG;
  485. goto error;
  486. }
  487. /* init dst */
  488. init_dest_info(&dst);
  489. ret=proxy2su(&dst.to, (struct proxy_l*)a->val[0].u.data);
  490. if(ret==0)
  491. proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
  492. }
  493. if (ret==0){
  494. if (p_onsend){
  495. tmp=p_onsend->buf;
  496. len=p_onsend->len;
  497. }else{
  498. tmp=msg->buf;
  499. len=msg->len;
  500. }
  501. if (a->type==SEND_T){
  502. /*udp*/
  503. dst.proto=PROTO_UDP; /* not really needed for udp_send */
  504. dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
  505. if (dst.send_sock!=0){
  506. ret=udp_send(&dst, tmp, len);
  507. }else{
  508. ret=-1;
  509. }
  510. }
  511. #ifdef USE_TCP
  512. else{
  513. /*tcp*/
  514. dst.proto=PROTO_TCP;
  515. dst.id=0;
  516. ret=tcp_send(&dst, 0, tmp, len);
  517. }
  518. #endif
  519. }else{
  520. ret=E_BUG;
  521. goto error;
  522. }
  523. if (ret>=0) ret=1;
  524. break;
  525. case LOG_T:
  526. if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
  527. LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
  528. a->val[0].type, a->val[1].type);
  529. ret=E_BUG;
  530. goto error;
  531. }
  532. LOG_(DEFAULT_FACILITY, a->val[0].u.number, "<script>: ", "%s",
  533. a->val[1].u.string);
  534. ret=1;
  535. break;
  536. /* jku -- introduce a new branch */
  537. case APPEND_BRANCH_T:
  538. if (unlikely(a->val[0].type!=STR_ST)) {
  539. LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
  540. a->val[0].type );
  541. ret=E_BUG;
  542. goto error;
  543. }
  544. getbflagsval(0, (flag_t*)&flags);
  545. ret=append_branch(msg, &a->val[0].u.str, &msg->dst_uri,
  546. &msg->path_vec, a->val[1].u.number,
  547. (flag_t)flags, msg->force_send_socket);
  548. /* if the uri is the ruri and q was also not changed, mark
  549. ruri as consumed, to avoid having an identical branch */
  550. if ((a->val[0].u.str.s == 0 || a->val[0].u.str.len == 0) &&
  551. a->val[1].u.number == Q_UNSPECIFIED)
  552. ruri_mark_consumed();
  553. break;
  554. /* remove last branch */
  555. case REMOVE_BRANCH_T:
  556. if (a->val[0].type!=NUMBER_ST) {
  557. ret=drop_sip_branch(0) ? -1 : 1;
  558. } else {
  559. ret=drop_sip_branch(a->val[0].u.number) ? -1 : 1;
  560. }
  561. break;
  562. /* remove all branches */
  563. case CLEAR_BRANCHES_T:
  564. clear_branches();
  565. ret=1;
  566. break;
  567. /* jku begin: is_length_greater_than */
  568. case LEN_GT_T:
  569. if (a->val[0].type!=NUMBER_ST) {
  570. LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
  571. a->val[0].type );
  572. ret=E_BUG;
  573. goto error;
  574. }
  575. /* DBG("XXX: message length %d, max %d\n",
  576. msg->len, a->val[0].u.number ); */
  577. ret = msg->len >= a->val[0].u.number ? 1 : -1;
  578. break;
  579. /* jku end: is_length_greater_than */
  580. /* jku - begin : flag processing */
  581. case SETFLAG_T:
  582. if (a->val[0].type!=NUMBER_ST) {
  583. LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
  584. a->val[0].type );
  585. ret=E_BUG;
  586. goto error;
  587. }
  588. if (!flag_in_range( a->val[0].u.number )) {
  589. ret=E_CFG;
  590. goto error;
  591. }
  592. setflag( msg, a->val[0].u.number );
  593. ret=1;
  594. break;
  595. case RESETFLAG_T:
  596. if (a->val[0].type!=NUMBER_ST) {
  597. LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
  598. a->val[0].type );
  599. ret=E_BUG;
  600. goto error;
  601. }
  602. if (!flag_in_range( a->val[0].u.number )) {
  603. ret=E_CFG;
  604. goto error;
  605. }
  606. resetflag( msg, a->val[0].u.number );
  607. ret=1;
  608. break;
  609. case ISFLAGSET_T:
  610. if (a->val[0].type!=NUMBER_ST) {
  611. LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
  612. a->val[0].type );
  613. ret=E_BUG;
  614. goto error;
  615. }
  616. if (!flag_in_range( a->val[0].u.number )) {
  617. ret=E_CFG;
  618. goto error;
  619. }
  620. ret=isflagset( msg, a->val[0].u.number );
  621. break;
  622. /* jku - end : flag processing */
  623. case AVPFLAG_OPER_T:
  624. ret = 0;
  625. if ((a->val[0].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL ||
  626. (a->val[0].u.attr->type & AVP_NAME_RE)!=0) {
  627. for (avp=search_first_avp(a->val[0].u.attr->type,
  628. a->val[0].u.attr->name, NULL, &st);
  629. avp;
  630. avp = search_next_avp(&st, NULL)) {
  631. switch (a->val[2].u.number) {
  632. /* oper: 0..reset, 1..set, -1..no change */
  633. case 0:
  634. avp->flags &= ~(avp_flags_t)a->val[1].u.number;
  635. break;
  636. case 1:
  637. avp->flags |= (avp_flags_t)a->val[1].u.number;
  638. break;
  639. default:;
  640. }
  641. ret = ret ||
  642. ((avp->flags & (avp_flags_t)a->val[1].u.number) != 0);
  643. }
  644. } else {
  645. avp = search_avp_by_index(a->val[0].u.attr->type,
  646. a->val[0].u.attr->name, NULL,
  647. a->val[0].u.attr->index);
  648. if (avp) {
  649. switch (a->val[2].u.number) {
  650. /* oper: 0..reset, 1..set, -1..no change */
  651. case 0:
  652. avp->flags &= ~(avp_flags_t)a->val[1].u.number;
  653. break;
  654. case 1:
  655. avp->flags |= (avp_flags_t)a->val[1].u.number;
  656. break;
  657. default:;
  658. }
  659. ret = (avp->flags & (avp_flags_t)a->val[1].u.number) != 0;
  660. }
  661. }
  662. if (ret==0)
  663. ret = -1;
  664. break;
  665. case ERROR_T:
  666. if ((a->val[0].type!=STRING_ST)|(a->val[1].type!=STRING_ST)){
  667. LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
  668. a->val[0].type, a->val[1].type);
  669. ret=E_BUG;
  670. goto error;
  671. }
  672. LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
  673. "not implemented yet\n", a->val[0].u.string, a->val[1].u.string);
  674. ret=1;
  675. break;
  676. case ROUTE_T:
  677. if (likely(a->val[0].type == NUMBER_ST))
  678. i = a->val[0].u.number;
  679. else if (a->val[0].type == RVE_ST) {
  680. rv = rval_expr_eval(h, msg, a->val[0].u.data);
  681. rval_cache_init(&c1);
  682. if (unlikely(rv == 0 ||
  683. rval_get_tmp_str(h, msg, &s, rv, 0, &c1) < 0)) {
  684. rval_destroy(rv);
  685. rval_cache_clean(&c1);
  686. ERR("failed to convert RVE to string\n");
  687. ret = E_UNSPEC;
  688. goto error;
  689. }
  690. i = route_lookup(&main_rt, s.s);
  691. if (unlikely(i < 0)) {
  692. ERR("route \"%s\" not found at %s:%d\n",
  693. s.s, (a->cfile)?a->cfile:"line", a->cline);
  694. rval_destroy(rv);
  695. rval_cache_clean(&c1);
  696. s.s = 0;
  697. ret = E_SCRIPT;
  698. goto error;
  699. }
  700. rval_destroy(rv);
  701. rval_cache_clean(&c1);
  702. s.s = 0;
  703. } else {
  704. LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
  705. a->val[0].type);
  706. ret=E_BUG;
  707. goto error;
  708. }
  709. if (unlikely((i>=main_rt.idx)||(i<0))){
  710. LOG(L_ERR, "ERROR: invalid routing table number in"
  711. "route(%lu) at %s:%d\n", a->val[0].u.number,
  712. (a->cfile)?a->cfile:"line", a->cline);
  713. ret=E_CFG;
  714. goto error;
  715. }
  716. /*ret=((ret=run_actions(rlist[a->val[0].u.number],msg))<0)?ret:1;*/
  717. ret=run_actions(h, main_rt.rlist[i], msg);
  718. h->last_retcode=ret;
  719. _last_returned_code = h->last_retcode;
  720. h->run_flags&=~(RETURN_R_F|BREAK_R_F); /* absorb return & break */
  721. break;
  722. case EXEC_T:
  723. if (a->val[0].type!=STRING_ST){
  724. LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
  725. a->val[0].type);
  726. ret=E_BUG;
  727. goto error;
  728. }
  729. LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,"
  730. " using dumb version...\n", a->val[0].u.string);
  731. ret=system(a->val[0].u.string);
  732. if (ret!=0){
  733. LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
  734. }
  735. ret=1;
  736. break;
  737. case REVERT_URI_T:
  738. if (msg->new_uri.s) {
  739. pkg_free(msg->new_uri.s);
  740. msg->new_uri.len=0;
  741. msg->new_uri.s=0;
  742. msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
  743. ruri_mark_new(); /* available for forking */
  744. };
  745. ret=1;
  746. break;
  747. case SET_HOST_T:
  748. case SET_HOSTPORT_T:
  749. case SET_HOSTPORTTRANS_T:
  750. case SET_HOSTALL_T:
  751. case SET_USER_T:
  752. case SET_USERPASS_T:
  753. case SET_PORT_T:
  754. case SET_URI_T:
  755. case PREFIX_T:
  756. case STRIP_T:
  757. case STRIP_TAIL_T:
  758. case SET_USERPHONE_T:
  759. user=0;
  760. if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
  761. if (a->val[0].type!=NUMBER_ST) {
  762. LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
  763. a->val[0].type);
  764. ret=E_BUG;
  765. goto error;
  766. }
  767. } else if (a->type!=SET_USERPHONE_T) {
  768. if (a->val[0].type!=STRING_ST) {
  769. LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
  770. a->val[0].type);
  771. ret=E_BUG;
  772. goto error;
  773. }
  774. }
  775. if (a->type==SET_URI_T){
  776. if (msg->new_uri.s) {
  777. pkg_free(msg->new_uri.s);
  778. msg->new_uri.len=0;
  779. }
  780. msg->parsed_uri_ok=0;
  781. len=strlen(a->val[0].u.string);
  782. msg->new_uri.s=pkg_malloc(len+1);
  783. if (msg->new_uri.s==0){
  784. LOG(L_ERR, "ERROR: do_action: memory allocation"
  785. " failure\n");
  786. ret=E_OUT_OF_MEM;
  787. goto error;
  788. }
  789. memcpy(msg->new_uri.s, a->val[0].u.string, len);
  790. msg->new_uri.s[len]=0;
  791. msg->new_uri.len=len;
  792. ruri_mark_new(); /* available for forking */
  793. ret=1;
  794. break;
  795. }
  796. if (msg->parsed_uri_ok==0) {
  797. if (msg->new_uri.s) {
  798. tmp=msg->new_uri.s;
  799. len=msg->new_uri.len;
  800. }else{
  801. tmp=msg->first_line.u.request.uri.s;
  802. len=msg->first_line.u.request.uri.len;
  803. }
  804. if (parse_uri(tmp, len, &uri)<0){
  805. LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
  806. " packet\n", tmp);
  807. ret=E_UNSPEC;
  808. goto error;
  809. }
  810. } else {
  811. uri=msg->parsed_uri;
  812. }
  813. /* skip SET_USERPHONE_T action if the URI is already
  814. * a tel: or tels: URI, or contains the user=phone param */
  815. if ((a->type==SET_USERPHONE_T)
  816. && ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T)
  817. || ((uri.user_param_val.len==5) && (memcmp(uri.user_param_val.s, "phone", 5)==0)))
  818. ) {
  819. ret=1;
  820. break;
  821. }
  822. /* SET_PORT_T does not work with tel: URIs */
  823. if ((a->type==SET_PORT_T)
  824. && ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
  825. && ((uri.flags & URI_SIP_USER_PHONE)==0)
  826. ) {
  827. LOG(L_ERR, "ERROR: do_action: port number of a tel: URI cannot be set\n");
  828. ret=E_UNSPEC;
  829. goto error;
  830. }
  831. new_uri=pkg_malloc(MAX_URI_SIZE);
  832. if (new_uri==0){
  833. LOG(L_ERR, "ERROR: do_action: memory allocation "
  834. " failure\n");
  835. ret=E_OUT_OF_MEM;
  836. goto error;
  837. }
  838. end=new_uri+MAX_URI_SIZE;
  839. crt=new_uri;
  840. /* begin copying */
  841. /* Preserve the URI scheme unless the host part needs
  842. * to be rewritten, and the shceme is tel: or tels: */
  843. switch (uri.type) {
  844. case SIP_URI_T:
  845. len=s_sip.len;
  846. tmp=s_sip.s;
  847. break;
  848. case SIPS_URI_T:
  849. len=s_sips.len;
  850. tmp=s_sips.s;
  851. break;
  852. case TEL_URI_T:
  853. if ((uri.flags & URI_SIP_USER_PHONE)
  854. || (a->type==SET_HOST_T)
  855. || (a->type==SET_HOSTPORT_T)
  856. || (a->type==SET_HOSTPORTTRANS_T)
  857. ) {
  858. len=s_sip.len;
  859. tmp=s_sip.s;
  860. break;
  861. }
  862. len=s_tel.len;
  863. tmp=s_tel.s;
  864. break;
  865. case TELS_URI_T:
  866. if ((uri.flags & URI_SIP_USER_PHONE)
  867. || (a->type==SET_HOST_T)
  868. || (a->type==SET_HOSTPORT_T)
  869. || (a->type==SET_HOSTPORTTRANS_T)
  870. ) {
  871. len=s_sips.len;
  872. tmp=s_sips.s;
  873. break;
  874. }
  875. len=s_tels.len;
  876. tmp=s_tels.s;
  877. break;
  878. default:
  879. LOG(L_ERR, "ERROR: Unsupported URI scheme (%d), "
  880. "reverted to sip:\n",
  881. uri.type);
  882. len=s_sip.len;
  883. tmp=s_sip.s;
  884. }
  885. if(crt+len+1 /* colon */ >end) goto error_uri;
  886. memcpy(crt,tmp,len);crt+=len;
  887. *crt=':'; crt++;
  888. /* user */
  889. /* prefix (-jiri) */
  890. if (a->type==PREFIX_T) {
  891. tmp=a->val[0].u.string;
  892. len=strlen(tmp); if(crt+len>end) goto error_uri;
  893. memcpy(crt,tmp,len);crt+=len;
  894. /* whatever we had before, with prefix we have username
  895. now */
  896. user=1;
  897. }
  898. if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
  899. tmp=a->val[0].u.string;
  900. len=strlen(tmp);
  901. } else if (a->type==STRIP_T) {
  902. if (a->val[0].u.number>uri.user.len) {
  903. LOG(L_WARN, "Error: too long strip asked; "
  904. " deleting username: %lu of <%.*s>\n",
  905. a->val[0].u.number, uri.user.len, uri.user.s );
  906. len=0;
  907. } else if (a->val[0].u.number==uri.user.len) {
  908. len=0;
  909. } else {
  910. tmp=uri.user.s + a->val[0].u.number;
  911. len=uri.user.len - a->val[0].u.number;
  912. }
  913. } else if (a->type==STRIP_TAIL_T) {
  914. if (a->val[0].u.number>uri.user.len) {
  915. LOG(L_WARN, "WARNING: too long strip_tail asked; "
  916. " deleting username: %lu of <%.*s>\n",
  917. a->val[0].u.number, uri.user.len, uri.user.s );
  918. len=0;
  919. } else if (a->val[0].u.number==uri.user.len) {
  920. len=0;
  921. } else {
  922. tmp=uri.user.s;
  923. len=uri.user.len - a->val[0].u.number;
  924. }
  925. } else {
  926. tmp=uri.user.s;
  927. len=uri.user.len;
  928. }
  929. if (len){
  930. if(crt+len>end) goto error_uri;
  931. memcpy(crt,tmp,len);crt+=len;
  932. user=1; /* we have an user field so mark it */
  933. }
  934. if (a->type==SET_USERPASS_T) tmp=0;
  935. else tmp=uri.passwd.s;
  936. /* passwd */
  937. if (tmp){
  938. len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
  939. *crt=':'; crt++;
  940. memcpy(crt,tmp,len);crt+=len;
  941. }
  942. /* tel: URI parameters */
  943. if ((uri.type==TEL_URI_T)
  944. || (uri.type==TELS_URI_T)
  945. ) {
  946. tmp=uri.params.s;
  947. if (tmp){
  948. len=uri.params.len; if(crt+len+1>end) goto error_uri;
  949. *crt=';'; crt++;
  950. memcpy(crt,tmp,len);crt+=len;
  951. }
  952. }
  953. /* host */
  954. if ((a->type==SET_HOST_T)
  955. || (a->type==SET_HOSTPORT_T)
  956. || (a->type==SET_HOSTALL_T)
  957. || (a->type==SET_HOSTPORTTRANS_T)
  958. ) {
  959. tmp=a->val[0].u.string;
  960. if (tmp) len = strlen(tmp);
  961. else len=0;
  962. } else if ((uri.type==SIP_URI_T)
  963. || (uri.type==SIPS_URI_T)
  964. || (uri.flags & URI_SIP_USER_PHONE)
  965. ) {
  966. tmp=uri.host.s;
  967. len=uri.host.len;
  968. } else {
  969. tmp=0;
  970. }
  971. if (tmp){
  972. if (user) { /* add @ */
  973. if(crt+1>end) goto error_uri;
  974. *crt='@'; crt++;
  975. }
  976. if(crt+len>end) goto error_uri;
  977. memcpy(crt,tmp,len);crt+=len;
  978. }
  979. if(a->type==SET_HOSTALL_T)
  980. goto done_seturi;
  981. /* port */
  982. if ((a->type==SET_HOSTPORT_T)
  983. || (a->type==SET_HOSTPORTTRANS_T))
  984. tmp=0;
  985. else if (a->type==SET_PORT_T) {
  986. tmp=a->val[0].u.string;
  987. if (tmp) {
  988. len = strlen(tmp);
  989. if(len==0) tmp = 0;
  990. } else len = 0;
  991. } else {
  992. tmp=uri.port.s;
  993. len = uri.port.len;
  994. }
  995. if (tmp){
  996. if(crt+len+1>end) goto error_uri;
  997. *crt=':'; crt++;
  998. memcpy(crt,tmp,len);crt+=len;
  999. }
  1000. /* params */
  1001. if ((a->type==SET_HOSTPORTTRANS_T)
  1002. && uri.sip_params.s
  1003. && uri.transport.s
  1004. ) {
  1005. /* bypass the transport parameter */
  1006. if (uri.sip_params.s < uri.transport.s) {
  1007. /* there are parameters before transport */
  1008. len = uri.transport.s - uri.sip_params.s - 1;
  1009. /* ignore the ';' at the end */
  1010. if (crt+len+1>end) goto error_uri;
  1011. *crt=';'; crt++;
  1012. memcpy(crt,uri.sip_params.s,len);crt+=len;
  1013. }
  1014. len = (uri.sip_params.s + uri.sip_params.len) -
  1015. (uri.transport.s + uri.transport.len);
  1016. if (len > 0) {
  1017. /* there are parameters after transport */
  1018. if (crt+len>end) goto error_uri;
  1019. tmp = uri.transport.s + uri.transport.len;
  1020. memcpy(crt,tmp,len);crt+=len;
  1021. }
  1022. } else {
  1023. tmp=uri.sip_params.s;
  1024. if (tmp){
  1025. len=uri.sip_params.len; if(crt+len+1>end) goto error_uri;
  1026. *crt=';'; crt++;
  1027. memcpy(crt,tmp,len);crt+=len;
  1028. }
  1029. }
  1030. /* Add the user=phone param if a tel: or tels:
  1031. * URI was converted to sip: or sips:.
  1032. * (host part of a tel/tels URI was set.)
  1033. * Or in case of sip: URI and SET_USERPHONE_T action */
  1034. if (((((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
  1035. && ((uri.flags & URI_SIP_USER_PHONE)==0))
  1036. && ((a->type==SET_HOST_T)
  1037. || (a->type==SET_HOSTPORT_T)
  1038. || (a->type==SET_HOSTPORTTRANS_T)))
  1039. || (a->type==SET_USERPHONE_T)
  1040. ) {
  1041. tmp=";user=phone";
  1042. len=strlen(tmp);
  1043. if(crt+len>end) goto error_uri;
  1044. memcpy(crt,tmp,len);crt+=len;
  1045. }
  1046. /* headers */
  1047. tmp=uri.headers.s;
  1048. if (tmp){
  1049. len=uri.headers.len; if(crt+len+1>end) goto error_uri;
  1050. *crt='?'; crt++;
  1051. memcpy(crt,tmp,len);crt+=len;
  1052. }
  1053. done_seturi:
  1054. *crt=0; /* null terminate the thing */
  1055. /* copy it to the msg */
  1056. if (msg->new_uri.s) pkg_free(msg->new_uri.s);
  1057. msg->new_uri.s=new_uri;
  1058. msg->new_uri.len=crt-new_uri;
  1059. msg->parsed_uri_ok=0;
  1060. ruri_mark_new(); /* available for forking */
  1061. ret=1;
  1062. break;
  1063. case IF_T:
  1064. rve=(struct rval_expr*)a->val[0].u.data;
  1065. if (unlikely(rval_expr_eval_int(h, msg, &v, rve) != 0)){
  1066. ERR("if expression evaluation failed (%d,%d-%d,%d)\n",
  1067. rve->fpos.s_line, rve->fpos.s_col,
  1068. rve->fpos.e_line, rve->fpos.e_col);
  1069. v=0; /* false */
  1070. }
  1071. if (unlikely(h->run_flags & EXIT_R_F)){
  1072. ret=0;
  1073. break;
  1074. }
  1075. h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
  1076. break in expr*/
  1077. ret=1; /*default is continue */
  1078. if (v>0) {
  1079. if ((a->val[1].type==ACTIONS_ST)&&a->val[1].u.data){
  1080. ret=run_actions(h,
  1081. (struct action*)a->val[1].u.data, msg);
  1082. }
  1083. }else if ((a->val[2].type==ACTIONS_ST)&&a->val[2].u.data){
  1084. ret=run_actions(h,
  1085. (struct action*)a->val[2].u.data, msg);
  1086. }
  1087. break;
  1088. case MODULE0_T:
  1089. MODF_CALL(cmd_function, h, msg, a->val, 0, 0);
  1090. break;
  1091. /* instead of using the parameter number, we use different names
  1092. * for calls to functions with 3, 4, 5, 6 or variable number of
  1093. * parameters due to performance reasons */
  1094. case MODULE1_T:
  1095. MODF_CALL(cmd_function, h, msg, a->val,
  1096. (char*)a->val[2].u.data,
  1097. 0
  1098. );
  1099. break;
  1100. case MODULE2_T:
  1101. MODF_CALL(cmd_function, h, msg, a->val,
  1102. (char*)a->val[2].u.data,
  1103. (char*)a->val[3].u.data
  1104. );
  1105. break;
  1106. case MODULE3_T:
  1107. MODF_CALL(cmd_function3, h, msg, a->val,
  1108. (char*)a->val[2].u.data,
  1109. (char*)a->val[3].u.data,
  1110. (char*)a->val[4].u.data
  1111. );
  1112. break;
  1113. case MODULE4_T:
  1114. MODF_CALL(cmd_function4, h, msg, a->val,
  1115. (char*)a->val[2].u.data,
  1116. (char*)a->val[3].u.data,
  1117. (char*)a->val[4].u.data,
  1118. (char*)a->val[5].u.data
  1119. );
  1120. break;
  1121. case MODULE5_T:
  1122. MODF_CALL(cmd_function5, h, msg, a->val,
  1123. (char*)a->val[2].u.data,
  1124. (char*)a->val[3].u.data,
  1125. (char*)a->val[4].u.data,
  1126. (char*)a->val[5].u.data,
  1127. (char*)a->val[6].u.data
  1128. );
  1129. break;
  1130. case MODULE6_T:
  1131. MODF_CALL(cmd_function6, h, msg, a->val,
  1132. (char*)a->val[2].u.data,
  1133. (char*)a->val[3].u.data,
  1134. (char*)a->val[4].u.data,
  1135. (char*)a->val[5].u.data,
  1136. (char*)a->val[6].u.data,
  1137. (char*)a->val[7].u.data
  1138. );
  1139. break;
  1140. case MODULEX_T:
  1141. MODF_CALL(cmd_function_var, h, msg, a->val,
  1142. a->val[1].u.number, &a->val[2]);
  1143. break;
  1144. case MODULE1_RVE_T:
  1145. MODF_RVE_CALL(cmd_function, h, msg, a->val, mod_f_params,
  1146. (char*)mod_f_params[2].u.data,
  1147. 0
  1148. );
  1149. break;
  1150. case MODULE2_RVE_T:
  1151. MODF_RVE_CALL(cmd_function, h, msg, a->val, mod_f_params,
  1152. (char*)mod_f_params[2].u.data,
  1153. (char*)mod_f_params[3].u.data
  1154. );
  1155. break;
  1156. case MODULE3_RVE_T:
  1157. MODF_RVE_CALL(cmd_function3, h, msg, a->val, mod_f_params,
  1158. (char*)mod_f_params[2].u.data,
  1159. (char*)mod_f_params[3].u.data,
  1160. (char*)mod_f_params[4].u.data
  1161. );
  1162. break;
  1163. case MODULE4_RVE_T:
  1164. MODF_RVE_CALL(cmd_function4, h, msg, a->val, mod_f_params,
  1165. (char*)mod_f_params[2].u.data,
  1166. (char*)mod_f_params[3].u.data,
  1167. (char*)mod_f_params[4].u.data,
  1168. (char*)mod_f_params[5].u.data
  1169. );
  1170. break;
  1171. case MODULE5_RVE_T:
  1172. MODF_RVE_CALL(cmd_function5, h, msg, a->val, mod_f_params,
  1173. (char*)mod_f_params[2].u.data,
  1174. (char*)mod_f_params[3].u.data,
  1175. (char*)mod_f_params[4].u.data,
  1176. (char*)mod_f_params[5].u.data,
  1177. (char*)mod_f_params[6].u.data
  1178. );
  1179. break;
  1180. case MODULE6_RVE_T:
  1181. MODF_RVE_CALL(cmd_function6, h, msg, a->val, mod_f_params,
  1182. (char*)mod_f_params[2].u.data,
  1183. (char*)mod_f_params[3].u.data,
  1184. (char*)mod_f_params[4].u.data,
  1185. (char*)mod_f_params[5].u.data,
  1186. (char*)mod_f_params[6].u.data,
  1187. (char*)mod_f_params[7].u.data
  1188. );
  1189. break;
  1190. case MODULEX_RVE_T:
  1191. MODF_RVE_CALL(cmd_function_var, h, msg, a->val, mod_f_params,
  1192. a->val[1].u.number, &mod_f_params[2]);
  1193. break;
  1194. case EVAL_T:
  1195. /* only eval the expression to account for possible
  1196. side-effect */
  1197. rval_expr_eval_int(h, msg, &v,
  1198. (struct rval_expr*)a->val[0].u.data);
  1199. if (h->run_flags & EXIT_R_F){
  1200. ret=0;
  1201. break;
  1202. }
  1203. h->run_flags &= ~RETURN_R_F|BREAK_R_F; /* catch return & break in
  1204. expr */
  1205. ret=1; /* default is continue */
  1206. break;
  1207. case SWITCH_COND_T:
  1208. sct=(struct switch_cond_table*)a->val[1].u.data;
  1209. if (unlikely( rval_expr_eval_int(h, msg, &v,
  1210. (struct rval_expr*)a->val[0].u.data) <0)){
  1211. /* handle error in expression => use default */
  1212. ret=-1;
  1213. goto sw_cond_def;
  1214. }
  1215. if (h->run_flags & EXIT_R_F){
  1216. ret=0;
  1217. break;
  1218. }
  1219. h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
  1220. in expr */
  1221. ret=1; /* default is continue */
  1222. for(i=0; i<sct->n; i++)
  1223. if (sct->cond[i]==v){
  1224. if (likely(sct->jump[i])){
  1225. ret=run_actions(h, sct->jump[i], msg);
  1226. h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
  1227. returns passthrough */
  1228. }
  1229. goto skip;
  1230. }
  1231. sw_cond_def:
  1232. if (sct->def){
  1233. ret=run_actions(h, sct->def, msg);
  1234. h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
  1235. returns passthrough */
  1236. }
  1237. break;
  1238. case SWITCH_JT_T:
  1239. sjt=(struct switch_jmp_table*)a->val[1].u.data;
  1240. if (unlikely( rval_expr_eval_int(h, msg, &v,
  1241. (struct rval_expr*)a->val[0].u.data) <0)){
  1242. /* handle error in expression => use default */
  1243. ret=-1;
  1244. goto sw_jt_def;
  1245. }
  1246. if (h->run_flags & EXIT_R_F){
  1247. ret=0;
  1248. break;
  1249. }
  1250. h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
  1251. in expr */
  1252. ret=1; /* default is continue */
  1253. if (likely(v >= sjt->first && v <= sjt->last)){
  1254. if (likely(sjt->tbl[v - sjt->first])){
  1255. ret=run_actions(h, sjt->tbl[v - sjt->first], msg);
  1256. h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
  1257. returns passthrough */
  1258. }
  1259. break;
  1260. }else{
  1261. for(i=0; i<sjt->rest.n; i++)
  1262. if (sjt->rest.cond[i]==v){
  1263. if (likely(sjt->rest.jump[i])){
  1264. ret=run_actions(h, sjt->rest.jump[i], msg);
  1265. h->run_flags &= ~BREAK_R_F; /* catch breaks, but
  1266. let returns pass */
  1267. }
  1268. goto skip;
  1269. }
  1270. }
  1271. /* not found => try default */
  1272. sw_jt_def:
  1273. if (sjt->rest.def){
  1274. ret=run_actions(h, sjt->rest.def, msg);
  1275. h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
  1276. returns passthrough */
  1277. }
  1278. break;
  1279. case BLOCK_T:
  1280. if (likely(a->val[0].u.data)){
  1281. ret=run_actions(h, (struct action*)a->val[0].u.data, msg);
  1282. h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
  1283. returns passthrough */
  1284. }
  1285. break;
  1286. case MATCH_COND_T:
  1287. mct=(struct match_cond_table*)a->val[1].u.data;
  1288. rval_cache_init(&c1);
  1289. rv=0;
  1290. rv1=0;
  1291. ret=rval_expr_eval_rvint(h, msg, &rv, &v,
  1292. (struct rval_expr*)a->val[0].u.data, &c1);
  1293. if (unlikely( ret<0)){
  1294. /* handle error in expression => use default */
  1295. ret=-1;
  1296. goto match_cond_def;
  1297. }
  1298. if (h->run_flags & EXIT_R_F){
  1299. ret=0;
  1300. break;
  1301. }
  1302. h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
  1303. in expr */
  1304. if (likely(rv)){
  1305. rv1=rval_convert(h, msg, RV_STR, rv, &c1);
  1306. if (unlikely(rv1==0)){
  1307. ret=-1;
  1308. goto match_cond_def;
  1309. }
  1310. s=rv1->v.s;
  1311. }else{
  1312. /* int result in v */
  1313. rval_cache_clean(&c1);
  1314. s.s=sint2str(v, &s.len);
  1315. }
  1316. ret=1; /* default is continue */
  1317. for(i=0; i<mct->n; i++)
  1318. if (( mct->match[i].type==MATCH_STR &&
  1319. mct->match[i].l.s.len==s.len &&
  1320. memcmp(mct->match[i].l.s.s, s.s, s.len) == 0 ) ||
  1321. ( mct->match[i].type==MATCH_RE &&
  1322. regexec(mct->match[i].l.regex, s.s, 0, 0, 0) == 0)
  1323. ){
  1324. if (likely(mct->jump[i])){
  1325. /* make sure we cleanup first, in case run_actions()
  1326. exits the script directly via longjmp() */
  1327. if (rv1){
  1328. rval_destroy(rv1);
  1329. rval_destroy(rv);
  1330. rval_cache_clean(&c1);
  1331. }else if (rv){
  1332. rval_destroy(rv);
  1333. rval_cache_clean(&c1);
  1334. }
  1335. ret=run_actions(h, mct->jump[i], msg);
  1336. h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
  1337. returns passthrough */
  1338. goto skip;
  1339. }
  1340. goto match_cleanup;
  1341. }
  1342. match_cond_def:
  1343. if (mct->def){
  1344. /* make sure we cleanup first, in case run_actions()
  1345. exits the script directly via longjmp() */
  1346. if (rv1){
  1347. rval_destroy(rv1);
  1348. rval_destroy(rv);
  1349. rval_cache_clean(&c1);
  1350. }else if (rv){
  1351. rval_destroy(rv);
  1352. rval_cache_clean(&c1);
  1353. }
  1354. ret=run_actions(h, mct->def, msg);
  1355. h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
  1356. returns passthrough */
  1357. break;
  1358. }
  1359. match_cleanup:
  1360. if (rv1){
  1361. rval_destroy(rv1);
  1362. rval_destroy(rv);
  1363. rval_cache_clean(&c1);
  1364. }else if (rv){
  1365. rval_destroy(rv);
  1366. rval_cache_clean(&c1);
  1367. }
  1368. break;
  1369. case WHILE_T:
  1370. i=0;
  1371. flags=0;
  1372. rve=(struct rval_expr*)a->val[0].u.data;
  1373. ret=1;
  1374. while(!(flags & (BREAK_R_F|RETURN_R_F|EXIT_R_F)) &&
  1375. (rval_expr_eval_int(h, msg, &v, rve) == 0) && v){
  1376. if (cfg_get(core, core_cfg, max_while_loops) > 0)
  1377. i++;
  1378. if (unlikely(i > cfg_get(core, core_cfg, max_while_loops))){
  1379. LOG(L_ERR, "ERROR: runaway while (%d, %d): more then"
  1380. " %d loops\n",
  1381. rve->fpos.s_line, rve->fpos.s_col,
  1382. cfg_get(core, core_cfg, max_while_loops));
  1383. ret=-1;
  1384. goto error;
  1385. }
  1386. if (likely(a->val[1].u.data)){
  1387. ret=run_actions(h, (struct action*)a->val[1].u.data, msg);
  1388. flags|=h->run_flags;
  1389. h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
  1390. returns pass-through */
  1391. }
  1392. }
  1393. break;
  1394. case FORCE_RPORT_T:
  1395. msg->msg_flags|=FL_FORCE_RPORT;
  1396. ret=1; /* continue processing */
  1397. break;
  1398. case ADD_LOCAL_RPORT_T:
  1399. msg->msg_flags|=FL_ADD_LOCAL_RPORT;
  1400. ret=1; /* continue processing */
  1401. break;
  1402. case UDP_MTU_TRY_PROTO_T:
  1403. msg->msg_flags|= (unsigned int)a->val[0].u.number & FL_MTU_FB_MASK;
  1404. ret=1; /* continue processing */
  1405. break;
  1406. case SET_ADV_ADDR_T:
  1407. if (a->val[0].type!=STR_ST){
  1408. LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
  1409. "type %d\n", a->val[0].type);
  1410. ret=E_BUG;
  1411. goto error;
  1412. }
  1413. msg->set_global_address=*((str*)a->val[0].u.data);
  1414. ret=1; /* continue processing */
  1415. break;
  1416. case SET_ADV_PORT_T:
  1417. if (a->val[0].type!=STR_ST){
  1418. LOG(L_CRIT, "BUG: do_action: bad set_advertised_port() "
  1419. "type %d\n", a->val[0].type);
  1420. ret=E_BUG;
  1421. goto error;
  1422. }
  1423. msg->set_global_port=*((str*)a->val[0].u.data);
  1424. ret=1; /* continue processing */
  1425. break;
  1426. #ifdef USE_TCP
  1427. case FORCE_TCP_ALIAS_T:
  1428. if ( msg->rcv.proto==PROTO_TCP
  1429. #ifdef USE_TLS
  1430. || msg->rcv.proto==PROTO_TLS
  1431. #endif
  1432. ){
  1433. if (a->val[0].type==NOSUBTYPE) port=msg->via1->port;
  1434. else if (a->val[0].type==NUMBER_ST) port=(int)a->val[0].u.number;
  1435. else{
  1436. LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
  1437. " port type %d\n", a->val[0].type);
  1438. ret=E_BUG;
  1439. goto error;
  1440. }
  1441. if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
  1442. msg->rcv.proto)!=0){
  1443. LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
  1444. ret=E_UNSPEC;
  1445. goto error;
  1446. }
  1447. }
  1448. #endif
  1449. ret=1; /* continue processing */
  1450. break;
  1451. case FORCE_SEND_SOCKET_T:
  1452. if (a->val[0].type!=SOCKETINFO_ST){
  1453. LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument"
  1454. " type: %d\n", a->val[0].type);
  1455. ret=E_BUG;
  1456. goto error;
  1457. }
  1458. set_force_socket(msg, (struct socket_info*)a->val[0].u.data);
  1459. ret=1; /* continue processing */
  1460. break;
  1461. case ADD_T:
  1462. case ASSIGN_T:
  1463. v=lval_assign(h, msg, (struct lvalue*)a->val[0].u.data,
  1464. (struct rval_expr*)a->val[1].u.data);
  1465. if (likely(v>=0))
  1466. ret = 1;
  1467. else if (unlikely (v == EXPR_DROP)) /* hack to quit on DROP*/
  1468. ret=0;
  1469. else
  1470. ret=v;
  1471. break;
  1472. case SET_FWD_NO_CONNECT_T:
  1473. msg->fwd_send_flags.f|= SND_F_FORCE_CON_REUSE;
  1474. ret=1; /* continue processing */
  1475. break;
  1476. case SET_RPL_NO_CONNECT_T:
  1477. msg->rpl_send_flags.f|= SND_F_FORCE_CON_REUSE;
  1478. ret=1; /* continue processing */
  1479. break;
  1480. case SET_FWD_CLOSE_T:
  1481. msg->fwd_send_flags.f|= SND_F_CON_CLOSE;
  1482. ret=1; /* continue processing */
  1483. break;
  1484. case SET_RPL_CLOSE_T:
  1485. msg->rpl_send_flags.f|= SND_F_CON_CLOSE;
  1486. ret=1; /* continue processing */
  1487. break;
  1488. case CFG_SELECT_T:
  1489. if (a->val[0].type != CFG_GROUP_ST) {
  1490. BUG("unsupported parameter in CFG_SELECT_T: %d\n",
  1491. a->val[0].type);
  1492. ret=-1;
  1493. goto error;
  1494. }
  1495. switch(a->val[1].type) {
  1496. case NUMBER_ST:
  1497. v=(int)a->val[1].u.number;
  1498. break;
  1499. case RVE_ST:
  1500. if (rval_expr_eval_int(h, msg, &v, (struct rval_expr*)a->val[1].u.data) < 0) {
  1501. ret=-1;
  1502. goto error;
  1503. }
  1504. break;
  1505. default:
  1506. BUG("unsupported group id type in CFG_SELECT_T: %d\n",
  1507. a->val[1].type);
  1508. ret=-1;
  1509. goto error;
  1510. }
  1511. ret=(cfg_select((cfg_group_t*)a->val[0].u.data, v) == 0) ? 1 : -1;
  1512. break;
  1513. case CFG_RESET_T:
  1514. if (a->val[0].type != CFG_GROUP_ST) {
  1515. BUG("unsupported parameter in CFG_RESET_T: %d\n",
  1516. a->val[0].type);
  1517. ret=-1;
  1518. goto error;
  1519. }
  1520. ret=(cfg_reset((cfg_group_t*)a->val[0].u.data) == 0) ? 1 : -1;
  1521. break;
  1522. /*
  1523. default:
  1524. LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
  1525. */
  1526. }
  1527. skip:
  1528. return ret;
  1529. error_uri:
  1530. LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
  1531. if (new_uri) pkg_free(new_uri);
  1532. LM_ERR("run action error at: %s:%d\n", (a->cfile)?a->cfile:"", a->cline);
  1533. return E_UNSPEC;
  1534. error_fwd_uri:
  1535. /*free_uri(&uri); -- not needed anymore, using msg->parsed_uri*/
  1536. error:
  1537. LM_ERR("run action error at: %s:%d\n", (a->cfile)?a->cfile:"", a->cline);
  1538. return ret;
  1539. }
  1540. /* returns: 0, or 1 on success, <0 on error */
  1541. /* (0 if drop or break encountered, 1 if not ) */
  1542. int run_actions(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
  1543. {
  1544. struct action* t;
  1545. int ret;
  1546. struct sr_module *mod;
  1547. unsigned int ms = 0;
  1548. ret=E_UNSPEC;
  1549. h->rec_lev++;
  1550. if (unlikely(h->rec_lev>ROUTE_MAX_REC_LEV)){
  1551. LOG(L_ERR, "WARNING: too many recursive routing table lookups (%d)"
  1552. " giving up!\n", h->rec_lev);
  1553. ret=E_UNSPEC;
  1554. goto error;
  1555. }
  1556. if (unlikely(h->rec_lev==1)){
  1557. h->run_flags=0;
  1558. h->last_retcode=0;
  1559. _last_returned_code = h->last_retcode;
  1560. #ifdef USE_LONGJMP
  1561. if (unlikely(setjmp(h->jmp_env))){
  1562. h->rec_lev=0;
  1563. ret=h->last_retcode;
  1564. goto end;
  1565. }
  1566. #endif
  1567. }
  1568. if (unlikely(a==0)){
  1569. DBG("DEBUG: run_actions: null action list (rec_level=%d)\n",
  1570. h->rec_lev);
  1571. ret=1;
  1572. }
  1573. for (t=a; t!=0; t=t->next){
  1574. if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0))
  1575. ms = TICKS_TO_MS(get_ticks_raw());
  1576. ret=do_action(h, t, msg);
  1577. if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0)) {
  1578. ms = TICKS_TO_MS(get_ticks_raw()) - ms;
  1579. if(ms >= cfg_get(core, core_cfg, latency_limit_action)) {
  1580. LOG(cfg_get(core, core_cfg, latency_log),
  1581. "alert - action [%s (%d)]"
  1582. " cfg [%s:%d] took too long [%u ms]\n",
  1583. is_mod_func(t) ?
  1584. ((cmd_export_common_t*)(t->val[0].u.data))->name
  1585. : "corefunc",
  1586. t->type, (t->cfile)?t->cfile:"", t->cline, ms);
  1587. }
  1588. }
  1589. /* break, return or drop/exit stop execution of the current
  1590. block */
  1591. if (unlikely(h->run_flags & (BREAK_R_F|RETURN_R_F|EXIT_R_F))){
  1592. if (unlikely(h->run_flags & EXIT_R_F)) {
  1593. h->last_retcode=ret;
  1594. _last_returned_code = h->last_retcode;
  1595. #ifdef USE_LONGJMP
  1596. longjmp(h->jmp_env, ret);
  1597. #endif
  1598. }
  1599. break;
  1600. }
  1601. /* ignore error returns */
  1602. }
  1603. h->rec_lev--;
  1604. end:
  1605. /* process module onbreak handlers if present */
  1606. if (unlikely(h->rec_lev==0 && ret==0 &&
  1607. !(h->run_flags & IGNORE_ON_BREAK_R_F)))
  1608. for (mod=modules;mod;mod=mod->next)
  1609. if (unlikely(mod->exports.onbreak_f)) {
  1610. mod->exports.onbreak_f( msg );
  1611. }
  1612. return ret;
  1613. error:
  1614. h->rec_lev--;
  1615. return ret;
  1616. }
  1617. #ifdef USE_LONGJMP
  1618. /** safe version of run_actions().
  1619. * It always return (it doesn't longjmp on forced script end).
  1620. * @returns 0, or 1 on success, <0 on error
  1621. * (0 if drop or break encountered, 1 if not ) */
  1622. int run_actions_safe(struct run_act_ctx* h, struct action* a,
  1623. struct sip_msg* msg)
  1624. {
  1625. struct run_act_ctx ctx;
  1626. int ret;
  1627. int ign_on_break;
  1628. /* start with a fresh action context */
  1629. init_run_actions_ctx(&ctx);
  1630. ctx.last_retcode = h->last_retcode;
  1631. ign_on_break = h->run_flags & IGNORE_ON_BREAK_R_F;
  1632. ctx.run_flags = h->run_flags | IGNORE_ON_BREAK_R_F;
  1633. ret = run_actions(&ctx, a, msg);
  1634. h->last_retcode = ctx.last_retcode;
  1635. h->run_flags = (ctx.run_flags & ~IGNORE_ON_BREAK_R_F) | ign_on_break;
  1636. return ret;
  1637. }
  1638. #endif /* USE_LONGJMP */
  1639. int run_top_route(struct action* a, sip_msg_t* msg, struct run_act_ctx *c)
  1640. {
  1641. struct run_act_ctx ctx;
  1642. struct run_act_ctx *p;
  1643. int ret;
  1644. flag_t sfbk;
  1645. p = (c)?c:&ctx;
  1646. sfbk = getsflags();
  1647. setsflagsval(0);
  1648. reset_static_buffer();
  1649. init_run_actions_ctx(p);
  1650. ret = run_actions(p, a, msg);
  1651. setsflagsval(sfbk);
  1652. return ret;
  1653. }