vpncloud/src/net.rs

142 lines
4.4 KiB
Rust
Raw Normal View History

2019-12-04 08:32:35 +00:00
use std::{
2019-12-04 12:09:20 +00:00
collections::{HashMap, VecDeque},
2019-12-04 08:32:35 +00:00
io::{self, ErrorKind},
net::{SocketAddr, SocketAddrV4, SocketAddrV6, UdpSocket},
2019-12-04 12:09:20 +00:00
os::unix::io::{AsRawFd, RawFd},
sync::atomic::{AtomicBool, Ordering}
2019-12-04 08:32:35 +00:00
};
2019-02-21 21:41:36 +00:00
2019-12-04 12:09:20 +00:00
use super::util::{get_internal_ip, MockTimeSource, Time, TimeSource};
2019-02-21 21:41:36 +00:00
use net2::UdpBuilder;
pub trait Socket: AsRawFd + Sized {
fn listen_v4(host: &str, port: u16) -> Result<Self, io::Error>;
fn listen_v6(host: &str, port: u16) -> Result<Self, io::Error>;
fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), io::Error>;
fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error>;
fn address(&self) -> Result<SocketAddr, io::Error>;
2019-12-04 12:09:20 +00:00
fn detect_nat(&self) -> bool;
2019-02-21 21:41:36 +00:00
}
impl Socket for UdpSocket {
fn listen_v4(host: &str, port: u16) -> Result<Self, io::Error> {
2019-12-04 08:32:35 +00:00
UdpBuilder::new_v4()
.expect("Failed to obtain ipv4 socket builder")
.reuse_address(true)
.expect("Failed to set so_reuseaddr")
.bind((host, port))
2019-02-21 21:41:36 +00:00
}
fn listen_v6(host: &str, port: u16) -> Result<Self, io::Error> {
2019-12-04 08:32:35 +00:00
UdpBuilder::new_v6()
.expect("Failed to obtain ipv4 socket builder")
.only_v6(true)
.expect("Failed to set only_v6")
.reuse_address(true)
.expect("Failed to set so_reuseaddr")
.bind((host, port))
2019-02-21 21:41:36 +00:00
}
fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), io::Error> {
self.recv_from(buffer)
}
fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error> {
self.send_to(data, addr)
}
fn address(&self) -> Result<SocketAddr, io::Error> {
self.local_addr()
}
2019-12-04 12:09:20 +00:00
fn detect_nat(&self) -> bool {
get_internal_ip().is_private()
}
2019-02-21 21:41:36 +00:00
}
2019-12-04 12:09:20 +00:00
thread_local! {
static MOCK_SOCKET_NAT: AtomicBool = AtomicBool::new(false);
}
2019-02-21 21:41:36 +00:00
pub struct MockSocket {
2019-12-04 12:09:20 +00:00
nat: bool,
nat_peers: HashMap<SocketAddr, Time>,
2019-02-21 21:41:36 +00:00
address: SocketAddr,
outbound: VecDeque<(SocketAddr, Vec<u8>)>,
inbound: VecDeque<(SocketAddr, Vec<u8>)>
}
impl MockSocket {
pub fn new(address: SocketAddr) -> Self {
2019-12-04 12:09:20 +00:00
Self {
nat: Self::get_nat(),
nat_peers: HashMap::new(),
address,
outbound: VecDeque::new(),
inbound: VecDeque::new()
}
}
pub fn set_nat(nat: bool) {
MOCK_SOCKET_NAT.with(|t| t.store(nat, Ordering::SeqCst))
2019-02-21 21:41:36 +00:00
}
2019-12-04 12:09:20 +00:00
pub fn get_nat() -> bool {
MOCK_SOCKET_NAT.with(|t| t.load(Ordering::SeqCst))
}
pub fn put_inbound(&mut self, from: SocketAddr, data: Vec<u8>) -> bool {
if !self.nat {
self.inbound.push_back((from, data));
return true
}
if let Some(timeout) = self.nat_peers.get(&from) {
if *timeout >= MockTimeSource::now() {
self.inbound.push_back((from, data));
return true
}
}
warn!("Sender {:?} is filtered out by NAT", from);
false
2019-02-21 21:41:36 +00:00
}
pub fn pop_outbound(&mut self) -> Option<(SocketAddr, Vec<u8>)> {
self.outbound.pop_front()
}
}
impl AsRawFd for MockSocket {
fn as_raw_fd(&self) -> RawFd {
unimplemented!()
}
}
impl Socket for MockSocket {
fn listen_v4(host: &str, port: u16) -> Result<Self, io::Error> {
let ip = try_fail!(host.parse(), "Failed to parse IPv4 address: {}");
Ok(Self::new(SocketAddr::V4(SocketAddrV4::new(ip, port))))
}
fn listen_v6(host: &str, port: u16) -> Result<Self, io::Error> {
let ip = try_fail!(host.parse(), "Failed to parse IPv6 address: {}");
Ok(Self::new(SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0))))
}
fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), io::Error> {
if let Some((addr, data)) = self.inbound.pop_front() {
buffer[0..data.len()].copy_from_slice(&data);
Ok((data.len(), addr))
} else {
2019-12-04 12:09:20 +00:00
Err(io::Error::new(ErrorKind::Other, "nothing in queue"))
2019-02-21 21:41:36 +00:00
}
}
fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error> {
self.outbound.push_back((addr, data.to_owned()));
2019-12-04 12:09:20 +00:00
if self.nat {
self.nat_peers.insert(addr, MockTimeSource::now() + 300);
}
2019-02-21 21:41:36 +00:00
Ok(data.len())
}
fn address(&self) -> Result<SocketAddr, io::Error> {
Ok(self.address)
}
2019-12-04 12:09:20 +00:00
fn detect_nat(&self) -> bool {
self.nat
}
2019-12-04 08:32:35 +00:00
}