Browse code

bug_fix: on_negative_reply now sets msg id and transaction context (previously, it didn't do so, which resulted in a lookup that consumed CPU and even worse, refcounted -- transaction that entered reply_route was never released)

Jiri Kuthan authored on 06/01/2003 12:48:56
Showing 3 changed files
... ...
@@ -113,7 +113,8 @@ static struct cell *T;
113 113
 unsigned int     global_msg_id;
114 114
 
115 115
 struct cell *get_t() { return T; }
116
-void init_t() {global_msg_id=0; T=T_UNDEFINED;}
116
+void set_t(struct cell *t) { T=t; }
117
+void init_t() {global_msg_id=0; set_t(T_UNDEFINED);}
117 118
 
118 119
 
119 120
 /* transaction matching a-la RFC-3261 using transaction ID in branch
... ...
@@ -188,7 +189,7 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked )
188 188
 	if (check_transaction_quadruple(p_msg)==0)
189 189
 	{
190 190
 		LOG(L_ERR, "ERROR: TM module: t_lookup_request: too few headers\n");
191
-		T=0;
191
+		set_t(0);	
192 192
 		/* stop processing */
193 193
 		return 0;
194 194
 	}
... ...
@@ -211,7 +212,7 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked )
211 211
 	 */
212 212
 	if (!p_msg->via1) {
213 213
 		LOG(L_ERR, "ERROR: t_lookup_request: no via\n");
214
-		T=0;
214
+		set_t(0);	
215 215
 		return 0;
216 216
 	}
217 217
 	branch=p_msg->via1->branch;
... ...
@@ -334,7 +335,7 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked )
334 334
 
335 335
 notfound:
336 336
 	/* no transaction found */
337
-	T = 0;
337
+	set_t(0);
338 338
 	if (!leave_new_locked) {
339 339
 		UNLOCK_HASH(p_msg->hash_index);
340 340
 	}
... ...
@@ -342,7 +343,7 @@ notfound:
342 342
 	return ret;
343 343
 
344 344
 found:
345
-	T=p_cell;
345
+	set_t(p_cell);
346 346
 	REF_UNSAFE( T );
347 347
 	T->kr|=REQ_EXIST;
348 348
 	UNLOCK_HASH( p_msg->hash_index );
... ...
@@ -376,7 +377,7 @@ struct cell* t_lookupOriginalT(  struct sip_msg* p_msg )
376 376
 	 */
377 377
 	if (!p_msg->via1) {
378 378
 		LOG(L_ERR, "ERROR: t_lookup_request: no via\n");
379
-		T=0;
379
+		set_t(0);
380 380
 		return 0;
381 381
 	}
382 382
 	branch=p_msg->via1->branch;
... ...
@@ -619,7 +620,7 @@ int t_reply_matching( struct sip_msg *p_msg , int *p_branch )
619 619
 		/* we passed all disqualifying factors .... the transaction has been
620 620
 		   matched !
621 621
 		*/
622
-		T=p_cell;
622
+		set_t(p_cell);
623 623
 		*p_branch = branch_id;
624 624
 		REF_UNSAFE( T );
625 625
 		UNLOCK_HASH(hash_index);
... ...
@@ -634,7 +635,7 @@ int t_reply_matching( struct sip_msg *p_msg , int *p_branch )
634 634
 nomatch2:
635 635
 	DBG("DEBUG: t_reply_matching: failure to match a transaction\n");
636 636
 	*p_branch = -1;
637
-	T = 0;
637
+	set_t(0);
638 638
 	return -1;
639 639
 }
640 640
 
... ...
@@ -807,7 +808,7 @@ int t_newtran( struct sip_msg* p_msg )
807 807
 				ret = E_OUT_OF_MEM;
808 808
 			} else {
809 809
 				insert_into_hash_table_unsafe( new_cell );
810
-				T=new_cell;
810
+				set_t(new_cell);
811 811
 				INIT_REF_UNSAFE(T);
812 812
 				/* init pointers to headers needed to construct local
813 813
 				   requests such as CANCEL/ACK
... ...
@@ -883,7 +884,7 @@ int t_unref( struct sip_msg* p_msg  )
883 883
 		t_release_transaction(T);
884 884
 	}
885 885
 	UNREF( T );
886
-	T=T_UNDEFINED;
886
+	set_t(T_UNDEFINED);
887 887
 	return 1;
888 888
 }
889 889
 
... ...
@@ -65,6 +65,10 @@ int t_check( struct sip_msg* , int *branch );
65 65
 
66 66
 struct cell *get_t();
67 67
 
68
+/* use carefully or better not at all -- current transaction is 
69
+ * primarily set by lookup functions */
70
+void set_t(struct cell *t);
71
+
68 72
 
69 73
 #endif
70 74
 
... ...
@@ -862,6 +862,8 @@ void on_negative_reply( struct cell* t, struct sip_msg* msg,
862 862
 	int act_ret;
863 863
 	struct sip_msg faked_msg;
864 864
 	enum route_mode backup_mode;
865
+	struct cell *backup_t;
866
+	unsigned int backup_msgid;
865 867
 
866 868
 	/* nobody cares about a negative transaction -- ok, return */
867 869
 	if (!t->on_negative) {
... ...
@@ -904,9 +906,28 @@ void on_negative_reply( struct cell* t, struct sip_msg* msg,
904 904
 	*/
905 905
 	faked_msg.id=t->uas.request->id-1;
906 906
 
907
+	/* remember we are back in request processing, but process
908
+	 * a shmem-ed replica of the request; advertise it in rmode;
909
+	 * for example t_reply needs to know that
910
+	 */
907 911
 	backup_mode=rmode;
908 912
 	rmode=MODE_ONREPLY_REQUEST;
913
+	/* also, tm actions look in beginning whether tranaction is
914
+	 * set -- whether we are called from a reply-processing 
915
+	 * or a timer process, we need to set current transaction;
916
+	 * otherwise the actions would attempt to look the transaction
917
+	 * up (unnecessary overhead, refcounting)
918
+	 */
919
+	/* backup */
920
+	backup_t=get_t();
921
+	backup_msgid=global_msg_id;
922
+	/* fake */
923
+	global_msg_id=faked_msg.id;
924
+	set_t(t);
925
+	/* run */
909 926
 	act_ret=run_actions(reply_rlist[t->on_negative], &faked_msg );
927
+	/* restore */
928
+	global_msg_id=backup_msgid;
910 929
 	rmode=backup_mode;
911 930
 
912 931
 	if (act_ret<0) {