Always save flight first, (re)send later
This will allow fragmentation to always happen in the same place, always from
a buffer distinct from ssl->out_msg, and with the same way of resuming after
returning WANT_WRITE
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 253c81f..4b17dea 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1094,6 +1094,15 @@
return( ret );
}
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+ return( ret );
+ }
+#endif
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
return( 0 );
@@ -3402,7 +3411,7 @@
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
{
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
+ if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
return( ret );
}
#endif
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 66de2e4..eda50bb 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -2390,6 +2390,15 @@
return( ret );
}
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+ return( ret );
+ }
+#endif
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) );
return( 0 );
@@ -3369,6 +3378,15 @@
return( ret );
}
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+ return( ret );
+ }
+#endif
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) );
return( 0 );
@@ -4258,7 +4276,7 @@
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
{
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
+ if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
return( ret );
}
#endif
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index b66b4fe..5f03223 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2822,18 +2822,34 @@
/*
* Retransmit the current flight of messages.
+ */
+int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
+{
+ int ret = 0;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
+
+ ret = mbedtls_ssl_flight_transmit( ssl );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
+
+ return( ret );
+}
+
+/*
+ * Transmit or retransmit the current flight of messages.
*
* Need to remember the current message in case flush_output returns
* WANT_WRITE, causing us to exit this function and come back later.
* This function must be called until state is no longer SENDING.
*/
-int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise resending" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise fligh transmission" ) );
ssl->handshake->cur_msg = ssl->handshake->flight;
ssl_swap_epochs( ssl );
@@ -2861,7 +2877,7 @@
ssl->handshake->cur_msg = cur->next;
- MBEDTLS_SSL_DEBUG_BUF( 3, "resent handshake message header", ssl->out_msg, 12 );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
{
@@ -2878,7 +2894,7 @@
ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
}
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) );
return( 0 );
}
@@ -2931,14 +2947,15 @@
*/
/*
- * Write current handshake (including CCS) message.
+ * Write (DTLS: or queue) current handshake (including CCS) message.
*
* - fill in handshake headers
* - update handshake checksum
* - DTLS: save message for resending
* - then pass to the record layer
*
- * DTLS: only used when first writing the message, not for resending.
+ * DTLS: except for HelloRequest, messages are only queued, and will only be
+ * actually sent when calling flight_transmit() or resend().
*
* Inputs:
* - ssl->out_msglen: 4 + actual handshake message len
@@ -2946,7 +2963,7 @@
* - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
* - ssl->out_msg + 4: the handshake message body
*
- * Outputs:
+ * Ouputs, ie state before passing to flight_append() or write_record():
* - ssl->out_msglen: the length of the record contents
* (including handshake headers but excluding record headers)
* - ssl->out_msg: the record contents (handshake headers + content)
@@ -3044,7 +3061,7 @@
ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
}
- /* Save for resending */
+ /* Either send now, or just save to be sent (and resent) later */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
@@ -3055,14 +3072,19 @@
return( ret );
}
}
+ else
#endif
-
- /* Actually send out */
- ret = mbedtls_ssl_write_record( ssl );
+ {
+ if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
+ return( ret );
+ }
+ }
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) );
- return( ret );
+ return( 0 );
}
/*
@@ -5645,6 +5667,15 @@
return( ret );
}
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+ return( ret );
+ }
+#endif
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) );
return( 0 );
@@ -7207,7 +7238,7 @@
if( ssl->handshake != NULL &&
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
{
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
+ if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
return( ret );
}
}