Skip to main content

Handle

Struct Handle 

Source
pub struct Handle { /* private fields */ }
Expand description

A handle to a running endpoint.

Implementations§

Source§

impl Handle

Source

pub fn begin_drain(&self)

Close admission for outbound requests which can establish a dialog.

Existing transactions and requests carrying a To tag remain legal. The call dispatcher supplies the inbound half of this barrier; Self::shutdown remains the final ownership and task-join path.

Source

pub fn is_draining(&self) -> bool

Whether graceful drain has closed new-dialog admission.

Source

pub fn replace_source_admission( &self, prefixes: Vec<SourcePrefix>, ) -> Result<u64>

Replace the complete live source-admission set and return its generation.

An empty set refuses every new source. Use Self::clear_source_admission to allow all.

§Errors

Returns Error::SourceAdmissionCapacity without changing the active generation when prefixes exceeds Config::source_admission_limit.

Source

pub fn clear_source_admission(&self) -> u64

Clear source admission to allow all new sources and return the new generation.

Source

pub fn observe(&self, capacity: usize) -> Receiver<EndpointObservation>

Replace the optional bounded endpoint observer.

Producers never await this receiver. A full receiver drops and increments Counters::observation_dropped; dropping it simply detaches observation.

Source

pub fn local_addr(&self) -> SocketAddr

The address the endpoint is bound to.

Source

pub fn tls_addr(&self) -> Option<SocketAddr>

The address the TLS listener is bound to, if one was configured.

Needed because the TLS port may be 0 — “any” — and the caller cannot put a port it does not know into a Contact.

Source

pub fn reload_server_identity(&self, identity: Identity) -> Result<()>

Replace the identity selected by new TLS and WSS server handshakes (§3.6).

Validation happens before publication: the complete certificate chain and private key are first turned into one immutable crate::tls::ServerTls configuration. If they do not belong together, this returns a typed TLS error and the active configuration is untouched.

Existing connections are not renegotiated or closed. File watching and secret-store I/O belong to the host, which supplies an already parsed crate::tls::Identity here.

Source

pub fn ws_addr(&self) -> Option<SocketAddr>

The address the WebSocket listener is bound to, if one was configured.

Source

pub fn wss_addr(&self) -> Option<SocketAddr>

The address the secure WebSocket listener is bound to, if one was configured.

Source

pub fn advertised(&self) -> String

The host and port this endpoint tells peers to reach it on.

Not the same as Self::local_addr, and the difference matters wherever an address goes into a message. An endpoint bound to 0.0.0.0 has a local address that means “everywhere” to us and nothing to a peer; behind a NAT the local address is private. Contact and Via must carry this.

Source

pub async fn send(&self, request: Request, target: Target) -> Result<Responses>

Send a request, creating a client transaction.

A Via is added if the request has none — the transport owns that header, since only it knows the branch and where responses should come back to.

Source

pub async fn cancel_invite( &self, invitation: &mut Responses, reason: Option<Reason>, ) -> Result<CancelInviteOutcome>

Cancel the exact outgoing INVITE transaction represented by invitation (RFC 3261 §9.1).

The operation waits for a provisional response before creating CANCEL. A final response, timeout or transport failure that wins that race is returned without sending a late CANCEL. Events observed while waiting remain available from invitation.

§Errors

Returns Error::InvalidCancellation when invitation belongs to another method, lacks mandatory CANCEL identity, or already created a CANCEL transaction. Other errors are the ordinary request-policy, endpoint and build failures from creating the CANCEL transaction.

Source

pub async fn send_directly( &self, request: Request, target: Target, ) -> Result<()>

Send a request straight to the transport, with no transaction behind it.

For the one request that has no transaction of its own: the ACK to a 2xx. RFC 3261 §13.2.2.4 has it “passed to the transport layer directly for transmission”, and it is the UAC core — not a transaction — that resends it when a retransmitted 2xx arrives. Putting it in a transaction instead earns it Timer E retransmissions toward a response that will never come, and a timeout 32 seconds later for a call that is up and talking.

The Via is the caller’s business here: an ACK for a 2xx carries a new branch (§13.2.2.4 makes it a new transaction as far as any proxy is concerned), and only the caller knows the dialog it belongs to.

Returns once the bytes have been handed to the socket.

Source

pub async fn send_to_uri<R: Resolver + ?Sized>( &self, request: Request, uri: &Uri, resolver: &R, ) -> Result<Responses>

Resolve a URI (RFC 3263) and send to the resulting candidates in order.

A candidate that fails is not the request failing — the next one is tried, and only an exhausted list is an error. Each attempt is its own transaction with its own branch, which is what makes retrying legal: a transaction is bound to the destination it was created for.

Note what “fails” costs on an unreliable transport. A dead TCP peer refuses the connection and is known bad in milliseconds; a dead UDP peer says nothing at all, and the only way to learn it is dead is to let the transaction time out — 64·T1, or 32 seconds with the default constants. That is a property of UDP, not of this function, but it means a long candidate list over UDP is slow to exhaust. Callers that cannot afford it should use Handle::send with a candidate list they manage themselves.

Source

pub fn sent_by_for(&self, transport: TransportKind) -> String

The host and port this endpoint tells peers to reach it on over this transport.

Almost always its real host and port, as Self::advertised gives them. The exception is a WebSocket sipx dialled out on: RFC 7118 §5.2 says such a client has no listening port and must invent an unresolvable name, and advertising a real address instead would send a proxy off to a port that is not listening while the connection it should have used sits open. An endpoint that does listen for WebSocket connections is not that client, and keeps its own name.

Belongs in a Contact as much as in a Via, for the same reason: both are answers to “where do I reach you”.

Source

pub async fn respond( &self, key: &TransactionKey, response: Response, ) -> Result<()>

Send a response on a server transaction.

Returns once the response has been handed to the socket, not merely queued. The difference is invisible until a process answers a call and exits — then the queued version loses the response to the exit, and the caller sees a timeout for a call that was in fact refused. Every caller already assumed this; now it is true.

Source

pub async fn keepalive( &self, target: Target, within: Duration, ) -> Result<Option<SocketAddr>>

Keep a flow alive, and wait for the answer (RFC 5626 §4.4).

Over UDP this is a STUN Binding Request (§4.4.2) and the answer carries the reflexive address the far end saw — which is the reason to prefer STUN over a SIP request: §4.4.2 has a changed mapped address mean the flow has failed, so the keep-alive detects a NAT rebinding rather than only proving the socket still works. Over anything connection-oriented it is §4.4.1’s CRLFCRLF ping, and the pong carries nothing but its own arrival, so the answer is None.

within is how long to wait. §4.4.1 sets it at 10 seconds for the CRLF technique and requires a UA whose pong does not arrive to “treat the flow as failed”; the number is the caller’s because it is RFC 5626 policy rather than a property of the transport.

Sent over the same connection a request would take, which is the whole point: a ping on a second connection proves a flow nobody is using.

Source

pub async fn watch_unmatched( &self, capacity: usize, ) -> Result<Receiver<Unmatched>>

Watch for responses that match no client transaction (RFC 3261 §16.7).

Opt-in, and the reason it is opt-in is the whole design: a user agent has no answer for one of these — it either answers a request this endpoint did not send, or it arrived after its transaction was gone — and should not have to handle a case it cannot act on. A forwarding element is required to act on it, so it asks.

Until someone calls this, unmatched responses are logged and dropped exactly as before, and no channel exists to allocate into.

Calling it twice replaces the sink. Two watchers would each see some of the responses and neither would see all of them, which is a subtler failure than having none.

Source

pub fn shed(&self) -> ShedCounts

What this endpoint has dropped because the application was not keeping up.

Read straight from a shared counter rather than by asking the event loop, because the loop is busy in precisely the situation this counts. A metric that is unavailable exactly when it is interesting is not a metric.

Non-zero is not automatically a fault — shedding under load is a policy, and a 503 tells a peer something true. ShedCounts::acks is different: see its documentation.

Source

pub fn counters(&self) -> Counters

Everything this endpoint will say about itself (§12).

Synchronous, and deliberately so. Self::outstanding beside it is async and returns a Result because it asks the event loop; this reads shared atomics and cannot fail, because a snapshot that was unavailable while the loop was busy would be unavailable in exactly the situation an operator reaches for it.

A snapshot is not a consistent instant — see Counters for what that does and does not allow you to conclude.

Source

pub fn quic_addr(&self) -> Option<SocketAddr>

Address of the experimental QUIC listener, when configured.

Source

pub async fn outstanding(&self) -> Result<usize>

How many transactions and destinations the endpoint is still holding.

Exposed for the soak test in sipx-testkit, and worth exposing: a transaction store that leaks is a slow, quiet outage — the stack goes on working for hours and then stops, and by then the cause is a long way behind. This is the cheapest way to notice.

Note what a non-zero answer does not mean. RFC 3261 §17 keeps a completed transaction for Timer J, thirty-two seconds, so it can absorb a retransmission. Sampling before that has elapsed counts the specification.

Source

pub async fn settled(&self) -> Result<()>

Wait until the endpoint transaction layer has no client or server transaction.

This is a driver event, not a polling loop. The command is serialized with transaction creation and terminal outputs, so a caller can use it as the transaction half of a graceful-drain completion barrier.

Source

pub async fn shutdown(&self)

Stop the endpoint.

Trait Implementations§

Source§

impl Clone for Handle

Source§

fn clone(&self) -> Handle

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Handle

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,