23 Commits

Author SHA1 Message Date
Tobin Harding
7bf5266a02
Add addresses field for closing listeners (#1485)
* Add addresses field for closing listeners

Add an addresses field to the ListenersEvent and the ListenerClosed to
hold the addresses of a listener that has just closed. When we return a
ListenerClosed network event loop over the addresses and call
inject_expired_listen_address on each one.

Fixes: #1482

* Use Vec instead of SmallVec

In order to not expose a third party dependency in our API use a `Vec`
type for the addresses list instead of a `SmallVec`.

* Do not clone for ListenersEvent::Closed

We would like to avoid clones where possible for efficiency reasons.
When returning a `ListenersEvent::Closed` we are already consuming the
listener (by way of a pin projection).  We can therefore use a consuming
iterator instead of cloning.

Use `drain(..).collect()` instead of clone to consume the addresses when
returning a `ListenersEvent::Closed`.

* Expire addresses before listener

The listener and its addresses technically expire at the same time, but
since here we have to pick an order, it makes more sense that the
addresses expire first.

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
2020-03-23 11:31:38 +01:00
Roman Borschel
58ee13b630
Fix regression w.r.t. reporting of dial errors. (#1493)
* Fix regression w.r.t. reporting of dial errors.

PR [1440] introduced a regression w.r.t. the reporting of
dial errors. In particular, if a connection attempt fails
due to an invalid remote peer ID, any remaining addresses
for the same peer would not be tried (intentional) but
the dial failure would not be reported to the behaviour,
causing e.g. libp2p-kad queries to potentially stall.

In hindsight, I figured it is better to preserve the
previous behaviour to still try alternative addresses
of the peer even on invalid peer ID errors on an earlier
address. In particular because in the context of libp2p-kad
it is not uncommon for peers to report localhost addresses
while the local node actually has e.g. an ipfs node running
on that address, obviously with a different peer ID, which
is the scenario causing frequent invalid peer ID (mismatch)
errors when running the ipfs-kad example.

This commit thus restores the previous behaviour w.r.t.
trying all remaining addresses on invalid peer ID errors
as well as making sure `inject_dial_error` is always
called when the last attempt failed.

[1440]: https://github.com/libp2p/rust-libp2p/pull/1440.

* Remove an fmt::Debug requirement.
2020-03-16 16:53:21 +01:00
Roman Borschel
8337687b3a
Multiple connections per peer (#1440)
* Allow multiple connections per peer in libp2p-core.

Instead of trying to enforce a single connection per peer,
which involves quite a bit of additional complexity e.g.
to prioritise simultaneously opened connections and can
have other undesirable consequences [1], we now
make multiple connections per peer a feature.

The gist of these changes is as follows:

The concept of a "node" with an implicit 1-1 correspondence
to a connection has been replaced with the "first-class"
concept of a "connection". The code from `src/nodes` has moved
(with varying degrees of modification) to `src/connection`.
A `HandledNode` has become a `Connection`, a `NodeHandler` a
`ConnectionHandler`, the `CollectionStream` was the basis for
the new `connection::Pool`, and so forth.

Conceptually, a `Network` contains a `connection::Pool` which
in turn internally employs the `connection::Manager` for
handling the background `connection::manager::Task`s, one
per connection, as before. These are all considered implementation
details. On the public API, `Peer`s are managed as before through
the `Network`, except now the API has changed with the shift of focus
to (potentially multiple) connections per peer. The `NetworkEvent`s have
accordingly also undergone changes.

The Swarm APIs remain largely unchanged, except for the fact that
`inject_replaced` is no longer called. It may now practically happen
that multiple `ProtocolsHandler`s are associated with a single
`NetworkBehaviour`, one per connection. If implementations of
`NetworkBehaviour` rely somehow on communicating with exactly
one `ProtocolsHandler`, this may cause issues, but it is unlikely.

[1]: https://github.com/paritytech/substrate/issues/4272

* Fix intra-rustdoc links.

* Update core/src/connection/pool.rs

Co-Authored-By: Max Inden <mail@max-inden.de>

* Address some review feedback and fix doc links.

* Allow responses to be sent on the same connection.

* Remove unnecessary remainders of inject_replaced.

* Update swarm/src/behaviour.rs

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Update swarm/src/lib.rs

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Update core/src/connection/manager.rs

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Update core/src/connection/manager.rs

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Update core/src/connection/pool.rs

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Incorporate more review feedback.

* Move module declaration below imports.

* Update core/src/connection/manager.rs

Co-Authored-By: Toralf Wittner <tw@dtex.org>

* Update core/src/connection/manager.rs

Co-Authored-By: Toralf Wittner <tw@dtex.org>

* Simplify as per review.

* Fix rustoc link.

* Add try_notify_handler and simplify.

* Relocate DialingConnection and DialingAttempt.

For better visibility constraints.

* Small cleanup.

* Small cleanup. More robust EstablishedConnectionIter.

* Clarify semantics of `DialingPeer::connect`.

* Don't call inject_disconnected on InvalidPeerId.

To preserve the previous behavior and ensure calls to
`inject_disconnected` are always paired with calls to
`inject_connected`.

* Provide public ConnectionId constructor.

Mainly needed for testing purposes, e.g. in substrate.

* Move the established connection limit check to the right place.

* Clean up connection error handling.

Separate connection errors into those occuring during
connection setup or upon rejecting a newly established
connection (the `PendingConnectionError`) and those
errors occurring on previously established connections,
i.e. for which a `ConnectionEstablished` event has
been emitted by the connection pool earlier.

* Revert change in log level and clarify an invariant.

* Remove inject_replaced entirely.

* Allow notifying all connection handlers.

Thereby simplify by introducing a new enum `NotifyHandler`,
used with a single constructor `NetworkBehaviourAction::NotifyHandler`.

* Finishing touches.

Small API simplifications and code deduplication.
Some more useful debug logging.

Co-authored-by: Max Inden <mail@max-inden.de>
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: Toralf Wittner <tw@dtex.org>
2020-03-04 13:49:25 +01:00
Rüdiger Klaehn
145200fa4f
Implement FusedStream for Swarm (#1433)
* Implement FusedStream for Swarm

The stream for swarm will never terminate, and therefore does not have to
keep track of termination.

* Get rid of the wall of complex type constraints

...as they don't seem to be necessary anymore for latest master
2020-02-18 10:33:01 +01:00
Pierre Krieger
1eff4b9823
Simplify trait bounds on NetworkBehaviour (#1405)
* Simplify trait bounds requirements

* More work

* Moar

* Finish

* Fix final tests

* More simplification

* Use separate traits for Inbound/Outbound

* Update gossipsub and remove warnings

* Add documentation to swarm

* Remove BoxSubstream

* Fix tests not compiling

* Fix stack overflow

* Address concerns

* For some reason my IDE ignored libp2p-kad
2020-02-07 16:29:30 +01:00
Pierre Krieger
7d0c80fce1
Executor + Send (#1399) 2020-01-20 15:22:47 +01:00
Pierre Krieger
f89683419a
Allow configuring the tasks executor (#1391)
* Allow configuring the tasks executor

* Minor tweaks

* Add executor_fn

* Create ThreadsPool at the end if necessary

* Allow configuring the tasks executor

* Minor tweaks

* Add executor_fn

* Create ThreadsPool at the end if necessary

* WIP

* Don't depend on async-std and tokio in core

* Replace FutureObj with PinBoxFuture

* Some docs on Executor

* Fix tests

Co-authored-by: Toralf Wittner <tw@dtex.org>
2020-01-20 14:18:35 +01:00
Roman Borschel
c241014ddb
Log connection close in swarm. Simplify bounds. (#1393) 2020-01-16 13:17:39 +01:00
Pierre Krieger
3f968cbf92
Remove some Unpin requirements on Futures (#1384)
* Remove lots of Unpin requirements

* Make Transport::and_then accept pinned futures

* Finish the PR

* Work on secio

* Fix BandwidthTransport

* Adjust ListenersStrema

* Fix nodes/tasks

* Fix nodes

* Various more fixes

* Fix yamux

* Fix Swarm

* Fix WebSockets

* Fix rw-stream-sink
2020-01-14 12:03:10 +01:00
Pierre Krieger
42a45e2630
Remove Negotiated from upgrade traits (#1388)
* Remove Negotiated from upgrade traits

* Remove import
2020-01-13 14:34:43 +01:00
Pierre Krieger
84b6a7d04d
Add Swarm::next_extended (#1374)
* Add Swarm::next_extended

* Fix ipfs-kad example

* Fix tests

* Renames
2020-01-07 11:57:00 +01:00
Pierre Krieger
c7148d5ee5
Address some reviewing (#1246) 2019-09-20 10:46:13 +02:00
Pierre Krieger
170d2d268f
Switch to stable futures (#1196)
* Switch to stable futures

* Remove from_fn

* Fix secio

* Fix core --lib tests
2019-09-16 11:08:44 +02:00
Toralf Wittner
2c4b52a545 Return TCP listener errors. (#1218)
* Add listener ID and error event.

Report listener errors to client code so they are aware that an error
occurred within a listener. By default we continue to poll listeners
which produced an error, but clients can remove listeners by ID.

* tcp: Report errors.

Instead of silently waiting after errors we return all errors, but pause
after each error, before continuing.

* Add a test.

To ease testing, `Listener` is made generic and we test that no values
and errors are lost. Elapsed time between item generation is not
measured.

* Support the new methods in core-derive.

* Address review concerns.

* Remove `Display` impl of `ListenerId`.

* Add 'static bound to `on_listener_error` error.
2019-08-13 15:41:12 +02:00
Max Inden
5861474d99 core/src/translation: Support dns4 and dns6 (#1204)
* core/src/translation: Add unit tests

* core/src/translation: Support dns4 and dns6

Add dns4 and dns6 as valid protocol replacements for the origin address
to construct external addresses of a given node.

* core/nodes/network: %s/nat_translation/address_translation/

When receiving an observed address on a tcp connection that we initiated, the
observed address contains our tcp dial port, not our tcp listen port. We know
which port we are listening on, thereby we can replace the port within the
observed address.

When receiving an observed address on a tcp connection that we did **not**
initiated, the observed address should contain our listening port. In case it
differs from our listening port there might be a NAT along the path.

With the above in mind, the function name `nat_translation` is misleading.
2019-07-18 18:41:09 +02:00
Roman Borschel
dfbf5b65c5
Rename RawSwarm* to Network*. (#1194)
* Rename RawSwarm* to Network*.

To complete the cut performed in [1].

The only remaining mention of a "swarm" in libp2p-core is in some tests
which actually depend on libp2p-swarm.

[1]: https://github.com/libp2p/rust-libp2p/pull/1188

* Post-merge corrections.
2019-07-10 10:27:21 +02:00
Toralf Wittner
6aba7961d1 Replace unbounded channels with bounded ones. (#1191)
* Replace unbounded channels with bounded ones.

To remove the unbounded channels used for communicating with node tasks
an API similar to `futures::Sink` is used, i.e. sending is split into a
start and complete phase. The start phase returns `StartSend` and first
attempts to complete any pending send operations. Completing the send
means polling until `Poll::Ready(())` is returned.

In addition this PR has split the `handled_node_tasks` module into
several smaller ones (cf. `nodes::tasks`) and renamed some types:

- `nodes::handled_node_tasks::NodeTask` -> `nodes::tasks::task::Task`
- `nodes::handled_node_tasks::NodeTaskInner` -> `nodes::tasks::task::State`
- `nodes::handled_node_tasks::NodeTasks` -> `nodes::tasks::Manager`
- `nodes::handled_node_tasks::TaskClosedEvent` -> `nodes::tasks::Error`
- `nodes::handled_node_tasks::HandledNodesEvent` -> `nodes::tasks::Event`
- `nodes::handled_node_tasks::Task` -> `nodes::tasks::TaskEntry`
- `nodes::handled_node_tasks::ExtToInMessage` -> `nodes::tasks::task::ToTaskMessage`
- `nodes::handled_node_tasks::InToExtMessage` -> `nodes::tasks::task::FromTaskMessage`

* `take_over_to_complete` can be an `Option`.

Since it is always holding just a single pending message.

* `send_event_to_complete` can be an `Option`.

* Update core/src/nodes/tasks/manager.rs

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Update core/src/nodes/tasks/manager.rs

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Add comments to explain the need to flush sends ...

of take-over and event messages delivered over Sinks.
2019-07-09 16:47:24 +02:00
Toralf Wittner
68c36d87d3
Move swarm and protocols handler into swarm crate. (#1188)
Move swarm and protocols handler into swarm crate.
2019-07-04 14:47:59 +02:00
Pierre Krieger
5c1890e66a
Rename libp2p_swarm to libp2p_core (#189) 2018-05-16 12:59:36 +02:00
Pierre Krieger
f787f3d8b8
Swarm rework (#182)
* Rename Transport::RawConn to Output

* Remove AsyncRead + AsyncWrite bound on Transport::Output

* UpgradedNode now always implements Transport

* Add and tweak modifiers for Transport and ConnectionUpgrade

* Secio upgrade now returns the pubkey in its output

* Add upgrade::apply

* Add Transport::and_then

* Rework the swarm

* Rustfmt

* Fix concerns
2018-05-14 15:55:16 +02:00
Toralf Wittner
d346a6f495 Refactor transport into multiple modules. (#170)
Addresses #158.

Besides the refactoring, the type `EitherIncomingStream` has been
removed as it is not used.
2018-05-02 11:50:48 +02:00
Pierre Krieger
2445d9e9ee
Various fixes and improvements (#166) 2018-04-11 17:32:32 +02:00
Jef
5c4aefe457 Remove libp2p- prefix (#152)
* Remove `libp2p-` prefix

* More sed-fu
2018-03-20 14:44:46 +01:00