Skip to main content

sipx_call/
rel.rs

1//! Reliable provisional responses in a live call (RFC 3262).
2//!
3//! The state machine and the header types are in [`sipx_sip::rel`], which has no clock. This is
4//! the half that does: sending PRACK when a numbered provisional arrives, and — on the
5//! answering side — retransmitting a `180 Ringing` until the caller says it got there.
6
7use std::net::IpAddr;
8use std::sync::Arc;
9use std::time::Duration;
10
11use bytes::Bytes;
12use sipx_sdp::{Capabilities, Direction, SessionDescription};
13use sipx_sip::build::{RequestBuilder, ResponseBuilder};
14use sipx_sip::rel::{self, Numbering, Offered, RAck, RSeq, Reliability};
15use sipx_sip::transaction::TransactionKey;
16use sipx_sip::update;
17use sipx_sip::{HeaderName, Method, Response, StatusCode};
18use sipx_transport::{Handle, Incoming, Target};
19
20use crate::call::{Early, EarlyOffer, MediaAddress};
21use crate::dialog::{Dialog, strip_header_params};
22use crate::error::{Error, Result};
23use crate::media_policy::{Codecs, MediaPolicy};
24
25/// RFC 3261 §17 T1, the round-trip estimate every retransmission schedule is built from.
26const T1: Duration = Duration::from_millis(500);
27
28/// §3: "If a reliable provisional response is retransmitted for 64*T1 seconds without reception
29/// of a corresponding PRACK, the UAS SHOULD reject the original request."
30const GIVE_UP: Duration = Duration::from_secs(32);
31
32/// The body a PRACK must carry, if any (RFC 3262 §5).
33///
34/// Only one case calls for one: the INVITE carried no offer, so the first reliable provisional
35/// had to carry it, and "the UAC ... MUST generate an answer in the PRACK". When the INVITE did
36/// offer, whatever SDP comes back in the provisional is the *answer* to it, and putting a
37/// second description in the PRACK would start a renegotiation nobody asked for.
38#[must_use]
39pub fn prack_body(
40    invite_offered: bool,
41    provisional_body: &[u8],
42    capabilities: &Capabilities,
43) -> Option<SessionDescription> {
44    if invite_offered || provisional_body.is_empty() {
45        return None;
46    }
47    let offer = sipx_sdp::parse(&String::from_utf8_lossy(provisional_body)).ok()?;
48    Some(sipx_sdp::answer(&offer, capabilities))
49}
50
51/// Whether a provisional response was sent reliably, and its sequence number.
52///
53/// §4: a `100 Trying` is hop-by-hop, so a `Require: 100rel` on one "MUST be ignored". Checking
54/// the status here rather than at the call site is what stops a proxy's `100` from being
55/// `PRACK`ed at a UAS that never numbered it.
56#[must_use]
57pub fn reliable_sequence(response: &Response) -> Option<u32> {
58    const TRYING: u16 = 100;
59    if response.status.code() <= TRYING || response.status.is_final() {
60        return None;
61    }
62    if !response
63        .headers
64        .get_all(&HeaderName::Require)
65        .any(|header| contains_100rel(&header.value()))
66    {
67        return None;
68    }
69    response
70        .headers
71        .typed::<RSeq>()
72        .and_then(std::result::Result::ok)
73        .map(|seq| seq.0)
74}
75
76fn contains_100rel(value: &[u8]) -> bool {
77    value.split(|&b| b == b',').any(|tag| {
78        let tag: &[u8] = tag
79            .iter()
80            .position(|b| !b.is_ascii_whitespace())
81            .map_or(&[][..], |start| tag.get(start..).unwrap_or_default());
82        let end = tag
83            .iter()
84            .rposition(|b| !b.is_ascii_whitespace())
85            .map_or(0, |last| last + 1);
86        tag.get(..end)
87            .unwrap_or_default()
88            .eq_ignore_ascii_case(rel::OPTION_TAG.as_bytes())
89    })
90}
91
92/// Send the PRACK acknowledging a reliable provisional (RFC 3262 §4).
93///
94/// It goes inside the dialog the provisional established — which may be a dialog that did not
95/// exist a moment ago, since §4 says "the provisional response MUST establish a dialog if one is
96/// not yet created". Sending it outside would reach a UAS that has no matching transaction.
97pub async fn send_prack(
98    endpoint: &Handle,
99    dialog: &mut Dialog,
100    target: &Target,
101    rseq: u32,
102    invite_cseq: u32,
103    body: Option<SessionDescription>,
104) -> Result<()> {
105    let (local, remote) = dialog.local_and_remote();
106    let cseq = dialog.next_cseq();
107    let (uri, routes) = dialog.request_target();
108    let ack = RAck {
109        rseq,
110        cseq: invite_cseq,
111        method: Method::Invite.as_bytes().to_vec(),
112    };
113
114    let mut builder = RequestBuilder::new(Method::Prack, uri)
115        .header(HeaderName::To, Bytes::from(remote))?
116        .header(HeaderName::From, Bytes::from(local))?
117        .header(HeaderName::CallId, Bytes::from(dialog.id.call_id.clone()))?
118        .cseq(cseq, &Method::Prack)?
119        .header(HeaderName::RAck, Bytes::from(ack.to_string()))?
120        .max_forwards(70);
121    if let Some(answer) = body {
122        builder = builder
123            .header(
124                HeaderName::ContentType,
125                Bytes::from_static(b"application/sdp"),
126            )?
127            .body(Bytes::from(answer.to_string_sdp()));
128    }
129
130    let request = crate::call::add_routes(builder, &routes)?.build();
131    let mut responses = endpoint.send(request, target.clone()).await?;
132    // §3: a matching PRACK "MUST be responded to with a 2xx". A failure here is worth
133    // surfacing rather than swallowing — a 481 means the UAS has no record of the provisional
134    // we just acknowledged, so the two sides disagree about what has happened.
135    match responses.final_response().await {
136        Some(response) if response.status.is_success() => Ok(()),
137        Some(response) => Err(Error::Rejected {
138            status: response.status.code(),
139            reason: String::from_utf8_lossy(&response.reason).into_owned(),
140        }),
141        None => Err(Error::NoResponse),
142    }
143}
144
145/// An invitation that has been rung but not yet answered.
146///
147/// Holding this is what makes a reliable `180` possible at all: the response has to be
148/// retransmitted until a PRACK arrives, and something has to own the sequence number and the
149/// early dialog's tag in the meantime.
150#[derive(Debug)]
151pub struct Ringing {
152    endpoint: Handle,
153    tag: String,
154    invite_cseq: u32,
155    numbering: Numbering,
156    reliable: bool,
157    stop: Option<Arc<tokio::sync::Notify>>,
158    acknowledged: bool,
159    /// The early dialog the provisional created (RFC 3261 §12.1.1).
160    ///
161    /// `None` only when the INVITE carried no usable `Contact`, which is a caller we could not
162    /// address anyway. It is held here rather than rebuilt at answer time because an UPDATE
163    /// arriving in the meantime numbers itself against it, and a dialog rebuilt afterwards
164    /// would have forgotten that.
165    dialog: Option<Dialog>,
166    /// Where in-dialog requests go while the invitation is still ringing.
167    target: Target,
168    /// Whose turn it is to offer and to answer (RFC 3311 §5, RFC 3264).
169    negotiation: update::Negotiation,
170    /// Whether the caller's `Allow` listed UPDATE (RFC 3311 §4).
171    peer_allows_update: bool,
172    /// The session this side answered in the provisional, when it answered one.
173    ///
174    /// Its presence is exactly the difference between a dialog whose session may be
175    /// renegotiated before it is answered and one whose may not — see [`ring_early`].
176    early: Option<Early>,
177    /// An offer sent in the reliable provisional, until its answer arrives in PRACK.
178    early_offer: Option<Box<EarlyOffer>>,
179}
180
181impl Ringing {
182    /// The `To` tag this side chose, which the eventual 200 must reuse.
183    ///
184    /// A provisional that establishes a dialog has already told the caller what the remote tag
185    /// is (RFC 3261 §12.1.1). Answering later with a *different* tag creates a second dialog,
186    /// and the caller ACKs the one it knows about while this side waits for an ACK to the other.
187    #[must_use]
188    pub fn tag(&self) -> &str {
189        &self.tag
190    }
191
192    /// Whether the provisional was sent reliably.
193    #[must_use]
194    pub fn is_reliable(&self) -> bool {
195        self.reliable
196    }
197
198    /// Whether the caller has acknowledged it.
199    #[must_use]
200    pub fn is_acknowledged(&self) -> bool {
201        self.acknowledged || !self.reliable
202    }
203
204    /// Whether the caller's `Allow` listed UPDATE (RFC 3311 §4).
205    #[must_use]
206    pub fn peer_allows_update(&self) -> bool {
207        self.peer_allows_update
208    }
209
210    /// Whether the session was described *and answered* before the call was accepted.
211    ///
212    /// True only after [`ring_early`]. It is what makes an offer-carrying UPDATE legal in this
213    /// dialog: RFC 3311 §5.1 will not let one out while an offer/answer exchange is open, and
214    /// before the 200 the only way to close one is RFC 3262 §5's answer in a reliable
215    /// provisional.
216    #[must_use]
217    pub fn has_early_session(&self) -> bool {
218        self.early.is_some()
219    }
220
221    /// The running media session described by the reliable provisional, when there is one.
222    ///
223    /// [`ring_early`] starts it before returning, so an answerer can send an announcement and
224    /// receive caller audio before the INVITE is accepted. [`crate::answer_early`] moves this
225    /// exact session into the resulting [`crate::Call`].
226    #[must_use]
227    pub fn media(&self) -> Option<&sipx_media::MediaSession> {
228        self.early.as_ref().map(|early| &early.media)
229    }
230
231    /// Hand the early session over to the [`Call`](crate::Call) that is taking its place.
232    ///
233    /// Empties this ringing rather than consuming it, because it still owns the retransmission
234    /// of the provisional and must go on owning it until it is dropped.
235    pub(crate) fn take_early(&mut self) -> Result<(Early, Dialog, update::Negotiation, bool)> {
236        let early = self.early.take().ok_or(Error::NoEarlySession)?;
237        let dialog = self.dialog.take().ok_or(Error::NoDialog)?;
238        Ok((early, dialog, self.negotiation, self.peer_allows_update))
239    }
240
241    /// The early dialog's mutable parts, borrowed for one UPDATE.
242    ///
243    /// `None` when the INVITE carried no usable `Contact` and no dialog was ever built, which is
244    /// a peer there is nothing to answer *to*.
245    fn early_dialog(&mut self) -> Option<crate::update::EarlyDialog<'_>> {
246        Some(crate::update::EarlyDialog {
247            endpoint: &self.endpoint,
248            dialog: self.dialog.as_mut()?,
249            target: &mut self.target,
250            negotiation: &mut self.negotiation,
251            peer_allows: &mut self.peer_allows_update,
252            early: self.early.as_mut(),
253        })
254    }
255
256    /// Answer an UPDATE that arrived in the early dialog (RFC 3311 §5.2).
257    ///
258    /// Returns whether it was one for this dialog. The rules are the same code the *calling*
259    /// side runs from [`Dialing::on_update`](crate::Dialing::on_update): §5.1 makes UPDATE
260    /// something either end may send, so a second copy of §5.2 here would be a second place for
261    /// it to drift.
262    ///
263    /// An offer arriving before this side has answered the INVITE's own — that is, after
264    /// [`ring`] rather than [`ring_early`] — draws the **500** of §5.2's third rule. Not 491:
265    /// nothing of ours is outstanding, the peer is simply early, and telling it otherwise would
266    /// send it into a back-off instead of the retry that will work.
267    pub async fn on_update(&mut self, incoming: &Incoming) -> Result<bool> {
268        let Some(early) = self.early_dialog() else {
269            return Ok(false);
270        };
271        crate::update::receive(early, incoming).await
272    }
273
274    /// Renegotiate the early session from this side (RFC 3311 §5.1).
275    ///
276    /// Requires [`ring_early`]: without an answer already given to the INVITE's offer this side
277    /// owes one, and RFC 3264 forbids a second offer while one is open — the far end would
278    /// answer 500 and be right to.
279    pub async fn update(&mut self, direction: Direction) -> Result<()> {
280        // `NoDialog` for a missing early session as well as for a missing dialog, which is this
281        // method's existing contract. `crate::update::offer` distinguishes the two, and the
282        // caller's handle takes the sharper error; changing what an application already matches
283        // on is not something a story about the *other* role should do on its way past.
284        if self.early.is_none() {
285            return Err(Error::NoDialog);
286        }
287        let Some(early) = self.early_dialog() else {
288            return Err(Error::NoDialog);
289        };
290        crate::update::offer(early, direction).await
291    }
292
293    /// Handle an in-dialog PRACK. Returns whether it was one for this ringing.
294    ///
295    /// §3: a PRACK that matches is answered 2xx and stops the retransmissions; one that matches
296    /// nothing "MUST" be answered 481. Answering 481 matters more than it looks — it tells a
297    /// caller that acknowledged something we never sent that the two sides disagree, instead of
298    /// leaving its PRACK transaction to time out looking like a lost packet.
299    pub async fn on_prack(&mut self, incoming: &Incoming) -> Result<bool> {
300        if incoming.request.method != Method::Prack {
301            return Ok(false);
302        }
303        let ack = incoming
304            .request
305            .headers
306            .typed::<RAck>()
307            .and_then(std::result::Result::ok);
308
309        let matched = ack.is_some_and(|ack| {
310            self.numbering
311                .acknowledge(&ack, self.invite_cseq, Method::Invite.as_bytes())
312        });
313
314        let negotiated = if matched {
315            match self.early_offer.take() {
316                Some(offered) => {
317                    let answer = sipx_sdp::parse(&String::from_utf8_lossy(incoming.request.body()))
318                        .map_err(|error| Error::Sdp(error.to_string()));
319                    match answer {
320                        Ok(answer) => match offered.settle(&answer).await {
321                            Ok(early) => {
322                                self.early = Some(early);
323                                self.negotiation.received_answer();
324                                Ok(())
325                            }
326                            Err(error) => Err(error),
327                        },
328                        Err(error) => Err(error),
329                    }
330                }
331                None => Ok(()),
332            }
333        } else {
334            Ok(())
335        };
336        let (status, reason) = match (&negotiated, matched) {
337            (Err(_), true) => (488, "Not Acceptable Here"),
338            (_, true) => (200, "OK"),
339            (_, false) => (481, "Call/Transaction Does Not Exist"),
340        };
341        let code = StatusCode::new(status)
342            .ok_or_else(|| Error::Sdp("unreachable: literal status".to_owned()))?;
343        let response = ResponseBuilder::to_request(&incoming.request, code, reason)?.build();
344        self.endpoint.respond(&incoming.key, response).await?;
345
346        if matched {
347            self.acknowledged = true;
348            if let Some(stop) = self.stop.take() {
349                stop.notify_waiters();
350            }
351        }
352        negotiated?;
353        Ok(matched)
354    }
355}
356
357impl Drop for Ringing {
358    fn drop(&mut self) {
359        // Retransmissions outlive this value otherwise, and would go on resending a `180` for a
360        // call that has since been answered or abandoned.
361        if let Some(stop) = self.stop.take() {
362            stop.notify_waiters();
363        }
364    }
365}
366
367/// Ring: send a provisional response, reliably if RFC 3262 says to.
368///
369/// `enabled` is local policy for 100rel. A caller that put `100rel` in `Require` and is told no
370/// gets a `420 Bad Extension` naming the tag (§3) and this returns an error — refusing plainly
371/// beats accepting and then never numbering anything, which the caller cannot tell from a dead
372/// network.
373pub async fn ring(
374    endpoint: &Handle,
375    incoming: &Incoming,
376    status: u16,
377    reason: &'static str,
378    enabled: bool,
379) -> Result<Ringing> {
380    ring_with(endpoint, incoming, status, reason, enabled, None).await
381}
382
383/// Ring with an SDP offer in a reliable provisional response.
384///
385/// The initial INVITE must be offerless. Its caller owes the answer in PRACK (RFC 3262 section
386/// 5), and [`Ringing::on_prack`] does not acknowledge the negotiation until that answer parses and
387/// establishes the early session.
388pub async fn ring_offer_early(
389    endpoint: &Handle,
390    incoming: &Incoming,
391    status: u16,
392    reason: &'static str,
393    media_address: IpAddr,
394    direction: Direction,
395) -> Result<Ringing> {
396    ring_offer_early_with_policy(
397        endpoint,
398        incoming,
399        status,
400        reason,
401        media_address,
402        direction,
403        MediaPolicy::default(),
404    )
405    .await
406}
407
408/// [`ring_offer_early`], using one coherent codec, security and ICE policy.
409pub async fn ring_offer_early_with_policy(
410    endpoint: &Handle,
411    incoming: &Incoming,
412    status: u16,
413    reason: &'static str,
414    media_address: IpAddr,
415    direction: Direction,
416    policy: MediaPolicy,
417) -> Result<Ringing> {
418    ring_offer_early_with_policy_at(
419        endpoint,
420        incoming,
421        status,
422        reason,
423        MediaAddress::new(media_address),
424        direction,
425        policy,
426    )
427    .await
428}
429
430/// [`ring_offer_early_with_policy`] with independent advertised and bound media addresses.
431pub async fn ring_offer_early_with_policy_at(
432    endpoint: &Handle,
433    incoming: &Incoming,
434    status: u16,
435    reason: &'static str,
436    media_address: MediaAddress,
437    direction: Direction,
438    policy: MediaPolicy,
439) -> Result<Ringing> {
440    if !incoming.request.body().is_empty() {
441        return Err(Error::Rejected {
442            status: 500,
443            reason: "the INVITE already carries an offer".to_owned(),
444        });
445    }
446    if !Offered::in_request(&incoming.request).supported {
447        return Err(Error::Rejected {
448            status: 421,
449            reason: "the caller did not offer 100rel, so no offer may go in a provisional"
450                .to_owned(),
451        });
452    }
453    let offered = EarlyOffer::bind(
454        media_address,
455        incoming.transport.is_secure(),
456        direction,
457        policy,
458    )
459    .await?;
460    ring_with(
461        endpoint,
462        incoming,
463        status,
464        reason,
465        true,
466        Some(ProvisionalSession::Offer(Box::new(offered))),
467    )
468    .await
469}
470
471/// Ring, and answer the INVITE's offer in the provisional (RFC 3262 §5 + RFC 3311 §4).
472///
473/// This is what makes an early dialog *renegotiable*. RFC 3311 §5.1 will not let an UPDATE
474/// carry an offer while an offer/answer exchange is open, so a session described in the INVITE
475/// cannot be changed before the 200 unless its answer has already gone back — and before the
476/// 200 there is exactly one place to put an answer: a reliable provisional response.
477///
478/// 100rel is therefore not optional here and there is no flag to switch it off. RFC 3262 §5
479/// forbids an answer in an unreliable provisional outright, and one sent anyway can be lost
480/// without either side noticing, leaving them disagreeing about which description is in force.
481/// A caller that did not offer 100rel gets an error and should fall back to [`ring`].
482///
483/// The media port is bound now, and the [`Call`](crate::Call) that
484/// [`answer_early`](crate::answer_early) builds takes it over: the answer has already told the
485/// far end where to send, and binding a second port would make the 200 contradict the 183.
486///
487/// Answers from the default codec set, [`Codecs::G711`]. [`ring_early_with`] takes a selection,
488/// and it has to be made *here* rather than at [`crate::answer_early`]: the answer goes out in
489/// this provisional, so by the time the 200 is built the codec has been agreed for some time.
490pub async fn ring_early(
491    endpoint: &Handle,
492    incoming: &Incoming,
493    status: u16,
494    reason: &'static str,
495    media_address: IpAddr,
496) -> Result<Ringing> {
497    ring_early_with(
498        endpoint,
499        incoming,
500        status,
501        reason,
502        media_address,
503        Codecs::default(),
504    )
505    .await
506}
507
508/// [`ring_early`], from a chosen codec set rather than the default one (`M-30`).
509///
510/// The [`Call`](crate::Call) that [`crate::answer_early`] builds inherits `codecs`, so an UPDATE
511/// arriving before the 200 — the whole reason this path exists — is answered from the same set the
512/// 183 answered from rather than from the default one.
513pub async fn ring_early_with(
514    endpoint: &Handle,
515    incoming: &Incoming,
516    status: u16,
517    reason: &'static str,
518    media_address: IpAddr,
519    codecs: Codecs,
520) -> Result<Ringing> {
521    ring_early_with_policy(
522        endpoint,
523        incoming,
524        status,
525        reason,
526        media_address,
527        MediaPolicy::default().with_codecs(codecs),
528    )
529    .await
530}
531
532/// [`ring_early`], using one coherent codec and ICE policy.
533///
534/// ICE has to be selected here because the answer and its candidates leave in the provisional;
535/// [`crate::answer_early`] only confirms the already-completed exchange.
536pub async fn ring_early_with_policy(
537    endpoint: &Handle,
538    incoming: &Incoming,
539    status: u16,
540    reason: &'static str,
541    media_address: IpAddr,
542    policy: MediaPolicy,
543) -> Result<Ringing> {
544    ring_early_with_policy_at(
545        endpoint,
546        incoming,
547        status,
548        reason,
549        MediaAddress::new(media_address),
550        policy,
551    )
552    .await
553}
554
555/// [`ring_early_with_policy`] with independent advertised and bound media addresses.
556pub async fn ring_early_with_policy_at(
557    endpoint: &Handle,
558    incoming: &Incoming,
559    status: u16,
560    reason: &'static str,
561    media_address: MediaAddress,
562    policy: MediaPolicy,
563) -> Result<Ringing> {
564    if !Offered::in_request(&incoming.request).supported {
565        // Not a refusal of the call — the caller can still be rung the ordinary way. It is a
566        // refusal to put an answer somewhere it may be silently lost.
567        return Err(Error::Rejected {
568            status: 421,
569            reason: "the caller did not offer 100rel, so no answer may go in a provisional"
570                .to_owned(),
571        });
572    }
573    let offer = sipx_sdp::parse(&String::from_utf8_lossy(incoming.request.body()))
574        .map_err(|error| Error::Sdp(error.to_string()))?;
575    let settled = Early::settle(
576        media_address,
577        incoming.transport.is_secure(),
578        &offer,
579        policy,
580    )
581    .await?;
582    ring_with(
583        endpoint,
584        incoming,
585        status,
586        reason,
587        true,
588        Some(ProvisionalSession::Answer(
589            Box::new(settled.0),
590            Box::new(settled.1),
591        )),
592    )
593    .await
594}
595
596enum ProvisionalSession {
597    Answer(Box<Early>, Box<SessionDescription>),
598    Offer(Box<EarlyOffer>),
599}
600
601#[allow(
602    clippy::too_many_lines,
603    reason = "one construction keeps reliability, SDP carrier and retained media state aligned"
604)]
605async fn ring_with(
606    endpoint: &Handle,
607    incoming: &Incoming,
608    status: u16,
609    reason: &'static str,
610    enabled: bool,
611    session: Option<ProvisionalSession>,
612) -> Result<Ringing> {
613    let offered = Offered::in_request(&incoming.request);
614    let decision = rel::reliability(offered, enabled);
615
616    if decision == Reliability::Refuse {
617        return refuse_bad_extension(endpoint, incoming).await;
618    }
619
620    let tag = crate::call::token();
621    let invite_cseq = incoming
622        .request
623        .headers
624        .typed::<sipx_sip::CSeq>()
625        .and_then(std::result::Result::ok)
626        .map_or(1, |cseq| cseq.sequence);
627
628    // §3: "The value of the header field for the first reliable provisional response ... MUST
629    // be between 1 and 2**31 - 1. It is RECOMMENDED that it be chosen uniformly in this range."
630    // Uniform rather than sequential because the numbering is a per-transaction secret: a
631    // predictable one lets an off-path attacker forge a PRACK and stop the retransmissions.
632    let mut numbering = Numbering::starting_at({
633        use rand::Rng as _;
634        rand::rng().random_range(1..=rel::MAX_FIRST_RSEQ)
635    });
636
637    let code = StatusCode::new(status)
638        .ok_or_else(|| Error::Sdp(format!("status {status} out of range")))?;
639    let to_with_tag = {
640        let existing = incoming
641            .request
642            .headers
643            .value(&HeaderName::To)
644            .map(|value| String::from_utf8_lossy(&value).into_owned())
645            .unwrap_or_default();
646        format!("{};tag={tag}", strip_header_params(&existing))
647    };
648
649    let mut builder = ResponseBuilder::to_request(&incoming.request, code, reason)?
650        .set_header(&HeaderName::To, Bytes::from(to_with_tag))?
651        .header(
652            HeaderName::Contact,
653            Bytes::from(crate::call::contact_for(endpoint, incoming.transport)),
654        )?
655        // RFC 3311 §4: a reliable provisional carrying SDP "SHOULD contain an Allow header
656        // field that lists the UPDATE method", which is the far end's permission to renegotiate
657        // the session this response just answered. It goes on every provisional rather than
658        // only that one, because a peer that learns it earlier can act on it earlier and
659        // nothing is claimed that is not true.
660        .header(
661            HeaderName::Allow,
662            Bytes::from_static(update::ALLOW.as_bytes()),
663        )?;
664
665    let reliable = decision != Reliability::Forbidden;
666    if reliable {
667        let allocated = numbering
668            .allocate()
669            .ok_or_else(|| Error::Sdp("unreachable: first allocation".to_owned()))?;
670        builder = builder
671            .header(HeaderName::Require, Bytes::from_static(b"100rel"))?
672            .header(HeaderName::RSeq, Bytes::from(allocated.to_string()))?;
673    }
674
675    // The answer, when there is one. Guarded by `reliable` because RFC 3262 §5 permits an
676    // answer only in a reliable provisional; `ring_early` has already refused the case where
677    // that cannot be met, so reaching here with an unreliable response and a description would
678    // be a bug rather than a peer's doing.
679    let (early, early_offer) = match session {
680        Some(ProvisionalSession::Answer(settled, answer)) if reliable => {
681            builder = builder
682                .header(
683                    HeaderName::ContentType,
684                    Bytes::from_static(b"application/sdp"),
685                )?
686                .body(Bytes::from(answer.to_string_sdp()));
687            (Some(*settled), None)
688        }
689        Some(ProvisionalSession::Offer(offered)) if reliable => {
690            builder = builder
691                .header(
692                    HeaderName::ContentType,
693                    Bytes::from_static(b"application/sdp"),
694                )?
695                .body(Bytes::from(offered.description().to_string_sdp()));
696            (None, Some(offered))
697        }
698        _ => (None, None),
699    };
700
701    let response = builder.build();
702    endpoint.respond(&incoming.key, response.clone()).await?;
703
704    let stop = reliable.then(|| {
705        let stop = Arc::new(tokio::sync::Notify::new());
706        tokio::spawn(retransmit_until_pracked(
707            endpoint.clone(),
708            incoming.key.clone(),
709            response,
710            Arc::clone(&stop),
711        ));
712        stop
713    });
714
715    // The offer/answer state the early dialog starts in. With an answer already sent nothing is
716    // outstanding either way, so an UPDATE carrying an offer is legal; without one this side
717    // owes an answer to the INVITE, and RFC 3311 §5.2's third rule refuses such an UPDATE with
718    // a 500 until the 200 settles it.
719    let negotiation = if early_offer.is_some() {
720        update::Negotiation::offering()
721    } else if early.is_none() && crate::update::carries_offer(&incoming.request) {
722        update::Negotiation::owing()
723    } else {
724        update::Negotiation::idle()
725    };
726
727    let dialog = Dialog::from_request(&incoming.request, &tag);
728    let target = dialog.as_ref().map_or_else(
729        || Target::new(incoming.source, incoming.transport),
730        |dialog| {
731            crate::call::in_dialog_target(dialog, Target::new(incoming.source, incoming.transport))
732        },
733    );
734
735    Ok(Ringing {
736        endpoint: endpoint.clone(),
737        tag,
738        invite_cseq,
739        numbering,
740        reliable,
741        stop,
742        acknowledged: false,
743        dialog,
744        target,
745        negotiation,
746        peer_allows_update: update::peer_allows(&incoming.request.headers),
747        early,
748        early_offer,
749    })
750}
751
752/// Refuse an invitation that requires 100rel from a side that has it switched off (§3).
753///
754/// The `Unsupported` naming the tag is what makes this actionable: without it the caller learns
755/// only that it failed, and a caller left waiting for an `RSeq` that will never come cannot tell
756/// that from a dead network.
757async fn refuse_bad_extension(endpoint: &Handle, incoming: &Incoming) -> Result<Ringing> {
758    const BAD_EXTENSION: u16 = 420;
759    let code = StatusCode::new(BAD_EXTENSION)
760        .ok_or_else(|| Error::Sdp("unreachable: literal status".to_owned()))?;
761    let refusal = ResponseBuilder::to_request(&incoming.request, code, "Bad Extension")?
762        .header(HeaderName::Unsupported, Bytes::from_static(b"100rel"))?
763        .build();
764    endpoint.respond(&incoming.key, refusal).await?;
765    Err(Error::Rejected {
766        status: BAD_EXTENSION,
767        reason: "Bad Extension".to_owned(),
768    })
769}
770
771/// Resend a reliable provisional on the RFC 3262 §3 schedule until it is acknowledged.
772///
773/// The interval "starts at T1 seconds and doubles for each retransmission" — and, unlike a 2xx,
774/// **does not cap at T2**. The RFC explains why: ACK retransmissions are triggered by receiving
775/// a 2xx, but PRACK is sent once and independently of further 1xx, so a fast repeat buys
776/// nothing after the first few and only adds traffic.
777async fn retransmit_until_pracked(
778    endpoint: Handle,
779    key: TransactionKey,
780    response: Response,
781    stop: Arc<tokio::sync::Notify>,
782) {
783    let deadline = tokio::time::Instant::now() + GIVE_UP;
784    let mut interval = T1;
785    loop {
786        let wake = tokio::time::Instant::now() + interval;
787        if wake >= deadline {
788            return;
789        }
790        tokio::select! {
791            () = stop.notified() => return,
792            () = tokio::time::sleep_until(wake) => {}
793        }
794        if endpoint.respond(&key, response.clone()).await.is_err() {
795            return;
796        }
797        interval = interval.saturating_mul(2);
798    }
799}