2017-11-02 11:58:02 +01:00
|
|
|
// Copyright 2017 Parity Technologies (UK) Ltd.
|
2018-03-07 16:20:55 +01:00
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
2017-11-02 11:58:02 +01:00
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
2018-03-07 16:20:55 +01:00
|
|
|
// The above copyright notice and this permission notice shall be included in
|
2017-11-02 11:58:02 +01:00
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
2018-03-07 16:20:55 +01:00
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
2017-11-02 11:58:02 +01:00
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
//! Implementation of the libp2p `Transport` trait for TCP/IP.
|
2017-12-04 16:05:37 +01:00
|
|
|
//!
|
|
|
|
//! # Usage
|
2018-03-07 16:20:55 +01:00
|
|
|
//!
|
2017-12-04 16:05:37 +01:00
|
|
|
//! Example:
|
|
|
|
//!
|
|
|
|
//! ```
|
2018-12-10 13:39:11 +01:00
|
|
|
//! extern crate libp2p_tcp;
|
|
|
|
//! use libp2p_tcp::TcpConfig;
|
2017-12-04 16:05:37 +01:00
|
|
|
//!
|
|
|
|
//! # fn main() {
|
2018-07-16 12:15:27 +02:00
|
|
|
//! let tcp = TcpConfig::new();
|
2017-12-04 16:05:37 +01:00
|
|
|
//! # }
|
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! 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.
|
2017-11-02 11:58:02 +01:00
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
use async_std::net::TcpStream;
|
2019-11-14 13:42:14 +01:00
|
|
|
use futures::{future::{self, Ready}, prelude::*};
|
2019-09-16 11:08:44 +02:00
|
|
|
use futures_timer::Delay;
|
2019-06-03 17:55:15 +02:00
|
|
|
use get_if_addrs::{IfAddr, get_if_addrs};
|
|
|
|
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
|
2019-04-30 21:14:57 +03:00
|
|
|
use libp2p_core::{
|
|
|
|
Transport,
|
|
|
|
multiaddr::{Protocol, Multiaddr},
|
|
|
|
transport::{ListenerEvent, TransportError}
|
|
|
|
};
|
2019-06-24 13:54:22 +02:00
|
|
|
use log::{debug, trace};
|
2019-04-11 22:51:07 +02:00
|
|
|
use std::{
|
2019-06-03 17:55:15 +02:00
|
|
|
collections::VecDeque,
|
2019-09-16 11:08:44 +02:00
|
|
|
io,
|
2019-04-11 22:51:07 +02:00
|
|
|
iter::{self, FromIterator},
|
|
|
|
net::{IpAddr, SocketAddr},
|
2019-09-16 11:08:44 +02:00
|
|
|
pin::Pin,
|
|
|
|
task::{Context, Poll},
|
|
|
|
time::Duration
|
2019-04-11 22:51:07 +02:00
|
|
|
};
|
2017-09-18 16:52:51 +02:00
|
|
|
|
2017-12-04 16:05:37 +01:00
|
|
|
/// Represents the configuration for a TCP/IP transport capability for libp2p.
|
2017-11-02 11:58:02 +01:00
|
|
|
///
|
2018-07-16 12:15:27 +02:00
|
|
|
/// The TCP sockets created by libp2p will need to be progressed by running the futures and streams
|
|
|
|
/// obtained by libp2p through the tokio reactor.
|
2018-07-17 11:55:18 +02:00
|
|
|
#[derive(Debug, Clone, Default)]
|
2018-08-08 17:54:15 +02:00
|
|
|
pub struct TcpConfig {
|
2018-09-11 12:04:35 +02:00
|
|
|
/// How long a listener should sleep after receiving an error, before trying again.
|
2018-08-08 17:54:15 +02:00
|
|
|
sleep_on_error: Duration,
|
2018-09-11 12:04:35 +02:00
|
|
|
/// TTL to set for opened sockets, or `None` to keep default.
|
|
|
|
ttl: Option<u32>,
|
|
|
|
/// `TCP_NODELAY` to set for opened sockets, or `None` to keep default.
|
|
|
|
nodelay: Option<bool>,
|
2018-08-08 17:54:15 +02:00
|
|
|
}
|
2017-09-18 17:25:04 +02:00
|
|
|
|
2017-12-04 16:05:37 +01:00
|
|
|
impl TcpConfig {
|
2018-07-16 12:15:27 +02:00
|
|
|
/// Creates a new configuration object for TCP/IP.
|
|
|
|
pub fn new() -> TcpConfig {
|
2018-08-08 17:54:15 +02:00
|
|
|
TcpConfig {
|
|
|
|
sleep_on_error: Duration::from_millis(100),
|
2018-09-11 12:04:35 +02:00
|
|
|
ttl: None,
|
|
|
|
nodelay: None,
|
2018-08-08 17:54:15 +02:00
|
|
|
}
|
2017-10-23 11:45:35 +02:00
|
|
|
}
|
2018-09-11 12:04:35 +02:00
|
|
|
|
|
|
|
/// Sets the TTL to set for opened sockets.
|
|
|
|
pub fn ttl(mut self, value: u32) -> Self {
|
|
|
|
self.ttl = Some(value);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Sets the `TCP_NODELAY` to set for opened sockets.
|
|
|
|
pub fn nodelay(mut self, value: bool) -> Self {
|
|
|
|
self.nodelay = Some(value);
|
|
|
|
self
|
|
|
|
}
|
2017-09-18 17:25:04 +02:00
|
|
|
}
|
2017-09-18 16:52:51 +02:00
|
|
|
|
2017-12-04 16:05:37 +01:00
|
|
|
impl Transport for TcpConfig {
|
2018-07-21 13:01:59 +02:00
|
|
|
type Output = TcpTransStream;
|
2019-01-10 11:27:06 +01:00
|
|
|
type Error = io::Error;
|
2019-09-16 11:08:44 +02:00
|
|
|
type Listener = Pin<Box<dyn Stream<Item = Result<ListenerEvent<Self::ListenerUpgrade>, io::Error>> + Send>>;
|
|
|
|
type ListenerUpgrade = Ready<Result<Self::Output, Self::Error>>;
|
|
|
|
type Dial = Pin<Box<dyn Future<Output = Result<TcpTransStream, io::Error>> + Send>>;
|
2017-10-23 11:45:35 +02:00
|
|
|
|
2019-04-10 10:29:21 +02:00
|
|
|
fn listen_on(self, addr: Multiaddr) -> Result<Self::Listener, TransportError<Self::Error>> {
|
2019-04-11 22:51:07 +02:00
|
|
|
let socket_addr =
|
|
|
|
if let Ok(sa) = multiaddr_to_socketaddr(&addr) {
|
|
|
|
sa
|
|
|
|
} else {
|
|
|
|
return Err(TransportError::MultiaddrNotSupported(addr))
|
2017-11-24 16:10:34 +01:00
|
|
|
};
|
2017-12-19 18:09:17 +01:00
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
async fn do_listen(cfg: TcpConfig, socket_addr: SocketAddr)
|
|
|
|
-> Result<impl Stream<Item = Result<ListenerEvent<Ready<Result<TcpTransStream, io::Error>>>, io::Error>>, io::Error>
|
|
|
|
{
|
|
|
|
let listener = async_std::net::TcpListener::bind(&socket_addr).await?;
|
|
|
|
let local_addr = listener.local_addr()?;
|
|
|
|
let port = local_addr.port();
|
|
|
|
|
|
|
|
// Determine all our listen addresses which is either a single local IP address
|
|
|
|
// or (if a wildcard IP address was used) the addresses of all our interfaces,
|
|
|
|
// as reported by `get_if_addrs`.
|
|
|
|
let addrs =
|
|
|
|
if socket_addr.ip().is_unspecified() {
|
|
|
|
let addrs = host_addresses(port)?;
|
|
|
|
debug!("Listening on {:?}", addrs.iter().map(|(_, _, ma)| ma).collect::<Vec<_>>());
|
|
|
|
Addresses::Many(addrs)
|
|
|
|
} else {
|
|
|
|
let ma = ip_to_multiaddr(local_addr.ip(), port);
|
|
|
|
debug!("Listening on {:?}", ma);
|
|
|
|
Addresses::One(ma)
|
|
|
|
};
|
|
|
|
|
|
|
|
// Generate `NewAddress` events for each new `Multiaddr`.
|
|
|
|
let pending = match addrs {
|
|
|
|
Addresses::One(ref ma) => {
|
|
|
|
let event = ListenerEvent::NewAddress(ma.clone());
|
|
|
|
let mut list = VecDeque::new();
|
|
|
|
list.push_back(Ok(event));
|
|
|
|
list
|
|
|
|
}
|
|
|
|
Addresses::Many(ref aa) => {
|
|
|
|
aa.iter()
|
|
|
|
.map(|(_, _, ma)| ma)
|
|
|
|
.cloned()
|
|
|
|
.map(ListenerEvent::NewAddress)
|
|
|
|
.map(Result::Ok)
|
|
|
|
.collect::<VecDeque<_>>()
|
|
|
|
}
|
2019-04-11 22:51:07 +02:00
|
|
|
};
|
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
let listen_stream = TcpListenStream {
|
|
|
|
stream: listener,
|
|
|
|
pause: None,
|
|
|
|
pause_duration: cfg.sleep_on_error,
|
|
|
|
port,
|
|
|
|
addrs,
|
|
|
|
pending,
|
|
|
|
config: cfg
|
|
|
|
};
|
2019-04-11 22:51:07 +02:00
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
Ok(stream::unfold(listen_stream, |s| s.next().map(Some)))
|
|
|
|
}
|
2019-04-11 22:51:07 +02:00
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
Ok(Box::pin(do_listen(self, socket_addr).try_flatten_stream()))
|
2017-10-23 11:45:35 +02:00
|
|
|
}
|
|
|
|
|
2019-01-10 11:27:06 +01:00
|
|
|
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
|
2019-04-11 22:51:07 +02:00
|
|
|
let socket_addr =
|
|
|
|
if let Ok(socket_addr) = multiaddr_to_socketaddr(&addr) {
|
|
|
|
if socket_addr.port() == 0 || socket_addr.ip().is_unspecified() {
|
|
|
|
debug!("Instantly refusing dialing {}, as it is invalid", addr);
|
|
|
|
return Err(TransportError::Other(io::ErrorKind::ConnectionRefused.into()))
|
|
|
|
}
|
|
|
|
socket_addr
|
2018-07-02 10:51:10 +02:00
|
|
|
} else {
|
2019-04-11 22:51:07 +02:00
|
|
|
return Err(TransportError::MultiaddrNotSupported(addr))
|
|
|
|
};
|
|
|
|
|
|
|
|
debug!("Dialing {}", addr);
|
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
async fn do_dial(cfg: TcpConfig, socket_addr: SocketAddr) -> Result<TcpTransStream, io::Error> {
|
|
|
|
let stream = TcpStream::connect(&socket_addr).await?;
|
|
|
|
apply_config(&cfg, &stream)?;
|
|
|
|
Ok(TcpTransStream { inner: stream })
|
|
|
|
}
|
2019-04-11 22:51:07 +02:00
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
Ok(Box::pin(do_dial(self, socket_addr)))
|
2017-10-23 11:45:35 +02:00
|
|
|
}
|
2017-09-18 16:52:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// This type of logic should probably be moved into the multiaddr package
|
2017-11-24 16:10:34 +01:00
|
|
|
fn multiaddr_to_socketaddr(addr: &Multiaddr) -> Result<SocketAddr, ()> {
|
2018-08-09 14:04:15 +02:00
|
|
|
let mut iter = addr.iter();
|
|
|
|
let proto1 = iter.next().ok_or(())?;
|
|
|
|
let proto2 = iter.next().ok_or(())?;
|
2017-10-23 11:45:35 +02:00
|
|
|
|
2018-08-09 14:04:15 +02:00
|
|
|
if iter.next().is_some() {
|
2017-12-15 17:29:54 +01:00
|
|
|
return Err(());
|
|
|
|
}
|
|
|
|
|
2018-08-09 14:04:15 +02:00
|
|
|
match (proto1, proto2) {
|
2018-09-20 19:51:00 +02:00
|
|
|
(Protocol::Ip4(ip), Protocol::Tcp(port)) => Ok(SocketAddr::new(ip.into(), port)),
|
|
|
|
(Protocol::Ip6(ip), Protocol::Tcp(port)) => Ok(SocketAddr::new(ip.into(), port)),
|
2018-08-09 14:04:15 +02:00
|
|
|
_ => Err(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-11 22:51:07 +02:00
|
|
|
// Create a [`Multiaddr`] from the given IP address and port number.
|
2019-06-03 17:55:15 +02:00
|
|
|
fn ip_to_multiaddr(ip: IpAddr, port: u16) -> Multiaddr {
|
2019-04-11 22:51:07 +02:00
|
|
|
let proto = match ip {
|
|
|
|
IpAddr::V4(ip) => Protocol::Ip4(ip),
|
|
|
|
IpAddr::V6(ip) => Protocol::Ip6(ip)
|
|
|
|
};
|
|
|
|
let it = iter::once(proto).chain(iter::once(Protocol::Tcp(port)));
|
|
|
|
Multiaddr::from_iter(it)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Collect all local host addresses and use the provided port number as listen port.
|
2019-06-03 17:55:15 +02:00
|
|
|
fn host_addresses(port: u16) -> io::Result<Vec<(IpAddr, IpNet, Multiaddr)>> {
|
|
|
|
let mut addrs = Vec::new();
|
2019-04-11 22:51:07 +02:00
|
|
|
for iface in get_if_addrs()? {
|
2019-06-03 17:55:15 +02:00
|
|
|
let ip = iface.ip();
|
|
|
|
let ma = ip_to_multiaddr(ip, port);
|
|
|
|
let ipn = match iface.addr {
|
|
|
|
IfAddr::V4(ip4) => {
|
|
|
|
let prefix_len = (!u32::from_be_bytes(ip4.netmask.octets())).leading_zeros();
|
|
|
|
let ipnet = Ipv4Net::new(ip4.ip, prefix_len as u8)
|
|
|
|
.expect("prefix_len is the number of bits in a u32, so can not exceed 32");
|
|
|
|
IpNet::V4(ipnet)
|
|
|
|
}
|
|
|
|
IfAddr::V6(ip6) => {
|
|
|
|
let prefix_len = (!u128::from_be_bytes(ip6.netmask.octets())).leading_zeros();
|
|
|
|
let ipnet = Ipv6Net::new(ip6.ip, prefix_len as u8)
|
|
|
|
.expect("prefix_len is the number of bits in a u128, so can not exceed 128");
|
|
|
|
IpNet::V6(ipnet)
|
|
|
|
}
|
|
|
|
};
|
|
|
|
addrs.push((ip, ipn, ma))
|
2019-04-11 22:51:07 +02:00
|
|
|
}
|
|
|
|
Ok(addrs)
|
|
|
|
}
|
|
|
|
|
2018-09-11 12:04:35 +02:00
|
|
|
/// Applies the socket configuration parameters to a socket.
|
2019-01-10 11:27:06 +01:00
|
|
|
fn apply_config(config: &TcpConfig, socket: &TcpStream) -> Result<(), io::Error> {
|
2018-09-11 12:04:35 +02:00
|
|
|
if let Some(ttl) = config.ttl {
|
|
|
|
socket.set_ttl(ttl)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(nodelay) = config.nodelay {
|
|
|
|
socket.set_nodelay(nodelay)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2019-04-11 22:51:07 +02:00
|
|
|
/// Listen address information.
|
|
|
|
#[derive(Debug)]
|
|
|
|
enum Addresses {
|
|
|
|
/// A specific address is used to listen.
|
|
|
|
One(Multiaddr),
|
|
|
|
/// A set of addresses is used to listen.
|
2019-06-03 17:55:15 +02:00
|
|
|
Many(Vec<(IpAddr, IpNet, Multiaddr)>)
|
2019-04-11 22:51:07 +02:00
|
|
|
}
|
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
type Buffer = VecDeque<Result<ListenerEvent<Ready<Result<TcpTransStream, io::Error>>>, io::Error>>;
|
2019-06-03 17:55:15 +02:00
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
/// Stream that listens on an TCP/IP address.
|
|
|
|
pub struct TcpListenStream {
|
2019-08-13 15:41:12 +02:00
|
|
|
/// The incoming connections.
|
2019-09-16 11:08:44 +02:00
|
|
|
stream: async_std::net::TcpListener,
|
2019-08-13 15:41:12 +02:00
|
|
|
/// The current pause if any.
|
|
|
|
pause: Option<Delay>,
|
|
|
|
/// How long to pause after an error.
|
2019-09-16 11:08:44 +02:00
|
|
|
pause_duration: Duration,
|
2019-04-11 22:51:07 +02:00
|
|
|
/// The port which we use as our listen port in listener event addresses.
|
|
|
|
port: u16,
|
|
|
|
/// The set of known addresses.
|
|
|
|
addrs: Addresses,
|
|
|
|
/// Temporary buffer of listener events.
|
2019-06-03 17:55:15 +02:00
|
|
|
pending: Buffer,
|
2018-09-11 12:04:35 +02:00
|
|
|
/// Original configuration.
|
2019-04-11 22:51:07 +02:00
|
|
|
config: TcpConfig
|
2018-08-09 14:04:15 +02:00
|
|
|
}
|
|
|
|
|
2019-08-15 13:18:19 +02:00
|
|
|
// If we listen on all interfaces, find out to which interface the given
|
|
|
|
// socket address belongs. In case we think the address is new, check
|
|
|
|
// all host interfaces again and report new and expired listen addresses.
|
|
|
|
fn check_for_interface_changes(
|
|
|
|
socket_addr: &SocketAddr,
|
|
|
|
listen_port: u16,
|
|
|
|
listen_addrs: &mut Vec<(IpAddr, IpNet, Multiaddr)>,
|
|
|
|
pending: &mut Buffer
|
|
|
|
) -> Result<(), io::Error> {
|
|
|
|
// Check for exact match:
|
|
|
|
if listen_addrs.iter().find(|(ip, ..)| ip == &socket_addr.ip()).is_some() {
|
|
|
|
return Ok(())
|
|
|
|
}
|
2019-06-03 17:55:15 +02:00
|
|
|
|
2019-08-15 13:18:19 +02:00
|
|
|
// No exact match => check netmask
|
|
|
|
if listen_addrs.iter().find(|(_, net, _)| net.contains(&socket_addr.ip())).is_some() {
|
|
|
|
return Ok(())
|
|
|
|
}
|
2019-06-03 17:55:15 +02:00
|
|
|
|
2019-08-15 13:18:19 +02:00
|
|
|
// The local IP address of this socket is new to us.
|
|
|
|
// We check for changes in the set of host addresses and report new
|
|
|
|
// and expired addresses.
|
|
|
|
//
|
|
|
|
// TODO: We do not detect expired addresses unless there is a new address.
|
|
|
|
let old_listen_addrs = std::mem::replace(listen_addrs, host_addresses(listen_port)?);
|
|
|
|
|
|
|
|
// Check for addresses no longer in use.
|
|
|
|
for (ip, _, ma) in old_listen_addrs.iter() {
|
|
|
|
if listen_addrs.iter().find(|(i, ..)| i == ip).is_none() {
|
|
|
|
debug!("Expired listen address: {}", ma);
|
2019-09-16 11:08:44 +02:00
|
|
|
pending.push_back(Ok(ListenerEvent::AddressExpired(ma.clone())));
|
2019-08-15 13:18:19 +02:00
|
|
|
}
|
|
|
|
}
|
2019-06-03 17:55:15 +02:00
|
|
|
|
2019-08-15 13:18:19 +02:00
|
|
|
// Check for new addresses.
|
|
|
|
for (ip, _, ma) in listen_addrs.iter() {
|
|
|
|
if old_listen_addrs.iter().find(|(i, ..)| i == ip).is_none() {
|
|
|
|
debug!("New listen address: {}", ma);
|
2019-09-16 11:08:44 +02:00
|
|
|
pending.push_back(Ok(ListenerEvent::NewAddress(ma.clone())));
|
2019-06-03 17:55:15 +02:00
|
|
|
}
|
|
|
|
}
|
2019-08-15 13:18:19 +02:00
|
|
|
|
|
|
|
// We should now be able to find the local address, if not something
|
|
|
|
// is seriously wrong and we report an error.
|
|
|
|
if listen_addrs.iter()
|
|
|
|
.find(|(ip, net, _)| ip == &socket_addr.ip() || net.contains(&socket_addr.ip()))
|
|
|
|
.is_none()
|
|
|
|
{
|
|
|
|
let msg = format!("{} does not match any listen address", socket_addr.ip());
|
|
|
|
return Err(io::Error::new(io::ErrorKind::Other, msg))
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
2019-06-03 17:55:15 +02:00
|
|
|
}
|
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
impl TcpListenStream {
|
|
|
|
/// Takes ownership of the listener, and returns the next incoming event and the listener.
|
|
|
|
async fn next(mut self) -> (Result<ListenerEvent<Ready<Result<TcpTransStream, io::Error>>>, io::Error>, Self) {
|
2018-10-17 10:17:40 +01:00
|
|
|
loop {
|
2019-04-11 22:51:07 +02:00
|
|
|
if let Some(event) = self.pending.pop_front() {
|
2019-09-16 11:08:44 +02:00
|
|
|
return (event, self);
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(pause) = self.pause.take() {
|
|
|
|
let _ = pause.await;
|
2019-04-11 22:51:07 +02:00
|
|
|
}
|
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
// TODO: do we get the peer_addr at the same time?
|
|
|
|
let (sock, _) = match self.stream.accept().await {
|
|
|
|
Ok(s) => s,
|
|
|
|
Err(e) => {
|
|
|
|
debug!("error accepting incoming connection: {}", e);
|
|
|
|
self.pause = Some(Delay::new(self.pause_duration));
|
|
|
|
return (Err(e), self);
|
|
|
|
}
|
2019-04-11 22:51:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
let sock_addr = match sock.peer_addr() {
|
|
|
|
Ok(addr) => addr,
|
|
|
|
Err(err) => {
|
2019-06-24 13:54:22 +02:00
|
|
|
debug!("Failed to get peer address: {:?}", err);
|
|
|
|
continue
|
2019-04-11 22:51:07 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-08-15 13:18:19 +02:00
|
|
|
let local_addr = match sock.local_addr() {
|
|
|
|
Ok(sock_addr) => {
|
|
|
|
if let Addresses::Many(ref mut addrs) = self.addrs {
|
2019-09-16 11:08:44 +02:00
|
|
|
if let Err(err) = check_for_interface_changes(&sock_addr, self.port, addrs, &mut self.pending) {
|
|
|
|
return (Err(err), self);
|
|
|
|
}
|
2019-08-15 13:18:19 +02:00
|
|
|
}
|
|
|
|
ip_to_multiaddr(sock_addr.ip(), sock_addr.port())
|
|
|
|
}
|
2019-04-11 22:51:07 +02:00
|
|
|
Err(err) => {
|
2019-06-24 13:54:22 +02:00
|
|
|
debug!("Failed to get local address of incoming socket: {:?}", err);
|
|
|
|
continue
|
2019-04-11 22:51:07 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-06-03 17:55:15 +02:00
|
|
|
let remote_addr = ip_to_multiaddr(sock_addr.ip(), sock_addr.port());
|
2019-04-11 22:51:07 +02:00
|
|
|
|
|
|
|
match apply_config(&self.config, &sock) {
|
|
|
|
Ok(()) => {
|
2019-08-15 13:18:19 +02:00
|
|
|
trace!("Incoming connection from {} at {}", remote_addr, local_addr);
|
2019-09-16 11:08:44 +02:00
|
|
|
self.pending.push_back(Ok(ListenerEvent::Upgrade {
|
2019-04-10 10:29:21 +02:00
|
|
|
upgrade: future::ok(TcpTransStream { inner: sock }),
|
2019-08-15 13:18:19 +02:00
|
|
|
local_addr,
|
2019-04-11 22:51:07 +02:00
|
|
|
remote_addr
|
2019-09-16 11:08:44 +02:00
|
|
|
}))
|
2019-04-11 22:51:07 +02:00
|
|
|
}
|
|
|
|
Err(err) => {
|
2019-05-15 14:48:26 +02:00
|
|
|
debug!("Error upgrading incoming connection from {}: {:?}", remote_addr, err);
|
2019-09-16 11:08:44 +02:00
|
|
|
self.pending.push_back(Ok(ListenerEvent::Upgrade {
|
2019-04-11 22:51:07 +02:00
|
|
|
upgrade: future::err(err),
|
2019-08-15 13:18:19 +02:00
|
|
|
local_addr,
|
2019-04-11 22:51:07 +02:00
|
|
|
remote_addr
|
2019-09-16 11:08:44 +02:00
|
|
|
}))
|
2018-10-17 10:17:40 +01:00
|
|
|
}
|
2018-08-09 14:04:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-21 13:01:59 +02:00
|
|
|
/// Wraps around a `TcpStream` and adds logging for important events.
|
2018-08-09 14:04:15 +02:00
|
|
|
#[derive(Debug)]
|
2018-07-21 13:01:59 +02:00
|
|
|
pub struct TcpTransStream {
|
2018-08-09 14:04:15 +02:00
|
|
|
inner: TcpStream,
|
2018-07-21 13:01:59 +02:00
|
|
|
}
|
|
|
|
|
2019-05-10 11:26:18 +02:00
|
|
|
impl AsyncRead for TcpTransStream {
|
2019-09-16 11:08:44 +02:00
|
|
|
fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll<Result<usize, io::Error>> {
|
|
|
|
AsyncRead::poll_read(Pin::new(&mut self.inner), cx, buf)
|
2019-05-10 11:26:18 +02:00
|
|
|
}
|
|
|
|
}
|
2018-07-21 13:01:59 +02:00
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
impl AsyncWrite for TcpTransStream {
|
|
|
|
fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize, io::Error>> {
|
|
|
|
AsyncWrite::poll_write(Pin::new(&mut self.inner), cx, buf)
|
2018-07-21 13:01:59 +02:00
|
|
|
}
|
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
|
|
|
|
AsyncWrite::poll_flush(Pin::new(&mut self.inner), cx)
|
2018-07-21 13:01:59 +02:00
|
|
|
}
|
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
|
|
|
|
AsyncWrite::poll_close(Pin::new(&mut self.inner), cx)
|
2018-07-21 13:01:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for TcpTransStream {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
if let Ok(addr) = self.inner.peer_addr() {
|
|
|
|
debug!("Dropped TCP connection to {:?}", addr);
|
|
|
|
} else {
|
|
|
|
debug!("Dropped TCP connection to undeterminate peer");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-30 15:55:57 +02:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2019-09-26 09:33:37 +02:00
|
|
|
use futures::prelude::*;
|
2019-06-03 17:55:15 +02:00
|
|
|
use libp2p_core::{Transport, multiaddr::{Multiaddr, Protocol}, transport::ListenerEvent};
|
2019-11-14 13:42:14 +01:00
|
|
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
2019-09-26 09:33:37 +02:00
|
|
|
use super::{multiaddr_to_socketaddr, TcpConfig};
|
2019-08-13 15:41:12 +02:00
|
|
|
|
2019-04-11 22:51:07 +02:00
|
|
|
#[test]
|
|
|
|
fn wildcard_expansion() {
|
|
|
|
let mut listener = TcpConfig::new()
|
|
|
|
.listen_on("/ip4/0.0.0.0/tcp/0".parse().unwrap())
|
|
|
|
.expect("listener");
|
|
|
|
|
|
|
|
// Get the first address.
|
2019-09-16 11:08:44 +02:00
|
|
|
let addr = futures::executor::block_on_stream(listener.by_ref())
|
2019-04-11 22:51:07 +02:00
|
|
|
.next()
|
|
|
|
.expect("some event")
|
|
|
|
.expect("no error")
|
|
|
|
.into_new_address()
|
|
|
|
.expect("listen address");
|
|
|
|
|
|
|
|
// Process all initial `NewAddress` events and make sure they
|
|
|
|
// do not contain wildcard address or port.
|
|
|
|
let server = listener
|
2019-09-16 11:08:44 +02:00
|
|
|
.take_while(|event| match event.as_ref().unwrap() {
|
2019-04-11 22:51:07 +02:00
|
|
|
ListenerEvent::NewAddress(a) => {
|
|
|
|
let mut iter = a.iter();
|
|
|
|
match iter.next().expect("ip address") {
|
|
|
|
Protocol::Ip4(ip) => assert!(!ip.is_unspecified()),
|
|
|
|
Protocol::Ip6(ip) => assert!(!ip.is_unspecified()),
|
|
|
|
other => panic!("Unexpected protocol: {}", other)
|
|
|
|
}
|
|
|
|
if let Protocol::Tcp(port) = iter.next().expect("port") {
|
|
|
|
assert_ne!(0, port)
|
|
|
|
} else {
|
|
|
|
panic!("No TCP port in address: {}", a)
|
|
|
|
}
|
2019-09-16 11:08:44 +02:00
|
|
|
futures::future::ready(true)
|
2019-04-11 22:51:07 +02:00
|
|
|
}
|
2019-09-16 11:08:44 +02:00
|
|
|
_ => futures::future::ready(false)
|
2019-04-11 22:51:07 +02:00
|
|
|
})
|
2019-09-16 11:08:44 +02:00
|
|
|
.for_each(|_| futures::future::ready(()));
|
2019-04-11 22:51:07 +02:00
|
|
|
|
|
|
|
let client = TcpConfig::new().dial(addr).expect("dialer");
|
2019-12-18 16:31:31 +01:00
|
|
|
async_std::task::block_on(futures::future::join(server, client)).1.unwrap();
|
2019-04-11 22:51:07 +02:00
|
|
|
}
|
|
|
|
|
2017-10-23 11:45:35 +02:00
|
|
|
#[test]
|
|
|
|
fn multiaddr_to_tcp_conversion() {
|
|
|
|
use std::net::Ipv6Addr;
|
|
|
|
|
2018-03-07 16:20:55 +01:00
|
|
|
assert!(
|
|
|
|
multiaddr_to_socketaddr(&"/ip4/127.0.0.1/udp/1234".parse::<Multiaddr>().unwrap())
|
|
|
|
.is_err()
|
|
|
|
);
|
2017-11-16 23:59:38 +08:00
|
|
|
|
2017-10-23 11:45:35 +02:00
|
|
|
assert_eq!(
|
2017-12-28 18:07:49 +01:00
|
|
|
multiaddr_to_socketaddr(&"/ip4/127.0.0.1/tcp/12345".parse::<Multiaddr>().unwrap()),
|
2017-10-23 11:45:35 +02:00
|
|
|
Ok(SocketAddr::new(
|
|
|
|
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
|
|
|
12345,
|
|
|
|
))
|
|
|
|
);
|
|
|
|
assert_eq!(
|
2018-08-09 14:04:15 +02:00
|
|
|
multiaddr_to_socketaddr(
|
|
|
|
&"/ip4/255.255.255.255/tcp/8080"
|
|
|
|
.parse::<Multiaddr>()
|
|
|
|
.unwrap()
|
|
|
|
),
|
2017-10-23 11:45:35 +02:00
|
|
|
Ok(SocketAddr::new(
|
|
|
|
IpAddr::V4(Ipv4Addr::new(255, 255, 255, 255)),
|
|
|
|
8080,
|
|
|
|
))
|
|
|
|
);
|
|
|
|
assert_eq!(
|
2017-12-28 18:07:49 +01:00
|
|
|
multiaddr_to_socketaddr(&"/ip6/::1/tcp/12345".parse::<Multiaddr>().unwrap()),
|
2017-10-23 11:45:35 +02:00
|
|
|
Ok(SocketAddr::new(
|
|
|
|
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
|
|
|
|
12345,
|
|
|
|
))
|
|
|
|
);
|
|
|
|
assert_eq!(
|
2018-08-09 14:04:15 +02:00
|
|
|
multiaddr_to_socketaddr(
|
|
|
|
&"/ip6/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/tcp/8080"
|
|
|
|
.parse::<Multiaddr>()
|
|
|
|
.unwrap()
|
|
|
|
),
|
2017-10-23 11:45:35 +02:00
|
|
|
Ok(SocketAddr::new(
|
|
|
|
IpAddr::V6(Ipv6Addr::new(
|
2018-07-11 11:14:40 +02:00
|
|
|
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
|
2017-10-23 11:45:35 +02:00
|
|
|
)),
|
|
|
|
8080,
|
|
|
|
))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn communicating_between_dialer_and_listener() {
|
2019-09-26 09:33:37 +02:00
|
|
|
let (ready_tx, ready_rx) = futures::channel::oneshot::channel();
|
|
|
|
let mut ready_tx = Some(ready_tx);
|
2017-10-23 11:45:35 +02:00
|
|
|
|
2019-09-26 09:33:37 +02:00
|
|
|
async_std::task::spawn(async move {
|
|
|
|
let addr = "/ip4/127.0.0.1/tcp/0".parse::<Multiaddr>().unwrap();
|
2018-07-16 12:15:27 +02:00
|
|
|
let tcp = TcpConfig::new();
|
2019-09-26 09:33:37 +02:00
|
|
|
let mut listener = tcp.listen_on(addr).unwrap();
|
|
|
|
|
|
|
|
loop {
|
|
|
|
match listener.next().await.unwrap().unwrap() {
|
|
|
|
ListenerEvent::NewAddress(listen_addr) => {
|
|
|
|
ready_tx.take().unwrap().send(listen_addr).unwrap();
|
|
|
|
},
|
|
|
|
ListenerEvent::Upgrade { upgrade, .. } => {
|
|
|
|
let mut upgrade = upgrade.await.unwrap();
|
|
|
|
let mut buf = [0u8; 3];
|
|
|
|
upgrade.read_exact(&mut buf).await.unwrap();
|
|
|
|
assert_eq!(buf, [1, 2, 3]);
|
|
|
|
upgrade.write_all(&[4, 5, 6]).await.unwrap();
|
|
|
|
},
|
|
|
|
_ => unreachable!()
|
|
|
|
}
|
|
|
|
}
|
2017-10-23 11:45:35 +02:00
|
|
|
});
|
2019-09-26 09:33:37 +02:00
|
|
|
|
|
|
|
async_std::task::block_on(async move {
|
|
|
|
let addr = ready_rx.await.unwrap();
|
|
|
|
let tcp = TcpConfig::new();
|
|
|
|
|
|
|
|
// Obtain a future socket through dialing
|
|
|
|
let mut socket = tcp.dial(addr.clone()).unwrap().await.unwrap();
|
|
|
|
socket.write_all(&[0x1, 0x2, 0x3]).await.unwrap();
|
|
|
|
|
|
|
|
let mut buf = [0u8; 3];
|
|
|
|
socket.read_exact(&mut buf).await.unwrap();
|
|
|
|
assert_eq!(buf, [4, 5, 6]);
|
2017-10-23 11:45:35 +02:00
|
|
|
});
|
|
|
|
}
|
2017-11-24 16:10:34 +01:00
|
|
|
|
|
|
|
#[test]
|
2018-01-02 16:00:08 +01:00
|
|
|
fn replace_port_0_in_returned_multiaddr_ipv4() {
|
2018-07-16 12:15:27 +02:00
|
|
|
let tcp = TcpConfig::new();
|
2017-11-24 16:10:34 +01:00
|
|
|
|
2017-12-28 18:07:49 +01:00
|
|
|
let addr = "/ip4/127.0.0.1/tcp/0".parse::<Multiaddr>().unwrap();
|
2017-11-24 16:10:34 +01:00
|
|
|
assert!(addr.to_string().contains("tcp/0"));
|
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
let new_addr = futures::executor::block_on_stream(tcp.listen_on(addr).unwrap())
|
2019-04-10 10:29:21 +02:00
|
|
|
.next()
|
|
|
|
.expect("some event")
|
|
|
|
.expect("no error")
|
|
|
|
.into_new_address()
|
|
|
|
.expect("listen address");
|
|
|
|
|
2017-11-24 16:10:34 +01:00
|
|
|
assert!(!new_addr.to_string().contains("tcp/0"));
|
|
|
|
}
|
2017-12-15 17:29:54 +01:00
|
|
|
|
2018-01-02 16:00:08 +01:00
|
|
|
#[test]
|
|
|
|
fn replace_port_0_in_returned_multiaddr_ipv6() {
|
2018-07-16 12:15:27 +02:00
|
|
|
let tcp = TcpConfig::new();
|
2018-01-02 16:00:08 +01:00
|
|
|
|
2017-12-28 18:07:49 +01:00
|
|
|
let addr: Multiaddr = "/ip6/::1/tcp/0".parse().unwrap();
|
2018-01-02 16:00:08 +01:00
|
|
|
assert!(addr.to_string().contains("tcp/0"));
|
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
let new_addr = futures::executor::block_on_stream(tcp.listen_on(addr).unwrap())
|
2019-04-10 10:29:21 +02:00
|
|
|
.next()
|
|
|
|
.expect("some event")
|
|
|
|
.expect("no error")
|
|
|
|
.into_new_address()
|
|
|
|
.expect("listen address");
|
|
|
|
|
2018-01-02 16:00:08 +01:00
|
|
|
assert!(!new_addr.to_string().contains("tcp/0"));
|
|
|
|
}
|
|
|
|
|
2017-12-15 17:29:54 +01:00
|
|
|
#[test]
|
|
|
|
fn larger_addr_denied() {
|
2018-07-16 12:15:27 +02:00
|
|
|
let tcp = TcpConfig::new();
|
2017-12-15 17:29:54 +01:00
|
|
|
|
2018-03-07 16:20:55 +01:00
|
|
|
let addr = "/ip4/127.0.0.1/tcp/12345/tcp/12345"
|
|
|
|
.parse::<Multiaddr>()
|
|
|
|
.unwrap();
|
2017-12-15 17:29:54 +01:00
|
|
|
assert!(tcp.listen_on(addr).is_err());
|
|
|
|
}
|
2017-09-18 16:52:51 +02:00
|
|
|
}
|