pub(crate) struct HandshakeDeframer {
spans: Vec<FragmentSpan>,
outer_discard: usize,
}
Fields§
§spans: Vec<FragmentSpan>
Spans covering individual handshake payloads, in order of receipt.
outer_discard: usize
Discard value, tracking the rightmost extent of the last message
in spans
.
Implementations§
Source§impl HandshakeDeframer
impl HandshakeDeframer
Sourcepub(crate) fn input_message(
&mut self,
msg: InboundPlainMessage<'_>,
containing_buffer: &Locator,
outer_discard: usize,
)
pub(crate) fn input_message( &mut self, msg: InboundPlainMessage<'_>, containing_buffer: &Locator, outer_discard: usize, )
Accepts a message into the deframer.
containing_buffer
allows mapping the message payload to its position
in the input buffer, and thereby avoid retaining a borrow on the input
buffer.
That is required because our processing of handshake messages requires
them to be contiguous (and avoiding that would mean supporting gather-based
parsing in a large number of places, including core
, webpki
, and the
CryptoProvider
interface). coalesce()
arranges for that to happen, but
to do so it needs to move the fragments together in the original buffer.
This would not be possible if the messages were borrowing from that buffer.
outer_discard
is the rightmost extent of the original message.
Sourcepub(crate) fn progress(&self) -> BufferProgress
pub(crate) fn progress(&self) -> BufferProgress
Returns a BufferProgress
that skips over unprocessed handshake data.
Sourcepub(crate) fn has_message_ready(&self) -> bool
pub(crate) fn has_message_ready(&self) -> bool
Do we have a message ready? ie, would iter().next()
return Some
?
Sourcepub(crate) fn is_aligned(&self) -> bool
pub(crate) fn is_aligned(&self) -> bool
We are “aligned” if there is no partial fragment of a handshake message.
Sourcepub(crate) fn iter<'a, 'b>(
&'a mut self,
containing_buffer: &'b [u8],
) -> HandshakeIter<'a, 'b> ⓘ
pub(crate) fn iter<'a, 'b>( &'a mut self, containing_buffer: &'b [u8], ) -> HandshakeIter<'a, 'b> ⓘ
Iterate over the complete messages.
Sourcepub(crate) fn coalesce(
&mut self,
containing_buffer: &mut [u8],
) -> Result<(), InvalidMessage>
pub(crate) fn coalesce( &mut self, containing_buffer: &mut [u8], ) -> Result<(), InvalidMessage>
Coalesce the handshake portions of the given buffer, if needed.
This does nothing if there is nothing to do.
In a normal TLS stream, handshake messages need not be contiguous. For example, each handshake message could be delivered in its own outer TLS message. This would mean the handshake messages are separated by the outer TLS message headers, and likely also separated by encryption overhead (any explicit nonce in front, any padding and authentication tag afterwards).
For a toy example of one handshake message in two fragments, and:
- the letter
h
for handshake header octets - the letter
H
for handshake payload octets - the letter
x
for octets in the buffer ignored by this code,
the buffer and spans
data structure could look like:
0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9
x x x x x h h h h H H H x x x x x H H H H H H x x x
'------------' '----------'
| |
spans = [ { bounds = (5, 12), |
size = Some(9), .. }, |
{ bounds = (17, 23), .. } ]
In this case, requires_coalesce
returns Some(0)
. Then
coalesce_one
moves the second range leftwards:
0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9
x x x x x h h h h H H H x x x x x H H H H H H x x x
'----------'
^ '----------'
| v
'--<---<--'
copy_within(from = (17, 23),
to = (12, 18))
Leaving the buffer and spans:
0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9
x x x x x h h h h H H H H H H H H H x x x x x x x x
'------------------------'
|
spans = [ { bounds = (5, 18), size = Some(9), .. } ]
Sourcefn coalesce_one(&mut self, index: usize, containing_buffer: Coalescer<'_>)
fn coalesce_one(&mut self, index: usize, containing_buffer: Coalescer<'_>)
Within containing_buffer
, move span[index+1]
to be contiguous
with span[index]
.
Sourcefn requires_coalesce(&self) -> Option<usize>
fn requires_coalesce(&self) -> Option<usize>
We require coalescing if any span except the last is not complete.
Returns an index into spans
for the first non-complete span:
this will never be the last item.