gst-plugins-bad, gstsrtpenc: encrypts packets with wrong roc after rollover counter resets.
When running an rtsp server/rtsp client session using SAVP and, by extension, SRTP, I've observed that a seek_simple() call on the client pipeline works correctly for a while, but after a few seconds to a few minutes (depending on the initial sequence number of the srtp stream), the call causes the media to appear to freeze. This does not happen using simple AVP.
I've observed this with gstreamer at 1.12.0, using libsrtp v1.6.0, but I believe that the issue exists with current master of both systems.
Analysis:
The libsrtp's srtp_dealloc() is invoked from the gstsrtpenc filter, through gst_srtp_enc_reset_no_lock, in several places. For example, it happens whenever the encoder receives the GST_EVENT_FLUSH_STOP sink event. When this occurs, srtp_dealloc() effectively resets the rollover counter (roc), for all streams in the session, to 0. If the roc was non-zero before srtp_dealloc(), this causes libsrtp's srtp_protect() function to encrypt the rtp payload using an incorrect roc of 0. The corresponding srtp_unprotect code, called from the gstsrtpdec filter, has no idea that the roc was reset, so it will attempt to decrpyt the payload using the correct, non-zero roc. Consequently, libsrtp's initial authentication check of the decryption process immediately fails, and the affected buffer, and all subsequent buffers, in the stream, are dropped.
Short attached python demonstration: server.py implements an rtsp server using the SAVP profile. It expects the full path to an mp4 file (not provided), having 1 H264 video stream and 1 aac audio stream, as its only argument. It serves the uri: rtsp://localhost:8554/test.
python server.py /path/to/some-mp4-file.mp4
client.py connects to this uri, plays it, and continually seeks, effectively loop the segment from 5 - 10 seconds. After a few seconds to a few minutes, the media freezes, and never recovers.
python client.py