1use std::collections::{HashMap, VecDeque};
9use std::net::SocketAddr;
10use std::sync::atomic::{AtomicBool, Ordering};
11use std::sync::{Arc, Mutex};
12
13use bytes::Bytes;
14use sipx_sip::build::RequestBuilder;
15use sipx_sip::transaction::{Dispatch, Output, Timer, TransactionKey, TransactionLayer, TuEvent};
16use sipx_sip::{
17 CSeq, Header, HeaderName, Limits, Message, Method, Reason, Request, Response, Timers,
18 parse_datagram,
19};
20use tokio::net::{TcpListener, UdpSocket};
21#[cfg(any(feature = "tls", feature = "ws"))]
22use tokio::sync::Semaphore;
23#[cfg(feature = "tls")]
24use tokio::sync::watch;
25use tokio::sync::{mpsc, oneshot};
26use tokio_util::sync::CancellationToken;
27use tokio_util::task::TaskTracker;
28
29use crate::capture::{Capture, CaptureConfig, Direction};
30use crate::counters::{Counters, Meters, ShedCounts};
31use crate::error::{Error, Result};
32use crate::nat::apply_received_and_rport;
33use crate::overload::{Controller as OverloadController, OverloadConfig};
34use crate::policy::{
35 ConnectionState, EndpointObservation, MessageDirection, MessageObservation, ObservationHub,
36 RequestPolicyDecision, RequestPolicyRef, SourceAdmission, SourcePrefix, TransactionClass,
37 connection_event, duplicate_policy_header, policy_header,
38};
39use crate::target::{ConnectionKey, Target, TransportKind, response_destination};
40use crate::tcp::{self, Pool, PoolConfig};
41use crate::timers::TimerQueue;
42
43const UDP_RECEIVE_BATCH: usize = 512;
45
46const UNKNOWN_PATH_MTU_REQUEST_LIMIT: usize = 1_300;
48const PATH_MTU_HEADROOM: usize = 200;
50
51const fn unreliable_request_limit(path_mtu: Option<usize>) -> usize {
52 match path_mtu {
53 Some(path_mtu) => path_mtu.saturating_sub(PATH_MTU_HEADROOM),
54 None => UNKNOWN_PATH_MTU_REQUEST_LIMIT,
55 }
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
60#[non_exhaustive]
61pub enum CleartextTransports {
62 None,
64 Udp,
66 Tcp,
68 #[default]
70 UdpAndTcp,
71}
72
73impl CleartextTransports {
74 const fn udp(self) -> bool {
75 matches!(self, Self::Udp | Self::UdpAndTcp)
76 }
77
78 const fn tcp(self) -> bool {
79 matches!(self, Self::Tcp | Self::UdpAndTcp)
80 }
81}
82
83#[derive(Debug, Clone)]
85pub struct Config {
86 pub bind: SocketAddr,
88 pub sent_by: String,
93 pub sent_by_port: Option<u16>,
99 pub timers: Timers,
101 pub limits: Limits,
103 pub capacity: usize,
105 pub handshake_limit: usize,
107 pub handshake_timeout: std::time::Duration,
109 pub path_mtu: Option<usize>,
115 pub cleartext: CleartextTransports,
117 #[cfg(feature = "tls")]
119 pub tls_client: Option<crate::tls::ClientTls>,
120 #[cfg(feature = "tls")]
125 pub tls_server: Option<(crate::tls::ServerTls, u16)>,
126 #[cfg(feature = "quic")]
128 pub quic_client: Option<crate::tls::ClientTls>,
129 #[cfg(feature = "quic")]
131 pub quic_server: Option<(crate::tls::ServerTls, u16)>,
132 #[cfg(feature = "ws")]
137 pub ws_server: Option<u16>,
138 #[cfg(feature = "wss")]
140 pub wss_server: Option<(crate::tls::ServerTls, u16)>,
141 #[cfg(feature = "ws")]
147 pub ws_keepalive: std::time::Duration,
148 pub unanswered_limit: std::time::Duration,
159 pub pool: PoolConfig,
161 pub capture: Option<CaptureConfig>,
166 pub overload: OverloadConfig,
169 pub request_policy: Option<RequestPolicyRef>,
171 pub source_admission_limit: usize,
175}
176
177impl Config {
178 #[must_use]
184 pub fn new(bind: SocketAddr) -> Self {
185 Self {
186 bind,
187 sent_by: bind.ip().to_string(),
188 sent_by_port: None,
189 timers: Timers::default(),
190 limits: Limits::datagram(),
191 capacity: 1024,
192 handshake_limit: 64,
193 handshake_timeout: std::time::Duration::from_secs(10),
194 path_mtu: None,
195 cleartext: CleartextTransports::default(),
196 #[cfg(feature = "tls")]
197 tls_client: None,
198 #[cfg(feature = "tls")]
199 tls_server: None,
200 #[cfg(feature = "quic")]
201 quic_client: None,
202 #[cfg(feature = "quic")]
203 quic_server: None,
204 #[cfg(feature = "ws")]
205 ws_server: None,
206 #[cfg(feature = "wss")]
207 wss_server: None,
208 capture: None,
209 overload: OverloadConfig::default(),
210 request_policy: None,
211 source_admission_limit: 1024,
212 #[cfg(feature = "ws")]
213 ws_keepalive: std::time::Duration::from_secs(25),
214 unanswered_limit: std::time::Duration::from_secs(180),
215 pool: PoolConfig::default(),
216 }
217 }
218
219 fn validate(&self) -> Result<()> {
220 let nonzero = |field| Error::InvalidConfig {
221 field,
222 reason: "must be non-zero",
223 };
224 if self.capacity == 0 {
225 return Err(nonzero("capacity"));
226 }
227 if self
228 .capture
229 .as_ref()
230 .is_some_and(|capture| capture.hep.is_some() && !capture.redact)
231 {
232 return Err(Error::InvalidConfig {
233 field: "capture.redact",
234 reason: "must be enabled when HEP export leaves the process",
235 });
236 }
237 if self.capacity > tokio::sync::Semaphore::MAX_PERMITS {
238 return Err(Error::InvalidConfig {
239 field: "capacity",
240 reason: "exceeds the runtime channel limit",
241 });
242 }
243 if self.pool.max_connections == 0 {
244 return Err(nonzero("pool.max_connections"));
245 }
246 if self.handshake_limit == 0 {
247 return Err(nonzero("handshake_limit"));
248 }
249 if self.handshake_timeout.is_zero() {
250 return Err(nonzero("handshake_timeout"));
251 }
252 if self.source_admission_limit == 0 {
253 return Err(nonzero("source_admission_limit"));
254 }
255 if self.overload.validity.is_zero() {
256 return Err(nonzero("overload.validity"));
257 }
258 if self.overload.validity.as_millis() == 0 {
259 return Err(Error::InvalidConfig {
260 field: "overload.validity",
261 reason: "must be at least one millisecond",
262 });
263 }
264 if self.overload.peer_limit == 0 {
265 return Err(nonzero("overload.peer_limit"));
266 }
267 if matches!(self.overload.feedback, crate::OverloadFeedback::Loss(value) if value > 100) {
268 return Err(Error::InvalidConfig {
269 field: "overload.feedback",
270 reason: "loss percentage must be between 0 and 100",
271 });
272 }
273 if self.overload.rate_tolerance_intervals >= self.overload.rate_priority_tolerance_intervals
274 {
275 return Err(Error::InvalidConfig {
276 field: "overload.rate_priority_tolerance_intervals",
277 reason: "must be greater than overload.rate_tolerance_intervals",
278 });
279 }
280 if self.cleartext == CleartextTransports::None && !self.has_other_signalling_listener() {
281 return Err(Error::InvalidConfig {
282 field: "cleartext",
283 reason: "at least one signalling listener must be configured",
284 });
285 }
286 #[cfg(feature = "ws")]
287 if self.ws_keepalive.is_zero() {
288 return Err(nonzero("ws_keepalive"));
289 }
290 Ok(())
291 }
292
293 fn has_other_signalling_listener(&self) -> bool {
294 #[allow(unused_mut)]
295 let mut configured = false;
296 #[cfg(feature = "tls")]
297 {
298 configured |= self.tls_server.is_some();
299 }
300 #[cfg(feature = "ws")]
301 {
302 configured |= self.ws_server.is_some();
303 }
304 #[cfg(feature = "wss")]
305 {
306 configured |= self.wss_server.is_some();
307 }
308 #[cfg(feature = "quic")]
309 {
310 configured |= self.quic_server.is_some();
311 }
312 configured
313 }
314}
315
316#[derive(Debug)]
317struct Background {
318 cancel: CancellationToken,
319 tasks: TaskTracker,
320 owns_lifetime: bool,
321}
322
323#[derive(Debug, Default)]
324struct ShutdownState {
325 complete: AtomicBool,
326 notify: tokio::sync::Notify,
327}
328
329impl ShutdownState {
330 async fn wait(&self) {
331 let notified = self.notify.notified();
332 tokio::pin!(notified);
333 notified.as_mut().enable();
334 if !self.complete.load(Ordering::SeqCst) {
335 notified.await;
336 }
337 }
338
339 fn complete(&self) {
340 self.complete.store(true, Ordering::SeqCst);
341 self.notify.notify_waiters();
342 }
343}
344
345impl Clone for Background {
346 fn clone(&self) -> Self {
347 Self {
348 cancel: self.cancel.clone(),
349 tasks: self.tasks.clone(),
350 owns_lifetime: false,
351 }
352 }
353}
354
355impl Background {
356 fn new() -> Self {
357 Self {
358 cancel: CancellationToken::new(),
359 tasks: TaskTracker::new(),
360 owns_lifetime: true,
361 }
362 }
363
364 fn spawn<F>(&self, future: F)
365 where
366 F: std::future::Future<Output = ()> + Send + 'static,
367 {
368 self.tasks.spawn(future);
369 }
370
371 async fn shutdown(&self) {
372 self.cancel.cancel();
373 self.tasks.close();
374 self.tasks.wait().await;
375 }
376}
377
378impl Drop for Background {
379 fn drop(&mut self) {
380 if self.owns_lifetime {
381 self.cancel.cancel();
384 self.tasks.close();
385 }
386 }
387}
388
389fn apply_network_source(message: Message, source: SocketAddr) -> Message {
390 match message {
391 Message::Request(mut request) => {
392 apply_received_and_rport(&mut request, source);
393 Message::Request(request)
394 }
395 response @ Message::Response(_) => response,
396 }
397}
398
399#[cfg(any(feature = "tls", feature = "ws"))]
400#[derive(Debug, Clone)]
401struct HandshakeRuntime {
402 deadline: std::time::Duration,
403 permits: Arc<Semaphore>,
404 owner: Background,
405 #[cfg(test)]
406 observations: Option<mpsc::UnboundedSender<HandshakeObservation>>,
407}
408
409#[cfg(feature = "tls")]
414#[derive(Debug, Clone)]
415struct ServerHandshakePolicy {
416 configured: crate::tls::ServerTls,
417 replacement: watch::Receiver<Option<crate::tls::ServerTls>>,
418}
419
420#[cfg(feature = "tls")]
421impl ServerHandshakePolicy {
422 fn new(
423 configured: crate::tls::ServerTls,
424 replacement: watch::Receiver<Option<crate::tls::ServerTls>>,
425 ) -> Self {
426 Self {
427 configured,
428 replacement,
429 }
430 }
431
432 fn acceptor(&self) -> tokio_rustls::TlsAcceptor {
433 self.replacement
436 .borrow()
437 .as_ref()
438 .unwrap_or(&self.configured)
439 .acceptor()
440 }
441}
442
443#[cfg(test)]
444#[derive(Debug, Clone, Copy, PartialEq, Eq)]
445enum HandshakeObservation {
446 Admitted,
447 Refused,
448}
449
450#[cfg(test)]
451fn observe_handshake(
452 observations: Option<&mpsc::UnboundedSender<HandshakeObservation>>,
453 observation: HandshakeObservation,
454) {
455 if let Some(observations) = observations {
456 let _ = observations.send(observation);
459 }
460}
461
462type Adopt = Box<dyn FnOnce(&mut Pool) + Send>;
467
468#[derive(Debug)]
470pub struct Incoming {
471 pub key: TransactionKey,
473 pub request: Request,
475 pub source: SocketAddr,
477 pub transport: TransportKind,
479 pub connection_generation: Option<u64>,
481}
482
483#[derive(Debug)]
485pub struct Responses {
486 rx: mpsc::Receiver<TuEvent>,
487 failures: mpsc::Receiver<Error>,
488 buffered: VecDeque<TuEvent>,
489 connection_generation: Option<u64>,
490 invitation: Option<Box<InviteCancellationState>>,
491}
492
493#[derive(Debug, Clone)]
494struct InviteCancellationContext {
495 request: Request,
496 target: Target,
497}
498
499#[derive(Debug, Clone, Copy)]
500struct TcpFallback {
501 size: usize,
502 limit: usize,
503}
504
505impl TcpFallback {
506 fn unavailable(self, source: Error) -> Error {
507 Error::TcpFallbackUnavailable {
508 size: self.size,
509 limit: self.limit,
510 source: Box::new(source),
511 }
512 }
513}
514
515#[derive(Debug, Clone)]
516struct InviteCancellationState {
517 key: TransactionKey,
518 context: InviteCancellationContext,
519 observation: InviteObservation,
520 cancel_created: bool,
521}
522
523#[derive(Debug, Clone)]
524enum InviteObservation {
525 Awaiting,
526 Provisional,
527 Final(Box<Response>),
528 Timeout,
529 TransportError,
530}
531
532#[derive(Debug)]
534#[non_exhaustive]
535pub enum CancelInviteOutcome {
536 Sent(Box<InviteCancellation>),
538 FinalResponse {
540 invite: TransactionKey,
542 response: Response,
544 },
545 InviteTimeout {
547 invite: TransactionKey,
549 },
550 InviteTransportError {
552 invite: TransactionKey,
554 error: Option<Error>,
556 },
557}
558
559#[derive(Debug)]
561pub struct InviteCancellation {
562 invite: TransactionKey,
563 transaction: TransactionKey,
564 responses: Responses,
565}
566
567#[derive(Debug)]
569#[non_exhaustive]
570pub enum CancelTransactionOutcome {
571 FinalResponse(Response),
573 Timeout,
575 TransportError {
577 error: Option<Error>,
579 },
580}
581
582impl InviteCancellation {
583 #[must_use]
585 pub fn invite_key(&self) -> &TransactionKey {
586 &self.invite
587 }
588
589 #[must_use]
591 pub fn transaction_key(&self) -> &TransactionKey {
592 &self.transaction
593 }
594
595 pub async fn outcome(&mut self) -> CancelTransactionOutcome {
597 while let Some(event) = self.responses.next().await {
598 match event {
599 TuEvent::Response(response) if response.status.is_final() => {
600 return CancelTransactionOutcome::FinalResponse(*response);
601 }
602 TuEvent::Timeout => return CancelTransactionOutcome::Timeout,
603 TuEvent::TransportError => {
604 return CancelTransactionOutcome::TransportError {
605 error: self.responses.take_transport_error(),
606 };
607 }
608 _ => {}
609 }
610 }
611 CancelTransactionOutcome::TransportError {
612 error: Some(Error::EndpointClosed),
613 }
614 }
615}
616
617impl Responses {
618 #[must_use]
620 pub fn transaction_key(&self) -> Option<&TransactionKey> {
621 self.invitation.as_ref().map(|state| &state.key)
622 }
623
624 #[must_use]
626 pub fn connection_generation(&self) -> Option<u64> {
627 self.connection_generation
628 }
629
630 pub async fn next(&mut self) -> Option<TuEvent> {
632 let event = match self.buffered.pop_front() {
633 Some(event) => Some(event),
634 None => self.rx.recv().await,
635 };
636 if let Some(event) = &event {
637 self.observe_invite(event);
638 }
639 event
640 }
641
642 pub fn take_transport_error(&mut self) -> Option<Error> {
648 self.failures.try_recv().ok()
649 }
650
651 pub async fn peek(&mut self) -> Option<&TuEvent> {
656 if self.buffered.is_empty()
657 && let Some(event) = self.rx.recv().await
658 {
659 self.observe_invite(&event);
660 self.buffered.push_back(event);
661 }
662 self.buffered.front()
663 }
664
665 pub async fn final_response(&mut self) -> Option<Response> {
671 while let Some(event) = self.next().await {
672 if let TuEvent::Response(response) = event
673 && response.status.is_final()
674 {
675 return Some(*response);
676 }
677 }
678 None
679 }
680
681 fn observe_invite(&mut self, event: &TuEvent) {
682 let Some(invitation) = self.invitation.as_mut() else {
683 return;
684 };
685 invitation.observation = match event {
686 TuEvent::Response(response) if response.status.is_final() => {
687 InviteObservation::Final(Box::new((**response).clone()))
688 }
689 TuEvent::Response(_) => InviteObservation::Provisional,
690 TuEvent::Timeout => InviteObservation::Timeout,
691 TuEvent::TransportError => InviteObservation::TransportError,
692 TuEvent::Request(_) | TuEvent::Ack(_) => return,
693 };
694 }
695
696 async fn cancellation_precondition(&mut self) -> Result<InviteObservation> {
697 loop {
698 let observation = &self
699 .invitation
700 .as_ref()
701 .ok_or(Error::InvalidCancellation {
702 reason: "the response stream does not belong to an INVITE",
703 })?
704 .observation;
705 match observation {
706 InviteObservation::Awaiting => {}
707 observed => return Ok(observed.clone()),
708 }
709 let Some(event) = self.rx.recv().await else {
710 return Err(Error::EndpointClosed);
711 };
712 self.observe_invite(&event);
713 self.buffered.push_back(event);
714 }
715 }
716}
717
718#[derive(Debug)]
719enum Command {
720 Request {
721 request: Box<Request>,
722 target: Target,
723 tcp_fallback: Option<TcpFallback>,
724 events: mpsc::Sender<TuEvent>,
725 failures: mpsc::Sender<Error>,
726 reply: oneshot::Sender<Result<(TransactionKey, Option<u64>)>>,
727 },
728 Respond {
729 key: TransactionKey,
730 response: Box<Response>,
731 sent: oneshot::Sender<Result<()>>,
734 },
735 Direct {
737 request: Box<Request>,
738 target: Target,
739 tcp_fallback: Option<TcpFallback>,
740 sent: oneshot::Sender<Result<()>>,
742 },
743 Keepalive {
746 target: Target,
747 answered: oneshot::Sender<Result<Option<SocketAddr>>>,
750 },
751 WatchUnmatched(mpsc::Sender<Unmatched>),
753 Outstanding(oneshot::Sender<usize>),
755 Settled(oneshot::Sender<()>),
757 Shutdown,
759}
760
761#[derive(Debug)]
762struct ClientSink {
763 events: mpsc::Sender<TuEvent>,
764 failures: mpsc::Sender<Error>,
765}
766
767#[derive(Debug, Clone)]
778pub struct Unmatched {
779 pub response: Response,
781 pub source: SocketAddr,
783 pub transport: TransportKind,
785}
786
787#[derive(Debug, Clone)]
789pub struct Handle {
790 commands: mpsc::Sender<Command>,
791 shutdown: Arc<ShutdownState>,
792 draining: Arc<AtomicBool>,
794 local_addr: SocketAddr,
795 meters: Arc<Meters>,
798 admission: Arc<SourceAdmission>,
799 observations: Arc<ObservationHub>,
800 request_policy: Option<RequestPolicyRef>,
801 #[cfg(feature = "tls")]
802 tls_addr: Option<SocketAddr>,
803 #[cfg(feature = "tls")]
808 server_identity: Option<watch::Sender<Option<crate::tls::ServerTls>>>,
809 #[cfg(feature = "ws")]
810 ws_addr: Option<SocketAddr>,
811 #[cfg(feature = "wss")]
812 wss_addr: Option<SocketAddr>,
813 #[cfg(feature = "quic")]
814 quic_addr: Option<SocketAddr>,
815 #[cfg(feature = "ws")]
820 ws_sent_by: Arc<str>,
821 advertise_overload: bool,
822 sent_by: Arc<String>,
823 sent_by_port: u16,
824 unreliable_request_limit: usize,
825}
826
827impl Handle {
828 pub fn begin_drain(&self) {
834 self.draining.store(true, Ordering::SeqCst);
835 }
836
837 #[must_use]
839 pub fn is_draining(&self) -> bool {
840 self.draining.load(Ordering::SeqCst)
841 }
842
843 pub fn replace_source_admission(&self, prefixes: Vec<SourcePrefix>) -> Result<u64> {
852 self.admission.replace(prefixes)
853 }
854
855 pub fn clear_source_admission(&self) -> u64 {
857 self.admission.clear()
858 }
859
860 #[must_use]
865 pub fn observe(&self, capacity: usize) -> mpsc::Receiver<EndpointObservation> {
866 self.observations.subscribe(capacity)
867 }
868
869 fn apply_request_policy(&self, request: &mut Request, target: &Target) -> Result<()> {
870 let Some(policy) = &self.request_policy else {
871 return Ok(());
872 };
873 match policy.decide(request, target) {
874 RequestPolicyDecision::Allow => Ok(()),
875 RequestPolicyDecision::Reject(reason) => Err(Error::PolicyRejected { reason }),
876 RequestPolicyDecision::AddHeaders(headers) => {
877 for header in headers {
878 let (semantic, allowed) = policy_header(header.name());
879 if !allowed || duplicate_policy_header(request, &semantic) {
880 return Err(Error::ProtectedPolicyHeader {
881 name: String::from_utf8_lossy(semantic.canonical()).into_owned(),
882 });
883 }
884 request.headers.push(header);
885 }
886 Ok(())
887 }
888 }
889 }
890
891 #[must_use]
893 pub fn local_addr(&self) -> SocketAddr {
894 self.local_addr
895 }
896
897 #[cfg(feature = "tls")]
902 #[must_use]
903 pub fn tls_addr(&self) -> Option<SocketAddr> {
904 self.tls_addr
905 }
906
907 #[cfg(feature = "tls")]
916 pub fn reload_server_identity(&self, identity: crate::tls::Identity) -> Result<()> {
917 let Some(publication) = &self.server_identity else {
918 return Err(Error::InvalidConfig {
919 field: "server_identity",
920 reason: "reload requires a configured TLS or WSS server listener",
921 });
922 };
923 let replacement = crate::tls::ServerTls::new(identity).map_err(|error| {
924 tracing::warn!(%error, "TLS server identity reload refused");
925 Error::Tls(error)
926 })?;
927 publication.send(Some(replacement)).map_err(|_| {
928 tracing::warn!("TLS server identity reload refused because no secure listener remains");
929 Error::InvalidConfig {
930 field: "server_identity",
931 reason: "no TLS or WSS server listener is running",
932 }
933 })?;
934 tracing::info!("TLS server identity reloaded for new TLS and WSS handshakes");
935 Ok(())
936 }
937
938 #[cfg(feature = "ws")]
940 #[must_use]
941 pub fn ws_addr(&self) -> Option<SocketAddr> {
942 self.ws_addr
943 }
944
945 #[cfg(feature = "wss")]
947 #[must_use]
948 pub fn wss_addr(&self) -> Option<SocketAddr> {
949 self.wss_addr
950 }
951
952 #[must_use]
959 pub fn advertised(&self) -> String {
960 format!("{}:{}", self.sent_by, self.sent_by_port)
961 }
962
963 pub async fn send(&self, mut request: Request, target: Target) -> Result<Responses> {
968 if self.is_draining() && starts_dialog(&request) {
969 return Err(Error::EndpointDraining);
970 }
971 let mut target = target;
972 self.apply_request_policy(&mut request, &target)?;
973 let generated_branch = if request.headers.get(&HeaderName::Via).is_none() {
974 let branch = new_branch();
975 let via = format!(
976 "SIP/2.0/{} {};rport;branch={}",
977 target.transport.as_str(),
978 self.sent_by_for(target.transport),
979 branch
980 );
981 let header = Header::build(HeaderName::Via, Bytes::from(via))?;
982 request.headers.push_front(header);
983 Some(branch)
984 } else {
985 None
986 };
987 if self.advertise_overload {
988 crate::overload::advertise(&mut request);
989 }
990 let tcp_fallback = self.select_tcp_for_oversized_request(
991 &mut request,
992 &mut target,
993 generated_branch.as_deref(),
994 )?;
995 let invitation = (request.method == Method::Invite).then(|| InviteCancellationContext {
996 request: request.clone(),
997 target: target.clone(),
998 });
999
1000 let (events_tx, events_rx) = mpsc::channel(32);
1001 let (failures_tx, failures_rx) = mpsc::channel(1);
1002 let (reply_tx, reply_rx) = oneshot::channel();
1003 self.commands
1004 .send(Command::Request {
1005 request: Box::new(request),
1006 target,
1007 tcp_fallback,
1008 events: events_tx,
1009 failures: failures_tx,
1010 reply: reply_tx,
1011 })
1012 .await
1013 .map_err(|_| Error::EndpointClosed)?;
1014 let (key, connection_generation) = reply_rx.await.map_err(|_| Error::EndpointClosed)??;
1015 let invitation = invitation.map(|context| {
1016 Box::new(InviteCancellationState {
1017 key,
1018 context,
1019 observation: InviteObservation::Awaiting,
1020 cancel_created: false,
1021 })
1022 });
1023 Ok(Responses {
1024 rx: events_rx,
1025 failures: failures_rx,
1026 buffered: VecDeque::new(),
1027 connection_generation,
1028 invitation,
1029 })
1030 }
1031
1032 pub async fn cancel_invite(
1044 &self,
1045 invitation: &mut Responses,
1046 reason: Option<Reason>,
1047 ) -> Result<CancelInviteOutcome> {
1048 let state = invitation
1049 .invitation
1050 .as_ref()
1051 .ok_or(Error::InvalidCancellation {
1052 reason: "the response stream does not belong to an INVITE",
1053 })?;
1054 if state.cancel_created {
1055 return Err(Error::InvalidCancellation {
1056 reason: "a CANCEL transaction was already created for this INVITE",
1057 });
1058 }
1059 let context = state.context.clone();
1060
1061 let invite = state.key.clone();
1062 match invitation.cancellation_precondition().await? {
1063 InviteObservation::Provisional => {}
1064 InviteObservation::Final(response) => {
1065 return Ok(CancelInviteOutcome::FinalResponse {
1066 invite,
1067 response: *response,
1068 });
1069 }
1070 InviteObservation::Timeout => {
1071 return Ok(CancelInviteOutcome::InviteTimeout { invite });
1072 }
1073 InviteObservation::TransportError => {
1074 return Ok(CancelInviteOutcome::InviteTransportError {
1075 invite,
1076 error: invitation.take_transport_error(),
1077 });
1078 }
1079 InviteObservation::Awaiting => {
1080 return Err(Error::InvalidCancellation {
1081 reason: "the INVITE cancellation precondition did not resolve",
1082 });
1083 }
1084 }
1085
1086 let request = cancel_request(&context.request, reason)?;
1087 let transaction = TransactionKey::from_sent_request(&request).ok_or(Error::NoVia)?;
1088 if let Some(state) = invitation.invitation.as_mut() {
1091 state.cancel_created = true;
1092 }
1093 let responses = self.send(request, context.target).await?;
1094 Ok(CancelInviteOutcome::Sent(Box::new(InviteCancellation {
1095 invite,
1096 transaction,
1097 responses,
1098 })))
1099 }
1100
1101 pub async fn send_directly(&self, mut request: Request, target: Target) -> Result<()> {
1115 if self.is_draining() && starts_dialog(&request) {
1116 return Err(Error::EndpointDraining);
1117 }
1118 let mut target = target;
1119 self.apply_request_policy(&mut request, &target)?;
1120 if self.advertise_overload {
1121 crate::overload::advertise(&mut request);
1122 }
1123 let tcp_fallback =
1124 self.select_tcp_for_oversized_request(&mut request, &mut target, None)?;
1125 let (sent_tx, sent_rx) = oneshot::channel();
1126 self.commands
1127 .send(Command::Direct {
1128 request: Box::new(request),
1129 target,
1130 tcp_fallback,
1131 sent: sent_tx,
1132 })
1133 .await
1134 .map_err(|_| Error::EndpointClosed)?;
1135 sent_rx.await.map_err(|_| Error::EndpointClosed)?
1136 }
1137
1138 fn select_tcp_for_oversized_request(
1139 &self,
1140 request: &mut Request,
1141 target: &mut Target,
1142 generated_branch: Option<&str>,
1143 ) -> Result<Option<TcpFallback>> {
1144 if target.transport != TransportKind::Udp {
1145 return Ok(None);
1146 }
1147 let size = Message::Request(request.clone()).to_bytes().len();
1148 if size <= self.unreliable_request_limit {
1149 return Ok(None);
1150 }
1151
1152 let fallback = TcpFallback {
1153 size,
1154 limit: self.unreliable_request_limit,
1155 };
1156 target.transport = TransportKind::Tcp;
1157 if let Some(branch) = generated_branch {
1158 let _owned_via = request.headers.remove_first(&HeaderName::Via);
1159 let via = format!(
1160 "SIP/2.0/TCP {};rport;branch={branch}",
1161 self.sent_by_for(TransportKind::Tcp)
1162 );
1163 request
1164 .headers
1165 .push_front(Header::build(HeaderName::Via, Bytes::from(via))?);
1166 }
1167 self.meters.oversized_request_tcp_fallback();
1168 tracing::info!(
1169 peer = %target.addr,
1170 size,
1171 limit = self.unreliable_request_limit,
1172 "oversized UDP request switched to TCP"
1173 );
1174 Ok(Some(fallback))
1175 }
1176
1177 pub async fn send_to_uri<R: crate::resolve::Resolver + ?Sized>(
1191 &self,
1192 request: Request,
1193 uri: &sipx_sip::Uri,
1194 resolver: &R,
1195 ) -> Result<Responses> {
1196 let candidates = crate::resolve::resolve(uri, resolver, &mut crate::resolve::OsRng);
1197 if candidates.is_empty() {
1198 return Err(Error::Unresolvable(uri.to_bytes().to_vec()));
1199 }
1200
1201 let mut last = Err(Error::Unresolvable(uri.to_bytes().to_vec()));
1202 for target in candidates {
1203 let mut responses = self.send(request.clone(), target).await?;
1204 match responses.peek().await {
1207 Some(TuEvent::TransportError) => last = Err(Error::EndpointClosed),
1210 Some(TuEvent::Timeout) => {
1211 last = Err(Error::Unresolvable(uri.to_bytes().to_vec()));
1212 }
1213 _ => return Ok(responses),
1214 }
1215 }
1216 last
1217 }
1218
1219 #[must_use]
1231 pub fn sent_by_for(&self, transport: TransportKind) -> String {
1232 #[cfg(feature = "ws")]
1233 if matches!(transport, TransportKind::Ws | TransportKind::Wss) && !self.listens_for_ws() {
1234 return self.ws_sent_by.to_string();
1235 }
1236 #[cfg(feature = "tls")]
1240 if matches!(transport, TransportKind::Tls)
1241 && let Some(addr) = self.tls_addr
1242 {
1243 return format!("{}:{}", self.sent_by, addr.port());
1244 }
1245 #[cfg(feature = "quic")]
1246 if transport == TransportKind::Quic
1247 && let Some(addr) = self.quic_addr
1248 {
1249 return format!("{}:{}", self.sent_by, addr.port());
1250 }
1251 let _ = transport;
1254 format!("{}:{}", self.sent_by, self.sent_by_port)
1255 }
1256
1257 #[cfg(feature = "ws")]
1258 fn listens_for_ws(&self) -> bool {
1259 #[cfg(feature = "wss")]
1260 if self.wss_addr.is_some() {
1261 return true;
1262 }
1263 self.ws_addr.is_some()
1264 }
1265
1266 pub async fn respond(&self, key: &TransactionKey, response: Response) -> Result<()> {
1273 let (sent, delivered) = oneshot::channel();
1274 self.commands
1275 .send(Command::Respond {
1276 key: key.clone(),
1277 response: Box::new(response),
1278 sent,
1279 })
1280 .await
1281 .map_err(|_| Error::EndpointClosed)?;
1282 delivered.await.map_err(|_| Error::EndpointClosed)?
1283 }
1284
1285 pub async fn keepalive(
1301 &self,
1302 target: Target,
1303 within: std::time::Duration,
1304 ) -> Result<Option<SocketAddr>> {
1305 let (answered_tx, answered_rx) = oneshot::channel();
1306 self.commands
1307 .send(Command::Keepalive {
1308 target,
1309 answered: answered_tx,
1310 })
1311 .await
1312 .map_err(|_| Error::EndpointClosed)?;
1313 match tokio::time::timeout(within, answered_rx).await {
1314 Ok(Ok(result)) => result,
1315 Ok(Err(_)) => Err(Error::EndpointClosed),
1317 Err(_) => Err(Error::KeepaliveUnanswered),
1319 }
1320 }
1321
1322 pub async fn watch_unmatched(&self, capacity: usize) -> Result<mpsc::Receiver<Unmatched>> {
1335 let (tx, rx) = mpsc::channel(capacity.max(1));
1336 self.commands
1337 .send(Command::WatchUnmatched(tx))
1338 .await
1339 .map_err(|_| Error::EndpointClosed)?;
1340 Ok(rx)
1341 }
1342
1343 #[must_use]
1352 pub fn shed(&self) -> ShedCounts {
1353 self.meters.snapshot().shed
1354 }
1355
1356 #[must_use]
1366 pub fn counters(&self) -> Counters {
1367 self.meters.snapshot()
1368 }
1369
1370 #[cfg(feature = "quic")]
1372 #[must_use]
1373 pub fn quic_addr(&self) -> Option<SocketAddr> {
1374 self.quic_addr
1375 }
1376
1377 pub async fn outstanding(&self) -> Result<usize> {
1387 let (tx, rx) = oneshot::channel();
1388 self.commands
1389 .send(Command::Outstanding(tx))
1390 .await
1391 .map_err(|_| Error::EndpointClosed)?;
1392 rx.await.map_err(|_| Error::EndpointClosed)
1393 }
1394
1395 pub async fn settled(&self) -> Result<()> {
1401 let (tx, rx) = oneshot::channel();
1402 self.commands
1403 .send(Command::Settled(tx))
1404 .await
1405 .map_err(|_| Error::EndpointClosed)?;
1406 rx.await.map_err(|_| Error::EndpointClosed)
1407 }
1408
1409 pub async fn shutdown(&self) {
1411 if !self.shutdown.complete.load(Ordering::SeqCst) {
1412 let _ = self.commands.send(Command::Shutdown).await;
1415 self.shutdown.wait().await;
1416 }
1417 }
1418}
1419
1420fn starts_dialog(request: &Request) -> bool {
1421 matches!(
1422 request.method,
1423 Method::Invite | Method::Subscribe | Method::Refer
1424 ) && request
1425 .headers
1426 .typed::<sipx_sip::headers::To>()
1427 .and_then(std::result::Result::ok)
1428 .and_then(|to| to.tag().map(<[u8]>::to_vec))
1429 .is_none()
1430}
1431
1432fn branch_with_rng<R>(rng: &mut R) -> String
1433where
1434 R: rand::CryptoRng + ?Sized,
1435{
1436 let value = rand::RngCore::next_u64(rng);
1437 format!("z9hG4bK{value:016x}")
1438}
1439
1440#[must_use]
1445pub fn new_branch() -> String {
1446 branch_with_rng(&mut rand::rng())
1447}
1448
1449fn cancellation_header(invite: &Request, name: &HeaderName, reason: &'static str) -> Result<Bytes> {
1450 invite
1451 .headers
1452 .value(name)
1453 .map(|value| Bytes::from(value.into_owned()))
1454 .ok_or(Error::InvalidCancellation { reason })
1455}
1456
1457fn cancel_request(invite: &Request, reason: Option<Reason>) -> Result<Request> {
1459 if invite.method != Method::Invite {
1460 return Err(Error::InvalidCancellation {
1461 reason: "the stored request is not an INVITE",
1462 });
1463 }
1464
1465 let mut builder = RequestBuilder::new(Method::Cancel, invite.uri.clone()).header(
1466 HeaderName::Via,
1467 cancellation_header(invite, &HeaderName::Via, "the INVITE has no Via")?,
1468 )?;
1469 for route in invite.headers.get_all(&HeaderName::Route) {
1470 builder = builder.header(HeaderName::Route, Bytes::from(route.value().into_owned()))?;
1471 }
1472 for (name, missing) in [
1473 (HeaderName::To, "the INVITE has no To header"),
1474 (HeaderName::From, "the INVITE has no From header"),
1475 (HeaderName::CallId, "the INVITE has no Call-ID header"),
1476 ] {
1477 let value = cancellation_header(invite, &name, missing)?;
1478 builder = builder.header(name, value)?;
1479 }
1480 let sequence = invite
1481 .headers
1482 .typed::<CSeq>()
1483 .and_then(std::result::Result::ok)
1484 .filter(|cseq| cseq.method == Method::Invite)
1485 .map(|cseq| cseq.sequence)
1486 .ok_or(Error::InvalidCancellation {
1487 reason: "the INVITE has no valid INVITE CSeq",
1488 })?;
1489 builder = builder.cseq(sequence, &Method::Cancel)?.max_forwards(70);
1490 if let Some(reason) = reason {
1491 builder = builder.header(HeaderName::Reason, reason.to_bytes())?;
1492 }
1493 Ok(builder.build())
1494}
1495
1496#[allow(
1500 clippy::too_many_lines,
1501 reason = "one ordered assembly keeps validation, every bind and task ownership auditable"
1502)]
1503pub async fn bind(config: Config) -> Result<(Handle, mpsc::Receiver<Incoming>)> {
1504 config.validate()?;
1505 let CleartextBindings {
1506 udp: socket,
1507 tcp: listener,
1508 local_addr: cleartext_addr,
1509 } = bind_cleartext(&config).await?;
1510 let background = Background::new();
1511 let meters = Arc::new(Meters::default());
1512 let admission = Arc::new(SourceAdmission::new(config.source_admission_limit));
1513 let observations = Arc::new(ObservationHub::new(Arc::clone(&meters)));
1514 #[cfg(any(feature = "tls", feature = "ws"))]
1515 let handshakes = HandshakeRuntime {
1516 deadline: config.handshake_timeout,
1517 permits: Arc::new(Semaphore::new(config.handshake_limit)),
1518 owner: background.clone(),
1519 #[cfg(test)]
1520 observations: None,
1521 };
1522 let (adopt_tx, adopt_rx) = mpsc::channel::<Adopt>(64);
1529
1530 #[cfg(feature = "tls")]
1534 let (server_identity_tx, server_identity_rx) =
1535 watch::channel::<Option<crate::tls::ServerTls>>(None);
1536 #[cfg(feature = "tls")]
1537 let has_reloadable_server = config.tls_server.is_some() || {
1538 #[cfg(feature = "wss")]
1539 {
1540 config.wss_server.is_some()
1541 }
1542 #[cfg(not(feature = "wss"))]
1543 {
1544 false
1545 }
1546 };
1547
1548 #[cfg(feature = "tls")]
1549 let secure_addr = match config.tls_server.clone() {
1550 Some((server, port)) => Some(
1551 listen_tls(
1552 config.bind.ip(),
1553 port,
1554 ServerHandshakePolicy::new(server, server_identity_rx.clone()),
1555 &adopt_tx,
1556 &handshakes,
1557 Arc::clone(&admission),
1558 Arc::clone(&meters),
1559 )
1560 .await?,
1561 ),
1562 None => None,
1563 };
1564 #[cfg(feature = "ws")]
1565 let upgrade_addr = match config.ws_server {
1566 Some(port) => Some(
1567 listen_ws(
1568 config.bind.ip(),
1569 port,
1570 config.ws_keepalive,
1571 config.limits,
1572 &adopt_tx,
1573 &handshakes,
1574 Arc::clone(&admission),
1575 Arc::clone(&meters),
1576 )
1577 .await?,
1578 ),
1579 None => None,
1580 };
1581 #[cfg(feature = "wss")]
1582 let secure_upgrade_addr = match config.wss_server.clone() {
1583 Some((server, port)) => Some(
1584 listen_wss(
1585 config.bind.ip(),
1586 port,
1587 ServerHandshakePolicy::new(server, server_identity_rx.clone()),
1588 config.ws_keepalive,
1589 config.limits,
1590 &adopt_tx,
1591 &handshakes,
1592 Arc::clone(&admission),
1593 Arc::clone(&meters),
1594 )
1595 .await?,
1596 ),
1597 None => None,
1598 };
1599 #[cfg(feature = "quic")]
1600 let quic_endpoint = if config.quic_client.is_some() || config.quic_server.is_some() {
1601 let port = config.quic_server.as_ref().map_or(0, |(_, port)| *port);
1602 Some(crate::quic::endpoint(
1603 config.bind.ip(),
1604 port,
1605 config.quic_client.as_ref(),
1606 config.quic_server.as_ref().map(|(server, _)| server),
1607 )?)
1608 } else {
1609 None
1610 };
1611 #[cfg(feature = "quic")]
1612 let quic_addr = match (&quic_endpoint, &config.quic_server) {
1613 (Some(endpoint), Some(_)) => {
1614 let addr = endpoint.local_addr()?;
1615 listen_quic(
1616 endpoint.clone(),
1617 &adopt_tx,
1618 &handshakes,
1619 Arc::clone(&admission),
1620 Arc::clone(&meters),
1621 );
1622 Some(addr)
1623 }
1624 _ => None,
1625 };
1626
1627 #[allow(unused_mut)]
1628 let mut primary_addr = cleartext_addr;
1629 #[cfg(feature = "tls")]
1630 if primary_addr.is_none() {
1631 primary_addr = secure_addr;
1632 }
1633 #[cfg(feature = "ws")]
1634 if primary_addr.is_none() {
1635 primary_addr = upgrade_addr;
1636 }
1637 #[cfg(feature = "wss")]
1638 if primary_addr.is_none() {
1639 primary_addr = secure_upgrade_addr;
1640 }
1641 #[cfg(feature = "quic")]
1642 if primary_addr.is_none() {
1643 primary_addr = quic_addr;
1644 }
1645 let local_addr = primary_addr.ok_or(Error::InvalidConfig {
1646 field: "cleartext",
1647 reason: "at least one signalling listener must be configured",
1648 })?;
1649 let sent_by_port = match config.sent_by_port {
1652 Some(port) if port != 0 => port,
1653 _ => local_addr.port(),
1654 };
1655
1656 let (commands_tx, commands_rx) = mpsc::channel(config.capacity);
1657 let (incoming_tx, incoming_rx) = mpsc::channel(config.capacity);
1658 let shutdown = Arc::new(ShutdownState::default());
1659
1660 let handle = Handle {
1661 commands: commands_tx,
1662 shutdown: Arc::clone(&shutdown),
1663 draining: Arc::new(AtomicBool::new(false)),
1664 local_addr,
1665 meters: Arc::clone(&meters),
1666 admission: Arc::clone(&admission),
1667 observations: Arc::clone(&observations),
1668 request_policy: config.request_policy.clone(),
1669 #[cfg(feature = "tls")]
1670 tls_addr: secure_addr,
1671 #[cfg(feature = "tls")]
1672 server_identity: has_reloadable_server.then_some(server_identity_tx),
1673 #[cfg(feature = "ws")]
1674 ws_addr: upgrade_addr,
1675 #[cfg(feature = "wss")]
1676 wss_addr: secure_upgrade_addr,
1677 #[cfg(feature = "quic")]
1678 quic_addr,
1679 #[cfg(feature = "ws")]
1680 ws_sent_by: Arc::from(crate::ws::invented_sent_by()),
1681 advertise_overload: config.overload.advertise,
1682 sent_by: Arc::new(config.sent_by.clone()),
1683 sent_by_port,
1684 unreliable_request_limit: unreliable_request_limit(config.path_mtu),
1685 };
1686
1687 let capture = match &config.capture {
1690 Some(wanted) => Some(
1691 Capture::start(wanted, Arc::clone(&meters)).map_err(|source| Error::Capture {
1692 path: wanted.path.display().to_string(),
1693 source,
1694 })?,
1695 ),
1696 None => None,
1697 };
1698
1699 let (net_tx, net_rx) = mpsc::channel(config.capacity);
1700 let (udp_tx, udp_rx) = mpsc::channel(config.capacity);
1701 let socket = socket.map(Arc::new);
1702 if let Some(socket) = &socket {
1703 background.spawn(receive_udp_until(
1704 Arc::clone(socket),
1705 udp_tx,
1706 background.cancel.clone(),
1707 ));
1708 }
1709 let (accept_tx, accept_rx) = mpsc::channel(64);
1710 if let Some(listener) = listener {
1711 let cancel = background.cancel.clone();
1712 background.spawn(accept_tcp_until(
1713 listener,
1714 accept_tx,
1715 cancel,
1716 Arc::clone(&admission),
1717 Arc::clone(&meters),
1718 ));
1719 }
1720
1721 let driver = Driver {
1722 socket,
1723 udp: udp_rx,
1724 layer: TransactionLayer::new(config.timers),
1725 timers: TimerQueue::new(),
1726 destinations: HashMap::new(),
1727 transaction_generations: HashMap::new(),
1728 unanswered_since: HashMap::new(),
1729 reconnect: HashMap::new(),
1730 tcp_fallbacks: HashMap::new(),
1731 unanswered_limit: config.unanswered_limit,
1732 overload: OverloadController::new(
1733 config.overload.rate_tolerance_intervals,
1734 config.overload.rate_priority_tolerance_intervals,
1735 config.overload.peer_limit,
1736 ),
1737 overload_config: config.overload.clone(),
1738 overload_epoch: tokio::time::Instant::now(),
1739 overload_sequence: 0,
1740 server_overloaded_until: None,
1741 clients: HashMap::new(),
1742 incoming: incoming_tx,
1743 commands: commands_rx,
1744 net: net_rx,
1745 accepts: accept_rx,
1746 adopts: adopt_rx,
1747 _adopt: adopt_tx,
1748 #[cfg(feature = "tls")]
1749 tls_client: config.tls_client.clone(),
1750 #[cfg(feature = "ws")]
1751 ws_keepalive: config.ws_keepalive,
1752 #[cfg(feature = "quic")]
1753 quic_client: config.quic_client.clone(),
1754 #[cfg(feature = "quic")]
1755 quic_endpoint,
1756 pool: Pool::new_observed(
1757 config.pool,
1758 config.limits,
1759 net_tx,
1760 Arc::clone(&observations),
1761 ),
1762 limits: config.limits,
1763 unreliable_request_limit: unreliable_request_limit(config.path_mtu),
1764 meters,
1765 admission,
1766 observations,
1767 capture,
1768 local_addr,
1769 unmatched: None,
1770 stun_waiters: HashMap::new(),
1771 pong_waiters: HashMap::new(),
1772 #[cfg(feature = "quic")]
1773 quic_replies: HashMap::new(),
1774 background,
1775 shutdown,
1776 settled: Vec::new(),
1777 };
1778 tokio::spawn(driver.run());
1779
1780 Ok((handle, incoming_rx))
1781}
1782
1783#[doc(hidden)]
1785pub type InProcessEndpoint = (Handle, mpsc::Receiver<Incoming>);
1786
1787#[doc(hidden)]
1789pub type InProcessPair = (InProcessEndpoint, InProcessEndpoint);
1790
1791#[doc(hidden)]
1802pub fn in_process_pair(capacity: usize) -> Result<InProcessPair> {
1803 let runtime = tokio::runtime::Handle::try_current().map_err(|_| Error::RuntimeUnavailable)?;
1804 let capacity = capacity.max(1);
1805 let routes = Arc::new(Mutex::new(HashMap::<
1806 (InProcessSide, TransactionKey),
1807 ClientSink,
1808 >::new()));
1809 let left_addr = SocketAddr::from(([127, 0, 0, 1], 50_600));
1810 let right_addr = SocketAddr::from(([127, 0, 0, 1], 50_601));
1811 let (left, left_commands, left_incoming_tx, left_incoming_rx) =
1812 in_process_handle(left_addr, capacity);
1813 let (right, right_commands, right_incoming_tx, right_incoming_rx) =
1814 in_process_handle(right_addr, capacity);
1815
1816 runtime.spawn(run_in_process(
1817 InProcessSide::Left,
1818 left_addr,
1819 capacity,
1820 left_commands,
1821 right_incoming_tx,
1822 Arc::clone(&routes),
1823 Arc::clone(&left.shutdown),
1824 ));
1825 runtime.spawn(run_in_process(
1826 InProcessSide::Right,
1827 right_addr,
1828 capacity,
1829 right_commands,
1830 left_incoming_tx,
1831 routes,
1832 Arc::clone(&right.shutdown),
1833 ));
1834
1835 Ok(((left, left_incoming_rx), (right, right_incoming_rx)))
1836}
1837
1838#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1839enum InProcessSide {
1840 Left,
1841 Right,
1842}
1843
1844impl InProcessSide {
1845 const fn peer(self) -> Self {
1846 match self {
1847 Self::Left => Self::Right,
1848 Self::Right => Self::Left,
1849 }
1850 }
1851}
1852
1853type InProcessRoutes = Arc<Mutex<HashMap<(InProcessSide, TransactionKey), ClientSink>>>;
1854
1855fn insert_in_process_route(
1856 routes: &InProcessRoutes,
1857 capacity: usize,
1858 owner: InProcessSide,
1859 key: TransactionKey,
1860 sink: ClientSink,
1861 peer: SocketAddr,
1862) -> Result<()> {
1863 let mut routes = routes
1864 .lock()
1865 .unwrap_or_else(std::sync::PoisonError::into_inner);
1866 routes.retain(|_, client| !client.events.is_closed());
1867 if routes.len() >= capacity {
1868 return Err(Error::Overloaded { peer });
1869 }
1870 routes.insert((owner, key), sink);
1871 Ok(())
1872}
1873
1874fn in_process_response_events(
1875 routes: &InProcessRoutes,
1876 owner: InProcessSide,
1877 key: TransactionKey,
1878 final_response: bool,
1879) -> Option<mpsc::Sender<TuEvent>> {
1880 let mut routes = routes
1881 .lock()
1882 .unwrap_or_else(std::sync::PoisonError::into_inner);
1883 if final_response {
1884 routes.remove(&(owner, key)).map(|client| client.events)
1885 } else {
1886 routes
1887 .get(&(owner, key))
1888 .map(|client| client.events.clone())
1889 }
1890}
1891
1892fn clear_in_process_routes(routes: &InProcessRoutes) {
1893 routes
1894 .lock()
1895 .unwrap_or_else(std::sync::PoisonError::into_inner)
1896 .clear();
1897}
1898
1899fn wake_in_process_settled(
1900 routes: &InProcessRoutes,
1901 side: InProcessSide,
1902 settled: &mut Vec<oneshot::Sender<()>>,
1903) {
1904 let has_transaction = routes
1905 .lock()
1906 .unwrap_or_else(std::sync::PoisonError::into_inner)
1907 .keys()
1908 .any(|(owner, _)| *owner == side);
1909 if !has_transaction {
1910 for answered in settled.drain(..) {
1911 let _ = answered.send(());
1912 }
1913 }
1914}
1915
1916fn in_process_outstanding(routes: &InProcessRoutes, side: InProcessSide) -> usize {
1917 routes
1918 .lock()
1919 .unwrap_or_else(std::sync::PoisonError::into_inner)
1920 .keys()
1921 .filter(|(owner, _)| *owner == side)
1922 .count()
1923}
1924
1925fn in_process_handle(
1926 local_addr: SocketAddr,
1927 capacity: usize,
1928) -> (
1929 Handle,
1930 mpsc::Receiver<Command>,
1931 mpsc::Sender<Incoming>,
1932 mpsc::Receiver<Incoming>,
1933) {
1934 let (commands, command_rx) = mpsc::channel(capacity);
1935 let incoming = mpsc::channel(capacity);
1936 let shutdown = Arc::new(ShutdownState::default());
1937 let sent_by = Arc::new(local_addr.ip().to_string());
1938 let meters = Arc::new(Meters::default());
1939 let handle = Handle {
1940 commands,
1941 shutdown,
1942 draining: Arc::new(AtomicBool::new(false)),
1943 local_addr,
1944 meters: Arc::clone(&meters),
1945 admission: Arc::new(SourceAdmission::default()),
1946 observations: Arc::new(ObservationHub::new(meters)),
1947 request_policy: None,
1948 #[cfg(feature = "tls")]
1949 tls_addr: None,
1950 #[cfg(feature = "tls")]
1951 server_identity: None,
1952 #[cfg(feature = "ws")]
1953 ws_addr: None,
1954 #[cfg(feature = "wss")]
1955 wss_addr: None,
1956 #[cfg(feature = "quic")]
1957 quic_addr: None,
1958 #[cfg(feature = "ws")]
1959 ws_sent_by: Arc::from(format!("in-process-{}", local_addr.port())),
1960 advertise_overload: false,
1961 sent_by,
1962 sent_by_port: local_addr.port(),
1963 unreliable_request_limit: UNKNOWN_PATH_MTU_REQUEST_LIMIT,
1964 };
1965 (handle, command_rx, incoming.0, incoming.1)
1966}
1967
1968async fn run_in_process(
1969 side: InProcessSide,
1970 local_addr: SocketAddr,
1971 capacity: usize,
1972 mut commands: mpsc::Receiver<Command>,
1973 peer_incoming: mpsc::Sender<Incoming>,
1974 routes: InProcessRoutes,
1975 shutdown: Arc<ShutdownState>,
1976) {
1977 let mut settled = Vec::<oneshot::Sender<()>>::new();
1978 while let Some(command) = commands.recv().await {
1979 match command {
1980 Command::Request {
1981 request,
1982 target,
1983 events,
1984 failures,
1985 reply,
1986 ..
1987 } => {
1988 let Some(client_key) = TransactionKey::from_sent_request(&request) else {
1989 let _ = reply.send(Err(Error::NoVia));
1990 continue;
1991 };
1992 let Some(server_key) = TransactionKey::from_request(&request) else {
1993 let _ = reply.send(Err(Error::NoVia));
1994 continue;
1995 };
1996 if let Err(error) = insert_in_process_route(
1997 &routes,
1998 capacity,
1999 side.peer(),
2000 server_key.clone(),
2001 ClientSink { events, failures },
2002 target.addr,
2003 ) {
2004 let _ = reply.send(Err(error));
2005 continue;
2006 }
2007 let _ = reply.send(Ok((client_key, None)));
2008 if peer_incoming
2009 .send(Incoming {
2010 key: server_key,
2011 request: *request,
2012 source: local_addr,
2013 transport: target.transport,
2014 connection_generation: None,
2015 })
2016 .await
2017 .is_err()
2018 {
2019 break;
2020 }
2021 }
2022 Command::Respond {
2023 key,
2024 response,
2025 sent,
2026 } => {
2027 let events =
2028 in_process_response_events(&routes, side, key, response.status.is_final());
2029 let result = if let Some(events) = events {
2030 events
2031 .send(TuEvent::Response(response))
2032 .await
2033 .map_err(|_| Error::EndpointClosed)
2034 } else {
2035 Err(Error::EndpointClosed)
2036 };
2037 let _ = sent.send(result);
2038 }
2039 Command::Direct {
2040 request,
2041 target,
2042 sent,
2043 ..
2044 } => {
2045 let result =
2046 send_in_process_direct(local_addr, &peer_incoming, request, target).await;
2047 let _ = sent.send(result);
2048 }
2049 Command::Keepalive { answered, .. } => {
2050 let _ = answered.send(Ok(None));
2051 }
2052 Command::WatchUnmatched(_) => {}
2053 Command::Outstanding(answered) => {
2054 let _ = answered.send(in_process_outstanding(&routes, side));
2055 }
2056 Command::Settled(answered) => settled.push(answered),
2057 Command::Shutdown => break,
2058 }
2059 wake_in_process_settled(&routes, side, &mut settled);
2060 }
2061 clear_in_process_routes(&routes);
2062 shutdown.complete();
2063}
2064
2065async fn send_in_process_direct(
2066 local_addr: SocketAddr,
2067 peer_incoming: &mpsc::Sender<Incoming>,
2068 request: Box<Request>,
2069 target: Target,
2070) -> Result<()> {
2071 let Some(key) = TransactionKey::from_request(&request) else {
2072 return Err(Error::NoVia);
2073 };
2074 peer_incoming
2075 .send(Incoming {
2076 key,
2077 request: *request,
2078 source: local_addr,
2079 transport: target.transport,
2080 connection_generation: None,
2081 })
2082 .await
2083 .map_err(|_| Error::EndpointClosed)
2084}
2085
2086#[cfg(feature = "tls")]
2092async fn listen_tls(
2093 ip: std::net::IpAddr,
2094 port: u16,
2095 server: ServerHandshakePolicy,
2096 adopt: &mpsc::Sender<Adopt>,
2097 runtime: &HandshakeRuntime,
2098 admission: Arc<SourceAdmission>,
2099 meters: Arc<Meters>,
2100) -> Result<SocketAddr> {
2101 let listener = TcpListener::bind(SocketAddr::new(ip, port)).await?;
2102 let addr = listener.local_addr()?;
2103 let adopt = adopt.clone();
2104 let owner = runtime.owner.clone();
2105 let cancel = owner.cancel.clone();
2106 let permits = Arc::clone(&runtime.permits);
2107 let deadline = runtime.deadline;
2108 #[cfg(test)]
2109 let observations = runtime.observations.clone();
2110 runtime.owner.spawn(async move {
2111 loop {
2112 let accepted = tokio::select! {
2113 biased;
2114 () = cancel.cancelled() => break,
2115 accepted = listener.accept() => accepted,
2116 };
2117 let (stream, peer) = match accepted {
2118 Ok(accepted) => accepted,
2119 Err(error) => {
2120 tracing::warn!(%error, "TLS accept failed");
2121 break;
2122 }
2123 };
2124 let Some(admission_generation) = admission.admit(peer.ip()) else {
2125 meters.source_refusal(TransportKind::Tls);
2126 tracing::debug!(%peer, "refused inbound TLS source before handshake");
2127 continue;
2128 };
2129 let permit = Arc::clone(&permits).try_acquire_owned();
2130 #[cfg(test)]
2131 observe_handshake(
2132 observations.as_ref(),
2133 if permit.is_ok() {
2134 HandshakeObservation::Admitted
2135 } else {
2136 HandshakeObservation::Refused
2137 },
2138 );
2139 let Ok(permit) = permit else {
2140 tracing::debug!(%peer, "refused inbound TLS handshake at capacity");
2143 continue;
2144 };
2145 let acceptor = server.acceptor();
2146 let adopt = adopt.clone();
2147 let cancel = cancel.clone();
2148 owner.spawn(async move {
2149 let outcome = tokio::select! {
2150 biased;
2151 () = cancel.cancelled() => None,
2152 result = tokio::time::timeout(deadline, acceptor.accept(stream)) => Some(result),
2153 };
2154 match outcome {
2155 Some(Ok(Ok(tls))) => {
2156 tokio::select! {
2164 biased;
2165 () = cancel.cancelled() => {}
2166 result = adopt.send(Box::new(move |pool: &mut Pool| pool.accept_tls_admitted(tls, peer, admission_generation))) => {
2167 let _ = result;
2168 }
2169 }
2170 }
2171 Some(Ok(Err(error))) => {
2172 tracing::debug!(%error, %peer, "inbound TLS handshake failed");
2173 }
2174 Some(Err(_)) => tracing::debug!(%peer, "inbound TLS handshake timed out"),
2175 None => {}
2176 }
2177 drop(permit);
2178 });
2179 }
2180 });
2181 Ok(addr)
2182}
2183
2184#[cfg(feature = "quic")]
2187fn listen_quic(
2188 endpoint: quinn::Endpoint,
2189 adopt: &mpsc::Sender<Adopt>,
2190 runtime: &HandshakeRuntime,
2191 admission: Arc<SourceAdmission>,
2192 meters: Arc<Meters>,
2193) {
2194 let adopt = adopt.clone();
2195 let owner = runtime.owner.clone();
2196 let cancel = owner.cancel.clone();
2197 let permits = Arc::clone(&runtime.permits);
2198 let deadline = runtime.deadline;
2199 runtime.owner.spawn(async move {
2200 loop {
2201 let incoming = tokio::select! {
2202 biased;
2203 () = cancel.cancelled() => break,
2204 incoming = endpoint.accept() => incoming,
2205 };
2206 let Some(incoming) = incoming else {
2207 break;
2208 };
2209 let peer = incoming.remote_address();
2210 let Some(admission_generation) = admission.admit(peer.ip()) else {
2211 incoming.refuse();
2212 meters.source_refusal(TransportKind::Quic);
2213 tracing::debug!(%peer, "refused inbound QUIC source before handshake");
2214 continue;
2215 };
2216 let Ok(permit) = Arc::clone(&permits).try_acquire_owned() else {
2217 incoming.refuse();
2218 tracing::debug!(%peer, "refused inbound QUIC handshake at capacity");
2219 continue;
2220 };
2221 let adopt = adopt.clone();
2222 let cancel = cancel.clone();
2223 owner.spawn(async move {
2224 let connected = tokio::select! {
2225 biased;
2226 () = cancel.cancelled() => None,
2227 result = tokio::time::timeout(deadline, incoming) => Some(result),
2228 };
2229 match connected {
2230 Some(Ok(Ok(connection))) => {
2231 let result = adopt
2232 .send(Box::new(move |pool: &mut Pool| {
2233 pool.accept_quic_admitted(connection, peer, admission_generation);
2234 }))
2235 .await;
2236 if result.is_err() {
2237 tracing::debug!(%peer, "QUIC connection lost its endpoint before adoption");
2238 }
2239 }
2240 Some(Ok(Err(error))) => {
2241 tracing::debug!(%error, %peer, "inbound QUIC handshake failed");
2242 }
2243 Some(Err(_)) => tracing::debug!(%peer, "inbound QUIC handshake timed out"),
2244 None => {}
2245 }
2246 drop(permit);
2247 });
2248 }
2249 });
2250}
2251
2252#[cfg(feature = "ws")]
2254#[allow(clippy::too_many_arguments)]
2255async fn listen_ws(
2256 ip: std::net::IpAddr,
2257 port: u16,
2258 keepalive: std::time::Duration,
2259 limits: Limits,
2260 adopt: &mpsc::Sender<Adopt>,
2261 runtime: &HandshakeRuntime,
2262 admission: Arc<SourceAdmission>,
2263 meters: Arc<Meters>,
2264) -> Result<SocketAddr> {
2265 let listener = TcpListener::bind(SocketAddr::new(ip, port)).await?;
2266 let addr = listener.local_addr()?;
2267 let adopt = adopt.clone();
2268 let owner = runtime.owner.clone();
2269 let cancel = owner.cancel.clone();
2270 let permits = Arc::clone(&runtime.permits);
2271 let deadline = runtime.deadline;
2272 #[cfg(test)]
2273 let observations = runtime.observations.clone();
2274 runtime.owner.spawn(async move {
2275 loop {
2276 let accepted = tokio::select! {
2277 biased;
2278 () = cancel.cancelled() => break,
2279 accepted = listener.accept() => accepted,
2280 };
2281 let (stream, peer) = match accepted {
2282 Ok(accepted) => accepted,
2283 Err(error) => {
2284 tracing::warn!(%error, "WebSocket accept failed");
2285 break;
2286 }
2287 };
2288 let Some(admission_generation) = admission.admit(peer.ip()) else {
2289 meters.source_refusal(TransportKind::Ws);
2290 tracing::debug!(%peer, "refused inbound WebSocket source before handshake");
2291 continue;
2292 };
2293 let permit = Arc::clone(&permits).try_acquire_owned();
2294 #[cfg(test)]
2295 observe_handshake(
2296 observations.as_ref(),
2297 if permit.is_ok() {
2298 HandshakeObservation::Admitted
2299 } else {
2300 HandshakeObservation::Refused
2301 },
2302 );
2303 let Ok(permit) = permit else {
2304 tracing::debug!(%peer, "refused inbound WebSocket handshake at capacity");
2307 continue;
2308 };
2309 let adopt = adopt.clone();
2310 let cancel = cancel.clone();
2311 owner.spawn(async move {
2312 let upgraded = tokio::select! {
2313 biased;
2314 () = cancel.cancelled() => None,
2315 result = tokio::time::timeout(
2316 deadline,
2317 crate::ws::accept_with_limits(stream, peer, &limits),
2318 ) => Some(result),
2319 };
2320 match upgraded {
2321 Some(Ok(result)) => {
2322 adopt_upgraded(
2323 result,
2324 peer,
2325 TransportKind::Ws,
2326 keepalive,
2327 admission_generation,
2328 &adopt,
2329 &cancel,
2330 )
2331 .await;
2332 }
2333 Some(Err(_)) => tracing::debug!(%peer, "inbound WebSocket handshake timed out"),
2334 None => {}
2335 }
2336 drop(permit);
2337 });
2338 }
2339 });
2340 Ok(addr)
2341}
2342
2343#[cfg(feature = "wss")]
2349#[allow(clippy::too_many_arguments)]
2350async fn listen_wss(
2351 ip: std::net::IpAddr,
2352 port: u16,
2353 server: ServerHandshakePolicy,
2354 keepalive: std::time::Duration,
2355 limits: Limits,
2356 adopt: &mpsc::Sender<Adopt>,
2357 runtime: &HandshakeRuntime,
2358 admission: Arc<SourceAdmission>,
2359 meters: Arc<Meters>,
2360) -> Result<SocketAddr> {
2361 let listener = TcpListener::bind(SocketAddr::new(ip, port)).await?;
2362 let addr = listener.local_addr()?;
2363 let adopt = adopt.clone();
2364 let owner = runtime.owner.clone();
2365 let cancel = owner.cancel.clone();
2366 let permits = Arc::clone(&runtime.permits);
2367 let deadline = runtime.deadline;
2368 #[cfg(test)]
2369 let observations = runtime.observations.clone();
2370 runtime.owner.spawn(async move {
2371 loop {
2372 let accepted = tokio::select! {
2373 biased;
2374 () = cancel.cancelled() => break,
2375 accepted = listener.accept() => accepted,
2376 };
2377 let (stream, peer) = match accepted {
2378 Ok(accepted) => accepted,
2379 Err(error) => {
2380 tracing::warn!(%error, "WSS accept failed");
2381 break;
2382 }
2383 };
2384 let Some(admission_generation) = admission.admit(peer.ip()) else {
2385 meters.source_refusal(TransportKind::Wss);
2386 tracing::debug!(%peer, "refused inbound WSS source before handshake");
2387 continue;
2388 };
2389 let permit = Arc::clone(&permits).try_acquire_owned();
2390 #[cfg(test)]
2391 observe_handshake(
2392 observations.as_ref(),
2393 if permit.is_ok() {
2394 HandshakeObservation::Admitted
2395 } else {
2396 HandshakeObservation::Refused
2397 },
2398 );
2399 let Ok(permit) = permit else {
2400 tracing::debug!(%peer, "refused inbound WSS handshake at capacity");
2403 continue;
2404 };
2405 let acceptor = server.acceptor();
2406 let adopt = adopt.clone();
2407 let cancel = cancel.clone();
2408 owner.spawn(async move {
2409 let upgraded = tokio::select! {
2410 biased;
2411 () = cancel.cancelled() => None,
2412 result = tokio::time::timeout(deadline, async move {
2413 let tls = acceptor.accept(stream).await.map_err(|error| error.to_string())?;
2414 crate::ws::accept_with_limits(tls, peer, &limits)
2415 .await
2416 .map_err(|error| error.to_string())
2417 }) => Some(result),
2418 };
2419 match upgraded {
2420 Some(Ok(Ok(socket))) => {
2421 adopt_upgraded(
2422 Ok(socket),
2423 peer,
2424 TransportKind::Wss,
2425 keepalive,
2426 admission_generation,
2427 &adopt,
2428 &cancel,
2429 )
2430 .await;
2431 }
2432 Some(Ok(Err(error))) => {
2433 tracing::debug!(%error, %peer, "inbound WSS handshake failed");
2434 }
2435 Some(Err(_)) => tracing::debug!(%peer, "inbound WSS handshake timed out"),
2436 None => {}
2437 }
2438 drop(permit);
2439 });
2440 }
2441 });
2442 Ok(addr)
2443}
2444
2445#[cfg(feature = "ws")]
2447async fn adopt_upgraded<S>(
2448 upgraded: std::result::Result<crate::ws::Socket<S>, crate::ws::WsError>,
2449 peer: SocketAddr,
2450 transport: TransportKind,
2451 keepalive: std::time::Duration,
2452 admission_generation: u64,
2453 adopt: &mpsc::Sender<Adopt>,
2454 cancel: &CancellationToken,
2455) where
2456 S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send + 'static,
2457{
2458 match upgraded {
2459 Ok(socket) => {
2460 let key = ConnectionKey::new(peer, transport);
2461 tokio::select! {
2466 biased;
2467 () = cancel.cancelled() => {}
2468 result = adopt.send(Box::new(move |pool: &mut Pool| {
2469 pool.accept_ws_admitted(socket, key, keepalive, admission_generation);
2470 })) => {
2471 let _ = result;
2472 }
2473 }
2474 }
2475 Err(error) => tracing::debug!(%error, %peer, "inbound websocket handshake failed"),
2476 }
2477}
2478
2479async fn accept_tcp_until(
2481 listener: TcpListener,
2482 incoming: mpsc::Sender<(tokio::net::TcpStream, SocketAddr, u64)>,
2483 cancel: CancellationToken,
2484 admission: Arc<SourceAdmission>,
2485 meters: Arc<Meters>,
2486) {
2487 loop {
2488 let accepted = tokio::select! {
2489 biased;
2490 () = cancel.cancelled() => return,
2491 accepted = listener.accept() => accepted,
2492 };
2493 let (stream, peer) = match accepted {
2494 Ok(accepted) => accepted,
2495 Err(error) => {
2496 tracing::warn!(%error, "accept failed");
2497 return;
2498 }
2499 };
2500 let Some(generation) = admission.admit(peer.ip()) else {
2501 meters.source_refusal(TransportKind::Tcp);
2502 tracing::debug!(%peer, "refused inbound TCP source before stream parsing");
2503 continue;
2504 };
2505 tokio::select! {
2506 biased;
2507 () = cancel.cancelled() => return,
2508 result = incoming.send((stream, peer, generation)) => {
2509 if result.is_err() {
2510 return;
2511 }
2512 }
2513 }
2514 }
2515}
2516
2517struct CleartextBindings {
2518 udp: Option<UdpSocket>,
2519 tcp: Option<TcpListener>,
2520 local_addr: Option<SocketAddr>,
2521}
2522
2523async fn bind_cleartext(config: &Config) -> Result<CleartextBindings> {
2533 const ATTEMPTS: usize = 16;
2534
2535 if !config.cleartext.udp() {
2536 if config.cleartext.tcp() {
2537 let listener = TcpListener::bind(config.bind).await?;
2538 let local_addr = listener.local_addr()?;
2539 return Ok(CleartextBindings {
2540 udp: None,
2541 tcp: Some(listener),
2542 local_addr: Some(local_addr),
2543 });
2544 }
2545 return Ok(CleartextBindings {
2546 udp: None,
2547 tcp: None,
2548 local_addr: None,
2549 });
2550 }
2551
2552 let wants_any_port = config.bind.port() == 0;
2553 let mut last_error = None;
2554
2555 for _ in 0..ATTEMPTS {
2556 let socket = UdpSocket::bind(config.bind).await?;
2557 let local_addr = socket.local_addr()?;
2558
2559 if !config.cleartext.tcp() {
2560 return Ok(CleartextBindings {
2561 udp: Some(socket),
2562 tcp: None,
2563 local_addr: Some(local_addr),
2564 });
2565 }
2566
2567 match TcpListener::bind(local_addr).await {
2568 Ok(listener) => {
2569 return Ok(CleartextBindings {
2570 udp: Some(socket),
2571 tcp: Some(listener),
2572 local_addr: Some(local_addr),
2573 });
2574 }
2575 Err(error) if wants_any_port && error.kind() == std::io::ErrorKind::AddrInUse => {
2576 drop(socket);
2579 last_error = Some(error);
2580 }
2581 Err(error) => return Err(error.into()),
2582 }
2583 }
2584
2585 Err(last_error
2586 .unwrap_or_else(|| {
2587 std::io::Error::new(
2588 std::io::ErrorKind::AddrInUse,
2589 "no port was free for both UDP and TCP",
2590 )
2591 })
2592 .into())
2593}
2594
2595struct Driver {
2596 socket: Option<Arc<UdpSocket>>,
2597 udp: mpsc::Receiver<(Bytes, SocketAddr)>,
2599 layer: TransactionLayer,
2600 timers: TimerQueue<(TransactionKey, Timer)>,
2601 destinations: HashMap<TransactionKey, Target>,
2602 transaction_generations: HashMap<TransactionKey, ConnectionGeneration>,
2604 unanswered_since: HashMap<TransactionKey, tokio::time::Instant>,
2607 reconnect: HashMap<TransactionKey, Target>,
2614 tcp_fallbacks: HashMap<TransactionKey, TcpFallback>,
2616 unanswered_limit: std::time::Duration,
2618 overload: OverloadController,
2620 overload_config: OverloadConfig,
2621 overload_epoch: tokio::time::Instant,
2622 overload_sequence: u64,
2623 server_overloaded_until: Option<tokio::time::Instant>,
2625 clients: HashMap<TransactionKey, ClientSink>,
2626 incoming: mpsc::Sender<Incoming>,
2627 commands: mpsc::Receiver<Command>,
2628 net: mpsc::Receiver<tcp::Event>,
2629 accepts: mpsc::Receiver<(tokio::net::TcpStream, SocketAddr, u64)>,
2630 adopts: mpsc::Receiver<Adopt>,
2631 _adopt: mpsc::Sender<Adopt>,
2634 #[cfg(feature = "tls")]
2635 tls_client: Option<crate::tls::ClientTls>,
2636 #[cfg(feature = "ws")]
2637 ws_keepalive: std::time::Duration,
2638 #[cfg(feature = "quic")]
2639 quic_client: Option<crate::tls::ClientTls>,
2640 #[cfg(feature = "quic")]
2641 quic_endpoint: Option<quinn::Endpoint>,
2642 pool: Pool,
2643 limits: Limits,
2644 unreliable_request_limit: usize,
2645 meters: Arc<Meters>,
2647 admission: Arc<SourceAdmission>,
2648 observations: Arc<ObservationHub>,
2649 capture: Option<Capture>,
2651 local_addr: SocketAddr,
2657 unmatched: Option<mpsc::Sender<Unmatched>>,
2662 stun_waiters: HashMap<crate::stun::TransactionId, oneshot::Sender<Result<Option<SocketAddr>>>>,
2663 pong_waiters: HashMap<
2668 ConnectionGeneration,
2669 std::collections::VecDeque<oneshot::Sender<Result<Option<SocketAddr>>>>,
2670 >,
2671 #[cfg(feature = "quic")]
2673 quic_replies: HashMap<TransactionKey, crate::quic::Reply>,
2674 background: Background,
2676 shutdown: Arc<ShutdownState>,
2678 settled: Vec<oneshot::Sender<()>>,
2680}
2681
2682fn forget_transaction_timers(
2683 timers: &mut TimerQueue<(TransactionKey, Timer)>,
2684 key: &TransactionKey,
2685) {
2686 for timer in Timer::ALL {
2687 timers.forget(&(key.clone(), timer));
2688 }
2689}
2690
2691#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2692struct ConnectionGeneration {
2693 key: ConnectionKey,
2694 id: u64,
2695}
2696
2697struct Performed {
2710 sent_message: bool,
2712}
2713
2714impl Performed {
2715 #[must_use]
2717 fn sent_message(&self) -> bool {
2718 self.sent_message
2719 }
2720
2721 #[allow(
2728 clippy::unused_self,
2729 clippy::unnecessary_wraps,
2730 reason = "consuming self is the guarantee; the Result is the channel's type"
2731 )]
2732 fn into_result(self) -> Result<()> {
2733 Ok(())
2734 }
2735}
2736
2737impl Driver {
2738 async fn run(mut self) {
2739 let mut idle_sweep = tokio::time::interval(std::time::Duration::from_secs(30));
2742 idle_sweep.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
2743 loop {
2744 let deadline = self.timers.next_deadline();
2745 let receives_udp = self.socket.is_some();
2746 tokio::select! {
2747 Some((datagram, source)) = self.udp.recv(), if receives_udp => {
2748 self.on_datagram(datagram, source).await;
2749 }
2750 () = sleep_until(deadline), if deadline.is_some() => {
2751 self.on_timers().await;
2752 }
2753 command = self.commands.recv() => match command {
2754 Some(Command::Shutdown) | None => break,
2755 Some(command) => self.on_command(command).await,
2756 },
2757 Some(event) = self.net.recv() => self.on_net_event(event).await,
2758 Some((stream, peer, generation)) = self.accepts.recv() => {
2759 self.pool.accept_admitted(stream, peer, generation);
2760 },
2761 Some(adopt) = self.adopts.recv() => adopt(&mut self.pool),
2762 _ = idle_sweep.tick() => {
2763 for closed in self.pool.evict_idle() {
2764 tracing::debug!(peer = %closed.peer, "closed an idle connection");
2765 }
2766 self.abandon_unanswered();
2767 }
2768 }
2769 self.wake_settled();
2770 }
2771 self.commands.close();
2772 self.background.shutdown().await;
2773 self.pool.shutdown().await;
2774 let shutdown = Arc::clone(&self.shutdown);
2777 drop(self);
2778 shutdown.complete();
2779 }
2780
2781 async fn on_datagram(&mut self, datagram: Bytes, source: SocketAddr) {
2782 if self.admission.admit(source.ip()).is_none() {
2783 self.meters.source_refusal(TransportKind::Udp);
2784 tracing::debug!(%source, "refused inbound UDP source before parsing");
2785 return;
2786 }
2787 if crate::stun::is_stun(&datagram) {
2790 self.on_stun(&datagram, source);
2791 return;
2792 }
2793 self.observe(source, TransportKind::Udp, Direction::In, || {
2796 datagram.clone()
2797 });
2798
2799 match parse_datagram(datagram, &self.limits) {
2800 Ok(message) => {
2801 self.on_message(
2802 message,
2803 source,
2804 TransportKind::Udp,
2805 None,
2806 #[cfg(feature = "quic")]
2807 None,
2808 )
2809 .await;
2810 }
2811 Err(error) => {
2812 self.meters.parse_failure(TransportKind::Udp);
2818 tracing::debug!(%error, %source, "dropping malformed datagram");
2819 }
2820 }
2821 }
2822
2823 fn wake_settled(&mut self) {
2824 if self.layer.len() == (0, 0) {
2825 for answered in self.settled.drain(..) {
2826 let _ = answered.send(());
2827 }
2828 }
2829 }
2830
2831 async fn on_keepalive(
2833 &mut self,
2834 target: Target,
2835 answered: oneshot::Sender<Result<Option<SocketAddr>>>,
2836 ) {
2837 self.stun_waiters.retain(|_, waiter| !waiter.is_closed());
2840 self.pong_waiters.retain(|_, queue| {
2841 queue.retain(|waiter| !waiter.is_closed());
2842 !queue.is_empty()
2843 });
2844
2845 if target.transport == TransportKind::Udp {
2846 let id = crate::stun::new_transaction_id();
2850 let request = Bytes::from(crate::stun::binding_request(&id));
2851 match self.transmit_raw(request, &target).await {
2852 Ok(_) => {
2853 self.stun_waiters.insert(id, answered);
2854 }
2855 Err(error) => {
2856 let _ = answered.send(Err(error));
2859 }
2860 }
2861 return;
2862 }
2863
2864 match self
2867 .transmit_raw(Bytes::from_static(b"\r\n\r\n"), &target)
2868 .await
2869 {
2870 Ok(Some(generation)) => {
2871 self.pong_waiters
2872 .entry(generation)
2873 .or_default()
2874 .push_back(answered);
2875 }
2876 Ok(None) => {
2877 let _ = answered.send(Err(Error::ConnectionClosed));
2879 }
2880 Err(error) => {
2881 let _ = answered.send(Err(error));
2884 }
2885 }
2886 }
2887
2888 fn on_stun(&mut self, datagram: &[u8], source: SocketAddr) {
2890 let Some(reply) = crate::stun::parse_reply(datagram) else {
2891 self.meters.discard_stun_unmatched();
2894 tracing::debug!(%source, "ignoring a STUN message that is not a reply");
2895 return;
2896 };
2897 let Some(waiter) = self.stun_waiters.remove(&reply.id()) else {
2898 self.meters.discard_stun_unmatched();
2901 tracing::debug!(%source, "a STUN reply matched no keep-alive");
2902 return;
2903 };
2904 let answer = match reply {
2905 crate::stun::Reply::Bound { mapped, .. } => Ok(mapped),
2906 crate::stun::Reply::Failed { .. } => Err(Error::KeepaliveRefused),
2909 };
2910 let _ = waiter.send(answer);
2913 }
2914
2915 #[allow(
2916 clippy::too_many_lines,
2917 reason = "one exhaustive transport-event dispatch keeps ordering and loss accounting visible"
2918 )]
2919 async fn on_net_event(&mut self, event: tcp::Event) {
2920 match event {
2921 tcp::Event::Message {
2922 message,
2923 source,
2924 transport,
2925 id,
2926 #[cfg(feature = "quic")]
2927 quic_reply,
2928 } => {
2929 self.observe(source, transport, Direction::In, || message.to_bytes());
2935 self.on_message(
2936 *message,
2937 source,
2938 transport,
2939 Some(id),
2940 #[cfg(feature = "quic")]
2941 quic_reply,
2942 )
2943 .await;
2944 }
2945 tcp::Event::FramingFailed { key } => {
2946 if let Some((id, admission_generation)) = self.pool.observation_generation(&key) {
2947 self.observations.emit(connection_event(
2948 key.clone(),
2949 id,
2950 admission_generation,
2951 ConnectionState::Failed,
2952 ));
2953 }
2954 self.meters.parse_failure(key.transport);
2959 }
2960 tcp::Event::Pong { key, id } => {
2961 let generation = ConnectionGeneration { key, id };
2964 if let Some(queue) = self.pong_waiters.get_mut(&generation)
2965 && let Some(waiter) = queue.pop_front()
2966 {
2967 let _ = waiter.send(Ok(None));
2970 }
2971 }
2972 tcp::Event::ConnectFailed {
2973 key,
2974 id,
2975 kind,
2976 detail,
2977 } => {
2978 if !self.pool.remove(&key, id) {
2981 return;
2982 }
2983 let generation = ConnectionGeneration { key, id };
2984 self.fail_transactions_on(&generation, None, Some((kind, detail)))
2985 .await;
2986 }
2987 #[cfg(feature = "tls")]
2988 tcp::Event::HandshakeFailed { key, id, detail } => {
2989 let admission_generation = self
2990 .pool
2991 .observation_generation(&key)
2992 .filter(|(current, _)| *current == id)
2993 .and_then(|(_, admission_generation)| admission_generation);
2994 self.observations.emit(connection_event(
2995 key.clone(),
2996 id,
2997 admission_generation,
2998 ConnectionState::Failed,
2999 ));
3000 if !self.pool.remove(&key, id) {
3004 return;
3005 }
3006 let generation = ConnectionGeneration {
3007 key: key.clone(),
3008 id,
3009 };
3010 self.fail_transactions_on(&generation, Some(detail), None)
3011 .await;
3012 }
3013 #[cfg(feature = "quic")]
3014 tcp::Event::QuicClosed { key, id, detail } => {
3015 if !self.pool.remove(&key, id) {
3016 return;
3017 }
3018 let generation = ConnectionGeneration {
3019 key: key.clone(),
3020 id,
3021 };
3022 for (transaction, bound) in &self.transaction_generations {
3023 if bound == &generation
3024 && let Some(client) = self.clients.get(transaction)
3025 {
3026 let failure = Error::Quic(crate::quic::QuicError::ConnectionClosed {
3027 peer: key.peer.to_string(),
3028 detail: detail.clone(),
3029 });
3030 let _ = client.failures.try_send(failure);
3031 }
3032 }
3033 self.fail_transactions_on(&generation, None, None).await;
3034 }
3035 tcp::Event::Closed { key, id } => {
3036 if !self.pool.remove(&key, id) {
3040 return;
3041 }
3042 let generation = ConnectionGeneration {
3043 key: key.clone(),
3044 id,
3045 };
3046 if let Some(queue) = self.pong_waiters.remove(&generation) {
3049 for waiter in queue {
3050 let _ = waiter.send(Err(Error::ConnectionClosed));
3053 }
3054 }
3055 self.fail_transactions_on(&generation, None, None).await;
3056 }
3057 }
3058 }
3059
3060 async fn fail_transactions_on(
3065 &mut self,
3066 closed: &ConnectionGeneration,
3067 tls_detail: Option<String>,
3068 connect_failure: Option<(std::io::ErrorKind, String)>,
3069 ) {
3070 let affected: Vec<TransactionKey> = self
3071 .transaction_generations
3072 .iter()
3073 .filter(|(_, generation)| *generation == closed)
3074 .filter(|(key, _)| !self.reconnect.contains_key(*key))
3078 .map(|(key, _)| key.clone())
3079 .collect();
3080 for key in affected {
3081 if connect_failure.is_some() || tls_detail.is_some() {
3082 self.meters.discard_send_failure();
3083 if let Some(request) = self.layer.client_request(&key) {
3084 self.meters.unsent(&request.method);
3085 }
3086 }
3087 if let Some(fallback) = self.tcp_fallbacks.get(&key).copied()
3088 && let Some(client) = self.clients.get(&key)
3089 {
3090 let source = connect_failure
3095 .as_ref()
3096 .map_or(Error::ConnectionClosed, |failure| {
3097 Error::Io(std::io::Error::new(failure.0, failure.1.clone()))
3098 });
3099 let failure = fallback.unavailable(source);
3100 let _ = client.failures.try_send(failure);
3101 }
3102 #[cfg(feature = "tls")]
3103 if let Some(detail) = &tls_detail
3104 && let Some(client) = self.clients.get(&key)
3105 {
3106 #[cfg(feature = "quic")]
3107 let failure = if closed.key.transport == TransportKind::Quic {
3108 Error::Quic(crate::quic::QuicError::handshake(
3109 closed.key.peer.to_string(),
3110 detail.clone(),
3111 ))
3112 } else {
3113 Error::Tls(crate::tls::TlsError::Handshake {
3114 peer: closed.key.peer.to_string(),
3115 detail: detail.clone(),
3116 })
3117 };
3118 #[cfg(not(feature = "quic"))]
3119 let failure = Error::Tls(crate::tls::TlsError::Handshake {
3120 peer: closed.key.peer.to_string(),
3121 detail: detail.clone(),
3122 });
3123 let _ = client.failures.try_send(failure);
3124 }
3125 #[cfg(not(feature = "tls"))]
3126 let _ = &tls_detail;
3127 let outputs = self.layer.on_transport_error(&key);
3128 self.perform(&key, outputs, None).await;
3129 }
3130 }
3131
3132 async fn on_message(
3133 &mut self,
3134 message: Message,
3135 source: SocketAddr,
3136 transport: TransportKind,
3137 generation: Option<u64>,
3138 #[cfg(feature = "quic")] quic_reply: Option<crate::quic::Reply>,
3139 ) {
3140 let overload_response = match &message {
3141 Message::Response(response) => Some(response.clone()),
3142 Message::Request(_) => None,
3143 };
3144 self.meters
3146 .message_in(transport, matches!(message, Message::Response(_)));
3147 let message = apply_network_source(message, source);
3148 let observed_message = message.clone();
3149
3150 let advertised = match &message {
3156 Message::Request(request) => request
3157 .headers
3158 .typed::<sipx_sip::headers::Via>()
3159 .and_then(std::result::Result::ok)
3160 .map(|via| response_destination(&via, source, transport)),
3161 Message::Response(_) => None,
3162 };
3163 let reply_to = match &message {
3164 Message::Request(_) if transport == TransportKind::Udp => advertised
3165 .clone()
3166 .unwrap_or_else(|| Target::new(source, transport)),
3167 _ => Target::new(source, transport),
3168 };
3169 match self.layer.receive(message, transport.reliability()) {
3170 Dispatch::Created { key, outputs } => {
3171 self.observe_inbound(
3172 observed_message,
3173 source,
3174 transport,
3175 TransactionClass::ServerCreated,
3176 );
3177 self.destinations.insert(key.clone(), reply_to);
3178 if let Some(id) = generation {
3179 self.transaction_generations.insert(
3180 key.clone(),
3181 ConnectionGeneration {
3182 key: ConnectionKey::new(source, transport),
3183 id,
3184 },
3185 );
3186 }
3187 #[cfg(feature = "quic")]
3188 self.remember_quic_reply(&key, quic_reply);
3189 self.unanswered_since
3190 .insert(key.clone(), tokio::time::Instant::now());
3191 if transport.reliability().is_reliable()
3193 && transport != TransportKind::Quic
3194 && let Some(advertised) = advertised
3195 {
3196 self.reconnect.insert(key.clone(), advertised);
3197 }
3198 self.perform(&key, outputs, Some((source, transport))).await;
3199 }
3200 Dispatch::Matched { key, outputs } => {
3201 self.observe_inbound(
3202 observed_message,
3203 source,
3204 transport,
3205 TransactionClass::Matched,
3206 );
3207 self.observe_overload_response(source, overload_response.as_ref());
3208 self.perform(&key, outputs, Some((source, transport))).await;
3209 }
3210 Dispatch::Unmatched(message) => {
3211 self.observe_inbound(
3212 observed_message,
3213 source,
3214 transport,
3215 TransactionClass::Unmatched,
3216 );
3217 self.on_unmatched(message, source, transport, generation);
3218 }
3219 }
3220 }
3221
3222 fn on_unmatched(
3223 &mut self,
3224 message: Box<Message>,
3225 source: SocketAddr,
3226 transport: TransportKind,
3227 connection_generation: Option<u64>,
3228 ) {
3229 tracing::debug!(%source, "message matched no transaction");
3230 if let Message::Response(response) = &*message {
3234 self.meters.unmatched_response();
3235 if let Some(sink) = &self.unmatched
3236 && sink
3237 .try_send(Unmatched {
3238 response: response.clone(),
3239 source,
3240 transport,
3241 })
3242 .is_err()
3243 {
3244 self.meters.shed.unmatched.fetch_add(1, Ordering::Relaxed);
3246 tracing::warn!(
3247 %source,
3248 "unmatched-response watcher is not keeping up; dropped one"
3249 );
3250 }
3251 return;
3252 }
3253
3254 if let Message::Request(request) = *message {
3257 let Some(key) = TransactionKey::from_request(&request) else {
3258 return;
3259 };
3260 let method = request.method.clone();
3261 if self
3262 .incoming
3263 .try_send(Self::incoming_request(
3264 key,
3265 request,
3266 source,
3267 transport,
3268 connection_generation,
3269 ))
3270 .is_err()
3271 {
3272 self.meters.shed.unmatched.fetch_add(1, Ordering::Relaxed);
3274 tracing::warn!(
3275 %source,
3276 method = %method,
3277 "application queue full; an unmatched request was dropped"
3278 );
3279 }
3280 }
3281 }
3282
3283 fn incoming_request(
3284 key: TransactionKey,
3285 request: Request,
3286 source: SocketAddr,
3287 transport: TransportKind,
3288 connection_generation: Option<u64>,
3289 ) -> Incoming {
3290 Incoming {
3291 key,
3292 request,
3293 source,
3294 transport,
3295 connection_generation,
3296 }
3297 }
3298
3299 fn abandon_unanswered(&mut self) {
3311 let now = tokio::time::Instant::now();
3312 let stale: Vec<TransactionKey> = self
3313 .unanswered_since
3314 .iter()
3315 .filter(|(_, at)| now.saturating_duration_since(**at) > self.unanswered_limit)
3316 .map(|(key, _)| key.clone())
3317 .collect();
3318
3319 for key in stale {
3320 self.unanswered_since.remove(&key);
3321
3322 let described = self.layer.server_request(&key).map(|request| {
3326 (
3327 request.method.clone(),
3328 request
3329 .headers
3330 .value(&HeaderName::CallId)
3331 .map(|id| String::from_utf8_lossy(&id).into_owned())
3332 .unwrap_or_default(),
3333 )
3334 });
3335
3336 if !self.layer.abandon(&key) {
3337 continue;
3338 }
3339 if let Some((method, call_id)) = described {
3340 tracing::warn!(
3341 ?method,
3342 %call_id,
3343 limit = ?self.unanswered_limit,
3344 "abandoning a transaction the application never answered; that is an \
3345 application bug rather than a network one"
3346 );
3347 self.meters.discard_unanswered();
3348 }
3349
3350 if self.clients.contains_key(&key) {
3357 continue;
3358 }
3359 forget_transaction_timers(&mut self.timers, &key);
3360 self.destinations.remove(&key);
3361 self.transaction_generations.remove(&key);
3362 #[cfg(feature = "quic")]
3363 self.quic_replies.remove(&key);
3364 self.reconnect.remove(&key);
3368 self.tcp_fallbacks.remove(&key);
3369 }
3370 }
3371
3372 async fn on_timers(&mut self) {
3373 let due = self.timers.take_due(tokio::time::Instant::now());
3374 for (key, timer) in due {
3375 self.meters.on_timer(timer);
3380 let outputs = self.layer.on_timer(&key, timer);
3381 self.perform(&key, outputs, None).await;
3382 }
3383 }
3384
3385 async fn on_command(&mut self, command: Command) {
3386 match command {
3387 Command::Request {
3388 request,
3389 target,
3390 tcp_fallback,
3391 events,
3392 failures,
3393 reply,
3394 } => {
3395 let now =
3396 tokio::time::Instant::now().saturating_duration_since(self.overload_epoch);
3397 let category = (self.overload_config.categorize)(&request);
3398 if !self.overload.admit(target.addr, category, now) {
3399 self.meters.overload_rejection();
3400 let _ = reply.send(Err(Error::Overloaded { peer: target.addr }));
3403 return;
3404 }
3405 let Some((key, outputs)) = self
3406 .layer
3407 .send_request(*request, target.transport.reliability())
3408 else {
3409 let _ = reply.send(Err(Error::NoVia));
3412 return;
3413 };
3414 self.destinations.insert(key.clone(), target);
3415 if let Some(fallback) = tcp_fallback {
3416 self.tcp_fallbacks.insert(key.clone(), fallback);
3417 }
3418 self.clients
3419 .insert(key.clone(), ClientSink { events, failures });
3420 self.perform(&key, outputs, None).await;
3423 let generation = self.transaction_generations.get(&key).map(|value| value.id);
3424 let _ = reply.send(Ok((key, generation)));
3425 }
3426 Command::Respond {
3427 key,
3428 response,
3429 sent,
3430 } => self.on_respond_command(key, response, sent).await,
3431 Command::Direct {
3432 request,
3433 target,
3434 tcp_fallback,
3435 sent,
3436 } => {
3437 self.on_direct_command(request, target, tcp_fallback, sent)
3438 .await;
3439 }
3440 Command::WatchUnmatched(sink) => {
3441 self.unmatched = Some(sink);
3445 }
3446 Command::Keepalive { target, answered } => {
3447 self.on_keepalive(target, answered).await;
3448 }
3449 Command::Outstanding(reply) => {
3450 let (clients, servers) = self.layer.len();
3451 let _ = reply.send(
3457 clients
3458 + servers
3459 + self.destinations.len()
3460 + self.transaction_generations.len()
3461 + self.tcp_fallbacks.len()
3462 + {
3463 #[cfg(feature = "quic")]
3464 {
3465 self.quic_replies.len()
3466 }
3467 #[cfg(not(feature = "quic"))]
3468 {
3469 0
3470 }
3471 }
3472 + self.reconnect.len()
3473 + self.unanswered_since.len(),
3474 );
3475 }
3476 Command::Settled(reply) => {
3477 self.settled.push(reply);
3478 }
3479 Command::Shutdown => {}
3480 }
3481 }
3482
3483 async fn on_direct_command(
3484 &mut self,
3485 request: Box<Request>,
3486 target: Target,
3487 tcp_fallback: Option<TcpFallback>,
3488 sent: oneshot::Sender<Result<()>>,
3489 ) {
3490 let now = tokio::time::Instant::now().saturating_duration_since(self.overload_epoch);
3491 let category = (self.overload_config.categorize)(&request);
3492 if !self.overload.admit(target.addr, category, now) {
3493 self.meters.overload_rejection();
3494 let _ = sent.send(Err(Error::Overloaded { peer: target.addr }));
3497 return;
3498 }
3499 let method = request.method.clone();
3500 let message = Message::Request(*request);
3501 self.observe_message(
3502 message.clone(),
3503 target.addr,
3504 target.transport,
3505 MessageDirection::Outbound,
3506 TransactionClass::Direct,
3507 );
3508 let bytes = message.to_bytes();
3509 self.observe_out(&bytes, &target, false);
3510 let result = self
3511 .transmit(bytes, target, false, None)
3512 .await
3513 .map(|_| ())
3514 .map_err(|error| match tcp_fallback {
3515 Some(fallback) => fallback.unavailable(error),
3516 None => error,
3517 });
3518 if result.is_err() {
3519 self.meters.unsent(&method);
3523 }
3524 let _ = sent.send(result);
3527 }
3528
3529 async fn on_respond_command(
3530 &mut self,
3531 key: TransactionKey,
3532 response: Box<Response>,
3533 sent: oneshot::Sender<Result<()>>,
3534 ) {
3535 if self.layer.server_request(&key).is_none() {
3536 let _ = sent.send(Err(Error::NoTransaction));
3540 return;
3541 }
3542 let provisional = response.status.is_provisional();
3543 let outputs = self.layer.send_response(&key, *response);
3544 let sent_response = outputs.iter().any(|output| {
3545 matches!(
3546 output,
3547 Output::Send(message) if matches!(message.as_ref(), Message::Response(_))
3548 )
3549 });
3550 let performed = self.perform(&key, outputs, None).await;
3553 if sent_response && performed.sent_message() {
3554 if provisional && self.layer.server_request(&key).is_some() {
3555 if let Some(since) = self.unanswered_since.get_mut(&key) {
3556 *since = tokio::time::Instant::now();
3557 }
3558 } else if !provisional {
3559 self.unanswered_since.remove(&key);
3560 }
3561 }
3562 let _ = sent.send(performed.into_result());
3564 }
3565
3566 async fn perform(
3568 &mut self,
3569 key: &TransactionKey,
3570 outputs: Vec<Output>,
3571 origin: Option<(SocketAddr, TransportKind)>,
3572 ) -> Performed {
3573 let mut sent_message = false;
3574 for output in outputs {
3575 match output {
3576 Output::Send(message) => {
3577 let mut message = *message;
3578 if let Message::Response(response) = &mut message
3579 && let Some(request) = self.layer.server_request(key).cloned()
3580 {
3581 self.decorate_overload_response(response, &request);
3582 }
3583 let target =
3584 self.destinations.get(key).cloned().or_else(|| {
3585 origin.map(|(addr, transport)| Target::new(addr, transport))
3586 });
3587 let Some(target) = target else {
3588 self.meters.discard_no_destination();
3589 tracing::warn!("no destination for a message the transaction wants sent");
3590 continue;
3591 };
3592 let method = match &message {
3595 Message::Request(request) => Some(request.method.clone()),
3596 Message::Response(_) => None,
3597 };
3598 let is_response = method.is_none();
3599 self.observe_message(
3600 message.clone(),
3601 target.addr,
3602 target.transport,
3603 MessageDirection::Outbound,
3604 if is_response {
3605 TransactionClass::Matched
3606 } else {
3607 TransactionClass::ClientCreated
3608 },
3609 );
3610 let bytes = message.to_bytes();
3611 let addr = target.addr;
3612 self.observe_out(&bytes, &target, is_response);
3613 let fallback = self.reconnect.get(key).cloned();
3614 #[cfg(feature = "quic")]
3615 let transmitted = if is_response && target.transport == TransportKind::Quic {
3616 match self.quic_replies.get(key).cloned() {
3617 Some(reply) => reply
3618 .send(bytes)
3619 .await
3620 .map(|()| self.transaction_generations.get(key).cloned())
3621 .map_err(|_| Error::ConnectionClosed),
3622 None => Err(Error::ConnectionClosed),
3623 }
3624 } else {
3625 self.transmit(bytes, target, is_response, fallback).await
3626 };
3627 #[cfg(not(feature = "quic"))]
3628 let transmitted = self.transmit(bytes, target, is_response, fallback).await;
3629 match transmitted {
3630 Ok(Some(generation)) => {
3631 self.transaction_generations.insert(key.clone(), generation);
3632 sent_message = true;
3633 }
3634 Ok(None) => {
3635 self.transaction_generations.remove(key);
3636 sent_message = true;
3637 }
3638 Err(error) => {
3639 let error = match self.tcp_fallbacks.get(key).copied() {
3640 Some(fallback) => fallback.unavailable(error),
3641 None => error,
3642 };
3643 self.meters.discard_send_failure();
3644 if let Some(method) = &method {
3649 self.meters.unsent(method);
3650 }
3651 tracing::warn!(%error, %addr, "send failed");
3652 if let Some(client) = self.clients.get(key) {
3653 let _ = client.failures.try_send(error);
3657 }
3658 let outputs = self.layer.on_transport_error(key);
3659 let remainder = Box::pin(self.perform(key, outputs, origin)).await;
3660 return Performed {
3661 sent_message: sent_message || remainder.sent_message,
3662 };
3663 }
3664 }
3665 }
3666 Output::SetTimer { timer, after } => {
3669 self.timers
3670 .set((key.clone(), timer), tokio::time::Instant::now(), after);
3671 }
3672 Output::ClearTimer(timer) => self.timers.clear(&(key.clone(), timer)),
3673 Output::ToTu(event) => self.deliver(key, *event, origin).await,
3674 Output::Terminated(_) => self.finish_transaction(key),
3675 }
3676 }
3677 Performed { sent_message }
3678 }
3679
3680 fn finish_transaction(&mut self, key: &TransactionKey) {
3681 forget_transaction_timers(&mut self.timers, key);
3682 self.destinations.remove(key);
3683 self.transaction_generations.remove(key);
3684 #[cfg(feature = "quic")]
3685 self.quic_replies.remove(key);
3686 self.unanswered_since.remove(key);
3687 self.reconnect.remove(key);
3688 self.tcp_fallbacks.remove(key);
3689 self.clients.remove(key);
3692 }
3693
3694 fn observe(
3700 &mut self,
3701 peer: SocketAddr,
3702 transport: TransportKind,
3703 direction: Direction,
3704 bytes: impl FnOnce() -> Bytes,
3705 ) {
3706 Capture::observe_if_capturing(
3709 self.capture.as_mut(),
3710 &self.meters,
3711 self.local_addr,
3712 peer,
3713 transport,
3714 direction,
3715 bytes,
3716 );
3717 }
3718
3719 fn observe_message(
3720 &self,
3721 message: Message,
3722 peer: SocketAddr,
3723 transport: TransportKind,
3724 direction: MessageDirection,
3725 transaction: TransactionClass,
3726 ) {
3727 self.observations
3728 .emit(EndpointObservation::Message(Box::new(MessageObservation {
3729 message,
3730 local: self.local_addr,
3731 peer,
3732 transport,
3733 direction,
3734 transaction,
3735 })));
3736 }
3737
3738 fn observe_inbound(
3739 &self,
3740 message: Message,
3741 peer: SocketAddr,
3742 transport: TransportKind,
3743 transaction: TransactionClass,
3744 ) {
3745 self.observe_message(
3746 message,
3747 peer,
3748 transport,
3749 MessageDirection::Inbound,
3750 transaction,
3751 );
3752 }
3753
3754 fn observe_out(&mut self, bytes: &Bytes, target: &Target, is_response: bool) {
3760 self.meters.message_out(target.transport, is_response);
3761 self.observe(target.addr, target.transport, Direction::Out, || {
3763 bytes.clone()
3764 });
3765 }
3766
3767 async fn transmit_raw(
3774 &mut self,
3775 bytes: Bytes,
3776 target: &Target,
3777 ) -> Result<Option<ConnectionGeneration>> {
3778 self.transmit(bytes, target.clone(), true, None).await
3779 }
3780
3781 #[cfg(feature = "quic")]
3782 fn remember_quic_reply(&mut self, key: &TransactionKey, reply: Option<crate::quic::Reply>) {
3783 if let Some(reply) = reply {
3784 self.quic_replies.insert(key.clone(), reply);
3785 }
3786 }
3787
3788 #[cfg(feature = "quic")]
3789 async fn transmit_quic(
3790 &mut self,
3791 bytes: Bytes,
3792 target: &Target,
3793 is_response: bool,
3794 ) -> Result<Option<ConnectionGeneration>> {
3795 if is_response {
3796 return Err(Error::ConnectionClosed);
3797 }
3798 let Some(client) = self.quic_client.clone() else {
3799 return Err(Error::UnsupportedTransport(
3800 "QUIC (no client configuration, so no outbound connection can be verified)",
3801 ));
3802 };
3803 let Some(endpoint) = self.quic_endpoint.clone() else {
3804 return Err(Error::UnsupportedTransport("QUIC (no local endpoint)"));
3805 };
3806 let key = target.connection();
3807 let name = target
3808 .verify_as
3809 .as_deref()
3810 .map_or_else(|| target.addr.ip().to_string(), str::to_owned);
3811 let id = self
3812 .pool
3813 .send_quic_generation(&key, &name, &client, &endpoint, bytes)
3814 .await?;
3815 Ok(Some(ConnectionGeneration { key, id }))
3816 }
3817
3818 async fn transmit(
3826 &mut self,
3827 bytes: Bytes,
3828 target: Target,
3829 is_response: bool,
3830 fallback: Option<Target>,
3831 ) -> Result<Option<ConnectionGeneration>> {
3832 match target.transport {
3833 TransportKind::Udp => {
3834 if !is_response && bytes.len() > self.unreliable_request_limit {
3844 return Err(Error::TooLarge {
3845 size: bytes.len(),
3846 limit: self.unreliable_request_limit,
3847 });
3848 }
3849 let Some(socket) = &self.socket else {
3850 return Err(Error::TransportNotConfigured { transport: "UDP" });
3851 };
3852 socket.send_to(&bytes, target.addr).await?;
3853 Ok(None)
3854 }
3855 TransportKind::Tcp => {
3856 let key = target.connection();
3857 if is_response
3858 && let Some(id) = self
3859 .pool
3860 .send_on_existing_generation(&key, bytes.clone())
3861 .await
3862 {
3863 return Ok(Some(ConnectionGeneration { key, id }));
3864 }
3865 let key = match (is_response, &fallback) {
3869 (true, Some(advertised)) => advertised.connection(),
3870 _ => key,
3871 };
3872 let id = self.pool.send_generation(&key, bytes).await?;
3873 Ok(Some(ConnectionGeneration { key, id }))
3874 }
3875 #[cfg(feature = "tls")]
3876 TransportKind::Tls => {
3877 let key = target.connection();
3881 if is_response
3882 && let Some(id) = self
3883 .pool
3884 .send_on_existing_generation(&key, bytes.clone())
3885 .await
3886 {
3887 return Ok(Some(ConnectionGeneration { key, id }));
3888 }
3889 let Some(client) = self.tls_client.clone() else {
3891 return Err(Error::UnsupportedTransport(
3892 "TLS (no client configuration, so no outbound connection can be verified)",
3893 ));
3894 };
3895 let name = target
3898 .verify_as
3899 .as_deref()
3900 .map_or_else(|| target.addr.ip().to_string(), str::to_owned);
3901 let id = self
3902 .pool
3903 .send_tls_generation(&key, &name, &client, bytes)
3904 .await?;
3905 Ok(Some(ConnectionGeneration { key, id }))
3906 }
3907 #[cfg(feature = "ws")]
3908 TransportKind::Ws | TransportKind::Wss => {
3909 let key = target.connection();
3910 if let Some(id) = self
3917 .pool
3918 .send_on_existing_generation(&key, bytes.clone())
3919 .await
3920 {
3921 return Ok(Some(ConnectionGeneration { key, id }));
3922 }
3923 let authority = target.verify_as.as_deref().map_or_else(
3924 || target.addr.to_string(),
3925 |name| format!("{name}:{}", target.addr.port()),
3926 );
3927 let id = self
3928 .pool
3929 .send_ws_generation(
3930 &key,
3931 &authority,
3932 self.ws_keepalive,
3933 #[cfg(feature = "wss")]
3934 self.tls_client.as_ref(),
3935 bytes,
3936 )
3937 .await?;
3938 Ok(Some(ConnectionGeneration { key, id }))
3939 }
3940 #[cfg(feature = "quic")]
3941 TransportKind::Quic => self.transmit_quic(bytes, &target, is_response).await,
3942 #[allow(unreachable_patterns)]
3943 other => Err(Error::UnsupportedTransport(other.as_str())),
3944 }
3945 }
3946
3947 async fn deliver(
3948 &mut self,
3949 key: &TransactionKey,
3950 event: TuEvent,
3951 origin: Option<(SocketAddr, TransportKind)>,
3952 ) {
3953 if let Some(client) = self.clients.get(key) {
3955 if client.events.send(event).await.is_err() {
3960 self.meters.discard_transaction_event();
3961 tracing::debug!(
3962 "a transaction event had no receiver; the caller stopped listening"
3963 );
3964 }
3965 return;
3966 }
3967
3968 let (source, transport) = origin.unwrap_or((self.local_addr(), TransportKind::Udp));
3969 match event {
3970 TuEvent::Request(request) | TuEvent::Ack(request) => {
3971 let is_ack = request.method == sipx_sip::Method::Ack;
3972 if self
3973 .incoming
3974 .try_send(Incoming {
3975 key: key.clone(),
3976 request: *request,
3977 source,
3978 transport,
3979 connection_generation: self
3980 .transaction_generations
3981 .get(key)
3982 .map(|value| value.id),
3983 })
3984 .is_err()
3985 {
3986 if is_ack {
3990 self.meters.shed.acks.fetch_add(1, Ordering::Relaxed);
3998 tracing::error!(
3999 %source,
4000 "application queue full; an ACK was dropped and cannot be refused — \
4001 the dialog it would have completed will not be reaped"
4002 );
4003 } else {
4004 self.meters.shed.requests.fetch_add(1, Ordering::Relaxed);
4005 tracing::warn!(%source, "application queue full; refusing the transaction");
4006 self.refuse(key).await;
4007 }
4008 }
4009 }
4010 _ => {}
4011 }
4012 }
4013
4014 async fn refuse(&mut self, key: &TransactionKey) {
4015 let Some(status) = sipx_sip::StatusCode::new(503) else {
4016 return;
4017 };
4018 let Some(request) = self.layer.server_request(key).cloned() else {
4019 return;
4020 };
4021 let Ok(builder) =
4022 sipx_sip::build::ResponseBuilder::to_request(&request, status, "Service Unavailable")
4023 else {
4024 return;
4025 };
4026 let Ok(builder) = builder.header(HeaderName::RetryAfter, Bytes::from_static(b"5")) else {
4027 return;
4028 };
4029 self.server_overloaded_until =
4030 Some(tokio::time::Instant::now() + self.overload_config.validity);
4031 let outputs = self.layer.send_response(key, builder.build());
4032 Box::pin(self.perform(key, outputs, None)).await;
4033 }
4034
4035 fn observe_overload_response(&mut self, source: SocketAddr, response: Option<&Response>) {
4038 if !self.overload_config.advertise {
4039 return;
4040 }
4041 if let Some(response) = response {
4042 let now = tokio::time::Instant::now().saturating_duration_since(self.overload_epoch);
4043 self.overload.observe(source, response, now);
4044 }
4045 }
4046
4047 fn decorate_overload_response(&mut self, response: &mut Response, request: &Request) {
4049 let now = tokio::time::Instant::now();
4050 let active_for = self
4051 .server_overloaded_until
4052 .and_then(|until| until.checked_duration_since(now));
4053 let (feedback, validity) = match active_for {
4054 Some(remaining) if !remaining.is_zero() => {
4055 let millis = u64::try_from(remaining.as_millis().max(1)).unwrap_or(u64::MAX);
4056 (
4057 self.overload_config.feedback,
4058 std::time::Duration::from_millis(millis),
4059 )
4060 }
4061 _ => {
4062 self.server_overloaded_until = None;
4063 let stopped = match self.overload_config.feedback {
4064 crate::OverloadFeedback::Loss(_) => crate::OverloadFeedback::Loss(0),
4065 crate::OverloadFeedback::Rate(_) => crate::OverloadFeedback::Rate(0),
4066 };
4067 (stopped, std::time::Duration::ZERO)
4068 }
4069 };
4070 self.overload_sequence = if self.overload_sequence >= 999_999_999_999 {
4071 1
4072 } else {
4073 self.overload_sequence.saturating_add(1)
4074 };
4075 if let Some(sequence) =
4076 sipx_sip::headers::OverloadSequence::from_integer(self.overload_sequence)
4077 {
4078 crate::overload::add_feedback(response, request, feedback, validity, sequence);
4079 }
4080 }
4081
4082 fn local_addr(&self) -> SocketAddr {
4083 self.local_addr
4084 }
4085}
4086
4087async fn receive_udp_until(
4088 socket: Arc<UdpSocket>,
4089 datagrams: mpsc::Sender<(Bytes, SocketAddr)>,
4090 cancel: CancellationToken,
4091) {
4092 let mut buf = vec![0u8; 65_536];
4093 loop {
4094 let received = tokio::select! {
4095 biased;
4096 () = cancel.cancelled() => return,
4097 received = socket.recv_from(&mut buf) => received,
4098 };
4099 let (len, source) = match received {
4100 Ok(received) => received,
4101 Err(error) => {
4102 tracing::warn!(%error, "UDP receive task stopped");
4103 return;
4104 }
4105 };
4106 let mut ready = Vec::with_capacity(UDP_RECEIVE_BATCH);
4107 ready.push((
4108 Bytes::copy_from_slice(buf.get(..len).unwrap_or(&[])),
4109 source,
4110 ));
4111 while ready.len() < UDP_RECEIVE_BATCH {
4112 match socket.try_recv_from(&mut buf) {
4113 Ok((len, source)) => {
4114 ready.push((
4115 Bytes::copy_from_slice(buf.get(..len).unwrap_or(&[])),
4116 source,
4117 ));
4118 }
4119 Err(error) if error.kind() == std::io::ErrorKind::WouldBlock => break,
4120 Err(error) => {
4121 tracing::warn!(%error, "UDP receive task stopped");
4122 return;
4123 }
4124 }
4125 }
4126 for datagram in ready {
4127 tokio::select! {
4128 biased;
4129 () = cancel.cancelled() => return,
4130 sent = datagrams.send(datagram) => {
4131 if sent.is_err() {
4132 return;
4133 }
4134 }
4135 }
4136 }
4137 }
4138}
4139
4140async fn sleep_until(deadline: Option<tokio::time::Instant>) {
4141 match deadline {
4142 Some(deadline) => tokio::time::sleep_until(deadline).await,
4143 None => std::future::pending().await,
4145 }
4146}
4147
4148#[cfg(test)]
4149#[allow(
4150 clippy::unwrap_used,
4151 clippy::expect_used,
4152 clippy::panic,
4153 clippy::indexing_slicing
4154)]
4155mod tests {
4156 use std::sync::Arc;
4157 use std::time::Duration;
4158
4159 use bytes::Bytes;
4160 use sipx_sip::build::{RequestBuilder, ResponseBuilder};
4161 use sipx_sip::{HeaderName, Host, HostName, Method, StatusCode, Uri};
4162 use tokio::net::TcpStream;
4163 #[cfg(any(feature = "tls", feature = "ws"))]
4164 use tokio::sync::Semaphore;
4165 use tokio::sync::mpsc;
4166
4167 #[cfg(any(feature = "tls", feature = "ws"))]
4168 use super::{Adopt, HandshakeObservation, HandshakeRuntime};
4169 use super::{
4170 Background, Driver, Message, ShutdownState, Target, TransportKind, unreliable_request_limit,
4171 };
4172
4173 const IDENTIFIER_SAMPLE_SIZE: u64 = 4096;
4174
4175 #[test]
4176 fn unreliable_request_limit_is_derived_once_from_path_mtu() {
4177 assert_eq!(unreliable_request_limit(None), 1_300);
4178 assert_eq!(unreliable_request_limit(Some(1_500)), 1_300);
4179 assert_eq!(unreliable_request_limit(Some(1_200)), 1_000);
4180 assert_eq!(unreliable_request_limit(Some(100)), 0);
4181 }
4182
4183 fn in_process_request(call_id: &'static [u8]) -> sipx_sip::Request {
4184 let uri = Uri::sip(Host::Name(
4185 HostName::new("callee.example").expect("valid host"),
4186 ));
4187 RequestBuilder::new(Method::Options, uri)
4188 .header(HeaderName::To, Bytes::from_static(b"<sip:callee.example>"))
4189 .expect("valid To")
4190 .header(
4191 HeaderName::From,
4192 Bytes::from_static(b"<sip:caller.example>;tag=caller"),
4193 )
4194 .expect("valid From")
4195 .header(HeaderName::CallId, Bytes::from_static(call_id))
4196 .expect("valid Call-ID")
4197 .cseq(1, &Method::Options)
4198 .expect("valid CSeq")
4199 .max_forwards(70)
4200 .build()
4201 }
4202
4203 #[tokio::test]
4204 async fn in_process_routes_are_bounded_and_closed_consumers_release_capacity() {
4205 let ((originating, _), (answering, mut incoming)) =
4206 super::in_process_pair(1).expect("runtime is entered");
4207 let target = Target::new(answering.local_addr(), TransportKind::Udp);
4208 let first = originating
4209 .send(in_process_request(b"first@example"), target.clone())
4210 .await
4211 .expect("first route is admitted");
4212 let _ = incoming.recv().await.expect("first request arrives");
4213
4214 let refused = originating
4215 .send(in_process_request(b"second@example"), target.clone())
4216 .await
4217 .expect_err("the one-slot route table is full");
4218 assert!(matches!(refused, crate::Error::Overloaded { .. }));
4219
4220 drop(first);
4221 originating
4222 .send(in_process_request(b"third@example"), target)
4223 .await
4224 .expect("a closed response stream releases its route");
4225 }
4226
4227 #[tokio::test]
4228 async fn a_final_in_process_response_releases_its_route() {
4229 let ((originating, _), (answering, mut incoming)) =
4230 super::in_process_pair(1).expect("runtime is entered");
4231 let target = Target::new(answering.local_addr(), TransportKind::Udp);
4232 let mut responses = originating
4233 .send(in_process_request(b"final@example"), target)
4234 .await
4235 .expect("route is admitted");
4236 let invitation = incoming.recv().await.expect("request arrives");
4237 assert_eq!(answering.outstanding().await.expect("route count"), 1);
4238
4239 let status = StatusCode::new(200).expect("valid final status");
4240 let response = ResponseBuilder::to_request(&invitation.request, status, "OK")
4241 .expect("response headers")
4242 .build();
4243 answering
4244 .respond(&invitation.key, response)
4245 .await
4246 .expect("final response is delivered");
4247 assert!(responses.next().await.is_some());
4248 assert_eq!(answering.outstanding().await.expect("route count"), 0);
4249 }
4250
4251 fn bit_counts(values: impl IntoIterator<Item = u64>) -> [usize; 64] {
4252 let mut counts = [0; 64];
4253 for value in values {
4254 for (bit, count) in counts.iter_mut().enumerate() {
4255 *count += usize::from(value & (1_u64 << bit) != 0);
4256 }
4257 }
4258 counts
4259 }
4260
4261 fn assert_full_width(counts: &[usize; 64], subject: &str) {
4262 for (bit, ones) in counts.iter().copied().enumerate() {
4263 assert!(
4264 (1664..=2432).contains(&ones), "{subject} bit {bit} had {ones} ones in {IDENTIFIER_SAMPLE_SIZE} samples"
4266 );
4267 }
4268 }
4269
4270 #[tokio::test]
4271 async fn stream_generation_is_reported_on_both_transaction_boundaries() {
4272 let mut server_config = crate::Config::new("127.0.0.1:0".parse().expect("address"));
4273 server_config.cleartext = crate::CleartextTransports::UdpAndTcp;
4274 let (server, mut incoming) = super::bind(server_config).await.expect("server");
4275 let mut client_config = crate::Config::new("127.0.0.1:0".parse().expect("address"));
4276 client_config.cleartext = crate::CleartextTransports::UdpAndTcp;
4277 let (client, _) = super::bind(client_config).await.expect("client");
4278 let uri = Uri::parse(Bytes::from(format!("sip:{}", server.local_addr()))).expect("URI");
4279 let request = RequestBuilder::new(Method::Options, uri)
4280 .header(HeaderName::To, "<sip:server@example.test>")
4281 .expect("To")
4282 .header(HeaderName::From, "<sip:client@example.test>;tag=a")
4283 .expect("From")
4284 .header(HeaderName::CallId, "generation@example.test")
4285 .expect("Call-ID")
4286 .cseq(1, &Method::Options)
4287 .expect("CSeq")
4288 .max_forwards(70)
4289 .build();
4290 let responses = client
4291 .send(
4292 request,
4293 Target::new(server.local_addr(), TransportKind::Tcp),
4294 )
4295 .await
4296 .expect("transaction starts");
4297 assert!(responses.connection_generation().is_some());
4298 let received = tokio::time::timeout(Duration::from_secs(2), incoming.recv())
4299 .await
4300 .expect("request is bounded")
4301 .expect("server stays open");
4302 assert!(received.connection_generation.is_some());
4303 client.shutdown().await;
4304 server.shutdown().await;
4305 }
4306
4307 #[test]
4311 fn via_branch_keeps_the_cookie_and_all_sixty_four_random_bits() {
4312 let values = (0..IDENTIFIER_SAMPLE_SIZE).map(|_| {
4313 let branch = super::new_branch();
4314 let random = branch
4315 .strip_prefix("z9hG4bK")
4316 .expect("the RFC 3261 magic cookie");
4317 assert_eq!(random.len(), 16, "exactly 64 bits in hexadecimal");
4318 assert!(
4319 random
4320 .bytes()
4321 .all(|byte| byte.is_ascii_hexdigit() && !byte.is_ascii_uppercase()),
4322 "the random portion is canonical lowercase hexadecimal: {random}"
4323 );
4324 u64::from_str_radix(random, 16).expect("the generator wrote hexadecimal")
4325 });
4326 assert_full_width(&bit_counts(values), "Via branch");
4327 }
4328
4329 #[test]
4332 fn via_branch_requires_a_cryptographic_rng_by_construction() {
4333 fn draw<R: rand::CryptoRng + ?Sized>(rng: &mut R) -> String {
4334 super::branch_with_rng(rng)
4335 }
4336
4337 let branch = draw(&mut rand::rng());
4338 assert!(branch.starts_with("z9hG4bK"));
4339 }
4340
4341 #[test]
4344 fn the_width_guard_rejects_a_counter() {
4345 let counts = bit_counts(0..IDENTIFIER_SAMPLE_SIZE);
4346 assert!(
4347 counts.iter().any(|ones| !(1664..=2432).contains(ones)),
4348 "a 12-bit counter must not look like a 64-bit generator"
4349 );
4350 }
4351
4352 async fn driver_with_pool(
4353 pool: crate::tcp::Pool,
4354 net: mpsc::Receiver<crate::tcp::Event>,
4355 ) -> Driver {
4356 let socket = Arc::new(
4357 tokio::net::UdpSocket::bind("127.0.0.1:0")
4358 .await
4359 .expect("UDP binds"),
4360 );
4361 let local_addr = socket.local_addr().expect("local address");
4362 let (_commands_tx, commands) = mpsc::channel(8);
4363 let (_udp_tx, udp) = mpsc::channel(8);
4364 let (incoming, _incoming_rx) = mpsc::channel(8);
4365 let (_accepts_tx, accepts) = mpsc::channel(8);
4366 let (adopt, adopts) = mpsc::channel(8);
4367 let meters = Arc::new(crate::counters::Meters::default());
4368 let admission = Arc::new(crate::policy::SourceAdmission::default());
4369 let observations = Arc::new(crate::policy::ObservationHub::new(Arc::clone(&meters)));
4370 Driver {
4371 socket: Some(socket),
4372 udp,
4373 layer: sipx_sip::transaction::TransactionLayer::new(sipx_sip::Timers::default()),
4374 timers: crate::timers::TimerQueue::new(),
4375 destinations: std::collections::HashMap::new(),
4376 transaction_generations: std::collections::HashMap::new(),
4377 unanswered_since: std::collections::HashMap::new(),
4378 reconnect: std::collections::HashMap::new(),
4379 tcp_fallbacks: std::collections::HashMap::new(),
4380 unanswered_limit: Duration::from_secs(60),
4381 overload: crate::overload::Controller::new(5, 10, 1024),
4382 overload_config: crate::OverloadConfig::default(),
4383 overload_epoch: tokio::time::Instant::now(),
4384 overload_sequence: 0,
4385 server_overloaded_until: None,
4386 clients: std::collections::HashMap::new(),
4387 incoming,
4388 commands,
4389 net,
4390 accepts,
4391 adopts,
4392 _adopt: adopt,
4393 #[cfg(feature = "tls")]
4394 tls_client: None,
4395 #[cfg(feature = "ws")]
4396 ws_keepalive: Duration::from_secs(60),
4397 #[cfg(feature = "quic")]
4398 quic_client: None,
4399 #[cfg(feature = "quic")]
4400 quic_endpoint: None,
4401 pool,
4402 limits: sipx_sip::Limits::stream(),
4403 unreliable_request_limit: unreliable_request_limit(None),
4404 meters,
4405 admission,
4406 observations,
4407 capture: None,
4408 local_addr,
4409 unmatched: None,
4410 stun_waiters: std::collections::HashMap::new(),
4411 pong_waiters: std::collections::HashMap::new(),
4412 #[cfg(feature = "quic")]
4413 quic_replies: std::collections::HashMap::new(),
4414 background: Background::new(),
4415 shutdown: Arc::new(ShutdownState::default()),
4416 settled: Vec::new(),
4417 }
4418 }
4419
4420 #[tokio::test(start_paused = true)]
4421 async fn a_response_with_no_destination_does_not_refresh_application_liveness() {
4422 let (events, net_rx) = mpsc::channel(8);
4423 let pool = crate::tcp::Pool::new(
4424 crate::tcp::PoolConfig::default(),
4425 sipx_sip::Limits::stream(),
4426 events,
4427 );
4428 let mut driver = driver_with_pool(pool, net_rx).await;
4429 let parsed = sipx_sip::parse_datagram(
4430 Bytes::from_static(
4431 b"OPTIONS sip:a@example.com SIP/2.0\r\n\
4432 Via: SIP/2.0/UDP 127.0.0.1:5060;branch=z9hG4bKno-destination\r\n\
4433 To: <sip:a@example.com>\r\n\
4434 From: <sip:b@example.net>;tag=1\r\n\
4435 Call-ID: no-destination@example.net\r\n\
4436 CSeq: 1 OPTIONS\r\n\
4437 Max-Forwards: 70\r\n\
4438 Content-Length: 0\r\n\r\n",
4439 ),
4440 &sipx_sip::Limits::datagram(),
4441 )
4442 .expect("request parses");
4443 let Message::Request(request) = parsed else {
4444 panic!("expected a request");
4445 };
4446 let response =
4447 ResponseBuilder::to_request(&request, StatusCode::new(180).expect("valid"), "Ringing")
4448 .expect("response builds")
4449 .build();
4450 let sipx_sip::transaction::Dispatch::Created { key, .. } = driver
4451 .layer
4452 .receive(Message::Request(request), sipx_sip::Reliability::Unreliable)
4453 else {
4454 panic!("server transaction is created");
4455 };
4456 let handed_over = tokio::time::Instant::now();
4457 driver.unanswered_since.insert(key.clone(), handed_over);
4458
4459 tokio::time::advance(Duration::from_secs(20)).await;
4460 let (sent, result) = tokio::sync::oneshot::channel();
4461 driver
4462 .on_respond_command(key.clone(), Box::new(response), sent)
4463 .await;
4464
4465 assert!(matches!(result.await, Ok(Ok(()))));
4466 assert_eq!(driver.unanswered_since.get(&key), Some(&handed_over));
4467 assert_eq!(driver.meters.snapshot().discards.no_destination, 1);
4468 driver.pool.shutdown().await;
4469 }
4470
4471 #[tokio::test]
4472 async fn stale_close_does_not_fail_a_transaction_on_the_live_generation() {
4473 use sipx_sip::transaction::Reliability;
4474
4475 let listener = tokio::net::TcpListener::bind("127.0.0.1:0")
4476 .await
4477 .expect("TCP binds");
4478 let address = listener.local_addr().expect("listener address");
4479 let peer_socket = TcpStream::connect(address).await.expect("peer connects");
4480 let (server_socket, peer) = listener.accept().await.expect("connection accepts");
4481 let key = crate::ConnectionKey::new(peer, TransportKind::Tcp);
4482 let (net_tx, net_rx) = mpsc::channel(8);
4483 let mut pool = crate::tcp::Pool::new(
4484 crate::tcp::PoolConfig::default(),
4485 sipx_sip::Limits::stream(),
4486 net_tx,
4487 );
4488 pool.accept(server_socket, peer);
4489 assert!(pool.holds(&key), "the live generation is installed");
4490
4491 let mut driver = driver_with_pool(pool, net_rx).await;
4492 let parsed = sipx_sip::parse_datagram(
4493 bytes::Bytes::from_static(
4494 b"OPTIONS sip:a@example.com SIP/2.0\r\n\
4495 Via: SIP/2.0/TCP 127.0.0.1:5555;branch=z9hG4bKstale\r\n\
4496 To: <sip:a@example.com>\r\n\
4497 From: <sip:b@example.net>;tag=1\r\n\
4498 Call-ID: stale-close@example.net\r\n\
4499 CSeq: 1 OPTIONS\r\n\
4500 Max-Forwards: 70\r\n\
4501 Content-Length: 0\r\n\r\n",
4502 ),
4503 &sipx_sip::Limits::datagram(),
4504 )
4505 .expect("request parses");
4506 let Message::Request(request) = parsed else {
4507 panic!("expected a request");
4508 };
4509 let (transaction, _outputs) = driver
4510 .layer
4511 .send_request(request, Reliability::Reliable)
4512 .expect("transaction starts");
4513 driver
4514 .destinations
4515 .insert(transaction.clone(), Target::new(peer, TransportKind::Tcp));
4516 let live_id = driver.pool.generation(&key).expect("live generation");
4517 driver.transaction_generations.insert(
4518 transaction.clone(),
4519 super::ConnectionGeneration {
4520 key: key.clone(),
4521 id: live_id,
4522 },
4523 );
4524 let (client_events, mut received) = mpsc::channel(8);
4525 let (failures, _failure_rx) = mpsc::channel(1);
4526 driver.clients.insert(
4527 transaction.clone(),
4528 super::ClientSink {
4529 events: client_events,
4530 failures,
4531 },
4532 );
4533
4534 driver
4537 .on_net_event(crate::tcp::Event::Closed {
4538 key: key.clone(),
4539 id: 0,
4540 })
4541 .await;
4542
4543 assert!(driver.pool.holds(&key), "the live connection survives");
4544 assert_eq!(driver.layer.len(), (1, 0), "the transaction stays live");
4545 assert!(driver.destinations.contains_key(&transaction));
4546 assert!(driver.clients.contains_key(&transaction));
4547 assert!(
4548 matches!(received.try_recv(), Err(mpsc::error::TryRecvError::Empty)),
4549 "the client receives no stale transport error"
4550 );
4551 driver.pool.shutdown().await;
4552 drop(peer_socket);
4553 }
4554
4555 #[tokio::test]
4556 async fn retiring_current_generation_fails_its_transaction_and_pong_waiter_once() {
4557 use sipx_sip::transaction::Reliability;
4558
4559 let listener = tokio::net::TcpListener::bind("127.0.0.1:0")
4560 .await
4561 .expect("TCP binds");
4562 let address = listener.local_addr().expect("listener address");
4563 let peer_socket = TcpStream::connect(address).await.expect("peer connects");
4564 let (server_socket, peer) = listener.accept().await.expect("connection accepts");
4565 let key = crate::ConnectionKey::new(peer, TransportKind::Tcp);
4566 let (net_tx, net_rx) = mpsc::channel(8);
4567 let mut pool = crate::tcp::Pool::new(
4568 crate::tcp::PoolConfig {
4569 idle_timeout: Duration::ZERO,
4570 ..crate::tcp::PoolConfig::default()
4571 },
4572 sipx_sip::Limits::stream(),
4573 net_tx,
4574 );
4575 pool.accept(server_socket, peer);
4576 let id = pool.generation(&key).expect("generation");
4577 let mut driver = driver_with_pool(pool, net_rx).await;
4578 let parsed = sipx_sip::parse_datagram(
4579 bytes::Bytes::from_static(
4580 b"OPTIONS sip:a@example.com SIP/2.0\r\n\
4581 Via: SIP/2.0/TCP 127.0.0.1:5555;branch=z9hG4bKretire\r\n\
4582 To: <sip:a@example.com>\r\n\
4583 From: <sip:b@example.net>;tag=1\r\n\
4584 Call-ID: retire@example.net\r\n\
4585 CSeq: 1 OPTIONS\r\n\
4586 Max-Forwards: 70\r\n\
4587 Content-Length: 0\r\n\r\n",
4588 ),
4589 &sipx_sip::Limits::datagram(),
4590 )
4591 .expect("request parses");
4592 let Message::Request(request) = parsed else {
4593 panic!("expected request");
4594 };
4595 let (transaction, _outputs) = driver
4596 .layer
4597 .send_request(request, Reliability::Reliable)
4598 .expect("transaction starts");
4599 driver
4600 .destinations
4601 .insert(transaction.clone(), Target::new(peer, TransportKind::Tcp));
4602 let generation = super::ConnectionGeneration {
4603 key: key.clone(),
4604 id,
4605 };
4606 driver
4607 .transaction_generations
4608 .insert(transaction.clone(), generation.clone());
4609 let (client_events, mut received) = mpsc::channel(8);
4610 let (failures, _failure_rx) = mpsc::channel(1);
4611 driver.clients.insert(
4612 transaction,
4613 super::ClientSink {
4614 events: client_events,
4615 failures,
4616 },
4617 );
4618 let (pong, pong_result) = tokio::sync::oneshot::channel();
4619 driver
4620 .pong_waiters
4621 .entry(generation)
4622 .or_default()
4623 .push_back(pong);
4624
4625 assert_eq!(driver.pool.evict_idle(), vec![key.clone()]);
4626 driver
4627 .on_net_event(crate::tcp::Event::Closed {
4628 key: key.clone(),
4629 id,
4630 })
4631 .await;
4632 assert!(matches!(
4633 received.recv().await,
4634 Some(sipx_sip::transaction::TuEvent::TransportError)
4635 ));
4636 assert!(matches!(
4637 pong_result.await,
4638 Ok(Err(crate::Error::ConnectionClosed))
4639 ));
4640 assert!(!driver.pool.holds(&key));
4641
4642 driver
4644 .on_net_event(crate::tcp::Event::Closed { key, id })
4645 .await;
4646 driver.pool.shutdown().await;
4647 drop(peer_socket);
4648 }
4649
4650 #[tokio::test]
4651 async fn queued_old_pong_cannot_answer_the_replacement_generation_waiter() {
4652 let (events, net_rx) = mpsc::channel(8);
4653 let pool = crate::tcp::Pool::new(
4654 crate::tcp::PoolConfig::default(),
4655 sipx_sip::Limits::stream(),
4656 events,
4657 );
4658 let mut driver = driver_with_pool(pool, net_rx).await;
4659 let key = crate::ConnectionKey::new(
4660 "127.0.0.1:59999".parse().expect("address"),
4661 TransportKind::Tcp,
4662 );
4663 let replacement_id = 2;
4664 let (answered, mut answer) = tokio::sync::oneshot::channel();
4665 driver
4666 .pong_waiters
4667 .entry(super::ConnectionGeneration {
4668 key: key.clone(),
4669 id: replacement_id,
4670 })
4671 .or_default()
4672 .push_back(answered);
4673
4674 driver
4675 .on_net_event(crate::tcp::Event::Pong {
4676 key: key.clone(),
4677 id: 1,
4678 })
4679 .await;
4680 assert!(matches!(
4681 answer.try_recv(),
4682 Err(tokio::sync::oneshot::error::TryRecvError::Empty)
4683 ));
4684
4685 driver
4686 .on_net_event(crate::tcp::Event::Pong {
4687 key,
4688 id: replacement_id,
4689 })
4690 .await;
4691 assert!(matches!(answer.await, Ok(Ok(None))));
4692 driver.pool.shutdown().await;
4693 }
4694
4695 fn handle_with_shutdown_barrier(
4696 commands: mpsc::Sender<super::Command>,
4697 shutdown: Arc<ShutdownState>,
4698 ) -> super::Handle {
4699 let meters = Arc::new(crate::counters::Meters::default());
4700 super::Handle {
4701 commands,
4702 shutdown,
4703 draining: Arc::new(std::sync::atomic::AtomicBool::new(false)),
4704 local_addr: "127.0.0.1:5060".parse().expect("address"),
4705 meters: Arc::clone(&meters),
4706 admission: Arc::new(crate::policy::SourceAdmission::default()),
4707 observations: Arc::new(crate::policy::ObservationHub::new(meters)),
4708 request_policy: None,
4709 #[cfg(feature = "tls")]
4710 tls_addr: None,
4711 #[cfg(feature = "tls")]
4712 server_identity: None,
4713 #[cfg(feature = "ws")]
4714 ws_addr: None,
4715 #[cfg(feature = "wss")]
4716 wss_addr: None,
4717 #[cfg(feature = "quic")]
4718 quic_addr: None,
4719 #[cfg(feature = "ws")]
4720 ws_sent_by: Arc::from("shutdown.invalid"),
4721 advertise_overload: false,
4722 sent_by: Arc::new("127.0.0.1".to_owned()),
4723 sent_by_port: 5060,
4724 unreliable_request_limit: unreliable_request_limit(None),
4725 }
4726 }
4727
4728 #[tokio::test]
4729 async fn caller_arriving_after_command_closure_still_waits_for_cleanup_completion() {
4730 let (commands, mut received) = mpsc::channel(8);
4731 let shutdown = Arc::new(ShutdownState::default());
4732 let handle = handle_with_shutdown_barrier(commands, Arc::clone(&shutdown));
4733 let (receiver_closed, closed) = tokio::sync::oneshot::channel();
4734 let (release_cleanup, cleanup_released) = tokio::sync::oneshot::channel();
4735 let driver = tokio::spawn(async move {
4736 assert!(matches!(
4737 received.recv().await,
4738 Some(super::Command::Shutdown)
4739 ));
4740 received.close();
4741 receiver_closed.send(()).expect("test remains present");
4742 cleanup_released.await.expect("cleanup is released");
4743 shutdown.complete();
4744 });
4745
4746 let first = {
4747 let handle = handle.clone();
4748 tokio::spawn(async move { handle.shutdown().await })
4749 };
4750 closed.await.expect("driver closed command receiver");
4751 let late = {
4752 let handle = handle.clone();
4753 tokio::spawn(async move { handle.shutdown().await })
4754 };
4755 tokio::task::yield_now().await;
4756 assert!(
4757 !late.is_finished(),
4758 "late caller waits on the durable barrier after send fails"
4759 );
4760
4761 release_cleanup.send(()).expect("driver remains present");
4762 first.await.expect("first shutdown returns after cleanup");
4763 late.await.expect("late shutdown returns after cleanup");
4764 driver.await.expect("driver completes");
4765 }
4766
4767 #[cfg(any(feature = "tls", feature = "ws"))]
4768 const DEADLINE: Duration = Duration::from_millis(150);
4769
4770 #[cfg(any(feature = "tls", feature = "ws"))]
4771 fn handshake_runtime(
4772 limit: usize,
4773 ) -> (
4774 Background,
4775 HandshakeRuntime,
4776 mpsc::UnboundedReceiver<HandshakeObservation>,
4777 ) {
4778 let owner = Background::new();
4779 let (observations, observed) = mpsc::unbounded_channel();
4780 let runtime = HandshakeRuntime {
4781 deadline: DEADLINE,
4782 permits: Arc::new(Semaphore::new(limit)),
4783 owner: owner.clone(),
4784 observations: Some(observations),
4785 };
4786 (owner, runtime, observed)
4787 }
4788
4789 async fn wait_for_observation(
4790 observed: &mut mpsc::UnboundedReceiver<HandshakeObservation>,
4791 expected: HandshakeObservation,
4792 ) {
4793 assert_eq!(
4794 observed.recv().await.expect("listener remains alive"),
4795 expected
4796 );
4797 }
4798
4799 #[cfg(any(feature = "tls", feature = "ws"))]
4800 async fn wait_for_available(runtime: &HandshakeRuntime, expected: usize) {
4801 for _ in 0..512 {
4802 if runtime.permits.available_permits() == expected {
4803 return;
4804 }
4805 tokio::task::yield_now().await;
4806 }
4807 assert_eq!(runtime.permits.available_permits(), expected);
4808 }
4809
4810 #[cfg(any(feature = "tls", feature = "ws"))]
4811 async fn wait_for_eof(stream: &TcpStream) {
4812 tokio::time::timeout(Duration::from_secs(2), async {
4813 let mut byte = [0u8; 1];
4814 loop {
4815 stream.readable().await.expect("socket remains readable");
4816 match stream.try_read(&mut byte) {
4817 Ok(0) => return,
4818 Ok(_) => panic!("a refused incomplete handshake produced bytes"),
4819 Err(error) if error.kind() == std::io::ErrorKind::WouldBlock => {}
4820 Err(error)
4821 if matches!(
4822 error.kind(),
4823 std::io::ErrorKind::ConnectionReset
4824 | std::io::ErrorKind::ConnectionAborted
4825 | std::io::ErrorKind::BrokenPipe
4826 ) =>
4827 {
4828 return;
4829 }
4830 Err(error) => panic!("unexpected read error: {error}"),
4831 }
4832 }
4833 })
4834 .await
4835 .expect("peer closes within the configured handshake deadline");
4836 }
4837
4838 #[cfg(any(feature = "tls", feature = "ws"))]
4839 fn open_source_policy() -> (
4840 Arc<crate::policy::SourceAdmission>,
4841 Arc<crate::counters::Meters>,
4842 ) {
4843 (
4844 Arc::new(crate::policy::SourceAdmission::default()),
4845 Arc::new(crate::counters::Meters::default()),
4846 )
4847 }
4848
4849 #[cfg(feature = "ws")]
4851 #[tokio::test]
4852 async fn websocket_handshake_budget_has_deterministic_admission_and_reclamation() {
4853 let (owner, runtime, mut observed) = handshake_runtime(2);
4854 let (admission, meters) = open_source_policy();
4855 let (adopt, mut adopted) = mpsc::channel::<Adopt>(8);
4856 let address = super::listen_ws(
4857 "127.0.0.1".parse().expect("loopback"),
4858 0,
4859 Duration::from_secs(60),
4860 sipx_sip::Limits::stream(),
4861 &adopt,
4862 &runtime,
4863 admission,
4864 meters,
4865 )
4866 .await
4867 .expect("listener binds");
4868
4869 let first = TcpStream::connect(address).await.expect("first connects");
4870 wait_for_observation(&mut observed, HandshakeObservation::Admitted).await;
4871 wait_for_available(&runtime, 1).await;
4872 let second = TcpStream::connect(address).await.expect("second connects");
4873 wait_for_observation(&mut observed, HandshakeObservation::Admitted).await;
4874 wait_for_available(&runtime, 0).await;
4875
4876 for _ in 0..16 {
4877 let refused = TcpStream::connect(address).await.expect("excess connects");
4878 wait_for_observation(&mut observed, HandshakeObservation::Refused).await;
4879 wait_for_eof(&refused).await;
4880 }
4881
4882 wait_for_eof(&first).await;
4883 wait_for_eof(&second).await;
4884 wait_for_available(&runtime, 2).await;
4885
4886 let stream = TcpStream::connect(address)
4887 .await
4888 .expect("connects after deadline");
4889 let socket = crate::ws::connect(stream, &address.to_string(), "/", false)
4890 .await
4891 .expect("released permit admits an upgrade");
4892 let adoption = adopted.recv().await.expect("upgraded socket is adopted");
4893 drop(adoption);
4894 drop(socket);
4895 owner.shutdown().await;
4896 }
4897
4898 #[cfg(all(feature = "tls", feature = "ws"))]
4900 #[tokio::test]
4901 async fn tls_and_websocket_share_one_deterministic_handshake_budget() {
4902 use sipx_testkit::certs::Ca;
4903
4904 use crate::tls::{Identity, ServerTls};
4905
4906 let ca = Ca::new();
4907 let (certificate, key) = ca.issue_for("localhost");
4908 let identity =
4909 Identity::from_pem(certificate.as_bytes(), key.as_bytes()).expect("an identity");
4910 let (owner, runtime, mut observed) = handshake_runtime(1);
4911 let (admission, meters) = open_source_policy();
4912 let (adopt, mut adopted) = mpsc::channel::<Adopt>(8);
4913 let (_identity_tx, identity_rx) = tokio::sync::watch::channel(None);
4914 let tls_address = super::listen_tls(
4915 "127.0.0.1".parse().expect("loopback"),
4916 0,
4917 super::ServerHandshakePolicy::new(
4918 ServerTls::new(identity).expect("a server"),
4919 identity_rx,
4920 ),
4921 &adopt,
4922 &runtime,
4923 Arc::clone(&admission),
4924 Arc::clone(&meters),
4925 )
4926 .await
4927 .expect("TLS listener binds");
4928 let ws_address = super::listen_ws(
4929 "127.0.0.1".parse().expect("loopback"),
4930 0,
4931 Duration::from_secs(60),
4932 sipx_sip::Limits::stream(),
4933 &adopt,
4934 &runtime,
4935 admission,
4936 meters,
4937 )
4938 .await
4939 .expect("WebSocket listener binds");
4940
4941 let partial_tls = TcpStream::connect(tls_address).await.expect("TLS connects");
4942 wait_for_observation(&mut observed, HandshakeObservation::Admitted).await;
4943 wait_for_available(&runtime, 0).await;
4944 let refused_ws = TcpStream::connect(ws_address)
4945 .await
4946 .expect("WebSocket TCP connects");
4947 wait_for_observation(&mut observed, HandshakeObservation::Refused).await;
4948 wait_for_eof(&refused_ws).await;
4949
4950 wait_for_eof(&partial_tls).await;
4951 wait_for_available(&runtime, 1).await;
4952
4953 let stream = TcpStream::connect(ws_address)
4954 .await
4955 .expect("connects after deadline");
4956 let socket = crate::ws::connect(stream, &ws_address.to_string(), "/", false)
4957 .await
4958 .expect("released shared permit admits WebSocket");
4959 let adoption = adopted.recv().await.expect("upgraded socket is adopted");
4960 drop(adoption);
4961 drop(socket);
4962 owner.shutdown().await;
4963 }
4964
4965 #[cfg(feature = "wss")]
4967 #[tokio::test]
4968 async fn wss_handshake_budget_has_deterministic_admission_and_reclamation() {
4969 use sipx_testkit::certs::Ca;
4970
4971 use crate::tls::{Identity, ServerTls};
4972
4973 let ca = Ca::new();
4974 let (certificate, key) = ca.issue_for("localhost");
4975 let identity =
4976 Identity::from_pem(certificate.as_bytes(), key.as_bytes()).expect("an identity");
4977 let (owner, runtime, mut observed) = handshake_runtime(1);
4978 let (admission, meters) = open_source_policy();
4979 let (adopt, _adopted) = mpsc::channel::<Adopt>(8);
4980 let (_identity_tx, identity_rx) = tokio::sync::watch::channel(None);
4981 let address = super::listen_wss(
4982 "127.0.0.1".parse().expect("loopback"),
4983 0,
4984 super::ServerHandshakePolicy::new(
4985 ServerTls::new(identity).expect("a server"),
4986 identity_rx,
4987 ),
4988 Duration::from_secs(60),
4989 sipx_sip::Limits::stream(),
4990 &adopt,
4991 &runtime,
4992 admission,
4993 meters,
4994 )
4995 .await
4996 .expect("WSS listener binds");
4997
4998 let first = TcpStream::connect(address).await.expect("first connects");
4999 wait_for_observation(&mut observed, HandshakeObservation::Admitted).await;
5000 wait_for_available(&runtime, 0).await;
5001 let refused = TcpStream::connect(address).await.expect("second connects");
5002 wait_for_observation(&mut observed, HandshakeObservation::Refused).await;
5003 wait_for_eof(&refused).await;
5004
5005 wait_for_eof(&first).await;
5006 wait_for_available(&runtime, 1).await;
5007
5008 let admitted = TcpStream::connect(address).await.expect("third connects");
5009 wait_for_observation(&mut observed, HandshakeObservation::Admitted).await;
5010 wait_for_available(&runtime, 0).await;
5011 owner.shutdown().await;
5012 wait_for_eof(&admitted).await;
5013 }
5014}