1use crate::{Read, Stream, Write};
10use std::collections::VecDeque;
11use std::io;
12use std::sync::{Arc, Condvar, Mutex, MutexGuard};
13use std::time::{Duration, Instant};
14
15pub type Duplex = Stream<Reader, Writer>;
17
18impl Duplex {
19 pub fn into_halves(self) -> (Reader, Writer) {
38 let (reader, writer, _, _) = self.into_parts();
39 (reader, writer)
40 }
41}
42
43pub fn duplex(capacity: usize) -> (Duplex, Duplex) {
68 assert!(capacity > 0, "duplex capacity must be nonzero");
69 let incoming = Arc::new(Pipe::new(capacity));
70 let outgoing = Arc::new(Pipe::new(capacity));
71 (
72 endpoint(incoming.clone(), outgoing.clone()),
73 endpoint(outgoing, incoming),
74 )
75}
76
77fn endpoint(incoming: Arc<Pipe>, outgoing: Arc<Pipe>) -> Duplex {
79 Stream::new(
80 Reader {
81 pipe: incoming.clone(),
82 deadline: None,
83 },
84 Writer {
85 pipe: outgoing.clone(),
86 deadline: None,
87 },
88 move || {
89 incoming.close_reader();
90 outgoing.close_writer();
91 },
92 )
93}
94
95#[derive(Debug)]
97pub struct Reader {
98 pipe: Arc<Pipe>,
99 deadline: Option<Instant>,
100}
101
102impl io::Read for Reader {
103 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
104 let mut state = self.pipe.lock();
105 loop {
106 if buf.is_empty() || !state.reader_open {
107 return Ok(0);
108 }
109 if !state.bytes.is_empty() {
110 let count = buf.len().min(state.bytes.len());
111 for (out, byte) in buf.iter_mut().zip(state.bytes.drain(..count)) {
112 *out = byte;
113 }
114 drop(state);
115 self.pipe.changed.notify_all();
116 return Ok(count);
117 }
118 if !state.writer_open {
119 return Ok(0);
120 }
121 state = self.pipe.wait(state, time_left(self.deadline)?);
122 }
123 }
124}
125
126impl Read for Reader {
127 fn set_read_deadline(&mut self, deadline: Option<Instant>) -> io::Result<()> {
128 self.deadline = deadline;
129 Ok(())
130 }
131}
132
133impl Drop for Reader {
134 fn drop(&mut self) {
135 self.pipe.close_reader();
136 }
137}
138
139#[derive(Debug)]
141pub struct Writer {
142 pipe: Arc<Pipe>,
143 deadline: Option<Instant>,
144}
145
146impl io::Write for Writer {
147 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
148 let mut state = self.pipe.lock();
149 loop {
150 let timeout = time_left(self.deadline)?;
151 if buf.is_empty() {
152 return Ok(0);
153 }
154 if !state.reader_open || !state.writer_open {
155 return Err(io::ErrorKind::BrokenPipe.into());
156 }
157 let count = buf.len().min(self.pipe.capacity - state.bytes.len());
158 if count > 0 {
159 state.bytes.extend(&buf[..count]);
160 drop(state);
161 self.pipe.changed.notify_all();
162 return Ok(count);
163 }
164 state = self.pipe.wait(state, timeout);
165 }
166 }
167
168 fn flush(&mut self) -> io::Result<()> {
169 let state = self.pipe.lock();
170 time_left(self.deadline)?;
171 if !state.writer_open || state.lost {
172 return Err(io::ErrorKind::BrokenPipe.into());
173 }
174 Ok(())
175 }
176}
177
178impl Write for Writer {
179 fn set_write_deadline(&mut self, deadline: Instant) -> io::Result<()> {
180 self.deadline = Some(deadline);
181 Ok(())
182 }
183}
184
185impl Drop for Writer {
186 fn drop(&mut self) {
187 self.pipe.close_writer();
188 }
189}
190
191#[derive(Debug)]
193struct Pipe {
194 capacity: usize,
195 state: Mutex<State>,
196 changed: Condvar,
197}
198
199#[derive(Debug)]
200struct State {
201 bytes: VecDeque<u8>,
202 reader_open: bool,
203 writer_open: bool,
204 lost: bool, #[cfg(test)]
206 waiting: usize,
207}
208
209impl Pipe {
210 fn new(capacity: usize) -> Self {
211 Self {
212 capacity,
213 state: Mutex::new(State {
214 bytes: VecDeque::with_capacity(capacity),
215 reader_open: true,
216 writer_open: true,
217 lost: false,
218 #[cfg(test)]
219 waiting: 0,
220 }),
221 changed: Condvar::new(),
222 }
223 }
224
225 fn lock(&self) -> MutexGuard<'_, State> {
226 self.state.lock().unwrap_or_else(|err| err.into_inner())
228 }
229
230 fn wait<'a>(
231 &self,
232 state: MutexGuard<'a, State>,
233 timeout: Option<Duration>,
234 ) -> MutexGuard<'a, State> {
235 #[cfg(test)]
236 let state = {
237 let mut state = state;
238 state.waiting += 1;
239 self.changed.notify_all();
240 state
241 };
242 let state = match timeout {
243 Some(timeout) => {
244 self.changed
245 .wait_timeout(state, timeout)
246 .unwrap_or_else(|err| err.into_inner())
247 .0
248 }
249 None => self
250 .changed
251 .wait(state)
252 .unwrap_or_else(|err| err.into_inner()),
253 };
254 #[cfg(test)]
255 let state = {
256 let mut state = state;
257 state.waiting -= 1;
258 state
259 };
260 state
261 }
262
263 fn close_reader(&self) {
264 let mut state = self.lock();
265 state.reader_open = false;
266 state.lost |= !state.bytes.is_empty();
267 state.bytes.clear();
268 drop(state);
269 self.changed.notify_all();
270 }
271
272 fn close_writer(&self) {
273 self.lock().writer_open = false;
274 self.changed.notify_all();
275 }
276}
277
278fn time_left(deadline: Option<Instant>) -> io::Result<Option<Duration>> {
280 deadline
281 .map(|deadline| {
282 deadline
283 .checked_duration_since(Instant::now())
284 .filter(|left| !left.is_zero())
285 .ok_or_else(|| io::ErrorKind::TimedOut.into())
286 })
287 .transpose()
288}
289
290#[cfg(test)]
291#[cfg_attr(coverage_nightly, coverage(off))]
292mod tests {
293 use super::*;
294 use crate::Closer;
295 use std::io::{Read as _, Write as _};
296 use std::sync::mpsc;
297 use std::thread;
298
299 const PATIENCE: Duration = Duration::from_secs(5);
300 const TIMEOUT: Duration = Duration::from_millis(50);
301
302 fn halves(stream: Duplex) -> (Reader, Writer, Closer) {
304 let closer = stream.closer();
305 let (reader, writer) = stream.into_halves();
306 (reader, writer, closer)
307 }
308
309 fn blocked(pipe: &Pipe) {
311 let deadline = Instant::now() + PATIENCE;
312 let mut state = pipe.lock();
313 while state.waiting == 0 {
314 let timeout = deadline.checked_duration_since(Instant::now()).unwrap();
315 state = pipe.changed.wait_timeout(state, timeout).unwrap().0;
316 }
317 }
318
319 #[test]
320 #[should_panic(expected = "duplex capacity must be nonzero")]
321 fn test_zero_capacity() {
322 duplex(0);
323 }
324
325 #[test]
328 fn test_byte_stream_and_independent_deadlines() {
329 let (host, ark) = duplex(4);
330 let (mut host_read, mut host_write, _host_close) = halves(host);
331 let (mut ark_read, mut ark_write, _ark_close) = halves(ark);
332
333 assert_eq!(host_read.read(&mut []).unwrap(), 0);
334 assert_eq!(host_write.write(b"abcdef").unwrap(), 4);
335 assert_eq!(host_write.write(&[]).unwrap(), 0);
336 host_write.flush().unwrap();
338 let mut first = [0; 2];
339 ark_read.read_exact(&mut first).unwrap();
340 assert_eq!(&first, b"ab");
341 host_write.write_all(b"ef").unwrap();
342 let mut rest = [0; 4];
343 ark_read.read_exact(&mut rest).unwrap();
344 assert_eq!(&rest, b"cdef");
345
346 ark_write.write_all(b"xy").unwrap();
347 host_read.set_read_deadline(Some(Instant::now())).unwrap();
348 host_read.read_exact(&mut first).unwrap();
349 assert_eq!(&first, b"xy");
350 assert_eq!(
351 host_read.read(&mut first).unwrap_err().kind(),
352 io::ErrorKind::TimedOut
353 );
354 assert_eq!(host_read.read(&mut []).unwrap(), 0);
355 host_write.write_all(b"q").unwrap();
356
357 host_write.set_write_deadline(Instant::now()).unwrap();
358 host_read.set_read_deadline(None).unwrap();
359 ark_write.write_all(b"uv").unwrap();
360 host_read.read_exact(&mut first).unwrap();
361 assert_eq!(&first, b"uv");
362 for bytes in [b"t".as_slice(), b""] {
363 assert_eq!(
364 host_write.write(bytes).unwrap_err().kind(),
365 io::ErrorKind::TimedOut
366 );
367 }
368 assert_eq!(
369 host_write.flush().unwrap_err().kind(),
370 io::ErrorKind::TimedOut
371 );
372
373 host_write
374 .set_write_deadline(Instant::now() + PATIENCE)
375 .unwrap();
376 host_write.write_all(b"rs").unwrap();
377 host_write.flush().unwrap();
378 let mut accepted = [0; 3];
379 ark_read.read_exact(&mut accepted).unwrap();
380 assert_eq!(&accepted, b"qrs");
381 }
382
383 #[test]
386 fn test_read_timeout_and_reuse() {
387 let (host, ark) = duplex(1);
388 let (mut reader, _host_write, _host_close) = halves(host);
389 let (_ark_read, mut writer, _ark_close) = halves(ark);
390 let pipe = reader.pipe.clone();
391 let (done, result) = mpsc::channel();
392 let timed = thread::spawn(move || {
393 let deadline = Instant::now() + TIMEOUT;
394 reader.set_read_deadline(Some(deadline)).unwrap();
395 let mut buf = [99];
396 let error = reader.read(&mut buf).unwrap_err();
397 assert!(Instant::now() >= deadline);
398 assert_eq!(buf, [99]);
399 done.send((reader, error.kind())).unwrap();
400 });
401 let (mut reader, kind) = result.recv_timeout(PATIENCE).unwrap();
402 timed.join().unwrap();
403 assert_eq!(kind, io::ErrorKind::TimedOut);
404
405 reader.set_read_deadline(None).unwrap();
406 let (done, result) = mpsc::channel();
407 let reading = thread::spawn(move || {
408 let mut buf = [0];
409 reader.read_exact(&mut buf).unwrap();
410 done.send(buf).unwrap();
411 });
412 blocked(&pipe);
413 writer.write_all(b"x").unwrap();
414 assert_eq!(&result.recv_timeout(PATIENCE).unwrap(), b"x");
415 reading.join().unwrap();
416 }
417
418 #[test]
421 fn test_write_timeout_and_reuse() {
422 let (host, ark) = duplex(3);
423 let (_host_read, mut writer, _host_close) = halves(host);
424 let (mut reader, _ark_write, _ark_close) = halves(ark);
425 let (done, result) = mpsc::channel();
426 let writing = thread::spawn(move || {
427 let deadline = Instant::now() + TIMEOUT;
428 writer.set_write_deadline(deadline).unwrap();
429 let error = writer.write_all(b"abcd").unwrap_err();
430 assert!(Instant::now() >= deadline);
431 done.send((writer, error.kind())).unwrap();
432 });
433 let (mut writer, kind) = result.recv_timeout(PATIENCE).unwrap();
434 writing.join().unwrap();
435 assert_eq!(kind, io::ErrorKind::TimedOut);
436 let mut prefix = [0; 3];
437 reader.read_exact(&mut prefix).unwrap();
438 assert_eq!(&prefix, b"abc");
439
440 writer
441 .set_write_deadline(Instant::now() + PATIENCE)
442 .unwrap();
443 writer.write_all(b"ef").unwrap();
444 drop(writer);
445 let mut suffix = Vec::new();
446 reader.read_to_end(&mut suffix).unwrap();
447 assert_eq!(&suffix, b"ef");
448 }
449
450 #[test]
453 fn test_backpressure_wakes_writer() {
454 let (host, ark) = duplex(3);
455 let (_host_read, mut writer, _host_close) = halves(host);
456 let (mut reader, _ark_write, _ark_close) = halves(ark);
457 writer.write_all(b"abc").unwrap();
458 let pipe = writer.pipe.clone();
459 let (done, result) = mpsc::channel();
460 let writing = thread::spawn(move || {
461 writer
462 .set_write_deadline(Instant::now() + PATIENCE)
463 .unwrap();
464 done.send(writer.write_all(b"defgh")).unwrap();
465 });
466 blocked(&pipe);
467 reader
468 .set_read_deadline(Some(Instant::now() + PATIENCE))
469 .unwrap();
470 let mut bytes = [0; 8];
471 reader.read_exact(&mut bytes).unwrap();
472 assert_eq!(&bytes, b"abcdefgh");
473 result.recv_timeout(PATIENCE).unwrap().unwrap();
474 writing.join().unwrap();
475 }
476
477 #[test]
480 fn test_shutdown_wakes_both_directions() {
481 for local in [false, true] {
482 let (host, ark) = duplex(1);
483 let (mut reader, mut writer, closer) = halves(host);
484 writer.write_all(b"a").unwrap();
485 let incoming = reader.pipe.clone();
486 let outgoing = writer.pipe.clone();
487 let (read_done, read_result) = mpsc::channel();
488 let reading = thread::spawn(move || {
489 read_done.send(reader.read(&mut [0])).unwrap();
490 });
491 let (write_done, write_result) = mpsc::channel();
492 let writing = thread::spawn(move || {
493 write_done.send(writer.write(b"b")).unwrap();
494 });
495 blocked(&incoming);
496 blocked(&outgoing);
497 if local {
498 closer.close();
499 } else {
500 drop(ark);
501 }
502 assert_eq!(read_result.recv_timeout(PATIENCE).unwrap().unwrap(), 0);
503 assert_eq!(
504 write_result
505 .recv_timeout(PATIENCE)
506 .unwrap()
507 .unwrap_err()
508 .kind(),
509 io::ErrorKind::BrokenPipe
510 );
511 reading.join().unwrap();
512 writing.join().unwrap();
513 }
514 }
515
516 #[test]
519 fn test_shutdown_drains_output_and_discards_input() {
520 let (host, ark) = duplex(3);
521 let (mut host_read, mut host_write, closer) = halves(host);
522 let (mut ark_read, mut ark_write, _ark_close) = halves(ark);
523 host_write.write_all(b"abc").unwrap();
524 ark_write.write_all(b"xy").unwrap();
525 host_read.set_read_deadline(Some(Instant::now())).unwrap();
526 ark_read.set_read_deadline(Some(Instant::now())).unwrap();
527 closer.close();
528 closer.close();
529 assert_eq!(host_read.read(&mut [0]).unwrap(), 0);
530 let mut bytes = Vec::new();
531 ark_read.read_to_end(&mut bytes).unwrap();
532 assert_eq!(&bytes, b"abc");
533 for writer in [&mut host_write, &mut ark_write] {
534 assert_eq!(
535 writer.write(b"z").unwrap_err().kind(),
536 io::ErrorKind::BrokenPipe
537 );
538 assert_eq!(
539 writer.flush().unwrap_err().kind(),
540 io::ErrorKind::BrokenPipe
541 );
542 }
543 }
544
545 #[test]
548 fn test_flush_after_peer_drained_and_closed() {
549 let (host, ark) = duplex(4);
550 let (_host_read, mut host_write) = host.into_halves();
551 let (mut ark_read, _ark_write) = ark.into_halves();
552 host_write.write_all(b"ab").unwrap();
553 let mut bytes = [0; 2];
554 ark_read.read_exact(&mut bytes).unwrap();
555 drop(ark_read);
556 host_write.flush().unwrap();
557 assert_eq!(
558 host_write.write(b"c").unwrap_err().kind(),
559 io::ErrorKind::BrokenPipe
560 );
561 }
562
563 #[test]
566 fn test_into_halves_and_independent_drop() {
567 let (host, ark) = duplex(4);
568 let (mut host_read, mut host_write) = host.set_write_timeout(Duration::ZERO).into_halves();
569 let (mut ark_read, mut ark_write) = ark.into_halves();
570
571 host_write.write_all(b"abc").unwrap();
572 drop(host_write);
573 let mut bytes = Vec::new();
574 ark_read.read_to_end(&mut bytes).unwrap();
575 assert_eq!(&bytes, b"abc");
576
577 ark_write.write_all(b"xy").unwrap();
578 let mut reply = [0; 2];
579 host_read.read_exact(&mut reply).unwrap();
580 assert_eq!(&reply, b"xy");
581 drop(host_read);
582 assert_eq!(
583 ark_write.write(b"z").unwrap_err().kind(),
584 io::ErrorKind::BrokenPipe
585 );
586 }
587
588 #[test]
591 fn test_protocol_round_trip() {
592 use crate::protocol::{self, Message};
593 use crate::transport::mock::self_attestation;
594 use darkbio_crypto::xdsa;
595
596 let signer = xdsa::SecretKey::generate();
597 let identity = signer.public_key();
598 let attestation = self_attestation(&signer);
599 let (host, ark) = duplex(64 * 1024);
600 let mut server = protocol::Server::new(ark, signer, attestation);
601 let (client, _) = protocol::connect(host, &identity).unwrap();
602 let mut session = server.accept().unwrap();
603 let payload: Vec<u8> = (0..256 * 1024).map(|n| n as u8).collect();
604 let deadline = Instant::now() + PATIENCE;
605 let answer = client
606 .requester()
607 .request(payload.clone(), deadline)
608 .unwrap();
609 let (message, responder) = session.recv().unwrap();
610 assert_eq!(message, Message::Develop(payload.clone()));
611 let written = responder.reply(message, deadline).unwrap();
612 assert_eq!(answer.wait::<Vec<u8>>().unwrap(), payload);
613 written.wait().unwrap();
614 client.close();
615 server.close();
616 }
617}