Add ssl_set_renegotiation_enforced()
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 91e3981..b90b232 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -221,6 +221,9 @@
 #define SSL_RENEGOTIATION_DISABLED      0
 #define SSL_RENEGOTIATION_ENABLED       1
 
+#define SSL_RENEGOTIATION_NOT_ENFORCED  -1
+#define SSL_RENEGO_MAX_RECORDS_DEFAULT  16
+
 #define SSL_LEGACY_NO_RENEGOTIATION     0
 #define SSL_LEGACY_ALLOW_RENEGOTIATION  1
 #define SSL_LEGACY_BREAK_HANDSHAKE      2
@@ -620,6 +623,7 @@
      */
     int state;                  /*!< SSL handshake: current state     */
     int renegotiation;          /*!< Initial or renegotiation         */
+    int renego_records_seen;    /*!< Records since renego request     */
 
     int major_ver;              /*!< equal to  SSL_MAJOR_VERSION_3    */
     int minor_ver;              /*!< either 0 (SSL3) or 1 (TLS1.0)    */
@@ -744,6 +748,7 @@
     int verify_result;                  /*!<  verification result     */
     int disable_renegotiation;          /*!<  enable/disable renegotiation   */
     int allow_legacy_renegotiation;     /*!<  allow legacy renegotiation     */
+    int renego_max_records;             /*!<  grace period for renegotiation */
     const int *ciphersuite_list[4];     /*!<  allowed ciphersuites / version */
 #if defined(POLARSSL_SSL_SET_CURVES)
     const ecp_group_id *curve_list;     /*!<  allowed curves                 */
@@ -1422,6 +1427,33 @@
 void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy );
 
 /**
+ * \brief          Enforce server-requested renegotiation.
+ *                 (Default: enforced, max_records = 16)
+ *                 (No effect on client.)
+ *
+ *                 When a server requests a renegotiation, the client can
+ *                 comply or ignore the request. This function allows the
+ *                 server to decide if it should enforce its renegotiation
+ *                 requests by closing the connection if the client doesn't
+ *                 initiate a renegotiation.
+ *
+ *                 However, records could already be in transit from the
+ *                 client to the server when the request is emitted. In order
+ *                 to increase reliability, the server can accept a number of
+ *                 records containing application data before the ClientHello
+ *                 that was requested.
+ *
+ *                 The optimal value is highly dependent on the specific usage
+ *                 scenario.
+ *
+ * \param ssl      SSL context
+ * \param max_records Use SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to
+ *                 enforce renegotiation, or a non-negative value to enforce
+ *                 it but allow for a grace period of max_records records.
+ */
+void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records );
+
+/**
  * \brief          Return the number of data bytes available to read
  *
  * \param ssl      SSL context
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index a1428dc..7c8f306 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3055,7 +3055,10 @@
     ssl->handshake = NULL;
 
     if( ssl->renegotiation == SSL_RENEGOTIATION )
+    {
         ssl->renegotiation =  SSL_RENEGOTIATION_DONE;
+        ssl->renego_records_seen = 0;
+    }
 
     /*
      * Switch in our now active transform context
@@ -3345,6 +3348,8 @@
 
     ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() );
 
+    ssl->renego_max_records = SSL_RENEGO_MAX_RECORDS_DEFAULT;
+
 #if defined(POLARSSL_DHM_C)
     if( ( ret = mpi_read_string( &ssl->dhm_P, 16,
                                  POLARSSL_DHM_RFC5114_MODP_1024_P) ) != 0 ||
@@ -3435,6 +3440,8 @@
     ssl->transform_in = NULL;
     ssl->transform_out = NULL;
 
+    ssl->renego_records_seen = 0;
+
     memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
     memset( ssl->in_ctr, 0, SSL_BUFFER_LEN );
 
@@ -3952,6 +3959,11 @@
     ssl->allow_legacy_renegotiation = allow_legacy;
 }
 
+void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records )
+{
+    ssl->renego_max_records = max_records;
+}
+
 #if defined(POLARSSL_SSL_SESSION_TICKETS)
 int ssl_set_session_tickets( ssl_context *ssl, int use_tickets )
 {
@@ -4296,9 +4308,15 @@
         }
         else if( ssl->renegotiation == SSL_RENEGOTIATION_PENDING )
         {
-            SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
-                                "but not honored by client" ) );
-            return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
+            ssl->renego_records_seen++;
+
+            if( ssl->renego_max_records >= 0 &&
+                ssl->renego_records_seen > ssl->renego_max_records )
+            {
+                SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
+                                    "but not honored by client" ) );
+                return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
+            }
         }
         else if( ssl->in_msgtype != SSL_MSG_APPLICATION_DATA )
         {
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 102a5b5..6c2a92d 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -630,8 +630,8 @@
             -C "=> renegotiate" \
             -S "=> renegotiate" \
             -s "write hello request" \
-            -s "SSL - An unexpected message was received from our peer" \
-            -s "failed"
+            -S "SSL - An unexpected message was received from our peer" \
+            -S "failed"
 
 # Tests for auth_mode