Repository navigation
fix(dialog): a server in-dialog request with no route and no dial-back fails at once - #187
Merged
shenjinti merged 1 commit intoOct 8, 2026
Conversation
…k fails at once When the target locator fails, Transaction::send returns before the transaction enters Calling, so no timer is armed and nothing is ever sent. A server dialog then looks for a dial-back address; with none it went on to wait in tx.receive() for a response that cannot come, and BYE, re-INVITE, INFO and every other in-dialog request never returned. Return the send error in that case, as a client dialog already does. The dial-back retry is unchanged.
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 #186.
Problem
In
send_dialog_request(dialog.rs:1118), whentx.send()fails for a server dialog, the error is kept for the dial-back retry (line 1152). In practicesend()fails there only on aTargetLocatorerror (transaction.rs:274), which returns before the transaction entersCalling(line 339): nothing is sent and no timer is armed. With no dial-back address the code then waits intx.receive()(line 1239) on a transaction nothing will ever end, sobye(),reinvite(),info()and every other in-dialog request on that dialog never return.Fix
Remember the first send's error, and return it when there is no dial-back address (the "giving up after first send" branch). +7 lines in
src/dialog/dialog.rs.Unchanged on purpose:
Callingwith its timers armed.destination, so the locator is not consulted and lookup failures are left to the transaction's timers.Contract / coverage
What an in-dialog request on a server dialog does when its send fails:
ErrErr(<locator error>)at onceErrreceived/rport, or recorded from the connectionOk/ none (send succeeds), no connectionThe locator error is returned as is, the same error a client dialog gets. For
bye(),send_byethen transitions toTerminatedas for any other BYE error. The failure happens before any transport is chosen, so it is the same for UDP, TCP, TLS and WS; a server dialog with a live reliable affinity connection never consults the locator and is not affected.Tests
src/dialog/tests/test_connection_affinity.rs:test_server_request_without_route_fails_unless_dialed_back. A UDP endpoint with a locator that always fails, and a confirmed server dialog with no recorded connection:received/rport:info(),reinvite()andbye()each returnErrcontaining "no route" within 5 s;received/rportpointing at a UDP socket: the BYE reaches that socket (the dial-back after a failed first send, which no existing test covers).On
main(92cec74) it fails at the first request:Row by row (assertions turned into prints),
mainthen this PR:Checks
cargo test --features bench: 407 lib tests passed, 0 failed (406 onmainplus the new one), and 65 doc tests passed. Plaincargo testpasses too. The new test passed 20 runs in a row.cargo check --no-default-features --features platform-embassy: the same output as onmain.cargo clippy --features bench --all-targets: the same output as onmain, none in the changed code. (Onmainit stops at aclippy::never_looperror insrc/dialog/tests/test_refer_notify.rs:98, unrelated to this PR; with-A clippy::never_loopthe warnings are the same as onmain.)rustfmt --checkon the changed files: clean.