mod_fix.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  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. * History:
  18. * --------
  19. * 2008-11-25 initial version (andrei)
  20. */
  21. /*!
  22. * \file
  23. * \brief SIP-router core :: kamailio compatible fixups
  24. * \ingroup core
  25. * Module: \ref core
  26. */
  27. #include "mod_fix.h"
  28. #include "mem/mem.h"
  29. #include "trim.h"
  30. #if 0
  31. /* TODO: */
  32. int fixup_regexpNL_null(void** param, int param_no); /* not used */
  33. int fixup_regexpNL_none(void** param, int param_no); /* textops */
  34. #endif
  35. #define FREE_FIXUP_FP(suffix, minp, maxp) \
  36. int fixup_free_##suffix(void** param, int param_no) \
  37. { \
  38. if ((param_no > (maxp)) || (param_no < (minp))) \
  39. return E_UNSPEC; \
  40. if (*param) \
  41. fparam_free_restore(param); \
  42. return 0; \
  43. }
  44. /** macro for declaring a fixup and the corresponding free_fixup
  45. * for a function which fixes to fparam_t and expects 2 different types.
  46. *
  47. * The result (in *param) will be a fparam_t.
  48. *
  49. * @param suffix - function suffix (fixup_ will be pre-pended to it
  50. * @param minp - minimum parameter number acceptable
  51. * @param maxp - maximum parameter number
  52. * @param no1 - number of parameters of type1
  53. * @param type1 - fix_param type for the 1st param
  54. * @param type2 - fix_param type for all the other params
  55. */
  56. #define FIXUP_F2FP(suffix, minp, maxp, no1, type1, type2) \
  57. int fixup_##suffix (void** param, int param_no) \
  58. { \
  59. if ((param_no > (maxp)) || (param_no <(minp))) \
  60. return E_UNSPEC; \
  61. if (param_no <= (no1)){ \
  62. if (fix_param_types((type1), param)!=0) {\
  63. ERR("Cannot convert function parameter %d to" #type1 "\n", \
  64. param_no);\
  65. return E_UNSPEC; \
  66. } \
  67. }else{ \
  68. if (fix_param_types((type2), param)!=0) {\
  69. ERR("Cannot convert function parameter %d to" #type2 "\n", \
  70. param_no); \
  71. return E_UNSPEC; \
  72. } \
  73. }\
  74. return 0; \
  75. } \
  76. FREE_FIXUP_FP(suffix, minp, maxp)
  77. /** macro for declaring a fixup and the corresponding free_fixup
  78. * for a function which fixes directly to the requested type.
  79. *
  80. * @see FIXUP_F2FP for the parameters
  81. * Side effect: declares also some _fp_helper functions
  82. */
  83. #define FIXUP_F2T(suffix, minp, maxp, no1, type1, type2) \
  84. FIXUP_F2FP(fp_##suffix, minp, maxp, no1, type1, type2) \
  85. int fixup_##suffix (void** param, int param_no) \
  86. { \
  87. int ret; \
  88. if ((ret=fixup_fp_##suffix (param, param_no))!=0) \
  89. return ret; \
  90. *param=((fparam_t*)*param)->fixed; \
  91. return 0; \
  92. } \
  93. int fixup_free_##suffix (void** param, int param_no) \
  94. { \
  95. void* p; \
  96. int ret; \
  97. if (param && *param){ \
  98. p=*param - (long)&((fparam_t*)0)->v; \
  99. if ((ret=fixup_free_fp_##suffix(&p, param_no))==0) *param=p; \
  100. return ret; \
  101. } \
  102. return 0; \
  103. }
  104. /** macro for declaring a fixup and the corresponding free_fixup
  105. * for a function expecting first no1 params as fparamt_t and the
  106. * rest as direct type.
  107. *
  108. * @see FIXUP_F2FP for the parameters with the exception
  109. * that only the first no1 parameters are converted to
  110. * fparamt_t and the rest directly to the correponding type
  111. *
  112. * Side effect: declares also some _fpt_helper functions
  113. */
  114. #define FIXUP_F2FP_T(suffix, minp, maxp, no1, type1, type2) \
  115. FIXUP_F2FP(fpt_##suffix, minp, maxp, no1, type1, type2) \
  116. int fixup_##suffix (void** param, int param_no) \
  117. { \
  118. int ret; \
  119. if ((ret=fixup_fpt_##suffix(param, param_no))!=0) \
  120. return ret; \
  121. if (param_no>(no1)) *param=&((fparam_t*)*param)->v; \
  122. return 0; \
  123. } \
  124. int fixup_free_##suffix (void** param, int param_no) \
  125. { \
  126. void* p; \
  127. int ret; \
  128. if (param && *param){ \
  129. p=(param_no>(no1))? *param - (long)&((fparam_t*)0)->v : *param;\
  130. if ((ret=fixup_free_fpt_##suffix(&p, param_no))==0) *param=p; \
  131. return ret; \
  132. } \
  133. return 0; \
  134. }
  135. /** macro for declaring a fixup which fixes all the paremeters to the same
  136. * type.
  137. *
  138. * @see FIXUP_F2T.
  139. */
  140. #define FIXUP_F1T(suffix, minp, maxp, type) \
  141. FIXUP_F2T(suffix, minp, maxp, maxp, type, 0)
  142. FIXUP_F1T(str_null, 1, 1, FPARAM_STR)
  143. FIXUP_F1T(str_str, 1, 2, FPARAM_STR)
  144. FIXUP_F1T(str_all, 1, 100, FPARAM_STR)
  145. /*
  146. no free fixups possible for unit_*
  147. (they overwrite the pointer with the converted number => the original
  148. value cannot be recovered)
  149. FIXUP_F1T(uint_null, 1, 1, FPARAM_INT)
  150. FIXUP_F1T(uint_uint, 1, 2, FPARAM_INT)
  151. */
  152. int fixup_uint_uint(void** param, int param_no)
  153. {
  154. str s;
  155. unsigned int num;
  156. s.s = *param;
  157. s.len = strlen(s.s);
  158. if (likely(str2int(&s, &num) == 0)) {
  159. *param = (void*)(long)num;
  160. } else
  161. /* not a number */
  162. return E_UNSPEC;
  163. return 0;
  164. }
  165. int fixup_uint_null(void** param, int param_no)
  166. {
  167. if (param_no == 1)
  168. return fixup_uint_uint(param, param_no);
  169. return E_UNSPEC;
  170. }
  171. /* fixup_regexp_null() has to be written "by hand", since
  172. it needs to save the original pointer (the fixup users expects
  173. a pointer to the regex in *param and hence the original value
  174. needed on free cannot be recovered directly).
  175. FIXUP_F1T(regexp_null, 1, 1, FPARAM_REGEX)
  176. */
  177. struct regex_fixup {
  178. regex_t regex; /* compiled regex */
  179. void* orig; /* original pointer */
  180. };
  181. int fixup_regexp_null(void** param, int param_no)
  182. {
  183. struct regex_fixup* re;
  184. if (param_no != 1)
  185. return E_UNSPEC;
  186. if ((re=pkg_malloc(sizeof(*re))) ==0) {
  187. ERR("No memory left\n");
  188. goto error;
  189. }
  190. if (regcomp(&re->regex, *param,
  191. REG_EXTENDED|REG_ICASE|REG_NEWLINE))
  192. goto error;
  193. re->orig = *param;
  194. *param = re;
  195. return 0;
  196. error:
  197. if (re)
  198. pkg_free(re);
  199. return E_UNSPEC;
  200. }
  201. int fixup_free_regexp_null(void** param, int param_no)
  202. {
  203. struct regex_fixup* re;
  204. if (param_no != 1)
  205. return E_UNSPEC;
  206. if (*param) {
  207. re = *param;
  208. *param = re->orig;
  209. regfree(&re->regex);
  210. pkg_free(re);
  211. }
  212. return 0;
  213. }
  214. /* fixup_pvar_*() has to be written "by hand", since
  215. it needs to save the original pointer (the fixup users expects
  216. a pointer to the pv_spec_t in *param and hence the original value
  217. needed on free cannot be recovered directly).
  218. FIXUP_F1T(pvar_null, 1, 1, FPARAM_PVS)
  219. FIXUP_F1T(pvar_pvar, 1, 2, FPARAM_PVS)
  220. */
  221. struct pvs_fixup {
  222. pv_spec_t pvs; /* parsed pv spec */
  223. void* orig; /* original pointer */
  224. };
  225. int fixup_pvar_all(void** param, int param_no)
  226. {
  227. struct pvs_fixup* pvs_f;
  228. str name;
  229. pvs_f = 0;
  230. name.s = *param;
  231. name.len = strlen(name.s);
  232. trim(&name);
  233. if (name.len == 0 || name.s[0] != '$')
  234. /* not a pvs id */
  235. goto error;
  236. if ((pvs_f=pkg_malloc(sizeof(*pvs_f))) == 0) {
  237. ERR("No memory left\n");
  238. goto error;
  239. }
  240. if (pv_parse_spec2(&name, &pvs_f->pvs, 1) == 0)
  241. /* not a valid pvs identifier */
  242. goto error;
  243. pvs_f->orig = *param;
  244. *param = pvs_f;
  245. return 0;
  246. error:
  247. if (pvs_f)
  248. pkg_free(pvs_f);
  249. return E_UNSPEC;
  250. }
  251. int fixup_free_pvar_all(void** param, int param_no)
  252. {
  253. struct pvs_fixup* pvs_f;
  254. if (*param) {
  255. pvs_f = *param;
  256. *param = pvs_f->orig;
  257. /* free only the contents (don't attempt to free &pvs_f->pvs)*/
  258. pv_spec_destroy(&pvs_f->pvs);
  259. /* free the whole pvs_fixup */
  260. pkg_free(pvs_f);
  261. }
  262. return 0;
  263. }
  264. int fixup_pvar_pvar(void** param, int param_no)
  265. {
  266. if (param_no > 2)
  267. return E_UNSPEC;
  268. return fixup_pvar_all(param, param_no);
  269. }
  270. int fixup_free_pvar_pvar(void** param, int param_no)
  271. {
  272. if (param_no > 2)
  273. return E_UNSPEC;
  274. return fixup_free_pvar_all(param, param_no);
  275. }
  276. int fixup_pvar_null(void** param, int param_no)
  277. {
  278. if (param_no != 1)
  279. return E_UNSPEC;
  280. return fixup_pvar_all(param, param_no);
  281. }
  282. int fixup_free_pvar_null(void** param, int param_no)
  283. {
  284. if (param_no != 1)
  285. return E_UNSPEC;
  286. return fixup_free_pvar_all(param, param_no);
  287. }
  288. int fixup_pvar_none(void** param, int param_no)
  289. {
  290. if (param_no == 1)
  291. return fixup_pvar_all(param, param_no);
  292. return 0;
  293. }
  294. int fixup_free_pvar_none(void** param, int param_no)
  295. {
  296. if (param_no == 1)
  297. return fixup_free_pvar_all(param, param_no);
  298. return 0;
  299. }
  300. /* must be written "by hand", see above (fixup_pvar_pvar).
  301. FIXUP_F2T(pvar_str, 1, 2, 1, FPARAM_PVS, FPARAM_STR)
  302. FIXUP_F2T(pvar_str_str, 1, 3, 1, FPARAM_PVS, FPARAM_STR)
  303. */
  304. int fixup_pvar_str(void** param, int param_no)
  305. {
  306. if (param_no == 1)
  307. return fixup_pvar_all(param, param_no);
  308. else if (param_no == 2)
  309. return fixup_str_str(param, param_no);
  310. return E_UNSPEC;
  311. }
  312. int fixup_free_pvar_str(void** param, int param_no)
  313. {
  314. if (param_no == 1)
  315. return fixup_free_pvar_all(param, param_no);
  316. else if (param_no == 2)
  317. return fixup_free_str_str(param, param_no);
  318. return E_UNSPEC;
  319. }
  320. int fixup_pvar_str_str(void** param, int param_no)
  321. {
  322. if (param_no == 1)
  323. return fixup_pvar_all(param, param_no);
  324. else if (param_no == 2 || param_no == 3)
  325. return fixup_str_all(param, param_no);
  326. return E_UNSPEC;
  327. }
  328. int fixup_free_pvar_str_str(void** param, int param_no)
  329. {
  330. if (param_no == 1)
  331. return fixup_free_pvar_all(param, param_no);
  332. else if (param_no == 2 || param_no == 3)
  333. return fixup_free_str_all(param, param_no);
  334. return E_UNSPEC;
  335. }
  336. int fixup_pvar_uint(void** param, int param_no)
  337. {
  338. if (param_no == 1)
  339. return fixup_pvar_all(param, param_no);
  340. else if (param_no == 2)
  341. return fixup_uint_uint(param, param_no);
  342. return E_UNSPEC;
  343. }
  344. int fixup_free_pvar_uint(void** param, int param_no)
  345. {
  346. if (param_no == 1)
  347. return fixup_free_pvar_all(param, param_no);
  348. return E_UNSPEC;
  349. }
  350. FIXUP_F2FP(igp_null, 1, 1, 1, FPARAM_INT|FPARAM_PVS, 0)
  351. FIXUP_F2FP(igp_igp, 1, 2, 2, FPARAM_INT|FPARAM_PVS, 0)
  352. /* must be declared by hand, because of the pvar special handling
  353. (see above)
  354. FIXUP_F2FP(igp_pvar, 1, 2, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
  355. FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
  356. */
  357. int fixup_igp_pvar(void** param, int param_no)
  358. {
  359. if (param_no == 1)
  360. return fixup_igp_null(param, param_no);
  361. else if (param_no == 2)
  362. return fixup_pvar_all(param, param_no);
  363. return E_UNSPEC;
  364. }
  365. int fixup_free_igp_pvar(void** param, int param_no)
  366. {
  367. if (param_no == 1)
  368. return fixup_free_igp_null(param, param_no);
  369. else if (param_no == 2)
  370. return fixup_free_pvar_all(param, param_no);
  371. return E_UNSPEC;
  372. }
  373. int fixup_igp_pvar_pvar(void** param, int param_no)
  374. {
  375. if (param_no == 1)
  376. return fixup_igp_null(param, param_no);
  377. else if (param_no == 2 || param_no == 3)
  378. return fixup_pvar_all(param, param_no);
  379. return E_UNSPEC;
  380. }
  381. int fixup_free_igp_pvar_pvar(void** param, int param_no)
  382. {
  383. if (param_no == 1)
  384. return fixup_free_igp_null(param, param_no);
  385. else if (param_no == 2 || param_no == 3)
  386. return fixup_free_pvar_all(param, param_no);
  387. return E_UNSPEC;
  388. }
  389. /** macro for declaring a spve fixup and the corresponding free_fixup
  390. * for a function expecting first no1 params as fparam converted spve
  391. * and the * rest as direct type.
  392. *
  393. * @see FIXUP_F2FP for the parameters with the exception
  394. * that the first no1 parameters are converted to fparam_t from spve
  395. * and the rest directly to the corresponding type
  396. *
  397. * Side effect: declares also some _spvet_helper functions
  398. */
  399. #define FIXUP_F_SPVE_T(suffix, minp, maxp, no1, type2) \
  400. FIXUP_F1T(spvet_##suffix, minp, maxp, type2) \
  401. int fixup_##suffix (void** param, int param_no) \
  402. { \
  403. int ret; \
  404. fparam_t* fp; \
  405. if (param_no<=(no1)){ \
  406. if ((ret=fix_param_types(FPARAM_PVE, param))<0){ \
  407. ERR("Cannot convert function parameter %d to spve \n", \
  408. param_no);\
  409. return E_UNSPEC; \
  410. } else{ \
  411. fp=(fparam_t*)*param; \
  412. if ((ret==0) && (fp->v.pve->spec==0 \
  413. || fp->v.pve->spec->getf==0)){ \
  414. fparam_free_restore(param); \
  415. return fix_param_types(FPARAM_STR, param); \
  416. } else if (ret==1) \
  417. return fix_param_types(FPARAM_STR, param); \
  418. return ret; \
  419. } \
  420. } else return fixup_spvet_##suffix(param, param_no); \
  421. return 0; \
  422. } \
  423. int fixup_free_##suffix (void** param, int param_no) \
  424. { \
  425. if (param && *param){ \
  426. if (param_no<=(no1)) \
  427. fparam_free_restore(param); \
  428. else \
  429. return fixup_free_spvet_##suffix(param, param_no); \
  430. } \
  431. return 0; \
  432. }
  433. /* format: name, minp, maxp, no_of_spve_params, type_for_rest_params */
  434. FIXUP_F_SPVE_T(spve_spve, 1, 2, 2, 0)
  435. FIXUP_F_SPVE_T(spve_uint, 1, 2, 1, FPARAM_INT)
  436. FIXUP_F_SPVE_T(spve_str, 1, 2, 1, FPARAM_STR)
  437. FIXUP_F_SPVE_T(spve_null, 1, 1, 1, 0)
  438. /** get the corresp. fixup_free* function.
  439. * @param f -fixup function pointer.
  440. * @return - pointer to free_fixup function if known, 0 otherwise.
  441. */
  442. free_fixup_function mod_fix_get_fixup_free(fixup_function f)
  443. {
  444. if (f == fixup_str_null) return fixup_free_str_null;
  445. if (f == fixup_str_str) return fixup_free_str_str;
  446. /* no free fixup for fixup_uint_* (they overwrite the pointer
  447. value with a number and the original value cannot be recovered) */
  448. if (f == fixup_uint_null) return 0;
  449. if (f == fixup_uint_uint) return 0;
  450. if (f == fixup_regexp_null) return fixup_free_regexp_null;
  451. if (f == fixup_pvar_null) return fixup_free_pvar_null;
  452. if (f == fixup_pvar_pvar) return fixup_free_pvar_pvar;
  453. if (f == fixup_pvar_str) return fixup_free_pvar_str;
  454. if (f == fixup_pvar_str_str) return fixup_free_pvar_str_str;
  455. if (f == fixup_igp_igp) return fixup_free_igp_igp;
  456. if (f == fixup_igp_null) return fixup_free_igp_null;
  457. if (f == fixup_igp_pvar) return fixup_free_igp_pvar;
  458. if (f == fixup_igp_pvar_pvar) return fixup_free_igp_pvar_pvar;
  459. if (f == fixup_spve_spve) return fixup_free_spve_spve;
  460. if (f == fixup_spve_null) return fixup_free_spve_null;
  461. /* no free fixup, because of the uint part (the uint cannot be freed,
  462. see above fixup_uint_null) */
  463. if (f == fixup_spve_uint) return 0;
  464. if (f == fixup_spve_str) return fixup_free_spve_str;
  465. return 0;
  466. }
  467. /**
  468. *
  469. */
  470. int fixup_spve_all(void** param, int param_no)
  471. {
  472. return fixup_spve_null(param, 1);
  473. }
  474. /**
  475. *
  476. */
  477. int fixup_igp_all(void** param, int param_no)
  478. {
  479. return fixup_igp_null(param, 1);
  480. }
  481. /**
  482. *
  483. */
  484. int fixup_spve_igp(void** param, int param_no)
  485. {
  486. if(param_no==1)
  487. return fixup_spve_null(param, 1);
  488. if(param_no==2)
  489. return fixup_igp_null(param, 1);
  490. return E_UNSPEC;
  491. }
  492. /**
  493. *
  494. */
  495. int fixup_free_spve_igp(void** param, int param_no)
  496. {
  497. if(param_no==1)
  498. return fixup_free_spve_null(param, 1);
  499. if(param_no==2)
  500. return fixup_free_igp_null(param, 1);
  501. return E_UNSPEC;
  502. }