54 Commits

Author SHA1 Message Date
Thomas Eizinger
c93f753018
feat: replace ProtocolName with AsRef<str>
Previously, a protocol could be any sequence of bytes as long as it started with `/`. Now, we directly parse a protocol as `String` which enforces it to be valid UTF8.

To notify users of this change, we delete the `ProtocolName` trait. The new requirement is that users need to provide a type that implements `AsRef<str>`.

We also add a `StreamProtocol` newtype in `libp2p-swarm` which provides an easy way for users to ensure their protocol strings are compliant. The newtype enforces that protocol strings start with `/`. `StreamProtocol` also implements `AsRef<str>`, meaning users can directly use it in their upgrades.

`multistream-select` by itself only changes marginally with this patch. The only thing we enforce in the type-system is that protocols must implement `AsRef<str>`.

Resolves: #2831.

Pull-Request: #3746.
2023-05-04 04:47:11 +00:00
João Oliveira
280c51ef83
*: Link to libp2p/specs in doc comments (#3077) 2022-11-04 10:32:41 +00:00
Hannes
fcadc83aca
*: Use auto_doc_cfg instead of doc(cfg) attributes (#2983)
Co-authored-by: João Oliveira <hello@jxs.pt>
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2022-10-24 13:00:20 +11:00
Thomas Eizinger
cef505685c
core/muxing: Generalise StreamMuxer::poll_address_change to poll (#2797)
This is to allow general-purpose background work to be performed
by implementations.
2022-08-16 04:50:17 +02:00
Thomas Eizinger
028decec69
core/muxing: Have functions on StreamMuxer take Pin<&mut Self> (#2765)
Co-authored-by: Elena Frank <elena.frank@protonmail.com>
Co-authored-by: Max Inden <mail@max-inden.de>
2022-08-03 23:12:11 +10:00
Thomas Eizinger
1a553db596
core/muxing: Flatten StreamMuxer interface to poll_{inbound,outbound,address_change,close} (#2724)
Instead of having a mix of `poll_event`, `poll_outbound` and `poll_close`, we
flatten the entire interface of `StreamMuxer` into 4 individual functions:

- `poll_inbound`
- `poll_outbound`
- `poll_address_change`
- `poll_close`

This design is closer to the design of other async traits like `AsyncRead` and
`AsyncWrite`. It also allows us to delete the `StreamMuxerEvent`.
2022-07-18 05:20:11 +02:00
Thomas Eizinger
eb490c08e9
core/muxing: Force StreamMuxer::Substream to implement Async{Read,Write} (#2707)
Co-authored-by: Max Inden <mail@max-inden.de>
2022-06-23 21:52:11 +10:00
Thomas Eizinger
ea487aebfe
muxers/mplex: Implement AsyncRead and AsyncWrite for Substream (#2706)
This aligns the public API of the `libp2p-mplex` module with the one
from `libp2p-yamux`. This change has two benefits:

1. For standalone users of `libp2p-mplex`, the substreams itself are
now useful, similar to `libp2p-yamux` and don't necessarily need to
be polled via the `StreamMuxer`. The `StreamMuxer` only forwards to
the `Async{Read,Write}` implementations.

2. This will reduce the diff of #2648 because we can chunk the one
giant commit into smaller atomic ones.
2022-06-20 05:33:59 +02:00
Thomas Eizinger
2b79f113bb
core/muxing: Remove the StreamMuxer::flush_all function (#2669)
`libp2p-core` provides the `StreamMuxer` abstraction so it can provide
functionality that abstracts over this trait.

We never use the `flush_all` function as part of our abstractions.
No one else is going to use it so we can remove it from the abstraction.
2022-05-29 17:23:13 +02:00
Thomas Eizinger
25c8bc24de
core/muxing: Rename close to poll_close (#2666)
It is common practise to prefix functions that return a `Poll` with
`poll_`.
2022-05-29 16:27:40 +02:00
hanabi1224
243f587eed
muxers/mplex: Allow setting custom protocol name (#2332)
Co-authored-by: Max Inden <mail@max-inden.de>
2021-11-23 17:57:17 +01:00
Max Inden
f701b24ec0
*: Format with rustfmt (#2188)
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2021-08-11 13:12:12 +02:00
Roman Borschel
6499e924a3
Make clippy "happy". (#1950)
* Make clippy "happy".

Address all clippy complaints that are not purely stylistic (or even
have corner cases with false positives). Ignore all "style" and "pedantic" lints.

* Fix tests.

* Undo unnecessary API change.
2021-02-15 11:59:51 +01:00
Roman Borschel
0b18b864f2
[mplex] Refactoring with Patches (#1769)
* Refactor Mplex.

Thereby addressing the following issues:

  * Send a `Reset` frame when open substreams get dropped (313).
  * Avoid stalls caused by a read operation on one substream
    reading (and buffering) frames for another substream without
    notifying the corresponding task. I.e. the tracked read-interest
    must be scoped to a substream.
  * Remove dropped substreams from the tracked set of open
    substreams, to avoid artificially running into substream
    limits.

* Update CHANGELOG.

* Refine behaviour of dropping substreams.

By taking the substream state into account. The refined
behaviour is modeled after the behaviour of Yamux.

* Tweak docs and recv buffer retention.

* Further small tweaks.

 * Make the pending frames a FIFO queue.
 * Take more care to avoid keeping read-wakers around
   and to notify them when streams close.

* Prefer wake over unregister.

It is probably safer to always wake pending wakers.

* Update muxers/mplex/src/codec.rs

Co-authored-by: Max Inden <mail@max-inden.de>

* Update muxers/mplex/src/io.rs

Co-authored-by: Max Inden <mail@max-inden.de>

* Some review feedback and cosmetics.

* Update muxers/mplex/src/io.rs

Co-authored-by: Max Inden <mail@max-inden.de>

* Revise read control flow for clarity.

While seemingly duplicating some control flow between
`poll_next_strean` and `poll_read_stream`, the individual
control flow of each read operation is easier to follow.

* CI

* Rename Status::Ok to Status::Open.

* Rename pending_flush to pending_flush_open.

* Finishing touches.

* Tweak changelog.

Co-authored-by: Max Inden <mail@max-inden.de>
2020-09-28 10:30:49 +02:00
Demi Obenour
9178459cc8
Automatic fixes by cargo-fix (#1662) 2020-07-27 22:27:33 +02:00
Pierre Krieger
826f5130cd
Allow StreamMuxer to notify changes in the address (#1621)
* Allow StreamMuxer to notify changes in the address

* Fix doc link

* Revert accidental rename

* Other accidental rename

Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
2020-06-30 17:10:53 +02:00
Pierre Krieger
00fc223487
Deprecate StreamMuxer::is_remote_acknowledged (#1616) 2020-06-19 11:59:24 +02:00
Toralf Wittner
3f12a5ceaa
mplex: Check for error and shutdown. (#1529)
* mplex: Check for error and shutdown.

Issues #1504 and #1523 reported panics caused by polling the sink of
`secio::LenPrefixCodec` after it had entered its terminal state, i.e.
after it had previously encountered an error or was closed. According
to the reports this happened only when using mplex as a stream
multiplexer. It seems that because mplex always stores and keeps the
`Waker` when polling, a wakeup of any of those wakers will resume the
polling even for those cases where the previous poll did not return
`Poll::Pending` but resolved to a value.

To prevent polling after the connection was closed or an error
happened we check for those conditions prior to every poll.

* Keep error when operations fail.

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
2020-04-01 14:28:59 +02: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
Toralf Wittner
2bc8d9590d Update to bytes v0.5
Except for `multiaddr` which encapsulates its use of bytes v0.4 now.
2019-12-21 15:42:24 +01:00
Max Inden
8944899fe0 *: Remove usage of custom buffer initialization usage (#1263)
* *: Remove usage of custom buffer initialization usage

With version `0.3.0-alpha.19` the futures-preview crate makes the
`AsyncRead::initializer` API unstable.

In order to improve interoperability with e.g. both a library depending
on alpha.18 as well as a library depending on alpha.19 and in order for
rust-libp2p to become stable again, this commit removes all usages of
the unstable `initializer` API.

* protocols/noise: Remove NoiseOutput Asyncread initializer

* transports/tcp: Remove TcpTransStream AsyncRead initializer

* *: Remove version pinning of futures-preview to 0.3.0-alpha.18

With version 0.3.0-alpha.19 the futures-preview crate makes the
AsyncRead::initializer API unstable. Given that the previous commits
removed usage of the initializer API, the version pinning is not needed
any longer.
2019-11-01 16:53:11 +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
Roman Borschel
589d280bb5
[multistream-select] Reduce roundtrips in protocol negotiation. (#1212)
* Remove tokio-codec dependency from multistream-select.

In preparation for the eventual switch from tokio to std futures.

Includes some initial refactoring in preparation for further work
in the context of https://github.com/libp2p/rust-libp2p/issues/659.

* Reduce default buffer sizes.

* Allow more than one frame to be buffered for sending.

* Doc tweaks.

* Remove superfluous (duplicated) Message types.

* Reduce roundtrips in multistream-select negotiation.

1. Enable 0-RTT: If the dialer only supports a single protocol, it can send
   protocol data (e.g. the actual application request) together with
   the multistream-select header and protocol proposal. Similarly,
   if the listener supports a proposed protocol, it can send protocol
   data (e.g. the actual application response) together with the
   multistream-select header and protocol confirmation.

2. In general, the dialer "settles on" an expected protocol as soon
   as it runs out of alternatives. Furthermore, both dialer and listener
   do not immediately flush the final protocol confirmation, allowing it
   to be sent together with application protocol data. Attempts to read
   from the negotiated I/O stream implicitly flushes any pending data.

3. A clean / graceful shutdown of an I/O stream always completes protocol
   negotiation.

The publich API of multistream-select changed slightly, requiring both
AsyncRead and AsyncWrite bounds for async reading and writing due to
the implicit buffering and "lazy" negotiation. The error types have
also been changed, but they were not previously fully exported.

Includes some general refactoring with simplifications and some more tests,
e.g. there was an edge case relating to a possible ambiguity when parsing
multistream-select protocol messages.

* Further missing commentary.

* Remove unused test dependency.

* Adjust commentary.

* Cleanup NegotiatedComplete::poll()

* Fix deflate protocol tests.

* Stabilise network_simult test.

The test implicitly relied on "slow" connection establishment
in order to have a sufficient probability of passing.
With the removal of roundtrips in multistream-select, it is now
more likely that within the up to 50ms duration between swarm1
and swarm2 dialing, the connection is already established, causing
the expectation of step == 1 to fail when receiving a Connected event,
since the step may then still be 0.

This commit aims to avoid these spurious errors by detecting runs
during which a connection is established "too quickly", repeating
the test run.

It still seems theoretically possible that, if connections are always
established "too quickly", the test runs forever. However, given that
the delta between swarm1 and swarm2 dialing is 0-50ms and that the
TCP transport is used, that seems probabilistically unlikely.
Nevertheless, the purpose of the artificial dialing delay between
swarm1 and swarm2 should be re-evaluated and possibly at least
the maximum delay further reduced.

* Complete negotiation between upgrades in libp2p-core.

While multistream-select, as a standalone library and providing
an API at the granularity of a single negotiation, supports
lazy negotiation (and in particular 0-RTT negotiation), in the
context of libp2p-core where any number of negotiations are
composed generically within the concept of composable "upgrades",
it is necessary to wait for protocol negotiation between upgrades
to complete.

* Clarify docs. Simplify listener upgrades.

Since reading from a Negotiated I/O stream implicitly flushes any pending
negotiation data, there is no pitfall involved in not waiting for completion.
2019-08-12 12:09:53 +02:00
Roman Borschel
bcc7c4d349
Fix missed task notifications. (#1210)
Addresses https://github.com/libp2p/rust-libp2p/issues/1206 by always
registering the current task before calling poll_*_notify functions.
This is in the same spirit as the corresponding fix for yamux
in https://github.com/paritytech/yamux/pull/54.

Also adds missing registration of the current task in close()
and flush_all(), which have been observed to cause stalls
when trying to do a graceful connection shutdown / close.
2019-07-24 11:32:59 +02:00
Pierre Krieger
c2398adf67
Add implementations of prepare_uninitialized_buffer and read_buf where relevant (#1107)
* Fix #1080

* Fix browser WebSockets
2019-05-10 11:26:18 +02:00
Fedor Sakharov
68df8c07cf muxing: adds an error type to streammuxer (#1083)
* muxing: adds an error type to streammuxer

* Update examples/chat.rs

Co-Authored-By: montekki <fedor.sakharov@gmail.com>

* make the trait error type bound to io error
2019-04-28 13:42:18 +02:00
Pierre Krieger
96e559b503
Wrap multistream-select streams under a Negotiated (#1001) 2019-03-19 17:27:30 +01:00
Pierre Krieger
bbe0bd3377
Fix warning in mplex (#1000) 2019-03-16 12:18:12 +01:00
Pierre Krieger
1eb7dd8582
Add half-closed mplex substream support (#984) 2019-03-12 15:59:37 +01:00
Pierre Krieger
8059a693a3
Cleaner shutdown process (#992)
* Cleaner shutdown process

* Finish

* Fix Yamux panic

* Remove irrelevant tests

* Update core/src/nodes/handled_node_tasks.rs

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

* Fix yamux error handling

* Update yamux
2019-03-11 17:19:50 +01:00
Pierre Krieger
747478a55d
Fix simultaneous dialing test (#957) 2019-02-20 16:25:34 +01:00
Toralf Wittner
e23b2733e2
Fix some rustc/clippy warnings. (#895) 2019-01-30 15:41:54 +01:00
Pierre Krieger
f492cb3786
Remove even substream numbers from mplex (#869)
* Remove even substream numbers from mplex

* Add panic on overflow
2019-01-25 11:26:37 +01:00
David
90bafa7b0c Add a setter for split_send_size (#801)
* Add a setter for `split_send_size`

* Cap `split_send_size` to the Mplex max of 1Mbyte
2019-01-04 13:25:51 +01:00
Pierre Krieger
af698a1ce7
Update muxers to edition 2018 (#788)
* Upgrade mplex to edition 2018

* Upgrade yamux to edition 2018
2018-12-18 11:06:37 +01:00
Toralf Wittner
a152e18821
Simplify handling of upgrade information. (#761) 2018-12-11 15:13:10 +01:00
David
2004b196e2 Send Close when shutting down gracefully, as per spec (#631) 2018-11-16 11:35:57 +01:00
Toralf Wittner
2e549884ef Split ConnectionUpgrade. (#642)
Introduce `InboundUpgrade` and `OutboundUpgrade`.
2018-11-15 17:41:11 +01:00
James Ray
61f280f3ef Fix grammar in core/nodes etc. (#608)
* Fix grammar

* Nothing we can *do* except ...

* Implementer

* Implementation
2018-11-07 17:01:33 +01:00
James Ray
45cd7db6e9 Remove spaces before semicolons (#591) 2018-10-29 10:38:32 +01:00
Pierre Krieger
5d1c54cc10
New core (#568)
* New core

* Fix lifetime requirements

* Remove identify transport

* Address &mut & ref ref mut

* Fix whitespaces
2018-10-17 10:17:40 +01:00
Toralf Wittner
da05a10790
Shut down yamux and fix mplex shutdown. (#559)
mplex gets a new flag `is_shutdown` to keep track of when `shutdown` has
been called. We need to make certain that after the shutdown no more
`Sink::poll_complete` or `Sink::start_send` calls are being made which
may result in a panic.
2018-10-11 15:43:34 +02:00
Toralf Wittner
7016b86b3a
Add StreamMuxer::flush. (#534)
Update the `StreamMuxer` trait.

- `read_substream`, `write_substream` and `flush_substream` now return `Poll` instead of `Result`.
- A new `Shutdown` enum allows for half-closing of substreams and is used in `shutdown_substream`.
- `close_inbound` and `close_outbound` have been merged into `shutdown` which takes a `Shutdown` parameter to allow closing only one direction.
- Add a new `flush_all` method  to allow flushing after a series of actions (e.g. multiple `shutdown_substream`).

W.r.t. flushing the general idea is that normal use drains buffers over time. Shutting down a substream does not imply flushing, so can be followed by `flush_substream` or (if multiple substreams are to be shut down) a single `flush_all`. Shutting down the muxer itself proceeds likewise, i.e. `shutdown` followed by `flush_all`.
2018-10-11 10:35:14 +02:00
Pierre Krieger
063ab178a9
Add an alternative to the swarm (#472)
* Rewrite the swarm

* Small improvement to Debug of ListenersStream

* Fix Swarm::Replaced never being produced

* Fix logic problem when reaching a node in swarm

* Small comment in swarm

* Add closed_multiaddr to Replaced event

* Add address to NodeClosed and NodeError

* Fix concerns

* Remove StreamMuxer::boxed
2018-09-14 13:18:10 +02:00
Toralf Wittner
cfdfca1a06
Similar to #469, consider endpoint while retaining. (#470) 2018-09-10 14:03:38 +02:00
Toralf Wittner
ec6ec92a79
mplex: fix destroy_substream (#469)
Retain all incoming buffer elements with different substream ID or equal
Endpoint. The latter was previously not considered which could result in
the removal of data for another substream with same ID but opposite
Endpoint.
2018-09-10 10:21:19 +02:00
Pierre Krieger
bccd710fb4
Limit upload frame sizes to 1024 in mplex (#462) 2018-09-06 15:43:49 +02:00
Toralf Wittner
5c35047ee3 Change stream ID handling to consider flags. (#436)
Replaces the former odd/even distinction of IDs. However we still increment stream IDs by 2
for backwards compatibility.
2018-09-06 13:59:14 +02:00
Pierre Krieger
ba4bd79fd9
Fix mplex notifications system (#455)
* Fix mplex notifications system

* Some fixes
2018-09-05 01:53:39 +02:00