drachtio / drachtio-server

A SIP call processing server that can be controlled via nodejs applications
https://drachtio.org
MIT License
237 stars 92 forks source link

Drachtio Unable to Handle Branched/Forked Calls #297

Open DBoag opened 1 year ago

DBoag commented 1 year ago

Hi Dave,

I've described the issue below and have included the Drachtio log with verbosity set high. For the sake of discretion I've replaced the external IP addresses with 111.111.111.x in the log files and obfuscated them in the screenshots. I also have a PCAP of the SIP conversation, but will send that directly if required as it contains external IPs which I cannot edit out.

The Setup

Looking at figure 1, we are primarily concerned with the last 2 columns: RTCv2 kam01 (Kamailio) and RTCv2 dra01 (Drachtio).

figure1

The Kamailio box received one INVITE and forked it into the multiple INVITEs we see being sent to Drachtio starting at notation (1). Each of the INVITEs to Drachtio is essentially the same SIP payload, but with an added Via: header. Kamailio added these Via: headers with an incrementing final digit, with the first one starting at 1. In this example the top Via: header added is: Via: SIP/2.0/UDP 10.155.248.52;branch=z9hG4bK0e3a.957c640f749512fb23422e1c88ba66b8.1

That first INVITE (1) is to an Android device which returns a "100 Trying" immediately as it's about to send a push notification to ring the device. The following INVITEs (2) all have their top Via: header set to the incrementing value, and the "100 Trying"s below that also contain the correct Via: headers to indicate which leg/dialogue/transaction (?) they are responding to.

Then when we get to notation (3), we can see Drachtio responding with a number of "410 Gone" packets. This is correct as those endpoints were no longer available, and those packets all contain the correct, corresponding Via: headers to identify the endpoints which were "Gone". So far so good - on with the call...

The Problem

figure2

Looking at figure 2 above, We see Drachtio sending the "200 OK" when the endpoint answers. Immediately, we see Kamailio sending a CANCEL to end the call branch to the remaining ringing endpoint to stop it ringing as we expect. Note that this CANCEL only has one Via: header, but it is the correct one to identify the relevant branch - I'm not sure if that is relevant, but just mentioning it.

But now we see Drachtio respond with a "481 Transaction Does Not Exist" which we do not expect. Having looked at the source code, as best we can understand, Drachtio had "evaporated" all the branches of the call during the process of replying with the"200 OK", and this appears to be deep in the bowels of Sofia SIP.

Drachtio then sends a BYE which then tears down the whole call. Interestingly, this BYE does not contain any of the "incrementing" Via: headers, but that appears moot at this point as the call has effectively failed.

We are looking for some idea of what this will take to fix. Thanks for listening. :)

drachtio.log.zip

DBoag commented 1 year ago

I've tried building Drachtio Server from the feature/sofia-forked-invites branch as suggested. This changes the Sofia SIP branch to HEAD detached at 3d75ced9 - I hope this is correct as I don't work much with submodules. This is the install process I performed:

git clone https://github.com/drachtio/drachtio-server.git && cd drachtio-server
git checkout feature/sofia-forked-invitesgit submodule update --init --recursive
./autogen.sh
mkdir build && cd $_
./configure CPPFLAGS='-DNDEBUG'
make
make install

This is a VoIPmonitor trace of a test call after the update which looks basically the same as the original "problem" trace:

Screenshot 2023-07-20 at 14 24 33

A log of this activity with Sofia debug set to "9" and Drachtio set to "debug" included below:

drachtio.log.zip