-
Notifications
You must be signed in to change notification settings - Fork 184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support forking SIP calls #227
base: master
Are you sure you want to change the base?
Conversation
Great work @alexdowad @andywolk how we can have this reviewed? |
Will this also fix #211? |
Yes, it will. |
ref: freeswitch/sofia-sip#227 (cherry picked from commit 143c519)
ref: freeswitch/sofia-sip#227 (cherry picked from commit 143c519)
ref: freeswitch/sofia-sip#227 (cherry picked from commit 143c519)
ref: freeswitch/sofia-sip#227 (cherry picked from commit 143c519)
As suggested in the last FS Community Call please find attached a sipp scenario that can be used to see the problem before the patch and it working after the patch. That scenario assumes you have 2 extensions registered in FS (1234 and 1235). An INVITE is sent to 1234 and after 10 seconds ringing (do not answer it) it will fork the call to 1235 (new INVITE with a different branch parameter in Via header) and later CANCEL the original INVITE. Before the proposed patch you will see that the second INVITE will be replied with After applying the proposed patch the second INVITE will be processed as as expected. |
libsofia-sip-ua/nta/nta.c
Outdated
@@ -4316,6 +4319,7 @@ nta_leg_t *nta_leg_tcreate(nta_agent_t *agent, | |||
su_home_t *home; | |||
url_t *url; | |||
char const *what = NULL; | |||
sip_via_t *via = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sip_via_t *via = NULL; | |
const sip_via_t *via = NULL; |
To fix the following build error with gcc 14:
nta.c: In function 'nta_leg_tcreate':
./../sip/sofia-sip/sip_tag.h:340:57: error: passing argument 1 of 'siptag_via_vr' from incompatible pointer type [-Wincompatible-pointer-types]
340 | #define SIPTAG_VIA_REF(x) siptag_via_ref, siptag_via_vr(&(x))
| ^~~~
| |
| sip_via_t ** {aka struct sip_via_s **}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is done, thanks!
When a SIP call is forked, the client will send an INVITE with the same Call ID and same From tag as an earlier INVITE, but with a different Branch ID in the topmost Via header. There were two issues with sofia-sip which prevented call forking from working; first, its logic for merging SIP requests (as per RFC3261 section 8.2.2.2) did not respect the Branch ID. It would merge requests with a different Branch ID, which is contrary to RFC3261 section 17.2.3. Second, sofia-sip has some logic for checking whether incoming requests are part of an established SIP dialog or not. The matching criteria were such that incoming INVITE requests forking a call would be treated as part of the already established dialog, and then an error would be returned to the client, essentially telling the client that this new INVITE is invalid because the call is already established. Therefore, add some extra matching conditions which ensure that an INVITE forking a call will not be treated as part of the previously established call leg. The matching conditions are as specific as possible, to minimize the chances of unintentionally affecting how other types of SIP messages are handled. Implementing these new matching conditions can only be done by recording the Branch ID for established calls, so we can check whether another INVITE which comes later has the same Branch ID or a different one. This requires adding a new member to nta_leg_s. Co-Authored-By: João Arruda <[email protected]>
When a SIP call is forked, the client will send an INVITE with the same Call ID and same From tag as an earlier INVITE, but with a different Branch ID in the topmost Via header.
There were two issues with sofia-sip which prevented it from handling multiple INVITE requests for forked SIP calls; first, its logic for merging SIP requests (as per RFC3261 section 8.2.2.2) did not respect the Branch ID. It would merge requests with a different Branch ID, which is contrary to RFC3261 section 17.2.3.
Second, sofia-sip has some logic for checking whether incoming requests are part of an established SIP dialog or not. The matching criteria were such that incoming INVITE requests for forked calls would be treated as part of the already established dialog, and then an error would be returned to the client, essentially telling the client that this new INVITE is invalid because the call is already established.
Therefore, add some extra matching conditions which ensure that an INVITE establishing a forked call will not be treated as part of the previously established call leg. The matching conditions are as specific as possible, to minimize the chances of unintentionally affecting how other types of SIP messages are handled.
Implementing these new matching conditions can only be done by recording the Branch ID for established calls, so we can check whether another INVITE which comes later has the same Branch ID or a different one. This requires adding a new member to nta_leg_s.
My goal here is to allow FreeSWITCH (via
mod_sofia
) to be able to successfully proxy INVITE requests for forked SIP calls, when both destinations of the forked call are behind the same FreeSWITCH instance. However, it also means that all other users oflibsofia
will potentially be able to handle forked calls as well.