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