mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-05-29 18:51:22 +00:00
Change some nat_traversal
s to consider a prefix. (#550)
Change some `nat_traversal`s to consider a prefix. Transports should consider only the relevant address prefix.
This commit is contained in:
parent
e179951c74
commit
2c98d06942
@ -116,8 +116,12 @@ pub trait Transport {
|
|||||||
/// a remote node observes for one of our dialers.
|
/// a remote node observes for one of our dialers.
|
||||||
///
|
///
|
||||||
/// For example, if `server` is `/ip4/0.0.0.0/tcp/3000` and `observed` is
|
/// For example, if `server` is `/ip4/0.0.0.0/tcp/3000` and `observed` is
|
||||||
/// `/ip4/80.81.82.83/tcp/29601`, then we should return `/ip4/80.81.82.83/tcp/3000`. Each
|
/// `/ip4/80.81.82.83/tcp/29601`, then we should return `/ip4/80.81.82.83/tcp/3000`.
|
||||||
/// implementation of `Transport` is only responsible for handling the protocols it supports.
|
///
|
||||||
|
/// Each implementation of `Transport` is only responsible for handling the protocols it
|
||||||
|
/// supports and should only consider the prefix of `observed` necessary to perform the
|
||||||
|
/// address translation (e.g. `/ip4/80.81.82.83`) but should otherwise preserve `server`
|
||||||
|
/// as is.
|
||||||
///
|
///
|
||||||
/// 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 related.
|
||||||
|
@ -120,6 +120,11 @@ impl fmt::Display for Multiaddr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Multiaddr {
|
impl Multiaddr {
|
||||||
|
/// Create a new, empty multiaddress.
|
||||||
|
pub fn empty() -> Multiaddr {
|
||||||
|
Multiaddr { bytes: Vec::new() }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the raw bytes representation of the multiaddr.
|
/// Returns the raw bytes representation of the multiaddr.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_bytes(self) -> Vec<u8> {
|
pub fn into_bytes(self) -> Vec<u8> {
|
||||||
|
@ -54,7 +54,6 @@ use futures::{future, future::FutureResult, prelude::*, Async, Poll};
|
|||||||
use multiaddr::{Protocol, Multiaddr, ToMultiaddr};
|
use multiaddr::{Protocol, Multiaddr, ToMultiaddr};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{Error as IoError, Read, Write};
|
use std::io::{Error as IoError, Read, Write};
|
||||||
use std::iter;
|
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use swarm::Transport;
|
use swarm::Transport;
|
||||||
@ -194,40 +193,21 @@ impl Transport for TcpConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
||||||
// Check that `server` only has two components and retreive them.
|
let mut address = Multiaddr::empty();
|
||||||
let mut server_protocols_iter = server.iter();
|
|
||||||
let server_proto1 = server_protocols_iter.next()?;
|
// Use the observed IP address.
|
||||||
let server_proto2 = server_protocols_iter.next()?;
|
match server.iter().zip(observed.iter()).next() {
|
||||||
if server_protocols_iter.next().is_some() {
|
Some((Protocol::Ip4(_), x@Protocol::Ip4(_))) => address.append(x),
|
||||||
return None;
|
Some((Protocol::Ip6(_), x@Protocol::Ip6(_))) => address.append(x),
|
||||||
|
_ => return None
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that `observed` only has two components and retreive them.
|
// Carry over everything else from the server address.
|
||||||
let mut observed_protocols_iter = observed.iter();
|
for proto in server.iter().skip(1) {
|
||||||
let observed_proto1 = observed_protocols_iter.next()?;
|
address.append(proto)
|
||||||
let observed_proto2 = observed_protocols_iter.next()?;
|
|
||||||
if observed_protocols_iter.next().is_some() {
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that `server` is a valid TCP/IP address.
|
Some(address)
|
||||||
match (&server_proto1, &server_proto2) {
|
|
||||||
(&Protocol::Ip4(_), &Protocol::Tcp(_))
|
|
||||||
| (&Protocol::Ip6(_), &Protocol::Tcp(_)) => {}
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that `observed` is a valid TCP/IP address.
|
|
||||||
match (&observed_proto1, &observed_proto2) {
|
|
||||||
(&Protocol::Ip4(_), &Protocol::Tcp(_))
|
|
||||||
| (&Protocol::Ip6(_), &Protocol::Tcp(_)) => {}
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = iter::once(observed_proto1.clone())
|
|
||||||
.chain(iter::once(server_proto2.clone()))
|
|
||||||
.collect();
|
|
||||||
Some(result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,49 +209,40 @@ impl Transport for BrowserWsConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
||||||
let mut server_protocols = server.iter();
|
let mut address = Multiaddr::empty();
|
||||||
let server_proto0 = server_protocols.next()?;
|
|
||||||
let server_proto1 = server_protocols.next()?;
|
let mut iter = server.iter().zip(observed.iter());
|
||||||
let server_proto2 = server_protocols.next()?;
|
|
||||||
if server_protocols.next().is_some() {
|
// Use the observed IP address.
|
||||||
return None;
|
match iter.next() {
|
||||||
|
Some((Protocol::Ip4(_), x@Protocol::Ip4(_))) => address.append(x),
|
||||||
|
Some((Protocol::Ip6(_), x@Protocol::Ip6(_))) => address.append(x),
|
||||||
|
_ => return None
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut observed_protocols = observed.iter();
|
// Skip over next protocol (assumed to contain port information).
|
||||||
let obs_proto0 = observed_protocols.next()?;
|
if iter.next().is_none() {
|
||||||
let obs_proto1 = observed_protocols.next()?;
|
return None
|
||||||
let obs_proto2 = observed_protocols.next()?;
|
|
||||||
if observed_protocols.next().is_some() {
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that `server` is a valid TCP/IP address.
|
// Check for WS/WSS.
|
||||||
match (&server_proto0, &server_proto1, &server_proto2) {
|
//
|
||||||
(&Protocol::Ip4(_), &Protocol::Tcp(_), &Protocol::Ws)
|
// Note that it will still work if the server uses WSS while the client uses
|
||||||
| (&Protocol::Ip6(_), &Protocol::Tcp(_), &Protocol::Ws)
|
// WS, or vice-versa.
|
||||||
| (&Protocol::Ip4(_), &Protocol::Tcp(_), &Protocol::Wss)
|
match iter.next() {
|
||||||
| (&Protocol::Ip6(_), &Protocol::Tcp(_), &Protocol::Wss) => {}
|
Some((x@Protocol::Ws, Protocol::Ws)) => address.append(x),
|
||||||
_ => return None,
|
Some((x@Protocol::Ws, Protocol::Wss)) => address.append(x),
|
||||||
|
Some((x@Protocol::Wss, Protocol::Ws)) => address.append(x),
|
||||||
|
Some((x@Protocol::Wss, Protocol::Wss)) => address.append(x),
|
||||||
|
_ => return None
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that `observed` is a valid TCP/IP address.
|
// Carry over everything else from the server address.
|
||||||
match (&obs_proto0, &obs_proto1, &obs_proto2) {
|
for proto in server.iter().skip(3) {
|
||||||
(&Protocol::Ip4(_), &Protocol::Tcp(_), &Protocol::Ws)
|
address.append(proto)
|
||||||
| (&Protocol::Ip6(_), &Protocol::Tcp(_), &Protocol::Ws)
|
|
||||||
| (&Protocol::Ip4(_), &Protocol::Tcp(_), &Protocol::Wss)
|
|
||||||
| (&Protocol::Ip6(_), &Protocol::Tcp(_), &Protocol::Wss) => {}
|
|
||||||
_ => return None,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that it will still work if the server uses WSS while the client uses WS,
|
Some(address)
|
||||||
// or vice-versa.
|
|
||||||
|
|
||||||
let result = iter::once(obs_proto0)
|
|
||||||
.chain(iter::once(server_proto1))
|
|
||||||
.chain(iter::once(server_proto2))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Some(result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,25 +236,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
||||||
let mut server = server.clone();
|
self.transport.nat_traversal(server, observed)
|
||||||
let last_proto = match server.pop() {
|
|
||||||
Some(v @ Protocol::Ws) | Some(v @ Protocol::Wss) => v,
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut observed = observed.clone();
|
|
||||||
match observed.pop() {
|
|
||||||
Some(Protocol::Ws) => false,
|
|
||||||
Some(Protocol::Wss) => true,
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.transport
|
|
||||||
.nat_traversal(&server, &observed)
|
|
||||||
.map(move |mut result| {
|
|
||||||
result.append(last_proto);
|
|
||||||
result
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user