I noticed that whenever renegotiation happens because of the automatic
control by time or byte count, the other counter is not reset when one
of them happens.  So if you have both enabled, you might have more
renegotiations than you wanted: perhaps the byte count is about to reach
the threshold when the time is out, and then you run two in quick
succession.  I notice this has been like this since the SSLeay 0.9.0b
import by Ralf Engelschall in 1998 (commit 58964a492275).

The attached patch solves this by resetting both the time and byte count
anytime one of them causes a renegotiation to occur.

I am just starting to dive into the OpenSSL code, so apologies if I am
doing something wrong here.

Comments?

-- 
Álvaro Herrera <[email protected]>
PostgreSQL Development, 24x7 Support, Training & Services
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c
index e9552ca..1603184 100644
--- a/ssl/bio_ssl.c
+++ b/ssl/bio_ssl.c
@@ -177,6 +177,10 @@ static int ssl_read(BIO *b, char *out, int outl)
 			if (sb->byte_count > sb->renegotiate_count)
 				{
 				sb->byte_count=0;
+				/* reset time as well, but avoid syscall if
+				 * time-based renegotiation is not enabled */
+				if (sb->renegotiate_timeout > 0)
+					sb->last_time=(unsigned long)time(NULL);
 				sb->num_renegotiates++;
 				SSL_renegotiate(ssl);
 				r=1;
@@ -189,6 +193,7 @@ static int ssl_read(BIO *b, char *out, int outl)
 			tm=(unsigned long)time(NULL);
 			if (tm > sb->last_time+sb->renegotiate_timeout)
 				{
+				sb->byte_count=0;
 				sb->last_time=tm;
 				sb->num_renegotiates++;
 				SSL_renegotiate(ssl);
@@ -252,6 +257,10 @@ static int ssl_write(BIO *b, const char *out, int outl)
 			if (bs->byte_count > bs->renegotiate_count)
 				{
 				bs->byte_count=0;
+				/* reset time as well, but avoid syscall if
+				 * time-based renegotiation is not enabled */
+				if (bs->renegotiate_timeout > 0)
+					bs->last_time=(unsigned long)time(NULL);
 				bs->num_renegotiates++;
 				SSL_renegotiate(ssl);
 				r=1;
@@ -264,6 +273,7 @@ static int ssl_write(BIO *b, const char *out, int outl)
 			tm=(unsigned long)time(NULL);
 			if (tm > bs->last_time+bs->renegotiate_timeout)
 				{
+				bs->byte_count=0;
 				bs->last_time=tm;
 				bs->num_renegotiates++;
 				SSL_renegotiate(ssl);

Reply via email to