Auto-renegotiate before sequence number wrapping
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index df57bb1..0e97c11 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4273,6 +4273,33 @@
 
     return( ret );
 }
+
+/*
+ * Check record counters and renegotiate if they're above the limit.
+ */
+static int ssl_check_ctr_renegotiate( ssl_context *ssl )
+{
+    static const unsigned char ctr_limit[8] = {
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00
+    };
+
+    if( ssl->state != SSL_HANDSHAKE_OVER ||
+        ssl->renegotiation == SSL_RENEGOTIATION_PENDING ||
+        ssl->disable_renegotiation == SSL_RENEGOTIATION_DISABLED )
+    {
+        return( 0 );
+    }
+
+    // TODO: adapt for DTLS
+    if( memcmp( ssl->in_ctr,  ctr_limit, 8 ) <= 0 &&
+        memcmp( ssl->out_ctr, ctr_limit, 8 ) <= 0 )
+    {
+        return( 0 );
+    }
+
+    SSL_DEBUG_MSG( 2, ( "record counter about to wrap: renegotiate" ) );
+    return( ssl_renegotiate( ssl ) );
+}
 #endif /* POLARSSL_SSL_RENEGOTIATION */
 
 /*
@@ -4285,6 +4312,14 @@
 
     SSL_DEBUG_MSG( 2, ( "=> read" ) );
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
+    if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+        return( ret );
+    }
+#endif
+
     if( ssl->state != SSL_HANDSHAKE_OVER )
     {
         ret = ssl_handshake( ssl );
@@ -4457,6 +4492,14 @@
 
     SSL_DEBUG_MSG( 2, ( "=> write" ) );
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
+    if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+        return( ret );
+    }
+#endif
+
     if( ssl->state != SSL_HANDSHAKE_OVER )
     {
         if( ( ret = ssl_handshake( ssl ) ) != 0 )