Skip to main content

sipx_ua/
lib.rs

1//! SIP user agent: registration, authentication, and answering what arrives.
2//!
3//! This crate sits on `sipx-transport` and turns transactions into the things a phone or a
4//! service actually does. Digest authentication and registration leases live here because
5//! both are about *state over time* rather than about a single message, which is what
6//! separates a user agent from a transaction layer.
7//!
8//! Dialogs and calls are the next layer up, in `sipx-call`.
9
10//! # Without a runtime
11//!
12//! Digest is hashing and header text, and a caller whose decision logic touches no IO must be able
13//! to use it without linking one. `default-features = false` drops the `runtime` feature and with
14//! it the modules that drive a socket — `agent`, `flows`, and the error type that wraps a transport
15//! failure — leaving `auth`, `challenge`, `gruu`, `identity`, `outbound`, `push` and `registrar`.
16//! Identity signing and verification take caller-supplied time, authority policy, and credential
17//! acquisition, so they remain usable without a runtime as well. The alternative for such a caller
18//! is to write digest or identity processing a second time, and two implementations of one
19//! algorithm eventually disagree about who is authenticated.
20//!
21//! # Stability
22//!
23//! sipx is pre-1.0, so **neither word below means frozen**. `1.0.0` is what freezes an API, and its
24//! predicates are in `docs/roadmap.md`. Until then:
25//!
26//! - **Supported** — meant to be depended on. Breaking changes get a `CHANGELOG.md` entry saying what
27//!   to do instead. New enum variants and new struct fields may still appear in a minor release, so a
28//!   downstream `match` should carry a `_` arm.
29//! - **Experimental** — may change shape or be removed without a migration note. Depend on it only if
30//!   you are prepared to follow it.
31//!
32//!
33//! **Supported**: registration leases, digest authentication, authenticated caller identity, Path,
34//! Service-Route, registering as one Outbound flow, push, and the subscription store plus built-in
35//! dialog, registration and presence package documents selected by `sipx-call::Notifier`.
36//! `S-34` gives identity its caller:
37//! outbound and inbound policies in `sipx-call` select the authentication and verification
38//! services. `S-29` is what gives Outbound and push their callers — `sipx register --outbound` and
39//! `--push-provider`/`--push-prid` — and it is why `X-37` had demoted their compliance rows in the
40//! first place.
41//!
42//! **Which application backs that claim, stated because the two are not the same** (`X-38`). Every
43//! Registration, Outbound and push are called by `sipx-cli`, while authenticated identity is called
44//! by `sipx-call`, which is itself the call framework used by `sipx-app`. The host uses only this
45//! crate's answering half directly: `Host::agent_config` builds a [`Config`] to answer OPTIONS with
46//! and names the listener's own address as a registrar that nothing ever sends to, so `register` is
47//! never called. `X-38` defines the *call*-reachable surface as what the host uses, and registration
48//! is not call-reachable in principle rather than by omission — it happens before and outside any
49//! call. So the registration claim rests on `A-8`'s other rule: the CLI's promise is its command-line
50//! surface, documented in `website/docs/reference/cli.md` and asserted by `tests/cli.rs`.
51//! `scripts/check-app-surface.py` checks that citation rather than trusting it, so this paragraph
52//! cannot rot into a claim with no caller at all. Push is earned in full: the `pn-*` parameters,
53//! §8.2's answer read back, and §4.1.3's refresh through `UserAgent::woken`. Outbound is earned
54//! only as far as the registration goes, which is what the wording above says and no further.
55//!
56//! **Experimental**: `event_client` and `publication_client`. They are public and tested.
57//! `event_client` is the bounded sans-I/O subscriber driven by
58//! `sipx-call::EventSubscriptions`, and `sipx-call::Publications` carries the publication core and
59//! exact compositor through live endpoints. The bounded `reginfo` consumer is reached by
60//! `sipx peers --registrar`; no CLI command publishes, and published presence is not automatically
61//! projected into later NOTIFY documents. Their pre-1.0 API shape is still soft.
62//!
63//! By that same rule, and named here rather than left for a reader to discover: the rest of
64//! Outbound is experimental too. `Flows` and `Attempt` — one registration per outbound proxy,
65//! each flow failing independently under §4.5's backoff — plus `UserAgent::keepalive_after`
66//! (§4.4) and `UserAgent::dialog_contact`'s `ob` parameter (§4.3) are exercised by this crate's
67//! own tests and by nothing above them. `sipx register` places a single flow and does not hold it
68//! open, so those shapes have never been constrained by a caller either.
69
70#[cfg(feature = "runtime")]
71pub mod agent;
72pub mod auth;
73pub mod challenge;
74#[cfg(feature = "runtime")]
75pub mod error;
76pub mod event_client;
77#[cfg(feature = "runtime")]
78pub mod flows;
79pub mod gruu;
80pub mod history;
81pub mod identity;
82pub mod outbound;
83pub mod packages;
84pub mod presence;
85pub mod publication_client;
86pub mod push;
87pub mod reginfo;
88pub mod registrar;
89pub mod subscribe;
90
91#[cfg(feature = "runtime")]
92pub use agent::{Config, Flow, UserAgent};
93pub use auth::{Algorithm, Challenge, Credentials};
94pub use challenge::{Authenticator, Presented, Reason, Verdict};
95#[cfg(feature = "runtime")]
96pub use error::{Error, Result};
97#[cfg(feature = "runtime")]
98pub use flows::{Attempt, Flows};
99pub use gruu::{Gruus, Kind as GruuKind};
100pub use history::{RetargetError, retarget};
101pub use outbound::{InstanceId, Keepalive, Power, RegId};
102pub use push::{Pending, PushService, Support};
103pub use registrar::{
104    Lease, Outcome, PathSet, Registered, Registration, RegistrationObservation,
105    RegistrationObservationError, ServiceRoute,
106};