(mut a: A, mut b: B, config: &ProxyConfig)
| 91 | } |
| 92 | |
| 93 | pub(crate) async fn bridge<A, B>(mut a: A, mut b: B, config: &ProxyConfig) -> Result<()> |
| 94 | where |
| 95 | A: AsyncRead + AsyncWrite + Unpin, |
| 96 | B: AsyncRead + AsyncWrite + Unpin, |
| 97 | { |
| 98 | let buf_size = config.buffer_size; |
| 99 | if !config.timeouts.data_timeout_enabled { |
| 100 | debug!("copying bidirectionally"); |
| 101 | tokio::io::copy_bidirectional_with_sizes(&mut a, &mut b, buf_size, buf_size) |
| 102 | .await |
| 103 | .context("failed to copy")?; |
| 104 | return Ok(()); |
| 105 | } |
| 106 | |
| 107 | let (mut ra, mut wa) = tokio::io::split(a); |
| 108 | let (mut rb, mut wb) = tokio::io::split(b); |
| 109 | |
| 110 | let mut a2b = OneDirection { |
| 111 | dir: "a2b", |
| 112 | cfg: config, |
| 113 | buf: BytesMut::with_capacity(buf_size), |
| 114 | reader: &mut ra, |
| 115 | writer: &mut wb, |
| 116 | next_step: NextStep::Read, |
| 117 | }; |
| 118 | let mut b2a = OneDirection { |
| 119 | dir: "b2a", |
| 120 | cfg: config, |
| 121 | buf: BytesMut::with_capacity(buf_size), |
| 122 | reader: &mut rb, |
| 123 | writer: &mut wa, |
| 124 | next_step: NextStep::Read, |
| 125 | }; |
| 126 | |
| 127 | let mut rest; |
| 128 | // Transfer data between a and b bidirectionally. |
| 129 | loop { |
| 130 | tokio::select! { |
| 131 | done = a2b.step() => { |
| 132 | if done? { |
| 133 | // a to b is EOF, switch to b to a only |
| 134 | rest = Rest::B2a(b2a); |
| 135 | drop(a2b); |
| 136 | break; |
| 137 | } |
| 138 | } |
| 139 | done = b2a.step() => { |
| 140 | if done? { |
| 141 | // b to a is EOF, switch to a to b only |
| 142 | rest = Rest::A2b(a2b); |
| 143 | drop(b2a); |
| 144 | break; |
| 145 | } |
| 146 | } |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | // One of the direction is closed, copy the other direction. |
no test coverage detected