Skip to main content

sipx_ua/
agent.rs

1//! The user agent: registering, keeping registered, and answering what arrives.
2
3use std::time::Duration;
4
5use bytes::Bytes;
6use sipx_sip::build::ResponseBuilder;
7use sipx_sip::{Address, HeaderName, Method, Request, StatusCode, Uri};
8use sipx_transport::{Handle, Incoming, Target};
9
10use crate::auth::Credentials;
11use crate::error::{Error, Result};
12use crate::gruu;
13use crate::outbound::{self, InstanceId, RegId};
14use crate::registrar::{self, Lease, Outcome, Registration, RegistrationObservation};
15
16/// How a user agent is configured.
17#[derive(Debug, Clone)]
18pub struct Config {
19    /// The address of record, as it appears in `To` and `From`.
20    pub aor: String,
21    /// Where to reach this agent.
22    pub contact: String,
23    /// The registrar's URI.
24    pub registrar: Uri,
25    /// Where to send registrations.
26    pub target: Target,
27    /// Credentials, if the registrar wants them.
28    pub credentials: Option<Credentials>,
29    /// The lease to ask for.
30    pub expires: Duration,
31    /// What to put in `User-Agent`.
32    pub user_agent: String,
33    /// Validated application-owned fields preserved on every REGISTER attempt and refresh.
34    pub headers: Vec<sipx_sip::Header>,
35    /// The device identity this agent registers under (RFC 5626 §4.1, RFC 5627 §4.1).
36    ///
37    /// One field for both mechanisms, because both name the instance with the same
38    /// `+sip.instance` media feature tag and a registrar that correlates them must see one
39    /// value. Set it with [`Config::with_outbound`] or [`Config::with_gruu`]; whichever is
40    /// called last decides, and either way there is only ever one identity to present.
41    ///
42    /// `None` registers the ordinary way: a `Contact` naming an address and nothing naming the
43    /// device behind it, so every restart looks to the registrar like a new phone.
44    pub instance: Option<InstanceId>,
45    /// Which Outbound flow this registration is, when Outbound is in use (RFC 5626 §4.2).
46    ///
47    /// `None` registers the ordinary way: a binding that is only as durable as the NAT mapping
48    /// behind it.
49    pub reg_id: Option<RegId>,
50    /// Which GRUU this agent uses, when it is asking for one (RFC 5627 §4.4).
51    ///
52    /// `None` does not ask. See [`gruu::Kind`] for why the choice is the application's.
53    pub gruu: Option<gruu::Kind>,
54    /// How a push notification service can wake this device (RFC 8599 §4.1.2).
55    ///
56    /// `None` registers without push, which is every client that holds a connection of its
57    /// own. Set it with [`Config::with_push`]; the values come from the application's push
58    /// service, behind [`crate::push::PushService`].
59    pub push: Option<sipx_sip::push::Device>,
60    /// How long a keep-alive may go unanswered before the flow is failed (RFC 5626 §4.4).
61    ///
62    /// Defaults to §4.4.1's ten seconds. It is configurable because the RFC gives *two* rules and
63    /// only one of them is a duration: §4.4.1 fixes ten seconds for the CRLF pong, while §4.4.2
64    /// bounds the STUN case by 7 retransmissions of an RTO estimate instead. Ten seconds is the
65    /// conservative reading of both, and a deployment that knows its round-trip times — or a test
66    /// that does not want to wait — is entitled to a shorter one.
67    pub keepalive_timeout: Duration,
68}
69
70pub use crate::outbound::Flow;
71
72impl Config {
73    /// A configuration for an address of record.
74    #[must_use]
75    pub fn new(
76        aor: impl Into<String>,
77        contact: impl Into<String>,
78        registrar: Uri,
79        target: Target,
80    ) -> Self {
81        Self {
82            aor: aor.into(),
83            contact: contact.into(),
84            registrar,
85            target,
86            credentials: None,
87            expires: Duration::from_secs(3600),
88            user_agent: concat!("sipx/", env!("CARGO_PKG_VERSION")).to_owned(),
89            headers: Vec::new(),
90            instance: None,
91            reg_id: None,
92            gruu: None,
93            push: None,
94            keepalive_timeout: outbound::PONG_TIMEOUT,
95        }
96    }
97
98    /// Fail a flow whose keep-alive is unanswered for this long (RFC 5626 §4.4).
99    #[must_use]
100    pub fn with_keepalive_timeout(mut self, within: Duration) -> Self {
101        self.keepalive_timeout = within;
102        self
103    }
104
105    /// Register this contact as one Outbound flow (RFC 5626).
106    ///
107    /// The `Contact` gains `reg-id` and `+sip.instance`, and the REGISTER offers the `outbound`
108    /// option tag. Whether the registrar actually *did* an outbound registration is a separate
109    /// question, answered by `UserAgent::flow_accepted` after the fact — §6 has the registrar say
110    /// so in `Require`, and a UA that assumes it would keep a flow alive that nothing routes down.
111    #[must_use]
112    pub fn with_outbound(mut self, flow: Flow) -> Self {
113        self.instance = Some(flow.instance);
114        self.reg_id = Some(flow.reg_id);
115        self
116    }
117
118    /// Ask the registrar for a GRUU, and say which of the two to use (RFC 5627 §4.1, §4.4).
119    ///
120    /// The REGISTER gains the `gruu` option tag and presents `instance`; the GRUUs that come back
121    /// are readable through [`UserAgent::gruus`] and are what
122    /// [`UserAgent::dialog_contact`] then publishes.
123    ///
124    /// **`instance` is the same identity Outbound registers with**, and it is stored in the same
125    /// field: a UA using both mechanisms presents one instance ID, because a registrar
126    /// correlating them would otherwise see one device claiming to be two. Whether the registrar
127    /// actually *issues* a GRUU is its business — §4.2 requires a UA to cope with one, both or
128    /// neither, and getting neither is not an error.
129    ///
130    /// See [`gruu::Kind`] for why `Kind::Public` is the default and why asking for
131    /// `Kind::Temporary` never quietly yields the public one.
132    #[must_use]
133    pub fn with_gruu(mut self, instance: InstanceId, kind: gruu::Kind) -> Self {
134        self.instance = Some(instance);
135        self.gruu = Some(kind);
136        self
137    }
138
139    /// Add credentials.
140    #[must_use]
141    pub fn with_credentials(mut self, credentials: Credentials) -> Self {
142        self.credentials = Some(credentials);
143        self
144    }
145
146    /// Add a validated application-owned field to every REGISTER request.
147    #[must_use]
148    pub fn with_header(mut self, header: sipx_sip::Header) -> Self {
149        self.headers.push(header);
150        self
151    }
152
153    /// Be reachable through this push notification service (RFC 8599 §4.1.2).
154    ///
155    /// The `Contact` **URI** gains `pn-provider`, `pn-param` and `pn-prid` — inside the angle
156    /// brackets, where a registrar's URI parser looks; §8.7 registers them as URI parameters
157    /// and a `;` outside the brackets starts a different grammar entirely.
158    ///
159    /// Registering is only half the mechanism. When the push arrives, call
160    /// [`UserAgent::woken`] — §4.1.3's binding-refresh REGISTER — *before* expecting the
161    /// request the push was sent for, because until the refresh there is no flow for it to
162    /// arrive on. And after any registration, ask [`UserAgent::push_support`] whether the
163    /// registrar named this service: a 200 from a registrar that supports a different one is a
164    /// binding nothing will ever wake.
165    #[must_use]
166    pub fn with_push(mut self, device: sipx_sip::push::Device) -> Self {
167        self.push = Some(device);
168        self
169    }
170}
171
172/// A user agent bound to a transport endpoint.
173#[derive(Debug)]
174pub struct UserAgent {
175    endpoint: Handle,
176    config: Config,
177    registration: Registration,
178    /// What the registrar reported as the source of the last successful REGISTER.
179    ///
180    /// Observation only: it is never copied into registration, routing or media policy.
181    registration_observation: RegistrationObservation,
182    /// The last nonce answered, and how many requests have used it. RFC 7616 §3.4.3 defines
183    /// `nc` per nonce, not per client, so the pair travels together.
184    nonce_use: Option<(String, u32)>,
185    /// The proxies the registrar recorded as being on the path back here (RFC 3327).
186    path: registrar::PathSet,
187    /// The proxies this UA's own outbound requests must traverse (RFC 3608).
188    service_route: registrar::ServiceRoute,
189    /// Whether the registrar reported an *outbound* registration (RFC 5626 §6).
190    flow_accepted: bool,
191    /// The `Flow-Timer` the registrar named, if it named one (RFC 5626 §4.4).
192    flow_timer: Option<Duration>,
193    /// The reflexive address the last keep-alive reported (RFC 5626 §4.4.2).
194    ///
195    /// Kept because a *change* in it is a flow failure: the NAT has rebound, so the address the
196    /// registrar has for this flow no longer reaches it, even though the socket still works.
197    reflexive: Option<std::net::SocketAddr>,
198    /// The GRUUs the registrar issued for this instance (RFC 5627 §4.2).
199    ///
200    /// Replaced on every 2xx and cleared whenever an attempt does not produce one, because a
201    /// GRUU is only as valid as the binding behind it: §5.2 has a registrar stop resolving a
202    /// temporary GRUU once nothing is bound to it, and §4.2 requires a UA to discard the ones it
203    /// learned when its `Call-ID` changes. Keeping a stale one means publishing an address that
204    /// no longer reaches anything, in the header a peer will route its next request by.
205    gruus: gruu::Gruus,
206    /// What the registrar said about push (RFC 8599 §8.2).
207    ///
208    /// Replaced on every 2xx and cleared when an attempt fails, for the reason the GRUUs are:
209    /// it describes the registration that exists, and holding what an older one said would
210    /// answer [`UserAgent::push_support`]'s question about a binding that is gone.
211    push_support: crate::push::Support,
212}
213
214impl UserAgent {
215    /// A user agent that will send through `endpoint`.
216    #[must_use]
217    pub fn new(endpoint: Handle, config: Config) -> Self {
218        let registration = Registration {
219            registrar: config.registrar.clone(),
220            aor: config.aor.clone(),
221            contact: config.contact.clone(),
222            expires: config.expires,
223            call_id: format!("{}@sipx", crate::auth::new_cnonce()),
224            // Zero, not one: `register` advances before building, so the first request is 1
225            // and every later one is strictly greater. A REGISTER that reuses a sequence
226            // number inside the same Call-ID is out of order, and a registrar is entitled to
227            // ignore it — which looks exactly like the refresh silently not happening.
228            cseq: 0,
229            instance: config.instance.clone(),
230            reg_id: config.reg_id,
231            gruu: config.gruu,
232            push: config.push.clone(),
233            headers: config.headers.clone(),
234        };
235        Self {
236            endpoint,
237            config,
238            registration,
239            registration_observation: RegistrationObservation::NotRegistered,
240            nonce_use: None,
241            path: registrar::PathSet::default(),
242            service_route: registrar::ServiceRoute::default(),
243            flow_accepted: false,
244            flow_timer: None,
245            reflexive: None,
246            gruus: gruu::Gruus::default(),
247            push_support: crate::push::Support::default(),
248        }
249    }
250
251    /// The path the registrar recorded for this binding (RFC 3327).
252    ///
253    /// Empty until a registration succeeds, and empty afterwards if no proxy on the way put
254    /// itself on the path. This is reported rather than routed on: §5.1 says "the general
255    /// operation of the UA is to ignore the Path header field in the response", because the
256    /// vector exists so that requests arriving *at the registrar* can be steered back toward a
257    /// UA behind a NAT. What §5.1 does offer it for is inspection — seeing a proxy that has
258    /// "inappropriately added" itself — and that is only possible if the value survives.
259    #[must_use]
260    pub fn path(&self) -> &registrar::PathSet {
261        &self.path
262    }
263
264    /// The route the registrar dictated for requests this UA sends (RFC 3608).
265    ///
266    /// The opposite direction from [`UserAgent::path`], and the one a UA is meant to act on:
267    /// §6.1 has it used "as a preloaded Route header field in outgoing initial requests". sipx
268    /// does not preload it behind the caller's back — a `Route` set silently attached to every
269    /// request is the kind of thing that is impossible to debug from the outside — so this is
270    /// handed to whoever builds the request, via `DialOptions::with_service_route` for a call.
271    ///
272    /// Empty until a registration succeeds, and empty again after any 2xx that carries no
273    /// `Service-Route`.
274    #[must_use]
275    pub fn service_route(&self) -> &registrar::ServiceRoute {
276        &self.service_route
277    }
278
279    /// What the registrar's top response `Via` reported for the last successful registration.
280    ///
281    /// [`RegistrationObservation::NotRegistered`] means no registration has succeeded yet;
282    /// [`RegistrationObservation::Absent`] is different: a success carried a valid top `Via` but
283    /// no observation parameters.
284    ///
285    /// This does not authorize rewriting `Contact`, routing, GRUU, Outbound, push, SDP or media
286    /// addresses. [`RegistrationObservation::Invalid`] still accompanies a successful lease.
287    #[must_use]
288    pub const fn registration_observation(&self) -> &RegistrationObservation {
289        &self.registration_observation
290    }
291
292    /// The registrar-observed address, when one was reported unambiguously.
293    ///
294    /// This convenience accessor deliberately returns no fallback for absent or invalid data. Use
295    /// [`Self::registration_observation`] when the distinction matters.
296    #[must_use]
297    pub const fn observed_registration_address(&self) -> Option<std::net::SocketAddr> {
298        self.registration_observation.address()
299    }
300
301    /// Whether the registrar reported performing an Outbound registration (RFC 5626 §6).
302    ///
303    /// False until a registration succeeds, and false afterwards if the registrar did not put the
304    /// option tag in `Require` — which is the case for every registrar that does not implement
305    /// RFC 5626 at all. Asking for Outbound and not getting it is not an error: the binding is an
306    /// ordinary one, and the only thing that changes is that there is no flow to keep alive.
307    #[must_use]
308    pub fn flow_accepted(&self) -> bool {
309        self.flow_accepted
310    }
311
312    /// How long to wait before the next keep-alive on this flow, if it is one (RFC 5626 §4.4).
313    ///
314    /// `None` when the registrar did not perform an Outbound registration — there is no flow, so
315    /// pinging would be traffic with nothing at the far end that cares. Re-drawn on every call,
316    /// because §4.4.1 requires a fresh random interval for each ping: a fleet on a fixed period
317    /// synchronises after any shared outage and arrives back as one spike.
318    #[must_use]
319    pub fn keepalive_after(&self, power: crate::outbound::Power) -> Option<Duration> {
320        self.flow_accepted.then(|| {
321            crate::outbound::keepalive_interval(
322                self.flow_timer,
323                crate::outbound::keepalive_for(self.config.target.transport),
324                power,
325                crate::outbound::fraction(),
326            )
327        })
328    }
329
330    /// Send one keep-alive on this flow and judge the answer (RFC 5626 §4.4).
331    ///
332    /// Three ways this reports a failed flow, and §4.4 makes each of them one:
333    ///
334    /// - no answer within [`outbound::PONG_TIMEOUT`] (§4.4.1),
335    /// - a STUN Binding Error Response (§4.4.2),
336    /// - a reflexive address **different from the last one** (§4.4.2).
337    ///
338    /// The third is the one that is easy to leave out and the reason STUN is the UDP technique at
339    /// all. The socket still works; what has changed is that the NAT rebound, so the mapping the
340    /// registrar holds for this flow no longer reaches it. A keep-alive that only asked "did
341    /// anything come back" would call that flow healthy right up until a call failed to arrive.
342    ///
343    /// `Ok(())` on a flow the registrar did not accept: there is no flow, so there is nothing to
344    /// keep alive and nothing has failed.
345    pub async fn keepalive(&mut self) -> Result<()> {
346        if !self.flow_accepted {
347            return Ok(());
348        }
349        let mapped = self
350            .endpoint
351            .keepalive(self.config.target.clone(), self.config.keepalive_timeout)
352            .await?;
353        if let (Some(previous), Some(current)) = (self.reflexive, mapped)
354            && previous != current
355        {
356            self.reflexive = Some(current);
357            return Err(Error::FlowRebound { previous, current });
358        }
359        if mapped.is_some() {
360            self.reflexive = mapped;
361        }
362        Ok(())
363    }
364
365    /// The reflexive address the last keep-alive reported, if one did (RFC 5626 §4.4.2).
366    #[must_use]
367    pub fn reflexive_address(&self) -> Option<std::net::SocketAddr> {
368        self.reflexive
369    }
370
371    /// The GRUUs the registrar issued for this instance (RFC 5627 §4.2).
372    ///
373    /// Empty until a registration succeeds, empty afterwards if GRUU was not asked for, and empty
374    /// again if it was and the registrar issued nothing — §4.2 requires a UA to be ready for one,
375    /// both or neither, and a registrar that does not implement RFC 5627 answers a REGISTER
376    /// perfectly well and attaches none.
377    #[must_use]
378    pub fn gruus(&self) -> &gruu::Gruus {
379        &self.gruus
380    }
381
382    /// Whether a request that arrived was sent to one of this instance's GRUUs (RFC 5627 §4.5).
383    ///
384    /// This is the question the mechanism exists to make answerable, and it is not the question
385    /// "is this request for me": an address of record reaches every device the user registered,
386    /// and RFC 5627 §5.4 notes that a public GRUU "will always be equivalent to the AOR based on
387    /// URI equality rules". A `true` here means the sender addressed *this* instance and nothing
388    /// else — which is what a transfer target or a callback is relying on.
389    #[must_use]
390    pub fn sent_to_our_gruu(&self, request: &Request) -> bool {
391        self.gruus.sent_to(&request.uri)
392    }
393
394    /// The `Contact` to put on a dialog-forming or target-refresh request (RFC 5627 §4.4,
395    /// RFC 5626 §4.3).
396    ///
397    /// Three answers, in the order the RFCs put them:
398    ///
399    /// - **The GRUU**, when one is known. §4.4: "A UA SHOULD use a GRUU when populating the
400    ///   Contact header field of dialog-forming and target refresh requests and responses." It is
401    ///   an address that survives this flow, this NAT mapping and this registration, which is
402    ///   more than either of the others can say.
403    /// - **The contact with `ob`**, when this is an accepted flow and no GRUU is known. RFC 5626
404    ///   §4.3 makes that a MUST *in the absence of a GRUU*, and it tells the far end that
405    ///   mid-dialog requests belong on this flow rather than at the address in the URI — behind a
406    ///   NAT, the difference between a re-INVITE arriving and vanishing.
407    /// - **The plain contact**, when neither applies.
408    ///
409    /// A caller that asked for a temporary GRUU and did not get one lands in the second or third
410    /// case, never the first: the public GRUU is not a substitute for an unlinkable address, and
411    /// quietly publishing the device's permanent name to a peer that was promised otherwise is a
412    /// worse outcome than publishing the contact. It is logged, because the caller asked for
413    /// something it did not get.
414    #[must_use]
415    pub fn dialog_contact(&self) -> String {
416        if let Some(kind) = self.config.gruu {
417            if let Some(gruu) = self.gruus.preferred(kind) {
418                return format!("<{gruu}>");
419            }
420            if kind == gruu::Kind::Temporary {
421                tracing::warn!(
422                    "no temporary GRUU was issued; publishing the contact rather than the public \
423                     GRUU, which would not be unlinkable"
424                );
425            }
426        }
427        if self.flow_accepted {
428            crate::outbound::with_ob(&self.config.contact)
429        } else {
430            self.config.contact.clone()
431        }
432    }
433
434    /// What the registrar said about push notifications (RFC 8599 §8.2).
435    ///
436    /// Empty until a registration succeeds, and empty afterwards when the registrar implements
437    /// nothing of RFC 8599 — which is not a refusal, just silence. The question to ask it is
438    /// [`Support::supports`](crate::push::Support::supports) with the provider this side
439    /// registered: a registrar that answered 200 while naming a *different* push service has
440    /// recorded a binding nothing will ever wake, and this is the only place that says so.
441    #[must_use]
442    pub fn push_support(&self) -> &crate::push::Support {
443        &self.push_support
444    }
445
446    /// A push notification arrived: refresh the binding, and only then expect the request
447    /// (RFC 8599 §4.1.3).
448    ///
449    /// §4.1.3: "When a UA receives a push notification, the UA MUST send a binding-refresh
450    /// REGISTER request." The push is not the call — it is permission to go and get a flow,
451    /// and the request the push was sent for arrives down the flow this REGISTER creates. A
452    /// client that skips this and waits for the INVITE is waiting on a path that does not
453    /// exist yet, which is why the [`Pending`](crate::push::Pending) that licenses the wait
454    /// comes from here and nowhere else.
455    ///
456    /// sipx neither sends nor receives the push itself: the service is behind
457    /// [`crate::push::PushService`], and *when* to call this is the application's — it is
458    /// whatever "the notification fired" means on its platform.
459    pub async fn woken(&mut self) -> Result<crate::push::Pending> {
460        let lease = self.register().await?;
461        Ok(crate::push::Pending {
462            lease,
463            purr: self.push_support.purr().map(str::to_owned),
464        })
465    }
466
467    /// Register, answering a challenge if one comes.
468    ///
469    /// One retry, not a loop. A second challenge after credentials were supplied means the
470    /// credentials are wrong — unless the server says the nonce was merely stale, which is a
471    /// different thing and is retried. Looping on a genuine rejection is how a client locks
472    /// out the account it is trying to use.
473    pub async fn register(&mut self) -> Result<Lease> {
474        self.registration.advance();
475        let mut request = self.registration.request()?;
476        let mut outcome = self.attempt(request.clone()).await?;
477
478        if let Outcome::Challenged(challenge) = outcome {
479            let credentials = self
480                .config
481                .credentials
482                .as_ref()
483                .ok_or(Error::CredentialsRequired)?;
484
485            self.registration.advance();
486            let count = nonce_count_for(&mut self.nonce_use, &challenge.nonce);
487            request = self.registration.request()?;
488            registrar::authorize(&mut request, &challenge, credentials, count)?;
489            outcome = self.attempt(request).await?;
490
491            // A stale nonce is the server asking for the same credentials against a fresh
492            // nonce, not a refusal. One further attempt, then stop.
493            if let Outcome::Challenged(again) = &outcome
494                && again.stale
495            {
496                self.registration.advance();
497                let count = nonce_count_for(&mut self.nonce_use, &again.nonce);
498                let mut retry = self.registration.request()?;
499                registrar::authorize(&mut retry, again, credentials, count)?;
500                outcome = self.attempt(retry).await?;
501            }
502        }
503
504        match outcome {
505            Outcome::Registered(registered) => {
506                let registrar::Registered {
507                    lease,
508                    observation,
509                    path,
510                    service_route,
511                    flow_accepted,
512                    flow_timer,
513                    gruus,
514                    push,
515                } = *registered;
516                self.flow_accepted = flow_accepted;
517                self.registration_observation = observation;
518                self.flow_timer = flow_timer;
519                self.path = path;
520                // Replaced, never merged — the same rule as the service route, and for a
521                // stronger reason: RFC 5627 §4.2 requires temporary GRUUs learned earlier to be
522                // discarded outright rather than kept alongside, and a set that merges cannot
523                // tell which of the two it is holding.
524                self.gruus = gruus;
525                // Replaced, never merged, like the GRUUs: this is what the registrar said about
526                // the binding it just recorded, and what it said about an earlier one answers
527                // "can this registrar wake me" for a binding that no longer exists.
528                self.push_support = push;
529                // Replaced on every success, never merged. RFC 3608 §6.1: the stored value is
530                // "updated according to the Service-Route header field of the latest 200 class
531                // response", and a response with no such header "clears any service route ...
532                // previously stored". Both are one rule, and assignment is it.
533                for hop in service_route.hops_without_loose_routing() {
534                    tracing::warn!(
535                        hop = %hop,
536                        "the registrar's Service-Route omits ;lr, which RFC 3608 §5 requires"
537                    );
538                }
539                self.service_route = service_route;
540                Ok(lease)
541            }
542            // The binding did not happen, so neither did the GRUUs that hang off it. Holding
543            // them would leave the agent publishing an address for a registration it does not
544            // have (RFC 5627 §5.2).
545            Outcome::Challenged(_) => {
546                self.gruus = gruu::Gruus::default();
547                self.push_support = crate::push::Support::default();
548                Err(Error::AuthenticationFailed)
549            }
550            // §8.1's one answer that is not about this attempt: the named push service will not
551            // become usable on a retry, so it surfaces as itself rather than as the rejection
552            // below — folded in, it is indistinguishable from a bad password.
553            Outcome::PushNotSupported { reason } => {
554                self.gruus = gruu::Gruus::default();
555                self.push_support = crate::push::Support::default();
556                Err(Error::PushNotSupported { reason })
557            }
558            Outcome::Rejected { status, reason } => {
559                self.gruus = gruu::Gruus::default();
560                self.push_support = crate::push::Support::default();
561                Err(Error::Rejected { status, reason })
562            }
563        }
564    }
565
566    async fn attempt(&self, request: Request) -> Result<Outcome> {
567        let mut responses = self
568            .endpoint
569            .send(request, self.config.target.clone())
570            .await?;
571        let response = responses.final_response().await.ok_or(Error::NoResponse)?;
572        Ok(registrar::interpret(&response, &self.registration))
573    }
574
575    /// Register and keep registering, refreshing before each lease expires.
576    ///
577    /// A failed refresh is retried once inside the margin left by the last granted lease. The
578    /// registrar's grant defines both deadlines: the first attempt starts at `refresh_after`, and
579    /// the retry divides what remains before `granted`. A second failure returns rather than
580    /// creating an unbounded retry loop.
581    pub async fn keep_registered(&mut self) -> Result<std::convert::Infallible> {
582        let mut lease = self.register().await?;
583        loop {
584            let granted_at = tokio::time::Instant::now();
585            tracing::info!(
586                granted = lease.granted.as_secs(),
587                refresh_in = lease.refresh_after.as_secs(),
588                "registered"
589            );
590            tokio::time::sleep(lease.refresh_after).await;
591            match self.register().await {
592                Ok(refreshed) => lease = refreshed,
593                Err(first_error) => {
594                    // A failed transaction may itself consume most of the safety margin. Count
595                    // that time rather than subtracting only the scheduled refresh delay, or a
596                    // timeout could schedule its "within-lease" retry after the lease expired.
597                    let remaining = lease
598                        .granted
599                        .saturating_sub(tokio::time::Instant::now().duration_since(granted_at));
600                    if remaining.is_zero() {
601                        return Err(first_error);
602                    }
603                    let retry_after = remaining / 2;
604                    tracing::warn!(
605                        error = %first_error,
606                        retry_in = retry_after.as_secs_f64(),
607                        lease_remaining = remaining.as_secs_f64(),
608                        "registration refresh failed; retrying within the granted lease"
609                    );
610                    tokio::time::sleep(retry_after).await;
611                    lease = self.register().await?;
612                }
613            }
614        }
615    }
616
617    /// Answer a request that arrived, when the user-agent layer owns the decision.
618    ///
619    /// Handles what a user agent must answer to be a good citizen on the network, and refuses an
620    /// initial INVITE addressed to a GRUU this registered instance does not own. Anything else is
621    /// left to the caller, which is why this returns whether it acted.
622    ///
623    /// The GRUU guard applies only after this agent has learned at least one GRUU. An unregistered
624    /// agent cannot prove that an unfamiliar value belongs to somebody else, while one holding its
625    /// registrar-issued values can. RFC 5627 §4.5 says `gr` identifies an instance-specific URI;
626    /// §6.1 gives an unresolved GRUU the ordinary `404 Not Found` response. Applying that response
627    /// at the last hop keeps a proxy's accidental misrouting from turning an instance address back
628    /// into an address-of-record fan-out.
629    pub async fn answer(&self, incoming: &Incoming) -> Result<bool> {
630        match incoming.request.method {
631            Method::Options => {
632                self.answer_options(incoming).await?;
633                Ok(true)
634            }
635            Method::Invite
636                if !self.gruus.is_empty()
637                    && tagless_to(&incoming.request).is_some()
638                    && sipx_sip::gruu::is_gruu(&incoming.request.uri)
639                    && !self.sent_to_our_gruu(&incoming.request) =>
640            {
641                self.refuse_foreign_gruu(incoming).await?;
642                Ok(true)
643            }
644            _ => Ok(false),
645        }
646    }
647
648    /// Refuse a dialog-forming request whose GRUU names another registered instance.
649    async fn refuse_foreign_gruu(&self, incoming: &Incoming) -> Result<()> {
650        let mut builder = ResponseBuilder::to_request(
651            &incoming.request,
652            StatusCode::new(404).ok_or(Error::NoResponse)?,
653            "Not Found",
654        )?;
655        if let Some(to) = tagless_to(&incoming.request) {
656            builder = builder.set_header(
657                &HeaderName::To,
658                Bytes::from(format!("{to};tag={}", crate::auth::new_cnonce())),
659            )?;
660        }
661        self.endpoint
662            .respond(&incoming.key, builder.build())
663            .await?;
664        Ok(())
665    }
666
667    /// Answer an `OPTIONS` ping (RFC 3261 §11.2).
668    ///
669    /// The point of OPTIONS is the capability list, so a 200 with an empty `Allow` is a wasted
670    /// exchange: the peer asked what we can do and learned nothing.
671    async fn answer_options(&self, incoming: &Incoming) -> Result<()> {
672        let mut builder = ResponseBuilder::to_request(
673            &incoming.request,
674            StatusCode::new(200).ok_or(Error::NoResponse)?,
675            "OK",
676        )?
677        // The one list, shared with everything else that advertises what this stack answers.
678        // A second copy here would drift from the one on the INVITE, and RFC 3311 §4 makes an
679        // `Allow` that omits UPDATE a standing instruction to the peer never to send one.
680        .header(
681            HeaderName::Allow,
682            Bytes::from_static(sipx_sip::update::ALLOW.as_bytes()),
683        )?
684        .header(HeaderName::Accept, Bytes::from_static(b"application/sdp"))?
685        .header(
686            HeaderName::UserAgent,
687            Bytes::from(self.config.user_agent.clone()),
688        )?;
689        // RFC 3261 §8.2.6.2: every response but a 100 must carry a `To` tag, and an
690        // out-of-dialog request arrives without one, so the tag is added rather than
691        // copied. `new_cnonce` gives 64 random bits, which covers §19.3's demand for global
692        // uniqueness with at least 32 bits of randomness. Appending works in both forms of
693        // the header: after `>` in a name-addr, and after a bare addr-spec, where the
694        // semicolon starts a header parameter (RFC 3261 §20).
695        if let Some(to) = tagless_to(&incoming.request) {
696            builder = builder.set_header(
697                &HeaderName::To,
698                Bytes::from(format!("{to};tag={}", crate::auth::new_cnonce())),
699            )?;
700        }
701        let response = builder.build();
702        self.endpoint.respond(&incoming.key, response).await?;
703        Ok(())
704    }
705
706    /// The transport handle this agent sends through.
707    #[must_use]
708    pub fn endpoint(&self) -> &Handle {
709        &self.endpoint
710    }
711}
712
713/// The request's `To` value, when it arrived without a tag and needs one added.
714///
715/// `None` also covers a `To` that does not parse: `ResponseBuilder::to_request` copies it
716/// verbatim so a malformed request still gets a well-formed answer, and appending a tag to
717/// a value whose shape is unknown could change what the rest of it means.
718fn tagless_to(request: &Request) -> Option<String> {
719    let value = request.headers.value(&HeaderName::To)?;
720    let address = Address::parse(&value, "To").ok()?;
721    address
722        .tag()
723        .is_none()
724        .then(|| String::from_utf8_lossy(&value).into_owned())
725}
726
727/// The `nc` for a request about to answer `nonce`, recorded in `nonce_use`.
728///
729/// RFC 7616 §3.4.3: `nc` counts the requests sent *with this nonce*, so a nonce not seen
730/// before starts at one — including the fresh nonce a stale challenge carries. A count
731/// carried across nonces looks like a replay to the registrar that tracks it, which is the
732/// registrar the count exists to satisfy.
733fn nonce_count_for(nonce_use: &mut Option<(String, u32)>, nonce: &str) -> u32 {
734    let count = match nonce_use {
735        Some((last, count)) if last == nonce => count.saturating_add(1),
736        _ => 1,
737    };
738    *nonce_use = Some((nonce.to_owned(), count));
739    count
740}