- C++ 88.7%
- CMake 4.9%
- Dockerfile 2.9%
- C 1.8%
- Shell 1.7%
| src | ||
| .dockerignore | ||
| .gitignore | ||
| .gitlab-ci.yml | ||
| build.sh | ||
| CMakeLists.txt | ||
| config.dist.ini | ||
| Dockerfile | ||
| README.md | ||
RTP monitor
This project contains code to monitor RTP multicast streams. Currently it compiles on both MacOS and Linux. On Linux, the binary will be statically linked to make redistribution between different distribution versions and such easier.
Purpose
When you're running an IPTV platform and distribute IPTV streams over multicast, at some point you're going to want to monitor loss on such streams in various parts of your network. When you're using RTP streams, this tool is useful for monitoring such loss.
Loss is measured by comparing the sequence numbers in the RTP headers. For each packet read, it registers the current RTP sequence number. If in the following packet, the sequence number is not previous+1, it is considered lost. The RTP sequence number is actually a 16 bit counter. Usually, the counter wraps within a minute and if that happens, it won't be considered as a lost packet.
The loss statistics will be sent to the configured statsd host.
Building rtpmon
Install cmake if not installed yet. Then run the following commands:
cmake .
cmake --build .
External dependencies
The following libraries need to be installed in order to build rtpmon:
Other code
In this code, external code has been included:
- statsd-client
- Darwin/apple pthread compatibility. This one is necessary for statsd-client and compiling/running on MacOS.
Configuration file format
rtpmon uses an ini configuration file to read the configuration from. Example:
[network]
interface=eth0
; Also possible:
;interface=1.2.3.4
[statsd]
host=192.168.0.1
port=8125
ident=rtphost.
[groups]
224.0.252.129:7258=discovery_channel
224.0.251.105:8210=national_geographic
Configuration items explained:
- network.interface: the interface name or IP address on which the multicast group joins need to be done.
- statsd.host: the statsd host to send the stats to
- statsd.port: the statsd port to send the stats to (only udp!)
- stats.ident: will be prepended to the statsd key.
- groups.mcastip:port: a list of multicast group addresses and the statsd identifier.
Statsd
As indicated in the previous paragraphs, stats will be sent to a statsd host. When loss occurs, a UDP statsd packet will be sent to the configured host and port.
For example, when loss occurs on a group identified by 'discovery_channel' as in the example configuration and the statsd ident is set to 'rtphost.', the amount of lost packets will be sent as:
rtphost.discovery_channel:50|c
So, rtpmon sends the stats as a counter.
Known bugs and limitations
Losing packets at startup
rtpmon first joins all configured groups, and then stats the libev event loop. As the group joining process takes some time, some packets may be considered lost in the startup phase.
Single threadedness
The amount of streams monitored is highly dependent on the CPU power. rtpmon is a single threaded process and so all data is read in one thread.
I've run the process on an 1.6 GHz Atoms processor with about 50 Mbits of multicast traffic and the CPU usage was below 40%.
In a later version I may split up the group joins in different processes or threads.
Apologies
In no way I consider myself a C++ programmer. Before this project I created a Python version which hit the CPU limit with less than 50 Mbit of multicast streams. So I needed the performance and decided it'd be a good idea to get up to speed with C++ and build this project with it.
So my apologies if this code contains anti-patterns or stupidities otherwise. I welcome any patches.