freeswitch / sofia-sip

Sofia-SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
GNU Lesser General Public License v2.1
254 stars 173 forks source link

Support forking SIP calls #227

Open alexdowad opened 10 months ago

alexdowad commented 10 months ago

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 of libsofia will potentially be able to handle forked calls as well.

jvarruda commented 10 months ago

Great work @alexdowad

@andywolk how we can have this reviewed?

ncopa commented 10 months ago

Will this also fix https://github.com/freeswitch/sofia-sip/pull/211?

alexdowad commented 10 months ago

Will this also fix #211?

Yes, it will.

jvarruda commented 10 months ago

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 SIP/2.0 482 Request merged Debug log shows: nta.c:3102 agent_recv_request() nta: INVITE (1) is a merged request

After applying the proposed patch the second INVITE will be processed as as expected.

sipp-sofia-sip.xml.txt