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