pub struct Connection<S, Tx>{
pub connection_info: Arc<ConnectionInfo>,
pub(super) state: State,
pub(super) request_timer: Option<Pin<Box<Sleep>>>,
pub(super) cached_addrs: Vec<MetaAddr>,
pub(super) svc: S,
pub(super) client_rx: ClientRequestReceiver,
pub(super) error_slot: ErrorSlot,
pub(super) peer_tx: PeerTx<Tx>,
pub(super) connection_tracker: ConnectionTracker,
pub(super) metrics_label: String,
pub(super) last_metrics_state: Option<Cow<'static, str>>,
last_overload_time: Option<Instant>,
}Expand description
The channels, services, and associated state for a peer connection.
Fields§
§connection_info: Arc<ConnectionInfo>The metadata for the connected peer service.
This field is used for debugging.
state: StateThe state of this connection’s current request or response.
request_timer: Option<Pin<Box<Sleep>>>A timeout for a client request. This is stored separately from State so that we can move the future out of it independently of other state handling.
cached_addrs: Vec<MetaAddr>Unused peers from recent addr or addrv2 messages from this peer.
Also holds the initial addresses sent in version messages, or guessed from the remote IP.
When peers send solicited or unsolicited peer advertisements, Zebra puts them in this cache.
When Zebra’s components request peers, some cached peers are randomly selected,
consumed, and returned as a modified response. This works around zcashd’s address
response rate-limit.
The cache size is limited to avoid denial of service attacks.
svc: SThe inbound service, used to answer requests from this connection’s peer.
client_rx: ClientRequestReceiverA channel for requests that Zebra’s internal services want to send to remote peers.
This channel accepts Requests, and produces InProgressClientRequests.
error_slot: ErrorSlotA slot for an error shared between the Connection and the Client that uses it.
None unless the connection or client have errored.
peer_tx: PeerTx<Tx>A channel for sending Zcash messages to the connected peer.
This channel accepts Messages.
The corresponding peer message receiver is passed to Connection::run.
connection_tracker: ConnectionTrackerA connection tracker that reduces the open connection count when dropped. Used to limit the number of open connections in Zebra.
This field does nothing until it is dropped.
§Security
If this connection tracker or Connections are leaked,
the number of active connections will appear higher than it actually is.
If enough connections leak, Zebra will stop making new connections.
metrics_label: StringThe metrics label for this peer. Usually the remote IP and port.
last_metrics_state: Option<Cow<'static, str>>The state for this peer, when the metrics were last updated.
last_overload_time: Option<Instant>The time of the last overload error response from the inbound service to a request from this connection, or None if this connection hasn’t yet received an overload error.
Implementations§
Source§impl<S, Tx> Connection<S, Tx>
impl<S, Tx> Connection<S, Tx>
Sourcepub(crate) fn new(
inbound_service: S,
client_rx: Receiver<ClientRequest>,
error_slot: ErrorSlot,
peer_tx: Tx,
connection_tracker: ConnectionTracker,
connection_info: Arc<ConnectionInfo>,
initial_cached_addrs: Vec<MetaAddr>,
) -> Self
pub(crate) fn new( inbound_service: S, client_rx: Receiver<ClientRequest>, error_slot: ErrorSlot, peer_tx: Tx, connection_tracker: ConnectionTracker, connection_info: Arc<ConnectionInfo>, initial_cached_addrs: Vec<MetaAddr>, ) -> Self
Return a new connection from its channels, services, shared state, and metadata.
Source§impl<S, Tx> Connection<S, Tx>
impl<S, Tx> Connection<S, Tx>
Sourcepub async fn run<Rx>(self, peer_rx: Rx)
pub async fn run<Rx>(self, peer_rx: Rx)
Consume this Connection to form a spawnable future containing its event loop.
peer_rx is a channel for receiving Zcash Messages from the connected peer.
The corresponding peer message receiver is Connection::peer_tx.
Sourceasync fn fail_with(&mut self, error: impl Into<SharedPeerError>)
async fn fail_with(&mut self, error: impl Into<SharedPeerError>)
Fail this connection, log the failure, and shut it down.
See Self::shutdown_async() for details.
Use Self::shutdown_async() to avoid logging the failure,
and Self::shutdown() from non-async code.
Sourceasync fn handle_client_request(&mut self, req: InProgressClientRequest)
async fn handle_client_request(&mut self, req: InProgressClientRequest)
Handle an internal client request, possibly generating outgoing messages to the remote peer.
NOTE: the caller should use .instrument(msg.span) to instrument the function.
Sourceasync fn handle_message_as_request(&mut self, msg: Message) -> Option<Message>
async fn handle_message_as_request(&mut self, msg: Message) -> Option<Message>
Handle msg as a request from a peer to this Zebra instance.
If the message is not handled, it is returned.
Sourceasync fn drive_peer_request(&mut self, req: Request)
async fn drive_peer_request(&mut self, req: Request)
Given a req originating from the peer, drive it to completion and send
any appropriate messages to the remote peer. If an error occurs while
processing the request (e.g., the service is shedding load), then we call
fail_with to terminate the entire peer connection, shrinking the number
of connected peers.
Sourceasync fn handle_inbound_overload(
&mut self,
req: Request,
now: Instant,
error: PeerError,
)
async fn handle_inbound_overload( &mut self, req: Request, now: Instant, error: PeerError, )
Handle inbound service overload and timeout error responses by randomly terminating some connections.
§Security
When the inbound service is overloaded with requests, Zebra needs to drop some connections,
to reduce the load on the application. But dropping every connection that receives an
Overloaded error from the inbound service could cause Zebra to drop too many peer
connections, and stop itself downloading blocks or transactions.
Malicious or misbehaving peers can also overload the inbound service, and make Zebra drop its connections to other peers.
So instead, Zebra drops some overloaded connections at random. If a connection has recently overloaded the inbound service, it is more likely to be dropped. This makes it harder for a single peer (or multiple peers) to perform a denial of service attack.
The inbound connection rate-limit also makes it hard for multiple peers to perform this attack, because each inbound connection can only send one inbound request before its probability of being disconnected increases.
Source§impl<S, Tx> Connection<S, Tx>
impl<S, Tx> Connection<S, Tx>
Sourcefn update_state_metrics(&mut self, extra_state_info: impl Into<Option<String>>)
fn update_state_metrics(&mut self, extra_state_info: impl Into<Option<String>>)
Update the connection state metrics for this connection,
using extra_state_info as additional state information.
Sourcefn erase_state_metrics(&mut self)
fn erase_state_metrics(&mut self)
Erase the connection state metrics for this connection.
Sourceasync fn shutdown_async(&mut self, error: impl Into<SharedPeerError>)
async fn shutdown_async(&mut self, error: impl Into<SharedPeerError>)
Marks the peer as having failed with error, and performs connection cleanup,
including async channel closes.
If the connection has errored already, re-use the original error.
Otherwise, fail the connection with error.
Sourcefn shutdown(&mut self, error: impl Into<SharedPeerError>)
fn shutdown(&mut self, error: impl Into<SharedPeerError>)
Marks the peer as having failed with error, and performs connection cleanup.
See Self::shutdown_async() for details.
Call Self::shutdown_async() in async code, because it can shut down more channels.
Trait Implementations§
Source§impl<S, Tx> Debug for Connection<S, Tx>
impl<S, Tx> Debug for Connection<S, Tx>
Auto Trait Implementations§
impl<S, Tx> Freeze for Connection<S, Tx>
impl<S, Tx> !RefUnwindSafe for Connection<S, Tx>
impl<S, Tx> Send for Connection<S, Tx>
impl<S, Tx> Sync for Connection<S, Tx>
impl<S, Tx> Unpin for Connection<S, Tx>where
S: Unpin,
impl<S, Tx> UnsafeUnpin for Connection<S, Tx>where
S: UnsafeUnpin,
Tx: UnsafeUnpin,
impl<S, Tx> !UnwindSafe for Connection<S, Tx>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<D> OwoColorize for D
impl<D> OwoColorize for D
§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg] or
a color-specific method, such as [OwoColorize::green], Read more§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg] or
a color-specific method, such as [OwoColorize::on_yellow], Read more§fn fg_rgb<const R: u8, const G: u8, const B: u8>(
&self,
) -> FgColorDisplay<'_, CustomColor<R, G, B>, Self>
fn fg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> FgColorDisplay<'_, CustomColor<R, G, B>, Self>
§fn bg_rgb<const R: u8, const G: u8, const B: u8>(
&self,
) -> BgColorDisplay<'_, CustomColor<R, G, B>, Self>
fn bg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> BgColorDisplay<'_, CustomColor<R, G, B>, Self>
§fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self>
fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self>
§fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self>
fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self>
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<Response, Error> ResponseResult<Response, Error> for Response
impl<Response, Error> ResponseResult<Response, Error> for Response
Source§fn into_result(self) -> Result<Response, Error>
fn into_result(self) -> Result<Response, Error>
Result that can be sent as a response.§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.§impl<T> TryConv for T
impl<T> TryConv for T
§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
Source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
Source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
Source§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
Layout§
Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.