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) -> ®istrar::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) -> ®istrar::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}