|
@@ -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( ¤t_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, ¤t_uri,
|
|
|
(dst_uri.len) ? (&dst_uri) : ¤t_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
|