Browse code

- avp core replaced with .14 version - avp DB support removed from core (later to be added as separate module) - tm support for avps (avp list saved into transactions and made available into tm callbacks, in failure and reply routes).

Bogdan-Andrei Iancu authored on 23/08/2004 20:47:51
Showing 13 changed files
... ...
@@ -36,7 +36,6 @@
36 36
  *  2003-04-22  strip_tail added (jiri)
37 37
  *  2003-10-02  added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei)
38 38
  *  2003-10-29  added FORCE_TCP_ALIAS_T (andrei)
39
- *  2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
40 39
  */
41 40
 
42 41
 
... ...
@@ -57,7 +56,6 @@
57 57
 #include "mem/mem.h"
58 58
 #include "globals.h"
59 59
 #include "dset.h"
60
-#include "usr_avp.h"
61 60
 #ifdef USE_TCP
62 61
 #include "tcp_server.h"
63 62
 #endif
... ...
@@ -90,7 +88,6 @@ int do_action(struct action* a, struct sip_msg* msg)
90 90
 	int len;
91 91
 	int user;
92 92
 	struct sip_uri uri, next_hop;
93
-	struct usr_avp *avp;
94 93
 	struct sip_uri *u;
95 94
 	unsigned short port;
96 95
 	int proto;
... ...
@@ -661,58 +658,6 @@ int do_action(struct action* a, struct sip_msg* msg)
661 661
 #endif
662 662
 			ret=1; /* continue processing */
663 663
 			break;
664
-		case LOAD_AVP_T:
665
-			if (a->p1_type!=NUMBER_ST || a->p2_type!=STRING_ST ||
666
-			a->p3_type!=NUMBER_ST) {
667
-				LOG(L_CRIT,"BUG: do_action: bad load_avp(%d,%d,%d) params "
668
-						"types\n",a->p1_type,a->p2_type,a->p3_type);
669
-				ret=E_BUG;
670
-				break;
671
-			}
672
-			/* load the attribute(s)*/
673
-			if ( (ret=load_avp( msg, (int)a->p1.number, a->p2.string,
674
-			(int)a->p3.number))==-1 ) {
675
-				LOG(L_ERR,"ERROR:do_action: load avp failed\n");
676
-				ret=E_UNSPEC;
677
-				break;
678
-			}
679
-			ret = (ret==0)?1/*success*/:E_UNSPEC/*notfound*/;
680
-			break;
681
-		case AVP_TO_URI_T:
682
-			if (a->p1_type!=STR_ST ) {
683
-				LOG(L_CRIT,"BUG: do_action: bad avp_to_uri(%d) params "
684
-						"types\n",a->p1_type);
685
-				ret=E_BUG;
686
-				break;
687
-			}
688
-			/* look for the attribute */
689
-			if ( (avp=search_avp( (str*)a->p1.string ))==0) {
690
-				ret=E_UNSPEC;
691
-				break;
692
-			}
693
-			if (avp->val_type!=AVP_TYPE_STR) {
694
-				LOG(L_ERR,"ERROR:do_action: in avp_to_uri attribute <%s> "
695
-					"doesn't has a STR value\n",((str*)a->p1.string)->s);
696
-				ret=E_UNSPEC;
697
-				break;
698
-			}
699
-			/* replace the ruri */
700
-			new_uri = (char*)pkg_malloc( avp->val.str_val.len+1 );
701
-			if (new_uri==0) {
702
-				LOG(L_ERR,"ERROR:tm:t_attr_to_uri: no more pkg memory\n");
703
-				ret = E_OUT_OF_MEM;
704
-				break;
705
-			}
706
-			memcpy( new_uri, avp->val.str_val.s, avp->val.str_val.len);
707
-			new_uri[avp->val.str_val.len] = 0;
708
-			if (msg->new_uri.s)
709
-				pkg_free( msg->new_uri.s );
710
-			msg->new_uri.s = new_uri;
711
-			msg->new_uri.len = avp->val.str_val.len;
712
-			msg->parsed_uri_ok=0;
713
-
714
-			ret = 1;
715
-			break;
716 664
 		default:
717 665
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
718 666
 	}
... ...
@@ -44,7 +44,6 @@
44 44
  *  2003-10-13  added fifo_dir (andrei)
45 45
  *  2003-10-28  added tcp_accept_aliases (andrei)
46 46
  *  2003-11-29  added {tcp_send, tcp_connect, tls_*}_timeout (andrei)
47
- *  2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
48 47
  *  2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
49 48
  *  2004-04-28  added sock_mode (replaces fifo_mode), sock_user &
50 49
  *               sock_group  (andrei)
... ...
@@ -120,8 +119,6 @@ IF				"if"
120 120
 ELSE			"else"
121 121
 SET_ADV_ADDRESS	"set_advertised_address"
122 122
 SET_ADV_PORT	"set_advertised_port"
123
-LOAD_AVP		"load_avp"
124
-AVP_TO_URI		"avp_to_uri"
125 123
 
126 124
 /*ACTION LVALUES*/
127 125
 URIHOST			"uri:host"
... ...
@@ -184,7 +181,6 @@ FIFO_DB_URL fifo_db_url
184 184
 UNIX_SOCK unix_sock
185 185
 UNIX_SOCK_CHILDREN unix_sock_children
186 186
 UNIX_TX_TIMEOUT unix_tx_timeout
187
-AVP_DB_URL  avp_db_url
188 187
 SERVER_SIGNATURE server_signature
189 188
 REPLY_TO_VIA reply_to_via
190 189
 USER		"user"|"uid"
... ...
@@ -304,9 +300,6 @@ EAT_ABLE	[\ \t\b\r]
304 304
 <INITIAL>{FORCE_RPORT}	{ count(); yylval.strval=yytext; return FORCE_RPORT; }
305 305
 <INITIAL>{FORCE_TCP_ALIAS}	{ count(); yylval.strval=yytext;
306 306
 								return FORCE_TCP_ALIAS; }
307
-<INITIAL>{LOAD_AVP}	{ count(); yylval.strval=yytext; return LOAD_AVP; }
308
-<INITIAL>{AVP_TO_URI}	{ count(); yylval.strval=yytext; return AVP_TO_URI; }
309
-	
310 307
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
311 308
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
312 309
 
... ...
@@ -385,7 +378,6 @@ EAT_ABLE	[\ \t\b\r]
385 385
 <INITIAL>{UNIX_SOCK} { count(); yylval.strval=yytext; return UNIX_SOCK; }
386 386
 <INITIAL>{UNIX_SOCK_CHILDREN} { count(); yylval.strval=yytext; return UNIX_SOCK_CHILDREN; }
387 387
 <INITIAL>{UNIX_TX_TIMEOUT} { count(); yylval.strval=yytext; return UNIX_TX_TIMEOUT; }
388
-<INITIAL>{AVP_DB_URL}	{ count(); yylval.strval=yytext; return AVP_DB_URL; }
389 388
 <INITIAL>{SERVER_SIGNATURE}	{ count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
390 389
 <INITIAL>{REPLY_TO_VIA}	{ count(); yylval.strval=yytext; return REPLY_TO_VIA; }
391 390
 <INITIAL>{ADVERTISED_ADDRESS}	{	count(); yylval.strval=yytext;
... ...
@@ -50,7 +50,6 @@
50 50
  * 2003-10-24  converted to the new socket_info lists (andrei)
51 51
  * 2003-10-28  added tcp_accept_aliases (andrei)
52 52
  * 2003-11-20  added {tcp_connect, tcp_send, tls_*}_timeout (andrei)
53
- * 2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
54 53
  * 2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
55 54
  * 2004-04-29  added SOCK_MODE, SOCK_USER & SOCK_GROUP (andrei)
56 55
  * 2004-05-03  applied multicast support patch (MCAST_LOOPBACK) from janakj
... ...
@@ -80,7 +79,6 @@
80 80
 #include "resolve.h"
81 81
 #include "socket_info.h"
82 82
 #include "name_alias.h"
83
-#include "usr_avp.h"
84 83
 #include "ut.h"
85 84
 #include "dset.h"
86 85
 
... ...
@@ -186,8 +184,6 @@ static struct id_list* mk_listen_id(char*, int, int);
186 186
 %token UDP
187 187
 %token TCP
188 188
 %token TLS
189
-%token LOAD_AVP
190
-%token AVP_TO_URI
191 189
 
192 190
 /* config vars. */
193 191
 %token DEBUG
... ...
@@ -214,7 +210,6 @@ static struct id_list* mk_listen_id(char*, int, int);
214 214
 %token UNIX_SOCK
215 215
 %token UNIX_SOCK_CHILDREN
216 216
 %token UNIX_TX_TIMEOUT
217
-%token AVP_DB_URL
218 217
 %token SERVER_SIGNATURE
219 218
 %token REPLY_TO_VIA
220 219
 %token LOADMODULE
... ...
@@ -438,8 +433,6 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
438 438
 		| UNIX_SOCK_CHILDREN EQUAL error { yyerror("int value expected\n"); }
439 439
 		| UNIX_TX_TIMEOUT EQUAL NUMBER { unixsock_tx_timeout=$3; }
440 440
 		| UNIX_TX_TIMEOUT EQUAL error { yyerror("int value expected\n"); }
441
-		| AVP_DB_URL EQUAL STRING { avp_db_url=$3; }
442
-		| AVP_DB_URL EQUAL error  { yyerror("string value expected"); }
443 441
 		| USER EQUAL STRING     { user=$3; }
444 442
 		| USER EQUAL ID         { user=$3; }
445 443
 		| USER EQUAL error      { yyerror("string value expected"); }
... ...
@@ -1561,40 +1554,6 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
1561 1561
 		| FORCE_TCP_ALIAS LPAREN error RPAREN	{$$=0; 
1562 1562
 					yyerror("bad argument, number expected");
1563 1563
 					}
1564
-		| LOAD_AVP LPAREN STRING COMMA NUMBER RPAREN {
1565
-					$$=(void*)get_user_type( $3 );
1566
-					if ($$==(void*)-1) {
1567
-						yyerror("unknown user type in arg 1 for "
1568
-							"load_avp(x,x)");
1569
-					} else {
1570
-						$$=mk_action3( LOAD_AVP_T, NUMBER_ST, STRING_ST,
1571
-							NUMBER_ST, $$, 0,(void*)$5);
1572
-					}
1573
-					}
1574
-		| LOAD_AVP LPAREN STRING COMMA STRING COMMA NUMBER RPAREN {
1575
-					$$=(void*)get_user_type( $3 );
1576
-					if ($$==(void*)-1) {
1577
-						yyerror("unknown user type in arg 1 for "
1578
-							"load_avp(x,x,x)");
1579
-					} else {
1580
-						$$=mk_action3( LOAD_AVP_T, NUMBER_ST, STRING_ST,
1581
-							NUMBER_ST, $$, $5, (void*)$7);
1582
-					}
1583
-					}
1584
-		| LOAD_AVP error { $$=0; yyerror("missing '(' or ')' ?"); }
1585
-		| AVP_TO_URI LPAREN STRING RPAREN {
1586
-								$$=0;
1587
-								if ((str_tmp=pkg_malloc(sizeof(str)))==0){
1588
-										LOG(L_CRIT, "ERROR: cfg. parser:"
1589
-													" out of memory.\n");
1590
-								}else{
1591
-										str_tmp->s=$3;
1592
-										str_tmp->len=strlen($3);
1593
-										$$=mk_action(AVP_TO_URI_T, STR_ST,
1594
-											0, str_tmp, 0);
1595
-								}
1596
-										}
1597
-		| AVP_TO_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
1598 1564
 		| SET_ADV_ADDRESS LPAREN listen_id RPAREN {
1599 1565
 								$$=0;
1600 1566
 								if ((str_tmp=pkg_malloc(sizeof(str)))==0){
... ...
@@ -45,7 +45,6 @@
45 45
  *  2003-06-29  replaced port_no_str snprintf w/ int2str (andrei)
46 46
  *  2003-10-10  added switch for config check (-c) (andrei)
47 47
  *  2003-10-24  converted to the new socket_info lists (andrei)
48
- *  2004-02-06  added support for user pref. - init_avp_child() (bogdan)
49 48
  *  2004-03-30  core dump is enabled by default
50 49
  *              added support for increasing the open files limit    (andrei)
51 50
  *  2004-04-28  sock_{user,group,uid,gid,mode} added
... ...
@@ -100,7 +99,6 @@
100 100
 #include "parser/digest/digest_parser.h"
101 101
 #include "fifo_server.h"
102 102
 #include "unixsock_server.h"
103
-#include "usr_avp.h"
104 103
 #include "name_alias.h"
105 104
 #include "hash_func.h"
106 105
 #include "pt.h"
... ...
@@ -826,10 +824,6 @@ int main_loop()
826 826
 			LOG(L_ERR, "main_dontfork: init_child failed\n");
827 827
 			goto error;
828 828
 		}
829
-		if (init_avp_child(1)<0) {
830
-			LOG(L_ERR, "init_avp_child failed\n");
831
-			goto error;
832
-		}
833 829
 
834 830
 		is_main=1; /* hack 42: call init_child with is_main=0 in case
835 831
 					 some modules wants to fork a child */
... ...
@@ -944,10 +938,6 @@ int main_loop()
944 944
 					}
945 945
 #endif
946 946
 					bind_address=si; /* shortcut */
947
-					if (init_avp_child(i + 1)<0) {
948
-						LOG(L_ERR, "init_avp_child failed\n");
949
-						goto error;
950
-					}
951 947
 					if (init_child(i + 1) < 0) {
952 948
 						LOG(L_ERR, "init_child failed\n");
953 949
 						goto error;
... ...
@@ -39,6 +39,8 @@
39 39
  * 2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
40 40
  * 2004-02-13  t->is_invite and t->local replaced with flags;
41 41
  *             timer_link.payload removed (bogdan)
42
+ * 2004-08-23  avp support added - move and remove avp list to/from
43
+ *             transactions (bogdan)
42 44
  */
43 45
 
44 46
 #include <stdlib.h>
... ...
@@ -157,6 +159,10 @@ void free_cell( struct cell* dead_cell )
157 157
 		tt=foo;
158 158
 	}
159 159
 
160
+	/* free the avp list */
161
+	if (dead_cell->user_avps)
162
+		destroy_avp_list_unsafe( &dead_cell->user_avps );
163
+
160 164
 	/* the cell's body */
161 165
 	shm_free_unsafe( dead_cell );
162 166
 
... ...
@@ -219,6 +225,7 @@ struct cell*  build_cell( struct sip_msg* p_msg )
219 219
 {
220 220
 	struct cell* new_cell;
221 221
 	int          sip_msg_len;
222
+	struct usr_avp **old;
222 223
 
223 224
 	/* allocs a new cell */
224 225
 	new_cell = (struct cell*)shm_malloc( sizeof( struct cell ) );
... ...
@@ -237,6 +244,11 @@ struct cell*  build_cell( struct sip_msg* p_msg )
237 237
 #endif
238 238
 	new_cell->uas.response.my_T=new_cell;
239 239
 
240
+	/* move the current avp list to transaction -bogdan */
241
+	old = set_avp_list( &new_cell->user_avps );
242
+	new_cell->user_avps = *old;
243
+	*old = 0;
244
+
240 245
 	/* enter callback, which may potentially want to parse some stuff,
241 246
 	 * before the request is shmem-ized */
242 247
 	if ( p_msg && has_reqin_tmcbs() )
... ...
@@ -265,6 +277,8 @@ struct cell*  build_cell( struct sip_msg* p_msg )
265 265
 
266 266
 error:
267 267
 	shm_free(new_cell);
268
+	/* unlink transaction AVP list and link back the global AVP list (bogdan)*/
269
+	reset_avps();
268 270
 	return NULL;
269 271
 }
270 272
 
... ...
@@ -32,8 +32,9 @@
32 32
  * 2003-12-04  callbacks per transaction added; completion callback
33 33
  *             merge into them as LOCAL_COMPETED (bogdan)
34 34
  * 2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
35
- * 2004-02-13: t->is_invite, t->local, t->noisy_ctimer replaced
35
+ * 2004-02-13  t->is_invite, t->local, t->noisy_ctimer replaced
36 36
  *             with flags (bogdan)
37
+ * 2004-08-23  avp support added - avp list linked in transaction (bogdan)
37 38
  */
38 39
 
39 40
 #include "defs.h"
... ...
@@ -48,6 +49,7 @@
48 48
 #include "../../parser/msg_parser.h"
49 49
 #include "../../types.h"
50 50
 #include "../../md5utils.h"
51
+#include "../../usr_avp.h"
51 52
 #include "config.h"
52 53
 
53 54
 struct s_table;
... ...
@@ -249,6 +251,9 @@ typedef struct cell
249 249
 	 * forwarded or passed to UAC; note that there can be arbitrarily 
250 250
 	 * many due to downstream forking; */
251 251
 	struct totag_elem *fwded_totags;
252
+
253
+	/* list with user avp */
254
+	struct usr_avp *user_avps;
252 255
 }cell_type;
253 256
 
254 257
 
... ...
@@ -184,6 +184,7 @@ error:
184 184
 }
185 185
 
186 186
 
187
+#define EMAIL_AVP_ID  0xcaca
187 188
 static int assemble_msg(struct sip_msg* msg, char* action)
188 189
 {
189 190
 	static char     id_buf[IDBUF_LEN];
... ...
@@ -191,7 +192,7 @@ static int assemble_msg(struct sip_msg* msg, char* action)
191 191
 	static char     hdrs_buf[HDRS_BUFFER_MAX];
192 192
 	static char     cmd_buf[CMD_BUFFER_MAX];
193 193
 	static str      empty_param = {".",1};
194
-	static str      email_attr = {"email",5};
194
+	int_str           email_val;
195 195
 	unsigned int      hash_index, label;
196 196
 	contact_body_t*   cb=0;
197 197
 	contact_t*        c=0;
... ...
@@ -199,7 +200,6 @@ static int assemble_msg(struct sip_msg* msg, char* action)
199 199
 	rr_t*             record_route;
200 200
 	struct hdr_field* p_hdr;
201 201
 	param_hooks_t     hooks;
202
-	struct usr_avp    *email_avp;
203 202
 	int               l;
204 203
 	char*             s, fproxy_lr;
205 204
 	str               route, next_hop, hdrs, tmp_s, body, str_uri;
... ...
@@ -210,7 +210,7 @@ static int assemble_msg(struct sip_msg* msg, char* action)
210 210
 		goto error;
211 211
 	}
212 212
 
213
-	email_avp = 0;
213
+	email_val.s = 0;
214 214
 	body = empty_param;
215 215
 
216 216
 	/* parse all -- we will need every header field for a UAS */
... ...
@@ -344,12 +344,7 @@ static int assemble_msg(struct sip_msg* msg, char* action)
344 344
 		body.len = msg->len - (body.s - msg->buf);
345 345
 
346 346
 		/* get email (if any) */
347
-		if ( (email_avp=search_avp( &email_attr ))!=0 &&
348
-		email_avp->val_type!=AVP_TYPE_STR ) {
349
-			LOG(L_WARN, "assemble_msg: 'email' avp found but "
350
-			    "not string -> ignoring it\n");
351
-			email_avp = 0;
352
-		}
347
+		search_first_avp( 0, (int_str)EMAIL_AVP_ID, &email_val);
353 348
 	}
354 349
 
355 350
 	/* additional headers */
... ...
@@ -400,7 +395,7 @@ static int assemble_msg(struct sip_msg* msg, char* action)
400 400
 
401 401
 	eol_line(2)=REQ_LINE(msg).method;     /* method type */
402 402
 	eol_line(3)=msg->parsed_uri.user;     /* user from r-uri */
403
-	eol_line(4)=email_avp?(email_avp->val.str_val):empty_param;  /* email */
403
+	eol_line(4)=(email_val.s)?(*email_val.s):(empty_param);  /* email */
404 404
 	eol_line(5)=msg->parsed_uri.host;     /* domain */
405 405
 
406 406
 	eol_line(6)=msg->rcv.bind_address->address_str; /* dst ip */
... ...
@@ -31,6 +31,8 @@
31 31
  *  2003-12-04  global callbacks moved into transaction callbacks;
32 32
  *              multiple events per callback added; single list per
33 33
  *              transaction for all its callbacks (bogdan)
34
+ *  2004-08-23  user avp(attribute value pair) added -> making avp list
35
+ *              available in callbacks (bogdan)
34 36
  */
35 37
 
36 38
 #include "defs.h"
... ...
@@ -40,6 +42,7 @@
40 40
 #include "../../dprint.h"
41 41
 #include "../../error.h"
42 42
 #include "../../mem/mem.h"
43
+#include "../../usr_avp.h"
43 44
 #include "t_hooks.h"
44 45
 #include "t_lookup.h"
45 46
 #include "t_funcs.h"
... ...
@@ -169,11 +172,16 @@ void run_trans_callbacks( int type , struct cell *trans,
169 169
 {
170 170
 	static struct tmcb_params params = {0,0,0,0};
171 171
 	struct tm_callback    *cbp;
172
+	struct usr_avp **backup;
172 173
 
173 174
 	params.req = req;
174 175
 	params.rpl = rpl;
175 176
 	params.code = code;
176 177
 
178
+	if (trans->tmcb_hl.first==0 || ((trans->tmcb_hl.reg_types)&type)==0 )
179
+		return;
180
+
181
+	backup = set_avp_list( &trans->user_avps );
177 182
 	for (cbp=trans->tmcb_hl.first; cbp; cbp=cbp->next)  {
178 183
 		if ( (cbp->types)&type ) {
179 184
 			DBG("DBG: trans=%p, callback type %d, id %d entered\n",
... ...
@@ -181,6 +189,7 @@ void run_trans_callbacks( int type , struct cell *trans,
181 181
 			params.param = &(cbp->param);
182 182
 			cbp->callback( trans, type, &params );
183 183
 		}
184
+	set_avp_list( backup );
184 185
 	}
185 186
 }
186 187
 
... ...
@@ -190,15 +199,21 @@ void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code )
190 190
 {
191 191
 	static struct tmcb_params params = {0,0,0,0};
192 192
 	struct tm_callback    *cbp;
193
+	struct usr_avp **backup;
193 194
 
194 195
 	params.req = req;
195 196
 	params.code = code;
196 197
 
198
+	if (req_in_tmcb_hl->first==0)
199
+		return;
200
+
201
+	backup = set_avp_list( &trans->user_avps );
197 202
 	for (cbp=req_in_tmcb_hl->first; cbp; cbp=cbp->next)  {
198 203
 		DBG("DBG: trans=%p, callback type %d, id %d entered\n",
199 204
 			trans, cbp->types, cbp->id );
200 205
 		params.param = &(cbp->param);
201 206
 		cbp->callback( trans, cbp->types, &params );
202 207
 	}
208
+	set_avp_list( backup );
203 209
 }
204 210
 
... ...
@@ -60,6 +60,7 @@
60 60
  *  2003-11-11: build_lump_rpl() removed, add_lump_rpl() has flags (bogdan)
61 61
  *  2004-02-13: t->is_invite and t->local replaced with flags (bogdan)
62 62
  *  2004-02-18  fifo_t_reply imported from vm module (bogdan)
63
+ *  2004-08-23  avp list is available from failure/on_reply routes (bogdan)
63 64
  */
64 65
 
65 66
 
... ...
@@ -473,31 +474,36 @@ static inline void faked_env( struct cell *t,struct sip_msg *msg)
473 473
 	static enum route_mode backup_mode;
474 474
 	static struct cell *backup_t;
475 475
 	static unsigned int backup_msgid;
476
+	static struct usr_avp **backup_list;
476 477
 
477 478
 	if (msg) {
478
-	/* remember we are back in request processing, but process
479
-	 * a shmem-ed replica of the request; advertise it in rmode;
480
-	 * for example t_reply needs to know that
481
-	 */
482
-	backup_mode=rmode;
483
-	rmode=MODE_ONFAILURE;
484
-	/* also, tm actions look in beginning whether tranaction is
485
-	 * set -- whether we are called from a reply-processing 
486
-	 * or a timer process, we need to set current transaction;
487
-	 * otherwise the actions would attempt to look the transaction
488
-	 * up (unnecessary overhead, refcounting)
489
-	 */
490
-	/* backup */
491
-	backup_t=get_t();
492
-	backup_msgid=global_msg_id;
493
-	/* fake transaction and message id */
479
+		/* remember we are back in request processing, but process
480
+		 * a shmem-ed replica of the request; advertise it in rmode;
481
+		 * for example t_reply needs to know that
482
+		 */
483
+		backup_mode=rmode;
484
+		rmode=MODE_ONFAILURE;
485
+		/* also, tm actions look in beginning whether tranaction is
486
+		 * set -- whether we are called from a reply-processing 
487
+		 * or a timer process, we need to set current transaction;
488
+		 * otherwise the actions would attempt to look the transaction
489
+		 * up (unnecessary overhead, refcounting)
490
+		 */
491
+		/* backup */
492
+		backup_t=get_t();
493
+		backup_msgid=global_msg_id;
494
+		/* fake transaction and message id */
494 495
 		global_msg_id=msg->id;
495 496
 		set_t(t);
497
+		/* make available the avp list from transaction */
498
+		backup_list = set_avp_list( &t->user_avps );
496 499
 	} else {
497 500
 		/* restore original environment */
498 501
 		set_t(backup_t);
499 502
 		global_msg_id=backup_msgid;
500 503
 		rmode=backup_mode;
504
+		/* restore original avp list */
505
+		set_avp_list( backup_list );
501 506
 	}
502 507
 }
503 508
 
... ...
@@ -532,33 +538,7 @@ static inline int fake_req(struct sip_msg *faked_req,
532 532
 		faked_req->new_uri.s[faked_req->new_uri.len]=0;
533 533
 	}
534 534
 
535
-#if 0
536
-	/* create a duplicated lump list to which actions can add
537
-	 * new pkg items  */
538
-	if (shmem_msg->add_rm) {
539
-		faked_req->add_rm=dup_lump_list(shmem_msg->add_rm);
540
-		if (!faked_req->add_rm) { /* non_emty->empty ... failure */
541
-			LOG(L_ERR, "ERROR: fake_req: lump dup failed\n");
542
-			goto error01;
543
-		}
544
-	}
545
-	/* same for the body lumps */
546
-	if (shmem_msg->body_lumps) {
547
-		faked_req->body_lumps=dup_lump_list(shmem_msg->body_lumps);
548
-		if (!faked_req->body_lumps) { /* non_empty->empty ... failure */
549
-			LOG(L_ERR, "ERROR: fake_req: lump dup failed\n");
550
-			goto error02;
551
-		}
552
-	}
553
-#endif
554 535
 	return 1;
555
-
556
-#if 0
557
-error02:
558
-	free_duped_lump_list(faked_req->add_rm);
559
-error01:
560
-	if (faked_req->new_uri.s) pkg_free(faked_req->new_uri.s);
561
-#endif
562 536
 error00:
563 537
 	return 0;
564 538
 }
... ...
@@ -567,11 +547,6 @@ void inline static free_faked_req(struct sip_msg *faked_req, struct cell *t)
567 567
 {
568 568
 	struct hdr_field *hdr;
569 569
 
570
-#if 0
571
-	free_duped_lump_list(faked_req->add_rm);
572
-	free_duped_lump_list(faked_req->body_lumps);
573
-	faked_req->add_rm = faked_req->body_lumps = 0;
574
-#endif
575 570
 	if (faked_req->new_uri.s) {
576 571
 		pkg_free(faked_req->new_uri.s);
577 572
 		faked_req->new_uri.s = 0;
... ...
@@ -608,12 +583,10 @@ static inline int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
608 608
 
609 609
 	/* failure_route for a local UAC? */
610 610
 	if (!shmem_msg) {
611
-		LOG(L_WARN, 
612
-			"Warning: run_failure_handlers: no UAC support (%d, %d) \n",
613
-			t->on_negative, 
614
-			t->tmcb_hl.reg_types);
615
-                return 0;
616
-        }
611
+		LOG(L_WARN,"Warning: run_failure_handlers: no UAC support (%d, %d) \n",
612
+			t->on_negative, t->tmcb_hl.reg_types);
613
+		return 0;
614
+	}
617 615
 
618 616
 	/* don't start faking anything if we don't have to */
619 617
 	if ( !has_tran_tmcbs( t, TMCB_ON_FAILURE) && !t->on_negative ) {
... ...
@@ -644,9 +617,6 @@ static inline int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
644 644
 		/* run a reply_route action if some was marked */
645 645
 		if (run_actions(failure_rlist[on_failure], &faked_req)<0)
646 646
 			LOG(L_ERR, "ERROR: run_failure_handlers: Error in do_action\n");
647
-		/* destroy any eventual avps */
648
-		if (users_avps)
649
-			destroy_avps();
650 647
 	}
651 648
 
652 649
 	/* restore original environment and free the fake msg */
... ...
@@ -1225,6 +1195,7 @@ int reply_received( struct sip_msg  *p_msg )
1225 1225
 	struct ua_client *uac;
1226 1226
 	struct cell *t;
1227 1227
 	str next_hop;
1228
+	struct usr_avp **backup_list;
1228 1229
 
1229 1230
 	/* make sure we know the assosociated transaction ... */
1230 1231
 	if (t_check( p_msg  , &branch )==-1)
... ...
@@ -1265,9 +1236,9 @@ int reply_received( struct sip_msg  *p_msg )
1265 1265
 		/* acknowledge negative INVITE replies (do it before detailed
1266 1266
 		 * on_reply processing, which may take very long, like if it
1267 1267
 		 * is attempted to establish a TCP connection to a fail-over dst */
1268
-
1269
-        if (t->flags & T_IS_INVITE_FLAG) {
1270
-                if (msg_status >= 300) {
1268
+		
1269
+	if (t->flags & T_IS_INVITE_FLAG) {
1270
+		if (msg_status >= 300) {
1271 1271
 			ack = build_ack(p_msg, t, branch, &ack_len);
1272 1272
 			if (ack) {
1273 1273
 				SEND_PR_BUFFER(&uac->request, ack, ack_len);
... ...
@@ -1283,18 +1254,19 @@ int reply_received( struct sip_msg  *p_msg )
1283 1283
 			}
1284 1284
 		}
1285 1285
 	}
1286
-	     /* processing of on_reply block */
1286
+	/* processing of on_reply block */
1287 1287
 	if (t->on_reply) {
1288 1288
 		rmode=MODE_ONREPLY;
1289
-		     /* transfer transaction flag to message context */
1289
+		/* transfer transaction flag to message context */
1290 1290
 		if (t->uas.request) p_msg->flags=t->uas.request->flags;
1291
-	 	if (run_actions(onreply_rlist[t->on_reply], p_msg)<0) 
1291
+		/* set the as avp_list the one from transaction */
1292
+		backup_list = set_avp_list( &t->user_avps );
1293
+		if (run_actions(onreply_rlist[t->on_reply], p_msg)<0) 
1292 1294
 			LOG(L_ERR, "ERROR: on_reply processing failed\n");
1293
-		     /* destroy any eventual avps */
1294
-		if (users_avps)
1295
-			destroy_avps();
1296
-		     /* transfer current message context back to t */
1295
+		/* transfer current message context back to t */
1297 1296
 		if (t->uas.request) t->uas.request->flags=p_msg->flags;
1297
+		/* restore original avp list */
1298
+		set_avp_list( backup_list );
1298 1299
 	}
1299 1300
 	LOCK_REPLIES( t );
1300 1301
 	if ( is_local(t) ) {
... ...
@@ -49,6 +49,7 @@
49 49
  *              merged in transaction callbacks as LOCAL_COMPLETED (bogdan)
50 50
  *  2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
51 51
  *  2004-02-13  t->is_invite, t->local, t->noisy_ctimer replaced (bogdan)
52
+ *  2004-08-23  avp support in t_uac (bogdan)
52 53
  */
53 54
 
54 55
 #include <string.h>
... ...
@@ -198,6 +199,10 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
198 198
 		goto error2;
199 199
 	}
200 200
 
201
+	/* better reset avp list now - anyhow, it's useless from
202
+	 * this point (bogdan) */
203
+	reset_avps();
204
+
201 205
 	/* add the callback the the transaction for LOCAL_COMPLETED event */
202 206
 	if(cb && insert_tmcb(&(new_cell->tmcb_hl),TMCB_LOCAL_COMPLETED,cb,cbp)!=1){
203 207
 		ret=E_OUT_OF_MEM;
... ...
@@ -36,6 +36,7 @@
36 36
  * 2004-02-06 added user preferences support - destroy_avps() (bogdan)
37 37
  * 2004-04-30 exec_pre_cb is called after basic sanity checks (at least one
38 38
  *            via present & parsed ok)  (andrei)
39
+ * 2004-08-23 avp core changed - destroy_avp-> reset_avps (bogdan)
39 40
  */
40 41
 
41 42
 
... ...
@@ -57,6 +58,7 @@
57 57
 #include "dset.h"
58 58
 #include "usr_avp.h"
59 59
 
60
+
60 61
 #include "tcp_server.h" /* for tcpconn_add_alias */
61 62
 
62 63
 
... ...
@@ -166,10 +168,6 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
166 166
 			goto error;
167 167
 		}
168 168
 
169
-		/* ... free posible loaded avps */
170
-		if (users_avps)
171
-			destroy_avps();
172
-
173 169
 #ifdef STATS
174 170
 		gettimeofday( & tve, &tz );
175 171
 		diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
... ...
@@ -229,6 +227,8 @@ end:
229 229
 #endif
230 230
 	/* execute post-script callbacks, if any; -jiri */
231 231
 	exec_post_cb(msg);
232
+	/* free possible loaded avps -bogdan */
233
+	reset_avps();
232 234
 	DBG("receive_msg: cleaning up\n");
233 235
 	free_sip_msg(msg);
234 236
 	pkg_free(msg);
... ...
@@ -240,6 +240,8 @@ error:
240 240
 	DBG("error:...\n");
241 241
 	/* execute post-script callbacks, if any; -jiri */
242 242
 	exec_post_cb(msg);
243
+	/* free possible loaded avps -bogdan */
244
+	reset_avps();
243 245
 error02:
244 246
 	free_sip_msg(msg);
245 247
 	pkg_free(msg);
... ...
@@ -26,349 +26,318 @@
26 26
  *
27 27
  * History:
28 28
  * ---------
29
- *  2004-02-06  created (bogdan)
30
- *  2004-06-06  updated to the current DB api (andrei)
29
+ *  2004-07-21  created (bogdan)
31 30
  */
32 31
 
33 32
 
33
+#include <assert.h>
34
+
34 35
 #include "sr_module.h"
35 36
 #include "dprint.h"
36 37
 #include "str.h"
37 38
 #include "ut.h"
38
-#include "mem/mem.h"
39
-#include "db/db.h"
40
-#include "parser/parse_from.h"
41
-#include "parser/parse_uri.h"
39
+#include "mem/shm_mem.h"
42 40
 #include "usr_avp.h"
43 41
 
44 42
 
45 43
 
46
-static db_con_t  *avp_db_con = 0;
47
-static db_func_t avp_dbf; /* database call backs */
48
-struct usr_avp   *users_avps = 0;
49
-char             *avp_db_url = 0;
44
+struct str_int_data {
45
+	str  name;
46
+	int  val;
47
+};
48
+
49
+struct str_str_data {
50
+	str  name;
51
+	str  val;
52
+};
50 53
 
51 54
 
52
-static char* usr_type[] = {"ruri","from","to",0};
55
+static struct usr_avp *global_avps = 0;
56
+static struct usr_avp **crt_avps  = &global_avps;
53 57
 
54 58
 
55
-int init_avp_child( int rank )
59
+
60
+inline static unsigned short compute_ID( str *name )
56 61
 {
57
-	if ( rank>PROC_MAIN ) {
58
-		if (avp_db_url==0) {
59
-			LOG(L_NOTICE,"NOTICE:init_avp_child: no avp_db_url specified "
60
-				"-> feature disabled\n");
61
-			return 0;
62
-		}
63
-		/* init db connection */
64
-		if ( bind_dbmod(avp_db_url, &avp_dbf) < 0 ) {
65
-			LOG(L_ERR,"ERROR:init_avp_child: unable to find any db module\n");
66
-			return -1;
67
-		}
68
-		if ( (avp_db_con=avp_dbf.init( avp_db_url ))==0) {
69
-			/* connection failed */
70
-			LOG(L_ERR,"ERROR:init_avp_child: unable to connect to database\n");
71
-			return -1;
72
-		}
73
-		if (avp_dbf.use_table( avp_db_con, AVP_DB_TABLE ) < 0) {
74
-			/* table selection failed */
75
-			LOG(L_ERR,"ERROR:init_avp_child: unable to select db table\n");
76
-			return -1;
77
-		}
62
+	char *p;
63
+	unsigned short id;
64
+
65
+	id=0;
66
+	for( p=name->s+name->len-1 ; p>=name->s ; p-- )
67
+		id ^= *p;
68
+	return id;
69
+}
70
+
71
+
72
+int add_avp(unsigned short flags, int_str name, int_str val)
73
+{
74
+	struct usr_avp *avp;
75
+	str *s;
76
+	struct str_int_data *sid;
77
+	struct str_str_data *ssd;
78
+	int len;
79
+
80
+	assert( crt_avps!=0 );
81
+
82
+	/* compute the required mem size */
83
+	len = sizeof(struct usr_avp);
84
+	if (flags&AVP_NAME_STR) {
85
+		if (flags&AVP_VAL_STR)
86
+			len += sizeof(struct str_str_data)-sizeof(void*) + name.s->len
87
+				+ val.s->len;
88
+		else
89
+			len += sizeof(struct str_int_data)-sizeof(void*) + name.s->len;
90
+	} else if (flags&AVP_VAL_STR)
91
+			len += sizeof(str)-sizeof(void*) + val.s->len;
92
+
93
+	avp = (struct usr_avp*)shm_malloc( len );
94
+	if (avp==0) {
95
+		LOG(L_ERR,"ERROR:avp:add_avp: no more shm mem\n");
96
+		goto error;
97
+	}
98
+
99
+	avp->flags = flags;
100
+	avp->id = (flags&AVP_NAME_STR)? compute_ID(name.s) : name.n ;
101
+
102
+	avp->next = *crt_avps;
103
+	*crt_avps = avp;
104
+
105
+	switch ( flags&(AVP_NAME_STR|AVP_VAL_STR) )
106
+	{
107
+		case 0:
108
+			/* avp type ID, int value */
109
+			avp->data = (void*)(long)val.n;
110
+			break;
111
+		case AVP_NAME_STR:
112
+			/* avp type str, int value */
113
+			sid = (struct str_int_data*)&(avp->data);
114
+			sid->val = val.n;
115
+			sid->name.len =name.s->len;
116
+			sid->name.s = (char*)sid + sizeof(struct str_int_data);
117
+			memcpy( sid->name.s , name.s->s, name.s->len);
118
+			break;
119
+		case AVP_VAL_STR:
120
+			/* avp type ID, str value */
121
+			s = (str*)&(avp->data);
122
+			s->len = val.s->len;
123
+			s->s = (char*)s + sizeof(str);
124
+			memcpy( s->s, val.s->s , s->len);
125
+			break;
126
+		case AVP_NAME_STR|AVP_VAL_STR:
127
+			/* avp type str, str value */
128
+			ssd = (struct str_str_data*)&(avp->data);
129
+			ssd->name.len = name.s->len;
130
+			ssd->name.s = (char*)ssd + sizeof(struct str_str_data);
131
+			memcpy( ssd->name.s , name.s->s, name.s->len);
132
+			ssd->val.len = val.s->len;
133
+			ssd->val.s = ssd->name.s + ssd->name.len;
134
+			memcpy( ssd->val.s , val.s->s, val.s->len);
135
+			break;
78 136
 	}
79 137
 
80 138
 	return 0;
139
+error:
140
+	return -1;
81 141
 }
82 142
 
83 143
 
84
-void print_avps(struct usr_avp *avp)
144
+inline static str* get_avp_name(struct usr_avp *avp)
85 145
 {
86
-	if (!avp)
87
-		return;
88
-	if (avp->val_type==AVP_TYPE_STR)
89
-		DBG("DEBUG:print_avp: %.*s=%.*s\n",
90
-			avp->attr.len,avp->attr.s,
91
-			avp->val.str_val.len,avp->val.str_val.s);
92
-	else
93
-		DBG("DEBUG:print_avp: %.*s=%u\n",
94
-			avp->attr.len,avp->attr.s,
95
-			avp->val.uint_val);
96
-	print_avps(avp->next);
146
+	switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) )
147
+	{
148
+		case 0:
149
+			/* avp type ID, int value */
150
+		case AVP_VAL_STR:
151
+			/* avp type ID, str value */
152
+			return 0;
153
+		case AVP_NAME_STR:
154
+			/* avp type str, int value */
155
+			return &((struct str_int_data*)&avp->data)->name;
156
+		case AVP_NAME_STR|AVP_VAL_STR:
157
+			/* avp type str, str value */
158
+			return &((struct str_str_data*)&avp->data)->name;
159
+	}
160
+
161
+	LOG(L_ERR,"BUG:avp:get_avp_name: unknown avp type (name&val) %d\n",
162
+		avp->flags&(AVP_NAME_STR|AVP_VAL_STR));
163
+	return 0;
97 164
 }
98 165
 
99 166
 
100
-void destroy_avps( )
167
+/* get value functions */
168
+
169
+inline void get_avp_val(struct usr_avp *avp, int_str *val)
101 170
 {
102
-	struct usr_avp *avp;
171
+	if (avp==0 || val==0)
172
+		return;
103 173
 
104
-	/*print_avps(users_avps);*/
105
-	while (users_avps) {
106
-		avp = users_avps;
107
-		users_avps = users_avps->next;
108
-		pkg_free( avp );
174
+	switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) ) {
175
+		case 0:
176
+			/* avp type ID, int value */
177
+			val->n = (long)(avp->data);
178
+			break;
179
+		case AVP_NAME_STR:
180
+			/* avp type str, int value */
181
+			val->n = ((struct str_int_data*)(&avp->data))->val;
182
+			break;
183
+		case AVP_VAL_STR:
184
+			/* avp type ID, str value */
185
+			val->s = (str*)(&avp->data);
186
+			break;
187
+		case AVP_NAME_STR|AVP_VAL_STR:
188
+			/* avp type str, str value */
189
+			val->s = &(((struct str_str_data*)(&avp->data))->val);
190
+			break;
109 191
 	}
110 192
 }
111 193
 
112 194
 
113 195
 
114
-int get_user_type( char *id )
115
-{
116
-	int i;
117 196
 
118
-	for(i=0;usr_type[i];i++) {
119
-		if (!strcasecmp( id, usr_type[i]) )
120
-			return i;
121
-	}
197
+/* seach functions */
122 198
 
123
-	LOG(L_ERR,"ERROR:avp:get_user_type: unknown user type <%s>\n",id);
124
-	return -1;
199
+inline static struct usr_avp *internal_search_ID_avp( struct usr_avp *avp,
200
+												unsigned short id)
201
+{
202
+	for( ; avp ; avp=avp->next ) {
203
+		if ( id==avp->id && (avp->flags&AVP_NAME_STR)==0  ) {
204
+			return avp;
205
+		}
206
+	}
207
+	return 0;
125 208
 }
126 209
 
127 210
 
128 211
 
129
-inline static unsigned int compute_ID( str *attr )
212
+inline static struct usr_avp *internal_search_name_avp( struct usr_avp *avp,
213
+												unsigned short id, str *name)
130 214
 {
131
-	char *p;
132
-	unsigned int id;
215
+	str * avp_name;
133 216
 
134
-	id=0;
135
-	for( p=attr->s+attr->len-1 ; p>=attr->s ; p-- )
136
-		id ^= *p;
137
-	return id;
217
+	for( ; avp ; avp=avp->next )
218
+		if ( id==avp->id && avp->flags&AVP_NAME_STR &&
219
+		(avp_name=get_avp_name(avp))!=0 && avp_name->len==name->len
220
+		 && !strncasecmp( avp_name->s, name->s, name->len) ) {
221
+			return avp;
222
+		}
223
+	return 0;
138 224
 }
139 225
 
140 226
 
141
-inline static db_res_t *do_db_query(struct sip_uri *uri,char *attr,int use_dom)
227
+
228
+struct usr_avp *search_first_avp( unsigned short name_type,
229
+										int_str name, int_str *val)
142 230
 {
143
-	static db_key_t   keys_cmp[3] = {"username","domain","attribute"};
144
-	static db_key_t   keys_ret[] = {"attribute","value","type"};
145
-	static db_val_t   vals_cmp[3];
146
-	unsigned int      nr_keys_cmp;
147
-	db_res_t          *res;
148
-
149
-	/* prepare DB query */
150
-	nr_keys_cmp = 0;
151
-	keys_cmp[ nr_keys_cmp ] = "username";
152
-	vals_cmp[ nr_keys_cmp ].type = DB_STR;
153
-	vals_cmp[ nr_keys_cmp ].nul  = 0;
154
-	vals_cmp[ nr_keys_cmp ].val.str_val = uri->user;
155
-	nr_keys_cmp++;
156
-	if (use_dom) {
157
-		keys_cmp[ nr_keys_cmp ] = "domain";
158
-		vals_cmp[ nr_keys_cmp ].type = DB_STR;
159
-		vals_cmp[ nr_keys_cmp ].nul  = 0;
160
-		vals_cmp[ nr_keys_cmp ].val.str_val = uri->host;
161
-		nr_keys_cmp++;
162
-	}
163
-	if (attr) {
164
-		keys_cmp[ nr_keys_cmp ] = "attribute";
165
-		vals_cmp[ nr_keys_cmp ].type = DB_STRING;
166
-		vals_cmp[ nr_keys_cmp ].nul  = 0;
167
-		vals_cmp[ nr_keys_cmp ].val.string_val = attr;
168
-		nr_keys_cmp++;
169
-	}
231
+	struct usr_avp *avp;
170 232
 
171
-	/* do the DB query */
172
-	if ( avp_dbf.query( avp_db_con, keys_cmp, 0/*op*/, vals_cmp, keys_ret,
173
-	nr_keys_cmp, 3, 0/*order*/, &res) < 0)
233
+	assert( crt_avps!=0 );
234
+	
235
+	if (*crt_avps==0)
174 236
 		return 0;
175 237
 
176
-	return res;
238
+	/* search for the AVP by ID (&name) */
239
+	if (name_type&AVP_NAME_STR)
240
+		avp = internal_search_name_avp(*crt_avps,compute_ID(name.s),name.s);
241
+	else
242
+		avp = internal_search_ID_avp( *crt_avps, name.n );
243
+
244
+	/* get the value - if required */
245
+	if (avp && val)
246
+		get_avp_val(avp, val);
247
+
248
+	return avp;
177 249
 }
178 250
 
179 251
 
180 252
 
181
-inline static int validate_db_row(struct db_row *row, unsigned int *val_type,
182
-													unsigned int *uint_val)
253
+struct usr_avp *search_next_avp( struct usr_avp *avp,  int_str *val )
183 254
 {
184
-	/* we don't accept null values */
185
-	if (row->values[0].nul || row->values[1].nul || row->values[2].nul ) {
186
-		LOG(L_ERR,"ERROR:avp:validat_db_row: DBreply contains NULL entryes\n");
187
-		return -1;
188
-	}
189
-	/* check the value types */
190
-	if ( (row->values[0].type!=DB_STRING && row->values[0].type!=DB_STR)
191
-	||  (row->values[1].type!=DB_STRING && row->values[1].type!=DB_STR)
192
-	|| row->values[2].type!=DB_INT ) {
193
-		LOG(L_ERR,"ERROR:avp:validat_db_row: bad DB types in response\n");
194
-		return -1;
195
-	}
196
-	/* check the content of TYPE filed */
197
-	*val_type = (unsigned int)row->values[2].val.int_val;
198
-	if (*val_type!=AVP_TYPE_INT && *val_type!=AVP_TYPE_STR) {
199
-		LOG(L_ERR,"ERROR:avp:validat_db_row: bad val %d in type field\n",
200
-			*val_type);
201
-		return -1;
202
-	}
203
-	/* convert from DB_STRING to DB_STR if necesary */
204
-	if (row->values[0].type==DB_STRING) {
205
-		row->values[0].val.str_val.s =  (char*)row->values[0].val.string_val;
206
-		row->values[0].val.str_val.len = strlen(row->values[0].val.str_val.s);
207
-	}
208
-	if (row->values[1].type==DB_STRING) {
209
-		row->values[1].val.str_val.s =  (char*)row->values[1].val.string_val;
210
-		row->values[1].val.str_val.len = strlen(row->values[1].val.str_val.s);
211
-	}
212
-	/* if type is INT decode the value */
213
-	if ( *val_type==AVP_TYPE_INT &&
214
-	str2int( &row->values[1].val.str_val, uint_val)==-1 ) {
215
-		LOG(L_ERR,"ERROR:avp:validat_db_row: type is INT, but value not "
216
-			"<%s>\n",row->values[1].val.str_val.s);
217
-		return -1;
218
-	}
219
-	return 0;
220
-}
255
+	if (avp==0 || (avp=avp->next)==0)
256
+		return 0;
221 257
 
258
+	if (avp->flags&AVP_NAME_STR)
259
+		avp = internal_search_name_avp( avp, avp->id, get_avp_name(avp));
260
+	else
261
+		avp = internal_search_ID_avp( avp, avp->id );
222 262
 
263
+	if (avp && val)
264
+		get_avp_val(avp, val);
223 265
 
224
-#define copy_str(_p_,_sd_,_ss_) \
225
-	do {\
226
-		(_sd_).s = (_p_);\
227
-		(_sd_).len = (_ss_).len;\
228
-		memcpy( _p_, (_ss_).s, (_ss_).len);\
229
-		(_p_) += (_ss_).len;\
230
-	}while(0)
231
-/*
232
- * Returns:   -1 : error
233
- *             0 : sucess and avp(s) loaded
234
- *             1 : sucess but no avp loaded
235
- */
236
-int load_avp( struct sip_msg *msg, int uri_type, char *attr, int use_dom)
237
-{
238
-	db_res_t          *res;
239
-	struct sip_uri    uri;
240
-	struct usr_avp    *avp;
241
-	str               *uri_s;
242
-	int               n;
243
-	unsigned int      val_type;
244
-	unsigned int      uint_val;
245
-	int               len;
246
-	char              *p;
247
-
248
-	/* featch the user name [and domain] */
249
-	switch (uri_type) {
250
-		case 0: /* RURI */
251
-			uri_s = &(msg->first_line.u.request.uri);
252
-			break;
253
-		case 1: /* from */
254
-			if (parse_from_header( msg )<0 ) {
255
-				LOG(L_ERR,"ERROR:load_avp: failed to parse from\n");
256
-				goto error;
257
-			}
258
-			uri_s = &(get_from(msg)->uri);
259
-			break;
260
-		case 2: /* to */
261
-			if (parse_headers( msg, HDR_TO, 0)<0) {
262
-				LOG(L_ERR,"ERROR:load_avp: failed to parse to\n");
263
-				goto error;
264
-			}
265
-			uri_s = &(get_to(msg)->uri);
266
-			break;
267
-		default:
268
-			LOG(L_CRIT,"BUG:load_avp: unknow username type <%d>\n",uri_type);
269
-			goto error;
270
-	}
266
+	return avp;
267
+}
271 268
 
272
-	/* parse uri */
273
-	if (parse_uri( uri_s->s, uri_s->len , &uri )<0) {
274
-		LOG(L_ERR,"ERROR:load_avp: failed to parse uri\n");
275
-		goto error;
276
-	}
277 269
 
278
-	/* check uri */
279
-	if (!uri.user.s||!uri.user.len||(use_dom&&(!uri.host.len||!uri.host.s))) {
280
-		LOG(L_ERR,"ERROR:load_avp: uri has no user/host part <%.*s>\n",
281
-			uri_s->len,uri_s->s);
282
-		goto error;
283
-	}
284 270
 
285
-	/* do DB query */
286
-	if ( (res=do_db_query( &uri, attr,use_dom))==0 ) {
287
-		LOG(L_ERR,"ERROR:load_avp: db_query failed\n");
288
-		goto error;
289
-	}
290 271
 
291
-	/* process DB response */
292
-	if (res->n==0) {
293
-		DBG("DEBUG:load_avp: no avp found for %.*s@%.*s <%s>\n",
294
-			uri.user.len,uri.user.s,(use_dom!=0)*uri.host.len,uri.host.s,
295
-			attr?attr:"NULL");
296
-		avp_dbf.free_result( avp_db_con, res);
297
-		/*no avp found*/
298
-		return 1;
299
-	}
272
+/********* free functions ********/
300 273
 
301
-	for( n=0 ; n<res->n ; n++) {
302
-		/* validate row */
303
-		if (validate_db_row( &res->rows[n] ,&val_type, &uint_val) < 0 )
304
-			continue;
305
-		/* what do we have here?! */
306
-		DBG("DEBUG:load_avp: found avp: <%s,%s,%d>\n",
307
-			res->rows[n].values[0].val.string_val,
308
-			res->rows[n].values[1].val.string_val,
309
-		res->rows[n].values[2].val.int_val);
310
-		/* build a new avp struct */
311
-		len = sizeof(struct usr_avp);
312
-		len += res->rows[n].values[0].val.str_val.len ;
313
-		if (val_type==AVP_TYPE_STR)
314
-			len += res->rows[n].values[1].val.str_val.len ;
315
-		avp = (struct usr_avp*)pkg_malloc( len );
316
-		if (avp==0) {
317
-			LOG(L_ERR,"ERROR:load_avp: no more pkg mem\n");
318
-			continue;
319
-		}
320
-		/* fill the structure in */
321
-		p = ((char*)avp) + sizeof(struct usr_avp);
322
-		avp->id = compute_ID( &res->rows[n].values[0].val.str_val );
323
-		avp->val_type = val_type;
324
-		/* attribute name */
325
-		copy_str( p, avp->attr, res->rows[n].values[0].val.str_val);
326
-		if (val_type==AVP_TYPE_INT) {
327
-			/* INT */
328
-			avp->val.uint_val = uint_val;
329
-		} else {
330
-			/* STRING */
331
-			copy_str( p, avp->val.str_val,
332
-				res->rows[n].values[1].val.str_val);
274
+void destroy_avp( struct usr_avp *avp_del)
275
+{
276
+	struct usr_avp *avp;
277
+	struct usr_avp *avp_prev;
278
+
279
+	for( avp_prev=0,avp=*crt_avps ; avp ; avp_prev=avp,avp=avp->next ) {
280
+		if (avp==avp_del) {
281
+			if (avp_prev)
282
+				avp_prev->next=avp->next;
283
+			else
284
+				*crt_avps = avp->next;
285
+			shm_free(avp);
286
+			return;
333 287
 		}
334
-		/* add avp to internal list */
335
-		avp->next = users_avps;
336
-		users_avps = avp;
337 288
 	}
338
-
339
-	avp_dbf.free_result( avp_db_con, res);
340
-	return 0;
341
-error:
342
-	return -1;
343 289
 }
344 290
 
345 291
 
346
-
347
-inline static struct usr_avp *internal_search_avp( unsigned int id, str *attr)
292
+void destroy_avp_list_unsafe( struct usr_avp **list )
348 293
 {
349
-	struct usr_avp *avp;
294
+	struct usr_avp *avp, *foo;
350 295
 
351
-	for( avp=users_avps ; avp ; avp=avp->next )
352
-		if ( id==avp->id 
353
-		&& attr->len==avp->attr.len
354
-		&& !strncasecmp( attr->s, avp->attr.s, attr->len)
355
-		) {
356
-			return avp;
357
-		}
358
-	return 0;
296
+	avp = *list;
297
+	while( avp ) {
298
+		foo = avp;
299
+		avp = avp->next;
300
+		shm_free_unsafe( foo );
301
+	}
302
+	*list = 0;
359 303
 }
360 304
 
361 305
 
306
+inline void destroy_avp_list( struct usr_avp **list )
307
+{
308
+	struct usr_avp *avp, *foo;
309
+
310
+	DBG("DEBUG:destroy_avp_list: destroing list %p\n",*list);
311
+	avp = *list;
312
+	while( avp ) {
313
+		foo = avp;
314
+		avp = avp->next;
315
+		shm_free( foo );
316
+	}
317
+	*list = 0;
318
+}
362 319
 
363
-struct usr_avp *search_avp( str *attr)
320
+
321
+void reset_avps( )
364 322
 {
365
-	return internal_search_avp( compute_ID( attr ), attr);
323
+	assert( crt_avps!=0 );
324
+	
325
+	if ( crt_avps!=&global_avps) {
326
+		crt_avps = &global_avps;
327
+	}
328
+	destroy_avp_list( crt_avps );
366 329
 }
367 330
 
368 331
 
369 332
 
370
-struct usr_avp *search_next_avp( struct usr_avp *avp )
333
+struct usr_avp** set_avp_list( struct usr_avp **list )
371 334
 {
372
-	return internal_search_avp( avp->id, &avp->attr);
335
+	struct usr_avp **foo;
336
+	
337
+	assert( crt_avps!=0 );
338
+
339
+	foo = crt_avps;
340
+	crt_avps = list;
341
+	return foo;
373 342
 }
374 343
 
... ...
@@ -26,50 +26,52 @@
26 26
  *
27 27
  * History:
28 28
  * ---------
29
- *  2004-02-06  created (bogdan)
29
+ *  2004-07-21  created (bogdan)
30 30
  */
31 31
 
32 32
 #ifndef _SER_URS_AVP_H_
33 33
 #define _SER_URS_AVP_H_
34 34
 
35 35
 
36
-#include "parser/msg_parser.h"
36
+#include "str.h"
37
+
38
+typedef union {
39
+	int  n;
40
+	str *s;
41
+} int_str;
42
+
37 43
 
38 44
 
39 45
 struct usr_avp {
40
-	unsigned int id;
41
-	str attr;
42
-	unsigned int val_type;
43
-	union {
44
-		str  str_val;
45
-		unsigned int uint_val;
46
-	}val;
46
+	unsigned short id;
47
+	unsigned short flags;
47 48
 	struct usr_avp *next;
49
+	void *data;
48 50
 };
49 51
 
50
-extern struct usr_avp   *users_avps;
52
+#define AVP_NAME_STR     (1<<0)
53
+#define AVP_VAL_STR      (1<<1)
51 54
 
55
+/* add functions */
56
+int add_avp( unsigned short flags, int_str name, int_str val);
52 57
 
53
-#define AVP_TYPE_INT     1
54
-#define AVP_TYPE_STR     2
55 58
 
56
-#define AVP_DB_TABLE     "usr_preferences"
59
+/* seach functions */
60
+struct usr_avp *search_first_avp( unsigned short name_type, int_str name,
61
+															int_str *val );
62
+struct usr_avp *search_next_avp( struct usr_avp *avp, int_str *val  );
57 63
 
58
-#define AVP_USER_RURI    1
59
-#define AVP_USER_FROM    2
60
-#define AVP_USER_TO      3
61 64
 
62
-#define AVP_ALL_ATTR     ((char*)0xffffffff)
65
+/* free functions */
66
+void reset_avps( );
67
+void destroy_avp( struct usr_avp *avp);
68
+void destroy_avp_list( struct usr_avp **list );
69
+void destroy_avp_list_unsafe( struct usr_avp **list );
63 70
 
64
-/* init function */
65
-int init_avp_child( int rank );
66
-int get_user_type( char *id );
71
+/* get val func */
72
+void get_avp_val(struct usr_avp *avp, int_str *val );
73
+struct usr_avp** set_avp_list( struct usr_avp **list );
67 74
 
68
-/* load/free/seach functions */
69
-void destroy_avps( );
70
-int load_avp( struct sip_msg *msg, int type, char *attr, int use_dom);
71
-struct usr_avp *search_avp( str *attr);
72
-struct usr_avp *search_next_avp( struct usr_avp *avp );
73 75
 
74 76
 #endif
75 77