Conversation
…sent on DialogInner::make_request built the Via of every in-dialog request (BYE, re-INVITE, UPDATE, INFO, PRACK, ...) with get_via(None), i.e. from the endpoint's first listener. On an endpoint that binds UDP first and TCP as well, a dialog established over TCP therefore sent its BYE and re-INVITE over the TCP flow (affinity) or towards a ;transport=tcp route or remote target, but with a "Via: SIP/2.0/UDP" header. RFC 3261 §18.1.1 requires the Via to name the transport the request is sent over; peers may drop the mismatched request or answer it over UDP. The initial INVITE already picks the listener that matches the target transport (make_invite_request), and REGISTER does the same since 0c2dcc1. Do the same for in-dialog requests when the caller pins no address: take the transport of the affinity connection, else of the outbound proxy, else of the first route, else of the remote target, and use the matching listener. UDP, an unknown transport, or a target locator (which decides the transport at send time) keeps the previous behaviour. When a server dialog's request falls back to the dial-back address, its Via is rebuilt (same branch) for that address's transport.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #151.
Problem
DialogInner::make_requestbuilds the Via of every in-dialog request (BYE, re-INVITE, UPDATE, INFO, PRACK, …) withget_via(None), i.e. from the endpoint's first listener. On an endpoint that binds UDP first and TCP as well, a dialog established over TCP sends its BYE and re-INVITE over the TCP flow (RFC 5626 affinity) or towards a;transport=tcproute / remote target, but withVia: SIP/2.0/UDP …. Peers may drop the mismatched request or send the response over UDP.The initial INVITE already picks the listener matching the target transport (
make_invite_request), and REGISTER does the same since 0c2dcc1. In-dialog requests did not.Reproduction
New
src/dialog/tests/test_in_dialog_via.rs(real UDP + TCP listeners, raw TCP peer; the two failing cases use only the public API, the locator and dial-back guards use crate internals): a UAC endpoint with UDP bound first and TCP second establishes a call over TCP, then sends a re-INVITE and a BYE.;transport=tcp;lrRecord-Route: fails on main the same way;TargetLocatorconfigured: the Via stays the default (the locator decides the transport at send time) — passes on main and on this branch;Fix
When the caller pins no address,
make_requesttakes the transport of, in order: the affinity connection, the outbound proxy, the first route, the remote target — and uses the matching listener for the Via. UDP, an unknown transport, no matching listener, or a configured target locator keeps the previous behaviour. When a server dialog's request falls back to the dial-back address, its Via is rebuilt with the same branch for that address's transport.EndpointInner::locatorbecomespub(crate)so the dialog layer can see whether a locator is set. No public API change.Checks (on
main@ 3ea35cd)src/change reverted and the new test kept,cargo test --lib test_in_dialog_via→ 2 failed (a re-INVITE sent over TCP must carry a TCP Via, got: SIP/2.0/UDP …, for the reused-flow and the;transport=tcpRecord-Route cases); the locator and dial-back guards pass.cargo test→ 336 lib + 65 doc passed, 0 failed.rustfmt --checkclean on the changed files.EndpointInner::locatorbecomespub(crate)so the dialog layer can see whether a locator is configured).