diff options
| author | Jethro Beekman <jethro@fortanix.com> | 2018-09-18 15:25:08 -0700 |
|---|---|---|
| committer | Jethro Beekman <jethro@fortanix.com> | 2018-12-06 20:37:15 +0530 |
| commit | 22c43689937a81cf5ad6ecfe22d9e63e3cebed04 (patch) | |
| tree | 137d0de6228d8ec2527b2c151c874b8d20e5b0cd /src/libstd/sys/redox | |
| parent | 030b1ed7f709539f5ca422758e9fe00d173aee76 (diff) | |
| download | rust-22c43689937a81cf5ad6ecfe22d9e63e3cebed04.tar.gz rust-22c43689937a81cf5ad6ecfe22d9e63e3cebed04.zip | |
Refactor net::each_addr/lookup_host to forward error from resolve
Diffstat (limited to 'src/libstd/sys/redox')
| -rw-r--r-- | src/libstd/sys/redox/net/mod.rs | 153 | ||||
| -rw-r--r-- | src/libstd/sys/redox/net/tcp.rs | 8 | ||||
| -rw-r--r-- | src/libstd/sys/redox/net/udp.rs | 8 |
3 files changed, 102 insertions, 67 deletions
diff --git a/src/libstd/sys/redox/net/mod.rs b/src/libstd/sys/redox/net/mod.rs index 67f22231d5f..04a183f2417 100644 --- a/src/libstd/sys/redox/net/mod.rs +++ b/src/libstd/sys/redox/net/mod.rs @@ -9,7 +9,7 @@ // except according to those terms. use fs::File; -use io::{Error, Result, Read}; +use io::{Error, Read, self}; use iter::Iterator; use net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use str::FromStr; @@ -17,6 +17,7 @@ use string::{String, ToString}; use sys::syscall::EINVAL; use time::{self, Duration}; use vec::{IntoIter, Vec}; +use convert::{TryFrom, TryInto}; use self::dns::{Dns, DnsQuery}; @@ -29,7 +30,13 @@ mod dns; mod tcp; mod udp; -pub struct LookupHost(IntoIter<SocketAddr>); +pub struct LookupHost(IntoIter<SocketAddr>, u16); + +impl LookupHost { + pub fn port(&self) -> u16 { + self.1 + } +} impl Iterator for LookupHost { type Item = SocketAddr; @@ -38,65 +45,93 @@ impl Iterator for LookupHost { } } -pub fn lookup_host(host: &str) -> Result<LookupHost> { - let mut ip_string = String::new(); - File::open("/etc/net/ip")?.read_to_string(&mut ip_string)?; - let ip: Vec<u8> = ip_string.trim().split('.').map(|part| part.parse::<u8>() - .unwrap_or(0)).collect(); - - let mut dns_string = String::new(); - File::open("/etc/net/dns")?.read_to_string(&mut dns_string)?; - let dns: Vec<u8> = dns_string.trim().split('.').map(|part| part.parse::<u8>() - .unwrap_or(0)).collect(); - - if ip.len() == 4 && dns.len() == 4 { - let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap(); - let tid = (time.subsec_nanos() >> 16) as u16; - - let packet = Dns { - transaction_id: tid, - flags: 0x0100, - queries: vec![DnsQuery { - name: host.to_string(), - q_type: 0x0001, - q_class: 0x0001, - }], - answers: vec![] - }; - - let packet_data = packet.compile(); - - 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)?; - - let mut buf = [0; 65536]; - let count = socket.recv(&mut buf)?; - - match Dns::parse(&buf[.. count]) { - Ok(response) => { - let mut addrs = vec![]; - for answer in response.answers.iter() { - if answer.a_type == 0x0001 && answer.a_class == 0x0001 - && answer.data.len() == 4 - { - let answer_ip = Ipv4Addr::new(answer.data[0], - answer.data[1], - answer.data[2], - answer.data[3]); - addrs.push(SocketAddr::V4(SocketAddrV4::new(answer_ip, 0))); - } +impl<'a> TryFrom<&'a str> for LookupHost { + type Error = io::Error; + + fn try_from(s: &str) -> io::Result<LookupHost> { + macro_rules! try_opt { + ($e:expr, $msg:expr) => ( + match $e { + Some(r) => r, + None => return Err(io::Error::new(io::ErrorKind::InvalidInput, + $msg)), } - Ok(LookupHost(addrs.into_iter())) - }, - Err(_err) => Err(Error::from_raw_os_error(EINVAL)) + ) + } + + // split the string by ':' and convert the second part to u16 + let mut parts_iter = s.rsplitn(2, ':'); + let port_str = try_opt!(parts_iter.next(), "invalid socket address"); + let host = try_opt!(parts_iter.next(), "invalid socket address"); + let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value"); + + (host, port).try_into() + } +} + +impl<'a> TryFrom<(&'a str, u16)> for LookupHost { + type Error = io::Error; + + fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> { + let mut ip_string = String::new(); + File::open("/etc/net/ip")?.read_to_string(&mut ip_string)?; + let ip: Vec<u8> = ip_string.trim().split('.').map(|part| part.parse::<u8>() + .unwrap_or(0)).collect(); + + let mut dns_string = String::new(); + File::open("/etc/net/dns")?.read_to_string(&mut dns_string)?; + let dns: Vec<u8> = dns_string.trim().split('.').map(|part| part.parse::<u8>() + .unwrap_or(0)).collect(); + + if ip.len() == 4 && dns.len() == 4 { + let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap(); + let tid = (time.subsec_nanos() >> 16) as u16; + + let packet = Dns { + transaction_id: tid, + flags: 0x0100, + queries: vec![DnsQuery { + name: host.to_string(), + q_type: 0x0001, + q_class: 0x0001, + }], + answers: vec![] + }; + + let packet_data = packet.compile(); + + 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(Ok(&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(Ok(&SocketAddr::V4(SocketAddrV4::new(dns_ip, 53))))?; + socket.send(&packet_data)?; + + let mut buf = [0; 65536]; + let count = socket.recv(&mut buf)?; + + match Dns::parse(&buf[.. count]) { + Ok(response) => { + let mut addrs = vec![]; + for answer in response.answers.iter() { + if answer.a_type == 0x0001 && answer.a_class == 0x0001 + && answer.data.len() == 4 + { + let answer_ip = Ipv4Addr::new(answer.data[0], + answer.data[1], + answer.data[2], + answer.data[3]); + addrs.push(SocketAddr::V4(SocketAddrV4::new(answer_ip, 0))); + } + } + Ok(LookupHost(addrs.into_iter(), port)) + }, + Err(_err) => Err(Error::from_raw_os_error(EINVAL)) + } + } else { + Err(Error::from_raw_os_error(EINVAL)) } - } else { - Err(Error::from_raw_os_error(EINVAL)) } } diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs index b5664908479..37457d87f33 100644 --- a/src/libstd/sys/redox/net/tcp.rs +++ b/src/libstd/sys/redox/net/tcp.rs @@ -24,8 +24,8 @@ use super::{path_to_peer_addr, path_to_local_addr}; pub struct TcpStream(File); impl TcpStream { - pub fn connect(addr: &SocketAddr) -> Result<TcpStream> { - let path = format!("tcp:{}", addr); + pub fn connect(addr: Result<&SocketAddr>) -> Result<TcpStream> { + let path = format!("tcp:{}", addr?); let mut options = OpenOptions::new(); options.read(true); options.write(true); @@ -180,8 +180,8 @@ impl IntoInner<File> for TcpStream { pub struct TcpListener(File); impl TcpListener { - pub fn bind(addr: &SocketAddr) -> Result<TcpListener> { - let path = format!("tcp:/{}", addr); + pub fn bind(addr: Result<&SocketAddr>) -> Result<TcpListener> { + let path = format!("tcp:/{}", addr?); let mut options = OpenOptions::new(); options.read(true); options.write(true); diff --git a/src/libstd/sys/redox/net/udp.rs b/src/libstd/sys/redox/net/udp.rs index 22af02079e7..85bfd425924 100644 --- a/src/libstd/sys/redox/net/udp.rs +++ b/src/libstd/sys/redox/net/udp.rs @@ -25,8 +25,8 @@ use super::{path_to_peer_addr, path_to_local_addr}; pub struct UdpSocket(File, UnsafeCell<Option<SocketAddr>>); impl UdpSocket { - pub fn bind(addr: &SocketAddr) -> Result<UdpSocket> { - let path = format!("udp:/{}", addr); + pub fn bind(addr: Result<&SocketAddr>) -> Result<UdpSocket> { + let path = format!("udp:/{}", addr?); let mut options = OpenOptions::new(); options.read(true); options.write(true); @@ -37,8 +37,8 @@ impl UdpSocket { unsafe { &mut *(self.1.get()) } } - pub fn connect(&self, addr: &SocketAddr) -> Result<()> { - unsafe { *self.1.get() = Some(*addr) }; + pub fn connect(&self, addr: Result<&SocketAddr>) -> Result<()> { + unsafe { *self.1.get() = Some(*addr?) }; Ok(()) } |
