Browse code

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

Jiri Kuthan authored on 30/04/2003 13:01:26
Showing 1 changed files
... ...
@@ -69,6 +69,7 @@
69 69
  *             UAC transactions (jiri)
70 70
  * 2003-04-07  new transactions inherit on_negative and on_relpy from script
71 71
  *             variables on instatntiation (jiri)
72
+ * 2003-04-30  t_newtran clean up (jiri)
72 73
  */
73 74
 
74 75
 
... ...
@@ -919,6 +920,59 @@ int init_rb( struct retr_buf *rb, struct sip_msg *msg)
919 919
 }
920 920
 
921 921
 
922
+static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg)
923
+{
924
+	struct sip_msg *shm_msg;
925
+
926
+	shm_msg=new_cell->uas.request;
927
+	new_cell->from.s=shm_msg->from->name.s;
928
+	new_cell->from.len=HF_LEN(shm_msg->from);
929
+	new_cell->to.s=shm_msg->to->name.s;
930
+	new_cell->to.len=HF_LEN(shm_msg->to);
931
+	new_cell->callid.s=shm_msg->callid->name.s;
932
+	new_cell->callid.len=HF_LEN(shm_msg->callid);
933
+	new_cell->cseq_n.s=shm_msg->cseq->name.s;
934
+	new_cell->cseq_n.len=get_cseq(shm_msg)->number.s
935
+		+get_cseq(shm_msg)->number.len
936
+		-shm_msg->cseq->name.s;
937
+
938
+	new_cell->method=new_cell->uas.request->first_line.u.request.method;
939
+	new_cell->is_invite=p_msg->REQ_METHOD==METHOD_INVITE;
940
+	new_cell->on_negative=get_on_negative();
941
+	new_cell->on_reply=get_on_reply();
942
+}
943
+
944
+static inline int new_t(struct sip_msg *p_msg)
945
+{
946
+	struct cell *new_cell;
947
+
948
+	/* for ACK-dlw-wise matching, we want From-tags */
949
+	if (p_msg->REQ_METHOD==METHOD_INVITE && parse_from_header(p_msg)<0) {
950
+			LOG(L_ERR, "ERROR: new_t: no valid From in INVITE\n");
951
+			return E_BAD_REQ;
952
+	}
953
+	/* make sure uri will be parsed before cloning */
954
+	if (parse_sip_msg_uri(p_msg)<0) {
955
+		LOG(L_ERR, "ERROR: new_t: uri invalid\n");
956
+		return E_BAD_REQ;
957
+	}
958
+			
959
+	/* add new transaction */
960
+	new_cell = build_cell( p_msg ) ;
961
+	if  ( !new_cell ){
962
+		LOG(L_ERR, "ERROR: new_t: out of mem:\n");
963
+		return E_OUT_OF_MEM;
964
+	} 
965
+
966
+	insert_into_hash_table_unsafe( new_cell );
967
+	set_t(new_cell);
968
+	INIT_REF_UNSAFE(T);
969
+	/* init pointers to headers needed to construct local
970
+	   requests such as CANCEL/ACK
971
+	*/
972
+	init_new_t(new_cell, p_msg);
973
+	return 1;
974
+}
922 975
 
923 976
 /* atomic "new_tran" construct; it returns:
924 977
 
... ...
@@ -936,11 +990,7 @@ int init_rb( struct retr_buf *rb, struct sip_msg *msg)
936 936
 int t_newtran( struct sip_msg* p_msg )
937 937
 {
938 938
 
939
-	int ret, lret, my_err;
940
-	struct cell *new_cell;
941
-	struct sip_msg *shm_msg;
942
-
943
-	ret=1;
939
+	int lret, my_err;
944 940
 
945 941
 	/* is T still up-to-date ? */
946 942
 	DBG("DEBUG: t_addifnew: msg id=%d , global msg id=%d ,"
... ...
@@ -954,13 +1004,11 @@ int t_newtran( struct sip_msg* p_msg )
954 954
 
955 955
 	global_msg_id = p_msg->id;
956 956
 	T = T_UNDEFINED;
957
-	/* first of all, parse everything -- we will store
958
-	   in shared memory and need to have all headers
959
-	   ready for generating potential replies later;
960
-	   parsing later on demand is not an option since
961
-	   the request will be in shmem and applying 
962
-	   parse_headers to it would intermix shmem with
963
-	   pkg_mem
957
+	/* first of all, parse everything -- we will store in shared memory 
958
+	   and need to have all headers ready for generating potential replies 
959
+	   later; parsing later on demand is not an option since the request 
960
+	   will be in shmem and applying parse_headers to it would intermix 
961
+	   shmem with pkg_mem
964 962
 	*/
965 963
 	
966 964
 	if (parse_headers(p_msg, HDR_EOH, 0 )) {
... ...
@@ -976,117 +1024,80 @@ int t_newtran( struct sip_msg* p_msg )
976 976
 	   safe to assume we have from/callid/cseq/to
977 977
 	*/ 
978 978
 	lret = t_lookup_request( p_msg, 1 /* leave locked if not found */ );
979
-	/* on error, pass the error in the stack ... */
980
-	if (lret==0) return E_BAD_TUPEL;
981
-	/* transaction not found, it's a new request;
982
-	   establish a new transaction (unless it is an ACK) */
983
-	if (lret<0) {
984
-		new_cell=0;
985
-		if ( p_msg->REQ_METHOD!=METHOD_ACK ) {
986
-			/* REVIEW */
987
-			/* for ACK-dlw-wise matching, we want From-tags */
988
-			if (p_msg->REQ_METHOD==METHOD_INVITE) {
989
-				if (parse_from_header(p_msg)<0) {
990
-					LOG(L_ERR, "ERROR: t_newtran: no valid From\n");
991
-					my_err=E_BAD_REQ;
992
-					goto new_err;
993
-				}
994
-			}
995
-			/* REVIEW */
996
-			/* make sure uri will be parsed before cloning */
997
-			if (parse_sip_msg_uri(p_msg)<0) {
998
-				LOG(L_ERR, "ERROR: t_new_tran: uri invalid\n");
999
-				my_err=E_BAD_REQ;
1000
-				goto new_err;
1001
-			}
1002
-			
1003
-			/* add new transaction */
1004
-			new_cell = build_cell( p_msg ) ;
1005
-			if  ( !new_cell ){
1006
-				LOG(L_ERR, "ERROR: t_addifnew: out of mem:\n");
1007
-				my_err = E_OUT_OF_MEM;
1008
-				goto new_err;
1009
-			} else {
1010
-				insert_into_hash_table_unsafe( new_cell );
1011
-				set_t(new_cell);
1012
-				INIT_REF_UNSAFE(T);
1013
-				/* init pointers to headers needed to construct local
1014
-				   requests such as CANCEL/ACK
1015
-				*/
1016 979
 
1017
-				shm_msg=new_cell->uas.request;
1018
-				new_cell->from.s=shm_msg->from->name.s;
1019
-				new_cell->from.len=HF_LEN(shm_msg->from);
1020
-				new_cell->to.s=shm_msg->to->name.s;
1021
-				new_cell->to.len=HF_LEN(shm_msg->to);
1022
-				new_cell->callid.s=shm_msg->callid->name.s;
1023
-				new_cell->callid.len=HF_LEN(shm_msg->callid);
1024
-				new_cell->cseq_n.s=shm_msg->cseq->name.s;
1025
-				new_cell->cseq_n.len=get_cseq(shm_msg)->number.s
1026
-					+get_cseq(shm_msg)->number.len
1027
-					-shm_msg->cseq->name.s;
1028
-
1029
-				new_cell->method=new_cell->uas.request->first_line.u.request.method;
1030
-				new_cell->is_invite=p_msg->REQ_METHOD==METHOD_INVITE;
1031
-				new_cell->on_negative=get_on_negative();
1032
-				new_cell->on_reply=get_on_reply();
1033
-
1034
-			}
980
+	/* on error, pass the error in the stack ... nothing is locked yet
981
+	   if 0 is returned */
982
+	if (lret==0) return E_BAD_TUPEL;
1035 983
 
984
+	/* transaction found, it's a retransmission  */
985
+	if (lret>0) {
986
+		if (p_msg->REQ_METHOD==METHOD_ACK) {
987
+			t_release_transaction(T);
988
+		} else {
989
+			t_retransmit_reply(T);
1036 990
 		}
991
+		/* things are done -- return from script */
992
+		return 0;
993
+	}
1037 994
 
1038
-		/* was it an e2e ACK ? if so, trigger a callback */
1039
-		if (lret==-2) {
1040
-				/* no callbacks? complete quickly */
1041
-				if (!callback_array[TMCB_E2EACK_IN]) {
1042
-					UNLOCK_HASH(p_msg->hash_index);
1043
-				} else {
1044
-					REF_UNSAFE(t_ack);
1045
-					UNLOCK_HASH(p_msg->hash_index);
1046
-					/* we don't call from within REPLY_LOCK -- that introduces
1047
-				   	   a race condition; however, it is so unlikely and the
1048
-				   	   impact is so small (callback called multiple times of
1049
-			           multiple ACK/200s received in parallel), that we do not
1050
-				   	    better waste time in locks
1051
-					 */
1052
-					if (unmatched_totag(t_ack, p_msg)) {
1053
-						callback_event( TMCB_E2EACK_IN, t_ack, p_msg, 
1054
-							p_msg->REQ_METHOD );
1055
-					}
1056
-					UNREF(t_ack);
1057
-				}
1058
-		} else { /* not e2e ACK */
995
+	/* from now on, be careful -- hash table is locked */
996
+
997
+	if (lret==-2) { /* was it an e2e ACK ? if so, trigger a callback */
998
+		/* no callbacks? complete quickly */
999
+		if (!callback_array[TMCB_E2EACK_IN]) {
1059 1000
 			UNLOCK_HASH(p_msg->hash_index);
1060
-			/* now, when the transaction state exists, check if
1061
-		 	   there is a meaningful Via and calculate it; better
1062
-		 	   do it now than later: state is established so that
1063
-		 	   subsequent retransmissions will be absorbed and will
1064
-	 		   not possibly block during Via DNS resolution; doing
1065
-			   it later would only burn more CPU as if there is an
1066
-			   error, we cannot relay later whatever comes out of the
1067
-  			   the transaction 
1068
-			*/
1069
-			if (new_cell && p_msg->REQ_METHOD!=METHOD_ACK) {
1070
-				if (!init_rb( &T->uas.response, p_msg)) {
1071
-					LOG(L_ERR, "ERROR: t_newtran: unresolveable via1\n");
1072
-					put_on_wait( T );
1073
-					t_unref(p_msg);
1074
-					ret=E_BAD_VIA;
1075
-				}
1076
-			}
1001
+			return 1;
1002
+		} 
1003
+		REF_UNSAFE(t_ack);
1004
+		UNLOCK_HASH(p_msg->hash_index);
1005
+		/* we don't call from within REPLY_LOCK -- that introduces
1006
+	   	   a race condition; however, it is so unlikely and the
1007
+	   	   impact is so small (callback called multiple times of
1008
+           multiple ACK/200s received in parallel), that we do not
1009
+	   	    better waste time in locks
1010
+		 */
1011
+		if (unmatched_totag(t_ack, p_msg)) {
1012
+			callback_event( TMCB_E2EACK_IN, t_ack, p_msg, 
1013
+				p_msg->REQ_METHOD );
1077 1014
 		}
1078
-
1079
-		return ret;
1015
+		UNREF(t_ack);
1016
+		return 1;
1080 1017
 	} 
1081 1018
 
1082
-	/* transaction found, it's a retransmission  or hbh ACK */
1083
-	if (p_msg->REQ_METHOD==METHOD_ACK) {
1084
-		t_release_transaction(T);
1085
-	} else {
1086
-		t_retransmit_reply(T);
1019
+
1020
+	/* transaction not found, it's a new request (lret<0, lret!=-2);
1021
+	   establish a new transaction ... */
1022
+	if (p_msg->REQ_METHOD==METHOD_ACK) { /* ... unless it is in ACK */
1023
+		my_err=1;
1024
+		goto new_err;
1087 1025
 	}
1088
-	/* things are done -- return from script */
1089
-	return 0;
1026
+
1027
+	my_err=new_t(p_msg);
1028
+	if (my_err<0) {
1029
+		LOG(L_ERR, "ERROR: t_newtran: new_t failed\n");
1030
+		goto new_err;
1031
+	}
1032
+
1033
+
1034
+	UNLOCK_HASH(p_msg->hash_index);
1035
+	/* now, when the transaction state exists, check if
1036
+ 	   there is a meaningful Via and calculate it; better
1037
+ 	   do it now than later: state is established so that
1038
+ 	   subsequent retransmissions will be absorbed and will
1039
+  	  not possibly block during Via DNS resolution; doing
1040
+	   it later would only burn more CPU as if there is an
1041
+	   error, we cannot relay later whatever comes out of the
1042
+  	   the transaction 
1043
+	*/
1044
+	if (!init_rb( &T->uas.response, p_msg)) {
1045
+		LOG(L_ERR, "ERROR: t_newtran: unresolveable via1\n");
1046
+		put_on_wait( T );
1047
+		t_unref(p_msg);
1048
+		return E_BAD_VIA;
1049
+	}
1050
+
1051
+	return 1;
1052
+
1090 1053
 
1091 1054
 new_err:
1092 1055
 	UNLOCK_HASH(p_msg->hash_index);