Fix max_fragment_length with DTLS
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index d2559ba..91f92f9 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -1946,6 +1946,12 @@
  * \note           When this function returns POLARSSL_ERR_NET_WANT_WRITE,
  *                 it must be called later with the *same* arguments,
  *                 until it returns a positive value.
+ *
+ * \note           When DTLS is in use, and a maximum fragment length was
+ *                 either set with \c ssl_set_max_frag_len() or negotiated by
+ *                 the peer, len must not not be greater than the maximum
+ *                 fragment length, or POLARSSL_ERR_SSL_BAD_INPUT_DATA is
+ *                 returned.
  */
 int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len );
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4edf19a..3206a73 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -5894,8 +5894,9 @@
 int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len )
 {
     int ret;
-    size_t n;
-    unsigned int max_len = SSL_MAX_CONTENT_LEN;
+#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
+    unsigned int max_len;
+#endif
 
     SSL_DEBUG_MSG( 2, ( "=> write" ) );
 
@@ -5922,9 +5923,22 @@
     {
         max_len = mfl_code_to_length[ssl->session_out->mfl_code];
     }
-#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
 
-    n = ( len < max_len) ? len : max_len;
+    if( len > max_len )
+    {
+#if defined(POLARSSL_SSL_PROTO_DTLS)
+        if( ssl->transport == SSL_TRANSPORT_DATAGRAM )
+        {
+            SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
+                                "maximum fragment length: %d > %d",
+                                len, max_len ) );
+            return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+        }
+        else
+#endif
+            len = max_len;
+    }
+#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
 
     if( ssl->out_left != 0 )
     {
@@ -5936,9 +5950,9 @@
     }
     else
     {
-        ssl->out_msglen  = n;
+        ssl->out_msglen  = len;
         ssl->out_msgtype = SSL_MSG_APPLICATION_DATA;
-        memcpy( ssl->out_msg, buf, n );
+        memcpy( ssl->out_msg, buf, len );
 
         if( ( ret = ssl_write_record( ssl ) ) != 0 )
         {
@@ -5949,7 +5963,7 @@
 
     SSL_DEBUG_MSG( 2, ( "<= write" ) );
 
-    return( (int) n );
+    return( (int) len );
 }
 
 /*
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index df94fe0..e9a0971 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -748,6 +748,39 @@
             -c "client hello, adding max_fragment_length extension" \
             -c "found max_fragment_length extension"
 
+run_test    "Max fragment length: client, message just fits" \
+            "$P_SRV debug_level=3" \
+            "$P_CLI debug_level=3 max_frag_len=2048 request_size=2048" \
+            0 \
+            -c "client hello, adding max_fragment_length extension" \
+            -s "found max fragment length extension" \
+            -s "server hello, max_fragment_length extension" \
+            -c "found max_fragment_length extension" \
+            -c "2048 bytes written in 1 fragments" \
+            -s "2048 bytes read"
+
+run_test    "Max fragment length: client, larger message" \
+            "$P_SRV debug_level=3" \
+            "$P_CLI debug_level=3 max_frag_len=2048 request_size=2345" \
+            0 \
+            -c "client hello, adding max_fragment_length extension" \
+            -s "found max fragment length extension" \
+            -s "server hello, max_fragment_length extension" \
+            -c "found max_fragment_length extension" \
+            -c "2345 bytes written in 2 fragments" \
+            -s "2048 bytes read" \
+            -s "297 bytes read"
+
+run_test    "Max fragment length: client, larger message" \
+            "$P_SRV debug_level=3 dtls=1" \
+            "$P_CLI debug_level=3 dtls=1 max_frag_len=2048 request_size=2345" \
+            1 \
+            -c "client hello, adding max_fragment_length extension" \
+            -s "found max fragment length extension" \
+            -s "server hello, max_fragment_length extension" \
+            -c "found max_fragment_length extension" \
+            -c "fragment larger than.*maximum"
+
 # Tests for renegotiation
 
 run_test    "Renegotiation: none, for reference" \