mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-21 13:51:33 +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
|
||||
|
||||
# 0.46.0 [unreleased]
|
||||
|
||||
- Semver bump Rust from `1.56.1` to `1.60.0` . See [PR 2646].
|
||||
- Added weak dependencies for features. See [PR 2646].
|
||||
- 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-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).
|
||||
|
||||
[PR 2646]: https://github.com/libp2p/rust-libp2p/pull/2646
|
||||
|
46
Cargo.toml
46
Cargo.toml
@ -3,7 +3,7 @@ name = "libp2p"
|
||||
edition = "2021"
|
||||
rust-version = "1.60.0"
|
||||
description = "Peer-to-peer networking library"
|
||||
version = "0.46.0"
|
||||
version = "0.47.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
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
|
||||
lazy_static = "1.2"
|
||||
|
||||
libp2p-autonat = { version = "0.4.0", path = "protocols/autonat", optional = true }
|
||||
libp2p-core = { version = "0.33.0", path = "core", default-features = false }
|
||||
libp2p-dcutr = { version = "0.3.1", path = "protocols/dcutr", optional = true }
|
||||
libp2p-floodsub = { version = "0.36.0", path = "protocols/floodsub", optional = true }
|
||||
libp2p-identify = { version = "0.36.1", path = "protocols/identify", optional = true }
|
||||
libp2p-kad = { version = "0.37.1", path = "protocols/kad", optional = true }
|
||||
libp2p-metrics = { version = "0.6.0", path = "misc/metrics", optional = true }
|
||||
libp2p-autonat = { version = "0.5.0", path = "protocols/autonat", optional = true }
|
||||
libp2p-core = { version = "0.34.0", path = "core", default-features = false }
|
||||
libp2p-dcutr = { version = "0.4.0", path = "protocols/dcutr", optional = true }
|
||||
libp2p-floodsub = { version = "0.37.0", path = "protocols/floodsub", optional = true }
|
||||
libp2p-identify = { version = "0.37.0", path = "protocols/identify", optional = true }
|
||||
libp2p-kad = { version = "0.38.0", path = "protocols/kad", 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-noise = { version = "0.36.0", path = "transports/noise", optional = true }
|
||||
libp2p-ping = { version = "0.36.0", path = "protocols/ping", optional = true }
|
||||
libp2p-plaintext = { version = "0.33.0", path = "transports/plaintext", optional = true }
|
||||
libp2p-noise = { version = "0.37.0", path = "transports/noise", optional = true }
|
||||
libp2p-ping = { version = "0.37.0", path = "protocols/ping", 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-relay = { version = "0.9.1", path = "protocols/relay", optional = true }
|
||||
libp2p-rendezvous = { version = "0.6.0", path = "protocols/rendezvous", optional = true }
|
||||
libp2p-request-response = { version = "0.18.0", path = "protocols/request-response", optional = true }
|
||||
libp2p-swarm = { version = "0.36.1", path = "swarm" }
|
||||
libp2p-relay = { version = "0.10.0", path = "protocols/relay", optional = true }
|
||||
libp2p-rendezvous = { version = "0.7.0", path = "protocols/rendezvous", optional = true }
|
||||
libp2p-request-response = { version = "0.19.0", path = "protocols/request-response", optional = true }
|
||||
libp2p-swarm = { version = "0.37.0", path = "swarm" }
|
||||
libp2p-swarm-derive = { version = "0.27.0", path = "swarm-derive" }
|
||||
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-yamux = { version = "0.37.0", path = "muxers/yamux", optional = true }
|
||||
libp2p-wasm-ext = { version = "0.34.0", path = "transports/wasm-ext", default-features = false, optional = true }
|
||||
libp2p-yamux = { version = "0.38.0", path = "muxers/yamux", optional = true }
|
||||
multiaddr = { version = "0.14.0" }
|
||||
parking_lot = "0.12.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"
|
||||
|
||||
[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-dns = { version = "0.33.0", path = "transports/dns", optional = true, default-features = false }
|
||||
libp2p-mdns = { version = "0.37.0", path = "protocols/mdns", optional = true }
|
||||
libp2p-tcp = { version = "0.33.0", path = "transports/tcp", default-features = false, optional = true }
|
||||
libp2p-websocket = { version = "0.35.0", path = "transports/websocket", optional = true }
|
||||
libp2p-deflate = { version = "0.34.0", path = "transports/deflate", optional = true }
|
||||
libp2p-dns = { version = "0.34.0", path = "transports/dns", optional = true, default-features = false }
|
||||
libp2p-mdns = { version = "0.38.0", path = "protocols/mdns", optional = true }
|
||||
libp2p-tcp = { version = "0.34.0", path = "transports/tcp", default-features = false, optional = true }
|
||||
libp2p-websocket = { version = "0.36.0", path = "transports/websocket", optional = true }
|
||||
|
||||
[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]
|
||||
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].
|
||||
- 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 2707]: https://github.com/libp2p/rust-libp2p/pull/2707
|
||||
|
||||
# 0.33.0
|
||||
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-core"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Core traits and structs of libp2p"
|
||||
version = "0.33.1"
|
||||
version = "0.34.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
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>> {
|
||||
match self {
|
||||
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.
|
||||
//!
|
||||
//! 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
|
||||
//! on open substreams.
|
||||
//! has ownership of a connection, lets you open and close substreams.
|
||||
//!
|
||||
//! > **Note**: You normally don't need to use the methods of the `StreamMuxer` directly, as this
|
||||
//! > 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
|
||||
//! 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 std::{fmt, io, ops::Deref, pin::Pin};
|
||||
use std::io;
|
||||
|
||||
pub use self::boxed::StreamMuxerBox;
|
||||
pub use self::boxed::SubstreamBox;
|
||||
pub use self::singleton::SingletonMuxer;
|
||||
|
||||
mod boxed;
|
||||
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 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.
|
||||
/// A substream created by a [`StreamMuxer`] is a type that implements [`AsyncRead`] and [`AsyncWrite`].
|
||||
///
|
||||
/// 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 {
|
||||
/// 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.
|
||||
type OutboundSubstream;
|
||||
@ -126,86 +121,12 @@ pub trait StreamMuxer {
|
||||
/// or if you want to interrupt it.
|
||||
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`.
|
||||
///
|
||||
/// 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,
|
||||
/// 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
|
||||
/// > that the remote is properly informed of the shutdown. However, apart from
|
||||
/// > 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::StreamMuxer;
|
||||
use fnv::FnvHashMap;
|
||||
use futures::{AsyncRead, AsyncWrite};
|
||||
use parking_lot::Mutex;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::io::{IoSlice, IoSliceMut};
|
||||
use std::pin::Pin;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// Abstract `StreamMuxer`.
|
||||
pub struct StreamMuxerBox {
|
||||
inner: Box<
|
||||
dyn StreamMuxer<Substream = usize, OutboundSubstream = usize, Error = io::Error>
|
||||
dyn StreamMuxer<Substream = SubstreamBox, OutboundSubstream = usize, Error = io::Error>
|
||||
+ Send
|
||||
+ 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>
|
||||
where
|
||||
T: StreamMuxer,
|
||||
{
|
||||
inner: T,
|
||||
substreams: Mutex<FnvHashMap<usize, T::Substream>>,
|
||||
next_substream: AtomicUsize,
|
||||
outbound: Mutex<FnvHashMap<usize, T::OutboundSubstream>>,
|
||||
next_outbound: AtomicUsize,
|
||||
}
|
||||
@ -29,8 +37,9 @@ where
|
||||
impl<T> StreamMuxer for Wrap<T>
|
||||
where
|
||||
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 Error = io::Error;
|
||||
|
||||
@ -48,9 +57,9 @@ where
|
||||
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(StreamMuxerEvent::InboundSubstream(id)))
|
||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(SubstreamBox::new(
|
||||
substream,
|
||||
))))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -76,9 +85,8 @@ where
|
||||
Poll::Ready(Ok(s)) => s,
|
||||
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(id))
|
||||
|
||||
Poll::Ready(Ok(SubstreamBox::new(substream)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -88,63 +96,6 @@ where
|
||||
.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]
|
||||
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
self.inner.poll_close(cx).map_err(|e| e.into())
|
||||
@ -157,12 +108,10 @@ impl StreamMuxerBox {
|
||||
where
|
||||
T: StreamMuxer + Send + Sync + 'static,
|
||||
T::OutboundSubstream: Send,
|
||||
T::Substream: Send,
|
||||
T::Substream: Send + Unpin + 'static,
|
||||
{
|
||||
let wrap = Wrap {
|
||||
inner: muxer,
|
||||
substreams: Mutex::new(Default::default()),
|
||||
next_substream: AtomicUsize::new(0),
|
||||
outbound: Mutex::new(Default::default()),
|
||||
next_outbound: AtomicUsize::new(0),
|
||||
};
|
||||
@ -174,7 +123,7 @@ impl StreamMuxerBox {
|
||||
}
|
||||
|
||||
impl StreamMuxer for StreamMuxerBox {
|
||||
type Substream = usize; // TODO: use a newtype
|
||||
type Substream = SubstreamBox;
|
||||
type OutboundSubstream = usize; // TODO: use a newtype
|
||||
type Error = io::Error;
|
||||
|
||||
@ -205,51 +154,82 @@ impl StreamMuxer for StreamMuxerBox {
|
||||
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]
|
||||
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
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 parking_lot::Mutex;
|
||||
use std::{
|
||||
io,
|
||||
pin::Pin,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
task::Context,
|
||||
task::Poll,
|
||||
};
|
||||
use std::cell::Cell;
|
||||
use std::{io, task::Context, task::Poll};
|
||||
|
||||
/// Implementation of `StreamMuxer` that allows only one substream on top of a connection,
|
||||
/// yielding the connection itself.
|
||||
@ -40,9 +34,7 @@ use std::{
|
||||
/// Most notably, no protocol is negotiated.
|
||||
pub struct SingletonMuxer<TSocket> {
|
||||
/// The inner connection.
|
||||
inner: Mutex<TSocket>,
|
||||
/// If true, a substream has been produced and any further attempt should fail.
|
||||
substream_extracted: AtomicBool,
|
||||
inner: Cell<Option<TSocket>>,
|
||||
/// Our local endpoint. Always the same value as was passed to `new`.
|
||||
endpoint: Endpoint,
|
||||
}
|
||||
@ -54,15 +46,12 @@ impl<TSocket> SingletonMuxer<TSocket> {
|
||||
/// If `endpoint` is `Listener`, then only one inbound substream will be permitted.
|
||||
pub fn new(inner: TSocket, endpoint: Endpoint) -> Self {
|
||||
SingletonMuxer {
|
||||
inner: Mutex::new(inner),
|
||||
substream_extracted: AtomicBool::new(false),
|
||||
inner: Cell::new(Some(inner)),
|
||||
endpoint,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Substream of the `SingletonMuxer`.
|
||||
pub struct Substream {}
|
||||
/// Outbound substream attempt of the `SingletonMuxer`.
|
||||
pub struct OutboundSubstream {}
|
||||
|
||||
@ -70,7 +59,7 @@ impl<TSocket> StreamMuxer for SingletonMuxer<TSocket>
|
||||
where
|
||||
TSocket: AsyncRead + AsyncWrite + Unpin,
|
||||
{
|
||||
type Substream = Substream;
|
||||
type Substream = TSocket;
|
||||
type OutboundSubstream = OutboundSubstream;
|
||||
type Error = io::Error;
|
||||
|
||||
@ -83,8 +72,8 @@ where
|
||||
Endpoint::Listener => {}
|
||||
}
|
||||
|
||||
if !self.substream_extracted.swap(true, Ordering::Relaxed) {
|
||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(Substream {})))
|
||||
if let Some(stream) = self.inner.replace(None) {
|
||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(stream)))
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
@ -104,8 +93,8 @@ where
|
||||
Endpoint::Dialer => {}
|
||||
}
|
||||
|
||||
if !self.substream_extracted.swap(true, Ordering::Relaxed) {
|
||||
Poll::Ready(Ok(Substream {}))
|
||||
if let Some(stream) = self.inner.replace(None) {
|
||||
Poll::Ready(Ok(stream))
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
@ -113,42 +102,6 @@ where
|
||||
|
||||
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>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ impl<T> Multiplexed<T> {
|
||||
T::ListenerUpgrade: Send + 'static,
|
||||
T::Error: Send + Sync,
|
||||
M: StreamMuxer + Send + Sync + 'static,
|
||||
M::Substream: Send + 'static,
|
||||
M::Substream: Send + Unpin + 'static,
|
||||
M::OutboundSubstream: Send + 'static,
|
||||
{
|
||||
boxed(self.map(|(i, m), _| (i, StreamMuxerBox::new(m))))
|
||||
|
@ -13,5 +13,5 @@ clap = {version = "3.1.6", features = ["derive"]}
|
||||
zeroize = "1"
|
||||
serde = { version = "1.0.136", features = ["derive"] }
|
||||
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"
|
||||
|
@ -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
|
||||
|
||||
- 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"
|
||||
rust-version = "1.56.1"
|
||||
description = "Metrics for libp2p"
|
||||
version = "0.6.1"
|
||||
version = "0.7.0"
|
||||
authors = ["Max Inden <mail@max-inden.de>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -19,17 +19,17 @@ relay = ["libp2p-relay"]
|
||||
dcutr = ["libp2p-dcutr"]
|
||||
|
||||
[dependencies]
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-dcutr = { version = "0.3.0", path = "../../protocols/dcutr", optional = true }
|
||||
libp2p-identify = { version = "0.36.0", path = "../../protocols/identify", optional = true }
|
||||
libp2p-kad = { version = "0.37.0", path = "../../protocols/kad", optional = true }
|
||||
libp2p-ping = { version = "0.36.0", path = "../../protocols/ping", optional = true }
|
||||
libp2p-relay = { version = "0.9.0", path = "../../protocols/relay", optional = true }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
libp2p-dcutr = { version = "0.4.0", path = "../../protocols/dcutr", optional = true }
|
||||
libp2p-identify = { version = "0.37.0", path = "../../protocols/identify", optional = true }
|
||||
libp2p-kad = { version = "0.38.0", path = "../../protocols/kad", optional = true }
|
||||
libp2p-ping = { version = "0.37.0", path = "../../protocols/ping", optional = true }
|
||||
libp2p-relay = { version = "0.10.0", path = "../../protocols/relay", optional = true }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
prometheus-client = "0.16.0"
|
||||
|
||||
[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]
|
||||
log = "0.4.0"
|
||||
|
@ -1,6 +1,7 @@
|
||||
# 0.34.0 [unreleased]
|
||||
|
||||
- `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/
|
||||
|
||||
|
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
bytes = "1"
|
||||
futures = "0.3.1"
|
||||
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"
|
||||
nohash-hasher = "0.2"
|
||||
parking_lot = "0.12"
|
||||
|
@ -32,6 +32,7 @@ use libp2p_core::{
|
||||
};
|
||||
use libp2p_mplex as mplex;
|
||||
use libp2p_plaintext::PlainText2Config;
|
||||
use std::pin::Pin;
|
||||
use std::time::Duration;
|
||||
|
||||
type BenchTransport = transport::Boxed<(PeerId, muxing::StreamMuxerBox)>;
|
||||
@ -115,7 +116,7 @@ fn run(transport: &mut BenchTransport, payload: &Vec<u8>, listen_addr: &Multiadd
|
||||
loop {
|
||||
// Read in typical chunk sizes of up to 8KiB.
|
||||
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
|
||||
.unwrap();
|
||||
off += n;
|
||||
@ -139,12 +140,12 @@ fn run(transport: &mut BenchTransport, payload: &Vec<u8>, listen_addr: &Multiadd
|
||||
.unwrap();
|
||||
let mut off = 0;
|
||||
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
|
||||
.unwrap();
|
||||
off += n;
|
||||
if off == payload.len() {
|
||||
poll_fn(|cx| conn.flush_substream(cx, &mut stream))
|
||||
poll_fn(|cx| Pin::new(&mut stream).poll_flush(cx))
|
||||
.await
|
||||
.unwrap();
|
||||
return;
|
||||
|
@ -116,44 +116,6 @@ where
|
||||
// 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>> {
|
||||
self.io.lock().poll_close(cx)
|
||||
}
|
||||
|
@ -18,8 +18,9 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use futures::future::poll_fn;
|
||||
use futures::{channel::oneshot, prelude::*};
|
||||
use libp2p_core::{muxing, upgrade, Transport};
|
||||
use libp2p_core::{upgrade, StreamMuxer, Transport};
|
||||
use libp2p_tcp::TcpConfig;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -60,7 +61,8 @@ fn async_write() {
|
||||
.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
|
||||
.unwrap();
|
||||
|
||||
@ -76,7 +78,7 @@ fn async_write() {
|
||||
|
||||
let client = Arc::new(transport.dial(rx.await.unwrap()).unwrap().await.unwrap());
|
||||
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
|
||||
.unwrap()
|
||||
.into_inbound_substream()
|
||||
|
@ -18,8 +18,9 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use futures::future::poll_fn;
|
||||
use futures::{channel::oneshot, prelude::*};
|
||||
use libp2p_core::{muxing, upgrade, Transport};
|
||||
use libp2p_core::{upgrade, StreamMuxer, Transport};
|
||||
use libp2p_tcp::TcpConfig;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -60,7 +61,8 @@ fn client_to_server_outbound() {
|
||||
.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
|
||||
.unwrap();
|
||||
|
||||
@ -76,7 +78,7 @@ fn client_to_server_outbound() {
|
||||
|
||||
let client = Arc::new(transport.dial(rx.await.unwrap()).unwrap().await.unwrap());
|
||||
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
|
||||
.unwrap()
|
||||
.into_inbound_substream()
|
||||
@ -131,7 +133,7 @@ fn client_to_server_inbound() {
|
||||
);
|
||||
|
||||
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
|
||||
.unwrap()
|
||||
.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));
|
||||
|
||||
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
|
||||
.unwrap();
|
||||
outbound.write_all(b"hello world").await.unwrap();
|
||||
@ -196,7 +200,8 @@ fn protocol_not_match() {
|
||||
.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
|
||||
.unwrap();
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
# 0.38.0 [unreleased]
|
||||
|
||||
- Update to `libp2p-core` `v0.34.0`.
|
||||
|
||||
# 0.37.0
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-yamux"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Yamux multiplexing protocol for libp2p"
|
||||
version = "0.37.0"
|
||||
version = "0.38.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
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"
|
||||
thiserror = "1.0"
|
||||
yamux = "0.10.0"
|
||||
|
@ -137,46 +137,6 @@ where
|
||||
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<()>> {
|
||||
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
|
||||
|
||||
- Export `DEFAULT_PROTOCOL_NAME`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-autonat"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
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>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -18,9 +18,9 @@ async-trait = "0.1"
|
||||
futures = "0.3"
|
||||
futures-timer = "3.0"
|
||||
instant = "0.1"
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-request-response = { version = "0.18.0", path = "../request-response" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
libp2p-request-response = { version = "0.19.0", path = "../request-response" }
|
||||
log = "0.4"
|
||||
rand = "0.8"
|
||||
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
|
||||
|
||||
- Upgrade at most one inbound connect request.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-dcutr"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Direct connection upgrade through relay"
|
||||
version = "0.3.1"
|
||||
version = "0.4.0"
|
||||
authors = ["Max Inden <mail@max-inden.de>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -17,8 +17,8 @@ either = "1.6.0"
|
||||
futures = "0.3.1"
|
||||
futures-timer = "3.0"
|
||||
instant = "0.1.11"
|
||||
libp2p-core = { version = "0.33.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
log = "0.4"
|
||||
prost-codec = { version = "0.1", path = "../../misc/prost-codec" }
|
||||
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
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-floodsub"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Floodsub protocol for libp2p"
|
||||
version = "0.36.0"
|
||||
version = "0.37.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -14,8 +14,8 @@ categories = ["network-programming", "asynchronous"]
|
||||
cuckoofilter = "0.5.0"
|
||||
fnv = "1.0"
|
||||
futures = "0.3.1"
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
log = "0.4"
|
||||
prost = "0.10"
|
||||
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
|
||||
|
||||
- Fix duplicate connection id. See [PR 2702].
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-gossipsub"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Gossipsub protocol for libp2p"
|
||||
version = "0.38.1"
|
||||
version = "0.39.0"
|
||||
authors = ["Age Manning <Age@AgeManning.com>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -11,8 +11,8 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
bytes = "1.0"
|
||||
byteorder = "1.3.4"
|
||||
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
|
||||
|
||||
- Allow at most one inbound identify push stream.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-identify"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Nodes identifcation protocol for libp2p"
|
||||
version = "0.36.1"
|
||||
version = "0.37.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -14,8 +14,8 @@ categories = ["network-programming", "asynchronous"]
|
||||
asynchronous-codec = "0.6"
|
||||
futures = "0.3.1"
|
||||
futures-timer = "3.0.2"
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
log = "0.4.1"
|
||||
lru = "0.7.2"
|
||||
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
|
||||
|
||||
- Limit # of inbound streams to 32. [See PR 2699].
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-kad"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Kademlia protocol for libp2p"
|
||||
version = "0.37.1"
|
||||
version = "0.38.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -18,8 +18,8 @@ fnv = "1.0"
|
||||
asynchronous-codec = "0.6"
|
||||
futures = "0.3.1"
|
||||
log = "0.4"
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
prost = "0.10"
|
||||
rand = "0.7.2"
|
||||
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
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-mdns"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
version = "0.37.0"
|
||||
version = "0.38.0"
|
||||
description = "Implementation of the libp2p mDNS discovery method"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
@ -17,8 +17,8 @@ dns-parser = "0.8.0"
|
||||
futures = "0.3.13"
|
||||
if-watch = "1.0.0"
|
||||
lazy_static = "1.4.0"
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
log = "0.4.14"
|
||||
rand = "0.8.3"
|
||||
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
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-ping"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Ping protocol for libp2p"
|
||||
version = "0.36.0"
|
||||
version = "0.37.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -14,8 +14,8 @@ categories = ["network-programming", "asynchronous"]
|
||||
futures = "0.3.1"
|
||||
futures-timer = "3.0.2"
|
||||
instant = "0.1.11"
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
log = "0.4.1"
|
||||
rand = "0.7.2"
|
||||
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
|
||||
|
||||
- Respond to at most one incoming reservation request. Deny <= 8 incoming
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-relay"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
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>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -17,8 +17,8 @@ either = "1.6.0"
|
||||
futures = "0.3.1"
|
||||
futures-timer = "3"
|
||||
instant = "0.1.11"
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
log = "0.4"
|
||||
pin-project = "1"
|
||||
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
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-rendezvous"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Rendezvous protocol for libp2p"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
authors = ["The COMIT guys <hello@comit.network>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -12,8 +12,8 @@ categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
asynchronous-codec = "0.6"
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
prost = "0.10"
|
||||
void = "1"
|
||||
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
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-request-response"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Generic Request/Response Protocols"
|
||||
version = "0.18.0"
|
||||
version = "0.19.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -15,8 +15,8 @@ async-trait = "0.1"
|
||||
bytes = "1"
|
||||
futures = "0.3.1"
|
||||
instant = "0.1.11"
|
||||
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.36.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
|
||||
libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
|
||||
log = "0.4.11"
|
||||
rand = "0.7"
|
||||
smallvec = "1.6.1"
|
||||
|
@ -1,3 +1,7 @@
|
||||
# 0.37.0 [unreleased]
|
||||
|
||||
- Update to `libp2p-core` `v0.34.0`.
|
||||
|
||||
# 0.36.2 [unreleased]
|
||||
|
||||
- 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"
|
||||
rust-version = "1.56.1"
|
||||
description = "The libp2p swarm"
|
||||
version = "0.36.2"
|
||||
version = "0.37.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -16,7 +16,7 @@ fnv = "1.0"
|
||||
futures = "0.3.1"
|
||||
futures-timer = "3.0.2"
|
||||
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"
|
||||
pin-project = "1.0.0"
|
||||
rand = "0.7"
|
||||
|
@ -32,7 +32,7 @@ pub use error::{
|
||||
pub use listeners::{ListenersEvent, ListenersStream};
|
||||
pub use pool::{ConnectionCounters, ConnectionLimits};
|
||||
pub use pool::{EstablishedConnection, PendingConnection};
|
||||
pub use substream::{Close, Substream, SubstreamEndpoint};
|
||||
pub use substream::{Close, SubstreamEndpoint};
|
||||
|
||||
use crate::handler::ConnectionHandler;
|
||||
use crate::IntoConnectionHandler;
|
||||
|
@ -18,7 +18,7 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::connection::{Substream, SubstreamEndpoint};
|
||||
use crate::connection::SubstreamEndpoint;
|
||||
use crate::handler::{
|
||||
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive,
|
||||
};
|
||||
@ -30,7 +30,7 @@ use futures::stream::FuturesUnordered;
|
||||
use futures_timer::Delay;
|
||||
use instant::Instant;
|
||||
use libp2p_core::{
|
||||
muxing::StreamMuxerBox,
|
||||
muxing::SubstreamBox,
|
||||
upgrade::{self, InboundUpgradeApply, OutboundUpgradeApply, UpgradeError},
|
||||
Multiaddr,
|
||||
};
|
||||
@ -55,20 +55,14 @@ where
|
||||
negotiating_in: FuturesUnordered<
|
||||
SubstreamUpgrade<
|
||||
TConnectionHandler::InboundOpenInfo,
|
||||
InboundUpgradeApply<
|
||||
Substream<StreamMuxerBox>,
|
||||
SendWrapper<TConnectionHandler::InboundProtocol>,
|
||||
>,
|
||||
InboundUpgradeApply<SubstreamBox, SendWrapper<TConnectionHandler::InboundProtocol>>,
|
||||
>,
|
||||
>,
|
||||
/// Futures that upgrade outgoing substreams.
|
||||
negotiating_out: FuturesUnordered<
|
||||
SubstreamUpgrade<
|
||||
TConnectionHandler::OutboundOpenInfo,
|
||||
OutboundUpgradeApply<
|
||||
Substream<StreamMuxerBox>,
|
||||
SendWrapper<TConnectionHandler::OutboundProtocol>,
|
||||
>,
|
||||
OutboundUpgradeApply<SubstreamBox, SendWrapper<TConnectionHandler::OutboundProtocol>>,
|
||||
>,
|
||||
>,
|
||||
/// 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
|
||||
/// negotiating inbound streams. The total number of inbound streams on a
|
||||
/// connection is the sum of negotiating and negotiated streams. A limit on
|
||||
/// the total number of streams can be enforced at the [`StreamMuxerBox`]
|
||||
/// level.
|
||||
/// the total number of streams can be enforced at the
|
||||
/// [`StreamMuxerBox`](libp2p_core::muxing::StreamMuxerBox) level.
|
||||
max_negotiating_inbound_streams: usize,
|
||||
}
|
||||
|
||||
@ -254,7 +248,7 @@ where
|
||||
{
|
||||
pub fn inject_substream(
|
||||
&mut self,
|
||||
substream: Substream<StreamMuxerBox>,
|
||||
substream: SubstreamBox,
|
||||
// The first element of the tuple is the unique upgrade identifier
|
||||
// (see `unique_dial_upgrade_id`).
|
||||
endpoint: SubstreamEndpoint<OutboundOpenInfo<TConnectionHandler>>,
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
use futures::prelude::*;
|
||||
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 std::sync::Arc;
|
||||
use std::{fmt, io::Error as IoError, pin::Pin, task::Context, task::Poll};
|
||||
@ -55,9 +55,6 @@ pub struct Close<TMuxer> {
|
||||
muxer: Arc<TMuxer>,
|
||||
}
|
||||
|
||||
/// A successfully opened substream.
|
||||
pub type Substream<TMuxer> = SubstreamRef<Arc<TMuxer>>;
|
||||
|
||||
/// Event that can happen on the `Muxing`.
|
||||
pub enum SubstreamEvent<TMuxer, TUserData>
|
||||
where
|
||||
@ -67,7 +64,7 @@ where
|
||||
InboundSubstream {
|
||||
/// The newly-opened substream. Will return EOF of an error if the `Muxing` is
|
||||
/// destroyed or `close_graceful` is called.
|
||||
substream: Substream<TMuxer>,
|
||||
substream: TMuxer::Substream,
|
||||
},
|
||||
|
||||
/// An outbound substream has successfully been opened.
|
||||
@ -76,7 +73,7 @@ where
|
||||
user_data: TUserData,
|
||||
/// The newly-opened substream. Will return EOF of an error if the `Muxing` is
|
||||
/// destroyed or `close_graceful` is called.
|
||||
substream: Substream<TMuxer>,
|
||||
substream: TMuxer::Substream,
|
||||
},
|
||||
|
||||
/// Address to the remote has changed. The previous one is now obsolete.
|
||||
@ -141,7 +138,6 @@ where
|
||||
// Polling inbound substream.
|
||||
match self.inner.poll_event(cx) {
|
||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(substream))) => {
|
||||
let substream = substream_from_ref(self.inner.clone(), substream);
|
||||
return Poll::Ready(Ok(SubstreamEvent::InboundSubstream { substream }));
|
||||
}
|
||||
Poll::Ready(Ok(StreamMuxerEvent::AddressChange(addr))) => {
|
||||
@ -157,7 +153,6 @@ where
|
||||
let (user_data, mut outbound) = self.outbound_substreams.swap_remove(n);
|
||||
match self.inner.poll_outbound(cx, &mut outbound) {
|
||||
Poll::Ready(Ok(substream)) => {
|
||||
let substream = substream_from_ref(self.inner.clone(), substream);
|
||||
self.inner.destroy_outbound(outbound);
|
||||
return Poll::Ready(Ok(SubstreamEvent::OutboundSubstream {
|
||||
user_data,
|
||||
|
@ -79,11 +79,12 @@ pub use handler::{
|
||||
pub use registry::{AddAddressResult, AddressRecord, AddressScore};
|
||||
|
||||
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 either::Either;
|
||||
use futures::{executor::ThreadPoolBuilder, prelude::*, stream::FusedStream};
|
||||
use libp2p_core::connection::{ConnectionId, PendingPoint};
|
||||
use libp2p_core::muxing::SubstreamBox;
|
||||
use libp2p_core::{
|
||||
connection::{ConnectedPoint, ListenerId},
|
||||
multiaddr::Protocol,
|
||||
@ -110,7 +111,7 @@ use upgrade::UpgradeInfoSend as _;
|
||||
///
|
||||
/// Implements the [`AsyncRead`](futures::io::AsyncRead) and
|
||||
/// [`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.
|
||||
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
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-deflate"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Deflate encryption protocol for libp2p"
|
||||
version = "0.33.0"
|
||||
version = "0.34.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
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"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -1,3 +1,7 @@
|
||||
# 0.34.0 [unreleased]
|
||||
|
||||
- Update to `libp2p-core` `v0.34.0`.
|
||||
|
||||
# 0.33.0
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-dns"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "DNS transport implementation for libp2p"
|
||||
version = "0.33.0"
|
||||
version = "0.34.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -11,7 +11,7 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[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"
|
||||
futures = "0.3.1"
|
||||
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
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-noise"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Cryptographic handshake protocol using the noise framework."
|
||||
version = "0.36.0"
|
||||
version = "0.37.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -13,7 +13,7 @@ bytes = "1"
|
||||
curve25519-dalek = "3.0.0"
|
||||
futures = "0.3.1"
|
||||
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"
|
||||
prost = "0.10"
|
||||
rand = "0.8.3"
|
||||
|
@ -1,3 +1,7 @@
|
||||
# 0.34.0 [unreleased]
|
||||
|
||||
- Update to `libp2p-core` `v0.34.0`.
|
||||
|
||||
# 0.33.0
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-plaintext"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "Plaintext encryption dummy protocol for libp2p"
|
||||
version = "0.33.0"
|
||||
version = "0.34.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
bytes = "1"
|
||||
futures = "0.3.1"
|
||||
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"
|
||||
prost = "0.10"
|
||||
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
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-tcp"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "TCP/IP transport protocol for libp2p"
|
||||
version = "0.33.0"
|
||||
version = "0.34.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
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 }
|
||||
ipnet = "2.0.0"
|
||||
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"
|
||||
socket2 = { version = "0.4.0", features = ["all"] }
|
||||
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 to `libp2p-core` `v0.34.0`.
|
||||
|
||||
# 0.32.0 [2022-01-27]
|
||||
|
||||
|
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[target.'cfg(all(unix, not(target_os = "emscripten")))'.dependencies]
|
||||
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"
|
||||
futures = "0.3.1"
|
||||
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
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-wasm-ext"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
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>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -13,7 +13,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
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"
|
||||
wasm-bindgen = "0.2.42"
|
||||
wasm-bindgen-futures = "0.4.4"
|
||||
|
@ -1,3 +1,7 @@
|
||||
# 0.36.0 [unreleased]
|
||||
|
||||
- Update to `libp2p-core` `v0.34.0`.
|
||||
|
||||
# 0.35.0
|
||||
|
||||
- Update to `libp2p-core` `v0.33.0`.
|
||||
|
@ -3,7 +3,7 @@ name = "libp2p-websocket"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
description = "WebSocket transport for libp2p"
|
||||
version = "0.35.0"
|
||||
version = "0.36.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
futures-rustls = "0.22"
|
||||
either = "1.5.3"
|
||||
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"
|
||||
parking_lot = "0.12.0"
|
||||
quicksink = "0.1"
|
||||
|
Reference in New Issue
Block a user