1use alloc::vec::Vec;
4#[cfg(feature = "std")]
5use core::error::Error as StdError;
6use core::num::NonZeroUsize;
7use core::{fmt, mem};
8
9use super::UnbufferedConnectionCommon;
10use crate::client::ClientConnectionData;
11use crate::common_state::process_main_protocol;
12use crate::conn::SideData;
13use crate::crypto::cipher::Payload;
14use crate::error::Error;
15use crate::msgs::{DeframerSliceBuffer, Delocator, Locator};
16use crate::server::ServerConnectionData;
17
18impl UnbufferedConnectionCommon<ClientConnectionData> {
19 pub fn process_tls_records<'c, 'i>(
22 &'c mut self,
23 incoming_tls: &'i mut [u8],
24 ) -> UnbufferedStatus<'c, 'i, ClientConnectionData> {
25 self.process_tls_records_common(incoming_tls, |_| false, |_, _| unreachable!())
26 }
27}
28
29impl UnbufferedConnectionCommon<ServerConnectionData> {
30 pub fn process_tls_records<'c, 'i>(
33 &'c mut self,
34 incoming_tls: &'i mut [u8],
35 ) -> UnbufferedStatus<'c, 'i, ServerConnectionData> {
36 self.process_tls_records_common(
37 incoming_tls,
38 |conn| conn.peek_early_data().is_some(),
39 |conn, incoming_tls| ReadEarlyData::new(conn, incoming_tls).into(),
40 )
41 }
42}
43
44impl<Side: SideData> UnbufferedConnectionCommon<Side> {
45 fn process_tls_records_common<'c, 'i>(
46 &'c mut self,
47 incoming_tls: &'i mut [u8],
48 mut early_data_available: impl FnMut(&mut Self) -> bool,
49 early_data_state: impl FnOnce(&'c mut Self, &'i mut [u8]) -> ConnectionState<'c, 'i, Side>,
50 ) -> UnbufferedStatus<'c, 'i, Side> {
51 let plaintext_locator = Locator::new(incoming_tls);
52 let mut buffer = DeframerSliceBuffer::new(incoming_tls);
53 let mut buffer_progress = self.core.hs_deframer.progress();
54
55 let (discard, state) = loop {
56 if early_data_available(self) {
57 break (
58 buffer.pending_discard(),
59 early_data_state(self, incoming_tls),
60 );
61 }
62
63 if let Some(chunk) = self.core.side.send.sendable_tls.pop() {
64 break (
65 buffer.pending_discard(),
66 EncodeTlsData::new(self, chunk).into(),
67 );
68 }
69
70 let deframer_output = if self
71 .core
72 .side
73 .recv
74 .has_received_close_notify
75 {
76 None
77 } else {
78 match self
79 .core
80 .deframe(buffer.filled_mut(), &mut buffer_progress)
81 {
82 Err(err) => {
83 self.core
84 .side
85 .send
86 .maybe_send_fatal_alert(&err);
87 buffer.queue_discard(buffer_progress.take_discard());
88 return UnbufferedStatus {
89 discard: buffer.pending_discard(),
90 state: Err(err),
91 };
92 }
93 Ok(r) => r,
94 }
95 };
96
97 if let Some(msg) = deframer_output {
98 let state =
99 match mem::replace(&mut self.core.state, Err(Error::HandshakeNotComplete)) {
100 Ok(state) => state,
101 Err(e) => {
102 buffer.queue_discard(buffer_progress.take_discard());
103 self.core.state = Err(e.clone());
104 return UnbufferedStatus {
105 discard: buffer.pending_discard(),
106 state: Err(e),
107 };
108 }
109 };
110
111 let mut received_plaintext = None;
112 match process_main_protocol(
113 msg,
114 self.core.hs_deframer.aligned(),
115 state,
116 &plaintext_locator,
117 &mut received_plaintext,
118 &mut self.core.side,
119 ) {
120 Ok(new) => {
121 buffer.queue_discard(buffer_progress.take_discard());
122 self.core.state = Ok(new);
123
124 if let Some(payload) = received_plaintext {
125 let discard = buffer.pending_discard();
126 let payload = payload.reborrow(&Delocator::new(incoming_tls));
127 break (discard, ReadTraffic::new(self, payload).into());
128 }
129 }
130 Err(e) => {
131 self.core
132 .side
133 .send
134 .maybe_send_fatal_alert(&e);
135 buffer.queue_discard(buffer_progress.take_discard());
136 self.core.state = Err(e.clone());
137 return UnbufferedStatus {
138 discard: buffer.pending_discard(),
139 state: Err(e),
140 };
141 }
142 }
143 } else if self.wants_write {
144 break (
145 buffer.pending_discard(),
146 TransmitTlsData { conn: self }.into(),
147 );
148 } else if self
149 .core
150 .side
151 .recv
152 .has_received_close_notify
153 && !self.emitted_peer_closed_state
154 {
155 self.emitted_peer_closed_state = true;
156 break (buffer.pending_discard(), ConnectionState::PeerClosed);
157 } else if self
158 .core
159 .side
160 .recv
161 .has_received_close_notify
162 && self
163 .core
164 .side
165 .send
166 .has_sent_close_notify
167 {
168 break (buffer.pending_discard(), ConnectionState::Closed);
169 } else if self
170 .core
171 .side
172 .send
173 .may_send_application_data
174 {
175 break (
176 buffer.pending_discard(),
177 ConnectionState::WriteTraffic(WriteTraffic { conn: self }),
178 );
179 } else {
180 break (buffer.pending_discard(), ConnectionState::BlockedHandshake);
181 }
182 };
183
184 UnbufferedStatus {
185 discard,
186 state: Ok(state),
187 }
188 }
189}
190
191#[non_exhaustive]
193#[must_use]
194#[derive(Debug)]
195pub struct UnbufferedStatus<'c, 'i, Data: SideData> {
196 pub discard: usize,
205
206 pub state: Result<ConnectionState<'c, 'i, Data>, Error>,
212}
213
214#[non_exhaustive] pub enum ConnectionState<'c, 'i, Side: SideData> {
217 ReadTraffic(ReadTraffic<'c, 'i, Side>),
222
223 PeerClosed,
238
239 Closed,
244
245 ReadEarlyData(ReadEarlyData<'c, 'i, Side>),
247
248 EncodeTlsData(EncodeTlsData<'c, Side>),
253
254 TransmitTlsData(TransmitTlsData<'c, Side>),
267
268 BlockedHandshake,
273
274 WriteTraffic(WriteTraffic<'c, Side>),
288}
289
290impl<'c, 'i, Data: SideData> From<ReadTraffic<'c, 'i, Data>> for ConnectionState<'c, 'i, Data> {
291 fn from(v: ReadTraffic<'c, 'i, Data>) -> Self {
292 Self::ReadTraffic(v)
293 }
294}
295
296impl<'c, 'i, Data: SideData> From<ReadEarlyData<'c, 'i, Data>> for ConnectionState<'c, 'i, Data> {
297 fn from(v: ReadEarlyData<'c, 'i, Data>) -> Self {
298 Self::ReadEarlyData(v)
299 }
300}
301
302impl<'c, Data: SideData> From<EncodeTlsData<'c, Data>> for ConnectionState<'c, '_, Data> {
303 fn from(v: EncodeTlsData<'c, Data>) -> Self {
304 Self::EncodeTlsData(v)
305 }
306}
307
308impl<'c, Data: SideData> From<TransmitTlsData<'c, Data>> for ConnectionState<'c, '_, Data> {
309 fn from(v: TransmitTlsData<'c, Data>) -> Self {
310 Self::TransmitTlsData(v)
311 }
312}
313
314impl<Side: SideData> fmt::Debug for ConnectionState<'_, '_, Side> {
315 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316 match self {
317 Self::ReadTraffic(..) => f.debug_tuple("ReadTraffic").finish(),
318
319 Self::PeerClosed => write!(f, "PeerClosed"),
320
321 Self::Closed => write!(f, "Closed"),
322
323 Self::ReadEarlyData(..) => f.debug_tuple("ReadEarlyData").finish(),
324
325 Self::EncodeTlsData(..) => f.debug_tuple("EncodeTlsData").finish(),
326
327 Self::TransmitTlsData(..) => f
328 .debug_tuple("TransmitTlsData")
329 .finish(),
330
331 Self::BlockedHandshake => f
332 .debug_tuple("BlockedHandshake")
333 .finish(),
334
335 Self::WriteTraffic(..) => f.debug_tuple("WriteTraffic").finish(),
336 }
337 }
338}
339
340pub struct ReadTraffic<'c, 'i, Side: SideData> {
342 _conn: &'c mut UnbufferedConnectionCommon<Side>,
343
344 payload: Payload<'i>,
345}
346
347impl<'c, 'i, Side: SideData> ReadTraffic<'c, 'i, Side> {
348 fn new(_conn: &'c mut UnbufferedConnectionCommon<Side>, payload: Payload<'i>) -> Self {
349 Self { _conn, payload }
350 }
351
352 pub fn record(&self) -> AppDataRecord<'_> {
354 AppDataRecord {
355 discard: 0,
356 payload: self.payload.bytes(),
357 }
358 }
359}
360
361pub struct ReadEarlyData<'c, 'i, Side: SideData> {
363 conn: &'c mut UnbufferedConnectionCommon<Side>,
364
365 _incoming_tls: &'i mut [u8],
367
368 chunk: Option<Vec<u8>>,
371}
372
373impl<'c, 'i> ReadEarlyData<'c, 'i, ServerConnectionData> {
374 fn new(
375 conn: &'c mut UnbufferedConnectionCommon<ServerConnectionData>,
376 _incoming_tls: &'i mut [u8],
377 ) -> Self {
378 Self {
379 conn,
380 _incoming_tls,
381 chunk: None,
382 }
383 }
384
385 pub fn next_record(&mut self) -> Option<Result<AppDataRecord<'_>, Error>> {
388 self.chunk = self.conn.pop_early_data();
389 self.chunk.as_ref().map(|chunk| {
390 Ok(AppDataRecord {
391 discard: 0,
392 payload: chunk,
393 })
394 })
395 }
396
397 pub fn peek_len(&self) -> Option<NonZeroUsize> {
401 self.conn
402 .peek_early_data()
403 .and_then(|ch| NonZeroUsize::new(ch.len()))
404 }
405}
406
407#[non_exhaustive]
409pub struct AppDataRecord<'i> {
410 pub discard: usize,
415
416 pub payload: &'i [u8],
418}
419
420pub struct WriteTraffic<'c, Side: SideData> {
422 conn: &'c mut UnbufferedConnectionCommon<Side>,
423}
424
425impl<Side: SideData> WriteTraffic<'_, Side> {
426 pub fn encrypt(
431 &mut self,
432 application_data: &[u8],
433 outgoing_tls: &mut [u8],
434 ) -> Result<usize, EncryptError> {
435 self.conn
436 .core
437 .maybe_refresh_traffic_keys();
438 self.conn
439 .core
440 .side
441 .send
442 .write_plaintext(application_data.into(), outgoing_tls)
443 }
444
445 pub fn queue_close_notify(&mut self, outgoing_tls: &mut [u8]) -> Result<usize, EncryptError> {
450 self.conn
451 .core
452 .side
453 .send
454 .eager_send_close_notify(outgoing_tls)
455 }
456
457 pub fn refresh_traffic_keys(self) -> Result<(), Error> {
469 self.conn.core.refresh_traffic_keys()
470 }
471}
472
473pub struct EncodeTlsData<'c, Side: SideData> {
475 conn: &'c mut UnbufferedConnectionCommon<Side>,
476 chunk: Option<Vec<u8>>,
477}
478
479impl<'c, Side: SideData> EncodeTlsData<'c, Side> {
480 fn new(conn: &'c mut UnbufferedConnectionCommon<Side>, chunk: Vec<u8>) -> Self {
481 Self {
482 conn,
483 chunk: Some(chunk),
484 }
485 }
486
487 pub fn encode(&mut self, outgoing_tls: &mut [u8]) -> Result<usize, EncodeError> {
492 let Some(chunk) = self.chunk.take() else {
493 return Err(EncodeError::AlreadyEncoded);
494 };
495
496 let required_size = chunk.len();
497
498 if required_size > outgoing_tls.len() {
499 self.chunk = Some(chunk);
500 Err(InsufficientSizeError { required_size }.into())
501 } else {
502 let written = chunk.len();
503 outgoing_tls[..written].copy_from_slice(&chunk);
504
505 self.conn.wants_write = true;
506
507 Ok(written)
508 }
509 }
510}
511
512pub struct TransmitTlsData<'c, Side: SideData> {
514 pub(crate) conn: &'c mut UnbufferedConnectionCommon<Side>,
515}
516
517impl<Side: SideData> TransmitTlsData<'_, Side> {
518 pub fn done(self) {
520 self.conn.wants_write = false;
521 }
522
523 pub fn may_encrypt_app_data(&mut self) -> Option<WriteTraffic<'_, Side>> {
527 if self
528 .conn
529 .core
530 .side
531 .send
532 .may_send_application_data
533 {
534 Some(WriteTraffic { conn: self.conn })
535 } else {
536 None
537 }
538 }
539}
540
541#[non_exhaustive]
543#[derive(Debug)]
544pub enum EncodeError {
545 InsufficientSize(InsufficientSizeError),
547
548 AlreadyEncoded,
550}
551
552impl From<InsufficientSizeError> for EncodeError {
553 fn from(v: InsufficientSizeError) -> Self {
554 Self::InsufficientSize(v)
555 }
556}
557
558impl fmt::Display for EncodeError {
559 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
560 match self {
561 Self::InsufficientSize(InsufficientSizeError { required_size }) => write!(
562 f,
563 "cannot encode due to insufficient size, {required_size} bytes are required"
564 ),
565 Self::AlreadyEncoded => "cannot encode, data has already been encoded".fmt(f),
566 }
567 }
568}
569
570#[cfg(feature = "std")]
571impl StdError for EncodeError {}
572
573#[non_exhaustive]
575#[derive(Debug)]
576pub enum EncryptError {
577 InsufficientSize(InsufficientSizeError),
579
580 EncryptExhausted,
582}
583
584impl From<InsufficientSizeError> for EncryptError {
585 fn from(v: InsufficientSizeError) -> Self {
586 Self::InsufficientSize(v)
587 }
588}
589
590impl fmt::Display for EncryptError {
591 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
592 match self {
593 Self::InsufficientSize(InsufficientSizeError { required_size }) => write!(
594 f,
595 "cannot encrypt due to insufficient size, {required_size} bytes are required"
596 ),
597 Self::EncryptExhausted => f.write_str("encrypter has been exhausted"),
598 }
599 }
600}
601
602#[cfg(feature = "std")]
603impl StdError for EncryptError {}
604
605#[non_exhaustive]
607#[derive(Clone, Copy, Debug)]
608pub struct InsufficientSizeError {
609 pub required_size: usize,
611}