aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJake McGinty <me@jake.su>2018-04-11 03:05:39 -0700
committerJake McGinty <me@jake.su>2018-04-11 03:05:39 -0700
commit94d936f42ef368fbc76ec84fffa576c6820e5291 (patch)
tree8b4bc7d909cfadbe254ea5c43431e8442913d9b2
parenttests: add little sleep when setting up interfaces (diff)
downloadwireguard-rs-94d936f42ef368fbc76ec84fffa576c6820e5291.tar.xz
wireguard-rs-94d936f42ef368fbc76ec84fffa576c6820e5291.zip
udp: set IPV6_RECVPKTINFO sockopt (darwin)
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml1
-rw-r--r--src/lib.rs1
-rw-r--r--src/udp/mod.rs37
4 files changed, 38 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a06144a..a852d8d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1491,6 +1491,7 @@ dependencies = [
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.11.0-pre (git+https://github.com/nix-rust/nix)",
diff --git a/Cargo.toml b/Cargo.toml
index c13451f..218c917 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -38,6 +38,7 @@ derive_deref = "^1.0"
failure = "^0.1"
futures = "^0.1"
lazy_static = "^1"
+libc = "^0.2"
log = "^0.4"
hex = "^0.3"
notify = "4.0.0"
diff --git a/src/lib.rs b/src/lib.rs
index a693518..d39ba78 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -20,6 +20,7 @@ extern crate byteorder;
extern crate bytes;
extern crate chacha20_poly1305_aead;
extern crate hex;
+extern crate libc;
extern crate mio;
extern crate nix;
extern crate notify;
diff --git a/src/udp/mod.rs b/src/udp/mod.rs
index 4916e31..f75a05d 100644
--- a/src/udp/mod.rs
+++ b/src/udp/mod.rs
@@ -1,11 +1,14 @@
#![allow(unused)]
-use std::io;
+use std::{fmt, io, mem};
use std::net::{self, SocketAddr, Ipv4Addr, Ipv6Addr};
-use std::fmt;
+use std::os::unix::io::AsRawFd;
use futures::{Async, Future, Poll};
+use libc;
use mio;
+use nix::{self, errno::Errno};
+use nix::sys::{uio::IoVec, socket::{CmsgSpace, MsgFlags, SockAddr, recvmsg}};
use socket2::{Socket, Domain, Type, Protocol};
use tokio_core::reactor::{Handle, PollEvented};
@@ -16,6 +19,22 @@ pub struct UdpSocket {
handle: Handle,
}
+/// IPV6_RECVPKTINFO is missing from the libc crate. Value taken from https://git.io/vxNel.
+pub const IPV6_RECVPKTINFO: i32 = 61;
+
+/*
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr; /* src/dst IPv6 address */
+ unsigned int ipi6_ifindex; /* send/recv interface index */
+};
+*/
+
+#[repr(C)]
+struct in6_pktinfo {
+ ipi6_addr : libc::in6_addr,
+ ipi6_ifindex : libc::c_uint
+}
+
mod frame;
pub use self::frame::{UdpChannel, UdpFramed, VecUdpCodec, PeerServerMessage};
@@ -40,6 +59,20 @@ impl UdpSocket {
socket.set_only_v6(false)?;
socket.set_nonblocking(true)?;
socket.set_reuse_port(true)?;
+
+ unsafe {
+ let optval: libc::c_int = 1;
+ let ret = libc::setsockopt(socket.as_raw_fd(),
+ libc::IPPROTO_IPV6,
+ IPV6_RECVPKTINFO,
+ &optval as *const _ as *const libc::c_void,
+ mem::size_of_val(&optval) as libc::socklen_t);
+ if ret != 0 {
+ let err: Result<(), _> = Err(io::Error::last_os_error());
+ err.expect("setsockopt failed");
+ }
+ }
+
socket.bind(&addr.into())?;
Self::from_socket(socket.into_udp_socket(), handle)
}