res_pjsip_sdp_rtp: Use auto-selected transport bind address for RTP#1848
res_pjsip_sdp_rtp: Use auto-selected transport bind address for RTP#1848arcivanov wants to merge 1 commit into
Conversation
|
Workflow Check completed successfully |
|
Workflow Check completed successfully |
|
Workflow Check failed |
|
This has been verified to work with the patch on top of 22.8.2. |
|
Workflow Check failed |
|
will do |
|
@gtjoseph why would IAX2 fail with SIP changes is beyond me |
|
When a PJSIP endpoint does not explicitly set `transport`, the RTP socket binds to `[::]` (or `0.0.0.0`) instead of the transport's bind address. This is because `create_rtp()` only resolves the transport via a sorcery lookup on `session->endpoint->transport`, which is empty when the transport is auto-selected. On a multi-homed host or NAT gateway whose transport binds to a specific interface, the wildcard-bound RTP socket causes the kernel to select a source IP that may conflict with conntrack DNAT entries for inbound RTP, causing MASQUERADE to silently remap the RTP source port. The remote end receives RTP from an unexpected port and drops it, resulting in one-way audio with no errors logged by Asterisk. When no explicit transport is configured and ICE is not in use, determine the transport type from the dialog's target URI and acquire the transport via `pjsip_tpmgr_acquire_transport()`. If the transport's bind address is a specific (non-wildcard) address, use it for RTP. When the transport binds to a wildcard address (0.0.0.0 or [::]), the RTP socket is left on the wildcard as well, matching the behaviour of the explicit-transport code path and preserving dual-stack operation. When ICE is enabled the wildcard bind is left as-is since ICE needs to discover candidates on all interfaces. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> UserNote: When a PJSIP endpoint does not have an explicit `transport` configured, ICE is disabled, and the auto-selected transport binds to a specific (non-wildcard) address, the RTP socket now binds to that address instead of the wildcard. This fixes one-way audio on multi-homed hosts and NAT gateways where the wildcard bind caused the kernel to select an incorrect source address for outbound RTP. Fixes: asterisk#1847
|
Workflow Check completed successfully |
|
Reconfirmed working on top of LTS 22.2.8. |
Pull Request Checklist Complete
|
Workflow CPCheck failed |
|
Workflow CPCheck completed successfully |
Significant changes since last approval.
|
FYI: Tested the patch with 22.9.0, no problems, no one-way audio: https://copr.fedorainfracloud.org/coprs/karellen/asterisk/ |
| pjsip_sip_uri *sip_uri; | ||
| pjsip_transport_type_e type; | ||
|
|
||
| sip_uri = pjsip_uri_get_uri(session->inv_session->dlg->target); |
There was a problem hiding this comment.
Has the case been tested with this where a SIP INVITE is sent to a hostname that does SRV/NAPTR and resolves down to multiple targets, and then goes from IPv6 to IPv4 as a result of failure/failover? Would that result in the SDP containing IPv6 despite being an IPv4 target? Or worse - do we update the SDP elsewhere under the assumption that it is wildcard, but it's not so audio would fail?
There was a problem hiding this comment.
I definitely didn't test that scenario. Let me see what I can do.
When a PJSIP endpoint does not explicitly set
transport, the RTPsocket binds to
[::](or0.0.0.0) instead of the transport's bindaddress. This is because
create_rtp()only resolves the transportvia a sorcery lookup on
session->endpoint->transport, which is emptywhen the transport is auto-selected.
On a multi-homed host or NAT gateway whose transport binds to a
specific interface, the wildcard-bound RTP socket causes the kernel to
select a source IP that may conflict with conntrack DNAT entries for
inbound RTP, causing MASQUERADE to silently remap the RTP source port.
The remote end receives RTP from an unexpected port and drops it,
resulting in one-way audio with no errors logged by Asterisk.
When no explicit transport is configured and ICE is not in use,
determine the transport type from the dialog's target URI and acquire
the transport via
pjsip_tpmgr_acquire_transport(). If thetransport's bind address is a specific (non-wildcard) address, use it
for RTP. When the transport binds to a wildcard address (0.0.0.0 or
[::]), the RTP socket is left on the wildcard as well, matching the
behaviour of the explicit-transport code path and preserving
dual-stack operation.
When ICE is enabled the wildcard bind is left as-is since ICE needs
to discover candidates on all interfaces.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
UserNote: When a PJSIP endpoint does not have an explicit
transportconfigured, ICE is disabled, and the auto-selected transport binds to
a specific (non-wildcard) address, the RTP socket now binds to that
address instead of the wildcard. This fixes one-way audio on
multi-homed hosts and NAT gateways where the wildcard bind caused the
kernel to select an incorrect source address for outbound RTP.
Fixes: #1847