mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Auto merge of #38707 - redox-os:master, r=brson
Add socket timeout and ttl support in `sys::redox` This adds support for `read_timeout`, `write_timeout`, and `ttl` on `TcpStream`, `TcpListener`, and `UdpSocket` in the `sys::redox` module. The DNS lookup has been set to use a 5 second timeout by default.
This commit is contained in:
commit
01677eeef2
@ -25,14 +25,7 @@ pub fn opts() -> TargetOptions {
|
|||||||
"-Wl,--as-needed".to_string(),
|
"-Wl,--as-needed".to_string(),
|
||||||
|
|
||||||
// Always enable NX protection when it is available
|
// Always enable NX protection when it is available
|
||||||
"-Wl,-z,noexecstack".to_string(),
|
"-Wl,-z,noexecstack".to_string()
|
||||||
|
|
||||||
// Static link
|
|
||||||
"-static".to_string()
|
|
||||||
],
|
|
||||||
late_link_args: vec![
|
|
||||||
"-lc".to_string(),
|
|
||||||
"-lm".to_string()
|
|
||||||
],
|
],
|
||||||
executables: true,
|
executables: true,
|
||||||
relocation_model: "static".to_string(),
|
relocation_model: "static".to_string(),
|
||||||
@ -40,7 +33,6 @@ pub fn opts() -> TargetOptions {
|
|||||||
eliminate_frame_pointer: false,
|
eliminate_frame_pointer: false,
|
||||||
target_family: None,
|
target_family: None,
|
||||||
linker_is_gnu: true,
|
linker_is_gnu: true,
|
||||||
no_default_libraries: true,
|
|
||||||
lib_allocation_crate: "alloc_system".to_string(),
|
lib_allocation_crate: "alloc_system".to_string(),
|
||||||
exe_allocation_crate: "alloc_system".to_string(),
|
exe_allocation_crate: "alloc_system".to_string(),
|
||||||
has_elf_tls: true,
|
has_elf_tls: true,
|
||||||
|
@ -15,7 +15,7 @@ use net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
|||||||
use str::FromStr;
|
use str::FromStr;
|
||||||
use string::{String, ToString};
|
use string::{String, ToString};
|
||||||
use sys::syscall::EINVAL;
|
use sys::syscall::EINVAL;
|
||||||
use time;
|
use time::{self, Duration};
|
||||||
use vec::{IntoIter, Vec};
|
use vec::{IntoIter, Vec};
|
||||||
|
|
||||||
use self::dns::{Dns, DnsQuery};
|
use self::dns::{Dns, DnsQuery};
|
||||||
@ -69,6 +69,8 @@ pub fn lookup_host(host: &str) -> Result<LookupHost> {
|
|||||||
let my_ip = Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]);
|
let my_ip = Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]);
|
||||||
let dns_ip = Ipv4Addr::new(dns[0], dns[1], dns[2], dns[3]);
|
let dns_ip = Ipv4Addr::new(dns[0], dns[1], dns[2], dns[3]);
|
||||||
let socket = UdpSocket::bind(&SocketAddr::V4(SocketAddrV4::new(my_ip, 0)))?;
|
let socket = UdpSocket::bind(&SocketAddr::V4(SocketAddrV4::new(my_ip, 0)))?;
|
||||||
|
socket.set_read_timeout(Some(Duration::new(5, 0)))?;
|
||||||
|
socket.set_write_timeout(Some(Duration::new(5, 0)))?;
|
||||||
socket.connect(&SocketAddr::V4(SocketAddrV4::new(dns_ip, 53)))?;
|
socket.connect(&SocketAddr::V4(SocketAddrV4::new(dns_ip, 53)))?;
|
||||||
socket.send(&packet_data)?;
|
socket.send(&packet_data)?;
|
||||||
|
|
||||||
|
@ -8,10 +8,13 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
use cmp;
|
||||||
use io::{Error, ErrorKind, Result};
|
use io::{Error, ErrorKind, Result};
|
||||||
|
use mem;
|
||||||
use net::{SocketAddr, Shutdown};
|
use net::{SocketAddr, Shutdown};
|
||||||
use path::Path;
|
use path::Path;
|
||||||
use sys::fs::{File, OpenOptions};
|
use sys::fs::{File, OpenOptions};
|
||||||
|
use sys::syscall::TimeSpec;
|
||||||
use sys_common::{AsInner, FromInner, IntoInner};
|
use sys_common::{AsInner, FromInner, IntoInner};
|
||||||
use time::Duration;
|
use time::Duration;
|
||||||
use vec::Vec;
|
use vec::Vec;
|
||||||
@ -77,15 +80,30 @@ impl TcpStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn ttl(&self) -> Result<u32> {
|
pub fn ttl(&self) -> Result<u32> {
|
||||||
Err(Error::new(ErrorKind::Other, "TcpStream::ttl not implemented"))
|
let mut ttl = [0];
|
||||||
|
let file = self.0.dup(b"ttl")?;
|
||||||
|
file.read(&mut ttl)?;
|
||||||
|
Ok(ttl[0] as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_timeout(&self) -> Result<Option<Duration>> {
|
pub fn read_timeout(&self) -> Result<Option<Duration>> {
|
||||||
Err(Error::new(ErrorKind::Other, "TcpStream::read_timeout not implemented"))
|
let mut time = TimeSpec::default();
|
||||||
|
let file = self.0.dup(b"read_timeout")?;
|
||||||
|
if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
|
||||||
|
Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_timeout(&self) -> Result<Option<Duration>> {
|
pub fn write_timeout(&self) -> Result<Option<Duration>> {
|
||||||
Err(Error::new(ErrorKind::Other, "TcpStream::write_timeout not implemented"))
|
let mut time = TimeSpec::default();
|
||||||
|
let file = self.0.dup(b"write_timeout")?;
|
||||||
|
if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
|
||||||
|
Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_nodelay(&self, _nodelay: bool) -> Result<()> {
|
pub fn set_nodelay(&self, _nodelay: bool) -> Result<()> {
|
||||||
@ -100,16 +118,36 @@ impl TcpStream {
|
|||||||
Err(Error::new(ErrorKind::Other, "TcpStream::set_only_v6 not implemented"))
|
Err(Error::new(ErrorKind::Other, "TcpStream::set_only_v6 not implemented"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_ttl(&self, _ttl: u32) -> Result<()> {
|
pub fn set_ttl(&self, ttl: u32) -> Result<()> {
|
||||||
Err(Error::new(ErrorKind::Other, "TcpStream::set_ttl not implemented"))
|
let file = self.0.dup(b"ttl")?;
|
||||||
|
file.write(&[cmp::min(ttl, 255) as u8])?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_read_timeout(&self, _dur: Option<Duration>) -> Result<()> {
|
pub fn set_read_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
|
||||||
Err(Error::new(ErrorKind::Other, "TcpStream::set_read_timeout not implemented"))
|
let file = self.0.dup(b"read_timeout")?;
|
||||||
|
if let Some(duration) = duration_option {
|
||||||
|
file.write(&TimeSpec {
|
||||||
|
tv_sec: duration.as_secs() as i64,
|
||||||
|
tv_nsec: duration.subsec_nanos() as i32
|
||||||
|
})?;
|
||||||
|
} else {
|
||||||
|
file.write(&[])?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_write_timeout(&self, _dur: Option<Duration>) -> Result<()> {
|
pub fn set_write_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
|
||||||
Err(Error::new(ErrorKind::Other, "TcpStream::set_write_timeout not implemented"))
|
let file = self.0.dup(b"write_timeout")?;
|
||||||
|
if let Some(duration) = duration_option {
|
||||||
|
file.write(&TimeSpec {
|
||||||
|
tv_sec: duration.as_secs() as i64,
|
||||||
|
tv_nsec: duration.subsec_nanos() as i32
|
||||||
|
})?;
|
||||||
|
} else {
|
||||||
|
file.write(&[])?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +206,10 @@ impl TcpListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn ttl(&self) -> Result<u32> {
|
pub fn ttl(&self) -> Result<u32> {
|
||||||
Err(Error::new(ErrorKind::Other, "TcpListener::ttl not implemented"))
|
let mut ttl = [0];
|
||||||
|
let file = self.0.dup(b"ttl")?;
|
||||||
|
file.read(&mut ttl)?;
|
||||||
|
Ok(ttl[0] as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_nonblocking(&self, _nonblocking: bool) -> Result<()> {
|
pub fn set_nonblocking(&self, _nonblocking: bool) -> Result<()> {
|
||||||
@ -179,8 +220,10 @@ impl TcpListener {
|
|||||||
Err(Error::new(ErrorKind::Other, "TcpListener::set_only_v6 not implemented"))
|
Err(Error::new(ErrorKind::Other, "TcpListener::set_only_v6 not implemented"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_ttl(&self, _ttl: u32) -> Result<()> {
|
pub fn set_ttl(&self, ttl: u32) -> Result<()> {
|
||||||
Err(Error::new(ErrorKind::Other, "TcpListener::set_ttl not implemented"))
|
let file = self.0.dup(b"ttl")?;
|
||||||
|
file.write(&[cmp::min(ttl, 255) as u8])?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,10 +9,13 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use cell::UnsafeCell;
|
use cell::UnsafeCell;
|
||||||
|
use cmp;
|
||||||
use io::{Error, ErrorKind, Result};
|
use io::{Error, ErrorKind, Result};
|
||||||
|
use mem;
|
||||||
use net::{SocketAddr, Ipv4Addr, Ipv6Addr};
|
use net::{SocketAddr, Ipv4Addr, Ipv6Addr};
|
||||||
use path::Path;
|
use path::Path;
|
||||||
use sys::fs::{File, OpenOptions};
|
use sys::fs::{File, OpenOptions};
|
||||||
|
use sys::syscall::TimeSpec;
|
||||||
use sys_common::{AsInner, FromInner, IntoInner};
|
use sys_common::{AsInner, FromInner, IntoInner};
|
||||||
use time::Duration;
|
use time::Duration;
|
||||||
|
|
||||||
@ -109,15 +112,30 @@ impl UdpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn ttl(&self) -> Result<u32> {
|
pub fn ttl(&self) -> Result<u32> {
|
||||||
Err(Error::new(ErrorKind::Other, "UdpSocket::ttl not implemented"))
|
let mut ttl = [0];
|
||||||
|
let file = self.0.dup(b"ttl")?;
|
||||||
|
file.read(&mut ttl)?;
|
||||||
|
Ok(ttl[0] as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_timeout(&self) -> Result<Option<Duration>> {
|
pub fn read_timeout(&self) -> Result<Option<Duration>> {
|
||||||
Err(Error::new(ErrorKind::Other, "UdpSocket::read_timeout not implemented"))
|
let mut time = TimeSpec::default();
|
||||||
|
let file = self.0.dup(b"read_timeout")?;
|
||||||
|
if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
|
||||||
|
Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_timeout(&self) -> Result<Option<Duration>> {
|
pub fn write_timeout(&self) -> Result<Option<Duration>> {
|
||||||
Err(Error::new(ErrorKind::Other, "UdpSocket::write_timeout not implemented"))
|
let mut time = TimeSpec::default();
|
||||||
|
let file = self.0.dup(b"write_timeout")?;
|
||||||
|
if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
|
||||||
|
Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_broadcast(&self, _broadcast: bool) -> Result<()> {
|
pub fn set_broadcast(&self, _broadcast: bool) -> Result<()> {
|
||||||
@ -144,16 +162,36 @@ impl UdpSocket {
|
|||||||
Err(Error::new(ErrorKind::Other, "UdpSocket::set_only_v6 not implemented"))
|
Err(Error::new(ErrorKind::Other, "UdpSocket::set_only_v6 not implemented"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_ttl(&self, _ttl: u32) -> Result<()> {
|
pub fn set_ttl(&self, ttl: u32) -> Result<()> {
|
||||||
Err(Error::new(ErrorKind::Other, "UdpSocket::set_ttl not implemented"))
|
let file = self.0.dup(b"ttl")?;
|
||||||
|
file.write(&[cmp::min(ttl, 255) as u8])?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_read_timeout(&self, _dur: Option<Duration>) -> Result<()> {
|
pub fn set_read_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
|
||||||
Err(Error::new(ErrorKind::Other, "UdpSocket::set_read_timeout not implemented"))
|
let file = self.0.dup(b"read_timeout")?;
|
||||||
|
if let Some(duration) = duration_option {
|
||||||
|
file.write(&TimeSpec {
|
||||||
|
tv_sec: duration.as_secs() as i64,
|
||||||
|
tv_nsec: duration.subsec_nanos() as i32
|
||||||
|
})?;
|
||||||
|
} else {
|
||||||
|
file.write(&[])?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_write_timeout(&self, _dur: Option<Duration>) -> Result<()> {
|
pub fn set_write_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
|
||||||
Err(Error::new(ErrorKind::Other, "UdpSocket::set_write_timeout not implemented"))
|
let file = self.0.dup(b"write_timeout")?;
|
||||||
|
if let Some(duration) = duration_option {
|
||||||
|
file.write(&TimeSpec {
|
||||||
|
tv_sec: duration.as_secs() as i64,
|
||||||
|
tv_nsec: duration.subsec_nanos() as i32
|
||||||
|
})?;
|
||||||
|
} else {
|
||||||
|
file.write(&[])?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join_multicast_v4(&self, _multiaddr: &Ipv4Addr, _interface: &Ipv4Addr) -> Result<()> {
|
pub fn join_multicast_v4(&self, _multiaddr: &Ipv4Addr, _interface: &Ipv4Addr) -> Result<()> {
|
||||||
|
@ -84,3 +84,22 @@ pub struct TimeSpec {
|
|||||||
pub tv_sec: i64,
|
pub tv_sec: i64,
|
||||||
pub tv_nsec: i32,
|
pub tv_nsec: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Deref for TimeSpec {
|
||||||
|
type Target = [u8];
|
||||||
|
fn deref(&self) -> &[u8] {
|
||||||
|
unsafe {
|
||||||
|
slice::from_raw_parts(self as *const TimeSpec as *const u8,
|
||||||
|
mem::size_of::<TimeSpec>()) as &[u8]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for TimeSpec {
|
||||||
|
fn deref_mut(&mut self) -> &mut [u8] {
|
||||||
|
unsafe {
|
||||||
|
slice::from_raw_parts_mut(self as *mut TimeSpec as *mut u8,
|
||||||
|
mem::size_of::<TimeSpec>()) as &mut [u8]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user