cisco / libsrtp

Library for SRTP (Secure Realtime Transport Protocol)
Other
1.19k stars 472 forks source link

one-way-audio after atxfr/hold, because of resetting sequence numbers? #600

Closed denzs closed 2 years ago

denzs commented 2 years ago

We are using kamailio in combination with rtpengine (10.4.1.1+0~mr10.4.1.1) as an edge proxy to bridge between our SIP-clients and the pbx. The edge proxy terminates SIP with TLS (using client certificates) and bridges from SRTP (internet) to RTP (core).

We discovered that in some cases when using attended transfer the leg between A and C will have one-way audio. This means, the original caller is not able to hear the final call target. We could even reproduce it by just putting the caller on hold.

We tested using blink and linphone as sip clients, and when the problem occurs, the blink log contains:

[blink 155459] (5) b'2022-04-27 14:27:23.825     strm0x7f0c5c1a2648 Jitter buffer empty (prefetch=0), plc invoked'
[blink 155459] (5) b'2022-04-27 14:27:23.852     srtp0x7f0c5c1b0d50 Failed to unprotect SRTP, pkt size=182, err=replay check failed (index too old)'
[blink 155459] (5) b'2022-04-27 14:27:23.852     srtp0x7f0c5c1b0d50 Failed to unprotect SRTP, pkt size=182, err=replay check failed (index too old)'
[blink 155459] (5) b'2022-04-27 14:27:23.852     srtp0x7f0c5c1b0d50 Failed to unprotect SRTP, pkt size=182, err=replay check failed (index too old)'
[blink 155459] (5) b'2022-04-27 14:27:23.852     srtp0x7f0c5c1b0d50 Failed to unprotect SRTP, pkt size=182, err=replay check failed (index too old)'

After digging into the packets, it looks like rtpengine is resetting the sequence counter to 4095 while keeping the old ssrc. We would expect rtpengine to use another ssrc for the new session or at least continue increasing the existing sequence numbers..

seq_pseudo_reset )

After a while (guess: when the sequence is bigger than from the call before) media starts flowing again, respective it can be decoded/heard again..

The relevant part from our kamailio config looks like:

        if ($si == "UPSTREAM_IP") {
            xlog("L_INFO", "MY_LOG FIX_MEDIA $rm/$rs from $si to $du : Core->User\n");
            rtpengine_manage("direction=core direction=access ICE=force trust-address replace-origin replace-session-connection SRTP");
            return;
        }
        if ($proto == "tls") {
            xlog("L_INFO", "MY_LOG FIX_MEDIA $rm/$rs from $si to $du : User->Core\n");
            rtpengine_manage("direction=access direction=core port-latching ICE=remove trust-address replace-origin replace-session-connection RTP/AVP SDES-off");
            return;
        }

A corresponding rtpengine log is attached.

Any hints on this would be really appreacited! If we need to provide any further information, please let us know :)

c27b9d90-1474-47ea-ac01-7ab0793577ea.rtpengine.log

denzs commented 2 years ago

sry wrong project :(