[asterisk-dev] Rules for binding with regards to RTP

Mark Michelson mmichelson at digium.com
Wed Dec 10 15:05:34 CST 2014

On 12/09/2014 12:42 PM, Mark Michelson wrote:
> <snip>
> 5. If we are responding to a media_offer, and there is either no 
> configured media_address on the endpoint or the media_address is of a 
> different IP address family than the offerer's media address for the 
> given stream, and the signaling address for the call is of the same 
> address family as the offerer's media address for the given stream, 
> then we will bind the RTP stream to the signaling address for the call.

This is proving to be more difficult than I had anticipated when the 
signaling address is itself a wildcard IP address. Let's revisit the 
situation that the original e-mail was about, but change the 
configuration to have a wildcard address for the transport. Let's say I 
have the following configuration:
type = transport
protocol = udp
bind =

type = endpoint
media_address =

Let's walk through what happens here.

When creating a UDP transport in PJSIP and binding a wildcard IP address 
to it, PJSIP does some immediate magic to determine a single published 
address for the transport. In my case, PJSIP always chooses to publish 
the address

SIPp places a call into Asterisk, sending its INVITE request from to

The INVITE arrives into Asterisk, and Asterisk needs to create a new UAS 
dialog. Asterisk determines the local contact URI for the dialog based 
on the IP address of the transport on which the INVITE arrived. In this 
case, the transport on which the INVITE arrived is the PJSIP UDP 
transport we created based on the my_transport settings. This means 
that, due to the previous determination of a published address on the 
transport, Asterisk tells the UAS dialog to use the contact URI 

Now comes the time when we need to determine what IP address to bind RTP 
to. At the point that we are handling an incoming SDP stream, the best 
we can do to determine a signaling address is to examine the local 
contact URI of the dialog. After all, that's where SIP traffic is to be 
sent, so it makes sense that that would be the signaling address, right? 
So going by the cited rule, we would bind the RTP stream to

The problem now is that because of the media_address option, the 200 OK 
Asterisk sends to SIPp will contain SDP instructing SIPp to send RTP 
traffic to, but Asterisk is listening for media on This will result in one-way audio since Asterisk will not 
be reading the audio sent by SIPp.

With that media_address, you'd have a one-way audio problem, but what if 
you didn't have a media_address specified at all? Then you might have 
two-way audio, but you'd have a less-than-ideal situation where you are 
communicating across different interfaces. In a test environment, this 
doesn't matter so much, but in a production environment, this could be 
very bad. And if anything, this is a step backwards compared to previous 

So why can't I get a signaling address other than the dialog's contact 
address? The simple reason is that nothing better is actually available 
to me. I can't see what the transport is actually bound to because I 
don't have access to the transport at this point [1]. I can't see what 
address the incoming INVITE was sent to because that isn't stored 
anywhere either.

"But Mark," you may say, "I just set this up and when I did, the 200 OK 
that Asterisk sends to SIPp has in the Contact header, not my 
externally-facing IP address!" This is because the res_pjsip_multihomed 
module modifies the Contact header because the transport in use on the 
outbound packet was bound to a wildcard address. As I said before, I 
don't have access to the transport when handling the incoming SDP offer, 
so I can't do anything similar. Plus, even if I did, it would have the 
exact same effect as if I had bound RTP to a wildcard address, which was 
what I was trying to avoid in the first place!

So because I lack the following information in the res_pjsip_sdp_rtp code:

* The transport in use for the dialog
* The IP address on which the INVITE was received

I can't make a reasonable assumption for an address to bind on other 
than a wildcard address. Unless someone can point me to something I'm 
missing that would allow for me to bind to a more appropriate address 
than a wildcard, please let me know.

[1] pjsip_dialog has a pjsip_tpselector on it, but its type is 
PJSIP_TPSELECTOR_NONE at the point where we are handling the incoming 
SDP offer.

More information about the asterisk-dev mailing list