Преглед изворни кода

Merge remote branch 'origin/tmp/ruri_branch'

* origin/tmp/ruri_branch:
  modules*: mark r-uri as "new" when changed
  tm: failure route start with r-uri marked as "consumed"
  tm: use ruri for forking only if marked as "new"
  core: mark uri as new on  new message or seturi()
  core: support for marking a "consumed" r-uri
Andrei Pelinescu-Onciul пре 15 година
родитељ
комит
9b0c1a0e1f

+ 3 - 0
action.c

@@ -545,6 +545,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 				msg->new_uri.len=0;
 				msg->new_uri.s=0;
 				msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
+				ruri_mark_new(); /* available for forking */
 			};
 			ret=1;
 			break;
@@ -593,6 +594,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 					memcpy(msg->new_uri.s, a->val[0].u.string, len);
 					msg->new_uri.s[len]=0;
 					msg->new_uri.len=len;
+					ruri_mark_new(); /* available for forking */
 
 					ret=1;
 					break;
@@ -870,6 +872,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 				msg->new_uri.s=new_uri;
 				msg->new_uri.len=crt-new_uri;
 				msg->parsed_uri_ok=0;
+				ruri_mark_new(); /* available for forking */
 				ret=1;
 				break;
 		case IF_T:

+ 10 - 5
dset.c

@@ -27,11 +27,10 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/*!
- * \file
- * \brief SIP-router core :: 
- * \ingroup core
- * Module: \ref core
+/** destination set / branches support.
+ * @file dset.c
+ * @ingroup core
+ * Module: @ref core
  */
 
 #include <string.h>
@@ -68,6 +67,9 @@ unsigned int nr_branches = 0;
 /* branch iterator */
 static int branch_iterator = 0;
 
+/* used to mark ruris "consumed" when branching (1 new, 0 consumed) */
+int ruri_is_new = 0;
+
 /* The q parameter of the Request-URI */
 static qvalue_t ruri_q = Q_UNSPECIFIED;
 
@@ -266,6 +268,7 @@ void clear_branches(void)
 	nr_branches = 0;
 	ruri_q = Q_UNSPECIFIED;
 	ruri_bflags = 0;
+	ruri_mark_consumed();
 }
 
 
@@ -493,6 +496,8 @@ int rewrite_uri(struct sip_msg* _m, str* _s)
 
         _m->new_uri.s = buf;
         _m->new_uri.len = _s->len;
+        /* mark ruri as new and available for forking */
+        ruri_mark_new();
 
         return 1;
 }

+ 10 - 0
dset.h

@@ -37,6 +37,7 @@
 
 
 extern unsigned int nr_branches;
+extern int ruri_is_new;
 
 /*! \brief
  * Structure for storing branch attributes
@@ -166,6 +167,15 @@ inline static int get_request_uri(struct sip_msg* _m, str* _u)
 }
 
 
+#define ruri_mark_new() (ruri_is_new = 1)
+
+#define ruri_mark_consumed()  (ruri_is_new = 0)
+
+/** returns whether or not ruri should be used when forking.
+  * (usefull for serial forking)
+  * @return 0 if already marked as consumed, 1 if not.
+ */
+#define ruri_get_forking_state() (ruri_is_new)
 
 int rewrite_uri(struct sip_msg* _m, str* _s);
 

+ 3 - 0
modules/app_python/python_msgobj.c

@@ -146,6 +146,9 @@ msg_set_dst_uri(msgobject *self, PyObject *args)
         LM_ERR("Error in set_dst_uri\n");
         PyErr_SetString(PyExc_RuntimeError, "Error in set_dst_uri\n");
     }
+    /* dst_uri changes, so it makes sense to re-use the current uri for
+       forking */
+    ruri_mark_new(); /* re-use uri for serial forking */
 
     Py_INCREF(Py_None);
     return Py_None;

+ 3 - 0
modules/avpops/avpops_impl.c

@@ -1020,6 +1020,9 @@ int ops_pushto_avp (struct sip_msg* msg, struct fis_param* dst,
 				LM_ERR("changing dst uri failed\n");
 				goto error;
 			}
+			/* dst_uri changes, so it makes sense to re-use the current uri for
+				forking */
+			ruri_mark_new(); /* re-use uri for serial forking */
 		} else if (dst->opd&AVPOPS_USE_BRANCH) {
 			if (append_branch( msg, &val, 0, 0, Q_UNSPECIFIED, 0,
 								msg->force_send_socket)!=1 )

+ 8 - 4
modules/tm/t_fwd.c

@@ -1328,11 +1328,9 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 		branch_route = 0;
 	}
 	
-	/* on first-time forwarding, use current uri, later only what
-	   is in additional branches (which may be continuously refilled
-	*/
-	if (first_branch==0) {
 #ifdef POSTPONE_MSG_CLONING
+	/* on first-time forwarding, update the lumps */
+	if (first_branch==0) {
 		/* update the shmem-ized msg with the lumps */
 		if ((is_route_type(REQUEST_ROUTE)) &&
 			save_msg_lumps(t->uas.request, p_msg)) {
@@ -1340,7 +1338,13 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 					"failed to save the message lumps\n");
 				return -1;
 			}
+	}
 #endif
+	/* if ruri is not already consumed (by another invocation), use current
+	   uri too. Else add only additional branches (which may be continuously
+	   refilled).
+	*/
+	if (ruri_get_forking_state()) {
 		try_new=1;
 		branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg),
 							&p_msg->path_vec, proxy, p_msg->force_send_socket,

+ 6 - 0
modules/tm/t_reply.c

@@ -718,6 +718,7 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg,
 /** create or restore a "fake environment" for running a failure_route.
  *if msg is set -> it will fake the env. vars conforming with the msg; if NULL
  * the env. will be restore to original.
+ * Side-effect: mark_ruri_consumed().
  */
 void faked_env( struct cell *t, struct sip_msg *msg)
 {
@@ -740,6 +741,11 @@ void faked_env( struct cell *t, struct sip_msg *msg)
 		 */
 		backup_route_type=get_route_type();
 		set_route_type(FAILURE_ROUTE);
+		/* don't bother backing up ruri state, since failure route
+		   is called either on reply or on timer and in both cases
+		   the ruri should not be used again for forking */
+		ruri_mark_consumed(); /* in failure route we assume ruri
+								 should not be used again for forking */
 		/* also, tm actions look in beginning whether transaction is
 		 * set -- whether we are called from a reply-processing
 		 * or a timer process, we need to set current transaction;

+ 3 - 0
modules_k/cpl-c/cpl_sig.c

@@ -72,6 +72,9 @@ int cpl_proxy_to_loc_set( struct sip_msg *msg, struct location **locs,
 				LM_ERR("Error while setting the dst uri\n");
 				goto error;
 			}
+			/* dst_uri changes, so it makes sense to re-use the current uri for
+				forking */
+			ruri_mark_new(); /* re-use uri for serial forking */
 		}
 		/* is the location NATED? */
 		if ((*locs)->flags&CPL_LOC_NATED)

+ 4 - 1
modules_k/dispatcher/dispatch.c

@@ -1234,7 +1234,10 @@ static inline int ds_update_dst(struct sip_msg *msg, str *uri, int mode)
 			if (set_dst_uri(msg, uri) < 0) {
 				LM_ERR("error while setting dst uri\n");
 				return -1;
-			}	
+			}
+			/* dst_uri changes, so it makes sense to re-use the current uri for
+				forking */
+			ruri_mark_new(); /* re-use uri for serial forking */
 		break;
 	}
 	if(ds_append_branch!=0 && is_route_type(FAILURE_ROUTE))

+ 3 - 0
modules_k/domainpolicy/domainpolicy.c

@@ -1021,6 +1021,9 @@ int dp_apply_policy(struct sip_msg* _msg, char* _s1, char* _s2) {
 	duri_str.len = at - duri_str.s;
 	LM_DBG("new DURI is '%.*s'\n",duri_str.len, ZSW(duri_str.s));
 	set_dst_uri(_msg, &duri_str);
+	/* dst_uri changes, so it makes sense to re-use the current uri for
+		forking */
+	ruri_mark_new(); /* re-use uri for serial forking */
 
 	return 1;
 }

+ 2 - 0
modules_k/drouting/drouting.c

@@ -45,6 +45,7 @@
 #include "../../resolve.h"
 #include "../../parser/parse_from.h"
 #include "../../parser/parse_uri.h"
+#include "../../dset.h"
 #include "../../lib/kmi/mi.h"
 
 #include "dr_load.h"
@@ -873,6 +874,7 @@ again:
 		pkg_free(msg->new_uri.s);
 	msg->new_uri = *ruri;
 	msg->parsed_uri_ok = 0;
+	ruri_mark_new();
 
 	return 1;
 error2:

+ 3 - 0
modules_k/kex/km_core.c

@@ -77,6 +77,9 @@ int w_setdsturi(struct sip_msg *msg, char *uri, str *s2)
 	
 	if(set_dst_uri(msg, &s)!=0)
 		return -1;
+	/* dst_uri changes, so it makes sense to re-use the current uri for
+		forking */
+	ruri_mark_new(); /* re-use uri for serial forking */
 	return 1;
 
 }

+ 4 - 0
modules_k/path/path.c

@@ -36,6 +36,7 @@
 #include "../../mem/mem.h"
 #include "../../data_lump.h"
 #include "../../parser/parse_param.h"
+#include "../../dset.h"
 
 #include "path.h"
 #include "path_mod.h"
@@ -219,6 +220,9 @@ void path_rr_callback(struct sip_msg *_m, str *r_param, void *cb_param)
 			free_params(params);
 			return;
 		}
+		/* dst_uri changed, so it makes sense to re-use the current uri for
+			forking */
+		ruri_mark_new(); /* re-use uri for serial forking */
 	}
 	free_params(params);
 }

+ 3 - 0
modules_k/pv/pv_core.c

@@ -1670,6 +1670,9 @@ int pv_set_dsturi(struct sip_msg* msg, pv_param_t *param,
 	
 	if(set_dst_uri(msg, &val->rs)!=0)
 		goto error;
+	/* dst_uri changed, so it makes sense to re-use the current uri for
+		forking */
+	ruri_mark_new(); /* re-use uri for serial forking */
 
 	return 0;
 error:

+ 3 - 0
modules_k/rr/loose.c

@@ -872,6 +872,9 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
 			LM_ERR("failed to set dst_uri\n");
 			return RR_ERROR;
 		}
+		/* dst_uri changed, so it makes sense to re-use the current uri for
+			forking */
+		ruri_mark_new(); /* re-use uri for serial forking */
 
 		/* There is a previous route uri which was 2nd uri of mine
 		 * and must be removed here */

+ 2 - 0
modules_k/textops/textops.c

@@ -67,6 +67,7 @@
 #include "../../lib/kcore/parse_privacy.h"
 #include "../../msg_translator.h"
 #include "../../ut.h"
+#include "../../dset.h"
 #include "../../lib/kcore/cmpapi.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -694,6 +695,7 @@ static int subst_uri_f(struct sip_msg* msg, char*  subst, char* ignored)
 		if (msg->new_uri.s) pkg_free(msg->new_uri.s);
 		msg->new_uri=*result;
 		msg->parsed_uri_ok=0; /* reset "use cached parsed uri" flag */
+		ruri_mark_new();
 		pkg_free(result); /* free str* pointer */
 		return 1; /* success */
 	}

+ 2 - 0
modules_k/uac/auth.c

@@ -36,6 +36,7 @@
 #include "../../data_lump.h"
 #include "../../mem/mem.h"
 #include "../../hashes.h"
+#include "../../dset.h"
 #include "../../modules/tm/tm_load.h"
 
 #include "auth.h"
@@ -341,6 +342,7 @@ static inline int apply_urihdr_changes( struct sip_msg *req,
 	memcpy( req->new_uri.s, uri->s, uri->len);
 	req->new_uri.s[uri->len]=0;
 	req->new_uri.len=uri->len;
+	ruri_mark_new();
 
 	/* add the header */
 	if (parse_headers(req, HDR_EOH_F, 0) == -1)

+ 3 - 0
modules_s/avp/avp.c

@@ -1156,6 +1156,9 @@ static int attr_destination(struct sip_msg* msg, char* p1, char* p2)
 		LOG(L_ERR, "ERROR: avp_destination: Can't set dst uri\n");
 		return -1;
 	    };
+		/* dst_uri changed, so it makes sense to re-use the current uri for
+			forking */
+		ruri_mark_new(); /* re-use uri for serial forking */
 	    return 1;
 	} else {
 	    ERR("avp_destination:AVP has numeric value\n");

+ 6 - 0
modules_s/dispatcher/ds_backend.c

@@ -38,6 +38,7 @@
 #include "../../mem/shm_mem.h"
 #include "../../parser/parse_uri.h"
 #include "../../parser/parse_from.h"
+#include "../../dset.h"
 
 #include "dispatcher.h"
 
@@ -348,6 +349,7 @@ static int set_new_uri_simple(struct sip_msg *msg, str *uri)
 	memcpy(msg->new_uri.s, uri->s, uri->len);
 	msg->new_uri.s[uri->len]=0;
 	msg->new_uri.len=uri->len;
+	ruri_mark_new();
 	return 0;
 }
 
@@ -394,6 +396,7 @@ static int set_new_uri_with_user(struct sip_msg *msg, str *uri, str *user)
 	
 	msg->new_uri.len=uri->len + user->len + 1;
 	msg->new_uri.s[msg->new_uri.len]=0;
+	ruri_mark_new();
 	
 	return 0;
 }
@@ -544,6 +547,9 @@ int ds_select_dst_impl(struct sip_msg *msg, char *set_, char *alg_, int set_new)
 				"DISPATCHER:dst_select_dst: Error while setting dst_uri\n");
             return -1;
         }
+		/* dst_uri changed, so it makes sense to re-use the current uri for
+			forking */
+		ruri_mark_new(); /* re-use uri for serial forking */
     	DBG("DISPATCHER:ds_select_dst: selected [%d-%d-%d] <%.*s>\n",
         	alg, set, hash, msg->dst_uri.len, msg->dst_uri.s);
 	} else {

+ 1 - 0
modules_s/mangler/contact_ops.c

@@ -184,6 +184,7 @@ decode_contact (struct sip_msg *msg,char *unused1,char *unused2)
 		msg->new_uri = newUri;
 		msg->parsed_uri_ok=0;
 		msg->dst_uri = dst_uri;
+		ruri_mark_new();
 	}
 	return 1;
 }

+ 2 - 0
modules_s/registrar/lookup.c

@@ -125,6 +125,7 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
 			if (_m->new_uri.s)      pkg_free(_m->new_uri.s);
 			_m->new_uri=new_uri;
 			_m->parsed_uri_ok=0;
+			ruri_mark_new();
 			goto skip_rewrite_uri;
 			}else if (set_dst_uri(_m, &ptr->received) < 0) {
 				ul.unlock_udomain((udomain_t*)_t);
@@ -288,6 +289,7 @@ int lookup2(struct sip_msg* msg, char* table, char* p2)
 			if (msg->new_uri.s) pkg_free(msg->new_uri.s);
 			msg->new_uri = new_uri;
 			msg->parsed_uri_ok = 0;
+			ruri_mark_new();
 			goto skip_rewrite_uri;
 			} else if (set_dst_uri(msg, &ptr->received) < 0) {
 			        ul.unlock_udomain((udomain_t*)table);

+ 3 - 0
modules_s/rr/loose.c

@@ -970,6 +970,9 @@ static inline int after_loose(struct sip_msg* _m, struct sip_uri* _pru, int _rou
 			LOG(L_ERR, "after_loose: Error while setting dst_uri\n");
 			return RR_ERROR;
 		}
+		/* dst_uri changed, so it makes sense to re-use the current uri for
+			forking */
+		ruri_mark_new(); /* re-use uri for serial forking */
 
 		     /* There is a previous route uri which was 2nd uri of mine
 		      * and must be removed here

+ 2 - 0
modules_s/textops/textops.c

@@ -78,6 +78,7 @@
 #include "../../script_cb.h"
 #include "../../select_buf.h"
 #include "../../ser_time.h"
+#include "../../dset.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -531,6 +532,7 @@ static int subst_uri_f(struct sip_msg* msg, char*  subst, char* ignored)
 		if (msg->new_uri.s) pkg_free(msg->new_uri.s);
 		msg->new_uri=*result;
 		msg->parsed_uri_ok=0; /* reset "use cached parsed uri" flag */
+		ruri_mark_new();
 		pkg_free(result); /* free str* pointer */
 		return 1; /* success */
 	}

+ 2 - 0
modules_s/uac/auth.c

@@ -37,6 +37,7 @@
 #include "../../dprint.h"
 #include "../../data_lump.h"
 #include "../../mem/mem.h"
+#include "../../dset.h"
 #include "../../modules/tm/tm_load.h"
 
 #include "auth.h"
@@ -292,6 +293,7 @@ static inline int apply_urihdr_changes( struct sip_msg *req,
 	memcpy( req->new_uri.s, uri->s, uri->len);
 	req->new_uri.s[uri->len]=0;
 	req->new_uri.len=uri->len;
+	ruri_mark_new();
 
 	/* add the header */
 	if (parse_headers(req, HDR_EOH_F, 0) == -1)

+ 1 - 0
receive.c

@@ -149,6 +149,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 	clear_branches();
 
 	if (msg->first_line.type==SIP_REQUEST){
+		ruri_mark_new(); /* ruri is usable for forking (not consumed yet) */
 		if (!IS_SIP(msg)){
 			if ((ret=nonsip_msg_run_hooks(msg))!=NONSIP_MSG_ACCEPT){
 				if (unlikely(ret==NONSIP_MSG_ERROR))