Bläddra i källkod

modules/tm: Make ruid available in uac structure

- ruid is stored per uac
- ruid can be retrieved when a response to the branch is received
Hugh Waite 12 år sedan
förälder
incheckning
ef9115b65f
4 ändrade filer med 107 tillägg och 11 borttagningar
  1. 1 0
      modules/tm/h_table.h
  2. 79 11
      modules/tm/t_fwd.c
  3. 26 0
      modules/tm/t_reply.c
  4. 1 0
      modules/tm/t_reply.h

+ 1 - 0
modules/tm/h_table.h

@@ -230,6 +230,7 @@ typedef struct ua_client
 	str uri;
 	str path;
 	str instance;
+	str ruid;
 	/* if we don't store, we at least want to know the status */
 	int             last_received;
 

+ 79 - 11
modules/tm/t_fwd.c

@@ -188,7 +188,7 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
 									struct socket_info* fsocket,
 									snd_flags_t snd_flags,
 									int fproto, int flags,
-									str *instance)
+									str *instance, str *ruid)
 {
 	char *shbuf;
 	struct lump* add_rm_backup, *body_lumps_backup;
@@ -203,6 +203,8 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
 	int free_path;
 	str instance_bak;
 	int free_instance;
+	str ruid_bak;
+	int free_ruid;
 	int backup_route_type;
 	snd_flags_t fwd_snd_flags_bak;
 	snd_flags_t rpl_snd_flags_bak;
@@ -225,6 +227,9 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
 	instance_bak.s=0;
 	instance_bak.len=0;
 	free_instance=0;
+	ruid_bak.s=0;
+	ruid_bak.len=0;
+	free_ruid=0;
 	dst=&t->uac[branch].request.dst;
 
 	/* ... we calculate branch ... */	
@@ -266,6 +271,7 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
 	parsed_uri_ok_bak=i_req->parsed_uri_ok;
 	path_bak=i_req->path_vec;
 	instance_bak=i_req->instance;
+	ruid_bak=i_req->ruid;
 	
 	if (unlikely(branch_route || has_tran_tmcbs(t, TMCB_REQUEST_FWDED))){
 		/* dup uris, path a.s.o. if we have a branch route or callback */
@@ -314,6 +320,22 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
 			}
 			free_instance=1;
 		}
+
+		/* update ruid */
+		/* if ruid points to msg ruid, it needs to be "fixed" so that we 
+		   can change/update msg->ruid */
+		if (ruid==&i_req->ruid)
+			ruid=&ruid_bak;
+		/* zero it first so that set_ruid will work */
+		i_req->ruid.s=0;
+		i_req->ruid.len=0;
+		if (unlikely(ruid)){
+			if (unlikely(set_ruid(i_req, ruid)<0)){
+				ret=E_OUT_OF_MEM;
+				goto error03;
+			}
+			free_ruid=1;
+		}
 	
 		/* backup dst uri  & zero it*/
 		dst_uri_bak=i_req->dst_uri;
@@ -426,6 +448,13 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
 			i_req->instance.s=0;
 			i_req->instance.len=0;
 		}
+		if (unlikely(ruid && (i_req->ruid.s!=ruid->s ||
+							  i_req->ruid.len!=ruid->len))){
+			i_req->ruid=*ruid;
+		}else if (unlikely(ruid==0 && i_req->ruid.len!=0)){
+			i_req->ruid.s=0;
+			i_req->ruid.len=0;
+		}
 	}
 	
 	if (likely(next_hop!=0 || (flags & UAC_DNS_FAILOVER_F))){
@@ -507,6 +536,21 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
 		t->uac[branch].instance.s[i_req->instance.len]=0;
 		memcpy( t->uac[branch].instance.s, i_req->instance.s, i_req->instance.len);
 	}
+	if (unlikely(i_req->ruid.s && i_req->ruid.len)){
+		t->uac[branch].ruid.s=shm_malloc(i_req->ruid.len+1);
+		if (unlikely(t->uac[branch].ruid.s==0)) {
+			shm_free(shbuf);
+			t->uac[branch].request.buffer=0;
+			t->uac[branch].request.buffer_len=0;
+			t->uac[branch].uri.s=0;
+			t->uac[branch].uri.len=0;
+			ret=E_OUT_OF_MEM;
+			goto error01;
+		}
+		t->uac[branch].ruid.len=i_req->ruid.len;
+		t->uac[branch].ruid.s[i_req->ruid.len]=0;
+		memcpy( t->uac[branch].ruid.s, i_req->ruid.s, i_req->ruid.len);
+	}
 	ret=0;
 
 error01:
@@ -521,6 +565,9 @@ error03:
 	if (unlikely(free_instance)){
 		reset_instance(i_req);
 	}
+	if (unlikely(free_ruid)){
+		reset_ruid(i_req);
+	}
 	if (dst_uri_backed_up){
 		reset_dst_uri(i_req); /* free dst_uri */
 		i_req->dst_uri=dst_uri_bak;
@@ -531,6 +578,7 @@ error03:
 	i_req->parsed_uri_ok=parsed_uri_ok_bak;
 	i_req->path_vec=path_bak;
 	i_req->instance=instance_bak;
+	i_req->ruid=ruid_bak;
 	
 	/* Delete the duplicated lump lists, this will also delete
 	 * all lumps created here, such as lumps created in per-branch
@@ -694,7 +742,7 @@ int add_blind_uac( /*struct cell *t*/ )
 static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
 					str* next_hop, str* path, struct proxy_l *proxy,
 					struct socket_info* fsocket, snd_flags_t snd_flags,
-					int proto, int flags, str *instance)
+					int proto, int flags, str *instance, str *ruid)
 {
 
 	int ret;
@@ -739,7 +787,7 @@ static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
 	/* now message printing starts ... */
 	if (unlikely( (ret=prepare_new_uac(t, request, branch, uri, path,
 										next_hop, fsocket, snd_flags,
-										proto, flags, instance)) < 0)){
+										proto, flags, instance, ruid)) < 0)){
 		ser_error=ret;
 		goto error01;
 	}
@@ -779,7 +827,8 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
 								struct socket_info* fsocket,
 								snd_flags_t send_flags,
 								int proto,
-								char *buf, short buf_len, str *instance)
+								char *buf, short buf_len,
+								str *instance, str *ruid)
 {
 
 	int ret;
@@ -866,6 +915,22 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
 		t->uac[branch].instance.s[instance->len]=0;
 		memcpy( t->uac[branch].instance.s, instance->s, instance->len);
 	}
+	/* copy the ruid */
+	if (unlikely(ruid && ruid->s)){
+		t->uac[branch].ruid.s=shm_malloc(ruid->len+1);
+		if (unlikely(t->uac[branch].ruid.s==0)) {
+			shm_free(shbuf);
+			t->uac[branch].request.buffer=0;
+			t->uac[branch].request.buffer_len=0;
+			t->uac[branch].uri.s=0;
+			t->uac[branch].uri.len=0;
+			ret=ser_error=E_OUT_OF_MEM;
+			goto error;
+		}
+		t->uac[branch].ruid.len=ruid->len;
+		t->uac[branch].ruid.s[ruid->len]=0;
+		memcpy( t->uac[branch].ruid.s, ruid->s, ruid->len);
+	}
 	membar_write(); /* to allow lockless ops (e.g. prepare_to_cancel()) we want
 					   to be sure everything above is fully written before
 					   updating branches no. */
@@ -937,7 +1002,8 @@ int add_uac_dns_fallback(struct cell *t, struct sip_msg* msg,
 							old_uac->request.dst.send_flags,
 							old_uac->request.dst.proto,
 							old_uac->request.buffer,
-							old_uac->request.buffer_len, NULL);
+							old_uac->request.buffer_len,
+							&old_uac->instance, &old_uac->ruid);
 			}else
 				/* add_uac will use dns_h => next_hop will be ignored.
 				 * Unfortunately we can't reuse the old buffer, the branch id
@@ -948,7 +1014,8 @@ int add_uac_dns_fallback(struct cell *t, struct sip_msg* msg,
 								SND_F_FORCE_SOCKET)?
 									old_uac->request.dst.send_sock:0,
 							old_uac->request.dst.send_flags,
-							old_uac->request.dst.proto, UAC_DNS_FAILOVER_F, &old_uac->instance);
+							old_uac->request.dst.proto, UAC_DNS_FAILOVER_F,
+							&old_uac->instance, &old_uac->ruid);
 
 			if (ret<0){
 				/* failed, delete the copied dns_h */
@@ -1023,7 +1090,8 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
 		if (unlikely((ret=prepare_new_uac( t_cancel, cancel_msg, branch,
 									&t_invite->uac[branch].uri,
 									&t_invite->uac[branch].path,
-									0, 0, snd_flags, PROTO_NONE, 0, NULL)) <0)){
+									0, 0, snd_flags, PROTO_NONE, 0,
+									NULL, NULL)) <0)){
 			ser_error=ret;
 			goto error;
 		}
@@ -1482,7 +1550,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 	int success_branch;
 	int try_new;
 	int lock_replies;
-	str dst_uri, path, instance;
+	str dst_uri, path, instance, ruid;
 	struct socket_info* si;
 	flag_t backup_bflags = 0;
 	flag_t bflags = 0;
@@ -1548,7 +1616,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 		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,
 							p_msg->fwd_send_flags, proto,
-							(p_msg->dst_uri.len)?0:UAC_SKIP_BR_DST_F, &p_msg->instance);
+							(p_msg->dst_uri.len)?0:UAC_SKIP_BR_DST_F, &p_msg->instance, &p_msg->ruid);
 		if (branch_ret>=0) 
 			added_branches |= 1<<branch_ret;
 		else
@@ -1557,14 +1625,14 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 
 	init_branch_iterator();
 	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
-										&bflags, &si, 0, &instance))) {
+										&bflags, &si, &ruid, &instance))) {
 		try_new++;
 		setbflagsval(0, bflags);
 
 		branch_ret=add_uac( t, p_msg, &current_uri,
 							(dst_uri.len) ? (&dst_uri) : &current_uri,
 							&path, proxy, si, p_msg->fwd_send_flags,
-							proto, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance);
+							proto, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance, &ruid);
 		/* pick some of the errors in case things go wrong;
 		   note that picking lowest error is just as good as
 		   any other algorithm which picks any other negative

+ 26 - 0
modules/tm/t_reply.c

@@ -2633,6 +2633,32 @@ int t_get_this_branch_instance(struct sip_msg *msg, str *instance)
 	return 1;
 }
 
+int t_get_this_branch_ruid(struct sip_msg *msg, str *ruid)
+{
+	struct cell *t;
+	if (!msg || !ruid)
+	{
+		LM_ERR("Invalid params\n");
+		return -1;
+	}
+	if (get_route_type() != BRANCH_FAILURE_ROUTE)
+	{
+		LM_ERR("Called t_get_this_branch_ruid not in a branch_failure_route\n");
+		return -1;
+	}
+
+	t = 0;
+	/* first get the transaction */
+	if (t_check(msg, 0 ) == -1) return -1;
+	if ((t = get_t()) == 0) {
+		LOG(L_ERR, "ERROR: t_check_status: cannot check status for a reply "
+			"which has no T-state established\n");
+		return -1;
+	}
+	*ruid = t->uac[get_t_branch()].ruid;
+	return 1;
+}
+
 #if 0
 static int send_reply(struct cell *trans, unsigned int code, str* text, str* body, str* headers, str* to_tag)
 {

+ 1 - 0
modules/tm/t_reply.h

@@ -244,5 +244,6 @@ typedef int (*tget_picked_f)(void);
 int t_get_picked_branch(void);
 
 int t_get_this_branch_instance(struct sip_msg *msg, str *instance);
+int t_get_this_branch_ruid(struct sip_msg *msg, str *ruid);
 
 #endif