*** a/src/backend/libpq/be-secure.c
--- b/src/backend/libpq/be-secure.c
***************
*** 324,344 **** secure_write(Port *port, void *ptr, size_t len)
  	if (port->ssl)
  	{
  		int			err;
- 		static long renegotiation_count = 0;
  
  		/*
  		 * If SSL renegotiations are enabled and we're getting close to the
  		 * limit, start one now; but avoid it if there's one already in
! 		 * progress.  Request the renegotiation before the limit has actually
! 		 * expired; we give it 1% of the specified limit, or 1kB, whichever is
! 		 * greater.
  		 */
  		if (ssl_renegotiation_limit && !in_ssl_renegotiation &&
! 			port->count > Min((ssl_renegotiation_limit - 1) * 1024L,
! 						(long) rint(ssl_renegotiation_limit * 1024L * 0.99)))
  		{
  			in_ssl_renegotiation = true;
  
  			SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
  									   sizeof(SSL_context));
  			if (SSL_renegotiate(port->ssl) <= 0)
--- 324,352 ----
  	if (port->ssl)
  	{
  		int			err;
  
  		/*
  		 * If SSL renegotiations are enabled and we're getting close to the
  		 * limit, start one now; but avoid it if there's one already in
! 		 * progress.  Request the renegotiation 1kB before the limit has
! 		 * actually expired.
  		 */
  		if (ssl_renegotiation_limit && !in_ssl_renegotiation &&
! 			port->count > (ssl_renegotiation_limit - 1) * 1024L)
  		{
  			in_ssl_renegotiation = true;
  
+ 			/*
+ 			 * The way we determine that a renegotiation has completed is by
+ 			 * observing OpenSSL's internal renegotiation counter.  Make sure
+ 			 * we start out at zero, and assume that the renegotiation is
+ 			 * complete when the counter advances.
+ 			 *
+ 			 * OpenSSL provides SSL_renegotiation_pending(), but this doesn't
+ 			 * seem to work in testing.
+ 			 */
+ 			SSL_clear_num_renegotiations(port->ssl);
+ 
  			SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
  									   sizeof(SSL_context));
  			if (SSL_renegotiate(port->ssl) <= 0)
***************
*** 347,379 **** secure_write(Port *port, void *ptr, size_t len)
  						 errmsg("SSL failure during renegotiation start")));
  			else
  			{
! 				int			handshake;
! 				int			retries = 20;
  
  				/*
! 				 * The way we determine that a renegotiation has completed is
! 				 * by observing OpenSSL's internal renegotiation counter.
! 				 * Memoize it when starting the renegotiation, and assume that
! 				 * the renegotiation is complete when the counter advances.
! 				 *
! 				 * OpenSSL provides SSL_renegotiation_pending(), but this
! 				 * doesn't seem to work in testing.
  				 */
! 				renegotiation_count = SSL_num_renegotiations(port->ssl);
! 
! 				/*
! 				 * A handshake can fail, so be prepared to retry it, but only a
! 				 * few times
! 				 */
! 				for (;;)
  				{
! 					handshake = SSL_do_handshake(port->ssl);
! 					if (handshake > 0)
  						break;	/* done */
  					ereport(COMMERROR,
  							(errcode(ERRCODE_PROTOCOL_VIOLATION),
  							 errmsg("SSL handshake failure on renegotiation, retrying")));
! 					if (retries-- <= 0)
  						ereport(FATAL,
  								(errcode(ERRCODE_PROTOCOL_VIOLATION),
  								 errmsg("unable to complete SSL handshake")));
--- 355,374 ----
  						 errmsg("SSL failure during renegotiation start")));
  			else
  			{
! 				int			retries;
  
  				/*
! 				 * A handshake can fail, so be prepared to retry it, but only
! 				 * a few times.
  				 */
! 				for (retries = 0; retries++;)
  				{
! 					if (SSL_do_handshake(port->ssl) > 0)
  						break;	/* done */
  					ereport(COMMERROR,
  							(errcode(ERRCODE_PROTOCOL_VIOLATION),
  							 errmsg("SSL handshake failure on renegotiation, retrying")));
! 					if (retries >= 20)
  						ereport(FATAL,
  								(errcode(ERRCODE_PROTOCOL_VIOLATION),
  								 errmsg("unable to complete SSL handshake")));
***************
*** 427,439 **** wloop:
  
  		/* is renegotiation complete? */
  		if (in_ssl_renegotiation &&
! 			SSL_num_renegotiations(port->ssl) > renegotiation_count)
  		{
  			in_ssl_renegotiation = false;
  			port->count = 0;
- 			/* avoid overflow issues by resetting counter */
- 			SSL_clear_num_renegotiations(port->ssl);
- 			renegotiation_count = SSL_num_renegotiations(port->ssl);
  		}
  
  		/*
--- 422,431 ----
  
  		/* is renegotiation complete? */
  		if (in_ssl_renegotiation &&
! 			SSL_num_renegotiations(port->ssl) >= 1)
  		{
  			in_ssl_renegotiation = false;
  			port->count = 0;
  		}
  
  		/*
