瀏覽代碼

tm: extra checks to see if the transaction was canceled before forwarding branches

- catch cases when CANCEL arrives during branch_route execution
- reported  Sławomir Bocheński, FS#468
Daniel-Constantin Mierla 11 年之前
父節點
當前提交
b66033d054
共有 1 個文件被更改,包括 19 次插入7 次删除
  1. 19 7
      modules/tm/t_fwd.c

+ 19 - 7
modules/tm/t_fwd.c

@@ -1664,11 +1664,10 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 	/* make -Wall happy */
 	/* make -Wall happy */
 	current_uri.s=0;
 	current_uri.s=0;
 
 
-	if (t->flags & T_CANCELED){
-		DBG("t_forward_non_ack: no forwarding on a canceled transaction\n");
-		ser_error=E_CANCELED;
-		return -1;
-	}
+	getbflagsval(0, &backup_bflags);
+
+	if (t->flags & T_CANCELED) goto canceled;
+
 	if (p_msg->REQ_METHOD==METHOD_CANCEL) { 
 	if (p_msg->REQ_METHOD==METHOD_CANCEL) { 
 		t_invite=t_lookupOriginalT(  p_msg );
 		t_invite=t_lookupOriginalT(  p_msg );
 		if (t_invite!=T_NULL_CELL) {
 		if (t_invite!=T_NULL_CELL) {
@@ -1681,8 +1680,6 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 		}
 		}
 	}
 	}
 
 
-	getbflagsval(0, &backup_bflags);
-
 	/* if no more specific error code is known, use this */
 	/* if no more specific error code is known, use this */
 	lowest_ret=E_UNSPEC;
 	lowest_ret=E_UNSPEC;
 	/* branches added */
 	/* branches added */
@@ -1727,6 +1724,8 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 							p_msg->fwd_send_flags, proto,
 							p_msg->fwd_send_flags, proto,
 							(p_msg->dst_uri.len)?0:UAC_SKIP_BR_DST_F, &p_msg->instance,
 							(p_msg->dst_uri.len)?0:UAC_SKIP_BR_DST_F, &p_msg->instance,
 							&p_msg->ruid, &p_msg->location_ua);
 							&p_msg->ruid, &p_msg->location_ua);
+		/* test if cancel was received meanwhile */
+		if (t->flags & T_CANCELED) goto canceled;
 		if (branch_ret>=0) 
 		if (branch_ret>=0) 
 			added_branches |= 1<<branch_ret;
 			added_branches |= 1<<branch_ret;
 		else
 		else
@@ -1744,6 +1743,8 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 							&path, proxy, si, p_msg->fwd_send_flags,
 							&path, proxy, si, p_msg->fwd_send_flags,
 							proto, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance,
 							proto, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance,
 							&ruid, &location_ua);
 							&ruid, &location_ua);
+		/* test if cancel was received meanwhile */
+		if (t->flags & T_CANCELED) goto canceled;
 		/* pick some of the errors in case things go wrong;
 		/* pick some of the errors in case things go wrong;
 		   note that picking lowest error is just as good as
 		   note that picking lowest error is just as good as
 		   any other algorithm which picks any other negative
 		   any other algorithm which picks any other negative
@@ -1817,6 +1818,17 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 	ser_error=0; /* clear branch send errors, we have overall success */
 	ser_error=0; /* clear branch send errors, we have overall success */
 	set_kr(REQ_FWDED);
 	set_kr(REQ_FWDED);
 	return 1;
 	return 1;
+
+canceled:
+	DBG("t_forward_non_ack: no forwarding on a canceled transaction\n");
+	/* reset processed branches */
+	clear_branches();
+	/* restore backup flags from initial env */
+	setbflagsval(0, backup_bflags);
+	/* update message flags, if changed in branch route */
+	t->uas.request->flags = p_msg->flags;
+	ser_error=E_CANCELED;
+	return -1;
 }
 }