[Freeswitch-users] [RTPproxy] Handling multiple re invites from media server
sobomax at sippysoft.com
Wed Aug 12 17:59:05 UTC 2020
Hi Babak, sorry for the late reply. I've been quite busy here lately.
Your setup seems very complicated, I am not sure if that's for a reason or
something that "just happened". One immediate problem is that the call is
proxied twice - even before FS is switched in, the RTP already takes 4 hops:
RTP in, ssrc=0x3a8d7fbe: 205.1:4008 -> 205.34:20042/20012 ->
205.34:20068/20020 -> 205.1:4006
RTP out, ssrc=0x339a275d: 205.1:4006 -> 205.34:20020/20068 ->
205.34:20012/20042 -> 205.1:4008
Two hops in the middle is basically RTPPproxy sending packets to itself
between call legs. This of course increases delay and jitter, as well as
doubles the work for the RTPProxy. It is a good practice to only pin media
once in general, either when the inbound leg comes in or when outbound leg
Now, a little bit later FS comes in and tries to update both legs to make
the session like the following. Square brackets indicate the part where
packets don't reach:
RTP in, ssrc=0xf7229438: 205.129:18804 -> 205.134:20068 [/20020 ->
RTP out, ssrc=0xf71e7468: 205.129:17100 -> 205.134:20012 [/20042 ->
The reason this does not really work I think is that the RTPProxy
historically and by design treats any IP/port in the re-INVITE with utter
suspicion, more like a hint than actual direction by default. This is
because it's designed to provide NAT traversal in the majority of cases.
Including the weird case of either side to "float" to the new IP:port
without any notification from the signalling end (i.e. roaming between hot
So it normally expects the original sender to stop sending packets before
it can fully switch over to the new IP/port from the re-INVITE. In your
case, however, since original endpoints are shielded from the port change
in re-INVITE by the virtue of having rtpproxy essentially in the middle of
the call twice on both sides (i.e. you are trying to go from
UA1<->RTPP(1)<->RTPP(2)<->UA2 to UA1<->RTPP(1)<->FS<->RTPP(2)<->UA2 and
then back when the playback is done) , both sessions in the RTPProxy keep
receiving packets from their originally latched sources, i.e. RTPP(1)
continues receiving packets from RTPP(2) and new stream comes from FS and
RTPP(2) keeps receiving packets from RTPP(1) and FS starts sending, that
re-latch never happens on neither end. On top of that, the stream generated
by the FS has (obviously) different SSRC, so again it makes RTPProxy a bit
suspicious if it's some kind of foul play (google "RTP Bleed" attack) and
very reluctant to switch over.
I cannot tell for sure since I am not familiar with its logic and defaults,
but I suspect the rtpengine has none of those features, which may explain
In any case the situation ends up in a stalemate: both RTPP sessions keep
happily receiving/sending packets from each other, totally ignoring that
additional streams from the FS.
Now, as I said there at least one solution to your particular problem, in
fact more like at least 4:
1. Since having two sessions on both ends is wasteful and inefficient,
consider straightening that out. So instead make your RTP path look like
Then when FS comes in and triggers re-invite on both legs, the UA1 would be
shielded from that port change, while UA2 won't (since there is no RTPProxy
on the outbound leg). As a result UA2 would start sending RTP directly to
FS (as opposed to the RTPProxy), the RTPProxy would stop receiving that
traffic from UA2 on its outbound "leg" and latch FS instead, resulting in a
proper RTP path being:
This may or not may be solution to your problem. If you still want for
whatever reason shield UA2 from getting RTP traffic directly from the FS,
then my next pick is:
2) Only create RTPP(2) session when FS wants to talk and abandon when it
stops. This can be accomplished by enabling OpenSIPS on inbound call leg to
append a:nortpproxy=yes attribute (default behavior) and OpenSIPS on the
outbound leg obey it. Then original session would look like expected, i.e.:
Then when FS intervenes, neither of re-INVITEs has that attribute, so the
new RTPP session on outbound leg is allocated and the chain becomes:
RTPP(1) stops receiving RTP from the UA2 and happily re-latches to FS
Then again after FS drops out that should reduce the RTP flow back to the
following and RTPP(2) session eventually timeouts:
3) Disable any NAT compensation in the RTPProxy in general. Bit of a
hevy-weight, but if you expect both UA1 and UA2 to provide trustworthy
IP:port in the SDP i.e. if you are only concerned with the topology hiding
and don't have NAT in or out it might be the easiest way to go. This should
make RTPProxy obey any IP:port combinations it gets from OpenSIPS verbatim.
There was functionality for that in RTPProxy, however turns out it was not
exposed, so I've just added a new option for that --force_asymmetric (
4) Disable NAT compensation for the RTP "leg" that goes to/fro FS. This one
might be a bit trickier to implement - you'd have to have a logic in both
request route and response route to add "A" flag into (re-)INVITE that goes
from FS and 200/183 that it generates.
Hope it helps. 😀
On Tue, Aug 11, 2020 at 5:22 AM Babak Yakhchali <babak.yakhchali at gmail.com>
> The same configuration worked with rtp-engine
> On Tue, Aug 11, 2020 at 12:58 PM Babak Yakhchali <
> babak.yakhchali at gmail.com> wrote:
>> I tried the latest rtpproxy from github and prompt is played
>> successfully. But after the prompt is played, freeswitch sends two
>> re-invites to clients to remove itself from the rtp path. In these
>> re-invties freeswitch places initial rtpproxy generated ports for clients.
>> Everything is logically ok but when I capture rtp traffic I can see that
>> rtpproxy is still sending rtp packets to freeswitch which is wrong. It
>> should be noted that after the last re-invites freeswitch stops sending rtp
>> to rtpproxy so there will be no new re-latching.
>> On Tue, Jul 21, 2020 at 5:09 PM Babak Yakhchali <
>> babak.yakhchali at gmail.com> wrote:
>>> I'm trying to handle a mid call playback using opensips with rtpproxy on
>>> the same box and a freeswith server as media server like this:
>>> client1 and client2 <=> opensips (rtpproxy on same box) <=> freeswitch
>>> [image: arch.jpg]
>>> At start freeswitch is involved in signaling but not in the rtp session
>>> and rtp goes through rtpproxy to clients. After 3 seconds freeswitch sends
>>> re-invites to come to the rtp session and play the sound file to both
>>> clients and after playback sends re-invites to leave the rtp path.
>>> All sip signalling is done correctly and the sound file is played
>>> successfully(as I can see in freeswitch console and analyzing captures),
>>> but nothing is heard on clients.
>>> Can rtpproxy handle such a scenario?
>>> opensips version is 2.4 git branch
>>> rtpproxy version is 2.2.alpha.61e74c0
>>> I've attached my opensips config with rtpproxy log and packet capture
>>> You received this message because you are subscribed to the Google
>>> Groups "rtpproxy" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to rtpproxy+unsubscribe at googlegroups.com.
>>> To view this discussion on the web visit
> You received this message because you are subscribed to the Google Groups
> "rtpproxy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rtpproxy+unsubscribe at googlegroups.com.
> To view this discussion on the web visit
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the FreeSWITCH-users