diff options
author | Jake McGinty <me@jake.su> | 2018-04-16 18:43:52 -0700 |
---|---|---|
committer | Jake McGinty <me@jake.su> | 2018-04-22 14:08:41 -0700 |
commit | 0cc9ecc94a31ecca99c334c1b06df70f650ec82b (patch) | |
tree | 1f429f220a5888b79596f82dc3a63f45454eed13 /src | |
parent | udp: return back "magic" endpoint in recv_from (diff) | |
download | wireguard-rs-0cc9ecc94a31ecca99c334c1b06df70f650ec82b.tar.xz wireguard-rs-0cc9ecc94a31ecca99c334c1b06df70f650ec82b.zip |
global: SocketAddr -> Endpoint
Diffstat (limited to 'src')
-rw-r--r-- | src/interface/config.rs | 4 | ||||
-rw-r--r-- | src/interface/peer_server.rs | 14 | ||||
-rw-r--r-- | src/peer.rs | 11 | ||||
-rw-r--r-- | src/types.rs | 3 | ||||
-rw-r--r-- | src/udp/frame.rs | 12 | ||||
-rw-r--r-- | src/udp/mod.rs | 29 |
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")) |