Browse code

- bug fixed in logging node - lookup() node implemented - it does lookup in usrloc tables

Bogdan-Andrei Iancu authored on 23/10/2003 17:27:19
Showing 6 changed files
... ...
@@ -146,8 +146,8 @@
146 146
 /* attributs and values for LOOKUP node */
147 147
 #define  SOURCE_ATTR                 0
148 148
 #define  TIMEOUT_ATTR                1    /*shared with PROXY node*/
149
-#define  USE_ATTR                    3
150
-#define  IGNORE_ATTR                 4
149
+#define  SOURCE_REG_STR              "registration"
150
+#define  SOURCE_REG_STR_LEN          (sizeof("registration")-1)
151 151
 
152 152
 /* attributs and values for REMOVE_LOCATION node */
153 153
 #define  LOCATION_ATTR               0
... ...
@@ -52,6 +52,7 @@
52 52
 #include "../../parser/parse_disposition.h"
53 53
 #include "../../db/db.h"
54 54
 #include "../tm/tm_load.h"
55
+#include "../usrloc/usrloc.h"
55 56
 #include "cpl_run.h"
56 57
 #include "cpl_db.h"
57 58
 #include "cpl_loader.h"
... ...
@@ -63,17 +64,20 @@
63 64
 #define MAX_PROXY_RECURSE  10
64 65
 
65 66
 
66
-static char *DB_URL      = 0;  /* database url */
67
-static char *DB_TABLE    = 0;  /* */
68
-static pid_t aux_process = 0;  /* pid of the private aux. process */
69
-static char *dtd_file    = 0;  /* name of the DTD file for CPL parser */
67
+/* modules param variables */
68
+static char *DB_URL        = 0;  /* database url */
69
+static char *DB_TABLE      = 0;  /* */
70
+static char *dtd_file      = 0;  /* name of the DTD file for CPL parser */
71
+static char *lookup_domain = 0;
72
+int    proxy_recurse       = 0;
73
+static char   *log_dir     = 0;  /* dir where the user log should be dumped*/
70 74
 
71 75
 
72
-int    proxy_recurse     = 0;
73
-char   *log_dir          = 0; /*directory where the user log should be dumped*/
76
+static pid_t aux_process = 0;  /* pid of the private aux. process */
74 77
 int    cpl_cmd_pipe[2];
75
-struct tm_binds cpl_tmb;
76
-
78
+struct tm_binds cpl_tmb;       /* Structure with pointers to tm funcs */
79
+usrloc_api_t cpl_ulb;          /* Structure with pointers to usrloc funcs */
80
+udomain_t*   cpl_domain  = 0;
77 81
 str    cpl_orig_tz = {0,0}; /* a copy of the original TZ; keept as a null
78 82
                              * terminated string in "TZ=value" format;
79 83
                              * used only by run_time_switch */
... ...
@@ -81,7 +85,7 @@ str    cpl_orig_tz = {0,0}; /* a copy of the original TZ; keept as a null
81 85
 /* this vars are used outside only for loading scripts */
82 86
 db_con_t* db_hdl   = 0;   /* this should be static !!!!*/
83 87
 
84
-int (*sl_reply)(struct sip_msg* _m, char* _s1, char* _s2);
88
+static int (*sl_reply)(struct sip_msg* _m, char* _s1, char* _s2);
85 89
 
86 90
 
87 91
 MODULE_VERSION
... ...
@@ -113,6 +117,7 @@ static param_export_t params[] = {
113 117
 	{"cpl_table",     STR_PARAM, &DB_TABLE      },
114 118
 	{"cpl_dtd_file",  STR_PARAM, &dtd_file      },
115 119
 	{"proxy_recurse", INT_PARAM, &proxy_recurse },
120
+	{"lookup_domain", STR_PARAM, &lookup_domain },
116 121
 	{"log_dir",       STR_PARAM, &log_dir       },
117 122
 	{0, 0, 0}
118 123
 };
... ...
@@ -156,8 +161,9 @@ static int fixup_cpl_run_script(void** param, int param_no)
156 161
 
157 162
 static int cpl_init(void)
158 163
 {
159
-	load_tm_f  load_tm;
160
-	struct stat stat_t;
164
+	bind_usrloc_t bind_usrloc;
165
+	load_tm_f     load_tm;
166
+	struct stat   stat_t;
161 167
 	char *ptr;
162 168
 	int val;
163 169
 
... ...
@@ -177,7 +183,7 @@ static int cpl_init(void)
177 183
 	}
178 184
 
179 185
 	if (proxy_recurse>MAX_PROXY_RECURSE) {
180
-		LOG(L_CRIT,"ERROR:cpl_init: value of proxy_recurse param ()%d exceeds "
186
+		LOG(L_CRIT,"ERROR:cpl_init: value of proxy_recurse param (%d) exceeds "
181 187
 			"the maximum safty value (%d)\n",proxy_recurse,MAX_PROXY_RECURSE);
182 188
 		goto error;
183 189
 	}
... ...
@@ -255,6 +261,30 @@ static int cpl_init(void)
255 261
 		goto error;
256 262
 	}
257 263
 
264
+	/* bind to usrloc module if requested */
265
+	if (lookup_domain) {
266
+		/* import all usrloc functions */
267
+		bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
268
+		if (!bind_usrloc) {
269
+			LOG(L_ERR, "ERROR:cpl_c:cpl_init: Can't bind usrloc\n");
270
+			goto error;
271
+		}
272
+		if (bind_usrloc(&cpl_ulb) < 0) {
273
+			LOG(L_ERR, "ERROR:cpl_c:cpl_init: importing usrloc failed\n");
274
+			goto error;
275
+		}
276
+		/* convert lookup_domain from char* to udomain_t* pointer */
277
+		if (cpl_ulb.register_udomain(lookup_domain, &cpl_domain) < 0) {
278
+			LOG(L_ERR, "ERROR:cpl_c:cpl_init: Error while registering domain "
279
+				"<%s>\n",lookup_domain);
280
+			goto error;
281
+		}
282
+	} else {
283
+		LOG(L_NOTICE,"NOTICE:cpl_init: no lookup_domain given -> disable "
284
+			" lookup node\n");
285
+	}
286
+
287
+
258 288
 	/* register the fifo commands */
259 289
 	if (register_fifo_cmd( cpl_load, "LOAD_CPL", 0)!=1) {
260 290
 		LOG(L_CRIT,"ERROR:cpl_init: cannot register LOAD_CPL fifo cmd!\n");
... ...
@@ -480,7 +510,7 @@ static int cpl_invoke_script(struct sip_msg* msg, char* str1, char* str2)
480 510
 	if ( (cpl_intr=new_cpl_interpreter(msg,&script))==0 )
481 511
 		goto error;
482 512
 	/* set the flags */
483
-	cpl_intr->flags = (unsigned int)str1;
513
+	cpl_intr->flags = ((unsigned int)str1);
484 514
 	/* attache the user */
485 515
 	cpl_intr->user = user;
486 516
 	/* for OUTGOING we need also the destination user for init. with him
... ...
@@ -523,6 +553,7 @@ error:
523 553
 }
524 554
 
525 555
 
556
+
526 557
 #define CPL_SCRIPT          "script"
527 558
 #define CPL_SCRIPT_LEN      (sizeof(CPL_SCRIPT)-1)
528 559
 #define ACTION_PARAM        "action"
... ...
@@ -703,7 +703,8 @@ error:
703 703
  *  [| attr16_t(2) attr16_len(2) attr_val16(2*x) |]?  BYDAY attr (NT)
704 704
  *  [| attr17_t(2) attr17_len(2) attr_val17(2*x) |]?  BYWEEKNO attr (NT)
705 705
  */
706
-static inline int encode_time_attr(xmlNodePtr  node, char *node_ptr, char *buf_end)
706
+static inline int encode_time_attr(xmlNodePtr  node, char *node_ptr,
707
+																char *buf_end)
707 708
 {
708 709
 	xmlAttrPtr     attr;
709 710
 	char           *p, *p_orig;
... ...
@@ -784,12 +785,70 @@ error:
784 785
 
785 786
 
786 787
 
788
+/* Attr. encoding for LOOKUP node:
789
+ *  | attr1_t(2) attr1_len(2) attr1_val(2*x) |      SOURCE attr  (NT)
790
+ * [| attr2_t(2) attr2_val(2) |]?                   CLEAR attr
791
+ */
792
+static inline int encode_lookup_attr(xmlNodePtr  node, char *node_ptr,
793
+																char *buf_end)
794
+{
795
+	xmlAttrPtr     attr;
796
+	char           *p, *p_orig;
797
+	unsigned char  *nr_attr;
798
+	str            val;
799
+
800
+	nr_attr = &(NR_OF_ATTR(node_ptr));
801
+	*nr_attr = 0;
802
+	p = p_orig = ATTR_PTR(node_ptr);
803
+
804
+	FOR_ALL_ATTR(node,attr) {
805
+		(*nr_attr)++;
806
+		/* get attribute's value */
807
+		get_attr_val( attr->name , val, error);
808
+		if ( !strcasecmp(attr->name,"source") ) {
809
+			/* this param will not be copied, since it has only one value ;-)*/
810
+			if ( val.len!=SOURCE_REG_STR_LEN ||
811
+			strncasecmp( val.s, SOURCE_REG_STR, val.len) ) {
812
+				LOG(L_ERR,"ERROR:cpl_c:encode_location_attr: unsupported value"
813
+					" <%.*s> in SOURCE param\n",val.len,val.s);
814
+				goto error;
815
+			}
816
+		} else if ( !strcasecmp(attr->name,"clear") ) {
817
+			set_attr_type(p, CLEAR_ATTR, buf_end, error);
818
+			if ( val.len==3 && !strncasecmp(val.s,"yes",3) )
819
+				append_short_attr(p, YES_VAL, buf_end, error);
820
+			else if ( val.len==2 && !strncasecmp(val.s,"no",2) )
821
+				append_short_attr(p, NO_VAL, buf_end, error);
822
+			else {
823
+				LOG(L_ERR,"ERROR:cpl_c:encode_location_attr: unknown value "
824
+					"<%.*s> for attribute CLEAR\n",val.len,val.s);
825
+				goto error;
826
+			}
827
+		} else if ( !strcasecmp(attr->name,"timeout") ) {
828
+			LOG(L_WARN,"WARNING:cpl_c:encode_lookup_attr: unsupported param "
829
+				"TIMEOUT; skipping\n");
830
+		} else {
831
+			LOG(L_ERR,"ERROR:cpl_c:encode_location_attr: unknown attribute "
832
+				"<%s>\n",attr->name);
833
+			goto error;
834
+		}
835
+	}
836
+
837
+	return p-p_orig;
838
+error:
839
+	return -1;
840
+}
841
+
842
+
843
+
844
+
787 845
 /* Attr. encoding for LOCATION node:
788 846
  *  | attr1_t(2) attr1_len(2) attr1_val(2*x) |      URL attr  (NT)
789 847
  * [| attr2_t(2) attr2_val(2) |]?                   PRIORITY attr
790 848
  * [| attr3_t(2) attr3_val(2) |]?                   CLEAR attr
791 849
  */
792
-static inline int encode_location_attr(xmlNodePtr  node, char *node_ptr, char *buf_end)
850
+static inline int encode_location_attr(xmlNodePtr  node, char *node_ptr,
851
+																char *buf_end)
793 852
 {
794 853
 	struct sip_uri uri;
795 854
 	xmlAttrPtr     attr;
... ...
@@ -1312,8 +1371,7 @@ int encode_node( xmlNodePtr node, char *p, char *p_end)
1312 1371
 					break;
1313 1372
 				case 'o':case 'O':
1314 1373
 					NODE_TYPE(p) = LOOKUP_NODE;
1315
-					/* we do not encode lookup node because we decide that it's
1316
-					 * to unsecure to run it */
1374
+					attr_size = encode_lookup_attr( node, p, p_end);
1317 1375
 					break;
1318 1376
 				case 'c':case 'C':
1319 1377
 					NODE_TYPE(p) = LOCATION_NODE;
... ...
@@ -311,7 +311,7 @@ static inline char *run_proxy( struct cpl_interpreter *intr )
311 311
 						intr->proxy.recurse = 0;
312 312
 						break;
313 313
 					case YES_VAL:
314
-						intr->proxy.recurse = (unsigned short)proxy_recurse;
314
+						/* already set as default */
315 315
 						break;
316 316
 					default:
317 317
 						LOG(L_ERR,"ERROR:run_proxy: invalid value (%u) found"
... ...
@@ -379,6 +379,12 @@ static inline char *run_proxy( struct cpl_interpreter *intr )
379 379
 	/* if it's the first execution of a proxy node, force parsing of the needed
380 380
 	 * headers and duplicate them in shared memory */
381 381
 	if (!(intr->flags&CPL_PROXY_DONE)) {
382
+		/* save the user name - we will need it */
383
+		if ( (p=(char*)shm_malloc( intr->user.len ))==0)
384
+			goto mem_error;
385
+		memcpy( p, intr->user.s, intr->user.len);
386
+		intr->user.s = p;
387
+		intr->flags |= CPL_USER_DUPLICATED;
382 388
 		/* requested URI - mandatory in SIP msg (cannot be STR_NOT_FOUND) */
383 389
 		s = GET_RURI( intr->msg );
384 390
 		duplicate_str( s , intr->ruri );
... ...
@@ -37,6 +37,7 @@
37 37
 #include "../../parser/msg_parser.h"
38 38
 #include "../../data_lump_rpl.h"
39 39
 #include "../tm/tm_load.h"
40
+#include "../usrloc/usrloc.h"
40 41
 #include "CPL_tree.h"
41 42
 #include "loc_set.h"
42 43
 #include "cpl_utils.h"
... ...
@@ -101,10 +102,10 @@
101 102
 	}while(0)
102 103
 
103 104
 
104
-extern int    (*sl_send_rpl)(struct sip_msg*, char*, char*);
105 105
 extern char   *log_dir;
106 106
 extern struct tm_binds cpl_tmb;
107
-
107
+extern udomain_t*   cpl_domain;
108
+extern usrloc_api_t cpl_ulb;
108 109
 
109 110
 
110 111
 struct cpl_interpreter* new_cpl_interpreter( struct sip_msg *msg, str *script)
... ...
@@ -140,11 +141,12 @@ error:
140 141
 
141 142
 void free_cpl_interpreter(struct cpl_interpreter *intr)
142 143
 {
143
-	DBG("DEBUG:----------------> free intr at %p \n",intr);
144 144
 	if (intr) {
145 145
 		if (intr->script.s)
146 146
 			shm_free( intr->script.s);
147 147
 		empty_location_set( &(intr->loc_set) );
148
+		if (intr->flags&CPL_USER_DUPLICATED)
149
+			shm_free(intr->user.s);
148 150
 		if (intr->flags&CPL_RURI_DUPLICATED)
149 151
 			shm_free(intr->ruri);
150 152
 		if (intr->flags&CPL_TO_DUPLICATED)
... ...
@@ -205,16 +207,50 @@ static inline char *run_cpl_node( struct cpl_interpreter *intr )
205 207
  */
206 208
 static inline char *run_lookup( struct cpl_interpreter *intr )
207 209
 {
210
+	unsigned short attr_name;
211
+	unsigned short n;
212
+	unsigned char  clear;
213
+	char *p;
208 214
 	char *kid;
209 215
 	char *failure_kid = 0;
210
-	int i;
216
+	char *success_kid = 0;
217
+	char *notfound_kid = 0;
218
+	int  i;
219
+	time_t      tc;
220
+	urecord_t*  r;
221
+	ucontact_t* contact;
222
+
223
+	clear = NO_VAL;
224
+
225
+	/* check the params */
226
+	for( i=NR_OF_ATTR(intr->ip),p=ATTR_PTR(intr->ip) ; i>0 ; i-- ) {
227
+		get_basic_attr(p,attr_name,n,intr,script_error);
228
+		switch (attr_name) {
229
+			case CLEAR_ATTR:
230
+				if (n!=YES_VAL && n!=NO_VAL)
231
+					LOG(L_WARN,"WARNING:run_lookup: invalid value (%u) found"
232
+						" for param. CLEAR in LOOKUP node -> using "
233
+						"default (%u)!\n",n,clear);
234
+				else
235
+					clear = n;
236
+				break;
237
+			default:
238
+				LOG(L_ERR,"ERROR:run_lookup: unknown attribute (%d) in "
239
+					"LOOKUP node\n",attr_name);
240
+				goto script_error;
241
+		}
242
+	}
211 243
 
244
+	/* check the kids */
212 245
 	for( i=0 ; i<NR_OF_KIDS(intr->ip) ; i++ ) {
213 246
 		kid = intr->ip + KID_OFFSET(intr->ip,i);
214 247
 		check_overflow_by_ptr( kid+SIMPLE_NODE_SIZE(kid), intr, script_error);
215 248
 		switch ( NODE_TYPE(kid) ) {
216 249
 			case SUCCESS_NODE :
250
+				success_kid = kid;
251
+				break;
217 252
 			case NOTFOUND_NODE:
253
+				notfound_kid = kid;
218 254
 				break;
219 255
 			case FAILURE_NODE:
220 256
 				failure_kid = kid;
... ...
@@ -226,11 +262,56 @@ static inline char *run_lookup( struct cpl_interpreter *intr )
226 262
 		}
227 263
 	}
228 264
 
229
-	LOG(L_NOTICE,"NOTICE:cpl_c:run_lookup: this node failes by default - "
230
-		"to unsecure and tiem consuming to be exectuted\n");
231
-	if (failure_kid)
232
-		return get_first_child(failure_kid);
265
+	kid = failure_kid;
266
+
267
+	if (cpl_domain) {
268
+		/* fetch user's contacts via usrloc */
269
+		tc = time(0);
270
+		cpl_ulb.lock_udomain( cpl_domain );
271
+		i = cpl_ulb.get_urecord( cpl_domain, &intr->user, &r);
272
+		if (i < 0) {
273
+			/* failure */
274
+			LOG(L_ERR, "ERROR:run_lookup: Error while querying usrloc\n");
275
+			cpl_ulb.unlock_udomain( cpl_domain );
276
+		} else if (i > 0) {
277
+			/* not found */
278
+			DBG("DBG:cpl-c:run_lookup: '%.*s' Not found in usrloc\n",
279
+				intr->user.len, intr->user.s);
280
+			cpl_ulb.unlock_udomain( cpl_domain );
281
+			kid = notfound_kid;
282
+		} else {
283
+			contact = r->contacts;
284
+			/* skip expired contacts */
285
+			while ((contact) && ((contact->expires <= tc) ||
286
+			(contact->state >= CS_ZOMBIE_N)))
287
+				contact = contact->next;
288
+			if (contact) {
289
+				/* clear loc set if requested */
290
+				if (clear)
291
+					empty_location_set( &(intr->loc_set) );
292
+				/* add first location to set */
293
+				DBG("DBG:cpl-c:run_lookup: adding <%.*s>q=%d\n",
294
+					contact->c.len,contact->c.s,(int)(10*contact->q));
295
+				if (add_location( &(intr->loc_set), &contact->c,
296
+				(int)(10*contact->q), 1/*dup*/ )==-1) {
297
+					LOG(L_ERR,"ERROR:cpl-c:run_lookup: unable to add "
298
+						"location to set :-(\n");
299
+					cpl_ulb.unlock_udomain( cpl_domain );
300
+					goto runtime_error;
301
+				}
302
+				/* set the flag for modifing the location set */
303
+				intr->flags |= CPL_LOC_SET_MODIFIED;
304
+			}
305
+			cpl_ulb.unlock_udomain( cpl_domain );
306
+		}
307
+
308
+	}
309
+
310
+	if (kid)
311
+		return get_first_child(kid);
233 312
 	return DEFAULT_ACTION;
313
+runtime_error:
314
+	return CPL_RUNTIME_ERROR;
234 315
 script_error:
235 316
 	return CPL_SCRIPT_ERROR;
236 317
 }
... ...
@@ -42,14 +42,15 @@
42 42
 #define CPL_RUN_INCOMING               (1<<1)
43 43
 #define CPL_LOC_SET_MODIFIED           (1<<2)
44 44
 #define CPL_PROXY_DONE                 (1<<3)
45
-#define CPL_RURI_DUPLICATED            (1<<4)
46
-#define CPL_TO_DUPLICATED              (1<<5)
47
-#define CPL_FROM_DUPLICATED            (1<<6)
48
-#define CPL_SUBJECT_DUPLICATED         (1<<7)
49
-#define CPL_ORGANIZATION_DUPLICATED    (1<<8)
50
-#define CPL_USERAGENT_DUPLICATED       (1<<9)
51
-#define CPL_ACCEPTLANG_DUPLICATED      (1<<10)
52
-#define CPL_PRIORITY_DUPLICATED        (1<<11)
45
+#define CPL_USER_DUPLICATED            (1<<4)
46
+#define CPL_RURI_DUPLICATED            (1<<5)
47
+#define CPL_TO_DUPLICATED              (1<<6)
48
+#define CPL_FROM_DUPLICATED            (1<<7)
49
+#define CPL_SUBJECT_DUPLICATED         (1<<8)
50
+#define CPL_ORGANIZATION_DUPLICATED    (1<<9)
51
+#define CPL_USERAGENT_DUPLICATED       (1<<10)
52
+#define CPL_ACCEPTLANG_DUPLICATED      (1<<11)
53
+#define CPL_PRIORITY_DUPLICATED        (1<<12)
53 54
 
54 55
 #define STR_NOT_FOUND           ((str*)0xffffffff)
55 56