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  */
init_avps(void)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  */
select_list(avp_flags_t flags)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 
compute_ID(str * name)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 
create_avp(avp_flags_t flags,avp_name_t name,avp_value_t val)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 == NULL || 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 
add_avp_list(avp_list_t * list,avp_flags_t flags,avp_name_t name,avp_value_t val)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 
add_avp(avp_flags_t flags,avp_name_t name,avp_value_t val)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 
add_avp_before(avp_t * avp,avp_flags_t flags,avp_name_t name,avp_value_t val)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 */
get_avp_name(avp_t * avp)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 
get_avp_val(avp_t * avp,avp_value_t * val)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 */
get_avp_list(avp_flags_t flags)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  */
match_by_id(avp_t * avp,avp_id_t id)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  */
match_by_name(avp_t * avp,avp_id_t id,str * name)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  */
match_by_re(avp_t * avp,regex_t * re)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 
search_first_avp(avp_flags_t flags,avp_name_t name,avp_value_t * val,struct search_state * s)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 
search_avp(avp_ident_t ident,avp_value_t * val,struct search_state * state)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 
search_next_avp(struct search_state * s,avp_value_t * val)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 
search_reverse(avp_t * cur,struct search_state * st,avp_index_t index,avp_list_t * ret)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 
search_avp_by_index(avp_flags_t flags,avp_name_t name,avp_value_t * val,avp_index_t index)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 
destroy_avp(avp_t * avp_del)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 
destroy_avp_list_unsafe(avp_list_t * list)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 
destroy_avp_list(avp_list_t * list)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 
reset_avp_list(int flags)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 
reset_avps(void)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 
set_avp_list(avp_flags_t flags,avp_list_t * list)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 
check_avp_galias(str * alias,int type,int_str avp_name)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 
add_avp_galias(str * alias,int type,int_str avp_name)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 
lookup_avp_galias(str * alias,int * type,int_str * avp_name)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 
parse_avp_name(str * name,int * type,int_str * avp_name,int * index)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  */
parse_avp_ident(str * name,avp_ident_t * attr)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 
free_avp_ident(avp_ident_t * attr)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 
km_parse_avp_spec(str * name,int * type,int_str * avp_name)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 
parse_avp_spec(str * name,int * type,int_str * avp_name,int * index)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 
free_avp_name(avp_flags_t * type,int_str * avp_name)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 
add_avp_galias_str(char * alias_definition)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 
destroy_avps(avp_flags_t flags,avp_name_t name,int all)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 
delete_avp(avp_flags_t flags,avp_name_t name)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 */
register_avpflag(char * name)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 
get_avpflag_no(char * name)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 }
1211