diff options
author | Jake McGinty <me@jake.su> | 2018-02-05 15:54:26 +0000 |
---|---|---|
committer | Jake McGinty <me@jake.su> | 2018-02-05 15:54:26 +0000 |
commit | da0fef8beecacc186d9d9c95e7914f975dc4b364 (patch) | |
tree | 90b76e0489a34c1a190d2e031f3d0c97f93148d3 /src | |
parent | make the fallback-session code a bit more canonical rust (diff) | |
download | wireguard-rs-da0fef8beecacc186d9d9c95e7914f975dc4b364.tar.xz wireguard-rs-da0fef8beecacc186d9d9c95e7914f975dc4b364.zip |
use dual-stack ipv6 UDP socket
Diffstat (limited to 'src')
-rw-r--r-- | src/interface/mod.rs | 7 | ||||
-rw-r--r-- | src/interface/peer_server.rs | 38 | ||||
-rw-r--r-- | src/main.rs | 2 |
3 files changed, 35 insertions, 12 deletions
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; |