aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2021-01-11 22:08:05 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-01-11 22:08:05 +0000
commitc0e79347ee459d10ccd1c5b336955c5e6b894f69 (patch)
treea101b157e865fd1669dc9e122b0adddb7ce94978
parent566a3612a54480ba74fca12e0da1468464560a10 (diff)
parent597a11b6e4cb4a0ffa556ab81904440c6f8b3783 (diff)
downloadmio-c0e79347ee459d10ccd1c5b336955c5e6b894f69.tar.gz
Upgrade rust/crates/mio to 0.7.7 am: 0cb7a8f313 am: 68512db9b4 am: 597a11b6e4
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/mio/+/1541459 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Icb53fd16a142347c5b46cd13e74c89d032c9d1e5
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp2
-rw-r--r--CHANGELOG.md60
-rw-r--r--Cargo.lock20
-rw-r--r--Cargo.toml7
-rw-r--r--Cargo.toml.orig23
-rw-r--r--METADATA10
-rw-r--r--src/event/event.rs5
-rw-r--r--src/lib.rs2
-rw-r--r--src/net/tcp/socket.rs3
-rw-r--r--src/net/udp.rs6
-rw-r--r--src/poll.rs11
-rw-r--r--src/sys/shell/tcp.rs12
-rw-r--r--src/sys/shell/udp.rs4
-rw-r--r--src/sys/unix/pipe.rs49
-rw-r--r--src/sys/unix/udp.rs18
-rw-r--r--src/sys/unix/uds/socketaddr.rs4
-rw-r--r--src/sys/unix/waker.rs6
-rw-r--r--src/sys/windows/event.rs1
-rw-r--r--src/sys/windows/udp.rs30
20 files changed, 237 insertions, 38 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 7fefbd3..5454293 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
{
"git": {
- "sha1": "e6e403fe2a4fc14dfbc74dbb3ae3a14e3044eb6f"
+ "sha1": "0fef0d61ade20be45eb670eb3786af0e06e59f63"
}
}
diff --git a/Android.bp b/Android.bp
index 825e135..6cc4e23 100644
--- a/Android.bp
+++ b/Android.bp
@@ -28,5 +28,5 @@ rust_library {
// dependent_library ["feature_list"]
// cfg-if-0.1.10
-// libc-0.2.80 "align,default,std"
+// libc-0.2.81 "align,default,std"
// log-0.4.11 "std"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f024bfb..9e5059c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,33 @@
+# 0.7.7
+
+## Added
+
+* `UdpSocket::only_v6`
+ (https://github.com/tokio-rs/mio/commit/0101e05a800f17fb88f4315d9b9fe0f08cca6e57).
+* `Clone` implementation for `Event`
+ (https://github.com/tokio-rs/mio/commit/26540ebbae89df6d4d08465c56f715d8f2addfc3).
+* `AsRawFd` implementation for `Registry`
+ (https://github.com/tokio-rs/mio/commit/f70daa72da0042b1880256164774c3286d315a02).
+* `Read` and `Write` implementation for `&unix::pipe::Sender` and `Receiver`,
+ that is on the reference to them, an implementation existed on the types
+ themselves already
+ (https://github.com/tokio-rs/mio/commit/1be481dcbbcb6906364008b5d61e7f53cddc3eb3).
+
+
+## Fixes
+
+* Underflow in `SocketAddr::address`
+ (https://github.com/tokio-rs/mio/commit/6d3fa69240cd4bb95e9d34605c660c30245a18bd).
+* Android build with the net feature enabled, but with os-poll disabled
+ (https://github.com/tokio-rs/mio/commit/49d8fd33e026ad6e2c055d05d6667180ba2af7be).
+* Solaris build with the net feature enabled, but with os-poll disabled
+ (https://github.com/tokio-rs/mio/commit/a6e025e9d9511639ec106ebedc0dd312bdc9be12).
+* Ensure that `Waker::wake` works on illumos systems with poor `pipe(2)` and
+ `epoll(2)` interaction using `EPOLLET`
+ (https://github.com/tokio-rs/mio/commit/943d4249dcc17cd8b4d2250c4fa19116097248fa).
+* Fix `unix::pipe` on illumos
+ (https://github.com/tokio-rs/mio/commit/0db49f6d5caf54b12176821363d154384357e70a).
+
# 0.7.6
## Added
@@ -182,6 +212,36 @@ information.
* The `fmt::Debug` implementation of `Events` is now actually useful as it
prints all `Event`s.
+# 0.6.23 (Dec 01, 2020)
+
+### Changed
+- **MSRV**: Increased the MSRV from 1.18.0 (Jun 8, 2017) to 1.31.0 (Dec 6,
+ 2018)
+ (https://github.com/tokio-rs/mio/commit/4879e0d32ddfd98e762fc87240e594a3ad8fca30).
+
+### Fixed
+- Work around Linux kernel < 2.6.37 bug on 32-bits making timeouts longer then
+ ~30 minutes effectively infinite
+ (https://github.com/tokio-rs/mio/commit/e7cba59950e9c9fa6194e29b5b1e72029e3df455).
+- Update miow and net2 depedencies to get rid of invalid memory layout assumption
+ (https://github.com/tokio-rs/mio/commit/13f02ac0a86d7c0c0001e5ff8960a0b4340d075c).
+
+# 0.6.22 (May 01, 2020)
+
+### Added
+- Add support for illumos target (#1294)
+
+# 0.6.21 (November 27, 2019)
+
+### Fixed
+- remove `=` dependency on `cfg-if`.
+
+# 0.6.20 (November 21, 2019)
+
+### Fixed
+- Use default IOCP concurrency value (#1161).
+- setting FD_CLOEXEC in pipe (#1095).
+
# 0.6.19 (May 28, 2018)
### Fixed
diff --git a/Cargo.lock b/Cargo.lock
index 25ad6d6..6e36e56 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7,6 +7,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
name = "env_logger"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -23,9 +29,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "libc"
-version = "0.2.80"
+version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
+checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
[[package]]
name = "log"
@@ -33,12 +39,12 @@ version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
]
[[package]]
name = "mio"
-version = "0.7.6"
+version = "0.7.7"
dependencies = [
"env_logger",
"libc",
@@ -113,11 +119,11 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "socket2"
-version = "0.3.16"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fd8b795c389288baa5f355489c65e71fd48a02104600d15c4cfbc561e9e429d"
+checksum = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
"libc",
"redox_syscall",
"winapi",
diff --git a/Cargo.toml b/Cargo.toml
index 7f0d023..1115469 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,12 +13,12 @@
[package]
edition = "2018"
name = "mio"
-version = "0.7.6"
-authors = ["Carl Lerche <me@carllerche.com>"]
+version = "0.7.7"
+authors = ["Carl Lerche <me@carllerche.com>", "Thomas de Zeeuw <thomasdezeeuw@gmail.com>", "Tokio Contributors <team@tokio.rs>"]
include = ["Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md", "src/**/*.rs", "examples/**/*.rs"]
description = "Lightweight non-blocking IO"
homepage = "https://github.com/tokio-rs/mio"
-documentation = "https://docs.rs/mio/0.7.6"
+documentation = "https://docs.rs/mio/0.7.7"
readme = "README.md"
keywords = ["io", "async", "non-blocking"]
categories = ["asynchronous"]
@@ -27,6 +27,7 @@ repository = "https://github.com/tokio-rs/mio"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
+targets = ["aarch64-apple-ios", "aarch64-linux-android", "x86_64-apple-darwin", "x86_64-pc-windows-msvc", "x86_64-sun-solaris", "x86_64-unknown-dragonfly", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu", "x86_64-unknown-netbsd", "x86_64-unknown-openbsd"]
[package.metadata.playground]
features = ["os-poll", "os-ext", "net"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index e0937ed..e4158eb 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -6,11 +6,15 @@ name = "mio"
# - Update CHANGELOG.md.
# - Update doc URL.
# - Create git tag
-version = "0.7.6"
+version = "0.7.7"
license = "MIT"
-authors = ["Carl Lerche <me@carllerche.com>"]
+authors = [
+ "Carl Lerche <me@carllerche.com>",
+ "Thomas de Zeeuw <thomasdezeeuw@gmail.com>",
+ "Tokio Contributors <team@tokio.rs>",
+]
description = "Lightweight non-blocking IO"
-documentation = "https://docs.rs/mio/0.7.6"
+documentation = "https://docs.rs/mio/0.7.7"
homepage = "https://github.com/tokio-rs/mio"
repository = "https://github.com/tokio-rs/mio"
readme = "README.md"
@@ -63,6 +67,19 @@ rand = "0.4"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
+targets = [
+ "aarch64-apple-ios",
+ "aarch64-linux-android",
+ "x86_64-apple-darwin",
+ "x86_64-pc-windows-msvc",
+ "x86_64-sun-solaris",
+ "x86_64-unknown-dragonfly",
+ "x86_64-unknown-freebsd",
+ "x86_64-unknown-linux-gnu",
+ "x86_64-unknown-netbsd",
+ "x86_64-unknown-openbsd",
+]
+
[package.metadata.playground]
features = ["os-poll", "os-ext", "net"]
diff --git a/METADATA b/METADATA
index 54e4612..94c9d6c 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/mio/mio-0.7.6.crate"
+ value: "https://static.crates.io/crates/mio/mio-0.7.7.crate"
}
- version: "0.7.6"
+ version: "0.7.7"
license_type: NOTICE
last_upgrade_date {
- year: 2020
- month: 11
- day: 16
+ year: 2021
+ month: 1
+ day: 5
}
}
diff --git a/src/event/event.rs b/src/event/event.rs
index 959affd..9e4a95e 100644
--- a/src/event/event.rs
+++ b/src/event/event.rs
@@ -12,6 +12,7 @@ use std::fmt;
/// [`Poll::poll`]: ../struct.Poll.html#method.poll
/// [`Poll`]: ../struct.Poll.html
/// [`Token`]: ../struct.Token.html
+#[derive(Clone)]
#[repr(transparent)]
pub struct Event {
inner: sys::Event,
@@ -65,9 +66,9 @@ impl Event {
/// Read closed readiness can be expected after any of the following have
/// occurred:
/// * The local stream has shutdown the read half of its socket
- /// * The local stream has shtudown both the read half and the write half
+ /// * The local stream has shutdown both the read half and the write half
/// of its socket
- /// * The peer stream has shtudown the write half its socket; this sends a
+ /// * The peer stream has shutdown the write half its socket; this sends a
/// `FIN` packet that has been received by the local stream
///
/// Method is a best effort implementation. While some platforms may not
diff --git a/src/lib.rs b/src/lib.rs
index 1491a62..e815754 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,4 @@
-#![doc(html_root_url = "https://docs.rs/mio/0.7.6")]
+#![doc(html_root_url = "https://docs.rs/mio/0.7.7")]
#![deny(
missing_docs,
missing_debug_implementations,
diff --git a/src/net/tcp/socket.rs b/src/net/tcp/socket.rs
index 35a589c..69fbacf 100644
--- a/src/net/tcp/socket.rs
+++ b/src/net/tcp/socket.rs
@@ -218,7 +218,8 @@ impl TcpSocket {
/// be passed every time it is called.
///
/// # Examples
- /// ```
+ #[cfg_attr(feature = "os-poll", doc = "```")]
+ #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
/// use mio::net::{TcpSocket, TcpKeepalive};
/// use std::time::Duration;
///
diff --git a/src/net/udp.rs b/src/net/udp.rs
index 436b4cc..c5c3ba9 100644
--- a/src/net/udp.rs
+++ b/src/net/udp.rs
@@ -511,6 +511,12 @@ impl UdpSocket {
self.inner.leave_multicast_v6(multiaddr, interface)
}
+ /// Get the value of the `IPV6_V6ONLY` option on this socket.
+ #[allow(clippy::trivially_copy_pass_by_ref)]
+ pub fn only_v6(&self) -> io::Result<bool> {
+ sys::udp::only_v6(&self.inner)
+ }
+
/// Get the value of the `SO_ERROR` option on this socket.
///
/// This will retrieve the stored error in the underlying socket, clearing
diff --git a/src/poll.rs b/src/poll.rs
index b06f138..a6f4ab0 100644
--- a/src/poll.rs
+++ b/src/poll.rs
@@ -361,7 +361,7 @@ cfg_os_poll! {
#[cfg(unix)]
impl AsRawFd for Poll {
fn as_raw_fd(&self) -> RawFd {
- self.registry.selector.as_raw_fd()
+ self.registry.as_raw_fd()
}
}
@@ -528,7 +528,7 @@ impl Registry {
/// // the token is the same it must be specified.
/// poll.registry().reregister(
/// &mut socket,
- /// Token(2),
+ /// Token(0),
/// Interest::WRITABLE)?;
/// # Ok(())
/// # }
@@ -636,6 +636,13 @@ impl fmt::Debug for Registry {
}
}
+#[cfg(unix)]
+impl AsRawFd for Registry {
+ fn as_raw_fd(&self) -> RawFd {
+ self.selector.as_raw_fd()
+ }
+}
+
/// Get access to the `sys::Selector` from `Registry`.
pub(crate) fn selector(registry: &Registry) -> &sys::Selector {
&registry.selector
diff --git a/src/sys/shell/tcp.rs b/src/sys/shell/tcp.rs
index 2017bda..0ed225f 100644
--- a/src/sys/shell/tcp.rs
+++ b/src/sys/shell/tcp.rs
@@ -1,7 +1,7 @@
+use crate::net::TcpKeepalive;
use std::io;
use std::net::{self, SocketAddr};
use std::time::Duration;
-use crate::net::TcpKeepalive;
pub(crate) type TcpSocket = i32;
@@ -79,24 +79,18 @@ pub(crate) fn get_keepalive(_: TcpSocket) -> io::Result<bool> {
os_required!();
}
-#[cfg(any(
- target_os = "linux",
- target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "windows",
-))]
pub(crate) fn set_keepalive_params(_: TcpSocket, _: TcpKeepalive) -> io::Result<()> {
os_required!()
}
#[cfg(any(
+ target_os = "android",
target_os = "linux",
target_os = "macos",
target_os = "ios",
target_os = "freebsd",
target_os = "netbsd",
+ target_os = "solaris",
))]
pub(crate) fn get_keepalive_time(_: TcpSocket) -> io::Result<Option<Duration>> {
os_required!()
diff --git a/src/sys/shell/udp.rs b/src/sys/shell/udp.rs
index 3ff1625..48ccac7 100644
--- a/src/sys/shell/udp.rs
+++ b/src/sys/shell/udp.rs
@@ -4,3 +4,7 @@ use std::net::{self, SocketAddr};
pub fn bind(_: SocketAddr) -> io::Result<net::UdpSocket> {
os_required!()
}
+
+pub(crate) fn only_v6(_: &net::UdpSocket) -> io::Result<bool> {
+ os_required!()
+}
diff --git a/src/sys/unix/pipe.rs b/src/sys/unix/pipe.rs
index d838ebc..ccf5252 100644
--- a/src/sys/unix/pipe.rs
+++ b/src/sys/unix/pipe.rs
@@ -154,6 +154,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> {
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd",
+ target_os = "illumos",
))]
unsafe {
if libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC | libc::O_NONBLOCK) != 0 {
@@ -192,6 +193,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> {
target_os = "ios",
target_os = "macos",
target_os = "solaris",
+ target_os = "illumos",
)))]
compile_error!("unsupported target for `mio::unix::pipe`");
@@ -254,6 +256,20 @@ impl Write for Sender {
}
}
+impl Write for &Sender {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.inner.do_io(|sender| (&*sender).write(buf))
+ }
+
+ fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+ self.inner.do_io(|sender| (&*sender).write_vectored(bufs))
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.inner.do_io(|sender| (&*sender).flush())
+ }
+}
+
/// # Notes
///
/// The underlying pipe is **not** set to non-blocking.
@@ -333,6 +349,16 @@ impl Read for Receiver {
}
}
+impl Read for &Receiver {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ self.inner.do_io(|sender| (&*sender).read(buf))
+ }
+
+ fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+ self.inner.do_io(|sender| (&*sender).read_vectored(bufs))
+ }
+}
+
/// # Notes
///
/// The underlying pipe is **not** set to non-blocking.
@@ -373,6 +399,7 @@ impl IntoRawFd for Receiver {
}
}
+#[cfg(not(target_os = "illumos"))]
fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
let value = nonblocking as libc::c_int;
if unsafe { libc::ioctl(fd, libc::FIONBIO, &value) } == -1 {
@@ -381,3 +408,25 @@ fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
Ok(())
}
}
+
+#[cfg(target_os = "illumos")]
+fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
+ let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) };
+ if flags < 0 {
+ return Err(io::Error::last_os_error());
+ }
+
+ let nflags = if nonblocking {
+ flags | libc::O_NONBLOCK
+ } else {
+ flags & !libc::O_NONBLOCK
+ };
+
+ if flags != nflags {
+ if unsafe { libc::fcntl(fd, libc::F_SETFL, nflags) } < 0 {
+ return Err(io::Error::last_os_error());
+ }
+ }
+
+ Ok(())
+}
diff --git a/src/sys/unix/udp.rs b/src/sys/unix/udp.rs
index e9c4d4c..5a97cbd 100644
--- a/src/sys/unix/udp.rs
+++ b/src/sys/unix/udp.rs
@@ -1,8 +1,9 @@
use crate::sys::unix::net::{new_ip_socket, socket_addr};
use std::io;
+use std::mem;
use std::net::{self, SocketAddr};
-use std::os::unix::io::FromRawFd;
+use std::os::unix::io::{AsRawFd, FromRawFd};
pub fn bind(addr: SocketAddr) -> io::Result<net::UdpSocket> {
// Gives a warning for non Apple platforms.
@@ -21,3 +22,18 @@ pub fn bind(addr: SocketAddr) -> io::Result<net::UdpSocket> {
.map(|_| unsafe { net::UdpSocket::from_raw_fd(socket) })
})
}
+
+pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result<bool> {
+ let mut optval: libc::c_int = 0;
+ let mut optlen = mem::size_of::<libc::c_int>() as libc::socklen_t;
+
+ syscall!(getsockopt(
+ socket.as_raw_fd(),
+ libc::IPPROTO_IPV6,
+ libc::IPV6_V6ONLY,
+ &mut optval as *mut _ as *mut _,
+ &mut optlen,
+ ))?;
+
+ Ok(optval != 0)
+}
diff --git a/src/sys/unix/uds/socketaddr.rs b/src/sys/unix/uds/socketaddr.rs
index 31f8a51..a9f9ea9 100644
--- a/src/sys/unix/uds/socketaddr.rs
+++ b/src/sys/unix/uds/socketaddr.rs
@@ -28,6 +28,10 @@ enum AddressKind<'a> {
impl SocketAddr {
fn address(&self) -> AddressKind<'_> {
let offset = path_offset(&self.sockaddr);
+ // Don't underflow in `len` below.
+ if (self.socklen as usize) < offset {
+ return AddressKind::Unnamed;
+ }
let len = self.socklen as usize - offset;
let path = unsafe { &*(&self.sockaddr.sun_path as *const [libc::c_char] as *const [u8]) };
diff --git a/src/sys/unix/waker.rs b/src/sys/unix/waker.rs
index 1305bd6..a7cf484 100644
--- a/src/sys/unix/waker.rs
+++ b/src/sys/unix/waker.rs
@@ -137,6 +137,12 @@ mod pipe {
}
pub fn wake(&self) -> io::Result<()> {
+ // The epoll emulation on some illumos systems currently requires
+ // the pipe buffer to be completely empty for an edge-triggered
+ // wakeup on the pipe read side.
+ #[cfg(target_os = "illumos")]
+ self.empty();
+
match (&self.sender).write(&[1]) {
Ok(_) => Ok(()),
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
diff --git a/src/sys/windows/event.rs b/src/sys/windows/event.rs
index 4d04e64..a49252a 100644
--- a/src/sys/windows/event.rs
+++ b/src/sys/windows/event.rs
@@ -5,6 +5,7 @@ use miow::iocp::CompletionStatus;
use super::afd;
use crate::Token;
+#[derive(Clone)]
pub struct Event {
pub flags: u32,
pub data: u64,
diff --git a/src/sys/windows/udp.rs b/src/sys/windows/udp.rs
index ba2aeac..825eccc 100644
--- a/src/sys/windows/udp.rs
+++ b/src/sys/windows/udp.rs
@@ -1,9 +1,13 @@
use std::io;
+use std::mem::{self, MaybeUninit};
use std::net::{self, SocketAddr};
-use std::os::windows::io::FromRawSocket;
+use std::os::windows::io::{AsRawSocket, FromRawSocket};
use std::os::windows::raw::SOCKET as StdSocket; // winapi uses usize, stdlib uses u32/u64.
-use winapi::um::winsock2::{bind as win_bind, closesocket, SOCKET_ERROR, SOCK_DGRAM};
+use winapi::ctypes::c_int;
+use winapi::shared::ws2def::IPPROTO_IPV6;
+use winapi::shared::ws2ipdef::IPV6_V6ONLY;
+use winapi::um::winsock2::{bind as win_bind, closesocket, getsockopt, SOCKET_ERROR, SOCK_DGRAM};
use crate::sys::windows::net::{init, new_ip_socket, socket_addr};
@@ -25,3 +29,25 @@ pub fn bind(addr: SocketAddr) -> io::Result<net::UdpSocket> {
.map(|_| unsafe { net::UdpSocket::from_raw_socket(socket as StdSocket) })
})
}
+
+pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result<bool> {
+ let mut optval: MaybeUninit<c_int> = MaybeUninit::uninit();
+ let mut optlen = mem::size_of::<c_int>() as c_int;
+
+ syscall!(
+ getsockopt(
+ socket.as_raw_socket() as usize,
+ IPPROTO_IPV6 as c_int,
+ IPV6_V6ONLY as c_int,
+ optval.as_mut_ptr().cast(),
+ &mut optlen,
+ ),
+ PartialEq::eq,
+ SOCKET_ERROR
+ )?;
+
+ debug_assert_eq!(optlen as usize, mem::size_of::<c_int>());
+ // Safety: `getsockopt` initialised `optval` for us.
+ let optval = unsafe { optval.assume_init() };
+ Ok(optval != 0)
+}