Welcome to sipperf’s documentation!

sipperf is a performance-testing tool for SIP, a VoIP (Voice-over-IP) communication protocol.

It’s free software licensed under the 3-clause BSD license.

Quickstart

Create a users.csv file in the format SIPURI,USERNAME,PASSWORD:

sip:1234@example.com,1234@example.com,secret
sip:1235@example.com,1235@example.com,secret

Then run ./sipperf --target sip:localhost --rps 5 --cps 1 --max-calls 1

You should see output similar to the following:

2 successful registers
0 failed registers
0 calls initiated
0 calls successfully set up
0 calls failed

Command-line options

sipperf - a command-line SIP performance testing tool

Usage:
  sipperf --target sip:1.2.3.4 [options]
  sipperf --help
  sipperf --version

Options:
  -h --help            Show this screen.
  
  --version            Show version.
  
  --target=<sipuri>    Outbound proxy for traffic.
  
  --users-file=<file>  Path to a CSV file containing URIs, usernames and passwords for
                       each user [default: ./users.csv]
  
  --rps=<n>            Registrations-per-second rate for initial REGISTERs [default: 10].
  
  --cps=<n>            Calls-per-second rate after initial registration phase [default: 10].
  
  --max-calls=<n>      Maximum calls to make before exiting [default: 100].

Performance tips

Here are some tips on getting the best performance out of sipperf.

DNS

sipperf doesn’t have any built-in DNS caching, so it does DNS lookups for each call, and may be slowed down by waiting for DNS responses from the network.

Two tips for getting around this problem are:

  • install dnsmasq - this adds a local DNS server that caches DNS lookups, giving faster response times
  • use SIP URIs that minimise the number of DNS lookups - “sip:example.com” will need three or four DNS lookups (NAPTR, one or two SRV lookups, and an A record lookup), whereas “sip:example.com:5060;transport=tcp” will just need the A record lookup - and “sip:1.2.3.4” won’t need any

Scaling to multiple cores

Because sipperf is a single-threaded process, it doesn’t make use of multiple CPU cores. If you have multiple CPU cores and want to use them, the best way to do so is to shard your performance testing:

  • split your subscriber base into N equal parts, and put each part in its own CSV file
  • start N instances of sipperf, each using one CSV file, and each running 1/Nth of your load

Comparison with similar projects

The main goals of sipperf are to be:

  • high-performance - it should be able to handle hundreds of calls per second on a single, reasonably-powered CPU core
  • realistic - it should be able to emulate
  • SIP-focused - while media performance testing is important

SIPp

SIPp is the main other SIP performance testing tool I’m familiar with

It has a couple of disadvantages:

  • it’s focused on SIP dialogs rather than users - so it allows you to define a call scenario, for example (SIP INVITE through to BYE) and run that repeatedly, but not to define a mix of dialogs bound together by a user (a user sends a REGISTER, then makes some calls and sends some text messages, and it also able to answer calls)
  • it’s quite cluttered - it supports a lot of features which are either not directly relevant to SIP performance testing (like the ability to replay media) or quite niche (like SCTP support)

The main advantages of SIPp over sipperf are:

  • it’s very user-programmable -
  • it’s much more mature

Developing sipperf

Getting the source

The sipperf source code is hosted on Github at https://github.com/rkday/sipperf.

You can check the code out by running:

git clone --recursive https://github.com/rkday/sipperf

Building sipperf

sipperf is built with CMake:

cmake .
make

This produces a sipperf binary in the current directory.

Understanding the code

For a high-level overview, see the architecture documentation (Architecture).

After that, the header files are well-commented and should help you understand what code does what.

If something still isn’t clear to you, drop me an email at rkd@rkd.me.uk!

Writing documentation

Architecture

sipperf uses the libre SIP library to handle all its SIP work (e.g. listening for SIP messages, message parsing, maintaining the various SIP state machines and timers that handle retransmissions).

All its work is done on a single thread - the main thread running libre_main. This thread processes both incoming SIP messages and timers - before calling into libre_main, sipperf sets up various recurring timers to do work (for example, a recurring timer to start calls).

libre is relatively efficient - it uses epoll on Linux for good signaling performance, and the custom version of libre used in sipperf includes a timer heap for good timer performance (which is being contributed back into libre).

Control flow

  • main() does various setup, such as parsing arguments and reading the CSV file containing user details
  • it then starts the user registration timer
  • it then calls libre_main(0, which continues running until program exit
  • periodically, the user registration timer will fire and register some users
  • when all users are registered, the user registration timer starts the call timer, and stops itself
  • libre takes care of re-registering users when their registrations expire - we don’t need a separate timer for that
  • periodically, the user registration timer will fire and set up some calls
  • when the required number of calls have been set up, the call timer will start the cleanup timer and stop itself
  • the cleanup timer will attempt a graceful shutdown of the libre_main event loop (e.g. waiting for all outstanding traffic to finish)
  • if the cleanup timer fires too many times, it will do a hard shutdown instead
  • after the cleanup timer shuts down the event loop, sipperf exits

Representing users

Statistics

Statistics reporting