RTP via ICE to public IP

From what I understand in SIP, the IP / port of RTP media is established by the c and media tags in SDP. When I see some of the logs, I see sent RTP packet (via ICE) to a public IP in a scenario where c in SDP points to private IP. Closest SIP that exposes public IP of the client is the (via) tag in the SIP message. What is the logic / hierarchy in which the RTP destination is decided by asterisk - as in when does it take from SDP c tag or when does it take the address from other SIP tags and what are the other tags that matter in this decisioning?

In some cases I see (via ICE) and in some cases I do not - with the same config - what are the conditions that decide whether via ICE is applied?

ICE[1] is a specification for declaring candidates (IP address and port - there may be multiple, and STUN can be used to determine a public one if behind NAT), using STUN packets back and forth to determine viable ones, and then using that for transport. If (via ICE) then that process succeeded. If not then it either didn’t succeed, or wasn’t used.

[1] https://tools.ietf.org/html/rfc5245

Thanks jcolp. In our case ice_support = yes, stunaddr is set. So if I do not see via ICE even then, does it mean that it could not get viable response from STUN server?

If you could also tell me what is the hierarchy of logic to select where the RTP packets are sent to, that will be great.

It means that ICE negotiation failed. It couldn’t find a viable path between the two sides. The logic is easy: If ICE is enabled and was successful then the resulting successful candidate pair is used, if ICE is disabled or it failed then the c= line is used unless the nat option is enabled in which case we will switch to the source of media after we receive it.

I’ll also add that ICE is a foundational part of WebRTC. If you are deploying WebRTC In any way you need to learn about it. WebRTC can, and will, fail.

How can I enable nat option in pjsip - I see nat=yes in sip.conf but no equivalent in pjsip.

As per the pjsip NAT documentation, we have set local_net, external_media_address and external_signaling_address in transport tag. In the browser and bandwidth.com endpoints we have direct_media=no, force_rport=yes and ice_support=yes. Is there something else we should be doing to enable nat in pjsip?

NAT options are documented on the wiki[1]. ICE has to work for WebRTC to work, though. It is required. The browser will not work without it succeeding. If that is failing then the NAT options will do nothing.

[1] https://wiki.asterisk.org/wiki/display/AST/Configuring+res_pjsip+to+work+through+NAT

We are using sipML5 on the browser side that uses WebRTC and does ICE negotiations. We have set that stun server to be used in ICE negotiations to ours. I see ICE returning srflx address on the browser side. So, technically if that is working on the browser side, as per our configuration things should work.

But what you are saying is that ICE can fail with WebRTC and if it does, there is no configuration on Asterisk that will help. Is that right?

That depends on network deployment and how exactly it has failed and why. Asterisk is only one part of the equation. The networks involved and the browser are the other part. They all work together. Asterisk can only do so much.

And as for your “things should work” that depends on the above. It would most likely work, but it may not work. It depends.

Ultimately my point is what I stated before - you have to learn the foundational parts of WebRTC if you are going to deploy it in any capacity. You can’t rely on this forum except for quick questions.

Will do.

In some of the cases, ICE negotiations are passed on the browser (see srflx address being set) but there is no audio. Struggling with this scenario to see why audio can be missed and what we are missing on the asterisk configuration to enable it.

Thanks for your valuable information - appreciate it.

So, decisioning logic for RTP address is below

  1. ice_support=yes, stunaddr = xx and ICE was able to negotiate - IP addresses are based on this
  2. nat option is set - local_net, external_media_address, external_signaling_address, direct_media=no, ice_support=yes, force_rport=yes, rtp_symmetric=yes -> In this case asterisk uses the source of the media once it receives
  3. Use c= in SDP

Thanks for the reply