lvalue.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * Copyright (C) 2008 iptelorg GmbH
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /**
  17. * @file
  18. * @brief SIP-router core :: lvalues (assignment)
  19. * \ingroup core
  20. * Module: \ref core
  21. */
  22. /*
  23. * History:
  24. * --------
  25. * 2008-11-30 initial version (andrei)
  26. * 2009-04-24 delete avps after finding their new value and not before
  27. * (fixed $avp=$avp)
  28. * when assigning something undefined (e.g. non-existing avp),
  29. * delete the lvalue (similar to perl) (andrei)
  30. */
  31. #include "lvalue.h"
  32. #include "dprint.h"
  33. #include "route.h"
  34. /**
  35. * @brief eval rve and assign the result to an avp
  36. *
  37. * eval rve and assign the result to an avp, lv->lv.avp=eval(rve)
  38. * based on do_action() ASSIGN_T.
  39. * @param h - script context
  40. * @param msg - sip msg
  41. * @param lv - lvalue
  42. * @param rv - rvalue expression
  43. * @return >= 0 on success (expr. bool value), -1 on error
  44. */
  45. inline static int lval_avp_assign(struct run_act_ctx* h, struct sip_msg* msg,
  46. struct lvalue* lv, struct rvalue* rv)
  47. {
  48. avp_spec_t* avp;
  49. avp_t* r_avp;
  50. avp_t* avp_mark;
  51. pv_value_t pval;
  52. int_str value;
  53. unsigned short flags;
  54. struct search_state st;
  55. int ret, v, destroy_pval;
  56. int avp_add;
  57. #if 0
  58. #define AVP_ASSIGN_NOVAL() \
  59. /* unknown value => reset the avp in function of its type */ \
  60. flags=avp->type; \
  61. if (flags & AVP_VAL_STR){ \
  62. value.s.s=""; \
  63. value.s.len=0; \
  64. }else{ \
  65. value.n=0; \
  66. }
  67. #endif
  68. #define AVP_ASSIGN_NOVAL() \
  69. /* no value => delete avp */ \
  70. avp_add=0
  71. destroy_pval=0;
  72. flags = 0;
  73. avp=&lv->lv.avps;
  74. ret=0;
  75. avp_add=1;
  76. switch(rv->type){
  77. case RV_NONE:
  78. BUG("non-intialized rval / rval expr \n");
  79. /* unknown value => reset the avp in function of its type */
  80. flags=avp->type;
  81. AVP_ASSIGN_NOVAL();
  82. ret=-1;
  83. break;
  84. case RV_INT:
  85. value.n=rv->v.l;
  86. flags=avp->type & ~AVP_VAL_STR;
  87. ret=!(!value.n);
  88. break;
  89. case RV_STR:
  90. value.s=rv->v.s;
  91. flags=avp->type | AVP_VAL_STR;
  92. ret=(value.s.len>0);
  93. break;
  94. case RV_ACTION_ST:
  95. flags=avp->type & ~AVP_VAL_STR;
  96. if (rv->v.action) {
  97. value.n=run_actions_safe(h, rv->v.action, msg);
  98. h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
  99. break in expr*/
  100. } else
  101. value.n=-1;
  102. ret=value.n;
  103. break;
  104. case RV_BEXPR: /* logic/boolean expr. */
  105. value.n=eval_expr(h, rv->v.bexpr, msg);
  106. if (unlikely(value.n<0)){
  107. if (value.n==EXPR_DROP) /* hack to quit on drop */
  108. goto drop;
  109. WARN("error in expression\n");
  110. value.n=0; /* expr. is treated as false */
  111. }
  112. flags=avp->type & ~AVP_VAL_STR;
  113. ret=value.n;
  114. break;
  115. case RV_SEL:
  116. flags=avp->type|AVP_VAL_STR;
  117. v=run_select(&value.s, &rv->v.sel, msg);
  118. if (unlikely(v!=0)){
  119. value.s.s="";
  120. value.s.len=0;
  121. if (v<0){
  122. ret=-1;
  123. break;
  124. } /* v>0 */
  125. }
  126. ret=(value.s.len>0);
  127. break;
  128. case RV_AVP:
  129. avp_mark=0;
  130. if (unlikely((rv->v.avps.type & AVP_INDEX_ALL) == AVP_INDEX_ALL)){
  131. /* special case: add the value to the avp */
  132. r_avp = search_first_avp(rv->v.avps.type, rv->v.avps.name,
  133. &value, &st);
  134. while(r_avp){
  135. /* We take only the val type from the source avp
  136. * and reset the class, track flags and name type */
  137. flags=(avp->type & ~(AVP_INDEX_ALL|AVP_VAL_STR)) |
  138. (r_avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL|
  139. AVP_NAME_STR|AVP_NAME_RE));
  140. if (add_avp_before(avp_mark, flags, avp->name, value)<0){
  141. ERR("failed to assign avp\n");
  142. ret=-1;
  143. goto error;
  144. }
  145. /* move the mark, so the next found AVP will come before
  146. the one currently added so they will have the same
  147. order as in the source list */
  148. if (avp_mark) avp_mark=avp_mark->next;
  149. else
  150. avp_mark=search_first_avp(flags, avp->name, 0, 0);
  151. r_avp=search_next_avp(&st, &value);
  152. }
  153. ret=1;
  154. goto end;
  155. }else{
  156. /* normal case, value is replaced */
  157. r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
  158. &value, rv->v.avps.index);
  159. if (likely(r_avp)){
  160. /* take only the val type from the source avp
  161. * and reset the class, track flags and name type */
  162. flags=(avp->type & ~AVP_VAL_STR) | (r_avp->flags &
  163. ~(AVP_CLASS_ALL|AVP_TRACK_ALL|AVP_NAME_STR|
  164. AVP_NAME_RE));
  165. ret=1;
  166. }else{
  167. /* on error, keep the type of the assigned avp, but
  168. reset it to an empty value */
  169. AVP_ASSIGN_NOVAL();
  170. ret=0;
  171. break;
  172. }
  173. }
  174. break;
  175. case RV_PVAR:
  176. memset(&pval, 0, sizeof(pval));
  177. if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){
  178. destroy_pval=1;
  179. if (pval.flags & PV_TYPE_INT){
  180. value.n=pval.ri;
  181. ret=value.n;
  182. flags=avp->type & ~AVP_VAL_STR;
  183. }else if (pval.flags & PV_VAL_STR){
  184. value.s=pval.rs;
  185. ret=(value.s.len>0);
  186. flags=avp->type | AVP_VAL_STR;
  187. }else if (pval.flags==PV_VAL_NONE ||
  188. (pval.flags & (PV_VAL_NULL|PV_VAL_EMPTY))){
  189. AVP_ASSIGN_NOVAL();
  190. ret=0;
  191. }
  192. }else{
  193. /* non existing pvar */
  194. /* on error, keep the type of the assigned avp, but
  195. reset it to an empty value */
  196. AVP_ASSIGN_NOVAL();
  197. ret=0;
  198. }
  199. break;
  200. }
  201. /* If the left attr was specified without indexing brackets delete
  202. * existing AVPs before adding the new value */
  203. delete_avp(avp->type, avp->name);
  204. if (avp_add && (add_avp(flags & ~AVP_INDEX_ALL, avp->name, value) < 0)) {
  205. ERR("failed to assign value to avp\n");
  206. goto error;
  207. }
  208. end:
  209. if (destroy_pval) pv_value_destroy(&pval);
  210. return ret;
  211. error:
  212. if (destroy_pval) pv_value_destroy(&pval);
  213. return -1;
  214. drop:
  215. if (destroy_pval) pv_value_destroy(&pval);
  216. return EXPR_DROP;
  217. }
  218. /**
  219. * @brief eval rve and assign the result to a pvar
  220. *
  221. * eval rve and assign the result to a pvar, lv->lv.pvar=eval(rve)
  222. * based on do_action() ASSIGN_T.
  223. * @param h - script context
  224. * @param msg - sip msg
  225. * @param lv - lvalue
  226. * @param rv - rvalue expression
  227. * @return >= 0 on success (expr. bool value), -1 on error
  228. */
  229. inline static int lval_pvar_assign(struct run_act_ctx* h, struct sip_msg* msg,
  230. struct lvalue* lv, struct rvalue* rv)
  231. {
  232. pv_spec_t* pvar;
  233. pv_value_t pval;
  234. avp_t* r_avp;
  235. int_str avp_val;
  236. int ret;
  237. int v;
  238. int destroy_pval;
  239. #define PVAR_ASSIGN_NOVAL() \
  240. /* no value found => "undefine" */ \
  241. pv_get_null(msg, 0, &pval)
  242. destroy_pval=0;
  243. pvar=&lv->lv.pvs;
  244. if (unlikely(!pv_is_w(pvar))){
  245. ERR("read only pvar\n");
  246. goto error;
  247. }
  248. memset(&pval, 0, sizeof(pval));
  249. ret=0;
  250. switch(rv->type){
  251. case RV_NONE:
  252. BUG("non-intialized rval / rval expr \n");
  253. PVAR_ASSIGN_NOVAL();
  254. ret=-1;
  255. break;
  256. case RV_INT:
  257. pval.flags=PV_TYPE_INT|PV_VAL_INT;
  258. pval.ri=rv->v.l;
  259. ret=!(!pval.ri);
  260. break;
  261. case RV_STR:
  262. pval.flags=PV_VAL_STR;
  263. pval.rs=rv->v.s;
  264. ret=(pval.rs.len>0);
  265. break;
  266. case RV_ACTION_ST:
  267. pval.flags=PV_TYPE_INT|PV_VAL_INT;
  268. if (rv->v.action) {
  269. pval.ri=run_actions_safe(h, rv->v.action, msg);
  270. h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
  271. break in expr*/
  272. } else
  273. pval.ri=0;
  274. ret=!(!pval.ri);
  275. break;
  276. case RV_BEXPR: /* logic/boolean expr. */
  277. pval.flags=PV_TYPE_INT|PV_VAL_INT;
  278. pval.ri=eval_expr(h, rv->v.bexpr, msg);
  279. if (unlikely(pval.ri<0)){
  280. if (pval.ri==EXPR_DROP) /* hack to quit on drop */
  281. goto drop;
  282. WARN("error in expression\n");
  283. pval.ri=0; /* expr. is treated as false */
  284. }
  285. ret=!(!pval.ri);
  286. break;
  287. case RV_SEL:
  288. pval.flags=PV_VAL_STR;
  289. v=run_select(&pval.rs, &rv->v.sel, msg);
  290. if (unlikely(v!=0)){
  291. pval.flags|=PV_VAL_EMPTY;
  292. pval.rs.s="";
  293. pval.rs.len=0;
  294. if (v<0){
  295. ret=-1;
  296. break;
  297. }
  298. }
  299. ret=(pval.rs.len>0);
  300. break;
  301. case RV_AVP:
  302. r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
  303. &avp_val, rv->v.avps.index);
  304. if (likely(r_avp)){
  305. if (r_avp->flags & AVP_VAL_STR){
  306. pval.flags=PV_VAL_STR;
  307. pval.rs=avp_val.s;
  308. ret=(pval.rs.len>0);
  309. }else{
  310. pval.flags=PV_TYPE_INT|PV_VAL_INT;
  311. pval.ri=avp_val.n;
  312. ret=!(!pval.ri);
  313. }
  314. }else{
  315. PVAR_ASSIGN_NOVAL();
  316. ret=0; /* avp not defined (valid case) */
  317. break;
  318. }
  319. break;
  320. case RV_PVAR:
  321. if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){
  322. destroy_pval=1;
  323. if (pval.flags & PV_TYPE_INT){
  324. ret=!(!pval.ri);
  325. }else if (pval.flags & PV_VAL_STR){
  326. ret=(pval.rs.len>0);
  327. }else{
  328. /* no value / not defined (e.g. avp) -> keep the flags */
  329. ret=0;
  330. }
  331. }else{
  332. ERR("non existing right pvar\n");
  333. PVAR_ASSIGN_NOVAL();
  334. ret=-1;
  335. }
  336. break;
  337. }
  338. if (unlikely(pvar->setf(msg, &pvar->pvp, EQ_T, &pval)<0)){
  339. ERR("setting pvar failed\n");
  340. goto error;
  341. }
  342. if (destroy_pval) pv_value_destroy(&pval);
  343. return ret;
  344. error:
  345. if (destroy_pval) pv_value_destroy(&pval);
  346. return -1;
  347. drop:
  348. if (destroy_pval) pv_value_destroy(&pval);
  349. return EXPR_DROP;
  350. }
  351. /** eval rve and assign the result to lv
  352. * lv=eval(rve)
  353. *
  354. * @param h - script context
  355. * @param msg - sip msg
  356. * @param lv - lvalue
  357. * @param rve - rvalue expression
  358. * @return >= 0 on success (expr. bool value), -1 on error
  359. */
  360. int lval_assign(struct run_act_ctx* h, struct sip_msg* msg,
  361. struct lvalue* lv, struct rval_expr* rve)
  362. {
  363. struct rvalue* rv;
  364. int ret;
  365. ret=0;
  366. rv=rval_expr_eval(h, msg, rve);
  367. if (unlikely(rv==0)){
  368. ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
  369. rve->fpos.s_line, rve->fpos.s_col,
  370. rve->fpos.e_line, rve->fpos.e_col);
  371. goto error;
  372. }
  373. switch(lv->type){
  374. case LV_NONE:
  375. BUG("uninitialized/invalid lvalue (%d) (cfg line: %d)\n",
  376. lv->type, rve->fpos.s_line);
  377. goto error;
  378. case LV_AVP:
  379. ret=lval_avp_assign(h, msg, lv, rv);
  380. break;
  381. case LV_PVAR:
  382. ret=lval_pvar_assign(h, msg, lv, rv);
  383. break;
  384. }
  385. if (unlikely(ret<0)){
  386. ERR("assignment failed at pos: (%d,%d-%d,%d)\n",
  387. rve->fpos.s_line, rve->fpos.s_col,
  388. rve->fpos.e_line, rve->fpos.e_col);
  389. }
  390. rval_destroy(rv);
  391. return ret;
  392. error:
  393. if (rv) rval_destroy(rv);
  394. return -1;
  395. }