浏览代码

t_newtran cleaned up (unfortunately not tested -- if problems occur at fox,
please reverse)

Jiri Kuthan 22 年之前
父节点
当前提交
6ef782aba6
共有 1 个文件被更改,包括 125 次插入114 次删除
  1. 125 114
      modules/tm/t_lookup.c

+ 125 - 114
modules/tm/t_lookup.c

@@ -69,6 +69,7 @@
  *             UAC transactions (jiri)
  * 2003-04-07  new transactions inherit on_negative and on_relpy from script
  *             variables on instatntiation (jiri)
+ * 2003-04-30  t_newtran clean up (jiri)
  */
 
 
@@ -919,6 +920,59 @@ int init_rb( struct retr_buf *rb, struct sip_msg *msg)
 }
 
 
+static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg)
+{
+	struct sip_msg *shm_msg;
+
+	shm_msg=new_cell->uas.request;
+	new_cell->from.s=shm_msg->from->name.s;
+	new_cell->from.len=HF_LEN(shm_msg->from);
+	new_cell->to.s=shm_msg->to->name.s;
+	new_cell->to.len=HF_LEN(shm_msg->to);
+	new_cell->callid.s=shm_msg->callid->name.s;
+	new_cell->callid.len=HF_LEN(shm_msg->callid);
+	new_cell->cseq_n.s=shm_msg->cseq->name.s;
+	new_cell->cseq_n.len=get_cseq(shm_msg)->number.s
+		+get_cseq(shm_msg)->number.len
+		-shm_msg->cseq->name.s;
+
+	new_cell->method=new_cell->uas.request->first_line.u.request.method;
+	new_cell->is_invite=p_msg->REQ_METHOD==METHOD_INVITE;
+	new_cell->on_negative=get_on_negative();
+	new_cell->on_reply=get_on_reply();
+}
+
+static inline int new_t(struct sip_msg *p_msg)
+{
+	struct cell *new_cell;
+
+	/* for ACK-dlw-wise matching, we want From-tags */
+	if (p_msg->REQ_METHOD==METHOD_INVITE && parse_from_header(p_msg)<0) {
+			LOG(L_ERR, "ERROR: new_t: no valid From in INVITE\n");
+			return E_BAD_REQ;
+	}
+	/* make sure uri will be parsed before cloning */
+	if (parse_sip_msg_uri(p_msg)<0) {
+		LOG(L_ERR, "ERROR: new_t: uri invalid\n");
+		return E_BAD_REQ;
+	}
+			
+	/* add new transaction */
+	new_cell = build_cell( p_msg ) ;
+	if  ( !new_cell ){
+		LOG(L_ERR, "ERROR: new_t: out of mem:\n");
+		return E_OUT_OF_MEM;
+	} 
+
+	insert_into_hash_table_unsafe( new_cell );
+	set_t(new_cell);
+	INIT_REF_UNSAFE(T);
+	/* init pointers to headers needed to construct local
+	   requests such as CANCEL/ACK
+	*/
+	init_new_t(new_cell, p_msg);
+	return 1;
+}
 
 /* atomic "new_tran" construct; it returns:
 
@@ -936,11 +990,7 @@ int init_rb( struct retr_buf *rb, struct sip_msg *msg)
 int t_newtran( struct sip_msg* p_msg )
 {
 
-	int ret, lret, my_err;
-	struct cell *new_cell;
-	struct sip_msg *shm_msg;
-
-	ret=1;
+	int lret, my_err;
 
 	/* is T still up-to-date ? */
 	DBG("DEBUG: t_addifnew: msg id=%d , global msg id=%d ,"
@@ -954,13 +1004,11 @@ int t_newtran( struct sip_msg* p_msg )
 
 	global_msg_id = p_msg->id;
 	T = T_UNDEFINED;
-	/* first of all, parse everything -- we will store
-	   in shared memory and need to have all headers
-	   ready for generating potential replies later;
-	   parsing later on demand is not an option since
-	   the request will be in shmem and applying 
-	   parse_headers to it would intermix shmem with
-	   pkg_mem
+	/* first of all, parse everything -- we will store in shared memory 
+	   and need to have all headers ready for generating potential replies 
+	   later; parsing later on demand is not an option since the request 
+	   will be in shmem and applying parse_headers to it would intermix 
+	   shmem with pkg_mem
 	*/
 	
 	if (parse_headers(p_msg, HDR_EOH, 0 )) {
@@ -976,117 +1024,80 @@ int t_newtran( struct sip_msg* p_msg )
 	   safe to assume we have from/callid/cseq/to
 	*/ 
 	lret = t_lookup_request( p_msg, 1 /* leave locked if not found */ );
-	/* on error, pass the error in the stack ... */
-	if (lret==0) return E_BAD_TUPEL;
-	/* transaction not found, it's a new request;
-	   establish a new transaction (unless it is an ACK) */
-	if (lret<0) {
-		new_cell=0;
-		if ( p_msg->REQ_METHOD!=METHOD_ACK ) {
-			/* REVIEW */
-			/* for ACK-dlw-wise matching, we want From-tags */
-			if (p_msg->REQ_METHOD==METHOD_INVITE) {
-				if (parse_from_header(p_msg)<0) {
-					LOG(L_ERR, "ERROR: t_newtran: no valid From\n");
-					my_err=E_BAD_REQ;
-					goto new_err;
-				}
-			}
-			/* REVIEW */
-			/* make sure uri will be parsed before cloning */
-			if (parse_sip_msg_uri(p_msg)<0) {
-				LOG(L_ERR, "ERROR: t_new_tran: uri invalid\n");
-				my_err=E_BAD_REQ;
-				goto new_err;
-			}
-			
-			/* add new transaction */
-			new_cell = build_cell( p_msg ) ;
-			if  ( !new_cell ){
-				LOG(L_ERR, "ERROR: t_addifnew: out of mem:\n");
-				my_err = E_OUT_OF_MEM;
-				goto new_err;
-			} else {
-				insert_into_hash_table_unsafe( new_cell );
-				set_t(new_cell);
-				INIT_REF_UNSAFE(T);
-				/* init pointers to headers needed to construct local
-				   requests such as CANCEL/ACK
-				*/
 
-				shm_msg=new_cell->uas.request;
-				new_cell->from.s=shm_msg->from->name.s;
-				new_cell->from.len=HF_LEN(shm_msg->from);
-				new_cell->to.s=shm_msg->to->name.s;
-				new_cell->to.len=HF_LEN(shm_msg->to);
-				new_cell->callid.s=shm_msg->callid->name.s;
-				new_cell->callid.len=HF_LEN(shm_msg->callid);
-				new_cell->cseq_n.s=shm_msg->cseq->name.s;
-				new_cell->cseq_n.len=get_cseq(shm_msg)->number.s
-					+get_cseq(shm_msg)->number.len
-					-shm_msg->cseq->name.s;
-
-				new_cell->method=new_cell->uas.request->first_line.u.request.method;
-				new_cell->is_invite=p_msg->REQ_METHOD==METHOD_INVITE;
-				new_cell->on_negative=get_on_negative();
-				new_cell->on_reply=get_on_reply();
-
-			}
+	/* on error, pass the error in the stack ... nothing is locked yet
+	   if 0 is returned */
+	if (lret==0) return E_BAD_TUPEL;
 
+	/* transaction found, it's a retransmission  */
+	if (lret>0) {
+		if (p_msg->REQ_METHOD==METHOD_ACK) {
+			t_release_transaction(T);
+		} else {
+			t_retransmit_reply(T);
 		}
+		/* things are done -- return from script */
+		return 0;
+	}
 
-		/* was it an e2e ACK ? if so, trigger a callback */
-		if (lret==-2) {
-				/* no callbacks? complete quickly */
-				if (!callback_array[TMCB_E2EACK_IN]) {
-					UNLOCK_HASH(p_msg->hash_index);
-				} else {
-					REF_UNSAFE(t_ack);
-					UNLOCK_HASH(p_msg->hash_index);
-					/* we don't call from within REPLY_LOCK -- that introduces
-				   	   a race condition; however, it is so unlikely and the
-				   	   impact is so small (callback called multiple times of
-			           multiple ACK/200s received in parallel), that we do not
-				   	    better waste time in locks
-					 */
-					if (unmatched_totag(t_ack, p_msg)) {
-						callback_event( TMCB_E2EACK_IN, t_ack, p_msg, 
-							p_msg->REQ_METHOD );
-					}
-					UNREF(t_ack);
-				}
-		} else { /* not e2e ACK */
+	/* from now on, be careful -- hash table is locked */
+
+	if (lret==-2) { /* was it an e2e ACK ? if so, trigger a callback */
+		/* no callbacks? complete quickly */
+		if (!callback_array[TMCB_E2EACK_IN]) {
 			UNLOCK_HASH(p_msg->hash_index);
-			/* now, when the transaction state exists, check if
-		 	   there is a meaningful Via and calculate it; better
-		 	   do it now than later: state is established so that
-		 	   subsequent retransmissions will be absorbed and will
-	 		   not possibly block during Via DNS resolution; doing
-			   it later would only burn more CPU as if there is an
-			   error, we cannot relay later whatever comes out of the
-  			   the transaction 
-			*/
-			if (new_cell && p_msg->REQ_METHOD!=METHOD_ACK) {
-				if (!init_rb( &T->uas.response, p_msg)) {
-					LOG(L_ERR, "ERROR: t_newtran: unresolveable via1\n");
-					put_on_wait( T );
-					t_unref(p_msg);
-					ret=E_BAD_VIA;
-				}
-			}
+			return 1;
+		} 
+		REF_UNSAFE(t_ack);
+		UNLOCK_HASH(p_msg->hash_index);
+		/* we don't call from within REPLY_LOCK -- that introduces
+	   	   a race condition; however, it is so unlikely and the
+	   	   impact is so small (callback called multiple times of
+           multiple ACK/200s received in parallel), that we do not
+	   	    better waste time in locks
+		 */
+		if (unmatched_totag(t_ack, p_msg)) {
+			callback_event( TMCB_E2EACK_IN, t_ack, p_msg, 
+				p_msg->REQ_METHOD );
 		}
-
-		return ret;
+		UNREF(t_ack);
+		return 1;
 	} 
 
-	/* transaction found, it's a retransmission  or hbh ACK */
-	if (p_msg->REQ_METHOD==METHOD_ACK) {
-		t_release_transaction(T);
-	} else {
-		t_retransmit_reply(T);
+
+	/* transaction not found, it's a new request (lret<0, lret!=-2);
+	   establish a new transaction ... */
+	if (p_msg->REQ_METHOD==METHOD_ACK) { /* ... unless it is in ACK */
+		my_err=1;
+		goto new_err;
 	}
-	/* things are done -- return from script */
-	return 0;
+
+	my_err=new_t(p_msg);
+	if (my_err<0) {
+		LOG(L_ERR, "ERROR: t_newtran: new_t failed\n");
+		goto new_err;
+	}
+
+
+	UNLOCK_HASH(p_msg->hash_index);
+	/* now, when the transaction state exists, check if
+ 	   there is a meaningful Via and calculate it; better
+ 	   do it now than later: state is established so that
+ 	   subsequent retransmissions will be absorbed and will
+  	  not possibly block during Via DNS resolution; doing
+	   it later would only burn more CPU as if there is an
+	   error, we cannot relay later whatever comes out of the
+  	   the transaction 
+	*/
+	if (!init_rb( &T->uas.response, p_msg)) {
+		LOG(L_ERR, "ERROR: t_newtran: unresolveable via1\n");
+		put_on_wait( T );
+		t_unref(p_msg);
+		return E_BAD_VIA;
+	}
+
+	return 1;
+
 
 new_err:
 	UNLOCK_HASH(p_msg->hash_index);