diff options
| author | bors <bors@rust-lang.org> | 2022-08-29 05:12:53 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-08-29 05:12:53 +0000 |
| commit | 94b2b15e63c5d2b2a6a0910e3dae554ce9415bf9 (patch) | |
| tree | 52fe4cbdebc7c7b04dcd6a25793b8a8660969700 /library/std/src | |
| parent | 7c142a61373eda083cec64de383cf79e9a173f16 (diff) | |
| parent | fa177a9db2d7c96ced985d018a0108de033f5ded (diff) | |
| download | rust-94b2b15e63c5d2b2a6a0910e3dae554ce9415bf9.tar.gz rust-94b2b15e63c5d2b2a6a0910e3dae554ce9415bf9.zip | |
Auto merge of #101143 - matthiaskrgr:rollup-g8y5k0g, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #94890 (Support parsing IP addresses from a byte string) - #96334 (socket `set_mark` addition.) - #99027 (Replace `Body::basic_blocks()` with field access) - #100437 (Improve const mismatch `FulfillmentError`) - #100843 (Migrate part of rustc_infer to session diagnostic) - #100897 (extra sanity check against consts pointing to mutable memory) - #100959 (translations: rename warn_ to warning) - #101111 (Use the declaration's SourceInfo for FnEntry retags, not the outermost) - #101116 ([rustdoc] Remove Attrs type alias) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/net/parser.rs | 138 | ||||
| -rw-r--r-- | library/std/src/os/unix/net/datagram.rs | 25 | ||||
| -rw-r--r-- | library/std/src/os/unix/net/stream.rs | 25 | ||||
| -rw-r--r-- | library/std/src/sys/unix/net.rs | 11 |
4 files changed, 186 insertions, 13 deletions
diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs index 069b6609985..a38031c48c8 100644 --- a/library/std/src/net/parser.rs +++ b/library/std/src/net/parser.rs @@ -39,8 +39,8 @@ struct Parser<'a> { } impl<'a> Parser<'a> { - fn new(input: &'a str) -> Parser<'a> { - Parser { state: input.as_bytes() } + fn new(input: &'a [u8]) -> Parser<'a> { + Parser { state: input } } /// Run a parser, and restore the pre-parse state if it fails. @@ -273,32 +273,106 @@ impl<'a> Parser<'a> { } } +impl IpAddr { + /// Parse an IP address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + /// + /// let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); + /// let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); + /// + /// assert_eq!(IpAddr::parse_ascii(b"127.0.0.1"), Ok(localhost_v4)); + /// assert_eq!(IpAddr::parse_ascii(b"::1"), Ok(localhost_v6)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> { + Parser::new(b).parse_with(|p| p.read_ip_addr(), AddrKind::Ip) + } +} + #[stable(feature = "ip_addr", since = "1.7.0")] impl FromStr for IpAddr { type Err = AddrParseError; fn from_str(s: &str) -> Result<IpAddr, AddrParseError> { - Parser::new(s).parse_with(|p| p.read_ip_addr(), AddrKind::Ip) + Self::parse_ascii(s.as_bytes()) } } -#[stable(feature = "rust1", since = "1.0.0")] -impl FromStr for Ipv4Addr { - type Err = AddrParseError; - fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> { +impl Ipv4Addr { + /// Parse an IPv4 address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::Ipv4Addr; + /// + /// let localhost = Ipv4Addr::new(127, 0, 0, 1); + /// + /// assert_eq!(Ipv4Addr::parse_ascii(b"127.0.0.1"), Ok(localhost)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> { // don't try to parse if too long - if s.len() > 15 { + if b.len() > 15 { Err(AddrParseError(AddrKind::Ipv4)) } else { - Parser::new(s).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4) + Parser::new(b).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4) } } } #[stable(feature = "rust1", since = "1.0.0")] +impl FromStr for Ipv4Addr { + type Err = AddrParseError; + fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> { + Self::parse_ascii(s.as_bytes()) + } +} + +impl Ipv6Addr { + /// Parse an IPv6 address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::Ipv6Addr; + /// + /// let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); + /// + /// assert_eq!(Ipv6Addr::parse_ascii(b"::1"), Ok(localhost)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> { + Parser::new(b).parse_with(|p| p.read_ipv6_addr(), AddrKind::Ipv6) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] impl FromStr for Ipv6Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> { - Parser::new(s).parse_with(|p| p.read_ipv6_addr(), AddrKind::Ipv6) + Self::parse_ascii(s.as_bytes()) + } +} + +impl SocketAddrV4 { + /// Parse an IPv4 socket address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::{Ipv4Addr, SocketAddrV4}; + /// + /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); + /// + /// assert_eq!(SocketAddrV4::parse_ascii(b"127.0.0.1:8080"), Ok(socket)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> { + Parser::new(b).parse_with(|p| p.read_socket_addr_v4(), AddrKind::SocketV4) } } @@ -306,7 +380,25 @@ impl FromStr for Ipv6Addr { impl FromStr for SocketAddrV4 { type Err = AddrParseError; fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> { - Parser::new(s).parse_with(|p| p.read_socket_addr_v4(), AddrKind::SocketV4) + Self::parse_ascii(s.as_bytes()) + } +} + +impl SocketAddrV6 { + /// Parse an IPv6 socket address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::{Ipv6Addr, SocketAddrV6}; + /// + /// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0); + /// + /// assert_eq!(SocketAddrV6::parse_ascii(b"[2001:db8::1]:8080"), Ok(socket)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> { + Parser::new(b).parse_with(|p| p.read_socket_addr_v6(), AddrKind::SocketV6) } } @@ -314,7 +406,27 @@ impl FromStr for SocketAddrV4 { impl FromStr for SocketAddrV6 { type Err = AddrParseError; fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> { - Parser::new(s).parse_with(|p| p.read_socket_addr_v6(), AddrKind::SocketV6) + Self::parse_ascii(s.as_bytes()) + } +} + +impl SocketAddr { + /// Parse a socket address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; + /// + /// let socket_v4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); + /// let socket_v6 = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 8080); + /// + /// assert_eq!(SocketAddr::parse_ascii(b"127.0.0.1:8080"), Ok(socket_v4)); + /// assert_eq!(SocketAddr::parse_ascii(b"[::1]:8080"), Ok(socket_v6)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> { + Parser::new(b).parse_with(|p| p.read_socket_addr(), AddrKind::Socket) } } @@ -322,7 +434,7 @@ impl FromStr for SocketAddrV6 { impl FromStr for SocketAddr { type Err = AddrParseError; fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> { - Parser::new(s).parse_with(|p| p.read_socket_addr(), AddrKind::Socket) + Self::parse_ascii(s.as_bytes()) } } diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index 8008acfd1c9..f758f88d0a3 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -838,6 +838,31 @@ impl UnixDatagram { self.0.passcred() } + /// Set the id of the socket for network filtering purpose + /// + #[cfg_attr( + any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"), + doc = "```no_run" + )] + #[cfg_attr( + not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")), + doc = "```ignore" + )] + /// #![feature(unix_set_mark)] + /// use std::os::unix::net::UnixDatagram; + /// + /// fn main() -> std::io::Result<()> { + /// let sock = UnixDatagram::unbound()?; + /// sock.set_mark(32)?; + /// Ok(()) + /// } + /// ``` + #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))] + #[unstable(feature = "unix_set_mark", issue = "96467")] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + self.0.set_mark(mark) + } + /// Returns the value of the `SO_ERROR` option. /// /// # Examples diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index cc3a8858793..dff8f6e8567 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -427,6 +427,31 @@ impl UnixStream { self.0.passcred() } + /// Set the id of the socket for network filtering purpose + /// + #[cfg_attr( + any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"), + doc = "```no_run" + )] + #[cfg_attr( + not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")), + doc = "```ignore" + )] + /// #![feature(unix_set_mark)] + /// use std::os::unix::net::UnixStream; + /// + /// fn main() -> std::io::Result<()> { + /// let sock = UnixStream::connect("/tmp/sock")?; + /// sock.set_mark(32)?; + /// Ok(()) + /// } + /// ``` + #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))] + #[unstable(feature = "unix_set_mark", issue = "96467")] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + self.0.set_mark(mark) + } + /// Returns the value of the `SO_ERROR` option. /// /// # Examples diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index 85dcfc747af..b84bf8f9264 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -438,6 +438,17 @@ impl Socket { self.0.set_nonblocking(nonblocking) } + #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + #[cfg(target_os = "linux")] + let option = libc::SO_MARK; + #[cfg(target_os = "freebsd")] + let option = libc::SO_USER_COOKIE; + #[cfg(target_os = "openbsd")] + let option = libc::SO_RTABLE; + setsockopt(self, libc::SOL_SOCKET, option, mark as libc::c_int) + } + pub fn take_error(&self) -> io::Result<Option<io::Error>> { let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } |
