Added `ReverseSink<R>`, temporary type for handling reads (chacha20stream currently only has a wrapper type for writes.)

Fortune for rsh's current commit: Curse − 凶
exchange-unsafe
Avril 3 years ago
parent 62f3c384b2
commit 7216f0f8de
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -16,10 +16,17 @@ use tokio::{
RwLock, RwLock,
}, },
io::{ io::{
self,
DuplexStream, DuplexStream,
}, },
}; };
use std::{
io,
task::{
Context, Poll,
},
pin::Pin,
marker::Unpin,
};
/// Encrypted socket information. /// Encrypted socket information.
#[derive(Debug)] #[derive(Debug)]
@ -28,6 +35,50 @@ struct ESockInfo {
them: Option<RsaPublicKey>, them: Option<RsaPublicKey>,
} }
/// A shitty way of reversing `AsyncSink`
//TODO: Implement a decrypting reader in `chacha20stream`.
#[pin_project]
#[derive(Debug)]
struct ReverseSink<R: ?Sized> {
#[pin] temp_sink: AsyncSink<DuplexStream>,
#[pin] rx: DuplexStream,
#[pin] raw: R,
}
impl<R: AsyncRead + ?Sized> AsyncRead for ReverseSink<R>
{
fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<io::Result<usize>> {
let proj = self.project();
use futures::ready;
macro_rules! try_ready {
($poll_res:expr) => {
match ready!($poll_res) {
Ok(v) => v,
Err(e) => return Poll::Ready(Err(e)),
}
}
}
alloc_local_bytes(buf.len(), |temp_buf| -> Poll<io::Result<usize>> {
//XXX: Does this work? I dunno... Maybe just pin and poll a local `async{}` block.
// Read encrypted bytes into `temp_buf`.
let filled_buffer: &[u8] = try_ready!(proj.raw.poll_read(cx, temp_buf).map_ok(|read| {
&temp_buf[..read]
}));
// Sink the `filled_buffer`.
let sunk: usize = try_ready!(proj.temp_sink.poll_write(cx, filled_buffer));
debug_assert_eq!(sunk, filled_buffer.len());
// Ready from the `rx`.
let bytes_read: usize = try_ready!(proj.rx.poll_read(cx, &mut buf[..sunk]));
debug_assert_eq!(bytes_read, sunk);
Poll::Ready(Ok(bytes_read))
})
}
}
/// A tx+rx socket. /// A tx+rx socket.
#[pin_project] #[pin_project]
#[derive(Debug)] #[derive(Debug)]
@ -51,8 +102,6 @@ pub struct ESockWriteHalf<W>(Arc<ESockInfo>, #[pin] AsyncSink<W>);
#[derive(Debug)] #[derive(Debug)]
pub struct ESockReadHalf<R>( pub struct ESockReadHalf<R>(
Arc<ESockInfo>, Arc<ESockInfo>,
#[pin] R, // read from this (raw.) #[pin] ReverseSink<R>,
#[pin] AsyncSink<DuplexStream>, // sink raw from `R` here, outputs decrypted bytes into next.
#[pin] DuplexStream, // read decrypted bytes from here.
); );

Loading…
Cancel
Save