usr_avp.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. /*
  2. * Copyright (C) 2001-2003 FhG Fokus
  3. *
  4. * This file is part of ser, a free SIP server.
  5. *
  6. * ser is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version
  10. *
  11. * For a license to use the ser software under conditions
  12. * other than those described here, or to purchase support for this
  13. * software, please contact iptel.org by e-mail at the following addresses:
  14. * [email protected]
  15. *
  16. * ser is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24. *
  25. * History:
  26. * ---------
  27. * 2004-07-21 created (bogdan)
  28. * 2004-10-09 interface more flexible - more function available (bogdan)
  29. * 2004-11-07 AVP string values are kept 0 terminated (bogdan)
  30. * 2004-11-14 global aliases support added
  31. * 2005-01-05 parse avp name according new syntax
  32. */
  33. /*!
  34. * \file
  35. * \brief SIP-router core ::
  36. * \ingroup core
  37. * Module: \ref core
  38. */
  39. #include <assert.h>
  40. #include <ctype.h>
  41. #include <string.h>
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include "sr_module.h"
  45. #include "dprint.h"
  46. #include "str.h"
  47. #include "ut.h"
  48. #include "mem/shm_mem.h"
  49. #include "mem/mem.h"
  50. #include "usr_avp.h"
  51. enum idx {
  52. IDX_FROM_URI = 0,
  53. IDX_TO_URI,
  54. IDX_FROM_USER,
  55. IDX_TO_USER,
  56. IDX_FROM_DOMAIN,
  57. IDX_TO_DOMAIN,
  58. IDX_MAX
  59. };
  60. struct avp_galias {
  61. str alias;
  62. struct avp_spec avp;
  63. struct avp_galias *next;
  64. };
  65. static struct avp_galias *galiases = 0;
  66. static avp_list_t def_list[IDX_MAX]; /* Default AVP lists */
  67. static avp_list_t* crt_list[IDX_MAX]; /* Pointer to current AVP lists */
  68. /* Global AVP related variables go to shm mem */
  69. static avp_list_t* def_glist;
  70. static avp_list_t** crt_glist;
  71. /* AVP flags */
  72. int registered_avpflags_no = 0;
  73. static char *registered_avpflags[MAX_AVPFLAG];
  74. /* Initialize AVP lists in private memory and allocate memory
  75. * for shared lists
  76. */
  77. int init_avps(void)
  78. {
  79. int i;
  80. /* Empty default lists */
  81. memset(def_list, 0, sizeof(avp_list_t) * IDX_MAX);
  82. /* Point current pointers to default lists */
  83. for(i = 0; i < IDX_MAX; i++) {
  84. crt_list[i] = &def_list[i];
  85. }
  86. def_glist = (avp_list_t*)shm_malloc(sizeof(avp_list_t));
  87. crt_glist = (avp_list_t**)shm_malloc(sizeof(avp_list_t*));
  88. if (!def_glist || !crt_glist) {
  89. LOG(L_ERR, "ERROR: No memory to allocate default global AVP list\n");
  90. return -1;
  91. }
  92. *def_glist = 0;
  93. *crt_glist = def_glist;
  94. return 0;
  95. }
  96. /*
  97. * Select active AVP list based on the value of flags
  98. */
  99. static avp_list_t* select_list(avp_flags_t flags)
  100. {
  101. if (flags & AVP_CLASS_URI) {
  102. if (flags & AVP_TRACK_TO) {
  103. return crt_list[IDX_TO_URI];
  104. } else {
  105. return crt_list[IDX_FROM_URI];
  106. }
  107. } else if (flags & AVP_CLASS_USER) {
  108. if (flags & AVP_TRACK_TO) {
  109. return crt_list[IDX_TO_USER];
  110. } else {
  111. return crt_list[IDX_FROM_USER];
  112. }
  113. } else if (flags & AVP_CLASS_DOMAIN) {
  114. if (flags & AVP_TRACK_TO) {
  115. return crt_list[IDX_TO_DOMAIN];
  116. } else {
  117. return crt_list[IDX_FROM_DOMAIN];
  118. }
  119. } else if (flags & AVP_CLASS_GLOBAL) {
  120. return *crt_glist;
  121. }
  122. return NULL;
  123. }
  124. inline static avp_id_t compute_ID( str *name )
  125. {
  126. char *p;
  127. avp_id_t id;
  128. id=0;
  129. for( p=name->s+name->len-1 ; p>=name->s ; p-- )
  130. id ^= *p;
  131. return id;
  132. }
  133. avp_t *create_avp (avp_flags_t flags, avp_name_t name, avp_value_t val)
  134. {
  135. avp_t *avp;
  136. str *s;
  137. struct str_int_data *sid;
  138. struct str_str_data *ssd;
  139. int len;
  140. if (name.s.s == 0 && name.s.len == 0) {
  141. LOG(L_ERR,"ERROR:avp:add_avp: 0 ID or NULL NAME AVP!");
  142. goto error;
  143. }
  144. /* compute the required mem size */
  145. len = sizeof(struct usr_avp);
  146. if (flags&AVP_NAME_STR) {
  147. if ( name.s.s==0 || name.s.len==0) {
  148. LOG(L_ERR,"ERROR:avp:add_avp: EMPTY NAME AVP!");
  149. goto error;
  150. }
  151. if (flags&AVP_VAL_STR) {
  152. len += sizeof(struct str_str_data)-sizeof(union usr_avp_data)
  153. + name.s.len + 1 /* Terminating zero for regex search */
  154. + val.s.len + 1; /* Value is zero terminated */
  155. } else {
  156. len += sizeof(struct str_int_data)-sizeof(union usr_avp_data)
  157. + name.s.len + 1; /* Terminating zero for regex search */
  158. }
  159. } else if (flags&AVP_VAL_STR) {
  160. len += sizeof(str)-sizeof(union usr_avp_data) + val.s.len + 1;
  161. }
  162. avp = (struct usr_avp*)shm_malloc( len );
  163. if (avp==0) {
  164. LOG(L_ERR,"ERROR:avp:add_avp: no more shm mem\n");
  165. return 0;
  166. }
  167. avp->flags = flags;
  168. avp->id = (flags&AVP_NAME_STR)? compute_ID(&name.s) : name.n ;
  169. avp->next = NULL;
  170. switch ( flags&(AVP_NAME_STR|AVP_VAL_STR) )
  171. {
  172. case 0:
  173. /* avp type ID, int value */
  174. avp->d.l = val.n;
  175. break;
  176. case AVP_NAME_STR:
  177. /* avp type str, int value */
  178. sid = (struct str_int_data*)&avp->d.data[0];
  179. sid->val = val.n;
  180. sid->name.len =name.s.len;
  181. sid->name.s = (char*)sid + sizeof(struct str_int_data);
  182. memcpy( sid->name.s , name.s.s, name.s.len);
  183. sid->name.s[name.s.len] = '\0'; /* Zero terminator */
  184. break;
  185. case AVP_VAL_STR:
  186. /* avp type ID, str value */
  187. s = (str*)&avp->d.data[0];
  188. s->len = val.s.len;
  189. s->s = (char*)s + sizeof(str);
  190. memcpy( s->s, val.s.s , s->len);
  191. s->s[s->len] = 0;
  192. break;
  193. case AVP_NAME_STR|AVP_VAL_STR:
  194. /* avp type str, str value */
  195. ssd = (struct str_str_data*)&avp->d.data[0];
  196. ssd->name.len = name.s.len;
  197. ssd->name.s = (char*)ssd + sizeof(struct str_str_data);
  198. memcpy( ssd->name.s , name.s.s, name.s.len);
  199. ssd->name.s[name.s.len]='\0'; /* Zero terminator */
  200. ssd->val.len = val.s.len;
  201. ssd->val.s = ssd->name.s + ssd->name.len + 1;
  202. memcpy( ssd->val.s , val.s.s, val.s.len);
  203. ssd->val.s[ssd->val.len] = 0;
  204. break;
  205. }
  206. return avp;
  207. error:
  208. return 0;
  209. }
  210. int add_avp_list(avp_list_t* list, avp_flags_t flags, avp_name_t name, avp_value_t val)
  211. {
  212. avp_t *avp;
  213. assert(list != 0);
  214. if ((avp = create_avp(flags, name, val))) {
  215. avp->next = *list;
  216. *list = avp;
  217. return 0;
  218. }
  219. return -1;
  220. }
  221. int add_avp(avp_flags_t flags, avp_name_t name, avp_value_t val)
  222. {
  223. avp_flags_t avp_class;
  224. avp_list_t* list;
  225. /* Add avp to uri class if no class has been
  226. * specified by the caller
  227. */
  228. if ((flags & AVP_CLASS_ALL) == 0) flags |= AVP_CLASS_URI;
  229. if ((flags & AVP_TRACK_ALL) == 0) flags |= AVP_TRACK_FROM;
  230. if (!(list = select_list(flags)))
  231. return -1;
  232. if (flags & AVP_CLASS_URI) avp_class = AVP_CLASS_URI;
  233. else if (flags & AVP_CLASS_USER) avp_class = AVP_CLASS_USER;
  234. else if (flags & AVP_CLASS_DOMAIN) avp_class = AVP_CLASS_DOMAIN;
  235. else avp_class = AVP_CLASS_GLOBAL;
  236. /* Make that only the selected class is set
  237. * if the caller set more classes in flags
  238. */
  239. return add_avp_list(list, flags & (~(AVP_CLASS_ALL) | avp_class), name, val);
  240. }
  241. int add_avp_before(avp_t *avp, avp_flags_t flags, avp_name_t name, avp_value_t val)
  242. {
  243. avp_t *new_avp;
  244. if (!avp) {
  245. return add_avp(flags, name, val);
  246. }
  247. if ((flags & AVP_CLASS_ALL) == 0) flags |= (avp->flags & AVP_CLASS_ALL);
  248. if ((flags & AVP_TRACK_ALL) == 0) flags |= (avp->flags & AVP_TRACK_ALL);
  249. if ((avp->flags & (AVP_CLASS_ALL|AVP_TRACK_ALL)) != (flags & (AVP_CLASS_ALL|AVP_TRACK_ALL))) {
  250. ERR("add_avp_before:Source and target AVPs have different CLASS/TRACK\n");
  251. return -1;
  252. }
  253. if ((new_avp=create_avp(flags, name, val))) {
  254. new_avp->next=avp->next;
  255. avp->next=new_avp;
  256. return 0;
  257. }
  258. return -1;
  259. }
  260. /* get value functions */
  261. inline str* get_avp_name(avp_t *avp)
  262. {
  263. struct str_int_data *sid;
  264. struct str_str_data *ssd;
  265. switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) )
  266. {
  267. case 0:
  268. /* avp type ID, int value */
  269. case AVP_VAL_STR:
  270. /* avp type ID, str value */
  271. return 0;
  272. case AVP_NAME_STR:
  273. /* avp type str, int value */
  274. sid = (struct str_int_data*)&avp->d.data[0];
  275. return &sid->name;
  276. case AVP_NAME_STR|AVP_VAL_STR:
  277. /* avp type str, str value */
  278. ssd = (struct str_str_data*)&avp->d.data[0];
  279. return &ssd->name;
  280. }
  281. LOG(L_ERR,"BUG:avp:get_avp_name: unknown avp type (name&val) %d\n",
  282. avp->flags&(AVP_NAME_STR|AVP_VAL_STR));
  283. return 0;
  284. }
  285. inline void get_avp_val(avp_t *avp, avp_value_t *val)
  286. {
  287. str *s;
  288. struct str_int_data *sid;
  289. struct str_str_data *ssd;
  290. if (avp==0 || val==0)
  291. return;
  292. switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) ) {
  293. case 0:
  294. /* avp type ID, int value */
  295. val->n = avp->d.l;
  296. break;
  297. case AVP_NAME_STR:
  298. /* avp type str, int value */
  299. sid = (struct str_int_data*)&avp->d.data[0];
  300. val->n = sid->val;
  301. break;
  302. case AVP_VAL_STR:
  303. /* avp type ID, str value */
  304. s = (str*)&avp->d.data[0];
  305. val->s = *s;
  306. break;
  307. case AVP_NAME_STR|AVP_VAL_STR:
  308. /* avp type str, str value */
  309. ssd = (struct str_str_data*)&avp->d.data[0];
  310. val->s = ssd->val;
  311. break;
  312. }
  313. }
  314. /* Return the current list of user attributes */
  315. avp_list_t get_avp_list(avp_flags_t flags)
  316. {
  317. avp_list_t *list;
  318. list = select_list(flags);
  319. return (list ? *list : NULL);
  320. }
  321. /*
  322. * Compare given id with id in avp, return true if they match
  323. */
  324. static inline int match_by_id(avp_t* avp, avp_id_t id)
  325. {
  326. if (avp->id == id && (avp->flags&AVP_NAME_STR)==0) {
  327. return 1;
  328. }
  329. return 0;
  330. }
  331. /*
  332. * Compare given name with name in avp, return true if they are same
  333. */
  334. static inline int match_by_name(avp_t* avp, avp_id_t id, str* name)
  335. {
  336. str* avp_name;
  337. if (id==avp->id && avp->flags&AVP_NAME_STR &&
  338. (avp_name=get_avp_name(avp))!=0 && avp_name->len==name->len
  339. && !strncasecmp( avp_name->s, name->s, name->len) ) {
  340. return 1;
  341. }
  342. return 0;
  343. }
  344. /*
  345. * Compare name with name in AVP using regular expressions, return
  346. * true if they match
  347. */
  348. static inline int match_by_re(avp_t* avp, regex_t* re)
  349. {
  350. regmatch_t pmatch;
  351. str * avp_name;
  352. /* AVP identifiable by name ? */
  353. if (!(avp->flags&AVP_NAME_STR)) return 0;
  354. if ((avp_name=get_avp_name(avp))==0) /* valid AVP name ? */
  355. return 0;
  356. if (!avp_name->s) /* AVP name validation */
  357. return 0;
  358. if (regexec(re, avp_name->s, 1, &pmatch,0)==0) { /* re match ? */
  359. return 1;
  360. }
  361. return 0;
  362. }
  363. avp_t *search_first_avp(avp_flags_t flags, avp_name_t name, avp_value_t *val, struct search_state* s)
  364. {
  365. avp_ident_t id;
  366. id.flags = flags;
  367. id.name = name;
  368. id.index = 0;
  369. return search_avp (id, val, s);
  370. }
  371. avp_t *search_avp (avp_ident_t ident, avp_value_t* val, struct search_state* state)
  372. {
  373. avp_t* ret;
  374. static struct search_state st;
  375. avp_list_t* list;
  376. if (ident.name.s.s==0 && ident.name.s.len == 0) {
  377. LOG(L_ERR,"ERROR:avp:search_first_avp: 0 ID or NULL NAME AVP!");
  378. return 0;
  379. }
  380. switch (ident.flags & AVP_INDEX_ALL) {
  381. case AVP_INDEX_BACKWARD:
  382. case AVP_INDEX_FORWARD:
  383. WARN("AVP specified with index, but not used for search\n");
  384. break;
  385. }
  386. if (!state) state = &st;
  387. if ((ident.flags & AVP_CLASS_ALL) == 0) {
  388. /* The caller did not specify any class to search in, so enable
  389. * all of them by default
  390. */
  391. ident.flags |= AVP_CLASS_ALL;
  392. if ((ident.flags & AVP_TRACK_ALL) == 0) {
  393. /* The caller did not specify even the track to search in, so search
  394. * in the track_from
  395. */
  396. ident.flags |= AVP_TRACK_FROM;
  397. }
  398. }
  399. if (!(list = select_list(ident.flags)))
  400. return NULL;
  401. state->flags = ident.flags;
  402. state->avp = *list;
  403. state->name = ident.name;
  404. if (ident.flags & AVP_NAME_STR) {
  405. state->id = compute_ID(&ident.name.s);
  406. }
  407. ret = search_next_avp(state, val);
  408. /* Make sure that search next avp stays in the same class as the first
  409. * avp found
  410. */
  411. if (state && ret) state->flags = (ident.flags & ~AVP_CLASS_ALL) | (ret->flags & AVP_CLASS_ALL);
  412. return ret;
  413. }
  414. avp_t *search_next_avp(struct search_state* s, avp_value_t *val )
  415. {
  416. int matched;
  417. avp_t* avp;
  418. avp_list_t *list;
  419. if (s == 0) {
  420. LOG(L_ERR, "search_next:avp: Invalid parameter value\n");
  421. return 0;
  422. }
  423. switch (s->flags & AVP_INDEX_ALL) {
  424. case AVP_INDEX_BACKWARD:
  425. case AVP_INDEX_FORWARD:
  426. WARN("AVP specified with index, but not used for search\n");
  427. break;
  428. }
  429. while(1) {
  430. for( ; s->avp; s->avp = s->avp->next) {
  431. if (s->flags & AVP_NAME_RE) {
  432. matched = match_by_re(s->avp, s->name.re);
  433. } else if (s->flags & AVP_NAME_STR) {
  434. matched = match_by_name(s->avp, s->id, &s->name.s);
  435. } else {
  436. matched = match_by_id(s->avp, s->name.n);
  437. }
  438. if (matched) {
  439. avp = s->avp;
  440. s->avp = s->avp->next;
  441. if (val) get_avp_val(avp, val);
  442. return avp;
  443. }
  444. }
  445. if (s->flags & AVP_CLASS_URI) {
  446. s->flags &= ~AVP_CLASS_URI;
  447. list = select_list(s->flags);
  448. } else if (s->flags & AVP_CLASS_USER) {
  449. s->flags &= ~AVP_CLASS_USER;
  450. list = select_list(s->flags);
  451. } else if (s->flags & AVP_CLASS_DOMAIN) {
  452. s->flags &= ~AVP_CLASS_DOMAIN;
  453. list = select_list(s->flags);
  454. } else {
  455. s->flags &= ~AVP_CLASS_GLOBAL;
  456. return 0;
  457. }
  458. if (!list) return 0;
  459. s->avp = *list;
  460. }
  461. return 0;
  462. }
  463. int search_reverse( avp_t *cur, struct search_state* st,
  464. avp_index_t index, avp_list_t *ret)
  465. {
  466. avp_index_t lvl;
  467. if (!cur)
  468. return 0;
  469. lvl = search_reverse(search_next_avp(st, NULL), st, index, ret)+1;
  470. if (index==lvl)
  471. *ret=cur;
  472. return lvl;
  473. }
  474. avp_t *search_avp_by_index( avp_flags_t flags, avp_name_t name,
  475. avp_value_t *val, avp_index_t index)
  476. {
  477. avp_t *ret, *cur;
  478. struct search_state st;
  479. if (flags & AVP_NAME_RE) {
  480. BUG("search_by_index not supported for AVP_NAME_RE\n");
  481. return 0;
  482. }
  483. switch (flags & AVP_INDEX_ALL) {
  484. case 0:
  485. ret = search_first_avp(flags, name, val, &st);
  486. if (!ret || search_next_avp(&st, NULL))
  487. return 0;
  488. else
  489. return ret;
  490. case AVP_INDEX_ALL:
  491. BUG("search_by_index not supported for anonymous index []\n");
  492. return 0;
  493. case AVP_INDEX_FORWARD:
  494. ret = NULL;
  495. cur = search_first_avp(flags & ~AVP_INDEX_ALL, name, NULL, &st);
  496. search_reverse(cur, &st, index, &ret);
  497. if (ret && val)
  498. get_avp_val(ret, val);
  499. return ret;
  500. case AVP_INDEX_BACKWARD:
  501. ret = search_first_avp(flags & ~AVP_INDEX_ALL, name, val, &st);
  502. for (index--; (ret && index); ret=search_next_avp(&st, val), index--);
  503. return ret;
  504. }
  505. return 0;
  506. }
  507. /* FIXME */
  508. /********* free functions ********/
  509. void destroy_avp(avp_t *avp_del)
  510. {
  511. int i;
  512. avp_t *avp, *avp_prev;
  513. for (i = 0; i < IDX_MAX; i++) {
  514. for( avp_prev=0,avp=*crt_list[i] ; avp ;
  515. avp_prev=avp,avp=avp->next ) {
  516. if (avp==avp_del) {
  517. if (avp_prev) {
  518. avp_prev->next=avp->next;
  519. } else {
  520. *crt_list[i] = avp->next;
  521. }
  522. shm_free(avp);
  523. return;
  524. }
  525. }
  526. }
  527. for( avp_prev=0,avp=**crt_glist ; avp ;
  528. avp_prev=avp,avp=avp->next ) {
  529. if (avp==avp_del) {
  530. if (avp_prev) {
  531. avp_prev->next=avp->next;
  532. } else {
  533. **crt_glist = avp->next;
  534. }
  535. shm_free(avp);
  536. return;
  537. }
  538. }
  539. }
  540. void destroy_avp_list_unsafe(avp_list_t* list)
  541. {
  542. avp_t *avp, *foo;
  543. avp = *list;
  544. while( avp ) {
  545. foo = avp;
  546. avp = avp->next;
  547. shm_free_unsafe( foo );
  548. }
  549. *list = 0;
  550. }
  551. inline void destroy_avp_list(avp_list_t* list)
  552. {
  553. avp_t *avp, *foo;
  554. DBG("DEBUG:destroy_avp_list: destroying list %p\n", *list);
  555. avp = *list;
  556. while( avp ) {
  557. foo = avp;
  558. avp = avp->next;
  559. shm_free( foo );
  560. }
  561. *list = 0;
  562. }
  563. int reset_avp_list(int flags)
  564. {
  565. int i;
  566. if (flags & AVP_CLASS_URI) {
  567. if (flags & AVP_TRACK_FROM) i = IDX_FROM_URI;
  568. else i = IDX_TO_URI;
  569. } else if (flags & AVP_CLASS_USER) {
  570. if (flags & AVP_TRACK_FROM) i = IDX_FROM_USER;
  571. else i = IDX_TO_USER;
  572. } else if (flags & AVP_CLASS_DOMAIN) {
  573. if (flags & AVP_TRACK_FROM) i = IDX_FROM_DOMAIN;
  574. else i = IDX_TO_DOMAIN;
  575. } else return -1;
  576. crt_list[i] = &def_list[i];
  577. destroy_avp_list(crt_list[i]);
  578. return 0;
  579. }
  580. void reset_avps(void)
  581. {
  582. int i;
  583. for(i = 0; i < IDX_MAX; i++) {
  584. crt_list[i] = &def_list[i];
  585. destroy_avp_list(crt_list[i]);
  586. }
  587. }
  588. avp_list_t* set_avp_list( avp_flags_t flags, avp_list_t* list )
  589. {
  590. avp_list_t* prev;
  591. if (flags & AVP_CLASS_URI) {
  592. if (flags & AVP_TRACK_FROM) {
  593. prev = crt_list[IDX_FROM_URI];
  594. crt_list[IDX_FROM_URI] = list;
  595. } else {
  596. prev = crt_list[IDX_TO_URI];
  597. crt_list[IDX_TO_URI] = list;
  598. }
  599. } else if (flags & AVP_CLASS_USER) {
  600. if (flags & AVP_TRACK_FROM) {
  601. prev = crt_list[IDX_FROM_USER];
  602. crt_list[IDX_FROM_USER] = list;
  603. } else {
  604. prev = crt_list[IDX_TO_USER];
  605. crt_list[IDX_TO_USER] = list;
  606. }
  607. } else if (flags & AVP_CLASS_DOMAIN) {
  608. if (flags & AVP_TRACK_FROM) {
  609. prev = crt_list[IDX_FROM_DOMAIN];
  610. crt_list[IDX_FROM_DOMAIN] = list;
  611. } else {
  612. prev = crt_list[IDX_TO_DOMAIN];
  613. crt_list[IDX_TO_DOMAIN] = list;
  614. }
  615. } else {
  616. prev = *crt_glist;
  617. *crt_glist = list;
  618. }
  619. return prev;
  620. }
  621. /********* global aliases functions ********/
  622. static inline int check_avp_galias(str *alias, int type, int_str avp_name)
  623. {
  624. struct avp_galias *ga;
  625. type &= AVP_NAME_STR;
  626. for( ga=galiases ; ga ; ga=ga->next ) {
  627. /* check for duplicated alias names */
  628. if ( alias->len==ga->alias.len &&
  629. (strncasecmp( alias->s, ga->alias.s, alias->len)==0) )
  630. return -1;
  631. /*check for duplicated avp names */
  632. if (type==ga->avp.type) {
  633. if (type&AVP_NAME_STR){
  634. if (avp_name.s.len==ga->avp.name.s.len &&
  635. (strncasecmp(avp_name.s.s, ga->avp.name.s.s,
  636. avp_name.s.len)==0) )
  637. return -1;
  638. } else {
  639. if (avp_name.n==ga->avp.name.n)
  640. return -1;
  641. }
  642. }
  643. }
  644. return 0;
  645. }
  646. int add_avp_galias(str *alias, int type, int_str avp_name)
  647. {
  648. struct avp_galias *ga;
  649. if ((type&AVP_NAME_STR && (!avp_name.s.s ||
  650. !avp_name.s.len)) ||!alias || !alias->s ||
  651. !alias->len ){
  652. LOG(L_ERR, "ERROR:add_avp_galias: null params received\n");
  653. goto error;
  654. }
  655. if (check_avp_galias(alias,type,avp_name)!=0) {
  656. LOG(L_ERR, "ERROR:add_avp_galias: duplicate alias/avp entry\n");
  657. goto error;
  658. }
  659. ga = (struct avp_galias*)pkg_malloc( sizeof(struct avp_galias) );
  660. if (ga==0) {
  661. LOG(L_ERR, "ERROR:add_avp_galias: no more pkg memory\n");
  662. goto error;
  663. }
  664. ga->alias.s = (char*)pkg_malloc( alias->len+1 );
  665. if (ga->alias.s==0) {
  666. LOG(L_ERR, "ERROR:add_avp_galias: no more pkg memory\n");
  667. goto error1;
  668. }
  669. memcpy( ga->alias.s, alias->s, alias->len);
  670. ga->alias.len = alias->len;
  671. ga->avp.type = type&AVP_NAME_STR;
  672. if (type&AVP_NAME_STR) {
  673. ga->avp.name.s.s = (char*)pkg_malloc( avp_name.s.len+1 );
  674. if (ga->avp.name.s.s==0) {
  675. LOG(L_ERR, "ERROR:add_avp_galias: no more pkg memory\n");
  676. goto error2;
  677. }
  678. ga->avp.name.s.len = avp_name.s.len;
  679. memcpy( ga->avp.name.s.s, avp_name.s.s, avp_name.s.len);
  680. ga->avp.name.s.s[avp_name.s.len] = 0;
  681. DBG("DEBUG:add_avp_galias: registering <%s> for avp name <%s>\n",
  682. ga->alias.s, ga->avp.name.s.s);
  683. } else {
  684. ga->avp.name.n = avp_name.n;
  685. DBG("DEBUG:add_avp_galias: registering <%s> for avp id <%d>\n",
  686. ga->alias.s, ga->avp.name.n);
  687. }
  688. ga->next = galiases;
  689. galiases = ga;
  690. return 0;
  691. error2:
  692. pkg_free(ga->alias.s);
  693. error1:
  694. pkg_free(ga);
  695. error:
  696. return -1;
  697. }
  698. int lookup_avp_galias(str *alias, int *type, int_str *avp_name)
  699. {
  700. struct avp_galias *ga;
  701. for( ga=galiases ; ga ; ga=ga->next )
  702. if (alias->len==ga->alias.len &&
  703. (strncasecmp( alias->s, ga->alias.s, alias->len)==0) ) {
  704. *type = ga->avp.type;
  705. *avp_name = ga->avp.name;
  706. return 0;
  707. }
  708. return -1;
  709. }
  710. /* parsing functions */
  711. #define ERR_IF_CONTAINS(name,chr) \
  712. if (memchr(name->s,chr,name->len)) { \
  713. ERR("Unexpected control character '%c' in AVP name\n", chr); \
  714. goto error; \
  715. }
  716. int parse_avp_name( str *name, int *type, int_str *avp_name, int *index)
  717. {
  718. int ret;
  719. avp_ident_t attr;
  720. ret=parse_avp_ident(name, &attr);
  721. if (!ret) {
  722. if (type) *type = attr.flags;
  723. if (avp_name) *avp_name = attr.name;
  724. if (index) *index = attr.index;
  725. }
  726. return ret;
  727. }
  728. /** parse an avp indentifier.
  729. *
  730. * Parses the following avp indentifier forms:
  731. * - "i:<number>" - old form, deprecated (e.g. i:42)
  732. * - "s:<string>" - old form, deprecated (e.g. s:foo)
  733. * - "<track>.<name>" (e.g.: f.bar)
  734. * - "<track>.<name>[<index>]" (e.g.: f.bar[1])
  735. * - "<track><class>.<name>" (e.g: tu.bar)
  736. * - "<track><class>.<name>[<index>]" (e.g: fd.bar[2])
  737. * - "<string>" (e.g.: foo)
  738. * Where:
  739. * \<string\> = ascii string
  740. * \<id\> = ascii string w/o '[', ']', '.' and '/'
  741. * \<name\> = \<id\> | '/' regex '/'
  742. * (Note: regex use is deprecated)
  743. * \<track\> = 'f' | 't'
  744. * (from or to)
  745. * \<class\> = 'r' | 'u' | 'd' | 'g'
  746. * (uri, user, domain or global)
  747. * \<index\> = \<number\> | '-' \<number\> | ''
  748. * (the avp index, if missing it means AVP_INDEX_ALL, but
  749. * it's use is deprecated)
  750. * More examples:
  751. * "fr.bar[1]" - from track, uri class, avp "bar", the value 1.
  752. * "tu./^foo/" - to track, user class, all avps for which the name
  753. * starts with foo (note RE in avp names are deprecated).
  754. * "t.did" - to track, "did" avp
  755. *
  756. * @param name - avp identifier
  757. * @param *attr - the result will be stored here
  758. * @return 0 on success, -1 on error
  759. */
  760. int parse_avp_ident( str *name, avp_ident_t* attr)
  761. {
  762. unsigned int id;
  763. char c;
  764. char *p;
  765. str s;
  766. if (name==0 || name->s==0 || name->len==0) {
  767. ERR("NULL name or name->s or name->len\n");
  768. goto error;
  769. }
  770. attr->index = 0;
  771. DBG("Parsing '%.*s'\n", name->len, name->s);
  772. if (name->len>=2 && name->s[1]==':') { /* old fashion i: or s: */
  773. /* WARN("i: and s: avp name syntax is deprecated!\n"); */
  774. c = name->s[0];
  775. name->s += 2;
  776. name->len -= 2;
  777. if (name->len==0)
  778. goto error;
  779. switch (c) {
  780. case 's': case 'S':
  781. attr->flags = AVP_NAME_STR;
  782. attr->name.s = *name;
  783. break;
  784. case 'i': case 'I':
  785. attr->flags = 0;
  786. if (str2int( name, &id)!=0) {
  787. ERR("invalid ID "
  788. "<%.*s> - not a number\n", name->len, name->s);
  789. goto error;
  790. }
  791. attr->name.n = (int)id;
  792. break;
  793. default:
  794. ERR("unsupported type "
  795. "[%c]\n", c);
  796. goto error;
  797. }
  798. } else if ((p=memchr(name->s, '.', name->len))) {
  799. if (p-name->s==1) {
  800. id=name->s[0];
  801. name->s +=2;
  802. name->len -=2;
  803. } else if (p-name->s==2) {
  804. id=name->s[0]<<8 | name->s[1];
  805. name->s +=3;
  806. name->len -=3;
  807. } else {
  808. ERR("AVP unknown class prefix '%.*s'\n", name->len, name->s);
  809. goto error;
  810. }
  811. if (name->len==0) {
  812. ERR("AVP name not specified after the prefix separator\n");
  813. goto error;
  814. }
  815. switch (id) {
  816. case 'f':
  817. attr->flags = AVP_TRACK_FROM;
  818. break;
  819. case 't':
  820. attr->flags = AVP_TRACK_TO;
  821. break;
  822. case 0x6672: /* 'fr' */
  823. attr->flags = AVP_TRACK_FROM | AVP_CLASS_URI;
  824. break;
  825. case 0x7472: /* 'tr' */
  826. attr->flags = AVP_TRACK_TO | AVP_CLASS_URI;
  827. break;
  828. case 0x6675: /* 'fu' */
  829. attr->flags = AVP_TRACK_FROM | AVP_CLASS_USER;
  830. break;
  831. case 0x7475: /* 'tu' */
  832. attr->flags = AVP_TRACK_TO | AVP_CLASS_USER;
  833. break;
  834. case 0x6664: /* 'fd' */
  835. attr->flags = AVP_TRACK_FROM | AVP_CLASS_DOMAIN;
  836. break;
  837. case 0x7464: /* 'td' */
  838. attr->flags = AVP_TRACK_TO | AVP_CLASS_DOMAIN;
  839. break;
  840. case 'g':
  841. attr->flags = AVP_TRACK_ALL | AVP_CLASS_GLOBAL;
  842. break;
  843. default:
  844. if (id < 1<<8)
  845. ERR("AVP unknown class prefix '%c'\n", id);
  846. else
  847. ERR("AVP unknown class prefix '%c%c'\n", id>>8,id);
  848. goto error;
  849. }
  850. if (name->s[name->len-1]==']') {
  851. p=memchr(name->s, '[', name->len);
  852. if (!p) {
  853. ERR("missing '[' for AVP index\n");
  854. goto error;
  855. }
  856. s.s=p+1;
  857. s.len=name->len-(p-name->s)-2; /* [ and ] */
  858. if (s.len == 0) {
  859. attr->flags |= AVP_INDEX_ALL;
  860. } else {
  861. if (s.s[0]=='-') {
  862. attr->flags |= AVP_INDEX_BACKWARD;
  863. s.s++;s.len--;
  864. } else {
  865. attr->flags |= AVP_INDEX_FORWARD;
  866. }
  867. if ((str2int(&s, &id) != 0)||(id==0)) {
  868. ERR("Invalid AVP index '%.*s'\n", s.len, s.s);
  869. goto error;
  870. }
  871. attr->index = id;
  872. }
  873. name->len=p-name->s;
  874. }
  875. ERR_IF_CONTAINS(name,'.');
  876. ERR_IF_CONTAINS(name,'[');
  877. ERR_IF_CONTAINS(name,']');
  878. if ((name->len > 2) && (name->s[0]=='/') && (name->s[name->len-1]=='/')) {
  879. attr->name.re=pkg_malloc(sizeof(regex_t));
  880. if (!attr->name.re) {
  881. BUG("No free memory to allocate AVP_NAME_RE regex\n");
  882. goto error;
  883. }
  884. name->s[name->len-1]=0;
  885. if (regcomp(attr->name.re, name->s+1, REG_EXTENDED|REG_NOSUB|REG_ICASE)) {
  886. pkg_free(attr->name.re);
  887. attr->name.re=0;
  888. name->s[name->len-1] = '/';
  889. goto error;
  890. }
  891. name->s[name->len-1] = '/';
  892. attr->flags |= AVP_NAME_RE;
  893. } else {
  894. ERR_IF_CONTAINS(name,'/');
  895. attr->flags |= AVP_NAME_STR;
  896. attr->name.s = *name;
  897. }
  898. } else {
  899. /*default is string name*/
  900. attr->flags = AVP_NAME_STR;
  901. attr->name.s = *name;
  902. }
  903. return 0;
  904. error:
  905. return -1;
  906. }
  907. void free_avp_ident(avp_ident_t* attr)
  908. {
  909. if (attr->flags & AVP_NAME_RE) {
  910. if (! attr->name.re) {
  911. BUG("attr ident @%p has the regexp flag set, but no regexp.\n",
  912. attr);
  913. #ifdef EXTRA_DEBUG
  914. abort();
  915. #endif
  916. } else {
  917. regfree(attr->name.re);
  918. pkg_free(attr->name.re);
  919. }
  920. }
  921. }
  922. int km_parse_avp_spec( str *name, int *type, int_str *avp_name)
  923. {
  924. char *p;
  925. int index = 0;
  926. if (name==0 || name->s==0 || name->len==0)
  927. return -1;
  928. p = (char*)memchr((void*)name->s, ':', name->len);
  929. if (p==NULL) {
  930. /* might be kamailio avp alias or ser avp name style */
  931. if(lookup_avp_galias( name, type, avp_name)==0)
  932. return 0; /* found */
  933. }
  934. return parse_avp_name( name, type, avp_name, &index);
  935. }
  936. int parse_avp_spec( str *name, int *type, int_str *avp_name, int *index)
  937. {
  938. str alias;
  939. if (name==0 || name->s==0 || name->len==0)
  940. return -1;
  941. if (name->s[0]==GALIAS_CHAR_MARKER) {
  942. /* it's an avp alias */
  943. if (name->len==1) {
  944. LOG(L_ERR,"ERROR:parse_avp_spec: empty alias\n");
  945. return -1;
  946. }
  947. alias.s = name->s+1;
  948. alias.len = name->len-1;
  949. return lookup_avp_galias( &alias, type, avp_name);
  950. } else {
  951. return parse_avp_name( name, type, avp_name, index);
  952. }
  953. }
  954. void free_avp_name(avp_flags_t *type, int_str *avp_name)
  955. {
  956. if ((*type & AVP_NAME_RE) && (avp_name->re)){
  957. regfree(avp_name->re);
  958. pkg_free(avp_name->re);
  959. avp_name->re=0;
  960. }
  961. }
  962. int add_avp_galias_str(char *alias_definition)
  963. {
  964. int_str avp_name;
  965. char *s;
  966. str name;
  967. str alias;
  968. int type;
  969. int index;
  970. s = alias_definition;
  971. while(*s && isspace((int)*s))
  972. s++;
  973. while (*s) {
  974. /* parse alias name */
  975. alias.s = s;
  976. while(*s && *s!=';' && !isspace((int)*s) && *s!='=')
  977. s++;
  978. if (alias.s==s || *s==0 || *s==';')
  979. goto parse_error;
  980. alias.len = s-alias.s;
  981. while(*s && isspace((int)*s))
  982. s++;
  983. /* equal sign */
  984. if (*s!='=')
  985. goto parse_error;
  986. s++;
  987. while(*s && isspace((int)*s))
  988. s++;
  989. /* avp name */
  990. name.s = s;
  991. while(*s && *s!=';' && !isspace((int)*s))
  992. s++;
  993. if (name.s==s)
  994. goto parse_error;
  995. name.len = s-name.s;
  996. while(*s && isspace((int)*s))
  997. s++;
  998. /* check end */
  999. if (*s!=0 && *s!=';')
  1000. goto parse_error;
  1001. if (*s==';') {
  1002. for( s++ ; *s && isspace((int)*s) ; s++ );
  1003. if (*s==0)
  1004. goto parse_error;
  1005. }
  1006. if (parse_avp_name( &name, &type, &avp_name, &index)!=0) {
  1007. LOG(L_ERR, "ERROR:add_avp_galias_str: <%.*s> not a valid AVP "
  1008. "name\n", name.len, name.s);
  1009. goto error;
  1010. }
  1011. if (add_avp_galias( &alias, type, avp_name)!=0) {
  1012. LOG(L_ERR, "ERROR:add_avp_galias_str: add global alias failed\n");
  1013. goto error;
  1014. }
  1015. } /*end while*/
  1016. return 0;
  1017. parse_error:
  1018. LOG(L_ERR, "ERROR:add_avp_galias_str: parse error in <%s> around "
  1019. "pos %ld\n", alias_definition, (long)(s-alias_definition));
  1020. error:
  1021. return -1;
  1022. }
  1023. int destroy_avps(avp_flags_t flags, avp_name_t name, int all)
  1024. {
  1025. struct search_state st;
  1026. avp_t* avp;
  1027. int n;
  1028. n = 0;
  1029. avp = search_first_avp(flags, name, 0, &st);
  1030. while (avp) {
  1031. destroy_avp(avp);
  1032. n++;
  1033. if (!all) break;
  1034. avp = search_next_avp(&st, 0);
  1035. }
  1036. return n;
  1037. }
  1038. void delete_avp(avp_flags_t flags, avp_name_t name)
  1039. {
  1040. struct search_state st;
  1041. avp_t* avp;
  1042. avp = search_first_avp(flags, name, 0, &st);
  1043. while(avp) {
  1044. destroy_avp(avp);
  1045. avp = search_next_avp(&st, 0);
  1046. }
  1047. }
  1048. /* AVP flags functions */
  1049. /* name2id conversion is intended to use during fixup (cfg parsing and modinit) only therefore no hash is used */
  1050. avp_flags_t register_avpflag(char* name) {
  1051. avp_flags_t ret;
  1052. ret = get_avpflag_no(name);
  1053. if (ret == 0) {
  1054. if (registered_avpflags_no >= MAX_AVPFLAG) {
  1055. LOG(L_ERR, "register_avpflag: cannot register new avp flag ('%s'), max.number of flags (%d) reached\n", name, MAX_AVPFLAG);
  1056. return -1;
  1057. }
  1058. ret = 1<<(AVP_CUSTOM_FLAGS+registered_avpflags_no);
  1059. registered_avpflags[registered_avpflags_no++] = name;
  1060. }
  1061. return ret;
  1062. }
  1063. avp_flags_t get_avpflag_no(char* name) {
  1064. int i;
  1065. for (i=0; i<registered_avpflags_no; i++) {
  1066. if (strcasecmp(name, registered_avpflags[i])==0)
  1067. return 1<<(AVP_CUSTOM_FLAGS+i);
  1068. }
  1069. return 0;
  1070. }