Open-source project
sipwise/rtpengine avatar
sipwise/rtpengine

rtpengine: the media proxy behind Kamailio's RTP handling

The Sipwise media proxy for Kamailio

1,008 stars475 forksPerlGPL-3.0

At a glance

What is it?
rtpengine is the Sipwise media proxy for Kamailio, handling RTP and other UDP media traffic, with SDP rewriting, ICE, SRTP, recording and transcoding available through its own module. It suits telecom operators running Kamailio, and its kernel module and Debian packaging are what make it a production component rather than a library.
Who is it for?
rtpengine fits operators who run Kamailio as their SIP proxy and need media handling that goes beyond simple RTP relaying, in particular because the SDP rewriting, ICE and SRTP features are only reachable through the rtpengine module or its rtpproxy-ng counterpart. It does not fit a deployment outside GNU/Linux, and it does not fit a call that requires ZRTP, since ZRTP is not implemented even though traffic passes through.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Perl, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

Editorial analysis

rtpengine sits beside Kamailio and moves the media

rtpengine is the Sipwise NGCP rtpengine, a proxy for RTP traffic and other UDP based media traffic. It is meant to be used with the Kamailio SIP proxy, and the project describes it as a drop-in replacement for any of the other available RTP and media proxies. The split of responsibility is the important part: Kamailio handles signalling, and the media never has to traverse the SIP proxy at all. The proxy asks rtpengine to set up a session, and rtpengine relays the RTP and RTCP streams between the two legs of a call.

The audience is telecom operators and anyone else running Kamailio in anger, not application developers. A single instance handles many concurrent calls, the feature list includes multi-threaded operation and a customizable port range, and the media traffic can run over either IPv4 or IPv6 with bridging between IPv4 and IPv6 user agents and between different IP networks or interfaces. There is also support for advertising different addresses for operation behind NAT, and for setting the TOS and QoS fields.

Only one platform is supported. The README states plainly that the only supported platform is GNU/Linux, which is a reasonable constraint for a component that includes a kernel module, but it does mean the project is not a candidate for a BSD or Windows deployment.

In-kernel forwarding with a userspace fallback

The performance feature that distinguishes rtpengine is the kernel module. The project lists in-kernel packet forwarding for low-latency and low-CPU performance, and immediately after it the safety net: automatic fallback to normal userspace operation if the kernel module is unavailable. That pairing is what makes the design deployable. A deployment that loads the module gets the forwarding path in the kernel, and a deployment that does not, or that runs on a kernel where the module will not build, still works with the userspace path rather than failing to start.

The build system reflects this split. The Makefile exposes a with-kernel target that builds the kernel-module directory after the main build, and a matching install-with-kernel target:

bash
with-kernel: all
install-with-kernel: all install

The kernel module lives in its own directory in the repository, kernel-module/, next to daemon/, lib/ and include/. The main daemon is built from the daemon directory, and the full build also produces the recording daemon and the performance tester when transcoding is enabled. The choice to build the kernel module is therefore a separate step rather than a compile-time flag buried in the daemon build, which is the right way round for something that touches the packet path.

A consequence worth keeping in mind: the two paths are not the same implementation, and the fallback is a fallback. Behaviour that depends on the kernel module should be tested in both modes if your deployment might ever run without it.

SDP rewriting, ICE and SRTP come with the rtpengine module

rtpengine has two integration modes with Kamailio, and the difference between them defines the feature set. When it is used through the rtpengine module, or its older counterpart rtpproxy-ng, the project adds full SDP parsing and rewriting, non-standard RTCP ports under RFC 3605, ICE support under RFC 8445, and SRTP support under RFC 3711. The project also states that it supports Kamailio's rtpproxy module and, with legacy support, the old OpenSER mediaproxy module, so existing setups can be migrated without changing the signalling side first.

The ICE and SRTP lists show how much detail is covered. ICE includes bridging between ICE-enabled and ICE-unaware user agents, acting only as an additional ICE relay candidate, forcing relay of media streams by removing other ICE candidates, acting as an ICE lite peer only, optional trickle ICE under RFC 8838, and optional ICE2 support. SRTP covers SDES and DTLS-SRTP key exchange, AES-CM and AES-F8 ciphers in both userspace and kernel, HMAC-SHA1 packet authentication, bridging between RTP and SRTP user agents, opportunistic SRTP, AES-GCM authenticated encryption under RFC 7714, and the a=tls-id attribute from RFC 8842.

The profile handling is similarly broad, with arbitrary bridging between the supported RTP profiles and multiplexed and demultiplexed RTP and RTCP under RFC 5761, plus breaking of BUNDLE'd media streams. RTCP feedback extensions and the RFC 8842 attribute are the kind of detail that only matter once a carrier-grade mix of endpoints is on the line.

Recording, transcoding and DTMF handling

Beyond relaying packets, rtpengine can record calls, convert between media formats and manipulate DTMF. Recording of media streams is supported, decrypted if possible, which is what makes an encrypted call recordable at the point where the proxy holds the keys. The recording daemon is a separate binary built from the recording-daemon directory, and the project links dedicated documentation for call recording and for transcoding.

The transcoding list is long enough to be worth reading closely. It covers transcoding and repacketization, conversion between RFC 2833 and 4733 DTMF event packets and in-band DTMF tones in both directions, injection of DTMF events or PCM DTMF tones into running audio streams, playback of pre-recorded streams and announcements, transcoding between T.38 and PCM with G.711 or other audio codecs, and silence detection with comfort noise payloads under RFC 3389. There is also media forking and a publish and subscribe mechanism for N-to-N media forwarding, which is what legal intercept and analytics pipelines usually need.

Transcoding is not free either, since it pulls in extra dependencies, which is why the build can switch it off. The Makefile computes a with_transcoding setting from the Debian packaging profiles, so a distribution build can be produced without the transcoding components.

Control interfaces: NG, TCP-NG, HTTP and WebSocket

The control plane is what the SIP proxy talks to, and rtpengine offers several ways to reach it. The project documents the NG Control Protocol and the TCP-NG Control Protocol, and the feature list adds HTTP, HTTPS and WebSocket interfaces with both WS and WSS. The traditional path is the datagram protocol on a Unix socket or a local port, and the HTTP and WebSocket interfaces exist for operators who want to query and drive the engine from a management plane or a web console rather than from Kamailio itself.

There is also limited support for using rtpengine as a drop-in replacement for Janus using the native Janus control protocol, with its own documentation page for that interface. Limited is the operative word, and if Janus interop is the reason you are looking at rtpengine, that page is the thing to read before anything else.

The utility programs that come with the project are installed alongside the daemon: rtpengine-get-table goes into the libexec directory, and rtpengine-ctl and rtpengine-ng-client are installed into the binary directory with their man pages. The CLI tool is what you use to talk to a running instance for administration and debugging, which matters because the documentation points at a troubleshooting overview as well as the usage pages.

Building the daemon and running it in a container

The README points to the online documentation for compiling and installing, and the repository carries the build machinery in the form of a Makefile, a debian/ directory for Debian packaging and a Dockerfile. The Dockerfile is a multi-stage build on debian:trixie-slim that installs the build dependencies, compiles the daemon and the recording daemon, and copies the stripped binaries into the runtime image. The runtime stage installs the shared libraries the daemon needs and sets:

dockerfile
VOLUME ["/rec"]
ENTRYPOINT ["/entrypoint.sh"]
CMD ["rtpengine"]
EXPOSE 23000-65535/udp 22222/udp

The exposed port range is the media port range the engine uses, and the 22222 range covers the control interface. The volume at /rec is where recorded media lands, and the entrypoint script is what prepares the environment before the daemon starts.

The build is also exercised by continuous integration, with separate workflows for code testing and for Debian packaging. A Makefile target named check builds the daemon and then runs the test suite in the t directory, and there are address sanitizer variants of the check, which is the sort of tooling you want in a component that parses attacker-influenced SDP and media from the network.

The boundaries: no ZRTP, Linux only, and features behind a module

The project lists what it does not support, and there is only one entry, but it is a significant one: ZRTP is not supported, although ZRTP passes through rtpengine just fine. In other words, a ZRTP call can be proxied without breaking, but the proxy has no support for the ZRTP handshake itself, and it cannot decrypt media that stays protected end to end. If your deployment depends on ZRTP key exchange semantics rather than merely on relaying the traffic, that boundary decides the question for you.

The second boundary is the module split described earlier. Running through Kamailio's rtpproxy module keeps you on the basic path, and the SDP, ICE and SRTP features arrive only with the rtpengine module or rtpproxy-ng. Operators migrating from an older mediaproxy setup should check that list before assuming a drop-in replacement gives them the same capabilities.

The third boundary is the platform. GNU/Linux only, and if you want the in-kernel path you also need a kernel module that matches your kernel, with a userspace fallback when that is not available. The project is under active development, with the last push on 2026-10-19 and three release tags in the mr26 series in the same week, and it is distributed under the GNU General Public License version 3.

Editorial conclusion

rtpengine fits operators who run Kamailio as their SIP proxy and need media handling that goes beyond simple RTP relaying, in particular because the SDP rewriting, ICE and SRTP features are only reachable through the rtpengine module or its rtpproxy-ng counterpart. It does not fit a deployment outside GNU/Linux, and it does not fit a call that requires ZRTP, since ZRTP is not implemented even though traffic passes through. Before adopting it, decide whether you run the rtpengine module or the older rtpproxy module, because the feature set differs sharply between the two, and check whether you want the kernel module, since the in-kernel path and the userspace path behave differently when the module is not loaded. The last push was on 2026-10-19 and the newest release is mr26.3.1.1.

Frequently asked questions

What is rtpengine and what is it used with?

rtpengine is the Sipwise media proxy for RTP and other UDP based media traffic, meant to be used with the Kamailio SIP proxy. The project describes it as a drop-in replacement for other RTP and media proxies, and it supports Kamailio's rtpproxy module as well as the older OpenSER mediaproxy module.

Which extra features require the rtpengine module in Kamailio?

Full SDP parsing and rewriting, non-standard RTCP ports, ICE support and SRTP support are only available when rtpengine is used through the rtpengine module or its older counterpart rtpproxy-ng.

Does rtpengine support ZRTP?

No. The project states that rtpengine does not support ZRTP, although ZRTP passes through it just fine, so the handshake itself cannot be handled by the proxy.

Does rtpengine have a kernel module, and what happens without it?

Yes, and the project lists automatic fallback to normal userspace operation if the kernel module is unavailable. The kernel module is built with the with-kernel target of the Makefile, and the in-kernel path is the low-latency, low-CPU option.

Can rtpengine record calls and transcode audio?

Yes. Recording of media streams is supported, decrypted if possible, and the transcoding list covers repacketization, DTMF event and in-band tone conversion, playback of pre-recorded streams, T.38 to PCM conversion, and comfort noise.

Which operating systems does rtpengine run on?

GNU/Linux is the only supported platform, according to the README. The project is licensed under the GNU General Public License version 3.

Official sources

  1. Issues
  2. License: GPL-3.0
  3. README
  4. Releases
  5. sipwise/rtpengine on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sipwise-rtpengine.svg)](https://hysenlabs.com/projects/sipwise-rtpengine)

Was this useful?