[asterisk-commits] oej: branch oej/codename-pineapple r47218 - in
/team/oej/codename-pineapple/c...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Nov 6 07:06:42 MST 2006
Author: oej
Date: Mon Nov 6 08:06:42 2006
New Revision: 47218
URL: http://svn.digium.com/view/asterisk?rev=47218&view=rev
Log:
Updates
Modified:
team/oej/codename-pineapple/channels/chan_sip3.c
team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?rev=47218&r1=47217&r2=47218&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Mon Nov 6 08:06:42 2006
@@ -113,16 +113,16 @@
/*! \page chan_sip3_00index Chan_sip3: Index over docs
\title Chan_sip3 :: Index
- - \ref chan_sip3_start
- - \ref chan_sip3_objects
- - \ref chan_sip3_files
- - \ref chan_sip3_auth
- - \ref chan_sip3_dialogs
- - \ref chan_sip3_overview
+ - \subpage chan_sip3_start
+ - \subpage chan_sip3_objects
+ - \subpage chan_sip3_files
+ - \subpage chan_sip3_auth
+ - \subpage chan_sip3_dialogs
+ - \subpage chan_sip3_overview
\par todo Things to do, ideas
- - \ref chan_sip3_todo
- - \ref chan_sip3_subs
+ - \subpage chan_sip3_todo
+ - \subpage chan_sip3_subs
*/
@@ -635,9 +635,9 @@
}
/*! \brief Find via branch parameter */
-static void find_via_branch(struct sip_dialog *dialog, struct sip_request *req)
-{
- char *dupvia = ast_strdupa(req->via);
+static void find_via_branch(struct sip_request *req, char *viabuf, size_t vialen)
+{
+ char *dupvia;
char *viabranch;
char *sep;
@@ -651,7 +651,7 @@
*sep = '\0';
if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug > 3)
ast_log(LOG_DEBUG, "* Found via branch %s\n", viabranch);
- ast_string_field_set(dialog, remotebranch, viabranch);
+ strncpy(viabuf, vialen, viabranch);
}
Modified: team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_dialog.c?rev=47218&r1=47217&r2=47218&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_dialog.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_dialog.c Mon Nov 6 08:06:42 2006
@@ -805,13 +805,94 @@
}
/*! \brief Connect incoming SIP message to current dialog or create new dialog structure
- Called by handle_request, sipsock_read */
+ \note Called by handle_request, sipsock_read
+
+ \title Dialog matching
+
+ SIP can be forked, so we need to separate dialogs from each other in a
+ good way.
+
+ \title 1. Calling out, getting the same call back
+ An OUTBOUND INVITE can be sent to a SiP proxy and come back twice. We
+ separate the two different calls by branch tag in the topmost via header.
+ Asterisk1 ----> INVITE ---> PROXY
+ PROXY --> INVITE branch 1 ---> Asterisk1
+ PROXY --> INVITE branch 2 ---> Asterisk1
+ PROXY --> INVITE branch 3 ---> UA3 (not Asterisk)
+ We have to treat the two calls as separate calls. But how do we handle
+ this situation, where we actually can take the media internally somehow?
+ If the proxy does not add Record-Route, we can just tear down the SIP
+ signalling and shortcut the call internally. If the proxy Record-Route the
+ call, we need to keep the SIP signalling or just fake a tear down with
+ a fake BYE and handle it internally, which wouuld be bad if the proxy
+ logs are important.
+
+ \title 2. Getting the same INCOMING call multiple times
+ UAC ----> INVITE ---> PROXY
+ PROXY --> INVITE branch 1 ---> Asterisk1
+ PROXY --> INVITE branch 2 ---> Asterisk1
+ PROXY --> INVITE branch 3 ---> UA3 (not Asterisk)
+
+ \title 3. Sending INVITE, getting many replies
+
+ An OUTBOUND INVITE may be forked to two or more separate UA's. If there's
+ a stateless SIP proxy between us and the UA's, we get multiple replies.
+ In a worst case scenario, we get multiple 200 OK at the same time.
+ Since we don't know about the fork, we won't send CANCEL.
+ INVITE -->
+ <--- 100 trying from UA1
+ <--- 100 trying from UA2
+ <--- 200 OK from UA1
+ <--- 200 OK from UA2
+ in this case
+
+ If it's a secondary 200 OK to a current
+ INVITE, we're in interesting waters.
+ In this case, we have to copy the current dialog, create
+ a new and send ACK, then immediately BYE since there's
+ no call to bridge it with.
+ of course, there's a usability issue here. how do you
+ tell the person that answers the forked call that someone
+ else answered already? Too late to cancel the call...
+
+ Scenarios:
+ INVITE
+ 100 from first device
+ 100 from second device
+ 183 from first device
+ 183 from second device
+ - provisional responses, don't create new dialog,
+ just ignore the secondary answers and be happy
+ --- 2. Double 200 OKs
+ 200 OK from first device
+ 200 OK from second
+ - Creates new branch
+ --- 3. Error and 200 OK from different devices
+ 200 OK from first device response
+ 603 Declined from secondary device response
+ - Sorry, just ACK the 603 and close
+
+ 603 declined from first response
+ 200 OK from second response
+ - In this case, the call failed. We can't wait
+ for the possibility that we get a 200 OK
+ from a device we don't know about.
+ - But we might be clever, if we get two 100 trying
+ then we know that something's going on.
+ - Without trickery, the second 200 OK will have to
+ get an ACK, then a BYE
+
+ \title 4. How do we handle this in Asterisk chan_sip3 ???
+
+
+*/
struct sip_dialog *match_or_create_dialog(struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
{
struct sip_dialog *cur = NULL;
char *tag = ""; /* note, tag is never NULL */
char totag[128];
char fromtag[128];
+ char branch[128];
if (ast_strlen_zero(req->callid))
req->callid = get_header(req, "Call-ID");
@@ -841,6 +922,7 @@
if (option_debug > 4 )
ast_log(LOG_DEBUG, "= Looking for Call ID: %s (Checking %s) --From tag %s --To-tag %s \n", req->callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag);
+ findviabranch(req, branch, sizeof(branch));
dialoglist_lock();
for (cur = dialoglist; cur; cur = cur->next) {
/* we do not want packets with bad syntax to be connected to a PVT */
@@ -861,11 +943,35 @@
found = FALSE;
} else if (totag[0]) { /* Both have tags, compare them */
if (strcmp(totag, cur->tag)) {
- found = FALSE; /* This is not our packet */
+ found = FALSE; /* This is not our dialog */
}
}
if (!found && option_debug > 4)
ast_log(LOG_DEBUG, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", cur->callid, totag, sip_method2txt(req->method));
+ }
+
+ /* We need to check the branch too, to make sure this is the proper reply */
+ /* If it is an INVITE from us coming back with a new branch, we need to
+ do some masquerading trickery with the audio.
+ We might also get several INVITEs with different branches
+ and have to treat them as several calls
+ */
+ if (found) {
+ if (!strcmp(cur->ourbranch, branch)) {
+ /* This is our own request coming back to us strangely enough */
+ /* Propably through DNS, but not a proxy */
+ /* Bad dialplan design... ; -) */
+ /* Any way we can handle this??? */
+ }
+ /* If we have a remote branch already, and get a new branch with the
+ same call ID, then something is happening.
+ For responses - we might have a forking proxy and get responses
+ from several UAs on one request.
+ For requests, we might be getting a statelessly forked call to us.
+ */
+ if (!ast_strlen_zero(cur->remotebranch) && strcmp(cur->remotebranch, branch) {
+
+ }
}
More information about the asterisk-commits
mailing list