On Thu, Feb 07, 2013 at 06:49:14PM +0400, Samat Galimov wrote:
> Thank you very much, overlooked your email due to filters, sorry for delay.
> I am very happy to help, sure I would accept a patch.
> Server is available from outside world but is not heavily used ??? we dont
> point load to it because of this SSL errors.
> 
> By the way, I am using default haproxy-devel port in FreeBSD tree, so
> http://haproxy.1wt.eu/download/1.5/src/devel/haproxy-1.5-dev17.tar.gzsource
> is being used.

OK, please find it attached. You should apply it on top of your current
source tree and rebuild.

Thanks,
Willy

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 87eff2b..07b1ca7 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -128,7 +128,8 @@ int ssl_sock_verifycbk(int ok, X509_STORE_CTX *x_store)
                }
 
                if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL 
<< err)) {
-                       ERR_clear_error();
+                       if (ERR_peek_error())
+                               ERR_clear_error();
                        return 1;
                }
 
@@ -141,7 +142,8 @@ int ssl_sock_verifycbk(int ok, X509_STORE_CTX *x_store)
 
        /* check if certificate error needs to be ignored */
        if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) 
{
-               ERR_clear_error();
+               if (ERR_peek_error())
+                       ERR_clear_error();
                return 1;
        }
 
@@ -885,6 +887,9 @@ int ssl_sock_handshake(struct connection *conn, unsigned 
int flag)
        if ((conn->flags & CO_FL_CONNECTED) && 
SSL_renegotiate_pending(conn->xprt_ctx)) {
                char c;
 
+               if (unlikely(ERR_peek_error()))
+                       ERR_clear_error();
+
                ret = SSL_peek(conn->xprt_ctx, &c, 1);
                if (ret <= 0) {
                        /* handshake may have not been completed, let's find 
why */
@@ -942,6 +947,9 @@ int ssl_sock_handshake(struct connection *conn, unsigned 
int flag)
                goto reneg_ok;
        }
 
+       if (unlikely(ERR_peek_error()))
+               ERR_clear_error();
+
        ret = SSL_do_handshake(conn->xprt_ctx);
        if (ret != 1) {
                /* handshake did not complete, let's find why */
@@ -1008,7 +1016,8 @@ reneg_ok:
 
  out_error:
        /* Clear openssl global errors stack */
-       ERR_clear_error();
+       if (ERR_peek_error())
+               ERR_clear_error();
 
        /* free resumed session if exists */
        if (objt_server(conn->target) && 
objt_server(conn->target)->ssl_ctx.reused_sess) {
@@ -1062,6 +1071,9 @@ static int ssl_sock_to_buf(struct connection *conn, 
struct buffer *buf, int coun
         * EINTR too.
         */
        while (try) {
+               if (unlikely(ERR_peek_error()))
+                       ERR_clear_error();
+
                ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
                if (conn->flags & CO_FL_ERROR) {
                        /* CO_FL_ERROR may be set by ssl_sock_infocbk */
@@ -1084,7 +1096,8 @@ static int ssl_sock_to_buf(struct connection *conn, 
struct buffer *buf, int coun
                                        conn->flags |= CO_FL_ERROR;
 
                                /* Clear openssl global errors stack */
-                               ERR_clear_error();
+                               if (ERR_peek_error())
+                                       ERR_clear_error();
                        }
                        goto read0;
                }
@@ -1118,7 +1131,8 @@ static int ssl_sock_to_buf(struct connection *conn, 
struct buffer *buf, int coun
        return done;
  out_error:
        /* Clear openssl global errors stack */
-       ERR_clear_error();
+       if (ERR_peek_error())
+               ERR_clear_error();
 
        conn->flags |= CO_FL_ERROR;
        return done;
@@ -1158,6 +1172,9 @@ static int ssl_sock_from_buf(struct connection *conn, 
struct buffer *buf, int fl
                if (buf->data + try > buf->p)
                        try = buf->data + try - buf->p;
 
+               if (unlikely(ERR_peek_error()))
+                       ERR_clear_error();
+
                ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
                if (conn->flags & CO_FL_ERROR) {
                        /* CO_FL_ERROR may be set by ssl_sock_infocbk */
@@ -1201,7 +1218,8 @@ static int ssl_sock_from_buf(struct connection *conn, 
struct buffer *buf, int fl
 
  out_error:
        /* Clear openssl global errors stack */
-       ERR_clear_error();
+       if (ERR_peek_error())
+               ERR_clear_error();
 
        conn->flags |= CO_FL_ERROR;
        return done;
@@ -1226,7 +1244,8 @@ static void ssl_sock_shutw(struct connection *conn, int 
clean)
        /* no handshake was in progress, try a clean ssl shutdown */
        if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
                /* Clear openssl global errors stack */
-               ERR_clear_error();
+               if (ERR_peek_error())
+                       ERR_clear_error();
        }
 
        /* force flag on ssl to keep session in cache regardless shutdown 
result */

Reply via email to