Browse code

dialog: force cleanup of aged terminated dialogs

- reported by Dmitri Savolainen, GH #545

Daniel-Constantin Mierla authored on 18/03/2016 12:23:06
Showing 4 changed files
... ...
@@ -425,6 +425,10 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
425 425
 				srjson_DestroyDoc(&jdoc);
426 426
 			}
427 427
 			dlg->iflags = (unsigned int)VAL_INT(values+22);
428
+			if(dlg->state==DLG_STATE_DELETED) {
429
+				/* end_ts used for force clean up not stored - set it to now */
430
+				dlg->end_ts = (unsigned int)time(0);
431
+			}
428 432
 			/*restore the timer values */
429 433
 			if (0 != insert_dlg_timer( &(dlg->tl), (int)dlg->tl.timeout )) {
430 434
 				LM_CRIT("Unable to insert dlg %p [%u:%u] "
... ...
@@ -524,6 +524,11 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
524 524
 		goto done;
525 525
 	}
526 526
 
527
+	if(new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
528
+		/* set end time */
529
+		dlg->end_ts = (unsigned int)(time(0));
530
+	}
531
+
527 532
 	if ( new_state==DLG_STATE_DELETED
528 533
 				&& (old_state==DLG_STATE_UNCONFIRMED
529 534
 					|| old_state==DLG_STATE_EARLY) ) {
... ...
@@ -1280,7 +1285,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
1280 1285
 			iuid = NULL;
1281 1286
 		}
1282 1287
 	}
1283
-	
1288
+
1284 1289
 	/* run state machine */
1285 1290
 	switch ( req->first_line.u.request.method_value ) {
1286 1291
 		case METHOD_PRACK:
... ...
@@ -1304,6 +1309,8 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
1304 1309
 	/* delay deletion of dialog until transaction has died off in order
1305 1310
 	 * to absorb in-air messages */
1306 1311
 	if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
1312
+		/* set end time */
1313
+		dlg->end_ts = (unsigned int)(time(0));
1307 1314
 		iuid = dlg_get_iuid_shm_clone(dlg);
1308 1315
 		if(iuid!=NULL) {
1309 1316
 			if ( d_tmb.register_tmcb(req, NULL, TMCB_DESTROY,
... ...
@@ -1478,7 +1485,7 @@ void dlg_ontimeout(struct dlg_tl *tl)
1478 1485
 			dlg_set_ctx_iuid(dlg);
1479 1486
 			if(dlg_bye_all(dlg, NULL)<0)
1480 1487
 				dlg_unref(dlg, 1);
1481
-			dlg_reset_ctx_iuid();	
1488
+			dlg_reset_ctx_iuid();
1482 1489
 
1483 1490
 			dlg_unref(dlg, 1);
1484 1491
 			if_update_stat(dlg_enable_stats, expired_dlgs, 1);
... ...
@@ -1490,7 +1497,7 @@ void dlg_ontimeout(struct dlg_tl *tl)
1490 1497
     /* used for computing duration for timed out acknowledged dialog */
1491 1498
 	if (DLG_STATE_CONFIRMED == old_state) {
1492 1499
 		timeout_cb = (void *)CONFIRMED_DIALOG_STATE;
1493
-	}	
1500
+	}
1494 1501
 
1495 1502
 	dlg_run_event_route(dlg, NULL, old_state, new_state);
1496 1503
 
... ...
@@ -1500,6 +1507,9 @@ void dlg_ontimeout(struct dlg_tl *tl)
1500 1507
 			dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
1501 1508
 			dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
1502 1509
 
1510
+		/* set end time */
1511
+		dlg->end_ts = (unsigned int)(time(0));
1512
+
1503 1513
 		/* dialog timeout */
1504 1514
 		run_dlg_callbacks( DLGCB_EXPIRED, dlg, NULL, NULL, DLG_DIR_NONE, timeout_cb);
1505 1515
 
... ...
@@ -239,6 +239,13 @@ int dlg_clean_run(ticks_t ti)
239 239
 				tdlg->lifetime = 10;
240 240
 				tdlg->dflags |= DLG_FLAG_CHANGED;
241 241
 			}
242
+			if(tdlg->state==DLG_STATE_DELETED && tdlg->end_ts<tm-300) {
243
+				/* dialog in deleted state older than 5min */
244
+				LM_NOTICE("dialog in delete state is too old (%p ref %d)\n",
245
+						tdlg, tdlg->ref);
246
+				unlink_unsafe_dlg(&d_table->entries[i], tdlg);
247
+				destroy_dlg(tdlg);
248
+			}
242 249
 		}
243 250
 		dlg_unlock(d_table, &d_table->entries[i]);
244 251
 	}
... ...
@@ -108,6 +108,7 @@ typedef struct dlg_cell
108 108
 	unsigned int         lifetime;		/*!< dialog lifetime */
109 109
 	unsigned int         init_ts;		/*!< init (creation) time (absolute UNIX ts)*/
110 110
 	unsigned int         start_ts;		/*!< start time  (absolute UNIX ts)*/
111
+	unsigned int         end_ts;		/*!< end time  (absolute UNIX ts)*/
111 112
 	unsigned int         dflags;		/*!< internal dialog memory flags */
112 113
 	unsigned int         iflags;		/*!< internal dialog persistent flags */
113 114
 	unsigned int         sflags;		/*!< script dialog persistent flags */