Skip to content

Commit 195633a

Browse files
committed
Improve TCP
1. Fix Handling connection closed by client. a. In Windows and Unix, 0-sized read requests succeed even after connection has been closed. 2. Implement timeouts using timer event. 3. Replace `unimplemented!()` and `todo!()` with `unsupported()`. 4. Fix handling u32 limits in size of vectored read/writes 5. Performance Enhancements: Create events for different actions only once. Signed-off-by: Ayush Singh <[email protected]>
1 parent dae6b19 commit 195633a

File tree

4 files changed

+473
-245
lines changed

4 files changed

+473
-245
lines changed

library/std/src/sys/uefi/common.rs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,56 @@ impl Event {
6363
}
6464
}
6565

66+
pub(crate) fn create_timer() -> io::Result<Event> {
67+
Self::create(
68+
r_efi::efi::EVT_TIMER | r_efi::efi::EVT_NOTIFY_WAIT,
69+
r_efi::efi::TPL_CALLBACK,
70+
Some(empty_notify),
71+
None,
72+
)
73+
}
74+
75+
fn set_timer(&self, timeout: u64) -> io::Result<()> {
76+
let boot_services = boot_services();
77+
let r = unsafe {
78+
((*boot_services.as_ptr()).set_timer)(
79+
self.as_raw_event(),
80+
r_efi::efi::TIMER_RELATIVE,
81+
timeout,
82+
)
83+
};
84+
if r.is_error() { Err(status_to_io_error(r)) } else { Ok(()) }
85+
}
86+
87+
// timeout is the number of 100ns
88+
pub(crate) fn wait_with_timer(&self, timer_event: &Event, timeout: u64) -> io::Result<()> {
89+
timer_event.set_timer(timeout)?;
90+
let index = Self::wait_raw(&mut [self.as_raw_event(), timer_event.as_raw_event()])?;
91+
match index {
92+
0 => Ok(()),
93+
1 => Err(io::const_io_error!(io::ErrorKind::TimedOut, "Event Timout")),
94+
_ => unreachable!(),
95+
}
96+
}
97+
6698
pub(crate) fn wait(&self) -> io::Result<()> {
99+
Self::wait_raw(&mut [self.as_raw_event()])?;
100+
Ok(())
101+
}
102+
103+
fn wait_raw(events: &mut [*mut crate::ffi::c_void]) -> io::Result<usize> {
67104
let boot_services = boot_services();
68105

69106
let mut index = 0usize;
70107
let r = unsafe {
71108
((*boot_services.as_ptr()).wait_for_event)(
72-
1,
73-
[self.as_raw_event()].as_mut_ptr(),
109+
events.len(),
110+
events.as_mut_ptr(),
74111
&mut index,
75112
)
76113
};
77114

78-
if r.is_error() { Err(status_to_io_error(r)) } else { Ok(()) }
115+
if r.is_error() { Err(status_to_io_error(r)) } else { Ok(index) }
79116
}
80117

81118
#[inline]
@@ -84,6 +121,8 @@ impl Event {
84121
}
85122
}
86123

124+
extern "efiapi" fn empty_notify(_: r_efi::efi::Event, _: *mut crate::ffi::c_void) {}
125+
87126
impl Drop for Event {
88127
fn drop(&mut self) {
89128
let boot_services = boot_services();
@@ -277,7 +316,7 @@ pub(crate) fn status_to_io_error(s: r_efi::efi::Status) -> io::Error {
277316
const_io_error!(ErrorKind::Other, "EFI_COMPRIMISED_DATA")
278317
}
279318
Status::CONNECTION_FIN => {
280-
const_io_error!(ErrorKind::ConnectionAborted, "EFI_CONNECTION_FIN")
319+
const_io_error!(ErrorKind::Other, "EFI_CONNECTION_FIN")
281320
}
282321
Status::CONNECTION_REFUSED => {
283322
const_io_error!(ErrorKind::ConnectionRefused, "EFI_CONNECTION_REFUSED")

library/std/src/sys/uefi/net/implementation.rs

Lines changed: 68 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,27 @@ impl TcpStream {
2020
Ok(Self { inner })
2121
}
2222

23-
pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
24-
todo!()
23+
pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
24+
let timeout = u64::try_from(timeout.as_nanos() / 100)
25+
.map_err(|_| io::const_io_error!(io::ErrorKind::InvalidInput, "timeout is too long"))?;
26+
let inner = uefi_tcp::TcpProtocol::connect_timeout(addr, timeout)?;
27+
Ok(Self { inner })
2528
}
2629

27-
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
28-
unimplemented!()
30+
pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
31+
self.inner.set_read_timeout(timeout)
2932
}
3033

31-
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
32-
unimplemented!()
34+
pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
35+
self.inner.set_write_timeout(timeout)
3336
}
3437

35-
// Possible to implement while waiting for event
3638
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
37-
Ok(None)
39+
self.inner.read_timeout()
3840
}
3941

40-
// Possible to implement while waiting for event
4142
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
42-
Ok(None)
43+
self.inner.write_timeout()
4344
}
4445

4546
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
@@ -88,16 +89,15 @@ impl TcpStream {
8889
unsupported()
8990
}
9091

91-
// Seems to be similar to abort_on_close option in `EFI_TCP6_PROTOCOL->Close()`
9292
pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> {
93-
todo!()
93+
unsupported()
9494
}
9595

9696
pub fn linger(&self) -> io::Result<Option<Duration>> {
97-
todo!()
97+
unsupported()
9898
}
9999

100-
// Seems to be similar to `EFI_TCP6_OPTION->EnableNagle`
100+
// UEFI doesn't seem to allow configure for active connections
101101
pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
102102
unsupported()
103103
}
@@ -106,26 +106,34 @@ impl TcpStream {
106106
self.inner.nodelay()
107107
}
108108

109-
pub fn set_ttl(&self, x: u32) -> io::Result<()> {
110-
self.inner.set_ttl(x)
109+
// UEFI doesn't seem to allow configure for active connections
110+
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
111+
unsupported()
111112
}
112113

113114
pub fn ttl(&self) -> io::Result<u32> {
114115
self.inner.ttl()
115116
}
116117

117118
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
118-
unimplemented!()
119+
unsupported()
119120
}
120121

121122
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
122-
todo!()
123+
unsupported()
123124
}
124125
}
125126

126127
impl fmt::Debug for TcpStream {
127-
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
128-
todo!()
128+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129+
let mut res = f.debug_struct("TcpStream");
130+
if let Ok(addr) = self.socket_addr() {
131+
res.field("addr", &addr);
132+
}
133+
if let Ok(peer) = self.peer_addr() {
134+
res.field("peer", &peer);
135+
}
136+
res.finish()
129137
}
130138
}
131139

@@ -165,154 +173,158 @@ impl TcpListener {
165173
}
166174

167175
pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
168-
unimplemented!()
176+
unsupported()
169177
}
170178

171179
pub fn only_v6(&self) -> io::Result<bool> {
172180
Ok(false)
173181
}
174182

175183
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
176-
unimplemented!()
184+
unsupported()
177185
}
178186

179187
// Internally TCP Protocol is nonblocking
180188
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
181-
todo!()
189+
unsupported()
182190
}
183191
}
184192

185193
impl fmt::Debug for TcpListener {
186-
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
187-
todo!()
194+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195+
let mut res = f.debug_struct("TcpListener");
196+
if let Ok(addr) = self.socket_addr() {
197+
res.field("addr", &addr);
198+
}
199+
res.finish()
188200
}
189201
}
190202

191203
pub struct UdpSocket {}
192204

193205
impl UdpSocket {
194206
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
195-
unimplemented!()
207+
unsupported()
196208
}
197209

198210
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
199-
unimplemented!()
211+
unsupported()
200212
}
201213

202214
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
203-
unimplemented!()
215+
unsupported()
204216
}
205217

206218
pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
207-
unimplemented!()
219+
unsupported()
208220
}
209221

210222
pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
211-
unimplemented!()
223+
unsupported()
212224
}
213225

214226
pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
215-
unimplemented!()
227+
unsupported()
216228
}
217229

218230
pub fn duplicate(&self) -> io::Result<UdpSocket> {
219-
unimplemented!()
231+
unsupported()
220232
}
221233

222234
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
223-
unimplemented!()
235+
unsupported()
224236
}
225237

226238
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
227-
unimplemented!()
239+
unsupported()
228240
}
229241

230242
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
231-
unimplemented!()
243+
unsupported()
232244
}
233245

234246
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
235-
unimplemented!()
247+
unsupported()
236248
}
237249

238250
pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
239-
unimplemented!()
251+
unsupported()
240252
}
241253

242254
pub fn broadcast(&self) -> io::Result<bool> {
243-
unimplemented!()
255+
unsupported()
244256
}
245257

246258
pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
247-
unimplemented!()
259+
unsupported()
248260
}
249261

250262
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
251-
unimplemented!()
263+
unsupported()
252264
}
253265

254266
pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
255-
unimplemented!()
267+
unsupported()
256268
}
257269

258270
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
259-
unimplemented!()
271+
unsupported()
260272
}
261273

262274
pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
263-
unimplemented!()
275+
unsupported()
264276
}
265277

266278
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
267-
unimplemented!()
279+
unsupported()
268280
}
269281

270282
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
271-
unimplemented!()
283+
unsupported()
272284
}
273285

274286
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
275-
unimplemented!()
287+
unsupported()
276288
}
277289

278290
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
279-
unimplemented!()
291+
unsupported()
280292
}
281293

282294
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
283-
unimplemented!()
295+
unsupported()
284296
}
285297

286298
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
287-
unimplemented!()
299+
unsupported()
288300
}
289301

290302
pub fn ttl(&self) -> io::Result<u32> {
291-
unimplemented!()
303+
unsupported()
292304
}
293305

294306
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
295-
unimplemented!()
307+
unsupported()
296308
}
297309

298310
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
299-
unimplemented!()
311+
unsupported()
300312
}
301313

302314
pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
303-
unimplemented!()
315+
unsupported()
304316
}
305317

306318
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
307-
unimplemented!()
319+
unsupported()
308320
}
309321

310322
pub fn send(&self, _: &[u8]) -> io::Result<usize> {
311-
unimplemented!()
323+
unsupported()
312324
}
313325

314326
pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
315-
unimplemented!()
327+
unsupported()
316328
}
317329
}
318330

0 commit comments

Comments
 (0)