vpncloud/src/net.rs

194 lines
5.9 KiB
Rust
Raw Normal View History

2020-05-28 07:07:34 +00:00
// VpnCloud - Peer-to-Peer VPN
2021-02-08 09:11:20 +00:00
// Copyright (C) 2015-2021 Dennis Schwerdel
2020-05-28 07:07:34 +00:00
// This software is licensed under GPL-3 or newer (see LICENSE.md)
2021-04-11 19:50:02 +00:00
use crate::config::DEFAULT_PORT;
2021-02-19 23:17:06 +00:00
use crate::port_forwarding::PortForwarding;
2021-04-11 19:50:02 +00:00
use crate::util::{MockTimeSource, MsgBuffer, Time, TimeSource};
2021-03-02 15:31:40 +00:00
use async_trait::async_trait;
2021-02-19 23:17:06 +00:00
use parking_lot::Mutex;
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},
2021-02-19 23:17:06 +00:00
net::{IpAddr, Ipv6Addr, SocketAddr, UdpSocket},
sync::{
atomic::{AtomicBool, Ordering},
2021-03-02 15:31:40 +00:00
Arc,
2021-02-19 23:17:06 +00:00
},
2019-12-04 08:32:35 +00:00
};
2019-02-21 21:41:36 +00:00
2020-09-24 17:48:13 +00:00
pub fn mapped_addr(addr: SocketAddr) -> SocketAddr {
2021-01-28 22:19:20 +00:00
// HOT PATH
2020-09-24 17:48:13 +00:00
match addr {
SocketAddr::V4(addr4) => SocketAddr::new(IpAddr::V6(addr4.ip().to_ipv6_mapped()), addr4.port()),
2021-03-02 15:31:40 +00:00
_ => addr,
2020-09-24 17:48:13 +00:00
}
}
2021-02-03 21:03:42 +00:00
pub fn get_ip() -> IpAddr {
let s = UdpSocket::bind("[::]:0").unwrap();
s.connect("8.8.8.8:0").unwrap();
s.local_addr().unwrap().ip()
}
2019-02-21 21:41:36 +00:00
2021-03-02 15:31:40 +00:00
#[async_trait]
pub trait Socket: Sized + Clone + Send + Sync + 'static {
async fn listen(addr: &str) -> Result<Self, io::Error>;
async fn receive(&mut self, buffer: &mut MsgBuffer) -> Result<SocketAddr, io::Error>;
async fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error>;
async fn address(&self) -> Result<SocketAddr, io::Error>;
async fn create_port_forwarding(&self) -> Option<PortForwarding>;
2020-12-20 00:40:32 +00:00
}
pub fn parse_listen(addr: &str, default_port: u16) -> SocketAddr {
2020-12-20 00:40:32 +00:00
if let Some(addr) = addr.strip_prefix("*:") {
let port = try_fail!(addr.parse::<u16>(), "Invalid port: {}");
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
} else if addr.contains(':') {
try_fail!(addr.parse::<SocketAddr>(), "Invalid address: {}: {}", addr)
} else if let Ok(port) = addr.parse::<u16>() {
2020-12-20 00:40:32 +00:00
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
} else {
let ip = try_fail!(addr.parse::<IpAddr>(), "Invalid addr: {}");
SocketAddr::new(ip, default_port)
2020-12-20 00:40:32 +00:00
}
2019-02-21 21:41:36 +00:00
}
2021-02-19 23:17:06 +00:00
pub struct NetSocket(UdpSocket);
impl Clone for NetSocket {
fn clone(&self) -> Self {
Self(try_fail!(self.0.try_clone(), "Failed to clone socket: {}"))
}
}
2021-03-02 15:31:40 +00:00
#[async_trait]
2021-02-19 23:17:06 +00:00
impl Socket for NetSocket {
2021-03-02 15:31:40 +00:00
async fn listen(addr: &str) -> Result<Self, io::Error> {
2021-04-11 19:50:02 +00:00
let addr = parse_listen(addr, DEFAULT_PORT);
2021-03-02 15:31:40 +00:00
Ok(NetSocket(UdpSocket::bind(addr)?))
2019-02-21 21:41:36 +00:00
}
2020-09-24 17:48:13 +00:00
2021-03-02 15:31:40 +00:00
async fn receive(&mut self, buffer: &mut MsgBuffer) -> Result<SocketAddr, io::Error> {
2020-09-24 17:48:13 +00:00
buffer.clear();
2021-02-19 23:17:06 +00:00
let (size, addr) = self.0.recv_from(buffer.buffer())?;
2020-09-24 17:48:13 +00:00
buffer.set_length(size);
Ok(addr)
2019-02-21 21:41:36 +00:00
}
2020-09-24 17:48:13 +00:00
2021-03-02 15:31:40 +00:00
async fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error> {
2021-02-19 23:17:06 +00:00
self.0.send_to(data, addr)
2019-02-21 21:41:36 +00:00
}
2020-09-24 17:48:13 +00:00
2021-03-02 15:31:40 +00:00
async fn address(&self) -> Result<SocketAddr, io::Error> {
2021-02-19 23:17:06 +00:00
let mut addr = self.0.local_addr()?;
2021-02-03 21:03:42 +00:00
addr.set_ip(get_ip());
Ok(addr)
2019-02-21 21:41:36 +00:00
}
2020-12-20 00:40:32 +00:00
2021-03-02 15:31:40 +00:00
async fn create_port_forwarding(&self) -> Option<PortForwarding> {
PortForwarding::new(self.address().await.unwrap().port())
2020-12-20 00:40:32 +00:00
}
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
2021-02-19 23:17:06 +00:00
#[derive(Clone)]
2019-02-21 21:41:36 +00:00
pub struct MockSocket {
2019-12-04 12:09:20 +00:00
nat: bool,
2021-02-19 23:17:06 +00:00
nat_peers: Arc<Mutex<HashMap<SocketAddr, Time>>>,
2019-02-21 21:41:36 +00:00
address: SocketAddr,
2021-02-19 23:17:06 +00:00
outbound: Arc<Mutex<VecDeque<(SocketAddr, Vec<u8>)>>>,
2021-03-02 15:31:40 +00:00
inbound: Arc<Mutex<VecDeque<(SocketAddr, Vec<u8>)>>>,
2019-02-21 21:41:36 +00:00
}
impl MockSocket {
pub fn new(address: SocketAddr) -> Self {
2019-12-04 12:09:20 +00:00
Self {
nat: Self::get_nat(),
2021-02-19 23:17:06 +00:00
nat_peers: Default::default(),
2019-12-04 12:09:20 +00:00
address,
2021-02-19 23:17:06 +00:00
outbound: Arc::new(Mutex::new(VecDeque::with_capacity(10))),
2021-03-02 15:31:40 +00:00
inbound: Arc::new(Mutex::new(VecDeque::with_capacity(10))),
2019-12-04 12:09:20 +00:00
}
}
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 {
2021-02-19 23:17:06 +00:00
self.inbound.lock().push_back((from, data));
2021-03-02 15:31:40 +00:00
return true;
2019-12-04 12:09:20 +00:00
}
2021-02-19 23:17:06 +00:00
if let Some(timeout) = self.nat_peers.lock().get(&from) {
2019-12-04 12:09:20 +00:00
if *timeout >= MockTimeSource::now() {
2021-02-19 23:17:06 +00:00
self.inbound.lock().push_back((from, data));
2021-03-02 15:31:40 +00:00
return true;
2019-12-04 12:09:20 +00:00
}
}
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>)> {
2021-02-19 23:17:06 +00:00
self.outbound.lock().pop_front()
2019-02-21 21:41:36 +00:00
}
}
2021-03-02 15:31:40 +00:00
#[async_trait]
2019-02-21 21:41:36 +00:00
impl Socket for MockSocket {
2021-03-02 15:31:40 +00:00
async fn listen(addr: &str) -> Result<Self, io::Error> {
2021-04-11 19:50:02 +00:00
Ok(Self::new(parse_listen(addr, DEFAULT_PORT)))
2019-02-21 21:41:36 +00:00
}
2020-09-24 17:48:13 +00:00
2021-03-02 15:31:40 +00:00
async fn receive(&mut self, buffer: &mut MsgBuffer) -> Result<SocketAddr, io::Error> {
2021-02-19 23:17:06 +00:00
if let Some((addr, data)) = self.inbound.lock().pop_front() {
2020-09-24 17:48:13 +00:00
buffer.clear();
buffer.set_length(data.len());
buffer.message_mut().copy_from_slice(&data);
Ok(addr)
2019-02-21 21:41:36 +00:00
} 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
}
}
2020-09-24 17:48:13 +00:00
2021-03-02 15:31:40 +00:00
async fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error> {
2021-02-19 23:17:06 +00:00
self.outbound.lock().push_back((addr, data.into()));
2019-12-04 12:09:20 +00:00
if self.nat {
2021-02-19 23:17:06 +00:00
self.nat_peers.lock().insert(addr, MockTimeSource::now() + 300);
2019-12-04 12:09:20 +00:00
}
2019-02-21 21:41:36 +00:00
Ok(data.len())
}
2020-09-24 17:48:13 +00:00
2021-03-02 15:31:40 +00:00
async fn address(&self) -> Result<SocketAddr, io::Error> {
2019-02-21 21:41:36 +00:00
Ok(self.address)
}
2020-12-20 00:40:32 +00:00
2021-03-02 15:31:40 +00:00
async fn create_port_forwarding(&self) -> Option<PortForwarding> {
2020-12-20 00:40:32 +00:00
None
}
2019-12-04 08:32:35 +00:00
}
2020-10-21 21:09:49 +00:00
#[cfg(feature = "bench")]
mod bench {
use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};
use test::Bencher;
#[bench]
fn udp_send(b: &mut Bencher) {
let sock = UdpSocket::bind("127.0.0.1:0").unwrap();
let data = [0; 1400];
let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 1);
b.iter(|| sock.send_to(&data, &addr).unwrap());
b.bytes = 1400;
}
2021-02-19 23:17:06 +00:00
}