Module: sip-router Branch: tmp/tm_async_reply_support Commit: f1bf9fa2f21a7c800c16f40b530e8f4042a280ae URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=f1bf9fa2...
Author: Richard Good richard.good@smilecoms.com Committer: Richard Good richard.good@smilecoms.com Date: Thu Mar 14 18:06:46 2013 +0200
tm: t_suspend/t_continue for replies 1st draft
- First attempt at allowing tm functions: t_continue and t_suspend to be used on SIP responses (currently this only works on SIP requests)
---
modules/tm/h_table.h | 5 ++- modules/tm/t_suspend.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 100 insertions(+), 5 deletions(-)
diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h index f30bd45..2c65906 100644 --- a/modules/tm/h_table.h +++ b/modules/tm/h_table.h @@ -196,6 +196,8 @@ typedef struct ua_server for e2e cancels */ #endif /* CANCEL_REASON_SUPPORT */ unsigned int status; + + int suspended_request; }ua_server_type;
@@ -251,6 +253,7 @@ typedef struct ua_client unsigned short on_failure; /* the onreply_route to be processed if registered to do so */ unsigned short on_reply; + int suspended_reply; }ua_client_type;
@@ -444,7 +447,7 @@ typedef struct cell
/* place holder for MD5checksum (meaningful only if syn_branch=0) */ char md5[0]; /* if syn_branch==0 then MD5_LEN bytes are extra alloc'ed*/ - + } tm_cell_t;
diff --git a/modules/tm/t_suspend.c b/modules/tm/t_suspend.c index 35adcb1..387e628 100644 --- a/modules/tm/t_suspend.c +++ b/modules/tm/t_suspend.c @@ -56,7 +56,8 @@ int t_suspend(struct sip_msg *msg, unsigned int *hash_index, unsigned int *label) { struct cell *t; - + int branch; + t = get_t(); if (!t || t == T_UNDEFINED) { LOG(L_ERR, "ERROR: t_suspend: " \ @@ -64,13 +65,14 @@ int t_suspend(struct sip_msg *msg, return -1; }
- if (t->flags & T_CANCELED) { + if (t->flags & T_CANCELED) { /* The transaction has already been canceled */ LOG(L_DBG, "DEBUG: t_suspend: " \ "trying to suspend an already canceled transaction\n"); ser_error = E_CANCELED; return 1; } + if (msg->first_line.type==SIP_REQUEST){
/* send a 100 Trying reply, because the INVITE processing will probably take a long time */ @@ -103,10 +105,47 @@ int t_suspend(struct sip_msg *msg, "failed to add the blind UAC\n"); return -1; } - + /* set as suspend request for when we continue */ + t->uas.suspended_request = 1; + + return 0; + + }else if (msg->first_line.type==SIP_REPLY){ + + LOG(L_DBG,"DBG: This is a suspend on reply - setting msg flag to SUSPEND"); + msg->flags &= FL_RPL_SUSPENDED; + //this is a reply suspend find which branch + + if (t_check( msg , &branch )==-1){ + LOG(L_ERR, "ERROR: t_suspend: " \ + "failed find UAC branch\n"); + return -1; + } + LOG(L_DBG,"DBG: Found a a match with branch id [%d]", branch); + + LOG(L_DBG,"DBG: Assigning reply message to t->uac[branch].reply"); + t->uac[branch].reply=msg; + + if (save_msg_lumps(t->uac[branch].reply, msg)) { + LOG(L_ERR, "ERROR: t_suspend: " \ + "failed to save the message lumps\n"); + return -1; + } + + LOG(L_DBG,"DBG: Saving stuff to transaction"); + /* set as suspend reply for when we continue */ + t->uac[branch].suspended_reply=1; + /* save the message flags */ + //TODO do we need this? + t->uac[branch].reply->flags = msg->flags; + + LOG(L_DBG,"DBG: Saving transaction hash and label"); + *hash_index = t->hash_index; + *label = t->label; + LOG(L_DBG,"DBG: Done"); + } return 0; } - /* Continues the SIP request processing previously saved by * t_suspend(). The script does not continue from the same * point, but a separate route block is executed instead. @@ -120,6 +159,7 @@ int t_continue(unsigned int hash_index, unsigned int label, { struct cell *t; struct sip_msg faked_req; + struct sip_msg faked_reply; int branch; struct ua_client *uac =NULL; int ret; @@ -142,6 +182,7 @@ int t_continue(unsigned int hash_index, unsigned int label, * form calling t_continue() multiple times simultaneously */ LOCK_REPLIES(t);
+ if (t->uas.suspended_request==1){ /* Try to find the blind UAC, and cancel its fr timer. * We assume that the last blind uac called t_continue(). */ for ( branch = t->nr_of_outgoings-1; @@ -223,9 +264,60 @@ int t_continue(unsigned int hash_index, unsigned int label, goto kill_trans; } } - + + }else{ + LOG(L_DBG,"This a continue from a reply suspend - getting the correct branch as transaction has %d branches", t->nr_of_outgoings); + //this is a continue from a reply suspend! + for ( branch = 0; + branch < t->nr_of_outgoings; + branch++ + ) { + //TODO not sure if this will work yet - think we need to pass which branch to continue when we call t_continue! + if (t->uac[branch].suspended_reply==1){ + LOG(L_DBG,"Found branch that has suspend reply set!"); + + LOG(L_DBG,"Forwarding reply with status code %d", t->uac[branch].reply->first_line.u.reply.statuscode); + + //TODO forward message now + /* Not sure how to do this yet - probably need to fake the environment and then send a fake reply similar to way done for requests */ + + //This might work: + //forward_reply(t->uac[branch].reply); + + //Or we need to fake the environment and send: + //fake_reply(t, branch, t->uac[branch].reply->first_line.u.reply.statuscode); + + //faked_env( t, &faked_req); + // + /* The sip msg is a faked msg just like in failure route + * therefore execute the pre- and post-script callbacks + * of failure route (Miklos) + */ +// if (exec_pre_script_cb(&faked_rep, FAILURE_CB_TYPE)>0) { +// if (run_top_route(route, &faked_rep, 0)<0) +// LOG(L_ERR, "ERROR: t_continue: Error in run_top_route\n"); +// exec_post_script_cb(&faked_rep, FAILURE_CB_TYPE); +// } + + //faked_env( t, 0); + //free_faked_rer(&faked_rep, t); + + /* update the flags */ + //t->uac[branch].reply->flags = faked_rep.flags; + + } + } + if (branch == t->nr_of_outgoings) { + LOG(L_DBG,"Could not find a branch with suspend reply set"); + /* This is a continue on reply suspend but can not find a suspended reply!. */ + ret = 0; + goto kill_trans; + } + } + LOG(L_DBG,"Unlocking transaction mutex"); UNLOCK_REPLIES(t); - + + LOG(L_DBG,"Unreffing the transaction"); /* unref the transaction */ t_unref(t->uas.request);