aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJake McGinty <me@jake.su>2018-02-05 15:54:26 +0000
committerJake McGinty <me@jake.su>2018-02-05 15:54:26 +0000
commitda0fef8beecacc186d9d9c95e7914f975dc4b364 (patch)
tree90b76e0489a34c1a190d2e031f3d0c97f93148d3 /src
parentmake the fallback-session code a bit more canonical rust (diff)
downloadwireguard-rs-da0fef8beecacc186d9d9c95e7914f975dc4b364.tar.xz
wireguard-rs-da0fef8beecacc186d9d9c95e7914f975dc4b364.zip
use dual-stack ipv6 UDP socket
Diffstat (limited to 'src')
-rw-r--r--src/interface/mod.rs7
-rw-r--r--src/interface/peer_server.rs38
-rw-r--r--src/main.rs2
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;