mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-05-30 11:11:21 +00:00
parent
7aa08917ea
commit
c77b1f5a0a
59
README.md
59
README.md
@ -1,55 +1,24 @@
|
|||||||
# [WIP] Central repository for work on libp2p
|
# Central repository for work on libp2p
|
||||||
|
|
||||||
This repository is the central place for rust development of the
|
This repository is the central place for Rust development of the [libp2p](https://libp2p.io) spec.
|
||||||
[libp2p](https://libp2p.io) spec.
|
|
||||||
|
|
||||||
This readme along with many others will be more fleshed out the closer
|
**This readme will be more fleshed out the closer the project gets to completion.
|
||||||
the project gets to completion. Right now everything including the crate
|
Right now everything including the crate organization is very much Work in Progress.**
|
||||||
organization is very much Work in Progress.
|
|
||||||
|
|
||||||
## The main crate: libp2p
|
## Documentation
|
||||||
|
|
||||||
This repository includes a facade crate named `libp2p`, which reexports the rest of the repository.
|
This repository includes a facade crate named `libp2p`, which reexports the rest of the repository.
|
||||||
|
|
||||||
## General overview of the architecture
|
For documentation, you are encouraged to clone this repository or add `libp2p` as a dependency in
|
||||||
|
your Cargo.toml and run `cargo doc`.
|
||||||
|
|
||||||
Architecture of the other crates of this repository:
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
libp2p = { git = "https://github.com/libp2p/rust-libp2p" }
|
||||||
|
```
|
||||||
|
|
||||||
- `cid`: implements [CID (Content IDentifier)](https://github.com/ipld/cid): Self-describing content-addressed identifiers for distributed systems.
|
## Notable users
|
||||||
- `circular-buffer`: An optimized FIFO queue that allows safe access to the internal storage as a slice (i.e. not just element-by-element). This is useful for circular buffers of bytes. Since it uses `smallvec`'s `Array` trait it can only be backed by an array of static size, this may change in the future.
|
|
||||||
- `core`: Transport, protocol upgrade and swarm systems of libp2p. This crate contains all the core traits and mechanisms of the transport and swarm systems of libp2p.
|
|
||||||
- `datastore`: Utility library whose API provides a key-value storage with multiple possible backends. Used by `peerstore`.
|
|
||||||
- `dns`: this crate provides the type `DnsConfig` that allows one to resolve the `/dns4/` and `/dns6/` components of multiaddresses.
|
|
||||||
- `example`: Example usages of this library.
|
|
||||||
- `floodsub`: a flooding PubSub implementation for p2p messaging.
|
|
||||||
- `identify`: implementation of the `/ipfs/id/1.0.0`<!--TODO: where is this? It's also stated in multicodec but I can't find the source code.--> protocol that allows a node A to query another node B what information B knows about A. Implements the `ConnectionUpgrade` trait of `core`. Also includes the addresses B is listening on.
|
|
||||||
- `kad`: kademlia DHT implementation for peer routing
|
|
||||||
- `mplex`: Implements a binary stream [multiplex](https://github.com/maxogden/multiplex)er, streams multiple streams of binary data over a single binary stream.
|
|
||||||
- [`multiaddr`](https://github.com/multiformats/multiaddr): composable, future-proof, efficient and self-describing network addresses
|
|
||||||
- [`multihash`](https://github.com/multiformats/multihash): self identifying hashes; differentiating outputs from various well-established cryptographic hash functions; addressing size + encoding considerations; future-proofing use of hashes, and allowing multiple hash functions to coexist.
|
|
||||||
- `multistream-select`: used internally by libp2p to negotiate a protocol over a newly-established connection with a peer, or after a connection upgrade.
|
|
||||||
- `peerstore`: Generic storage for information about remote peers (their multiaddresses and their public key), with multiple possible backends. Each multiaddress also has a time-to-live. Used by `core`.
|
|
||||||
- `ping`: Implementation of the `ping` protocol (the exact protocol is specific to libp2p). Implements the `ConnectionUpgrade` trait of `core`.
|
|
||||||
- `ratelimit`: manages rate limiting with a connection. Also see [here](https://github.com/libp2p/specs/blob/master/8-implementations.md#811-swarm-dialer) for design.
|
|
||||||
- `relay`: Implements the [`/libp2p/circuit/relay/0.1.0` protocol](https://github.com/libp2p/specs/blob/master/relay/). It allows a source `A` to connect to a destination `B` via an intermediate relay node `R` to which `B` is already connected to. This is used as a last resort to make `B` reachable from other nodes when it would normally not be, e.g. due to certain NAT setups.
|
|
||||||
- `rw-stream-sink`: Utility library that makes it possible to wrap around a tokio `Stream + Sink` of bytes and implements `AsyncRead + AsyncWrite`.
|
|
||||||
- `secio`: Implementation of the `secio` protocol. Encrypts communications. Implements the `ConnectionUpgrade` trait of `core`.
|
|
||||||
- `tcp-transport`: Implementation of the `Transport` trait of `core` for TCP/IP.
|
|
||||||
- `uds`: Implementation of `Transport` for UNIX domain sockets.
|
|
||||||
- `varint`: encoding and decoding state machines for protobuf varints.
|
|
||||||
- `websocket`: Implementation of the `Transport` trait of `core` for Websockets.
|
|
||||||
|
|
||||||
## About the `impl Trait` syntax
|
(open a pull request if you want your project to be added here)
|
||||||
|
|
||||||
Right now a lot of code of this library uses `Box<Future>` or `Box<Stream>` objects, or forces
|
|
||||||
`'static` lifetime bounds.
|
|
||||||
|
|
||||||
This is caused by the lack of a stable `impl Trait` syntax in the Rust language. Once this syntax
|
|
||||||
is fully implemented and stabilized, it will be possible to change this code to use plain and
|
|
||||||
non-static objects instead of boxes.
|
|
||||||
|
|
||||||
Progress for the `impl Trait` syntax can be tracked in [this issue of the Rust repository](https://github.com/rust-lang/rust/issues/34511).
|
|
||||||
|
|
||||||
Once this syntax is stable in the nightly version, we will consider requiring the nightly version
|
|
||||||
of the compiler and switching to this syntax.
|
|
||||||
|
|
||||||
|
- https://github.com/paritytech/polkadot
|
||||||
|
178
core/README.md
178
core/README.md
@ -1,178 +0,0 @@
|
|||||||
# libp2p-core
|
|
||||||
|
|
||||||
Transport, protocol upgrade and swarm systems of *libp2p*.
|
|
||||||
|
|
||||||
This crate contains all the core traits and mechanisms of the transport and swarm systems
|
|
||||||
of *libp2p*.
|
|
||||||
|
|
||||||
# The `Transport` trait
|
|
||||||
|
|
||||||
The main trait that this crate provides is `Transport`, which provides the `dial` and
|
|
||||||
`listen_on` methods and can be used to dial or listen on a multiaddress. The `swarm` crate
|
|
||||||
itself does not provide any concrete (i.e. non-dummy, non-adapter) implementation of this trait.
|
|
||||||
It is implemented on structs that are provided by external crates, such as `TcpConfig` from
|
|
||||||
`tcp-transport`, `UdpConfig`, or `WebsocketConfig` (note: as of the writing of this
|
|
||||||
documentation, the last two structs don't exist yet).
|
|
||||||
|
|
||||||
Each implementation of `Transport` only supports *some* multiaddress protocols, for example
|
|
||||||
the `TcpConfig` struct only supports multiaddresses that look like `/ip*/*.*.*.*/tcp/*`. It is
|
|
||||||
possible to group two implementations of `Transport` with the `or_transport` method, in order
|
|
||||||
to obtain a single object that supports the protocols of both objects at once. This can be done
|
|
||||||
multiple times in a row in order to chain as many implementations as you want.
|
|
||||||
|
|
||||||
```
|
|
||||||
// TODO: right now only tcp-transport exists, we need to add an example for chaining
|
|
||||||
// multiple transports once that makes sense
|
|
||||||
```
|
|
||||||
|
|
||||||
## The `MuxedTransport` trait
|
|
||||||
|
|
||||||
The `MuxedTransport` trait is an extension to the `Transport` trait, and is implemented on
|
|
||||||
transports that can receive incoming connections on streams that have been opened with `dial()`.
|
|
||||||
|
|
||||||
The trait provides the `next_incoming()` method, which returns a future that will resolve to
|
|
||||||
the next substream that arrives from a dialed node.
|
|
||||||
|
|
||||||
> **Note**: This trait is mainly implemented for transports that provide stream muxing
|
|
||||||
> capabilities, but it can also be implemented in a dummy way by returning an empty
|
|
||||||
> iterator.
|
|
||||||
|
|
||||||
# Connection upgrades
|
|
||||||
|
|
||||||
Once a socket has been opened with a remote through a `Transport`, it can be *upgraded*. This
|
|
||||||
consists in negotiating a protocol with the remote (through `multistream-select`), and applying
|
|
||||||
that protocol on the socket.
|
|
||||||
|
|
||||||
A potential connection upgrade is represented with the `ConnectionUpgrade` trait. The trait
|
|
||||||
consists in a protocol name plus a method that turns the socket into an `Output` object whose
|
|
||||||
nature and type is specific to each upgrade.
|
|
||||||
|
|
||||||
There exists three kinds of connection upgrades: middlewares, muxers, and actual protocols.
|
|
||||||
|
|
||||||
## Middlewares
|
|
||||||
|
|
||||||
Examples of middleware connection upgrades include `PlainTextConfig` (dummy upgrade) or
|
|
||||||
`SecioConfig` (encyption layer, provided by the `secio` crate).
|
|
||||||
|
|
||||||
The output of a middleware connection upgrade implements the `AsyncRead` and `AsyncWrite`
|
|
||||||
traits, just like sockets do.
|
|
||||||
|
|
||||||
A middleware can be applied on a transport by using the `with_upgrade` method of the
|
|
||||||
`Transport` trait. The return value of this method also implements the `Transport` trait, which
|
|
||||||
means that you can call `dial()` and `listen_on()` on it in order to directly obtain an
|
|
||||||
upgraded connection or a listener that will yield upgraded connections. Similarly, the
|
|
||||||
`next_incoming()` method will automatically apply the upgrade on both the dialer and the
|
|
||||||
listener. An error is produced if the remote doesn't support the protocol corresponding to the
|
|
||||||
connection upgrade.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate libp2p_core;
|
|
||||||
extern crate libp2p_tcp_transport;
|
|
||||||
extern crate tokio_current_thread;
|
|
||||||
|
|
||||||
use libp2p_core::Transport;
|
|
||||||
|
|
||||||
let tokio_core = tokio_core::reactor::Core::new().unwrap();
|
|
||||||
let tcp_transport = libp2p_tcp_transport::TcpConfig::new(tokio_core.handle());
|
|
||||||
let upgraded = tcp_transport.with_upgrade(libp2p_core::PlainTextConfig);
|
|
||||||
|
|
||||||
// upgraded.dial(...) // automatically applies the plain text protocol on the socket
|
|
||||||
```
|
|
||||||
|
|
||||||
## Muxers
|
|
||||||
|
|
||||||
The concept of *muxing* consists in using a single stream as if it was multiple substreams.
|
|
||||||
|
|
||||||
If the output of the connection upgrade instead implements the `StreamMuxer` and `Clone`
|
|
||||||
traits, then you can turn the `UpgradedNode` struct into a `ConnectionReuse` struct by calling
|
|
||||||
`ConnectionReuse::from(upgraded_node)`.
|
|
||||||
|
|
||||||
The `ConnectionReuse` struct then implements the `Transport` and `MuxedTransport` traits, and
|
|
||||||
can be used to dial or listen to multiaddresses, just like any other transport. The only
|
|
||||||
difference is that dialing a node will try to open a new substream on an existing connection
|
|
||||||
instead of opening a new one every time.
|
|
||||||
|
|
||||||
> **Note**: Right now the `ConnectionReuse` struct is not fully implemented.
|
|
||||||
|
|
||||||
`TODO: add an example once the multiplex pull request is merged`
|
|
||||||
|
|
||||||
## Actual protocols
|
|
||||||
|
|
||||||
*Actual protocols* work the same way as middlewares, except that their `Output` doesn't
|
|
||||||
implement the `AsyncRead` and `AsyncWrite` traits. This means that that the return value of
|
|
||||||
`with_upgrade` does **not** implement the `Transport` trait and thus cannot be used as a
|
|
||||||
transport.
|
|
||||||
|
|
||||||
However the `UpgradedNode` struct returned by `with_upgrade` still provides methods named
|
|
||||||
`dial`, `listen_on`, and `next_incoming`, which will yield you a `Future` or a `Stream`,
|
|
||||||
which you can use to obtain the `Output`. This `Output` can then be used in a protocol-specific
|
|
||||||
way to use the protocol.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate futures;
|
|
||||||
extern crate libp2p_ping;
|
|
||||||
extern crate libp2p_core;
|
|
||||||
extern crate libp2p_tcp_transport;
|
|
||||||
extern crate tokio_current_thread;
|
|
||||||
|
|
||||||
use futures::Future;
|
|
||||||
use libp2p_ping::Ping;
|
|
||||||
use libp2p_core::Transport;
|
|
||||||
|
|
||||||
let mut core = tokio_core::reactor::Core::new().unwrap();
|
|
||||||
|
|
||||||
let ping_finished_future = libp2p_tcp_transport::TcpConfig::new()
|
|
||||||
// We have a `TcpConfig` struct that implements `Transport`, and apply a `Ping` upgrade on it.
|
|
||||||
.with_upgrade(Ping)
|
|
||||||
// TODO: right now the only available protocol is ping, but we want to replace it with
|
|
||||||
// something that is more simple to use
|
|
||||||
.dial("127.0.0.1:12345".parse::<libp2p_core::Multiaddr>().unwrap()).unwrap_or_else(|_| panic!())
|
|
||||||
.and_then(|((mut pinger, service), _)| {
|
|
||||||
pinger.ping().map_err(|_| panic!()).select(service).map_err(|_| panic!())
|
|
||||||
});
|
|
||||||
|
|
||||||
// Runs until the ping arrives.
|
|
||||||
tokio_current_thread::block_on_all(ping_finished_future).unwrap();
|
|
||||||
```
|
|
||||||
|
|
||||||
## Grouping protocols
|
|
||||||
|
|
||||||
You can use the `.or_upgrade()` method to group multiple upgrades together. The return value
|
|
||||||
also implements the `ConnectionUpgrade` trait and will choose one of the protocols amongst the
|
|
||||||
ones supported.
|
|
||||||
|
|
||||||
# Swarm
|
|
||||||
|
|
||||||
Once you have created an object that implements the `Transport` trait, you can put it in a
|
|
||||||
*swarm*. This is done by calling the `swarm()` freestanding function with the transport
|
|
||||||
alongside with a function or a closure that will turn the output of the upgrade (usually an
|
|
||||||
actual protocol, as explained above) into a `Future` producing `()`.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate futures;
|
|
||||||
extern crate libp2p_ping;
|
|
||||||
extern crate libp2p_core;
|
|
||||||
extern crate libp2p_tcp_transport;
|
|
||||||
extern crate tokio_current_thread;
|
|
||||||
|
|
||||||
use futures::Future;
|
|
||||||
use libp2p_ping::Ping;
|
|
||||||
use libp2p_core::Transport;
|
|
||||||
|
|
||||||
let mut core = tokio_core::reactor::Core::new().unwrap();
|
|
||||||
|
|
||||||
let transport = libp2p_tcp_transport::TcpConfig::new()
|
|
||||||
.with_dummy_muxing();
|
|
||||||
|
|
||||||
let (swarm_controller, swarm_future) = libp2p_core::swarm(transport, Ping, |(mut pinger, service), client_addr| {
|
|
||||||
pinger.ping().map_err(|_| panic!())
|
|
||||||
.select(service).map_err(|_| panic!())
|
|
||||||
.map(|_| ())
|
|
||||||
});
|
|
||||||
|
|
||||||
// The `swarm_controller` can then be used to do some operations.
|
|
||||||
swarm_controller.listen_on("/ip4/0.0.0.0/tcp/0".parse().unwrap());
|
|
||||||
|
|
||||||
// Runs until everything is finished.
|
|
||||||
tokio_current_thread::block_on_all(swarm_future).unwrap();
|
|
||||||
```
|
|
@ -18,9 +18,6 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// TODO: use this once stable ; for now we just copy-paste the content of the README.md
|
|
||||||
//#![doc(include = "../README.md")]
|
|
||||||
|
|
||||||
//! Transport, protocol upgrade and swarm systems of *libp2p*.
|
//! Transport, protocol upgrade and swarm systems of *libp2p*.
|
||||||
//!
|
//!
|
||||||
//! This crate contains all the core traits and mechanisms of the transport and swarm systems
|
//! This crate contains all the core traits and mechanisms of the transport and swarm systems
|
||||||
|
@ -116,7 +116,7 @@ pub trait Transport {
|
|||||||
/// implementation of `Transport` is only responsible for handling the protocols it supports.
|
/// implementation of `Transport` is only responsible for handling the protocols it supports.
|
||||||
///
|
///
|
||||||
/// Returns `None` if nothing can be determined. This happens if this trait implementation
|
/// Returns `None` if nothing can be determined. This happens if this trait implementation
|
||||||
/// doesn't recognize the protocols, or if `server` and `observed` are related.
|
/// doesn't recognize the protocols, or if `server` and `observed` are unrelated.
|
||||||
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr>;
|
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr>;
|
||||||
|
|
||||||
/// Applies a function on the output of the `Transport`.
|
/// Applies a function on the output of the `Transport`.
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
General-purpose key-value storage.
|
|
||||||
The keys are strings, and the values are of any type you want.
|
|
||||||
|
|
||||||
> **Note**: This crate is meant to be a utility for the implementation of other crates ; it
|
|
||||||
> does not directly participate in the stack of libp2p.
|
|
||||||
|
|
||||||
This crate provides the `Datastore` trait, whose template parameter is the type of the value.
|
|
||||||
It is implemented on types that represent a key-value storage.
|
|
||||||
The only available implementation for now is `JsonFileDatastore`.
|
|
||||||
|
|
||||||
# JSON file datastore
|
|
||||||
|
|
||||||
The `JsonFileDatastore` can provide a key-value storage that loads and stores data in a single
|
|
||||||
JSON file. It is only available if the value implements the `Serialize`, `DeserializeOwned`
|
|
||||||
and `Clone` traits.
|
|
||||||
|
|
||||||
The `JsonFileDatastore::new` method will attempt to load existing data from the path you pass
|
|
||||||
as parameter. This path is also where the data will be stored. The content of the store is
|
|
||||||
flushed on drop or if you call `flush()`.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use datastore::Datastore;
|
|
||||||
use datastore::JsonFileDatastore;
|
|
||||||
|
|
||||||
let datastore = JsonFileDatastore::<Vec<u8>>::new("/tmp/test.json").unwrap();
|
|
||||||
datastore.put("foo".into(), vec![1, 2, 3]);
|
|
||||||
datastore.put("bar".into(), vec![0, 255, 127]);
|
|
||||||
assert_eq!(datastore.get("foo").unwrap(), &[1, 2, 3]);
|
|
||||||
datastore.flush().unwrap(); // optional
|
|
||||||
```
|
|
||||||
|
|
||||||
# Query
|
|
||||||
|
|
||||||
In addition to simple operations such as `get` or `put`, the `Datastore` trait also provides
|
|
||||||
a way to perform queries on the key-value storage, using the `query` method.
|
|
||||||
|
|
||||||
The struct returned by the `query` method implements the `Stream` trait from `futures`,
|
|
||||||
meaning that the result is asynchronous.
|
|
||||||
|
|
||||||
> **Note**: For now the API of the `get` and `has` methods makes them potentially blocking
|
|
||||||
> operations, though the only available implementation doesn't block. The API of these
|
|
||||||
> methods may become asynchronous in the future if deemed necessary.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate datastore;
|
|
||||||
extern crate futures;
|
|
||||||
|
|
||||||
use datastore::{Query, Order, Filter, FilterTy, FilterOp};
|
|
||||||
use datastore::Datastore;
|
|
||||||
use datastore::JsonFileDatastore;
|
|
||||||
use futures::{Future, Stream};
|
|
||||||
|
|
||||||
let datastore = JsonFileDatastore::<Vec<u8>>::new("/tmp/test.json").unwrap();
|
|
||||||
let query = datastore.query(Query {
|
|
||||||
// Only return the keys that start with this prefix.
|
|
||||||
prefix: "fo".into(),
|
|
||||||
// List of filters for the keys and/or values.
|
|
||||||
filters: vec![
|
|
||||||
Filter {
|
|
||||||
ty: FilterTy::ValueCompare(&vec![6, 7, 8].into()),
|
|
||||||
operation: FilterOp::NotEqual,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// Order in which to sort the results.
|
|
||||||
orders: vec![Order::ByKeyDesc],
|
|
||||||
// Number of entries to skip at the beginning of the results (after sorting).
|
|
||||||
skip: 1,
|
|
||||||
// Limit to the number of entries to return (use `u64::max_value()` for no limit).
|
|
||||||
limit: 12,
|
|
||||||
// If true, don't load the values. For optimization purposes.
|
|
||||||
keys_only: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
let results = query.collect().wait().unwrap();
|
|
||||||
println!("{:?}", results);
|
|
||||||
```
|
|
@ -18,9 +18,6 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// TODO: use this once stable ; for now we just copy-paste the content of the README.md
|
|
||||||
//#![doc(include = "../README.md")]
|
|
||||||
|
|
||||||
//! General-purpose key-value storage.
|
//! General-purpose key-value storage.
|
||||||
//! The keys are strings, and the values are of any type you want.
|
//! The keys are strings, and the values are of any type you want.
|
||||||
//!
|
//!
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
# libp2p-dns
|
|
||||||
|
|
||||||
This crate provides the type `DnsConfig` that allows one to resolve the `/dns4/` and `/dns6/`
|
|
||||||
components of multiaddresses.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
In order to use this crate, create a `DnsConfig` with one of its constructors and pass it an
|
|
||||||
implementation of the `Transport` trait.
|
|
||||||
|
|
||||||
Whenever we want to dial an address through the `DnsConfig` and that address contains a
|
|
||||||
`/dns4/` or `/dns6/` component, a DNS resolve will be performed and the component will be
|
|
||||||
replaced with respectively an `/ip4/` or an `/ip6/` component.
|
|
@ -18,9 +18,6 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// TODO: use this once stable ; for now we just copy-paste the content of the README.md
|
|
||||||
//#![doc(include = "../README.md")]
|
|
||||||
|
|
||||||
//! # libp2p-dns
|
//! # libp2p-dns
|
||||||
//!
|
//!
|
||||||
//! This crate provides the type `DnsConfig` that allows one to resolve the `/dns4/` and `/dns6/`
|
//! This crate provides the type `DnsConfig` that allows one to resolve the `/dns4/` and `/dns6/`
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
# How the keys were generated
|
|
||||||
|
|
||||||
The keys used in the examples were generated like this:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
openssl genrsa -out private.pem 2048
|
|
||||||
openssl rsa -in private.pem -outform DER -pubout -out public.der
|
|
||||||
openssl pkcs8 -in private.pem -topk8 -nocrypt -out private.pk8
|
|
||||||
rm private.pem # optional
|
|
||||||
```
|
|
@ -18,6 +18,118 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
//! Libp2p is a peer-to-peer framework.
|
||||||
|
//!
|
||||||
|
//! # Major libp2p concepts
|
||||||
|
//!
|
||||||
|
//! Here is a list of all the major concepts of libp2p.
|
||||||
|
//!
|
||||||
|
//! ## Multiaddr
|
||||||
|
//!
|
||||||
|
//! A `Multiaddr` is a way to reach a node. Examples:
|
||||||
|
//!
|
||||||
|
//! * `/ip4/80.123.90.4/tcp/5432`
|
||||||
|
//! * `/ip6/[::1]/udp/10560`
|
||||||
|
//! * `/unix//path/to/socket`
|
||||||
|
//!
|
||||||
|
//! ## Transport
|
||||||
|
//!
|
||||||
|
//! `Transport` is a trait that represents an object capable of dialing multiaddresses or
|
||||||
|
//! listening on multiaddresses. The `Transport` produces an output which varies depending on the
|
||||||
|
//! object that implements the trait.
|
||||||
|
//!
|
||||||
|
//! Each implementation of `Transport` typically supports only some multiaddresses. For example
|
||||||
|
//! the `TcpConfig` type (which implements `Transport`) only supports multiaddresses of the format
|
||||||
|
//! `/ip4/.../tcp/...`.
|
||||||
|
//!
|
||||||
|
//! Example:
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! use libp2p::{Multiaddr, Transport, tcp::TcpConfig};
|
||||||
|
//! let tcp_transport = TcpConfig::new();
|
||||||
|
//! let addr: Multiaddr = "/ip4/98.97.96.95/tcp/20500".parse().expect("invalid multiaddr");
|
||||||
|
//! let _outgoing_connec = tcp_transport.dial(addr);
|
||||||
|
//! // Note that `_outgoing_connec` is a `Future`, and therefore doesn't do anything by itself
|
||||||
|
//! // unless it is run through a tokio runtime.
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! The easiest way to create a transport is to use the `CommonTransport` struct. This struct
|
||||||
|
//! provides support for the most common protocols.
|
||||||
|
//!
|
||||||
|
//! Example:
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! use libp2p::CommonTransport;
|
||||||
|
//! let _transport = CommonTransport::new();
|
||||||
|
//! // _transport.dial(...);
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! See the documentation of the `libp2p-core` crate for more details about transports.
|
||||||
|
//!
|
||||||
|
//! # Connection upgrades
|
||||||
|
//!
|
||||||
|
//! Once a connection has been opened with a remote through a `Transport`, it can be *upgraded*.
|
||||||
|
//! This consists in negotiating a protocol with the remote (through the `multistream-select`
|
||||||
|
//! protocol), and applying that protocol on the socket.
|
||||||
|
//!
|
||||||
|
//! Example upgrades:
|
||||||
|
//!
|
||||||
|
//! - Adding a security layer on top of the connection.
|
||||||
|
//! - Applying multiplexing, so that a connection can be split into multiple substreams.
|
||||||
|
//! - Negotiating a specific protocol, such as *ping* or *kademlia*.
|
||||||
|
//!
|
||||||
|
//! A potential connection upgrade is represented with the `ConnectionUpgrade` trait. The trait
|
||||||
|
//! consists in a protocol name plus a method that turns the socket into an `Output` object whose
|
||||||
|
//! nature and type is specific to each upgrade. For example, if you upgrade a connection with a
|
||||||
|
//! security layer, the output might contain an encrypted stream and the public key of the remote.
|
||||||
|
//!
|
||||||
|
//! You can combine a `Transport` with a compatible `ConnectionUpgrade` in order to obtain another
|
||||||
|
//! `Transport` that yields the output of the upgrade.
|
||||||
|
//!
|
||||||
|
//! Example:
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! use libp2p::{Transport, tcp::TcpConfig, secio::{SecioConfig, SecioKeyPair}};
|
||||||
|
//! let tcp_transport = TcpConfig::new();
|
||||||
|
//! let secio_upgrade = SecioConfig {
|
||||||
|
//! key: SecioKeyPair::ed25519_generated().unwrap(),
|
||||||
|
//! };
|
||||||
|
//! let with_security = tcp_transport.with_upgrade(secio_upgrade);
|
||||||
|
//! // let _ = with_security.dial(...);
|
||||||
|
//! // `with_security` also implements the `Transport` trait, and all the connections opened
|
||||||
|
//! // through it will automatically negotiate the `secio` protocol.
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! See the documentation of the `libp2p-core` crate for more details about upgrades.
|
||||||
|
//!
|
||||||
|
//! ## Swarm
|
||||||
|
//!
|
||||||
|
//! Once you have created an object that implements the `Transport` trait, you can put it in a
|
||||||
|
//! *swarm*. This is done by calling the `swarm()` freestanding function with the transport
|
||||||
|
//! alongside with a function or a closure that will turn the output of the upgrade (usually an
|
||||||
|
//! actual protocol, as explained above) into a `Future` producing `()`.
|
||||||
|
//!
|
||||||
|
//! See the documentation of the `libp2p-core` crate for more details about creating a swarm.
|
||||||
|
//!
|
||||||
|
//! # Using libp2p
|
||||||
|
//!
|
||||||
|
//! This section contains details about how to use libp2p in practice.
|
||||||
|
//!
|
||||||
|
//! The most simple way to use libp2p consists in the following steps:
|
||||||
|
//!
|
||||||
|
//! - Create a *base* implementation of `Transport` that combines all the protocols you want and
|
||||||
|
//! the upgrades you want, such as the security layer and multiplexing.
|
||||||
|
//! - Create structs that implement the `ConnectionUpgrade` trait for the protocols you want to
|
||||||
|
//! create, or use the protocols provided by the `libp2p` crate.
|
||||||
|
//! - Create a swarm that combines your base transport and all the upgrades and that handles the
|
||||||
|
//! behaviour that happens.
|
||||||
|
//! - Use this swarm to dial and listen.
|
||||||
|
//!
|
||||||
|
//! You probably also want to have some sort of nodes discovery mechanism, so that you
|
||||||
|
//! automatically connect to nodes of the network. The details of this haven't been fleshed out
|
||||||
|
//! in libp2p and will be written later.
|
||||||
|
//!
|
||||||
|
|
||||||
pub extern crate bytes;
|
pub extern crate bytes;
|
||||||
pub extern crate futures;
|
pub extern crate futures;
|
||||||
#[cfg(not(target_os = "emscripten"))]
|
#[cfg(not(target_os = "emscripten"))]
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
# Multiplex
|
|
||||||
|
|
||||||
A Rust implementation of [multiplex](https://github.com/maxogden/multiplex).
|
|
@ -1,63 +0,0 @@
|
|||||||
# rust-multiaddr
|
|
||||||
|
|
||||||
[](http://ipn.io)
|
|
||||||
[](https://github.com/multiformats/multiformats)
|
|
||||||
[](https://webchat.freenode.net/?channels=%23ipfs)
|
|
||||||
[](https://travis-ci.org/multiformats/rust-multiaddr)
|
|
||||||
[](https://codecov.io/github/multiformats/rust-multiaddr?branch=master)
|
|
||||||
[](https://docs.rs/crate/multiaddr)
|
|
||||||
[](https://crates.io/crates/multiaddr)
|
|
||||||
[](https://github.com/RichardLitt/standard-readme)
|
|
||||||
|
|
||||||
|
|
||||||
> [multiaddr](https://github.com/multiformats/multiaddr) implementation in Rust.
|
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
|
|
||||||
- [Install](#install)
|
|
||||||
- [Usage](#usage)
|
|
||||||
- [Maintainers](#maintainers)
|
|
||||||
- [Contribute](#contribute)
|
|
||||||
- [License](#license)
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
First add this to your `Cargo.toml`
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
multiaddr = "*"
|
|
||||||
```
|
|
||||||
|
|
||||||
then run `cargo build`.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate multiaddr;
|
|
||||||
|
|
||||||
use multiaddr::{Multiaddr, ToMultiaddr};
|
|
||||||
|
|
||||||
let address = "/ip4/127.0.0.1/udp/1234".parse::<Multiaddr>().unwrap();
|
|
||||||
// or directly from a string
|
|
||||||
let other = "/ip4/127.0.0.1".to_multiaddr().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(address.to_string(), "/ip4/127.0.0.1/udp/1234");
|
|
||||||
assert_eq!(other.to_string(), "/ip4/127.0.0.1");
|
|
||||||
```
|
|
||||||
|
|
||||||
## Maintainers
|
|
||||||
|
|
||||||
Captain: [@dignifiedquire](https://github.com/dignifiedquire).
|
|
||||||
|
|
||||||
## Contribute
|
|
||||||
|
|
||||||
Contributions welcome. Please check out [the issues](https://github.com/multiformats/rust-multiaddr/issues).
|
|
||||||
|
|
||||||
Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
|
|
||||||
|
|
||||||
Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
[MIT](LICENSE) © 2015-2017 Friedel Ziegelmeyer
|
|
@ -1,68 +0,0 @@
|
|||||||
# rust-multihash
|
|
||||||
|
|
||||||
[](http://ipn.io)
|
|
||||||
[](https://github.com/multiformats/multiformats)
|
|
||||||
[](https://webchat.freenode.net/?channels=%23ipfs)
|
|
||||||
[](https://travis-ci.org/multiformats/rust-multihash)
|
|
||||||
[](https://codecov.io/github/multiformats/rust-multihash?branch=master)
|
|
||||||
[](https://docs.rs/multihash/)
|
|
||||||
[](https://crates.io/crates/multihash)
|
|
||||||
[](https://github.com/RichardLitt/standard-readme)
|
|
||||||
|
|
||||||
> [multihash](https://github.com/multiformats/multihash) implementation in Rust.
|
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
|
|
||||||
- [Install](#install)
|
|
||||||
- [Usage](#usage)
|
|
||||||
- [Supported Hash Types](#supported-hash-types)
|
|
||||||
- [Dependencies](#dependencies)
|
|
||||||
- [Maintainers](#maintainers)
|
|
||||||
- [Contribute](#contribute)
|
|
||||||
- [License](#license)
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
First add this to your `Cargo.toml`
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
multihash = "*"
|
|
||||||
```
|
|
||||||
|
|
||||||
Then run `cargo build`.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate multihash;
|
|
||||||
|
|
||||||
use multihash::{encode, decode, Hash};
|
|
||||||
|
|
||||||
let hash = encode(Hash::SHA2256, b"my hash").unwrap();
|
|
||||||
let multi = decode(&hash).unwrap();
|
|
||||||
```
|
|
||||||
|
|
||||||
## Supported Hash Types
|
|
||||||
|
|
||||||
* `SHA1`
|
|
||||||
* `SHA2-256`
|
|
||||||
* `SHA2-512`
|
|
||||||
* `SHA3`/`Keccak`
|
|
||||||
|
|
||||||
## Maintainers
|
|
||||||
|
|
||||||
Captain: [@dignifiedquire](https://github.com/dignifiedquire).
|
|
||||||
|
|
||||||
## Contribute
|
|
||||||
|
|
||||||
Contributions welcome. Please check out [the issues](https://github.com/multiformats/rust-multihash/issues).
|
|
||||||
|
|
||||||
Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
|
|
||||||
|
|
||||||
Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
[MIT](LICENSE) © 2015-2017 Friedel Ziegelmayer
|
|
@ -1,92 +0,0 @@
|
|||||||
# Multistream-select
|
|
||||||
|
|
||||||
This crate implements the `multistream-select` protocol, which is the protocol used by libp2p
|
|
||||||
to negotiate which protocol to use with the remote.
|
|
||||||
|
|
||||||
> **Note**: This crate is used by the internals of *libp2p*, and it is not required to
|
|
||||||
> understand it in order to use *libp2p*.
|
|
||||||
|
|
||||||
Whenever a new connection or a new multiplexed substream is opened, libp2p uses
|
|
||||||
`multistream-select` to negotiate with the remote which protocol to use. After a protocol has
|
|
||||||
been successfully negotiated, the stream (ie. the connection or the multiplexed substream)
|
|
||||||
immediately stops using `multistream-select` and starts using the negotiated protocol.
|
|
||||||
|
|
||||||
## Protocol explanation
|
|
||||||
|
|
||||||
The dialer has two options available: either request the list of protocols that the listener
|
|
||||||
supports, or suggest a protocol. If a protocol is suggested, the listener can either accept (by
|
|
||||||
answering with the same protocol name) or refuse the choice (by answering "not available").
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
For a dialer:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate bytes;
|
|
||||||
extern crate futures;
|
|
||||||
extern crate multistream_select;
|
|
||||||
extern crate tokio_current_thread;
|
|
||||||
|
|
||||||
use bytes::Bytes;
|
|
||||||
use multistream_select::dialer_select_proto;
|
|
||||||
use futures::{Future, Sink, Stream};
|
|
||||||
use tokio_core::net::TcpStream;
|
|
||||||
use tokio_core::reactor::Core;
|
|
||||||
|
|
||||||
let mut core = Core::new().unwrap();
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
enum MyProto { Echo, Hello }
|
|
||||||
|
|
||||||
let client = TcpStream::connect(&"127.0.0.1:10333".parse().unwrap(), &core.handle())
|
|
||||||
.from_err()
|
|
||||||
.and_then(move |connec| {
|
|
||||||
let protos = vec![
|
|
||||||
(Bytes::from("/echo/1.0.0"), <Bytes as PartialEq>::eq, MyProto::Echo),
|
|
||||||
(Bytes::from("/hello/2.5.0"), <Bytes as PartialEq>::eq, MyProto::Hello),
|
|
||||||
]
|
|
||||||
.into_iter();
|
|
||||||
dialer_select_proto(connec, protos).map(|r| r.0)
|
|
||||||
});
|
|
||||||
|
|
||||||
let negotiated_protocol: MyProto = tokio_current_thread::block_on_all(client).expect("failed to find a protocol");
|
|
||||||
println!("negotiated: {:?}", negotiated_protocol);
|
|
||||||
```
|
|
||||||
|
|
||||||
For a listener:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate bytes;
|
|
||||||
extern crate futures;
|
|
||||||
extern crate multistream_select;
|
|
||||||
extern crate tokio_current_thread;
|
|
||||||
|
|
||||||
use bytes::Bytes;
|
|
||||||
use multistream_select::listener_select_proto;
|
|
||||||
use futures::{Future, Sink, Stream};
|
|
||||||
use tokio_core::net::TcpListener;
|
|
||||||
use tokio_core::reactor::Core;
|
|
||||||
|
|
||||||
let mut core = Core::new().unwrap();
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
enum MyProto { Echo, Hello }
|
|
||||||
|
|
||||||
let server = TcpListener::bind(&"127.0.0.1:0".parse().unwrap(), &core.handle()).unwrap()
|
|
||||||
.incoming()
|
|
||||||
.from_err()
|
|
||||||
.and_then(move |(connec, _)| {
|
|
||||||
let protos = vec![
|
|
||||||
(Bytes::from("/echo/1.0.0"), <Bytes as PartialEq>::eq, MyProto::Echo),
|
|
||||||
(Bytes::from("/hello/2.5.0"), <Bytes as PartialEq>::eq, MyProto::Hello),
|
|
||||||
]
|
|
||||||
.into_iter();
|
|
||||||
listener_select_proto(connec, protos)
|
|
||||||
})
|
|
||||||
.for_each(|(proto, _connec)| {
|
|
||||||
println!("new remote with {:?} negotiated", proto);
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
|
|
||||||
tokio_current_thread::block_on_all(server).expect("failed to run server");
|
|
||||||
```
|
|
@ -18,9 +18,6 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// TODO: use this once stable ; for now we just copy-paste the content of the README.md
|
|
||||||
//#![doc(include = "../README.md")]
|
|
||||||
|
|
||||||
//! # Multistream-select
|
//! # Multistream-select
|
||||||
//!
|
//!
|
||||||
//! This crate implements the `multistream-select` protocol, which is the protocol used by libp2p
|
//! This crate implements the `multistream-select` protocol, which is the protocol used by libp2p
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
The `peerstore` crate allows one to store information about a peer.
|
|
||||||
|
|
||||||
`peerstore` is a key-value database, where the keys are multihashes (which usually corresponds
|
|
||||||
to the hash of the public key of the peer, but that is not enforced by this crate) and the
|
|
||||||
values are the public key and a list of multiaddresses. Additionally, the multiaddresses stored
|
|
||||||
by the `peerstore` have a time-to-live after which they disappear.
|
|
||||||
|
|
||||||
This crate consists of a generic `Peerstore` trait and the follow implementations:
|
|
||||||
|
|
||||||
- `JsonPeerstore`: Stores the information in a single JSON file.
|
|
||||||
- `MemoryPeerstore`: Stores the information in memory.
|
|
||||||
|
|
||||||
Note that the peerstore implementations do not consider information inside a peer store to be
|
|
||||||
critical. In case of an error (eg. corrupted file, disk error, etc.) they will prefer to lose
|
|
||||||
data rather than returning the error.
|
|
||||||
|
|
||||||
# Example
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate multiaddr;
|
|
||||||
extern crate libp2p_peerstore;
|
|
||||||
|
|
||||||
use libp2p_peerstore::memory_peerstore::MemoryPeerstore;
|
|
||||||
use libp2p_peerstore::{Peerstore, PeerAccess};
|
|
||||||
use multiaddr::Multiaddr;
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
// In this example we use a `MemoryPeerstore`, but you can easily swap it for another backend.
|
|
||||||
let mut peerstore = MemoryPeerstore::empty();
|
|
||||||
let peer_id = vec![1, 2, 3, 4];
|
|
||||||
|
|
||||||
// Let's write some information about a peer.
|
|
||||||
{
|
|
||||||
// `peer_or_create` mutably borrows the peerstore, so we have to do it in a local scope.
|
|
||||||
let mut peer = peerstore.peer_or_create(&peer_id);
|
|
||||||
peer.set_pub_key(vec![60, 90, 120, 150]);
|
|
||||||
peer.add_addr("/ip4/10.11.12.13/tcp/20000".parse::<Multiaddr>().unwrap(),
|
|
||||||
Duration::from_millis(5000));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now let's load back the info.
|
|
||||||
{
|
|
||||||
let mut peer = peerstore.peer(&peer_id).expect("peer doesn't exist in the peerstore");
|
|
||||||
assert_eq!(peer.get_pub_key().unwrap(), &[60, 90, 120, 150]);
|
|
||||||
assert_eq!(peer.addrs().collect::<Vec<_>>(),
|
|
||||||
&["/ip4/10.11.12.13/tcp/20000".parse::<Multiaddr>().unwrap()]);
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,52 +0,0 @@
|
|||||||
Handles the `/ipfs/ping/1.0.0` protocol. This allows pinging a remote node and waiting for an
|
|
||||||
answer.
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
|
|
||||||
Create a `Ping` struct, which implements the `ConnectionUpgrade` trait. When used as a
|
|
||||||
connection upgrade, it will produce a tuple of type `(Pinger, impl Future<Item = ()>)` which
|
|
||||||
are named the *pinger* and the *ponger*.
|
|
||||||
|
|
||||||
The *pinger* has a method named `ping` which will send a ping to the remote, while the *ponger*
|
|
||||||
is a future that will process the data received on the socket and will be signalled only when
|
|
||||||
the connection closes.
|
|
||||||
|
|
||||||
# About timeouts
|
|
||||||
|
|
||||||
For technical reasons, this crate doesn't handle timeouts. The action of pinging returns a
|
|
||||||
future that is signalled only when the remote answers. If the remote is not responsive, the
|
|
||||||
future will never be signalled.
|
|
||||||
|
|
||||||
For implementation reasons, resources allocated for a ping are only ever fully reclaimed after
|
|
||||||
a pong has been received by the remote. Therefore if you repeatedly ping a non-responsive
|
|
||||||
remote you will end up using more and more memory (albeit the amount is very very small every
|
|
||||||
time), even if you destroy the future returned by `ping`.
|
|
||||||
|
|
||||||
This is probably not a problem in practice, because the nature of the ping protocol is to
|
|
||||||
determine whether a remote is still alive, and any reasonable user of this crate will close
|
|
||||||
connections to non-responsive remotes (which would then de-allocate memory for the ping).
|
|
||||||
|
|
||||||
# Example
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate futures;
|
|
||||||
extern crate libp2p_ping;
|
|
||||||
extern crate libp2p_core;
|
|
||||||
extern crate libp2p_tcp_transport;
|
|
||||||
extern crate tokio_current_thread;
|
|
||||||
|
|
||||||
use futures::Future;
|
|
||||||
use libp2p_ping::Ping;
|
|
||||||
use libp2p_core::Transport;
|
|
||||||
|
|
||||||
let ping_finished_future = libp2p_tcp_transport::TcpConfig::new()
|
|
||||||
.with_upgrade(Ping)
|
|
||||||
.dial("127.0.0.1:12345".parse::<libp2p_core::Multiaddr>().unwrap()).unwrap_or_else(|_| panic!())
|
|
||||||
.and_then(|((mut pinger, service), _)| {
|
|
||||||
pinger.ping().map_err(|_| panic!()).select(service).map_err(|_| panic!())
|
|
||||||
});
|
|
||||||
|
|
||||||
// Runs until the ping arrives.
|
|
||||||
tokio_current_thread::block_on_all(ping_finished_future).unwrap();
|
|
||||||
```
|
|
||||||
|
|
@ -18,9 +18,6 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// TODO: use this once stable ; for now we just copy-paste the content of the README.md
|
|
||||||
//#![doc(include = "../README.md")]
|
|
||||||
|
|
||||||
//! Handles the `/ipfs/ping/1.0.0` protocol. This allows pinging a remote node and waiting for an
|
//! Handles the `/ipfs/ping/1.0.0` protocol. This allows pinging a remote node and waiting for an
|
||||||
//! answer.
|
//! answer.
|
||||||
//!
|
//!
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
# Circuit Relay v0.1.0
|
|
||||||
|
|
||||||
Implements the `/libp2p/circuit/relay/0.1.0` protocol [[1][1]]. It allows a source `A` to connect
|
|
||||||
to a destination `B` via an intermediate relay node `R` to which `B` is already connected to. This
|
|
||||||
is used as a last resort to make `B` reachable from other nodes when it would normally not be, e.g.
|
|
||||||
due to certain NAT setups.
|
|
||||||
|
|
||||||
[1]: https://github.com/libp2p/specs/blob/97b86236ce07ff35d9bff5c1ba60daa8879f8f03/relay/
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
This crate provides the `RwStreamSink` type. It wraps around a `Stream + Sink` that produces
|
|
||||||
and accepts byte arrays, and implements `AsyncRead` and `AsyncWrite`.
|
|
||||||
|
|
||||||
Each call to `write()` will send one packet on the sink. Calls to `read()` will read from
|
|
||||||
incoming packets.
|
|
||||||
|
|
||||||
> **Note**: Although this crate is hosted in the libp2p repo, it is purely a utility crate and
|
|
||||||
> not at all specific to libp2p.
|
|
@ -18,9 +18,6 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// TODO: use this once stable ; for now we just copy-paste the content of the README.md
|
|
||||||
//#![doc(include = "../README.md")]
|
|
||||||
|
|
||||||
//! This crate provides the `RwStreamSink` type. It wraps around a `Stream + Sink` that produces
|
//! This crate provides the `RwStreamSink` type. It wraps around a `Stream + Sink` that produces
|
||||||
//! and accepts byte arrays, and implements `AsyncRead` and `AsyncWrite`.
|
//! and accepts byte arrays, and implements `AsyncRead` and `AsyncWrite`.
|
||||||
//!
|
//!
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
The `secio` protocol is a middleware that will encrypt and decrypt communications going
|
|
||||||
through a socket (or anything that implements `AsyncRead + AsyncWrite`).
|
|
||||||
|
|
||||||
# Connection upgrade
|
|
||||||
|
|
||||||
The `SecioConfig` struct implements the `ConnectionUpgrade` trait. You can apply it over a
|
|
||||||
`Transport` by using the `with_upgrade` method. The returned object will also implement
|
|
||||||
`Transport` and will automatically apply the secio protocol over any connection that is opened
|
|
||||||
through it.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate futures;
|
|
||||||
extern crate tokio_current_thread;
|
|
||||||
extern crate tokio_io;
|
|
||||||
extern crate libp2p_core;
|
|
||||||
extern crate libp2p_secio;
|
|
||||||
extern crate libp2p_tcp_transport;
|
|
||||||
|
|
||||||
use futures::Future;
|
|
||||||
use libp2p_secio::{SecioConfig, SecioKeyPair};
|
|
||||||
use libp2p_core::{Multiaddr, Transport};
|
|
||||||
use libp2p_tcp_transport::TcpConfig;
|
|
||||||
use tokio_core::reactor::Core;
|
|
||||||
use tokio_io::io::write_all;
|
|
||||||
|
|
||||||
let mut core = Core::new().unwrap();
|
|
||||||
|
|
||||||
let transport = TcpConfig::new()
|
|
||||||
.with_upgrade({
|
|
||||||
# let private_key = b"";
|
|
||||||
//let private_key = include_bytes!("test-rsa-private-key.pk8");
|
|
||||||
# let public_key = vec![];
|
|
||||||
//let public_key = include_bytes!("test-rsa-public-key.der").to_vec();
|
|
||||||
SecioConfig {
|
|
||||||
// See the documentation of `SecioKeyPair`.
|
|
||||||
key: SecioKeyPair::rsa_from_pkcs8(private_key, public_key).unwrap(),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let future = transport.dial("/ip4/127.0.0.1/tcp/12345".parse::<Multiaddr>().unwrap())
|
|
||||||
.unwrap_or_else(|_| panic!("Unable to dial node"))
|
|
||||||
.and_then(|(connection, _)| {
|
|
||||||
// Sends "hello world" on the connection, will be encrypted.
|
|
||||||
write_all(connection, "hello world")
|
|
||||||
});
|
|
||||||
|
|
||||||
tokio_current_thread::block_on_all(future).unwrap();
|
|
||||||
```
|
|
||||||
|
|
||||||
# Manual usage
|
|
||||||
|
|
||||||
> **Note**: You are encouraged to use `SecioConfig` as described above.
|
|
||||||
|
|
||||||
You can add the `secio` layer over a socket by calling `SecioMiddleware::handshake()`. This
|
|
||||||
method will perform a handshake with the host, and return a future that corresponds to the
|
|
||||||
moment when the handshake succeeds or errored. On success, the future produces a
|
|
||||||
`SecioMiddleware` that implements `Sink` and `Stream` and can be used to send packets of data.
|
|
@ -1,23 +0,0 @@
|
|||||||
# TCP transport
|
|
||||||
|
|
||||||
Implementation of the libp2p `Transport` trait for TCP/IP.
|
|
||||||
|
|
||||||
Uses [the *tokio* library](https://tokio.rs).
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate libp2p_tcp_transport;
|
|
||||||
extern crate tokio_current_thread;
|
|
||||||
|
|
||||||
use libp2p_tcp_transport::TcpConfig;
|
|
||||||
use tokio_core::reactor::Core;
|
|
||||||
|
|
||||||
let mut core = Core::new().unwrap();
|
|
||||||
let tcp = TcpConfig::new();
|
|
||||||
```
|
|
||||||
|
|
||||||
The `TcpConfig` structs implements the `Transport` trait of the `swarm` library. See the
|
|
||||||
documentation of `swarm` and of libp2p in general to learn how to use the `Transport` trait.
|
|
@ -18,9 +18,6 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// TODO: use this once stable ; for now we just copy-paste the content of the README.md
|
|
||||||
//#![doc(include = "../README.md")]
|
|
||||||
|
|
||||||
//! Implementation of the libp2p `Transport` trait for TCP/IP.
|
//! Implementation of the libp2p `Transport` trait for TCP/IP.
|
||||||
//!
|
//!
|
||||||
//! Uses [the *tokio* library](https://tokio.rs).
|
//! Uses [the *tokio* library](https://tokio.rs).
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
Implementation of the libp2p `Transport` trait for Websockets.
|
|
||||||
|
|
||||||
See the documentation of `swarm` and of libp2p in general to learn how to use the `Transport`
|
|
||||||
trait.
|
|
||||||
|
|
||||||
This library is used in a different way depending on whether you are compiling for emscripten
|
|
||||||
or for a different operating system.
|
|
||||||
|
|
||||||
# Emscripten
|
|
||||||
|
|
||||||
On emscripten, you can create a `BrowserWsConfig` object with `BrowserWsConfig::new()`. It can
|
|
||||||
then be used as a transport.
|
|
||||||
|
|
||||||
Listening on a websockets multiaddress isn't supported on emscripten. Dialing a multiaddress
|
|
||||||
which uses `ws` on top of TCP/IP will automatically use the `XMLHttpRequest` Javascript object.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use libp2p_websocket::BrowserWsConfig;
|
|
||||||
|
|
||||||
let ws_config = BrowserWsConfig::new();
|
|
||||||
// let _ = ws_config.dial("/ip4/40.41.42.43/tcp/12345/ws".parse().unwrap());
|
|
||||||
```
|
|
||||||
|
|
||||||
# Other operating systems
|
|
||||||
|
|
||||||
On other operating systems, this library doesn't open any socket by itself. Instead it must be
|
|
||||||
plugged on top of another implementation of `Transport` such as TCP/IP.
|
|
||||||
|
|
||||||
This underlying transport must be put inside a `WsConfig` object through the
|
|
||||||
`WsConfig::new()` function.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate libp2p_core;
|
|
||||||
extern crate libp2p_tcp_transport;
|
|
||||||
extern crate libp2p_websocket;
|
|
||||||
extern crate tokio_current_thread;
|
|
||||||
|
|
||||||
use libp2p_core::{Multiaddr, Transport};
|
|
||||||
use libp2p_tcp_transport::TcpConfig;
|
|
||||||
use libp2p_websocket::WsConfig;
|
|
||||||
use tokio_core::reactor::Core;
|
|
||||||
|
|
||||||
let core = Core::new().unwrap();
|
|
||||||
let ws_config = WsConfig::new(TcpConfig::new());
|
|
||||||
let _ = ws_config.dial("/ip4/40.41.42.43/tcp/12345/ws".parse().unwrap());
|
|
||||||
```
|
|
@ -20,9 +20,6 @@
|
|||||||
|
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
|
|
||||||
// TODO: use this once stable ; for now we just copy-paste the content of the README.md
|
|
||||||
//#![doc(include = "../README.md")]
|
|
||||||
|
|
||||||
//! Implementation of the libp2p `Transport` trait for Websockets.
|
//! Implementation of the libp2p `Transport` trait for Websockets.
|
||||||
//!
|
//!
|
||||||
//! See the documentation of `swarm` and of libp2p in general to learn how to use the `Transport`
|
//! See the documentation of `swarm` and of libp2p in general to learn how to use the `Transport`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user