Skip to content

Commit b6d825b

Browse files
authored
Rollup merge of rust-lang#146541 - joboet:simplify-lookup-host, r=tgross35
std: simplify host lookup The logic for splitting up a string into a hostname and port is currently duplicated across (nearly) all of the networking implementations in `sys`. Since it does not actually rely on any system internals, this PR moves it to the `ToSocketAddr` implementation for `&str`, making it easier to discover and maintain. On the other hand, the `ToSocketAddr` implementation (or rather the `resolve_socket_addr` function) contained logic to overwrite the port on the socket addresses returned by `LookupHost`, even though `LookupHost` is already aware of the port and sets the port already on Xous. This PR thus removes this logic by moving the responsibility of setting the port to the system-specific `LookupHost` implementation. As a consequence of these changes, there remains only one way of creating `LookupHost`, hence I've removed the `TryFrom` implementations in favour of a `lookup_host` function, mirroring other, public iterator-based features. And finally, I've simplified the parsing logic responsible for recognising IP addresses passed to `<(&str, u16)>::to_socket_addrs()` by using the `FromStr` impl of `IpAddr` rather than duplicating the parsing for both IP versions.
2 parents a977b1a + 09d3120 commit b6d825b

File tree

11 files changed

+51
-212
lines changed

11 files changed

+51
-212
lines changed

library/std/src/net/socket_addr.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ mod tests;
66
pub use core::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
77

88
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr};
9-
use crate::sys::net::LookupHost;
109
use crate::{io, iter, option, slice, vec};
1110

1211
/// A trait for objects which can be converted or resolved to one or more
@@ -188,15 +187,9 @@ impl ToSocketAddrs for (Ipv6Addr, u16) {
188187
}
189188
}
190189

191-
fn resolve_socket_addr(lh: LookupHost) -> io::Result<vec::IntoIter<SocketAddr>> {
192-
let p = lh.port();
193-
let v: Vec<_> = lh
194-
.map(|mut a| {
195-
a.set_port(p);
196-
a
197-
})
198-
.collect();
199-
Ok(v.into_iter())
190+
fn lookup_host(host: &str, port: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
191+
let addrs = crate::sys::net::lookup_host(host, port)?;
192+
Ok(Vec::from_iter(addrs).into_iter())
200193
}
201194

202195
#[stable(feature = "rust1", since = "1.0.0")]
@@ -205,17 +198,14 @@ impl ToSocketAddrs for (&str, u16) {
205198
fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
206199
let (host, port) = *self;
207200

208-
// try to parse the host as a regular IP address first
209-
if let Ok(addr) = host.parse::<Ipv4Addr>() {
210-
let addr = SocketAddrV4::new(addr, port);
211-
return Ok(vec![SocketAddr::V4(addr)].into_iter());
212-
}
213-
if let Ok(addr) = host.parse::<Ipv6Addr>() {
214-
let addr = SocketAddrV6::new(addr, port, 0, 0);
215-
return Ok(vec![SocketAddr::V6(addr)].into_iter());
201+
// Try to parse the host as a regular IP address first
202+
if let Ok(addr) = host.parse::<IpAddr>() {
203+
let addr = SocketAddr::new(addr, port);
204+
return Ok(vec![addr].into_iter());
216205
}
217206

218-
resolve_socket_addr((host, port).try_into()?)
207+
// Otherwise, make the system look it up.
208+
lookup_host(host, port)
219209
}
220210
}
221211

@@ -232,12 +222,21 @@ impl ToSocketAddrs for (String, u16) {
232222
impl ToSocketAddrs for str {
233223
type Iter = vec::IntoIter<SocketAddr>;
234224
fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
235-
// try to parse as a regular SocketAddr first
225+
// Try to parse as a regular SocketAddr first
236226
if let Ok(addr) = self.parse() {
237227
return Ok(vec![addr].into_iter());
238228
}
239229

240-
resolve_socket_addr(self.try_into()?)
230+
// Otherwise, split the string by ':' and convert the second part to u16...
231+
let Some((host, port_str)) = self.rsplit_once(':') else {
232+
return Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid socket address"));
233+
};
234+
let Ok(port) = port_str.parse::<u16>() else {
235+
return Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid port value"));
236+
};
237+
238+
// ... and make the system look up the host.
239+
lookup_host(host, port)
241240
}
242241
}
243242

library/std/src/sys/net/connection/sgx.rs

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -499,35 +499,16 @@ impl fmt::Display for NonIpSockAddr {
499499

500500
pub struct LookupHost(!);
501501

502-
impl LookupHost {
503-
fn new(host: String) -> io::Result<LookupHost> {
504-
Err(io::Error::new(io::ErrorKind::Uncategorized, NonIpSockAddr { host }))
505-
}
506-
507-
pub fn port(&self) -> u16 {
508-
self.0
509-
}
510-
}
511-
512502
impl Iterator for LookupHost {
513503
type Item = SocketAddr;
514504
fn next(&mut self) -> Option<SocketAddr> {
515505
self.0
516506
}
517507
}
518508

519-
impl TryFrom<&str> for LookupHost {
520-
type Error = io::Error;
521-
522-
fn try_from(v: &str) -> io::Result<LookupHost> {
523-
LookupHost::new(v.to_owned())
524-
}
525-
}
526-
527-
impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
528-
type Error = io::Error;
529-
530-
fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
531-
LookupHost::new(format!("{host}:{port}"))
532-
}
509+
pub fn lookup_host(host: &str, port: u16) -> io::Result<LookupHost> {
510+
Err(io::Error::new(
511+
io::ErrorKind::Uncategorized,
512+
NonIpSockAddr { host: format!("{host}:{port}") },
513+
))
533514
}

library/std/src/sys/net/connection/socket/mod.rs

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ fn to_ipv6mr_interface(value: u32) -> crate::ffi::c_uint {
258258
}
259259

260260
////////////////////////////////////////////////////////////////////////////////
261-
// get_host_addresses
261+
// lookup_host
262262
////////////////////////////////////////////////////////////////////////////////
263263

264264
pub struct LookupHost {
@@ -267,12 +267,6 @@ pub struct LookupHost {
267267
port: u16,
268268
}
269269

270-
impl LookupHost {
271-
pub fn port(&self) -> u16 {
272-
self.port
273-
}
274-
}
275-
276270
impl Iterator for LookupHost {
277271
type Item = SocketAddr;
278272
fn next(&mut self) -> Option<SocketAddr> {
@@ -281,7 +275,10 @@ impl Iterator for LookupHost {
281275
let cur = self.cur.as_ref()?;
282276
self.cur = cur.ai_next;
283277
match socket_addr_from_c(cur.ai_addr.cast(), cur.ai_addrlen as usize) {
284-
Ok(addr) => return Some(addr),
278+
Ok(mut addr) => {
279+
addr.set_port(self.port);
280+
return Some(addr);
281+
}
285282
Err(_) => continue,
286283
}
287284
}
@@ -298,42 +295,17 @@ impl Drop for LookupHost {
298295
}
299296
}
300297

301-
impl TryFrom<&str> for LookupHost {
302-
type Error = io::Error;
303-
304-
fn try_from(s: &str) -> io::Result<LookupHost> {
305-
macro_rules! try_opt {
306-
($e:expr, $msg:expr) => {
307-
match $e {
308-
Some(r) => r,
309-
None => return Err(io::const_error!(io::ErrorKind::InvalidInput, $msg)),
310-
}
311-
};
298+
pub fn lookup_host(host: &str, port: u16) -> io::Result<LookupHost> {
299+
init();
300+
run_with_cstr(host.as_bytes(), &|c_host| {
301+
let mut hints: c::addrinfo = unsafe { mem::zeroed() };
302+
hints.ai_socktype = c::SOCK_STREAM;
303+
let mut res = ptr::null_mut();
304+
unsafe {
305+
cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res))
306+
.map(|_| LookupHost { original: res, cur: res, port })
312307
}
313-
314-
// split the string by ':' and convert the second part to u16
315-
let (host, port_str) = try_opt!(s.rsplit_once(':'), "invalid socket address");
316-
let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
317-
(host, port).try_into()
318-
}
319-
}
320-
321-
impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
322-
type Error = io::Error;
323-
324-
fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
325-
init();
326-
327-
run_with_cstr(host.as_bytes(), &|c_host| {
328-
let mut hints: c::addrinfo = unsafe { mem::zeroed() };
329-
hints.ai_socktype = c::SOCK_STREAM;
330-
let mut res = ptr::null_mut();
331-
unsafe {
332-
cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res))
333-
.map(|_| LookupHost { original: res, cur: res, port })
334-
}
335-
})
336-
}
308+
})
337309
}
338310

339311
////////////////////////////////////////////////////////////////////////////////

library/std/src/sys/net/connection/socket/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::collections::HashMap;
44
#[test]
55
fn no_lookup_host_duplicates() {
66
let mut addrs = HashMap::new();
7-
let lh = match LookupHost::try_from(("localhost", 0)) {
7+
let lh = match lookup_host("localhost", 0) {
88
Ok(lh) => lh,
99
Err(e) => panic!("couldn't resolve `localhost`: {e}"),
1010
};

library/std/src/sys/net/connection/uefi/mod.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -333,31 +333,13 @@ impl fmt::Debug for UdpSocket {
333333

334334
pub struct LookupHost(!);
335335

336-
impl LookupHost {
337-
pub fn port(&self) -> u16 {
338-
self.0
339-
}
340-
}
341-
342336
impl Iterator for LookupHost {
343337
type Item = SocketAddr;
344338
fn next(&mut self) -> Option<SocketAddr> {
345339
self.0
346340
}
347341
}
348342

349-
impl TryFrom<&str> for LookupHost {
350-
type Error = io::Error;
351-
352-
fn try_from(_v: &str) -> io::Result<LookupHost> {
353-
unsupported()
354-
}
355-
}
356-
357-
impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
358-
type Error = io::Error;
359-
360-
fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
361-
unsupported()
362-
}
343+
pub fn lookup_host(_host: &str, _port: u16) -> io::Result<LookupHost> {
344+
unsupported()
363345
}

library/std/src/sys/net/connection/unsupported.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -304,31 +304,13 @@ impl fmt::Debug for UdpSocket {
304304

305305
pub struct LookupHost(!);
306306

307-
impl LookupHost {
308-
pub fn port(&self) -> u16 {
309-
self.0
310-
}
311-
}
312-
313307
impl Iterator for LookupHost {
314308
type Item = SocketAddr;
315309
fn next(&mut self) -> Option<SocketAddr> {
316310
self.0
317311
}
318312
}
319313

320-
impl TryFrom<&str> for LookupHost {
321-
type Error = io::Error;
322-
323-
fn try_from(_v: &str) -> io::Result<LookupHost> {
324-
unsupported()
325-
}
326-
}
327-
328-
impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
329-
type Error = io::Error;
330-
331-
fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
332-
unsupported()
333-
}
314+
pub fn lookup_host(_host: &str, _port: u16) -> io::Result<LookupHost> {
315+
unsupported()
334316
}

library/std/src/sys/net/connection/wasip1.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -477,31 +477,13 @@ impl fmt::Debug for UdpSocket {
477477

478478
pub struct LookupHost(!);
479479

480-
impl LookupHost {
481-
pub fn port(&self) -> u16 {
482-
self.0
483-
}
484-
}
485-
486480
impl Iterator for LookupHost {
487481
type Item = SocketAddr;
488482
fn next(&mut self) -> Option<SocketAddr> {
489483
self.0
490484
}
491485
}
492486

493-
impl<'a> TryFrom<&'a str> for LookupHost {
494-
type Error = io::Error;
495-
496-
fn try_from(_v: &'a str) -> io::Result<LookupHost> {
497-
unsupported()
498-
}
499-
}
500-
501-
impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
502-
type Error = io::Error;
503-
504-
fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
505-
unsupported()
506-
}
487+
pub fn lookup_host(_host: &str, _port: u16) -> io::Result<LookupHost> {
488+
unsupported()
507489
}

library/std/src/sys/net/connection/xous/dns.rs

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
use core::convert::{TryFrom, TryInto};
2-
31
use crate::io;
42
use crate::net::{Ipv4Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
53
use crate::os::xous::ffi::lend_mut;
64
use crate::os::xous::services::{DnsLendMut, dns_server};
75

8-
pub struct DnsError {
9-
#[allow(dead_code)]
10-
pub code: u8,
11-
}
12-
136
#[repr(C, align(4096))]
147
struct LookupHostQuery([u8; 4096]);
158

@@ -20,12 +13,6 @@ pub struct LookupHost {
2013
count: usize,
2114
}
2215

23-
impl LookupHost {
24-
pub fn port(&self) -> u16 {
25-
self.port
26-
}
27-
}
28-
2916
impl Iterator for LookupHost {
3017
type Item = SocketAddr;
3118
fn next(&mut self) -> Option<SocketAddr> {
@@ -72,7 +59,7 @@ impl Iterator for LookupHost {
7259
}
7360
}
7461

75-
pub fn lookup(query: &str, port: u16) -> Result<LookupHost, DnsError> {
62+
pub fn lookup_host(query: &str, port: u16) -> io::Result<LookupHost> {
7663
let mut result = LookupHost { data: LookupHostQuery([0u8; 4096]), offset: 0, count: 0, port };
7764

7865
// Copy the query into the message that gets sent to the DNS server
@@ -89,7 +76,7 @@ pub fn lookup(query: &str, port: u16) -> Result<LookupHost, DnsError> {
8976
)
9077
.unwrap();
9178
if result.data.0[0] != 0 {
92-
return Err(DnsError { code: result.data.0[1] });
79+
return Err(io::const_error!(io::ErrorKind::InvalidInput, "DNS failure"));
9380
}
9481
assert_eq!(result.offset, 0);
9582
result.count = result.data.0[1] as usize;
@@ -98,31 +85,3 @@ pub fn lookup(query: &str, port: u16) -> Result<LookupHost, DnsError> {
9885
result.offset = 2;
9986
Ok(result)
10087
}
101-
102-
impl TryFrom<&str> for LookupHost {
103-
type Error = io::Error;
104-
105-
fn try_from(s: &str) -> io::Result<LookupHost> {
106-
macro_rules! try_opt {
107-
($e:expr, $msg:expr) => {
108-
match $e {
109-
Some(r) => r,
110-
None => return Err(io::const_error!(io::ErrorKind::InvalidInput, &$msg)),
111-
}
112-
};
113-
}
114-
115-
// split the string by ':' and convert the second part to u16
116-
let (host, port_str) = try_opt!(s.rsplit_once(':'), "invalid socket address");
117-
let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
118-
(host, port).try_into()
119-
}
120-
}
121-
122-
impl TryFrom<(&str, u16)> for LookupHost {
123-
type Error = io::Error;
124-
125-
fn try_from(v: (&str, u16)) -> io::Result<LookupHost> {
126-
lookup(v.0, v.1).map_err(|_e| io::const_error!(io::ErrorKind::InvalidInput, "DNS failure"))
127-
}
128-
}

library/std/src/sys/net/connection/xous/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,4 @@ pub struct GetAddress {
4545
raw: [u8; 4096],
4646
}
4747

48-
pub use dns::LookupHost;
48+
pub use dns::lookup_host;

0 commit comments

Comments
 (0)