diff options
-rw-r--r-- | Cargo.lock | 12 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/interface/mod.rs | 7 | ||||
-rw-r--r-- | src/interface/peer_server.rs | 38 | ||||
-rw-r--r-- | src/main.rs | 2 |
5 files changed, 49 insertions, 12 deletions
@@ -620,6 +620,16 @@ dependencies = [ ] [[package]] +name = "socket2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "static_slice" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -889,6 +899,7 @@ dependencies = [ "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "snow 0.1.8-preview (git+https://github.com/mcginty/snow?branch=wireguard)", + "socket2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "structopt-derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1017,6 +1028,7 @@ dependencies = [ "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" "checksum snow 0.1.8-preview (git+https://github.com/mcginty/snow?branch=wireguard)" = "<none>" +"checksum socket2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a76b792959eba82f021c9028c8ecb6396f085268d6d46af2ed96a829cc758d7c" "checksum static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "92a7e0c5e3dfb52e8fbe0e63a1b947bbb17b4036408b151353c4491374931362" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum structopt 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "783cb22d520b177a3772e520d04a3c7970d51c3b647ba80739f99be01131b54f" @@ -30,6 +30,8 @@ tokio-uds = "^0.1" tokio-utun = "^0.1" tokio-timer = "^0.1" +socket2 = "^0.3" + snow = { git = "https://github.com/mcginty/snow", features = ["ring-accelerated"], branch = "wireguard" } base64 = "^0.5" hex = "^0.3" diff --git a/src/interface/mod.rs b/src/interface/mod.rs index 1cce00e..c6d441d 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -30,9 +30,9 @@ use tokio_timer::{Interval, Timer}; use treebitmap::{IpLookupTable, IpLookupTableOps}; -pub fn debug_packet(header: &str, packet: &[u8]) { +pub fn trace_packet(header: &str, packet: &[u8]) { let packet = Ipv4Packet::new(packet); - debug!("{} {:?}", header, packet); + trace!("{} {:?}", header, packet); } pub type SharedPeer = Rc<RefCell<Peer>>; @@ -62,7 +62,7 @@ impl UtunCodec for VecUtunCodec { type Out = Vec<u8>; fn decode(&mut self, buf: &[u8]) -> io::Result<Self::In> { - debug!("utun packet type {}", buf[3]); + trace!("utun packet type {}", buf[3]); Ok(buf[4..].to_vec()) } @@ -196,6 +196,7 @@ impl Interface { let _ = state.pubkey_map.insert(info.pub_key, peer); handle.spawn(tx.clone().send((info.endpoint.unwrap(), init_packet)).then(|_| Ok(()))); + debug!("sent handshake packet to new peer"); }, _ => unimplemented!() } diff --git a/src/interface/peer_server.rs b/src/interface/peer_server.rs index b9cccd5..126b8a0 100644 --- a/src/interface/peer_server.rs +++ b/src/interface/peer_server.rs @@ -1,15 +1,16 @@ -use super::{SharedState, SharedPeer, debug_packet}; +use super::{SharedState, SharedPeer, trace_packet}; use consts::{REKEY_AFTER_TIME, KEEPALIVE_TIMEOUT}; use protocol::Session; use std::io; -use std::net::SocketAddr; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use std::time::Duration; use base64; use byteorder::{ByteOrder, BigEndian, LittleEndian}; use futures::{self, Async, Future, Stream, Sink, Poll, future, unsync, sync, stream}; use pnet::packet::ipv4::Ipv4Packet; +use socket2::{Socket, Domain, Type, SockAddr, Protocol}; use snow::{self, NoiseBuilder}; use tokio_core::net::{UdpSocket, UdpCodec, UdpFramed}; use tokio_core::reactor::Handle; @@ -25,12 +26,27 @@ impl UdpCodec for VecUdpCodec { type Out = PeerServerMessage; fn decode(&mut self, src: &SocketAddr, buf: &[u8]) -> io::Result<Self::In> { - Ok((*src, buf.to_vec())) + let unmapped_ip = match src.ip() { + IpAddr::V6(v6addr) => { + if let Some(v4addr) = v6addr.to_ipv4() { + IpAddr::V4(v4addr) + } else { + IpAddr::V6(v6addr) + } + } + v4addr => v4addr + }; + Ok((SocketAddr::new(unmapped_ip, src.port()), buf.to_vec())) } fn encode(&mut self, msg: Self::Out, buf: &mut Vec<u8>) -> SocketAddr { - let (addr, mut data) = msg; + let (mut addr, mut data) = msg; buf.append(&mut data); + let mapped_ip = match addr.ip() { + IpAddr::V4(v4addr) => IpAddr::V6(v4addr.to_ipv6_mapped()), + v6addr => v6addr.clone() + }; + addr.set_ip(mapped_ip); addr } } @@ -56,7 +72,11 @@ pub struct PeerServer { impl PeerServer { pub fn bind(handle: Handle, shared_state: SharedState, tunnel_tx: unsync::mpsc::Sender<Vec<u8>>) -> Self { - let socket = UdpSocket::bind(&([0,0,0,0], 0).into(), &handle.clone()).unwrap(); + let socket = Socket::new(Domain::ipv6(), Type::dgram(), Some(Protocol::udp())).unwrap(); + socket.set_only_v6(false).unwrap(); + socket.set_nonblocking(true).unwrap(); + socket.bind(&SocketAddr::from((Ipv6Addr::unspecified(), 0)).into()).unwrap(); + let socket = UdpSocket::from_socket(socket.into_udp_socket(), &handle.clone()).unwrap(); let (udp_sink, udp_stream) = socket.framed(VecUdpCodec{}).split(); let (timer_tx, timer_rx) = unsync::mpsc::channel::<TimerMessage>(1024); let (udp_tx, udp_rx) = unsync::mpsc::channel::<(SocketAddr, Vec<u8>)>(1024); @@ -66,7 +86,7 @@ impl PeerServer { let udp_write_passthrough = udp_sink.sink_map_err(|_| ()).send_all( udp_rx.map(|(addr, packet)| { - debug!("sending UDP packet to {:?}", &addr); + trace!("sending UDP packet to {:?}", &addr); (addr, packet) }).map_err(|_| ())) .then(|_| Ok(())); @@ -87,7 +107,7 @@ impl PeerServer { // TODO: create a transport packet (type 0x4) queue until a handshake has been completed fn handle_incoming_packet(&mut self, addr: SocketAddr, packet: Vec<u8>) { - debug!("got a UDP packet of length {}, packet type {}", packet.len(), packet[0]); + debug!("got a UDP packet from {:?} of length {}, packet type {}", &addr, packet.len(), packet[0]); let mut state = self.shared_state.borrow_mut(); match packet[0] { 1 => { @@ -211,7 +231,7 @@ impl PeerServer { if let Ok(payload_len) = res { raw_packet.truncate(payload_len); - debug_packet("received TRANSPORT: ", &raw_packet); + trace_packet("received TRANSPORT: ", &raw_packet); self.handle.spawn(self.tunnel_tx.clone().send(raw_packet) .then(|_| Ok(()))); } else { @@ -271,7 +291,7 @@ impl PeerServer { Ok(Async::Ready(None)) | Err(_) => return Err(()), }; - debug_packet("received UTUN packet: ", &packet); + trace_packet("received UTUN packet: ", &packet); let state = self.shared_state.borrow(); let mut out_packet = vec![0u8; 1500]; let destination = Ipv4Packet::new(&packet).unwrap().get_destination(); diff --git a/src/main.rs b/src/main.rs index 5c16224..88371b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +#![feature(ip_constructors)] #![allow(unused_imports)] #[macro_use] extern crate error_chain; @@ -16,6 +17,7 @@ extern crate nix; extern crate pnet; extern crate rand; extern crate snow; +extern crate socket2; extern crate structopt; extern crate time; extern crate tokio_core; |