mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-05-28 10:11:19 +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.
|
||||
///
|
||||
/// 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
|
||||
/// implementation of `Transport` is only responsible for handling the protocols it supports.
|
||||
/// `/ip4/80.81.82.83/tcp/29601`, then we should return `/ip4/80.81.82.83/tcp/3000`.
|
||||
///
|
||||
/// 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
|
||||
/// doesn't recognize the protocols, or if `server` and `observed` are related.
|
||||
|
@ -120,6 +120,11 @@ impl fmt::Display for Multiaddr {
|
||||
}
|
||||
|
||||
impl Multiaddr {
|
||||
/// Create a new, empty multiaddress.
|
||||
pub fn empty() -> Multiaddr {
|
||||
Multiaddr { bytes: Vec::new() }
|
||||
}
|
||||
|
||||
/// Returns the raw bytes representation of the multiaddr.
|
||||
#[inline]
|
||||
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 std::fmt;
|
||||
use std::io::{Error as IoError, Read, Write};
|
||||
use std::iter;
|
||||
use std::net::SocketAddr;
|
||||
use std::time::Duration;
|
||||
use swarm::Transport;
|
||||
@ -194,40 +193,21 @@ impl Transport for TcpConfig {
|
||||
}
|
||||
|
||||
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
||||
// Check that `server` only has two components and retreive them.
|
||||
let mut server_protocols_iter = server.iter();
|
||||
let server_proto1 = server_protocols_iter.next()?;
|
||||
let server_proto2 = server_protocols_iter.next()?;
|
||||
if server_protocols_iter.next().is_some() {
|
||||
return None;
|
||||
let mut address = Multiaddr::empty();
|
||||
|
||||
// Use the observed IP address.
|
||||
match server.iter().zip(observed.iter()).next() {
|
||||
Some((Protocol::Ip4(_), x@Protocol::Ip4(_))) => address.append(x),
|
||||
Some((Protocol::Ip6(_), x@Protocol::Ip6(_))) => address.append(x),
|
||||
_ => return None
|
||||
}
|
||||
|
||||
// Check that `observed` only has two components and retreive them.
|
||||
let mut observed_protocols_iter = observed.iter();
|
||||
let observed_proto1 = observed_protocols_iter.next()?;
|
||||
let observed_proto2 = observed_protocols_iter.next()?;
|
||||
if observed_protocols_iter.next().is_some() {
|
||||
return None;
|
||||
// Carry over everything else from the server address.
|
||||
for proto in server.iter().skip(1) {
|
||||
address.append(proto)
|
||||
}
|
||||
|
||||
// Check that `server` is a valid TCP/IP 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)
|
||||
Some(address)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,49 +209,40 @@ impl Transport for BrowserWsConfig {
|
||||
}
|
||||
|
||||
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
||||
let mut server_protocols = server.iter();
|
||||
let server_proto0 = server_protocols.next()?;
|
||||
let server_proto1 = server_protocols.next()?;
|
||||
let server_proto2 = server_protocols.next()?;
|
||||
if server_protocols.next().is_some() {
|
||||
return None;
|
||||
let mut address = Multiaddr::empty();
|
||||
|
||||
let mut iter = server.iter().zip(observed.iter());
|
||||
|
||||
// Use the observed IP address.
|
||||
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();
|
||||
let obs_proto0 = observed_protocols.next()?;
|
||||
let obs_proto1 = observed_protocols.next()?;
|
||||
let obs_proto2 = observed_protocols.next()?;
|
||||
if observed_protocols.next().is_some() {
|
||||
return None;
|
||||
// Skip over next protocol (assumed to contain port information).
|
||||
if iter.next().is_none() {
|
||||
return None
|
||||
}
|
||||
|
||||
// Check that `server` is a valid TCP/IP address.
|
||||
match (&server_proto0, &server_proto1, &server_proto2) {
|
||||
(&Protocol::Ip4(_), &Protocol::Tcp(_), &Protocol::Ws)
|
||||
| (&Protocol::Ip6(_), &Protocol::Tcp(_), &Protocol::Ws)
|
||||
| (&Protocol::Ip4(_), &Protocol::Tcp(_), &Protocol::Wss)
|
||||
| (&Protocol::Ip6(_), &Protocol::Tcp(_), &Protocol::Wss) => {}
|
||||
_ => return None,
|
||||
// Check for WS/WSS.
|
||||
//
|
||||
// Note that it will still work if the server uses WSS while the client uses
|
||||
// WS, or vice-versa.
|
||||
match iter.next() {
|
||||
Some((x@Protocol::Ws, Protocol::Ws)) => address.append(x),
|
||||
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.
|
||||
match (&obs_proto0, &obs_proto1, &obs_proto2) {
|
||||
(&Protocol::Ip4(_), &Protocol::Tcp(_), &Protocol::Ws)
|
||||
| (&Protocol::Ip6(_), &Protocol::Tcp(_), &Protocol::Ws)
|
||||
| (&Protocol::Ip4(_), &Protocol::Tcp(_), &Protocol::Wss)
|
||||
| (&Protocol::Ip6(_), &Protocol::Tcp(_), &Protocol::Wss) => {}
|
||||
_ => return None,
|
||||
// Carry over everything else from the server address.
|
||||
for proto in server.iter().skip(3) {
|
||||
address.append(proto)
|
||||
}
|
||||
|
||||
// Note that it will still work if the server uses WSS while the client uses WS,
|
||||
// or vice-versa.
|
||||
|
||||
let result = iter::once(obs_proto0)
|
||||
.chain(iter::once(server_proto1))
|
||||
.chain(iter::once(server_proto2))
|
||||
.collect();
|
||||
|
||||
Some(result)
|
||||
Some(address)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,25 +236,7 @@ where
|
||||
}
|
||||
|
||||
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
||||
let mut server = server.clone();
|
||||
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
|
||||
})
|
||||
self.transport.nat_traversal(server, observed)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user