mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-13 10:01:25 +00:00
core/muxing: Flatten StreamMuxer
interface to poll_{inbound,outbound,address_change,close}
(#2724)
Instead of having a mix of `poll_event`, `poll_outbound` and `poll_close`, we flatten the entire interface of `StreamMuxer` into 4 individual functions: - `poll_inbound` - `poll_outbound` - `poll_address_change` - `poll_close` This design is closer to the design of other async traits like `AsyncRead` and `AsyncWrite`. It also allows us to delete the `StreamMuxerEvent`.
This commit is contained in:
20
Cargo.toml
20
Cargo.toml
@ -78,25 +78,25 @@ instant = "0.1.11" # Explicit dependency to be used in `wasm-bindgen` feature
|
|||||||
lazy_static = "1.2"
|
lazy_static = "1.2"
|
||||||
|
|
||||||
libp2p-autonat = { version = "0.6.0", path = "protocols/autonat", optional = true }
|
libp2p-autonat = { version = "0.6.0", path = "protocols/autonat", optional = true }
|
||||||
libp2p-core = { version = "0.34.0", path = "core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "core", default-features = false }
|
||||||
libp2p-dcutr = { version = "0.5.0", path = "protocols/dcutr", optional = true }
|
libp2p-dcutr = { version = "0.5.0", path = "protocols/dcutr", optional = true }
|
||||||
libp2p-floodsub = { version = "0.38.0", path = "protocols/floodsub", optional = true }
|
libp2p-floodsub = { version = "0.38.0", path = "protocols/floodsub", optional = true }
|
||||||
libp2p-identify = { version = "0.38.0", path = "protocols/identify", optional = true }
|
libp2p-identify = { version = "0.38.0", path = "protocols/identify", optional = true }
|
||||||
libp2p-kad = { version = "0.39.0", path = "protocols/kad", optional = true }
|
libp2p-kad = { version = "0.39.0", path = "protocols/kad", optional = true }
|
||||||
libp2p-metrics = { version = "0.8.0", path = "misc/metrics", optional = true }
|
libp2p-metrics = { version = "0.8.0", path = "misc/metrics", optional = true }
|
||||||
libp2p-mplex = { version = "0.34.0", path = "muxers/mplex", optional = true }
|
libp2p-mplex = { version = "0.35.0", path = "muxers/mplex", optional = true }
|
||||||
libp2p-noise = { version = "0.37.0", path = "transports/noise", optional = true }
|
libp2p-noise = { version = "0.38.0", path = "transports/noise", optional = true }
|
||||||
libp2p-ping = { version = "0.38.0", path = "protocols/ping", optional = true }
|
libp2p-ping = { version = "0.38.0", path = "protocols/ping", optional = true }
|
||||||
libp2p-plaintext = { version = "0.34.0", path = "transports/plaintext", optional = true }
|
libp2p-plaintext = { version = "0.35.0", path = "transports/plaintext", optional = true }
|
||||||
libp2p-pnet = { version = "0.22.0", path = "transports/pnet", optional = true }
|
libp2p-pnet = { version = "0.22.0", path = "transports/pnet", optional = true }
|
||||||
libp2p-relay = { version = "0.11.0", path = "protocols/relay", optional = true }
|
libp2p-relay = { version = "0.11.0", path = "protocols/relay", optional = true }
|
||||||
libp2p-rendezvous = { version = "0.8.0", path = "protocols/rendezvous", optional = true }
|
libp2p-rendezvous = { version = "0.8.0", path = "protocols/rendezvous", optional = true }
|
||||||
libp2p-request-response = { version = "0.20.0", path = "protocols/request-response", optional = true }
|
libp2p-request-response = { version = "0.20.0", path = "protocols/request-response", optional = true }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "swarm" }
|
||||||
libp2p-swarm-derive = { version = "0.28.0", path = "swarm-derive" }
|
libp2p-swarm-derive = { version = "0.28.0", path = "swarm-derive" }
|
||||||
libp2p-uds = { version = "0.33.0", path = "transports/uds", optional = true }
|
libp2p-uds = { version = "0.34.0", path = "transports/uds", optional = true }
|
||||||
libp2p-wasm-ext = { version = "0.34.0", path = "transports/wasm-ext", default-features = false, optional = true }
|
libp2p-wasm-ext = { version = "0.35.0", path = "transports/wasm-ext", default-features = false, optional = true }
|
||||||
libp2p-yamux = { version = "0.38.0", path = "muxers/yamux", optional = true }
|
libp2p-yamux = { version = "0.39.0", path = "muxers/yamux", optional = true }
|
||||||
multiaddr = { version = "0.14.0" }
|
multiaddr = { version = "0.14.0" }
|
||||||
parking_lot = "0.12.0"
|
parking_lot = "0.12.0"
|
||||||
pin-project = "1.0.0"
|
pin-project = "1.0.0"
|
||||||
@ -104,11 +104,11 @@ rand = "0.7.3" # Explicit dependency to be used in `wasm-bindgen` feature
|
|||||||
smallvec = "1.6.1"
|
smallvec = "1.6.1"
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))'.dependencies]
|
[target.'cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))'.dependencies]
|
||||||
libp2p-deflate = { version = "0.34.0", path = "transports/deflate", optional = true }
|
libp2p-deflate = { version = "0.35.0", path = "transports/deflate", optional = true }
|
||||||
libp2p-dns = { version = "0.34.0", path = "transports/dns", optional = true, default-features = false }
|
libp2p-dns = { version = "0.35.0", path = "transports/dns", optional = true, default-features = false }
|
||||||
libp2p-mdns = { version = "0.39.0", path = "protocols/mdns", optional = true }
|
libp2p-mdns = { version = "0.39.0", path = "protocols/mdns", optional = true }
|
||||||
libp2p-tcp = { version = "0.34.0", path = "transports/tcp", default-features = false, optional = true }
|
libp2p-tcp = { version = "0.34.0", path = "transports/tcp", default-features = false, optional = true }
|
||||||
libp2p-websocket = { version = "0.36.0", path = "transports/websocket", optional = true }
|
libp2p-websocket = { version = "0.37.0", path = "transports/websocket", optional = true }
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "unknown"))'.dependencies]
|
[target.'cfg(not(target_os = "unknown"))'.dependencies]
|
||||||
libp2p-gossipsub = { version = "0.40.0", path = "protocols/gossipsub", optional = true }
|
libp2p-gossipsub = { version = "0.40.0", path = "protocols/gossipsub", optional = true }
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
|
# 0.35.0 [unreleased]
|
||||||
|
|
||||||
|
- Remove `StreamMuxer::poll_event` in favor of individual functions: `poll_inbound`, `poll_outbound`
|
||||||
|
and `poll_address_change`. Consequently, `StreamMuxerEvent` is also removed. See [PR 2724].
|
||||||
|
|
||||||
|
[PR 2724]: https://github.com/libp2p/rust-libp2p/pull/2724
|
||||||
|
|
||||||
# 0.34.0
|
# 0.34.0
|
||||||
|
|
||||||
- Introduce `StreamMuxerEvent::map_inbound_stream`. See [PR 2691].
|
|
||||||
- Remove `{read,write,flush,shutdown,destroy}_substream` functions from `StreamMuxer` trait
|
- Remove `{read,write,flush,shutdown,destroy}_substream` functions from `StreamMuxer` trait
|
||||||
in favor of forcing `StreamMuxer::Substream` to implement `AsyncRead + AsyncWrite`. See [PR 2707].
|
in favor of forcing `StreamMuxer::Substream` to implement `AsyncRead + AsyncWrite`. See [PR 2707].
|
||||||
- Replace `Into<std::io::Error>` bound on `StreamMuxer::Error` with `std::error::Error`. See [PR 2710].
|
- Replace `Into<std::io::Error>` bound on `StreamMuxer::Error` with `std::error::Error`. See [PR 2710].
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-core"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Core traits and structs of libp2p"
|
description = "Core traits and structs of libp2p"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
muxing::{StreamMuxer, StreamMuxerEvent},
|
muxing::StreamMuxer,
|
||||||
transport::{ListenerId, Transport, TransportError, TransportEvent},
|
transport::{ListenerId, Transport, TransportError, TransportEvent},
|
||||||
Multiaddr, ProtocolName,
|
Multiaddr, ProtocolName,
|
||||||
};
|
};
|
||||||
@ -202,60 +202,38 @@ where
|
|||||||
B: StreamMuxer,
|
B: StreamMuxer,
|
||||||
{
|
{
|
||||||
type Substream = EitherOutput<A::Substream, B::Substream>;
|
type Substream = EitherOutput<A::Substream, B::Substream>;
|
||||||
type OutboundSubstream = EitherOutbound<A, B>;
|
|
||||||
type Error = EitherError<A::Error, B::Error>;
|
type Error = EitherError<A::Error, B::Error>;
|
||||||
|
|
||||||
fn poll_event(
|
fn poll_inbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
|
|
||||||
match self {
|
match self {
|
||||||
EitherOutput::First(inner) => inner
|
EitherOutput::First(inner) => inner
|
||||||
.poll_event(cx)
|
.poll_inbound(cx)
|
||||||
.map_err(EitherError::A)
|
.map_ok(EitherOutput::First)
|
||||||
.map_ok(|event| event.map_inbound_stream(EitherOutput::First)),
|
|
||||||
EitherOutput::Second(inner) => inner
|
|
||||||
.poll_event(cx)
|
|
||||||
.map_err(EitherError::B)
|
|
||||||
.map_ok(|event| event.map_inbound_stream(EitherOutput::Second)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open_outbound(&self) -> Self::OutboundSubstream {
|
|
||||||
match self {
|
|
||||||
EitherOutput::First(inner) => EitherOutbound::A(inner.open_outbound()),
|
|
||||||
EitherOutput::Second(inner) => EitherOutbound::B(inner.open_outbound()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_outbound(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
substream: &mut Self::OutboundSubstream,
|
|
||||||
) -> Poll<Result<Self::Substream, Self::Error>> {
|
|
||||||
match (self, substream) {
|
|
||||||
(EitherOutput::First(ref inner), EitherOutbound::A(ref mut substream)) => inner
|
|
||||||
.poll_outbound(cx, substream)
|
|
||||||
.map(|p| p.map(EitherOutput::First))
|
|
||||||
.map_err(EitherError::A),
|
.map_err(EitherError::A),
|
||||||
(EitherOutput::Second(ref inner), EitherOutbound::B(ref mut substream)) => inner
|
EitherOutput::Second(inner) => inner
|
||||||
.poll_outbound(cx, substream)
|
.poll_inbound(cx)
|
||||||
.map(|p| p.map(EitherOutput::Second))
|
.map_ok(EitherOutput::Second)
|
||||||
.map_err(EitherError::B),
|
.map_err(EitherError::B),
|
||||||
_ => panic!("Wrong API usage"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_outbound(&self, substream: Self::OutboundSubstream) {
|
fn poll_outbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
match self {
|
match self {
|
||||||
EitherOutput::First(inner) => match substream {
|
EitherOutput::First(inner) => inner
|
||||||
EitherOutbound::A(substream) => inner.destroy_outbound(substream),
|
.poll_outbound(cx)
|
||||||
_ => panic!("Wrong API usage"),
|
.map_ok(EitherOutput::First)
|
||||||
},
|
.map_err(EitherError::A),
|
||||||
EitherOutput::Second(inner) => match substream {
|
EitherOutput::Second(inner) => inner
|
||||||
EitherOutbound::B(substream) => inner.destroy_outbound(substream),
|
.poll_outbound(cx)
|
||||||
_ => panic!("Wrong API usage"),
|
.map_ok(EitherOutput::Second)
|
||||||
},
|
.map_err(EitherError::B),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_address_change(&self, cx: &mut Context<'_>) -> Poll<Result<Multiaddr, Self::Error>> {
|
||||||
|
match self {
|
||||||
|
EitherOutput::First(inner) => inner.poll_address_change(cx).map_err(EitherError::A),
|
||||||
|
EitherOutput::Second(inner) => inner.poll_address_change(cx).map_err(EitherError::B),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,13 +245,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
#[must_use = "futures do nothing unless polled"]
|
|
||||||
pub enum EitherOutbound<A: StreamMuxer, B: StreamMuxer> {
|
|
||||||
A(A::OutboundSubstream),
|
|
||||||
B(B::OutboundSubstream),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implements `Future` and dispatches all method calls to either `First` or `Second`.
|
/// Implements `Future` and dispatches all method calls to either `First` or `Second`.
|
||||||
#[pin_project(project = EitherFutureProj)]
|
#[pin_project(project = EitherFutureProj)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
@ -63,62 +63,25 @@ mod singleton;
|
|||||||
/// Provides multiplexing for a connection by allowing users to open substreams.
|
/// Provides multiplexing for a connection by allowing users to open substreams.
|
||||||
///
|
///
|
||||||
/// A substream created by a [`StreamMuxer`] is a type that implements [`AsyncRead`] and [`AsyncWrite`].
|
/// A substream created by a [`StreamMuxer`] is a type that implements [`AsyncRead`] and [`AsyncWrite`].
|
||||||
///
|
/// The [`StreamMuxer`] itself is modelled closely after [`AsyncWrite`]. It features `poll`-style
|
||||||
/// Inbound substreams are reported via [`StreamMuxer::poll_event`].
|
/// functions that allow the implementation to make progress on various tasks.
|
||||||
/// Outbound substreams can be opened via [`StreamMuxer::open_outbound`] and subsequent polling via
|
|
||||||
/// [`StreamMuxer::poll_outbound`].
|
|
||||||
pub trait StreamMuxer {
|
pub trait StreamMuxer {
|
||||||
/// Type of the object that represents the raw substream where data can be read and written.
|
/// Type of the object that represents the raw substream where data can be read and written.
|
||||||
type Substream: AsyncRead + AsyncWrite;
|
type Substream: AsyncRead + AsyncWrite;
|
||||||
|
|
||||||
/// Future that will be resolved when the outgoing substream is open.
|
|
||||||
type OutboundSubstream;
|
|
||||||
|
|
||||||
/// Error type of the muxer
|
/// Error type of the muxer
|
||||||
type Error: std::error::Error;
|
type Error: std::error::Error;
|
||||||
|
|
||||||
/// Polls for a connection-wide event.
|
/// Poll for new inbound substreams.
|
||||||
///
|
fn poll_inbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>>;
|
||||||
/// This function behaves the same as a `Stream`.
|
|
||||||
///
|
|
||||||
/// If `Pending` is returned, then the current task will be notified once the muxer
|
|
||||||
/// is ready to be polled, similar to the API of `Stream::poll()`.
|
|
||||||
/// Only the latest task that was used to call this method may be notified.
|
|
||||||
///
|
|
||||||
/// It is permissible and common to use this method to perform background
|
|
||||||
/// work, such as processing incoming packets and polling timers.
|
|
||||||
///
|
|
||||||
/// An error can be generated if the connection has been closed.
|
|
||||||
fn poll_event(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>>;
|
|
||||||
|
|
||||||
/// Opens a new outgoing substream, and produces the equivalent to a future that will be
|
/// Poll for a new, outbound substream.
|
||||||
/// resolved when it becomes available.
|
fn poll_outbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>>;
|
||||||
///
|
|
||||||
/// The API of `OutboundSubstream` is totally opaque, and the object can only be interfaced
|
|
||||||
/// through the methods on the `StreamMuxer` trait.
|
|
||||||
fn open_outbound(&self) -> Self::OutboundSubstream;
|
|
||||||
|
|
||||||
/// Polls the outbound substream.
|
/// Poll for an address change of the underlying connection.
|
||||||
///
|
///
|
||||||
/// If `Pending` is returned, then the current task will be notified once the substream
|
/// Not all implementations may support this feature.
|
||||||
/// is ready to be polled, similar to the API of `Future::poll()`.
|
fn poll_address_change(&self, cx: &mut Context<'_>) -> Poll<Result<Multiaddr, Self::Error>>;
|
||||||
/// However, for each individual outbound substream, only the latest task that was used to
|
|
||||||
/// call this method may be notified.
|
|
||||||
///
|
|
||||||
/// May panic or produce an undefined result if an earlier polling of the same substream
|
|
||||||
/// returned `Ready` or `Err`.
|
|
||||||
fn poll_outbound(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::OutboundSubstream,
|
|
||||||
) -> Poll<Result<Self::Substream, Self::Error>>;
|
|
||||||
|
|
||||||
/// Destroys an outbound substream future. Use this after the outbound substream has finished,
|
|
||||||
/// or if you want to interrupt it.
|
|
||||||
fn destroy_outbound(&self, s: Self::OutboundSubstream);
|
|
||||||
|
|
||||||
/// Closes this `StreamMuxer`.
|
/// Closes this `StreamMuxer`.
|
||||||
///
|
///
|
||||||
@ -132,38 +95,3 @@ pub trait StreamMuxer {
|
|||||||
/// > immediately dropping the muxer.
|
/// > immediately dropping the muxer.
|
||||||
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
|
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Event about a connection, reported by an implementation of [`StreamMuxer`].
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub enum StreamMuxerEvent<T> {
|
|
||||||
/// Remote has opened a new substream. Contains the substream in question.
|
|
||||||
InboundSubstream(T),
|
|
||||||
|
|
||||||
/// Address to the remote has changed. The previous one is now obsolete.
|
|
||||||
///
|
|
||||||
/// > **Note**: This can for example happen when using the QUIC protocol, where the two nodes
|
|
||||||
/// > can change their IP address while retaining the same QUIC connection.
|
|
||||||
AddressChange(Multiaddr),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> StreamMuxerEvent<T> {
|
|
||||||
/// If `self` is a [`StreamMuxerEvent::InboundSubstream`], returns the content. Otherwise
|
|
||||||
/// returns `None`.
|
|
||||||
pub fn into_inbound_substream(self) -> Option<T> {
|
|
||||||
if let StreamMuxerEvent::InboundSubstream(s) = self {
|
|
||||||
Some(s)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Map the stream within [`StreamMuxerEvent::InboundSubstream`] to a new type.
|
|
||||||
pub fn map_inbound_stream<O>(self, map: impl FnOnce(T) -> O) -> StreamMuxerEvent<O> {
|
|
||||||
match self {
|
|
||||||
StreamMuxerEvent::InboundSubstream(stream) => {
|
|
||||||
StreamMuxerEvent::InboundSubstream(map(stream))
|
|
||||||
}
|
|
||||||
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,23 +1,16 @@
|
|||||||
use crate::muxing::StreamMuxerEvent;
|
|
||||||
use crate::StreamMuxer;
|
use crate::StreamMuxer;
|
||||||
use fnv::FnvHashMap;
|
use futures::{AsyncRead, AsyncWrite};
|
||||||
use futures::{ready, AsyncRead, AsyncWrite};
|
use multiaddr::Multiaddr;
|
||||||
use parking_lot::Mutex;
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{IoSlice, IoSliceMut};
|
use std::io::{IoSlice, IoSliceMut};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
/// Abstract `StreamMuxer`.
|
/// Abstract `StreamMuxer`.
|
||||||
pub struct StreamMuxerBox {
|
pub struct StreamMuxerBox {
|
||||||
inner: Box<
|
inner: Box<dyn StreamMuxer<Substream = SubstreamBox, Error = io::Error> + Send + Sync>,
|
||||||
dyn StreamMuxer<Substream = SubstreamBox, OutboundSubstream = usize, Error = io::Error>
|
|
||||||
+ Send
|
|
||||||
+ Sync,
|
|
||||||
>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Abstract type for asynchronous reading and writing.
|
/// Abstract type for asynchronous reading and writing.
|
||||||
@ -31,8 +24,6 @@ where
|
|||||||
T: StreamMuxer,
|
T: StreamMuxer,
|
||||||
{
|
{
|
||||||
inner: T,
|
inner: T,
|
||||||
outbound: Mutex<FnvHashMap<usize, T::OutboundSubstream>>,
|
|
||||||
next_outbound: AtomicUsize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> StreamMuxer for Wrap<T>
|
impl<T> StreamMuxer for Wrap<T>
|
||||||
@ -42,54 +33,30 @@ where
|
|||||||
T::Error: Send + Sync + 'static,
|
T::Error: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
type Substream = SubstreamBox;
|
type Substream = SubstreamBox;
|
||||||
type OutboundSubstream = usize; // TODO: use a newtype
|
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn poll_event(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
|
|
||||||
let event = ready!(self.inner.poll_event(cx).map_err(into_io_error)?)
|
|
||||||
.map_inbound_stream(SubstreamBox::new);
|
|
||||||
|
|
||||||
Poll::Ready(Ok(event))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn open_outbound(&self) -> Self::OutboundSubstream {
|
|
||||||
let outbound = self.inner.open_outbound();
|
|
||||||
let id = self.next_outbound.fetch_add(1, Ordering::Relaxed);
|
|
||||||
self.outbound.lock().insert(id, outbound);
|
|
||||||
id
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn poll_outbound(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
substream: &mut Self::OutboundSubstream,
|
|
||||||
) -> Poll<Result<Self::Substream, Self::Error>> {
|
|
||||||
let mut list = self.outbound.lock();
|
|
||||||
let stream = ready!(self
|
|
||||||
.inner
|
|
||||||
.poll_outbound(cx, list.get_mut(substream).unwrap())
|
|
||||||
.map_err(into_io_error)?);
|
|
||||||
|
|
||||||
Poll::Ready(Ok(SubstreamBox::new(stream)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn destroy_outbound(&self, substream: Self::OutboundSubstream) {
|
|
||||||
let mut list = self.outbound.lock();
|
|
||||||
self.inner
|
|
||||||
.destroy_outbound(list.remove(&substream).unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
self.inner.poll_close(cx).map_err(into_io_error)
|
self.inner.poll_close(cx).map_err(into_io_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn poll_inbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
|
self.inner
|
||||||
|
.poll_inbound(cx)
|
||||||
|
.map_ok(SubstreamBox::new)
|
||||||
|
.map_err(into_io_error)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_outbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
|
self.inner
|
||||||
|
.poll_outbound(cx)
|
||||||
|
.map_ok(SubstreamBox::new)
|
||||||
|
.map_err(into_io_error)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_address_change(&self, cx: &mut Context<'_>) -> Poll<Result<Multiaddr, Self::Error>> {
|
||||||
|
self.inner.poll_address_change(cx).map_err(into_io_error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_io_error<E>(err: E) -> io::Error
|
fn into_io_error<E>(err: E) -> io::Error
|
||||||
@ -104,15 +71,10 @@ impl StreamMuxerBox {
|
|||||||
pub fn new<T>(muxer: T) -> StreamMuxerBox
|
pub fn new<T>(muxer: T) -> StreamMuxerBox
|
||||||
where
|
where
|
||||||
T: StreamMuxer + Send + Sync + 'static,
|
T: StreamMuxer + Send + Sync + 'static,
|
||||||
T::OutboundSubstream: Send,
|
|
||||||
T::Substream: Send + Unpin + 'static,
|
T::Substream: Send + Unpin + 'static,
|
||||||
T::Error: Send + Sync + 'static,
|
T::Error: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let wrap = Wrap {
|
let wrap = Wrap { inner: muxer };
|
||||||
inner: muxer,
|
|
||||||
outbound: Mutex::new(Default::default()),
|
|
||||||
next_outbound: AtomicUsize::new(0),
|
|
||||||
};
|
|
||||||
|
|
||||||
StreamMuxerBox {
|
StreamMuxerBox {
|
||||||
inner: Box::new(wrap),
|
inner: Box::new(wrap),
|
||||||
@ -122,40 +84,24 @@ impl StreamMuxerBox {
|
|||||||
|
|
||||||
impl StreamMuxer for StreamMuxerBox {
|
impl StreamMuxer for StreamMuxerBox {
|
||||||
type Substream = SubstreamBox;
|
type Substream = SubstreamBox;
|
||||||
type OutboundSubstream = usize; // TODO: use a newtype
|
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn poll_event(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
|
|
||||||
self.inner.poll_event(cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn open_outbound(&self) -> Self::OutboundSubstream {
|
|
||||||
self.inner.open_outbound()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn poll_outbound(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::OutboundSubstream,
|
|
||||||
) -> Poll<Result<Self::Substream, Self::Error>> {
|
|
||||||
self.inner.poll_outbound(cx, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn destroy_outbound(&self, substream: Self::OutboundSubstream) {
|
|
||||||
self.inner.destroy_outbound(substream)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
self.inner.poll_close(cx)
|
self.inner.poll_close(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn poll_inbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
|
self.inner.poll_inbound(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_outbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
|
self.inner.poll_outbound(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_address_change(&self, cx: &mut Context<'_>) -> Poll<Result<Multiaddr, Self::Error>> {
|
||||||
|
self.inner.poll_address_change(cx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SubstreamBox {
|
impl SubstreamBox {
|
||||||
|
@ -18,12 +18,10 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
use crate::{
|
use crate::{connection::Endpoint, muxing::StreamMuxer};
|
||||||
connection::Endpoint,
|
|
||||||
muxing::{StreamMuxer, StreamMuxerEvent},
|
|
||||||
};
|
|
||||||
|
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
|
use multiaddr::Multiaddr;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::{io, task::Context, task::Poll};
|
use std::{io, task::Context, task::Poll};
|
||||||
|
|
||||||
@ -52,55 +50,36 @@ impl<TSocket> SingletonMuxer<TSocket> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Outbound substream attempt of the `SingletonMuxer`.
|
|
||||||
pub struct OutboundSubstream {}
|
|
||||||
|
|
||||||
impl<TSocket> StreamMuxer for SingletonMuxer<TSocket>
|
impl<TSocket> StreamMuxer for SingletonMuxer<TSocket>
|
||||||
where
|
where
|
||||||
TSocket: AsyncRead + AsyncWrite + Unpin,
|
TSocket: AsyncRead + AsyncWrite + Unpin,
|
||||||
{
|
{
|
||||||
type Substream = TSocket;
|
type Substream = TSocket;
|
||||||
type OutboundSubstream = OutboundSubstream;
|
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
fn poll_event(
|
fn poll_inbound(&self, _: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
&self,
|
|
||||||
_: &mut Context<'_>,
|
|
||||||
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, io::Error>> {
|
|
||||||
match self.endpoint {
|
match self.endpoint {
|
||||||
Endpoint::Dialer => return Poll::Pending,
|
Endpoint::Dialer => Poll::Pending,
|
||||||
Endpoint::Listener => {}
|
Endpoint::Listener => match self.inner.replace(None) {
|
||||||
}
|
None => Poll::Pending,
|
||||||
|
Some(stream) => Poll::Ready(Ok(stream)),
|
||||||
if let Some(stream) = self.inner.replace(None) {
|
},
|
||||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(stream)))
|
|
||||||
} else {
|
|
||||||
Poll::Pending
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_outbound(&self) -> Self::OutboundSubstream {
|
fn poll_outbound(&self, _: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
OutboundSubstream {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_outbound(
|
|
||||||
&self,
|
|
||||||
_: &mut Context<'_>,
|
|
||||||
_: &mut Self::OutboundSubstream,
|
|
||||||
) -> Poll<Result<Self::Substream, io::Error>> {
|
|
||||||
match self.endpoint {
|
match self.endpoint {
|
||||||
Endpoint::Listener => return Poll::Pending,
|
Endpoint::Listener => Poll::Pending,
|
||||||
Endpoint::Dialer => {}
|
Endpoint::Dialer => match self.inner.replace(None) {
|
||||||
}
|
None => Poll::Pending,
|
||||||
|
Some(stream) => Poll::Ready(Ok(stream)),
|
||||||
if let Some(stream) = self.inner.replace(None) {
|
},
|
||||||
Poll::Ready(Ok(stream))
|
|
||||||
} else {
|
|
||||||
Poll::Pending
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_outbound(&self, _: Self::OutboundSubstream) {}
|
fn poll_address_change(&self, _: &mut Context<'_>) -> Poll<Result<Multiaddr, Self::Error>> {
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
|
||||||
fn poll_close(&self, _cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
fn poll_close(&self, _cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
|
@ -301,7 +301,6 @@ impl<T> Multiplexed<T> {
|
|||||||
T::Error: Send + Sync,
|
T::Error: Send + Sync,
|
||||||
M: StreamMuxer + Send + Sync + 'static,
|
M: StreamMuxer + Send + Sync + 'static,
|
||||||
M::Substream: Send + Unpin + 'static,
|
M::Substream: Send + Unpin + 'static,
|
||||||
M::OutboundSubstream: Send + 'static,
|
|
||||||
M::Error: Send + Sync + 'static,
|
M::Error: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
boxed(self.map(|(i, m), _| (i, StreamMuxerBox::new(m))))
|
boxed(self.map(|(i, m), _| (i, StreamMuxerBox::new(m))))
|
||||||
|
@ -13,5 +13,5 @@ clap = {version = "3.1.6", features = ["derive"]}
|
|||||||
zeroize = "1"
|
zeroize = "1"
|
||||||
serde = { version = "1.0.136", features = ["derive"] }
|
serde = { version = "1.0.136", features = ["derive"] }
|
||||||
serde_json = "1.0.79"
|
serde_json = "1.0.79"
|
||||||
libp2p-core = { path = "../../core", default-features = false, version = "0.34.0"}
|
libp2p-core = { path = "../../core", default-features = false, version = "0.35.0"}
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
- Track number of connected nodes supporting a specific protocol via the identify protocol. See [PR 2734].
|
- Track number of connected nodes supporting a specific protocol via the identify protocol. See [PR 2734].
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
[PR 2734]: https://github.com/libp2p/rust-libp2p/pull/2734/
|
[PR 2734]: https://github.com/libp2p/rust-libp2p/pull/2734/
|
||||||
|
|
||||||
# 0.7.0
|
# 0.7.0
|
||||||
|
@ -19,7 +19,7 @@ relay = ["libp2p-relay"]
|
|||||||
dcutr = ["libp2p-dcutr"]
|
dcutr = ["libp2p-dcutr"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
libp2p-dcutr = { version = "0.5.0", path = "../../protocols/dcutr", optional = true }
|
libp2p-dcutr = { version = "0.5.0", path = "../../protocols/dcutr", optional = true }
|
||||||
libp2p-identify = { version = "0.38.0", path = "../../protocols/identify", optional = true }
|
libp2p-identify = { version = "0.38.0", path = "../../protocols/identify", optional = true }
|
||||||
libp2p-kad = { version = "0.39.0", path = "../../protocols/kad", optional = true }
|
libp2p-kad = { version = "0.39.0", path = "../../protocols/kad", optional = true }
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.35.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`
|
||||||
|
|
||||||
# 0.34.0
|
# 0.34.0
|
||||||
|
|
||||||
- `Substream` now implements `AsyncRead` and `AsyncWrite`. See [PR 2706].
|
- `Substream` now implements `AsyncRead` and `AsyncWrite`. See [PR 2706].
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-mplex"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Mplex multiplexing protocol for libp2p"
|
description = "Mplex multiplexing protocol for libp2p"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
bytes = "1"
|
bytes = "1"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
asynchronous-codec = "0.6"
|
asynchronous-codec = "0.6"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
nohash-hasher = "0.2"
|
nohash-hasher = "0.2"
|
||||||
parking_lot = "0.12"
|
parking_lot = "0.12"
|
||||||
|
@ -114,11 +114,9 @@ fn run(
|
|||||||
}
|
}
|
||||||
transport::TransportEvent::Incoming { upgrade, .. } => {
|
transport::TransportEvent::Incoming { upgrade, .. } => {
|
||||||
let (_peer, conn) = upgrade.await.unwrap();
|
let (_peer, conn) = upgrade.await.unwrap();
|
||||||
let mut s = poll_fn(|cx| conn.poll_event(cx))
|
let mut s = poll_fn(|cx| conn.poll_inbound(cx))
|
||||||
.await
|
.await
|
||||||
.expect("unexpected error")
|
.expect("unexpected error");
|
||||||
.into_inbound_substream()
|
|
||||||
.expect("Unexpected muxer event");
|
|
||||||
|
|
||||||
let mut buf = vec![0u8; payload_len];
|
let mut buf = vec![0u8; payload_len];
|
||||||
let mut off = 0;
|
let mut off = 0;
|
||||||
@ -143,10 +141,7 @@ fn run(
|
|||||||
let sender = async move {
|
let sender = async move {
|
||||||
let addr = addr_receiver.await.unwrap();
|
let addr = addr_receiver.await.unwrap();
|
||||||
let (_peer, conn) = sender_trans.dial(addr).unwrap().await.unwrap();
|
let (_peer, conn) = sender_trans.dial(addr).unwrap().await.unwrap();
|
||||||
let mut handle = conn.open_outbound();
|
let mut stream = poll_fn(|cx| conn.poll_outbound(cx)).await.unwrap();
|
||||||
let mut stream = poll_fn(|cx| conn.poll_outbound(cx, &mut handle))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let mut off = 0;
|
let mut off = 0;
|
||||||
loop {
|
loop {
|
||||||
let n = poll_fn(|cx| Pin::new(&mut stream).poll_write(cx, &payload[off..]))
|
let n = poll_fn(|cx| Pin::new(&mut stream).poll_write(cx, &payload[off..]))
|
||||||
|
@ -28,9 +28,8 @@ use bytes::Bytes;
|
|||||||
use codec::LocalStreamId;
|
use codec::LocalStreamId;
|
||||||
use futures::{future, prelude::*, ready};
|
use futures::{future, prelude::*, ready};
|
||||||
use libp2p_core::{
|
use libp2p_core::{
|
||||||
muxing::StreamMuxerEvent,
|
|
||||||
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo},
|
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo},
|
||||||
StreamMuxer,
|
Multiaddr, StreamMuxer,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::{cmp, iter, pin::Pin, sync::Arc, task::Context, task::Poll};
|
use std::{cmp, iter, pin::Pin, sync::Arc, task::Context, task::Poll};
|
||||||
@ -75,9 +74,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Multiplexer. Implements the `StreamMuxer` trait.
|
/// Multiplexer. Implements the `StreamMuxer` trait.
|
||||||
///
|
|
||||||
/// This implementation isn't capable of detecting when the underlying socket changes its address,
|
|
||||||
/// and no [`StreamMuxerEvent::AddressChange`] event is ever emitted.
|
|
||||||
pub struct Multiplex<C> {
|
pub struct Multiplex<C> {
|
||||||
io: Arc<Mutex<io::Multiplexed<C>>>,
|
io: Arc<Mutex<io::Multiplexed<C>>>,
|
||||||
}
|
}
|
||||||
@ -87,33 +83,24 @@ where
|
|||||||
C: AsyncRead + AsyncWrite + Unpin,
|
C: AsyncRead + AsyncWrite + Unpin,
|
||||||
{
|
{
|
||||||
type Substream = Substream<C>;
|
type Substream = Substream<C>;
|
||||||
type OutboundSubstream = OutboundSubstream;
|
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
fn poll_event(
|
fn poll_inbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
&self,
|
self.io
|
||||||
cx: &mut Context<'_>,
|
.lock()
|
||||||
) -> Poll<io::Result<StreamMuxerEvent<Self::Substream>>> {
|
.poll_next_stream(cx)
|
||||||
let stream_id = ready!(self.io.lock().poll_next_stream(cx))?;
|
.map_ok(|stream_id| Substream::new(stream_id, self.io.clone()))
|
||||||
let stream = Substream::new(stream_id, self.io.clone());
|
|
||||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(stream)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_outbound(&self) -> Self::OutboundSubstream {
|
fn poll_outbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
OutboundSubstream {}
|
self.io
|
||||||
|
.lock()
|
||||||
|
.poll_open_stream(cx)
|
||||||
|
.map_ok(|stream_id| Substream::new(stream_id, self.io.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_outbound(
|
fn poll_address_change(&self, _: &mut Context<'_>) -> Poll<Result<Multiaddr, Self::Error>> {
|
||||||
&self,
|
Poll::Pending
|
||||||
cx: &mut Context<'_>,
|
|
||||||
_: &mut Self::OutboundSubstream,
|
|
||||||
) -> Poll<Result<Self::Substream, io::Error>> {
|
|
||||||
let stream_id = ready!(self.io.lock().poll_open_stream(cx))?;
|
|
||||||
Poll::Ready(Ok(Substream::new(stream_id, self.io.clone())))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destroy_outbound(&self, _substream: Self::OutboundSubstream) {
|
|
||||||
// Nothing to do, since `open_outbound` creates no new local state.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
||||||
@ -121,9 +108,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Active attempt to open an outbound substream.
|
|
||||||
pub struct OutboundSubstream {}
|
|
||||||
|
|
||||||
impl<C> AsyncRead for Substream<C>
|
impl<C> AsyncRead for Substream<C>
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + Unpin,
|
C: AsyncRead + AsyncWrite + Unpin,
|
||||||
|
@ -60,10 +60,7 @@ fn async_write() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut outbound_token = client.open_outbound();
|
let mut outbound = poll_fn(|cx| client.poll_outbound(cx)).await.unwrap();
|
||||||
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
outbound.read_to_end(&mut buf).await.unwrap();
|
outbound.read_to_end(&mut buf).await.unwrap();
|
||||||
@ -76,15 +73,7 @@ fn async_write() {
|
|||||||
.and_then(move |c, e| upgrade::apply(c, mplex, e, upgrade::Version::V1));
|
.and_then(move |c, e| upgrade::apply(c, mplex, e, upgrade::Version::V1));
|
||||||
|
|
||||||
let client = Arc::new(transport.dial(rx.await.unwrap()).unwrap().await.unwrap());
|
let client = Arc::new(transport.dial(rx.await.unwrap()).unwrap().await.unwrap());
|
||||||
let mut inbound = loop {
|
let mut inbound = poll_fn(|cx| client.poll_inbound(cx)).await.unwrap();
|
||||||
if let Some(s) = poll_fn(|cx| client.poll_event(cx))
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.into_inbound_substream()
|
|
||||||
{
|
|
||||||
break s;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
inbound.write_all(b"hello world").await.unwrap();
|
inbound.write_all(b"hello world").await.unwrap();
|
||||||
|
|
||||||
// The test consists in making sure that this flushes the substream.
|
// The test consists in making sure that this flushes the substream.
|
||||||
|
@ -60,10 +60,7 @@ fn client_to_server_outbound() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut outbound_token = client.open_outbound();
|
let mut outbound = poll_fn(|cx| client.poll_outbound(cx)).await.unwrap();
|
||||||
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
outbound.read_to_end(&mut buf).await.unwrap();
|
outbound.read_to_end(&mut buf).await.unwrap();
|
||||||
@ -77,15 +74,7 @@ fn client_to_server_outbound() {
|
|||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
let client = Arc::new(transport.dial(rx.await.unwrap()).unwrap().await.unwrap());
|
let client = Arc::new(transport.dial(rx.await.unwrap()).unwrap().await.unwrap());
|
||||||
let mut inbound = loop {
|
let mut inbound = poll_fn(|cx| client.poll_inbound(cx)).await.unwrap();
|
||||||
if let Some(s) = poll_fn(|cx| client.poll_event(cx))
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.into_inbound_substream()
|
|
||||||
{
|
|
||||||
break s;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
inbound.write_all(b"hello world").await.unwrap();
|
inbound.write_all(b"hello world").await.unwrap();
|
||||||
inbound.close().await.unwrap();
|
inbound.close().await.unwrap();
|
||||||
|
|
||||||
@ -131,15 +120,7 @@ fn client_to_server_inbound() {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut inbound = loop {
|
let mut inbound = poll_fn(|cx| client.poll_inbound(cx)).await.unwrap();
|
||||||
if let Some(s) = poll_fn(|cx| client.poll_event(cx))
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.into_inbound_substream()
|
|
||||||
{
|
|
||||||
break s;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
inbound.read_to_end(&mut buf).await.unwrap();
|
inbound.read_to_end(&mut buf).await.unwrap();
|
||||||
@ -154,10 +135,7 @@ fn client_to_server_inbound() {
|
|||||||
|
|
||||||
let client = transport.dial(rx.await.unwrap()).unwrap().await.unwrap();
|
let client = transport.dial(rx.await.unwrap()).unwrap().await.unwrap();
|
||||||
|
|
||||||
let mut outbound_token = client.open_outbound();
|
let mut outbound = poll_fn(|cx| client.poll_outbound(cx)).await.unwrap();
|
||||||
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
outbound.write_all(b"hello world").await.unwrap();
|
outbound.write_all(b"hello world").await.unwrap();
|
||||||
outbound.close().await.unwrap();
|
outbound.close().await.unwrap();
|
||||||
|
|
||||||
@ -199,10 +177,7 @@ fn protocol_not_match() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut outbound_token = client.open_outbound();
|
let mut outbound = poll_fn(|cx| client.poll_outbound(cx)).await.unwrap();
|
||||||
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
outbound.read_to_end(&mut buf).await.unwrap();
|
outbound.read_to_end(&mut buf).await.unwrap();
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.39.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`
|
||||||
|
|
||||||
# 0.38.0
|
# 0.38.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-yamux"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Yamux multiplexing protocol for libp2p"
|
description = "Yamux multiplexing protocol for libp2p"
|
||||||
version = "0.38.0"
|
version = "0.39.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
parking_lot = "0.12"
|
parking_lot = "0.12"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
yamux = "0.10.0"
|
yamux = "0.10.0"
|
||||||
|
@ -24,11 +24,11 @@
|
|||||||
use futures::{
|
use futures::{
|
||||||
future,
|
future,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
ready,
|
|
||||||
stream::{BoxStream, LocalBoxStream},
|
stream::{BoxStream, LocalBoxStream},
|
||||||
};
|
};
|
||||||
use libp2p_core::muxing::{StreamMuxer, StreamMuxerEvent};
|
use libp2p_core::muxing::StreamMuxer;
|
||||||
use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo};
|
use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo};
|
||||||
|
use libp2p_core::Multiaddr;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::{
|
use std::{
|
||||||
fmt, io, iter, mem,
|
fmt, io, iter, mem,
|
||||||
@ -36,6 +36,7 @@ use std::{
|
|||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use yamux::ConnectionError;
|
||||||
|
|
||||||
/// A Yamux connection.
|
/// A Yamux connection.
|
||||||
pub struct Yamux<S>(Mutex<Inner<S>>);
|
pub struct Yamux<S>(Mutex<Inner<S>>);
|
||||||
@ -97,44 +98,35 @@ where
|
|||||||
|
|
||||||
pub type YamuxResult<T> = Result<T, YamuxError>;
|
pub type YamuxResult<T> = Result<T, YamuxError>;
|
||||||
|
|
||||||
/// > **Note**: This implementation never emits [`StreamMuxerEvent::AddressChange`] events.
|
|
||||||
impl<S> StreamMuxer for Yamux<S>
|
impl<S> StreamMuxer for Yamux<S>
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<yamux::Stream, YamuxError>> + Unpin,
|
S: Stream<Item = Result<yamux::Stream, YamuxError>> + Unpin,
|
||||||
{
|
{
|
||||||
type Substream = yamux::Stream;
|
type Substream = yamux::Stream;
|
||||||
type OutboundSubstream = OpenSubstreamToken;
|
|
||||||
type Error = YamuxError;
|
type Error = YamuxError;
|
||||||
|
|
||||||
fn poll_event(
|
fn poll_inbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
&self,
|
self.0
|
||||||
c: &mut Context<'_>,
|
.lock()
|
||||||
) -> Poll<YamuxResult<StreamMuxerEvent<Self::Substream>>> {
|
.incoming
|
||||||
let mut inner = self.0.lock();
|
.poll_next_unpin(cx)
|
||||||
match ready!(inner.incoming.poll_next_unpin(c)) {
|
.map(|maybe_stream| {
|
||||||
Some(Ok(s)) => Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(s))),
|
let stream = maybe_stream
|
||||||
Some(Err(e)) => Poll::Ready(Err(e)),
|
.transpose()?
|
||||||
None => Poll::Ready(Err(yamux::ConnectionError::Closed.into())),
|
.ok_or(YamuxError(ConnectionError::Closed))?;
|
||||||
}
|
|
||||||
|
Ok(stream)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_outbound(&self) -> Self::OutboundSubstream {
|
fn poll_outbound(&self, cx: &mut Context<'_>) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||||
OpenSubstreamToken(())
|
Pin::new(&mut self.0.lock().control)
|
||||||
}
|
.poll_open_stream(cx)
|
||||||
|
|
||||||
fn poll_outbound(
|
|
||||||
&self,
|
|
||||||
c: &mut Context<'_>,
|
|
||||||
_: &mut OpenSubstreamToken,
|
|
||||||
) -> Poll<YamuxResult<Self::Substream>> {
|
|
||||||
let mut inner = self.0.lock();
|
|
||||||
Pin::new(&mut inner.control)
|
|
||||||
.poll_open_stream(c)
|
|
||||||
.map_err(YamuxError)
|
.map_err(YamuxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_outbound(&self, _: Self::OutboundSubstream) {
|
fn poll_address_change(&self, _: &mut Context<'_>) -> Poll<Result<Multiaddr, Self::Error>> {
|
||||||
self.0.lock().control.abort_open_stream()
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_close(&self, c: &mut Context<'_>) -> Poll<YamuxResult<()>> {
|
fn poll_close(&self, c: &mut Context<'_>) -> Poll<YamuxResult<()>> {
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
- Update to `libp2p-request-response` `v0.20.0`.
|
- Update to `libp2p-request-response` `v0.20.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.5.0
|
# 0.5.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -18,7 +18,7 @@ async-trait = "0.1"
|
|||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
futures-timer = "3.0"
|
futures-timer = "3.0"
|
||||||
instant = "0.1"
|
instant = "0.1"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
libp2p-request-response = { version = "0.20.0", path = "../request-response" }
|
libp2p-request-response = { version = "0.20.0", path = "../request-response" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
- Expose `PROTOCOL_NAME`. See [PR 2734].
|
- Expose `PROTOCOL_NAME`. See [PR 2734].
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
[PR 2734]: https://github.com/libp2p/rust-libp2p/pull/2734/
|
[PR 2734]: https://github.com/libp2p/rust-libp2p/pull/2734/
|
||||||
|
|
||||||
# 0.4.0
|
# 0.4.0
|
||||||
|
@ -17,7 +17,7 @@ either = "1.6.0"
|
|||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
futures-timer = "3.0"
|
futures-timer = "3.0"
|
||||||
instant = "0.1.11"
|
instant = "0.1.11"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core" }
|
libp2p-core = { version = "0.35.0", path = "../../core" }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
prost-codec = { version = "0.1", path = "../../misc/prost-codec" }
|
prost-codec = { version = "0.1", path = "../../misc/prost-codec" }
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.38.0`.
|
- Update to `libp2p-swarm` `v0.38.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.37.0
|
# 0.37.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
cuckoofilter = "0.5.0"
|
cuckoofilter = "0.5.0"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
prost = "0.10"
|
prost = "0.10"
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.38.0`.
|
- Update to `libp2p-swarm` `v0.38.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.39.0
|
# 0.39.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
bytes = "1.0"
|
bytes = "1.0"
|
||||||
byteorder = "1.3.4"
|
byteorder = "1.3.4"
|
||||||
fnv = "1.0.7"
|
fnv = "1.0.7"
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
- Expose `PROTOCOL_NAME` and `PUSH_PROTOCOL_NAME`. See [PR 2734].
|
- Expose `PROTOCOL_NAME` and `PUSH_PROTOCOL_NAME`. See [PR 2734].
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
[PR 2734]: https://github.com/libp2p/rust-libp2p/pull/2734/
|
[PR 2734]: https://github.com/libp2p/rust-libp2p/pull/2734/
|
||||||
|
|
||||||
# 0.37.0
|
# 0.37.0
|
||||||
|
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
asynchronous-codec = "0.6"
|
asynchronous-codec = "0.6"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
futures-timer = "3.0.2"
|
futures-timer = "3.0.2"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
log = "0.4.1"
|
log = "0.4.1"
|
||||||
lru = "0.7.2"
|
lru = "0.7.2"
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.38.0`.
|
- Update to `libp2p-swarm` `v0.38.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.38.0
|
# 0.38.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -18,7 +18,7 @@ fnv = "1.0"
|
|||||||
asynchronous-codec = "0.6"
|
asynchronous-codec = "0.6"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
prost = "0.10"
|
prost = "0.10"
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.38.0`.
|
- Update to `libp2p-swarm` `v0.38.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.38.0
|
# 0.38.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -17,7 +17,7 @@ dns-parser = "0.8.0"
|
|||||||
futures = "0.3.13"
|
futures = "0.3.13"
|
||||||
if-watch = "1.0.0"
|
if-watch = "1.0.0"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
rand = "0.8.3"
|
rand = "0.8.3"
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
- Expose `PROTOCOL_NAME`. See [PR 2734].
|
- Expose `PROTOCOL_NAME`. See [PR 2734].
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
[PR 2734]: https://github.com/libp2p/rust-libp2p/pull/2734/
|
[PR 2734]: https://github.com/libp2p/rust-libp2p/pull/2734/
|
||||||
|
|
||||||
# 0.37.0
|
# 0.37.0
|
||||||
|
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
futures-timer = "3.0.2"
|
futures-timer = "3.0.2"
|
||||||
instant = "0.1.11"
|
instant = "0.1.11"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
log = "0.4.1"
|
log = "0.4.1"
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
- Expose `HOP_PROTOCOL_NAME` and `STOP_PROTOCOL_NAME`. See [PR 2734].
|
- Expose `HOP_PROTOCOL_NAME` and `STOP_PROTOCOL_NAME`. See [PR 2734].
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
[PR 2734]: https://github.com/libp2p/rust-libp2p/pull/2734/
|
[PR 2734]: https://github.com/libp2p/rust-libp2p/pull/2734/
|
||||||
|
|
||||||
# 0.10.0
|
# 0.10.0
|
||||||
|
@ -17,7 +17,7 @@ either = "1.6.0"
|
|||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
futures-timer = "3"
|
futures-timer = "3"
|
||||||
instant = "0.1.11"
|
instant = "0.1.11"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
pin-project = "1"
|
pin-project = "1"
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.38.0`.
|
- Update to `libp2p-swarm` `v0.38.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.7.0
|
# 0.7.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
asynchronous-codec = "0.6"
|
asynchronous-codec = "0.6"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
prost = "0.10"
|
prost = "0.10"
|
||||||
void = "1"
|
void = "1"
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.38.0`.
|
- Update to `libp2p-swarm` `v0.38.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.19.0
|
# 0.19.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -15,7 +15,7 @@ async-trait = "0.1"
|
|||||||
bytes = "1"
|
bytes = "1"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
instant = "0.1.11"
|
instant = "0.1.11"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.38.0", path = "../../swarm" }
|
||||||
log = "0.4.11"
|
log = "0.4.11"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
- Update dial address concurrency factor to `8`, thus dialing up to 8 addresses concurrently for a single connection attempt. See `Swarm::dial_concurrency_factor` and [PR 2741].
|
- Update dial address concurrency factor to `8`, thus dialing up to 8 addresses concurrently for a single connection attempt. See `Swarm::dial_concurrency_factor` and [PR 2741].
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
[PR 2741]: https://github.com/libp2p/rust-libp2p/pull/2741/
|
[PR 2741]: https://github.com/libp2p/rust-libp2p/pull/2741/
|
||||||
|
|
||||||
# 0.37.0
|
# 0.37.0
|
||||||
|
@ -16,7 +16,7 @@ fnv = "1.0"
|
|||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
futures-timer = "3.0.2"
|
futures-timer = "3.0.2"
|
||||||
instant = "0.1.11"
|
instant = "0.1.11"
|
||||||
libp2p-core = { version = "0.34.0", path = "../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../core", default-features = false }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
pin-project = "1.0.0"
|
pin-project = "1.0.0"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
mod handler_wrapper;
|
mod handler_wrapper;
|
||||||
mod substream;
|
|
||||||
|
|
||||||
pub(crate) mod pool;
|
pub(crate) mod pool;
|
||||||
|
|
||||||
@ -30,18 +29,19 @@ pub use error::{
|
|||||||
};
|
};
|
||||||
pub use pool::{ConnectionCounters, ConnectionLimits};
|
pub use pool::{ConnectionCounters, ConnectionLimits};
|
||||||
pub use pool::{EstablishedConnection, PendingConnection};
|
pub use pool::{EstablishedConnection, PendingConnection};
|
||||||
pub use substream::{Close, SubstreamEndpoint};
|
|
||||||
|
|
||||||
use crate::handler::ConnectionHandler;
|
use crate::handler::ConnectionHandler;
|
||||||
use crate::IntoConnectionHandler;
|
use crate::IntoConnectionHandler;
|
||||||
|
use futures::future::poll_fn;
|
||||||
use handler_wrapper::HandlerWrapper;
|
use handler_wrapper::HandlerWrapper;
|
||||||
use libp2p_core::connection::ConnectedPoint;
|
use libp2p_core::connection::ConnectedPoint;
|
||||||
use libp2p_core::multiaddr::Multiaddr;
|
use libp2p_core::multiaddr::Multiaddr;
|
||||||
use libp2p_core::muxing::StreamMuxerBox;
|
use libp2p_core::muxing::StreamMuxerBox;
|
||||||
use libp2p_core::upgrade;
|
|
||||||
use libp2p_core::PeerId;
|
use libp2p_core::PeerId;
|
||||||
use std::{error::Error, fmt, pin::Pin, task::Context, task::Poll};
|
use libp2p_core::{upgrade, StreamMuxer};
|
||||||
use substream::{Muxing, SubstreamEvent};
|
use std::collections::VecDeque;
|
||||||
|
use std::future::Future;
|
||||||
|
use std::{error::Error, fmt, io, pin::Pin, task::Context, task::Poll};
|
||||||
|
|
||||||
/// Information about a successfully established connection.
|
/// Information about a successfully established connection.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
@ -52,6 +52,13 @@ pub struct Connected {
|
|||||||
pub peer_id: PeerId,
|
pub peer_id: PeerId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Endpoint for a received substream.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub enum SubstreamEndpoint<TDialInfo> {
|
||||||
|
Dialer(TDialInfo),
|
||||||
|
Listener,
|
||||||
|
}
|
||||||
|
|
||||||
/// Event generated by a [`Connection`].
|
/// Event generated by a [`Connection`].
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Event<T> {
|
pub enum Event<T> {
|
||||||
@ -67,19 +74,22 @@ where
|
|||||||
THandler: ConnectionHandler,
|
THandler: ConnectionHandler,
|
||||||
{
|
{
|
||||||
/// Node that handles the muxing.
|
/// Node that handles the muxing.
|
||||||
muxing: substream::Muxing<StreamMuxerBox, handler_wrapper::OutboundOpenInfo<THandler>>,
|
muxing: StreamMuxerBox,
|
||||||
/// Handler that processes substreams.
|
/// Handler that processes substreams.
|
||||||
handler: HandlerWrapper<THandler>,
|
handler: HandlerWrapper<THandler>,
|
||||||
|
/// List of "open_info" that is waiting for new outbound substreams.
|
||||||
|
open_info: VecDeque<handler_wrapper::OutboundOpenInfo<THandler>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<THandler> fmt::Debug for Connection<THandler>
|
impl<THandler> fmt::Debug for Connection<THandler>
|
||||||
where
|
where
|
||||||
THandler: ConnectionHandler + fmt::Debug,
|
THandler: ConnectionHandler + fmt::Debug,
|
||||||
|
THandler::OutboundOpenInfo: fmt::Debug,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Connection")
|
f.debug_struct("Connection")
|
||||||
.field("muxing", &self.muxing)
|
|
||||||
.field("handler", &self.handler)
|
.field("handler", &self.handler)
|
||||||
|
.field("open_info", &self.open_info)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,8 +118,9 @@ where
|
|||||||
max_negotiating_inbound_streams,
|
max_negotiating_inbound_streams,
|
||||||
);
|
);
|
||||||
Connection {
|
Connection {
|
||||||
muxing: Muxing::new(muxer),
|
muxing: muxer,
|
||||||
handler: wrapped_handler,
|
handler: wrapped_handler,
|
||||||
|
open_info: VecDeque::with_capacity(8),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,10 +131,10 @@ where
|
|||||||
|
|
||||||
/// Begins an orderly shutdown of the connection, returning the connection
|
/// Begins an orderly shutdown of the connection, returning the connection
|
||||||
/// handler and a `Future` that resolves when connection shutdown is complete.
|
/// handler and a `Future` that resolves when connection shutdown is complete.
|
||||||
pub fn close(self) -> (THandler, Close<StreamMuxerBox>) {
|
pub fn close(self) -> (THandler, impl Future<Output = io::Result<()>>) {
|
||||||
(
|
(
|
||||||
self.handler.into_connection_handler(),
|
self.handler.into_connection_handler(),
|
||||||
self.muxing.close().0,
|
poll_fn(move |cx| self.muxing.poll_close(cx)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,38 +149,38 @@ where
|
|||||||
match self.handler.poll(cx)? {
|
match self.handler.poll(cx)? {
|
||||||
Poll::Pending => {}
|
Poll::Pending => {}
|
||||||
Poll::Ready(handler_wrapper::Event::OutboundSubstreamRequest(user_data)) => {
|
Poll::Ready(handler_wrapper::Event::OutboundSubstreamRequest(user_data)) => {
|
||||||
self.muxing.open_substream(user_data);
|
self.open_info.push_back(user_data);
|
||||||
continue;
|
continue; // Poll handler until exhausted.
|
||||||
}
|
}
|
||||||
Poll::Ready(handler_wrapper::Event::Custom(event)) => {
|
Poll::Ready(handler_wrapper::Event::Custom(event)) => {
|
||||||
return Poll::Ready(Ok(Event::Handler(event)));
|
return Poll::Ready(Ok(Event::Handler(event)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform I/O on the connection through the muxer, informing the handler
|
if !self.open_info.is_empty() {
|
||||||
// of new substreams.
|
if let Poll::Ready(substream) = self.muxing.poll_outbound(cx)? {
|
||||||
match self.muxing.poll(cx)? {
|
let user_data = self
|
||||||
Poll::Pending => {}
|
.open_info
|
||||||
Poll::Ready(SubstreamEvent::InboundSubstream { substream }) => {
|
.pop_front()
|
||||||
self.handler
|
.expect("`open_info` is not empty");
|
||||||
.inject_substream(substream, SubstreamEndpoint::Listener);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Poll::Ready(SubstreamEvent::OutboundSubstream {
|
|
||||||
user_data,
|
|
||||||
substream,
|
|
||||||
}) => {
|
|
||||||
let endpoint = SubstreamEndpoint::Dialer(user_data);
|
let endpoint = SubstreamEndpoint::Dialer(user_data);
|
||||||
self.handler.inject_substream(substream, endpoint);
|
self.handler.inject_substream(substream, endpoint);
|
||||||
continue;
|
continue; // Go back to the top, handler can potentially make progress again.
|
||||||
}
|
|
||||||
Poll::Ready(SubstreamEvent::AddressChange(address)) => {
|
|
||||||
self.handler.inject_address_change(&address);
|
|
||||||
return Poll::Ready(Ok(Event::AddressChange(address)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Poll::Pending;
|
if let Poll::Ready(substream) = self.muxing.poll_inbound(cx)? {
|
||||||
|
self.handler
|
||||||
|
.inject_substream(substream, SubstreamEndpoint::Listener);
|
||||||
|
continue; // Go back to the top, handler can potentially make progress again.
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Poll::Ready(address) = self.muxing.poll_address_change(cx)? {
|
||||||
|
self.handler.inject_address_change(&address);
|
||||||
|
return Poll::Ready(Ok(Event::AddressChange(address)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Poll::Pending; // Nothing can make progress, return `Pending`.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,252 +0,0 @@
|
|||||||
// Copyright 2018 Parity Technologies (UK) Ltd.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
|
||||||
// to deal in the Software without restriction, including without limitation
|
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
use futures::prelude::*;
|
|
||||||
use libp2p_core::multiaddr::Multiaddr;
|
|
||||||
use libp2p_core::muxing::{StreamMuxer, StreamMuxerEvent};
|
|
||||||
use smallvec::SmallVec;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::{fmt, pin::Pin, task::Context, task::Poll};
|
|
||||||
|
|
||||||
/// Endpoint for a received substream.
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
||||||
pub enum SubstreamEndpoint<TDialInfo> {
|
|
||||||
Dialer(TDialInfo),
|
|
||||||
Listener,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation of `Stream` that handles substream multiplexing.
|
|
||||||
///
|
|
||||||
/// The stream will receive substreams and can be used to open new outgoing substreams. Destroying
|
|
||||||
/// the `Muxing` will **not** close the existing substreams.
|
|
||||||
///
|
|
||||||
/// The stream will close once both the inbound and outbound channels are closed, and no more
|
|
||||||
/// outbound substream attempt is pending.
|
|
||||||
pub struct Muxing<TMuxer, TUserData>
|
|
||||||
where
|
|
||||||
TMuxer: StreamMuxer,
|
|
||||||
{
|
|
||||||
/// The muxer used to manage substreams.
|
|
||||||
inner: Arc<TMuxer>,
|
|
||||||
/// List of substreams we are currently opening.
|
|
||||||
outbound_substreams: SmallVec<[(TUserData, TMuxer::OutboundSubstream); 8]>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Future that signals the remote that we have closed the connection.
|
|
||||||
pub struct Close<TMuxer> {
|
|
||||||
/// Muxer to close.
|
|
||||||
muxer: Arc<TMuxer>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Event that can happen on the `Muxing`.
|
|
||||||
pub enum SubstreamEvent<TMuxer, TUserData>
|
|
||||||
where
|
|
||||||
TMuxer: StreamMuxer,
|
|
||||||
{
|
|
||||||
/// A new inbound substream arrived.
|
|
||||||
InboundSubstream {
|
|
||||||
/// The newly-opened substream. Will return EOF of an error if the `Muxing` is
|
|
||||||
/// destroyed or `close_graceful` is called.
|
|
||||||
substream: TMuxer::Substream,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// An outbound substream has successfully been opened.
|
|
||||||
OutboundSubstream {
|
|
||||||
/// User data that has been passed to the `open_substream` method.
|
|
||||||
user_data: TUserData,
|
|
||||||
/// The newly-opened substream. Will return EOF of an error if the `Muxing` is
|
|
||||||
/// destroyed or `close_graceful` is called.
|
|
||||||
substream: TMuxer::Substream,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// Address to the remote has changed. The previous one is now obsolete.
|
|
||||||
///
|
|
||||||
/// > **Note**: This can for example happen when using the QUIC protocol, where the two nodes
|
|
||||||
/// > can change their IP address while retaining the same QUIC connection.
|
|
||||||
AddressChange(Multiaddr),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Identifier for a substream being opened.
|
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
pub struct OutboundSubstreamId(usize);
|
|
||||||
|
|
||||||
impl<TMuxer, TUserData> Muxing<TMuxer, TUserData>
|
|
||||||
where
|
|
||||||
TMuxer: StreamMuxer,
|
|
||||||
{
|
|
||||||
/// Creates a new node events stream.
|
|
||||||
pub fn new(muxer: TMuxer) -> Self {
|
|
||||||
Muxing {
|
|
||||||
inner: Arc::new(muxer),
|
|
||||||
outbound_substreams: SmallVec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Starts the process of opening a new outbound substream.
|
|
||||||
///
|
|
||||||
/// After calling this method, polling the stream should eventually produce either an
|
|
||||||
/// `OutboundSubstream` event or an `OutboundClosed` event containing the user data that has
|
|
||||||
/// been passed to this method.
|
|
||||||
pub fn open_substream(&mut self, user_data: TUserData) {
|
|
||||||
let raw = self.inner.open_outbound();
|
|
||||||
self.outbound_substreams.push((user_data, raw));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Destroys the node stream and returns all the pending outbound substreams, plus an object
|
|
||||||
/// that signals the remote that we shut down the connection.
|
|
||||||
#[must_use]
|
|
||||||
pub fn close(mut self) -> (Close<TMuxer>, Vec<TUserData>) {
|
|
||||||
let substreams = self.cancel_outgoing();
|
|
||||||
let close = Close {
|
|
||||||
muxer: self.inner.clone(),
|
|
||||||
};
|
|
||||||
(close, substreams)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Destroys all outbound streams and returns the corresponding user data.
|
|
||||||
pub fn cancel_outgoing(&mut self) -> Vec<TUserData> {
|
|
||||||
let mut out = Vec::with_capacity(self.outbound_substreams.len());
|
|
||||||
for (user_data, outbound) in self.outbound_substreams.drain(..) {
|
|
||||||
out.push(user_data);
|
|
||||||
self.inner.destroy_outbound(outbound);
|
|
||||||
}
|
|
||||||
out
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides an API similar to `Future`.
|
|
||||||
pub fn poll(
|
|
||||||
&mut self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
) -> Poll<Result<SubstreamEvent<TMuxer, TUserData>, TMuxer::Error>> {
|
|
||||||
// Polling inbound substream.
|
|
||||||
match self.inner.poll_event(cx) {
|
|
||||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(substream))) => {
|
|
||||||
return Poll::Ready(Ok(SubstreamEvent::InboundSubstream { substream }));
|
|
||||||
}
|
|
||||||
Poll::Ready(Ok(StreamMuxerEvent::AddressChange(addr))) => {
|
|
||||||
return Poll::Ready(Ok(SubstreamEvent::AddressChange(addr)))
|
|
||||||
}
|
|
||||||
Poll::Ready(Err(err)) => return Poll::Ready(Err(err)),
|
|
||||||
Poll::Pending => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Polling outbound substreams.
|
|
||||||
// We remove each element from `outbound_substreams` one by one and add them back.
|
|
||||||
for n in (0..self.outbound_substreams.len()).rev() {
|
|
||||||
let (user_data, mut outbound) = self.outbound_substreams.swap_remove(n);
|
|
||||||
match self.inner.poll_outbound(cx, &mut outbound) {
|
|
||||||
Poll::Ready(Ok(substream)) => {
|
|
||||||
self.inner.destroy_outbound(outbound);
|
|
||||||
return Poll::Ready(Ok(SubstreamEvent::OutboundSubstream {
|
|
||||||
user_data,
|
|
||||||
substream,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
Poll::Pending => {
|
|
||||||
self.outbound_substreams.push((user_data, outbound));
|
|
||||||
}
|
|
||||||
Poll::Ready(Err(err)) => {
|
|
||||||
self.inner.destroy_outbound(outbound);
|
|
||||||
return Poll::Ready(Err(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing happened. Register our task to be notified and return.
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<TMuxer, TUserData> fmt::Debug for Muxing<TMuxer, TUserData>
|
|
||||||
where
|
|
||||||
TMuxer: StreamMuxer,
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
|
||||||
f.debug_struct("Muxing")
|
|
||||||
.field("outbound_substreams", &self.outbound_substreams.len())
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<TMuxer, TUserData> Drop for Muxing<TMuxer, TUserData>
|
|
||||||
where
|
|
||||||
TMuxer: StreamMuxer,
|
|
||||||
{
|
|
||||||
fn drop(&mut self) {
|
|
||||||
// The substreams that were produced will continue to work, as the muxer is held in an Arc.
|
|
||||||
// However we will no longer process any further inbound or outbound substream, and we
|
|
||||||
// therefore close everything.
|
|
||||||
for (_, outbound) in self.outbound_substreams.drain(..) {
|
|
||||||
self.inner.destroy_outbound(outbound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<TMuxer> Future for Close<TMuxer>
|
|
||||||
where
|
|
||||||
TMuxer: StreamMuxer,
|
|
||||||
{
|
|
||||||
type Output = Result<(), TMuxer::Error>;
|
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
||||||
match self.muxer.poll_close(cx) {
|
|
||||||
Poll::Pending => Poll::Pending,
|
|
||||||
Poll::Ready(Ok(())) => Poll::Ready(Ok(())),
|
|
||||||
Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<TMuxer> fmt::Debug for Close<TMuxer>
|
|
||||||
where
|
|
||||||
TMuxer: StreamMuxer,
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
|
||||||
f.debug_struct("Close").finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<TMuxer, TUserData> fmt::Debug for SubstreamEvent<TMuxer, TUserData>
|
|
||||||
where
|
|
||||||
TMuxer: StreamMuxer,
|
|
||||||
TMuxer::Substream: fmt::Debug,
|
|
||||||
TUserData: fmt::Debug,
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
SubstreamEvent::InboundSubstream { substream } => f
|
|
||||||
.debug_struct("SubstreamEvent::OutboundClosed")
|
|
||||||
.field("substream", substream)
|
|
||||||
.finish(),
|
|
||||||
SubstreamEvent::OutboundSubstream {
|
|
||||||
user_data,
|
|
||||||
substream,
|
|
||||||
} => f
|
|
||||||
.debug_struct("SubstreamEvent::OutboundSubstream")
|
|
||||||
.field("user_data", user_data)
|
|
||||||
.field("substream", substream)
|
|
||||||
.finish(),
|
|
||||||
SubstreamEvent::AddressChange(address) => f
|
|
||||||
.debug_struct("SubstreamEvent::AddressChange")
|
|
||||||
.field("address", address)
|
|
||||||
.finish(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.35.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.34.0
|
# 0.34.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-deflate"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Deflate encryption protocol for libp2p"
|
description = "Deflate encryption protocol for libp2p"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.35.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.34.0
|
# 0.34.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-dns"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "DNS transport implementation for libp2p"
|
description = "DNS transport implementation for libp2p"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -11,7 +11,7 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
|
|||||||
categories = ["network-programming", "asynchronous"]
|
categories = ["network-programming", "asynchronous"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
log = "0.4.1"
|
log = "0.4.1"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
async-std-resolver = { version = "0.21", optional = true }
|
async-std-resolver = { version = "0.21", optional = true }
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.38.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.37.0
|
# 0.37.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-noise"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Cryptographic handshake protocol using the noise framework."
|
description = "Cryptographic handshake protocol using the noise framework."
|
||||||
version = "0.37.0"
|
version = "0.38.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -13,7 +13,7 @@ bytes = "1"
|
|||||||
curve25519-dalek = "3.0.0"
|
curve25519-dalek = "3.0.0"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
lazy_static = "1.2"
|
lazy_static = "1.2"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
prost = "0.10"
|
prost = "0.10"
|
||||||
rand = "0.8.3"
|
rand = "0.8.3"
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.35.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.34.0
|
# 0.34.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-plaintext"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Plaintext encryption dummy protocol for libp2p"
|
description = "Plaintext encryption dummy protocol for libp2p"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
bytes = "1"
|
bytes = "1"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
asynchronous-codec = "0.6"
|
asynchronous-codec = "0.6"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
prost = "0.10"
|
prost = "0.10"
|
||||||
unsigned-varint = { version = "0.7", features = ["asynchronous_codec"] }
|
unsigned-varint = { version = "0.7", features = ["asynchronous_codec"] }
|
||||||
|
@ -18,7 +18,7 @@ if-watch = { version = "1.0.0", optional = true }
|
|||||||
if-addrs = { version = "0.7.0", optional = true }
|
if-addrs = { version = "0.7.0", optional = true }
|
||||||
ipnet = "2.0.0"
|
ipnet = "2.0.0"
|
||||||
libc = "0.2.80"
|
libc = "0.2.80"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
log = "0.4.11"
|
log = "0.4.11"
|
||||||
socket2 = { version = "0.4.0", features = ["all"] }
|
socket2 = { version = "0.4.0", features = ["all"] }
|
||||||
tokio-crate = { package = "tokio", version = "1.19.0", default-features = false, features = ["net"], optional = true }
|
tokio-crate = { package = "tokio", version = "1.19.0", default-features = false, features = ["net"], optional = true }
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.34.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.33.0
|
# 0.33.0
|
||||||
|
|
||||||
- Update dependencies.
|
- Update dependencies.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-uds"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Unix domain sockets transport for libp2p"
|
description = "Unix domain sockets transport for libp2p"
|
||||||
version = "0.33.0"
|
version = "0.34.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
|
|
||||||
[target.'cfg(all(unix, not(target_os = "emscripten")))'.dependencies]
|
[target.'cfg(all(unix, not(target_os = "emscripten")))'.dependencies]
|
||||||
async-std = { version = "1.6.2", optional = true }
|
async-std = { version = "1.6.2", optional = true }
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
log = "0.4.1"
|
log = "0.4.1"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
tokio = { version = "1.15", default-features = false, features = ["net"], optional = true }
|
tokio = { version = "1.15", default-features = false, features = ["net"], optional = true }
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.35.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.34.0
|
# 0.34.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-wasm-ext"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Allows passing in an external transport in a WASM environment"
|
description = "Allows passing in an external transport in a WASM environment"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -13,7 +13,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
js-sys = "0.3.50"
|
js-sys = "0.3.50"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
parity-send-wrapper = "0.1.0"
|
parity-send-wrapper = "0.1.0"
|
||||||
wasm-bindgen = "0.2.42"
|
wasm-bindgen = "0.2.42"
|
||||||
wasm-bindgen-futures = "0.4.4"
|
wasm-bindgen-futures = "0.4.4"
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.37.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.35.0`.
|
||||||
|
|
||||||
# 0.36.0
|
# 0.36.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.34.0`.
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-websocket"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "WebSocket transport for libp2p"
|
description = "WebSocket transport for libp2p"
|
||||||
version = "0.36.0"
|
version = "0.37.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
futures-rustls = "0.22"
|
futures-rustls = "0.22"
|
||||||
either = "1.5.3"
|
either = "1.5.3"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.35.0", path = "../../core", default-features = false }
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
parking_lot = "0.12.0"
|
parking_lot = "0.12.0"
|
||||||
quicksink = "0.1"
|
quicksink = "0.1"
|
||||||
|
Reference in New Issue
Block a user