Skip to main content

Posts

Showing posts with the label VoIP

Notes on STUN protocol

 Since I needed to see a few details in the handling of attributes in STUN responses, I thought of going through the whole STUN protocol RFC again and take notes on the most important parts. I put my notes in some slides, and I'm sharing then in Slideshare in case somebody else may find them useful too: STUN protocol from Giacomo Vacca

Extracting RTP streams from network captures

I needed an efficient way to programmatically extract RTP streams from a network capture. In addition I wanted to: save each stream into a separate pcap file. extract SRTP-negotiated keys if present and available in the trace, associating them to the related RTP (or SRTP if the negotiation succeeded) stream. Some caveats: In normal conditions the negotiation of SRTP sessions happens via a secure transport, typically SIP over TLS, so the exchanged crypto information may not be available from a simple network capture. There are ways to extract RTP streams using Wireshark or tcpdump; it’s not necessary to do it programmatically. All this said I wrote a small tool ( https://github.com/giavac/pcap_tool ) that parses a network capture and tries to interpret each packet as either RTP/SRTP or SIP, and does two main things: save each detected RTP/SRTP stream into a dedicated pcap file, which name contains the related SSRC. print a summary of the crypto information exchanged, if available. With ...

kamailio-tests, a testing framework for Kamailio developers

Kamailio is an open source VoIP server, widely used in the VoIP industry for its performance and feature set. kamailio-tests is a project that aims to provide a level of automated testing for developers. The main idea is that simple things like loading a module or calling a core or module function can be tested without building an entire infrastructure around Kamailio. Also, we want to be able to perform the tests against various versions of Kamailio, and on various OS distributions. In this way a backward incompatible function or a regression can be discovered by a developer even though their system uses one single version and OS combination. This includes also third party libraries, e.g. you may think of testing the HTTP clients with different curl libraries, while Kamailio and OS stay at the same version. kamailio-test doesn't perform tests at function level (but it requires the application to run) or "integration testing" (because in order to re...

On Kamailio World 2018, part II

In the first part of my brain dump about this year's edition of Kamailio World I focused mainly on testing. Core developers and application designers want to be able to test the behaviour of Kamailio -based architectures with minimal effort and fast feedback. A different dimension to testing, that I haven't mentioned in my previous post, was related to Fuzz testing . There were two presentations focused on this: Sandro Gauci's (The easiest way to understand who Sandro is: listen on port 5060 on the public Internet and wait a couple of minutes. You'll see a SIP request from a tool called sipvicious (aka friendly-scanner), a penetration testing tool Sandro wrote (and others misuse)) and Henning Westerholt , historical member of the Kamailio community. Sandro's presentation focused around fuzzing approaches for RTC in general ( slides ), while Henning was more specifically focused on Kamailio. Fuzzing is a sophisticated technique to verify the robustness...

On Kamailio World 2018, part I

This was my fifth time in a row attending Kamailio World in Berlin. The weather was warmer and sunnier than usual. Apart from the obvious focus on Kamailio , as usual the RTC ecosystem was well represented (with Janus, Asterisk, FreeSWITCH, Homer, RTPEngine, and many others). Attendance from the other side of the Atlantic Ocean gave stronger emphasis to the "World" term in the title. My personal mission this year was to talk about a framework for testing Kamailio as a tool for developers and maintainers of the project: kamailio-tests . The main concept was that early tests that are not focused on a specific business logic (as we all have in our projects) and can be automated will be beneficial to Kamailio's reliability. We want to defer end-to-end testing to later stages, because they are expensive. To provide a uniform infrastructure where to run the tests, without requiring permanent test environments, we use Docker for this. This is, of course, not th...

The interesting case of Lua in RTC world

An interesting pattern that caught my attention is the role that Lua is gaining in the RTC (Real-Time Communications) world. Lua is a small-footprint programming language, powerful while keeping a simple syntax. I’ve been using Lua to script dialplan actions for FreeSWITCH since about 2014. It has provided me with a way to define relatively complex logic and speed up the definition of FS’ behaviour. Delegating this type of logic to a scripting language had several advantages, such as: It’s easier to read and understand than native dialplans or native routing logic. Makes unit testing of the dialplan possible/easier. Allows changing some pieces of logic easily, in many cases preventing expensive reload of modules or restart of applications. I’ve been using Lua for Kamailio as well. Kamailio is an open source programmable SIP Proxy . In a specific case, some bits of the routing logic required regex processing and was expecting to change often: an ideal case for...

Around sipp with pcap and authentication support

This is just a practical guide to have latest sipp on debian , to benefit from features that are not available in the stock package ( sip-tester  - version 3.2.1). For example support for playing pcap files or computing authentication hashes. Build sipp with pcap support apt-get install autoconf libncurses5-dev libpcap-dev g++ cd /usr/local/src/ git clone https://github.com/SIPp/sipp.git cd sipp/ ./build.sh --with-pcap ./sipp is the built binary. You can see the version and capabilities with './sipp -v', e.g.: $ ./sipp -v SIPp v3.6-dev-149-gb95f98f-PCAP-RTPSTREAM. ... This version will be able to use actions like exec rtp_stream="file.wav" or exec play_pcap_audio="pcap/g711a.pcap" (see details in current documentation ). A little caveat for 'rtp_stream' and WAV files . As the documentation says sipp expects a WAV file encoded with PCAM ('A-law'). You can also loop that audio for as long as you need, by adding '...

Analysing Opus media from network traces

VoIP/RTC platforms have typically many elements processing audio. When an issue is reported it's important to be able to restrict the investigation field, to save time and resources. A typical scenario is bad or missing audio perceived on the client side. As I've done previously ( here for Opus and here for SILK ) I'd like to share some practical strategies to extract audio from a pcap trace (to verify the audio received/sent was "correct") and to "re-play" the call inside a test bed (to verify that the audio was good but also carried correctly by the RTP stream). Of course a lot can be inferred by indirect data, for example the summary of RTCP reports showing the number of packets exchanged, packets lost, the latency. But sometimes those metrics are perfect while the issue is still there. Focusing in this case on Opus audio, and starting from a pcap file with the network traces for a call under investigation, let's see how to decode the Opus fr...

VoIP calls encoded with SILK: from RTP to WAV, update

Three and a half years ago (which really sounds like a lot of time!) I was working with a VoIP infrastructure using SILK . As it often happens to server-side developers/integrators, you have to prove whether the audio provided by a client or to a client is correctly encoded :-) Wireshark is able to decode, and play, G.711 streams, but not SILK (or Opus - more on this later). So I thought of having my own tool handy, to generate a WAV file for a PCAP with RTP carrying SILK frames. The first part requires extracting the SILK payload and writing it down into a bistream file. Then you have to decode the audio using the SILK SDK decoder, to get a raw audio file. From there to a WAV file it is very easy. As I tried to describe in this previous post , I had to reverse engineer the test files contained in the SDK, to see what a SILK file looked like. Since the SILK payload is not constant, all that was needed was to insert 2 Bytes with the length of the following SILK frame. At the be...

Opus/G.711 Transcoding For The Practical Man

Following my earlier post on "Opus SDP negotiation" in the series "For The Practical Man", I'm presenting today a related topic: Opus audio codec when transcoding is involved. Most of the providers of PSTN connectivity require the simplest possible VoIP codec: G.711 (which comes in two flavours, u-law and a-law). G.711 is a sort of PCM encoding at 8000 samples per second: 8000 times per second an audio sample is encoded with 8 bit. Sometimes Comfort Noise can be used, reducing the bitrate when silence is detected, but otherwise the typical working principle is a continuous flow of digitally-encoded packets of voice. u-law and a-law just use a different way to encode the data. (If you're curious about what does silence look like in G.711, I wrote a post about it some time ago ). G.729 is another widely adopted codec, but I'll leave it for another day. With 8000 samples per second and 8 bit dedicated for each sample G.711 requires a net...

Opus negotiation for the practical man

Opus [0] is a versatile audio codec, with a variable sample rate and bitrate, suitable for both music and speech. It is defined in RFC 6716 [1] and required by WebRTC [2]. Opus can operate at various sample rates, from 8 KHz to 48 KHz, and at variable bitrates, from 6 kbit/sec to 510 kbit/sec. The RTP payload format defined for Opus in RFC 7587 [3] explains the use of media type parameters in SDP, and this article aims to analyze them and show in particular how "asymmetric streams" can be achieved. This is an example of SDP defining an Opus offer or answer:       ...

Continuous Integration and Kamailio

I've presented a workshop at Kamailio World 2016 . It focused on tools to help automating the build, deployment and test of Kamailio -based applications using Jenkins , Docker and a few other technologies. It's been also an opportunity to show a sample usage of the new http_async_client module, designed to perform non-blocking HTTP queries from Kamailio. The interested reader can find the slides here: Continuous Integration and Kamailio from Giacomo Vacca And if you have an hour to spare, here's the full video: Any feedback or question you may have, please get in touch. I have a post on the event in progress, but there are so many things to highlight that it will require some more time. Many thanks to Daniel and Elena-Ramona ( more info here ), event hosts, and Pascom.net for video streaming, recording and editing.

Build a test bed with FreeSWITCH and PJSUA (with SILK)

Build and run FreeSWITCH This is based on debian wheezy, and uses master FreeSWITCH . You can switch to stable when cloning. In my experience this is the quickest way to get to a working, vanilla setup that you can use to automate tests with PJSUA (the PJSIP command-line client). mkdir git cd git # To get master git clone https://stash.freeswitch.org/scm/fs/freeswitch.git cd git/freeswitch ./bootstrap.sh -j # If changes are needed to the list of modules to be compiled vi modules.conf ./configure --enable-core-pgsql-support make sudo make install # Launch FS (in foreground) sudo /usr/bin/freeswitch You can find here the process for building it from source recommended by the FreeSWITCH team. In /etc/freeswitch/vars.xml you may want to change the default password in: cmd="set" data="default_password=XXXXXXXX" If you're enabling SILK , add it to the list in modules.conf.xml : load module="mod_silk" and add it to global_codec_prefs ...

VoIP calls encoded with SILK: from RTP to WAV

SILK is a codec defined by Skype, but can be found in many VoIP clients, like CSipSimple . It comes in different flavours (sample rates and frame sizes), from narrowband (8 KHz) to wideband (24 KHz). Since Wireshark doesn't allow you to decode an RTP stream carrying SILK frames, I was curious to find a programmatic way to do it. In fact, this has also allowed to me to earn a "tumbleweed" badge in stackoverflow . You may argue that a Wireshark plugin would be the right solution, but that's probably for another day. Initially I thought it was sufficient to read the specification for RTP payload when using SILK ; the truth is that I had to reverse engineer a solution by looking at SILK SDK's test vectors. There, I discovered that a file containing SILK audio doesn't have the file header indicated in the IETF draft ("!#SILK"), but a slightly different one ("!#SILK_V3"). More importantly, each encoded frame is not preced...

The sound of silence (encoded with G.711)

There are times where you check the RTP streams in your VoIP capture and everything looks sane, although one or more parties in the call reported no audio. Those times, in particular when G.711 is in use, can be made a little less frustrating by looking at the RTP payload. In fact, it's possible that one party is just sending silence. With G.711 silence has its own coding, and it's easy to spot: a-law : silence is either a payload entirely populated with 0x55 or 0xD5 (depending on the sign applied). u-law : silence is a payload entirely populated with 0xFF .

How to compute or validate the network bandwidth when using Speex

This is a quite simple computation or validation of the network bandwidth, but can be tricky if you don't take into account the "quality" parameter used in Speex . Speex is designed to change bitrate depending on the desired quality, and there are 10 different levels of quality per type (narrowband (8 KHz), wideband (16 KHz), ultra-wideband (32 KHz)). All you have to do is take the expected encoding bitrate for that quality ( e.g. 28 Kbps for wideband at quality 8/10 ), compute the payload per frame, optionally sum the payload when you have more than 1 frame per packet, add the overhead of IP, UDP and RTP, then recompute the overall bitrate. Each Speex frame has 20 msec duration. The payload for Speex wideband at quality 8 (28 kbps) is: P = (28*10^3 kbps * 20*10^-3 msec/frame) = 70 B/frame Consider 1 frame per packet and add the overhead from IP, UDP and RTP: Ptot = 70 B + 40 B = 110 B/packet Compute the final network bandwidth: BW = (110 B)*8 / (20 * 10^...