Module: sip-router
Branch: master
Commit: cd9460b0d8023c43348bce58fe38ef3ce9a686cc
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=cd9460b…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Tue Apr 28 20:40:26 2009 +0200
tm: handling of branch flags
- save/restore branch upon execution of tm specific routes
---
modules/tm/h_table.h | 3 +++
modules/tm/t_fwd.c | 9 +++++++++
modules/tm/t_reply.c | 9 +++++++--
modules/tm/t_reply.h | 2 +-
modules/tm/t_suspend.c | 4 +++-
5 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h
index 37aecc9..d38e3d6 100644
--- a/modules/tm/h_table.h
+++ b/modules/tm/h_table.h
@@ -70,6 +70,7 @@
#include "../../md5utils.h"
#include "../../usr_avp.h"
#include "../../timer.h"
+#include "../../flags.h"
#include "../../atomic_ops.h"
#include "../../hash_func.h"
#include "config.h"
@@ -85,6 +86,7 @@ struct entry;
struct cell;
struct timer;
struct retr_buf;
+struct ua_client;
#include "../../mem/shm_mem.h"
#include "lock.h"
@@ -224,6 +226,7 @@ typedef struct ua_client
/* internal flags per tm uac */
unsigned int flags;
#endif
+ flag_t branch_flags;
#ifdef WITH_AS_SUPPORT
/**
* Resent for every rcvd 2xx reply.
diff --git a/modules/tm/t_fwd.c b/modules/tm/t_fwd.c
index 9344e6f..46ddbfb 100644
--- a/modules/tm/t_fwd.c
+++ b/modules/tm/t_fwd.c
@@ -450,6 +450,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str*
next_hop,
else if(len==2)
t->uac[branch].flags = TM_UAC_FLAG_RR|TM_UAC_FLAG_R2;
#endif
+ getbflagsval(0, &t->uac[branch].branch_flags);
membar_write(); /* to allow lockless ops (e.g. which_cancel()) we want
to be sure everything above is fully written before
updating branches no. */
@@ -1005,6 +1006,8 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
int lock_replies;
str dst_uri;
struct socket_info* si, *backup_si;
+ flag_t backup_bflags = 0;
+ flag_t bflags = 0;
/* make -Wall happy */
@@ -1028,6 +1031,8 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
}
backup_si = p_msg->force_send_socket;
+ getbflagsval(0, &backup_bflags);
+
/* if no more specific error code is known, use this */
lowest_ret=E_UNSPEC;
/* branches added */
@@ -1072,6 +1077,9 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
while((current_uri.s=next_branch( ¤t_uri.len, &q, &dst_uri.s,
&dst_uri.len, &si))) {
try_new++;
p_msg->force_send_socket = si;
+ getbflagsval(get_branch_iterator(), &bflags);
+ setbflagsval(0, bflags);
+
branch_ret=add_uac( t, p_msg, ¤t_uri,
(dst_uri.len) ? (&dst_uri) : ¤t_uri,
proxy, proto);
@@ -1088,6 +1096,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
clear_branches();
p_msg->force_send_socket = backup_si;
+ setbflagsval(0, backup_bflags);
/* don't forget to clear all branches processed so far */
diff --git a/modules/tm/t_reply.c b/modules/tm/t_reply.c
index 5cb731f..e51142c 100644
--- a/modules/tm/t_reply.c
+++ b/modules/tm/t_reply.c
@@ -730,7 +730,7 @@ void faked_env( struct cell *t,struct sip_msg *msg)
int fake_req(struct sip_msg *faked_req,
- struct sip_msg *shmem_msg, int extra_flags)
+ struct sip_msg *shmem_msg, int extra_flags, struct ua_client *uac)
{
/* on_negative_reply faked msg now copied from shmem msg (as opposed
* to zero-ing) -- more "read-only" actions (exec in particular) will
@@ -771,6 +771,8 @@ int fake_req(struct sip_msg *faked_req,
faked_req->dst_uri.len);
faked_req->dst_uri.s[faked_req->dst_uri.len]=0;
}
+ if(uac) setbflagsval(0, uac->branch_flags);
+ else setbflagsval(0, 0);
return 1;
error00:
@@ -836,7 +838,7 @@ int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
return 1;
}
- if (!fake_req(&faked_req, shmem_msg, extra_flags)) {
+ if (!fake_req(&faked_req, shmem_msg, extra_flags, &t->uac[picked_branch])) {
LOG(L_ERR, "ERROR: run_failure_handlers: fake_req failed\n");
return 0;
}
@@ -1953,10 +1955,13 @@ int reply_received( struct sip_msg *p_msg )
backup_user_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to
);
backup_domain_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN,
&t->domain_avps_from );
backup_domain_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN,
&t->domain_avps_to );
+ setbflagsval(0, uac->branch_flags);
if (run_top_route(onreply_rt.rlist[t->on_reply], p_msg)<0)
LOG(L_ERR, "ERROR: on_reply processing failed\n");
/* transfer current message context back to t */
if (t->uas.request) t->uas.request->flags=p_msg->flags;
+ getbflagsval(0, &uac->branch_flags);
+
/* restore original avp list */
set_avp_list( AVP_TRACK_FROM | AVP_CLASS_URI, backup_uri_from );
set_avp_list( AVP_TRACK_TO | AVP_CLASS_URI, backup_uri_to );
diff --git a/modules/tm/t_reply.h b/modules/tm/t_reply.h
index 65b4498..c385697 100644
--- a/modules/tm/t_reply.h
+++ b/modules/tm/t_reply.h
@@ -160,7 +160,7 @@ void rpc_reply(rpc_t* rpc, void* c);
void faked_env( struct cell *t,struct sip_msg *msg);
int fake_req(struct sip_msg *faked_req,
- struct sip_msg *shmem_msg, int extra_flags);
+ struct sip_msg *shmem_msg, int extra_flags, struct ua_client *uac);
void free_faked_req(struct sip_msg *faked_req, struct cell *t);
diff --git a/modules/tm/t_suspend.c b/modules/tm/t_suspend.c
index 1c0b729..c1dc1b1 100644
--- a/modules/tm/t_suspend.c
+++ b/modules/tm/t_suspend.c
@@ -109,6 +109,7 @@ int t_continue(unsigned int hash_index, unsigned int label,
struct cell *t;
struct sip_msg faked_req;
int branch;
+ struct ua_client *uac =NULL;
if (t_lookup_ident(&t, hash_index, label) < 0) {
LOG(L_ERR, "ERROR: t_continue: transaction not found\n");
@@ -136,13 +137,14 @@ int t_continue(unsigned int hash_index, unsigned int label,
* a failure rute => deadlock, because both
* of them need the reply lock to be held. */
t->uac[branch].last_received=500;
+ uac = &t->uac[branch];
}
/* else
Not a huge problem, fr timer will fire, but CANCEL
will not be sent. last_received will be set to 408. */
/* fake the request and the environment, like in failure_route */
- if (!fake_req(&faked_req, t->uas.request, 0 /* extra flags */)) {
+ if (!fake_req(&faked_req, t->uas.request, 0 /* extra flags */, uac)) {
LOG(L_ERR, "ERROR: t_continue: fake_req failed\n");
UNLOCK_REPLIES(t);
return -1;