Enhance and extend checking of message processing state
- Enhances the documentation of mbedtls_ssl_get_bytes_avail (return the number of bytes left in the current application data record, if there is any). - Introduces a new public function mbedtls_ssl_check_pending for checking whether any data in the internal buffers still needs to be processed. This is necessary for users implementing event-driven IO to decide when they can safely idle until they receive further events from the underlying transport.
This commit is contained in:
parent
16970d2912
commit
8b170a0a0b
2 changed files with 106 additions and 2 deletions
|
@ -2235,11 +2235,54 @@ void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
|
|||
#endif /* MBEDTLS_SSL_RENEGOTIATION */
|
||||
|
||||
/**
|
||||
* \brief Return the number of data bytes available to read
|
||||
* \brief Check if there is data already read from the
|
||||
* underlying transport but not yet processed.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
*
|
||||
* \return how many bytes are available in the read buffer
|
||||
* \return 0 if nothing's pending, 1 otherwise.
|
||||
*
|
||||
* \note This function is essential when using the library
|
||||
* with event-driven I/O. The user should not idle
|
||||
* (waiting for events from the underlying transport
|
||||
* or from timers) before this function's check passes.
|
||||
* Otherwise, it's possible to run into a deadlock
|
||||
* (if processing the pending data involves essential
|
||||
* communication with the peer) or to accumulate and
|
||||
* potentially lose data.
|
||||
*
|
||||
* \note This is different in purpose and behaviour from
|
||||
* \c mbedtls_ssl_get_bytes_avail in that it considers
|
||||
* any kind of unprocessed data, not only unread
|
||||
* application data. If \c mbedtls_ssl_get_bytes
|
||||
* returns a non-zero value, this function will
|
||||
* also signal pending data, but the converse does
|
||||
* not hold. For example, in DTLS there might be
|
||||
* further records waiting to be processed from
|
||||
* the current underlying transport's datagram.
|
||||
*
|
||||
* \note If this function returns 0 (data pending), this
|
||||
* does not imply that a subsequent call to
|
||||
* \c mbedtls_ssl_read will provide any data;
|
||||
* e.g., the unprocessed data might turn out
|
||||
* to be an alert or a handshake message.
|
||||
*/
|
||||
int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl );
|
||||
|
||||
/**
|
||||
* \brief Return the number of application data bytes
|
||||
* remaining to be read from the current record.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
*
|
||||
* \return How many bytes are available in the application
|
||||
* data record read buffer.
|
||||
*
|
||||
* \note When working over a datagram transport, this is
|
||||
* useful to detect the current datagram's boundary
|
||||
* in case \c mbedtls_ssl_read has written the maximal
|
||||
* amount of data fitting into the input buffer.
|
||||
*
|
||||
*/
|
||||
size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl );
|
||||
|
||||
|
|
|
@ -6392,6 +6392,67 @@ size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
|
|||
return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
|
||||
}
|
||||
|
||||
int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl )
|
||||
{
|
||||
/*
|
||||
* Case A: We're currently holding back
|
||||
* a message for further processing.
|
||||
*/
|
||||
|
||||
if( ssl->keep_current_message == 1 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record "
|
||||
"held back for processing" ) );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Case B: Further records are pending in the current datagram.
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
|
||||
ssl->in_left > ssl->next_record_offset )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records "
|
||||
"within current datagram" ) );
|
||||
return( 1 );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_DTLS */
|
||||
|
||||
/*
|
||||
* Case C: A handshake message is being processed.
|
||||
*/
|
||||
|
||||
/* TODO This needs correction in the same way as
|
||||
* read_record_layer, see IOTSSL-1414 */
|
||||
if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake "
|
||||
"messages within current record" ) );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Case D: An application data message is being processed
|
||||
*/
|
||||
if( ssl->in_offt != NULL )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data "
|
||||
"record is being processed" ) );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* In all other cases, the rest of the message can be dropped.
|
||||
* As in ssl_read_record_layer, this needs to be adapted if
|
||||
* we implement support for multiple alerts in single records.
|
||||
*/
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl )
|
||||
{
|
||||
if( ssl->session != NULL )
|
||||
|
|
Loading…
Reference in a new issue