aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock12
-rw-r--r--Cargo.toml2
-rw-r--r--src/interface/mod.rs7
-rw-r--r--src/interface/peer_server.rs38
-rw-r--r--src/main.rs2
5 files changed, 49 insertions, 12 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ee4336d..65aba56 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index e751158..b1c0e94 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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;