usr_avp.c 26 KB

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