1use std::{collections::VecDeque, fmt, future::Future, io, pin::Pin};
4
5use tokio::io::{AsyncRead, AsyncWrite};
6
7use crate::{
8 ConnectTarget, NoPipeline, StartupParameters,
9 pipeline::{BackendAction, FrontendAction, FrontendHandling, Pipeline, PipelinePolicy},
10};
11
12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub enum CancellationPolicy {
18 Reject,
20 Forward,
22}
23
24#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
26pub enum EstablishmentFailurePolicy {
27 #[default]
29 Close,
30 SafeDiagnostic,
32}
33
34fn safe_establishment_diagnostic() -> crate::codec::BackendMessage {
35 crate::codec::BackendMessage::ErrorResponse(crate::codec::DiagnosticResponse {
36 fields: vec![
37 crate::codec::DiagnosticField {
38 code: b'S',
39 value: bytes::Bytes::from_static(b"ERROR"),
40 },
41 crate::codec::DiagnosticField {
42 code: b'M',
43 value: bytes::Bytes::from_static(b"connection establishment failed"),
44 },
45 ],
46 })
47}
48
49#[derive(Clone, Debug, Eq, PartialEq)]
51pub struct CancellationRoute {
52 target: ConnectTarget,
53 upstream: crate::demux::CancelKey,
54}
55
56impl CancellationRoute {
57 #[must_use]
59 pub const fn new(target: ConnectTarget, upstream: crate::demux::CancelKey) -> Self {
60 Self { target, upstream }
61 }
62 #[must_use]
64 pub const fn target(&self) -> &ConnectTarget {
65 &self.target
66 }
67 #[must_use]
69 pub const fn upstream_key(&self) -> &crate::demux::CancelKey {
70 &self.upstream
71 }
72}
73
74pub trait IntermediaryCancellationRegistry {
80 type Error;
82 fn register(&self, route: CancellationRoute) -> Result<crate::demux::CancelKey, Self::Error>;
88 fn resolve(&self, client: &crate::demux::CancelKey) -> Option<CancellationRoute>;
90 fn detach(&self, client: &crate::demux::CancelKey) -> Option<CancellationRoute>;
92}
93
94#[derive(Clone, Copy, Debug, Default)]
96pub struct RejectCancellation;
97impl IntermediaryCancellationRegistry for RejectCancellation {
98 type Error = std::convert::Infallible;
99 fn register(&self, _: CancellationRoute) -> Result<crate::demux::CancelKey, Self::Error> {
100 unreachable!()
101 }
102 fn resolve(&self, _: &crate::demux::CancelKey) -> Option<CancellationRoute> {
103 None
104 }
105 fn detach(&self, _: &crate::demux::CancelKey) -> Option<CancellationRoute> {
106 None
107 }
108}
109
110#[derive(Clone, Copy, Debug, Eq, PartialEq)]
112pub enum IntermediaryBuildError {
113 MissingServer,
115 MissingClient,
117 MissingStartupResolver,
119 MissingCancellationPolicy,
121}
122
123impl fmt::Display for IntermediaryBuildError {
124 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
125 formatter.write_str(match self {
126 Self::MissingServer => "an intermediary server component is required",
127 Self::MissingClient => "an intermediary client component is required",
128 Self::MissingStartupResolver => "an asynchronous startup resolver is required",
129 Self::MissingCancellationPolicy => "an explicit cancellation policy is required",
130 })
131 }
132}
133
134impl std::error::Error for IntermediaryBuildError {}
135
136#[derive(Clone, Copy, Debug)]
138pub struct InitialServerContext<'a, Peer> {
139 peer: &'a Peer,
140 tls: &'a crate::NegotiatedServerTls,
141}
142
143impl<'a, Peer> InitialServerContext<'a, Peer> {
144 pub(crate) const fn new(peer: &'a Peer, tls: &'a crate::NegotiatedServerTls) -> Self {
145 Self { peer, tls }
146 }
147
148 #[must_use]
150 pub const fn peer(&self) -> &Peer {
151 self.peer
152 }
153
154 #[must_use]
156 pub const fn tls(&self) -> &crate::NegotiatedServerTls {
157 self.tls
158 }
159}
160
161pub trait StartupRouteResolver<Peer> {
163 type Error;
165
166 fn resolve<'a>(
168 &'a self,
169 startup: StartupParameters,
170 context: InitialServerContext<'a, Peer>,
171 ) -> Pin<Box<dyn Future<Output = Result<ConnectTarget, Self::Error>> + 'a>>;
172}
173
174pub trait AuthenticatedRoutePolicy<Peer, Identity> {
176 type Error;
178 fn route<'a>(
180 &'a self,
181 target: ConnectTarget,
182 context: AuthenticatedRouteContext<'a, Peer, Identity>,
183 ) -> Pin<Box<dyn Future<Output = Result<ConnectTarget, Self::Error>> + 'a>>;
184}
185
186#[derive(Clone, Copy, Debug)]
188pub struct AuthenticatedRouteContext<'a, Peer, Identity> {
189 peer: &'a Peer,
190 identity: &'a Identity,
191}
192
193impl<Peer, Identity> AuthenticatedRouteContext<'_, Peer, Identity> {
194 #[must_use]
196 pub const fn peer(&self) -> &Peer {
197 self.peer
198 }
199
200 #[must_use]
202 pub const fn identity(&self) -> &Identity {
203 self.identity
204 }
205}
206
207#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
209pub struct AllowAuthenticatedRoute;
210
211impl<Peer, Identity> AuthenticatedRoutePolicy<Peer, Identity> for AllowAuthenticatedRoute {
212 type Error = std::convert::Infallible;
213 fn route<'a>(
214 &'a self,
215 target: ConnectTarget,
216 _context: AuthenticatedRouteContext<'a, Peer, Identity>,
217 ) -> Pin<Box<dyn Future<Output = Result<ConnectTarget, Self::Error>> + 'a>> {
218 Box::pin(async move { Ok(target) })
219 }
220}
221
222#[derive(Debug, Eq, PartialEq)]
224pub enum FrontendMiddlewareOutput {
225 Forward(crate::codec::FrontendMessage),
227 Suppress(crate::codec::FrontendMessage),
229 Respond {
231 request: crate::codec::FrontendMessage,
233 responses: Vec<crate::codec::BackendMessage>,
235 },
236}
237
238#[derive(Debug, Eq, PartialEq)]
240pub enum BackendMiddlewareOutput {
241 Forward(crate::codec::BackendMessage),
243 Expand(Vec<crate::codec::BackendMessage>),
245 Suppress(crate::codec::BackendMessage),
247}
248
249pub trait IntermediaryMiddleware<State, ServerContext, ClientContext> {
251 type Error;
253
254 fn frontend<'a>(
257 &'a mut self,
258 _server: &'a ServerContext,
259 _client: &'a ClientContext,
260 _state: &'a mut State,
261 message: crate::codec::FrontendMessage,
262 ) -> Pin<Box<dyn Future<Output = Result<FrontendMiddlewareOutput, Self::Error>> + 'a>> {
263 Box::pin(async move { Ok(FrontendMiddlewareOutput::Forward(message)) })
264 }
265
266 fn backend<'a>(
269 &'a mut self,
270 _server: &'a ServerContext,
271 _client: &'a ClientContext,
272 _state: &'a mut State,
273 message: crate::codec::BackendMessage,
274 ) -> Pin<Box<dyn Future<Output = Result<BackendMiddlewareOutput, Self::Error>> + 'a>> {
275 Box::pin(async move { Ok(BackendMiddlewareOutput::Forward(message)) })
276 }
277}
278
279#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
281pub struct IdentityIntermediaryMiddleware;
282
283impl<State, ServerContext, ClientContext>
284 IntermediaryMiddleware<State, ServerContext, ClientContext> for IdentityIntermediaryMiddleware
285{
286 type Error = std::convert::Infallible;
287}
288
289pub trait IntermediaryMiddlewareFactory<ServerContext, ClientContext> {
291 type Handler;
293 fn create(&self, server: &ServerContext, client: &ClientContext) -> Self::Handler;
295}
296
297impl<ServerContext, ClientContext, Handler, Factory>
298 IntermediaryMiddlewareFactory<ServerContext, ClientContext> for Factory
299where
300 Factory: Fn(&ServerContext, &ClientContext) -> Handler,
301{
302 type Handler = Handler;
303 fn create(&self, server: &ServerContext, client: &ClientContext) -> Handler {
304 self(server, client)
305 }
306}
307
308impl<ServerContext, ClientContext> IntermediaryMiddlewareFactory<ServerContext, ClientContext>
309 for IdentityIntermediaryMiddleware
310{
311 type Handler = Self;
312 fn create(&self, _server: &ServerContext, _client: &ClientContext) -> Self {
313 *self
314 }
315}
316
317pub struct Intermediary<
319 Server = (),
320 Client = (),
321 Resolver = (),
322 Route = AllowAuthenticatedRoute,
323 Policy = NoPipeline,
324 Boundary = IdentityIntermediaryMiddleware,
325 Cancellation = RejectCancellation,
326> {
327 pub(crate) server: Server,
328 pub(crate) client: Client,
329 pub(crate) resolver: Resolver,
330 pub(crate) route: Route,
331 pub(crate) pipeline: Policy,
332 pub(crate) boundary: Boundary,
333 pub(crate) cancellation: CancellationPolicy,
334 pub(crate) cancellation_registry: Cancellation,
335 pub(crate) failure_policy: EstablishmentFailurePolicy,
336}
337
338impl Intermediary<()> {
339 #[must_use]
341 pub fn builder() -> IntermediaryBuilder {
342 IntermediaryBuilder::default()
343 }
344}
345
346impl<S, C, R, A, P, B, K> fmt::Debug for Intermediary<S, C, R, A, P, B, K> {
347 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
348 formatter
349 .debug_struct("Intermediary")
350 .field("server", &"<configured>")
351 .field("client", &"<configured>")
352 .field("resolver", &"<redacted>")
353 .field("authenticated_route", &"<redacted>")
354 .field("cancellation", &self.cancellation)
355 .finish_non_exhaustive()
356 }
357}
358
359pub struct IntermediaryBuilder<
361 Server = (),
362 Client = (),
363 Resolver = (),
364 Route = AllowAuthenticatedRoute,
365 Policy = NoPipeline,
366 Boundary = IdentityIntermediaryMiddleware,
367 Cancellation = RejectCancellation,
368> {
369 server: Option<Server>,
370 client: Option<Client>,
371 resolver: Option<Resolver>,
372 route: Route,
373 pipeline: Policy,
374 boundary: Boundary,
375 cancellation: Option<CancellationPolicy>,
376 cancellation_registry: Cancellation,
377 failure_policy: EstablishmentFailurePolicy,
378}
379
380impl Default for IntermediaryBuilder {
381 fn default() -> Self {
382 Self {
383 server: None,
384 client: None,
385 resolver: None,
386 route: AllowAuthenticatedRoute,
387 pipeline: NoPipeline,
388 boundary: IdentityIntermediaryMiddleware,
389 cancellation: None,
390 cancellation_registry: RejectCancellation,
391 failure_policy: EstablishmentFailurePolicy::Close,
392 }
393 }
394}
395
396impl<S, C, R, A, P, B, K> IntermediaryBuilder<S, C, R, A, P, B, K> {
397 #[must_use]
399 pub fn server<Next>(self, server: Next) -> IntermediaryBuilder<Next, C, R, A, P, B, K> {
400 IntermediaryBuilder {
401 server: Some(server),
402 client: self.client,
403 resolver: self.resolver,
404 route: self.route,
405 pipeline: self.pipeline,
406 boundary: self.boundary,
407 cancellation: self.cancellation,
408 cancellation_registry: self.cancellation_registry,
409 failure_policy: self.failure_policy,
410 }
411 }
412
413 #[must_use]
415 pub fn client<Next>(self, client: Next) -> IntermediaryBuilder<S, Next, R, A, P, B, K> {
416 IntermediaryBuilder {
417 server: self.server,
418 client: Some(client),
419 resolver: self.resolver,
420 route: self.route,
421 pipeline: self.pipeline,
422 boundary: self.boundary,
423 cancellation: self.cancellation,
424 cancellation_registry: self.cancellation_registry,
425 failure_policy: self.failure_policy,
426 }
427 }
428
429 #[must_use]
431 pub fn startup_resolver<Next>(
432 self,
433 resolver: Next,
434 ) -> IntermediaryBuilder<S, C, Next, A, P, B, K> {
435 IntermediaryBuilder {
436 server: self.server,
437 client: self.client,
438 resolver: Some(resolver),
439 route: self.route,
440 pipeline: self.pipeline,
441 boundary: self.boundary,
442 cancellation: self.cancellation,
443 cancellation_registry: self.cancellation_registry,
444 failure_policy: self.failure_policy,
445 }
446 }
447
448 #[must_use]
450 pub fn authenticated_route<Next>(
451 self,
452 route: Next,
453 ) -> IntermediaryBuilder<S, C, R, Next, P, B, K> {
454 IntermediaryBuilder {
455 server: self.server,
456 client: self.client,
457 resolver: self.resolver,
458 route,
459 pipeline: self.pipeline,
460 boundary: self.boundary,
461 cancellation: self.cancellation,
462 cancellation_registry: self.cancellation_registry,
463 failure_policy: self.failure_policy,
464 }
465 }
466
467 #[must_use]
469 pub fn pipeline<Next: PipelinePolicy>(
470 self,
471 pipeline: Next,
472 ) -> IntermediaryBuilder<S, C, R, A, Next, B, K> {
473 IntermediaryBuilder {
474 server: self.server,
475 client: self.client,
476 resolver: self.resolver,
477 route: self.route,
478 pipeline,
479 boundary: self.boundary,
480 cancellation: self.cancellation,
481 cancellation_registry: self.cancellation_registry,
482 failure_policy: self.failure_policy,
483 }
484 }
485
486 #[must_use]
488 pub fn middleware<Next>(self, boundary: Next) -> IntermediaryBuilder<S, C, R, A, P, Next, K> {
489 IntermediaryBuilder {
490 server: self.server,
491 client: self.client,
492 resolver: self.resolver,
493 route: self.route,
494 pipeline: self.pipeline,
495 boundary,
496 cancellation: self.cancellation,
497 cancellation_registry: self.cancellation_registry,
498 failure_policy: self.failure_policy,
499 }
500 }
501
502 #[must_use]
504 pub fn cancellation(mut self, cancellation: CancellationPolicy) -> Self {
505 self.cancellation = match cancellation {
506 CancellationPolicy::Reject => Some(CancellationPolicy::Reject),
507 CancellationPolicy::Forward => None,
508 };
509 self
510 }
511
512 #[must_use]
514 pub fn establishment_failure(mut self, policy: EstablishmentFailurePolicy) -> Self {
515 self.failure_policy = policy;
516 self
517 }
518
519 #[must_use]
521 pub fn cancellation_registry<Next>(
522 self,
523 registry: Next,
524 ) -> IntermediaryBuilder<S, C, R, A, P, B, Next> {
525 IntermediaryBuilder {
526 server: self.server,
527 client: self.client,
528 resolver: self.resolver,
529 route: self.route,
530 pipeline: self.pipeline,
531 boundary: self.boundary,
532 cancellation: Some(CancellationPolicy::Forward),
533 cancellation_registry: registry,
534 failure_policy: self.failure_policy,
535 }
536 }
537
538 #[allow(clippy::type_complexity)]
544 pub fn build(self) -> Result<Intermediary<S, C, R, A, P, B, K>, IntermediaryBuildError> {
545 Ok(Intermediary {
546 server: self.server.ok_or(IntermediaryBuildError::MissingServer)?,
547 client: self.client.ok_or(IntermediaryBuildError::MissingClient)?,
548 resolver: self
549 .resolver
550 .ok_or(IntermediaryBuildError::MissingStartupResolver)?,
551 route: self.route,
552 pipeline: self.pipeline,
553 boundary: self.boundary,
554 cancellation: self
555 .cancellation
556 .ok_or(IntermediaryBuildError::MissingCancellationPolicy)?,
557 cancellation_registry: self.cancellation_registry,
558 failure_policy: self.failure_policy,
559 })
560 }
561}
562
563struct StartupResolverAdapter<'a, Resolver> {
564 resolver: &'a Resolver,
565}
566
567#[derive(Debug)]
569pub enum StartupResolutionError<Error> {
570 Parameters(io::Error),
572 Resolver(Error),
574}
575
576impl<Error: fmt::Display> fmt::Display for StartupResolutionError<Error> {
577 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
578 match self {
579 Self::Parameters(error) => error.fmt(formatter),
580 Self::Resolver(error) => error.fmt(formatter),
581 }
582 }
583}
584
585impl<Error: std::error::Error + 'static> std::error::Error for StartupResolutionError<Error> {
586 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
587 match self {
588 Self::Parameters(error) => Some(error),
589 Self::Resolver(error) => Some(error),
590 }
591 }
592}
593
594impl<Resolver, State, Peer, Identity>
595 crate::server_component::StartupResolver<State, Peer, Identity>
596 for StartupResolverAdapter<'_, Resolver>
597where
598 Resolver: StartupRouteResolver<Peer>,
599{
600 type Route = ConnectTarget;
601 type Error = StartupResolutionError<Resolver::Error>;
602
603 fn defer_ready(&self) -> bool {
604 true
605 }
606
607 fn resolve<'a>(
608 &'a mut self,
609 startup: &'a crate::startup::StartupMessage,
610 context: &'a crate::ServerConnectionContext<Peer, Identity>,
611 _state: &'a mut State,
612 ) -> Pin<Box<dyn Future<Output = Result<Self::Route, Self::Error>> + 'a>> {
613 let parameters = StartupParameters::from_wire(startup);
614 let initial = context
615 .tls_if_known()
616 .map(|tls| InitialServerContext::new(context.peer(), tls));
617 let resolver = self.resolver;
618 Box::pin(async move {
619 let parameters = parameters.map_err(StartupResolutionError::Parameters)?;
620 let initial = initial.expect("startup routing runs after TLS negotiation");
621 resolver
622 .resolve(parameters, initial)
623 .await
624 .map_err(StartupResolutionError::Resolver)
625 })
626 }
627}
628
629pub enum IntermediaryAcceptError<
631 ServerError,
632 ResolverError,
633 RouteError,
634 ClientError,
635 RegistryError = std::convert::Infallible,
636 CancellationError = std::convert::Infallible,
637 MiddlewareError = std::convert::Infallible,
638> {
639 Server(ServerError),
641 StartupRoute(StartupResolutionError<ResolverError>),
643 CancellationRejected,
645 AuthenticatedRoute(RouteError),
647 Client(ClientError),
649 CancellationRegistry(RegistryError),
651 ServerOutput(io::Error),
653 Cancellation(CancellationError),
655 Middleware(MiddlewareError),
657}
658
659impl<S, R, A, C, K, X, M> fmt::Debug for IntermediaryAcceptError<S, R, A, C, K, X, M> {
660 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
661 formatter.write_str(match self {
662 Self::Server(_) => "IntermediaryAcceptError::Server([REDACTED])",
663 Self::StartupRoute(_) => "IntermediaryAcceptError::StartupRoute([REDACTED])",
664 Self::CancellationRejected => "IntermediaryAcceptError::CancellationRejected",
665 Self::AuthenticatedRoute(_) => {
666 "IntermediaryAcceptError::AuthenticatedRoute([REDACTED])"
667 }
668 Self::Client(_) => "IntermediaryAcceptError::Client([REDACTED])",
669 Self::CancellationRegistry(_) => {
670 "IntermediaryAcceptError::CancellationRegistry([REDACTED])"
671 }
672 Self::ServerOutput(_) => "IntermediaryAcceptError::ServerOutput([REDACTED])",
673 Self::Cancellation(_) => "IntermediaryAcceptError::Cancellation([REDACTED])",
674 Self::Middleware(_) => "IntermediaryAcceptError::Middleware([REDACTED])",
675 })
676 }
677}
678
679impl<S, R, A, C, K, X, M> fmt::Display for IntermediaryAcceptError<S, R, A, C, K, X, M> {
680 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
681 match self {
682 Self::Server(_) => formatter.write_str("client-facing establishment failed"),
683 Self::StartupRoute(_) => formatter.write_str("startup routing failed"),
684 Self::CancellationRejected => {
685 formatter.write_str("cancellation is explicitly rejected")
686 }
687 Self::AuthenticatedRoute(_) => formatter.write_str("authenticated routing failed"),
688 Self::Client(_) => formatter.write_str("PostgreSQL-facing establishment failed"),
689 Self::CancellationRegistry(_) => {
690 formatter.write_str("cancellation registration failed")
691 }
692 Self::ServerOutput(_) => {
693 formatter.write_str("client-facing establishment output failed")
694 }
695 Self::Cancellation(_) => formatter.write_str("cancellation forwarding failed"),
696 Self::Middleware(_) => {
697 formatter.write_str("forwarding middleware rejected establishment output")
698 }
699 }
700 }
701}
702
703impl<S, R, A, C, K, X, M> std::error::Error for IntermediaryAcceptError<S, R, A, C, K, X, M>
704where
705 S: std::error::Error + 'static,
706 R: std::error::Error + 'static,
707 A: std::error::Error + 'static,
708 C: std::error::Error + 'static,
709 K: std::error::Error + 'static,
710 X: std::error::Error + 'static,
711 M: std::error::Error + 'static,
712{
713 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
714 match self {
715 Self::Server(error) => Some(error),
716 Self::StartupRoute(error) => Some(error),
717 Self::CancellationRejected => None,
718 Self::AuthenticatedRoute(error) => Some(error),
719 Self::Client(error) => Some(error),
720 Self::CancellationRegistry(error) => Some(error),
721 Self::ServerOutput(error) => Some(error),
722 Self::Cancellation(error) => Some(error),
723 Self::Middleware(error) => Some(error),
724 }
725 }
726}
727
728#[derive(Debug)]
730pub struct IntermediaryContexts<ServerContext, ClientContext> {
731 server: ServerContext,
732 client: ClientContext,
733}
734
735impl<ServerContext, ClientContext> IntermediaryContexts<ServerContext, ClientContext> {
736 #[must_use]
738 pub const fn server(&self) -> &ServerContext {
739 &self.server
740 }
741 #[must_use]
743 pub const fn client(&self) -> &ClientContext {
744 &self.client
745 }
746}
747
748pub struct IntermediaryConnection<
750 DT,
751 UT,
752 State,
753 Peer,
754 ServerIdentity,
755 ClientEvidence,
756 ServerHandler,
757 ClientHandler,
758 Boundary,
759 Policy,
760 Cancellation = RejectCancellation,
761> {
762 downstream:
763 crate::server_component::ServerConnectionCore<DT, Peer, ServerIdentity, ServerHandler>,
764 upstream: crate::client_component::ClientConnectionCore<
765 crate::ClientTransport<UT>,
766 crate::Pristine,
767 ClientEvidence,
768 ClientHandler,
769 >,
770 state: State,
771 boundary: Boundary,
772 pipeline: Pipeline<Policy>,
773 target: ConnectTarget,
774 pending_frontend: Option<crate::codec::FrontendMessage>,
775 pending_local: VecDeque<PendingLocalResponses>,
776 cancellation_registry: Cancellation,
777 client_cancel_key: Option<crate::demux::CancelKey>,
778}
779
780struct PendingLocalResponses {
781 operation: crate::pipeline::OperationId,
782 messages: VecDeque<crate::codec::BackendMessage>,
783}
784
785#[derive(Debug)]
787pub enum IntermediaryAccept<Connection> {
788 Session(Connection),
790 CancellationForwarded,
792}
793
794impl<Connection> IntermediaryAccept<Connection> {
795 #[must_use]
800 pub fn into_session(self) -> Connection {
801 match self {
802 Self::Session(connection) => connection,
803 Self::CancellationForwarded => panic!("accepted cancellation has no session"),
804 }
805 }
806}
807
808#[derive(Debug)]
810pub enum ForwardedMessage {
811 Frontend(crate::codec::FrontendMessage),
813 Backend(crate::codec::BackendMessage),
815 BackendExpanded {
817 source: crate::codec::BackendMessage,
819 messages: Vec<crate::codec::BackendMessage>,
821 },
822 FrontendSuppressed(crate::codec::FrontendMessage),
824 FrontendLocallyHandled(crate::codec::FrontendMessage),
826 BackendSuppressed(crate::codec::BackendMessage),
828}
829
830#[derive(Debug, Eq, PartialEq)]
832pub enum FrontendForwarding {
833 Forwarded(crate::codec::FrontendMessage),
835 Suppressed(crate::codec::FrontendMessage),
837 LocallyHandled(crate::codec::FrontendMessage),
839}
840
841impl FrontendForwarding {
842 #[must_use]
844 pub fn into_message(self) -> crate::codec::FrontendMessage {
845 match self {
846 Self::Forwarded(message)
847 | Self::Suppressed(message)
848 | Self::LocallyHandled(message) => message,
849 }
850 }
851}
852
853#[derive(Debug, Eq, PartialEq)]
855pub enum BackendForwarding {
856 Forwarded(crate::codec::BackendMessage),
858 Expanded {
860 source: crate::codec::BackendMessage,
862 messages: Vec<crate::codec::BackendMessage>,
864 },
865 Suppressed(crate::codec::BackendMessage),
867}
868
869impl BackendForwarding {
870 #[must_use]
872 pub fn into_message(self) -> crate::codec::BackendMessage {
873 match self {
874 Self::Forwarded(message) | Self::Suppressed(message) => message,
875 Self::Expanded { source, .. } => source,
876 }
877 }
878}
879
880impl<DT, UT, State, Peer, SI, CE, SH, CH, Boundary, Policy, K>
881 IntermediaryConnection<DT, UT, State, Peer, SI, CE, SH, CH, Boundary, Policy, K>
882where
883 Policy: PipelinePolicy,
884{
885 #[must_use]
887 pub const fn target(&self) -> &ConnectTarget {
888 &self.target
889 }
890 #[must_use]
892 pub const fn state(&self) -> &State {
893 &self.state
894 }
895 #[must_use]
897 pub const fn cancellation_key(&self) -> Option<&crate::demux::CancelKey> {
898 self.client_cancel_key.as_ref()
899 }
900
901 pub fn detach_cancellation(&mut self) -> Option<CancellationRoute>
903 where
904 K: IntermediaryCancellationRegistry,
905 {
906 self.client_cancel_key
907 .take()
908 .and_then(|key| self.cancellation_registry.detach(&key))
909 }
910}
911
912impl<
913 DT,
914 UT,
915 State,
916 Peer,
917 ServerIdentity,
918 ClientEvidence,
919 ServerHandler,
920 ClientHandler,
921 Boundary,
922 Policy,
923 K,
924>
925 IntermediaryConnection<
926 DT,
927 UT,
928 State,
929 Peer,
930 ServerIdentity,
931 ClientEvidence,
932 ServerHandler,
933 ClientHandler,
934 Boundary,
935 Policy,
936 K,
937 >
938where
939 DT: AsyncRead + AsyncWrite + Unpin,
940 UT: AsyncRead + AsyncWrite + Unpin,
941 ServerHandler:
942 crate::ServerMiddleware<State, crate::ServerConnectionContext<Peer, ServerIdentity>>,
943 ClientHandler: crate::ClientMiddleware<State, crate::ClientConnectionContext<ClientEvidence>>,
944 Boundary: IntermediaryMiddleware<
945 State,
946 crate::ServerConnectionContext<Peer, ServerIdentity>,
947 crate::ClientConnectionContext<ClientEvidence>,
948 >,
949 Policy: PipelinePolicy,
950 K: IntermediaryCancellationRegistry,
951{
952 pub async fn forward_frontend(
959 &mut self,
960 ) -> Result<FrontendForwarding, ForwardError<Boundary::Error>> {
961 if let Some(message) = self.pending_frontend.take() {
962 self.process_frontend(message, false).await
963 } else {
964 let message = self.downstream.receive_wire_raw().await?;
965 self.process_frontend(message, true).await
966 }
967 }
968
969 async fn process_frontend(
970 &mut self,
971 message: crate::codec::FrontendMessage,
972 intercept_source_and_boundary: bool,
973 ) -> Result<FrontendForwarding, ForwardError<Boundary::Error>> {
974 let decision = if intercept_source_and_boundary {
975 let message = self.downstream.intercept_frontend(&mut self.state, message);
976 self.boundary
977 .frontend(
978 self.downstream.context(),
979 self.upstream.context(),
980 &mut self.state,
981 message,
982 )
983 .await
984 .map_err(ForwardError::Middleware)?
985 } else {
986 FrontendMiddlewareOutput::Forward(message)
987 };
988 let (message, handling) = match decision {
989 FrontendMiddlewareOutput::Forward(message) => {
990 let message = if intercept_source_and_boundary {
991 self.upstream.intercept_frontend(&mut self.state, message)
992 } else {
993 message
994 };
995 (message, FrontendHandling::Forward)
996 }
997 FrontendMiddlewareOutput::Suppress(message) => {
998 return Ok(FrontendForwarding::Suppressed(message));
999 }
1000 FrontendMiddlewareOutput::Respond { request, responses } => {
1001 let admission = self
1002 .pipeline
1003 .accept_frontend(request.clone(), FrontendHandling::Local)
1004 .map_err(ForwardError::Frontend)?;
1005 let FrontendAction::Discard { id } = admission.into_action() else {
1006 unreachable!()
1007 };
1008 let messages = responses
1009 .into_iter()
1010 .map(|message| self.downstream.intercept_backend(&mut self.state, message))
1011 .collect();
1012 self.pending_local.push_back(PendingLocalResponses {
1013 operation: id,
1014 messages,
1015 });
1016 self.flush_local_responses().await?;
1017 return Ok(FrontendForwarding::LocallyHandled(request));
1018 }
1019 };
1020 let admission = match self.pipeline.accept_frontend(message.clone(), handling) {
1021 Ok(admission) => admission,
1022 Err(error) => {
1023 self.pending_frontend = Some(message);
1024 return Err(ForwardError::Frontend(error));
1025 }
1026 };
1027 let FrontendAction::Forward { message, .. } = admission.into_action() else {
1028 unreachable!()
1029 };
1030 self.upstream.send_wire_raw(message.clone()).await?;
1031 Ok(FrontendForwarding::Forwarded(message))
1032 }
1033
1034 pub async fn forward_backend(
1047 &mut self,
1048 ) -> Result<BackendForwarding, ForwardError<Boundary::Error>> {
1049 let message = self.upstream.receive_wire_raw().await?;
1050 self.process_backend(message).await
1051 }
1052
1053 async fn process_backend(
1054 &mut self,
1055 message: crate::codec::BackendMessage,
1056 ) -> Result<BackendForwarding, ForwardError<Boundary::Error>> {
1057 let message = self.upstream.intercept_backend(&mut self.state, message);
1058 let source = message.clone();
1059 let decision = self
1060 .boundary
1061 .backend(
1062 self.downstream.context(),
1063 self.upstream.context(),
1064 &mut self.state,
1065 message,
1066 )
1067 .await
1068 .map_err(ForwardError::Middleware)?;
1069 let outcome = match decision {
1070 BackendMiddlewareOutput::Forward(message) => {
1071 let message = self.downstream.intercept_backend(&mut self.state, message);
1072 let message = self.emit_backend(message).await?;
1073 BackendForwarding::Forwarded(message)
1074 }
1075 BackendMiddlewareOutput::Suppress(message) => {
1076 let message = self.advance_backend(message)?;
1077 BackendForwarding::Suppressed(message)
1078 }
1079 BackendMiddlewareOutput::Expand(messages) => {
1080 if messages.is_empty() {
1081 return Err(ForwardError::EmptyExpansion(source));
1082 }
1083 let mut emitted = Vec::with_capacity(messages.len());
1084 for message in messages {
1085 let message = self.downstream.intercept_backend(&mut self.state, message);
1086 emitted.push(self.emit_backend(message).await?);
1087 }
1088 BackendForwarding::Expanded {
1089 source,
1090 messages: emitted,
1091 }
1092 }
1093 };
1094 self.flush_local_responses().await?;
1095 Ok(outcome)
1096 }
1097
1098 fn advance_backend(
1099 &mut self,
1100 message: crate::codec::BackendMessage,
1101 ) -> Result<crate::codec::BackendMessage, ForwardError<Boundary::Error>> {
1102 match self
1103 .pipeline
1104 .accept_backend(message)
1105 .map_err(ForwardError::Backend)?
1106 {
1107 BackendAction::Emit(message) => Ok(message),
1108 BackendAction::Deferred(message) => Err(ForwardError::Deferred(message)),
1109 }
1110 }
1111
1112 async fn emit_backend(
1113 &mut self,
1114 message: crate::codec::BackendMessage,
1115 ) -> Result<crate::codec::BackendMessage, ForwardError<Boundary::Error>> {
1116 let message = self.advance_backend(message)?;
1117 self.downstream.send_wire_raw(message.clone()).await?;
1118 Ok(message)
1119 }
1120
1121 async fn flush_local_responses(&mut self) -> Result<(), ForwardError<Boundary::Error>> {
1122 loop {
1123 let Some(pending) = self.pending_local.front_mut() else {
1124 return Ok(());
1125 };
1126 let Some(message) = pending.messages.pop_front() else {
1127 self.pending_local.pop_front();
1128 continue;
1129 };
1130 match self.pipeline.try_emit_local(pending.operation, message) {
1131 Ok(BackendAction::Emit(message)) => {
1132 self.downstream.send_wire_raw(message).await?;
1133 }
1134 Ok(BackendAction::Deferred(message)) => {
1135 pending.messages.push_front(message);
1136 return Ok(());
1137 }
1138 Err(error) => return Err(ForwardError::Backend(error)),
1139 }
1140 }
1141 }
1142
1143 pub async fn forward_next(
1154 &mut self,
1155 ) -> Result<ForwardedMessage, ForwardError<Boundary::Error>> {
1156 if self.pending_frontend.is_some() {
1157 let message = self.upstream.receive_wire_raw().await?;
1158 return self
1159 .process_backend(message)
1160 .await
1161 .map(|outcome| match outcome {
1162 BackendForwarding::Forwarded(message) => ForwardedMessage::Backend(message),
1163 BackendForwarding::Expanded { source, messages } => {
1164 ForwardedMessage::BackendExpanded { source, messages }
1165 }
1166 BackendForwarding::Suppressed(message) => {
1167 ForwardedMessage::BackendSuppressed(message)
1168 }
1169 });
1170 }
1171 tokio::select! {
1172 result = self.downstream.receive_wire_raw() => {
1173 let message = result?;
1174 self.process_frontend(message, true).await.map(|outcome| match outcome {
1175 FrontendForwarding::Forwarded(message) => ForwardedMessage::Frontend(message),
1176 FrontendForwarding::Suppressed(message) => ForwardedMessage::FrontendSuppressed(message),
1177 FrontendForwarding::LocallyHandled(message) => ForwardedMessage::FrontendLocallyHandled(message),
1178 })
1179 }
1180 result = self.upstream.receive_wire_raw() => {
1181 let message = result?;
1182 self.process_backend(message).await.map(|outcome| match outcome {
1183 BackendForwarding::Forwarded(message) => ForwardedMessage::Backend(message),
1184 BackendForwarding::Expanded { source, messages } => {
1185 ForwardedMessage::BackendExpanded { source, messages }
1186 }
1187 BackendForwarding::Suppressed(message) => ForwardedMessage::BackendSuppressed(message),
1188 })
1189 }
1190 }
1191 }
1192
1193 #[allow(clippy::type_complexity)]
1196 pub fn teardown(
1197 mut self,
1198 ) -> (
1199 crate::AcceptedServerTransport<DT>,
1200 crate::ClientTransport<UT>,
1201 State,
1202 Boundary,
1203 (ServerHandler, ClientHandler),
1204 IntermediaryContexts<
1205 crate::ServerConnectionContext<Peer, ServerIdentity>,
1206 crate::ClientConnectionContext<ClientEvidence>,
1207 >,
1208 ) {
1209 let _ = self.detach_cancellation();
1210 let (downstream, server_handler, server_context) = self.downstream.into_parts();
1211 let (upstream, client_handler, client_context) = self.upstream.into_parts();
1212 (
1213 downstream,
1214 upstream,
1215 self.state,
1216 self.boundary,
1217 (server_handler, client_handler),
1218 IntermediaryContexts {
1219 server: server_context,
1220 client: client_context,
1221 },
1222 )
1223 }
1224}
1225
1226#[derive(Debug)]
1228pub enum ForwardError<MiddlewareError = std::convert::Infallible> {
1229 Io(io::Error),
1231 Frontend(crate::pipeline::FrontendProjectionError),
1233 Backend(crate::pipeline::BackendProjectionError),
1235 Deferred(crate::codec::BackendMessage),
1237 EmptyExpansion(crate::codec::BackendMessage),
1239 Middleware(MiddlewareError),
1241}
1242
1243impl<E> fmt::Display for ForwardError<E> {
1244 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1245 match self {
1246 Self::Io(error) => error.fmt(formatter),
1247 Self::Frontend(_) => {
1248 formatter.write_str("frontend message violates pipeline legality or capacity")
1249 }
1250 Self::Backend(_) => formatter.write_str("backend message violates pipeline legality"),
1251 Self::Deferred(_) => formatter.write_str("backend response is not yet emittable"),
1252 Self::EmptyExpansion(_) => {
1253 formatter.write_str("backend expansion must contain at least one response")
1254 }
1255 Self::Middleware(_) => formatter.write_str("forwarding middleware rejected a message"),
1256 }
1257 }
1258}
1259
1260impl<E> std::error::Error for ForwardError<E>
1261where
1262 E: std::error::Error + 'static,
1263{
1264 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1265 match self {
1266 Self::Io(error) => Some(error),
1267 Self::Middleware(error) => Some(error),
1268 Self::Frontend(_) | Self::Backend(_) | Self::Deferred(_) | Self::EmptyExpansion(_) => {
1269 None
1270 }
1271 }
1272 }
1273}
1274
1275impl<E> From<io::Error> for ForwardError<E> {
1276 fn from(error: io::Error) -> Self {
1277 Self::Io(error)
1278 }
1279}
1280
1281impl<ST, SA, SM, Connector, CT, CA, CM, Resolver, Route, Policy, Boundary, K>
1282 Intermediary<
1283 crate::Server<ST, SA, SM>,
1284 crate::Client<Connector, CT, CA, CM>,
1285 Resolver,
1286 Route,
1287 Policy,
1288 Boundary,
1289 K,
1290 >
1291where
1292 ST: crate::ServerTlsConfiguration,
1293 SA: crate::ServerAuthenticationProvider,
1294 CT: crate::client_component::ClientTlsConfiguration,
1295 CA: crate::ClientAuthentication,
1296 CM: crate::MiddlewareFactory<crate::ClientInitialContext>,
1297 Policy: PipelinePolicy,
1298 K: IntermediaryCancellationRegistry + Clone,
1299{
1300 #[allow(clippy::type_complexity, clippy::too_many_lines)]
1307 pub async fn accept<DT, State, Peer, CW, UT, CE>(
1308 &self,
1309 transport: DT,
1310 peer: Peer,
1311 state: State,
1312 ) -> Result<
1313 IntermediaryAccept<
1314 IntermediaryConnection<
1315 DT,
1316 UT,
1317 State,
1318 Peer,
1319 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1320 CA::Evidence,
1321 <SM as crate::MiddlewareFactory<
1322 crate::ServerConnectionContext<
1323 Peer,
1324 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1325 >,
1326 >>::Handler,
1327 <CM as crate::MiddlewareFactory<crate::ClientInitialContext>>::Handler,
1328 <Boundary as IntermediaryMiddlewareFactory<
1329 crate::ServerConnectionContext<
1330 Peer,
1331 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1332 >,
1333 crate::ClientConnectionContext<CA::Evidence>,
1334 >>::Handler,
1335 Policy,
1336 K,
1337 >,
1338 >,
1339 IntermediaryAcceptError<
1340 crate::AcceptError<
1341 <ST::Provider as crate::ServerIdentityProvider>::Error,
1342 <SA::Authentication as crate::ServerAuthentication<Peer>>::Error,
1343 >,
1344 Resolver::Error,
1345 Route::Error,
1346 crate::ConnectError<
1347 CE,
1348 crate::ClientTlsError<<CT::Provider as crate::ClientTlsProvider>::Error>,
1349 crate::ClientAuthenticationError<CA::Error>,
1350 >,
1351 K::Error,
1352 crate::CancelError<CE>,
1353 <<Boundary as IntermediaryMiddlewareFactory<
1354 crate::ServerConnectionContext<
1355 Peer,
1356 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1357 >,
1358 crate::ClientConnectionContext<CA::Evidence>,
1359 >>::Handler as IntermediaryMiddleware<
1360 State,
1361 crate::ServerConnectionContext<
1362 Peer,
1363 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1364 >,
1365 crate::ClientConnectionContext<CA::Evidence>,
1366 >>::Error,
1367 >,
1368 >
1369 where
1370 DT: AsyncRead + AsyncWrite + Unpin,
1371 UT: AsyncRead + AsyncWrite + Unpin,
1372 SA::Authentication: crate::ServerAuthentication<Peer>,
1373 SM: crate::MiddlewareFactory<
1374 crate::ServerConnectionContext<
1375 Peer,
1376 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1377 >,
1378 >,
1379 <SM as crate::MiddlewareFactory<
1380 crate::ServerConnectionContext<
1381 Peer,
1382 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1383 >,
1384 >>::Handler: crate::ServerMiddleware<
1385 State,
1386 crate::ServerConnectionContext<
1387 Peer,
1388 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1389 >,
1390 >,
1391 Resolver: StartupRouteResolver<Peer>,
1392 Connector: Fn(&ConnectTarget) -> CW,
1393 CW: Future<Output = Result<UT, CE>>,
1394 <CM as crate::MiddlewareFactory<crate::ClientInitialContext>>::Handler:
1395 crate::ClientMiddleware<State, crate::ClientConnectionContext<CA::Evidence>>,
1396 Route: AuthenticatedRoutePolicy<
1397 Peer,
1398 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1399 >,
1400 Boundary: IntermediaryMiddlewareFactory<
1401 crate::ServerConnectionContext<
1402 Peer,
1403 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1404 >,
1405 crate::ClientConnectionContext<CA::Evidence>,
1406 >,
1407 <Boundary as IntermediaryMiddlewareFactory<
1408 crate::ServerConnectionContext<
1409 Peer,
1410 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1411 >,
1412 crate::ClientConnectionContext<CA::Evidence>,
1413 >>::Handler: IntermediaryMiddleware<
1414 State,
1415 crate::ServerConnectionContext<
1416 Peer,
1417 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1418 >,
1419 crate::ClientConnectionContext<CA::Evidence>,
1420 >,
1421 {
1422 let mut resolver = StartupResolverAdapter {
1423 resolver: &self.resolver,
1424 };
1425 let (accepted, selected) = self
1426 .server
1427 .accept_routed(transport, peer, state, &mut resolver)
1428 .await
1429 .map_err(|error| match error {
1430 crate::server_component::RoutedAcceptError::Accept(error) => {
1431 IntermediaryAcceptError::Server(error)
1432 }
1433 crate::server_component::RoutedAcceptError::Route(error) => {
1434 IntermediaryAcceptError::StartupRoute(error)
1435 }
1436 })?;
1437 let mut downstream = match accepted {
1438 crate::ServerAccept::Session(downstream) => downstream,
1439 crate::ServerAccept::Cancellation(cancellation) => {
1440 if self.cancellation == CancellationPolicy::Reject {
1441 let _ = cancellation.teardown();
1442 return Err(IntermediaryAcceptError::CancellationRejected);
1443 }
1444 let request = cancellation.request();
1445 let client_key = crate::demux::CancelKey {
1446 process_id: request.process_id(),
1447 secret_key: bytes::Bytes::copy_from_slice(request.secret_key()),
1448 };
1449 let Some(route) = self.cancellation_registry.resolve(&client_key) else {
1450 let _ = cancellation.teardown();
1451 return Err(IntermediaryAcceptError::CancellationRejected);
1452 };
1453 if let Err(error) = self
1454 .client
1455 .cancel(route.target(), route.upstream_key())
1456 .await
1457 {
1458 let _ = cancellation.teardown();
1459 return Err(IntermediaryAcceptError::Cancellation(error));
1460 }
1461 let _ = cancellation.teardown();
1462 return Ok(IntermediaryAccept::CancellationForwarded);
1463 }
1464 };
1465 let startup = match StartupParameters::from_wire(downstream.startup()) {
1466 Ok(startup) => startup,
1467 Err(error) => {
1468 if self.failure_policy == EstablishmentFailurePolicy::SafeDiagnostic {
1469 let _ = downstream
1470 .send_generated_error(safe_establishment_diagnostic())
1471 .await;
1472 }
1473 let _ = downstream.teardown();
1474 return Err(IntermediaryAcceptError::StartupRoute(
1475 StartupResolutionError::Parameters(error),
1476 ));
1477 }
1478 };
1479 let context = AuthenticatedRouteContext {
1480 peer: downstream.context().peer(),
1481 identity: downstream.context().identity(),
1482 };
1483 let Some(selected) = selected else {
1484 let _ = downstream.teardown();
1485 return Err(IntermediaryAcceptError::CancellationRejected);
1486 };
1487 let selected = match self.route.route(selected, context).await {
1488 Ok(target) => target,
1489 Err(error) => {
1490 if self.failure_policy == EstablishmentFailurePolicy::SafeDiagnostic {
1491 let _ = downstream
1492 .send_generated_error(safe_establishment_diagnostic())
1493 .await;
1494 }
1495 let _ = downstream.teardown();
1496 return Err(IntermediaryAcceptError::AuthenticatedRoute(error));
1497 }
1498 };
1499 let (mut downstream, mut state) = downstream.into_core_and_state();
1500 let upstream = match self
1501 .client
1502 .connect_core(selected.clone(), startup, &mut state)
1503 .await
1504 {
1505 Ok(upstream) => upstream,
1506 Err(error) => {
1507 if self.failure_policy == EstablishmentFailurePolicy::SafeDiagnostic {
1508 let diagnostic = safe_establishment_diagnostic();
1509 let diagnostic = downstream.intercept_backend(&mut state, diagnostic);
1510 if matches!(diagnostic, crate::codec::BackendMessage::ErrorResponse(_)) {
1511 let _ = downstream.send_wire_raw(diagnostic).await;
1514 }
1515 }
1516 let _ = downstream.into_parts();
1517 return Err(IntermediaryAcceptError::Client(error));
1518 }
1519 };
1520 let boundary = self
1521 .boundary
1522 .create(downstream.context(), upstream.context());
1523 let (client_cancel_key, backend_key_message) =
1524 match (self.cancellation, upstream.context().backend_key().cloned()) {
1525 (CancellationPolicy::Forward, Some(upstream_key)) => {
1526 let client_key = match self
1527 .cancellation_registry
1528 .register(CancellationRoute::new(selected.clone(), upstream_key))
1529 {
1530 Ok(key) => key,
1531 Err(error) => {
1532 if self.failure_policy == EstablishmentFailurePolicy::SafeDiagnostic {
1533 let diagnostic = downstream
1534 .intercept_backend(&mut state, safe_establishment_diagnostic());
1535 if matches!(
1536 diagnostic,
1537 crate::codec::BackendMessage::ErrorResponse(_)
1538 ) {
1539 let _ = downstream.send_wire_raw(diagnostic).await;
1540 }
1541 }
1542 let _ = downstream.into_parts();
1543 let _ = upstream.into_parts();
1544 return Err(IntermediaryAcceptError::CancellationRegistry(error));
1545 }
1546 };
1547 let message = crate::codec::BackendMessage::BackendKeyData {
1548 process_id: client_key.process_id,
1549 secret_key: client_key.secret_key.clone(),
1550 };
1551 (Some(client_key), Some(message))
1552 }
1553 _ => (None, None),
1554 };
1555 let mut connection = IntermediaryConnection {
1556 downstream,
1557 upstream,
1558 state,
1559 boundary,
1560 pipeline: Pipeline::new(self.pipeline),
1561 target: selected,
1562 pending_frontend: None,
1563 pending_local: VecDeque::new(),
1564 cancellation_registry: self.cancellation_registry.clone(),
1565 client_cancel_key,
1566 };
1567 if let Some(message) = backend_key_message {
1568 let expected = message.clone();
1569 let message = connection
1570 .boundary
1571 .backend(
1572 connection.downstream.context(),
1573 connection.upstream.context(),
1574 &mut connection.state,
1575 message,
1576 )
1577 .await;
1578 let message = match message {
1579 Ok(BackendMiddlewareOutput::Forward(message)) => message,
1580 Ok(BackendMiddlewareOutput::Suppress(_) | BackendMiddlewareOutput::Expand(_)) => {
1581 let _ = connection.detach_cancellation();
1582 let _ = connection.teardown();
1583 return Err(IntermediaryAcceptError::ServerOutput(io::Error::new(
1584 io::ErrorKind::InvalidData,
1585 "middleware suppressed or expanded generated cancellation key",
1586 )));
1587 }
1588 Err(error) => {
1589 let _ = connection.detach_cancellation();
1590 let _ = connection.teardown();
1591 return Err(IntermediaryAcceptError::Middleware(error));
1592 }
1593 };
1594 let message = connection
1595 .downstream
1596 .intercept_backend(&mut connection.state, message);
1597 if message != expected {
1598 let _ = connection.detach_cancellation();
1599 let _ = connection.teardown();
1600 return Err(IntermediaryAcceptError::ServerOutput(io::Error::new(
1601 io::ErrorKind::InvalidData,
1602 "middleware rejected generated cancellation key",
1603 )));
1604 }
1605 if let Err(error) = connection.downstream.send_wire_raw(message).await {
1606 let _ = connection.detach_cancellation();
1607 let _ = connection.teardown();
1608 return Err(IntermediaryAcceptError::ServerOutput(error));
1609 }
1610 }
1611 let ready = connection.downstream.intercept_backend(
1612 &mut connection.state,
1613 crate::codec::BackendMessage::ReadyForQuery(crate::codec::TransactionStatus::Idle),
1614 );
1615 if !matches!(ready, crate::codec::BackendMessage::ReadyForQuery(_)) {
1616 let _ = connection.detach_cancellation();
1617 let _ = connection.teardown();
1618 return Err(IntermediaryAcceptError::ServerOutput(io::Error::new(
1619 io::ErrorKind::InvalidData,
1620 "middleware rejected generated readiness",
1621 )));
1622 }
1623 if let Err(error) = connection.downstream.send_wire_raw(ready).await {
1624 let _ = connection.detach_cancellation();
1625 let _ = connection.teardown();
1626 return Err(IntermediaryAcceptError::ServerOutput(error));
1627 }
1628 Ok(IntermediaryAccept::Session(connection))
1629 }
1630}