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