aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJake McGinty <me@jake.su>2018-04-13 21:02:53 -0700
committerJake McGinty <me@jake.su>2018-04-22 14:08:48 -0700
commitc713d75d0d616f1f6e2662396bd49e272fb0e5a7 (patch)
treeeda121e90c685d2a227fd9b3cb79d88248fc6fe4 /src
parentudp: dual-stack single socket -> dual socket (diff)
downloadwireguard-rs-c713d75d0d616f1f6e2662396bd49e272fb0e5a7.tar.xz
wireguard-rs-c713d75d0d616f1f6e2662396bd49e272fb0e5a7.zip
udp: parse in(6)_pktinfo cmsgs
Diffstat (limited to 'src')
-rw-r--r--src/udp/frame.rs17
-rw-r--r--src/udp/mod.rs43
2 files changed, 25 insertions, 35 deletions
diff --git a/src/udp/frame.rs b/src/udp/frame.rs
index f04b004..e8f3b69 100644
--- a/src/udp/frame.rs
+++ b/src/udp/frame.rs
@@ -140,27 +140,12 @@ pub type PeerServerMessage = (SocketAddr, Vec<u8>);
pub struct VecUdpCodec;
impl VecUdpCodec {
fn decode(&mut self, src: &SocketAddr, buf: &[u8]) -> io::Result<PeerServerMessage> {
- let unmapped_ip = match src.ip() {
- IpAddr::V6(v6addr) => {
- if let Some(v4addr) = v6_mapped_to_v4(v6addr) {
- IpAddr::V4(v4addr)
- } else {
- IpAddr::V6(v6addr)
- }
- }
- v4addr => v4addr
- };
- Ok((SocketAddr::new(unmapped_ip, src.port()), buf.to_vec()))
+ Ok((*src, buf.to_vec()))
}
fn encode(&mut self, msg: PeerServerMessage, buf: &mut Vec<u8>) -> SocketAddr {
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
- };
- addr.set_ip(mapped_ip);
addr
}
}
diff --git a/src/udp/mod.rs b/src/udp/mod.rs
index 30a0e0d..d54b726 100644
--- a/src/udp/mod.rs
+++ b/src/udp/mod.rs
@@ -23,7 +23,6 @@ pub struct UdpSocket {
/// 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;
-pub const IP_RECVDSTADDR : i32 = 7;
#[repr(C)]
struct in6_pktinfo {
@@ -46,20 +45,19 @@ impl UdpSocket {
let socket4 = Socket::new(Domain::ipv4(), Type::dgram(), Some(Protocol::udp()))?;
let socket6 = Socket::new(Domain::ipv6(), Type::dgram(), Some(Protocol::udp()))?;
- let off: libc::c_int = 0;
let on: libc::c_int = 1;
-// unsafe {
-// let ret = libc::setsockopt(socket.as_raw_fd(),
-// libc::IPPROTO_IP,
-// 3,
-// &off as *const _ as *const libc::c_void,
-// mem::size_of_val(&off) as libc::socklen_t);
-// if ret != 0 {
-// let err: Result<(), _> = Err(io::Error::last_os_error());
-// err.expect("setsockopt failed");
-// }
-// debug!("set IP_PKTINFO");
-// }
+ unsafe {
+ let ret = libc::setsockopt(socket4.as_raw_fd(),
+ libc::IPPROTO_IP,
+ IP_PKTINFO,
+ &on as *const _ as *const libc::c_void,
+ mem::size_of_val(&on) as libc::socklen_t);
+ if ret != 0 {
+ let err: Result<(), _> = Err(io::Error::last_os_error());
+ err.expect("setsockopt failed");
+ }
+ debug!("set IP_PKTINFO");
+ }
unsafe {
let ret = libc::setsockopt(socket6.as_raw_fd(),
@@ -75,9 +73,11 @@ impl UdpSocket {
debug!("set IPV6_PKTINFO");
}
+ socket4.set_nonblocking(true)?;
+ socket4.set_reuse_address(true)?;
+
socket6.set_only_v6(true)?;
socket6.set_nonblocking(true)?;
- socket6.set_reuse_port(true)?;
socket6.set_reuse_address(true)?;
socket4.bind(&SocketAddrV4::new(Ipv4Addr::unspecified(), port).into())?;
@@ -143,6 +143,8 @@ impl UdpSocket {
if let Async::NotReady = io.poll_write() {
return Err(io::ErrorKind::WouldBlock.into())
}
+
+ debug!("sending udp to {:?}", target);
match io.get_ref().send_to(buf, target) {
Ok(n) => Ok(n),
Err(e) => {
@@ -173,10 +175,13 @@ impl UdpSocket {
Ok(msg) => {
for cmsg in msg.cmsgs() {
match cmsg {
- ControlMessage::Unknown(_) => {
- debug!("unknown cmsg");
- }
- _ => debug!("known cmsg")
+ ControlMessage::Ipv4PacketInfo(_) => {
+ debug!("ipv4 cmsg");
+ },
+ ControlMessage::Ipv6PacketInfo(_) => {
+ debug!("ipv6 cmsg");
+ },
+ _ => debug!("unknown cmsg")
}
}
if let Some(SockAddr::Inet(addr)) = msg.address {