mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-24 07:11:38 +00:00
Merge branch 'rust_master' into libp2p_0_20
# Conflicts: # .github/workflows/ci.yml # Cargo.toml # core/Cargo.toml # examples/distributed-key-value-store.rs # misc/multistream-select/Cargo.toml # muxers/mplex/Cargo.toml # protocols/deflate/Cargo.toml # protocols/gossipsub/Cargo.toml # protocols/identify/Cargo.toml # protocols/kad/src/behaviour.rs # protocols/kad/src/behaviour/test.rs # protocols/kad/src/kbucket.rs # protocols/kad/src/kbucket/bucket.rs # protocols/kad/src/lib.rs # protocols/kad/src/query.rs # protocols/kad/src/query/peers/closest.rs # protocols/mdns/Cargo.toml # protocols/ping/Cargo.toml # protocols/secio/Cargo.toml # transports/tcp/Cargo.toml # transports/uds/Cargo.toml
This commit is contained in:
18
core/CHANGELOG.md
Normal file
18
core/CHANGELOG.md
Normal file
@ -0,0 +1,18 @@
|
||||
# 0.20.0 [????-??-??]
|
||||
|
||||
- Rename `StreamMuxer::poll_inbound` to `poll_event` and change the
|
||||
return value to `StreamMuxerEvent`. This new `StreamMuxerEvent` makes
|
||||
it possible for the multiplexing layer to notify the upper layers of
|
||||
a change in the address of the underlying connection.
|
||||
|
||||
- Add `ConnectionHandler::inject_address_change`.
|
||||
|
||||
# 0.19.2 [2020-06-22]
|
||||
|
||||
- Add PartialOrd and Ord for PeerId
|
||||
([PR 1594](https://github.com/libp2p/rust-libp2p/pull/1594)).
|
||||
|
||||
- Updated dependencies.
|
||||
|
||||
- Deprecate `StreamMuxer::is_remote_acknowledged`
|
||||
([PR 1616](https://github.com/libp2p/rust-libp2p/pull/1616)).
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-core"
|
||||
edition = "2018"
|
||||
description = "Core traits and structs of libp2p"
|
||||
version = "0.19.0"
|
||||
version = "0.19.2"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -20,30 +20,30 @@ futures-timer = "3"
|
||||
lazy_static = "1.2"
|
||||
libsecp256k1 = { version = "0.3.1", optional = true }
|
||||
log = "0.4"
|
||||
multiaddr = { package = "parity-multiaddr", version = "0.9.0", path = "../misc/multiaddr" }
|
||||
multiaddr = { package = "parity-multiaddr", version = "0.9.1", path = "../misc/multiaddr" }
|
||||
multihash = "0.11.0"
|
||||
multistream-select = { version = "0.8.0", path = "../misc/multistream-select" }
|
||||
multistream-select = { version = "0.8.2", path = "../misc/multistream-select" }
|
||||
parking_lot = "0.10.0"
|
||||
pin-project = "0.4.6"
|
||||
pin-project = "0.4.17"
|
||||
prost = "0.6.1"
|
||||
rand = "0.7"
|
||||
rw-stream-sink = "0.2.0"
|
||||
sha2 = "0.8.0"
|
||||
smallvec = "1.0"
|
||||
thiserror = "1.0"
|
||||
unsigned-varint = "0.3"
|
||||
unsigned-varint = "0.4"
|
||||
void = "1"
|
||||
zeroize = "1"
|
||||
serde = { version = "1.0.114", default-features = false }
|
||||
|
||||
[target.'cfg(not(any(target_os = "emscripten", target_os = "unknown")))'.dependencies]
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
ring = { version = "0.16.9", features = ["alloc", "std"], default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
async-std = "~1.5.0"
|
||||
libp2p-mplex = { version = "0.19.0", path = "../muxers/mplex" }
|
||||
libp2p-secio = { version = "0.19.0", path = "../protocols/secio" }
|
||||
libp2p-tcp = { version = "0.19.0", path = "../transports/tcp" }
|
||||
async-std = "1.6.2"
|
||||
libp2p-mplex = { path = "../muxers/mplex" }
|
||||
libp2p-secio = { path = "../protocols/secio" }
|
||||
libp2p-tcp = { path = "../transports/tcp", features = ["async-std"] }
|
||||
quickcheck = "0.9.0"
|
||||
wasm-timer = "0.2"
|
||||
|
||||
|
@ -132,6 +132,16 @@ impl ConnectedPoint {
|
||||
ConnectedPoint::Listener { .. } => true
|
||||
}
|
||||
}
|
||||
|
||||
/// Modifies the address of the remote stored in this struct.
|
||||
///
|
||||
/// For `Dialer`, this modifies `address`. For `Listener`, this modifies `send_back_addr`.
|
||||
pub fn set_remote_address(&mut self, new_address: Multiaddr) {
|
||||
match self {
|
||||
ConnectedPoint::Dialer { address } => *address = new_address,
|
||||
ConnectedPoint::Listener { send_back_addr, .. } => *send_back_addr = new_address,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about a successfully established connection.
|
||||
@ -169,6 +179,15 @@ impl ConnectionInfo for PeerId {
|
||||
}
|
||||
}
|
||||
|
||||
/// Event generated by a [`Connection`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Event<T> {
|
||||
/// Event generated by the [`ConnectionHandler`].
|
||||
Handler(T),
|
||||
/// Address of the remote has changed.
|
||||
AddressChange(Multiaddr),
|
||||
}
|
||||
|
||||
/// A multiplexed connection to a peer with an associated `ConnectionHandler`.
|
||||
pub struct Connection<TMuxer, THandler>
|
||||
where
|
||||
@ -230,14 +249,6 @@ where
|
||||
self.handler.inject_event(event);
|
||||
}
|
||||
|
||||
/// Returns `true` if the remote has shown any sign of activity
|
||||
/// since the connection has been established.
|
||||
///
|
||||
/// See also [`StreamMuxer::is_remote_acknowledged`].
|
||||
pub fn is_remote_acknowledged(&self) -> bool {
|
||||
self.muxing.is_remote_acknowledged()
|
||||
}
|
||||
|
||||
/// Begins an orderly shutdown of the connection, returning a
|
||||
/// `Future` that resolves when connection shutdown is complete.
|
||||
pub fn close(self) -> Close<TMuxer> {
|
||||
@ -247,7 +258,7 @@ where
|
||||
/// Polls the connection for events produced by the associated handler
|
||||
/// as a result of I/O activity on the substream multiplexer.
|
||||
pub fn poll(mut self: Pin<&mut Self>, cx: &mut Context)
|
||||
-> Poll<Result<THandler::OutEvent, ConnectionError<THandler::Error>>>
|
||||
-> Poll<Result<Event<THandler::OutEvent>, ConnectionError<THandler::Error>>>
|
||||
{
|
||||
loop {
|
||||
let mut io_pending = false;
|
||||
@ -263,6 +274,10 @@ where
|
||||
let endpoint = SubstreamEndpoint::Dialer(user_data);
|
||||
self.handler.inject_substream(substream, endpoint)
|
||||
}
|
||||
Poll::Ready(Ok(SubstreamEvent::AddressChange(address))) => {
|
||||
self.handler.inject_address_change(&address);
|
||||
return Poll::Ready(Ok(Event::AddressChange(address)));
|
||||
}
|
||||
Poll::Ready(Err(err)) => return Poll::Ready(Err(ConnectionError::IO(err))),
|
||||
}
|
||||
|
||||
@ -277,7 +292,7 @@ where
|
||||
self.muxing.open_substream(user_data);
|
||||
}
|
||||
Poll::Ready(Ok(ConnectionHandlerEvent::Custom(event))) => {
|
||||
return Poll::Ready(Ok(event));
|
||||
return Poll::Ready(Ok(Event::Handler(event)));
|
||||
}
|
||||
Poll::Ready(Err(err)) => return Poll::Ready(Err(ConnectionError::Handler(err))),
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::PeerId;
|
||||
use crate::{Multiaddr, PeerId};
|
||||
use std::{task::Context, task::Poll};
|
||||
use super::{Connected, SubstreamEndpoint};
|
||||
|
||||
@ -58,6 +58,9 @@ pub trait ConnectionHandler {
|
||||
/// Notifies the handler of an event.
|
||||
fn inject_event(&mut self, event: Self::InEvent);
|
||||
|
||||
/// Notifies the handler of a change in the address of the remote.
|
||||
fn inject_address_change(&mut self, new_address: &Multiaddr);
|
||||
|
||||
/// Polls the handler for events.
|
||||
///
|
||||
/// Returning an error will close the connection to the remote.
|
||||
|
@ -32,11 +32,13 @@ use std::{
|
||||
collections::hash_map,
|
||||
error,
|
||||
fmt,
|
||||
mem,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use super::{
|
||||
Connected,
|
||||
ConnectedPoint,
|
||||
Connection,
|
||||
ConnectionError,
|
||||
ConnectionHandler,
|
||||
@ -220,7 +222,17 @@ pub enum Event<'a, I, O, H, TE, HE, C> {
|
||||
entry: EstablishedEntry<'a, I, C>,
|
||||
/// The produced event.
|
||||
event: O
|
||||
}
|
||||
},
|
||||
|
||||
/// A connection to a node has changed its address.
|
||||
AddressChange {
|
||||
/// The entry associated with the connection that changed address.
|
||||
entry: EstablishedEntry<'a, I, C>,
|
||||
/// The former [`ConnectedPoint`].
|
||||
old_endpoint: ConnectedPoint,
|
||||
/// The new [`ConnectedPoint`].
|
||||
new_endpoint: ConnectedPoint,
|
||||
},
|
||||
}
|
||||
|
||||
impl<I, O, H, TE, HE, C> Manager<I, O, H, TE, HE, C> {
|
||||
@ -369,6 +381,23 @@ impl<I, O, H, TE, HE, C> Manager<I, O, H, TE, HE, C> {
|
||||
let _ = task.remove();
|
||||
Event::PendingConnectionError { id, error, handler }
|
||||
}
|
||||
task::Event::AddressChange { id: _, new_address } => {
|
||||
let (new, old) = if let TaskState::Established(c) = &mut task.get_mut().state {
|
||||
let mut new_endpoint = c.endpoint.clone();
|
||||
new_endpoint.set_remote_address(new_address);
|
||||
let old_endpoint = mem::replace(&mut c.endpoint, new_endpoint.clone());
|
||||
(new_endpoint, old_endpoint)
|
||||
} else {
|
||||
unreachable!(
|
||||
"`Event::AddressChange` implies (2) occurred on that task and thus (3)."
|
||||
)
|
||||
};
|
||||
Event::AddressChange {
|
||||
entry: EstablishedEntry { task },
|
||||
old_endpoint: old,
|
||||
new_endpoint: new,
|
||||
}
|
||||
},
|
||||
task::Event::Error { id, error } => {
|
||||
let id = ConnectionId(id);
|
||||
let task = task.remove();
|
||||
|
@ -19,8 +19,10 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{
|
||||
Multiaddr,
|
||||
muxing::StreamMuxer,
|
||||
connection::{
|
||||
self,
|
||||
Close,
|
||||
Connected,
|
||||
Connection,
|
||||
@ -55,8 +57,10 @@ pub enum Event<T, H, TE, HE, C> {
|
||||
Error { id: TaskId, error: ConnectionError<HE> },
|
||||
/// A pending connection failed.
|
||||
Failed { id: TaskId, error: PendingConnectionError<TE>, handler: H },
|
||||
/// A node we are connected to has changed its address.
|
||||
AddressChange { id: TaskId, new_address: Multiaddr },
|
||||
/// Notify the manager of an event from the connection.
|
||||
Notify { id: TaskId, event: T }
|
||||
Notify { id: TaskId, event: T },
|
||||
}
|
||||
|
||||
impl<T, H, TE, HE, C> Event<T, H, TE, HE, C> {
|
||||
@ -64,8 +68,9 @@ impl<T, H, TE, HE, C> Event<T, H, TE, HE, C> {
|
||||
match self {
|
||||
Event::Established { id, .. } => id,
|
||||
Event::Error { id, .. } => id,
|
||||
Event::Notify { id, .. } => id,
|
||||
Event::Failed { id, .. } => id,
|
||||
Event::AddressChange { id, .. } => id,
|
||||
Event::Notify { id, .. } => id,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -245,13 +250,20 @@ where
|
||||
this.state = State::EstablishedPending(connection);
|
||||
return Poll::Pending
|
||||
}
|
||||
Poll::Ready(Ok(event)) => {
|
||||
Poll::Ready(Ok(connection::Event::Handler(event))) => {
|
||||
this.state = State::EstablishedReady {
|
||||
connection: Some(connection),
|
||||
event: Event::Notify { id, event }
|
||||
};
|
||||
continue 'poll
|
||||
}
|
||||
Poll::Ready(Ok(connection::Event::AddressChange(new_address))) => {
|
||||
this.state = State::EstablishedReady {
|
||||
connection: Some(connection),
|
||||
event: Event::AddressChange { id, new_address }
|
||||
};
|
||||
continue 'poll
|
||||
}
|
||||
Poll::Ready(Err(error)) => {
|
||||
// Notify the manager of the error via an event,
|
||||
// dropping the connection.
|
||||
|
@ -125,6 +125,16 @@ pub enum PoolEvent<'a, TInEvent, TOutEvent, THandler, TTransErr, THandlerErr, TC
|
||||
/// The produced event.
|
||||
event: TOutEvent,
|
||||
},
|
||||
|
||||
/// The connection to a node has changed its address.
|
||||
AddressChange {
|
||||
/// The connection that has changed address.
|
||||
connection: EstablishedConnection<'a, TInEvent, TConnInfo, TPeerId>,
|
||||
/// The new endpoint.
|
||||
new_endpoint: ConnectedPoint,
|
||||
/// The old endpoint.
|
||||
old_endpoint: ConnectedPoint,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a, TInEvent, TOutEvent, THandler, TTransErr, THandlerErr, TConnInfo, TPeerId> fmt::Debug
|
||||
@ -162,6 +172,13 @@ where
|
||||
.field("event", event)
|
||||
.finish()
|
||||
},
|
||||
PoolEvent::AddressChange { ref connection, ref new_endpoint, ref old_endpoint } => {
|
||||
f.debug_struct("PoolEvent::AddressChange")
|
||||
.field("conn_info", connection.info())
|
||||
.field("new_endpoint", new_endpoint)
|
||||
.field("old_endpoint", old_endpoint)
|
||||
.finish()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -639,7 +656,27 @@ where
|
||||
}),
|
||||
_ => unreachable!("since `entry` is an `EstablishedEntry`.")
|
||||
}
|
||||
}
|
||||
},
|
||||
manager::Event::AddressChange { entry, new_endpoint, old_endpoint } => {
|
||||
let id = entry.id();
|
||||
|
||||
match self.established.get_mut(entry.connected().peer_id()) {
|
||||
Some(list) => *list.get_mut(&id)
|
||||
.expect("state inconsistency: entry is `EstablishedEntry` but absent \
|
||||
from `established`") = new_endpoint.clone(),
|
||||
None => unreachable!("since `entry` is an `EstablishedEntry`.")
|
||||
};
|
||||
|
||||
match self.get(id) {
|
||||
Some(PoolConnection::Established(connection)) =>
|
||||
return Poll::Ready(PoolEvent::AddressChange {
|
||||
connection,
|
||||
new_endpoint,
|
||||
old_endpoint,
|
||||
}),
|
||||
_ => unreachable!("since `entry` is an `EstablishedEntry`.")
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,9 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::muxing::{StreamMuxer, SubstreamRef, substream_from_ref};
|
||||
use crate::muxing::{StreamMuxer, StreamMuxerEvent, SubstreamRef, substream_from_ref};
|
||||
use futures::prelude::*;
|
||||
use multiaddr::Multiaddr;
|
||||
use smallvec::SmallVec;
|
||||
use std::sync::Arc;
|
||||
use std::{fmt, io::Error as IoError, pin::Pin, task::Context, task::Poll};
|
||||
@ -95,6 +96,12 @@ where
|
||||
/// destroyed or `close_graceful` is called.
|
||||
substream: Substream<TMuxer>,
|
||||
},
|
||||
|
||||
/// Address to the remote has changed. The previous one is now obsolete.
|
||||
///
|
||||
/// > **Note**: This can for example happen when using the QUIC protocol, where the two nodes
|
||||
/// > can change their IP address while retaining the same QUIC connection.
|
||||
AddressChange(Multiaddr),
|
||||
}
|
||||
|
||||
/// Identifier for a substream being opened.
|
||||
@ -123,13 +130,6 @@ where
|
||||
self.outbound_substreams.push((user_data, raw));
|
||||
}
|
||||
|
||||
/// Returns `true` if the remote has shown any sign of activity after the muxer has been open.
|
||||
///
|
||||
/// See `StreamMuxer::is_remote_acknowledged`.
|
||||
pub fn is_remote_acknowledged(&self) -> bool {
|
||||
self.inner.is_remote_acknowledged()
|
||||
}
|
||||
|
||||
/// Destroys the node stream and returns all the pending outbound substreams, plus an object
|
||||
/// that signals the remote that we shut down the connection.
|
||||
#[must_use]
|
||||
@ -152,13 +152,15 @@ where
|
||||
/// Provides an API similar to `Future`.
|
||||
pub fn poll(&mut self, cx: &mut Context) -> Poll<Result<SubstreamEvent<TMuxer, TUserData>, IoError>> {
|
||||
// Polling inbound substream.
|
||||
match self.inner.poll_inbound(cx) {
|
||||
Poll::Ready(Ok(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))) =>
|
||||
return Poll::Ready(Ok(SubstreamEvent::AddressChange(addr))),
|
||||
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
|
||||
Poll::Pending => {}
|
||||
}
|
||||
@ -260,6 +262,11 @@ where
|
||||
.field("substream", substream)
|
||||
.finish()
|
||||
},
|
||||
SubstreamEvent::AddressChange(address) => {
|
||||
f.debug_struct("SubstreamEvent::AddressChange")
|
||||
.field("address", address)
|
||||
.finish()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,13 +19,13 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{
|
||||
muxing::StreamMuxer,
|
||||
muxing::{StreamMuxer, StreamMuxerEvent},
|
||||
ProtocolName,
|
||||
transport::{Transport, ListenerEvent, TransportError},
|
||||
Multiaddr
|
||||
};
|
||||
use futures::{prelude::*, io::{IoSlice, IoSliceMut}};
|
||||
use pin_project::{pin_project, project};
|
||||
use pin_project::pin_project;
|
||||
use std::{fmt, io::{Error as IoError}, pin::Pin, task::Context, task::Poll};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@ -62,7 +62,7 @@ where
|
||||
|
||||
/// Implements `AsyncRead` and `AsyncWrite` and dispatches all method calls to
|
||||
/// either `First` or `Second`.
|
||||
#[pin_project]
|
||||
#[pin_project(project = EitherOutputProj)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum EitherOutput<A, B> {
|
||||
First(#[pin] A),
|
||||
@ -74,23 +74,19 @@ where
|
||||
A: AsyncRead,
|
||||
B: AsyncRead,
|
||||
{
|
||||
#[project]
|
||||
fn poll_read(self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll<Result<usize, IoError>> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => AsyncRead::poll_read(a, cx, buf),
|
||||
EitherOutput::Second(b) => AsyncRead::poll_read(b, cx, buf),
|
||||
EitherOutputProj::First(a) => AsyncRead::poll_read(a, cx, buf),
|
||||
EitherOutputProj::Second(b) => AsyncRead::poll_read(b, cx, buf),
|
||||
}
|
||||
}
|
||||
|
||||
#[project]
|
||||
fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context, bufs: &mut [IoSliceMut])
|
||||
-> Poll<Result<usize, IoError>>
|
||||
{
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => AsyncRead::poll_read_vectored(a, cx, bufs),
|
||||
EitherOutput::Second(b) => AsyncRead::poll_read_vectored(b, cx, bufs),
|
||||
EitherOutputProj::First(a) => AsyncRead::poll_read_vectored(a, cx, bufs),
|
||||
EitherOutputProj::Second(b) => AsyncRead::poll_read_vectored(b, cx, bufs),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -100,41 +96,33 @@ where
|
||||
A: AsyncWrite,
|
||||
B: AsyncWrite,
|
||||
{
|
||||
#[project]
|
||||
fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize, IoError>> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => AsyncWrite::poll_write(a, cx, buf),
|
||||
EitherOutput::Second(b) => AsyncWrite::poll_write(b, cx, buf),
|
||||
EitherOutputProj::First(a) => AsyncWrite::poll_write(a, cx, buf),
|
||||
EitherOutputProj::Second(b) => AsyncWrite::poll_write(b, cx, buf),
|
||||
}
|
||||
}
|
||||
|
||||
#[project]
|
||||
fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context, bufs: &[IoSlice])
|
||||
-> Poll<Result<usize, IoError>>
|
||||
{
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => AsyncWrite::poll_write_vectored(a, cx, bufs),
|
||||
EitherOutput::Second(b) => AsyncWrite::poll_write_vectored(b, cx, bufs),
|
||||
EitherOutputProj::First(a) => AsyncWrite::poll_write_vectored(a, cx, bufs),
|
||||
EitherOutputProj::Second(b) => AsyncWrite::poll_write_vectored(b, cx, bufs),
|
||||
}
|
||||
}
|
||||
|
||||
#[project]
|
||||
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), IoError>> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => AsyncWrite::poll_flush(a, cx),
|
||||
EitherOutput::Second(b) => AsyncWrite::poll_flush(b, cx),
|
||||
EitherOutputProj::First(a) => AsyncWrite::poll_flush(a, cx),
|
||||
EitherOutputProj::Second(b) => AsyncWrite::poll_flush(b, cx),
|
||||
}
|
||||
}
|
||||
|
||||
#[project]
|
||||
fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), IoError>> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => AsyncWrite::poll_close(a, cx),
|
||||
EitherOutput::Second(b) => AsyncWrite::poll_close(b, cx),
|
||||
EitherOutputProj::First(a) => AsyncWrite::poll_close(a, cx),
|
||||
EitherOutputProj::Second(b) => AsyncWrite::poll_close(b, cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,13 +134,11 @@ where
|
||||
{
|
||||
type Item = Result<I, EitherError<A::Error, B::Error>>;
|
||||
|
||||
#[project]
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => TryStream::try_poll_next(a, cx)
|
||||
EitherOutputProj::First(a) => TryStream::try_poll_next(a, cx)
|
||||
.map(|v| v.map(|r| r.map_err(EitherError::A))),
|
||||
EitherOutput::Second(b) => TryStream::try_poll_next(b, cx)
|
||||
EitherOutputProj::Second(b) => TryStream::try_poll_next(b, cx)
|
||||
.map(|v| v.map(|r| r.map_err(EitherError::B))),
|
||||
}
|
||||
}
|
||||
@ -165,39 +151,31 @@ where
|
||||
{
|
||||
type Error = EitherError<A::Error, B::Error>;
|
||||
|
||||
#[project]
|
||||
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => Sink::poll_ready(a, cx).map_err(EitherError::A),
|
||||
EitherOutput::Second(b) => Sink::poll_ready(b, cx).map_err(EitherError::B),
|
||||
EitherOutputProj::First(a) => Sink::poll_ready(a, cx).map_err(EitherError::A),
|
||||
EitherOutputProj::Second(b) => Sink::poll_ready(b, cx).map_err(EitherError::B),
|
||||
}
|
||||
}
|
||||
|
||||
#[project]
|
||||
fn start_send(self: Pin<&mut Self>, item: I) -> Result<(), Self::Error> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => Sink::start_send(a, item).map_err(EitherError::A),
|
||||
EitherOutput::Second(b) => Sink::start_send(b, item).map_err(EitherError::B),
|
||||
EitherOutputProj::First(a) => Sink::start_send(a, item).map_err(EitherError::A),
|
||||
EitherOutputProj::Second(b) => Sink::start_send(b, item).map_err(EitherError::B),
|
||||
}
|
||||
}
|
||||
|
||||
#[project]
|
||||
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => Sink::poll_flush(a, cx).map_err(EitherError::A),
|
||||
EitherOutput::Second(b) => Sink::poll_flush(b, cx).map_err(EitherError::B),
|
||||
EitherOutputProj::First(a) => Sink::poll_flush(a, cx).map_err(EitherError::A),
|
||||
EitherOutputProj::Second(b) => Sink::poll_flush(b, cx).map_err(EitherError::B),
|
||||
}
|
||||
}
|
||||
|
||||
#[project]
|
||||
fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherOutput::First(a) => Sink::poll_close(a, cx).map_err(EitherError::A),
|
||||
EitherOutput::Second(b) => Sink::poll_close(b, cx).map_err(EitherError::B),
|
||||
EitherOutputProj::First(a) => Sink::poll_close(a, cx).map_err(EitherError::A),
|
||||
EitherOutputProj::Second(b) => Sink::poll_close(b, cx).map_err(EitherError::B),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -211,10 +189,26 @@ where
|
||||
type OutboundSubstream = EitherOutbound<A, B>;
|
||||
type Error = IoError;
|
||||
|
||||
fn poll_inbound(&self, cx: &mut Context) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||
fn poll_event(&self, cx: &mut Context) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
|
||||
match self {
|
||||
EitherOutput::First(inner) => inner.poll_inbound(cx).map(|p| p.map(EitherOutput::First)).map_err(|e| e.into()),
|
||||
EitherOutput::Second(inner) => inner.poll_inbound(cx).map(|p| p.map(EitherOutput::Second)).map_err(|e| e.into()),
|
||||
EitherOutput::First(inner) => inner.poll_event(cx).map(|result| {
|
||||
result.map_err(|e| e.into()).map(|event| {
|
||||
match event {
|
||||
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
|
||||
StreamMuxerEvent::InboundSubstream(substream) =>
|
||||
StreamMuxerEvent::InboundSubstream(EitherOutput::First(substream))
|
||||
}
|
||||
})
|
||||
}),
|
||||
EitherOutput::Second(inner) => inner.poll_event(cx).map(|result| {
|
||||
result.map_err(|e| e.into()).map(|event| {
|
||||
match event {
|
||||
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
|
||||
StreamMuxerEvent::InboundSubstream(substream) =>
|
||||
StreamMuxerEvent::InboundSubstream(EitherOutput::Second(substream))
|
||||
}
|
||||
})
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,13 +313,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn is_remote_acknowledged(&self) -> bool {
|
||||
match self {
|
||||
EitherOutput::First(inner) => inner.is_remote_acknowledged(),
|
||||
EitherOutput::Second(inner) => inner.is_remote_acknowledged()
|
||||
}
|
||||
}
|
||||
|
||||
fn close(&self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
match self {
|
||||
EitherOutput::First(inner) => inner.close(cx).map_err(|e| e.into()),
|
||||
@ -349,7 +336,7 @@ pub enum EitherOutbound<A: StreamMuxer, B: StreamMuxer> {
|
||||
}
|
||||
|
||||
/// Implements `Stream` and dispatches all method calls to either `First` or `Second`.
|
||||
#[pin_project]
|
||||
#[pin_project(project = EitherListenStreamProj)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[must_use = "futures do nothing unless polled"]
|
||||
pub enum EitherListenStream<A, B> {
|
||||
@ -364,17 +351,15 @@ where
|
||||
{
|
||||
type Item = Result<ListenerEvent<EitherFuture<AInner, BInner>, EitherError<AError, BError>>, EitherError<AError, BError>>;
|
||||
|
||||
#[project]
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherListenStream::First(a) => match TryStream::try_poll_next(a, cx) {
|
||||
EitherListenStreamProj::First(a) => match TryStream::try_poll_next(a, cx) {
|
||||
Poll::Pending => Poll::Pending,
|
||||
Poll::Ready(None) => Poll::Ready(None),
|
||||
Poll::Ready(Some(Ok(le))) => Poll::Ready(Some(Ok(le.map(EitherFuture::First).map_err(EitherError::A)))),
|
||||
Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(EitherError::A(err)))),
|
||||
},
|
||||
EitherListenStream::Second(a) => match TryStream::try_poll_next(a, cx) {
|
||||
EitherListenStreamProj::Second(a) => match TryStream::try_poll_next(a, cx) {
|
||||
Poll::Pending => Poll::Pending,
|
||||
Poll::Ready(None) => Poll::Ready(None),
|
||||
Poll::Ready(Some(Ok(le))) => Poll::Ready(Some(Ok(le.map(EitherFuture::Second).map_err(EitherError::B)))),
|
||||
@ -385,7 +370,7 @@ where
|
||||
}
|
||||
|
||||
/// Implements `Future` and dispatches all method calls to either `First` or `Second`.
|
||||
#[pin_project]
|
||||
#[pin_project(project = EitherFutureProj)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[must_use = "futures do nothing unless polled"]
|
||||
pub enum EitherFuture<A, B> {
|
||||
@ -400,19 +385,17 @@ where
|
||||
{
|
||||
type Output = Result<EitherOutput<AInner, BInner>, EitherError<AFuture::Error, BFuture::Error>>;
|
||||
|
||||
#[project]
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherFuture::First(a) => TryFuture::try_poll(a, cx)
|
||||
EitherFutureProj::First(a) => TryFuture::try_poll(a, cx)
|
||||
.map_ok(EitherOutput::First).map_err(EitherError::A),
|
||||
EitherFuture::Second(a) => TryFuture::try_poll(a, cx)
|
||||
EitherFutureProj::Second(a) => TryFuture::try_poll(a, cx)
|
||||
.map_ok(EitherOutput::Second).map_err(EitherError::B),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project = EitherFuture2Proj)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[must_use = "futures do nothing unless polled"]
|
||||
pub enum EitherFuture2<A, B> { A(#[pin] A), B(#[pin] B) }
|
||||
@ -424,13 +407,11 @@ where
|
||||
{
|
||||
type Output = Result<EitherOutput<AItem, BItem>, EitherError<AError, BError>>;
|
||||
|
||||
#[project]
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
EitherFuture2::A(a) => TryFuture::try_poll(a, cx)
|
||||
EitherFuture2Proj::A(a) => TryFuture::try_poll(a, cx)
|
||||
.map_ok(EitherOutput::First).map_err(EitherError::A),
|
||||
EitherFuture2::B(a) => TryFuture::try_poll(a, cx)
|
||||
EitherFuture2Proj::B(a) => TryFuture::try_poll(a, cx)
|
||||
.map_ok(EitherOutput::Second).map_err(EitherError::B),
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
//! A node's network identity keys.
|
||||
|
||||
pub mod ed25519;
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod rsa;
|
||||
#[cfg(feature = "secp256k1")]
|
||||
pub mod secp256k1;
|
||||
@ -52,7 +52,7 @@ use crate::{PeerId, keys_proto};
|
||||
pub enum Keypair {
|
||||
/// An Ed25519 keypair.
|
||||
Ed25519(ed25519::Keypair),
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
/// An RSA keypair.
|
||||
Rsa(rsa::Keypair),
|
||||
/// A Secp256k1 keypair.
|
||||
@ -76,7 +76,7 @@ impl Keypair {
|
||||
/// format (i.e. unencrypted) as defined in [RFC5208].
|
||||
///
|
||||
/// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result<Keypair, DecodingError> {
|
||||
rsa::Keypair::from_pkcs8(pkcs8_der).map(Keypair::Rsa)
|
||||
}
|
||||
@ -97,7 +97,7 @@ impl Keypair {
|
||||
use Keypair::*;
|
||||
match self {
|
||||
Ed25519(ref pair) => Ok(pair.sign(msg)),
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(ref pair) => pair.sign(msg),
|
||||
#[cfg(feature = "secp256k1")]
|
||||
Secp256k1(ref pair) => pair.secret().sign(msg)
|
||||
@ -109,7 +109,7 @@ impl Keypair {
|
||||
use Keypair::*;
|
||||
match self {
|
||||
Ed25519(pair) => PublicKey::Ed25519(pair.public()),
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(pair) => PublicKey::Rsa(pair.public()),
|
||||
#[cfg(feature = "secp256k1")]
|
||||
Secp256k1(pair) => PublicKey::Secp256k1(pair.public().clone()),
|
||||
@ -122,7 +122,7 @@ impl Keypair {
|
||||
pub enum PublicKey {
|
||||
/// A public Ed25519 key.
|
||||
Ed25519(ed25519::PublicKey),
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
/// A public RSA key.
|
||||
Rsa(rsa::PublicKey),
|
||||
#[cfg(feature = "secp256k1")]
|
||||
@ -139,7 +139,7 @@ impl PublicKey {
|
||||
use PublicKey::*;
|
||||
match self {
|
||||
Ed25519(pk) => pk.verify(msg, sig),
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(pk) => pk.verify(msg, sig),
|
||||
#[cfg(feature = "secp256k1")]
|
||||
Secp256k1(pk) => pk.verify(msg, sig)
|
||||
@ -157,7 +157,7 @@ impl PublicKey {
|
||||
r#type: keys_proto::KeyType::Ed25519 as i32,
|
||||
data: key.encode().to_vec()
|
||||
},
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
PublicKey::Rsa(key) =>
|
||||
keys_proto::PublicKey {
|
||||
r#type: keys_proto::KeyType::Rsa as i32,
|
||||
@ -192,11 +192,11 @@ impl PublicKey {
|
||||
keys_proto::KeyType::Ed25519 => {
|
||||
ed25519::PublicKey::decode(&pubkey.data).map(PublicKey::Ed25519)
|
||||
},
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
keys_proto::KeyType::Rsa => {
|
||||
rsa::PublicKey::decode_x509(&pubkey.data).map(PublicKey::Rsa)
|
||||
}
|
||||
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
keys_proto::KeyType::Rsa => {
|
||||
log::debug!("support for RSA was disabled at compile-time");
|
||||
Err(DecodingError::new("Unsupported"))
|
||||
|
@ -53,6 +53,7 @@
|
||||
|
||||
use fnv::FnvHashMap;
|
||||
use futures::{future, prelude::*, task::Context, task::Poll};
|
||||
use multiaddr::Multiaddr;
|
||||
use parking_lot::Mutex;
|
||||
use std::{io, ops::Deref, fmt, pin::Pin, sync::atomic::{AtomicUsize, Ordering}};
|
||||
|
||||
@ -64,11 +65,11 @@ mod singleton;
|
||||
///
|
||||
/// The state of a muxer, as exposed by this API, is the following:
|
||||
///
|
||||
/// - A connection to the remote. The `is_remote_acknowledged`, `flush_all` and `close` methods
|
||||
/// operate on this.
|
||||
/// - A list of substreams that are open. The `poll_inbound`, `poll_outbound`, `read_substream`,
|
||||
/// `write_substream`, `flush_substream`, `shutdown_substream` and `destroy_substream` methods
|
||||
/// allow controlling these entries.
|
||||
/// - 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.
|
||||
///
|
||||
@ -82,7 +83,7 @@ pub trait StreamMuxer {
|
||||
/// Error type of the muxer
|
||||
type Error: Into<io::Error>;
|
||||
|
||||
/// Polls for an inbound substream.
|
||||
/// Polls for a connection-wide event.
|
||||
///
|
||||
/// This function behaves the same as a `Stream`.
|
||||
///
|
||||
@ -91,7 +92,7 @@ pub trait StreamMuxer {
|
||||
/// Only the latest task that was used to call this method may be notified.
|
||||
///
|
||||
/// An error can be generated if the connection has been closed.
|
||||
fn poll_inbound(&self, cx: &mut Context) -> Poll<Result<Self::Substream, Self::Error>>;
|
||||
fn poll_event(&self, cx: &mut Context) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>>;
|
||||
|
||||
/// Opens a new outgoing substream, and produces the equivalent to a future that will be
|
||||
/// resolved when it becomes available.
|
||||
@ -180,7 +181,10 @@ pub trait StreamMuxer {
|
||||
/// allowed to assume that the handshake has succeeded when it didn't in fact succeed. This
|
||||
/// method can be called in order to determine whether the remote has accepted our handshake or
|
||||
/// has potentially not received it yet.
|
||||
fn is_remote_acknowledged(&self) -> bool;
|
||||
#[deprecated(note = "This method is unused and will be removed in the future")]
|
||||
fn is_remote_acknowledged(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Closes this `StreamMuxer`.
|
||||
///
|
||||
@ -204,18 +208,49 @@ pub trait StreamMuxer {
|
||||
fn flush_all(&self, cx: &mut Context) -> Poll<Result<(), Self::Error>>;
|
||||
}
|
||||
|
||||
/// Polls for an inbound from the muxer but wraps the output in an object that
|
||||
/// implements `Read`/`Write`/`AsyncRead`/`AsyncWrite`.
|
||||
pub fn inbound_from_ref_and_wrap<P>(
|
||||
/// Event about a connection, reported by an implementation of [`StreamMuxer`].
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum StreamMuxerEvent<T> {
|
||||
/// Remote has opened a new substream. Contains the substream in question.
|
||||
InboundSubstream(T),
|
||||
|
||||
/// Address to the remote has changed. The previous one is now obsolete.
|
||||
///
|
||||
/// > **Note**: This can for example happen when using the QUIC protocol, where the two nodes
|
||||
/// > can change their IP address while retaining the same QUIC connection.
|
||||
AddressChange(Multiaddr),
|
||||
}
|
||||
|
||||
impl<T> StreamMuxerEvent<T> {
|
||||
/// If `self` is a [`StreamMuxerEvent::InboundSubstream`], returns the content. Otherwise
|
||||
/// returns `None`.
|
||||
pub fn into_inbound_substream(self) -> Option<T> {
|
||||
if let StreamMuxerEvent::InboundSubstream(s) = self {
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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<SubstreamRef<P>, <P::Target as StreamMuxer>::Error>>
|
||||
) -> 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_inbound(cx))
|
||||
.map_ok(|substream| substream_from_ref(muxer2, substream))
|
||||
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
|
||||
@ -476,8 +511,8 @@ impl StreamMuxer for StreamMuxerBox {
|
||||
type Error = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn poll_inbound(&self, cx: &mut Context) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||
self.inner.poll_inbound(cx)
|
||||
fn poll_event(&self, cx: &mut Context) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
|
||||
self.inner.poll_event(cx)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -525,11 +560,6 @@ impl StreamMuxer for StreamMuxerBox {
|
||||
self.inner.close(cx)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_remote_acknowledged(&self) -> bool {
|
||||
self.inner.is_remote_acknowledged()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush_all(&self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
self.inner.flush_all(cx)
|
||||
@ -553,16 +583,18 @@ where
|
||||
type Error = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn poll_inbound(&self, cx: &mut Context) -> Poll<Result<Self::Substream, Self::Error>> {
|
||||
let substream = match self.inner.poll_inbound(cx) {
|
||||
fn poll_event(&self, cx: &mut Context) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
|
||||
let substream = match self.inner.poll_event(cx) {
|
||||
Poll::Pending => return Poll::Pending,
|
||||
Poll::Ready(Ok(s)) => s,
|
||||
Poll::Ready(Ok(StreamMuxerEvent::AddressChange(a))) =>
|
||||
return Poll::Ready(Ok(StreamMuxerEvent::AddressChange(a))),
|
||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(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(StreamMuxerEvent::InboundSubstream(id)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -631,11 +663,6 @@ where
|
||||
self.inner.close(cx).map_err(|e| e.into())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_remote_acknowledged(&self) -> bool {
|
||||
self.inner.is_remote_acknowledged()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush_all(&self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
self.inner.flush_all(cx).map_err(|e| e.into())
|
||||
|
@ -18,7 +18,8 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{connection::Endpoint, muxing::StreamMuxer};
|
||||
use crate::{connection::Endpoint, muxing::{StreamMuxer, StreamMuxerEvent}};
|
||||
|
||||
use futures::prelude::*;
|
||||
use parking_lot::Mutex;
|
||||
use std::{io, pin::Pin, sync::atomic::{AtomicBool, Ordering}, task::Context, task::Poll};
|
||||
@ -35,8 +36,6 @@ pub struct SingletonMuxer<TSocket> {
|
||||
substream_extracted: AtomicBool,
|
||||
/// Our local endpoint. Always the same value as was passed to `new`.
|
||||
endpoint: Endpoint,
|
||||
/// If true, we have received data from the remote.
|
||||
remote_acknowledged: AtomicBool,
|
||||
}
|
||||
|
||||
impl<TSocket> SingletonMuxer<TSocket> {
|
||||
@ -49,7 +48,6 @@ impl<TSocket> SingletonMuxer<TSocket> {
|
||||
inner: Mutex::new(inner),
|
||||
substream_extracted: AtomicBool::new(false),
|
||||
endpoint,
|
||||
remote_acknowledged: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,14 +65,14 @@ where
|
||||
type OutboundSubstream = OutboundSubstream;
|
||||
type Error = io::Error;
|
||||
|
||||
fn poll_inbound(&self, _: &mut Context) -> Poll<Result<Self::Substream, io::Error>> {
|
||||
fn poll_event(&self, _: &mut Context) -> Poll<Result<StreamMuxerEvent<Self::Substream>, io::Error>> {
|
||||
match self.endpoint {
|
||||
Endpoint::Dialer => return Poll::Pending,
|
||||
Endpoint::Listener => {}
|
||||
}
|
||||
|
||||
if !self.substream_extracted.swap(true, Ordering::Relaxed) {
|
||||
Poll::Ready(Ok(Substream {}))
|
||||
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(Substream {})))
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
@ -101,11 +99,7 @@ where
|
||||
}
|
||||
|
||||
fn read_substream(&self, cx: &mut Context, _: &mut Self::Substream, buf: &mut [u8]) -> Poll<Result<usize, io::Error>> {
|
||||
let res = AsyncRead::poll_read(Pin::new(&mut *self.inner.lock()), cx, buf);
|
||||
if let Poll::Ready(Ok(_)) = res {
|
||||
self.remote_acknowledged.store(true, Ordering::Release);
|
||||
}
|
||||
res
|
||||
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>> {
|
||||
@ -123,10 +117,6 @@ where
|
||||
fn destroy_substream(&self, _: Self::Substream) {
|
||||
}
|
||||
|
||||
fn is_remote_acknowledged(&self) -> bool {
|
||||
self.remote_acknowledged.load(Ordering::Acquire)
|
||||
}
|
||||
|
||||
fn close(&self, cx: &mut Context) -> Poll<Result<(), io::Error>> {
|
||||
// The `StreamMuxer` trait requires that `close()` implies `flush_all()`.
|
||||
self.flush_all(cx)
|
||||
|
@ -416,7 +416,14 @@ where
|
||||
Poll::Ready(PoolEvent::ConnectionEvent { connection, event }) => {
|
||||
NetworkEvent::ConnectionEvent {
|
||||
connection,
|
||||
event
|
||||
event,
|
||||
}
|
||||
}
|
||||
Poll::Ready(PoolEvent::AddressChange { connection, new_endpoint, old_endpoint }) => {
|
||||
NetworkEvent::AddressChange {
|
||||
connection,
|
||||
new_endpoint,
|
||||
old_endpoint,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -155,6 +155,16 @@ where
|
||||
/// Event that was produced by the node.
|
||||
event: TOutEvent,
|
||||
},
|
||||
|
||||
/// An established connection has changed its address.
|
||||
AddressChange {
|
||||
/// The connection whose address has changed.
|
||||
connection: EstablishedConnection<'a, TInEvent, TConnInfo, TPeerId>,
|
||||
/// New endpoint of this connection.
|
||||
new_endpoint: ConnectedPoint,
|
||||
/// Old endpoint of this connection.
|
||||
old_endpoint: ConnectedPoint,
|
||||
},
|
||||
}
|
||||
|
||||
impl<TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId> fmt::Debug for
|
||||
@ -240,6 +250,13 @@ where
|
||||
.field("event", event)
|
||||
.finish()
|
||||
}
|
||||
NetworkEvent::AddressChange { connection, new_endpoint, old_endpoint } => {
|
||||
f.debug_struct("AddressChange")
|
||||
.field("connection", connection)
|
||||
.field("new_endpoint", new_endpoint)
|
||||
.field("old_endpoint", old_endpoint)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ use bs58;
|
||||
use thiserror::Error;
|
||||
use multihash::{self, Code, Sha2_256};
|
||||
use rand::Rng;
|
||||
use std::{convert::TryFrom, borrow::Borrow, fmt, hash, str::FromStr};
|
||||
use std::{convert::TryFrom, borrow::Borrow, fmt, hash, str::FromStr, cmp};
|
||||
|
||||
/// Public keys with byte-lengths smaller than `MAX_INLINE_KEY_LENGTH` will be
|
||||
/// automatically used as the peer id using an identity multihash.
|
||||
@ -57,6 +57,21 @@ impl fmt::Display for PeerId {
|
||||
}
|
||||
}
|
||||
|
||||
impl cmp::PartialOrd for PeerId {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
|
||||
Some(Ord::cmp(self, other))
|
||||
}
|
||||
}
|
||||
|
||||
impl cmp::Ord for PeerId {
|
||||
fn cmp(&self, other: &Self) -> cmp::Ordering {
|
||||
// must use borrow, because as_bytes is not consistent with equality
|
||||
let lhs: &[u8] = self.borrow();
|
||||
let rhs: &[u8] = other.borrow();
|
||||
lhs.cmp(rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl PeerId {
|
||||
/// Builds a `PeerId` from a public key.
|
||||
pub fn from_public_key(key: PublicKey) -> PeerId {
|
||||
|
@ -87,12 +87,12 @@ pub use self::{
|
||||
///
|
||||
/// # Context
|
||||
///
|
||||
/// In situations where we provide a list of protocols that we support, the elements of that list are required to
|
||||
/// implement the [`ProtocolName`] trait.
|
||||
/// In situations where we provide a list of protocols that we support,
|
||||
/// the elements of that list are required to implement the [`ProtocolName`] trait.
|
||||
///
|
||||
/// Libp2p will call the [`ProtocolName::protocol_name`] trait method on each element of that list, and transmit the
|
||||
/// returned value on the network. If the remote accepts a given protocol, the element serves as the return value of
|
||||
/// the function that performed the negotiation.
|
||||
/// Libp2p will call [`ProtocolName::protocol_name`] on each element of that list, and transmit the
|
||||
/// returned value on the network. If the remote accepts a given protocol, the element
|
||||
/// serves as the return value of the function that performed the negotiation.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@ -118,6 +118,9 @@ pub use self::{
|
||||
///
|
||||
pub trait ProtocolName {
|
||||
/// The protocol name as bytes. Transmitted on the network.
|
||||
///
|
||||
/// **Note:** Valid protocol names must start with `/` and
|
||||
/// not exceed 140 bytes in length.
|
||||
fn protocol_name(&self) -> &[u8];
|
||||
}
|
||||
|
||||
|
@ -2,15 +2,15 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use futures::prelude::*;
|
||||
use libp2p_core::muxing::StreamMuxer;
|
||||
use libp2p_core::{
|
||||
Multiaddr,
|
||||
connection::{
|
||||
ConnectionHandler,
|
||||
ConnectionHandlerEvent,
|
||||
Substream,
|
||||
SubstreamEndpoint,
|
||||
},
|
||||
muxing::StreamMuxerBox,
|
||||
muxing::{StreamMuxer, StreamMuxerBox},
|
||||
};
|
||||
use std::{io, pin::Pin, task::Context, task::Poll};
|
||||
|
||||
@ -29,6 +29,9 @@ impl ConnectionHandler for TestHandler {
|
||||
fn inject_event(&mut self, _: Self::InEvent)
|
||||
{}
|
||||
|
||||
fn inject_address_change(&mut self, _: &Multiaddr)
|
||||
{}
|
||||
|
||||
fn poll(&mut self, _: &mut Context)
|
||||
-> Poll<Result<ConnectionHandlerEvent<Self::OutboundOpenInfo, Self::OutEvent>, Self::Error>>
|
||||
{
|
||||
|
Reference in New Issue
Block a user