RTPProxy v2.1.0 release
Version 2.1.0 of the RTPProxy brings 3+ years of improvements and fixes into our 2.0 version. The goal of this release has been to stabilize the new code and subsystems added in 2.0.
We heavily focused on developing a test framework that is based on high-level functional testing, and fixed the issues as we went. Basic testing is done in the RTPProxy repository itself.
For more advanced test scenarios that use external components, an additional repository has been created, sippy/voiptests. The code in that repository builds on our Python SIP stack and brings together many different versions of Kamailio, OpenSIPS, RTPProxy, Sippy B2BUA (Python) and our recent addition Sippy B2BUA (Go), to test that they can perform the basic functions a user might want them to perform. So if we (god forbid!) break our ability to work with any of those by making changes to our code, we are instantly notified. And in reverse, if any of those nice folks break (never happens! :) whatever we consider a basic level of support for the RTPProxy, we are aware of it and do our best to bring the issue to light.
See the GitHub release for downloads.
Notable Changes
Improved session latching
Session latching is more intelligent now. Instead of disallowing another latch within a certain interval after the previous one (UPDATE_WINDOW), another update is allowed at any time if the new packet meets all of the following criteria:
- It’s a valid RTP packet (as far as
rtp_packet_parse()can tell); - It has the same SSRC value that has been saved during the previous latching;
- Its sequence number is greater than the sequence number saved during the previous latching.
If any of (1)-(3) fails, the old behaviour of disallowing a new update within UPDATE_WINDOW after the previous one applies.
This fixes the issue when an endpoint generates 3 packets from the proper IP, but then switches to a completely different port and sticks with it for the rest of the session. Previously, the RTPProxy would latch to the first of those 3 packets and discard the rest as garbage.
The SSRC and initial sequence number are now logged while latching, which helps to identify the session in the log. (fb594fb)
Count ignored packets
RTPProxy now counts the number of ignored packets per session, i.e. packets coming from unrecognized IP addresses/ports. (0020e45)
New n modifier for U/L commands to allocate new RTP/RTCP ports
The new n modifier for the U/L commands forces a new pair of RTP/RTCP ports to be allocated and the old ones released. This is useful when a call route-advances or fails over to a new destination, where the failed route may still be sending superfluous traffic to the previous ports.
(8066e51)
Q command takes a list of counters to return
The Q (session stats query) command takes an optional list of specific counters to return. This allows fetching only the stats that are relevant, and makes Q quite usable for test suite runs.
Example: Q call-id from_tag to_tag rtpa_nsent rtpa_nrcvd rtpa_ndups rtpa_nlost
(273292b)
New stats counters to track overall packet loss
The rtpa_nsent, rtpa_nrcvd and rtpa_ndups counters allow monitoring overall packet loss in all streams going to the RTPProxy as a function of time.
(4f58b4a)
SSRC packet tracking
Work in progress (b1ac79e)
Python rtpp client
python/rtpp_query.py is a simple client that allows an interactive rtpp session. It’s also useful for injecting commands via stdin or from files.
(48a603e)
Notification socket wildcard
The notification wildcard %%CC_SELF%% can be used to automatically register notification sockets for callers of the U and L commands.
(83b09c9)
The SIGHUP signal shuts the RTPProxy down gracefully
Use SIGHUP instead of SIGTERM to shut down the proxy. The difference is that SIGTERM tries to tear down everything from the signal handler, while SIGHUP makes main() exit gracefully, so there is no race between main() posting an event into the rtpp_proc queue and rtpp_proc actually exiting.
(55438f1)
Improved test coverage
The RTPProxy test suite has grown, and covers all common use cases, including re-packetization.
New pertools/udp_contention tool to simulate UDP traffic
(3025a33)
z option of the U and L commands to set ptime
The ptime value provided with the z option of the U/L commands is saved into the session parameters, and used to request a specific packet size when the P (playback) command is received with “session” as the codec type. The playback (rtp_server) API has been extended to generate frames with a ptime other than the absolute minimum supported by the codec.
(644072c)
rtpp_streamdb module
rtpp_streamdb is a new module serving as a central in-memory DB for the RTP/RTCP streams. Instead of using the call-id as an indexing/lookup parameter, or passing around a pointer to the structure, it assigns a unique (within an rtpp_streamdb instance) 64-bit integer to each session, and provides a way to use that integer to quickly look up the session in question. It also integrates reference counting, and requires it in order to protect a session from being released while it’s being used by some part of the code. This allows us to untangle some global locking between the command and RTP forwarding threads.
The 64-bit id is used as a “weak reference” in the critical path of the code, i.e. mapping from the file descriptor into the session structure while doing I/O, so some performance assessment has been done to make sure the lookup performance is adequate for the task. A quick assessment shows some 6,000,000 lookups/sec on a single thread on an E3-1220 V2 @ 3.10GHz with a set of 4,000 sessions with the initial code. This should be enough for the current architecture, and there are several relatively easy ways to reduce the overhead at least 2-3 times further, by increasing the size of the hash table and/or in-lining/optimizing the hashing code. We expect the current code to do some 70-100k lookups/second at 1.5-2k sessions at most. (34c2911)
Refactored session handling (internal changes)
struct rtpp_session is now struct rtpp_session_obj, and sp->stream[N] is a pointer, not a sub-structure. This also deals with some API changes in the weakref code and elsewhere.
(29bb9e1)
Jitter tracking
RTPProxy now tracks jitter metrics as per Appendix A.8 of RFC 3550. (e545b08)
Dynamically loadable modules
Infrastructure to support dynamically loadable modules has been implemented, and it is used for the new Accounting CSV module. (6305000)
Accounting CSV module
An accounting module that outputs stats for each ended call into a CSV file. It outputs a CSV string of the metrics specified at start time, appending a new line to the CSV file at the end of each session. Operators would typically configure a log collection agent to process the metrics further. (cd5afbf)
IPv6 improvements and fixes
Lots of IPv6 bugs have been fixed, along with overall improvements and code unification, plus integration tests added to our test suite. (3e13d18)
Contributors
Thank you to our contributors!
- @sobomax