Browse Source

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 years ago
parent
commit
ef9115b65f
4 changed files with 107 additions and 11 deletions
  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 uri;
 	str path;
 	str path;
 	str instance;
 	str instance;
+	str ruid;
 	/* if we don't store, we at least want to know the status */
 	/* if we don't store, we at least want to know the status */
 	int             last_received;
 	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,
 									struct socket_info* fsocket,
 									snd_flags_t snd_flags,
 									snd_flags_t snd_flags,
 									int fproto, int flags,
 									int fproto, int flags,
-									str *instance)
+									str *instance, str *ruid)
 {
 {
 	char *shbuf;
 	char *shbuf;
 	struct lump* add_rm_backup, *body_lumps_backup;
 	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;
 	int free_path;
 	str instance_bak;
 	str instance_bak;
 	int free_instance;
 	int free_instance;
+	str ruid_bak;
+	int free_ruid;
 	int backup_route_type;
 	int backup_route_type;
 	snd_flags_t fwd_snd_flags_bak;
 	snd_flags_t fwd_snd_flags_bak;
 	snd_flags_t rpl_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.s=0;
 	instance_bak.len=0;
 	instance_bak.len=0;
 	free_instance=0;
 	free_instance=0;
+	ruid_bak.s=0;
+	ruid_bak.len=0;
+	free_ruid=0;
 	dst=&t->uac[branch].request.dst;
 	dst=&t->uac[branch].request.dst;
 
 
 	/* ... we calculate branch ... */	
 	/* ... 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;
 	parsed_uri_ok_bak=i_req->parsed_uri_ok;
 	path_bak=i_req->path_vec;
 	path_bak=i_req->path_vec;
 	instance_bak=i_req->instance;
 	instance_bak=i_req->instance;
+	ruid_bak=i_req->ruid;
 	
 	
 	if (unlikely(branch_route || has_tran_tmcbs(t, TMCB_REQUEST_FWDED))){
 	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 */
 		/* 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;
 			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*/
 		/* backup dst uri  & zero it*/
 		dst_uri_bak=i_req->dst_uri;
 		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.s=0;
 			i_req->instance.len=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))){
 	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;
 		t->uac[branch].instance.s[i_req->instance.len]=0;
 		memcpy( t->uac[branch].instance.s, i_req->instance.s, i_req->instance.len);
 		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;
 	ret=0;
 
 
 error01:
 error01:
@@ -521,6 +565,9 @@ error03:
 	if (unlikely(free_instance)){
 	if (unlikely(free_instance)){
 		reset_instance(i_req);
 		reset_instance(i_req);
 	}
 	}
+	if (unlikely(free_ruid)){
+		reset_ruid(i_req);
+	}
 	if (dst_uri_backed_up){
 	if (dst_uri_backed_up){
 		reset_dst_uri(i_req); /* free dst_uri */
 		reset_dst_uri(i_req); /* free dst_uri */
 		i_req->dst_uri=dst_uri_bak;
 		i_req->dst_uri=dst_uri_bak;
@@ -531,6 +578,7 @@ error03:
 	i_req->parsed_uri_ok=parsed_uri_ok_bak;
 	i_req->parsed_uri_ok=parsed_uri_ok_bak;
 	i_req->path_vec=path_bak;
 	i_req->path_vec=path_bak;
 	i_req->instance=instance_bak;
 	i_req->instance=instance_bak;
+	i_req->ruid=ruid_bak;
 	
 	
 	/* Delete the duplicated lump lists, this will also delete
 	/* Delete the duplicated lump lists, this will also delete
 	 * all lumps created here, such as lumps created in per-branch
 	 * 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,
 static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
 					str* next_hop, str* path, struct proxy_l *proxy,
 					str* next_hop, str* path, struct proxy_l *proxy,
 					struct socket_info* fsocket, snd_flags_t snd_flags,
 					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;
 	int ret;
@@ -739,7 +787,7 @@ static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
 	/* now message printing starts ... */
 	/* now message printing starts ... */
 	if (unlikely( (ret=prepare_new_uac(t, request, branch, uri, path,
 	if (unlikely( (ret=prepare_new_uac(t, request, branch, uri, path,
 										next_hop, fsocket, snd_flags,
 										next_hop, fsocket, snd_flags,
-										proto, flags, instance)) < 0)){
+										proto, flags, instance, ruid)) < 0)){
 		ser_error=ret;
 		ser_error=ret;
 		goto error01;
 		goto error01;
 	}
 	}
@@ -779,7 +827,8 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
 								struct socket_info* fsocket,
 								struct socket_info* fsocket,
 								snd_flags_t send_flags,
 								snd_flags_t send_flags,
 								int proto,
 								int proto,
-								char *buf, short buf_len, str *instance)
+								char *buf, short buf_len,
+								str *instance, str *ruid)
 {
 {
 
 
 	int ret;
 	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;
 		t->uac[branch].instance.s[instance->len]=0;
 		memcpy( t->uac[branch].instance.s, instance->s, instance->len);
 		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
 	membar_write(); /* to allow lockless ops (e.g. prepare_to_cancel()) we want
 					   to be sure everything above is fully written before
 					   to be sure everything above is fully written before
 					   updating branches no. */
 					   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.send_flags,
 							old_uac->request.dst.proto,
 							old_uac->request.dst.proto,
 							old_uac->request.buffer,
 							old_uac->request.buffer,
-							old_uac->request.buffer_len, NULL);
+							old_uac->request.buffer_len,
+							&old_uac->instance, &old_uac->ruid);
 			}else
 			}else
 				/* add_uac will use dns_h => next_hop will be ignored.
 				/* add_uac will use dns_h => next_hop will be ignored.
 				 * Unfortunately we can't reuse the old buffer, the branch id
 				 * 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)?
 								SND_F_FORCE_SOCKET)?
 									old_uac->request.dst.send_sock:0,
 									old_uac->request.dst.send_sock:0,
 							old_uac->request.dst.send_flags,
 							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){
 			if (ret<0){
 				/* failed, delete the copied dns_h */
 				/* 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,
 		if (unlikely((ret=prepare_new_uac( t_cancel, cancel_msg, branch,
 									&t_invite->uac[branch].uri,
 									&t_invite->uac[branch].uri,
 									&t_invite->uac[branch].path,
 									&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;
 			ser_error=ret;
 			goto error;
 			goto error;
 		}
 		}
@@ -1482,7 +1550,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 	int success_branch;
 	int success_branch;
 	int try_new;
 	int try_new;
 	int lock_replies;
 	int lock_replies;
-	str dst_uri, path, instance;
+	str dst_uri, path, instance, ruid;
 	struct socket_info* si;
 	struct socket_info* si;
 	flag_t backup_bflags = 0;
 	flag_t backup_bflags = 0;
 	flag_t 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),
 		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->path_vec, proxy, p_msg->force_send_socket,
 							p_msg->fwd_send_flags, proto,
 							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) 
 		if (branch_ret>=0) 
 			added_branches |= 1<<branch_ret;
 			added_branches |= 1<<branch_ret;
 		else
 		else
@@ -1557,14 +1625,14 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 
 
 	init_branch_iterator();
 	init_branch_iterator();
 	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
 	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
-										&bflags, &si, 0, &instance))) {
+										&bflags, &si, &ruid, &instance))) {
 		try_new++;
 		try_new++;
 		setbflagsval(0, bflags);
 		setbflagsval(0, bflags);
 
 
 		branch_ret=add_uac( t, p_msg, &current_uri,
 		branch_ret=add_uac( t, p_msg, &current_uri,
 							(dst_uri.len) ? (&dst_uri) : &current_uri,
 							(dst_uri.len) ? (&dst_uri) : &current_uri,
 							&path, proxy, si, p_msg->fwd_send_flags,
 							&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;
 		/* pick some of the errors in case things go wrong;
 		   note that picking lowest error is just as good as
 		   note that picking lowest error is just as good as
 		   any other algorithm which picks any other negative
 		   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;
 	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
 #if 0
 static int send_reply(struct cell *trans, unsigned int code, str* text, str* body, str* headers, str* to_tag)
 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_picked_branch(void);
 
 
 int t_get_this_branch_instance(struct sip_msg *msg, str *instance);
 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
 #endif