mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-04-25 03:02:12 +00:00
libp2p 0.17
This commit is contained in:
parent
ec0b5dc364
commit
077b3301ab
50
CHANGELOG.md
50
CHANGELOG.md
@ -1,3 +1,53 @@
|
||||
# Version ???
|
||||
|
||||
|
||||
# Version 0.17.0 (2020-04-02)
|
||||
|
||||
- `libp2p-core`: Finished "identity hashing" for peer IDs migration.
|
||||
[PR 1460](https://github.com/libp2p/rust-libp2p/pull/1460)
|
||||
- `libp2p-core`: Remove `poll_broadcast`.
|
||||
[PR 1527](https://github.com/libp2p/rust-libp2p/pull/1527)
|
||||
- `libp2p-core`, `libp2p-swarm`: Report addresses of closed listeners.
|
||||
[PR 1485](https://github.com/libp2p/rust-libp2p/pull/1485)
|
||||
- `libp2p-core`: Support for multiple connections per peer and configurable connection limits.
|
||||
See [PR #1440](https://github.com/libp2p/rust-libp2p/pull/1440),
|
||||
[PR #1519](https://github.com/libp2p/rust-libp2p/pull/1519) and
|
||||
[issue #912](https://github.com/libp2p/rust-libp2p/issues/912) for details.
|
||||
|
||||
- `libp2p-swarm`: Pass the cause of closing a listener to `inject_listener_closed`.
|
||||
[PR 1517](https://github.com/libp2p/rust-libp2p/pull/1517)
|
||||
- `libp2p-swarm`: Support for multiple connections per peer and configurable connection limits.
|
||||
See [PR #1440](https://github.com/libp2p/rust-libp2p/pull/1440),
|
||||
[PR #1519](https://github.com/libp2p/rust-libp2p/pull/1519) and
|
||||
[issue #912](https://github.com/libp2p/rust-libp2p/issues/912) for details.
|
||||
- `libp2p-swarm`: The `SwarmEvent` now returns more events.
|
||||
[PR 1515](https://github.com/libp2p/rust-libp2p/pull/1515)
|
||||
- `libp2p-swarm`: New `protocols_handler::multi` module.
|
||||
[PR 1497](https://github.com/libp2p/rust-libp2p/pull/1497)
|
||||
- `libp2p-swarm`: Allow configuration of outbound substreams.
|
||||
[PR 1521](https://github.com/libp2p/rust-libp2p/pull/1521)
|
||||
|
||||
- `libp2p-kad`: Providers returned from a lookup are now deduplicated.
|
||||
[PR 1528](https://github.com/libp2p/rust-libp2p/pull/1528)
|
||||
- `libp2p-kad`: Allow customising the maximum packet size.
|
||||
[PR 1502](https://github.com/libp2p/rust-libp2p/pull/1502)
|
||||
- `libp2p-kad`: Allow customising the (libp2p) connection keep-alive timeout.
|
||||
[PR 1477](https://github.com/libp2p/rust-libp2p/pull/1477)
|
||||
- `libp2p-kad`: Avoid storing records that are expired upon receipt (optimisation).
|
||||
[PR 1496](https://github.com/libp2p/rust-libp2p/pull/1496)
|
||||
- `libp2p-kad`: Fixed potential panic on computing record expiry.
|
||||
[PR 1492](https://github.com/libp2p/rust-libp2p/pull/1492)
|
||||
|
||||
- `libp2p-mplex`: Guard against use of underlying `Sink` upon
|
||||
error or connection close.
|
||||
[PR 1529](https://github.com/libp2p/rust-libp2p/pull/1529)
|
||||
|
||||
- `multistream-select`: Upgrade to stable futures.
|
||||
[PR 1484](https://github.com/libp2p/rust-libp2p/pull/1484)
|
||||
|
||||
- `multihash`: Removed the crate in favour of the upstream crate.
|
||||
[PR 1472](https://github.com/libp2p/rust-libp2p/pull/1472)
|
||||
|
||||
# Version 0.16.2 (2020-02-28)
|
||||
|
||||
- Fixed yamux connections not properly closing and being stuck in the `CLOSE_WAIT` state.
|
||||
|
46
Cargo.toml
46
Cargo.toml
@ -2,7 +2,7 @@
|
||||
name = "libp2p"
|
||||
edition = "2018"
|
||||
description = "Peer-to-peer networking library"
|
||||
version = "0.16.2"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -54,36 +54,36 @@ secp256k1 = ["libp2p-core/secp256k1", "libp2p-secio/secp256k1"]
|
||||
[dependencies]
|
||||
bytes = "0.5"
|
||||
futures = "0.3.1"
|
||||
multiaddr = { package = "parity-multiaddr", version = "0.7.2", path = "misc/multiaddr" }
|
||||
multiaddr = { package = "parity-multiaddr", version = "0.8.0", path = "misc/multiaddr" }
|
||||
multihash = "0.10"
|
||||
lazy_static = "1.2"
|
||||
libp2p-mplex = { version = "0.16.0", path = "muxers/mplex", optional = true }
|
||||
libp2p-identify = { version = "0.16.0", path = "protocols/identify", optional = true }
|
||||
libp2p-kad = { version = "0.16.2", path = "protocols/kad", optional = true }
|
||||
libp2p-floodsub = { version = "0.16.0", path = "protocols/floodsub", optional = true }
|
||||
libp2p-gossipsub = { version = "0.16.0", path = "./protocols/gossipsub", optional = true }
|
||||
libp2p-ping = { version = "0.16.0", path = "protocols/ping", optional = true }
|
||||
libp2p-plaintext = { version = "0.16.0", path = "protocols/plaintext", optional = true }
|
||||
libp2p-pnet = { version = "0.16.0", path = "protocols/pnet", optional = true }
|
||||
libp2p-core = { version = "0.16.0", path = "core" }
|
||||
libp2p-core-derive = { version = "0.16.0", path = "misc/core-derive" }
|
||||
libp2p-secio = { version = "0.16.1", path = "protocols/secio", default-features = false, optional = true }
|
||||
libp2p-swarm = { version = "0.16.1", path = "swarm" }
|
||||
libp2p-uds = { version = "0.16.0", path = "transports/uds", optional = true }
|
||||
libp2p-wasm-ext = { version = "0.16.2", path = "transports/wasm-ext", optional = true }
|
||||
libp2p-yamux = { version = "0.16.2", path = "muxers/yamux", optional = true }
|
||||
libp2p-noise = { version = "0.16.2", path = "protocols/noise", optional = true }
|
||||
libp2p-mplex = { version = "0.17.0", path = "muxers/mplex", optional = true }
|
||||
libp2p-identify = { version = "0.17.0", path = "protocols/identify", optional = true }
|
||||
libp2p-kad = { version = "0.17.0", path = "protocols/kad", optional = true }
|
||||
libp2p-floodsub = { version = "0.17.0", path = "protocols/floodsub", optional = true }
|
||||
libp2p-gossipsub = { version = "0.17.0", path = "./protocols/gossipsub", optional = true }
|
||||
libp2p-ping = { version = "0.17.0", path = "protocols/ping", optional = true }
|
||||
libp2p-plaintext = { version = "0.17.0", path = "protocols/plaintext", optional = true }
|
||||
libp2p-pnet = { version = "0.17.0", path = "protocols/pnet", optional = true }
|
||||
libp2p-core = { version = "0.17.1", path = "core" }
|
||||
libp2p-core-derive = { version = "0.17.0", path = "misc/core-derive" }
|
||||
libp2p-secio = { version = "0.17.0", path = "protocols/secio", default-features = false, optional = true }
|
||||
libp2p-swarm = { version = "0.17.0", path = "swarm" }
|
||||
libp2p-uds = { version = "0.17.0", path = "transports/uds", optional = true }
|
||||
libp2p-wasm-ext = { version = "0.17.0", path = "transports/wasm-ext", optional = true }
|
||||
libp2p-yamux = { version = "0.17.0", path = "muxers/yamux", optional = true }
|
||||
libp2p-noise = { version = "0.17.0", path = "protocols/noise", optional = true }
|
||||
parking_lot = "0.10.0"
|
||||
pin-project = "0.4.6"
|
||||
smallvec = "1.0"
|
||||
wasm-timer = "0.2.4"
|
||||
|
||||
[target.'cfg(not(any(target_os = "emscripten", target_os = "unknown")))'.dependencies]
|
||||
libp2p-deflate = { version = "0.16.0", path = "protocols/deflate", optional = true }
|
||||
libp2p-dns = { version = "0.16.0", path = "transports/dns", optional = true }
|
||||
libp2p-mdns = { version = "0.16.0", path = "protocols/mdns", optional = true }
|
||||
libp2p-tcp = { version = "0.16.0", path = "transports/tcp", optional = true }
|
||||
libp2p-websocket = { version = "0.16.0", path = "transports/websocket", optional = true }
|
||||
libp2p-deflate = { version = "0.17.0", path = "protocols/deflate", optional = true }
|
||||
libp2p-dns = { version = "0.17.0", path = "transports/dns", optional = true }
|
||||
libp2p-mdns = { version = "0.17.0", path = "protocols/mdns", optional = true }
|
||||
libp2p-tcp = { version = "0.17.0", path = "transports/tcp", optional = true }
|
||||
libp2p-websocket = { version = "0.17.0", path = "transports/websocket", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
async-std = "1.0"
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-core"
|
||||
edition = "2018"
|
||||
description = "Core traits and structs of libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.1"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -20,9 +20,9 @@ futures-timer = "3"
|
||||
lazy_static = "1.2"
|
||||
libsecp256k1 = { version = "0.3.1", optional = true }
|
||||
log = "0.4"
|
||||
multiaddr = { package = "parity-multiaddr", version = "0.7.3", path = "../misc/multiaddr" }
|
||||
multiaddr = { package = "parity-multiaddr", version = "0.8.0", path = "../misc/multiaddr" }
|
||||
multihash = "0.10"
|
||||
multistream-select = { version = "0.7.0", path = "../misc/multistream-select" }
|
||||
multistream-select = { version = "0.8.0", path = "../misc/multistream-select" }
|
||||
parking_lot = "0.10.0"
|
||||
pin-project = "0.4.6"
|
||||
prost = "0.6.1"
|
||||
@ -40,9 +40,9 @@ ring = { version = "0.16.9", features = ["alloc", "std"], default-features = fal
|
||||
|
||||
[dev-dependencies]
|
||||
async-std = "1.0"
|
||||
libp2p-mplex = { version = "0.16.0", path = "../muxers/mplex" }
|
||||
libp2p-secio = { version = "0.16.0", path = "../protocols/secio" }
|
||||
libp2p-tcp = { version = "0.16.0", path = "../transports/tcp" }
|
||||
libp2p-mplex = { version = "0.17.0", path = "../muxers/mplex" }
|
||||
libp2p-secio = { version = "0.17.0", path = "../protocols/secio" }
|
||||
libp2p-tcp = { version = "0.17.0", path = "../transports/tcp" }
|
||||
quickcheck = "0.9.0"
|
||||
wasm-timer = "0.2"
|
||||
|
||||
|
@ -35,7 +35,7 @@ pub use pool::{EstablishedConnection, EstablishedConnectionIter, PendingConnecti
|
||||
|
||||
use crate::muxing::StreamMuxer;
|
||||
use crate::{Multiaddr, PeerId};
|
||||
use std::{fmt, pin::Pin, task::Context, task::Poll};
|
||||
use std::{error::Error, fmt, pin::Pin, task::Context, task::Poll};
|
||||
use std::hash::Hash;
|
||||
use substream::{Muxing, SubstreamEvent};
|
||||
|
||||
@ -334,3 +334,6 @@ impl fmt::Display for ConnectionLimit {
|
||||
write!(f, "{}/{}", self.current, self.limit)
|
||||
}
|
||||
}
|
||||
|
||||
/// A `ConnectionLimit` can represent an error if it has been exceeded.
|
||||
impl Error for ConnectionLimit {}
|
||||
|
@ -133,7 +133,7 @@ where
|
||||
/// the associated user data.
|
||||
#[derive(Debug)]
|
||||
struct TaskInfo<I, C> {
|
||||
/// channel endpoint to send messages to the task
|
||||
/// Channel endpoint to send messages to the task.
|
||||
sender: mpsc::Sender<task::Command<I>>,
|
||||
/// The state of the task as seen by the `Manager`.
|
||||
state: TaskState<C>,
|
||||
@ -286,40 +286,6 @@ impl<I, O, H, TE, HE, C> Manager<I, O, H, TE, HE, C> {
|
||||
ConnectionId(task_id)
|
||||
}
|
||||
|
||||
/// Notifies the handlers of all managed connections of an event.
|
||||
///
|
||||
/// This function is "atomic", in the sense that if `Poll::Pending` is
|
||||
/// returned then no event has been sent.
|
||||
#[must_use]
|
||||
pub fn poll_broadcast(&mut self, event: &I, cx: &mut Context) -> Poll<()>
|
||||
where
|
||||
I: Clone
|
||||
{
|
||||
for task in self.tasks.values_mut() {
|
||||
if let Poll::Pending = task.sender.poll_ready(cx) { // (*)
|
||||
return Poll::Pending;
|
||||
}
|
||||
}
|
||||
|
||||
for (id, task) in self.tasks.iter_mut() {
|
||||
let cmd = task::Command::NotifyHandler(event.clone());
|
||||
match task.sender.start_send(cmd) {
|
||||
Ok(()) => {},
|
||||
Err(e) if e.is_full() => unreachable!("by (*)"),
|
||||
Err(e) if e.is_disconnected() => {
|
||||
// The background task ended. The manager will eventually be
|
||||
// informed through an `Error` event from the task.
|
||||
log::trace!("Connection dropped: {:?}", id);
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Unexpected error: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Poll::Ready(())
|
||||
}
|
||||
|
||||
/// Gets an entry for a managed connection, if it exists.
|
||||
pub fn entry(&mut self, id: ConnectionId) -> Option<Entry<'_, I, C>> {
|
||||
if let hash_map::Entry::Occupied(task) = self.tasks.entry(id.0) {
|
||||
|
@ -87,7 +87,7 @@ where
|
||||
commands: stream::Fuse<mpsc::Receiver<Command<I>>>,
|
||||
|
||||
/// Inner state of this `Task`.
|
||||
state: State<F, M, H, I, O, E, C>,
|
||||
state: State<F, M, H, O, E, C>,
|
||||
}
|
||||
|
||||
impl<F, M, H, I, O, E, C> Task<F, M, H, I, O, E, C>
|
||||
@ -111,7 +111,6 @@ where
|
||||
state: State::Pending {
|
||||
future: Box::pin(future),
|
||||
handler,
|
||||
events: Vec::new()
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -133,7 +132,7 @@ where
|
||||
}
|
||||
|
||||
/// The state associated with the `Task` of a connection.
|
||||
enum State<F, M, H, I, O, E, C>
|
||||
enum State<F, M, H, O, E, C>
|
||||
where
|
||||
M: StreamMuxer,
|
||||
H: IntoConnectionHandler<C>,
|
||||
@ -146,12 +145,6 @@ where
|
||||
future: Pin<Box<F>>,
|
||||
/// The intended handler for the established connection.
|
||||
handler: H,
|
||||
/// While we are dialing the future, we need to buffer the events received via
|
||||
/// `Command::NotifyHandler` so that they get delivered to the `handler`
|
||||
/// once the connection is established. We can't leave these in `Task::receiver`
|
||||
/// because we have to detect if the connection attempt has been aborted (by
|
||||
/// dropping the corresponding `sender` owned by the manager).
|
||||
events: Vec<I>
|
||||
},
|
||||
|
||||
/// The connection is established and a new event is ready to be emitted.
|
||||
@ -198,30 +191,29 @@ where
|
||||
|
||||
'poll: loop {
|
||||
match std::mem::replace(&mut this.state, State::Done) {
|
||||
State::Pending { mut future, handler, mut events } => {
|
||||
// Process commands from the manager.
|
||||
loop {
|
||||
match Stream::poll_next(Pin::new(&mut this.commands), cx) {
|
||||
Poll::Pending => break,
|
||||
Poll::Ready(None) => return Poll::Ready(()),
|
||||
Poll::Ready(Some(Command::NotifyHandler(event))) =>
|
||||
events.push(event),
|
||||
}
|
||||
State::Pending { mut future, handler } => {
|
||||
// Check if the manager aborted this task by dropping the `commands`
|
||||
// channel sender side.
|
||||
match Stream::poll_next(Pin::new(&mut this.commands), cx) {
|
||||
Poll::Pending => {},
|
||||
Poll::Ready(None) => return Poll::Ready(()),
|
||||
Poll::Ready(Some(Command::NotifyHandler(_))) => unreachable!(
|
||||
"Manager does not allow sending commands to pending tasks.",
|
||||
)
|
||||
}
|
||||
// Check if the connection succeeded.
|
||||
match Future::poll(Pin::new(&mut future), cx) {
|
||||
Poll::Ready(Ok((info, muxer))) => {
|
||||
let mut c = Connection::new(muxer, handler.into_handler(&info));
|
||||
for event in events {
|
||||
c.inject_event(event)
|
||||
}
|
||||
this.state = State::EstablishedReady {
|
||||
connection: Some(c),
|
||||
connection: Some(Connection::new(
|
||||
muxer,
|
||||
handler.into_handler(&info),
|
||||
)),
|
||||
event: Event::Established { id, info }
|
||||
}
|
||||
}
|
||||
Poll::Pending => {
|
||||
this.state = State::Pending { future, handler, events };
|
||||
this.state = State::Pending { future, handler };
|
||||
return Poll::Pending
|
||||
}
|
||||
Poll::Ready(Err(error)) => {
|
||||
@ -338,4 +330,3 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +225,7 @@ where
|
||||
TPeerId: Clone + Send + 'static,
|
||||
{
|
||||
let endpoint = info.to_connected_point();
|
||||
if let Some(limit) = self.limits.max_pending_incoming {
|
||||
if let Some(limit) = self.limits.max_incoming {
|
||||
let current = self.iter_pending_incoming().count();
|
||||
if current >= limit {
|
||||
return Err(ConnectionLimit { limit, current })
|
||||
@ -330,18 +330,6 @@ where
|
||||
id
|
||||
}
|
||||
|
||||
/// Sends an event to all nodes.
|
||||
///
|
||||
/// This function is "atomic", in the sense that if `Poll::Pending` is returned then no event
|
||||
/// has been sent to any node yet.
|
||||
#[must_use]
|
||||
pub fn poll_broadcast(&mut self, event: &TInEvent, cx: &mut Context) -> Poll<()>
|
||||
where
|
||||
TInEvent: Clone
|
||||
{
|
||||
self.manager.poll_broadcast(event, cx)
|
||||
}
|
||||
|
||||
/// Adds an existing established connection to the pool.
|
||||
///
|
||||
/// Returns the assigned connection ID on success. An error is returned
|
||||
@ -846,8 +834,8 @@ where
|
||||
/// The configurable limits of a connection [`Pool`].
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct PoolLimits {
|
||||
pub max_pending_outgoing: Option<usize>,
|
||||
pub max_pending_incoming: Option<usize>,
|
||||
pub max_outgoing: Option<usize>,
|
||||
pub max_incoming: Option<usize>,
|
||||
pub max_established_per_peer: Option<usize>,
|
||||
}
|
||||
|
||||
@ -863,7 +851,7 @@ impl PoolLimits {
|
||||
where
|
||||
F: FnOnce() -> usize
|
||||
{
|
||||
Self::check(current, self.max_pending_outgoing)
|
||||
Self::check(current, self.max_outgoing)
|
||||
}
|
||||
|
||||
fn check<F>(current: F, limit: Option<usize>) -> Result<(), ConnectionLimit>
|
||||
|
@ -220,7 +220,7 @@ where
|
||||
/// [`Connection`](crate::connection::Connection) upon success and the
|
||||
/// connection ID is returned.
|
||||
pub fn dial(&mut self, address: &Multiaddr, handler: THandler)
|
||||
-> Result<ConnectionId, DialError<TTrans::Error>>
|
||||
-> Result<ConnectionId, ConnectionLimit>
|
||||
where
|
||||
TTrans: Transport<Output = (TConnInfo, TMuxer)>,
|
||||
TTrans::Error: Send + 'static,
|
||||
@ -232,10 +232,17 @@ where
|
||||
TConnInfo: Send + 'static,
|
||||
TPeerId: Send + 'static,
|
||||
{
|
||||
let future = self.transport().clone().dial(address.clone())?
|
||||
.map_err(|err| PendingConnectionError::Transport(TransportError::Other(err)));
|
||||
let info = OutgoingInfo { address, peer_id: None };
|
||||
self.pool.add_outgoing(future, handler, info).map_err(DialError::MaxPending)
|
||||
match self.transport().clone().dial(address.clone()) {
|
||||
Ok(f) => {
|
||||
let f = f.map_err(|err| PendingConnectionError::Transport(TransportError::Other(err)));
|
||||
self.pool.add_outgoing(f, handler, info)
|
||||
}
|
||||
Err(err) => {
|
||||
let f = future::err(PendingConnectionError::Transport(err));
|
||||
self.pool.add_outgoing(f, handler, info)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns information about the state of the `Network`.
|
||||
@ -269,24 +276,28 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
/// Notifies the connection handler of _every_ connection of _every_ peer of an event.
|
||||
///
|
||||
/// This function is "atomic", in the sense that if `Poll::Pending` is returned then no event
|
||||
/// has been sent to any node yet.
|
||||
#[must_use]
|
||||
pub fn poll_broadcast(&mut self, event: &TInEvent, cx: &mut Context) -> Poll<()>
|
||||
where
|
||||
TInEvent: Clone
|
||||
{
|
||||
self.pool.poll_broadcast(event, cx)
|
||||
}
|
||||
|
||||
/// Returns a list of all connected peers, i.e. peers to whom the `Network`
|
||||
/// has at least one established connection.
|
||||
pub fn connected_peers(&self) -> impl Iterator<Item = &TPeerId> {
|
||||
self.pool.iter_connected()
|
||||
}
|
||||
|
||||
/// Checks whether the network has an established connection to a peer.
|
||||
pub fn is_connected(&self, peer: &TPeerId) -> bool {
|
||||
self.pool.is_connected(peer)
|
||||
}
|
||||
|
||||
/// Checks whether the network has an ongoing dialing attempt to a peer.
|
||||
pub fn is_dialing(&self, peer: &TPeerId) -> bool {
|
||||
self.dialing.contains_key(peer)
|
||||
}
|
||||
|
||||
/// Checks whether the network has neither an ongoing dialing attempt,
|
||||
/// nor an established connection to a peer.
|
||||
pub fn is_disconnected(&self, peer: &TPeerId) -> bool {
|
||||
!self.is_connected(peer) && !self.is_dialing(peer)
|
||||
}
|
||||
|
||||
/// Returns a list of all the peers to whom a new outgoing connection
|
||||
/// is currently being established.
|
||||
pub fn dialing_peers(&self) -> impl Iterator<Item = &TPeerId> {
|
||||
@ -296,7 +307,7 @@ where
|
||||
/// Gets the configured limit on pending incoming connections,
|
||||
/// i.e. concurrent incoming connection attempts.
|
||||
pub fn incoming_limit(&self) -> Option<usize> {
|
||||
self.pool.limits().max_pending_incoming
|
||||
self.pool.limits().max_incoming
|
||||
}
|
||||
|
||||
/// The total number of established connections in the `Network`.
|
||||
@ -392,8 +403,9 @@ where
|
||||
}
|
||||
event
|
||||
}
|
||||
Poll::Ready(PoolEvent::ConnectionError { connected, error, num_established, .. }) => {
|
||||
Poll::Ready(PoolEvent::ConnectionError { id, connected, error, num_established, .. }) => {
|
||||
NetworkEvent::ConnectionError {
|
||||
id,
|
||||
connected,
|
||||
error,
|
||||
num_established,
|
||||
@ -569,43 +581,6 @@ pub struct NetworkInfo {
|
||||
pub num_connections_established: usize,
|
||||
}
|
||||
|
||||
/// The possible errors of [`Network::dial`].
|
||||
#[derive(Debug)]
|
||||
pub enum DialError<T> {
|
||||
/// The configured limit of pending outgoing connections has been reached.
|
||||
MaxPending(ConnectionLimit),
|
||||
/// A transport error occurred when creating the connection.
|
||||
Transport(TransportError<T>),
|
||||
}
|
||||
|
||||
impl<T> fmt::Display for DialError<T>
|
||||
where T: fmt::Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
DialError::MaxPending(limit) => write!(f, "Dial error (pending limit): {}", limit.current),
|
||||
DialError::Transport(err) => write!(f, "Dial error (transport): {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::error::Error for DialError<T>
|
||||
where T: std::error::Error + 'static,
|
||||
{
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
DialError::MaxPending(_) => None,
|
||||
DialError::Transport(e) => Some(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<TransportError<T>> for DialError<T> {
|
||||
fn from(e: TransportError<T>) -> DialError<T> {
|
||||
DialError::Transport(e)
|
||||
}
|
||||
}
|
||||
|
||||
/// The (optional) configuration for a [`Network`].
|
||||
///
|
||||
/// The default configuration specifies no dedicated task executor
|
||||
@ -622,17 +597,29 @@ impl NetworkConfig {
|
||||
self
|
||||
}
|
||||
|
||||
/// Shortcut for calling `executor` with an object that calls the given closure.
|
||||
pub fn set_executor_fn(mut self, f: impl Fn(Pin<Box<dyn Future<Output = ()> + Send>>) + Send + 'static) -> Self {
|
||||
struct SpawnImpl<F>(F);
|
||||
impl<F: Fn(Pin<Box<dyn Future<Output = ()> + Send>>)> Executor for SpawnImpl<F> {
|
||||
fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
|
||||
(self.0)(f)
|
||||
}
|
||||
}
|
||||
self.set_executor(Box::new(SpawnImpl(f)));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn executor(&self) -> Option<&Box<dyn Executor + Send>> {
|
||||
self.executor.as_ref()
|
||||
}
|
||||
|
||||
pub fn set_pending_incoming_limit(&mut self, n: usize) -> &mut Self {
|
||||
self.pool_limits.max_pending_incoming = Some(n);
|
||||
pub fn set_incoming_limit(&mut self, n: usize) -> &mut Self {
|
||||
self.pool_limits.max_incoming = Some(n);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_pending_outgoing_limit(&mut self, n: usize) -> &mut Self {
|
||||
self.pool_limits.max_pending_outgoing = Some(n);
|
||||
pub fn set_outgoing_limit(&mut self, n: usize) -> &mut Self {
|
||||
self.pool_limits.max_outgoing = Some(n);
|
||||
self
|
||||
}
|
||||
|
||||
@ -641,4 +628,3 @@ impl NetworkConfig {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,8 @@ where
|
||||
///
|
||||
/// The connection is closed as a result of the error.
|
||||
ConnectionError {
|
||||
/// The ID of the connection that encountered an error.
|
||||
id: ConnectionId,
|
||||
/// Information about the connection that encountered the error.
|
||||
connected: Connected<TConnInfo>,
|
||||
/// The error that occurred.
|
||||
|
@ -174,28 +174,66 @@ where
|
||||
TConnInfo: fmt::Debug + ConnectionInfo<PeerId = TPeerId> + Send + 'static,
|
||||
TPeerId: Eq + Hash + Clone + Send + 'static,
|
||||
{
|
||||
/// Checks whether the peer is currently connected.
|
||||
///
|
||||
/// Returns `true` iff [`Peer::into_connected`] returns `Some`.
|
||||
pub fn is_connected(&self) -> bool {
|
||||
match self {
|
||||
Peer::Connected(..) => true,
|
||||
Peer::Dialing(peer) => peer.is_connected(),
|
||||
Peer::Disconnected(..) => false,
|
||||
Peer::Local => false
|
||||
}
|
||||
}
|
||||
|
||||
/// If we are connected, returns the `ConnectedPeer`.
|
||||
/// Checks whether the peer is currently being dialed.
|
||||
///
|
||||
/// Returns `true` iff [`Peer::into_dialing`] returns `Some`.
|
||||
pub fn is_dialing(&self) -> bool {
|
||||
match self {
|
||||
Peer::Dialing(_) => true,
|
||||
Peer::Connected(peer) => peer.is_dialing(),
|
||||
Peer::Disconnected(..) => false,
|
||||
Peer::Local => false
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks whether the peer is currently disconnected.
|
||||
///
|
||||
/// Returns `true` iff [`Peer::into_disconnected`] returns `Some`.
|
||||
pub fn is_disconnected(&self) -> bool {
|
||||
match self {
|
||||
Peer::Disconnected(..) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts the peer into a `ConnectedPeer`, if there an established connection exists.
|
||||
pub fn into_connected(self) -> Option<
|
||||
ConnectedPeer<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>
|
||||
> {
|
||||
match self {
|
||||
Peer::Connected(peer) => Some(peer),
|
||||
_ => None,
|
||||
Peer::Dialing(peer) => peer.into_connected(),
|
||||
Peer::Disconnected(..) => None,
|
||||
Peer::Local => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// If a connection is pending, returns the `DialingPeer`.
|
||||
/// Converts the peer into a `DialingPeer`, if a dialing attempt exists.
|
||||
pub fn into_dialing(self) -> Option<
|
||||
DialingPeer<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>
|
||||
> {
|
||||
match self {
|
||||
Peer::Dialing(peer) => Some(peer),
|
||||
_ => None,
|
||||
Peer::Connected(peer) => peer.into_dialing(),
|
||||
Peer::Disconnected(..) => None,
|
||||
Peer::Local => None
|
||||
}
|
||||
}
|
||||
|
||||
/// If we are not connected, returns the `DisconnectedPeer`.
|
||||
/// Converts the peer into a `DisconnectedPeer`, if neither an established connection
|
||||
/// nor a dialing attempt exists.
|
||||
pub fn into_disconnected(self) -> Option<
|
||||
DisconnectedPeer<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>
|
||||
> {
|
||||
@ -225,6 +263,10 @@ where
|
||||
TConnInfo: ConnectionInfo<PeerId = TPeerId>,
|
||||
TPeerId: Eq + Hash + Clone,
|
||||
{
|
||||
pub fn id(&self) -> &TPeerId {
|
||||
&self.peer_id
|
||||
}
|
||||
|
||||
/// Attempts to establish a new connection to this peer using the given addresses,
|
||||
/// if there is currently no ongoing dialing attempt.
|
||||
///
|
||||
@ -294,7 +336,7 @@ where
|
||||
self.network.dialing.contains_key(&self.peer_id)
|
||||
}
|
||||
|
||||
/// Turns this peer into a [`DialingPeer`], if there is an ongoing
|
||||
/// Converts this peer into a [`DialingPeer`], if there is an ongoing
|
||||
/// dialing attempt, `None` otherwise.
|
||||
pub fn into_dialing(self) -> Option<
|
||||
DialingPeer<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>
|
||||
@ -373,12 +415,34 @@ where
|
||||
TConnInfo: ConnectionInfo<PeerId = TPeerId>,
|
||||
TPeerId: Eq + Hash + Clone,
|
||||
{
|
||||
pub fn id(&self) -> &TPeerId {
|
||||
&self.peer_id
|
||||
}
|
||||
|
||||
/// Disconnects from this peer, closing all pending connections.
|
||||
pub fn disconnect(self) -> DisconnectedPeer<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId> {
|
||||
self.network.disconnect(&self.peer_id);
|
||||
DisconnectedPeer { network: self.network, peer_id: self.peer_id }
|
||||
}
|
||||
|
||||
/// Checks whether there is an established connection to the peer.
|
||||
///
|
||||
/// Returns `true` iff [`DialingPeer::into_connected`] returns `Some`.
|
||||
pub fn is_connected(&self) -> bool {
|
||||
self.network.pool.is_connected(&self.peer_id)
|
||||
}
|
||||
|
||||
/// Converts the peer into a `ConnectedPeer`, if an established connection exists.
|
||||
pub fn into_connected(self)
|
||||
-> Option<ConnectedPeer<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>>
|
||||
{
|
||||
if self.is_connected() {
|
||||
Some(ConnectedPeer { peer_id: self.peer_id, network: self.network })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtains the connection that is currently being established.
|
||||
pub fn connection<'b>(&'b mut self) -> DialingConnection<'b, TInEvent, TConnInfo, TPeerId> {
|
||||
let attempt = match self.network.dialing.entry(self.peer_id.clone()) {
|
||||
@ -452,6 +516,10 @@ where
|
||||
TInEvent: Send + 'static,
|
||||
TOutEvent: Send + 'static,
|
||||
{
|
||||
pub fn id(&self) -> &TPeerId {
|
||||
&self.peer_id
|
||||
}
|
||||
|
||||
/// Attempts to connect to this peer using the given addresses.
|
||||
pub fn connect<TIter>(self, first: Multiaddr, rest: TIter, handler: THandler)
|
||||
-> Result<DialingPeer<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>,
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-core-derive"
|
||||
edition = "2018"
|
||||
description = "Procedural macros of libp2p-core"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -17,4 +17,4 @@ syn = { version = "1.0.8", default-features = false, features = ["clone-impls",
|
||||
quote = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
libp2p = { version = "0.16.0", path = "../.." }
|
||||
libp2p = { version = "0.17.0", path = "../.." }
|
||||
|
@ -131,44 +131,52 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
|
||||
// Build the list of statements to put in the body of `inject_connected()`.
|
||||
let inject_connected_stmts = {
|
||||
let num_fields = data_struct.fields.iter().filter(|f| !is_ignored(f)).count();
|
||||
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
|
||||
if is_ignored(&field) {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(if field_n == num_fields - 1 {
|
||||
match field.ident {
|
||||
Some(ref i) => quote!{ self.#i.inject_connected(peer_id, endpoint); },
|
||||
None => quote!{ self.#field_n.inject_connected(peer_id, endpoint); },
|
||||
}
|
||||
} else {
|
||||
match field.ident {
|
||||
Some(ref i) => quote!{ self.#i.inject_connected(peer_id.clone(), endpoint.clone()); },
|
||||
None => quote!{ self.#field_n.inject_connected(peer_id.clone(), endpoint.clone()); },
|
||||
}
|
||||
Some(match field.ident {
|
||||
Some(ref i) => quote!{ self.#i.inject_connected(peer_id); },
|
||||
None => quote!{ self.#field_n.inject_connected(peer_id); },
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
// Build the list of statements to put in the body of `inject_disconnected()`.
|
||||
let inject_disconnected_stmts = {
|
||||
let num_fields = data_struct.fields.iter().filter(|f| !is_ignored(f)).count();
|
||||
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
|
||||
if is_ignored(&field) {
|
||||
return None;
|
||||
}
|
||||
Some(match field.ident {
|
||||
Some(ref i) => quote!{ self.#i.inject_disconnected(peer_id); },
|
||||
None => quote!{ self.#field_n.inject_disconnected(peer_id); },
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
Some(if field_n == num_fields - 1 {
|
||||
match field.ident {
|
||||
Some(ref i) => quote!{ self.#i.inject_disconnected(peer_id, endpoint); },
|
||||
None => quote!{ self.#field_n.inject_disconnected(peer_id, endpoint); },
|
||||
}
|
||||
} else {
|
||||
match field.ident {
|
||||
Some(ref i) => quote!{ self.#i.inject_disconnected(peer_id, endpoint.clone()); },
|
||||
None => quote!{ self.#field_n.inject_disconnected(peer_id, endpoint.clone()); },
|
||||
}
|
||||
// Build the list of statements to put in the body of `inject_connection_established()`.
|
||||
let inject_connection_established_stmts = {
|
||||
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
|
||||
if is_ignored(&field) {
|
||||
return None;
|
||||
}
|
||||
Some(match field.ident {
|
||||
Some(ref i) => quote!{ self.#i.inject_connection_established(peer_id, connection_id, endpoint); },
|
||||
None => quote!{ self.#field_n.inject_connection_established(peer_id, connection_id, endpoint); },
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
// Build the list of statements to put in the body of `inject_connection_closed()`.
|
||||
let inject_connection_closed_stmts = {
|
||||
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
|
||||
if is_ignored(&field) {
|
||||
return None;
|
||||
}
|
||||
Some(match field.ident {
|
||||
Some(ref i) => quote!{ self.#i.inject_connection_closed(peer_id, connection_id, endpoint); },
|
||||
None => quote!{ self.#field_n.inject_connection_closed(peer_id, connection_id, endpoint); },
|
||||
})
|
||||
})
|
||||
};
|
||||
@ -263,8 +271,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
return None
|
||||
}
|
||||
Some(match field.ident {
|
||||
Some(ref i) => quote!(self.#i.inject_listener_closed(id);),
|
||||
None => quote!(self.#field_n.inject_listener_closed(id);)
|
||||
Some(ref i) => quote!(self.#i.inject_listener_closed(id, reason);),
|
||||
None => quote!(self.#field_n.inject_listener_closed(id, reason);)
|
||||
})
|
||||
})
|
||||
};
|
||||
@ -383,8 +391,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
std::task::Poll::Ready(#network_behaviour_action::DialAddress { address }) => {
|
||||
return std::task::Poll::Ready(#network_behaviour_action::DialAddress { address });
|
||||
}
|
||||
std::task::Poll::Ready(#network_behaviour_action::DialPeer { peer_id }) => {
|
||||
return std::task::Poll::Ready(#network_behaviour_action::DialPeer { peer_id });
|
||||
std::task::Poll::Ready(#network_behaviour_action::DialPeer { peer_id, condition }) => {
|
||||
return std::task::Poll::Ready(#network_behaviour_action::DialPeer { peer_id, condition });
|
||||
}
|
||||
std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { peer_id, handler, event }) => {
|
||||
return std::task::Poll::Ready(#network_behaviour_action::NotifyHandler {
|
||||
@ -421,14 +429,22 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
out
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, peer_id: #peer_id, endpoint: #connected_point) {
|
||||
fn inject_connected(&mut self, peer_id: &#peer_id) {
|
||||
#(#inject_connected_stmts);*
|
||||
}
|
||||
|
||||
fn inject_disconnected(&mut self, peer_id: &#peer_id, endpoint: #connected_point) {
|
||||
fn inject_disconnected(&mut self, peer_id: &#peer_id) {
|
||||
#(#inject_disconnected_stmts);*
|
||||
}
|
||||
|
||||
fn inject_connection_established(&mut self, peer_id: &#peer_id, connection_id: &#connection_id, endpoint: &#connected_point) {
|
||||
#(#inject_connection_established_stmts);*
|
||||
}
|
||||
|
||||
fn inject_connection_closed(&mut self, peer_id: &#peer_id, connection_id: &#connection_id, endpoint: &#connected_point) {
|
||||
#(#inject_connection_closed_stmts);*
|
||||
}
|
||||
|
||||
fn inject_addr_reach_failure(&mut self, peer_id: Option<&#peer_id>, addr: &#multiaddr, error: &dyn std::error::Error) {
|
||||
#(#inject_addr_reach_failure_stmts);*
|
||||
}
|
||||
@ -453,7 +469,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
#(#inject_listener_error_stmts);*
|
||||
}
|
||||
|
||||
fn inject_listener_closed(&mut self, id: #listener_id) {
|
||||
fn inject_listener_closed(&mut self, id: #listener_id, reason: Result<(), &std::io::Error>) {
|
||||
#(#inject_listener_closed_stmts);*
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ description = "Implementation of the multiaddr format"
|
||||
homepage = "https://github.com/libp2p/rust-libp2p"
|
||||
keywords = ["multiaddr", "ipfs"]
|
||||
license = "MIT"
|
||||
version = "0.7.3"
|
||||
version = "0.8.0"
|
||||
|
||||
[dependencies]
|
||||
arrayref = "0.3"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "multistream-select"
|
||||
description = "Multistream-select negotiation protocol for libp2p"
|
||||
version = "0.7.0"
|
||||
version = "0.8.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
|
@ -11,5 +11,5 @@ categories = ["network-programming", "asynchronous"]
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
num_cpus = "1.8"
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-mplex"
|
||||
edition = "2018"
|
||||
description = "Mplex multiplexing protocol for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -14,11 +14,11 @@ bytes = "0.5"
|
||||
fnv = "1.0"
|
||||
futures = "0.3.1"
|
||||
futures_codec = "0.3.4"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
log = "0.4"
|
||||
parking_lot = "0.10"
|
||||
unsigned-varint = { version = "0.3", features = ["futures-codec"] }
|
||||
|
||||
[dev-dependencies]
|
||||
async-std = "1.0"
|
||||
libp2p-tcp = { version = "0.16.0", path = "../../transports/tcp" }
|
||||
libp2p-tcp = { version = "0.17.0", path = "../../transports/tcp" }
|
||||
|
@ -53,7 +53,6 @@ pub struct MplexConfig {
|
||||
|
||||
impl MplexConfig {
|
||||
/// Builds the default configuration.
|
||||
#[inline]
|
||||
pub fn new() -> MplexConfig {
|
||||
Default::default()
|
||||
}
|
||||
@ -62,7 +61,6 @@ impl MplexConfig {
|
||||
/// generated and the connection closes.
|
||||
///
|
||||
/// A limit is necessary in order to avoid DoS attacks.
|
||||
#[inline]
|
||||
pub fn max_substreams(&mut self, max: usize) -> &mut Self {
|
||||
self.max_substreams = max;
|
||||
self
|
||||
@ -71,7 +69,6 @@ impl MplexConfig {
|
||||
/// Sets the maximum number of pending incoming messages.
|
||||
///
|
||||
/// A limit is necessary in order to avoid DoS attacks.
|
||||
#[inline]
|
||||
pub fn max_buffer_len(&mut self, max: usize) -> &mut Self {
|
||||
self.max_buffer_len = max;
|
||||
self
|
||||
@ -80,7 +77,6 @@ impl MplexConfig {
|
||||
/// Sets the behaviour when the maximum buffer length has been reached.
|
||||
///
|
||||
/// See the documentation of `MaxBufferBehaviour`.
|
||||
#[inline]
|
||||
pub fn max_buffer_len_behaviour(&mut self, behaviour: MaxBufferBehaviour) -> &mut Self {
|
||||
self.max_buffer_behaviour = behaviour;
|
||||
self
|
||||
@ -94,7 +90,6 @@ impl MplexConfig {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn upgrade<C>(self, i: C) -> Multiplex<C>
|
||||
where
|
||||
C: AsyncRead + AsyncWrite + Unpin
|
||||
@ -122,7 +117,6 @@ impl MplexConfig {
|
||||
}
|
||||
|
||||
impl Default for MplexConfig {
|
||||
#[inline]
|
||||
fn default() -> MplexConfig {
|
||||
MplexConfig {
|
||||
max_substreams: 128,
|
||||
@ -149,7 +143,6 @@ impl UpgradeInfo for MplexConfig {
|
||||
type Info = &'static [u8];
|
||||
type InfoIter = iter::Once<Self::Info>;
|
||||
|
||||
#[inline]
|
||||
fn protocol_info(&self) -> Self::InfoIter {
|
||||
iter::once(b"/mplex/6.7.0")
|
||||
}
|
||||
@ -334,9 +327,7 @@ where C: AsyncRead + AsyncWrite + Unpin,
|
||||
fn poll_send<C>(inner: &mut MultiplexInner<C>, cx: &mut Context, elem: codec::Elem) -> Poll<Result<(), IoError>>
|
||||
where C: AsyncRead + AsyncWrite + Unpin
|
||||
{
|
||||
if inner.is_shutdown {
|
||||
return Poll::Ready(Err(IoError::new(IoErrorKind::Other, "connection is shut down")))
|
||||
}
|
||||
ensure_no_error_no_close(inner)?;
|
||||
|
||||
inner.notifier_write.insert(cx.waker());
|
||||
|
||||
@ -348,10 +339,26 @@ where C: AsyncRead + AsyncWrite + Unpin
|
||||
}
|
||||
},
|
||||
Poll::Pending => Poll::Pending,
|
||||
Poll::Ready(Err(err)) => Poll::Ready(Err(err))
|
||||
Poll::Ready(Err(err)) => {
|
||||
inner.error = Err(IoError::new(err.kind(), err.to_string()));
|
||||
Poll::Ready(Err(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_no_error_no_close<C>(inner: &mut MultiplexInner<C>) -> Result<(), IoError>
|
||||
where
|
||||
C: AsyncRead + AsyncWrite + Unpin
|
||||
{
|
||||
if inner.is_shutdown {
|
||||
return Err(IoError::new(IoErrorKind::Other, "connection is shut down"))
|
||||
}
|
||||
if let Err(ref e) = inner.error {
|
||||
return Err(IoError::new(e.kind(), e.to_string()))
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<C> StreamMuxer for Multiplex<C>
|
||||
where C: AsyncRead + AsyncWrite + Unpin
|
||||
{
|
||||
@ -418,9 +425,7 @@ where C: AsyncRead + AsyncWrite + Unpin
|
||||
poll_send(&mut inner, cx, elem.clone())
|
||||
},
|
||||
OutboundSubstreamState::Flush => {
|
||||
if inner.is_shutdown {
|
||||
return Poll::Ready(Err(IoError::new(IoErrorKind::Other, "connection is shut down")))
|
||||
}
|
||||
ensure_no_error_no_close(&mut inner)?;
|
||||
let inner = &mut *inner; // Avoids borrow errors
|
||||
inner.notifier_write.insert(cx.waker());
|
||||
Sink::poll_flush(Pin::new(&mut inner.inner), &mut Context::from_waker(&waker_ref(&inner.notifier_write)))
|
||||
@ -438,6 +443,7 @@ where C: AsyncRead + AsyncWrite + Unpin
|
||||
inner.buffer.retain(|elem| {
|
||||
elem.substream_id() != substream.num || elem.endpoint() == Some(Endpoint::Dialer)
|
||||
});
|
||||
inner.error = Err(IoError::new(err.kind(), err.to_string()));
|
||||
return Poll::Ready(Err(err));
|
||||
},
|
||||
};
|
||||
@ -465,7 +471,6 @@ where C: AsyncRead + AsyncWrite + Unpin
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn destroy_outbound(&self, _substream: Self::OutboundSubstream) {
|
||||
// Nothing to do.
|
||||
}
|
||||
@ -548,13 +553,14 @@ where C: AsyncRead + AsyncWrite + Unpin
|
||||
|
||||
fn flush_substream(&self, cx: &mut Context, _substream: &mut Self::Substream) -> Poll<Result<(), IoError>> {
|
||||
let mut inner = self.inner.lock();
|
||||
if inner.is_shutdown {
|
||||
return Poll::Ready(Err(IoError::new(IoErrorKind::Other, "connection is shut down")))
|
||||
}
|
||||
|
||||
ensure_no_error_no_close(&mut inner)?;
|
||||
let inner = &mut *inner; // Avoids borrow errors
|
||||
inner.notifier_write.insert(cx.waker());
|
||||
Sink::poll_flush(Pin::new(&mut inner.inner), &mut Context::from_waker(&waker_ref(&inner.notifier_write)))
|
||||
let result = Sink::poll_flush(Pin::new(&mut inner.inner), &mut Context::from_waker(&waker_ref(&inner.notifier_write)));
|
||||
if let Poll::Ready(Err(err)) = &result {
|
||||
inner.error = Err(IoError::new(err.kind(), err.to_string()));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn shutdown_substream(&self, cx: &mut Context, sub: &mut Self::Substream) -> Poll<Result<(), IoError>> {
|
||||
@ -585,28 +591,42 @@ where C: AsyncRead + AsyncWrite + Unpin
|
||||
self.inner.lock().is_acknowledged
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn close(&self, cx: &mut Context) -> Poll<Result<(), IoError>> {
|
||||
let inner = &mut *self.inner.lock();
|
||||
if inner.is_shutdown {
|
||||
return Poll::Ready(Ok(()))
|
||||
}
|
||||
if let Err(ref e) = inner.error {
|
||||
return Poll::Ready(Err(IoError::new(e.kind(), e.to_string())))
|
||||
}
|
||||
inner.notifier_write.insert(cx.waker());
|
||||
match Sink::poll_close(Pin::new(&mut inner.inner), &mut Context::from_waker(&waker_ref(&inner.notifier_write))) {
|
||||
Poll::Ready(Ok(())) => {
|
||||
inner.is_shutdown = true;
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
|
||||
Poll::Ready(Err(err)) => {
|
||||
inner.error = Err(IoError::new(err.kind(), err.to_string()));
|
||||
Poll::Ready(Err(err))
|
||||
}
|
||||
Poll::Pending => Poll::Pending,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush_all(&self, cx: &mut Context) -> Poll<Result<(), IoError>> {
|
||||
let inner = &mut *self.inner.lock();
|
||||
if inner.is_shutdown {
|
||||
return Poll::Ready(Ok(()))
|
||||
}
|
||||
if let Err(ref e) = inner.error {
|
||||
return Poll::Ready(Err(IoError::new(e.kind(), e.to_string())))
|
||||
}
|
||||
inner.notifier_write.insert(cx.waker());
|
||||
Sink::poll_flush(Pin::new(&mut inner.inner), &mut Context::from_waker(&waker_ref(&inner.notifier_write)))
|
||||
let result = Sink::poll_flush(Pin::new(&mut inner.inner), &mut Context::from_waker(&waker_ref(&inner.notifier_write)));
|
||||
if let Poll::Ready(Err(err)) = &result {
|
||||
inner.error = Err(IoError::new(err.kind(), err.to_string()));
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-yamux"
|
||||
edition = "2018"
|
||||
description = "Yamux multiplexing protocol for libp2p"
|
||||
version = "0.16.2"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -11,7 +11,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
parking_lot = "0.10"
|
||||
thiserror = "1.0"
|
||||
yamux = "0.4.5"
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-deflate"
|
||||
edition = "2018"
|
||||
description = "Deflate encryption protocol for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -11,11 +11,11 @@ categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
flate2 = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
async-std = "1.0"
|
||||
libp2p-tcp = { version = "0.16.0", path = "../../transports/tcp" }
|
||||
libp2p-tcp = { version = "0.17.0", path = "../../transports/tcp" }
|
||||
rand = "0.7"
|
||||
quickcheck = "0.9"
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-floodsub"
|
||||
edition = "2018"
|
||||
description = "Floodsub protocol for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -13,8 +13,8 @@ categories = ["network-programming", "asynchronous"]
|
||||
cuckoofilter = "0.3.2"
|
||||
fnv = "1.0"
|
||||
futures = "0.3.1"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.16.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.17.0", path = "../../swarm" }
|
||||
prost = "0.6.1"
|
||||
rand = "0.7"
|
||||
smallvec = "1.0"
|
||||
|
@ -22,14 +22,15 @@ use crate::protocol::{FloodsubConfig, FloodsubMessage, FloodsubRpc, FloodsubSubs
|
||||
use crate::topic::Topic;
|
||||
use cuckoofilter::CuckooFilter;
|
||||
use fnv::FnvHashSet;
|
||||
use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, connection::ConnectionId};
|
||||
use libp2p_core::{Multiaddr, PeerId, connection::ConnectionId};
|
||||
use libp2p_swarm::{
|
||||
NetworkBehaviour,
|
||||
NetworkBehaviourAction,
|
||||
PollParameters,
|
||||
ProtocolsHandler,
|
||||
OneShotHandler,
|
||||
NotifyHandler
|
||||
NotifyHandler,
|
||||
DialPeerCondition,
|
||||
};
|
||||
use rand;
|
||||
use smallvec::SmallVec;
|
||||
@ -96,7 +97,9 @@ impl Floodsub {
|
||||
}
|
||||
|
||||
if self.target_peers.insert(peer_id.clone()) {
|
||||
self.events.push_back(NetworkBehaviourAction::DialPeer { peer_id });
|
||||
self.events.push_back(NetworkBehaviourAction::DialPeer {
|
||||
peer_id, condition: DialPeerCondition::Disconnected
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,9 +239,9 @@ impl NetworkBehaviour for Floodsub {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, id: PeerId, _: ConnectedPoint) {
|
||||
fn inject_connected(&mut self, id: &PeerId) {
|
||||
// We need to send our subscriptions to the newly-connected node.
|
||||
if self.target_peers.contains(&id) {
|
||||
if self.target_peers.contains(id) {
|
||||
for topic in self.subscribed_topics.iter().cloned() {
|
||||
self.events.push_back(NetworkBehaviourAction::NotifyHandler {
|
||||
peer_id: id.clone(),
|
||||
@ -257,14 +260,17 @@ impl NetworkBehaviour for Floodsub {
|
||||
self.connected_peers.insert(id.clone(), SmallVec::new());
|
||||
}
|
||||
|
||||
fn inject_disconnected(&mut self, id: &PeerId, _: ConnectedPoint) {
|
||||
fn inject_disconnected(&mut self, id: &PeerId) {
|
||||
let was_in = self.connected_peers.remove(id);
|
||||
debug_assert!(was_in.is_some());
|
||||
|
||||
// We can be disconnected by the remote in case of inactivity for example, so we always
|
||||
// try to reconnect.
|
||||
if self.target_peers.contains(id) {
|
||||
self.events.push_back(NetworkBehaviourAction::DialPeer { peer_id: id.clone() });
|
||||
self.events.push_back(NetworkBehaviourAction::DialPeer {
|
||||
peer_id: id.clone(),
|
||||
condition: DialPeerCondition::Disconnected
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-gossipsub"
|
||||
edition = "2018"
|
||||
description = "Gossipsub protocol for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Age Manning <Age@AgeManning.com>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -10,8 +10,8 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
libp2p-swarm = { version = "0.16.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.17.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
bytes = "0.5.4"
|
||||
byteorder = "1.3.2"
|
||||
fnv = "1.0.6"
|
||||
@ -30,8 +30,8 @@ prost = "0.6.1"
|
||||
[dev-dependencies]
|
||||
async-std = "1.4.0"
|
||||
env_logger = "0.7.1"
|
||||
libp2p-plaintext = { version = "0.16.0", path = "../plaintext" }
|
||||
libp2p-yamux = { version = "0.16.0", path = "../../muxers/yamux" }
|
||||
libp2p-plaintext = { version = "0.17.0", path = "../plaintext" }
|
||||
libp2p-yamux = { version = "0.17.0", path = "../../muxers/yamux" }
|
||||
quickcheck = "0.9.2"
|
||||
|
||||
[build-dependencies]
|
||||
|
@ -27,7 +27,7 @@ use crate::protocol::{
|
||||
};
|
||||
use crate::topic::{Topic, TopicHash};
|
||||
use futures::prelude::*;
|
||||
use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, connection::ConnectionId};
|
||||
use libp2p_core::{Multiaddr, PeerId, connection::ConnectionId};
|
||||
use libp2p_swarm::{
|
||||
NetworkBehaviour,
|
||||
NetworkBehaviourAction,
|
||||
@ -1012,7 +1012,7 @@ impl NetworkBehaviour for Gossipsub {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, id: PeerId, _: ConnectedPoint) {
|
||||
fn inject_connected(&mut self, id: &PeerId) {
|
||||
info!("New peer connected: {:?}", id);
|
||||
// We need to send our subscriptions to the newly-connected node.
|
||||
let mut subscriptions = vec![];
|
||||
@ -1040,7 +1040,7 @@ impl NetworkBehaviour for Gossipsub {
|
||||
self.peer_topics.insert(id.clone(), Vec::new());
|
||||
}
|
||||
|
||||
fn inject_disconnected(&mut self, id: &PeerId, _: ConnectedPoint) {
|
||||
fn inject_disconnected(&mut self, id: &PeerId) {
|
||||
// remove from mesh, topic_peers, peer_topic and fanout
|
||||
debug!("Peer disconnected: {:?}", id);
|
||||
{
|
||||
@ -1164,8 +1164,8 @@ impl NetworkBehaviour for Gossipsub {
|
||||
NetworkBehaviourAction::DialAddress { address } => {
|
||||
return Poll::Ready(NetworkBehaviourAction::DialAddress { address });
|
||||
}
|
||||
NetworkBehaviourAction::DialPeer { peer_id } => {
|
||||
return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id });
|
||||
NetworkBehaviourAction::DialPeer { peer_id, condition } => {
|
||||
return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition });
|
||||
}
|
||||
NetworkBehaviourAction::ReportObservedAddr { address } => {
|
||||
return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address });
|
||||
|
@ -49,17 +49,13 @@ mod tests {
|
||||
|
||||
// build and connect peer_no random peers
|
||||
let mut peers = vec![];
|
||||
let dummy_connected_point = ConnectedPoint::Dialer {
|
||||
address: "/ip4/0.0.0.0/tcp/0".parse().unwrap(),
|
||||
};
|
||||
|
||||
for _ in 0..peer_no {
|
||||
let peer = PeerId::random();
|
||||
peers.push(peer.clone());
|
||||
<Gossipsub as NetworkBehaviour>::inject_connected(
|
||||
&mut gs,
|
||||
peer.clone(),
|
||||
dummy_connected_point.clone(),
|
||||
&peer,
|
||||
);
|
||||
if to_subscribe {
|
||||
gs.handle_received_subscriptions(
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-identify"
|
||||
edition = "2018"
|
||||
description = "Nodes identifcation protocol for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -11,8 +11,8 @@ categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.16.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.17.0", path = "../../swarm" }
|
||||
log = "0.4.1"
|
||||
prost = "0.6.1"
|
||||
smallvec = "1.0"
|
||||
@ -20,9 +20,9 @@ wasm-timer = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
async-std = "1.0"
|
||||
libp2p-mplex = { version = "0.16.0", path = "../../muxers/mplex" }
|
||||
libp2p-secio = { version = "0.16.0", path = "../../protocols/secio" }
|
||||
libp2p-tcp = { version = "0.16.0", path = "../../transports/tcp" }
|
||||
libp2p-mplex = { version = "0.17.0", path = "../../muxers/mplex" }
|
||||
libp2p-secio = { version = "0.17.0", path = "../../protocols/secio" }
|
||||
libp2p-tcp = { version = "0.17.0", path = "../../transports/tcp" }
|
||||
|
||||
[build-dependencies]
|
||||
prost-build = "0.6"
|
||||
|
@ -37,7 +37,13 @@ use libp2p_swarm::{
|
||||
ProtocolsHandler,
|
||||
ProtocolsHandlerUpgrErr
|
||||
};
|
||||
use std::{collections::HashMap, collections::VecDeque, io, pin::Pin, task::Context, task::Poll};
|
||||
use std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
io,
|
||||
pin::Pin,
|
||||
task::Context,
|
||||
task::Poll
|
||||
};
|
||||
|
||||
/// Network behaviour that automatically identifies nodes periodically, returns information
|
||||
/// about them, and answers identify queries from other nodes.
|
||||
@ -49,7 +55,7 @@ pub struct Identify {
|
||||
/// The public key of the local node. To report on the wire.
|
||||
local_public_key: PublicKey,
|
||||
/// For each peer we're connected to, the observed address to send back to it.
|
||||
observed_addresses: HashMap<PeerId, Multiaddr>,
|
||||
observed_addresses: HashMap<PeerId, HashMap<ConnectionId, Multiaddr>>,
|
||||
/// Pending replies to send.
|
||||
pending_replies: VecDeque<Reply>,
|
||||
/// Pending events to be emitted when polled.
|
||||
@ -97,23 +103,32 @@ impl NetworkBehaviour for Identify {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) {
|
||||
let observed = match endpoint {
|
||||
ConnectedPoint::Dialer { address } => address,
|
||||
ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr,
|
||||
};
|
||||
|
||||
self.observed_addresses.insert(peer_id, observed);
|
||||
fn inject_connected(&mut self, _: &PeerId) {
|
||||
}
|
||||
|
||||
fn inject_disconnected(&mut self, peer_id: &PeerId, _: ConnectedPoint) {
|
||||
fn inject_connection_established(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) {
|
||||
let addr = match endpoint {
|
||||
ConnectedPoint::Dialer { address } => address.clone(),
|
||||
ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr.clone(),
|
||||
};
|
||||
|
||||
self.observed_addresses.entry(peer_id.clone()).or_default().insert(*conn, addr);
|
||||
}
|
||||
|
||||
fn inject_connection_closed(&mut self, peer_id: &PeerId, conn: &ConnectionId, _: &ConnectedPoint) {
|
||||
if let Some(addrs) = self.observed_addresses.get_mut(peer_id) {
|
||||
addrs.remove(conn);
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_disconnected(&mut self, peer_id: &PeerId) {
|
||||
self.observed_addresses.remove(peer_id);
|
||||
}
|
||||
|
||||
fn inject_event(
|
||||
&mut self,
|
||||
peer_id: PeerId,
|
||||
_connection: ConnectionId,
|
||||
connection: ConnectionId,
|
||||
event: <Self::ProtocolsHandler as ProtocolsHandler>::OutEvent,
|
||||
) {
|
||||
match event {
|
||||
@ -132,9 +147,9 @@ impl NetworkBehaviour for Identify {
|
||||
}
|
||||
IdentifyHandlerEvent::Identify(sender) => {
|
||||
let observed = self.observed_addresses.get(&peer_id)
|
||||
.expect("We only receive events from nodes we're connected to. We insert \
|
||||
into the hashmap when we connect to a node and remove only when we \
|
||||
disconnect; QED");
|
||||
.and_then(|addrs| addrs.get(&connection))
|
||||
.expect("`inject_event` is only called with an established connection \
|
||||
and `inject_connection_established` ensures there is an entry; qed");
|
||||
self.pending_replies.push_back(
|
||||
Reply::Queued {
|
||||
peer: peer_id,
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-kad"
|
||||
edition = "2018"
|
||||
description = "Kademlia protocol for libp2p"
|
||||
version = "0.16.2"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -17,8 +17,8 @@ fnv = "1.0"
|
||||
futures_codec = "0.3.4"
|
||||
futures = "0.3.1"
|
||||
log = "0.4"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.16.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.17.0", path = "../../swarm" }
|
||||
multihash = "0.10"
|
||||
prost = "0.6.1"
|
||||
rand = "0.7.2"
|
||||
@ -34,8 +34,8 @@ derivative = "2.0.2"
|
||||
trust-graph = { git = "ssh://git@github.com/fluencelabs/arqada.git", branch = "master" }
|
||||
|
||||
[dev-dependencies]
|
||||
libp2p-secio = { version = "0.16.0", path = "../secio" }
|
||||
libp2p-yamux = { version = "0.16.0", path = "../../muxers/yamux" }
|
||||
libp2p-secio = { version = "0.17.0", path = "../secio" }
|
||||
libp2p-yamux = { version = "0.17.0", path = "../../muxers/yamux" }
|
||||
quickcheck = "0.9.0"
|
||||
|
||||
[build-dependencies]
|
||||
|
@ -34,6 +34,7 @@ use crate::contact::Contact;
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, connection::ConnectionId, multiaddr};
|
||||
use libp2p_swarm::{
|
||||
DialPeerCondition,
|
||||
NetworkBehaviour,
|
||||
NetworkBehaviourAction,
|
||||
NotifyHandler,
|
||||
@ -43,7 +44,7 @@ use libp2p_swarm::{
|
||||
use log::{info, debug, warn};
|
||||
use smallvec::SmallVec;
|
||||
use std::{borrow::{Borrow, Cow}, error, iter, time::Duration};
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::{HashSet, VecDeque};
|
||||
use std::num::NonZeroUsize;
|
||||
use std::task::{Context, Poll};
|
||||
use wasm_timer::Instant;
|
||||
@ -546,7 +547,7 @@ where
|
||||
self.print_bucket_table();
|
||||
let info = QueryInfo::GetProviders {
|
||||
key: key.clone(),
|
||||
providers: Vec::new(),
|
||||
providers: HashSet::new(),
|
||||
};
|
||||
let target = kbucket::Key::new(key);
|
||||
debug!(
|
||||
@ -1228,12 +1229,25 @@ where
|
||||
peer_addrs
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, peer: PeerId, endpoint: ConnectedPoint) {
|
||||
fn inject_connection_established(&mut self, peer: &PeerId, _: &ConnectionId, endpoint: &ConnectedPoint) {
|
||||
// The remote's address can only be put into the routing table,
|
||||
// and thus shared with other nodes, if the local node is the dialer,
|
||||
// since the remote address on an inbound connection is specific to
|
||||
// that connection (e.g. typically the TCP port numbers).
|
||||
let address = match endpoint {
|
||||
ConnectedPoint::Dialer { address } => Some(address.clone()),
|
||||
ConnectedPoint::Listener { .. } => None,
|
||||
};
|
||||
|
||||
self.connection_updated(peer.clone(), address, NodeStatus::Connected);
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, peer: &PeerId) {
|
||||
// Queue events for sending pending RPCs to the connected peer.
|
||||
// There can be only one pending RPC for a particular peer and query per definition.
|
||||
for (peer_id, event) in self.queries.iter_mut().filter_map(|q|
|
||||
q.inner.pending_rpcs.iter()
|
||||
.position(|(p, _)| p == &peer)
|
||||
.position(|(p, _)| p == peer)
|
||||
.map(|p| q.inner.pending_rpcs.remove(p)))
|
||||
{
|
||||
self.queued_events.push_back(NetworkBehaviourAction::NotifyHandler {
|
||||
@ -1312,7 +1326,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_disconnected(&mut self, id: &PeerId, _old_endpoint: ConnectedPoint) {
|
||||
fn inject_disconnected(&mut self, id: &PeerId) {
|
||||
for query in self.queries.iter_mut() {
|
||||
query.on_failure(id);
|
||||
}
|
||||
@ -1378,7 +1392,7 @@ where
|
||||
providers, ..
|
||||
} = &mut query.inner.info {
|
||||
for peer in provider_peers {
|
||||
providers.push(peer.node_id);
|
||||
providers.insert(peer.node_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1587,7 +1601,7 @@ where
|
||||
} else if &peer_id != self.kbuckets.local_key().preimage() {
|
||||
query.inner.pending_rpcs.push((peer_id.clone(), event));
|
||||
self.queued_events.push_back(NetworkBehaviourAction::DialPeer {
|
||||
peer_id
|
||||
peer_id, condition: DialPeerCondition::Disconnected
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1851,7 +1865,7 @@ pub type GetProvidersResult = Result<GetProvidersOk, GetProvidersError>;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GetProvidersOk {
|
||||
pub key: record::Key,
|
||||
pub providers: Vec<PeerId>,
|
||||
pub providers: HashSet<PeerId>,
|
||||
pub closest_peers: Vec<PeerId>
|
||||
}
|
||||
|
||||
@ -1860,7 +1874,7 @@ pub struct GetProvidersOk {
|
||||
pub enum GetProvidersError {
|
||||
Timeout {
|
||||
key: record::Key,
|
||||
providers: Vec<PeerId>,
|
||||
providers: HashSet<PeerId>,
|
||||
closest_peers: Vec<PeerId>
|
||||
}
|
||||
}
|
||||
@ -2010,7 +2024,7 @@ enum QueryInfo {
|
||||
/// The key for which to search for providers.
|
||||
key: record::Key,
|
||||
/// The found providers.
|
||||
providers: Vec<PeerId>,
|
||||
providers: HashSet<PeerId>,
|
||||
},
|
||||
|
||||
/// A query that searches for the closest closest nodes to a key to be
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "libp2p-mdns"
|
||||
edition = "2018"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
description = "Implementation of the libp2p mDNS discovery method"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
@ -16,8 +16,8 @@ dns-parser = "0.8"
|
||||
either = "1.5.3"
|
||||
futures = "0.3.1"
|
||||
lazy_static = "1.2"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.16.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.17.0", path = "../../swarm" }
|
||||
log = "0.4"
|
||||
net2 = "0.2"
|
||||
rand = "0.7"
|
||||
|
@ -21,7 +21,6 @@
|
||||
use crate::service::{MdnsService, MdnsPacket, build_query_response, build_service_discovery_response};
|
||||
use futures::prelude::*;
|
||||
use libp2p_core::{
|
||||
ConnectedPoint,
|
||||
Multiaddr,
|
||||
PeerId,
|
||||
address_translation,
|
||||
@ -199,9 +198,9 @@ impl NetworkBehaviour for Mdns {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, _: PeerId, _: ConnectedPoint) {}
|
||||
fn inject_connected(&mut self, _: &PeerId) {}
|
||||
|
||||
fn inject_disconnected(&mut self, _: &PeerId, _: ConnectedPoint) {}
|
||||
fn inject_disconnected(&mut self, _: &PeerId) {}
|
||||
|
||||
fn inject_event(
|
||||
&mut self,
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "libp2p-noise"
|
||||
description = "Cryptographic handshake protocol using the noise framework."
|
||||
version = "0.16.2"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -11,7 +11,7 @@ edition = "2018"
|
||||
curve25519-dalek = "2.0.0"
|
||||
futures = "0.3.1"
|
||||
lazy_static = "1.2"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
log = "0.4"
|
||||
prost = "0.6.1"
|
||||
rand = "0.7.2"
|
||||
@ -28,7 +28,7 @@ snow = { version = "0.6.1", features = ["default-resolver"], default-features =
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.7.1"
|
||||
libp2p-tcp = { version = "0.16.0", path = "../../transports/tcp" }
|
||||
libp2p-tcp = { version = "0.17.0", path = "../../transports/tcp" }
|
||||
quickcheck = "0.9.0"
|
||||
sodiumoxide = "^0.2.5"
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-ping"
|
||||
edition = "2018"
|
||||
description = "Ping protocol for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -11,8 +11,8 @@ categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.16.0", path = "../../swarm" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
libp2p-swarm = { version = "0.17.0", path = "../../swarm" }
|
||||
log = "0.4.1"
|
||||
rand = "0.7.2"
|
||||
void = "1.0"
|
||||
@ -20,7 +20,7 @@ wasm-timer = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
async-std = "1.0"
|
||||
libp2p-tcp = { version = "0.16.0", path = "../../transports/tcp" }
|
||||
libp2p-secio = { version = "0.16.0", path = "../../protocols/secio" }
|
||||
libp2p-yamux = { version = "0.16.0", path = "../../muxers/yamux" }
|
||||
libp2p-tcp = { version = "0.17.0", path = "../../transports/tcp" }
|
||||
libp2p-secio = { version = "0.17.0", path = "../../protocols/secio" }
|
||||
libp2p-yamux = { version = "0.17.0", path = "../../muxers/yamux" }
|
||||
quickcheck = "0.9.0"
|
||||
|
@ -47,7 +47,7 @@ pub mod handler;
|
||||
pub use handler::{PingConfig, PingResult, PingSuccess, PingFailure};
|
||||
use handler::PingHandler;
|
||||
|
||||
use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, connection::ConnectionId};
|
||||
use libp2p_core::{Multiaddr, PeerId, connection::ConnectionId};
|
||||
use libp2p_swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters};
|
||||
use std::{collections::VecDeque, task::Context, task::Poll};
|
||||
use void::Void;
|
||||
@ -100,9 +100,9 @@ impl NetworkBehaviour for Ping {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, _: PeerId, _: ConnectedPoint) {}
|
||||
fn inject_connected(&mut self, _: &PeerId) {}
|
||||
|
||||
fn inject_disconnected(&mut self, _: &PeerId, _: ConnectedPoint) {}
|
||||
fn inject_disconnected(&mut self, _: &PeerId) {}
|
||||
|
||||
fn inject_event(&mut self, peer: PeerId, _: ConnectionId, result: PingResult) {
|
||||
self.events.push_front(PingEvent { peer, result })
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-plaintext"
|
||||
edition = "2018"
|
||||
description = "Plaintext encryption dummy protocol for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -13,7 +13,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
bytes = "0.5"
|
||||
futures = "0.3.1"
|
||||
futures_codec = "0.3.4"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
log = "0.4.8"
|
||||
prost = "0.6.1"
|
||||
rw-stream-sink = "0.2.0"
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-pnet"
|
||||
edition = "2018"
|
||||
description = "Private swarm support for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-secio"
|
||||
edition = "2018"
|
||||
description = "Secio encryption protocol for libp2p"
|
||||
version = "0.16.1"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -16,7 +16,7 @@ ctr = "0.3"
|
||||
futures = "0.3.1"
|
||||
hmac = "0.7.0"
|
||||
lazy_static = "1.2.0"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
log = "0.4.6"
|
||||
prost = "0.6.1"
|
||||
pin-project = "0.4.6"
|
||||
@ -48,8 +48,8 @@ aes-all = ["aesni"]
|
||||
[dev-dependencies]
|
||||
async-std = "1.0"
|
||||
criterion = "0.3"
|
||||
libp2p-mplex = { version = "0.16.0", path = "../../muxers/mplex" }
|
||||
libp2p-tcp = { version = "0.16.0", path = "../../transports/tcp" }
|
||||
libp2p-mplex = { version = "0.17.0", path = "../../muxers/mplex" }
|
||||
libp2p-tcp = { version = "0.17.0", path = "../../transports/tcp" }
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-swarm"
|
||||
edition = "2018"
|
||||
description = "The libp2p swarm"
|
||||
version = "0.16.1"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -11,7 +11,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
libp2p-core = { version = "0.16.0", path = "../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../core" }
|
||||
log = "0.4"
|
||||
rand = "0.7"
|
||||
smallvec = "1.0"
|
||||
@ -19,6 +19,6 @@ wasm-timer = "0.2"
|
||||
void = "1"
|
||||
|
||||
[dev-dependencies]
|
||||
libp2p-mplex = { version = "0.16.0", path = "../muxers/mplex" }
|
||||
libp2p-mplex = { version = "0.17.0", path = "../muxers/mplex" }
|
||||
quickcheck = "0.9.0"
|
||||
rand = "0.7.2"
|
||||
|
@ -72,18 +72,34 @@ pub trait NetworkBehaviour: Send + 'static {
|
||||
/// address should be the most likely to be reachable.
|
||||
fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec<Multiaddr>;
|
||||
|
||||
/// Indicates the behaviour that we connected to the node with the given peer id through the
|
||||
/// given endpoint.
|
||||
/// Indicates the behaviour that we connected to the node with the given peer id.
|
||||
///
|
||||
/// This node now has a handler (as spawned by `new_handler`) running in the background.
|
||||
fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint);
|
||||
///
|
||||
/// This method is only called when the connection to the peer is
|
||||
/// established, preceded by `inject_connection_established`.
|
||||
fn inject_connected(&mut self, peer_id: &PeerId);
|
||||
|
||||
/// Indicates the behaviour that we disconnected from the node with the given peer id. The
|
||||
/// endpoint is the one we used to be connected to.
|
||||
/// Indicates the behaviour that we disconnected from the node with the given peer id.
|
||||
///
|
||||
/// There is no handler running anymore for this node. Any event that has been sent to it may
|
||||
/// or may not have been processed by the handler.
|
||||
fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint);
|
||||
///
|
||||
/// This method is only called when the last established connection to the peer
|
||||
/// is closed, preceded by `inject_connection_closed`.
|
||||
fn inject_disconnected(&mut self, peer_id: &PeerId);
|
||||
|
||||
/// Informs the behaviour about a newly established connection to a peer.
|
||||
fn inject_connection_established(&mut self, _: &PeerId, _: &ConnectionId, _: &ConnectedPoint)
|
||||
{}
|
||||
|
||||
/// Informs the behaviour about a closed connection to a peer.
|
||||
///
|
||||
/// A call to this method is always paired with an earlier call to
|
||||
/// `inject_connection_established` with the same peer ID, connection ID and
|
||||
/// endpoint.
|
||||
fn inject_connection_closed(&mut self, _: &PeerId, _: &ConnectionId, _: &ConnectedPoint)
|
||||
{}
|
||||
|
||||
/// Informs the behaviour about an event generated by the handler dedicated to the peer identified by `peer_id`.
|
||||
/// for the behaviour.
|
||||
@ -130,7 +146,7 @@ pub trait NetworkBehaviour: Send + 'static {
|
||||
}
|
||||
|
||||
/// A listener closed.
|
||||
fn inject_listener_closed(&mut self, _id: ListenerId) {
|
||||
fn inject_listener_closed(&mut self, _id: ListenerId, _reason: Result<(), &std::io::Error>) {
|
||||
}
|
||||
|
||||
/// Polls for things that swarm should do.
|
||||
@ -204,6 +220,8 @@ pub enum NetworkBehaviourAction<TInEvent, TOutEvent> {
|
||||
DialPeer {
|
||||
/// The peer to try reach.
|
||||
peer_id: PeerId,
|
||||
/// The condition for initiating a new dialing attempt.
|
||||
condition: DialPeerCondition,
|
||||
},
|
||||
|
||||
/// Instructs the `Swarm` to send an event to the handler dedicated to a
|
||||
@ -253,3 +271,36 @@ pub enum NotifyHandler {
|
||||
All
|
||||
}
|
||||
|
||||
/// The available conditions under which a new dialing attempt to
|
||||
/// a peer is initiated when requested by [`NetworkBehaviourAction::DialPeer`].
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum DialPeerCondition {
|
||||
/// A new dialing attempt is initiated _only if_ the peer is currently
|
||||
/// considered disconnected, i.e. there is no established connection
|
||||
/// and no ongoing dialing attempt.
|
||||
///
|
||||
/// If there is an ongoing dialing attempt, the addresses reported by
|
||||
/// [`NetworkBehaviour::addresses_of_peer`] are added to the ongoing
|
||||
/// dialing attempt, ignoring duplicates.
|
||||
Disconnected,
|
||||
/// A new dialing attempt is initiated _only if_ there is currently
|
||||
/// no ongoing dialing attempt, i.e. the peer is either considered
|
||||
/// disconnected or connected but without an ongoing dialing attempt.
|
||||
///
|
||||
/// If there is an ongoing dialing attempt, the addresses reported by
|
||||
/// [`NetworkBehaviour::addresses_of_peer`] are added to the ongoing
|
||||
/// dialing attempt, ignoring duplicates.
|
||||
///
|
||||
/// This condition implies [`DialPeerCondition::Disconnected`].
|
||||
NotDialing,
|
||||
// TODO: Once multiple dialing attempts per peer are permitted.
|
||||
// See https://github.com/libp2p/rust-libp2p/pull/1506.
|
||||
// Always,
|
||||
}
|
||||
|
||||
impl Default for DialPeerCondition {
|
||||
fn default() -> Self {
|
||||
DialPeerCondition::Disconnected
|
||||
}
|
||||
}
|
||||
|
245
swarm/src/lib.rs
245
swarm/src/lib.rs
@ -65,7 +65,8 @@ pub use behaviour::{
|
||||
NetworkBehaviourAction,
|
||||
NetworkBehaviourEventProcess,
|
||||
PollParameters,
|
||||
NotifyHandler
|
||||
NotifyHandler,
|
||||
DialPeerCondition
|
||||
};
|
||||
pub use protocols_handler::{
|
||||
IntoProtocolsHandler,
|
||||
@ -76,6 +77,7 @@ pub use protocols_handler::{
|
||||
ProtocolsHandlerSelect,
|
||||
ProtocolsHandlerUpgrErr,
|
||||
OneShotHandler,
|
||||
OneShotHandlerConfig,
|
||||
SubstreamProtocol
|
||||
};
|
||||
|
||||
@ -89,7 +91,6 @@ use futures::{
|
||||
stream::FusedStream,
|
||||
};
|
||||
use libp2p_core::{
|
||||
ConnectedPoint,
|
||||
Executor,
|
||||
Transport,
|
||||
Multiaddr,
|
||||
@ -99,6 +100,8 @@ use libp2p_core::{
|
||||
ConnectionError,
|
||||
ConnectionId,
|
||||
ConnectionInfo,
|
||||
ConnectionLimit,
|
||||
ConnectedPoint,
|
||||
EstablishedConnection,
|
||||
IntoConnectionHandler,
|
||||
ListenerId,
|
||||
@ -108,7 +111,6 @@ use libp2p_core::{
|
||||
transport::{TransportError, boxed::Boxed as BoxTransport},
|
||||
muxing::{StreamMuxer, StreamMuxerBox},
|
||||
network::{
|
||||
DialError,
|
||||
Network,
|
||||
NetworkInfo,
|
||||
NetworkEvent,
|
||||
@ -201,12 +203,6 @@ pub enum SwarmEvent<TBvEv, THandleErr> {
|
||||
/// Endpoint of the connection that has been closed.
|
||||
endpoint: ConnectedPoint,
|
||||
},
|
||||
/// Starting to try to reach the given peer.
|
||||
///
|
||||
/// We are trying to connect to this peer until a [`ConnectionEstablished`](SwarmEvent::ConnectionEstablished)
|
||||
/// event is reported, or a [`UnreachableAddr`](SwarmEvent::UnreachableAddr) event is reported
|
||||
/// with `attempts_remaining` equal to 0.
|
||||
Dialing(PeerId),
|
||||
/// Tried to dial an address but it ended up being unreachaable.
|
||||
UnreachableAddr {
|
||||
/// `PeerId` that we were trying to reach.
|
||||
@ -246,6 +242,13 @@ pub enum SwarmEvent<TBvEv, THandleErr> {
|
||||
/// The listener error.
|
||||
error: io::Error,
|
||||
},
|
||||
/// A new dialing attempt has been initiated.
|
||||
///
|
||||
/// A [`ConnectionEstablished`](SwarmEvent::ConnectionEstablished)
|
||||
/// event is reported if the dialing attempt succeeds, otherwise a
|
||||
/// [`UnreachableAddr`](SwarmEvent::UnreachableAddr) event is reported
|
||||
/// with `attempts_remaining` equal to 0.
|
||||
Dialing(PeerId),
|
||||
}
|
||||
|
||||
/// Contains the state of the network, plus the way it should behave.
|
||||
@ -367,31 +370,65 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
/// Tries to dial the given address.
|
||||
///
|
||||
/// Returns an error if the address is not supported.
|
||||
pub fn dial_addr(me: &mut Self, addr: Multiaddr) -> Result<(), DialError<io::Error>> {
|
||||
pub fn dial_addr(me: &mut Self, addr: Multiaddr) -> Result<(), ConnectionLimit> {
|
||||
let handler = me.behaviour.new_handler();
|
||||
me.network.dial(&addr, handler.into_node_handler_builder()).map(|_id| ())
|
||||
}
|
||||
|
||||
/// Tries to reach the given peer using the elements in the topology.
|
||||
/// Tries to initiate a dialing attempt to the given peer.
|
||||
///
|
||||
/// Has no effect if we are already connected to that peer, or if no address is known for the
|
||||
/// peer.
|
||||
pub fn dial(me: &mut Self, peer_id: PeerId) {
|
||||
let addrs = me.behaviour.addresses_of_peer(&peer_id);
|
||||
/// If a new dialing attempt has been initiated, `Ok(true)` is returned.
|
||||
///
|
||||
/// If there is an ongoing dialing attempt, the current addresses of the
|
||||
/// peer, as reported by [`NetworkBehaviour::addresses_of_peer`] are added
|
||||
/// to the ongoing dialing attempt, ignoring duplicates. In this case no
|
||||
/// new dialing attempt is initiated.
|
||||
///
|
||||
/// If no new dialing attempt has been initiated, meaning there is an ongoing
|
||||
/// dialing attempt or `addresses_of_peer` reports no addresses, `Ok(false)`
|
||||
/// is returned.
|
||||
pub fn dial(me: &mut Self, peer_id: &PeerId) -> Result<bool, ConnectionLimit> {
|
||||
let mut addrs = me.behaviour.addresses_of_peer(peer_id).into_iter();
|
||||
match me.network.peer(peer_id.clone()) {
|
||||
Peer::Disconnected(peer) => {
|
||||
let mut addrs = addrs.into_iter();
|
||||
if let Some(first) = addrs.next() {
|
||||
let handler = me.behaviour.new_handler().into_node_handler_builder();
|
||||
if peer.connect(first, addrs, handler).is_err() {
|
||||
me.behaviour.inject_dial_failure(&peer_id);
|
||||
match peer.connect(first, addrs, handler) {
|
||||
Ok(_) => return Ok(true),
|
||||
Err(error) => {
|
||||
log::debug!(
|
||||
"New dialing attempt to disconnected peer {:?} failed: {:?}.",
|
||||
peer_id, error);
|
||||
me.behaviour.inject_dial_failure(&peer_id);
|
||||
return Err(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
},
|
||||
Peer::Connected(peer) => {
|
||||
if let Some(first) = addrs.next() {
|
||||
let handler = me.behaviour.new_handler().into_node_handler_builder();
|
||||
match peer.connect(first, addrs, handler) {
|
||||
Ok(_) => return Ok(true),
|
||||
Err(error) => {
|
||||
log::debug!(
|
||||
"New dialing attempt to connected peer {:?} failed: {:?}.",
|
||||
peer_id, error);
|
||||
me.behaviour.inject_dial_failure(&peer_id);
|
||||
return Err(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
Peer::Dialing(mut peer) => {
|
||||
peer.connection().add_addresses(addrs)
|
||||
peer.connection().add_addresses(addrs);
|
||||
Ok(false)
|
||||
},
|
||||
Peer::Connected(_) | Peer::Local => {}
|
||||
Peer::Local => {
|
||||
Err(ConnectionLimit { current: 0, limit: 0 })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,35 +535,29 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
peer_id,
|
||||
endpoint,
|
||||
});
|
||||
} else if num_established.get() == 1 {
|
||||
this.behaviour.inject_connected(peer_id.clone(), endpoint.clone());
|
||||
return Poll::Ready(SwarmEvent::ConnectionEstablished {
|
||||
peer_id,
|
||||
endpoint,
|
||||
num_established,
|
||||
});
|
||||
} else {
|
||||
// For now, secondary connections are not explicitly reported to
|
||||
// the behaviour. A behaviour only gets awareness of the
|
||||
// connections via the events emitted from the connection handlers.
|
||||
log::trace!("Secondary connection established: {:?}; Total (peer): {}.",
|
||||
log::debug!("Connection established: {:?}; Total (peer): {}.",
|
||||
connection.connected(), num_established);
|
||||
let endpoint = connection.endpoint().clone();
|
||||
this.behaviour.inject_connection_established(&peer_id, &connection.id(), &endpoint);
|
||||
if num_established.get() == 1 {
|
||||
this.behaviour.inject_connected(&peer_id);
|
||||
}
|
||||
return Poll::Ready(SwarmEvent::ConnectionEstablished {
|
||||
peer_id,
|
||||
endpoint,
|
||||
num_established,
|
||||
peer_id, num_established, endpoint
|
||||
});
|
||||
}
|
||||
},
|
||||
Poll::Ready(NetworkEvent::ConnectionError { connected, error, num_established }) => {
|
||||
log::debug!("Connection {:?} closed by {:?}", connected, error);
|
||||
let peer_id = connected.peer_id().clone();
|
||||
Poll::Ready(NetworkEvent::ConnectionError { id, connected, error, num_established }) => {
|
||||
log::debug!("Connection {:?} closed: {:?}", connected, error);
|
||||
let info = connected.info;
|
||||
let endpoint = connected.endpoint;
|
||||
this.behaviour.inject_connection_closed(info.peer_id(), &id, &endpoint);
|
||||
if num_established == 0 {
|
||||
this.behaviour.inject_disconnected(&peer_id, endpoint.clone());
|
||||
this.behaviour.inject_disconnected(info.peer_id());
|
||||
}
|
||||
return Poll::Ready(SwarmEvent::ConnectionClosed {
|
||||
peer_id,
|
||||
peer_id: info.peer_id().clone(),
|
||||
endpoint,
|
||||
cause: error,
|
||||
num_established,
|
||||
@ -563,7 +594,10 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
for addr in addresses.iter() {
|
||||
this.behaviour.inject_expired_listen_addr(addr);
|
||||
}
|
||||
this.behaviour.inject_listener_closed(listener_id);
|
||||
this.behaviour.inject_listener_closed(listener_id, match &reason {
|
||||
Ok(()) => Ok(()),
|
||||
Err(err) => Err(err),
|
||||
});
|
||||
return Poll::Ready(SwarmEvent::ListenerClosed {
|
||||
addresses,
|
||||
reason,
|
||||
@ -663,12 +697,40 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
Poll::Ready(NetworkBehaviourAction::DialAddress { address }) => {
|
||||
let _ = ExpandedSwarm::dial_addr(&mut *this, address);
|
||||
},
|
||||
Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id }) => {
|
||||
Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }) => {
|
||||
if this.banned_peers.contains(&peer_id) {
|
||||
this.behaviour.inject_dial_failure(&peer_id);
|
||||
} else {
|
||||
ExpandedSwarm::dial(&mut *this, peer_id.clone());
|
||||
return Poll::Ready(SwarmEvent::Dialing(peer_id))
|
||||
let result = match condition {
|
||||
DialPeerCondition::Disconnected
|
||||
if this.network.is_disconnected(&peer_id) =>
|
||||
{
|
||||
ExpandedSwarm::dial(this, &peer_id)
|
||||
}
|
||||
DialPeerCondition::NotDialing
|
||||
if !this.network.is_dialing(&peer_id) =>
|
||||
{
|
||||
ExpandedSwarm::dial(this, &peer_id)
|
||||
}
|
||||
_ => {
|
||||
log::trace!("Condition for new dialing attempt to {:?} not met: {:?}",
|
||||
peer_id, condition);
|
||||
if let Some(mut peer) = this.network.peer(peer_id.clone()).into_dialing() {
|
||||
let addrs = this.behaviour.addresses_of_peer(peer.id());
|
||||
peer.connection().add_addresses(addrs);
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
};
|
||||
match result {
|
||||
Ok(false) => {},
|
||||
Ok(true) => return Poll::Ready(SwarmEvent::Dialing(peer_id)),
|
||||
Err(err) => {
|
||||
log::debug!("Initiating dialing attempt to {:?} failed: {:?}",
|
||||
&peer_id, err);
|
||||
this.behaviour.inject_dial_failure(&peer_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, handler, event }) => {
|
||||
@ -922,28 +984,33 @@ impl<'a> PollParameters for SwarmPollParameters<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A `SwarmBuilder` provides an API for configuring and constructing a `Swarm`,
|
||||
/// including the underlying [`Network`].
|
||||
pub struct SwarmBuilder<TBehaviour, TConnInfo> {
|
||||
local_peer_id: PeerId,
|
||||
transport: BoxTransport<(TConnInfo, StreamMuxerBox), io::Error>,
|
||||
behaviour: TBehaviour,
|
||||
network: NetworkConfig,
|
||||
network_config: NetworkConfig,
|
||||
}
|
||||
|
||||
impl<TBehaviour, TConnInfo> SwarmBuilder<TBehaviour, TConnInfo>
|
||||
where TBehaviour: NetworkBehaviour,
|
||||
TConnInfo: ConnectionInfo<PeerId = PeerId> + fmt::Debug + Clone + Send + 'static,
|
||||
{
|
||||
pub fn new<TTransport, TMuxer>(transport: TTransport, behaviour: TBehaviour, local_peer_id: PeerId) -> Self
|
||||
/// Creates a new `SwarmBuilder` from the given transport, behaviour and
|
||||
/// local peer ID. The `Swarm` with its underlying `Network` is obtained
|
||||
/// via [`SwarmBuilder::build`].
|
||||
pub fn new<TTrans, TMuxer>(transport: TTrans, behaviour: TBehaviour, local_peer_id: PeerId) -> Self
|
||||
where
|
||||
TMuxer: StreamMuxer + Send + Sync + 'static,
|
||||
TMuxer::OutboundSubstream: Send + 'static,
|
||||
<TMuxer as StreamMuxer>::OutboundSubstream: Send + 'static,
|
||||
<TMuxer as StreamMuxer>::Substream: Send + 'static,
|
||||
TTransport: Transport<Output = (TConnInfo, TMuxer)> + Clone + Send + Sync + 'static,
|
||||
TTransport::Error: Send + Sync + 'static,
|
||||
TTransport::Listener: Send + 'static,
|
||||
TTransport::ListenerUpgrade: Send + 'static,
|
||||
TTransport::Dial: Send + 'static,
|
||||
TTrans: Transport<Output = (TConnInfo, TMuxer)> + Clone + Send + Sync + 'static,
|
||||
TTrans::Error: Send + Sync + 'static,
|
||||
TTrans::Listener: Send + 'static,
|
||||
TTrans::ListenerUpgrade: Send + 'static,
|
||||
TTrans::Dial: Send + 'static,
|
||||
{
|
||||
let transport = transport
|
||||
.map(|(conn_info, muxer), _| (conn_info, StreamMuxerBox::new(muxer)))
|
||||
@ -954,35 +1021,41 @@ where TBehaviour: NetworkBehaviour,
|
||||
local_peer_id,
|
||||
transport,
|
||||
behaviour,
|
||||
network: NetworkConfig::default(),
|
||||
network_config: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn incoming_limit(mut self, incoming_limit: usize) -> Self {
|
||||
self.network.set_pending_incoming_limit(incoming_limit);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the executor to use to spawn background tasks.
|
||||
/// Configures the `Executor` to use for spawning background tasks.
|
||||
///
|
||||
/// By default, uses a threads pool.
|
||||
pub fn executor(mut self, executor: impl Executor + Send + 'static) -> Self {
|
||||
self.network.set_executor(Box::new(executor));
|
||||
/// By default, unless another executor has been configured,
|
||||
/// [`SwarmBuilder::build`] will try to set up a `ThreadPool`.
|
||||
pub fn executor(mut self, e: Box<dyn Executor + Send>) -> Self {
|
||||
self.network_config.set_executor(e);
|
||||
self
|
||||
}
|
||||
|
||||
/// Shortcut for calling `executor` with an object that calls the given closure.
|
||||
pub fn executor_fn(mut self, executor: impl Fn(Pin<Box<dyn Future<Output = ()> + Send>>) + Send + 'static) -> Self {
|
||||
struct SpawnImpl<F>(F);
|
||||
impl<F: Fn(Pin<Box<dyn Future<Output = ()> + Send>>)> Executor for SpawnImpl<F> {
|
||||
fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
|
||||
(self.0)(f)
|
||||
}
|
||||
}
|
||||
self.network.set_executor(Box::new(SpawnImpl(executor)));
|
||||
/// Configures a limit for the number of simultaneous incoming
|
||||
/// connection attempts.
|
||||
pub fn incoming_connection_limit(mut self, n: usize) -> Self {
|
||||
self.network_config.set_incoming_limit(n);
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures a limit for the number of simultaneous outgoing
|
||||
/// connection attempts.
|
||||
pub fn outgoing_connection_limit(mut self, n: usize) -> Self {
|
||||
self.network_config.set_outgoing_limit(n);
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures a limit for the number of simultaneous
|
||||
/// established connections per peer.
|
||||
pub fn peer_connection_limit(mut self, n: usize) -> Self {
|
||||
self.network_config.set_established_per_peer_limit(n);
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds a `Swarm` with the current configuration.
|
||||
pub fn build(mut self) -> Swarm<TBehaviour, TConnInfo> {
|
||||
let supported_protocols = self.behaviour
|
||||
.new_handler()
|
||||
@ -992,9 +1065,10 @@ where TBehaviour: NetworkBehaviour,
|
||||
.map(|info| info.protocol_name().to_vec())
|
||||
.collect();
|
||||
|
||||
// If no executor has been explicitly configured, try to set up
|
||||
// a thread pool.
|
||||
if self.network.executor().is_none() {
|
||||
let mut network_cfg = self.network_config;
|
||||
|
||||
// If no executor has been explicitly configured, try to set up a thread pool.
|
||||
if network_cfg.executor().is_none() {
|
||||
struct PoolWrapper(ThreadPool);
|
||||
impl Executor for PoolWrapper {
|
||||
fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
|
||||
@ -1002,21 +1076,17 @@ where TBehaviour: NetworkBehaviour,
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(executor) = ThreadPoolBuilder::new()
|
||||
.name_prefix("libp2p-task-")
|
||||
match ThreadPoolBuilder::new()
|
||||
.name_prefix("libp2p-swarm-task-")
|
||||
.create()
|
||||
.ok()
|
||||
.map(|tp| Box::new(PoolWrapper(tp)) as Box<_>)
|
||||
{
|
||||
self.network.set_executor(Box::new(executor));
|
||||
Ok(executor) => { network_cfg.set_executor(Box::new(executor)); },
|
||||
Err(err) => log::warn!("Failed to create executor thread pool: {:?}", err)
|
||||
}
|
||||
}
|
||||
|
||||
let network = Network::new(
|
||||
self.transport,
|
||||
self.local_peer_id,
|
||||
self.network,
|
||||
);
|
||||
let network = Network::new(self.transport, self.local_peer_id, network_cfg);
|
||||
|
||||
ExpandedSwarm {
|
||||
network,
|
||||
@ -1047,9 +1117,13 @@ impl NetworkBehaviour for DummyBehaviour {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, _: PeerId, _: libp2p_core::ConnectedPoint) {}
|
||||
fn inject_connected(&mut self, _: &PeerId) {}
|
||||
|
||||
fn inject_disconnected(&mut self, _: &PeerId, _: libp2p_core::ConnectedPoint) {}
|
||||
fn inject_connection_established(&mut self, _: &PeerId, _: &ConnectionId, _: &ConnectedPoint) {}
|
||||
|
||||
fn inject_disconnected(&mut self, _: &PeerId) {}
|
||||
|
||||
fn inject_connection_closed(&mut self, _: &PeerId, _: &ConnectionId, _: &ConnectedPoint) {}
|
||||
|
||||
fn inject_event(&mut self, _: PeerId, _: ConnectionId,
|
||||
_: <Self::ProtocolsHandler as ProtocolsHandler>::OutEvent) {}
|
||||
@ -1067,9 +1141,9 @@ impl NetworkBehaviour for DummyBehaviour {
|
||||
mod tests {
|
||||
use crate::{DummyBehaviour, SwarmBuilder};
|
||||
use libp2p_core::{
|
||||
identity,
|
||||
PeerId,
|
||||
PublicKey,
|
||||
identity,
|
||||
transport::dummy::{DummyStream, DummyTransport}
|
||||
};
|
||||
use libp2p_mplex::Multiplex;
|
||||
@ -1084,7 +1158,8 @@ mod tests {
|
||||
let transport = DummyTransport::<(PeerId, Multiplex<DummyStream>)>::new();
|
||||
let behaviour = DummyBehaviour {};
|
||||
let swarm = SwarmBuilder::new(transport, behaviour, id.into())
|
||||
.incoming_limit(4).build();
|
||||
.incoming_connection_limit(4)
|
||||
.build();
|
||||
assert_eq!(swarm.network.incoming_limit(), Some(4));
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ pub use dummy::DummyProtocolsHandler;
|
||||
pub use map_in::MapInEvent;
|
||||
pub use map_out::MapOutEvent;
|
||||
pub use node_handler::{NodeHandlerWrapper, NodeHandlerWrapperBuilder, NodeHandlerWrapperError};
|
||||
pub use one_shot::OneShotHandler;
|
||||
pub use one_shot::{OneShotHandler, OneShotHandlerConfig};
|
||||
pub use select::{IntoProtocolsHandlerSelect, ProtocolsHandlerSelect};
|
||||
|
||||
/// A handler for a set of protocols used on a connection with a remote.
|
||||
|
@ -133,10 +133,10 @@ enum Shutdown {
|
||||
/// Error generated by the `NodeHandlerWrapper`.
|
||||
#[derive(Debug)]
|
||||
pub enum NodeHandlerWrapperError<TErr> {
|
||||
/// Error generated by the handler.
|
||||
/// The connection handler encountered an error.
|
||||
Handler(TErr),
|
||||
/// The connection has been deemed useless and has been closed.
|
||||
UselessTimeout,
|
||||
/// The connection keep-alive timeout expired.
|
||||
KeepAliveTimeout,
|
||||
}
|
||||
|
||||
impl<TErr> From<TErr> for NodeHandlerWrapperError<TErr> {
|
||||
@ -152,8 +152,8 @@ where
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
NodeHandlerWrapperError::Handler(err) => write!(f, "{}", err),
|
||||
NodeHandlerWrapperError::UselessTimeout =>
|
||||
write!(f, "Node has been closed due to inactivity"),
|
||||
NodeHandlerWrapperError::KeepAliveTimeout =>
|
||||
write!(f, "Connection closed due to expired keep-alive timeout."),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,7 +165,7 @@ where
|
||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||
match self {
|
||||
NodeHandlerWrapperError::Handler(err) => Some(err),
|
||||
NodeHandlerWrapperError::UselessTimeout => None,
|
||||
NodeHandlerWrapperError::KeepAliveTimeout => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -314,9 +314,9 @@ where
|
||||
if self.negotiating_in.is_empty() && self.negotiating_out.is_empty() {
|
||||
match self.shutdown {
|
||||
Shutdown::None => {},
|
||||
Shutdown::Asap => return Poll::Ready(Err(NodeHandlerWrapperError::UselessTimeout)),
|
||||
Shutdown::Asap => return Poll::Ready(Err(NodeHandlerWrapperError::KeepAliveTimeout)),
|
||||
Shutdown::Later(ref mut delay, _) => match Future::poll(Pin::new(delay), cx) {
|
||||
Poll::Ready(_) => return Poll::Ready(Err(NodeHandlerWrapperError::UselessTimeout)),
|
||||
Poll::Ready(_) => return Poll::Ready(Err(NodeHandlerWrapperError::KeepAliveTimeout)),
|
||||
Poll::Pending => {}
|
||||
}
|
||||
}
|
||||
|
@ -54,8 +54,8 @@ where
|
||||
max_dial_negotiated: u32,
|
||||
/// Value to return from `connection_keep_alive`.
|
||||
keep_alive: KeepAlive,
|
||||
/// After the given duration has elapsed, an inactive connection will shutdown.
|
||||
inactive_timeout: Duration,
|
||||
/// The configuration container for the handler
|
||||
config: OneShotHandlerConfig,
|
||||
}
|
||||
|
||||
impl<TInProto, TOutProto, TOutEvent>
|
||||
@ -67,7 +67,7 @@ where
|
||||
#[inline]
|
||||
pub fn new(
|
||||
listen_protocol: SubstreamProtocol<TInProto>,
|
||||
inactive_timeout: Duration
|
||||
config: OneShotHandlerConfig,
|
||||
) -> Self {
|
||||
OneShotHandler {
|
||||
listen_protocol,
|
||||
@ -77,7 +77,7 @@ where
|
||||
dial_negotiated: 0,
|
||||
max_dial_negotiated: 8,
|
||||
keep_alive: KeepAlive::Yes,
|
||||
inactive_timeout,
|
||||
config
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,7 +121,10 @@ where
|
||||
{
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
OneShotHandler::new(SubstreamProtocol::new(Default::default()), Duration::from_secs(10))
|
||||
OneShotHandler::new(
|
||||
SubstreamProtocol::new(Default::default()),
|
||||
OneShotHandlerConfig::default()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +160,7 @@ where
|
||||
) {
|
||||
// If we're shutting down the connection for inactivity, reset the timeout.
|
||||
if !self.keep_alive.is_yes() {
|
||||
self.keep_alive = KeepAlive::Until(Instant::now() + self.inactive_timeout);
|
||||
self.keep_alive = KeepAlive::Until(Instant::now() + self.config.inactive_timeout);
|
||||
}
|
||||
|
||||
self.events_out.push(out.into());
|
||||
@ -172,7 +175,7 @@ where
|
||||
self.dial_negotiated -= 1;
|
||||
|
||||
if self.dial_negotiated == 0 && self.dial_queue.is_empty() {
|
||||
self.keep_alive = KeepAlive::Until(Instant::now() + self.inactive_timeout);
|
||||
self.keep_alive = KeepAlive::Until(Instant::now() + self.config.inactive_timeout);
|
||||
}
|
||||
|
||||
self.events_out.push(out.into());
|
||||
@ -224,7 +227,8 @@ where
|
||||
self.dial_negotiated += 1;
|
||||
return Poll::Ready(
|
||||
ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: SubstreamProtocol::new(self.dial_queue.remove(0)),
|
||||
protocol: SubstreamProtocol::new(self.dial_queue.remove(0))
|
||||
.with_timeout(self.config.substream_timeout),
|
||||
info: (),
|
||||
},
|
||||
);
|
||||
@ -236,3 +240,21 @@ where
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration parameters for the `OneShotHandler`
|
||||
#[derive(Debug)]
|
||||
pub struct OneShotHandlerConfig {
|
||||
/// After the given duration has elapsed, an inactive connection will shutdown.
|
||||
pub inactive_timeout: Duration,
|
||||
/// Timeout duration for each newly opened outbound substream.
|
||||
pub substream_timeout: Duration,
|
||||
}
|
||||
|
||||
impl Default for OneShotHandlerConfig {
|
||||
fn default() -> Self {
|
||||
let inactive_timeout = Duration::from_secs(10);
|
||||
let substream_timeout = Duration::from_secs(10);
|
||||
OneShotHandlerConfig { inactive_timeout, substream_timeout }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,15 +76,27 @@ where
|
||||
self.inner.as_mut().map(|b| b.addresses_of_peer(peer_id)).unwrap_or_else(Vec::new)
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) {
|
||||
fn inject_connected(&mut self, peer_id: &PeerId) {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
inner.inject_connected(peer_id, endpoint)
|
||||
inner.inject_connected(peer_id)
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) {
|
||||
fn inject_disconnected(&mut self, peer_id: &PeerId) {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
inner.inject_disconnected(peer_id, endpoint)
|
||||
inner.inject_disconnected(peer_id)
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_connection_established(&mut self, peer_id: &PeerId, connection: &ConnectionId, endpoint: &ConnectedPoint) {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
inner.inject_connection_established(peer_id, connection, endpoint)
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_connection_closed(&mut self, peer_id: &PeerId, connection: &ConnectionId, endpoint: &ConnectedPoint) {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
inner.inject_connection_closed(peer_id, connection, endpoint)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-dns"
|
||||
edition = "2018"
|
||||
description = "DNS transport implementation for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -10,6 +10,6 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
log = "0.4.1"
|
||||
futures = "0.3.1"
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-tcp"
|
||||
edition = "2018"
|
||||
description = "TCP/IP transport protocol for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -15,7 +15,7 @@ futures = "0.3.1"
|
||||
futures-timer = "3.0"
|
||||
get_if_addrs = "0.5.3"
|
||||
ipnet = "2.0.0"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
log = "0.4.1"
|
||||
tokio = { version = "0.2", default-features = false, features = ["tcp"], optional = true }
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-uds"
|
||||
edition = "2018"
|
||||
description = "Unix domain sockets transport for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -11,7 +11,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[target.'cfg(all(unix, not(any(target_os = "emscripten", target_os = "unknown"))))'.dependencies]
|
||||
async-std = { version = "1.0", optional = true }
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
log = "0.4.1"
|
||||
futures = "0.3.1"
|
||||
tokio = { version = "0.2", default-features = false, features = ["uds"], optional = true }
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "libp2p-wasm-ext"
|
||||
version = "0.16.2"
|
||||
version = "0.17.0"
|
||||
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "Allows passing in an external transport in a WASM environment"
|
||||
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
js-sys = "0.3.19"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
parity-send-wrapper = "0.1.0"
|
||||
wasm-bindgen = "0.2.42"
|
||||
wasm-bindgen-futures = "0.4.4"
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "libp2p-websocket"
|
||||
edition = "2018"
|
||||
description = "WebSocket transport for libp2p"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/libp2p/rust-libp2p"
|
||||
@ -10,14 +10,14 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
async-tls = "0.6"
|
||||
async-tls = "0.7.0"
|
||||
bytes = "0.5"
|
||||
either = "1.5.3"
|
||||
futures = "0.3.1"
|
||||
libp2p-core = { version = "0.16.0", path = "../../core" }
|
||||
libp2p-core = { version = "0.17.0", path = "../../core" }
|
||||
log = "0.4.8"
|
||||
quicksink = "0.1"
|
||||
rustls = "0.16"
|
||||
rustls = "0.17.0"
|
||||
rw-stream-sink = "0.2.0"
|
||||
soketto = { version = "0.3", features = ["deflate"] }
|
||||
url = "2.1"
|
||||
@ -25,4 +25,4 @@ webpki = "0.21"
|
||||
webpki-roots = "0.18"
|
||||
|
||||
[dev-dependencies]
|
||||
libp2p-tcp = { version = "0.16.0", path = "../tcp" }
|
||||
libp2p-tcp = { version = "0.17.0", path = "../tcp" }
|
||||
|
@ -308,11 +308,6 @@ where
|
||||
let dns_name = dns_name.expect("for use_tls we have checked that dns_name is some");
|
||||
trace!("starting TLS handshake with {}", address);
|
||||
let stream = self.tls_config.client.connect(&dns_name, stream)
|
||||
.map_err(|e| {
|
||||
// We should never enter here as we passed a `DNSNameRef` to `connect`.
|
||||
debug!("invalid domain name: {:?}", dns_name);
|
||||
Error::Tls(e.into())
|
||||
})?
|
||||
.map_err(|e| {
|
||||
debug!("TLS handshake with {} failed: {}", address, e);
|
||||
Error::Tls(tls::Error::from(e))
|
||||
|
Loading…
x
Reference in New Issue
Block a user