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 */