-
Notifications
You must be signed in to change notification settings - Fork 30
Support parsing partial data #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
hi @chifflier, would you be available to review this pull request when you have a moment? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,
overall the pull request is interesting and I'm in favor in adding the support for fragmented message.
I have some questions about how this should be reflected in the API and/or structs. There are several choices, but even if we keep the current API we should probably add documentation to show how the caller can handle different cases (all fragments received, or not yet received, etc.)
false => ext_len as usize, | ||
true => min(ext_len as usize, i.len()), | ||
}; | ||
let (i, ext) = opt(complete(take(ext_len)))(i)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the logic here, but since ext_len
is lost when returning, how will the caller be aware that the message is partial?
Not sure how if this can cause problems.
Shouldn't we either return something, or maybe store ext_len
in the CH?
TlsHandshakeType::Certificate => match allow_partial { | ||
false => parse_dtls_handshake_msg_certificate(raw_msg), | ||
true => parse_partial_dtls_handshake_msg_certificate(raw_msg), | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment/discussion:
The match here could be avoided be directly calling parse_tls_certificate_inner
, something like:
let (rem,cert) = parse_tls_certificate_inner(raw_msg, allow_partial)?;
Ok((rem, DTLSMessageHandshakeBody::Certificate))
This reduces the number of if
/sub-functions and makes the allow_partial
explicit as argument, at the cost of adding code to map and add the Ok
. Maybe ?
after the match should be moved in each branch to avoid that. The code would become
let (_, body) = match msg_type {
//...
let (rem,cert) = parse_tls_certificate_inner(raw_msg, allow_partial)?;
(rem, DTLSMessageHandshakeBody::Certificate)
// ...
};
Could be done in a later PR
/// DTLS Client Hello allow partial | ||
// Section 4.2 of RFC6347 | ||
fn parse_partial_dtls_client_hello(i: &[u8]) -> IResult<&[u8], DTLSMessageHandshakeBody<'_>> { | ||
parse_dtls_client_hello_inner(i, true) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm correct, the client hello can only be fragmented in the extensions. This should be added to the function documentation
parse_dtls_record_with_header_inner(i, hdr, false) | ||
} | ||
|
||
pub fn parse_partial_dtls_record_with_header<'i>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above: how can be caller know the parsed message is partial?
Indeed, the caller cannot know whether the message is partial. Or we could keep the original API and record whether the message is partial in the returned structs. Is this better? |
At the moment I'd be tempted to:
|
Related issue #84