|
| 1 | +use std::cell::RefCell; |
1 | 2 | use std::io::{self, Read, Write};
|
2 | 3 | use std::{any, cmp, future::poll_fn, ops::Deref, ops::DerefMut, task::ready, task::Poll};
|
3 | 4 |
|
|
22 | 23 | S: DerefMut + Deref<Target = ConnectionCommon<SD>>,
|
23 | 24 | SD: SideData,
|
24 | 25 | {
|
25 |
| - pub(crate) async fn handshake<F>(&mut self, io: &Io<F>) -> Result<(), io::Error> { |
26 |
| - let session = &mut self.session; |
27 |
| - |
28 |
| - loop { |
29 |
| - let result = io.with_buf(|buf| { |
30 |
| - let mut wrp = Wrapper(buf); |
31 |
| - let mut result = Err(io::Error::new(io::ErrorKind::WouldBlock, "")); |
32 |
| - |
33 |
| - while session.wants_write() { |
34 |
| - result = session.write_tls(&mut wrp).map(|_| ()); |
35 |
| - if result.is_err() { |
36 |
| - break; |
37 |
| - } |
38 |
| - } |
39 |
| - if session.wants_read() { |
40 |
| - let has_data = buf.with_read_buf(|rbuf| { |
41 |
| - rbuf.with_src(|b| { |
42 |
| - b.as_ref().map(|b| !b.is_empty()).unwrap_or_default() |
43 |
| - }) |
44 |
| - }); |
45 |
| - |
46 |
| - if has_data { |
47 |
| - result = match session.read_tls(&mut wrp) { |
48 |
| - Ok(0) => Err(io::Error::new( |
49 |
| - io::ErrorKind::NotConnected, |
50 |
| - "disconnected", |
51 |
| - )), |
52 |
| - Ok(_) => Ok(()), |
53 |
| - Err(e) => Err(e), |
54 |
| - }; |
55 |
| - |
56 |
| - session.process_new_packets().map_err(|err| { |
57 |
| - // In case we have an alert to send describing this error, |
58 |
| - // try a last-gasp write -- but don't predate the primary |
59 |
| - // error. |
60 |
| - let _ = session.write_tls(&mut wrp); |
61 |
| - io::Error::new(io::ErrorKind::InvalidData, err) |
62 |
| - })?; |
63 |
| - } else { |
64 |
| - result = Err(io::Error::new(io::ErrorKind::WouldBlock, "")); |
65 |
| - } |
66 |
| - } |
67 |
| - |
68 |
| - Ok::<_, io::Error>(result) |
69 |
| - })??; |
70 |
| - |
71 |
| - match result { |
72 |
| - Ok(()) => return Ok(()), |
73 |
| - Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { |
74 |
| - if !session.is_handshaking() { |
75 |
| - return Ok(()); |
76 |
| - } |
77 |
| - poll_fn(|cx| { |
78 |
| - match ready!(io.poll_read_notify(cx))? { |
79 |
| - Some(_) => Ok(()), |
80 |
| - None => Err(io::Error::new( |
81 |
| - io::ErrorKind::NotConnected, |
82 |
| - "disconnected", |
83 |
| - )), |
84 |
| - }?; |
85 |
| - Poll::Ready(Ok::<_, io::Error>(())) |
86 |
| - }) |
87 |
| - .await?; |
88 |
| - } |
89 |
| - Err(e) => return Err(e), |
90 |
| - } |
91 |
| - } |
92 |
| - } |
93 |
| - |
94 | 26 | pub(crate) fn query(&self, id: any::TypeId) -> Option<Box<dyn any::Any>> {
|
95 | 27 | const H2: &[u8] = b"h2";
|
96 | 28 |
|
@@ -197,6 +129,77 @@ where
|
197 | 129 | }
|
198 | 130 | }
|
199 | 131 |
|
| 132 | +pub(crate) async fn handshake<F, S, SD>( |
| 133 | + session: &RefCell<S>, |
| 134 | + io: &Io<F>, |
| 135 | +) -> Result<(), io::Error> |
| 136 | +where |
| 137 | + S: DerefMut + Deref<Target = ConnectionCommon<SD>>, |
| 138 | + SD: SideData, |
| 139 | +{ |
| 140 | + loop { |
| 141 | + let (result, handshaking) = io.with_buf(|buf| { |
| 142 | + let mut session = session.borrow_mut(); |
| 143 | + let mut wrp = Wrapper(buf); |
| 144 | + let mut result = Err(io::Error::new(io::ErrorKind::WouldBlock, "")); |
| 145 | + |
| 146 | + while session.wants_write() { |
| 147 | + result = session.write_tls(&mut wrp).map(|_| ()); |
| 148 | + if result.is_err() { |
| 149 | + break; |
| 150 | + } |
| 151 | + } |
| 152 | + if session.wants_read() { |
| 153 | + let has_data = buf.with_read_buf(|rbuf| { |
| 154 | + rbuf.with_src(|b| b.as_ref().map(|b| !b.is_empty()).unwrap_or_default()) |
| 155 | + }); |
| 156 | + |
| 157 | + if has_data { |
| 158 | + result = match session.read_tls(&mut wrp) { |
| 159 | + Ok(0) => { |
| 160 | + Err(io::Error::new(io::ErrorKind::NotConnected, "disconnected")) |
| 161 | + } |
| 162 | + Ok(_) => Ok(()), |
| 163 | + Err(e) => Err(e), |
| 164 | + }; |
| 165 | + |
| 166 | + session.process_new_packets().map_err(|err| { |
| 167 | + // In case we have an alert to send describing this error, |
| 168 | + // try a last-gasp write -- but don't predate the primary |
| 169 | + // error. |
| 170 | + let _ = session.write_tls(&mut wrp); |
| 171 | + io::Error::new(io::ErrorKind::InvalidData, err) |
| 172 | + })?; |
| 173 | + } else { |
| 174 | + result = Err(io::Error::new(io::ErrorKind::WouldBlock, "")); |
| 175 | + } |
| 176 | + } |
| 177 | + |
| 178 | + Ok::<_, io::Error>((result, session.is_handshaking())) |
| 179 | + })??; |
| 180 | + |
| 181 | + match result { |
| 182 | + Ok(()) => return Ok(()), |
| 183 | + Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { |
| 184 | + if !handshaking { |
| 185 | + return Ok(()); |
| 186 | + } |
| 187 | + poll_fn(|cx| { |
| 188 | + match ready!(io.poll_read_notify(cx))? { |
| 189 | + Some(_) => Ok(()), |
| 190 | + None => { |
| 191 | + Err(io::Error::new(io::ErrorKind::NotConnected, "disconnected")) |
| 192 | + } |
| 193 | + }?; |
| 194 | + Poll::Ready(Ok::<_, io::Error>(())) |
| 195 | + }) |
| 196 | + .await?; |
| 197 | + } |
| 198 | + Err(e) => return Err(e), |
| 199 | + } |
| 200 | + } |
| 201 | +} |
| 202 | + |
200 | 203 | pub(crate) struct Wrapper<'a, 'b>(&'a WriteBuf<'b>);
|
201 | 204 |
|
202 | 205 | impl io::Read for Wrapper<'_, '_> {
|
|
0 commit comments