mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-14 02:21:21 +00:00
core/muxing: Force StreamMuxer::Substream
to implement Async{Read,Write}
(#2707)
Co-authored-by: Max Inden <mail@max-inden.de>
This commit is contained in:
17
CHANGELOG.md
17
CHANGELOG.md
@ -44,10 +44,27 @@
|
|||||||
# `libp2p` facade crate
|
# `libp2p` facade crate
|
||||||
|
|
||||||
# 0.46.0 [unreleased]
|
# 0.46.0 [unreleased]
|
||||||
|
|
||||||
- Semver bump Rust from `1.56.1` to `1.60.0` . See [PR 2646].
|
- Semver bump Rust from `1.56.1` to `1.60.0` . See [PR 2646].
|
||||||
- Added weak dependencies for features. See [PR 2646].
|
- Added weak dependencies for features. See [PR 2646].
|
||||||
- Update individual crates.
|
- Update individual crates.
|
||||||
|
- Update to [`libp2p-autonat` `v0.5.0`](protocols/autonat/CHANGELOG.md#050).
|
||||||
|
- Update to [`libp2p-core` `v0.34.0`](core/CHANGELOG.md#0340).
|
||||||
|
- Update to [`libp2p-dcutr` `v0.4.0`](protocols/dcutr/CHANGELOG.md#040).
|
||||||
|
- Update to [`libp2p-floodsub` `v0.37.0`](protocols/floodsub/CHANGELOG.md#0370).
|
||||||
|
- Update to [`libp2p-identify` `v0.37.0`](protocols/identify/CHANGELOG.md#0370).
|
||||||
|
- Update to [`libp2p-kad` `v0.38.0`](protocols/kad/CHANGELOG.md#0380).
|
||||||
|
- Update to [`libp2p-metrics` `v0.7.0`](misc/metrics/CHANGELOG.md#070).
|
||||||
- Update to [`libp2p-mplex` `v0.34.0`](muxers/mplex/CHANGELOG.md).
|
- Update to [`libp2p-mplex` `v0.34.0`](muxers/mplex/CHANGELOG.md).
|
||||||
|
- Update to [`libp2p-noise` `v0.37.0`](transports/noise/CHANGELOG.md#0370).
|
||||||
|
- Update to [`libp2p-ping` `v0.37.0`](protocols/ping/CHANGELOG.md#0370).
|
||||||
|
- Update to [`libp2p-plaintext` `v0.34.0`](transports/plaintext/CHANGELOG.md#0340).
|
||||||
|
- Update to [`libp2p-relay` `v0.10.0`](protocols/relay/CHANGELOG.md#0100).
|
||||||
|
- Update to [`libp2p-rendezvous` `v0.7.0`](protocols/rendezvous/CHANGELOG.md#070).
|
||||||
|
- Update to [`libp2p-request-response` `v0.19.0`](protocols/request-response/CHANGELOG.md#0190).
|
||||||
|
- Update to [`libp2p-swarm` `v0.37.0`](swarm/CHANGELOG.md#0370).
|
||||||
|
- Update to [`libp2p-wasm-ext` `v0.34.0`](transports/wasm-ext/CHANGELOG.md#0340).
|
||||||
|
- Update to [`libp2p-yamux` `v0.38.0`](muxers/yamux/CHANGELOG.md#0380).
|
||||||
- Update to `libp2p-uds` [`v0.33.0`](transports/uds/CHANGELOG.md).
|
- Update to `libp2p-uds` [`v0.33.0`](transports/uds/CHANGELOG.md).
|
||||||
|
|
||||||
[PR 2646]: https://github.com/libp2p/rust-libp2p/pull/2646
|
[PR 2646]: https://github.com/libp2p/rust-libp2p/pull/2646
|
||||||
|
46
Cargo.toml
46
Cargo.toml
@ -3,7 +3,7 @@ name = "libp2p"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.60.0"
|
rust-version = "1.60.0"
|
||||||
description = "Peer-to-peer networking library"
|
description = "Peer-to-peer networking library"
|
||||||
version = "0.46.0"
|
version = "0.47.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"
|
||||||
@ -76,26 +76,26 @@ getrandom = "0.2.3" # Explicit dependency to be used in `wasm-bindgen` feature
|
|||||||
instant = "0.1.11" # Explicit dependency to be used in `wasm-bindgen` feature
|
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.4.0", path = "protocols/autonat", optional = true }
|
libp2p-autonat = { version = "0.5.0", path = "protocols/autonat", optional = true }
|
||||||
libp2p-core = { version = "0.33.0", path = "core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "core", default-features = false }
|
||||||
libp2p-dcutr = { version = "0.3.1", path = "protocols/dcutr", optional = true }
|
libp2p-dcutr = { version = "0.4.0", path = "protocols/dcutr", optional = true }
|
||||||
libp2p-floodsub = { version = "0.36.0", path = "protocols/floodsub", optional = true }
|
libp2p-floodsub = { version = "0.37.0", path = "protocols/floodsub", optional = true }
|
||||||
libp2p-identify = { version = "0.36.1", path = "protocols/identify", optional = true }
|
libp2p-identify = { version = "0.37.0", path = "protocols/identify", optional = true }
|
||||||
libp2p-kad = { version = "0.37.1", path = "protocols/kad", optional = true }
|
libp2p-kad = { version = "0.38.0", path = "protocols/kad", optional = true }
|
||||||
libp2p-metrics = { version = "0.6.0", path = "misc/metrics", optional = true }
|
libp2p-metrics = { version = "0.7.0", path = "misc/metrics", optional = true }
|
||||||
libp2p-mplex = { version = "0.34.0", path = "muxers/mplex", optional = true }
|
libp2p-mplex = { version = "0.34.0", path = "muxers/mplex", optional = true }
|
||||||
libp2p-noise = { version = "0.36.0", path = "transports/noise", optional = true }
|
libp2p-noise = { version = "0.37.0", path = "transports/noise", optional = true }
|
||||||
libp2p-ping = { version = "0.36.0", path = "protocols/ping", optional = true }
|
libp2p-ping = { version = "0.37.0", path = "protocols/ping", optional = true }
|
||||||
libp2p-plaintext = { version = "0.33.0", path = "transports/plaintext", optional = true }
|
libp2p-plaintext = { version = "0.34.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.9.1", path = "protocols/relay", optional = true }
|
libp2p-relay = { version = "0.10.0", path = "protocols/relay", optional = true }
|
||||||
libp2p-rendezvous = { version = "0.6.0", path = "protocols/rendezvous", optional = true }
|
libp2p-rendezvous = { version = "0.7.0", path = "protocols/rendezvous", optional = true }
|
||||||
libp2p-request-response = { version = "0.18.0", path = "protocols/request-response", optional = true }
|
libp2p-request-response = { version = "0.19.0", path = "protocols/request-response", optional = true }
|
||||||
libp2p-swarm = { version = "0.36.1", path = "swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "swarm" }
|
||||||
libp2p-swarm-derive = { version = "0.27.0", path = "swarm-derive" }
|
libp2p-swarm-derive = { version = "0.27.0", path = "swarm-derive" }
|
||||||
libp2p-uds = { version = "0.33.0", path = "transports/uds", optional = true }
|
libp2p-uds = { version = "0.33.0", path = "transports/uds", optional = true }
|
||||||
libp2p-wasm-ext = { version = "0.33.0", path = "transports/wasm-ext", default-features = false, optional = true }
|
libp2p-wasm-ext = { version = "0.34.0", path = "transports/wasm-ext", default-features = false, optional = true }
|
||||||
libp2p-yamux = { version = "0.37.0", path = "muxers/yamux", optional = true }
|
libp2p-yamux = { version = "0.38.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"
|
||||||
@ -103,14 +103,14 @@ 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.33.0", path = "transports/deflate", optional = true }
|
libp2p-deflate = { version = "0.34.0", path = "transports/deflate", optional = true }
|
||||||
libp2p-dns = { version = "0.33.0", path = "transports/dns", optional = true, default-features = false }
|
libp2p-dns = { version = "0.34.0", path = "transports/dns", optional = true, default-features = false }
|
||||||
libp2p-mdns = { version = "0.37.0", path = "protocols/mdns", optional = true }
|
libp2p-mdns = { version = "0.38.0", path = "protocols/mdns", optional = true }
|
||||||
libp2p-tcp = { version = "0.33.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.35.0", path = "transports/websocket", optional = true }
|
libp2p-websocket = { version = "0.36.0", path = "transports/websocket", optional = true }
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "unknown"))'.dependencies]
|
[target.'cfg(not(target_os = "unknown"))'.dependencies]
|
||||||
libp2p-gossipsub = { version = "0.38.0", path = "protocols/gossipsub", optional = true }
|
libp2p-gossipsub = { version = "0.39.0", path = "protocols/gossipsub", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
async-std = { version = "1.6.2", features = ["attributes"] }
|
async-std = { version = "1.6.2", features = ["attributes"] }
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
# 0.33.1 - unreleased
|
# 0.34.0 - unreleased
|
||||||
|
|
||||||
- Introduce `StreamMuxerEvent::map_inbound_stream`. See [PR 2691].
|
- Introduce `StreamMuxerEvent::map_inbound_stream`. See [PR 2691].
|
||||||
|
- Remove `{read,write,flush,shutdown,destroy}_substream` functions from `StreamMuxer` trait
|
||||||
|
in favor of forcing `StreamMuxer::Substream` to implement `AsyncRead + AsyncWrite`. See [PR 2707].
|
||||||
|
|
||||||
[PR 2691]: https://github.com/libp2p/rust-libp2p/pull/2691
|
[PR 2691]: https://github.com/libp2p/rust-libp2p/pull/2691
|
||||||
|
[PR 2707]: https://github.com/libp2p/rust-libp2p/pull/2707
|
||||||
|
|
||||||
# 0.33.0
|
# 0.33.0
|
||||||
|
|
||||||
|
@ -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.33.1"
|
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"
|
||||||
|
@ -259,85 +259,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
sub: &mut Self::Substream,
|
|
||||||
buf: &mut [u8],
|
|
||||||
) -> Poll<Result<usize, Self::Error>> {
|
|
||||||
match (self, sub) {
|
|
||||||
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
|
|
||||||
inner.read_substream(cx, sub, buf).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
|
|
||||||
inner.read_substream(cx, sub, buf).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
_ => panic!("Wrong API usage"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
sub: &mut Self::Substream,
|
|
||||||
buf: &[u8],
|
|
||||||
) -> Poll<Result<usize, Self::Error>> {
|
|
||||||
match (self, sub) {
|
|
||||||
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
|
|
||||||
inner.write_substream(cx, sub, buf).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
|
|
||||||
inner.write_substream(cx, sub, buf).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
_ => panic!("Wrong API usage"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
sub: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), Self::Error>> {
|
|
||||||
match (self, sub) {
|
|
||||||
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
|
|
||||||
inner.flush_substream(cx, sub).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
|
|
||||||
inner.flush_substream(cx, sub).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
_ => panic!("Wrong API usage"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shutdown_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
sub: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), Self::Error>> {
|
|
||||||
match (self, sub) {
|
|
||||||
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
|
|
||||||
inner.shutdown_substream(cx, sub).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
|
|
||||||
inner.shutdown_substream(cx, sub).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
_ => panic!("Wrong API usage"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destroy_substream(&self, substream: Self::Substream) {
|
|
||||||
match self {
|
|
||||||
EitherOutput::First(inner) => match substream {
|
|
||||||
EitherOutput::First(substream) => inner.destroy_substream(substream),
|
|
||||||
_ => panic!("Wrong API usage"),
|
|
||||||
},
|
|
||||||
EitherOutput::Second(inner) => match substream {
|
|
||||||
EitherOutput::Second(substream) => inner.destroy_substream(substream),
|
|
||||||
_ => panic!("Wrong API usage"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
match self {
|
match self {
|
||||||
EitherOutput::First(inner) => inner.poll_close(cx).map_err(|e| e.into()),
|
EitherOutput::First(inner) => inner.poll_close(cx).map_err(|e| e.into()),
|
||||||
|
@ -21,8 +21,7 @@
|
|||||||
//! Muxing is the process of splitting a connection into multiple substreams.
|
//! Muxing is the process of splitting a connection into multiple substreams.
|
||||||
//!
|
//!
|
||||||
//! The main item of this module is the `StreamMuxer` trait. An implementation of `StreamMuxer`
|
//! The main item of this module is the `StreamMuxer` trait. An implementation of `StreamMuxer`
|
||||||
//! has ownership of a connection, lets you open and close substreams, and read/write data
|
//! has ownership of a connection, lets you open and close substreams.
|
||||||
//! on open substreams.
|
|
||||||
//!
|
//!
|
||||||
//! > **Note**: You normally don't need to use the methods of the `StreamMuxer` directly, as this
|
//! > **Note**: You normally don't need to use the methods of the `StreamMuxer` directly, as this
|
||||||
//! > is managed by the library's internals.
|
//! > is managed by the library's internals.
|
||||||
@ -51,31 +50,27 @@
|
|||||||
//! The upgrade process will take ownership of the connection, which makes it possible for the
|
//! The upgrade process will take ownership of the connection, which makes it possible for the
|
||||||
//! implementation of `StreamMuxer` to control everything that happens on the wire.
|
//! implementation of `StreamMuxer` to control everything that happens on the wire.
|
||||||
|
|
||||||
use futures::{future, prelude::*, task::Context, task::Poll};
|
use futures::{task::Context, task::Poll, AsyncRead, AsyncWrite};
|
||||||
use multiaddr::Multiaddr;
|
use multiaddr::Multiaddr;
|
||||||
use std::{fmt, io, ops::Deref, pin::Pin};
|
use std::io;
|
||||||
|
|
||||||
pub use self::boxed::StreamMuxerBox;
|
pub use self::boxed::StreamMuxerBox;
|
||||||
|
pub use self::boxed::SubstreamBox;
|
||||||
pub use self::singleton::SingletonMuxer;
|
pub use self::singleton::SingletonMuxer;
|
||||||
|
|
||||||
mod boxed;
|
mod boxed;
|
||||||
mod singleton;
|
mod singleton;
|
||||||
|
|
||||||
/// Implemented on objects that can open and manage substreams.
|
/// Provides multiplexing for a connection by allowing users to open substreams.
|
||||||
///
|
///
|
||||||
/// The state of a muxer, as exposed by this API, is the following:
|
/// A substream created by a [`StreamMuxer`] is a type that implements [`AsyncRead`] and [`AsyncWrite`].
|
||||||
///
|
|
||||||
/// - A connection to the remote. The `poll_event`, `flush_all` and `close` methods operate
|
|
||||||
/// on this.
|
|
||||||
/// - A list of substreams that are open. The `poll_outbound`, `read_substream`, `write_substream`,
|
|
||||||
/// `flush_substream`, `shutdown_substream` and `destroy_substream` methods allow controlling
|
|
||||||
/// these entries.
|
|
||||||
/// - A list of outbound substreams being opened. The `open_outbound`, `poll_outbound` and
|
|
||||||
/// `destroy_outbound` methods allow controlling these entries.
|
|
||||||
///
|
///
|
||||||
|
/// Inbound substreams are reported via [`StreamMuxer::poll_event`].
|
||||||
|
/// 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;
|
type Substream: AsyncRead + AsyncWrite;
|
||||||
|
|
||||||
/// Future that will be resolved when the outgoing substream is open.
|
/// Future that will be resolved when the outgoing substream is open.
|
||||||
type OutboundSubstream;
|
type OutboundSubstream;
|
||||||
@ -126,86 +121,12 @@ pub trait StreamMuxer {
|
|||||||
/// or if you want to interrupt it.
|
/// or if you want to interrupt it.
|
||||||
fn destroy_outbound(&self, s: Self::OutboundSubstream);
|
fn destroy_outbound(&self, s: Self::OutboundSubstream);
|
||||||
|
|
||||||
/// Reads data from a substream. The behaviour is the same as `futures::AsyncRead::poll_read`.
|
|
||||||
///
|
|
||||||
/// If `Pending` is returned, then the current task will be notified once the substream
|
|
||||||
/// is ready to be read. However, for each individual substream, only the latest task that
|
|
||||||
/// was used to call this method may be notified.
|
|
||||||
///
|
|
||||||
/// If `Async::Ready(0)` is returned, the substream has been closed by the remote and should
|
|
||||||
/// no longer be read afterwards.
|
|
||||||
///
|
|
||||||
/// An error can be generated if the connection has been closed, or if a protocol misbehaviour
|
|
||||||
/// happened.
|
|
||||||
fn read_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
buf: &mut [u8],
|
|
||||||
) -> Poll<Result<usize, Self::Error>>;
|
|
||||||
|
|
||||||
/// Write data to a substream. The behaviour is the same as `futures::AsyncWrite::poll_write`.
|
|
||||||
///
|
|
||||||
/// If `Pending` is returned, then the current task will be notified once the substream
|
|
||||||
/// is ready to be read. For each individual substream, only the latest task that was used to
|
|
||||||
/// call this method may be notified.
|
|
||||||
///
|
|
||||||
/// Calling `write_substream` does not guarantee that data will arrive to the remote. To
|
|
||||||
/// ensure that, you should call `flush_substream`.
|
|
||||||
///
|
|
||||||
/// It is incorrect to call this method on a substream if you called `shutdown_substream` on
|
|
||||||
/// this substream earlier.
|
|
||||||
fn write_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
buf: &[u8],
|
|
||||||
) -> Poll<Result<usize, Self::Error>>;
|
|
||||||
|
|
||||||
/// Flushes a substream. The behaviour is the same as `futures::AsyncWrite::poll_flush`.
|
|
||||||
///
|
|
||||||
/// After this method has been called, data written earlier on the substream is guaranteed to
|
|
||||||
/// be received by the remote.
|
|
||||||
///
|
|
||||||
/// If `Pending` is returned, then the current task will be notified once the substream
|
|
||||||
/// is ready to be read. For each individual substream, only the latest task that was used to
|
|
||||||
/// call this method may be notified.
|
|
||||||
///
|
|
||||||
/// > **Note**: This method may be implemented as a call to `flush_all`.
|
|
||||||
fn flush_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), Self::Error>>;
|
|
||||||
|
|
||||||
/// Attempts to shut down the writing side of a substream. The behaviour is similar to
|
|
||||||
/// `AsyncWrite::poll_close`.
|
|
||||||
///
|
|
||||||
/// Contrary to `AsyncWrite::poll_close`, shutting down a substream does not imply
|
|
||||||
/// `flush_substream`. If you want to make sure that the remote is immediately informed about
|
|
||||||
/// the shutdown, use `flush_substream` or `flush_all`.
|
|
||||||
///
|
|
||||||
/// After this method has been called, you should no longer attempt to write to this substream.
|
|
||||||
///
|
|
||||||
/// An error can be generated if the connection has been closed, or if a protocol misbehaviour
|
|
||||||
/// happened.
|
|
||||||
fn shutdown_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), Self::Error>>;
|
|
||||||
|
|
||||||
/// Destroys a substream.
|
|
||||||
fn destroy_substream(&self, s: Self::Substream);
|
|
||||||
|
|
||||||
/// Closes this `StreamMuxer`.
|
/// Closes this `StreamMuxer`.
|
||||||
///
|
///
|
||||||
/// After this has returned `Poll::Ready(Ok(()))`, the muxer has become useless. All
|
/// After this has returned `Poll::Ready(Ok(()))`, the muxer has become useless. All
|
||||||
/// subsequent reads must return either `EOF` or an error. All subsequent writes, shutdowns,
|
/// subsequent reads must return either `EOF` or an error. All subsequent writes, shutdowns,
|
||||||
/// or polls must generate an error or be ignored.
|
/// or polls must generate an error or be ignored.
|
||||||
///
|
///
|
||||||
/// Calling this method implies `flush_all`.
|
|
||||||
///
|
|
||||||
/// > **Note**: You are encouraged to call this method and wait for it to return `Ready`, so
|
/// > **Note**: You are encouraged to call this method and wait for it to return `Ready`, so
|
||||||
/// > that the remote is properly informed of the shutdown. However, apart from
|
/// > that the remote is properly informed of the shutdown. However, apart from
|
||||||
/// > properly informing the remote, there is no difference between this and
|
/// > properly informing the remote, there is no difference between this and
|
||||||
@ -247,252 +168,3 @@ impl<T> StreamMuxerEvent<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Polls for an event from the muxer and, if an inbound substream, wraps this substream in an
|
|
||||||
/// object that implements `Read`/`Write`/`AsyncRead`/`AsyncWrite`.
|
|
||||||
pub fn event_from_ref_and_wrap<P>(
|
|
||||||
muxer: P,
|
|
||||||
) -> impl Future<Output = Result<StreamMuxerEvent<SubstreamRef<P>>, <P::Target as StreamMuxer>::Error>>
|
|
||||||
where
|
|
||||||
P: Deref + Clone,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
let muxer2 = muxer.clone();
|
|
||||||
future::poll_fn(move |cx| muxer.poll_event(cx)).map_ok(|event| match event {
|
|
||||||
StreamMuxerEvent::InboundSubstream(substream) => {
|
|
||||||
StreamMuxerEvent::InboundSubstream(substream_from_ref(muxer2, substream))
|
|
||||||
}
|
|
||||||
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Same as `outbound_from_ref`, but wraps the output in an object that
|
|
||||||
/// implements `Read`/`Write`/`AsyncRead`/`AsyncWrite`.
|
|
||||||
pub fn outbound_from_ref_and_wrap<P>(muxer: P) -> OutboundSubstreamRefWrapFuture<P>
|
|
||||||
where
|
|
||||||
P: Deref + Clone,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
let inner = outbound_from_ref(muxer);
|
|
||||||
OutboundSubstreamRefWrapFuture { inner }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Future returned by `outbound_from_ref_and_wrap`.
|
|
||||||
pub struct OutboundSubstreamRefWrapFuture<P>
|
|
||||||
where
|
|
||||||
P: Deref + Clone,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
inner: OutboundSubstreamRefFuture<P>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> Future for OutboundSubstreamRefWrapFuture<P>
|
|
||||||
where
|
|
||||||
P: Deref + Clone,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
type Output = Result<SubstreamRef<P>, <P::Target as StreamMuxer>::Error>;
|
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
||||||
match Future::poll(Pin::new(&mut self.inner), cx) {
|
|
||||||
Poll::Ready(Ok(substream)) => {
|
|
||||||
let out = substream_from_ref(self.inner.muxer.clone(), substream);
|
|
||||||
Poll::Ready(Ok(out))
|
|
||||||
}
|
|
||||||
Poll::Pending => Poll::Pending,
|
|
||||||
Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds a new future for an outbound substream, where the muxer is a reference.
|
|
||||||
pub fn outbound_from_ref<P>(muxer: P) -> OutboundSubstreamRefFuture<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
let outbound = muxer.open_outbound();
|
|
||||||
OutboundSubstreamRefFuture {
|
|
||||||
muxer,
|
|
||||||
outbound: Some(outbound),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Future returned by `outbound_from_ref`.
|
|
||||||
pub struct OutboundSubstreamRefFuture<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
muxer: P,
|
|
||||||
outbound: Option<<P::Target as StreamMuxer>::OutboundSubstream>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> Unpin for OutboundSubstreamRefFuture<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> Future for OutboundSubstreamRefFuture<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
type Output = Result<<P::Target as StreamMuxer>::Substream, <P::Target as StreamMuxer>::Error>;
|
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
||||||
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
|
|
||||||
// multiple different fields from the `Pin` at the same time.
|
|
||||||
let this = &mut *self;
|
|
||||||
this.muxer
|
|
||||||
.poll_outbound(cx, this.outbound.as_mut().expect("outbound was empty"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> Drop for OutboundSubstreamRefFuture<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.muxer
|
|
||||||
.destroy_outbound(self.outbound.take().expect("outbound was empty"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds an implementation of `Read`/`Write`/`AsyncRead`/`AsyncWrite` from an `Arc` to the
|
|
||||||
/// muxer and a substream.
|
|
||||||
pub fn substream_from_ref<P>(
|
|
||||||
muxer: P,
|
|
||||||
substream: <P::Target as StreamMuxer>::Substream,
|
|
||||||
) -> SubstreamRef<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
SubstreamRef {
|
|
||||||
muxer,
|
|
||||||
substream: Some(substream),
|
|
||||||
shutdown_state: ShutdownState::Shutdown,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stream returned by `substream_from_ref`.
|
|
||||||
pub struct SubstreamRef<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
muxer: P,
|
|
||||||
substream: Option<<P::Target as StreamMuxer>::Substream>,
|
|
||||||
shutdown_state: ShutdownState,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ShutdownState {
|
|
||||||
Shutdown,
|
|
||||||
Flush,
|
|
||||||
Done,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> fmt::Debug for SubstreamRef<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
<P::Target as StreamMuxer>::Substream: fmt::Debug,
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
|
||||||
write!(f, "Substream({:?})", self.substream)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> Unpin for SubstreamRef<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> AsyncRead for SubstreamRef<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
fn poll_read(
|
|
||||||
mut self: Pin<&mut Self>,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
buf: &mut [u8],
|
|
||||||
) -> Poll<Result<usize, io::Error>> {
|
|
||||||
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
|
|
||||||
// multiple different fields from the `Pin` at the same time.
|
|
||||||
let this = &mut *self;
|
|
||||||
|
|
||||||
let s = this.substream.as_mut().expect("substream was empty");
|
|
||||||
this.muxer.read_substream(cx, s, buf).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> AsyncWrite for SubstreamRef<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
fn poll_write(
|
|
||||||
mut self: Pin<&mut Self>,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
buf: &[u8],
|
|
||||||
) -> Poll<Result<usize, io::Error>> {
|
|
||||||
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
|
|
||||||
// multiple different fields from the `Pin` at the same time.
|
|
||||||
let this = &mut *self;
|
|
||||||
|
|
||||||
let s = this.substream.as_mut().expect("substream was empty");
|
|
||||||
this.muxer.write_substream(cx, s, buf).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
|
||||||
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
|
|
||||||
// multiple different fields from the `Pin` at the same time.
|
|
||||||
let this = &mut *self;
|
|
||||||
|
|
||||||
let s = this.substream.as_mut().expect("substream was empty");
|
|
||||||
loop {
|
|
||||||
match this.shutdown_state {
|
|
||||||
ShutdownState::Shutdown => match this.muxer.shutdown_substream(cx, s) {
|
|
||||||
Poll::Ready(Ok(())) => this.shutdown_state = ShutdownState::Flush,
|
|
||||||
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
|
|
||||||
Poll::Pending => return Poll::Pending,
|
|
||||||
},
|
|
||||||
ShutdownState::Flush => match this.muxer.flush_substream(cx, s) {
|
|
||||||
Poll::Ready(Ok(())) => this.shutdown_state = ShutdownState::Done,
|
|
||||||
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
|
|
||||||
Poll::Pending => return Poll::Pending,
|
|
||||||
},
|
|
||||||
ShutdownState::Done => {
|
|
||||||
return Poll::Ready(Ok(()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
|
||||||
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
|
|
||||||
// multiple different fields from the `Pin` at the same time.
|
|
||||||
let this = &mut *self;
|
|
||||||
|
|
||||||
let s = this.substream.as_mut().expect("substream was empty");
|
|
||||||
this.muxer.flush_substream(cx, s).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> Drop for SubstreamRef<P>
|
|
||||||
where
|
|
||||||
P: Deref,
|
|
||||||
P::Target: StreamMuxer,
|
|
||||||
{
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.muxer
|
|
||||||
.destroy_substream(self.substream.take().expect("substream was empty"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,27 +1,35 @@
|
|||||||
use crate::muxing::StreamMuxerEvent;
|
use crate::muxing::StreamMuxerEvent;
|
||||||
use crate::StreamMuxer;
|
use crate::StreamMuxer;
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
|
use futures::{AsyncRead, AsyncWrite};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::io::{IoSlice, IoSliceMut};
|
||||||
|
use std::pin::Pin;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
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 = usize, OutboundSubstream = usize, Error = io::Error>
|
dyn StreamMuxer<Substream = SubstreamBox, OutboundSubstream = usize, Error = io::Error>
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync,
|
+ Sync,
|
||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Abstract type for asynchronous reading and writing.
|
||||||
|
///
|
||||||
|
/// A [`SubstreamBox`] erases the concrete type it is given and only retains its `AsyncRead`
|
||||||
|
/// and `AsyncWrite` capabilities.
|
||||||
|
pub struct SubstreamBox(Box<dyn AsyncReadWrite + Send + Unpin>);
|
||||||
|
|
||||||
struct Wrap<T>
|
struct Wrap<T>
|
||||||
where
|
where
|
||||||
T: StreamMuxer,
|
T: StreamMuxer,
|
||||||
{
|
{
|
||||||
inner: T,
|
inner: T,
|
||||||
substreams: Mutex<FnvHashMap<usize, T::Substream>>,
|
|
||||||
next_substream: AtomicUsize,
|
|
||||||
outbound: Mutex<FnvHashMap<usize, T::OutboundSubstream>>,
|
outbound: Mutex<FnvHashMap<usize, T::OutboundSubstream>>,
|
||||||
next_outbound: AtomicUsize,
|
next_outbound: AtomicUsize,
|
||||||
}
|
}
|
||||||
@ -29,8 +37,9 @@ where
|
|||||||
impl<T> StreamMuxer for Wrap<T>
|
impl<T> StreamMuxer for Wrap<T>
|
||||||
where
|
where
|
||||||
T: StreamMuxer,
|
T: StreamMuxer,
|
||||||
|
T::Substream: Send + Unpin + 'static,
|
||||||
{
|
{
|
||||||
type Substream = usize; // TODO: use a newtype
|
type Substream = SubstreamBox;
|
||||||
type OutboundSubstream = usize; // TODO: use a newtype
|
type OutboundSubstream = usize; // TODO: use a newtype
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
@ -48,9 +57,9 @@ where
|
|||||||
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
|
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let id = self.next_substream.fetch_add(1, Ordering::Relaxed);
|
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(SubstreamBox::new(
|
||||||
self.substreams.lock().insert(id, substream);
|
substream,
|
||||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(id)))
|
))))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -76,9 +85,8 @@ where
|
|||||||
Poll::Ready(Ok(s)) => s,
|
Poll::Ready(Ok(s)) => s,
|
||||||
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
|
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
|
||||||
};
|
};
|
||||||
let id = self.next_substream.fetch_add(1, Ordering::Relaxed);
|
|
||||||
self.substreams.lock().insert(id, substream);
|
Poll::Ready(Ok(SubstreamBox::new(substream)))
|
||||||
Poll::Ready(Ok(id))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -88,63 +96,6 @@ where
|
|||||||
.destroy_outbound(list.remove(&substream).unwrap())
|
.destroy_outbound(list.remove(&substream).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn read_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
buf: &mut [u8],
|
|
||||||
) -> Poll<Result<usize, Self::Error>> {
|
|
||||||
let mut list = self.substreams.lock();
|
|
||||||
self.inner
|
|
||||||
.read_substream(cx, list.get_mut(s).unwrap(), buf)
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
buf: &[u8],
|
|
||||||
) -> Poll<Result<usize, Self::Error>> {
|
|
||||||
let mut list = self.substreams.lock();
|
|
||||||
self.inner
|
|
||||||
.write_substream(cx, list.get_mut(s).unwrap(), buf)
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn flush_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), Self::Error>> {
|
|
||||||
let mut list = self.substreams.lock();
|
|
||||||
self.inner
|
|
||||||
.flush_substream(cx, list.get_mut(s).unwrap())
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn shutdown_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), Self::Error>> {
|
|
||||||
let mut list = self.substreams.lock();
|
|
||||||
self.inner
|
|
||||||
.shutdown_substream(cx, list.get_mut(s).unwrap())
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn destroy_substream(&self, substream: Self::Substream) {
|
|
||||||
let mut list = self.substreams.lock();
|
|
||||||
self.inner
|
|
||||||
.destroy_substream(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(|e| e.into())
|
self.inner.poll_close(cx).map_err(|e| e.into())
|
||||||
@ -157,12 +108,10 @@ impl StreamMuxerBox {
|
|||||||
where
|
where
|
||||||
T: StreamMuxer + Send + Sync + 'static,
|
T: StreamMuxer + Send + Sync + 'static,
|
||||||
T::OutboundSubstream: Send,
|
T::OutboundSubstream: Send,
|
||||||
T::Substream: Send,
|
T::Substream: Send + Unpin + 'static,
|
||||||
{
|
{
|
||||||
let wrap = Wrap {
|
let wrap = Wrap {
|
||||||
inner: muxer,
|
inner: muxer,
|
||||||
substreams: Mutex::new(Default::default()),
|
|
||||||
next_substream: AtomicUsize::new(0),
|
|
||||||
outbound: Mutex::new(Default::default()),
|
outbound: Mutex::new(Default::default()),
|
||||||
next_outbound: AtomicUsize::new(0),
|
next_outbound: AtomicUsize::new(0),
|
||||||
};
|
};
|
||||||
@ -174,7 +123,7 @@ impl StreamMuxerBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StreamMuxer for StreamMuxerBox {
|
impl StreamMuxer for StreamMuxerBox {
|
||||||
type Substream = usize; // TODO: use a newtype
|
type Substream = SubstreamBox;
|
||||||
type OutboundSubstream = usize; // TODO: use a newtype
|
type OutboundSubstream = usize; // TODO: use a newtype
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
@ -205,51 +154,82 @@ impl StreamMuxer for StreamMuxerBox {
|
|||||||
self.inner.destroy_outbound(substream)
|
self.inner.destroy_outbound(substream)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn read_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
buf: &mut [u8],
|
|
||||||
) -> Poll<Result<usize, Self::Error>> {
|
|
||||||
self.inner.read_substream(cx, s, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
buf: &[u8],
|
|
||||||
) -> Poll<Result<usize, Self::Error>> {
|
|
||||||
self.inner.write_substream(cx, s, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn flush_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), Self::Error>> {
|
|
||||||
self.inner.flush_substream(cx, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn shutdown_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), Self::Error>> {
|
|
||||||
self.inner.shutdown_substream(cx, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn destroy_substream(&self, s: Self::Substream) {
|
|
||||||
self.inner.destroy_substream(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SubstreamBox {
|
||||||
|
/// Construct a new [`SubstreamBox`] from something that implements [`AsyncRead`] and [`AsyncWrite`].
|
||||||
|
pub fn new<S: AsyncRead + AsyncWrite + Send + Unpin + 'static>(stream: S) -> Self {
|
||||||
|
Self(Box::new(stream))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for SubstreamBox {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "SubstreamBox({})", self.0.type_name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Workaround because Rust does not allow `Box<dyn AsyncRead + AsyncWrite>`.
|
||||||
|
trait AsyncReadWrite: AsyncRead + AsyncWrite + Unpin {
|
||||||
|
/// Helper function to capture the erased inner type.
|
||||||
|
///
|
||||||
|
/// Used to make the [`Debug`] implementation of [`SubstreamBox`] more useful.
|
||||||
|
fn type_name(&self) -> &'static str;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> AsyncReadWrite for S
|
||||||
|
where
|
||||||
|
S: AsyncRead + AsyncWrite + Unpin,
|
||||||
|
{
|
||||||
|
fn type_name(&self) -> &'static str {
|
||||||
|
std::any::type_name::<S>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncRead for SubstreamBox {
|
||||||
|
fn poll_read(
|
||||||
|
self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
buf: &mut [u8],
|
||||||
|
) -> Poll<std::io::Result<usize>> {
|
||||||
|
Pin::new(&mut self.get_mut().0).poll_read(cx, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_read_vectored(
|
||||||
|
self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
bufs: &mut [IoSliceMut<'_>],
|
||||||
|
) -> Poll<std::io::Result<usize>> {
|
||||||
|
Pin::new(&mut self.get_mut().0).poll_read_vectored(cx, bufs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncWrite for SubstreamBox {
|
||||||
|
fn poll_write(
|
||||||
|
self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
buf: &[u8],
|
||||||
|
) -> Poll<std::io::Result<usize>> {
|
||||||
|
Pin::new(&mut self.get_mut().0).poll_write(cx, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_write_vectored(
|
||||||
|
self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
bufs: &[IoSlice<'_>],
|
||||||
|
) -> Poll<std::io::Result<usize>> {
|
||||||
|
Pin::new(&mut self.get_mut().0).poll_write_vectored(cx, bufs)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
|
||||||
|
Pin::new(&mut self.get_mut().0).poll_flush(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
|
||||||
|
Pin::new(&mut self.get_mut().0).poll_close(cx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -24,14 +24,8 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use parking_lot::Mutex;
|
use std::cell::Cell;
|
||||||
use std::{
|
use std::{io, task::Context, task::Poll};
|
||||||
io,
|
|
||||||
pin::Pin,
|
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
|
||||||
task::Context,
|
|
||||||
task::Poll,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Implementation of `StreamMuxer` that allows only one substream on top of a connection,
|
/// Implementation of `StreamMuxer` that allows only one substream on top of a connection,
|
||||||
/// yielding the connection itself.
|
/// yielding the connection itself.
|
||||||
@ -40,9 +34,7 @@ use std::{
|
|||||||
/// Most notably, no protocol is negotiated.
|
/// Most notably, no protocol is negotiated.
|
||||||
pub struct SingletonMuxer<TSocket> {
|
pub struct SingletonMuxer<TSocket> {
|
||||||
/// The inner connection.
|
/// The inner connection.
|
||||||
inner: Mutex<TSocket>,
|
inner: Cell<Option<TSocket>>,
|
||||||
/// If true, a substream has been produced and any further attempt should fail.
|
|
||||||
substream_extracted: AtomicBool,
|
|
||||||
/// Our local endpoint. Always the same value as was passed to `new`.
|
/// Our local endpoint. Always the same value as was passed to `new`.
|
||||||
endpoint: Endpoint,
|
endpoint: Endpoint,
|
||||||
}
|
}
|
||||||
@ -54,15 +46,12 @@ impl<TSocket> SingletonMuxer<TSocket> {
|
|||||||
/// If `endpoint` is `Listener`, then only one inbound substream will be permitted.
|
/// If `endpoint` is `Listener`, then only one inbound substream will be permitted.
|
||||||
pub fn new(inner: TSocket, endpoint: Endpoint) -> Self {
|
pub fn new(inner: TSocket, endpoint: Endpoint) -> Self {
|
||||||
SingletonMuxer {
|
SingletonMuxer {
|
||||||
inner: Mutex::new(inner),
|
inner: Cell::new(Some(inner)),
|
||||||
substream_extracted: AtomicBool::new(false),
|
|
||||||
endpoint,
|
endpoint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Substream of the `SingletonMuxer`.
|
|
||||||
pub struct Substream {}
|
|
||||||
/// Outbound substream attempt of the `SingletonMuxer`.
|
/// Outbound substream attempt of the `SingletonMuxer`.
|
||||||
pub struct OutboundSubstream {}
|
pub struct OutboundSubstream {}
|
||||||
|
|
||||||
@ -70,7 +59,7 @@ impl<TSocket> StreamMuxer for SingletonMuxer<TSocket>
|
|||||||
where
|
where
|
||||||
TSocket: AsyncRead + AsyncWrite + Unpin,
|
TSocket: AsyncRead + AsyncWrite + Unpin,
|
||||||
{
|
{
|
||||||
type Substream = Substream;
|
type Substream = TSocket;
|
||||||
type OutboundSubstream = OutboundSubstream;
|
type OutboundSubstream = OutboundSubstream;
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
@ -83,8 +72,8 @@ where
|
|||||||
Endpoint::Listener => {}
|
Endpoint::Listener => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.substream_extracted.swap(true, Ordering::Relaxed) {
|
if let Some(stream) = self.inner.replace(None) {
|
||||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(Substream {})))
|
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(stream)))
|
||||||
} else {
|
} else {
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
@ -104,8 +93,8 @@ where
|
|||||||
Endpoint::Dialer => {}
|
Endpoint::Dialer => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.substream_extracted.swap(true, Ordering::Relaxed) {
|
if let Some(stream) = self.inner.replace(None) {
|
||||||
Poll::Ready(Ok(Substream {}))
|
Poll::Ready(Ok(stream))
|
||||||
} else {
|
} else {
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
@ -113,42 +102,6 @@ where
|
|||||||
|
|
||||||
fn destroy_outbound(&self, _: Self::OutboundSubstream) {}
|
fn destroy_outbound(&self, _: Self::OutboundSubstream) {}
|
||||||
|
|
||||||
fn read_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
_: &mut Self::Substream,
|
|
||||||
buf: &mut [u8],
|
|
||||||
) -> Poll<Result<usize, io::Error>> {
|
|
||||||
AsyncRead::poll_read(Pin::new(&mut *self.inner.lock()), cx, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
_: &mut Self::Substream,
|
|
||||||
buf: &[u8],
|
|
||||||
) -> Poll<Result<usize, io::Error>> {
|
|
||||||
AsyncWrite::poll_write(Pin::new(&mut *self.inner.lock()), cx, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
_: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), io::Error>> {
|
|
||||||
AsyncWrite::poll_flush(Pin::new(&mut *self.inner.lock()), cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shutdown_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
_: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), io::Error>> {
|
|
||||||
AsyncWrite::poll_close(Pin::new(&mut *self.inner.lock()), cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destroy_substream(&self, _: Self::Substream) {}
|
|
||||||
|
|
||||||
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(()))
|
||||||
}
|
}
|
||||||
|
@ -300,7 +300,7 @@ impl<T> Multiplexed<T> {
|
|||||||
T::ListenerUpgrade: Send + 'static,
|
T::ListenerUpgrade: Send + 'static,
|
||||||
T::Error: Send + Sync,
|
T::Error: Send + Sync,
|
||||||
M: StreamMuxer + Send + Sync + 'static,
|
M: StreamMuxer + Send + Sync + 'static,
|
||||||
M::Substream: Send + 'static,
|
M::Substream: Send + Unpin + 'static,
|
||||||
M::OutboundSubstream: Send + 'static,
|
M::OutboundSubstream: Send + '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.33.0"}
|
libp2p-core = { path = "../../core", default-features = false, version = "0.34.0"}
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# 0.7.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-dcutr` `v0.4.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-ping` `v0.37.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-identify` `v0.37.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-relay` `v0.10.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-kad` `v0.38.0`.
|
||||||
|
|
||||||
# 0.6.1
|
# 0.6.1
|
||||||
|
|
||||||
- Update `dcutr` events from `libp2p_relay_events` to `libp2p_dcutr_events`, to avoid conflict with `relay` events.
|
- Update `dcutr` events from `libp2p_relay_events` to `libp2p_dcutr_events`, to avoid conflict with `relay` events.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-metrics"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Metrics for libp2p"
|
description = "Metrics for libp2p"
|
||||||
version = "0.6.1"
|
version = "0.7.0"
|
||||||
authors = ["Max Inden <mail@max-inden.de>"]
|
authors = ["Max Inden <mail@max-inden.de>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -19,17 +19,17 @@ relay = ["libp2p-relay"]
|
|||||||
dcutr = ["libp2p-dcutr"]
|
dcutr = ["libp2p-dcutr"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
libp2p-dcutr = { version = "0.3.0", path = "../../protocols/dcutr", optional = true }
|
libp2p-dcutr = { version = "0.4.0", path = "../../protocols/dcutr", optional = true }
|
||||||
libp2p-identify = { version = "0.36.0", path = "../../protocols/identify", optional = true }
|
libp2p-identify = { version = "0.37.0", path = "../../protocols/identify", optional = true }
|
||||||
libp2p-kad = { version = "0.37.0", path = "../../protocols/kad", optional = true }
|
libp2p-kad = { version = "0.38.0", path = "../../protocols/kad", optional = true }
|
||||||
libp2p-ping = { version = "0.36.0", path = "../../protocols/ping", optional = true }
|
libp2p-ping = { version = "0.37.0", path = "../../protocols/ping", optional = true }
|
||||||
libp2p-relay = { version = "0.9.0", path = "../../protocols/relay", optional = true }
|
libp2p-relay = { version = "0.10.0", path = "../../protocols/relay", optional = true }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
prometheus-client = "0.16.0"
|
prometheus-client = "0.16.0"
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "unknown"))'.dependencies]
|
[target.'cfg(not(target_os = "unknown"))'.dependencies]
|
||||||
libp2p-gossipsub = { version = "0.38.0", path = "../../protocols/gossipsub", optional = true }
|
libp2p-gossipsub = { version = "0.39.0", path = "../../protocols/gossipsub", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
log = "0.4.0"
|
log = "0.4.0"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# 0.34.0 [unreleased]
|
# 0.34.0 [unreleased]
|
||||||
|
|
||||||
- `Substream` now implements `AsyncRead` and `AsyncWrite`. See [PR 2706].
|
- `Substream` now implements `AsyncRead` and `AsyncWrite`. See [PR 2706].
|
||||||
|
- Update to `libp2p-core` `v0.34.0`
|
||||||
|
|
||||||
[PR 2706]: https://github.com/libp2p/rust-libp2p/pull/2706/
|
[PR 2706]: https://github.com/libp2p/rust-libp2p/pull/2706/
|
||||||
|
|
||||||
|
@ -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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.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"
|
||||||
|
@ -32,6 +32,7 @@ use libp2p_core::{
|
|||||||
};
|
};
|
||||||
use libp2p_mplex as mplex;
|
use libp2p_mplex as mplex;
|
||||||
use libp2p_plaintext::PlainText2Config;
|
use libp2p_plaintext::PlainText2Config;
|
||||||
|
use std::pin::Pin;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
type BenchTransport = transport::Boxed<(PeerId, muxing::StreamMuxerBox)>;
|
type BenchTransport = transport::Boxed<(PeerId, muxing::StreamMuxerBox)>;
|
||||||
@ -115,7 +116,7 @@ fn run(transport: &mut BenchTransport, payload: &Vec<u8>, listen_addr: &Multiadd
|
|||||||
loop {
|
loop {
|
||||||
// Read in typical chunk sizes of up to 8KiB.
|
// Read in typical chunk sizes of up to 8KiB.
|
||||||
let end = off + std::cmp::min(buf.len() - off, 8 * 1024);
|
let end = off + std::cmp::min(buf.len() - off, 8 * 1024);
|
||||||
let n = poll_fn(|cx| conn.read_substream(cx, &mut s, &mut buf[off..end]))
|
let n = poll_fn(|cx| Pin::new(&mut s).poll_read(cx, &mut buf[off..end]))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
off += n;
|
off += n;
|
||||||
@ -139,12 +140,12 @@ fn run(transport: &mut BenchTransport, payload: &Vec<u8>, listen_addr: &Multiadd
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let mut off = 0;
|
let mut off = 0;
|
||||||
loop {
|
loop {
|
||||||
let n = poll_fn(|cx| conn.write_substream(cx, &mut stream, &payload[off..]))
|
let n = poll_fn(|cx| Pin::new(&mut stream).poll_write(cx, &payload[off..]))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
off += n;
|
off += n;
|
||||||
if off == payload.len() {
|
if off == payload.len() {
|
||||||
poll_fn(|cx| conn.flush_substream(cx, &mut stream))
|
poll_fn(|cx| Pin::new(&mut stream).poll_flush(cx))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
return;
|
return;
|
||||||
|
@ -116,44 +116,6 @@ where
|
|||||||
// Nothing to do, since `open_outbound` creates no new local state.
|
// Nothing to do, since `open_outbound` creates no new local state.
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
substream: &mut Self::Substream,
|
|
||||||
buf: &mut [u8],
|
|
||||||
) -> Poll<Result<usize, io::Error>> {
|
|
||||||
Pin::new(substream).poll_read(cx, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
substream: &mut Self::Substream,
|
|
||||||
buf: &[u8],
|
|
||||||
) -> Poll<Result<usize, io::Error>> {
|
|
||||||
Pin::new(substream).poll_write(cx, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
substream: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), io::Error>> {
|
|
||||||
Pin::new(substream).poll_flush(cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shutdown_substream(
|
|
||||||
&self,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
substream: &mut Self::Substream,
|
|
||||||
) -> Poll<Result<(), io::Error>> {
|
|
||||||
Pin::new(substream).poll_close(cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destroy_substream(&self, sub: Self::Substream) {
|
|
||||||
std::mem::drop(sub)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
||||||
self.io.lock().poll_close(cx)
|
self.io.lock().poll_close(cx)
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,9 @@
|
|||||||
// 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 futures::future::poll_fn;
|
||||||
use futures::{channel::oneshot, prelude::*};
|
use futures::{channel::oneshot, prelude::*};
|
||||||
use libp2p_core::{muxing, upgrade, Transport};
|
use libp2p_core::{upgrade, StreamMuxer, Transport};
|
||||||
use libp2p_tcp::TcpConfig;
|
use libp2p_tcp::TcpConfig;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -60,7 +61,8 @@ fn async_write() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut outbound = muxing::outbound_from_ref_and_wrap(Arc::new(client))
|
let mut outbound_token = client.open_outbound();
|
||||||
|
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -76,7 +78,7 @@ fn async_write() {
|
|||||||
|
|
||||||
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 = loop {
|
||||||
if let Some(s) = muxing::event_from_ref_and_wrap(client.clone())
|
if let Some(s) = poll_fn(|cx| client.poll_event(cx))
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_inbound_substream()
|
.into_inbound_substream()
|
||||||
|
@ -18,8 +18,9 @@
|
|||||||
// 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 futures::future::poll_fn;
|
||||||
use futures::{channel::oneshot, prelude::*};
|
use futures::{channel::oneshot, prelude::*};
|
||||||
use libp2p_core::{muxing, upgrade, Transport};
|
use libp2p_core::{upgrade, StreamMuxer, Transport};
|
||||||
use libp2p_tcp::TcpConfig;
|
use libp2p_tcp::TcpConfig;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -60,7 +61,8 @@ fn client_to_server_outbound() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut outbound = muxing::outbound_from_ref_and_wrap(Arc::new(client))
|
let mut outbound_token = client.open_outbound();
|
||||||
|
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -76,7 +78,7 @@ fn client_to_server_outbound() {
|
|||||||
|
|
||||||
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 = loop {
|
||||||
if let Some(s) = muxing::event_from_ref_and_wrap(client.clone())
|
if let Some(s) = poll_fn(|cx| client.poll_event(cx))
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_inbound_substream()
|
.into_inbound_substream()
|
||||||
@ -131,7 +133,7 @@ fn client_to_server_inbound() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut inbound = loop {
|
let mut inbound = loop {
|
||||||
if let Some(s) = muxing::event_from_ref_and_wrap(client.clone())
|
if let Some(s) = poll_fn(|cx| client.poll_event(cx))
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_inbound_substream()
|
.into_inbound_substream()
|
||||||
@ -151,7 +153,9 @@ fn client_to_server_inbound() {
|
|||||||
.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 = transport.dial(rx.await.unwrap()).unwrap().await.unwrap();
|
let client = transport.dial(rx.await.unwrap()).unwrap().await.unwrap();
|
||||||
let mut outbound = muxing::outbound_from_ref_and_wrap(Arc::new(client))
|
|
||||||
|
let mut outbound_token = client.open_outbound();
|
||||||
|
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
outbound.write_all(b"hello world").await.unwrap();
|
outbound.write_all(b"hello world").await.unwrap();
|
||||||
@ -196,7 +200,8 @@ fn protocol_not_match() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut outbound = muxing::outbound_from_ref_and_wrap(Arc::new(client))
|
let mut outbound_token = client.open_outbound();
|
||||||
|
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.38.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
# 0.37.0
|
# 0.37.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.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.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"
|
||||||
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.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"
|
||||||
|
@ -137,46 +137,6 @@ where
|
|||||||
self.0.lock().control.abort_open_stream()
|
self.0.lock().control.abort_open_stream()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_substream(
|
|
||||||
&self,
|
|
||||||
c: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
b: &mut [u8],
|
|
||||||
) -> Poll<YamuxResult<usize>> {
|
|
||||||
Pin::new(s)
|
|
||||||
.poll_read(c, b)
|
|
||||||
.map_err(|e| YamuxError(e.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_substream(
|
|
||||||
&self,
|
|
||||||
c: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
b: &[u8],
|
|
||||||
) -> Poll<YamuxResult<usize>> {
|
|
||||||
Pin::new(s)
|
|
||||||
.poll_write(c, b)
|
|
||||||
.map_err(|e| YamuxError(e.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush_substream(
|
|
||||||
&self,
|
|
||||||
c: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
) -> Poll<YamuxResult<()>> {
|
|
||||||
Pin::new(s).poll_flush(c).map_err(|e| YamuxError(e.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shutdown_substream(
|
|
||||||
&self,
|
|
||||||
c: &mut Context<'_>,
|
|
||||||
s: &mut Self::Substream,
|
|
||||||
) -> Poll<YamuxResult<()>> {
|
|
||||||
Pin::new(s).poll_close(c).map_err(|e| YamuxError(e.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destroy_substream(&self, _: Self::Substream) {}
|
|
||||||
|
|
||||||
fn poll_close(&self, c: &mut Context<'_>) -> Poll<YamuxResult<()>> {
|
fn poll_close(&self, c: &mut Context<'_>) -> Poll<YamuxResult<()>> {
|
||||||
let mut inner = self.0.lock();
|
let mut inner = self.0.lock();
|
||||||
|
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
# 0.5.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-request-response` `v0.19.0`.
|
||||||
|
|
||||||
# 0.4.1
|
# 0.4.1
|
||||||
|
|
||||||
- Export `DEFAULT_PROTOCOL_NAME`.
|
- Export `DEFAULT_PROTOCOL_NAME`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-autonat"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "NAT and firewall detection for libp2p"
|
description = "NAT and firewall detection for libp2p"
|
||||||
version = "0.4.1"
|
version = "0.5.0"
|
||||||
authors = ["David Craven <david@craven.ch>", "Elena Frank <elena.frank@protonmail.com>"]
|
authors = ["David Craven <david@craven.ch>", "Elena Frank <elena.frank@protonmail.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -18,9 +18,9 @@ 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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
libp2p-request-response = { version = "0.18.0", path = "../request-response" }
|
libp2p-request-response = { version = "0.19.0", path = "../request-response" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
prost = "0.10"
|
prost = "0.10"
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
# 0.4.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
# 0.3.1
|
# 0.3.1
|
||||||
|
|
||||||
- Upgrade at most one inbound connect request.
|
- Upgrade at most one inbound connect request.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-dcutr"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Direct connection upgrade through relay"
|
description = "Direct connection upgrade through relay"
|
||||||
version = "0.3.1"
|
version = "0.4.0"
|
||||||
authors = ["Max Inden <mail@max-inden.de>"]
|
authors = ["Max Inden <mail@max-inden.de>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -17,8 +17,8 @@ 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.33.0", path = "../../core" }
|
libp2p-core = { version = "0.34.0", path = "../../core" }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.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" }
|
||||||
prost = "0.10"
|
prost = "0.10"
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
# 0.37.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
# 0.36.0
|
# 0.36.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-floodsub"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Floodsub protocol for libp2p"
|
description = "Floodsub protocol 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,8 +14,8 @@ 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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
prost = "0.10"
|
prost = "0.10"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
# 0.39.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
# 0.38.1
|
# 0.38.1
|
||||||
|
|
||||||
- Fix duplicate connection id. See [PR 2702].
|
- Fix duplicate connection id. See [PR 2702].
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-gossipsub"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Gossipsub protocol for libp2p"
|
description = "Gossipsub protocol for libp2p"
|
||||||
version = "0.38.1"
|
version = "0.39.0"
|
||||||
authors = ["Age Manning <Age@AgeManning.com>"]
|
authors = ["Age Manning <Age@AgeManning.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -11,8 +11,8 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
|
|||||||
categories = ["network-programming", "asynchronous"]
|
categories = ["network-programming", "asynchronous"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.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"
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
# 0.37.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
# 0.36.1
|
# 0.36.1
|
||||||
|
|
||||||
- Allow at most one inbound identify push stream.
|
- Allow at most one inbound identify push stream.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-identify"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Nodes identifcation protocol for libp2p"
|
description = "Nodes identifcation protocol for libp2p"
|
||||||
version = "0.36.1"
|
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,8 +14,8 @@ 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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
log = "0.4.1"
|
log = "0.4.1"
|
||||||
lru = "0.7.2"
|
lru = "0.7.2"
|
||||||
prost-codec = { version = "0.1", path = "../../misc/prost-codec" }
|
prost-codec = { version = "0.1", path = "../../misc/prost-codec" }
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
# 0.38.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
# 0.37.1
|
# 0.37.1
|
||||||
|
|
||||||
- Limit # of inbound streams to 32. [See PR 2699].
|
- Limit # of inbound streams to 32. [See PR 2699].
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-kad"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Kademlia protocol for libp2p"
|
description = "Kademlia protocol for libp2p"
|
||||||
version = "0.37.1"
|
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"
|
||||||
@ -18,8 +18,8 @@ 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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
prost = "0.10"
|
prost = "0.10"
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
sha2 = "0.10.0"
|
sha2 = "0.10.0"
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
# 0.38.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
# 0.37.0
|
# 0.37.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.0`.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
name = "libp2p-mdns"
|
name = "libp2p-mdns"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
version = "0.37.0"
|
version = "0.38.0"
|
||||||
description = "Implementation of the libp2p mDNS discovery method"
|
description = "Implementation of the libp2p mDNS discovery method"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@ -17,8 +17,8 @@ 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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
rand = "0.8.3"
|
rand = "0.8.3"
|
||||||
smallvec = "1.6.1"
|
smallvec = "1.6.1"
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
# 0.37.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
# 0.36.0
|
# 0.36.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-ping"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Ping protocol for libp2p"
|
description = "Ping protocol 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,8 +14,8 @@ 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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
log = "0.4.1"
|
log = "0.4.1"
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
void = "1.0"
|
void = "1.0"
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
# 0.10.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
# 0.9.1
|
# 0.9.1
|
||||||
|
|
||||||
- Respond to at most one incoming reservation request. Deny <= 8 incoming
|
- Respond to at most one incoming reservation request. Deny <= 8 incoming
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-relay"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Communications relaying for libp2p"
|
description = "Communications relaying for libp2p"
|
||||||
version = "0.9.1"
|
version = "0.10.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>", "Max Inden <mail@max-inden.de>"]
|
authors = ["Parity Technologies <admin@parity.io>", "Max Inden <mail@max-inden.de>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -17,8 +17,8 @@ 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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
pin-project = "1"
|
pin-project = "1"
|
||||||
prost-codec = { version = "0.1", path = "../../misc/prost-codec" }
|
prost-codec = { version = "0.1", path = "../../misc/prost-codec" }
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
# 0.7.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
# 0.6.0
|
# 0.6.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-rendezvous"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Rendezvous protocol for libp2p"
|
description = "Rendezvous protocol for libp2p"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
authors = ["The COMIT guys <hello@comit.network>"]
|
authors = ["The COMIT guys <hello@comit.network>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
@ -12,8 +12,8 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
asynchronous-codec = "0.6"
|
asynchronous-codec = "0.6"
|
||||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
prost = "0.10"
|
prost = "0.10"
|
||||||
void = "1"
|
void = "1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
# 0.19.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
|
- Update to `libp2p-swarm` `v0.37.0`.
|
||||||
|
|
||||||
# 0.18.0
|
# 0.18.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-request-response"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "Generic Request/Response Protocols"
|
description = "Generic Request/Response Protocols"
|
||||||
version = "0.18.0"
|
version = "0.19.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"
|
||||||
@ -15,8 +15,8 @@ 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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||||
log = "0.4.11"
|
log = "0.4.11"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
smallvec = "1.6.1"
|
smallvec = "1.6.1"
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.37.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
# 0.36.2 [unreleased]
|
# 0.36.2 [unreleased]
|
||||||
|
|
||||||
- Extend log message when exceeding inbound negotiating streams with peer ID and limit. See [PR 2716].
|
- Extend log message when exceeding inbound negotiating streams with peer ID and limit. See [PR 2716].
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-swarm"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "The libp2p swarm"
|
description = "The libp2p swarm"
|
||||||
version = "0.36.2"
|
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"
|
||||||
@ -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.33.0", path = "../core", default-features = false }
|
libp2p-core = { version = "0.34.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"
|
||||||
|
@ -32,7 +32,7 @@ pub use error::{
|
|||||||
pub use listeners::{ListenersEvent, ListenersStream};
|
pub use listeners::{ListenersEvent, ListenersStream};
|
||||||
pub use pool::{ConnectionCounters, ConnectionLimits};
|
pub use pool::{ConnectionCounters, ConnectionLimits};
|
||||||
pub use pool::{EstablishedConnection, PendingConnection};
|
pub use pool::{EstablishedConnection, PendingConnection};
|
||||||
pub use substream::{Close, Substream, SubstreamEndpoint};
|
pub use substream::{Close, SubstreamEndpoint};
|
||||||
|
|
||||||
use crate::handler::ConnectionHandler;
|
use crate::handler::ConnectionHandler;
|
||||||
use crate::IntoConnectionHandler;
|
use crate::IntoConnectionHandler;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
// 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::connection::{Substream, SubstreamEndpoint};
|
use crate::connection::SubstreamEndpoint;
|
||||||
use crate::handler::{
|
use crate::handler::{
|
||||||
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive,
|
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive,
|
||||||
};
|
};
|
||||||
@ -30,7 +30,7 @@ use futures::stream::FuturesUnordered;
|
|||||||
use futures_timer::Delay;
|
use futures_timer::Delay;
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
use libp2p_core::{
|
use libp2p_core::{
|
||||||
muxing::StreamMuxerBox,
|
muxing::SubstreamBox,
|
||||||
upgrade::{self, InboundUpgradeApply, OutboundUpgradeApply, UpgradeError},
|
upgrade::{self, InboundUpgradeApply, OutboundUpgradeApply, UpgradeError},
|
||||||
Multiaddr,
|
Multiaddr,
|
||||||
};
|
};
|
||||||
@ -55,20 +55,14 @@ where
|
|||||||
negotiating_in: FuturesUnordered<
|
negotiating_in: FuturesUnordered<
|
||||||
SubstreamUpgrade<
|
SubstreamUpgrade<
|
||||||
TConnectionHandler::InboundOpenInfo,
|
TConnectionHandler::InboundOpenInfo,
|
||||||
InboundUpgradeApply<
|
InboundUpgradeApply<SubstreamBox, SendWrapper<TConnectionHandler::InboundProtocol>>,
|
||||||
Substream<StreamMuxerBox>,
|
|
||||||
SendWrapper<TConnectionHandler::InboundProtocol>,
|
|
||||||
>,
|
|
||||||
>,
|
>,
|
||||||
>,
|
>,
|
||||||
/// Futures that upgrade outgoing substreams.
|
/// Futures that upgrade outgoing substreams.
|
||||||
negotiating_out: FuturesUnordered<
|
negotiating_out: FuturesUnordered<
|
||||||
SubstreamUpgrade<
|
SubstreamUpgrade<
|
||||||
TConnectionHandler::OutboundOpenInfo,
|
TConnectionHandler::OutboundOpenInfo,
|
||||||
OutboundUpgradeApply<
|
OutboundUpgradeApply<SubstreamBox, SendWrapper<TConnectionHandler::OutboundProtocol>>,
|
||||||
Substream<StreamMuxerBox>,
|
|
||||||
SendWrapper<TConnectionHandler::OutboundProtocol>,
|
|
||||||
>,
|
|
||||||
>,
|
>,
|
||||||
>,
|
>,
|
||||||
/// For each outbound substream request, how to upgrade it. The first element of the tuple
|
/// For each outbound substream request, how to upgrade it. The first element of the tuple
|
||||||
@ -87,8 +81,8 @@ where
|
|||||||
/// Note: This only enforces a limit on the number of concurrently
|
/// Note: This only enforces a limit on the number of concurrently
|
||||||
/// negotiating inbound streams. The total number of inbound streams on a
|
/// negotiating inbound streams. The total number of inbound streams on a
|
||||||
/// connection is the sum of negotiating and negotiated streams. A limit on
|
/// connection is the sum of negotiating and negotiated streams. A limit on
|
||||||
/// the total number of streams can be enforced at the [`StreamMuxerBox`]
|
/// the total number of streams can be enforced at the
|
||||||
/// level.
|
/// [`StreamMuxerBox`](libp2p_core::muxing::StreamMuxerBox) level.
|
||||||
max_negotiating_inbound_streams: usize,
|
max_negotiating_inbound_streams: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +248,7 @@ where
|
|||||||
{
|
{
|
||||||
pub fn inject_substream(
|
pub fn inject_substream(
|
||||||
&mut self,
|
&mut self,
|
||||||
substream: Substream<StreamMuxerBox>,
|
substream: SubstreamBox,
|
||||||
// The first element of the tuple is the unique upgrade identifier
|
// The first element of the tuple is the unique upgrade identifier
|
||||||
// (see `unique_dial_upgrade_id`).
|
// (see `unique_dial_upgrade_id`).
|
||||||
endpoint: SubstreamEndpoint<OutboundOpenInfo<TConnectionHandler>>,
|
endpoint: SubstreamEndpoint<OutboundOpenInfo<TConnectionHandler>>,
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use libp2p_core::multiaddr::Multiaddr;
|
use libp2p_core::multiaddr::Multiaddr;
|
||||||
use libp2p_core::muxing::{substream_from_ref, StreamMuxer, StreamMuxerEvent, SubstreamRef};
|
use libp2p_core::muxing::{StreamMuxer, StreamMuxerEvent};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{fmt, io::Error as IoError, pin::Pin, task::Context, task::Poll};
|
use std::{fmt, io::Error as IoError, pin::Pin, task::Context, task::Poll};
|
||||||
@ -55,9 +55,6 @@ pub struct Close<TMuxer> {
|
|||||||
muxer: Arc<TMuxer>,
|
muxer: Arc<TMuxer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A successfully opened substream.
|
|
||||||
pub type Substream<TMuxer> = SubstreamRef<Arc<TMuxer>>;
|
|
||||||
|
|
||||||
/// Event that can happen on the `Muxing`.
|
/// Event that can happen on the `Muxing`.
|
||||||
pub enum SubstreamEvent<TMuxer, TUserData>
|
pub enum SubstreamEvent<TMuxer, TUserData>
|
||||||
where
|
where
|
||||||
@ -67,7 +64,7 @@ where
|
|||||||
InboundSubstream {
|
InboundSubstream {
|
||||||
/// The newly-opened substream. Will return EOF of an error if the `Muxing` is
|
/// The newly-opened substream. Will return EOF of an error if the `Muxing` is
|
||||||
/// destroyed or `close_graceful` is called.
|
/// destroyed or `close_graceful` is called.
|
||||||
substream: Substream<TMuxer>,
|
substream: TMuxer::Substream,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// An outbound substream has successfully been opened.
|
/// An outbound substream has successfully been opened.
|
||||||
@ -76,7 +73,7 @@ where
|
|||||||
user_data: TUserData,
|
user_data: TUserData,
|
||||||
/// The newly-opened substream. Will return EOF of an error if the `Muxing` is
|
/// The newly-opened substream. Will return EOF of an error if the `Muxing` is
|
||||||
/// destroyed or `close_graceful` is called.
|
/// destroyed or `close_graceful` is called.
|
||||||
substream: Substream<TMuxer>,
|
substream: TMuxer::Substream,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Address to the remote has changed. The previous one is now obsolete.
|
/// Address to the remote has changed. The previous one is now obsolete.
|
||||||
@ -141,7 +138,6 @@ where
|
|||||||
// Polling inbound substream.
|
// Polling inbound substream.
|
||||||
match self.inner.poll_event(cx) {
|
match self.inner.poll_event(cx) {
|
||||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(substream))) => {
|
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(substream))) => {
|
||||||
let substream = substream_from_ref(self.inner.clone(), substream);
|
|
||||||
return Poll::Ready(Ok(SubstreamEvent::InboundSubstream { substream }));
|
return Poll::Ready(Ok(SubstreamEvent::InboundSubstream { substream }));
|
||||||
}
|
}
|
||||||
Poll::Ready(Ok(StreamMuxerEvent::AddressChange(addr))) => {
|
Poll::Ready(Ok(StreamMuxerEvent::AddressChange(addr))) => {
|
||||||
@ -157,7 +153,6 @@ where
|
|||||||
let (user_data, mut outbound) = self.outbound_substreams.swap_remove(n);
|
let (user_data, mut outbound) = self.outbound_substreams.swap_remove(n);
|
||||||
match self.inner.poll_outbound(cx, &mut outbound) {
|
match self.inner.poll_outbound(cx, &mut outbound) {
|
||||||
Poll::Ready(Ok(substream)) => {
|
Poll::Ready(Ok(substream)) => {
|
||||||
let substream = substream_from_ref(self.inner.clone(), substream);
|
|
||||||
self.inner.destroy_outbound(outbound);
|
self.inner.destroy_outbound(outbound);
|
||||||
return Poll::Ready(Ok(SubstreamEvent::OutboundSubstream {
|
return Poll::Ready(Ok(SubstreamEvent::OutboundSubstream {
|
||||||
user_data,
|
user_data,
|
||||||
|
@ -79,11 +79,12 @@ pub use handler::{
|
|||||||
pub use registry::{AddAddressResult, AddressRecord, AddressScore};
|
pub use registry::{AddAddressResult, AddressRecord, AddressScore};
|
||||||
|
|
||||||
use connection::pool::{Pool, PoolConfig, PoolEvent};
|
use connection::pool::{Pool, PoolConfig, PoolEvent};
|
||||||
use connection::{EstablishedConnection, IncomingInfo, ListenersEvent, ListenersStream, Substream};
|
use connection::{EstablishedConnection, IncomingInfo, ListenersEvent, ListenersStream};
|
||||||
use dial_opts::{DialOpts, PeerCondition};
|
use dial_opts::{DialOpts, PeerCondition};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use futures::{executor::ThreadPoolBuilder, prelude::*, stream::FusedStream};
|
use futures::{executor::ThreadPoolBuilder, prelude::*, stream::FusedStream};
|
||||||
use libp2p_core::connection::{ConnectionId, PendingPoint};
|
use libp2p_core::connection::{ConnectionId, PendingPoint};
|
||||||
|
use libp2p_core::muxing::SubstreamBox;
|
||||||
use libp2p_core::{
|
use libp2p_core::{
|
||||||
connection::{ConnectedPoint, ListenerId},
|
connection::{ConnectedPoint, ListenerId},
|
||||||
multiaddr::Protocol,
|
multiaddr::Protocol,
|
||||||
@ -110,7 +111,7 @@ use upgrade::UpgradeInfoSend as _;
|
|||||||
///
|
///
|
||||||
/// Implements the [`AsyncRead`](futures::io::AsyncRead) and
|
/// Implements the [`AsyncRead`](futures::io::AsyncRead) and
|
||||||
/// [`AsyncWrite`](futures::io::AsyncWrite) traits.
|
/// [`AsyncWrite`](futures::io::AsyncWrite) traits.
|
||||||
pub type NegotiatedSubstream = Negotiated<Substream<StreamMuxerBox>>;
|
pub type NegotiatedSubstream = Negotiated<SubstreamBox>;
|
||||||
|
|
||||||
/// Event generated by the [`NetworkBehaviour`] that the swarm will report back.
|
/// Event generated by the [`NetworkBehaviour`] that the swarm will report back.
|
||||||
type TBehaviourOutEvent<TBehaviour> = <TBehaviour as NetworkBehaviour>::OutEvent;
|
type TBehaviourOutEvent<TBehaviour> = <TBehaviour as NetworkBehaviour>::OutEvent;
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.34.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
# 0.33.0
|
# 0.33.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.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.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"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.34.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
# 0.33.0
|
# 0.33.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.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.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"
|
||||||
@ -11,7 +11,7 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
|
|||||||
categories = ["network-programming", "asynchronous"]
|
categories = ["network-programming", "asynchronous"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.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.37.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
# 0.36.0
|
# 0.36.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.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.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"
|
||||||
@ -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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.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.34.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
# 0.33.0
|
# 0.33.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.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.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"
|
||||||
@ -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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.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"] }
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.34.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
# 0.33.0
|
# 0.33.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.0`.
|
||||||
|
@ -3,7 +3,7 @@ name = "libp2p-tcp"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56.1"
|
rust-version = "1.56.1"
|
||||||
description = "TCP/IP transport protocol for libp2p"
|
description = "TCP/IP transport protocol 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"
|
||||||
@ -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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.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.0.1", default-features = false, features = ["net"], optional = true }
|
tokio-crate = { package = "tokio", version = "1.0.1", default-features = false, features = ["net"], optional = true }
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# 0.33.0 - [unreleased]
|
# 0.33.0 [unreleased]
|
||||||
|
|
||||||
- Update dependencies.
|
- Update dependencies.
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
# 0.32.0 [2022-01-27]
|
# 0.32.0 [2022-01-27]
|
||||||
|
|
||||||
|
@ -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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.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.34.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
# 0.33.0
|
# 0.33.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.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.33.0"
|
version = "0.34.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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.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.36.0 [unreleased]
|
||||||
|
|
||||||
|
- Update to `libp2p-core` `v0.34.0`.
|
||||||
|
|
||||||
# 0.35.0
|
# 0.35.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.33.0`.
|
- Update to `libp2p-core` `v0.33.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.35.0"
|
version = "0.36.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.33.0", path = "../../core", default-features = false }
|
libp2p-core = { version = "0.34.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