Hey Iñaki,
Iñaki Baz Castillo wrote:
2010/3/12 Timo Reimann timo.reimann@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).
I think that with this approach all the cases are covered. Opinions?
Interesting idea. Let me ask two questions:
(1) I re-checked when dialog state is modified exactly for responses (and believe I have to doubt what I initially claimed to be true):
According to dlg_handlers.c, dlg_onreply() is called right before a response is forwarded, after it was forwarded, and when the associated transaction is terminated. (tm callbacks TMCB_RESPONSE_PRE_OUT, TMCB_RESPONSE_FWDED, and TMCB_TRANS_DELETED, respectively, in Kamailio 1.5. The 3.x branch seems to have renamed TMCB_RESPONSE_PRE_OUT to TMCB_RESPONSE_READY and TMCB_TRANS_DELETED to TMCB_DESTROY. Correct me if this wasn't just for the looks.) So, taking into account that (serial and parallel) forking proxies will *forward* responses only when all forking attempts have finally failed or one succeeded, wouldn't that automatically implement your "dialog-outs will properly adjust dialog-in's state" approach and render dialog-outs unnecessary? Or am I wrong on the assumption how forking works?
(2) How would your approach deal with unconfirmed requests traversing the same proxy multiple times, i.e., what has been denoted as "spiraling" in this thread, as in this example:
UA1 --> P1 --> P2 --> P1 --> UA2
Will that result in the creation of two dialog(-in)s?
Cheers,
--Timo
2010/3/16 Timo Reimann timo.reimann@1und1.de:
Interesting idea. Let me ask two questions:
(1) I re-checked when dialog state is modified exactly for responses (and believe I have to doubt what I initially claimed to be true):
So, taking into account that (serial and parallel) forking proxies will *forward* responses only when all forking attempts have finally failed or one succeeded,
Early dialogs are created when a provisional response with a different To-tag arrives, and of course all the provisional responses (different early-dialogs) are relayed by the proxy to the UAC.
wouldn't that automatically implement your "dialog-outs will properly adjust dialog-in's state" approach and render dialog-outs unnecessary? Or am I wrong on the assumption how forking works?
Not sure, but I think you miss the case in which parallel forking (or serial forking) is performed by a proxy (P2) behind kamailio (P1):
UAC ------------ P1 -------------- P2 ---------------UAS1,UAS2,UAS3 (different To-tags)
In this case, for each early-dialog (different To-tag) P1 will receive such response within the same outgoing transaction (P1 just created a single outgoing transaction to relay the INVITE to P2).
Theorically onlye the UAC cares about dialogs, and not a proxy. If a proxy must be aware of dialogs (dialog module) it should handle all the early-dialogs, and it doesn't matter if different early-dialogs have been originated due to forking in local proxy or in a proxy in the path (after the local proxy).
I'm not sure, however, if this replies your question. If not please explain it to me again.
(2) How would your approach deal with unconfirmed requests traversing the same proxy multiple times, i.e., what has been denoted as "spiraling" in this thread, as in this example:
UA1 --> P1 --> P2 --> P1 --> UA2
Will that result in the creation of two dialog(-in)s?
As the INVITE from P2 to P1 is a different transaction, it should create a new dialog-in entry. In order to distinguish which INVITE transaction each response belongs to, the dialog module should also store the INVITE branch (in both the dialog-in entry and dialog-out entry/entries pointing to the dialog-in entry).
Unfortunatelly in order to match in-dialog requests (as ACK, re-INVITE, UPDATe, BYE...) with the proper dialog-in entry, it would also be needed to store route-set information for each dialog-in entry.
This is, in you example if UA1 sends an in-dialog re-INVITE, the only difference between INVITE from UA1 to P1 and the INVITE from P2 to P1 would be the route set.
Other approach would be avoiding creating two dialog-in entries for such spiral case. This is, when the INVITE arrives from P2 to P1, P1 would create a new dialog-in entry as there is already a dialog-in entry with same Call-ID and From-tag.
Not sure which approach is better, perhaps the second one (from SIP point of view, the spiral is still a single dialog!).
Not sure which approach is better, perhaps the second one (from SIP point of view, the spiral is still a single dialog!).
From a SIP point of view, it is the same dialog, but from a practical
point of view it's a different call (the second INVITE may have a different SDP). Also, if you have a single dialog, when you need to send BYEs on timeout, where will you send the BYEs? What about the existing modules that are already working on top of the existing dialog design?
Regards, Ovidiu Sas
2010/3/16 Ovidiu Sas osas@voipembedded.com:
Not sure which approach is better, perhaps the second one (from SIP point of view, the spiral is still a single dialog!).
From a SIP point of view, it is the same dialog, but from a practical point of view it's a different call (the second INVITE may have a different SDP).
It doesn't change the fact that it remains being the same dialog :)
Also, if you have a single dialog, when you need to send BYEs on timeout, where will you send the BYEs?
The unique dialog entry (dialog-in entry in the design suggestion) must be created just for the *first* INVITE (and not when the same INVITE arrives again due to a spiral). Then when sending a local generated BYE it must be sent according to the first INVITE (so the BYE would also do the spiral and so).
The problem is:
UAC --------> P1 -----> P2 -----> P1 -------> UAS
- When the INVITE arrives from UAC to P1, P1 creates the dialog-in entry (From-tag, Call-ID).
- When the INVITE does spiral and arrives again to P1 from P2, the dialog module checks that there is already a dialog-in entry with same From-tag and Call-ID, so a new dialog-in entry is NOT created (even if the route-set is different).
- UAS replies 200 Ok which arrives first to P1.
- P1 tries to match the 200 response against entries in dialog-in table. Here is the problem as this response shouldn't match yet the created dialog, but the only way to know it is by storing the transaction branch of the last request within the dialog (for both sides!).
I've been thinking long time about it and I always find corner cases (or not so "corner") in which the mechanism would fail, there is not a magic solution (for now).
What about the existing modules that are already working on top of the existing dialog design?
For example? which modules do work over the dialog module? there are a lot of such modules in OpenSIPS and all of them fail due to the current dialog module limitations (same as we are debating here). IMHO there is nothing to preserve as the current dialog design is just limited to a few cases (any exotic and not so exotic case break it).
I will spent more time thinking about it. Regards.
Iñaki Baz Castillo wrote:
2010/3/16 Timo Reimann timo.reimann@1und1.de:
(1) I re-checked when dialog state is modified exactly for responses (and believe I have to doubt what I initially claimed to be true):
So, taking into account that (serial and parallel) forking proxies will *forward* responses only when all forking attempts have finally failed or one succeeded,
Early dialogs are created when a provisional response with a different To-tag arrives, and of course all the provisional responses (different early-dialogs) are relayed by the proxy to the UAC.
Multiple provisional responses should not interfere with dialog workings, as far as I can tell. But please read on below.
wouldn't that automatically implement your "dialog-outs will properly adjust dialog-in's state" approach and render dialog-outs unnecessary? Or am I wrong on the assumption how forking works?
Not sure, but I think you miss the case in which parallel forking (or serial forking) is performed by a proxy (P2) behind kamailio (P1):
UAC ------------ P1 -------------- P2 ---------------UAS1,UAS2,UAS3 (different To-tags)
In this case, for each early-dialog (different To-tag) P1 will receive such response within the same outgoing transaction (P1 just created a single outgoing transaction to relay the INVITE to P2).
Theorically onlye the UAC cares about dialogs, and not a proxy. If a proxy must be aware of dialogs (dialog module) it should handle all the early-dialogs, and it doesn't matter if different early-dialogs have been originated due to forking in local proxy or in a proxy in the path (after the local proxy).
The question is, to what extent does the dialog module need to handle early dialogs in order to track dialogs correctly?
As far as managing dialog state is concerned, multiple provisional responses from different UASes all forwarded to the same UAC shouldn't mess up with the dialog state as they all enforce the same state, i.e., "early". To stick with the routing example above: When the first provisional response (say, from UAS1) passes P1, it will change the dialog state from "none" to "early". When a second provisional response (say, from UAS2) arrives on P1 and is forwarded to UAC, no state transition will occur: The state machine just doesn't do anything when a 1xx response is parsed for a call which is already in the early state.
As far as dialog callbacks are concerned, a bit additional code may be required to make sure that callbacks to DLGCB_EARLY are executed once only. Should be as simple as limiting such callbacks to cases where the dialog state has actually transitioned from DLGCB_NONE to DLGCB_EARLY.
As far as the varying To-tags among different provisional responses are concerned, I wonder if that's an issue. It may suffice to associate just the To-tag from the final response with the dialog state and not any To-tags from provisional responses. However, there is RFC 3261, section 13.2.2.1, which mentions that early dialogs are needed (only) "if the UAC needs to send a request to its peer within the dialog before the initial INVITE transaction completes". I'm not aware whether the current dialog module is already capable of dealing with in-early-dialog messaging, and if not, whether your "dialog-in/dialog-out" approach could do so.
Before, you mentioned 100rel required by certain gateways, resulting in PRACKs, increased CSeq numbers, and problems for locally generated requests. It's not absolutely clear to me whether this is already taken care of by your approach, and whether anything of what I laid out in this post would possibly make such problems look less threatening for the current dialog implementation. Are locally generated requests generated in this context in-dialog or even in-early-dialog?
(2) How would your approach deal with unconfirmed requests traversing the same proxy multiple times, i.e., what has been denoted as "spiraling" in this thread, as in this example:
UA1 --> P1 --> P2 --> P1 --> UA2
Will that result in the creation of two dialog(-in)s?
As the INVITE from P2 to P1 is a different transaction, it should create a new dialog-in entry. In order to distinguish which INVITE transaction each response belongs to, the dialog module should also store the INVITE branch (in both the dialog-in entry and dialog-out entry/entries pointing to the dialog-in entry).
Other approach would be avoiding creating two dialog-in entries for such spiral case. This is, when the INVITE arrives from P2 to P1, P1 would create a new dialog-in entry as there is already a dialog-in entry with same Call-ID and From-tag.
Not sure which approach is better, perhaps the second one (from SIP point of view, the spiral is still a single dialog!).
As you have probably noted yourself by now, there has been an ongoing discussion on how to handle spiraling. To me, it seems that a design decision on this sub-topic is crucial and has to be settled before hands-on, coding work on a better, improved dialog module can start.
Cheers,
--Timo
2010/3/17 Timo Reimann timo.reimann@1und1.de:
Early dialogs are created when a provisional response with a different To-tag arrives, and of course all the provisional responses (different early-dialogs) are relayed by the proxy to the UAC.
Multiple provisional responses should not interfere with dialog workings, as far as I can tell. But please read on below.
Take for exmaple mediaproxy module and its function "engage_mediaproxy" which is based on dialog module. It doesn't work when there is forking! This is, if you call such function then the SDP is modified for all the parallel or serial branches you create. This is due to the dialog module limitation.
Theorically onlye the UAC cares about dialogs, and not a proxy. If a proxy must be aware of dialogs (dialog module) it should handle all the early-dialogs, and it doesn't matter if different early-dialogs have been originated due to forking in local proxy or in a proxy in the path (after the local proxy).
The question is, to what extent does the dialog module need to handle early dialogs in order to track dialogs correctly?
As far as managing dialog state is concerned, multiple provisional responses from different UASes all forwarded to the same UAC shouldn't mess up with the dialog state as they all enforce the same state, i.e., "early". To stick with the routing example above: When the first provisional response (say, from UAS1) passes P1, it will change the dialog state from "none" to "early". When a second provisional response (say, from UAS2) arrives on P1 and is forwarded to UAC, no state transition will occur: The state machine just doesn't do anything when a 1xx response is parsed for a call which is already in the early state.
It could occur a corner case (very famous in SIPit events) in which two UAS (UAS1 and UAS2) reply 200 for the INVITE at the same time so the proxy must relay *both* 200 responses to UAC which must ACK both and later send a BYE for one of them. Until such BYE occurs there are two established dialogs in the proxy (or there must be).
As far as dialog callbacks are concerned, a bit additional code may be required to make sure that callbacks to DLGCB_EARLY are executed once only. Should be as simple as limiting such callbacks to cases where the dialog state has actually transitioned from DLGCB_NONE to DLGCB_EARLY.
But AFAIK that would fail in case of serial forking as the new branch (created after the first one fails) doesn't inherit the callbacks.
However, there is RFC 3261, section 13.2.2.1, which mentions that early dialogs are needed (only) "if the UAC needs to send a request to its peer within the dialog before the initial INVITE transaction completes". I'm not aware whether the current dialog module is already capable of dealing with in-early-dialog messaging, and if not, whether your "dialog-in/dialog-out" approach could do so.
Well, a provisional response *containing Record-Route and Contact* is required for that, so the UAC can send an in-dialog request (i.e. UPDATE) to a specific branch. For this to work in the proxy it's needed that the dialog module stores all the early-dialogs (different To-tags) as different entries (each one with its own local/remote CSeq, route-set and remote-target/Contact-uri).
So having each early-dialog (each dialog) in its own dialog-out entry would do the job.
Before, you mentioned 100rel required by certain gateways, resulting in PRACKs, increased CSeq numbers, and problems for locally generated requests. It's not absolutely clear to me whether this is already taken care of by your approach,
It's taken in my approach as each dialog-out entry would store local and remote CSeq. In normal circumstances just one dialog-out entry would be in "established" status while the others have been cancelled or rejected by other UAS's. So finally, when invoking a local BYE from Kamailio, it would contain the proper CSeq value according to its dialog-out entry.
As stated above, during a parallel forking a server could require 100rel so the UAC would increase the CSeq jsut for such early-dialog, sending a PRACK. The dialog module would match the PRACK Call-ID, From-tag and To-tag against a dialog-out entry and update it accordingly.
Are locally generated requests generated in this context in-dialog or even in-early-dialog?
For now they are in-dialog (in-established-dialog). I expect that it's not useful that the proxy could generate local requests withing early-dialogs, as just the UPDATE (to change the SDP) and BYE would make sense from the UAC's point of view, but from a proxy's point of view it can terminate a branch by sending a CANCEL (if the branch is locally generated of course).
As you have probably noted yourself by now, there has been an ongoing discussion on how to handle spiraling. To me, it seems that a design decision on this sub-topic is crucial and has to be settled before hands-on, coding work on a better, improved dialog module can start.
Agree. I'm trying to figure out the best design taking spirals into account. It will take some time to me as I don't find a proper solution yet (all the solutions have some corner cases or vulnerabilities when handling spirals).
Regards.
Iñaki Baz Castillo wrote:
The question is, to what extent does the dialog module need to handle early dialogs in order to track dialogs correctly?
As far as managing dialog state is concerned, multiple provisional responses from different UASes all forwarded to the same UAC shouldn't mess up with the dialog state as they all enforce the same state, i.e., "early". To stick with the routing example above: When the first provisional response (say, from UAS1) passes P1, it will change the dialog state from "none" to "early". When a second provisional response (say, from UAS2) arrives on P1 and is forwarded to UAC, no state transition will occur: The state machine just doesn't do anything when a 1xx response is parsed for a call which is already in the early state.
It could occur a corner case (very famous in SIPit events) in which two UAS (UAS1 and UAS2) reply 200 for the INVITE at the same time so the proxy must relay *both* 200 responses to UAC which must ACK both and later send a BYE for one of them. Until such BYE occurs there are two established dialogs in the proxy (or there must be).
Since it's up to the UAC what to do with these "concurrent dialogs" (e.g., immediately BYE one dialog, or keep both for a long period of time) the creation of another, regular dialog should take care of things. That is, when a response is about to be forwarded for which a dialog with the same Call-ID and From-tag already exists, create a completely new dialog. That way, a concurrent dialog created from such a race condition would be treated and managed just like another dialog created "regularly", including in-dialog routing as the dialog identifiers will differ.
The only issue one have to think about in these scenarios is how to deal with callbacks as one of the two concurrent dialogs hasn't gone through the regular "none/early/confirmed" transition but starts off right at being "confirmed". Maybe a flag or a brand new callback type could be used to enable users to hook up to dialogs established this very special way.
As far as dialog callbacks are concerned, a bit additional code may be required to make sure that callbacks to DLGCB_EARLY are executed once only. Should be as simple as limiting such callbacks to cases where the dialog state has actually transitioned from DLGCB_NONE to DLGCB_EARLY.
But AFAIK that would fail in case of serial forking as the new branch (created after the first one fails) doesn't inherit the callbacks.
Does serial forking imply deletion of the transaction and creation of a new one? If so, the dialog callbacks will in fact be destroyed. If not, each branch's provisional response will map to the same transaction and hence, to the same dialog. I believe the latter is the case but please correct me if I am wrong.
However, there is RFC 3261, section 13.2.2.1, which mentions that early dialogs are needed (only) "if the UAC needs to send a request to its peer within the dialog before the initial INVITE transaction completes". I'm not aware whether the current dialog module is already capable of dealing with in-early-dialog messaging, and if not, whether your "dialog-in/dialog-out" approach could do so.
Well, a provisional response *containing Record-Route and Contact* is required for that, so the UAC can send an in-dialog request (i.e. UPDATE) to a specific branch. For this to work in the proxy it's needed that the dialog module stores all the early-dialogs (different To-tags) as different entries (each one with its own local/remote CSeq, route-set and remote-target/Contact-uri).
So having each early-dialog (each dialog) in its own dialog-out entry would do the job.
Yeah, I guess this is were you need dialog-outs. However, if what I recommended above really works and we (you ;) ) do not find any further deficits, it could be that you only need to use dialog-outs for routing but not for state management. This would make things easier as you would not have to modify dialog state from both dialog-ins and -outs but just from dialog-ins.
Before, you mentioned 100rel required by certain gateways, resulting in PRACKs, increased CSeq numbers, and problems for locally generated requests. It's not absolutely clear to me whether this is already taken care of by your approach,
It's taken in my approach as each dialog-out entry would store local and remote CSeq. In normal circumstances just one dialog-out entry would be in "established" status while the others have been cancelled or rejected by other UAS's. So finally, when invoking a local BYE from Kamailio, it would contain the proper CSeq value according to its dialog-out entry.
As stated above, during a parallel forking a server could require 100rel so the UAC would increase the CSeq jsut for such early-dialog, sending a PRACK. The dialog module would match the PRACK Call-ID, From-tag and To-tag against a dialog-out entry and update it accordingly.
Are locally generated requests generated in this context in-dialog or even in-early-dialog?
For now they are in-dialog (in-established-dialog). I expect that it's not useful that the proxy could generate local requests withing early-dialogs, as just the UPDATE (to change the SDP) and BYE would make sense from the UAC's point of view, but from a proxy's point of view it can terminate a branch by sending a CANCEL (if the branch is locally generated of course).
So this is another set of examples why dialog-outs seem required.
As you have probably noted yourself by now, there has been an ongoing discussion on how to handle spiraling. To me, it seems that a design decision on this sub-topic is crucial and has to be settled before hands-on, coding work on a better, improved dialog module can start.
Agree. I'm trying to figure out the best design taking spirals into account. It will take some time to me as I don't find a proper solution yet (all the solutions have some corner cases or vulnerabilities when handling spirals).
Do you happen to have a list of these corner cases where spiraling or the dialog module in general fails?
I think it would prove really helpful if we make a checklist of items, including issues we have already discussed and and those which we haven't but which you may know. That way, we could verify whether any new approach discussed here is sufficiently good.
Additionally, I think that as soon as we have figured out the most important design choices for the improved dialog module, we should set up a wiki page to maintain the new dialog design and have a rough specification to implement from.
Cheers,
--Timo
Timo Reimann wrote:
Additionally, I think that as soon as we have figured out the most important design choices for the improved dialog module, we should set up a wiki page to maintain the new dialog design and have a rough specification to implement from.
Nevermind Iñaki, I missed that footnote of yours in that other mail. :)
Cheers,
--Timo
2010/3/18 Timo Reimann timo.reimann@1und1.de:
It could occur a corner case (very famous in SIPit events) in which two UAS (UAS1 and UAS2) reply 200 for the INVITE at the same time so the proxy must relay *both* 200 responses to UAC which must ACK both and later send a BYE for one of them. Until such BYE occurs there are two established dialogs in the proxy (or there must be).
Since it's up to the UAC what to do with these "concurrent dialogs" (e.g., immediately BYE one dialog, or keep both for a long period of time) the creation of another, regular dialog should take care of things. That is, when a response is about to be forwarded for which a dialog with the same Call-ID and From-tag already exists, create a completely new dialog. That way, a concurrent dialog created from such a race condition would be treated and managed just like another dialog created "regularly", including in-dialog routing as the dialog identifiers will differ.
The only issue one have to think about in these scenarios is how to deal with callbacks as one of the two concurrent dialogs hasn't gone through the regular "none/early/confirmed" transition but starts off right at being "confirmed". Maybe a flag or a brand new callback type could be used to enable users to hook up to dialogs established this very special way.
I still think that the approach with an unique dialog_in and multiple dialog_out is easier. I'm going to send right now a mail inviting the people to comment all this stuf. I've writen a new proposal for the Dialog moduel trying to achieve all the cases explained in this thread (even complex ones).
But AFAIK that would fail in case of serial forking as the new branch (created after the first one fails) doesn't inherit the callbacks.
Does serial forking imply deletion of the transaction and creation of a new one? If so, the dialog callbacks will in fact be destroyed. If not, each branch's provisional response will map to the same transaction and hence, to the same dialog. I believe the latter is the case but please correct me if I am wrong.
The new transaction (due to serial forking) should inherit the callbacks applied to the original transaction, but... shouldn't in fact such callbacks be inserted into the proxy *server* transaction? that's an unique transaciton even if the proxy forkes.
Agree. I'm trying to figure out the best design taking spirals into account. It will take some time to me as I don't find a proper solution yet (all the solutions have some corner cases or vulnerabilities when handling spirals).
Do you happen to have a list of these corner cases where spiraling or the dialog module in general fails?
I hope this case is covered in the wiki proposal, but please check it :)
I think it would prove really helpful if we make a checklist of items, including issues we have already discussed and and those which we haven't but which you may know. That way, we could verify whether any new approach discussed here is sufficiently good.
Additionally, I think that as soon as we have figured out the most important design choices for the improved dialog module, we should set up a wiki page to maintain the new dialog design and have a rough specification to implement from.
There we go! :)
On 03/16/2010 08:39 PM, Timo Reimann wrote:
Hey Iñaki,
Iñaki Baz Castillo wrote:
2010/3/12 Timo Reimanntimo.reimann@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).
I think that with this approach all the cases are covered. Opinions?
Interesting idea. Let me ask two questions:
(1) I re-checked when dialog state is modified exactly for responses (and believe I have to doubt what I initially claimed to be true):
According to dlg_handlers.c, dlg_onreply() is called right before a response is forwarded, after it was forwarded, and when the associated transaction is terminated. (tm callbacks TMCB_RESPONSE_PRE_OUT, TMCB_RESPONSE_FWDED, and TMCB_TRANS_DELETED, respectively, in Kamailio 1.5. The 3.x branch seems to have renamed TMCB_RESPONSE_PRE_OUT to TMCB_RESPONSE_READY and TMCB_TRANS_DELETED to TMCB_DESTROY. Correct me if this wasn't just for the looks.
yes, those renaming happened.
To comment the rest I have to find the time to read whole thread, which got quite big for now :-)
Cheers, Daniel
) So, taking into account that (serial and parallel) forking proxies will *forward* responses only when all forking attempts have finally failed or one succeeded, wouldn't that automatically implement your "dialog-outs will properly adjust dialog-in's state" approach and render dialog-outs unnecessary? Or am I wrong on the assumption how forking works?
(2) How would your approach deal with unconfirmed requests traversing the same proxy multiple times, i.e., what has been denoted as "spiraling" in this thread, as in this example:
UA1 --> P1 --> P2 --> P1 --> UA2
Will that result in the creation of two dialog(-in)s?
Cheers,
--Timo
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev