[Kamailio-Devel] RFC: Dialog: Feature-Extensions

Jerome Martin jmartin at longphone.fr
Tue Sep 16 20:07:33 CEST 2008


Hi,

[LONG/BORING EMAIL WARNING - PLEASE BEAR WITH ME :-)]

On Tue, 2008-09-16 at 18:26 +0200, Carsten Bock wrote:
> > I think this is already mode 1 in 1.4 ?
> As i wrote in my previous mail ;-)
Yeah, I saw that, you use SIP headers not only if did is absent but also
if it does not match :-)

> > > - i've moved the loading of dialogs to the first child (rather than
> > > during the initialization of the module)
> > 
> > May I ask what is your goal there ?
> 
> Basically, this is required since the create-callbacks (registered by
> other modules) is empty when loading the module. The create-callbacks
> are registered after loading the dialog module and before creating the
> first child.

I was asking why it is better to delay the load in the first child, not
WHY we have to load the dialogs, but I think I got it. It is faster for
the initial kamailio startup.


> When looking at the code, it seems the proxy will load all dialogs and
> basically ignore the socket if not local.
Right. This is current behavior.

> I thought about implementing a fallback-to-db-feature for the dialog
> module, in case we receive a request which is not in the local memory of
> the proxy (e.g. in case of a failover due to a failed proxy on the way).
> Is this what you mean?
Part of it.
I was thinking of two orthogonal ideas:

a) If the current request is a BYE or a CANCEL, not matching any
existing dialog, fallback to DB and look for existing dialogs with
different sockets than ours. This enables proxies behind a dispatcher to
tolerate failure of one proxy and still bill/terminate calls initially
handled by that proxy. But I do not know what the implications are for
TM, because the transaction match won't work, so this might imply to go
stateless for those. 

b) Have a "shared-db" mode among proxies that not only ingores the
socket (loads all available dialogs in DB at startup), but also does a
full DB lookup when a request doe not match a dialog. Same comment as
above concerning TM.

> > 2/ I try to use is_in_profile() to determine if requests (ACK, etc...)
> > are for an existing dialog in the script. For replies, it works fine,
> > but for requests, the dialog callback creating the current_dlg is
> > called only during t_relay. So I have a patch that adds a callback in
> > pre script / request to create the dialog there. It means
> > is_in_profile() can now be used from the request route to check if an
> > ACk, a re-INVITE, etc... belongs to an existing dialog. It does not
> > work for CANCELs.
> 
> I haven't used the profiles of the dialog-module so far, but sounds
> interesting...

Well, I do not use the profiles neither :-)
This is just a hack to ask kamailio "is that request/reply part of an
existing dialog ?". I use only one default profile of which all my
dialogs are part of. This is to filter out requests/reply not being part
of an existing dialog and do DB accounting/billing only for those
requests that are actually part of an established call. I currently use
t_check_trans() but this has some shortcomings. One typical example is
the case of a 200OK to BYE packet lost: 
 A ---- BYE ----> B (cseq1 , triggers call to billing DB stored
procedure, destroy dialog)
(A <--- 200 ----- B, actually lost message)
 A ---- BYE ----> B (retransmit, will be absorbed by TM, no worries)
(A <--- 200 ----- B, actually lost message)
 A ---- BYE ----> B (cseq2, will NOT be absorbed, so if we cannot check
if the dialog still exists, we will call the DB again, with a <null>
$DLG_duration )

But the above is just an illustration, I think there are many cases were
this can be usefull.

> > 3/ I use 1.4 now, but I have patches for 1.3 (not ported yet ...) that
> > (quoting from memory) :
> >     . handles REQBYE properly when dialog is in DELETED state
> 
> Could you clarify, what you mean by "not handled properly"?

Handle them at all.
Without this patch, there is an error generated when a BYE arrives for a
dialog in state DELETED, but still in memory. But maybe this has been
fixed in 1.4, I haven't retested yet.

> >     . adds an extra_info column in the dialog from an avp (I think
> > this one is now obsolete)
> >     . move deleted dialogs to an other "archive" table instead of
> > deleting them
> 
> I would say, these are quite custom requirements. Maybe you could
> provide patches on the tracker, so these enhancements are not lost. I
> believe, these enhancements need further discussion.

OK. This is exactly the kind of answer I need, because I have no idea
how usefull those features are. 

But please note that the extra_info column is pretty generic. I think
someone suggested something quite alike for 1.4.

As for the dialog archiving, well, I think that could easily be an
option. And the code is not too intrusive.

> > 4/ I have partial patches that were aimed at :
> >     . saving the dialogs earlier in DB, as soon as the INVITE is
> > received
> 
> Is there any special use-case for this, why is this required?
[...]
> >     . adding a new state to the state_machine, RINGING
> What's the difference to the state "early"? A dialog should have the
> state "early", if a provisional response was received...

Those two are related to functionnalities we do provide to our customers
since many years by other means, and now want to integrate into the same
SIP-core based on kamailio. In fact, the dialog module rework that it
would lead to is far more ambitious (and controversial) than just what I
cited here. It is about moving from an RFC-based paradigm for the state
machine (EARLY, CONFIMED, etc... are all part of RFC 3261 lexicon) to an
user-experience-of-a-telephone-call paradigm. Let me give you some
examples :

- compute PDDs for the calls (this is used for rating our underlying
carriers, and also is a quality metric greatly impacting our customers)

- make it possible to display a realtime status of all/a subgroup of the
calls on your whole platform (we already have this on our legacy,
homemade POTS platform, and it is an invaluable administration tool.)

- We also have "callshop" customers to whom we provide an AJAX web
interface displaying the realtime status of their payphones, including
dialed destination, status like ringing/busy/in conversation.

Of course, implementing this in dialog is something controversial, and
to tell you the truth, the proxy config I have right now does not use
those patches. 

Instead, dialog is used to maintain call state (d'oh :-) ), compute call
duration, cut calls via external apps and MI and make all this without
reimplementing it in our DB logic. Let me explain my current proxy
state, and then WHY I would love to integrate all this in a unique
diqlog-based module ...

So from initial invite to final answer, we call a DB procedure for AA
(let's call it DB_AAROUTE) that decides if we need to reject, MD5
challenge, or route the call. For that last case, we load routing tables
from the DB reply to AVPs and start forking. When we have our final
answer, we call a stop_routing procedure and pass it the full log of our
routing attempts (we use this to rate our underlying carriers,
automatically take a malfunctionning carrier out-of-route, raise alarms,
give us stats on our carriers, etc...). This is DB call DB_STOPROUTING.
Until now (we use dialog db mode for partial resiliency in case of
reboot), dialog has made 1 insert and 2 updates to DB minimum. When the
dialog terminates (either by caller or callee, SST UAC/UAS, MI,
dialog_expire) we call a DB_STOPCALL procedure to give it origination of
the call termination, $DLG_duration, timestamp for crosschecking. Dialog
module, on its side has made at least one more DB call.

Now, this is working, but this is a DB-resource/network
ressource/latency-hog. A big fat one. Plus, what we really need,
conceptually, is just the current state of the call + some history a
state-change mechanism.

My natural inclination is to integrate all this into dialog, extending
it, and thus dividing the number of DB calls by a factor of 2. 

The two other options would be :
- Move the dialog-state-maintenance to the DB.
  I do not want to do this, because the extra information (like "does
this request belongs to an established/authorised dialog ?") is very
usefull to secure the decisions to forward or not the requests, to
detect alien SIP messages, to be able to generate BYE requests locally,
etc... Calling the DB for all this + generating full SIP request from an
antity alien to the proxy seems fooolish.
- Write a completely different beast than dialog for all this. Hook up
to the dialog callbacks and do all this in a separate module. This is,
am now beginning to think about it, maybe the best option. But it is
only viable if it can have its own private space in dialog table and
slide its own additional fields while still using dialog DB calls to
insert/update it when such calls already exist. Does not seem easy to
do. Writing a module BASED on dialog seems harder to maintain and still
benefit from improvements in dialog.

It seems you have similar requirements than me regarding billing and a
far deeper knowledge of the dialog module, so as I can use all help I
can get wrt this, please advise :-)

Best Regards,
-- 
Jérôme Martin | LongPhone
Responsable Architecture Réseau
122, rue la Boetie | 75008 Paris
Tel :  +33 (0)1 56 26 28 44
Fax : +33 (0)1 56 26 28 45
Mail : jmartin at longphone.fr
Web : www.longphone.com <http://www.longphone.com>




More information about the Devel mailing list