From dd7bf7b27748548e692db641c9fe8eea9225d2f6 Mon Sep 17 00:00:00 2001 From: Soner Tari Date: Fri, 28 Jul 2017 12:52:53 +0300 Subject: [PATCH] Fix srv_dst EOF on outbound connection before connection establishment, free conn, also move i/o debug lines to prevent segfault due to already freed srv_dst Remove squid header lines only in children --- pxyconn.c | 54 ++++++++++++++++++++++++++++------------------------ pxysslshut.c | 12 +++++++++--- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/pxyconn.c b/pxyconn.c index 2f15798..6673b9b 100644 --- a/pxyconn.c +++ b/pxyconn.c @@ -1501,15 +1501,15 @@ pxy_http_reqhdr_filter_line(const char *line, pxy_conn_ctx_t *ctx, int child) } return newhdr; } else if (!strncasecmp(line, "Accept-Encoding:", 16) || - !strncasecmp(line, "Keep-Alive:", 11) || + !strncasecmp(line, "Keep-Alive:", 11)) { + return NULL; + } else if (child && (!strncasecmp(line, SSLPROXY_ADDR_KEY, SSLPROXY_ADDR_KEY_LEN) || + !strncasecmp(line, SSLPROXY_SRCADDR_KEY, SSLPROXY_SRCADDR_KEY_LEN) || // @attention flickr keeps redirecting to https with 301 unless we remove the Via line of squid // Apparently flickr assumes the existence of Via header field or squid keyword a sign of plain http, even if we are using https !strncasecmp(line, "Via:", 4) || // Also do not send the loopback address to the Internet - !strncasecmp(line, "X-Forwarded-For:", 16)) { - return NULL; - } else if (child && (!strncasecmp(line, SSLPROXY_ADDR_KEY, SSLPROXY_ADDR_KEY_LEN) || - !strncasecmp(line, SSLPROXY_SRCADDR_KEY, SSLPROXY_SRCADDR_KEY_LEN))) { + !strncasecmp(line, "X-Forwarded-For:", 16))) { return NULL; } else if (line[0] == '\0') { ctx->seen_req_header = 1; @@ -2881,7 +2881,7 @@ leave: } static void -pxy_print_ssl_error(struct bufferevent *bev, pxy_conn_ctx_t *ctx) +pxy_print_ssl_error(struct bufferevent *bev, UNUSED pxy_conn_ctx_t *ctx) { unsigned long sslerr; @@ -3026,28 +3026,31 @@ pxy_bev_eventcb(struct bufferevent *bev, short events, void *arg) if (events & BEV_EVENT_EOF) { log_dbg_level_printf(LOG_DBG_MODE_FINEST, ">>>>>=================================== pxy_bev_eventcb: EOF %s fd=%d\n", event_name, ctx->fd); -#ifdef DEBUG_PROXY - if (OPTS_DEBUG(ctx->opts)) { - log_dbg_printf("evbuffer size at EOF: " - "i:%zu o:%zu i:%zu o:%zu\n", - evbuffer_get_length( - bufferevent_get_input(bev)), - evbuffer_get_length( - bufferevent_get_output(bev)), - evbuffer_get_length( - bufferevent_get_input(other->bev)), - evbuffer_get_length( - bufferevent_get_output(other->bev)) - ); - } -#endif /* DEBUG_PROXY */ - if (bev == ctx->srv_dst.bev) { - bufferevent_free_and_close_fd(ctx->srv_dst.bev, ctx); - ctx->srv_dst.bev = NULL; - ctx->srv_dst.closed = 1; +// bufferevent_free_and_close_fd(ctx->srv_dst.bev, ctx); +// ctx->srv_dst.bev = NULL; +// ctx->srv_dst.closed = 1; + log_dbg_level_printf(LOG_DBG_MODE_FINEST, ">>>>>=================================== pxy_bev_eventcb: EOF on outbound connection before connection establishment, fd=%d\n", ctx->fd); + pxy_conn_free(ctx, 1); return; } else { +#ifdef DEBUG_PROXY + if (OPTS_DEBUG(ctx->opts)) { + log_dbg_printf("evbuffer size at EOF: " + "i:%zu o:%zu i:%zu o:%zu\n", + evbuffer_get_length( + bufferevent_get_input(bev)), + evbuffer_get_length( + bufferevent_get_output(bev)), + evbuffer_get_length( + bufferevent_get_input(other->bev)), + evbuffer_get_length( + bufferevent_get_output(other->bev)) + ); + } +#endif /* DEBUG_PROXY */ + + // @todo How to handle the following case? if (!ctx->connected) { log_dbg_printf("EOF on outbound connection before " "connection establishment\n"); @@ -3183,6 +3186,7 @@ pxy_bev_eventcb_child(struct bufferevent *bev, short events, void *arg) if (!ctx->connected) { log_dbg_printf("EOF on outbound connection before " "connection establishment\n"); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, ">>>>>=================================== pxy_bev_eventcb_child: EOF on outbound connection before connection establishment, fd=%d, pfd=%d\n", ctx->fd, parent->fd); evutil_closesocket(ctx->fd); other->closed = 1; } else if (!other->closed) { diff --git a/pxysslshut.c b/pxysslshut.c index e4e5720..7afc6f4 100644 --- a/pxysslshut.c +++ b/pxysslshut.c @@ -90,6 +90,7 @@ pxy_ssl_shutdown_cb(evutil_socket_t fd, UNUSED short what, void *arg) { pxy_ssl_shutdown_ctx_t *ctx = arg; struct timeval retry_delay = {0, 100}; +// struct timeval retry_delay = {0, 500}; short want = 0; int rv, sslerr; @@ -116,18 +117,23 @@ pxy_ssl_shutdown_cb(evutil_socket_t fd, UNUSED short what, void *arg) switch ((sslerr = SSL_get_error(ctx->ssl, rv))) { case SSL_ERROR_WANT_READ: want = EV_READ; + log_dbg_level_printf(LOG_DBG_MODE_FINEST, ">>>>> pxy_ssl_shutdown_cb: SSL_ERROR_WANT_READ, retries=%d, fd=%d\n", ctx->retries, fd); goto retry; case SSL_ERROR_WANT_WRITE: want = EV_WRITE; + log_dbg_level_printf(LOG_DBG_MODE_FINEST, ">>>>> pxy_ssl_shutdown_cb: SSL_ERROR_WANT_WRITE, retries=%d, fd=%d\n", ctx->retries, fd); goto retry; case SSL_ERROR_ZERO_RETURN: + log_dbg_level_printf(LOG_DBG_MODE_FINEST, ">>>>> pxy_ssl_shutdown_cb: SSL_ERROR_ZERO_RETURN, retries=%d, fd=%d\n", ctx->retries, fd); goto retry; case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: + log_dbg_level_printf(LOG_DBG_MODE_FINEST, ">>>>> pxy_ssl_shutdown_cb: SSL_ERROR_SYSCALL or SSL_ERROR_SSL, retries=%d, fd=%d\n", ctx->retries, fd); goto complete; default: + log_dbg_level_printf(LOG_DBG_MODE_FINEST, ">>>>> pxy_ssl_shutdown_cb: default, retries=%d, fd=%d\n", ctx->retries, fd); log_err_printf("Unhandled SSL_shutdown() " - "error %i. Closing fd.\n", sslerr); + "error %i. Closing fd, fd=%d\n", sslerr, fd); goto complete; } goto complete; @@ -135,7 +141,7 @@ pxy_ssl_shutdown_cb(evutil_socket_t fd, UNUSED short what, void *arg) retry: if (ctx->retries++ >= 50) { log_err_printf("Failed to shutdown SSL connection cleanly: " - "Max retries reached. Closing fd.\n"); + "Max retries reached. Closing fd, fd=%d\n", fd); goto complete; } ctx->ev = event_new(ctx->evbase, fd, want, pxy_ssl_shutdown_cb, ctx); @@ -144,7 +150,7 @@ retry: return; } log_err_printf("Failed to shutdown SSL connection cleanly: " - "Cannot create event. Closing fd.\n"); + "Cannot create event. Closing fd, fd=%d\n", fd); complete: if (OPTS_DEBUG(ctx->opts)) {