Skip to content

Commit

Permalink
Rollup merge of rust-lang#94678 - kckeiks:set_ipv6_sock_hop_limit, r=…
Browse files Browse the repository at this point in the history
…joshtriplett

add methods to TCP and UDP sockets to modify hop limit

* adds methods to set value of IPV6_UNICAST_HOPS and IPV6_MULTICAST_HOPS on ipv6 sockets
* I added some noop methods for different systems to keep things consistent. Maybe someone could please clarify if these noop funcs are needed? and, if so, why? Just for my own learning.

This is my first addition of a new feature so let me know if I missed something in the process. I read the rustc dev guide about implementing new features but since the change here is simple, it suggested that a PR would be enough.

Fixes rust-lang#47727
  • Loading branch information
matthiaskrgr authored Oct 3, 2022
2 parents 0922559 + b3e9e94 commit 27bbb53
Show file tree
Hide file tree
Showing 12 changed files with 559 additions and 0 deletions.
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@
#![feature(exhaustive_patterns)]
#![feature(if_let_guard)]
#![feature(intra_doc_pointers)]
#![feature(ipv6_hop_limit)]
#![feature(lang_items)]
#![feature(let_chains)]
#![feature(linkage)]
Expand Down
156 changes: 156 additions & 0 deletions library/std/src/net/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,86 @@ impl TcpStream {
self.0.ttl()
}

/// Sets the value for the `IPV6_UNICAST_HOPS` option on this socket.
///
/// This value sets the unicast hop limit field that is used in every packet
/// sent from this socket.
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::TcpStream;
///
/// let stream = TcpStream::connect("127.0.0.1:54321")
/// .expect("Couldn't connect to the server...");
/// stream.set_hop_limit_v6(88).expect("set_hop_limit_v6 call failed");
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn set_hop_limit_v6(&self, limit: u32) -> io::Result<()> {
self.0.set_hop_limit_v6(limit)
}

/// Gets the value of the `IPV6_UNICAST_HOPS` option on this socket.
///
/// For more information about this option, see [`TcpStream::set_hop_limit_v6`].
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::TcpStream;
///
/// let stream = TcpStream::connect("127.0.0.1:54321")
/// .expect("Couldn't connect to the server...");
/// stream.set_hop_limit_v6(88).expect("set_hop_limit_v6 call failed");
/// assert_eq!(stream.hop_limit_v6().unwrap(), 88);
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn hop_limit_v6(&self) -> io::Result<u32> {
self.0.hop_limit_v6()
}

/// Sets the value for the `IPV6_MULTICAST_HOPS` option on this socket.
///
/// This value sets the hop limit field for outgoing multicast packets
/// sent from this socket.
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::TcpStream;
///
/// let stream = TcpStream::connect("127.0.0.1:54321")
/// .expect("Couldn't connect to the server...");
/// stream.set_multicast_hop_limit_v6(88).expect("set_multicast_hop_limit_v6 call failed");
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn set_multicast_hop_limit_v6(&self, limit: u32) -> io::Result<()> {
self.0.set_multicast_hop_limit_v6(limit)
}

/// Gets the value of the `IPV6_MULTICAST_HOPS` option on this socket.
///
/// For more information about this option, see [`TcpStream::set_multicast_hop_limit_v6`].
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::TcpStream;
///
/// let stream = TcpStream::connect("127.0.0.1:54321")
/// .expect("Couldn't connect to the server...");
/// stream.set_multicast_hop_limit_v6(88).expect("set_multicast_hop_limit_v6 call failed");
/// assert_eq!(stream.multicast_hop_limit_v6().unwrap(), 88);
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn multicast_hop_limit_v6(&self) -> io::Result<u32> {
self.0.multicast_hop_limit_v6()
}

/// Gets the value of the `SO_ERROR` option on this socket.
///
/// This will retrieve the stored error in the underlying socket, clearing
Expand Down Expand Up @@ -915,6 +995,82 @@ impl TcpListener {
self.0.ttl()
}

/// Sets the value for the `IPV6_UNICAST_HOPS` option on this socket.
///
/// This value sets the unicast hop limit field that is used in every packet
/// sent from this socket.
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::TcpListener;
///
/// let listener = TcpListener::bind("127.0.0.1:54321").unwrap();
/// listener.set_hop_limit_v6(88).expect("set_hop_limit_v6 call failed");
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn set_hop_limit_v6(&self, limit: u32) -> io::Result<()> {
self.0.set_hop_limit_v6(limit)
}

/// Gets the value of the `IPV6_UNICAST_HOPS` option on this socket.
///
/// For more information about this option, see [`TcpListener::set_hop_limit_v6`].
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::TcpListener;
///
/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
/// listener.set_hop_limit_v6(88).expect("set_hop_limit_v6 call failed");
/// assert_eq!(listener.hop_limit_v6().unwrap(), 88);
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn hop_limit_v6(&self) -> io::Result<u32> {
self.0.hop_limit_v6()
}

/// Sets the value for the `IPV6_MULTICAST_HOPS` option on this socket.
///
/// This value sets the hop limit field for outgoing multicast packets
/// sent from this socket.
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::TcpListener;
///
/// let listener = TcpListener::bind("127.0.0.1:54321").unwrap();
/// listener.set_multicast_hop_limit_v6(88).expect("set_multicast_hop_limit_v6 call failed");
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn set_multicast_hop_limit_v6(&self, limit: u32) -> io::Result<()> {
self.0.set_multicast_hop_limit_v6(limit)
}

/// Gets the value of the `IPV6_MULTICAST_HOPS` option on this socket.
///
/// For more information about this option, see [`TcpListener::set_multicast_hop_limit_v6`].
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::TcpListener;
///
/// let listener = TcpListener::bind("127.0.0.1:54321").unwrap();
/// listener.set_multicast_hop_limit_v6(88).expect("set_multicast_hop_limit_v6 call failed");
/// assert_eq!(listener.multicast_hop_limit_v6().unwrap(), 88);
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn multicast_hop_limit_v6(&self) -> io::Result<u32> {
self.0.multicast_hop_limit_v6()
}

#[stable(feature = "net2_mutators", since = "1.9.0")]
#[deprecated(since = "1.16.0", note = "this option can only be set before the socket is bound")]
#[allow(missing_docs)]
Expand Down
17 changes: 17 additions & 0 deletions library/std/src/net/tcp/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,23 @@ fn ttl() {
assert_eq!(ttl, t!(stream.ttl()));
}

#[test]
#[cfg_attr(target_env = "sgx", ignore)]
fn hop_limit() {
let hlim: u32 = 100;

let addr = next_test_ip6();
let listener = t!(TcpListener::bind(&addr));

t!(listener.set_hop_limit_v6(hlim));
assert_eq!(hlim, t!(listener.hop_limit_v6()));

let stream = t!(TcpStream::connect(&addr));

t!(stream.set_hop_limit_v6(hlim));
assert_eq!(hlim, t!(stream.hop_limit_v6()));
}

#[test]
#[cfg_attr(target_env = "sgx", ignore)]
fn set_nonblocking() {
Expand Down
76 changes: 76 additions & 0 deletions library/std/src/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,82 @@ impl UdpSocket {
self.0.ttl()
}

/// Sets the value for the `IPV6_UNICAST_HOPS` option on this socket.
///
/// This value sets the unicast hop limit field that is used in every packet
/// sent from this socket.
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::UdpSocket;
///
/// let socket = UdpSocket::bind("127.0.0.1:54321").expect("couldn't bind to address");
/// socket.set_hop_limit_v6(88).expect("set_hop_limit_v6 call failed");
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn set_hop_limit_v6(&self, limit: u32) -> io::Result<()> {
self.0.set_hop_limit_v6(limit)
}

/// Gets the value of the `IPV6_UNICAST_HOPS` option on this socket.
///
/// For more information about this option, see [`UdpSocket::set_hop_limit_v6`].
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::UdpSocket;
///
/// let socket = UdpSocket::bind("127.0.0.1:54321").expect("couldn't bind to address");
/// socket.set_hop_limit_v6(88).expect("set_hop_limit_v6 call failed");
/// assert_eq!(socket.hop_limit_v6().unwrap(), 88);
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn hop_limit_v6(&self) -> io::Result<u32> {
self.0.hop_limit_v6()
}

/// Sets the value for the `IPV6_MULTICAST_HOPS` option on this socket.
///
/// This value sets the hop limit field for outgoing multicast packets
/// sent from this socket.
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::UdpSocket;
///
/// let socket = UdpSocket::bind("127.0.0.1:54321").expect("couldn't bind to address");
/// socket.set_multicast_hop_limit_v6(88).expect("set_multicast_hop_limit_v6 call failed");
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn set_multicast_hop_limit_v6(&self, limit: u32) -> io::Result<()> {
self.0.set_multicast_hop_limit_v6(limit)
}

/// Gets the value of the `IPV6_MULTICAST_HOPS` option on this socket.
///
/// For more information about this option, see [`UdpSocket::set_multicast_hop_limit_v6`].
///
/// # Examples
///
/// ```no_run
/// #![feature(ipv6_hop_limit)]
/// use std::net::UdpSocket;
///
/// let socket = UdpSocket::bind("127.0.0.1:54321").expect("couldn't bind to address");
/// socket.set_multicast_hop_limit_v6(88).expect("set_multicast_hop_limit_v6 call failed");
/// assert_eq!(socket.multicast_hop_limit_v6().unwrap(), 88);
/// ```
#[unstable(feature = "ipv6_hop_limit", issue = "47727")]
pub fn multicast_hop_limit_v6(&self) -> io::Result<u32> {
self.0.multicast_hop_limit_v6()
}

/// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
///
/// This function specifies a new multicast group for this socket to join.
Expand Down
12 changes: 12 additions & 0 deletions library/std/src/net/udp/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,18 @@ fn ttl() {
assert_eq!(ttl, t!(stream.ttl()));
}

#[test]
fn hop_limit() {
let hlim = 100;

let addr = next_test_ip6();

let stream = t!(UdpSocket::bind(&addr));

t!(stream.set_hop_limit_v6(hlim));
assert_eq!(hlim, t!(stream.hop_limit_v6()));
}

#[test]
fn set_nonblocking() {
each_ip(&mut |addr, _| {
Expand Down
48 changes: 48 additions & 0 deletions library/std/src/sys/hermit/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,22 @@ impl TcpStream {
.map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to get TTL"))
}

pub fn set_hop_limit_v6(&self, _: u32) -> io::Result<()> {
unsupported()
}

pub fn hop_limit_v6(&self) -> io::Result<u32> {
unsupported()
}

pub fn set_multicast_hop_limit_v6(&self, _: u32) -> io::Result<()> {
unsupported()
}

pub fn multicast_hop_limit_v6(&self) -> io::Result<u32> {
unsupported()
}

pub fn take_error(&self) -> io::Result<Option<io::Error>> {
unsupported()
}
Expand Down Expand Up @@ -265,6 +281,22 @@ impl TcpListener {
unsupported()
}

pub fn set_hop_limit_v6(&self, _: u32) -> io::Result<()> {
unsupported()
}

pub fn hop_limit_v6(&self) -> io::Result<u32> {
unsupported()
}

pub fn set_multicast_hop_limit_v6(&self, _: u32) -> io::Result<()> {
unsupported()
}

pub fn multicast_hop_limit_v6(&self) -> io::Result<u32> {
unsupported()
}

pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
unsupported()
}
Expand Down Expand Up @@ -391,6 +423,22 @@ impl UdpSocket {
unsupported()
}

pub fn set_hop_limit_v6(&self, _: u32) -> io::Result<()> {
unsupported()
}

pub fn hop_limit_v6(&self) -> io::Result<u32> {
unsupported()
}

pub fn set_multicast_hop_limit_v6(&self, _: u32) -> io::Result<()> {
unsupported()
}

pub fn multicast_hop_limit_v6(&self) -> io::Result<u32> {
unsupported()
}

pub fn take_error(&self) -> io::Result<Option<io::Error>> {
unsupported()
}
Expand Down
Loading

0 comments on commit 27bbb53

Please sign in to comment.