Browse code

- fixed several bugs in presence handling - some reported/asigned by/to Lucian Stanescu, Norman Brandiger, Inaki Baz Castillo and Anca Vamanu (credits for hints and some fixes) - closes couple of bug tracker items

git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@5619 689a6050-402a-0410-94f2-e92a70836424

Daniel-Constantin Mierla authored on 18/02/2009 18:33:43
Showing 6 changed files
... ...
@@ -295,7 +295,8 @@ int delete_shtable(shtable_t htable,unsigned int hash_code,str to_tag)
295 295
 		{
296 296
 			found= s->local_cseq;
297 297
 			ps->next= s->next;
298
-			shm_free(s->contact.s);
298
+			if(s->contact.s!=NULL)
299
+				shm_free(s->contact.s);
299 300
 			shm_free(s);
300 301
 			break;
301 302
 		}
... ...
@@ -54,10 +54,15 @@
54 54
 #define ALLOC_SIZE 3000
55 55
 #define MAX_FORWARD 70
56 56
 
57
-c_back_param* shm_dup_cbparam(subs_t* , subs_t*);
57
+c_back_param* shm_dup_cbparam(subs_t*);
58 58
 void free_cbparam(c_back_param* cb_param);
59 59
 
60 60
 void p_tm_callback( struct cell *t, int type, struct tmcb_params *ps);
61
+int add_waiting_watchers(watcher_t *watchers, str pres_uri, str event);
62
+int add_watcher_list(subs_t *s, watcher_t *watchers);
63
+str* create_winfo_xml(watcher_t* watchers, char* version,
64
+		str resource, str event, int STATE_FLAG);
65
+void free_watcher_list(watcher_t* watchers);
61 66
 
62 67
 str str_to_user_col = str_init("to_user");
63 68
 str str_username_col = str_init("username");
... ...
@@ -95,6 +100,7 @@ char* get_status_str(int status_flag)
95 100
 		case ACTIVE_STATUS: return "active";
96 101
 		case PENDING_STATUS: return "pending";
97 102
 		case TERMINATED_STATUS: return "terminated";
103
+		case WAITING_STATUS: return "waiting";
98 104
 	}
99 105
 	return NULL;
100 106
 }
... ...
@@ -114,147 +120,142 @@ void printf_subs(subs_t* subs)
114 120
 		subs->to_tag.s,subs->from_tag.len, subs->from_tag.s,subs->contact.len,
115 121
 		subs->contact.s,subs->record_route.len,subs->record_route.s);
116 122
 }
117
-str* create_winfo_xml(watcher_t* watchers, char* version,str resource, int STATE_FLAG );
118 123
 
119
-int build_str_hdr(subs_t* subs, int is_body, str** hdr)
124
+int build_str_hdr(subs_t* subs, int is_body, str* hdr)
120 125
 {
121
-	str* str_hdr = NULL;	
122
-	char* subs_expires = NULL;
123
-	int len = 0;
124 126
 	pres_ev_t* event= subs->event;
125
-	int expires_t;
126
-	char* status= NULL;
127
+	str expires = {0, 0};
128
+	str status = {0, 0};
129
+	str tmp = {0, 0};
127 130
 
128
-	str_hdr =(str*)pkg_malloc(sizeof(str));
129
-	if(str_hdr== NULL)
131
+	if(hdr == NULL)
130 132
 	{
131
-		LM_ERR("while allocating memory\n");
133
+		LM_ERR("bad parameter\n");
132 134
 		return -1;
133 135
 	}
134
-	memset(str_hdr, 0, sizeof(str));
135
-
136
-	str_hdr->s = (char*)pkg_malloc(ALLOC_SIZE* sizeof(char));
137
-	if(str_hdr->s== NULL)
136
+	expires.s = int2str(subs->expires, &expires.len);
137
+	status.s= get_status_str(subs->status);
138
+	if(status.s == NULL)
138 139
 	{
139
-		LM_ERR("while allocating memory\n");
140
-		pkg_free(str_hdr);
140
+		LM_ERR("bad status %d\n", subs->status);
141 141
 		return -1;
142
-	}	
142
+	}
143
+	status.len = strlen(status.s);
143 144
 
144
-	strncpy(str_hdr->s ,"Max-Forwards: ", 14);
145
-	str_hdr->len = 14;
146
-	len= sprintf(str_hdr->s+str_hdr->len, "%d", MAX_FORWARD);
147
-	if(len<= 0)
145
+	hdr->len = 18 /*Max-Forwards:  + val*/ + CRLF_LEN + 
146
+		7 /*Event: */ + subs->event->name.len +4 /*;id=*/+ subs->event_id.len+
147
+		CRLF_LEN + 10 /*Contact: <*/ + subs->local_contact.len + 1/*>*/ +
148
+		15/*";transport=xxxx"*/ + CRLF_LEN + 20 /*Subscription-State: */ +
149
+		status.len + 10 /*reason/expires params*/
150
+		+ (subs->reason.len>expires.len?subs->reason.len:expires.len)
151
+		+ CRLF_LEN + (is_body?
152
+		(14 /*Content-Type: */+subs->event->content_type.len + CRLF_LEN):0) + 1;
153
+
154
+	hdr->s = (char*)pkg_malloc(hdr->len);
155
+	if(hdr->s == NULL)
148 156
 	{
149
-		LM_ERR("while printing in string\n");
150
-		pkg_free(str_hdr->s);
151
-		pkg_free(str_hdr);
157
+		LM_ERR("no more pkg\n");
152 158
 		return -1;
153
-	}	
154
-	str_hdr->len+= len; 
155
-	strncpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
156
-	str_hdr->len += CRLF_LEN;
157
-
158
-	strncpy(str_hdr->s+str_hdr->len  ,"Event: ", 7);
159
-	str_hdr->len+= 7;
160
-	strncpy(str_hdr->s+str_hdr->len, event->name.s, event->name.len);
161
-	str_hdr->len+= event->name.len;
159
+	}
160
+
161
+	strncpy(hdr->s, "Max-Forwards: ", 14);
162
+	tmp.s = int2str((unsigned long)MAX_FORWARD, &tmp.len);
163
+	strncpy(hdr->s+14, tmp.s, tmp.len);
164
+	tmp.s = hdr->s + tmp.len + 14;
165
+	strncpy(tmp.s, CRLF, CRLF_LEN);
166
+	tmp.s += CRLF_LEN;
167
+
168
+	strncpy(tmp.s  ,"Event: ", 7);
169
+	tmp.s += 7;
170
+	strncpy(tmp.s, event->name.s, event->name.len);
171
+	tmp.s += event->name.len;
162 172
 	if(subs->event_id.len && subs->event_id.s) 
163 173
 	{
164
- 		strncpy(str_hdr->s+str_hdr->len, ";id=", 4);
165
- 		str_hdr->len += 4;
166
- 		strncpy(str_hdr->s+str_hdr->len, subs->event_id.s, subs->event_id.len);
167
- 		str_hdr->len += subs->event_id.len;
174
+ 		strncpy(tmp.s, ";id=", 4);
175
+ 		tmp.s += 4;
176
+ 		strncpy(tmp.s, subs->event_id.s, subs->event_id.len);
177
+ 		tmp.s += subs->event_id.len;
168 178
  	}
169
-	strncpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
170
-	str_hdr->len += CRLF_LEN;
171
-
172
-	strncpy(str_hdr->s+str_hdr->len ,"Contact: <", 10);
173
-	str_hdr->len += 10;
174
-	strncpy(str_hdr->s+str_hdr->len, subs->local_contact.s, subs->local_contact.len);
175
-	str_hdr->len +=  subs->local_contact.len;
176
-	strncpy(str_hdr->s+str_hdr->len, ">", 1);
177
-	str_hdr->len += 1;
178
-	strncpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
179
-	str_hdr->len += CRLF_LEN;
180
-	
181
-	strncpy(str_hdr->s+str_hdr->len,"Subscription-State: ", 20);
182
-	str_hdr->len+= 20;
183
-	status= get_status_str(subs->status);
184
-	if(status== NULL)
185
-	{
186
-		LM_ERR("bad status flag= %d\n", subs->status);
187
-		pkg_free(str_hdr->s);
188
-		pkg_free(str_hdr);
189
-		return -1;
179
+	strncpy(tmp.s, CRLF, CRLF_LEN);
180
+	tmp.s += CRLF_LEN;
181
+
182
+	strncpy(tmp.s, "Contact: <", 10);
183
+	tmp.s += 10;
184
+	strncpy(tmp.s, subs->local_contact.s, subs->local_contact.len);
185
+	tmp.s +=  subs->local_contact.len;
186
+	if(subs->sockinfo_str.s!=NULL)
187
+	{
188
+		/* fix me */
189
+		switch(subs->sockinfo_str.s[0]) {
190
+			case 's':
191
+			case 'S':
192
+				strncpy(tmp.s, ";transport=sctp", 15);
193
+				tmp.s += 15;
194
+			break;
195
+			case 't':
196
+			case 'T':
197
+				switch(subs->sockinfo_str.s[1]) {
198
+					case 'c':
199
+					case 'C':
200
+						strncpy(tmp.s, ";transport=tcp", 14);
201
+						tmp.s += 14;
202
+					break;
203
+					case 'l':
204
+					case 'L':
205
+						strncpy(tmp.s, ";transport=tls", 14);
206
+						tmp.s += 14;
207
+					break;
208
+				}
209
+			break;
210
+		}
190 211
 	}
191
-	strcpy(str_hdr->s+str_hdr->len, status);
192
-	str_hdr->len+= strlen(status);
212
+	*tmp.s =  '>';
213
+	tmp.s++;
214
+	strncpy(tmp.s, CRLF, CRLF_LEN);
215
+	tmp.s += CRLF_LEN;
193 216
 	
194
-	expires_t= subs->expires;
217
+	strncpy(tmp.s, "Subscription-State: ", 20);
218
+	tmp.s += 20;
219
+	strncpy(tmp.s, status.s, status.len);
220
+	tmp.s += status.len;
195 221
 	
196
-	if(subs->status== TERMINATED_STATUS)
222
+	if(subs->status == TERMINATED_STATUS)
197 223
 	{
198 224
 		LM_DBG("state = terminated\n");
199 225
 		
200
-		strncpy(str_hdr->s+str_hdr->len,";reason=", 8);
201
-		str_hdr->len+= 8;
202
-		strncpy(str_hdr->s+str_hdr->len, subs->reason.s ,subs->reason.len );
203
-		str_hdr->len+= subs->reason.len;
204
-		strncpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
205
-		str_hdr->len+= CRLF_LEN;
206
-	}
207
-	else
208
-	{	
209
-		strncpy(str_hdr->s+str_hdr->len,";expires=", 9);
210
-		str_hdr->len+= 9;
211
-	
212
-		subs_expires= int2str(expires_t, &len); 
213
-
214
-		if(subs_expires == NULL || len == 0)
215
-		{
216
-			LM_ERR("converting int to str\n");
217
-			pkg_free(str_hdr->s);
218
-			pkg_free(str_hdr);
219
-			return -1;
220
-		}
221
-
222
-		LM_DBG("expires = %d\n", expires_t);
223
-
224
-		strncpy(str_hdr->s+str_hdr->len,subs_expires ,len );
225
-		str_hdr->len += len;
226
-		strncpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
227
-		str_hdr->len += CRLF_LEN;
228
-	}
226
+		strncpy(tmp.s, ";reason=", 8);
227
+		tmp.s += 8;
228
+		strncpy(tmp.s, subs->reason.s, subs->reason.len);
229
+		tmp.s += subs->reason.len;
230
+	} else {	
231
+		strncpy(tmp.s, ";expires=", 9);
232
+		tmp.s += 9;
233
+		LM_DBG("expires = %d\n", subs->expires);
234
+		strncpy(tmp.s, expires.s, expires.len);
235
+		tmp.s += expires.len;
236
+	}
237
+	strncpy(tmp.s, CRLF, CRLF_LEN);
238
+	tmp.s += CRLF_LEN;
229 239
 	
230 240
 	if(is_body)
231 241
 	{	
232
-		strncpy(str_hdr->s+str_hdr->len,"Content-Type: ", 14);
233
-		str_hdr->len += 14;
234
-		strncpy(str_hdr->s+str_hdr->len, event->content_type.s , event->content_type.len);
235
-		str_hdr->len += event->content_type.len;
236
-		strncpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN);
237
-		str_hdr->len += CRLF_LEN;
242
+		strncpy(tmp.s,"Content-Type: ", 14);
243
+		tmp.s += 14;
244
+		strncpy(tmp.s, event->content_type.s, event->content_type.len);
245
+		tmp.s += event->content_type.len;
246
+		strncpy(tmp.s, CRLF, CRLF_LEN);
247
+		tmp.s += CRLF_LEN;
238 248
 	}
239 249
 	
240
-	if(str_hdr->len> ALLOC_SIZE)
241
-	{
242
-		LM_ERR("buffer size overflown\n");
243
-		pkg_free(str_hdr->s);
244
-		pkg_free(str_hdr);
245
-		return -1;
246
-
247
-	}
248
-	str_hdr->s[str_hdr->len] = '\0';
249
-	*hdr= str_hdr;
250
+	*tmp.s = '\0';
251
+	hdr->len = tmp.s - hdr->s;
250 252
 
251 253
 	return 0;
252
-
253 254
 }
254 255
 
255
-int get_wi_subs_db(subs_t* subs, watcher_t** watchers)
256
+int get_wi_subs_db(subs_t* subs, watcher_t* watchers)
256 257
 {	
257
-	watcher_t *w;
258
+	subs_t sb;
258 259
 	db_key_t query_cols[6];
259 260
 	db_op_t  query_ops[6];
260 261
 	db_val_t query_vals[6];
... ...
@@ -265,8 +266,7 @@ int get_wi_subs_db(subs_t* subs, watcher_t** watchers)
265 266
 	int n_result_cols = 0;
266 267
 	int n_query_cols = 0;
267 268
 	int i;
268
-	int status_col, expires_col, from_user_col, from_domain_col;
269
-	str from_user, from_domain;
269
+	int status_col, expires_col, from_user_col, from_domain_col, callid_col;
270 270
 
271 271
 	query_cols[n_query_cols] = &str_presentity_uri_col;
272 272
 	query_ops[n_query_cols] = OP_EQ;
... ...
@@ -286,6 +286,7 @@ int get_wi_subs_db(subs_t* subs, watcher_t** watchers)
286 286
 	result_cols[expires_col=n_result_cols++] = &str_expires_col;
287 287
 	result_cols[from_user_col=n_result_cols++] = &str_watcher_username_col;
288 288
 	result_cols[from_domain_col=n_result_cols++] = &str_watcher_domain_col;
289
+	result_cols[callid_col=n_result_cols++] = &str_callid_col;
289 290
 
290 291
 	if (pa_dbf.use_table(pa_db, &active_watchers_table) < 0) 
291 292
 	{
... ...
@@ -318,40 +319,21 @@ int get_wi_subs_db(subs_t* subs, watcher_t** watchers)
318 319
 		row = &result->rows[i];
319 320
 		row_vals = ROW_VALUES(row);
320 321
 		
321
-		from_user.s= (char*)row_vals[from_user_col].val.string_val;
322
-		from_user.len= strlen(from_user.s);
322
+		sb.from_user.s= (char*)row_vals[from_user_col].val.string_val;
323
+		sb.from_user.len= strlen(sb.from_user.s);
323 324
 
324
-		from_domain.s= (char*)row_vals[from_domain_col].val.string_val;
325
-		from_domain.len= strlen(from_domain.s);
325
+		sb.from_domain.s= (char*)row_vals[from_domain_col].val.string_val;
326
+		sb.from_domain.len= strlen(sb.from_domain.s);
326 327
 
327
-		w= (watcher_t*)pkg_malloc(sizeof(watcher_t));
328
-		if(w== NULL)
329
-		{
330
-			ERR_MEM(PKG_MEM_STR);
331
-		}
332
-		w->status= row_vals[status_col].val.int_val;
333
-		if(uandd_to_uri(from_user, from_domain, &w->uri)<0)
334
-	 	{
335
-			pkg_free(w);
336
-   			LM_ERR("creating uri\n");
337
-   			goto error;
338
-   		}
339
-		w->id.s = (char*)pkg_malloc(w->uri.len*2 +1);
340
-		if(w->id.s== NULL)
341
-		{
342
-			pkg_free(w->uri.s);
343
-			pkg_free(w);
344
-			ERR_MEM(PKG_MEM_STR);
345
-		}
328
+		sb.callid.s= (char*)row_vals[callid_col].val.string_val;
329
+		sb.callid.len= strlen(sb.callid.s);
346 330
 
347
-		to64frombits((unsigned char *)w->id.s,
348
-   			(const unsigned char*)w->uri.s, w->uri.len);
349
-   
350
-   		w->id.len = strlen(w->id.s);
351
-  		w->event= subs->event->wipeer->name;
331
+		sb.event =subs->event->wipeer;
332
+		sb.status= row_vals[status_col].val.int_val;
352 333
 		
353
-		w->next= (*watchers)->next;
354
-		(*watchers)->next= w;
334
+		if(add_watcher_list(&sb, watchers)<0)
335
+			goto error;
336
+
355 337
 	}
356 338
 	
357 339
 	pa_dbf.free_result(pa_db, result);
... ...
@@ -367,18 +349,12 @@ str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs)
367 349
 {
368 350
 	str* notify_body = NULL;
369 351
 	char* version_str;
370
-	watcher_t *watchers = NULL, *w= NULL;
352
+	watcher_t *watchers = NULL;
371 353
 	int len = 0;
372 354
 	unsigned int hash_code;
373 355
 	subs_t* s= NULL;
374 356
 	int state = FULL_STATE_FLAG;
375 357
 
376
-	if(!subs->event->wipeer) {
377
-		LM_ERR("can not create NOTIFY body as wipeer not defined for event [%.*s]\n ",
378
-			subs->event->name.len, subs->event->name.s);
379
-		return NULL;
380
-	}
381
-
382 358
 	hash_code = 0;
383 359
 	version_str = int2str(subs->version, &len);
384 360
 	if(version_str ==NULL)
... ...
@@ -396,39 +372,8 @@ str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs)
396 372
 
397 373
 	if(watcher_subs != NULL) 
398 374
 	{		
399
-		w= (watcher_t *)pkg_malloc(sizeof(watcher_t));
400
-		if(w== NULL)
401
-		{
402
-			ERR_MEM(PKG_MEM_STR);
403
-		}
404
-		memset(w, 0, sizeof(watcher_t));
405
-
406
-		w->status= watcher_subs->status;
407
-		uandd_to_uri( watcher_subs->from_user,watcher_subs->from_domain,
408
-						&w->uri);
409
-		if(w->uri.s== NULL)
410
-		{
411
-			pkg_free(w);
375
+		if(add_watcher_list(watcher_subs, watchers)< 0)
412 376
 			goto error;
413
-		}
414
-
415
-		w->id.s = (char *)pkg_malloc(w->uri.len *2 +1);
416
-		if(w->id.s== NULL)
417
-		{
418
-			pkg_free(w->uri.s);
419
-			pkg_free(w);
420
-			ERR_MEM(PKG_MEM_STR);
421
-		}
422
-		to64frombits((unsigned char *)w->id.s,
423
-				(const unsigned char*)w->uri.s, w->uri.len );
424
-			
425
-		w->id.len = strlen(w->id.s);
426
-		
427
-		w->event= watcher_subs->event->name;
428
-		
429
-		w->next= watchers->next;
430
-		watchers->next= w;
431
-
432 377
 		state = PARTIAL_STATE_FLAG;
433 378
 
434 379
 		goto done;
... ...
@@ -436,7 +381,7 @@ str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs)
436 381
 
437 382
 	if(fallback2db)
438 383
 	{
439
-		if(get_wi_subs_db(subs, &watchers)< 0)
384
+		if(get_wi_subs_db(subs, watchers)< 0)
440 385
 		{
441 386
 			LM_ERR("getting watchers from database\n");
442 387
 			goto error;
... ...
@@ -469,43 +414,24 @@ str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs)
469 414
 			s->pres_uri.len== subs->pres_uri.len &&
470 415
 			strncmp(s->pres_uri.s, subs->pres_uri.s,subs->pres_uri.len)== 0)
471 416
 		{
472
-			w= (watcher_t*)pkg_malloc(sizeof(watcher_t));
473
-			if(w== NULL)
417
+			if(add_watcher_list(s, watchers)< 0)
474 418
 			{
475 419
 				lock_release(&subs_htable[hash_code].lock);
476
-				ERR_MEM(PKG_MEM_STR);
477
-			}
478
-			w->status= s->status;
479
-			if(uandd_to_uri(s->from_user, s->from_domain, &w->uri)<0)
480
-	 		{
481
-				lock_release(&subs_htable[hash_code].lock);
482
-				pkg_free(w);
483
-   				LM_ERR("creating uri\n");
484
-   				goto error;
485
-   			}
486
-			w->id.s = (char*)pkg_malloc(w->uri.len*2 +1);
487
-			if(w->id.s== NULL)
488
-			{
489
-				lock_release(&subs_htable[hash_code].lock);
490
-				pkg_free(w->uri.s);
491
-				pkg_free(w);
492
-				ERR_MEM(PKG_MEM_STR);
420
+				goto error;
493 421
 			}
494
-
495
-			to64frombits((unsigned char *)w->id.s,
496
-   				(const unsigned char*)w->uri.s, w->uri.len);
497
-   
498
-   			w->id.len = strlen(w->id.s);
499
-  			w->event= subs->event->wipeer->name;
500
-		
501
-			w->next= watchers->next;
502
-			watchers->next= w;
503 422
 		}
504 423
 	}
505 424
 	
425
+	if(add_waiting_watchers(watchers, subs->pres_uri,
426
+				subs->event->wipeer->name)< 0 )
427
+	{
428
+		LM_ERR("failed to add waiting watchers\n");
429
+		goto error;
430
+	}
431
+
506 432
 done:
507 433
 	notify_body = create_winfo_xml(watchers,version_str,subs->pres_uri,
508
-			state );
434
+			subs->event->wipeer->name, state);
509 435
 	
510 436
 	if(watcher_subs == NULL) 
511 437
 		lock_release(&subs_htable[hash_code].lock);
... ...
@@ -515,16 +441,7 @@ done:
515 441
 		LM_ERR("in function create_winfo_xml\n");
516 442
 		goto error;
517 443
 	}
518
-	while(watchers)
519
-	{	
520
-		w= watchers;
521
-		if(w->uri.s !=NULL)
522
-			pkg_free(w->uri.s);
523
-		if(w->id.s !=NULL)
524
-			pkg_free(w->id.s);
525
-		watchers= watchers->next;
526
-		pkg_free(w);
527
-	}
444
+	free_watcher_list(watchers);
528 445
 	return notify_body;
529 446
 
530 447
 error:
... ...
@@ -534,6 +451,13 @@ error:
534 451
 			xmlFree(notify_body->s);
535 452
 		pkg_free(notify_body);
536 453
 	}
454
+	free_watcher_list(watchers);
455
+	return NULL;
456
+}
457
+
458
+void free_watcher_list(watcher_t* watchers)
459
+{
460
+	watcher_t* w;
537 461
 	while(watchers)
538 462
 	{	
539 463
 		w= watchers;
... ...
@@ -544,8 +468,47 @@ error:
544 468
 		watchers= watchers->next;
545 469
 		pkg_free(w);
546 470
 	}
471
+}
547 472
 
548
-	return NULL;
473
+int add_watcher_list(subs_t *s, watcher_t *watchers)
474
+{
475
+	watcher_t* w;
476
+
477
+	w= (watcher_t*)pkg_malloc(sizeof(watcher_t));
478
+	if(w== NULL)
479
+	{
480
+		LM_ERR("No more private memory\n");
481
+		return -1;
482
+	}
483
+	w->status= s->status;
484
+	if(uandd_to_uri(s->from_user, s->from_domain, &w->uri)<0)
485
+	{
486
+		LM_ERR("failed to create uri\n");
487
+		goto error;
488
+	}
489
+	w->id.s = (char*)pkg_malloc(s->callid.len+ 1);
490
+	if(w->id.s == NULL)
491
+	{
492
+		LM_ERR("no more memory\n");
493
+		goto error;
494
+	}
495
+	memcpy(w->id.s, s->callid.s, s->callid.len);
496
+	w->id.len = s->callid.len;
497
+	w->id.s[w->id.len] = '\0';
498
+
499
+	w->next= watchers->next;
500
+	watchers->next= w;
501
+
502
+	return 0;
503
+
504
+error:
505
+	if(w)
506
+	{
507
+		if(w->uri.s)
508
+			pkg_free(w->uri.s);
509
+		pkg_free(w);
510
+	}
511
+	return -1;
549 512
 }
550 513
 
551 514
 str* build_empty_bla_body(str pres_uri)
... ...
@@ -1067,16 +1030,19 @@ int get_subs_db(str* pres_uri, pres_ev_t* event, str* sender,
1067 1030
 	query_vals[n_query_cols].val.int_val = ACTIVE_STATUS;
1068 1031
 	n_query_cols++;
1069 1032
 
1033
+	query_cols[n_query_cols] = &str_contact_col;
1034
+	query_ops[n_query_cols] = OP_NEQ;
1035
+	query_vals[n_query_cols].type = DB_STR;
1036
+	query_vals[n_query_cols].nul = 0;
1070 1037
 	if(sender)
1071 1038
 	{	
1072 1039
 		LM_DBG("Do not send Notify to:[uri]= %.*s\n",sender->len,sender->s);
1073
-		query_cols[n_query_cols] = &str_contact_col;
1074
-		query_ops[n_query_cols] = OP_NEQ;
1075
-		query_vals[n_query_cols].type = DB_STR;
1076
-		query_vals[n_query_cols].nul = 0;
1077 1040
 		query_vals[n_query_cols].val.str_val = *sender;
1078
-		n_query_cols++;
1041
+	} else {
1042
+		query_vals[n_query_cols].val.str_val.s = "";
1043
+		query_vals[n_query_cols].val.str_val.len = 0;
1079 1044
 	}
1045
+	n_query_cols++;
1080 1046
 
1081 1047
 	result_cols[to_user_col=n_result_cols++]      =   &str_to_user_col;
1082 1048
 	result_cols[to_domain_col=n_result_cols++]    =   &str_to_domain_col;
... ...
@@ -1361,11 +1327,11 @@ int publ_notify(presentity_t* p, str pres_uri, str* body, str* offline_etag, str
1361 1327
 	s= subs_array;
1362 1328
 	while(s)
1363 1329
 	{
1330
+		s->auth_rules_doc= rules_doc;
1364 1331
 		if (p->event->aux_body_processing) {
1365 1332
 			aux_body = p->event->aux_body_processing(s, notify_body?notify_body:body);
1366 1333
 		}
1367 1334
 
1368
-		s->auth_rules_doc= rules_doc;
1369 1335
 		if(notify(s, NULL, aux_body?aux_body:(notify_body?notify_body:body), 0)< 0 )
1370 1336
 		{
1371 1337
 			LM_ERR("Could not send notify for %.*s\n",
... ...
@@ -1475,7 +1441,7 @@ int send_notify_request(subs_t* subs, subs_t * watcher_subs,
1475 1441
 {
1476 1442
 	dlg_t* td = NULL;
1477 1443
 	str met = {"NOTIFY", 6};
1478
-	str* str_hdr = NULL;
1444
+	str str_hdr = {0, 0};
1479 1445
 	str* notify_body = NULL;
1480 1446
 	int result= 0;
1481 1447
     c_back_param *cb_param= NULL;
... ...
@@ -1496,11 +1462,13 @@ int send_notify_request(subs_t* subs, subs_t * watcher_subs,
1496 1462
 		if( subs->event->req_auth)
1497 1463
 		{
1498 1464
 			
1499
-			if(subs->auth_rules_doc && subs->event->apply_auth_nbody &&
1500
-				subs->event->apply_auth_nbody(n_body, subs, &notify_body)< 0)
1465
+			if(subs->auth_rules_doc && subs->event->apply_auth_nbody)
1501 1466
 			{
1502
-				LM_ERR("in function apply_auth_nbody\n");
1503
-				goto error;
1467
+				if(subs->event->apply_auth_nbody(n_body, subs, &notify_body)< 0)
1468
+				{
1469
+					LM_ERR("in function apply_auth_nbody\n");
1470
+					goto error;
1471
+				}
1504 1472
 			}
1505 1473
 			if(notify_body== NULL)
1506 1474
 				notify_body= n_body;
... ...
@@ -1530,7 +1498,7 @@ int send_notify_request(subs_t* subs, subs_t * watcher_subs,
1530 1498
 			else
1531 1499
 			{
1532 1500
 				notify_body = get_p_notify_body(subs->pres_uri,
1533
-						subs->event, NULL, (subs->contact.s)?&subs->contact:NULL);
1501
+					subs->event, NULL, (subs->contact.s)?&subs->contact:NULL);
1534 1502
 				if(notify_body == NULL || notify_body->s== NULL)
1535 1503
 				{
1536 1504
 					LM_DBG("Could not get the notify_body\n");
... ...
@@ -1539,8 +1507,9 @@ int send_notify_request(subs_t* subs, subs_t * watcher_subs,
1539 1507
 				if(subs->event->req_auth)
1540 1508
 				{
1541 1509
 					 
1542
-					if(subs->auth_rules_doc && subs->event->apply_auth_nbody &&
1543
-					subs->event->apply_auth_nbody(notify_body,subs,&final_body)<0)
1510
+					if(subs->auth_rules_doc && subs->event->apply_auth_nbody
1511
+							&& subs->event->apply_auth_nbody(notify_body,
1512
+								subs,&final_body)<0)
1544 1513
 					{
1545 1514
 						LM_ERR("in function apply_auth\n");
1546 1515
 						goto error;
... ...
@@ -1572,7 +1541,7 @@ jump_over_body:
1572 1541
 		LM_ERR("while building headers\n");
1573 1542
 		goto error;
1574 1543
 	}	
1575
-	LM_DBG("headers:\n%.*s\n", str_hdr->len, str_hdr->s);
1544
+	LM_DBG("headers:\n%.*s\n", str_hdr.len, str_hdr.s);
1576 1545
 
1577 1546
 	/* construct the dlg_t structure */
1578 1547
 	td = build_dlg_t(subs);
... ...
@@ -1582,25 +1551,22 @@ jump_over_body:
1582 1551
 		goto error;	
1583 1552
 	}
1584 1553
 
1585
-	if(subs->event->type == WINFO_TYPE && watcher_subs )
1586
-	{
1587
-		LM_DBG("Send notify for presence on callback\n");
1588
-		watcher_subs->send_on_cback = 1;			
1589
-	}
1590
-	cb_param = shm_dup_cbparam(watcher_subs, subs);
1554
+	cb_param = shm_dup_cbparam(subs);
1591 1555
 	if(cb_param == NULL)
1592 1556
 	{
1593 1557
 		LM_ERR("while duplicating cb_param in share memory\n");
1594 1558
 		goto error;	
1595 1559
 	}	
1596 1560
 
1561
+	LM_ERR("before tmb.t_request_within\n");
1597 1562
 	result = tmb.t_request_within
1598 1563
 		(&met,              /* method*/
1599
-		str_hdr,            /* extra headers*/
1564
+		&str_hdr,           /* extra headers*/
1600 1565
 		notify_body,        /* body*/
1601 1566
 		td,                 /* dialog structure*/
1602 1567
 		p_tm_callback,      /* callback function*/
1603 1568
 		(void*)cb_param);   /* callback parameter*/
1569
+	LM_ERR("after tmb.t_request_within\n");
1604 1570
 
1605 1571
 	if(result< 0)
1606 1572
 	{
... ...
@@ -1610,13 +1576,14 @@ jump_over_body:
1610 1576
 	}
1611 1577
 
1612 1578
 	LM_INFO("NOTIFY %.*s via %.*s on behalf of %.*s for event %.*s\n",
1613
-		td->rem_uri.len, td->rem_uri.s, td->hooks.next_hop->len, td->hooks.next_hop->s,
1614
-		td->loc_uri.len, td->loc_uri.s, subs->event->name.len, subs->event->name.s);
1579
+		td->rem_uri.len, td->rem_uri.s, td->hooks.next_hop->len,
1580
+		td->hooks.next_hop->s,
1581
+		td->loc_uri.len, td->loc_uri.s, subs->event->name.len,
1582
+		subs->event->name.s);
1615 1583
 
1616 1584
 	free_tm_dlg(td);
1617 1585
 	
1618
-	pkg_free(str_hdr->s);
1619
-	pkg_free(str_hdr);
1586
+	if(str_hdr.s) pkg_free(str_hdr.s);
1620 1587
 	
1621 1588
 	if((int)(long)n_body!= (int)(long)notify_body)
1622 1589
 	{
... ...
@@ -1627,7 +1594,8 @@ jump_over_body:
1627 1594
 				if(subs->event->type& WINFO_TYPE )
1628 1595
 					xmlFree(notify_body->s);
1629 1596
 				else
1630
-				if(subs->event->apply_auth_nbody== NULL && subs->event->agg_nbody== NULL)
1597
+				if(subs->event->apply_auth_nbody== NULL
1598
+						&& subs->event->agg_nbody== NULL)
1631 1599
 					pkg_free(notify_body->s);
1632 1600
 				else
1633 1601
 				subs->event->free_body(notify_body->s);
... ...
@@ -1639,12 +1607,8 @@ jump_over_body:
1639 1607
 
1640 1608
 error:
1641 1609
 	free_tm_dlg(td);
1642
-	if(str_hdr!=NULL)
1643
-	{
1644
-		if(str_hdr->s)
1645
-			pkg_free(str_hdr->s);
1646
-		pkg_free(str_hdr);
1647
-	}
1610
+	if(str_hdr.s!=NULL)
1611
+		pkg_free(str_hdr.s);
1648 1612
 	if((int)(long)n_body!= (int)(long)notify_body)
1649 1613
 	{
1650 1614
 		if(notify_body!=NULL)
... ...
@@ -1654,7 +1618,8 @@ error:
1654 1618
 				if(subs->event->type& WINFO_TYPE)
1655 1619
 					xmlFree(notify_body->s);
1656 1620
 				else
1657
-				if(subs->event->apply_auth_nbody== NULL && subs->event->agg_nbody== NULL)
1621
+				if(subs->event->apply_auth_nbody== NULL
1622
+						&& subs->event->agg_nbody== NULL)
1658 1623
 					pkg_free(notify_body->s);
1659 1624
 				else
1660 1625
 				subs->event->free_body(notify_body->s);
... ...
@@ -1735,111 +1700,52 @@ void p_tm_callback( struct cell *t, int type, struct tmcb_params *ps)
1735 1700
 
1736 1701
 		delete_db_subs(cb->pres_uri, cb->ev_name, cb->to_tag);
1737 1702
 	}	
1738
-	/* send a more accurate Notify for presence depending on the reply for winfo*/
1739
-	if(((c_back_param*)(*ps->param))->wi_subs!= NULL)
1740
-	{
1741
-		/* if an error message is received as a reply for the winfo Notify 
1742
-	  * send a Notify for presence with no body (the stored presence information is 
1743
-	  * not valid ) */
1744
-
1745
-		if(ps->code >= 408)
1746
-		{
1747
-			if(notify( ((c_back_param*)(*ps->param))->wi_subs, NULL,NULL,1)< 0)
1748
-			{
1749
-				LM_ERR("Could not send notify for presence\n");
1750
-			}
1751
-		}
1752
-		else
1753
-		{
1754
-			if(notify( ((c_back_param*)(*ps->param))->wi_subs, NULL,NULL,0)< 0)
1755
-			{
1756
-				LM_ERR("Could not send notify for presence\n");
1757
-			}
1758
-		}	
1759
-	}
1760
-	else
1761
-		LM_DBG("Empty wi_subs parameter\n");
1762 1703
 
1763 1704
 	if(*ps->param !=NULL  )
1764 1705
 		free_cbparam((c_back_param*)(*ps->param));
1765 1706
 	return ;
1766
-
1767 1707
 }
1768 1708
 
1769 1709
 void free_cbparam(c_back_param* cb_param)
1770 1710
 {
1771 1711
 	if(cb_param!= NULL)
1772
-	{
1773
-		if(cb_param->pres_uri.s)
1774
-			shm_free(cb_param->pres_uri.s);
1775
-		if(cb_param->ev_name.s)
1776
-			shm_free(cb_param->ev_name.s);
1777
-		if(cb_param->wi_subs)
1778
-			shm_free(cb_param->wi_subs);
1779
-		if(cb_param->to_tag.s)
1780
-			shm_free(cb_param->to_tag.s);
1781 1712
 		shm_free(cb_param);
1782
-	}
1783
-
1784 1713
 }
1785 1714
 
1786
-c_back_param* shm_dup_cbparam(subs_t* w_subs, subs_t* subs)
1715
+c_back_param* shm_dup_cbparam(subs_t* subs)
1787 1716
 {
1717
+	int size;
1788 1718
 	c_back_param* cb_param = NULL;
1719
+	
1720
+	size = sizeof(c_back_param) + subs->pres_uri.len+
1721
+			subs->event->name.len + subs->to_tag.len;
1789 1722
 
1790
-	cb_param= (c_back_param*)shm_malloc(sizeof(c_back_param));
1791
-	if(cb_param== NULL)
1723
+	cb_param= (c_back_param*)shm_malloc(size);
1724
+	LM_DBG("=== %d/%d/%d\n", subs->pres_uri.len,
1725
+			subs->event->name.len, subs->to_tag.len);
1726
+	if(cb_param==NULL)
1792 1727
 	{
1793
-		ERR_MEM(SHM_MEM_STR);
1728
+		LM_ERR("no more shared memory\n");
1729
+		return NULL;
1794 1730
 	}
1795
-	memset(cb_param, 0, sizeof(c_back_param));
1731
+	memset(cb_param, 0, size);
1796 1732
 
1797
-	cb_param->pres_uri.s= (char*)shm_malloc(subs->pres_uri.len* sizeof(char));
1798
-	if(cb_param->pres_uri.s== NULL)
1799
-	{
1800
-		ERR_MEM(SHM_MEM_STR);
1801
-	}
1733
+	cb_param->pres_uri.s = (char*)cb_param + sizeof(c_back_param);
1802 1734
 	memcpy(cb_param->pres_uri.s, subs->pres_uri.s, subs->pres_uri.len);
1803
-	cb_param->pres_uri.len= subs->pres_uri.len;
1735
+	cb_param->pres_uri.len = subs->pres_uri.len;
1736
+	cb_param->ev_name.s = (char*)(cb_param->pres_uri.s) + cb_param->pres_uri.len;
1737
+	memcpy(cb_param->ev_name.s, subs->event->name.s, subs->event->name.len);
1738
+	cb_param->ev_name.len = subs->event->name.len;
1739
+	cb_param->to_tag.s = (char*)(cb_param->ev_name.s) + cb_param->ev_name.len;
1740
+	memcpy(cb_param->to_tag.s, subs->to_tag.s, subs->to_tag.len);
1741
+	cb_param->to_tag.len = subs->to_tag.len;
1804 1742
 
1805
-	cb_param->ev_name.s= (char*)shm_malloc
1806
-			(subs->event->name.len* sizeof(char));
1807
-	if(cb_param->ev_name.s== NULL)
1808
-	{
1809
-		ERR_MEM(SHM_MEM_STR);
1810
-	}
1811
-	memcpy(cb_param->ev_name.s, subs->event->name.s,
1812
-			subs->event->name.len);
1813
-	cb_param->ev_name.len= subs->event->name.len;
1814
-
1815
-	cb_param->to_tag.s= (char*)shm_malloc(subs->to_tag.len*sizeof(char));
1816
-	if(cb_param->to_tag.s== NULL)
1817
-	{
1818
-		ERR_MEM(SHM_MEM_STR);
1819
-	}
1820
-	memcpy(cb_param->to_tag.s, subs->to_tag.s ,subs->to_tag.len) ;
1821
-	cb_param->to_tag.len= subs->to_tag.len;
1822
-
1823
-	if(w_subs && w_subs->send_on_cback)
1824
-	{
1825
-		cb_param->wi_subs= mem_copy_subs(w_subs, SHM_MEM_TYPE);
1826
-		if(cb_param->wi_subs== NULL)
1827
-		{
1828
-			LM_ERR("copying subs_t structure in share memory\n");
1829
-			goto error;
1830
-		}
1831
-	}
1832
-	
1833 1743
 	return cb_param;
1834
-
1835
-error:
1836
-	free_cbparam(cb_param);
1837
-	return NULL;
1838 1744
 }
1839 1745
 
1840 1746
 
1841 1747
 str* create_winfo_xml(watcher_t* watchers, char* version,
1842
-		str resource, int STATE_FLAG )
1748
+		str resource, str event, int STATE_FLAG)
1843 1749
 {
1844 1750
 	xmlDocPtr doc = NULL;       
1845 1751
     xmlNodePtr root_node = NULL, node = NULL;
... ...
@@ -1883,19 +1789,21 @@ str* create_winfo_xml(watcher_t* watchers, char* version,
1883 1789
 		LM_ERR("while adding child\n");
1884 1790
 		goto error;
1885 1791
 	}
1886
-	res= (char*)pkg_malloc(sizeof(char)*(resource.len+ 1));
1792
+	res= (char*)pkg_malloc((resource.len>event.len)?resource.len:event.len
1793
+			+ 1);
1887 1794
 	if(res== NULL)
1888 1795
 	{
1889 1796
 		ERR_MEM(PKG_MEM_STR);
1890 1797
 	}
1891 1798
 	memcpy(res, resource.s, resource.len);
1892 1799
 	res[resource.len]= '\0';
1893
-
1894 1800
 	xmlNewProp(w_list_node, BAD_CAST "resource", BAD_CAST res);
1895
-	xmlNewProp(w_list_node, BAD_CAST "package", BAD_CAST "presence");
1896
-
1801
+	memcpy(res, event.s, event.len);
1802
+	res[event.len]= '\0';
1803
+	xmlNewProp(w_list_node, BAD_CAST "package", BAD_CAST res);
1897 1804
 	pkg_free(res);
1898 1805
 
1806
+
1899 1807
 	w= watchers->next;
1900 1808
 	while(w)
1901 1809
 	{
... ...
@@ -1951,3 +1859,147 @@ error:
1951 1859
 	return NULL;
1952 1860
 }
1953 1861
 
1862
+int watcher_found_in_list(watcher_t * watchers, str wuri)
1863
+{
1864
+	watcher_t * w;
1865
+
1866
+	w = watchers->next;
1867
+
1868
+	while(w)
1869
+	{
1870
+		if(w->uri.len == wuri.len && strncmp(w->uri.s, wuri.s, wuri.len)== 0)
1871
+			return 1;
1872
+		w= w->next;
1873
+	}
1874
+
1875
+	return 0;
1876
+}
1877
+
1878
+int add_waiting_watchers(watcher_t *watchers, str pres_uri, str event)
1879
+{
1880
+	watcher_t * w;
1881
+	db_key_t query_cols[3];
1882
+	db_val_t query_vals[3];
1883
+	db_key_t result_cols[2];
1884
+	db_res_t *result = NULL;
1885
+	db_row_t *row= NULL ;	
1886
+	db_val_t *row_vals;
1887
+	int n_result_cols = 0;
1888
+	int n_query_cols = 0;
1889
+	int wuser_col, wdomain_col;
1890
+	str wuser, wdomain, wuri;
1891
+	int i;
1892
+
1893
+	/* select from watchers table the users that have subscribed
1894
+	 * to the presentity and have status pending */
1895
+
1896
+	query_cols[n_query_cols] = &str_presentity_uri_col;
1897
+	query_vals[n_query_cols].type = DB_STR;
1898
+	query_vals[n_query_cols].nul = 0;
1899
+	query_vals[n_query_cols].val.str_val = pres_uri;
1900
+	n_query_cols++;
1901
+
1902
+	query_cols[n_query_cols] = &str_event_col;
1903
+	query_vals[n_query_cols].type = DB_STR;
1904
+	query_vals[n_query_cols].nul = 0;
1905
+	query_vals[n_query_cols].val.str_val = event;
1906
+	n_query_cols++;
1907
+
1908
+	query_cols[n_query_cols] = &str_status_col;
1909
+	query_vals[n_query_cols].type = DB_INT;
1910
+	query_vals[n_query_cols].nul = 0;
1911
+	query_vals[n_query_cols].val.int_val = PENDING_STATUS;
1912
+	n_query_cols++;
1913
+
1914
+	result_cols[wuser_col=n_result_cols++] = &str_watcher_username_col;
1915
+	result_cols[wdomain_col=n_result_cols++] = &str_watcher_domain_col;
1916
+	
1917
+	if (pa_dbf.use_table(pa_db, &watchers_table) < 0) 
1918
+	{
1919
+		LM_ERR("sql use table 'watchers_table' failed\n");
1920
+		return -1;
1921
+	}
1922
+
1923
+	if (pa_dbf.query (pa_db, query_cols, 0, query_vals,
1924
+		 result_cols, n_query_cols, n_result_cols, 0, &result) < 0) 
1925
+	{
1926
+		LM_ERR("failed to query %.*s table\n",
1927
+				watchers_table.len, watchers_table.s);
1928
+		if(result)
1929
+			pa_dbf.free_result(pa_db, result);
1930
+		return -1;
1931
+	}
1932
+	
1933
+	if(result== NULL)
1934
+	{
1935
+		LM_ERR("mysql query failed - null result\n");
1936
+		return -1;
1937
+	}
1938
+
1939
+	if (result->n<=0 )
1940
+	{
1941
+		LM_DBG("The query returned no result\n");
1942
+		pa_dbf.free_result(pa_db, result);
1943
+		return 0;
1944
+	}
1945
+
1946
+	for(i=0; i< result->n; i++)
1947
+	{
1948
+		row = &result->rows[i];
1949
+		row_vals = ROW_VALUES(row);
1950
+
1951
+		wuser.s = (char*)row_vals[wuser_col].val.string_val;
1952
+		wuser.len = strlen(wuser.s);
1953
+
1954
+		wdomain.s = (char*)row_vals[wdomain_col].val.string_val;
1955
+		wdomain.len = strlen(wdomain.s);
1956
+
1957
+		if(uandd_to_uri(wuser, wdomain, &wuri)<0)
1958
+		{
1959
+			LM_ERR("creating uri from username and domain\n");
1960
+			goto error;
1961
+		}
1962
+
1963
+		if(watcher_found_in_list(watchers, wuri))
1964
+		{
1965
+			pkg_free(wuri.s);
1966
+			continue;
1967
+		}
1968
+		
1969
+		w= (watcher_t*)pkg_malloc(sizeof(watcher_t));
1970
+		if(w== NULL)
1971
+		{
1972
+			ERR_MEM(PKG_MEM_STR);
1973
+		}
1974
+		memset(w, 0, sizeof(watcher_t));
1975
+
1976
+		w->status= WAITING_STATUS;
1977
+		w->uri = wuri;
1978
+		w->id.s = (char*)pkg_malloc(w->uri.len*2 +1);
1979
+		if(w->id.s== NULL)
1980
+		{
1981
+			pkg_free(w->uri.s);
1982
+			pkg_free(w);
1983
+			ERR_MEM(PKG_MEM_STR);
1984
+		}
1985
+
1986
+		to64frombits((unsigned char *)w->id.s,
1987
+			(const unsigned char*)w->uri.s, w->uri.len);
1988
+		w->id.len = strlen(w->id.s);
1989
+		w->event= event;
1990
+	
1991
+		w->next= watchers->next;
1992
+		watchers->next= w;
1993
+
1994
+	}
1995
+
1996
+	pa_dbf.free_result(pa_db, result);
1997
+	return 0;
1998
+
1999
+error:
2000
+	if(result)
2001
+		pa_dbf.free_result(pa_db, result);
2002
+	return -1;
2003
+
2004
+}
2005
+
... ...
@@ -103,8 +103,8 @@ int publ_send200ok(struct sip_msg *msg, int lexpire, str etag)
103 103
 	
104 104
 	hdr_append.s = buf;
105 105
 	hdr_append.s[0]='\0';
106
-	hdr_append.len = snprintf(hdr_append.s, buf_len, "Expires: %d\r\n",lexpire -
107
-			expires_offset);
106
+	hdr_append.len = snprintf(hdr_append.s, buf_len, "Expires: %d\r\n",
107
+			((lexpire==0)?0:(lexpire-expires_offset)));
108 108
 	if(hdr_append.len < 0)
109 109
 	{
110 110
 		LM_ERR("unsuccessful snprintf\n");
... ...
@@ -635,6 +635,7 @@ after_dialog_check:
635 635
 				goto error;
636 636
 			}
637 637
 			*sent_reply= 1;
638
+			goto done;
638 639
 		}
639 640
 	}
640 641
 
... ...
@@ -981,3 +982,4 @@ error:
981 982
 	return NULL;
982 983
 
983 984
 }
985
+
... ...
@@ -61,23 +61,48 @@ static str pu_489_rpl  = str_init("Bad Event");
61 61
 int send_2XX_reply(struct sip_msg * msg, int reply_code, int lexpire,
62 62
 		str* local_contact)
63 63
 {
64
-	static str hdr_append;
64
+	str hdr_append = {0, 0};
65
+	str tmp;
65 66
 	
66
-	hdr_append.s = (char *)pkg_malloc( sizeof(char)*(local_contact->len+ 128));
67
+	tmp.s = int2str((unsigned long)lexpire, &tmp.len);
68
+	hdr_append.len = 9 + tmp.len + CRLF_LEN
69
+		+ 10 + local_contact->len + 16 + CRLF_LEN;
70
+	hdr_append.s = (char *)pkg_malloc(sizeof(char)*(hdr_append.len+1));
67 71
 	if(hdr_append.s == NULL)
68 72
 	{
69 73
 		ERR_MEM(PKG_MEM_STR);
70 74
 	}
71
-	hdr_append.len = sprintf(hdr_append.s, "Expires: %d\r\n", lexpire);	
72
-	
73
-	strncpy(hdr_append.s+hdr_append.len ,"Contact: <", 10);
74
-	hdr_append.len += 10;
75
-	strncpy(hdr_append.s+hdr_append.len, local_contact->s, local_contact->len);
76
-	hdr_append.len+= local_contact->len;
77
-	strncpy(hdr_append.s+hdr_append.len, ">", 1);
78
-	hdr_append.len += 1;
79
-	strncpy(hdr_append.s+hdr_append.len, CRLF, CRLF_LEN);
80
-	hdr_append.len += CRLF_LEN;
75
+	strncpy(hdr_append.s, "Expires: ", 9);
76
+	strncpy(hdr_append.s+9, tmp.s, tmp.len);
77
+	tmp.s = hdr_append.s+9+tmp.len;
78
+	strncpy(tmp.s, CRLF, CRLF_LEN);
79
+	tmp.s += CRLF_LEN;
80
+	strncpy(tmp.s, "Contact: <", 10);
81
+	tmp.s += 10;
82
+	strncpy(tmp.s, local_contact->s, local_contact->len);
83
+	tmp.s += local_contact->len;
84
+	switch (msg->rcv.proto)
85
+	{
86
+		case PROTO_TCP:
87
+			strncpy(tmp.s, ";transport=tcp", 14);
88
+			tmp.s += 14;
89
+			hdr_append.len -= 1;
90
+		break;
91
+		case PROTO_TLS:
92
+			strncpy(tmp.s, ";transport=tls", 14);
93
+			tmp.s += 14;
94
+			hdr_append.len -= 1;
95
+		break;
96
+		case PROTO_SCTP:
97
+			strncpy(tmp.s, ";transport=sctp", 15);
98
+			tmp.s += 15;
99
+			hdr_append.len -= 1;
100
+		break;
101
+		default:
102
+			hdr_append.len -= 15;
103
+	}
104
+	*tmp.s = '>';
105
+	strncpy(tmp.s+1, CRLF, CRLF_LEN);
81 106
 
82 107
 	hdr_append.s[hdr_append.len]= '\0';
83 108
 	
... ...
@@ -98,7 +123,8 @@ int send_2XX_reply(struct sip_msg * msg, int reply_code, int lexpire,
98 123
 
99 124
 error:
100 125
 
101
-	pkg_free(hdr_append.s);
126
+	if(hdr_append.s!=NULL)
127
+		pkg_free(hdr_append.s);
102 128
 	return -1;
103 129
 }
104 130
 
... ...
@@ -536,7 +562,8 @@ int handle_subscribe(struct sip_msg* msg, char* str1, char* str2)
536 562
 		ev_param= ev_param->next;
537 563
 	}		
538 564
 	
539
-	if(extract_sdialog_info(&subs, msg, max_expires, &to_tag_gen)< 0)
565
+	if(extract_sdialog_info(&subs, msg, max_expires, &to_tag_gen,
566
+				server_address)< 0)
540 567
 	{
541 568
 		LM_ERR("failed to extract dialog information\n");
542 569
 		goto error;
... ...
@@ -716,7 +743,8 @@ error:
716 743
 }
717 744
 
718 745
 
719
-int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, int* to_tag_gen)
746
+int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp,
747
+		int* to_tag_gen, str scontact)
720 748
 {
721 749
 	str rec_route= {0, 0};
722 750
 	int rt  = 0;
... ...
@@ -924,7 +952,7 @@ int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, int* to_tag
924 952
 
925 953
 	subs->version = 0;
926 954
 	
927
-	if((!server_address.s) || (server_address.len== 0))
955
+	if((!scontact.s) || (scontact.len== 0))
928 956
 	{
929 957
 		contact= get_local_contact(msg);
930 958
 		if(contact== NULL)
... ...
@@ -935,7 +963,7 @@ int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, int* to_tag
935 963
 		subs->local_contact= *contact;
936 964
 	}
937 965
 	else
938
-		subs->local_contact= server_address;
966
+		subs->local_contact= scontact;
939 967
 	
940 968
 	return 0;
941 969
 	
... ...
@@ -48,6 +48,7 @@ struct pres_ev;
48 48
 #define ACTIVE_STATUS        1
49 49
 #define PENDING_STATUS       2
50 50
 #define TERMINATED_STATUS    3
51
+#define WAITING_STATUS       4
51 52
 
52 53
 struct subscription
53 54
 {
... ...
@@ -107,8 +108,8 @@ typedef void (*update_db_subs_t)(db_con_t * ,db_func_t ,shtable_t ,int ,int ,
107 108
 		handle_expired_func_t);
108 109
 
109 110
 int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int max_expire,
110
-		int* to_tag_gen);
111
+		int* to_tag_gen, str scontact);
111 112
 typedef int (*extract_sdialog_info_t)(subs_t* subs, struct sip_msg* msg,
112
-		int max_expire, int* to_tag_gen);
113
+		int max_expire, int* to_tag_gen, str scontact);
113 114
 
114 115
 #endif
... ...
@@ -518,7 +518,8 @@ found_support:
518 518
 /*** examine the event header */
519 519
 
520 520
 	/* extract dialog information from message headers */
521
-	if(pres_extract_sdialog_info(&subs, msg, rls_max_expires, &to_tag_gen)< 0)
521
+	if(pres_extract_sdialog_info(&subs, msg, rls_max_expires,
522
+				&to_tag_gen, server_address)< 0)
522 523
 	{
523 524
 		LM_ERR("bad Subscribe request\n");
524 525
 		goto error;