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 95
 		case ACTIVE_STATUS: return "active";
96 96
 		case PENDING_STATUS: return "pending";
97 97
 		case TERMINATED_STATUS: return "terminated";
98
+		case WAITING_STATUS: return "waiting";
98 99
 	}
99 100
 	return NULL;
100 101
 }
... ...
@@ -114,147 +120,142 @@ void printf_subs(subs_t* subs)
114 114
 		subs->to_tag.s,subs->from_tag.len, subs->from_tag.s,subs->contact.len,
115 115
 		subs->contact.s,subs->record_route.len,subs->record_route.s);
116 116
 }
117
-str* create_winfo_xml(watcher_t* watchers, char* version,str resource, int STATE_FLAG );
118 117
 
119
-int build_str_hdr(subs_t* subs, int is_body, str** hdr)
118
+int build_str_hdr(subs_t* subs, int is_body, str* hdr)
120 119
 {
121
-	str* str_hdr = NULL;	
122
-	char* subs_expires = NULL;
123
-	int len = 0;
124 120
 	pres_ev_t* event= subs->event;
125
-	int expires_t;
126
-	char* status= NULL;
121
+	str expires = {0, 0};
122
+	str status = {0, 0};
123
+	str tmp = {0, 0};
127 124
 
128
-	str_hdr =(str*)pkg_malloc(sizeof(str));
129
-	if(str_hdr== NULL)
125
+	if(hdr == NULL)
130 126
 	{
131
-		LM_ERR("while allocating memory\n");
127
+		LM_ERR("bad parameter\n");
132 128
 		return -1;
133 129
 	}
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)
130
+	expires.s = int2str(subs->expires, &expires.len);
131
+	status.s= get_status_str(subs->status);
132
+	if(status.s == NULL)
138 133
 	{
139
-		LM_ERR("while allocating memory\n");
140
-		pkg_free(str_hdr);
134
+		LM_ERR("bad status %d\n", subs->status);
141 135
 		return -1;
142
-	}	
136
+	}
137
+	status.len = strlen(status.s);
143 138
 
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)
139
+	hdr->len = 18 /*Max-Forwards:  + val*/ + CRLF_LEN + 
140
+		7 /*Event: */ + subs->event->name.len +4 /*;id=*/+ subs->event_id.len+
141
+		CRLF_LEN + 10 /*Contact: <*/ + subs->local_contact.len + 1/*>*/ +
142
+		15/*";transport=xxxx"*/ + CRLF_LEN + 20 /*Subscription-State: */ +
143
+		status.len + 10 /*reason/expires params*/
144
+		+ (subs->reason.len>expires.len?subs->reason.len:expires.len)
145
+		+ CRLF_LEN + (is_body?
146
+		(14 /*Content-Type: */+subs->event->content_type.len + CRLF_LEN):0) + 1;
147
+
148
+	hdr->s = (char*)pkg_malloc(hdr->len);
149
+	if(hdr->s == NULL)
148 150
 	{
149
-		LM_ERR("while printing in string\n");
150
-		pkg_free(str_hdr->s);
151
-		pkg_free(str_hdr);
151
+		LM_ERR("no more pkg\n");
152 152
 		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;
153
+	}
154
+
155
+	strncpy(hdr->s, "Max-Forwards: ", 14);
156
+	tmp.s = int2str((unsigned long)MAX_FORWARD, &tmp.len);
157
+	strncpy(hdr->s+14, tmp.s, tmp.len);
158
+	tmp.s = hdr->s + tmp.len + 14;
159
+	strncpy(tmp.s, CRLF, CRLF_LEN);
160
+	tmp.s += CRLF_LEN;
161
+
162
+	strncpy(tmp.s  ,"Event: ", 7);
163
+	tmp.s += 7;
164
+	strncpy(tmp.s, event->name.s, event->name.len);
165
+	tmp.s += event->name.len;
162 166
 	if(subs->event_id.len && subs->event_id.s) 
163 167
 	{
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;
168
+ 		strncpy(tmp.s, ";id=", 4);
169
+ 		tmp.s += 4;
170
+ 		strncpy(tmp.s, subs->event_id.s, subs->event_id.len);
171
+ 		tmp.s += subs->event_id.len;
168 172
  	}
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;
173
+	strncpy(tmp.s, CRLF, CRLF_LEN);
174
+	tmp.s += CRLF_LEN;
175
+
176
+	strncpy(tmp.s, "Contact: <", 10);
177
+	tmp.s += 10;
178
+	strncpy(tmp.s, subs->local_contact.s, subs->local_contact.len);
179
+	tmp.s +=  subs->local_contact.len;
180
+	if(subs->sockinfo_str.s!=NULL)
181
+	{
182
+		/* fix me */
183
+		switch(subs->sockinfo_str.s[0]) {
184
+			case 's':
185
+			case 'S':
186
+				strncpy(tmp.s, ";transport=sctp", 15);
187
+				tmp.s += 15;
188
+			break;
189
+			case 't':
190
+			case 'T':
191
+				switch(subs->sockinfo_str.s[1]) {
192
+					case 'c':
193
+					case 'C':
194
+						strncpy(tmp.s, ";transport=tcp", 14);
195
+						tmp.s += 14;
196
+					break;
197
+					case 'l':
198
+					case 'L':
199
+						strncpy(tmp.s, ";transport=tls", 14);
200
+						tmp.s += 14;
201
+					break;
202
+				}
203
+			break;
204
+		}
190 205
 	}
191
-	strcpy(str_hdr->s+str_hdr->len, status);
192
-	str_hdr->len+= strlen(status);
206
+	*tmp.s =  '>';
207
+	tmp.s++;
208
+	strncpy(tmp.s, CRLF, CRLF_LEN);
209
+	tmp.s += CRLF_LEN;
193 210
 	
194
-	expires_t= subs->expires;
211
+	strncpy(tmp.s, "Subscription-State: ", 20);
212
+	tmp.s += 20;
213
+	strncpy(tmp.s, status.s, status.len);
214
+	tmp.s += status.len;
195 215
 	
196
-	if(subs->status== TERMINATED_STATUS)
216
+	if(subs->status == TERMINATED_STATUS)
197 217
 	{
198 218
 		LM_DBG("state = terminated\n");
199 219
 		
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
-	}
220
+		strncpy(tmp.s, ";reason=", 8);
221
+		tmp.s += 8;
222
+		strncpy(tmp.s, subs->reason.s, subs->reason.len);
223
+		tmp.s += subs->reason.len;
224
+	} else {	
225
+		strncpy(tmp.s, ";expires=", 9);
226
+		tmp.s += 9;
227
+		LM_DBG("expires = %d\n", subs->expires);
228
+		strncpy(tmp.s, expires.s, expires.len);
229
+		tmp.s += expires.len;
230
+	}
231
+	strncpy(tmp.s, CRLF, CRLF_LEN);
232
+	tmp.s += CRLF_LEN;
229 233
 	
230 234
 	if(is_body)
231 235
 	{	
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;
236
+		strncpy(tmp.s,"Content-Type: ", 14);
237
+		tmp.s += 14;
238
+		strncpy(tmp.s, event->content_type.s, event->content_type.len);
239
+		tmp.s += event->content_type.len;
240
+		strncpy(tmp.s, CRLF, CRLF_LEN);
241
+		tmp.s += CRLF_LEN;
238 242
 	}
239 243
 	
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;
244
+	*tmp.s = '\0';
245
+	hdr->len = tmp.s - hdr->s;
250 246
 
251 247
 	return 0;
252
-
253 248
 }
254 249
 
255
-int get_wi_subs_db(subs_t* subs, watcher_t** watchers)
250
+int get_wi_subs_db(subs_t* subs, watcher_t* watchers)
256 251
 {	
257
-	watcher_t *w;
252
+	subs_t sb;
258 253
 	db_key_t query_cols[6];
259 254
 	db_op_t  query_ops[6];
260 255
 	db_val_t query_vals[6];
... ...
@@ -265,8 +266,7 @@ int get_wi_subs_db(subs_t* subs, watcher_t** watchers)
265 265
 	int n_result_cols = 0;
266 266
 	int n_query_cols = 0;
267 267
 	int i;
268
-	int status_col, expires_col, from_user_col, from_domain_col;
269
-	str from_user, from_domain;
268
+	int status_col, expires_col, from_user_col, from_domain_col, callid_col;
270 269
 
271 270
 	query_cols[n_query_cols] = &str_presentity_uri_col;
272 271
 	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 318
 		row = &result->rows[i];
319 319
 		row_vals = ROW_VALUES(row);
320 320
 		
321
-		from_user.s= (char*)row_vals[from_user_col].val.string_val;
322
-		from_user.len= strlen(from_user.s);
321
+		sb.from_user.s= (char*)row_vals[from_user_col].val.string_val;
322
+		sb.from_user.len= strlen(sb.from_user.s);
323 323
 
324
-		from_domain.s= (char*)row_vals[from_domain_col].val.string_val;
325
-		from_domain.len= strlen(from_domain.s);
324
+		sb.from_domain.s= (char*)row_vals[from_domain_col].val.string_val;
325
+		sb.from_domain.len= strlen(sb.from_domain.s);
326 326
 
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
-		}
327
+		sb.callid.s= (char*)row_vals[callid_col].val.string_val;
328
+		sb.callid.len= strlen(sb.callid.s);
346 329
 
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;
330
+		sb.event =subs->event->wipeer;
331
+		sb.status= row_vals[status_col].val.int_val;
352 332
 		
353
-		w->next= (*watchers)->next;
354
-		(*watchers)->next= w;
333
+		if(add_watcher_list(&sb, watchers)<0)
334
+			goto error;
335
+
355 336
 	}
356 337
 	
357 338
 	pa_dbf.free_result(pa_db, result);
... ...
@@ -367,18 +349,12 @@ str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs)
367 367
 {
368 368
 	str* notify_body = NULL;
369 369
 	char* version_str;
370
-	watcher_t *watchers = NULL, *w= NULL;
370
+	watcher_t *watchers = NULL;
371 371
 	int len = 0;
372 372
 	unsigned int hash_code;
373 373
 	subs_t* s= NULL;
374 374
 	int state = FULL_STATE_FLAG;
375 375
 
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 376
 	hash_code = 0;
383 377
 	version_str = int2str(subs->version, &len);
384 378
 	if(version_str ==NULL)
... ...
@@ -396,39 +372,8 @@ str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs)
396 396
 
397 397
 	if(watcher_subs != NULL) 
398 398
 	{		
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);
399
+		if(add_watcher_list(watcher_subs, watchers)< 0)
412 400
 			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 401
 		state = PARTIAL_STATE_FLAG;
433 402
 
434 403
 		goto done;
... ...
@@ -436,7 +381,7 @@ str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs)
436 436
 
437 437
 	if(fallback2db)
438 438
 	{
439
-		if(get_wi_subs_db(subs, &watchers)< 0)
439
+		if(get_wi_subs_db(subs, watchers)< 0)
440 440
 		{
441 441
 			LM_ERR("getting watchers from database\n");
442 442
 			goto error;
... ...
@@ -469,43 +414,24 @@ str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs)
469 469
 			s->pres_uri.len== subs->pres_uri.len &&
470 470
 			strncmp(s->pres_uri.s, subs->pres_uri.s,subs->pres_uri.len)== 0)
471 471
 		{
472
-			w= (watcher_t*)pkg_malloc(sizeof(watcher_t));
473
-			if(w== NULL)
472
+			if(add_watcher_list(s, watchers)< 0)
474 473
 			{
475 474
 				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);
475
+				goto error;
493 476
 			}
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 477
 		}
504 478
 	}
505 479
 	
480
+	if(add_waiting_watchers(watchers, subs->pres_uri,
481
+				subs->event->wipeer->name)< 0 )
482
+	{
483
+		LM_ERR("failed to add waiting watchers\n");
484
+		goto error;
485
+	}
486
+
506 487
 done:
507 488
 	notify_body = create_winfo_xml(watchers,version_str,subs->pres_uri,
508
-			state );
489
+			subs->event->wipeer->name, state);
509 490
 	
510 491
 	if(watcher_subs == NULL) 
511 492
 		lock_release(&subs_htable[hash_code].lock);
... ...
@@ -515,16 +441,7 @@ done:
515 515
 		LM_ERR("in function create_winfo_xml\n");
516 516
 		goto error;
517 517
 	}
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
-	}
518
+	free_watcher_list(watchers);
528 519
 	return notify_body;
529 520
 
530 521
 error:
... ...
@@ -534,6 +451,13 @@ error:
534 534
 			xmlFree(notify_body->s);
535 535
 		pkg_free(notify_body);
536 536
 	}
537
+	free_watcher_list(watchers);
538
+	return NULL;
539
+}
540
+
541
+void free_watcher_list(watcher_t* watchers)
542
+{
543
+	watcher_t* w;
537 544
 	while(watchers)
538 545
 	{	
539 546
 		w= watchers;
... ...
@@ -544,8 +468,47 @@ error:
544 544
 		watchers= watchers->next;
545 545
 		pkg_free(w);
546 546
 	}
547
+}
547 548
 
548
-	return NULL;
549
+int add_watcher_list(subs_t *s, watcher_t *watchers)
550
+{
551
+	watcher_t* w;
552
+
553
+	w= (watcher_t*)pkg_malloc(sizeof(watcher_t));
554
+	if(w== NULL)
555
+	{
556
+		LM_ERR("No more private memory\n");
557
+		return -1;
558
+	}
559
+	w->status= s->status;
560
+	if(uandd_to_uri(s->from_user, s->from_domain, &w->uri)<0)
561
+	{
562
+		LM_ERR("failed to create uri\n");
563
+		goto error;
564
+	}
565
+	w->id.s = (char*)pkg_malloc(s->callid.len+ 1);
566
+	if(w->id.s == NULL)
567
+	{
568
+		LM_ERR("no more memory\n");
569
+		goto error;
570
+	}
571
+	memcpy(w->id.s, s->callid.s, s->callid.len);
572
+	w->id.len = s->callid.len;
573
+	w->id.s[w->id.len] = '\0';
574
+
575
+	w->next= watchers->next;
576
+	watchers->next= w;
577
+
578
+	return 0;
579
+
580
+error:
581
+	if(w)
582
+	{
583
+		if(w->uri.s)
584
+			pkg_free(w->uri.s);
585
+		pkg_free(w);
586
+	}
587
+	return -1;
549 588
 }
550 589
 
551 590
 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 1067
 	query_vals[n_query_cols].val.int_val = ACTIVE_STATUS;
1068 1068
 	n_query_cols++;
1069 1069
 
1070
+	query_cols[n_query_cols] = &str_contact_col;
1071
+	query_ops[n_query_cols] = OP_NEQ;
1072
+	query_vals[n_query_cols].type = DB_STR;
1073
+	query_vals[n_query_cols].nul = 0;
1070 1074
 	if(sender)
1071 1075
 	{	
1072 1076
 		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 1077
 		query_vals[n_query_cols].val.str_val = *sender;
1078
-		n_query_cols++;
1078
+	} else {
1079
+		query_vals[n_query_cols].val.str_val.s = "";
1080
+		query_vals[n_query_cols].val.str_val.len = 0;
1079 1081
 	}
1082
+	n_query_cols++;
1080 1083
 
1081 1084
 	result_cols[to_user_col=n_result_cols++]      =   &str_to_user_col;
1082 1085
 	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 1361
 	s= subs_array;
1362 1362
 	while(s)
1363 1363
 	{
1364
+		s->auth_rules_doc= rules_doc;
1364 1365
 		if (p->event->aux_body_processing) {
1365 1366
 			aux_body = p->event->aux_body_processing(s, notify_body?notify_body:body);
1366 1367
 		}
1367 1368
 
1368
-		s->auth_rules_doc= rules_doc;
1369 1369
 		if(notify(s, NULL, aux_body?aux_body:(notify_body?notify_body:body), 0)< 0 )
1370 1370
 		{
1371 1371
 			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 1475
 {
1476 1476
 	dlg_t* td = NULL;
1477 1477
 	str met = {"NOTIFY", 6};
1478
-	str* str_hdr = NULL;
1478
+	str str_hdr = {0, 0};
1479 1479
 	str* notify_body = NULL;
1480 1480
 	int result= 0;
1481 1481
     c_back_param *cb_param= NULL;
... ...
@@ -1496,11 +1462,13 @@ int send_notify_request(subs_t* subs, subs_t * watcher_subs,
1496 1496
 		if( subs->event->req_auth)
1497 1497
 		{
1498 1498
 			
1499
-			if(subs->auth_rules_doc && subs->event->apply_auth_nbody &&
1500
-				subs->event->apply_auth_nbody(n_body, subs, &notify_body)< 0)
1499
+			if(subs->auth_rules_doc && subs->event->apply_auth_nbody)
1501 1500
 			{
1502
-				LM_ERR("in function apply_auth_nbody\n");
1503
-				goto error;
1501
+				if(subs->event->apply_auth_nbody(n_body, subs, &notify_body)< 0)
1502
+				{
1503
+					LM_ERR("in function apply_auth_nbody\n");
1504
+					goto error;
1505
+				}
1504 1506
 			}
1505 1507
 			if(notify_body== NULL)
1506 1508
 				notify_body= n_body;
... ...
@@ -1530,7 +1498,7 @@ int send_notify_request(subs_t* subs, subs_t * watcher_subs,
1530 1530
 			else
1531 1531
 			{
1532 1532
 				notify_body = get_p_notify_body(subs->pres_uri,
1533
-						subs->event, NULL, (subs->contact.s)?&subs->contact:NULL);
1533
+					subs->event, NULL, (subs->contact.s)?&subs->contact:NULL);
1534 1534
 				if(notify_body == NULL || notify_body->s== NULL)
1535 1535
 				{
1536 1536
 					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 1539
 				if(subs->event->req_auth)
1540 1540
 				{
1541 1541
 					 
1542
-					if(subs->auth_rules_doc && subs->event->apply_auth_nbody &&
1543
-					subs->event->apply_auth_nbody(notify_body,subs,&final_body)<0)
1542
+					if(subs->auth_rules_doc && subs->event->apply_auth_nbody
1543
+							&& subs->event->apply_auth_nbody(notify_body,
1544
+								subs,&final_body)<0)
1544 1545
 					{
1545 1546
 						LM_ERR("in function apply_auth\n");
1546 1547
 						goto error;
... ...
@@ -1572,7 +1541,7 @@ jump_over_body:
1572 1572
 		LM_ERR("while building headers\n");
1573 1573
 		goto error;
1574 1574
 	}	
1575
-	LM_DBG("headers:\n%.*s\n", str_hdr->len, str_hdr->s);
1575
+	LM_DBG("headers:\n%.*s\n", str_hdr.len, str_hdr.s);
1576 1576
 
1577 1577
 	/* construct the dlg_t structure */
1578 1578
 	td = build_dlg_t(subs);
... ...
@@ -1582,25 +1551,22 @@ jump_over_body:
1582 1582
 		goto error;	
1583 1583
 	}
1584 1584
 
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);
1585
+	cb_param = shm_dup_cbparam(subs);
1591 1586
 	if(cb_param == NULL)
1592 1587
 	{
1593 1588
 		LM_ERR("while duplicating cb_param in share memory\n");
1594 1589
 		goto error;	
1595 1590
 	}	
1596 1591
 
1592
+	LM_ERR("before tmb.t_request_within\n");
1597 1593
 	result = tmb.t_request_within
1598 1594
 		(&met,              /* method*/
1599
-		str_hdr,            /* extra headers*/
1595
+		&str_hdr,           /* extra headers*/
1600 1596
 		notify_body,        /* body*/
1601 1597
 		td,                 /* dialog structure*/
1602 1598
 		p_tm_callback,      /* callback function*/
1603 1599
 		(void*)cb_param);   /* callback parameter*/
1600
+	LM_ERR("after tmb.t_request_within\n");
1604 1601
 
1605 1602
 	if(result< 0)
1606 1603
 	{
... ...
@@ -1610,13 +1576,14 @@ jump_over_body:
1610 1610
 	}
1611 1611
 
1612 1612
 	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);
1613
+		td->rem_uri.len, td->rem_uri.s, td->hooks.next_hop->len,
1614
+		td->hooks.next_hop->s,
1615
+		td->loc_uri.len, td->loc_uri.s, subs->event->name.len,
1616
+		subs->event->name.s);
1615 1617
 
1616 1618
 	free_tm_dlg(td);
1617 1619
 	
1618
-	pkg_free(str_hdr->s);
1619
-	pkg_free(str_hdr);
1620
+	if(str_hdr.s) pkg_free(str_hdr.s);
1620 1621
 	
1621 1622
 	if((int)(long)n_body!= (int)(long)notify_body)
1622 1623
 	{
... ...
@@ -1627,7 +1594,8 @@ jump_over_body:
1627 1627
 				if(subs->event->type& WINFO_TYPE )
1628 1628
 					xmlFree(notify_body->s);
1629 1629
 				else
1630
-				if(subs->event->apply_auth_nbody== NULL && subs->event->agg_nbody== NULL)
1630
+				if(subs->event->apply_auth_nbody== NULL
1631
+						&& subs->event->agg_nbody== NULL)
1631 1632
 					pkg_free(notify_body->s);
1632 1633
 				else
1633 1634
 				subs->event->free_body(notify_body->s);
... ...
@@ -1639,12 +1607,8 @@ jump_over_body:
1639 1639
 
1640 1640
 error:
1641 1641
 	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
-	}
1642
+	if(str_hdr.s!=NULL)
1643
+		pkg_free(str_hdr.s);
1648 1644
 	if((int)(long)n_body!= (int)(long)notify_body)
1649 1645
 	{
1650 1646
 		if(notify_body!=NULL)
... ...
@@ -1654,7 +1618,8 @@ error:
1654 1654
 				if(subs->event->type& WINFO_TYPE)
1655 1655
 					xmlFree(notify_body->s);
1656 1656
 				else
1657
-				if(subs->event->apply_auth_nbody== NULL && subs->event->agg_nbody== NULL)
1657
+				if(subs->event->apply_auth_nbody== NULL
1658
+						&& subs->event->agg_nbody== NULL)
1658 1659
 					pkg_free(notify_body->s);
1659 1660
 				else
1660 1661
 				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 1735
 
1736 1736
 		delete_db_subs(cb->pres_uri, cb->ev_name, cb->to_tag);
1737 1737
 	}	
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 1738
 
1763 1739
 	if(*ps->param !=NULL  )
1764 1740
 		free_cbparam((c_back_param*)(*ps->param));
1765 1741
 	return ;
1766
-
1767 1742
 }
1768 1743
 
1769 1744
 void free_cbparam(c_back_param* cb_param)
1770 1745
 {
1771 1746
 	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 1747
 		shm_free(cb_param);
1782
-	}
1783
-
1784 1748
 }
1785 1749
 
1786
-c_back_param* shm_dup_cbparam(subs_t* w_subs, subs_t* subs)
1750
+c_back_param* shm_dup_cbparam(subs_t* subs)
1787 1751
 {
1752
+	int size;
1788 1753
 	c_back_param* cb_param = NULL;
1754
+	
1755
+	size = sizeof(c_back_param) + subs->pres_uri.len+
1756
+			subs->event->name.len + subs->to_tag.len;
1789 1757
 
1790
-	cb_param= (c_back_param*)shm_malloc(sizeof(c_back_param));
1791
-	if(cb_param== NULL)
1758
+	cb_param= (c_back_param*)shm_malloc(size);
1759
+	LM_DBG("=== %d/%d/%d\n", subs->pres_uri.len,
1760
+			subs->event->name.len, subs->to_tag.len);
1761
+	if(cb_param==NULL)
1792 1762
 	{
1793
-		ERR_MEM(SHM_MEM_STR);
1763
+		LM_ERR("no more shared memory\n");
1764
+		return NULL;
1794 1765
 	}
1795
-	memset(cb_param, 0, sizeof(c_back_param));
1766
+	memset(cb_param, 0, size);
1796 1767
 
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
-	}
1768
+	cb_param->pres_uri.s = (char*)cb_param + sizeof(c_back_param);
1802 1769
 	memcpy(cb_param->pres_uri.s, subs->pres_uri.s, subs->pres_uri.len);
1803
-	cb_param->pres_uri.len= subs->pres_uri.len;
1770
+	cb_param->pres_uri.len = subs->pres_uri.len;
1771
+	cb_param->ev_name.s = (char*)(cb_param->pres_uri.s) + cb_param->pres_uri.len;
1772
+	memcpy(cb_param->ev_name.s, subs->event->name.s, subs->event->name.len);
1773
+	cb_param->ev_name.len = subs->event->name.len;
1774
+	cb_param->to_tag.s = (char*)(cb_param->ev_name.s) + cb_param->ev_name.len;
1775
+	memcpy(cb_param->to_tag.s, subs->to_tag.s, subs->to_tag.len);
1776
+	cb_param->to_tag.len = subs->to_tag.len;
1804 1777
 
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 1778
 	return cb_param;
1834
-
1835
-error:
1836
-	free_cbparam(cb_param);
1837
-	return NULL;
1838 1779
 }
1839 1780
 
1840 1781
 
1841 1782
 str* create_winfo_xml(watcher_t* watchers, char* version,
1842
-		str resource, int STATE_FLAG )
1783
+		str resource, str event, int STATE_FLAG)
1843 1784
 {
1844 1785
 	xmlDocPtr doc = NULL;       
1845 1786
     xmlNodePtr root_node = NULL, node = NULL;
... ...
@@ -1883,19 +1789,21 @@ str* create_winfo_xml(watcher_t* watchers, char* version,
1883 1883
 		LM_ERR("while adding child\n");
1884 1884
 		goto error;
1885 1885
 	}
1886
-	res= (char*)pkg_malloc(sizeof(char)*(resource.len+ 1));
1886
+	res= (char*)pkg_malloc((resource.len>event.len)?resource.len:event.len
1887
+			+ 1);
1887 1888
 	if(res== NULL)
1888 1889
 	{
1889 1890
 		ERR_MEM(PKG_MEM_STR);
1890 1891
 	}
1891 1892
 	memcpy(res, resource.s, resource.len);
1892 1893
 	res[resource.len]= '\0';
1893
-
1894 1894
 	xmlNewProp(w_list_node, BAD_CAST "resource", BAD_CAST res);
1895
-	xmlNewProp(w_list_node, BAD_CAST "package", BAD_CAST "presence");
1896
-
1895
+	memcpy(res, event.s, event.len);
1896
+	res[event.len]= '\0';
1897
+	xmlNewProp(w_list_node, BAD_CAST "package", BAD_CAST res);
1897 1898
 	pkg_free(res);
1898 1899
 
1900
+
1899 1901
 	w= watchers->next;
1900 1902
 	while(w)
1901 1903
 	{
... ...
@@ -1951,3 +1859,147 @@ error:
1951 1951
 	return NULL;
1952 1952
 }
1953 1953
 
1954
+int watcher_found_in_list(watcher_t * watchers, str wuri)
1955
+{
1956
+	watcher_t * w;
1957
+
1958
+	w = watchers->next;
1959
+
1960
+	while(w)
1961
+	{
1962
+		if(w->uri.len == wuri.len && strncmp(w->uri.s, wuri.s, wuri.len)== 0)
1963
+			return 1;
1964
+		w= w->next;
1965
+	}
1966
+
1967
+	return 0;
1968
+}
1969
+
1970
+int add_waiting_watchers(watcher_t *watchers, str pres_uri, str event)
1971
+{
1972
+	watcher_t * w;
1973
+	db_key_t query_cols[3];
1974
+	db_val_t query_vals[3];
1975
+	db_key_t result_cols[2];
1976
+	db_res_t *result = NULL;
1977
+	db_row_t *row= NULL ;	
1978
+	db_val_t *row_vals;
1979
+	int n_result_cols = 0;
1980
+	int n_query_cols = 0;
1981
+	int wuser_col, wdomain_col;
1982
+	str wuser, wdomain, wuri;
1983
+	int i;
1984
+
1985
+	/* select from watchers table the users that have subscribed
1986
+	 * to the presentity and have status pending */
1987
+
1988
+	query_cols[n_query_cols] = &str_presentity_uri_col;
1989
+	query_vals[n_query_cols].type = DB_STR;
1990
+	query_vals[n_query_cols].nul = 0;
1991
+	query_vals[n_query_cols].val.str_val = pres_uri;
1992
+	n_query_cols++;
1993
+
1994
+	query_cols[n_query_cols] = &str_event_col;
1995
+	query_vals[n_query_cols].type = DB_STR;
1996
+	query_vals[n_query_cols].nul = 0;
1997
+	query_vals[n_query_cols].val.str_val = event;
1998
+	n_query_cols++;
1999
+
2000
+	query_cols[n_query_cols] = &str_status_col;
2001
+	query_vals[n_query_cols].type = DB_INT;
2002
+	query_vals[n_query_cols].nul = 0;
2003
+	query_vals[n_query_cols].val.int_val = PENDING_STATUS;
2004
+	n_query_cols++;
2005
+
2006
+	result_cols[wuser_col=n_result_cols++] = &str_watcher_username_col;
2007
+	result_cols[wdomain_col=n_result_cols++] = &str_watcher_domain_col;
2008
+	
2009
+	if (pa_dbf.use_table(pa_db, &watchers_table) < 0) 
2010
+	{
2011
+		LM_ERR("sql use table 'watchers_table' failed\n");
2012
+		return -1;
2013
+	}
2014
+
2015
+	if (pa_dbf.query (pa_db, query_cols, 0, query_vals,
2016
+		 result_cols, n_query_cols, n_result_cols, 0, &result) < 0) 
2017
+	{
2018
+		LM_ERR("failed to query %.*s table\n",
2019
+				watchers_table.len, watchers_table.s);
2020
+		if(result)
2021
+			pa_dbf.free_result(pa_db, result);
2022
+		return -1;
2023
+	}
2024
+	
2025
+	if(result== NULL)
2026
+	{
2027
+		LM_ERR("mysql query failed - null result\n");
2028
+		return -1;
2029
+	}
2030
+
2031
+	if (result->n<=0 )
2032
+	{
2033
+		LM_DBG("The query returned no result\n");
2034
+		pa_dbf.free_result(pa_db, result);
2035
+		return 0;
2036
+	}
2037
+
2038
+	for(i=0; i< result->n; i++)
2039
+	{
2040
+		row = &result->rows[i];
2041
+		row_vals = ROW_VALUES(row);
2042
+
2043
+		wuser.s = (char*)row_vals[wuser_col].val.string_val;
2044
+		wuser.len = strlen(wuser.s);
2045
+
2046
+		wdomain.s = (char*)row_vals[wdomain_col].val.string_val;
2047
+		wdomain.len = strlen(wdomain.s);
2048
+
2049
+		if(uandd_to_uri(wuser, wdomain, &wuri)<0)
2050
+		{
2051
+			LM_ERR("creating uri from username and domain\n");
2052
+			goto error;
2053
+		}
2054
+
2055
+		if(watcher_found_in_list(watchers, wuri))
2056
+		{
2057
+			pkg_free(wuri.s);
2058
+			continue;
2059
+		}
2060
+		
2061
+		w= (watcher_t*)pkg_malloc(sizeof(watcher_t));
2062
+		if(w== NULL)
2063
+		{
2064
+			ERR_MEM(PKG_MEM_STR);
2065
+		}
2066
+		memset(w, 0, sizeof(watcher_t));
2067
+
2068
+		w->status= WAITING_STATUS;
2069
+		w->uri = wuri;
2070
+		w->id.s = (char*)pkg_malloc(w->uri.len*2 +1);
2071
+		if(w->id.s== NULL)
2072
+		{
2073
+			pkg_free(w->uri.s);
2074
+			pkg_free(w);
2075
+			ERR_MEM(PKG_MEM_STR);
2076
+		}
2077
+
2078
+		to64frombits((unsigned char *)w->id.s,
2079
+			(const unsigned char*)w->uri.s, w->uri.len);
2080
+		w->id.len = strlen(w->id.s);
2081
+		w->event= event;
2082
+	
2083
+		w->next= watchers->next;
2084
+		watchers->next= w;
2085
+
2086
+	}
2087
+
2088
+	pa_dbf.free_result(pa_db, result);
2089
+	return 0;
2090
+
2091
+error:
2092
+	if(result)
2093
+		pa_dbf.free_result(pa_db, result);
2094
+	return -1;
2095
+
2096
+}
2097
+
... ...
@@ -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 981
 	return NULL;
982 982
 
983 983
 }
984
+
... ...
@@ -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 98
 
99 99
 error:
100 100
 
101
-	pkg_free(hdr_append.s);
101
+	if(hdr_append.s!=NULL)
102
+		pkg_free(hdr_append.s);
102 103
 	return -1;
103 104
 }
104 105
 
... ...
@@ -536,7 +562,8 @@ int handle_subscribe(struct sip_msg* msg, char* str1, char* str2)
536 536
 		ev_param= ev_param->next;
537 537
 	}		
538 538
 	
539
-	if(extract_sdialog_info(&subs, msg, max_expires, &to_tag_gen)< 0)
539
+	if(extract_sdialog_info(&subs, msg, max_expires, &to_tag_gen,
540
+				server_address)< 0)
540 541
 	{
541 542
 		LM_ERR("failed to extract dialog information\n");
542 543
 		goto error;
... ...
@@ -716,7 +743,8 @@ error:
716 716
 }
717 717
 
718 718
 
719
-int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, int* to_tag_gen)
719
+int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp,
720
+		int* to_tag_gen, str scontact)
720 721
 {
721 722
 	str rec_route= {0, 0};
722 723
 	int rt  = 0;
... ...
@@ -924,7 +952,7 @@ int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, int* to_tag
924 924
 
925 925
 	subs->version = 0;
926 926
 	
927
-	if((!server_address.s) || (server_address.len== 0))
927
+	if((!scontact.s) || (scontact.len== 0))
928 928
 	{
929 929
 		contact= get_local_contact(msg);
930 930
 		if(contact== NULL)
... ...
@@ -935,7 +963,7 @@ int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, int* to_tag
935 935
 		subs->local_contact= *contact;
936 936
 	}
937 937
 	else
938
-		subs->local_contact= server_address;
938
+		subs->local_contact= scontact;
939 939
 	
940 940
 	return 0;
941 941
 	
... ...
@@ -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 107
 		handle_expired_func_t);
108 108
 
109 109
 int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int max_expire,
110
-		int* to_tag_gen);
110
+		int* to_tag_gen, str scontact);
111 111
 typedef int (*extract_sdialog_info_t)(subs_t* subs, struct sip_msg* msg,
112
-		int max_expire, int* to_tag_gen);
112
+		int max_expire, int* to_tag_gen, str scontact);
113 113
 
114 114
 #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;