Module: sip-router
Branch: andrei/rve_f_params
Commit: cad98b04136d6d48668b4b5c564ccaebd9b001f9
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=cad98b0…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Mon Mar 15 20:05:49 2010 +0100
core: support for expressions/variables in function parameters
- all module functions that do not have fixups can now be called
with variables, avps or expressions. They will be converted to
string, either on startup (if the expression is constant, e.g.
"a"+"b") or at runtime (if the expression is not constant, .e.g.
$a, $b+$var(foo)+"test").
E.g.: f("1+1=" + 1 + 1, "v=" + $v).
- slightly faster module function calls (eliminated some
never-triggered sanity tests).
---
action.c | 284 ++++++++++++++++++++++++++++++++++++++++++--------------
cfg.y | 183 ++++++++++++++++++++++++++++---------
route.c | 84 ++++++++++++++++-
route_struct.c | 11 ++-
route_struct.h | 7 +-
5 files changed, 448 insertions(+), 121 deletions(-)
Diff: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commitdiff;h=cad…
Module: sip-router
Branch: andrei/cancel_reason
Commit: e85232164c11ad4189861b499e08358c99174e5b
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e852321…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Mon Mar 8 22:54:55 2010 +0100
tm: fix Reason generation for on-the-fly branch CANCELs
For a canceled transaction, branches that have not received any
reply might not have any pre-generated cancel buffers (in case
cancel_b_method!=2). This could also happen when the first
provisional response on a branch arrives in the same time with the
event triggering the cancel (e.g. 2xx or 6xx on another branch,
e2e cancel or timeout).
In this cases, when generating the per-branch CANCEL for the first
time (triggered by a received provisional reply), use the final
transaction reply code as Reason. Note that this covers only the
final reply triggered CANCEL case (2xx or 6xx received, local
timeout or local script t_reply()) and it does not cover the e2e
CANCEL case, for which either no reason will be generated
(cancel_b_method == 1) or the reason might be 487
(cancel_b_method==0).
---
modules/tm/t_msgbuilder.c | 2 ++
modules/tm/t_reply.c | 10 ++++++++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/modules/tm/t_msgbuilder.c b/modules/tm/t_msgbuilder.c
index a05fdbc..91a82f0 100644
--- a/modules/tm/t_msgbuilder.c
+++ b/modules/tm/t_msgbuilder.c
@@ -171,6 +171,7 @@ char *build_local(struct cell *Trans,unsigned int branch,
*len+=CONTENT_LENGTH_LEN+1 + CRLF_LEN;
reason_len = 0;
reas1 = 0;
+ reas_last = 0;
/* compute reason size (if no reason or disabled => reason_len == 0)*/
if (reason && reason->cause != CANCEL_REAS_UNKNOWN){
if (likely(reason->cause > 0 &&
@@ -307,6 +308,7 @@ char *build_local_reparse(struct cell *Trans,unsigned int branch,
reason_len = 0;
reas1 = 0;
+ reas_last = 0;
/* compute reason size (if no reason or disabled => reason_len == 0)*/
if (reason && reason->cause != CANCEL_REAS_UNKNOWN){
if (likely(reason->cause > 0 &&
diff --git a/modules/tm/t_reply.c b/modules/tm/t_reply.c
index 6ee3fae..6bcef61 100644
--- a/modules/tm/t_reply.c
+++ b/modules/tm/t_reply.c
@@ -2043,8 +2043,14 @@ int reply_received( struct sip_msg *p_msg )
DBG("tm: reply_received: branch CANCEL created\n");
/* note that in this case we do not know the reason
(it could be a final reply or a received cancel)
- and we don't want to wait for it => no reason */
- cancel_branch(t, branch, 0, F_CANCEL_B_FORCE_C);
+ and we don't want to wait for it. However if
+ t->uas.status >= 200 it's probably due to a received
+ 2xx, 6xx, local timeout or a local final reply
+ (via t_reply()), so use t->uas.status as reason */
+ cancel_data.reason.cause = (t->uas.status>=200)?t->uas.status:
+ CANCEL_REAS_UNKNOWN;
+ cancel_branch(t, branch, &cancel_data.reason,
+ F_CANCEL_B_FORCE_C);
}
goto done; /* nothing to do */
}
Module: sip-router
Branch: andrei/cancel_reason
Commit: c96405e48681e2f7a9945c3ff8533ef7dcd703f4
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=c96405e…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Sat Mar 13 14:13:40 2010 +0100
tm: improved Reason support for E2E CANCELs
When generating CANCELs on-the-fly as response to a received
provisional reply on a branch of an E2E CANCELed transaction,
remember the Reason(s) from the original E2E CANCEL.
Up until now, the Reason was not remembered for branches where no
provisional replies were received (on these branches no CANCEL is
sent, unless cancel_b_method is set to 2 or at a later point a
provisional reply arrives).
Now each time an E2E CANCEL is received the Reason headers are
saved inside the INVITE transaction, for possible use in later
branch CANCEL generation (triggered by receiving a provisional
reply).
---
modules/tm/h_table.c | 2 +
modules/tm/h_table.h | 2 +
modules/tm/t_fwd.c | 123 +++++++++++++++++++++++++++++++++++++++++++--
modules/tm/t_msgbuilder.c | 22 +++++---
modules/tm/t_reply.c | 22 +++++---
modules/tm/t_reply.h | 12 ++++-
6 files changed, 160 insertions(+), 23 deletions(-)
Diff: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commitdiff;h=c96…
Hello,
some small maintenance tasks will be performed afternoon today to the
server hosting the mailing lists and kamailio.org site, if you notice
some downtime, try again a bit later.
Thanks,
Daniel
2010/3/12 Timo Reimann <timo.reimann(a)1und1.de>:
> If so, my major concern with this approach is that it will break dialog
> callback functionality. If a dialog user, upon creation of an
> unconfirmed dialog (initial request received), registers for further
> callbacks associated with that dialog (for instance, DLGCB_CONFIRMED),
> it won't get any further callbacks in the scenario outlined above. The
> reason for this is that when the dialog is terminated due to the 5xx
> response, all associated callbacks will be swept out too, and the
> re-created dialog's structure will not contain any callbacks yet.
A suggestion to cover all the cases:
There could be two kinds of dialog entries in the module:
- dialog-in: It's a *single* dialog entry generated upon receipt of
the INVITE. No info about To-tag is stored with it. It has a status
field (none, early, confirmed, terminated), but this status is handled
carefully (see below). This entry exists until the dialog or
early-dialog is terminated. Callbacks are inserted *here*.
- dialog-out: It's a single or multiple entries pointing to a single
dialog-in entry. It contains a To-tag and status fields. A dialog-out
is generated when a response for same Call-ID and From-tag is received
and contains a new To-tag. Status for each dialog-out is updated
according to the status of the response (early, confirmed,
terminated). No callbacks are inserted here.
When a dialog-out is generated (provisional response received) it
updates the dialog-in status to "early" (so callback is raised), but
just in case the dialog-in status was "none".
When a dialog-out receives a (200 it also updates the dialog-in status
to "confirmed" (so callback is raised), just in case it was in "none"
or "early" status.
When a dialog-out is terminated ([3456]XX response received) it *just*
updates the dialog-in status to "terminated" in case there are no more
alive dialog-outs (for parallel forking cases) and *also* in case the
INVITE transaction has terminated (for serial forking cases in which
still there is no new branches).
To simplify it: the dialog-in entry gets "terminated" status just in
case the incoming INVITE transaction gets a final negative response
(this covers parallel and serial forking).
So, from the point of view of the client (how many calls it has and
their status) just the "dialog-in" table must be inspected.
In order to get working callbacks when the dialog status changes, just
the unique dialog-in entry must be used (this exists forever until the
(early-)dialog(s) fully terminate).
Also with this approach there is no need to create a new dialog entry
when forking, but just when receiving a response with a new To tag (it
could occur due to local forking or due to remote forking generated by
a proxy behind us, it doesn't matter).
I think that with this approach all the cases are covered. Opinions?
--
Iñaki Baz Castillo
<ibc(a)aliax.net>
--
Iñaki Baz Castillo
<ibc(a)aliax.net>
Hey all,
I'm currently working on improving the dialog module. As some may know,
the module isn't perfect with regards to how and and under which
circumstances end-to-end calls are tracked properly. Although there are
several locations in the code where additional work could assumingly
raise the module's quality, I'd like to focus discussion on two major
components that IMHO require refurbishment first and foremost.
Any feedback on the described issues, my proposed solutions, or anything
else I haven't specifically addressed will be greatly appreciated.
Let's start with the problems and follow up with the solutions.
Problems
--------
(1)
When an *unconfirmed* request is received by a proxy multiple times, the
dialog module will establish a new dialog for each reception where
instead it should be just one. For instance, in our infrastructure, call
forwardings are implemented by means of sending out messages with the
request URI rewritten to a set of local balancers which will re-route
the (slightly modified) request back to our proxies. When this happens,
the dialog module doesn't match the subsequent, still unconfirmed
request to the initial, unconfirmed request, and creates a new dialog.
This erroneous behavior has several consequences, such as distorting
statistics, wasting memory, and others.
(2)
Forking isn't handled at all. Once you do so by, e.g., calling
append_branch() in the configuration script, all branches will be mapped
to the same, single dialog. Consequently, the state transition machine
of the dialog is affected by each and every of these branches and will
affect dialog tracking depending on the order of forked responses
received. (Consider the case where one branch's 5xx response is observed
first by the proxy, followed by a successful, other branch's 200. In
this case, the 200 doesn't affect the dialog state positively anymore
since the 5xx made it terminate prematurely.)
Solutions
---------
(1)
The reason why Kamailio keeps instantiating new dialogs while it should
not is that the dlg_onreq() function keeps things too simple. This
function is set up as a callback to tm's TMCB_REQUEST_IN event and only
refrains from its main purpose of creating new dialogs if a dialog to a
given message is already established. Naturally, this does do not cover
scenarios where unconfirmed requests are legitimately re-seen by a proxy
as described above.
The solution is to re-use the same basic dialog matching logic that the
dlg_onroute() function has with one particular exception that the yet
missing To-tag for an unconfirmed dialog must not be essential for
dialog matching to succeed. I managed to create a patch that implements
this kind of dialog continuation and tested it accordingly. The fix was
created for Kamailio 1.5 but should be rather easily portable to
sip-router. In my opinion, problem (1) should be considered as a bug
since it breaks correct dialog working in certain situation and
therefore the patch should be included in 1.5 as well. If no one
objects, I will submit it for evaluation and upstream incorporation soon.
(2)
Kamailio maps all forked branches to the same dialog because they all
carry the same dialog ID, i.e., Call-ID, From-tag, and To-tag. In order
to differentiate, a branch ID must be introduced to the dialog module to
tell dialogs apart. One way to do so would be to provide the branch
index to TMCB_REQUEST_BUILT callbacks during execution of the
t_forward_nonack() function (tm/t_fwd.c) . That way, the dialog module
could register for that specific tm event and treat branched,
unconfirmed dialogs accordingly.
A follow-up design choice that is to be made is how to treat branches
once the dialog module is capable of. Two approaches come to my mind:
Make the branch ID part of the dialog, thereby treating forked branches
as separate dialogs; or, continue mapping branches to the same dialog
but adjust the dialog state transition machine such that a forking
dialog is not discarded unless all branches failed. To me, the first
approach seems to be more straight as it allows to apply the same state
machine logic simply to each branched dialog.
To me, a proper solution to problem (2) seems more difficult to find,
and I haven't finally settled for a preferred method myself yet. That's
why I'd be especially glad for any further input on this point.
Finally, please note that I've been digging into Kamailio 1.5 code most
of the time because this is where I need to implement any improvements.
sip-router's implementation seemed to be quite on a par with 1.5's,
however, last time I checked. Naturally, I'd be helpful in getting any
improvements upstream in either version allowable.
Thanks and
cheers,
--Timo