From 603fcf6557a8b725651cc3efc82472855e1fe090 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Sat, 8 Apr 2017 03:31:22 +0200 Subject: [PATCH] initial commit: transport interfaces --- .gitignore | 2 + Cargo.toml | 7 +++ libp2p-transport/Cargo.toml | 10 +++ libp2p-transport/src/lib.rs | 118 ++++++++++++++++++++++++++++++++++++ src/lib.rs | 0 5 files changed, 137 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 libp2p-transport/Cargo.toml create mode 100644 libp2p-transport/src/lib.rs create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a9d37c56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..b74045c0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "libp2p" +version = "0.1.0" +authors = ["Parity Technologies "] + +[workspace] +members = ["libp2p-transport"] \ No newline at end of file diff --git a/libp2p-transport/Cargo.toml b/libp2p-transport/Cargo.toml new file mode 100644 index 00000000..d922893f --- /dev/null +++ b/libp2p-transport/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "libp2p-transport" +version = "0.1.0" +authors = ["Parity Technologies "] +workspace = ".." + +[dependencies] +multiaddr = "0.2.0" +futures = "0.1" +tokio-io = "0.1" \ No newline at end of file diff --git a/libp2p-transport/src/lib.rs b/libp2p-transport/src/lib.rs new file mode 100644 index 00000000..1a3e78e0 --- /dev/null +++ b/libp2p-transport/src/lib.rs @@ -0,0 +1,118 @@ +//! Rust libp2p implementation + +extern crate futures; +extern crate tokio_io; + +/// Multi-address re-export. +pub extern crate multiaddr; + +use futures::*; +use std::io::Error as IoError; +use tokio_io::{AsyncRead, AsyncWrite}; + +// libp2p interfaces built around futures-rs +// tokio was considered, but is primarily focused on request-response systems for the time being, +// while libp2p is more. We may provide a tokio-based wrapper for simple protocols in the future. + +// Something more strongly-typed? +pub type ProtocolId = String; +pub type PeerId = String; + +/// A logical wire between us and a peer. We can read and write through this asynchronously. +/// +/// You can have multiple `Socket`s between you and any given peer. +// +// What do we call it? Go-libp2p calls them "Streams", but "Streams" in futures-rs specifically +// denote the "writing" half. "Connections" have a different meaning in the libp2p definition. +// `Duplex`? +pub trait Socket: AsyncRead + AsyncWrite { + /// Get the protocol ID this socket uses. + fn protocol_id(&self) -> ProtocolId; + + /// Access the underlying connection. + fn conn(&self) -> &Conn; +} + +/// A connection between you and a peer. +pub trait Conn { + /// The socket type this connection manages. + type Socket; + + /// Initiate a socket between you and the peer on the given protocol. + fn make_socket(&self, proto: ProtocolId) -> BoxFuture; +} + +/// Produces a future for each incoming `Socket`. +pub trait Handler { + type Future: IntoFuture; + + /// Handle the incoming socket, producing a future which should resolve + /// when the handler is finished. + fn handle(&self, socket: S) -> Self::Future; + fn boxed(self) -> BoxHandler where + Self: Sized + Send + 'static, + ::Future: Send + 'static + { + BoxHandler(Box::new(move |socket| + self.handle(socket).into_future().boxed() + )) + } +} + +impl Handler for F + where F: Fn(S) -> U, U: IntoFuture +{ + type Future = U; + + fn handle(&self, socket: S) -> U { (self)(socket) } +} + +/// A boxed handler. +pub struct BoxHandler(Box>>); + +impl Handler for BoxHandler { + type Future = BoxFuture<(), ()>; + + fn handle(&self, socket: S) -> Self::Future { + self.0.handle(socket) + } +} + +/// Multiplexes sockets onto handlers by protocol-id. +pub trait Mux: Sync { + /// The socket type this manages. + type Socket: Socket; + + /// Attach an incoming socket. + fn push(&self, socket: Self::Socket); + + /// Set the socket handler for a given protocol id. + fn set_handler(&self, proto: ProtocolId, handler: BoxHandler); + + /// Remove the socket handler for the given protocol id, returning the old handler if it existed. + fn remove_handler(&self, proto: &ProtocolId) -> Option>; +} + +pub struct MultiAddr; // stub for multiaddr crate type. + +/// A transport is a stream producing incoming connections. +/// These are transports or wrappers around them. +pub trait Transport { + /// The raw connection. + type RawConn: AsyncRead + AsyncWrite; + + /// The listener produces incoming connections. + type Listener: Stream; + + /// A future which indicates currently dialing to a peer. + type Dial: IntoFuture; + + /// Listen on the given multi-addr. + /// Returns the address back if it isn't supported. + fn listen_on(&mut self, addr: MultiAddr) -> Result; + + /// Dial to the given multi-addr. + /// Returns either a future which may resolve to a connection, + /// or + fn dial(&mut self, addr: MultiAddr) -> Result; +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 00000000..e69de29b