Merge branch 'iotssl-165-dtls-hs-fragmentation-new' into datagram_packing
diff --git a/ChangeLog b/ChangeLog
index a95cc6c..9817c59 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,13 @@
is controlled by the maximum fragment length as set locally or negotiated
with the peer, as well as new per-connection MTU option, set using
mbedtls_ssl_set_mtu().
+ * Add support for fragmentation of outoing DTLS handshake messages.
+ * Add support for packing multiple records within a single datagram,
+ enabled by default.
+
+API Changes
+ * Add function mbedtls_ssl_conf_datagram_packing() to configure
+ the use of datagram packing (enabled by default).
Bugfix
* Fixes an issue with MBEDTLS_CHACHAPOLY_C which would not compile if
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index f563437..f72833e 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1098,6 +1098,11 @@
int keep_current_message; /*!< drop or reuse current message
on next call to record layer? */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ uint8_t disable_datagram_packing; /*!< Disable packing multiple records
+ * within a single datagram. */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
/*
* Record layer (outgoing data)
*/
@@ -1112,6 +1117,8 @@
size_t out_msglen; /*!< record header: message length */
size_t out_left; /*!< amount of data not yet written */
+ unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */
+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */
#endif
@@ -1801,6 +1808,38 @@
#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+/**
+ * \brief Allow or disallow packing of multiple handshake records
+ * within a single datagram.
+ *
+ * \param ssl The SSL context to configure.
+ * \param allow_packing This determines whether datagram packing may
+ * be used or not. A value of \c 0 means that every
+ * record will be sent in a separate datagram; a
+ * value of \c 1 means that, if space permits,
+ * multiple handshake messages (including CCS) belonging to
+ * a single flight may be packed within a single datagram.
+ *
+ * \note This is enabled by default and should only be disabled
+ * for test purposes, or if datagram packing causes
+ * interoperability issues with peers that don't support it.
+ *
+ * \note Allowing datagram packing reduces the network load since
+ * there's less overhead if multiple messages share the same
+ * datagram. Also, it increases the handshake efficiency
+ * since messages belonging to a single datagram will not
+ * be reordered in transit, and so future message buffering
+ * or flight retransmission (if no buffering is used) as
+ * means to deal with reordering are needed less frequently.
+ *
+ * \note Application datagrams are not affected by this option and
+ * are currently always sent in separate datagrams.
+ *
+ */
+void mbedtls_ssl_conf_datagram_packing( mbedtls_ssl_context *ssl,
+ unsigned allow_packing );
+
/**
* \brief Set retransmit timeout values for the DTLS handshake.
* (DTLS only, no effect on TLS.)
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 18982f8..765da7a 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -561,7 +561,7 @@
int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want );
int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl );
-int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush );
int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl );
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl );
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index eda50bb..7101f46 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1294,7 +1294,7 @@
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
- memcpy( ssl->out_ctr + 2, ssl->in_ctr + 2, 6 );
+ memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 );
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index da21db2..0b3fea1 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -54,6 +54,8 @@
#include "mbedtls/oid.h"
#endif
+static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl );
+
/* Length of the "epoch" field in the record header */
static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
{
@@ -96,7 +98,75 @@
return( 0 );
}
+static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
+ mbedtls_ssl_transform *transform );
+static void ssl_update_in_pointers( mbedtls_ssl_context *ssl,
+ mbedtls_ssl_transform *transform );
+
+#define SSL_DONT_FORCE_FLUSH 0
+#define SSL_FORCE_FLUSH 1
+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+static uint16_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
+{
+ uint16_t mtu = ssl->mtu;
+
+ if( mtu != 0 && mtu < MBEDTLS_SSL_OUT_BUFFER_LEN )
+ return( (int) mtu );
+
+ return( MBEDTLS_SSL_OUT_BUFFER_LEN );
+}
+
+static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
+{
+ size_t const bytes_written = ssl->out_left;
+ uint16_t const mtu = ssl_get_maximum_datagram_size( ssl );
+
+ /* Double-check that the write-index hasn't gone
+ * past what we can transmit in a single datagram. */
+ if( bytes_written > (size_t) mtu )
+ {
+ /* Should never happen... */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ return( (int) ( mtu - bytes_written ) );
+}
+
+static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
+{
+ int ret;
+ size_t remaining, expansion;
+ size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN;
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
+
+ if( max_len > mfl )
+ max_len = mfl;
+#endif
+
+ ret = ssl_get_remaining_space_in_datagram( ssl );
+ if( ret < 0 )
+ return( ret );
+ remaining = (size_t) ret;
+
+ ret = mbedtls_ssl_get_record_expansion( ssl );
+ if( ret < 0 )
+ return( ret );
+ expansion = (size_t) ret;
+
+ if( remaining <= expansion )
+ return( 0 );
+
+ remaining -= expansion;
+ if( remaining >= max_len )
+ remaining = max_len;
+
+ return( (int) remaining );
+}
+
/*
* Double the retransmit timeout value, within the allowed range,
* returning -1 if the maximum value has already been reached.
@@ -1345,14 +1415,6 @@
MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
ssl->out_msg, ssl->out_msglen );
- if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %u too large, maximum %d",
- (unsigned) ssl->out_msglen,
- MBEDTLS_SSL_OUT_CONTENT_LEN ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
/*
* Add MAC before if needed
*/
@@ -2644,7 +2706,7 @@
int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
{
int ret;
- unsigned char *buf, i;
+ unsigned char *buf;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
@@ -2667,8 +2729,7 @@
MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
- buf = ssl->out_hdr + mbedtls_ssl_hdr_len( ssl ) +
- ssl->out_msglen - ssl->out_left;
+ buf = ssl->out_hdr - ssl->out_left;
ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
@@ -2687,16 +2748,17 @@
ssl->out_left -= ret;
}
- for( i = 8; i > ssl_ep_len( ssl ); i-- )
- if( ++ssl->out_ctr[i - 1] != 0 )
- break;
-
- /* The loop goes to its end iff the counter is wrapping */
- if( i == ssl_ep_len( ssl ) )
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+ ssl->out_hdr = ssl->out_buf;
}
+ else
+#endif
+ {
+ ssl->out_hdr = ssl->out_buf + 8;
+ }
+ ssl_update_out_pointers( ssl, ssl->transform_out );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
@@ -2713,6 +2775,9 @@
static int ssl_flight_append( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_flight_item *msg;
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight",
+ ssl->out_msg, ssl->out_msglen );
/* Allocate space for current message */
if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL )
@@ -2746,6 +2811,7 @@
cur->next = msg;
}
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
return( 0 );
}
@@ -2794,19 +2860,12 @@
ssl->handshake->alt_transform_out = tmp_transform;
/* Swap epoch + sequence_number */
- memcpy( tmp_out_ctr, ssl->out_ctr, 8 );
- memcpy( ssl->out_ctr, ssl->handshake->alt_out_ctr, 8 );
+ memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 );
+ memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 );
memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
/* Adjust to the newly activated transform */
- if( ssl->transform_out != NULL &&
- ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- ssl->out_msg = ssl->out_iv + ssl->transform_out->ivlen -
- ssl->transform_out->fixed_ivlen;
- }
- else
- ssl->out_msg = ssl->out_iv;
+ ssl_update_out_pointers( ssl, ssl->transform_out );
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( mbedtls_ssl_hw_record_activate != NULL )
@@ -2845,6 +2904,7 @@
*/
int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
{
+ int ret;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
@@ -2860,22 +2920,43 @@
while( ssl->handshake->cur_msg != NULL )
{
- int ret;
+ size_t max_frag_len;
const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
+
+ int const is_finished =
+ ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
+
+ uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
+ SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
+
/* Swap epochs before sending Finished: we can't do it after
* sending ChangeCipherSpec, in case write returns WANT_READ.
* Must be done before copying, may change out_msg pointer */
- if( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
- cur->p[0] == MBEDTLS_SSL_HS_FINISHED )
+ if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
{
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
ssl_swap_epochs( ssl );
}
+ ret = ssl_get_remaining_payload_in_datagram( ssl );
+ if( ret < 0 )
+ return( ret );
+ max_frag_len = (size_t) ret;
+
/* CCS is copied as is, while HS messages may need fragmentation */
if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
{
+ if( max_frag_len == 0 )
+ {
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ continue;
+ }
+
memcpy( ssl->out_msg, cur->p, cur->len );
- ssl->out_msglen = cur->len;
+ ssl->out_msglen = cur->len;
ssl->out_msgtype = cur->type;
/* Update position inside current message */
@@ -2883,29 +2964,32 @@
}
else
{
- const int ret_payload = mbedtls_ssl_get_max_out_record_payload( ssl );
- const size_t max_record_payload = (size_t) ret_payload;
- /* DTLS handshake headers are 12 bytes */
- const size_t max_hs_fragment_len = max_record_payload - 12;
const unsigned char * const p = ssl->handshake->cur_msg_p;
const size_t hs_len = cur->len - 12;
const size_t frag_off = p - ( cur->p + 12 );
const size_t rem_len = hs_len - frag_off;
- const size_t frag_len = rem_len > max_hs_fragment_len
- ? max_hs_fragment_len : rem_len;
+ size_t cur_hs_frag_len, max_hs_frag_len;
- if( ret_payload < 0 )
+ if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload",
- ret_payload );
- return( ret_payload );
- }
+ if( is_finished )
+ ssl_swap_epochs( ssl );
- if( frag_off == 0 && frag_len != hs_len )
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ continue;
+ }
+ max_hs_frag_len = max_frag_len - 12;
+
+ cur_hs_frag_len = rem_len > max_hs_frag_len ?
+ max_hs_frag_len : rem_len;
+
+ if( frag_off == 0 && cur_hs_frag_len != hs_len )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
- (unsigned) hs_len,
- (unsigned) max_hs_fragment_len ) );
+ (unsigned) cur_hs_frag_len,
+ (unsigned) max_hs_frag_len ) );
}
/* Messages are stored with handshake headers as if not fragmented,
@@ -2917,19 +3001,19 @@
ssl->out_msg[7] = ( ( frag_off >> 8 ) & 0xff );
ssl->out_msg[8] = ( ( frag_off ) & 0xff );
- ssl->out_msg[ 9] = ( ( frag_len >> 16 ) & 0xff );
- ssl->out_msg[10] = ( ( frag_len >> 8 ) & 0xff );
- ssl->out_msg[11] = ( ( frag_len ) & 0xff );
+ ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff );
+ ssl->out_msg[10] = ( ( cur_hs_frag_len >> 8 ) & 0xff );
+ ssl->out_msg[11] = ( ( cur_hs_frag_len ) & 0xff );
MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
- /* Copy the handshake message content and set records fields */
- memcpy( ssl->out_msg + 12, p, frag_len );
- ssl->out_msglen = frag_len + 12;
+ /* Copy the handshame message content and set records fields */
+ memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
+ ssl->out_msglen = cur_hs_frag_len + 12;
ssl->out_msgtype = cur->type;
/* Update position inside current message */
- ssl->handshake->cur_msg_p += frag_len;
+ ssl->handshake->cur_msg_p += cur_hs_frag_len;
}
/* If done with the current message move to the next one if any */
@@ -2948,13 +3032,16 @@
}
/* Actually send the message out */
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
+ if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
return( ret );
}
}
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
/* Update state and set timer */
if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
@@ -3074,6 +3161,23 @@
}
#endif
+ /* Double-check that we did not exceed the bounds
+ * of the outgoing record buffer.
+ * This should never fail as the various message
+ * writing functions must obey the bounds of the
+ * outgoing record buffer, but better be safe.
+ *
+ * Note: We deliberately do not check for the MTU or MFL here.
+ */
+ if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: "
+ "size %u, maximum %u",
+ (unsigned) ssl->out_msglen,
+ (unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
/*
* Fill handshake headers
*/
@@ -3145,7 +3249,7 @@
else
#endif
{
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
+ if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
return( ret );
@@ -3169,10 +3273,11 @@
* - ssl->out_msglen: length of the record content (excl headers)
* - ssl->out_msg: record content
*/
-int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
{
int ret, done = 0;
size_t len = ssl->out_msglen;
+ uint8_t flush = force_flush;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
@@ -3208,10 +3313,14 @@
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
if( !done )
{
+ unsigned i;
+ size_t protected_record_size;
+
ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
ssl->conf->transport, ssl->out_hdr + 1 );
+ memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
ssl->out_len[0] = (unsigned char)( len >> 8 );
ssl->out_len[1] = (unsigned char)( len );
@@ -3228,18 +3337,64 @@
ssl->out_len[1] = (unsigned char)( len );
}
- ssl->out_left = mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen;
+ protected_record_size = len + mbedtls_ssl_hdr_len( ssl );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ /* In case of DTLS, double-check that we don't exceed
+ * the remaining space in the datagram. */
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ret = ssl_get_maximum_datagram_size( ssl );
+ if( ret < 0 )
+ return( ret );
+
+ if( protected_record_size > (size_t) ret )
+ {
+ /* Should never happen */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, "
- "version = [%d:%d], msglen = %d",
- ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2],
- ( ssl->out_len[0] << 8 ) | ssl->out_len[1] ) );
+ "version = [%d:%d], msglen = %d",
+ ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2], len ) );
+
MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
- ssl->out_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen );
+ ssl->out_hdr, protected_record_size );
+
+ ssl->out_left += protected_record_size;
+ ssl->out_hdr += protected_record_size;
+ ssl_update_out_pointers( ssl, ssl->transform_out );
+
+ for( i = 8; i > ssl_ep_len( ssl ); i-- )
+ if( ++ssl->cur_out_ctr[i - 1] != 0 )
+ break;
+
+ /* The loop goes to its end iff the counter is wrapping */
+ if( i == ssl_ep_len( ssl ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
+ return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+ }
}
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ size_t remaining = ssl_get_remaining_payload_in_datagram( ssl );
+ if( remaining == 0 )
+ flush = SSL_FORCE_FLUSH;
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) );
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ if( ( flush == SSL_FORCE_FLUSH ) &&
+ ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
return( ret );
@@ -4521,7 +4676,7 @@
ssl->out_msg[0] = level;
ssl->out_msg[1] = message;
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
+ if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
return( ret );
@@ -5170,16 +5325,7 @@
#endif /* MBEDTLS_SSL_PROTO_DTLS */
memset( ssl->in_ctr, 0, 8 );
- /*
- * Set the in_msg pointer to the correct location based on IV length
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- ssl->in_msg = ssl->in_iv + ssl->transform_negotiate->ivlen -
- ssl->transform_negotiate->fixed_ivlen;
- }
- else
- ssl->in_msg = ssl->in_iv;
+ ssl_update_in_pointers( ssl, ssl->transform_negotiate );
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( mbedtls_ssl_hw_record_activate != NULL )
@@ -5630,16 +5776,7 @@
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
- /*
- * Set the out_msg pointer to the correct location based on IV length
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- ssl->out_msg = ssl->out_iv + ssl->transform_negotiate->ivlen -
- ssl->transform_negotiate->fixed_ivlen;
- }
- else
- ssl->out_msg = ssl->out_iv;
+ ssl_update_out_pointers( ssl, ssl->transform_negotiate );
ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
@@ -5691,14 +5828,14 @@
/* Remember current epoch settings for resending */
ssl->handshake->alt_transform_out = ssl->transform_out;
- memcpy( ssl->handshake->alt_out_ctr, ssl->out_ctr, 8 );
+ memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 );
/* Set sequence_number to zero */
- memset( ssl->out_ctr + 2, 0, 6 );
+ memset( ssl->cur_out_ctr + 2, 0, 6 );
/* Increment epoch */
for( i = 2; i > 0; i-- )
- if( ++ssl->out_ctr[i - 1] != 0 )
+ if( ++ssl->cur_out_ctr[i - 1] != 0 )
break;
/* The loop goes to its end iff the counter is wrapping */
@@ -5710,7 +5847,7 @@
}
else
#endif /* MBEDTLS_SSL_PROTO_DTLS */
- memset( ssl->out_ctr, 0, 8 );
+ memset( ssl->cur_out_ctr, 0, 8 );
ssl->transform_out = ssl->transform_negotiate;
ssl->session_out = ssl->session_negotiate;
@@ -5998,6 +6135,78 @@
}
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
+/* Once ssl->out_hdr as the address of the beginning of the
+ * next outgoing record is set, deduce the other pointers.
+ *
+ * Note: For TLS, we save the implicit record sequence number
+ * (entering MAC computation) in the 8 bytes before ssl->out_hdr,
+ * and the caller has to make sure there's space for this.
+ */
+
+static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
+ mbedtls_ssl_transform *transform )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ssl->out_ctr = ssl->out_hdr + 3;
+ ssl->out_len = ssl->out_hdr + 11;
+ ssl->out_iv = ssl->out_hdr + 13;
+ }
+ else
+#endif
+ {
+ ssl->out_ctr = ssl->out_hdr - 8;
+ ssl->out_len = ssl->out_hdr + 3;
+ ssl->out_iv = ssl->out_hdr + 5;
+ }
+
+ /* Adjust out_msg to make space for explicit IV, if used. */
+ if( transform != NULL &&
+ ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen;
+ }
+ else
+ ssl->out_msg = ssl->out_iv;
+}
+
+/* Once ssl->in_hdr as the address of the beginning of the
+ * next incoming record is set, deduce the other pointers.
+ *
+ * Note: For TLS, we save the implicit record sequence number
+ * (entering MAC computation) in the 8 bytes before ssl->in_hdr,
+ * and the caller has to make sure there's space for this.
+ */
+
+static void ssl_update_in_pointers( mbedtls_ssl_context *ssl,
+ mbedtls_ssl_transform *transform )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ssl->in_ctr = ssl->in_hdr + 3;
+ ssl->in_len = ssl->in_hdr + 11;
+ ssl->in_iv = ssl->in_hdr + 13;
+ }
+ else
+#endif
+ {
+ ssl->in_ctr = ssl->in_hdr - 8;
+ ssl->in_len = ssl->in_hdr + 3;
+ ssl->in_iv = ssl->in_hdr + 5;
+ }
+
+ /* Offset in_msg from in_iv to allow space for explicit IV, if used. */
+ if( transform != NULL &&
+ ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ ssl->in_msg = ssl->in_iv + transform->ivlen - transform->fixed_ivlen;
+ }
+ else
+ ssl->in_msg = ssl->in_iv;
+}
+
/*
* Initialize an SSL context
*/
@@ -6009,6 +6218,28 @@
/*
* Setup an SSL context
*/
+
+static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl )
+{
+ /* Set the incoming and outgoing record pointers. */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ssl->out_hdr = ssl->out_buf;
+ ssl->in_hdr = ssl->in_buf;
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ ssl->out_hdr = ssl->out_buf + 8;
+ ssl->in_hdr = ssl->in_buf + 8;
+ }
+
+ /* Derive other internal pointers. */
+ ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
+ ssl_update_in_pointers ( ssl, NULL /* no transform enabled */ );
+}
+
int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
const mbedtls_ssl_config *conf )
{
@@ -6035,36 +6266,7 @@
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
}
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->out_hdr = ssl->out_buf;
- ssl->out_ctr = ssl->out_buf + 3;
- ssl->out_len = ssl->out_buf + 11;
- ssl->out_iv = ssl->out_buf + 13;
- ssl->out_msg = ssl->out_buf + 13;
-
- ssl->in_hdr = ssl->in_buf;
- ssl->in_ctr = ssl->in_buf + 3;
- ssl->in_len = ssl->in_buf + 11;
- ssl->in_iv = ssl->in_buf + 13;
- ssl->in_msg = ssl->in_buf + 13;
- }
- else
-#endif
- {
- ssl->out_ctr = ssl->out_buf;
- ssl->out_hdr = ssl->out_buf + 8;
- ssl->out_len = ssl->out_buf + 11;
- ssl->out_iv = ssl->out_buf + 13;
- ssl->out_msg = ssl->out_buf + 13;
-
- ssl->in_ctr = ssl->in_buf;
- ssl->in_hdr = ssl->in_buf + 8;
- ssl->in_len = ssl->in_buf + 11;
- ssl->in_iv = ssl->in_buf + 13;
- ssl->in_msg = ssl->in_buf + 13;
- }
+ ssl_reset_in_out_pointers( ssl );
if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
return( ret );
@@ -6083,6 +6285,11 @@
{
int ret;
+#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \
+ !defined(MBEDTLS_SSL_SRV_C)
+ ((void) partial);
+#endif
+
ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
/* Cancel any possibly running timer */
@@ -6099,12 +6306,10 @@
ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
ssl->in_offt = NULL;
+ ssl_reset_in_out_pointers( ssl );
- ssl->in_msg = ssl->in_buf + 13;
ssl->in_msgtype = 0;
ssl->in_msglen = 0;
- if( partial == 0 )
- ssl->in_left = 0;
#if defined(MBEDTLS_SSL_PROTO_DTLS)
ssl->next_record_offset = 0;
ssl->in_epoch = 0;
@@ -6118,7 +6323,6 @@
ssl->keep_current_message = 0;
- ssl->out_msg = ssl->out_buf + 13;
ssl->out_msgtype = 0;
ssl->out_msglen = 0;
ssl->out_left = 0;
@@ -6127,6 +6331,8 @@
ssl->split_done = 0;
#endif
+ memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
+
ssl->transform_in = NULL;
ssl->transform_out = NULL;
@@ -6134,8 +6340,14 @@
ssl->session_out = NULL;
memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN );
+
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
if( partial == 0 )
+#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
+ {
+ ssl->in_left = 0;
memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN );
+ }
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( mbedtls_ssl_hw_record_reset != NULL )
@@ -6168,7 +6380,9 @@
#endif
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
if( partial == 0 )
+#endif
{
mbedtls_free( ssl->cli_id );
ssl->cli_id = NULL;
@@ -6219,7 +6433,15 @@
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS)
-void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max )
+
+void mbedtls_ssl_conf_datagram_packing( mbedtls_ssl_context *ssl,
+ unsigned allow_packing )
+{
+ ssl->disable_datagram_packing = !allow_packing;
+}
+
+void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf,
+ uint32_t min, uint32_t max )
{
conf->hs_timeout_min = min;
conf->hs_timeout_max = max;
@@ -7120,6 +7342,11 @@
}
#endif
+#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
+ !defined(MBEDTLS_SSL_PROTO_DTLS)
+ ((void) ssl);
+#endif
+
return( (int) max_len );
}
@@ -7342,7 +7569,7 @@
in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
ssl->conf->renego_period + ep_len, 8 - ep_len );
- out_ctr_cmp = memcmp( ssl->out_ctr + ep_len,
+ out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
ssl->conf->renego_period + ep_len, 8 - ep_len );
if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
@@ -7723,7 +7950,7 @@
ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
memcpy( ssl->out_msg, buf, len );
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
+ if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
return( ret );
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index e4a7412..cfcb27d 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -107,6 +107,7 @@
#define DFL_HS_TO_MIN 0
#define DFL_HS_TO_MAX 0
#define DFL_DTLS_MTU -1
+#define DFL_DGRAM_PACKING 1
#define DFL_FALLBACK -1
#define DFL_EXTENDED_MS -1
#define DFL_ETM -1
@@ -200,7 +201,10 @@
" dtls=%%d default: 0 (TLS)\n" \
" hs_timeout=%%d-%%d default: (library default: 1000-60000)\n" \
" range of DTLS handshake timeouts in millisecs\n" \
- " mtu=%%d default: (library default: unlimited)\n"
+ " mtu=%%d default: (library default: unlimited)\n" \
+ " dgram_packing=%%d default: 1 (allowed)\n" \
+ " allow or forbid packing of multiple\n" \
+ " records within a single datgram.\n"
#else
#define USAGE_DTLS ""
#endif
@@ -349,6 +353,7 @@
uint32_t hs_to_max; /* Max value of DTLS handshake timer */
int dtls_mtu; /* UDP Maximum tranport unit for DTLS */
int fallback; /* is this a fallback connection? */
+ int dgram_packing; /* allow/forbid datagram packing */
int extended_ms; /* negotiate extended master secret? */
int etm; /* negotiate encrypt then mac? */
} opt;
@@ -624,6 +629,7 @@
opt.fallback = DFL_FALLBACK;
opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM;
+ opt.dgram_packing = DFL_DGRAM_PACKING;
for( i = 1; i < argc; i++ )
{
@@ -937,6 +943,15 @@
if( opt.dtls_mtu < 0 )
goto usage;
}
+ else if( strcmp( p, "dgram_packing" ) == 0 )
+ {
+ opt.dgram_packing = atoi( q );
+ if( opt.dgram_packing != 0 &&
+ opt.dgram_packing != 1 )
+ {
+ goto usage;
+ }
+ }
else if( strcmp( p, "recsplit" ) == 0 )
{
opt.recsplit = atoi( q );
@@ -1337,7 +1352,10 @@
if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min,
opt.hs_to_max );
-#endif
+
+ if( opt.dgram_packing != DFL_DGRAM_PACKING )
+ mbedtls_ssl_conf_datagram_packing( &ssl, opt.dgram_packing );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
if( ( ret = mbedtls_ssl_conf_max_frag_len( &conf, opt.mfl_code ) ) != 0 )
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 71ec85b..4378e4f 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -152,6 +152,7 @@
#define DFL_HS_TO_MAX 0
#define DFL_DTLS_MTU -1
#define DFL_BADMAC_LIMIT -1
+#define DFL_DGRAM_PACKING 1
#define DFL_EXTENDED_MS -1
#define DFL_ETM -1
@@ -299,7 +300,10 @@
" dtls=%%d default: 0 (TLS)\n" \
" hs_timeout=%%d-%%d default: (library default: 1000-60000)\n" \
" range of DTLS handshake timeouts in millisecs\n" \
- " mtu=%%d default: (library default: unlimited)\n"
+ " mtu=%%d default: (library default: unlimited)\n" \
+ " dgram_packing=%%d default: 1 (allowed)\n" \
+ " allow or forbid packing of multiple\n" \
+ " records within a single datgram.\n"
#else
#define USAGE_DTLS ""
#endif
@@ -473,6 +477,7 @@
uint32_t hs_to_min; /* Initial value of DTLS handshake timer */
uint32_t hs_to_max; /* Max value of DTLS handshake timer */
int dtls_mtu; /* UDP Maximum tranport unit for DTLS */
+ int dgram_packing; /* allow/forbid datagram packing */
int badmac_limit; /* Limit of records with bad MAC */
} opt;
@@ -1342,6 +1347,7 @@
opt.hs_to_min = DFL_HS_TO_MIN;
opt.hs_to_max = DFL_HS_TO_MAX;
opt.dtls_mtu = DFL_DTLS_MTU;
+ opt.dgram_packing = DFL_DGRAM_PACKING;
opt.badmac_limit = DFL_BADMAC_LIMIT;
opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM;
@@ -1694,6 +1700,15 @@
if( opt.dtls_mtu < 0 )
goto usage;
}
+ else if( strcmp( p, "dgram_packing" ) == 0 )
+ {
+ opt.dgram_packing = atoi( q );
+ if( opt.dgram_packing != 0 &&
+ opt.dgram_packing != 1 )
+ {
+ goto usage;
+ }
+ }
else if( strcmp( p, "sni" ) == 0 )
{
opt.sni = q;
@@ -2165,6 +2180,9 @@
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
+
+ if( opt.dgram_packing != DFL_DGRAM_PACKING )
+ mbedtls_ssl_conf_datagram_packing( &ssl, opt.dgram_packing );
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
@@ -2175,6 +2193,7 @@
};
#endif
+
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
if( opt.trunc_hmac != DFL_TRUNC_HMAC )
mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index f1c1982..886c44c 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -682,6 +682,9 @@
if [ "$PRESERVE_LOGS" -gt 0 ]; then
mv $SRV_OUT o-srv-${TESTS}.log
mv $CLI_OUT o-cli-${TESTS}.log
+ if [ -n "$PXY_CMD" ]; then
+ mv $PXY_OUT o-pxy-${TESTS}.log
+ fi
fi
rm -f $SRV_OUT $CLI_OUT $PXY_OUT
@@ -912,6 +915,35 @@
"$P_CLI key_file=data_files/cli-rsa.key crt_file=data_files/cli-rsa-sha256.crt" \
0
+# Tests for datagram packing
+run_test "DTLS: multiple records in same datagram, client and server" \
+ "$P_SRV dtls=1 dgram_packing=1 debug_level=2" \
+ "$P_CLI dtls=1 dgram_packing=1 debug_level=2" \
+ 0 \
+ -c "next record in same datagram" \
+ -s "next record in same datagram"
+
+run_test "DTLS: multiple records in same datagram, client only" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
+ "$P_CLI dtls=1 dgram_packing=1 debug_level=2" \
+ 0 \
+ -s "next record in same datagram" \
+ -C "next record in same datagram"
+
+run_test "DTLS: multiple records in same datagram, server only" \
+ "$P_SRV dtls=1 dgram_packing=1 debug_level=2" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
+ 0 \
+ -S "next record in same datagram" \
+ -c "next record in same datagram"
+
+run_test "DTLS: multiple records in same datagram, neither client nor server" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
+ 0 \
+ -S "next record in same datagram" \
+ -C "next record in same datagram"
+
# Tests for Truncated HMAC extension
run_test "Truncated HMAC: client default, server default" \
@@ -4960,11 +4992,11 @@
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \
- max_frag_len=2048" \
+ max_frag_len=4096" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \
- max_frag_len=2048" \
+ max_frag_len=4096" \
0 \
-S "found fragmented DTLS handshake message" \
-C "found fragmented DTLS handshake message" \
@@ -5049,11 +5081,11 @@
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \
- mtu=2048" \
+ mtu=4096" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \
- mtu=2048" \
+ mtu=4096" \
0 \
-S "found fragmented DTLS handshake message" \
-C "found fragmented DTLS handshake message" \
@@ -5066,7 +5098,7 @@
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \
- mtu=2048" \
+ mtu=4096" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \
@@ -5311,11 +5343,11 @@
client_needs_more_time 2
run_test "DTLS fragmenting: proxy MTU + 3d" \
-p "$P_PXY mtu=512 drop=8 delay=8 duplicate=8" \
- "$P_SRV dtls=1 debug_level=2 auth_mode=required \
+ "$P_SRV dgram_packing=0 dtls=1 debug_level=2 auth_mode=required \
crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \
hs_timeout=250-10000 mtu=512" \
- "$P_CLI dtls=1 debug_level=2 \
+ "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \
hs_timeout=250-10000 mtu=512" \
@@ -5328,6 +5360,7 @@
#
# here and below we just want to test that the we fragment in a way that
# pleases other implementations, so we don't need the peer to fragment
+requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C
requires_config_enabled MBEDTLS_ECDSA_C
@@ -5342,6 +5375,7 @@
-c "fragmenting handshake message" \
-C "error"
+requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled MBEDTLS_RSA_C
requires_config_enabled MBEDTLS_ECDSA_C
@@ -5453,7 +5487,7 @@
run_test "DTLS fragmenting: 3d, gnutls server, DTLS 1.2" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
"$G_NEXT_SRV -u" \
- "$P_CLI dtls=1 debug_level=2 \
+ "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \
hs_timeout=250-60000 mtu=512 force_version=dtls1_2" \
@@ -5470,7 +5504,7 @@
run_test "DTLS fragmenting: 3d, gnutls server, DTLS 1.0" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
"$G_NEXT_SRV -u" \
- "$P_CLI dtls=1 debug_level=2 \
+ "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \
hs_timeout=250-60000 mtu=512 force_version=dtls1" \
@@ -5551,7 +5585,7 @@
run_test "DTLS fragmenting: 3d, openssl server, DTLS 1.0" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
"$O_LEGACY_SRV -dtls1 -verify 10" \
- "$P_CLI dtls=1 debug_level=2 \
+ "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
crt_file=data_files/server8_int-ca2.crt \
key_file=data_files/server8.key \
hs_timeout=250-60000 mtu=512 force_version=dtls1" \
@@ -5585,7 +5619,7 @@
client_needs_more_time 4
run_test "DTLS fragmenting: 3d, openssl client, DTLS 1.0" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
- "$P_SRV dtls=1 debug_level=2 \
+ "$P_SRV dgram_packing=0 dtls=1 debug_level=2 \
crt_file=data_files/server7_int-ca.crt \
key_file=data_files/server7.key \
hs_timeout=250-60000 mtu=512 force_version=dtls1" \
@@ -5614,8 +5648,8 @@
not_with_valgrind # spurious resend due to timeout
run_test "DTLS proxy: duplicate every packet" \
-p "$P_PXY duplicate=1" \
- "$P_SRV dtls=1 debug_level=2" \
- "$P_CLI dtls=1 debug_level=2" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
0 \
-c "replayed record" \
-s "replayed record" \
@@ -5627,8 +5661,8 @@
run_test "DTLS proxy: duplicate every packet, server anti-replay off" \
-p "$P_PXY duplicate=1" \
- "$P_SRV dtls=1 debug_level=2 anti_replay=0" \
- "$P_CLI dtls=1 debug_level=2" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=2 anti_replay=0" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
0 \
-c "replayed record" \
-S "replayed record" \
@@ -5641,24 +5675,24 @@
run_test "DTLS proxy: multiple records in same datagram" \
-p "$P_PXY pack=50" \
- "$P_SRV dtls=1 debug_level=2" \
- "$P_CLI dtls=1 debug_level=2" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
0 \
-c "next record in same datagram" \
-s "next record in same datagram"
run_test "DTLS proxy: multiple records in same datagram, duplicate every packet" \
-p "$P_PXY pack=50 duplicate=1" \
- "$P_SRV dtls=1 debug_level=2" \
- "$P_CLI dtls=1 debug_level=2" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
0 \
-c "next record in same datagram" \
-s "next record in same datagram"
run_test "DTLS proxy: inject invalid AD record, default badmac_limit" \
-p "$P_PXY bad_ad=1" \
- "$P_SRV dtls=1 debug_level=1" \
- "$P_CLI dtls=1 debug_level=1 read_timeout=100" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=1" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=1 read_timeout=100" \
0 \
-c "discarding invalid record (mac)" \
-s "discarding invalid record (mac)" \
@@ -5669,8 +5703,8 @@
run_test "DTLS proxy: inject invalid AD record, badmac_limit 1" \
-p "$P_PXY bad_ad=1" \
- "$P_SRV dtls=1 debug_level=1 badmac_limit=1" \
- "$P_CLI dtls=1 debug_level=1 read_timeout=100" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=1 badmac_limit=1" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=1 read_timeout=100" \
1 \
-C "discarding invalid record (mac)" \
-S "discarding invalid record (mac)" \
@@ -5681,8 +5715,8 @@
run_test "DTLS proxy: inject invalid AD record, badmac_limit 2" \
-p "$P_PXY bad_ad=1" \
- "$P_SRV dtls=1 debug_level=1 badmac_limit=2" \
- "$P_CLI dtls=1 debug_level=1 read_timeout=100" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=1 badmac_limit=2" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=1 read_timeout=100" \
0 \
-c "discarding invalid record (mac)" \
-s "discarding invalid record (mac)" \
@@ -5693,8 +5727,8 @@
run_test "DTLS proxy: inject invalid AD record, badmac_limit 2, exchanges 2"\
-p "$P_PXY bad_ad=1" \
- "$P_SRV dtls=1 debug_level=1 badmac_limit=2 exchanges=2" \
- "$P_CLI dtls=1 debug_level=1 read_timeout=100 exchanges=2" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=1 badmac_limit=2 exchanges=2" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=1 read_timeout=100 exchanges=2" \
1 \
-c "discarding invalid record (mac)" \
-s "discarding invalid record (mac)" \
@@ -5705,8 +5739,8 @@
run_test "DTLS proxy: delay ChangeCipherSpec" \
-p "$P_PXY delay_ccs=1" \
- "$P_SRV dtls=1 debug_level=1" \
- "$P_CLI dtls=1 debug_level=1" \
+ "$P_SRV dtls=1 debug_level=1 dgram_packing=0" \
+ "$P_CLI dtls=1 debug_level=1 dgram_packing=0" \
0 \
-c "record from another epoch" \
-s "record from another epoch" \
@@ -5718,9 +5752,9 @@
client_needs_more_time 2
run_test "DTLS proxy: 3d (drop, delay, duplicate), \"short\" PSK handshake" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
-s "Extra-header:" \
@@ -5729,8 +5763,8 @@
client_needs_more_time 2
run_test "DTLS proxy: 3d, \"short\" RSA handshake" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none" \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 \
force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
0 \
-s "Extra-header:" \
@@ -5739,8 +5773,8 @@
client_needs_more_time 2
run_test "DTLS proxy: 3d, \"short\" (no ticket, no cli_auth) FS handshake" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=0" \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none" \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0" \
0 \
-s "Extra-header:" \
-c "HTTP/1.0 200 OK"
@@ -5748,8 +5782,8 @@
client_needs_more_time 2
run_test "DTLS proxy: 3d, FS, client auth" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=required" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=0" \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=required" \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0" \
0 \
-s "Extra-header:" \
-c "HTTP/1.0 200 OK"
@@ -5757,8 +5791,8 @@
client_needs_more_time 2
run_test "DTLS proxy: 3d, FS, ticket" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=1 auth_mode=none" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=1" \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=1 auth_mode=none" \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=1" \
0 \
-s "Extra-header:" \
-c "HTTP/1.0 200 OK"
@@ -5766,8 +5800,8 @@
client_needs_more_time 2
run_test "DTLS proxy: 3d, max handshake (FS, ticket + client auth)" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=1 auth_mode=required" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=1" \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=1 auth_mode=required" \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=1" \
0 \
-s "Extra-header:" \
-c "HTTP/1.0 200 OK"
@@ -5775,9 +5809,9 @@
client_needs_more_time 2
run_test "DTLS proxy: 3d, max handshake, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 nbio=2 tickets=1 \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 nbio=2 tickets=1 \
auth_mode=required" \
- "$P_CLI dtls=1 hs_timeout=250-10000 nbio=2 tickets=1" \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 nbio=2 tickets=1" \
0 \
-s "Extra-header:" \
-c "HTTP/1.0 200 OK"
@@ -5785,9 +5819,9 @@
client_needs_more_time 4
run_test "DTLS proxy: 3d, min handshake, resumption" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 debug_level=3" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
@@ -5799,9 +5833,9 @@
client_needs_more_time 4
run_test "DTLS proxy: 3d, min handshake, resumption, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 debug_level=3 nbio=2" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8 nbio=2" \
0 \
@@ -5814,9 +5848,9 @@
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, client-initiated renego" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiation=1 debug_level=2" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
renegotiate=1 debug_level=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
@@ -5829,9 +5863,9 @@
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, client-initiated renego, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiation=1 debug_level=2" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
renegotiate=1 debug_level=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
@@ -5844,10 +5878,10 @@
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, server-initiated renego" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiate=1 renegotiation=1 exchanges=4 \
debug_level=2" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
renegotiation=1 exchanges=4 debug_level=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
@@ -5860,10 +5894,10 @@
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, server-initiated renego, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiate=1 renegotiation=1 exchanges=4 \
debug_level=2 nbio=2" \
- "$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
+ "$P_CLI dtls=1 dgram_packing=0 hs_timeout=250-10000 tickets=0 psk=abc123 \
renegotiation=1 exchanges=4 debug_level=2 nbio=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
@@ -5877,7 +5911,7 @@
run_test "DTLS proxy: 3d, openssl server" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_SRV -dtls1 -mtu 2048" \
- "$P_CLI dtls=1 hs_timeout=250-60000 tickets=0" \
+ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000 tickets=0" \
0 \
-c "HTTP/1.0 200 OK"
@@ -5886,7 +5920,7 @@
run_test "DTLS proxy: 3d, openssl server, fragmentation" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_SRV -dtls1 -mtu 768" \
- "$P_CLI dtls=1 hs_timeout=250-60000 tickets=0" \
+ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000 tickets=0" \
0 \
-c "HTTP/1.0 200 OK"
@@ -5895,7 +5929,7 @@
run_test "DTLS proxy: 3d, openssl server, fragmentation, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_SRV -dtls1 -mtu 768" \
- "$P_CLI dtls=1 hs_timeout=250-60000 nbio=2 tickets=0" \
+ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000 nbio=2 tickets=0" \
0 \
-c "HTTP/1.0 200 OK"
@@ -5905,7 +5939,7 @@
run_test "DTLS proxy: 3d, gnutls server" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_SRV -u --mtu 2048 -a" \
- "$P_CLI dtls=1 hs_timeout=250-60000" \
+ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000" \
0 \
-s "Extra-header:" \
-c "Extra-header:"
@@ -5916,7 +5950,7 @@
run_test "DTLS proxy: 3d, gnutls server, fragmentation" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_SRV -u --mtu 512" \
- "$P_CLI dtls=1 hs_timeout=250-60000" \
+ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000" \
0 \
-s "Extra-header:" \
-c "Extra-header:"
@@ -5927,7 +5961,7 @@
run_test "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_SRV -u --mtu 512" \
- "$P_CLI dtls=1 hs_timeout=250-60000 nbio=2" \
+ "$P_CLI dgram_packing=0 dtls=1 hs_timeout=250-60000 nbio=2" \
0 \
-s "Extra-header:" \
-c "Extra-header:"