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
This commit is contained in:
Soner Tari 2017-07-28 12:52:53 +03:00
parent 2411f79582
commit dd7bf7b277
2 changed files with 38 additions and 28 deletions

View File

@ -1501,15 +1501,15 @@ pxy_http_reqhdr_filter_line(const char *line, pxy_conn_ctx_t *ctx, int child)
} }
return newhdr; return newhdr;
} else if (!strncasecmp(line, "Accept-Encoding:", 16) || } 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 // @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 // 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) || !strncasecmp(line, "Via:", 4) ||
// Also do not send the loopback address to the Internet // Also do not send the loopback address to the Internet
!strncasecmp(line, "X-Forwarded-For:", 16)) { !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))) {
return NULL; return NULL;
} else if (line[0] == '\0') { } else if (line[0] == '\0') {
ctx->seen_req_header = 1; ctx->seen_req_header = 1;
@ -2881,7 +2881,7 @@ leave:
} }
static void 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; unsigned long sslerr;
@ -3026,28 +3026,31 @@ pxy_bev_eventcb(struct bufferevent *bev, short events, void *arg)
if (events & BEV_EVENT_EOF) { 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); 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) { if (bev == ctx->srv_dst.bev) {
bufferevent_free_and_close_fd(ctx->srv_dst.bev, ctx); // bufferevent_free_and_close_fd(ctx->srv_dst.bev, ctx);
ctx->srv_dst.bev = NULL; // ctx->srv_dst.bev = NULL;
ctx->srv_dst.closed = 1; // 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; return;
} else { } 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) { if (!ctx->connected) {
log_dbg_printf("EOF on outbound connection before " log_dbg_printf("EOF on outbound connection before "
"connection establishment\n"); "connection establishment\n");
@ -3183,6 +3186,7 @@ pxy_bev_eventcb_child(struct bufferevent *bev, short events, void *arg)
if (!ctx->connected) { if (!ctx->connected) {
log_dbg_printf("EOF on outbound connection before " log_dbg_printf("EOF on outbound connection before "
"connection establishment\n"); "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); evutil_closesocket(ctx->fd);
other->closed = 1; other->closed = 1;
} else if (!other->closed) { } else if (!other->closed) {

View File

@ -90,6 +90,7 @@ pxy_ssl_shutdown_cb(evutil_socket_t fd, UNUSED short what, void *arg)
{ {
pxy_ssl_shutdown_ctx_t *ctx = arg; pxy_ssl_shutdown_ctx_t *ctx = arg;
struct timeval retry_delay = {0, 100}; struct timeval retry_delay = {0, 100};
// struct timeval retry_delay = {0, 500};
short want = 0; short want = 0;
int rv, sslerr; 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))) { switch ((sslerr = SSL_get_error(ctx->ssl, rv))) {
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
want = EV_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; goto retry;
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
want = EV_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; goto retry;
case SSL_ERROR_ZERO_RETURN: 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; goto retry;
case SSL_ERROR_SYSCALL: case SSL_ERROR_SYSCALL:
case SSL_ERROR_SSL: 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; goto complete;
default: 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() " 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;
} }
goto complete; goto complete;
@ -135,7 +141,7 @@ pxy_ssl_shutdown_cb(evutil_socket_t fd, UNUSED short what, void *arg)
retry: retry:
if (ctx->retries++ >= 50) { if (ctx->retries++ >= 50) {
log_err_printf("Failed to shutdown SSL connection cleanly: " 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; goto complete;
} }
ctx->ev = event_new(ctx->evbase, fd, want, pxy_ssl_shutdown_cb, ctx); ctx->ev = event_new(ctx->evbase, fd, want, pxy_ssl_shutdown_cb, ctx);
@ -144,7 +150,7 @@ retry:
return; return;
} }
log_err_printf("Failed to shutdown SSL connection cleanly: " 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: complete:
if (OPTS_DEBUG(ctx->opts)) { if (OPTS_DEBUG(ctx->opts)) {