Skip to content

Commit db1e118

Browse files
committed
std: net: uefi: Add support to query connection data
- Use EFI_TCP4_GET_MODE_DATA to be able to query for ttl, nodelay, peer_addr and socket_addr. - peer_addr is needed for implementation of `accept`. Signed-off-by: Ayush Singh <[email protected]>
1 parent 2f9c9ce commit db1e118

File tree

4 files changed

+87
-15
lines changed

4 files changed

+87
-15
lines changed

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

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ impl TcpStream {
8686
}
8787

8888
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
89-
unsupported()
89+
self.inner.peer_addr()
9090
}
9191

9292
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
93-
unsupported()
93+
self.inner.socket_addr()
9494
}
9595

9696
pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
@@ -114,15 +114,15 @@ impl TcpStream {
114114
}
115115

116116
pub fn nodelay(&self) -> io::Result<bool> {
117-
unsupported()
117+
self.inner.nodelay()
118118
}
119119

120120
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
121121
unsupported()
122122
}
123123

124124
pub fn ttl(&self) -> io::Result<u32> {
125-
unsupported()
125+
self.inner.ttl()
126126
}
127127

128128
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
@@ -140,53 +140,55 @@ impl fmt::Debug for TcpStream {
140140
}
141141
}
142142

143-
pub struct TcpListener(!);
143+
pub struct TcpListener {
144+
inner: tcp::Tcp,
145+
}
144146

145147
impl TcpListener {
146148
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
147149
unsupported()
148150
}
149151

150152
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
151-
self.0
153+
unsupported()
152154
}
153155

154156
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
155-
self.0
157+
unsupported()
156158
}
157159

158160
pub fn duplicate(&self) -> io::Result<TcpListener> {
159-
self.0
161+
unsupported()
160162
}
161163

162164
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
163-
self.0
165+
unsupported()
164166
}
165167

166168
pub fn ttl(&self) -> io::Result<u32> {
167-
self.0
169+
self.inner.ttl()
168170
}
169171

170172
pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
171-
self.0
173+
unsupported()
172174
}
173175

174176
pub fn only_v6(&self) -> io::Result<bool> {
175-
self.0
177+
unsupported()
176178
}
177179

178180
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
179-
self.0
181+
unsupported()
180182
}
181183

182184
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
183-
self.0
185+
unsupported()
184186
}
185187
}
186188

187189
impl fmt::Debug for TcpListener {
188190
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
189-
self.0
191+
todo!()
190192
}
191193
}
192194

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use super::tcp4;
22
use crate::io;
33
use crate::net::SocketAddr;
4+
use crate::ptr::NonNull;
5+
use crate::sys::{helpers, unsupported};
46
use crate::time::Duration;
57

68
pub(crate) enum Tcp {
@@ -31,4 +33,44 @@ impl Tcp {
3133
Self::V4(client) => client.read(buf, timeout),
3234
}
3335
}
36+
37+
pub(crate) fn ttl(&self) -> io::Result<u32> {
38+
match self {
39+
Self::V4(client) => client.get_mode_data().map(|x| x.time_to_live.into()),
40+
}
41+
}
42+
43+
pub(crate) fn nodelay(&self) -> io::Result<bool> {
44+
match self {
45+
Self::V4(client) => {
46+
let temp = client.get_mode_data()?;
47+
match NonNull::new(temp.control_option) {
48+
Some(x) => unsafe { Ok(x.as_ref().enable_nagle.into()) },
49+
None => unsupported(),
50+
}
51+
}
52+
}
53+
}
54+
55+
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
56+
match self {
57+
Self::V4(client) => client.get_mode_data().map(|x| {
58+
SocketAddr::new(
59+
helpers::ipv4_from_r_efi(x.access_point.remote_address).into(),
60+
x.access_point.remote_port,
61+
)
62+
}),
63+
}
64+
}
65+
66+
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
67+
match self {
68+
Self::V4(client) => client.get_mode_data().map(|x| {
69+
SocketAddr::new(
70+
helpers::ipv4_from_r_efi(x.access_point.station_address).into(),
71+
x.access_point.station_port,
72+
)
73+
}),
74+
}
75+
}
3476
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use r_efi::efi::{self, Status};
22
use r_efi::protocols::tcp4;
33

44
use crate::io;
5+
use crate::mem::MaybeUninit;
56
use crate::net::SocketAddrV4;
67
use crate::ptr::NonNull;
78
use crate::sync::atomic::{AtomicBool, Ordering};
@@ -67,6 +68,29 @@ impl Tcp4 {
6768
if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
6869
}
6970

71+
pub(crate) fn get_mode_data(&self) -> io::Result<tcp4::ConfigData> {
72+
// Using MaybeUninit::uninit() generates a Page Fault Here
73+
let mut config_data: MaybeUninit<tcp4::ConfigData> = MaybeUninit::zeroed();
74+
let protocol = self.protocol.as_ptr();
75+
76+
let r = unsafe {
77+
((*protocol).get_mode_data)(
78+
protocol,
79+
crate::ptr::null_mut(),
80+
config_data.as_mut_ptr(),
81+
crate::ptr::null_mut(),
82+
crate::ptr::null_mut(),
83+
crate::ptr::null_mut(),
84+
)
85+
};
86+
87+
if r.is_error() {
88+
return Err(io::Error::from_raw_os_error(r.as_usize()));
89+
} else {
90+
Ok(unsafe { config_data.assume_init() })
91+
}
92+
}
93+
7094
pub(crate) fn connect(&self, timeout: Option<Duration>) -> io::Result<()> {
7195
let evt = unsafe { self.create_evt() }?;
7296
let completion_token =

library/std/src/sys/pal/uefi/helpers.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,3 +761,7 @@ impl Drop for OwnedEvent {
761761
pub(crate) const fn ipv4_to_r_efi(addr: crate::net::Ipv4Addr) -> efi::Ipv4Address {
762762
efi::Ipv4Address { addr: addr.octets() }
763763
}
764+
765+
pub(crate) const fn ipv4_from_r_efi(ip: efi::Ipv4Address) -> crate::net::Ipv4Addr {
766+
crate::net::Ipv4Addr::new(ip.addr[0], ip.addr[1], ip.addr[2], ip.addr[3])
767+
}

0 commit comments

Comments
 (0)