Browse code

dialog: check if dialog exists after event route execution

- done for dlg_onroute(), as an extra safety for early detection of
races, related to GH #1059

Daniel-Constantin Mierla authored on 06/04/2017 15:06:37
Showing 1 changed files
... ...
@@ -1226,12 +1226,14 @@ dlg_cell_t *dlg_get_msg_dialog(sip_msg_t *msg)
1226 1226
  */
1227 1227
 void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
1228 1228
 {
1229
-	dlg_cell_t *dlg;
1230
-	dlg_iuid_t *iuid;
1229
+	dlg_cell_t *dlg = NULL;
1230
+	dlg_cell_t *dlg0 = NULL;
1231
+	dlg_iuid_t *iuid = NULL;
1231 1232
 	str val, callid, ftag, ttag;
1232
-	int h_entry, h_id, new_state, old_state, unref, event, timeout, reset;
1233
-	unsigned int dir;
1234
-	int ret = 0;
1233
+	int h_entry=0, h_id=0, new_state=0, old_state=0;
1234
+	int unref=0, event=0, timeout=0, reset=0;
1235
+	unsigned int dir=0;
1236
+	int ret=0;
1235 1237
 
1236 1238
 	dlg = dlg_get_ctx_dialog();
1237 1239
 	if (dlg!=NULL) {
... ...
@@ -1321,8 +1323,10 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
1321 1321
 
1322 1322
     /* set current dialog - re-use ref increment from dlg_get() above */
1323 1323
     set_current_dialog( req, dlg);
1324
-    _dlg_ctx.iuid.h_entry = dlg->h_entry;
1325
-    _dlg_ctx.iuid.h_id = dlg->h_id;
1324
+    h_entry = dlg->h_entry;
1325
+    h_id = dlg->h_id;
1326
+    _dlg_ctx.iuid.h_entry = h_entry;
1327
+    _dlg_ctx.iuid.h_id = h_id;
1326 1328
 
1327 1329
 	if(dlg->iflags & DLG_IFLAG_CSEQ_DIFF) {
1328 1330
 		if(dlg_cseq_refresh(req, dlg, dir)<0) {
... ...
@@ -1364,6 +1368,15 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
1364 1364
 
1365 1365
 	dlg_run_event_route(dlg, req, old_state, new_state);
1366 1366
 
1367
+	dlg0 = dlg_lookup(h_entry, h_id);
1368
+	if (dlg0==0) {
1369
+		LM_ALERT("after event route - dialog not found [%u:%u] (%d/%d) (%p)\n",
1370
+				h_entry, h_id, old_state, new_state, dlg);
1371
+		return;
1372
+	} else {
1373
+		dlg_release(dlg0);
1374
+	}
1375
+
1367 1376
 	/* delay deletion of dialog until transaction has died off in order
1368 1377
 	 * to absorb in-air messages */
1369 1378
 	if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {