Using AsyncSource instead of dump Duplex hack.

Fortune for rsh's current commit: Future small blessing − 末小吉
exchange-unsafe
Avril 3 years ago
parent 7f8acbba7f
commit d349c018c2
Signed by: flanchan
GPG Key ID: 284488987C31F630

4
Cargo.lock generated

@ -106,9 +106,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "chacha20stream" name = "chacha20stream"
version = "2.0.0" version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a27e1b4a96dea2045de11b4c72d5717f84acd73de7133f3ee6005244d838d56" checksum = "b5b34f4279658654cc2c7dbb36ba00b620dd5532153a9b9ebfea1b7ef282e1d4"
dependencies = [ dependencies = [
"base64 0.13.0", "base64 0.13.0",
"getrandom 0.2.3", "getrandom 0.2.3",

@ -7,7 +7,7 @@ edition = "2018"
[dependencies] [dependencies]
bytes = { version = "1.0.1", features = ["serde"] } bytes = { version = "1.0.1", features = ["serde"] }
chacha20stream = { version = "2.0", features = ["async"] } chacha20stream = { version = "2.0.1", features = ["async"] }
color-eyre = "0.5.11" color-eyre = "0.5.11"
cryptohelpers = { version = "1.8.1" , features = ["serialise", "full"] } cryptohelpers = { version = "1.8.1" , features = ["serialise", "full"] }
futures = "0.3.16" futures = "0.3.16"

@ -9,6 +9,7 @@ use cryptohelpers::{
}; };
use chacha20stream::{ use chacha20stream::{
AsyncSink, AsyncSink,
AsyncSource,
}; };
use std::sync::Arc; use std::sync::Arc;
use tokio::{ use tokio::{
@ -35,50 +36,6 @@ 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 (this doesn't work, because `raw` needs to be `Unpin`... sigh....).
// 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)]
@ -100,8 +57,4 @@ pub struct ESockWriteHalf<W>(Arc<ESockInfo>, #[pin] AsyncSink<W>);
/// Read half for `ESock`. /// Read half for `ESock`.
#[pin_project] #[pin_project]
#[derive(Debug)] #[derive(Debug)]
pub struct ESockReadHalf<R>( pub struct ESockReadHalf<R>(Arc<ESockInfo>, #[pin] AsyncSource<R>);
Arc<ESockInfo>,
#[pin] ReverseSink<R>,
);

Loading…
Cancel
Save