[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:
[my_transport]
type = transport
protocol = udp
bind = 0.0.0.0:5060
[sipp]
type = endpoint
media_address = 127.0.0.1
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 10.24.20.249.
SIPp places a call into Asterisk, sending its INVITE request from
127.0.0.2:5061 to 127.0.0.1:5060.
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
sip:10.24.20.249:5060.
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 10.24.20.249.
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 127.0.0.1, but Asterisk is listening for media on
10.24.20.249. 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
behavior.
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 127.0.0.2 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