Showing posts with label srtp. Show all posts
Showing posts with label srtp. Show all posts

Thursday, June 27, 2024

No or distorted sound using SRTP and rtpengine

 

TL;DR;

SDES-pad 

Long version:

Recently had a chance of upgrading rtpengine from version 8 to version 12. 

For those, who don't know what it is, it's just one of the most popular RTP proxy in the opensource ecosystem. And usually coming with Kamailio and OpenSIPS as a default RTP Proxy option nowdays. 

And I must say, it's a really stable software with great backwards compatibility. I did not expected to get any issues on this upgrade, but quite fast, got into situation, when receiving a calls on Linphone (mobile, if it matters to someone), sound get distorted in a case of Android and completely absent in a case of iOS.

First I've blamed a new chiper suites, that had been added and disabled it. (SDES-no-<CHIPER> string in rtpengine_manage(), if someone interested). But that does not help.

In the process of searching I've found this issue on github. And yes, turning on SDES-pad resolved the issue, but I was really interested why this option was introduced in a first place.

So, according to the documentation,

pad

   RFC 4568 (section 6.1) is somewhat ambiguous regarding the base64 encoding format of a=crypto parameters added to an SDP body. The default interpretation is that trailing = characters used for padding should be omitted. With this flag set, these padding characters will be left in place.

Hm, let's read the RFC about it.

   When base64 decoding the key and salt, padding characters (i.e., one or two "=" at the end of the base64-encoded data) are discarded (see [RFC3548] for details).
   Base64 encoding assumes that the base64 encoding input is an integral number of octets.  If a given crypto-suite requires the use of a concatenated key and salt with a length that is not an integral number of octets, said crypto-suite MUST define a padding scheme that results in the base64 input being an integral number of octets.

What I can see here is reference to how base64 is made, just explicit remark, that padding characters are not carrying any data, just.. padding according to the corresponding RFC:

   In some circumstances, the use of padding ("=") in base encoded data is not required nor used.  In the general case, when assumptions on size of transported data cannot be made, padding is required to yield correct decoded data.
   Implementations MUST include appropriate pad characters at the end of encoded data unless the specification referring to this document explicitly states otherwise.

Really, I can't see any way, that padding is "optional" in base64 encoding by default, both RFC's expicitly saying, that padding is needed and this is the case for SDP option a=crypto.

As a takeway for me, "default" options even in poular software not meaning "right".

Friday, October 15, 2021

Functional testing of VoIP infrastructure

 Sometimes, it's really hard to test VoIP infrastructure in an automated way. The usual way of testing any telco system is to take a phone, make some calls and that's it. Maybe to look at the logs. 

Some of the engineers going further and using famous SIPP, which is quite good in testing low-level SIP, but really could be a pain in some closer-to-world scenarios.

Another approach is to write some scripts and automating Asterisk or FreeSWITCH to do some test calls. And it's a good approach, but sometimes writing something simple could take a lot of time. And attention.

But there is one more way - use standalone SIP libraries like baresip or pjsip and control them via API or CLI.

Exactly this way was taken by Julien Chavanton in his voip_patrol project. After a short time of playing around with it, I can say it's a really good combination of simplicity of things it can test and a way it's configuring.

In my current position, I'm dealing mostly with opus/SRTP media (in DTLS-SRTP flavor) and I was able to add support of this  to voip_patrol (in this branch) and it's working well with rtpengine provided SRTP.

And here is just an example of voip_patrol scenario to register TLS endpoint, make a call with SRTP and catch it back. So, a simple register-call test as a good starting point for more complex scenarios. 

 

<config>
  <actions>
  <action type="codec" disable="all"/>
    <action type="codec" enable="pcma" priority="250"/>
    <action type="codec" enable="pcmu" priority="249"/>
    <action type="register" label="Register 88881"
            transport="tls"
            account="88881"
            username="88881"
            password="XXXXX"
            registrar="XXXXX"
            realm="XXXXX"
            expected_cause_code="200"
            srtp="dtls,sdes,force"
    />
    <action type="wait" complete="true"/>
    <action type="accept" label="Receive all calls"
            account="default"
            hangup="10"
            code="200" reason="OK"
            transport="tls"
            srtp="dtls,sdes,force"
    />
    <action type="call" label="Call to 88881"
            transport="tls"
            expected_cause_code="200"
            caller="88882@XXXXX"
            callee="88881@XXXXX"
            from="sip:88882@XXXXX"
            to_uri="88881@XXXXX"
            max_duration="20" hangup="16"
            username="88882"
            password="XXXXX"
            realm="XXXXX"
            rtp_stats="true"
            max_ringing_duration="15"
            srtp="dtls,force"
            play="/git/voip_patrol/voice_ref_files/reference_8000_12s.wav"
    />
    <action type="wait" complete="true"/>
  </actions>
</config>

 

For more advanced, I suggest to look on issues [1, 2] on GitHub, where author expands some concepts.

And as a good quickstart - video from author


UPDATE: Based on this tool, templating and reporting suite VOLTS was created. Stay tuned for more cool features to come!