Module: sip-router Branch: master Commit: cd9460b0d8023c43348bce58fe38ef3ce9a686cc URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=cd9460b0...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@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;