Skip to content

fix: CANCEL a dropped INVITE after its first provisional response (rebase of #168) - #171

Merged
shenjinti merged 1 commit into
mainfrom
fix/cancel-dropped-invite-on-first-provisional-rebased
Oct 6, 2026
Merged

shenjinti merged 1 commit into
mainfrom
fix/cancel-dropped-invite-on-first-provisional-rebased

Conversation

@shenjinti

Copy link
Copy Markdown
Contributor

Rebase of #168 by @tgeorge06, closes #166.

DialogGuardForUnconfirmed::drop no longer discards the INVITE transaction while the dialog is still Calling: the transaction is kept for one response window (64*T1). A provisional response triggers the existing CANCEL flow (RFC 3261 §9.1 — no CANCEL before a provisional); a 2xx that arrives with no provisional gets the end-to-end ACK and a BYE (RFC 3261 §13.2.2.4, §15, RFC 5407 §3.1.2 — same treatment as the #162 CANCEL/2xx race); a non-2xx final gets its ACK. Nothing is sent while no response has arrived.

Applied cleanly on the merged RFC 6026 state machine (#164/#169). Local verification: 380 lib + 65 doc tests green across repeated runs, fmt clean. The PR's #166 reproduction tests (180 → CANCEL; 200 → ACK+BYE; 486 → ACK) pass.

When the do_invite future is dropped before any provisional response,
the guard drops the INVITE transaction and sends nothing. The INVITE may
still have reached the callee: its 180 gets no CANCEL, and a 2xx is
neither ACKed nor ended, so the callee keeps ringing or answers into
dead air.

A CANCEL must not be sent before a provisional response; the UAC has to
wait for one and CANCEL then (RFC 3261 §9.1). Keep the INVITE
transaction, without retransmissions, until its first response (up to
64*T1): on a provisional, cancel it as a call dropped while ringing; on
a 2xx, ACK it and send a BYE; any other final response is ACKed by the
transaction. Terminated(UacCancel) is still reported at once, and
nothing is sent when no response arrives.
@shenjinti
shenjinti merged commit 8f8665e into main Oct 6, 2026
3 checks passed
shenjinti added a commit that referenced this pull request Oct 6, 2026
Ships this round on top of 0.7.0: proxy-mode auto_ack_2xx (#146/#172),
ACK CSeq routing (#155/#170/#172), digest auth_username (#153), dead
stream retirement (#161), remote-ack getter (#157), UAS ACK timeout →
BYE (#149/#169), RFC 6026 Accepted state + Timer L/M with documented
deviations (#164/#169), CANCEL/2xx race handling (#162/#171), in-dialog
Via transport (#163), flow-reuse and ACK hardening tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

An INVITE dropped before any response is never CANCELed, and its 2xx is never ACKed

2 participants