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::conn::SideData;
12use crate::crypto::cipher::Payload;
13use crate::error::Error;
14use crate::msgs::deframer::{DeframerSliceBuffer, Delocator, Locator};
15use crate::server::ServerConnectionData;
16
17impl UnbufferedConnectionCommon<ClientConnectionData> {
18 pub fn process_tls_records<'c, 'i>(
21 &'c mut self,
22 incoming_tls: &'i mut [u8],
23 ) -> UnbufferedStatus<'c, 'i, ClientConnectionData> {
24 self.process_tls_records_common(incoming_tls, |_| false, |_, _| unreachable!())
25 }
26}
27
28impl UnbufferedConnectionCommon<ServerConnectionData> {
29 pub fn process_tls_records<'c, 'i>(
32 &'c mut self,
33 incoming_tls: &'i mut [u8],
34 ) -> UnbufferedStatus<'c, 'i, ServerConnectionData> {
35 self.process_tls_records_common(
36 incoming_tls,
37 |conn| conn.peek_early_data().is_some(),
38 |conn, incoming_tls| ReadEarlyData::new(conn, incoming_tls).into(),
39 )
40 }
41}
42
43impl<Side: SideData> UnbufferedConnectionCommon<Side> {
44 fn process_tls_records_common<'c, 'i>(
45 &'c mut self,
46 incoming_tls: &'i mut [u8],
47 mut early_data_available: impl FnMut(&mut Self) -> bool,
48 early_data_state: impl FnOnce(&'c mut Self, &'i mut [u8]) -> ConnectionState<'c, 'i, Side>,
49 ) -> UnbufferedStatus<'c, 'i, Side> {
50 let plaintext_locator = Locator::new(incoming_tls);
51 let mut buffer = DeframerSliceBuffer::new(incoming_tls);
52 let mut buffer_progress = self.core.hs_deframer.progress();
53
54 let (discard, state) = loop {
55 if early_data_available(self) {
56 break (
57 buffer.pending_discard(),
58 early_data_state(self, incoming_tls),
59 );
60 }
61
62 if let Some(chunk) = self
63 .core
64 .common_state
65 .sendable_tls
66 .pop()
67 {
68 break (
69 buffer.pending_discard(),
70 EncodeTlsData::new(self, chunk).into(),
71 );
72 }
73
74 let deframer_output = if self
75 .core
76 .common_state
77 .has_received_close_notify
78 {
79 None
80 } else {
81 match self
82 .core
83 .deframe(buffer.filled_mut(), &mut buffer_progress)
84 {
85 Err(err) => {
86 self.core
87 .common_state
88 .maybe_send_fatal_alert(&err);
89 buffer.queue_discard(buffer_progress.take_discard());
90 return UnbufferedStatus {
91 discard: buffer.pending_discard(),
92 state: Err(err),
93 };
94 }
95 Ok(r) => r,
96 }
97 };
98
99 if let Some(msg) = deframer_output {
100 let state =
101 match mem::replace(&mut self.core.state, Err(Error::HandshakeNotComplete)) {
102 Ok(state) => state,
103 Err(e) => {
104 buffer.queue_discard(buffer_progress.take_discard());
105 self.core.state = Err(e.clone());
106 return UnbufferedStatus {
107 discard: buffer.pending_discard(),
108 state: Err(e),
109 };
110 }
111 };
112
113 let mut received_plaintext = None;
114 match self
115 .core
116 .common_state
117 .process_main_protocol(
118 msg,
119 state,
120 &mut self.core.side,
121 &plaintext_locator,
122 &mut received_plaintext,
123 None,
124 ) {
125 Ok(new) => {
126 buffer.queue_discard(buffer_progress.take_discard());
127 self.core.state = Ok(new);
128
129 if let Some(payload) = received_plaintext {
130 let discard = buffer.pending_discard();
131 let payload = payload.reborrow(&Delocator::new(incoming_tls));
132 break (discard, ReadTraffic::new(self, payload).into());
133 }
134 }
135 Err(e) => {
136 self.core
137 .common_state
138 .maybe_send_fatal_alert(&e);
139 buffer.queue_discard(buffer_progress.take_discard());
140 self.core.state = Err(e.clone());
141 return UnbufferedStatus {
142 discard: buffer.pending_discard(),
143 state: Err(e),
144 };
145 }
146 }
147 } else if self.wants_write {
148 break (
149 buffer.pending_discard(),
150 TransmitTlsData { conn: self }.into(),
151 );
152 } else if self
153 .core
154 .common_state
155 .has_received_close_notify
156 && !self.emitted_peer_closed_state
157 {
158 self.emitted_peer_closed_state = true;
159 break (buffer.pending_discard(), ConnectionState::PeerClosed);
160 } else if self
161 .core
162 .common_state
163 .has_received_close_notify
164 && self
165 .core
166 .common_state
167 .has_sent_close_notify
168 {
169 break (buffer.pending_discard(), ConnectionState::Closed);
170 } else if self
171 .core
172 .common_state
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 .common_state
441 .write_plaintext(application_data.into(), outgoing_tls)
442 }
443
444 pub fn queue_close_notify(&mut self, outgoing_tls: &mut [u8]) -> Result<usize, EncryptError> {
449 self.conn
450 .core
451 .common_state
452 .eager_send_close_notify(outgoing_tls)
453 }
454
455 pub fn refresh_traffic_keys(self) -> Result<(), Error> {
467 self.conn.core.refresh_traffic_keys()
468 }
469}
470
471pub struct EncodeTlsData<'c, Side: SideData> {
473 conn: &'c mut UnbufferedConnectionCommon<Side>,
474 chunk: Option<Vec<u8>>,
475}
476
477impl<'c, Side: SideData> EncodeTlsData<'c, Side> {
478 fn new(conn: &'c mut UnbufferedConnectionCommon<Side>, chunk: Vec<u8>) -> Self {
479 Self {
480 conn,
481 chunk: Some(chunk),
482 }
483 }
484
485 pub fn encode(&mut self, outgoing_tls: &mut [u8]) -> Result<usize, EncodeError> {
490 let Some(chunk) = self.chunk.take() else {
491 return Err(EncodeError::AlreadyEncoded);
492 };
493
494 let required_size = chunk.len();
495
496 if required_size > outgoing_tls.len() {
497 self.chunk = Some(chunk);
498 Err(InsufficientSizeError { required_size }.into())
499 } else {
500 let written = chunk.len();
501 outgoing_tls[..written].copy_from_slice(&chunk);
502
503 self.conn.wants_write = true;
504
505 Ok(written)
506 }
507 }
508}
509
510pub struct TransmitTlsData<'c, Side: SideData> {
512 pub(crate) conn: &'c mut UnbufferedConnectionCommon<Side>,
513}
514
515impl<Side: SideData> TransmitTlsData<'_, Side> {
516 pub fn done(self) {
518 self.conn.wants_write = false;
519 }
520
521 pub fn may_encrypt_app_data(&mut self) -> Option<WriteTraffic<'_, Side>> {
525 if self
526 .conn
527 .core
528 .common_state
529 .may_send_application_data
530 {
531 Some(WriteTraffic { conn: self.conn })
532 } else {
533 None
534 }
535 }
536}
537
538#[non_exhaustive]
540#[derive(Debug)]
541pub enum EncodeError {
542 InsufficientSize(InsufficientSizeError),
544
545 AlreadyEncoded,
547}
548
549impl From<InsufficientSizeError> for EncodeError {
550 fn from(v: InsufficientSizeError) -> Self {
551 Self::InsufficientSize(v)
552 }
553}
554
555impl fmt::Display for EncodeError {
556 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
557 match self {
558 Self::InsufficientSize(InsufficientSizeError { required_size }) => write!(
559 f,
560 "cannot encode due to insufficient size, {required_size} bytes are required"
561 ),
562 Self::AlreadyEncoded => "cannot encode, data has already been encoded".fmt(f),
563 }
564 }
565}
566
567#[cfg(feature = "std")]
568impl StdError for EncodeError {}
569
570#[non_exhaustive]
572#[derive(Debug)]
573pub enum EncryptError {
574 InsufficientSize(InsufficientSizeError),
576
577 EncryptExhausted,
579}
580
581impl From<InsufficientSizeError> for EncryptError {
582 fn from(v: InsufficientSizeError) -> Self {
583 Self::InsufficientSize(v)
584 }
585}
586
587impl fmt::Display for EncryptError {
588 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
589 match self {
590 Self::InsufficientSize(InsufficientSizeError { required_size }) => write!(
591 f,
592 "cannot encrypt due to insufficient size, {required_size} bytes are required"
593 ),
594 Self::EncryptExhausted => f.write_str("encrypter has been exhausted"),
595 }
596 }
597}
598
599#[cfg(feature = "std")]
600impl StdError for EncryptError {}
601
602#[non_exhaustive]
604#[derive(Clone, Copy, Debug)]
605pub struct InsufficientSizeError {
606 pub required_size: usize,
608}