I think this block is better written as:

        if (ssl_renegotiation_limit && port->count > ssl_renegotiation_limit * 
1024L)
        {
            SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
                                       sizeof(SSL_context));
            if (SSL_renegotiate(port->ssl) <= 0)
                ereport(COMMERROR,
                        (errcode(ERRCODE_PROTOCOL_VIOLATION),
                         errmsg("SSL renegotiation failure in renegotiate")));
            else
            {
                int    handshake;

                do {
                    handshake = SSL_do_handshake(port->ssl);
                    if (handshake <= 0)
                        ereport(COMMERROR,
                                (errcode(ERRCODE_PROTOCOL_VIOLATION),
                                 errmsg("SSL renegotiation failure in 
handshake, retrying")));
                } while (handshake <= 0);

                if (port->ssl->state != SSL_ST_OK)
                    ereport(COMMERROR,
                            (errcode(ERRCODE_PROTOCOL_VIOLATION),
                             errmsg("SSL failed to send renegotiation 
request")));
                else
                    port->count = 0;
            }
        }

In other words, retry the SSL_do_handshake() until it reports OK, but
not more than that; this seems to give better results in my (admittedly
crude) experiments.  I am unsure about checking port->ssl->state after
the handshake; it's probably pointless, really.

In any case, the old code was calling SSL_do_handshake() even if
SSL_renegotiate() failed; and it was resetting the port->count even if
the handshake failed.  Both of these smell like bugs to me.

-- 
Álvaro Herrera                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to