vpncloud/src/wsproxy.rs

170 lines
5.9 KiB
Rust
Raw Normal View History

2021-02-08 09:11:20 +00:00
// VpnCloud - Peer-to-Peer VPN
// Copyright (C) 2015-2021 Dennis Schwerdel
// This software is licensed under GPL-3 or newer (see LICENSE.md)
2020-12-20 00:40:32 +00:00
use super::{
2021-02-04 22:38:08 +00:00
net::{get_ip, mapped_addr, parse_listen, Socket},
2020-12-20 12:28:01 +00:00
poll::{WaitImpl, WaitResult},
2020-12-20 00:40:32 +00:00
port_forwarding::PortForwarding,
2021-04-06 10:28:31 +00:00
util::MsgBuffer,
2020-12-20 00:40:32 +00:00
};
2020-12-20 12:28:01 +00:00
use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
2020-12-20 00:40:32 +00:00
use std::{
2020-12-20 12:28:01 +00:00
io::{self, Cursor, Read, Write},
net::{Ipv6Addr, SocketAddr, SocketAddrV6, TcpListener, TcpStream, UdpSocket},
2020-12-20 00:40:32 +00:00
os::unix::io::{AsRawFd, RawFd},
2021-04-06 10:28:31 +00:00
thread::spawn,
2020-12-20 00:40:32 +00:00
};
2021-12-19 11:51:52 +00:00
use tungstenite::{connect, protocol::WebSocket, Message, accept, stream::{MaybeTlsStream, NoDelay}};
2020-12-20 00:40:32 +00:00
use url::Url;
2020-12-20 12:28:01 +00:00
macro_rules! io_error {
($val:expr, $format:expr) => ( {
$val.map_err(|err| io::Error::new(io::ErrorKind::Other, format!($format, err)))
} );
($val:expr, $format:expr, $( $arg:expr ),+) => ( {
$val.map_err(|err| io::Error::new(io::ErrorKind::Other, format!($format, $( $arg ),+, err)))
} );
}
fn write_addr<W: Write>(addr: SocketAddr, mut out: W) -> Result<(), io::Error> {
let addr = mapped_addr(addr);
match mapped_addr(addr) {
SocketAddr::V6(addr) => {
out.write_all(&addr.ip().octets())?;
out.write_u16::<NetworkEndian>(addr.port())?;
}
2021-04-06 10:28:31 +00:00
_ => unreachable!(),
2020-12-20 12:28:01 +00:00
}
Ok(())
}
fn read_addr<R: Read>(mut r: R) -> Result<SocketAddr, io::Error> {
let mut ip = [0u8; 16];
r.read_exact(&mut ip)?;
let port = r.read_u16::<NetworkEndian>()?;
let addr = SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::from(ip), port, 0, 0));
Ok(addr)
}
fn serve_proxy_connection(stream: TcpStream) -> Result<(), io::Error> {
let peer = stream.peer_addr()?;
info!("WS client {} connected", peer);
2021-02-04 22:38:08 +00:00
stream.set_nodelay(true)?;
2020-12-20 12:28:01 +00:00
let mut websocket = io_error!(accept(stream), "Failed to initialize websocket with {}: {}", peer)?;
let udpsocket = UdpSocket::bind("[::]:0")?;
let mut msg = Vec::with_capacity(18);
2021-02-03 21:03:42 +00:00
let mut addr = udpsocket.local_addr()?;
2020-12-20 12:28:01 +00:00
info!("Listening on {} for peer {}", addr, peer);
2021-02-03 21:03:42 +00:00
addr.set_ip(get_ip());
2020-12-20 12:28:01 +00:00
write_addr(addr, &mut msg)?;
io_error!(websocket.write_message(Message::Binary(msg)), "Failed to write to ws connection: {}")?;
let websocketfd = websocket.get_ref().as_raw_fd();
2021-02-04 22:38:08 +00:00
let poll = WaitImpl::new(websocketfd, udpsocket.as_raw_fd(), 60 * 1000)?;
2020-12-20 12:28:01 +00:00
let mut buffer = [0; 65535];
for evt in poll {
match evt {
WaitResult::Socket => {
let msg = io_error!(websocket.read_message(), "Failed to read message on websocket {}: {}", peer)?;
match msg {
Message::Binary(data) => {
let dst = read_addr(Cursor::new(&data))?;
udpsocket.send_to(&data[18..], dst)?;
}
Message::Close(_) => return Ok(()),
_ => {}
}
}
WaitResult::Device => {
let (size, addr) = udpsocket.recv_from(&mut buffer)?;
let mut data = Vec::with_capacity(18 + size);
write_addr(addr, &mut data)?;
data.write_all(&buffer[..size])?;
io_error!(websocket.write_message(Message::Binary(data)), "Failed to write to {}: {}", peer)?;
}
WaitResult::Timeout => {
io_error!(websocket.write_message(Message::Ping(vec![])), "Failed to send ping: {}")?;
}
2021-04-06 10:28:31 +00:00
WaitResult::Error(err) => return Err(err),
2020-12-20 12:28:01 +00:00
}
}
Ok(())
}
2021-02-04 20:19:05 +00:00
pub fn run_proxy(listen: &str) -> Result<(), io::Error> {
let addr = parse_listen(listen, 8080);
2021-02-04 20:19:05 +00:00
let server = TcpListener::bind(addr)?;
2021-02-04 22:38:08 +00:00
info!("Listening on ws://{}", server.local_addr()?);
2020-12-20 00:40:32 +00:00
for stream in server.incoming() {
2020-12-20 12:28:01 +00:00
let stream = stream?;
let peer = stream.peer_addr()?;
2020-12-20 00:40:32 +00:00
spawn(move || {
2020-12-20 12:28:01 +00:00
if let Err(err) = serve_proxy_connection(stream) {
error!("Error on connection {}: {}", peer, err);
2020-12-20 00:40:32 +00:00
}
});
}
2020-12-20 12:28:01 +00:00
Ok(())
2020-12-20 00:40:32 +00:00
}
pub struct ProxyConnection {
addr: SocketAddr,
2021-12-19 11:51:52 +00:00
socket: WebSocket<MaybeTlsStream<TcpStream>>,
2020-12-20 00:40:32 +00:00
}
2020-12-20 12:28:01 +00:00
impl ProxyConnection {
fn read_message(&mut self) -> Result<Vec<u8>, io::Error> {
loop {
if let Message::Binary(data) = io_error!(self.socket.read_message(), "Failed to read from ws proxy: {}")? {
2021-04-06 10:28:31 +00:00
return Ok(data);
2020-12-20 12:28:01 +00:00
}
}
}
}
2020-12-20 00:40:32 +00:00
impl AsRawFd for ProxyConnection {
fn as_raw_fd(&self) -> RawFd {
2021-12-19 11:51:52 +00:00
match self.socket.get_ref() {
MaybeTlsStream::Plain(stream) => stream.as_raw_fd(),
_ => unimplemented!()
}
2020-12-20 00:40:32 +00:00
}
}
impl Socket for ProxyConnection {
fn listen(url: &str) -> Result<Self, io::Error> {
2020-12-20 12:28:01 +00:00
let parsed_url = io_error!(Url::parse(url), "Invalid URL {}: {}", url)?;
2021-02-04 22:38:08 +00:00
let (mut socket, _) = io_error!(connect(parsed_url), "Failed to connect to URL {}: {}", url)?;
socket.get_mut().set_nodelay(true)?;
2020-12-20 00:40:32 +00:00
let addr = "0.0.0.0:0".parse::<SocketAddr>().unwrap();
2020-12-20 12:28:01 +00:00
let mut con = ProxyConnection { addr, socket };
let addr_data = con.read_message()?;
con.addr = read_addr(Cursor::new(&addr_data))?;
Ok(con)
2020-12-20 00:40:32 +00:00
}
fn receive(&mut self, buffer: &mut MsgBuffer) -> Result<SocketAddr, io::Error> {
buffer.clear();
2020-12-20 12:28:01 +00:00
let data = self.read_message()?;
let addr = read_addr(Cursor::new(&data))?;
buffer.clone_from(&data[18..]);
Ok(addr)
2020-12-20 00:40:32 +00:00
}
fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error> {
let mut msg = Vec::with_capacity(data.len() + 18);
2020-12-20 12:28:01 +00:00
write_addr(addr, &mut msg)?;
2020-12-20 00:40:32 +00:00
msg.write_all(data)?;
2020-12-20 12:28:01 +00:00
io_error!(self.socket.write_message(Message::Binary(msg)), "Failed to write to ws proxy: {}")?;
2020-12-20 00:40:32 +00:00
Ok(data.len())
}
fn address(&self) -> Result<SocketAddr, io::Error> {
Ok(self.addr)
}
fn create_port_forwarding(&self) -> Option<PortForwarding> {
None
}
2021-02-04 22:38:08 +00:00
}