diff --git a/Cargo.lock b/Cargo.lock index b00ebad..5f245df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3056,7 +3056,7 @@ dependencies = [ [[package]] name = "ruci-cmd" -version = "0.0.5" +version = "0.0.6" dependencies = [ "TinyUFO", "anyhow", @@ -3113,7 +3113,7 @@ dependencies = [ [[package]] name = "rucimp" -version = "0.0.7" +version = "0.0.8" dependencies = [ "anyhow", "array-init", diff --git a/crates/ruci-cmd/Cargo.toml b/crates/ruci-cmd/Cargo.toml index e24492c..6e76b96 100644 --- a/crates/ruci-cmd/Cargo.toml +++ b/crates/ruci-cmd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ruci-cmd" -version = "0.0.5" +version = "0.0.6" edition = "2021" license = "MIT OR Apache-2.0" diff --git a/dev_res/local.lua b/dev_res/local.lua index e3041f6..774c2b8 100644 --- a/dev_res/local.lua +++ b/dev_res/local.lua @@ -1005,7 +1005,7 @@ local config_26_chain_mitm_embedder = { } }, { Embedder = { file_name = "record_dir1/1-2_mitm_ruci_info.json" } }, - { Trojan = { password = "mypassword", do_not_use_early_data = true } } + { Trojan = { password = "mypassword", do_not_use_early_data = false } } } } } } diff --git a/doc/book/src/index.md b/doc/book/src/index.md index d37afcf..794f4a4 100644 --- a/doc/book/src/index.md +++ b/doc/book/src/index.md @@ -12,4 +12,4 @@ 让我们开始吧! [入门](get_started.md) -本手册基于 ruci v0.0.7 制作 +本手册基于 ruci v0.0.8 制作 diff --git a/rucimp/Cargo.toml b/rucimp/Cargo.toml index 1b12860..e290167 100644 --- a/rucimp/Cargo.toml +++ b/rucimp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rucimp" -version = "0.0.7" +version = "0.0.8" edition = "2021" [dependencies] diff --git a/rucimp/src/map/steganography/embed/mod.rs b/rucimp/src/map/steganography/embed/mod.rs index 6e9751f..bcf1110 100644 --- a/rucimp/src/map/steganography/embed/mod.rs +++ b/rucimp/src/map/steganography/embed/mod.rs @@ -521,6 +521,7 @@ impl AsyncWrite for EmbedConn { match self.write_state.take() { None => { + debug!("write buf when write_state is None"); let r = self.write_buf(cur_info, cx, buf, false); match ready!(r) { WriteBufResult::Continue => { diff --git a/src/map/trojan/client.rs b/src/map/trojan/client.rs index 0a2d37b..bc55540 100644 --- a/src/map/trojan/client.rs +++ b/src/map/trojan/client.rs @@ -7,7 +7,7 @@ use tokio::io::AsyncWriteExt; use tracing::debug; use crate::{ - map::{self, helpers::EarlyDataWrapper, Map, MapExt, MapResult, CID}, + map::{self, Map, MapExt, MapResult, CID}, net::{self, helpers, Network}, utils::ob_to_buf, }; @@ -74,23 +74,22 @@ impl Client { if self.do_not_use_early_data { debug!( "trojan client writing buf(not with early data) {}", - &buf[..50.min(buf.len())].escape_ascii() + buf.len() ); + base.write_all(&buf).await?; base.flush().await?; - debug!("trojan client write done"); if is_udp { let u = udp::from(base); Ok(MapResult::new_u(u).b(first_payload).a(Some(ta)).build()) } else { let b = ob_to_buf(first_payload); - if b.is_empty() || !self.is_tail_of_chain() { + + if b.is_empty() { Ok(MapResult::new_c(base).build()) } else { - debug!("trojan client using EarlyDataWrapper, {}", b.len()); - let ec = EarlyDataWrapper::from(b, base); - Ok(MapResult::new_c(Box::new(ec)).build()) + Ok(MapResult::new_c(base).b(Some(b)).build()) } } } else { @@ -105,13 +104,13 @@ impl Client { } } - debug!( - "trojan client writing buf {}", - &buf[..50.min(buf.len())].escape_ascii() - ); + // debug!( + // "trojan client writing buf {}", + // &buf[..50.min(buf.len())].escape_ascii() + // ); base.write_all(&buf).await?; base.flush().await?; - debug!("trojan client write done"); + // debug!("trojan client write done"); if is_udp { let u = udp::from(base); diff --git a/src/net/helpers/mod.rs b/src/net/helpers/mod.rs index b8e9b4b..c7a8e5b 100644 --- a/src/net/helpers/mod.rs +++ b/src/net/helpers/mod.rs @@ -216,7 +216,7 @@ impl AsyncWrite for RWWrapper } } -/// wrap base connection with an early data buffer, read from +/// wrap base connection with an early data buffer, READ from /// the buffer first. pub struct EarlyDataWrapper { ed: Option, @@ -244,8 +244,8 @@ impl AsyncRead for EarlyDataWrapper { Some(ed) => { let el = ed.len(); if el > 0 { + // debug!("EarlyDataWrapper read from ed, {}", el); let m = min(el, buf.initialized().len()); - //buf.set_filled(m); buf.put(&ed[..m]); ed.advance(m); if ed.is_empty() { @@ -285,6 +285,77 @@ impl AsyncWrite for EarlyDataWrapper { } } +pub struct EarlyWriteDataWrapper { + ed: Option, + base: Pin, +} + +impl EarlyWriteDataWrapper { + pub fn from(bs: BytesMut, conn: Conn) -> Self { + EarlyWriteDataWrapper { + ed: if bs.is_empty() { None } else { Some(bs) }, + base: Box::pin(conn), + } + } +} + +impl AsyncRead for EarlyWriteDataWrapper { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + self.base.as_mut().poll_read(cx, buf) + } +} + +impl AsyncWrite for EarlyWriteDataWrapper { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &[u8], + ) -> Poll> { + loop { + match self.ed.take() { + None => return self.base.as_mut().poll_write(cx, buf), + + Some(ed) => { + let edl = ed.len(); + let r = self.base.as_mut().poll_write(cx, &ed); + self.ed = Some(ed); + match ready!(r) { + Ok(n) => { + if n == edl { + self.ed = None; + } else { + let mut ed = self.ed.take().unwrap(); + ed.advance(n); + self.ed = Some(ed); + } + continue; + } + Err(e) => return Poll::Ready(Err(e)), + } + } + } + } + } + + fn poll_flush( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + self.base.as_mut().poll_flush(cx) + } + + fn poll_shutdown( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + self.base.as_mut().poll_shutdown(cx) + } +} + pub enum BytesDisplayMode { UTF8, Bytes,