usr_avp.c 27 KB

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