Browse code

- avp aliases support: any module can register and avp_galias (global alias) which will be visible for all other modules. Aliases should be exported as soon as possible, in modparam (by using function callbacks for processing the params) so that other modules will see them both in mod_init and fixup functions. In config scripts all aliases should start with "$".

- avp aliases common parsing functions (parse definitions of AVP aliases &
names)

Andrei Pelinescu-Onciul authored on 15/11/2004 16:46:14
Showing 3 changed files
... ...
@@ -1,13 +1,12 @@
1 1
 $Id$
2 2
 
3 3
 ( - todo, x - done)
4
-- apply & modify Maxim's server_name patch
5
-- change subst_run/str to return error (different from not found)
6
-- change subst_user as on serdev
7
-- tm : fake_env: fake also bind_address (else the default will be used
4
+x change subst_run/str to return error (different from not found)
5
+x change subst_user as on serdev
6
+x tm : fake_env: fake also bind_address (else the default will be used
8 7
  in the failure route)
9 8
 - [core] parse_uri support for new uri params
10
-- [core] on sig_child, kill the processes if they don't exit in a 
9
+x [core] on sig_child, kill the processes if they don't exit in a 
11 10
   reasonable time
12 11
 - [doc] document force_rport()
13 12
 - [fifo] fix fgets error handling (it does not set errno always,
... ...
@@ -17,9 +16,9 @@ $Id$
17 17
 - [mem] qm_compact_frags (compacts frags if possible), keep a 
18 18
         fragment count/bucket and if too much mem. is blocked in one bucket
19 19
         de-frag.
20
-- [mem] investigate: don't produce frag if frag size < request
20
+x [mem] investigate: don't produce frag if frag size < request
21 21
       (should reduce the unrequested fragments number)
22
-- [mem] investigate: keep an used/unused flag per fragment, on free
22
+x [mem] investigate: keep an used/unused flag per fragment, on free
23 23
       check if neighboring frags were not used and if so defragment
24 24
 - [timer] multiple timers? at least ticks should no be affected by the amount
25 25
    of work done in the timer handlers
... ...
@@ -67,7 +66,7 @@ x extend listen and alias to include port numbers and protocol:
67 67
        tcp foo.bar:5063, udp foo.bar:5062, foo2.bar
68 68
 x added set_advertised_{address,port} -- was: add force_via, force_srcip a.s.o
69 69
 (the advertised addresses should be overwritable from the script).
70
-- ? add force_outbound_socket(ip)? (choose an apropriate socket from the
70
+x ? add force_outbound_socket(ip)? (choose an apropriate socket from the
71 71
  listen list for sending the msg; works on udp only)
72 72
 
73 73
 release:
... ...
@@ -144,7 +143,7 @@ x fix via address someday
144 144
 x forward to received= if present
145 145
 - make it easier to register a statically linkable module.
146 146
 x add support for -u user and -g group (not only -u uid, -g uid)
147
-- change uid/gid after opening the sockets
147
+x change uid/gid after opening the sockets
148 148
 - exec improvments (add format strings to it)
149 149
 x command line switch for checking the config file syntax
150 150
 - config file version (a la sendmail)
... ...
@@ -27,18 +27,23 @@
27 27
  * History:
28 28
  * ---------
29 29
  *  2004-07-21  created (bogdan)
30
- *  2004-10-09  interface more flexibil - more function available (bogdan)
30
+ *  2004-10-09  interface more flexible - more function available (bogdan)
31 31
  *  2004-11-07  AVP string values are kept 0 terminated (bogdan)
32
+ *  2004-11-14  global aliases support added
32 33
  */
33 34
 
34 35
 
35 36
 #include <assert.h>
37
+#include <ctype.h>
38
+#include <string.h>
39
+#include <stdlib.h>
36 40
 
37 41
 #include "sr_module.h"
38 42
 #include "dprint.h"
39 43
 #include "str.h"
40 44
 #include "ut.h"
41 45
 #include "mem/shm_mem.h"
46
+#include "mem/mem.h"
42 47
 #include "usr_avp.h"
43 48
 
44 49
 
... ...
@@ -53,7 +58,13 @@ struct str_str_data {
53 53
 	str  val;
54 54
 };
55 55
 
56
+struct avp_galias {
57
+	str alias;
58
+	struct avp_spec  avp;
59
+	struct avp_galias *next;
60
+};
56 61
 
62
+static struct avp_galias *galiases = 0;
57 63
 static struct usr_avp *global_avps = 0;
58 64
 static struct usr_avp **crt_avps  = &global_avps;
59 65
 
... ...
@@ -318,7 +329,7 @@ inline void destroy_avp_list( struct usr_avp **list )
318 318
 {
319 319
 	struct usr_avp *avp, *foo;
320 320
 
321
-	DBG("DEBUG:destroy_avp_list: destroying list %p\n",*list);
321
+	DBG("DEBUG:destroy_avp_list: destroying list %p\n", *list);
322 322
 	avp = *list;
323 323
 	while( avp ) {
324 324
 		foo = avp;
... ...
@@ -340,7 +351,6 @@ void reset_avps( )
340 340
 }
341 341
 
342 342
 
343
-
344 343
 struct usr_avp** set_avp_list( struct usr_avp **list )
345 344
 {
346 345
 	struct usr_avp **foo;
... ...
@@ -352,3 +362,222 @@ struct usr_avp** set_avp_list( struct usr_avp **list )
352 352
 	return foo;
353 353
 }
354 354
 
355
+
356
+
357
+
358
+/********* global aliases functions ********/
359
+
360
+static inline int check_avp_galias(str *alias, int type, int_str avp_name)
361
+{
362
+	struct avp_galias *ga;
363
+
364
+	type &= AVP_NAME_STR;
365
+
366
+	for( ga=galiases ; ga ; ga=ga->next ) {
367
+		/* check for duplicated alias names */
368
+		if ( alias->len==ga->alias.len &&
369
+		(strncasecmp( alias->s, ga->alias.s, alias->len)==0) )
370
+			return -1;
371
+		/*check for duplicated avp names */
372
+		if (type==ga->avp.type) {
373
+			if (type&AVP_NAME_STR){
374
+				if (avp_name.s->len==ga->avp.name.s->len &&
375
+				(strncasecmp(avp_name.s->s, ga->avp.name.s->s,
376
+							 					avp_name.s->len)==0) )
377
+					return -1;
378
+			} else {
379
+				if (avp_name.n==ga->avp.name.n)
380
+					return -1;
381
+			}
382
+		}
383
+	}
384
+	return 0;
385
+}
386
+
387
+
388
+int add_avp_galias(str *alias, int type, int_str avp_name)
389
+{
390
+	struct avp_galias *ga;
391
+
392
+	if ((type&AVP_NAME_STR && (!avp_name.s || !avp_name.s->s ||
393
+								!avp_name.s->len)) ||!alias || !alias->s ||
394
+		!alias->len ){
395
+		LOG(L_ERR, "ERROR:add_avp_galias: null params received\n");
396
+		goto error;
397
+	}
398
+
399
+	if (check_avp_galias(alias,type,avp_name)!=0) {
400
+		LOG(L_ERR, "ERROR:add_avp_galias: duplicate alias/avp entry\n");
401
+		goto error;
402
+	}
403
+
404
+	ga = (struct avp_galias*)pkg_malloc( sizeof(struct avp_galias) );
405
+	if (ga==0) {
406
+		LOG(L_ERR, "ERROR:add_avp_galias: no more pkg memory\n");
407
+		goto error;
408
+	}
409
+
410
+	ga->alias.s = (char*)pkg_malloc( alias->len+1 );
411
+	if (ga->alias.s==0) {
412
+		LOG(L_ERR, "ERROR:add_avp_galias: no more pkg memory\n");
413
+		goto error1;
414
+	}
415
+	memcpy( ga->alias.s, alias->s, alias->len);
416
+	ga->alias.len = alias->len;
417
+
418
+	ga->avp.type = type&AVP_NAME_STR;
419
+
420
+	if (type&AVP_NAME_STR) {
421
+		ga->avp.name.s = (str*)pkg_malloc( sizeof(str)+avp_name.s->len+1 );
422
+		if (ga->avp.name.s==0) {
423
+			LOG(L_ERR, "ERROR:add_avp_galias: no more pkg memory\n");
424
+			goto error2;
425
+		}
426
+		ga->avp.name.s->s = ((char*)ga->avp.name.s)+sizeof(str);
427
+		ga->avp.name.s->len = avp_name.s->len;
428
+		memcpy( ga->avp.name.s->s, avp_name.s->s, avp_name.s->len);
429
+		ga->avp.name.s->s[avp_name.s->len] = 0;
430
+		DBG("DEBUG:add_avp_galias: registering <%s> for avp name <%s>\n",
431
+			ga->alias.s, ga->avp.name.s->s);
432
+	} else {
433
+		ga->avp.name.n = avp_name.n;
434
+		DBG("DEBUG:add_avp_galias: registering <%s> for avp id <%d>\n",
435
+			ga->alias.s, ga->avp.name.n);
436
+	}
437
+
438
+	ga->next = galiases;
439
+	galiases = ga;
440
+
441
+	return 0;
442
+error2:
443
+	pkg_free(ga->alias.s);
444
+error1:
445
+	pkg_free(ga);
446
+error:
447
+	return -1;
448
+}
449
+
450
+
451
+struct avp_spec *lookup_avp_galias(char *alias, int len)
452
+{
453
+	struct avp_galias *ga;
454
+
455
+	for( ga=galiases ; ga ; ga=ga->next )
456
+		if (len==ga->alias.len && (strncasecmp( alias, ga->alias.s, len)==0) )
457
+			return &ga->avp;
458
+
459
+	return 0;
460
+}
461
+
462
+
463
+/* parsing functions */
464
+
465
+int parse_avp_name( str *name, int *type, int_str *avp_name)
466
+{
467
+	unsigned int id;
468
+	char c;
469
+
470
+	if (name->len>=2 && name->s[1]==':') {
471
+		c = name->s[0];
472
+		name->s += 2;
473
+		name->len -= 2;
474
+		if (name->len==0)
475
+			goto error;
476
+		switch (c) {
477
+			case 's': case 'S':
478
+				*type = AVP_NAME_STR;
479
+				avp_name->s = name;
480
+				break;
481
+			case 'i': case 'I':
482
+				*type = 0;
483
+				if (str2int( name, &id)!=0) {
484
+					LOG(L_ERR, "ERROR:parse_avp_name: invalid ID "
485
+						"<%.*s> - not a number\n", name->len, name->s);
486
+					goto error;
487
+				}
488
+				avp_name->n = (int)id;
489
+				break;
490
+			default:
491
+				LOG(L_ERR, "ERROR:parse_avp_name: unsupported type "
492
+					"[%c]\n", c);
493
+				goto error;
494
+		}
495
+	} else {
496
+		/*default is string name*/
497
+		*type = AVP_NAME_STR;
498
+		avp_name->s = name;
499
+	}
500
+
501
+	return 0;
502
+error:
503
+	return -1;
504
+}
505
+
506
+
507
+int add_avp_galias_str(char *alias_definition)
508
+{
509
+	int_str avp_name;
510
+	char *s;
511
+	str  name;
512
+	str  alias;
513
+	int  type;
514
+
515
+	s = alias_definition;
516
+	while(*s && isspace((int)*s))
517
+		s++;
518
+
519
+	while (*s) {
520
+		/* parse alias name */
521
+		alias.s = s;
522
+		while(*s && *s!=';' && !isspace((int)*s) && *s!='=')
523
+			s++;
524
+		if (alias.s==s || *s==0 || *s==';')
525
+			goto parse_error;
526
+		alias.len = s-alias.s;
527
+		while(*s && isspace((int)*s))
528
+			s++;
529
+		/* equal sign */
530
+		if (*s!='=')
531
+			goto parse_error;
532
+		s++;
533
+		while(*s && isspace((int)*s))
534
+			s++;
535
+		/* avp name */
536
+		name.s = s;
537
+		while(*s && *s!=';' && !isspace((int)*s))
538
+			s++;
539
+		if (name.s==s)
540
+			goto parse_error;
541
+		name.len = s-name.s;
542
+		while(*s && isspace((int)*s))
543
+			s++;
544
+		/* check end */
545
+		if (*s!=0 && *s!=';')
546
+			goto parse_error;
547
+		if (*s==';') {
548
+			for( s++ ; *s && isspace((int)*s) ; s++ );
549
+			if (*s==0)
550
+				goto parse_error;
551
+		}
552
+
553
+		if (parse_avp_name( &name, &type, &avp_name)!=0) {
554
+			LOG(L_ERR, "ERROR:add_avp_galias_str: <%.*s> not a valid AVP "
555
+				"name\n", name.len, name.s);
556
+			goto error;
557
+		}
558
+
559
+		if (add_avp_galias( &alias, type, avp_name)!=0) {
560
+			LOG(L_ERR, "ERROR:add_avp_galias_str: add global alias failed\n");
561
+			goto error;
562
+		}
563
+	} /*end while*/
564
+
565
+	return 0;
566
+parse_error:
567
+	LOG(L_ERR, "ERROR:add_avp_galias_str: parse error in <%s> around "
568
+		"pos %ld\n", alias_definition, (long)(s-alias_definition));
569
+error:
570
+	return -1;
571
+}
572
+
573
+
... ...
@@ -27,6 +27,7 @@
27 27
  * History:
28 28
  * ---------
29 29
  *  2004-07-21  created (bogdan)
30
+ *  2004-11-14  global aliases support added
30 31
  */
31 32
 
32 33
 #ifndef _SER_URS_AVP_H_
... ...
@@ -41,7 +42,6 @@ typedef union {
41 41
 } int_str;
42 42
 
43 43
 
44
-
45 44
 struct usr_avp {
46 45
 	unsigned short id;
47 46
 	unsigned short flags;
... ...
@@ -49,6 +49,13 @@ struct usr_avp {
49 49
 	void *data;
50 50
 };
51 51
 
52
+
53
+struct avp_spec {
54
+	int type;
55
+	int_str name;
56
+};
57
+
58
+
52 59
 #define AVP_NAME_STR     (1<<0)
53 60
 #define AVP_VAL_STR      (1<<1)
54 61
 
... ...
@@ -74,6 +81,11 @@ str* get_avp_name(struct usr_avp *avp);
74 74
 struct usr_avp** set_avp_list( struct usr_avp **list );
75 75
 struct usr_avp** get_avp_list( );
76 76
 
77
+/* global alias functions (manipulation and parsing)*/
78
+int add_avp_galias_str(char *alias_definition);
79
+struct avp_spec *lookup_avp_galias(char *alias, int len);
80
+int add_avp_galias(str *alias, int type, int_str avp_name);
81
+int parse_avp_name( str *name, int *type, int_str *avp_name);
77 82
 
78 83
 #endif
79 84