usr_avp.c 28 KB

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