Module: sip-router Branch: master Commit: 090243564b4d54be19991457f7e014c46a131e06 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=09024356...
Author: Miklos Tirpak miklos@iptel.org Committer: Miklos Tirpak miklos@iptel.org Date: Thu Jul 2 18:37:56 2009 +0200
tm: suspended transaction was not always replied and freed
- When the suspended transaction continued but no new UAC was added to the transaction, for example all the new branches tried to reach a blacklisted destination, then there was no error message returned and the transaction was never freed.
---
modules/tm/t_suspend.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 files changed, 39 insertions(+), 1 deletions(-)
diff --git a/modules/tm/t_suspend.c b/modules/tm/t_suspend.c index 3c22ab9..2a0cb05 100644 --- a/modules/tm/t_suspend.c +++ b/modules/tm/t_suspend.c @@ -39,6 +39,7 @@ #include "h_table.h" #include "t_lookup.h" #include "t_fwd.h" +#include "t_funcs.h" #include "timer.h" #include "t_suspend.h"
@@ -145,6 +146,8 @@ int t_continue(unsigned int hash_index, unsigned int label, Not a huge problem, fr timer will fire, but CANCEL will not be sent. last_received will be set to 408. */
+ reset_kr(); + /* fake the request and the environment, like in failure_route */ if (!fake_req(&faked_req, t->uas.request, 0 /* extra flags */, uac)) { LOG(L_ERR, "ERROR: t_continue: fake_req failed\n"); @@ -171,9 +174,44 @@ int t_continue(unsigned int hash_index, unsigned int label, /* update the flags */ t->uas.request->flags = faked_req.flags;
+ if (t->uas.status < 200) { + /* No final reply has been sent yet. + * Check whether or not there is any pending branch. + */ + for ( branch = 0; + branch < t->nr_of_outgoings; + branch++ + ) { + if ((t->uac[branch].request.buffer != NULL) + && (t->uac[branch].last_received < 200) + ) + break; + } + + if (branch == t->nr_of_outgoings) { + /* There is not any open branch so there is + * no chance that a final response will be received. + * The script has hopefully set the error code. If not, + * let us reply with a default error. + */ + if ((kill_transaction_unsafe(t, + tm_error ? tm_error : E_UNSPEC)) <=0 + ) { + LOG(L_ERR, "ERROR: t_continue: " + "reply generation failed\n"); + /* The transaction must be explicitely released, + no more timer is running */ + UNLOCK_REPLIES(t); + t_release_transaction(t); + t_unref(t->uas.request); + return 0; + } + } + } + UNLOCK_REPLIES(t);
- /* release the transaction */ + /* unref the transaction */ t_unref(t->uas.request);
return 0;