Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add socket timeout and ttl support in sys::redox #38707

Merged
merged 3 commits into from
Jan 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions src/librustc_back/target/redox_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,14 @@ 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(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need these extra arguments anymore.

disable_redzone: true,
eliminate_frame_pointer: false,
target_family: None,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need these extra arguments anymore. -lc and -lm will be specified by the cross compiler

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,
Expand Down
4 changes: 3 additions & 1 deletion src/libstd/sys/redox/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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)?;

Expand Down
75 changes: 59 additions & 16 deletions src/libstd/sys/redox/net/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<()> {
Expand All @@ -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_read_timeout(&self, _dur: Option<Duration>) -> Result<()> {
Err(Error::new(ErrorKind::Other, "TcpStream::set_read_timeout not implemented"))
}

pub fn set_write_timeout(&self, _dur: Option<Duration>) -> Result<()> {
Err(Error::new(ErrorKind::Other, "TcpStream::set_write_timeout 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, 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, 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(())
}
}

Expand Down Expand Up @@ -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<()> {
Expand All @@ -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(())
}
}

Expand Down
56 changes: 47 additions & 9 deletions src/libstd/sys/redox/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<()> {
Expand All @@ -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<()> {
Expand Down
19 changes: 19 additions & 0 deletions src/libstd/sys/redox/syscall/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}
}
}