Browse code

rls(k): module polishing

- optimiezed error checking for broken sip requests
- internal naming changes to avoid object conflicts
- query for rls services documents (reported by Klaus Darilion)

Daniel-Constantin Mierla authored on 05/01/2011 18:52:27
Showing 3 changed files
... ...
@@ -65,24 +65,26 @@ db1_con_t *rls_db = NULL;
65 65
 db_func_t rls_dbf;
66 66
 
67 67
 /** modules variables */
68
-str server_address= {0, 0};
69
-int waitn_time= 10;
70
-str rlsubs_table= str_init("rls_watchers");
71
-str rlpres_table= str_init("rls_presentity");
72
-str rls_xcap_table= str_init("xcap");
73
-
74
-str db_url= str_init(DEFAULT_DB_URL);
75
-int hash_size= 512;
68
+str rls_server_address = {0, 0};
69
+int waitn_time = 10;
70
+str rlsubs_table = str_init("rls_watchers");
71
+str rlpres_table = str_init("rls_presentity");
72
+str rls_xcap_table = str_init("xcap");
73
+
74
+str db_url = str_init(DEFAULT_DB_URL);
75
+int hash_size = 512;
76 76
 shtable_t rls_table;
77 77
 int pid;
78 78
 contains_event_t pres_contains_event;
79 79
 search_event_t pres_search_event;
80 80
 get_event_list_t pres_get_ev_list;
81
-int clean_period= 100;
81
+int clean_period = 100;
82
+
83
+/* address and port(default: 80):"http://192.168.2.132:8000/xcap-root"*/
82 84
 char* xcap_root;
83
-unsigned int xcap_port= 8000;
85
+unsigned int xcap_port = 8000;
84 86
 int rls_restore_db_subs(void);
85
-int rls_integrated_xcap_server= 0;
87
+int rls_integrated_xcap_server = 0;
86 88
 
87 89
 /** libxml api */
88 90
 xmlDocGetNodeByName_t XMLDocGetNodeByName;
... ...
@@ -101,12 +103,12 @@ mem_copy_subs_t  pres_copy_subs;
101 101
 update_db_subs_t pres_update_db_subs;
102 102
 extract_sdialog_info_t pres_extract_sdialog_info;
103 103
 int rls_events= EVENT_PRESENCE;
104
-int to_presence_code= 1;
105
-int rls_max_expires= 7200;
104
+int to_presence_code = 1;
105
+int rls_max_expires = 7200;
106 106
 int rls_reload_db_subs = 0;
107 107
 
108 108
 /* functions imported from xcap_client module */
109
-xcapGetNewDoc_t xcap_GetNewDoc= 0;
109
+xcapGetNewDoc_t xcap_GetNewDoc = 0;
110 110
 
111 111
 /* functions imported from pua module*/
112 112
 send_subscribe_t pua_send_subscribe;
... ...
@@ -150,7 +152,7 @@ str str_etag_col = str_init("etag");
150 150
 str str_doc_col = str_init("doc");
151 151
 
152 152
 /* outbound proxy address */
153
-str outbound_proxy = {0, 0};
153
+str rls_outbound_proxy = {0, 0};
154 154
 
155 155
 /** module functions */
156 156
 
... ...
@@ -172,23 +174,22 @@ static cmd_export_t cmds[]=
172 172
 };
173 173
 
174 174
 static param_export_t params[]={
175
-	{ "server_address",         STR_PARAM,   &server_address.s			     },
176
-	{ "db_url",					STR_PARAM,   &db_url.s					     },
177
-	{ "rlsubs_table",	        STR_PARAM,   &rlsubs_table.s			     },
178
-	{ "rlpres_table",			STR_PARAM,   &rlpres_table.s			     },
179
-	{ "xcap_table",		    	STR_PARAM,   &rls_xcap_table.s    		     },
180
-	{ "waitn_time",				INT_PARAM,   &waitn_time				     },
181
-	{ "clean_period",			INT_PARAM,   &clean_period				     },
182
-	{ "max_expires",			INT_PARAM,   &rls_max_expires			     },
183
-	{ "hash_size",			    INT_PARAM,   &hash_size			             },
184
-	{ "integrated_xcap_server",	INT_PARAM,   &rls_integrated_xcap_server     },	
175
+	{ "server_address",         STR_PARAM,   &rls_server_address.s           },
176
+	{ "db_url",                 STR_PARAM,   &db_url.s                       },
177
+	{ "rlsubs_table",           STR_PARAM,   &rlsubs_table.s                 },
178
+	{ "rlpres_table",           STR_PARAM,   &rlpres_table.s                 },
179
+	{ "xcap_table",             STR_PARAM,   &rls_xcap_table.s               },
180
+	{ "waitn_time",             INT_PARAM,   &waitn_time                     },
181
+	{ "clean_period",           INT_PARAM,   &clean_period                   },
182
+	{ "max_expires",            INT_PARAM,   &rls_max_expires                },
183
+	{ "hash_size",              INT_PARAM,   &hash_size                      },
184
+	{ "integrated_xcap_server", INT_PARAM,   &rls_integrated_xcap_server     },
185 185
 	{ "to_presence_code",       INT_PARAM,   &to_presence_code               },
186 186
 	{ "xcap_root",              STR_PARAM,   &xcap_root                      },
187
-	/*address and port(default: 80):"http://192.168.2.132:8000/xcap-root"*/
188 187
 	{ "rls_event",              STR_PARAM|USE_FUNC_PARAM,(void*)add_rls_event},
189
-	{ "outbound_proxy",         STR_PARAM,   &outbound_proxy.s               },
188
+	{ "outbound_proxy",         STR_PARAM,   &rls_outbound_proxy.s           },
190 189
 	{ "reload_db_subs",         INT_PARAM,   &rls_reload_db_subs             },
191
-	{0,							0,				0						     }
190
+	{0,                         0,           0                               }
192 191
 };
193 192
 
194 193
 /** module exports */
... ...
@@ -224,21 +225,21 @@ static int mod_init(void)
224 224
 
225 225
 	LM_DBG("start\n");
226 226
 
227
-	if(server_address.s==NULL)
227
+	if(rls_server_address.s==NULL)
228 228
 	{
229 229
 		LM_ERR("server_address parameter not set in configuration file\n");
230 230
 		return -1;
231 231
 	}	
232 232
 
233
-	server_address.len= strlen(server_address.s);
233
+	rls_server_address.len= strlen(rls_server_address.s);
234 234
 	
235 235
 	if(!rls_integrated_xcap_server && xcap_root== NULL)
236 236
 	{
237 237
 		LM_ERR("xcap_root parameter not set\n");
238 238
 		return -1;
239 239
 	}
240
-	if(outbound_proxy.s!=NULL)
241
-		outbound_proxy.len = strlen(outbound_proxy.s);
240
+	if(rls_outbound_proxy.s!=NULL)
241
+		rls_outbound_proxy.len = strlen(rls_outbound_proxy.s);
242 242
 	/* extract port if any */
243 243
 	if(xcap_root)
244 244
     {
... ...
@@ -82,7 +82,7 @@ typedef struct rls_resource
82 82
 
83 83
 extern char* xcap_root;
84 84
 extern unsigned int xcap_port;
85
-extern str server_address;
85
+extern str rls_server_address;
86 86
 extern int waitn_time;
87 87
 extern str rlsubs_table;
88 88
 extern str rlpres_table;
... ...
@@ -95,7 +95,7 @@ extern int rls_max_expires;
95 95
 extern int rls_integrated_xcap_server;
96 96
 extern int rls_events;
97 97
 extern int to_presence_code;
98
-extern str outbound_proxy;
98
+extern str rls_outbound_proxy;
99 99
 
100 100
 /* database connection */
101 101
 extern db1_con_t *rls_db;
... ...
@@ -35,6 +35,7 @@
35 35
 #include "../../data_lump_rpl.h"
36 36
 #include "../../lib/kcore/cmpapi.h"
37 37
 #include "../../lib/kcore/hash_func.h"
38
+#include "../../lib/kcore/parse_supported.h"
38 39
 #include "../../parser/msg_parser.h"
39 40
 #include "../../parser/parse_event.h"
40 41
 #include "../../parser/parse_expires.h"
... ...
@@ -65,87 +66,132 @@ int resource_subscriptions(subs_t* subs, xmlNodePtr rl_node);
65 65
 
66 66
 int update_rlsubs( subs_t* subs,unsigned int hash_code);
67 67
 
68
-int get_resource_list(str* pres_uri, char** list)
68
+/**
69
+ * return the XML node for rls-services matching uri
70
+ */
71
+xmlNodePtr rls_get_by_service_uri(xmlDocPtr doc, str* uri)
72
+{
73
+	xmlNodePtr root, node;
74
+	char* val;
75
+
76
+	root = XMLDocGetNodeByName(doc, "rls-services", NULL);
77
+	if(root==NULL)
78
+	{
79
+		LM_ERR("no rls-services node in XML document\n");
80
+		return NULL;
81
+	}
82
+
83
+	for(node=root->children; node; node=node->next)
84
+	{
85
+		if(xmlStrcasecmp(node->name, (unsigned char*)"service")==0)
86
+		{
87
+			val = XMLNodeGetAttrContentByName(node, "uri");
88
+			if(val!=NULL)
89
+			{
90
+				if((uri->len==strlen(val)) && (strcmp(val, uri->s)==0))
91
+				{
92
+					xmlFree(val);
93
+					return node;
94
+				}
95
+				xmlFree(val);
96
+			}
97
+		}
98
+	}
99
+	return NULL;
100
+}
101
+
102
+/**
103
+ * return service_node and rootdoc based on service uri, user and domain
104
+ * - document is taken from DB or via xcap client
105
+ */
106
+int rls_get_service_list(str *service_uri, str *user, str *domain,
107
+		 xmlNodePtr *service_node, xmlDocPtr *rootdoc)
69 108
 {
70 109
 	db_key_t query_cols[5];
71 110
 	db_val_t query_vals[5];
72 111
 	db_key_t result_cols[3];
73 112
 	int n_query_cols = 0;
74 113
 	db1_res_t *result = 0;
75
-	db_row_t *row ;	
76
-	db_val_t *row_vals ;
77
-	str body ;
78
-	struct sip_uri uri;
114
+	db_row_t *row;
115
+	db_val_t *row_vals;
116
+	str body;
79 117
 	int n_result_cols= 0;
80 118
 	int etag_col, xcap_col;
81
-	char* etag= NULL;
119
+	char *etag= NULL;
82 120
 	xcap_get_req_t req;
83
-
121
+	xmlDocPtr xmldoc = NULL;
84 122
 	xcap_doc_sel_t doc_sel;
85
-	char* rls_list;
123
+	char *xcapdoc= NULL;
86 124
 
87
-	if(parse_uri(pres_uri->s, pres_uri->len, &uri)< 0)
125
+	if(service_uri==NULL || user==NULL || domain==NULL)
88 126
 	{
89
-		LM_ERR("while parsing uri\n");
127
+		LM_ERR("invalid parameters\n");
90 128
 		return -1;
91 129
 	}
130
+
92 131
 	/* first search in database */
93 132
 	query_cols[n_query_cols] = &str_username_col;
94 133
 	query_vals[n_query_cols].type = DB1_STR;
95 134
 	query_vals[n_query_cols].nul = 0;
96
-	query_vals[n_query_cols].val.str_val = uri.user;
135
+	query_vals[n_query_cols].val.str_val = *user;
97 136
 	n_query_cols++;
98 137
 	
99 138
 	query_cols[n_query_cols] = &str_domain_col;
100 139
 	query_vals[n_query_cols].type = DB1_STR;
101 140
 	query_vals[n_query_cols].nul = 0;
102
-	query_vals[n_query_cols].val.str_val = uri.host;
141
+	query_vals[n_query_cols].val.str_val = *domain;
103 142
 	n_query_cols++;
104 143
 	
105 144
 	query_cols[n_query_cols] = &str_doc_type_col;
106 145
 	query_vals[n_query_cols].type = DB1_INT;
107 146
 	query_vals[n_query_cols].nul = 0;
108
-	query_vals[n_query_cols].val.int_val= RESOURCE_LIST;
147
+	query_vals[n_query_cols].val.int_val= RLS_SERVICE;
109 148
 	n_query_cols++;
110 149
 
111
-	if (rls_dbf.use_table(rls_db, &rls_xcap_table) < 0)
150
+	LM_DBG("searching document for user sip:%.*s@%.*s\n",
151
+		user->len, user->s, domain->len, domain->s);
152
+
153
+	if(rls_dbf.use_table(rls_db, &rls_xcap_table) < 0)
112 154
 	{
113
-		LM_ERR("in use_table-[table]= %.*s\n", rls_xcap_table.len, rls_xcap_table.s);
155
+		LM_ERR("in use_table-[table]= %.*s\n",
156
+				rls_xcap_table.len, rls_xcap_table.s);
114 157
 		return -1;
115 158
 	}
116 159
 
117 160
 	result_cols[xcap_col= n_result_cols++] = &str_doc_col;
118
-	result_cols[etag_col= n_result_cols++]= &str_etag_col;
161
+	result_cols[etag_col= n_result_cols++] = &str_etag_col;
119 162
 
120 163
 	if(rls_dbf.query(rls_db, query_cols, 0 , query_vals, result_cols,
121 164
 				n_query_cols, n_result_cols, 0, &result)<0)
122 165
 	{
123
-		LM_ERR("while querying table xcap for [uri]=%.*s\n",
124
-				pres_uri->len, pres_uri->s);
166
+		LM_ERR("failed querying table xcap for document [service_uri]=%.*s\n",
167
+				service_uri->len, service_uri->s);
125 168
 		if(result)
126 169
 			rls_dbf.free_result(rls_db, result);
127 170
 		return -1;
128 171
 	}
129 172
 
130
-	if(result->n<= 0)
173
+	if(result->n<=0)
131 174
 	{
132
-		LM_DBG("No xcap document for [uri]=%.*s\n",pres_uri->len,pres_uri->s);
175
+		LM_DBG("No rl document found\n");
133 176
 		
134 177
 		if(rls_integrated_xcap_server)
135 178
 		{
136 179
 			rls_dbf.free_result(rls_db, result);
137
-			*list= 0;
138
-			return 0;		
180
+			return 0;
139 181
 		}
140 182
 		
141 183
 		/* make an initial request to xcap_client module */
142
-		doc_sel.auid.s= "resource-lists";
143
-		doc_sel.auid.len= strlen("resource-lists");
144
-		doc_sel.doc_type= RESOURCE_LIST;
184
+		memset(&doc_sel, 0, sizeof(xcap_doc_sel_t));
185
+		doc_sel.auid.s= "rls-services";
186
+		doc_sel.auid.len= strlen("rls-services");
187
+		doc_sel.doc_type= RLS_SERVICE;
145 188
 		doc_sel.type= USERS_TYPE;
146
-		doc_sel.xid= *pres_uri;
147
-		doc_sel.filename.s= "index";
148
-		doc_sel.filename.len= 5;
189
+		if(uandd_to_uri(*user, *domain, &doc_sel.xid)<0)
190
+		{
191
+			LM_ERR("failed to create uri from user and domain\n");
192
+			goto error;
193
+		}
149 194
 
150 195
 		memset(&req, 0, sizeof(xcap_get_req_t));
151 196
 		req.xcap_root= xcap_root;
... ...
@@ -154,54 +200,73 @@ int get_resource_list(str* pres_uri, char** list)
154 154
 		req.etag= etag;
155 155
 		req.match_type= IF_NONE_MATCH;
156 156
 
157
-		rls_list= xcap_GetNewDoc(req, uri.user, uri.host);
158
-		if(rls_list== NULL)
157
+		xcapdoc= xcap_GetNewDoc(req, *user, *domain);
158
+		if(xcapdoc==NULL)
159 159
 		{
160 160
 			LM_ERR("while fetching data from xcap server\n");
161
-			goto error;	
161
+			pkg_free(doc_sel.xid.s);
162
+			goto error;
163
+		}
164
+		pkg_free(doc_sel.xid.s);
165
+		body.s = xcapdoc;
166
+		body.len = strlen(xcapdoc);
167
+	} else {
168
+		row = &result->rows[0];
169
+		row_vals = ROW_VALUES(row);
170
+
171
+		body.s = (char*)row_vals[xcap_col].val.string_val;
172
+		if(body.s== NULL)
173
+		{
174
+			LM_ERR("xcap doc is null\n");
175
+			goto error;
176
+		}
177
+		body.len = strlen(body.s);
178
+		if(body.len==0)
179
+		{
180
+			LM_ERR("xcap document is empty\n");
181
+			goto error;
162 182
 		}
163
-		
164
-		*list= rls_list;
165
-		return 0;		
166 183
 	}
167 184
 
168
-	row = &result->rows[0];
169
-	row_vals = ROW_VALUES(row);
170
-
171
-	body.s = (char*)row_vals[xcap_col].val.string_val;
172
-	if(body.s== NULL)
185
+	LM_DBG("rls_services document:\n%.*s", body.len, body.s);
186
+	xmldoc = xmlParseMemory(body.s, body.len);
187
+	if(xmldoc==NULL)
173 188
 	{
174
-		LM_ERR("Xcap doc NULL\n");
189
+		LM_ERR("while parsing XML memory\n");
175 190
 		goto error;
176
-	}	
177
-	body.len = strlen(body.s);
178
-	if(body.len== 0)
191
+	}
192
+
193
+	*service_node = rls_get_by_service_uri(xmldoc, service_uri);
194
+	if(*service_node==NULL)
179 195
 	{
180
-		LM_ERR("Xcap doc empty\n");
196
+		LM_ERR("service uri %.*s not found in rl document for user"
197
+			" sip:%.*s@%.*s\n", service_uri->len, service_uri->s,
198
+			user->len, user->s, domain->len, domain->s);
181 199
 		goto error;
182
-	}			
183
-	LM_DBG("xcap body:\n%.*s", body.len,body.s);
184
-	rls_list= (char*)pkg_malloc((body.len+ 1)* sizeof(char));
185
-	if(rls_list== NULL)
186
-	{
187
-		rls_dbf.free_result(rls_db, result);
188
-		ERR_MEM(PKG_MEM_STR);
189 200
 	}
190
-	memcpy(rls_list, body.s, body.len);
191
-	rls_list[body.len]= '\0';
201
+
202
+	*rootdoc = xmldoc;
203
+
192 204
 	rls_dbf.free_result(rls_db, result);
193
-	*list= rls_list;
205
+	if(xcapdoc!=NULL)
206
+		pkg_free(xcapdoc);
194 207
 
195 208
 	return 0;
196 209
 
197 210
 error:
198
-	if(result)
211
+	if(result!=NULL)
199 212
 		rls_dbf.free_result(rls_db, result);
200
-	return -1;
213
+	if(xmldoc!=NULL)
214
+		xmlFreeDoc(xmldoc);
215
+	if(xcapdoc!=NULL)
216
+		pkg_free(xcapdoc);
201 217
 
218
+	return -1;
202 219
 }
203 220
 
204
-
221
+/**
222
+ * reply 421 with require header
223
+ */
205 224
 int reply_421(struct sip_msg* msg)
206 225
 {
207 226
 	str hdr_append;
... ...
@@ -232,6 +297,9 @@ int reply_421(struct sip_msg* msg)
232 232
 
233 233
 }
234 234
 
235
+/**
236
+ * reply 200 ok with require header
237
+ */
235 238
 int reply_200(struct sip_msg* msg, str* contact, int expires)
236 239
 {
237 240
 	str hdr_append;
... ...
@@ -286,6 +354,9 @@ error:
286 286
 	return -1;
287 287
 }	
288 288
 
289
+/**
290
+ * reply 489 with allow-events header
291
+ */
289 292
 int reply_489(struct sip_msg * msg)
290 293
 {
291 294
 	str hdr_append;
... ...
@@ -328,31 +399,31 @@ int reply_489(struct sip_msg * msg)
328 328
 }
329 329
 	
330 330
 
331
+/**
332
+ * handle RLS subscription
333
+ */
331 334
 int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
332 335
 {
333
-	struct to_body *pto, *pfrom = NULL, TO;
334
-	int found= 0;
335
-	struct hdr_field* hdr;
336 336
 	subs_t subs;
337
-	str resource_list= {0, 0};
338
-	int i, len= 0;
339
-	pres_ev_t* event= NULL;
340
-	int err_ret= -1;
341
-	str* contact= NULL;
342
-	xmlDocPtr doc= NULL;
343
-	xmlNodePtr rl_node= NULL;
337
+	str resource_list = {0, 0};
338
+	pres_ev_t* event = NULL;
339
+	int err_ret = -1;
340
+	str* contact = NULL;
341
+	xmlDocPtr doc = NULL;
342
+	xmlNodePtr service_node = NULL;
344 343
 	unsigned int hash_code;
345
-	int to_tag_gen= 0;
344
+	int to_tag_gen = 0;
346 345
 	event_t* parsed_event;
347
-	param_t* ev_param= NULL;
348
-
349
-/*** filter: 'For me or for presence server?' */	
346
+	param_t* ev_param = NULL;
347
+	str reason;
348
+	int rt;
350 349
 
351 350
 	memset(&subs, 0, sizeof(subs_t));
352 351
 
353
-	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
352
+	/** sanity checks - parse all headers */
353
+	if (parse_headers(msg, HDR_EOH_F, 0)<-1)
354 354
 	{
355
-		LM_ERR("parsing headers\n");
355
+		LM_ERR("failed parsing all headers\n");
356 356
 		if (slb.freply(msg, 400, &pu_400_rpl) < 0)
357 357
 		{
358 358
 			LM_ERR("while sending 400 reply\n");
... ...
@@ -360,6 +431,51 @@ int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
360 360
 		}
361 361
 		return 0;
362 362
 	}
363
+	/* check for To and From headesr */
364
+	if(parse_to_header(msg)<0 || parse_from_header(msg)<0)
365
+	{
366
+		LM_ERR("failed to find To or From headers\n");
367
+		if (slb.freply(msg, 400, &pu_400_rpl) < 0)
368
+		{
369
+			LM_ERR("while sending 400 reply\n");
370
+			return -1;
371
+		}
372
+		return 0;
373
+	}
374
+	if(get_from(msg)->tag_value.s ==NULL || get_from(msg)->tag_value.len==0)
375
+	{
376
+		LM_ERR("no from tag value present\n");
377
+		return -1;
378
+	}
379
+	if(msg->callid==NULL || msg->callid->body.s==NULL)
380
+	{
381
+		LM_ERR("cannot find callid header\n");
382
+		return -1;
383
+	}
384
+	if(parse_sip_msg_uri(msg)<0)
385
+	{
386
+		LM_ERR("failed parsing Request URI\n");
387
+		return -1;
388
+	}
389
+
390
+	/* check for header 'Support: eventlist' */
391
+	if(msg->supported==NULL)
392
+	{
393
+		LM_DBG("supported header not found - not for rls\n");
394
+		goto forpresence;
395
+	}
396
+
397
+	if(parse_supported(msg)<0)
398
+	{
399
+		LM_ERR("failed to parse supported headers\n");
400
+		return -1;
401
+	}
402
+
403
+	if(!(get_supported(msg) & F_SUPPORTED_EVENTLIST))
404
+	{
405
+		LM_DBG("No support for 'eventlist' - not for rls\n");
406
+		goto forpresence;
407
+	}
363 408
 
364 409
 	/* inspecting the Event header field */
365 410
 	if(msg->event && msg->event->body.len > 0)
... ...
@@ -371,16 +487,16 @@ int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
371 371
 		}
372 372
 		if(! ( ((event_t*)msg->event->parsed)->type & rls_events) )
373 373
 		{	
374
-			return to_presence_code;
374
+			goto forpresence;
375 375
 		}
376
-	}
377
-	else
376
+	} else {
378 377
 		goto bad_event;
378
+	}
379 379
 
380 380
 	/* search event in the list */
381
-	parsed_event= (event_t*)msg->event->parsed;
382
-	event= pres_search_event(parsed_event);
383
-	if(event== NULL)
381
+	parsed_event = (event_t*)msg->event->parsed;
382
+	event = pres_search_event(parsed_event);
383
+	if(event==NULL)
384 384
 	{
385 385
 		goto bad_event;
386 386
 	}
... ...
@@ -390,175 +506,92 @@ int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
390 390
 	ev_param= parsed_event->params.list;
391 391
 	while(ev_param)
392 392
 	{
393
-		if(ev_param->name.len== 2 && strncmp(ev_param->name.s, "id", 2)== 0)
393
+		if(ev_param->name.len==2 && strncmp(ev_param->name.s, "id", 2)==0)
394 394
 		{
395
-			subs.event_id= ev_param->body;
395
+			subs.event_id = ev_param->body;
396 396
 			break;
397 397
 		}
398 398
 		ev_param= ev_param->next;
399 399
 	}		
400 400
 
401
-
402
-	if(msg->to->parsed != NULL)
403
-	{
404
-		pto = (struct to_body*)msg->to->parsed;
405
-		LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",pto->uri.len,pto->uri.s);
406
-	}
407
-	else
408
-	{
409
-		memset( &TO , 0, sizeof(TO) );
410
-		parse_to(msg->to->body.s,msg->to->body.s+msg->to->body.len+1,&TO);
411
-		if( TO.uri.len <= 0 )
412
-		{
413
-			LM_DBG("'To' header NOT parsed\n");
414
-			goto error;
415
-		}
416
-		pto = &TO;
417
-	}
418
-
419
-	if(pto->tag_value.s== NULL || pto->tag_value.len==0)
420
-		/* if an initial Subscribe */
421
-	{
401
+	if(get_to(msg)->tag_value.s==NULL || get_to(msg)->tag_value.len==0)
402
+	{ /* initial Subscribe */
422 403
 		/*verify if Request URI represents a list by asking xcap server*/	
423 404
 		if(uandd_to_uri(msg->parsed_uri.user, msg->parsed_uri.host,
424
-					&subs.pres_uri)< 0)
405
+					&subs.pres_uri)<0)
425 406
 		{
426 407
 			LM_ERR("while constructing uri from user and domain\n");
427 408
 			goto error;
428 409
 		}
429
-		if( get_resource_list(&subs.pres_uri, &resource_list.s)< 0)
410
+		if(rls_get_service_list(&subs.pres_uri, &(GET_FROM_PURI(msg)->user),
411
+					&(GET_FROM_PURI(msg)->host), &service_node, &doc)<0)
430 412
 		{
431 413
 			LM_ERR("while attepmting to get a resource list\n");
432 414
 			goto error;
433 415
 		}
434
-		if( resource_list.s== NULL )    
416
+		if(doc==NULL)
435 417
 		{
436
-			/* if not a resource list subscribe , return  to_presence_code
437
-			 * so that presence will handle the subscription*/
438
-			return to_presence_code; 
418
+			/* if not for RLS, pass it to presence serivce */
419
+			LM_DBG("list not found - searched for uri <%.*s>\n",
420
+					subs.pres_uri.len, subs.pres_uri.s);
421
+			goto forpresence;
439 422
 		}
440
-		resource_list.len= strlen(resource_list.s);
441
-
442
-	}
443
-	else
444
-	{
445
-		if( msg->callid==NULL || msg->callid->body.s==NULL)
446
-		{
447
-			LM_ERR("cannot parse callid header\n");
448
-			goto error;
449
-		}
450
-		if (msg->from->parsed == NULL)
451
-		{
452
-			LM_DBG("'From' header not parsed\n");
453
-			/* parsing from header */
454
-			if ( parse_from_header( msg )<0 ) 
455
-			{
456
-				LM_DBG("ERROR cannot parse From header\n");
457
-				goto error;
458
-			}
459
-		}
460
-		pfrom = (struct to_body*)msg->from->parsed;
461
-		if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
462
-		{
463
-			LM_ERR("no from tag value present\n");
464
-			goto error;
465
-		}
466
-
423
+	} else {
467 424
 		/* search if a stored dialog */
468
-		hash_code= core_hash(&msg->callid->body, &pto->tag_value, hash_size);
425
+		hash_code = core_hash(&msg->callid->body,
426
+				&get_to(msg)->tag_value, hash_size);
469 427
 		lock_get(&rls_table[hash_code].lock);
470 428
 
471
-		if(pres_search_shtable(rls_table,msg->callid->body,
472
-					pto->tag_value,	pfrom->tag_value, hash_code)== NULL)
429
+		if(pres_search_shtable(rls_table, msg->callid->body,
430
+				get_to(msg)->tag_value, get_from(msg)->tag_value,
431
+				hash_code)==NULL)
473 432
 		{
474 433
 			lock_release(&rls_table[hash_code].lock);
475
-			return to_presence_code;	
434
+			LM_DBG("subscription dialog not found for <%.*s>\n",
435
+					get_from(msg)->uri.len, get_from(msg)->uri.s);
436
+			goto forpresence;
476 437
 		}
477 438
 		lock_release(&rls_table[hash_code].lock);
478 439
 	}
479 440
 
480
-/*** verify if it contains the 'Supported: eventlist' header
481
- * and if not - reply with '421 (Extension Required)' */
482
-
483
-/*
484
-	hdr = msg->supported;
485
-	if(hdr== NULL || hdr->body.s== 0 || hdr->body.len== 0)
486
-	{
487
-		LM_DBG("msg->supported header NULL\n");
488
-		goto found_support;
489
-	}
490
-*/
491
-	hdr= msg->headers;
492
-	while(hdr)
493
-	{
494
-		if(cmp_hdrname_strzn(&hdr->name, "Supported", 9)== 0)
495
-			break;
496
-		hdr= hdr->next;
497
-	}
498
-	while(hdr!= NULL )
499
-	{
500
-		len= hdr->body.len- 8;
501
-		for(i= 0; i< len; i++)
502
-		{	
503
-			if(strncmp(hdr->body.s+ i, "eventlist", 9)== 0)
504
-			{
505
-				found= 1;
506
-				goto found_support;
507
-			}
508
-		}
509
-		hdr = next_sibling_hdr(hdr);
510
-	}
511
-
512
-found_support:	
513
-	if(found== 0)	
514
-	{
515
-		LM_ERR("No 'Support: eventlist' header found\n");
516
-		if(reply_421(msg)< 0)
517
-			return -1;
518
-		return 0;
519
-	}
520
-/*** examine the event header */
521
-
522 441
 	/* extract dialog information from message headers */
523 442
 	if(pres_extract_sdialog_info(&subs, msg, rls_max_expires,
524
-				&to_tag_gen, server_address)< 0)
443
+				&to_tag_gen, rls_server_address)<0)
525 444
 	{
526
-		LM_ERR("bad Subscribe request\n");
445
+		LM_ERR("bad subscribe request\n");
527 446
 		goto error;
528 447
 	}
529 448
 
530
-	hash_code= core_hash(&subs.callid, &subs.to_tag, hash_size);
449
+	/* if correct reply with 200 OK */
450
+	if(reply_200(msg, &subs.local_contact, subs.expires)<0)
451
+		goto error;
531 452
 
532
-	if(pto->tag_value.s== NULL || pto->tag_value.len==0) 
533
-		/* if an initial subscribe */
534
-	{
535
-		subs.local_cseq= 0;
453
+	hash_code = core_hash(&subs.callid, &subs.to_tag, hash_size);
536 454
 
537
-		if(subs.expires!= 0)
455
+	if(get_to(msg)->tag_value.s==NULL || get_to(msg)->tag_value.len==0)
456
+	{ /* initial subscribe */
457
+		subs.local_cseq = 0;
458
+
459
+		if(subs.expires != 0)
538 460
 		{
539
-			subs.version= 1;
540
-			if(pres_insert_shtable(rls_table, hash_code, &subs)< 0)
461
+			subs.version = 1;
462
+			if(pres_insert_shtable(rls_table, hash_code, &subs)<0)
541 463
 			{
542 464
 				LM_ERR("while adding new subscription\n");
543 465
 				goto error;
544 466
 			}
545 467
 		}
546
-	}
547
-	else
548
-	{
549
-		str reason;
550
-		int rt;
551
-
552
-		rt= update_rlsubs(&subs, hash_code);
553
-		if(rt< 0)
468
+	} else {
469
+		rt = update_rlsubs(&subs, hash_code);
470
+		if(rt<0)
554 471
 		{
555 472
 			LM_ERR("while updating resource list subscription\n");
556 473
 			goto error;
557 474
 		}
558 475
 	
559
-		if(rt>= 400)
476
+		if(rt>=400)
560 477
 		{
561
-			reason= (rt==400)?pu_400_rpl:stale_cseq_rpl;
478
+			reason = (rt==400)?pu_400_rpl:stale_cseq_rpl;
562 479
 		
563 480
 			if (slb.freply(msg, 400, &reason) < 0)
564 481
 			{
... ...
@@ -568,86 +601,82 @@ found_support:
568 568
 			return 0;
569 569
 		}	
570 570
 
571
-		if(get_resource_list(&subs.pres_uri, &resource_list.s)< 0)
571
+		if(rls_get_service_list(&subs.pres_uri, &subs.from_user,
572
+					&subs.from_domain, &service_node, &doc)<0)
572 573
 		{
573
-			LM_ERR("when getting resource list\n");
574
+			LM_ERR("failed getting resource list\n");
574 575
 			goto error;
575 576
 		}
576
-		resource_list.len= strlen(resource_list.s);
577
-	}
578
-	
579
-	doc= xmlParseMemory(resource_list.s, resource_list.len);
580
-	if(doc== NULL)
581
-	{
582
-		LM_ERR("while parsing XML memory\n");
583
-		goto error;
584
-	}
585
-	rl_node= XMLDocGetNodeByName(doc, "resource-lists", NULL);
586
-	if(rl_node== NULL)
587
-	{
588
-		LM_ERR("while extracting resource-lists node\n");
589
-		goto error;
577
+		if(doc==NULL)
578
+		{
579
+			/* warning: no document returned?!?! */
580
+			LM_WARN("no document returned for uri <%.*s>\n",
581
+					subs.pres_uri.len, subs.pres_uri.s);
582
+			goto done;
583
+		}
590 584
 	}
591 585
 
592
-/*** send Subscribe requests for all in the list */
593
-	
594
-	if(resource_subscriptions(&subs, rl_node)< 0)
586
+	/* sending notify with full state */
587
+	if(send_full_notify(&subs, service_node, subs.version, &subs.pres_uri,
588
+				hash_code)<0)
595 589
 	{
596
-		LM_ERR("while sending Subscribe requests to resources in a list\n");
590
+		LM_ERR("failed sending full state sotify\n");
597 591
 		goto error;
598 592
 	}
599
-
600
-/*** if correct reply with 200 OK*/
601
-	if(reply_200(msg, &subs.local_contact, subs.expires)< 0)
602
-		goto error;
603
-
604
-	/* call sending Notify with full state */
605
-	if(send_full_notify(&subs,rl_node,subs.version,&subs.pres_uri,hash_code)< 0)
593
+	/* send subscribe requests for all in the list */
594
+	if(resource_subscriptions(&subs, service_node)< 0)
606 595
 	{
607
-		LM_ERR("while sending full state Notify\n");
596
+		LM_ERR("failed sending subscribe requests to resources in list\n");
608 597
 		goto error;
609 598
 	}
610
-	if(contact)
599
+
600
+done:
601
+	if(contact!=NULL)
611 602
 	{	
612
-		if(contact->s)
603
+		if(contact->s!=NULL)
613 604
 			pkg_free(contact->s);
614 605
 		pkg_free(contact);
615 606
 	}
616
-		
617
-	pkg_free(resource_list.s);
618
-	pkg_free(subs.pres_uri.s);
619 607
 
620
-	if(subs.record_route.s)
608
+	if(subs.pres_uri.s!=NULL)
609
+		pkg_free(subs.pres_uri.s);
610
+	if(subs.record_route.s!=NULL)
621 611
 		pkg_free(subs.record_route.s);
622
-	xmlFreeDoc(doc);
612
+	if(doc!=NULL)
613
+		xmlFreeDoc(doc);
623 614
 	return 1;
624 615
 
616
+forpresence:
617
+	if(subs.pres_uri.s!=NULL)
618
+		pkg_free(subs.pres_uri.s);
619
+	return to_presence_code;
620
+
625 621
 bad_event:
626
-	if(reply_489(msg)< 0)
622
+	err_ret = 0;
623
+	if(reply_489(msg)<0)
627 624
 	{
628
-		LM_ERR("while sending 489 reply\n");
629
-		err_ret= -1;
625
+		LM_ERR("failed sending 489 reply\n");
626
+		err_ret = -1;
630 627
 	}
631
-	err_ret= 0;
632 628
 
633 629
 error:
634 630
 	LM_ERR("occured in rls_handle_subscribe\n");
635 631
 
636
-	if(contact)
632
+	if(contact!=NULL)
637 633
 	{	
638
-		if(contact->s)
634
+		if(contact->s!=NULL)
639 635
 			pkg_free(contact->s);
640 636
 		pkg_free(contact);
641 637
 	}
642
-	if(subs.pres_uri.s)
638
+	if(subs.pres_uri.s!=NULL)
643 639
 		pkg_free(subs.pres_uri.s);
644
-		
645
-	if(subs.record_route.s)
646
-			pkg_free(subs.record_route.s);	
647
-	
648
-	if(doc)
640
+
641
+	if(subs.record_route.s!=NULL)
642
+		pkg_free(subs.record_route.s);
643
+
644
+	if(doc!=NULL)
649 645
 		xmlFreeDoc(doc);
650
-	if(resource_list.s)
646
+	if(resource_list.s!=NULL)
651 647
 		pkg_free(resource_list.s);
652 648
 	return err_ret;
653 649
 }
... ...
@@ -741,15 +770,19 @@ int send_resource_subs(char* uri, void* param)
741 741
 {
742 742
 	str pres_uri;
743 743
 
744
-	pres_uri.s= uri;
745
-	pres_uri.len= strlen(uri);
744
+	pres_uri.s = uri;
745
+	pres_uri.len = strlen(uri);
746 746
 
747
-	((subs_info_t*)param)->pres_uri= &pres_uri;
747
+	((subs_info_t*)param)->pres_uri = &pres_uri;
748
+	((subs_info_t*)param)->remote_target = &pres_uri;
748 749
 
749 750
 	return pua_send_subscribe((subs_info_t*)param);
750 751
 }
751 752
 
752
-int resource_subscriptions(subs_t* subs, xmlNodePtr rl_node)
753
+/**
754
+ * send subscriptions to the list from XML node
755
+ */
756
+int resource_subscriptions(subs_t* subs, xmlNodePtr xmlnode)
753 757
 {
754 758
 	char* uri= NULL;
755 759
 	subs_info_t s;
... ...
@@ -765,30 +798,29 @@ int resource_subscriptions(subs_t* subs, xmlNodePtr rl_node)
765 765
 	
766 766
 	memset(&s, 0, sizeof(subs_info_t));
767 767
 
768
-	if( uandd_to_uri(subs->from_user, subs->from_domain, &wuri)< 0)
768
+	if(uandd_to_uri(subs->from_user, subs->from_domain, &wuri)<0)
769 769
 	{
770 770
 		LM_ERR("while constructing uri from user and domain\n");
771 771
 		goto error;
772 772
 	}
773
-	s.id= did_str;
774
-	s.watcher_uri= &wuri;
775
-	s.contact= &server_address;
776
-	s.event= get_event_flag(&subs->event->name);
777
-	if(s.event< 0)
773
+	s.id = did_str;
774
+	s.watcher_uri = &wuri;
775
+	s.contact = &rls_server_address;
776
+	s.event = get_event_flag(&subs->event->name);
777
+	if(s.event<0)
778 778
 	{
779 779
 		LM_ERR("not recognized event\n");
780 780
 		goto error;
781 781
 	}
782
-	s.expires= subs->expires;
783
-	s.source_flag= RLS_SUBSCRIBE;
784
-	if(outbound_proxy.s)
785
-		s.outbound_proxy= &outbound_proxy;
786
-	extra_headers.s= buf;
787
-	extra_headers.len= sprintf(extra_headers.s,
788
-			"Supported: eventlist\r\n");
789
-	s.extra_headers= &extra_headers;
782
+	s.expires = subs->expires;
783
+	s.source_flag = RLS_SUBSCRIBE;
784
+	if(rls_outbound_proxy.s)
785
+		s.outbound_proxy = &rls_outbound_proxy;
786
+	extra_headers.s = buf;
787
+	extra_headers.len = sprintf(extra_headers.s, "Supported: eventlist\r\n");
788
+	s.extra_headers = &extra_headers;
790 789
 	
791
-	if(process_list_and_exec(rl_node, send_resource_subs,(void*)(&s))< 0)
790
+	if(process_list_and_exec(xmlnode, send_resource_subs, (void*)(&s))<0)
792 791
 	{
793 792
 		LM_ERR("while processing list\n");
794 793
 		goto error;