2010/4/12 Timo Reimann <timo.reimann(a)1und1.de>de>:
I just see a
minor issue with this. Imagine P1 is running the Dialog
module and a proxy P2 behind it does parallel forking and replies 2
early dialogs. This would mean two entries under dialog_out table.
Later P2 sends a negative final response for the first dialog. Just
the dialog_out entry matching the To-tag would be deleted, while the
other one would exist until the whole dialog is confirmed or
terminated.
Anyhow, I think this is not a big problem.
Forking proxies do not forward negative replies until a call has been
finally deemed unsuccessful. This means that once a negative response
arrives at P1, the entire call has failed and thus, P1 may safely delete
all branches belonging to that call. The way to find these branches is
by looking up all dialog_out entries with the dialog ID that matches the
one from the dialog_in table referenced by the callback-provided hash
ID. (Oh boy!)
Or, looking at our "Parallel forking" example, if P1's dialog tables
would look as following (showing just the relevant columns) right before
the reception of a final response:
dialog_in:
| hash_id | dialog_id |
| 1111 | 1111a |
dialog_out:
| dialog_id | To-tag |
| 1111a | foo |
| 1111a | bar |
Then, on reception of a final negative response, it will extract hash ID
1111 from the dialog callback parameter, find that it maps to dialog ID
1111a, and lookup both dialog_out entries with that dialog ID 1111a.
That's how I see it.
And I agree, you are right :)
dialog_out
entries are important in order to mantain the proper CSeq
of caller and callee and also remote target and route set for each
dialog (useful when using the Dialog module MI function to terminate a
call). Also dialog_out entries store per (early-)dialog flags
(dflags), probably needed by some modules also during early-dialog
(i.e. mediaproxy and "engage_media()" method).
Alright. I've added some of your examples to the wiki page as further
rationale behind the new proposal.
Thanks.
Imagine the
following case:
- alice calls to bob and the proxy forks to bob1 and bob2.
- Both replies 183 with SDP.
- 183 from bob2 requires PRACK.
- alice sends PRACK for bob2 (so its associated entry in dialog_out
gets the caller_cseq incremented).
- Module XXX sets a dflag(N) just for the dialog with bob1.
- bob1 replies 200.
- At this point the dialog_out entry for bob2 is destroyed.
- But bob2 replies 200 before receiving the CANCEL.
- As the text above states a new entry in dialog_out would be created
by copying the dflags from the already confirmed dialog_out entry (so
dfalg(N) is set), and copying the dialog_in's original_caller_cseq
into its caller_cseq.
This would be obviously wrong becase the created dialog for bob2 has a
wrong caller_cseq and wrong dflags.
However the solution seems easy:
When a dialog gets confirmed mantain the rest of dialog_out entries
for a while (maybe 3-5 seconds), time enough to ensure that if a new
200 arrives within an existing early-dialog it will match (an update
properly) such entry in dialog_out. What do you think?
Sounds reasonable. I wonder how much dependent the current dialog module
implementation is on the transaction deletion timer (i.e., if there is
already a delay that prevents the dialog from being removed right after
a final response has been forwarded). Unless you or someone else knows,
I'll try to find that out and update the wiki accordingly.
With the current design (the existing one I mean) a dialog is deleted
from memory after 4-5 seconds after being terminated. This is due to a
TM timer, so it's seems easy to reuse.
Regards.
--
Iñaki Baz Castillo
<ibc(a)aliax.net>