aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJake McGinty <me@jake.su>2018-04-16 18:43:52 -0700
committerJake McGinty <me@jake.su>2018-04-22 14:08:41 -0700
commit0cc9ecc94a31ecca99c334c1b06df70f650ec82b (patch)
tree1f429f220a5888b79596f82dc3a63f45454eed13 /src
parentudp: return back "magic" endpoint in recv_from (diff)
downloadwireguard-rs-0cc9ecc94a31ecca99c334c1b06df70f650ec82b.tar.xz
wireguard-rs-0cc9ecc94a31ecca99c334c1b06df70f650ec82b.zip
global: SocketAddr -> Endpoint
Diffstat (limited to 'src')
-rw-r--r--src/interface/config.rs4
-rw-r--r--src/interface/peer_server.rs14
-rw-r--r--src/peer.rs11
-rw-r--r--src/types.rs3
-rw-r--r--src/udp/frame.rs12
-rw-r--r--src/udp/mod.rs29
6 files changed, 44 insertions, 29 deletions
diff --git a/src/interface/config.rs b/src/interface/config.rs
index c40be20..574876d 100644
--- a/src/interface/config.rs
+++ b/src/interface/config.rs
@@ -12,10 +12,12 @@ use hex;
use interface::{SharedState, State};
use interface::grim_reaper::GrimReaper;
use peer::Peer;
+use std::net::SocketAddr;
use std::{cell::RefCell, iter::Iterator, rc::Rc, mem, str};
use std::fs::{create_dir, remove_file};
use std::path::{Path, PathBuf};
use tokio_core::reactor::Handle;
+use udp::Endpoint;
use types::PeerInfo;
use hex::FromHex;
use x25519_dalek as x25519;
@@ -56,7 +58,7 @@ impl UpdateEvent {
"replace_peers" => { events.push(UpdateEvent::RemoveAllPeers); },
"preshared_key" => { info.psk = Some(<[u8; 32]>::from_hex(&value)?); },
"persistent_keepalive_interval" => { info.keepalive = Some(value.parse()?); },
- "endpoint" => { info.endpoint = Some(value.parse()?); },
+ "endpoint" => { info.endpoint = Some(value.parse::<SocketAddr>()?.into()); },
"replace_allowed_ips" => { replace_allowed_ips = true; },
"remove" => { remove_pending_peer = true; },
"public_key" => {
diff --git a/src/interface/peer_server.rs b/src/interface/peer_server.rs
index 2b05b94..9f680fd 100644
--- a/src/interface/peer_server.rs
+++ b/src/interface/peer_server.rs
@@ -15,7 +15,7 @@ use byteorder::{ByteOrder, LittleEndian};
use failure::{Error, err_msg};
use futures::{Async, Future, Stream, Sink, Poll, unsync::mpsc};
use rand::{self, Rng};
-use udp::{UdpSocket, PeerServerMessage, UdpChannel};
+use udp::{Endpoint, UdpSocket, PeerServerMessage, UdpChannel};
use tokio_core::reactor::Handle;
struct Channel<T> {
@@ -110,7 +110,7 @@ impl PeerServer {
}
}
- fn handle_ingress_packet(&mut self, addr: SocketAddr, packet: Vec<u8>) -> Result<(), Error> {
+ fn handle_ingress_packet(&mut self, addr: Endpoint, packet: Vec<u8>) -> Result<(), Error> {
trace!("got a UDP packet from {:?} of length {}, packet type {}", &addr, packet.len(), packet[0]);
match packet.try_into()? {
@@ -121,7 +121,7 @@ impl PeerServer {
}
}
- fn handle_ingress_handshake_init(&mut self, addr: SocketAddr, packet: &Initiation) -> Result<(), Error> {
+ fn handle_ingress_handshake_init(&mut self, addr: Endpoint, packet: &Initiation) -> Result<(), Error> {
ensure!(packet.len() == 148, "handshake init packet length is incorrect");
let mut state = self.shared_state.borrow_mut();
{
@@ -139,7 +139,7 @@ impl PeerServer {
.ok_or_else(|| err_msg("unknown peer pubkey"))?.clone();
let index = Self::unused_index(&mut state);
- let (response, dead_index) = peer_ref.borrow_mut().complete_incoming_handshake(addr, index, handshake)?;
+ let (response, dead_index) = peer_ref.borrow_mut().complete_incoming_handshake(addr.clone(), index, handshake)?;
if let Some(index) = dead_index {
let _ = state.index_map.remove(&index);
}
@@ -152,7 +152,7 @@ impl PeerServer {
}
// TODO use the address to update endpoint if it changes i suppose
- fn handle_ingress_handshake_resp(&mut self, addr: SocketAddr, packet: &Response) -> Result<(), Error> {
+ fn handle_ingress_handshake_resp(&mut self, addr: Endpoint, packet: &Response) -> Result<(), Error> {
ensure!(packet.len() == 92, "handshake resp packet length is incorrect");
let mut state = self.shared_state.borrow_mut();
{
@@ -200,7 +200,7 @@ impl PeerServer {
Ok(())
}
- fn handle_ingress_cookie_reply(&mut self, _addr: SocketAddr, packet: &CookieReply) -> Result<(), Error> {
+ fn handle_ingress_cookie_reply(&mut self, _addr: Endpoint, packet: &CookieReply) -> Result<(), Error> {
let state = self.shared_state.borrow_mut();
let peer_ref = state.index_map.get(&packet.our_index()).ok_or_else(|| err_msg("unknown our_index"))?.clone();
let mut peer = peer_ref.borrow_mut();
@@ -208,7 +208,7 @@ impl PeerServer {
peer.consume_cookie_reply(packet)
}
- fn handle_ingress_transport(&mut self, addr: SocketAddr, packet: &Transport) -> Result<(), Error> {
+ fn handle_ingress_transport(&mut self, addr: Endpoint, packet: &Transport) -> Result<(), Error> {
let peer_ref = self.shared_state.borrow().index_map.get(&packet.our_index())
.ok_or_else(|| err_msg("unknown our_index"))?.clone();
diff --git a/src/peer.rs b/src/peer.rs
index 9aaf422..a7ee5f7 100644
--- a/src/peer.rs
+++ b/src/peer.rs
@@ -18,6 +18,7 @@ use hex;
use time::{Tai64n, Timestamp};
use snow;
use types::PeerInfo;
+use udp::Endpoint;
pub struct Peer {
pub info : PeerInfo,
@@ -218,7 +219,7 @@ impl Peer {
indices
}
- pub fn initiate_new_session(&mut self, private_key: &[u8], index: u32) -> Result<(SocketAddr, Vec<u8>, Option<u32>), Error> {
+ pub fn initiate_new_session(&mut self, private_key: &[u8], index: u32) -> Result<(Endpoint, Vec<u8>, Option<u32>), Error> {
let noise = noise::build_initiator(private_key, &self.info.pub_key, &self.info.psk)?;
let mut session = Session::new(noise, index);
let endpoint = self.info.endpoint.ok_or_else(|| err_msg("no known peer endpoint"))?;
@@ -260,7 +261,7 @@ impl Peer {
/// and generates a response.
///
/// Returns: the response packet (type 0x02), and an optional dead session index that was removed.
- pub fn complete_incoming_handshake(&mut self, addr: SocketAddr, index: u32, incomplete: IncompleteIncomingHandshake) -> Result<(Vec<u8>, Option<u32>), Error> {
+ pub fn complete_incoming_handshake(&mut self, addr: Endpoint, index: u32, incomplete: IncompleteIncomingHandshake) -> Result<(Vec<u8>, Option<u32>), Error> {
let IncompleteIncomingHandshake { timestamp, their_index, mut noise } = incomplete;
if let Some(ref last_tai64n) = self.last_handshake_tai64n {
@@ -312,7 +313,7 @@ impl Peer {
self.cookie.consume_reply(reply)
}
- pub fn process_incoming_handshake_response(&mut self, addr: SocketAddr, packet: &Response) -> Result<Option<u32>, Error> {
+ pub fn process_incoming_handshake_response(&mut self, addr: Endpoint, packet: &Response) -> Result<Option<u32>, Error> {
let mut session = mem::replace(&mut self.sessions.next, None).ok_or_else(|| err_msg("no next session"))?;
let _ = session.noise.read_message(packet.noise_bytes(), &mut [])?;
session = session.into_transport_mode()?;
@@ -327,7 +328,7 @@ impl Peer {
Ok(dead.map(|session| session.our_index))
}
- pub fn handle_incoming_transport(&mut self, addr: SocketAddr, packet: &Transport)
+ pub fn handle_incoming_transport(&mut self, addr: Endpoint, packet: &Transport)
-> Result<(Vec<u8>, SessionTransition), Error> {
let mut raw_packet = vec![0u8; packet.len()];
@@ -376,7 +377,7 @@ impl Peer {
Ok((raw_packet, transition))
}
- pub fn handle_outgoing_transport(&mut self, packet: &[u8]) -> Result<(SocketAddr, Vec<u8>), Error> {
+ pub fn handle_outgoing_transport(&mut self, packet: &[u8]) -> Result<(Endpoint, Vec<u8>), Error> {
let session = self.sessions.current.as_mut().ok_or_else(|| err_msg("no current noise session"))?;
let endpoint = self.info.endpoint.ok_or_else(|| err_msg("no known peer endpoint"))?;
let padding = PADDING_MULTIPLE - (packet.len() % PADDING_MULTIPLE);
diff --git a/src/types.rs b/src/types.rs
index 9f2597b..cc65105 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,12 +1,13 @@
use base64;
use std::fmt::{self, Display, Formatter};
use std::net::{IpAddr, SocketAddr};
+use udp::Endpoint;
#[derive(Clone, Debug, Default)]
pub struct PeerInfo {
pub pub_key: [u8; 32],
pub psk: Option<[u8; 32]>,
- pub endpoint: Option<SocketAddr>,
+ pub endpoint: Option<Endpoint>,
pub allowed_ips: Vec<(IpAddr, u32)>,
pub keepalive: Option<u16>,
}
diff --git a/src/udp/frame.rs b/src/udp/frame.rs
index e8f3b69..239a58d 100644
--- a/src/udp/frame.rs
+++ b/src/udp/frame.rs
@@ -5,7 +5,7 @@ use std::os::unix::io::{AsRawFd, RawFd};
use failure::Error;
use futures::{Async, Future, Poll, Stream, Sink, StartSend, AsyncSink, future, stream, unsync::mpsc};
use nix::sys::socket::{sockopt, setsockopt};
-use udp::UdpSocket;
+use udp::{Endpoint, UdpSocket};
use tokio_core::reactor::Handle;
use std::net::Ipv6Addr;
@@ -20,7 +20,7 @@ pub struct UdpFramed {
codec: VecUdpCodec,
rd: Vec<u8>,
wr: Vec<u8>,
- out_addr: SocketAddr,
+ out_addr: Endpoint,
flushed: bool,
}
@@ -89,7 +89,7 @@ pub fn new(socket: UdpSocket) -> UdpFramed {
UdpFramed {
socket,
codec: VecUdpCodec {},
- out_addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)),
+ out_addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)).into(),
rd: vec![0; 64 * 1024],
wr: Vec::with_capacity(8 * 1024),
flushed: true,
@@ -136,14 +136,14 @@ fn v6_mapped_to_v4(addr: Ipv6Addr) -> Option<Ipv4Addr> {
}
}
-pub type PeerServerMessage = (SocketAddr, Vec<u8>);
+pub type PeerServerMessage = (Endpoint, Vec<u8>);
pub struct VecUdpCodec;
impl VecUdpCodec {
- fn decode(&mut self, src: &SocketAddr, buf: &[u8]) -> io::Result<PeerServerMessage> {
+ fn decode(&mut self, src: &Endpoint, buf: &[u8]) -> io::Result<PeerServerMessage> {
Ok((*src, buf.to_vec()))
}
- fn encode(&mut self, msg: PeerServerMessage, buf: &mut Vec<u8>) -> SocketAddr {
+ fn encode(&mut self, msg: PeerServerMessage, buf: &mut Vec<u8>) -> Endpoint {
let (mut addr, mut data) = msg;
buf.append(&mut data);
addr
diff --git a/src/udp/mod.rs b/src/udp/mod.rs
index b6b6799..b6bca9e 100644
--- a/src/udp/mod.rs
+++ b/src/udp/mod.rs
@@ -23,6 +23,10 @@ use socket2::{Socket, Domain, Type, Protocol};
use tokio_core::reactor::{Handle, PollEvented};
+mod frame;
+pub use self::frame::{UdpChannel, UdpFramed, VecUdpCodec, PeerServerMessage};
+use std::ops::Deref;
+
/// An I/O object representing a UDP socket.
pub struct UdpSocket {
io4: PollEvented<mio::net::UdpSocket>,
@@ -30,9 +34,10 @@ pub struct UdpSocket {
handle: Handle,
}
+#[derive(Clone, Copy, Debug)]
pub struct Endpoint {
pub addr: SocketAddr,
- pub pktinfo: PktInfo,
+ pub pktinfo: Option<PktInfo>,
}
impl Deref for Endpoint {
@@ -43,19 +48,25 @@ impl Deref for Endpoint {
}
}
+impl From<SocketAddr> for Endpoint {
+ fn from(addr: SocketAddr) -> Self {
+ Endpoint {
+ addr,
+ pktinfo: None
+ }
+ }
+}
+
/// IPV6_RECVPKTINFO is missing from the libc crate. Value taken from https://git.io/vxNel.
pub const IPV6_RECVPKTINFO : i32 = 61;
pub const IP_PKTINFO : i32 = 26;
+#[derive(Clone, Copy, Debug)]
pub enum PktInfo {
V4(in_pktinfo),
V6(in6_pktinfo),
}
-mod frame;
-pub use self::frame::{UdpChannel, UdpFramed, VecUdpCodec, PeerServerMessage};
-use std::ops::Deref;
-
impl UdpSocket {
pub fn bind(port: u16, handle: Handle) -> io::Result<UdpSocket> {
let socket4 = Socket::new(Domain::ipv4(), Type::dgram(), Some(Protocol::udp()))?;
@@ -154,7 +165,7 @@ impl UdpSocket {
///
/// Address type can be any implementer of `ToSocketAddrs` trait. See its
/// documentation for concrete examples.
- pub fn send_to(&self, buf: &[u8], target: &SocketAddr) -> io::Result<usize> {
+ pub fn send_to(&self, buf: &[u8], target: &Endpoint) -> io::Result<usize> {
let io = self.get_io(target);
if let Async::NotReady = io.poll_write() {
return Err(io::ErrorKind::WouldBlock.into())
@@ -197,16 +208,16 @@ impl UdpSocket {
info.ipi_ifindex);
Ok((msg.bytes, Endpoint {
addr: addr.to_std(),
- pktinfo: PktInfo::V4(info.clone())
+ pktinfo: Some(PktInfo::V4(info.clone()))
}))
},
Some(ControlMessage::Ipv6PacketInfo(info)) => {
trace!("ipv6 cmsg (\n ipi6_addr: {:?},\n ipi6_ifindex: {}\n)",
- Ipv6Addr::from(info.ipi6_addr.s6_addr),
+ Ipv6Addr::from(info.ipi6_addr),
info.ipi6_ifindex);
Ok((msg.bytes, Endpoint {
addr: addr.to_std(),
- pktinfo: PktInfo::V6(info.clone())
+ pktinfo: Some(PktInfo::V6(info.clone()))
}))
},
_ => Err(io::Error::new(io::ErrorKind::Other, "missing pktinfo"))