about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2025-07-24 15:08:20 +0200
committerGitHub <noreply@github.com>2025-07-24 15:08:20 +0200
commit319d54f3ecc3ab002119e6d8ebecf730de80f3ff (patch)
tree6fcf0822a137f452bf4eb5548ffad22a89cc5a89 /library/std/src/sys
parent404f904f76531a43246c74e291e199a14b456f68 (diff)
parenteb9c65476c9dbcf90d67e938218731f58e6c699a (diff)
downloadrust-319d54f3ecc3ab002119e6d8ebecf730de80f3ff.tar.gz
rust-319d54f3ecc3ab002119e6d8ebecf730de80f3ff.zip
Rollup merge of #143838 - Ayush1325:uefi-tcp4-config-data, r=tgross35
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`.
- cc `````@nicholasbishop`````
- Also a heads up. The UEFI spec seems to be wrong or something for [EFI_TCP4_CONFIG_DATA](https://uefi.org/specs/UEFI/2.11/28_Network_Protocols_TCP_IP_and_Configuration.html#efi-tcp4-protocol-getmodedata). `ControlOption` should be a pointer as seen in [edk2](https://github.com/tianocore/edk2/blob/a1b509c1a453815acbc6c8b0fc5882fd03a6f2c0/MdePkg/Include/Protocol/Tcp4.h#L97).
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/net/connection/uefi/mod.rs32
-rw-r--r--library/std/src/sys/net/connection/uefi/tcp.rs42
-rw-r--r--library/std/src/sys/net/connection/uefi/tcp4.rs18
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs4
4 files changed, 81 insertions, 15 deletions
diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs
index 884cbd4ac1d..16e3487a174 100644
--- a/library/std/src/sys/net/connection/uefi/mod.rs
+++ b/library/std/src/sys/net/connection/uefi/mod.rs
@@ -86,11 +86,11 @@ impl TcpStream {
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        unsupported()
+        self.inner.peer_addr()
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        unsupported()
+        self.inner.socket_addr()
     }
 
     pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
@@ -114,7 +114,7 @@ impl TcpStream {
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        unsupported()
+        self.inner.nodelay()
     }
 
     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
@@ -122,7 +122,7 @@ impl TcpStream {
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        unsupported()
+        self.inner.ttl()
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
@@ -140,7 +140,9 @@ impl fmt::Debug for TcpStream {
     }
 }
 
-pub struct TcpListener(!);
+pub struct TcpListener {
+    inner: tcp::Tcp,
+}
 
 impl TcpListener {
     pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
@@ -148,45 +150,45 @@ impl TcpListener {
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        self.0
+        unsupported()
     }
 
     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
-        self.0
+        unsupported()
     }
 
     pub fn duplicate(&self) -> io::Result<TcpListener> {
-        self.0
+        unsupported()
     }
 
     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        self.0
+        unsupported()
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        self.0
+        self.inner.ttl()
     }
 
     pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
-        self.0
+        unsupported()
     }
 
     pub fn only_v6(&self) -> io::Result<bool> {
-        self.0
+        unsupported()
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        self.0
+        unsupported()
     }
 
     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        self.0
+        unsupported()
     }
 }
 
 impl fmt::Debug for TcpListener {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0
+        todo!()
     }
 }
 
diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs
index 1152f69446e..aac97007bbf 100644
--- a/library/std/src/sys/net/connection/uefi/tcp.rs
+++ b/library/std/src/sys/net/connection/uefi/tcp.rs
@@ -1,6 +1,8 @@
 use super::tcp4;
 use crate::io;
 use crate::net::SocketAddr;
+use crate::ptr::NonNull;
+use crate::sys::{helpers, unsupported};
 use crate::time::Duration;
 
 pub(crate) enum Tcp {
@@ -31,4 +33,44 @@ impl Tcp {
             Self::V4(client) => client.read(buf, timeout),
         }
     }
+
+    pub(crate) fn ttl(&self) -> io::Result<u32> {
+        match self {
+            Self::V4(client) => client.get_mode_data().map(|x| x.time_to_live.into()),
+        }
+    }
+
+    pub(crate) fn nodelay(&self) -> io::Result<bool> {
+        match self {
+            Self::V4(client) => {
+                let temp = client.get_mode_data()?;
+                match NonNull::new(temp.control_option) {
+                    Some(x) => unsafe { Ok(x.as_ref().enable_nagle.into()) },
+                    None => unsupported(),
+                }
+            }
+        }
+    }
+
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        match self {
+            Self::V4(client) => client.get_mode_data().map(|x| {
+                SocketAddr::new(
+                    helpers::ipv4_from_r_efi(x.access_point.remote_address).into(),
+                    x.access_point.remote_port,
+                )
+            }),
+        }
+    }
+
+    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+        match self {
+            Self::V4(client) => client.get_mode_data().map(|x| {
+                SocketAddr::new(
+                    helpers::ipv4_from_r_efi(x.access_point.station_address).into(),
+                    x.access_point.station_port,
+                )
+            }),
+        }
+    }
 }
diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs
index 6342718929a..75862ff247b 100644
--- a/library/std/src/sys/net/connection/uefi/tcp4.rs
+++ b/library/std/src/sys/net/connection/uefi/tcp4.rs
@@ -67,6 +67,24 @@ impl Tcp4 {
         if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
     }
 
+    pub(crate) fn get_mode_data(&self) -> io::Result<tcp4::ConfigData> {
+        let mut config_data = tcp4::ConfigData::default();
+        let protocol = self.protocol.as_ptr();
+
+        let r = unsafe {
+            ((*protocol).get_mode_data)(
+                protocol,
+                crate::ptr::null_mut(),
+                &mut config_data,
+                crate::ptr::null_mut(),
+                crate::ptr::null_mut(),
+                crate::ptr::null_mut(),
+            )
+        };
+
+        if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(config_data) }
+    }
+
     pub(crate) fn connect(&self, timeout: Option<Duration>) -> io::Result<()> {
         let evt = unsafe { self.create_evt() }?;
         let completion_token =
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index 420481648a7..271dc4d11de 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -761,3 +761,7 @@ impl Drop for OwnedEvent {
 pub(crate) const fn ipv4_to_r_efi(addr: crate::net::Ipv4Addr) -> efi::Ipv4Address {
     efi::Ipv4Address { addr: addr.octets() }
 }
+
+pub(crate) const fn ipv4_from_r_efi(ip: efi::Ipv4Address) -> crate::net::Ipv4Addr {
+    crate::net::Ipv4Addr::new(ip.addr[0], ip.addr[1], ip.addr[2], ip.addr[3])
+}