Fix passthrough mode engage upon srvdst ssl error

pull/48/head
Soner Tari 5 years ago
parent 6b8b819daa
commit c54cb627a1

@ -88,7 +88,8 @@ protopassthrough_engage(pxy_conn_ctx_t *ctx)
ctx->srvdst_connected = 0; ctx->srvdst_connected = 0;
// Close and free dst if open // Close and free dst if open
if (!ctx->dst.closed) { // Make sure bev is not NULL, as dst may not have been initialized yet
if (!ctx->dst.closed && ctx->dst.bev) {
ctx->dst.closed = 1; ctx->dst.closed = 1;
ctx->dst.free(ctx->dst.bev, ctx); ctx->dst.free(ctx->dst.bev, ctx);
ctx->dst.bev = NULL; ctx->dst.bev = NULL;

@ -46,13 +46,15 @@ static unsigned long ssl_session_context = 0x31415926;
#endif /* USE_SSL_SESSION_ID_CONTEXT */ #endif /* USE_SSL_SESSION_ID_CONTEXT */
void void
protossl_log_ssl_error(struct bufferevent *bev, UNUSED pxy_conn_ctx_t *ctx) protossl_log_ssl_error(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
{ {
unsigned long sslerr; unsigned long sslerr;
/* Can happen for socket errs, ssl errs; /* Can happen for socket errs, ssl errs;
* may happen for unclean ssl socket shutdowns. */ * may happen for unclean ssl socket shutdowns. */
sslerr = bufferevent_get_openssl_error(bev); sslerr = bufferevent_get_openssl_error(bev);
if (sslerr)
ctx->sslctx->have_sslerr = 1;
if (!errno && !sslerr) { if (!errno && !sslerr) {
#if LIBEVENT_VERSION_NUMBER >= 0x02010000 #if LIBEVENT_VERSION_NUMBER >= 0x02010000
/* We have disabled notification for unclean shutdowns /* We have disabled notification for unclean shutdowns
@ -1515,7 +1517,7 @@ protossl_bev_eventcb_connected_srvdst(UNUSED struct bufferevent *bev, pxy_conn_c
} }
static void NONNULL(1,2) static void NONNULL(1,2)
protossl_bev_eventcb_error_srvdst(struct bufferevent *bev, pxy_conn_ctx_t *ctx) protossl_bev_eventcb_error_srvdst(UNUSED struct bufferevent *bev, pxy_conn_ctx_t *ctx)
{ {
#ifdef DEBUG_PROXY #ifdef DEBUG_PROXY
log_dbg_level_printf(LOG_DBG_MODE_FINE, "protossl_bev_eventcb_error_srvdst: BEV_EVENT_ERROR, fd=%d\n", ctx->fd); log_dbg_level_printf(LOG_DBG_MODE_FINE, "protossl_bev_eventcb_error_srvdst: BEV_EVENT_ERROR, fd=%d\n", ctx->fd);
@ -1529,9 +1531,10 @@ protossl_bev_eventcb_error_srvdst(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
/* the callout to the original destination failed, /* the callout to the original destination failed,
* e.g. because it asked for client cert auth, so * e.g. because it asked for client cert auth, so
* close the accepted socket and clean up */ * close the accepted socket and clean up */
if (ctx->spec->opts->passthrough && bufferevent_get_openssl_error(bev)) { if (ctx->spec->opts->passthrough && ctx->sslctx->have_sslerr) {
/* ssl callout failed, fall back to plain TCP passthrough of SSL connection */ /* ssl callout failed, fall back to plain TCP passthrough of SSL connection */
log_err_level_printf(LOG_WARNING, "SSL srvdst connection failed; falling back to passthrough\n"); log_err_level_printf(LOG_WARNING, "SSL srvdst connection failed; falling back to passthrough\n");
ctx->sslctx->have_sslerr = 0;
protopassthrough_engage(ctx); protopassthrough_engage(ctx);
return; return;
} }

@ -122,6 +122,7 @@ struct ssl_ctx {
unsigned int sni_peek_retries : 6; /* max 64 SNI parse retries */ unsigned int sni_peek_retries : 6; /* max 64 SNI parse retries */
unsigned int immutable_cert : 1; /* 1 if the cert cannot be changed */ unsigned int immutable_cert : 1; /* 1 if the cert cannot be changed */
unsigned int generated_cert : 1; /* 1 if we generated a new cert */ unsigned int generated_cert : 1; /* 1 if we generated a new cert */
unsigned int have_sslerr : 1; /* 1 if we have an ssl error */
/* server name indicated by client in SNI TLS extension */ /* server name indicated by client in SNI TLS extension */
char *sni; char *sni;

Loading…
Cancel
Save