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(),
|
||||
|
||||
// Always enable NX protection when it is available
|
||||
"-Wl,-z,noexecstack".to_string(),
|
||||
|
||||
// Static link
|
||||
"-static".to_string()
|
||||
],
|
||||
late_link_args: vec![
|
||||
"-lc".to_string(),
|
||||
"-lm".to_string()
|
||||
"-Wl,-z,noexecstack".to_string()
|
||||
],
|
||||
executables: true,
|
||||
relocation_model: "static".to_string(),
|
||||
@ -40,7 +33,6 @@ pub fn opts() -> TargetOptions {
|
||||
eliminate_frame_pointer: false,
|
||||
target_family: None,
|
||||
linker_is_gnu: true,
|
||||
no_default_libraries: true,
|
||||
lib_allocation_crate: "alloc_system".to_string(),
|
||||
exe_allocation_crate: "alloc_system".to_string(),
|
||||
has_elf_tls: true,
|
||||
|
@ -15,7 +15,7 @@ use net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||
use str::FromStr;
|
||||
use string::{String, ToString};
|
||||
use sys::syscall::EINVAL;
|
||||
use time;
|
||||
use time::{self, Duration};
|
||||
use vec::{IntoIter, Vec};
|
||||
|
||||
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 dns_ip = Ipv4Addr::new(dns[0], dns[1], dns[2], dns[3]);
|
||||
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.send(&packet_data)?;
|
||||
|
||||
|
@ -8,10 +8,13 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use cmp;
|
||||
use io::{Error, ErrorKind, Result};
|
||||
use mem;
|
||||
use net::{SocketAddr, Shutdown};
|
||||
use path::Path;
|
||||
use sys::fs::{File, OpenOptions};
|
||||
use sys::syscall::TimeSpec;
|
||||
use sys_common::{AsInner, FromInner, IntoInner};
|
||||
use time::Duration;
|
||||
use vec::Vec;
|
||||
@ -77,15 +80,30 @@ impl TcpStream {
|
||||
}
|
||||
|
||||
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>> {
|
||||
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>> {
|
||||
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<()> {
|
||||
@ -100,16 +118,36 @@ impl TcpStream {
|
||||
Err(Error::new(ErrorKind::Other, "TcpStream::set_only_v6 not implemented"))
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _ttl: u32) -> Result<()> {
|
||||
Err(Error::new(ErrorKind::Other, "TcpStream::set_ttl not implemented"))
|
||||
pub fn set_ttl(&self, ttl: u32) -> Result<()> {
|
||||
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<()> {
|
||||
Err(Error::new(ErrorKind::Other, "TcpStream::set_read_timeout not implemented"))
|
||||
pub fn set_read_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
|
||||
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<()> {
|
||||
Err(Error::new(ErrorKind::Other, "TcpStream::set_write_timeout not implemented"))
|
||||
pub fn set_write_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
|
||||
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> {
|
||||
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<()> {
|
||||
@ -179,8 +220,10 @@ impl TcpListener {
|
||||
Err(Error::new(ErrorKind::Other, "TcpListener::set_only_v6 not implemented"))
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _ttl: u32) -> Result<()> {
|
||||
Err(Error::new(ErrorKind::Other, "TcpListener::set_ttl not implemented"))
|
||||
pub fn set_ttl(&self, ttl: u32) -> Result<()> {
|
||||
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.
|
||||
|
||||
use cell::UnsafeCell;
|
||||
use cmp;
|
||||
use io::{Error, ErrorKind, Result};
|
||||
use mem;
|
||||
use net::{SocketAddr, Ipv4Addr, Ipv6Addr};
|
||||
use path::Path;
|
||||
use sys::fs::{File, OpenOptions};
|
||||
use sys::syscall::TimeSpec;
|
||||
use sys_common::{AsInner, FromInner, IntoInner};
|
||||
use time::Duration;
|
||||
|
||||
@ -109,15 +112,30 @@ impl UdpSocket {
|
||||
}
|
||||
|
||||
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>> {
|
||||
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>> {
|
||||
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<()> {
|
||||
@ -144,16 +162,36 @@ impl UdpSocket {
|
||||
Err(Error::new(ErrorKind::Other, "UdpSocket::set_only_v6 not implemented"))
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _ttl: u32) -> Result<()> {
|
||||
Err(Error::new(ErrorKind::Other, "UdpSocket::set_ttl not implemented"))
|
||||
pub fn set_ttl(&self, ttl: u32) -> Result<()> {
|
||||
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<()> {
|
||||
Err(Error::new(ErrorKind::Other, "UdpSocket::set_read_timeout not implemented"))
|
||||
pub fn set_read_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
|
||||
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<()> {
|
||||
Err(Error::new(ErrorKind::Other, "UdpSocket::set_write_timeout not implemented"))
|
||||
pub fn set_write_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
|
||||
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<()> {
|
||||
|
@ -84,3 +84,22 @@ pub struct TimeSpec {
|
||||
pub tv_sec: i64,
|
||||
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