From bb6584e31092308b8d3a5cb90a541b224bea7487 Mon Sep 17 00:00:00 2001 From: Soner Tari Date: Mon, 24 Sep 2018 00:41:00 +0300 Subject: [PATCH] Refactor to reuse content logging code, remove redundant code, improve and clean up --- pxyconn.c | 427 ++++++++++++++++++++++++------------------------------ 1 file changed, 188 insertions(+), 239 deletions(-) diff --git a/pxyconn.c b/pxyconn.c index 2da6000..7613d6f 100644 --- a/pxyconn.c +++ b/pxyconn.c @@ -1907,28 +1907,69 @@ pxy_get_event_name_child(struct bufferevent *bev, pxy_conn_child_ctx_t *ctx) } #endif /* DEBUG_PROXY */ +static int +pxy_buffer_content_line(pxy_conn_ctx_t *ctx, char *line, unsigned char **buf, size_t *sz) +{ + if (WANT_CONTENT_LOG(ctx->conn)) { + size_t line_sz = strlen(line); + *buf = realloc(*buf, *sz + line_sz + 2); + if (!buf) { + return -1; + } + + memcpy(*buf + *sz, line, line_sz); + memcpy(*buf + *sz + line_sz, "\r\n", 2); + *sz += line_sz + 2; + } + return 0; +} + +static int +pxy_log_content_buf(pxy_conn_ctx_t *ctx, unsigned char *buf, size_t sz, int req) +{ + if (WANT_CONTENT_LOG(ctx->conn)) { + if (buf) { + logbuf_t *lb = logbuf_new_alloc(sz, NULL, NULL); + if (!lb) { + return -1; + } + memcpy(lb->buf, buf, lb->sz); + if (log_content_submit(ctx->conn->logctx, lb, req) == -1) { + logbuf_free(lb); + log_err_level_printf(LOG_WARNING, "Content log submission failed\n"); + return -1; + } + } + } + return 0; +} + +static int +pxy_log_content_inbuf(pxy_conn_ctx_t *ctx, struct evbuffer *inbuf, int req) +{ + if (WANT_CONTENT_LOG(ctx->conn)) { + size_t sz = evbuffer_get_length(inbuf); + unsigned char *buf = malloc(sz); + if (!buf || (evbuffer_copyout(inbuf, buf, sz) == -1) || (pxy_log_content_buf(ctx, buf, sz, req) == -1)) { + return -1; + } + } + return 0; +} + static void -pxy_http_reqhdr_filter(struct evbuffer *inbuf, struct evbuffer *outbuf, struct bufferevent *bev, pxy_conn_ctx_t *ctx) +pxy_http_reqhdr_filter(struct evbuffer *inbuf, struct evbuffer *outbuf, pxy_conn_ctx_t *ctx) { - logbuf_t *lb = NULL, *tail = NULL; + unsigned char *buf = NULL; + size_t sz = 0; char *line; while ((line = evbuffer_readln(inbuf, NULL, EVBUFFER_EOL_CRLF))) { - char *replace; - if (WANT_CONTENT_LOG(ctx->conn)) { - logbuf_t *tmp; - tmp = logbuf_new_printf(NULL, NULL, - "%s\r\n", line); - if (tail) { - if (tmp) { - tail->next = tmp; - tail = tail->next; - } - } else { - lb = tail = tmp; - } + if (pxy_buffer_content_line(ctx, line, &buf, &sz) == -1) { + goto errout; } - replace = pxy_http_reqhdr_filter_line(line, ctx); + + char *replace = pxy_http_reqhdr_filter_line(line, ctx); #ifdef DEBUG_PROXY log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_http_reqhdr_filter: src line, fd=%d: %s\n", ctx->fd, line); #endif /* DEBUG_PROXY */ @@ -1963,69 +2004,55 @@ pxy_http_reqhdr_filter(struct evbuffer *inbuf, struct evbuffer *outbuf, struct b break; } } - if (lb && WANT_CONTENT_LOG(ctx->conn)) { - if (log_content_submit(ctx->conn->logctx, lb, - 1/*req*/) == -1) { - logbuf_free(lb); - log_err_level_printf(LOG_WARNING, "Content log " - "submission failed\n"); - } + + if (pxy_log_content_buf(ctx, buf, sz, 1) == -1) { + goto errout; } + if (!ctx->seen_req_header) { - goto leave; + goto out; } // @todo Fix this /* out of memory condition? */ if (ctx->enomem) { - pxy_conn_free(ctx->conn, (bev == ctx->src.bev)); - goto leave; + goto errout; } /* no data left after parsing headers? */ - if (evbuffer_get_length(inbuf) == 0) - goto leave; + if (evbuffer_get_length(inbuf) == 0) { + goto out; + } - if (WANT_CONTENT_LOG(ctx->conn)) { - logbuf_t *lb; - lb = logbuf_new_alloc(evbuffer_get_length(inbuf), NULL, NULL); - if (lb && (evbuffer_copyout(inbuf, lb->buf, lb->sz) != -1)) { - if (log_content_submit(ctx->conn->logctx, lb, - (bev == ctx->src.bev)) == -1) { - logbuf_free(lb); - log_err_level_printf(LOG_WARNING, "Content log " - "submission failed\n"); - } - } + if (pxy_log_content_inbuf(ctx, inbuf, 1) == -1) { + goto errout; } + evbuffer_add_buffer(outbuf, inbuf); -leave: + goto out; + +errout: + pxy_conn_free(ctx->conn, 1); +out: + if (buf) { + free(buf); + } return; } static void -pxy_http_resphdr_filter(struct evbuffer *inbuf, struct evbuffer *outbuf, struct bufferevent *bev, pxy_conn_ctx_t *ctx) +pxy_http_resphdr_filter(struct evbuffer *inbuf, struct evbuffer *outbuf, pxy_conn_ctx_t *ctx) { - logbuf_t *lb = NULL, *tail = NULL; - + unsigned char *buf = NULL; + size_t sz = 0; char *line; - while ((line = evbuffer_readln(inbuf, NULL, - EVBUFFER_EOL_CRLF))) { - char *replace; - if (WANT_CONTENT_LOG(ctx->conn)) { - logbuf_t *tmp; - tmp = logbuf_new_printf(NULL, NULL, - "%s\r\n", line); - if (tail) { - if (tmp) { - tail->next = tmp; - tail = tail->next; - } - } else { - lb = tail = tmp; - } + + while ((line = evbuffer_readln(inbuf, NULL, EVBUFFER_EOL_CRLF))) { + if (pxy_buffer_content_line(ctx, line, &buf, &sz) == -1) { + goto errout; } - replace = pxy_http_resphdr_filter_line(line, ctx); + + char *replace = pxy_http_resphdr_filter_line(line, ctx); #ifdef DEBUG_PROXY log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_http_resphdr_filter: dst line, fd=%d: %s\n", ctx->fd, line); #endif /* DEBUG_PROXY */ @@ -2043,6 +2070,7 @@ pxy_http_resphdr_filter(struct evbuffer *inbuf, struct evbuffer *outbuf, struct #endif /* DEBUG_PROXY */ } free(line); + if (ctx->seen_resp_header) { /* response header complete: log connection */ if (!ctx->is_child && (WANT_CONNECT_LOG(ctx->conn) || ctx->conn->opts->statslog)) { @@ -2051,81 +2079,40 @@ pxy_http_resphdr_filter(struct evbuffer *inbuf, struct evbuffer *outbuf, struct break; } } - if (lb && WANT_CONTENT_LOG(ctx->conn)) { - if (log_content_submit(ctx->conn->logctx, lb, - 0/*resp*/) == -1) { - logbuf_free(lb); - log_err_level_printf(LOG_WARNING, "Content log " - "submission failed\n"); - } + + if (pxy_log_content_buf(ctx, buf, sz, 0) == -1) { + goto errout; } + if (!ctx->seen_resp_header) { - goto leave; + goto out; } // @todo Fix this /* out of memory condition? */ if (ctx->enomem) { - pxy_conn_free(ctx->conn, (bev == ctx->src.bev)); - goto leave; + goto errout; } /* no data left after parsing headers? */ - if (evbuffer_get_length(inbuf) == 0) - goto leave; - - if (WANT_CONTENT_LOG(ctx->conn)) { - logbuf_t *lb; - lb = logbuf_new_alloc(evbuffer_get_length(inbuf), NULL, NULL); - if (lb && (evbuffer_copyout(inbuf, lb->buf, lb->sz) != -1)) { - if (log_content_submit(ctx->conn->logctx, lb, - (bev == ctx->src.bev)) == -1) { - logbuf_free(lb); - log_err_level_printf(LOG_WARNING, "Content log " - "submission failed\n"); - } - } - } - evbuffer_add_buffer(outbuf, inbuf); -leave: - return; -} - -static void -pxy_process_response(struct evbuffer *inbuf, struct evbuffer *outbuf, struct bufferevent *bev, pxy_conn_ctx_t *ctx) -{ - size_t packet_size = evbuffer_get_length(inbuf); - char *packet = malloc(packet_size); - if (!packet) { - ctx->enomem = 1; - return; - } - - if (evbuffer_remove(inbuf, packet, packet_size) < 0) { - log_err_printf("evbuffer_remove cannot drain the buffer\n"); + if (evbuffer_get_length(inbuf) == 0) { + goto out; } - if (evbuffer_add(outbuf, packet, packet_size) < 0) { - log_err_printf("evbuffer_add failed\n"); + if (pxy_log_content_inbuf(ctx, inbuf, 0) == -1) { + goto errout; } -#ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_response: dst packet (size=%lu)\n", packet_size); -#endif /* DEBUG_PROXY */ + evbuffer_add_buffer(outbuf, inbuf); + goto out; - if (WANT_CONTENT_LOG(ctx->conn)) { - logbuf_t *lb; - lb = logbuf_new_alloc(packet_size, NULL, NULL); - if (lb) { - memcpy(lb->buf, packet, lb->sz); - if (log_content_submit(ctx->conn->logctx, lb, (bev == ctx->src.bev)) == -1) { - logbuf_free(lb); - log_err_level_printf(LOG_WARNING, "Content log " - "submission failed\n"); - } - } +errout: + pxy_conn_free(ctx->conn, 0); +out: + if (buf) { + free(buf); } - free(packet); + return; } /* @@ -2138,40 +2125,34 @@ pxy_bev_readcb(struct bufferevent *bev, void *arg) pxy_conn_ctx_t *ctx = arg; ctx->atime = time(NULL); - size_t bytes = evbuffer_get_length(bufferevent_get_input(bev)); #ifdef DEBUG_PROXY - if (OPTS_DEBUG(ctx->opts)) { - log_dbg_printf("%p %p %s readcb\n", arg, (void*)bev, - (bev == ctx->src.bev) ? "src" : "dst"); - } - char *event_name = pxy_get_event_name(bev, ctx); - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: ENTER %s, fd=%d, child_fd=%d, size=%lu\n", - event_name, ctx->fd, ctx->child_fd, bytes); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: ENTER %s, fd=%d, child_fd=%d, size=%zu\n", + event_name, ctx->fd, ctx->child_fd, evbuffer_get_length(bufferevent_get_input(bev))); #endif /* DEBUG_PROXY */ if (!ctx->connected) { - log_err_level_printf(LOG_CRIT, "readcb called when other end not connected - " - "aborting.\n"); + log_err_level_printf(LOG_CRIT, "pxy_bev_readcb: readcb called when other end not connected - aborting.\n"); log_exceptcb(); return; } struct evbuffer *inbuf = bufferevent_get_input(bev); pxy_conn_desc_t *other; - if (!ctx->passthrough) { - other = (bev==ctx->src.bev) ? &ctx->dst : &ctx->src; - } else { + if (ctx->passthrough) { // Passthrough packets are transfered between src and srv_dst other = (bev==ctx->src.bev) ? &ctx->srv_dst : &ctx->src; + } else { + other = (bev==ctx->src.bev) ? &ctx->dst : &ctx->src; } struct evbuffer *outbuf = bufferevent_get_output(other->bev); + size_t inbuf_size = evbuffer_get_length(inbuf); + if (other->closed) { - log_dbg_printf("Warning: Drained %zu bytes (conn closed)\n", - evbuffer_get_length(inbuf)); - evbuffer_drain(inbuf, evbuffer_get_length(inbuf)); + log_dbg_printf("Warning: Drained %zu bytes (conn closed)\n", inbuf_size); + evbuffer_drain(inbuf, inbuf_size); return; } @@ -2179,7 +2160,7 @@ pxy_bev_readcb(struct bufferevent *bev, void *arg) // Just pass packets along goto leave; } else if (bev == ctx->src.bev) { - ctx->thr->intif_in_bytes += bytes; + ctx->thr->intif_in_bytes += inbuf_size; if (ctx->clienthello_search) { if (pxy_conn_autossl_peek_and_upgrade(ctx)) { @@ -2199,20 +2180,21 @@ pxy_bev_readcb(struct bufferevent *bev, void *arg) if (ctx->spec->http) { if (!ctx->seen_req_header) { #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: HTTP Request Header size=%lu, fd=%d\n", evbuffer_get_length(inbuf), ctx->fd); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: HTTP Request Header size=%zu, fd=%d\n", inbuf_size, ctx->fd); #endif /* DEBUG_PROXY */ - pxy_http_reqhdr_filter(inbuf, outbuf, bev, ctx); + pxy_http_reqhdr_filter(inbuf, outbuf, ctx); + // Transfered packet to outbuf and logged content, just check watermark + goto watermark; } else { #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: HTTP Request Body size=%lu, fd=%d\n", evbuffer_get_length(inbuf), ctx->fd); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: HTTP Request Body size=%zu, fd=%d\n", inbuf_size, ctx->fd); #endif /* DEBUG_PROXY */ - goto leave; } } else { size_t header_len = strlen(ctx->header_str); - size_t packet_size = evbuffer_get_length(inbuf); + size_t packet_size = inbuf_size; // +2 is for \r\n - char *packet = malloc(packet_size + header_len + 2); + unsigned char *packet = malloc(packet_size + header_len + 2); if (!packet) { // @todo Should we just set enomem? ctx->enomem = 1; @@ -2220,12 +2202,12 @@ pxy_bev_readcb(struct bufferevent *bev, void *arg) return; } - if (evbuffer_remove(inbuf, packet, packet_size) < 0) { - log_err_printf("evbuffer_remove cannot drain the buffer\n"); + if (evbuffer_remove(inbuf, packet, packet_size) == -1) { + log_err_printf("pxy_bev_readcb: src evbuffer_remove failed, fd=%d\n", ctx->fd); } #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: src ORIG packet (size=%lu), fd=%d:\n%.*s\n", + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: src ORIG packet (size=%zu), fd=%d:\n%.*s\n", packet_size, ctx->fd, (int)packet_size, packet); #endif /* DEBUG_PROXY */ @@ -2238,64 +2220,50 @@ pxy_bev_readcb(struct bufferevent *bev, void *arg) ctx->sent_header = 1; } - if (evbuffer_add(outbuf, packet, packet_size) < 0) { - log_err_printf("evbuffer_add failed\n"); + if (evbuffer_add(outbuf, packet, packet_size) == -1) { + log_err_printf("pxy_bev_readcb: src evbuffer_add failed, fd=%d\n", ctx->fd); } #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: src packet (size=%lu), fd=%d:\n%.*s\n", + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: src NEW packet (size=%zu), fd=%d:\n%.*s\n", packet_size, ctx->fd, (int)packet_size, packet); #endif /* DEBUG_PROXY */ - if (WANT_CONTENT_LOG(ctx)) { - logbuf_t *lb; - lb = logbuf_new_alloc(packet_size, NULL, NULL); - if (lb) { - memcpy(lb->buf, packet, lb->sz); - if (log_content_submit(ctx->logctx, lb, (bev == ctx->src.bev)) == -1) { - logbuf_free(lb); - log_err_level_printf(LOG_WARNING, "Content log " - "submission failed\n"); - } - } + if (pxy_log_content_buf(ctx, packet, packet_size, 1) == -1) { + ctx->enomem = 1; } free(packet); + // Transfered packet to outbuf and logged content, just check watermark + goto watermark; } - } - else if (bev == ctx->dst.bev) { - ctx->thr->intif_out_bytes += bytes; + } else if (bev == ctx->dst.bev) { + ctx->thr->intif_out_bytes += inbuf_size; if (ctx->spec->http) { if (!ctx->seen_resp_header) { #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: HTTP Response Header size=%lu, fd=%d\n", evbuffer_get_length(inbuf), ctx->fd); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: HTTP Response Header size=%zu, fd=%d\n", inbuf_size, ctx->fd); #endif /* DEBUG_PROXY */ - pxy_http_resphdr_filter(inbuf, outbuf, bev, ctx); + pxy_http_resphdr_filter(inbuf, outbuf, ctx); + // Transfered packet to outbuf and logged content, just check watermark + goto watermark; } else { #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: HTTP Response Body size=%lu, fd=%d\n", evbuffer_get_length(inbuf), ctx->fd); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: HTTP Response Body size=%zu, fd=%d\n", inbuf_size, ctx->fd); #endif /* DEBUG_PROXY */ - goto leave; } } else { - pxy_process_response(inbuf, outbuf, bev, ctx); +#ifdef DEBUG_PROXY + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb: dst packet size=%zu, fd=%d\n", inbuf_size, ctx->fd); +#endif /* DEBUG_PROXY */ } } - goto watermark; -leave: - if (WANT_CONTENT_LOG(ctx)) { - logbuf_t *lb; - lb = logbuf_new_alloc(evbuffer_get_length(inbuf), NULL, NULL); - if (lb && (evbuffer_copyout(inbuf, lb->buf, lb->sz) != -1)) { - if (log_content_submit(ctx->logctx, lb, - (bev == ctx->src.bev)) == -1) { - logbuf_free(lb); - log_err_level_printf(LOG_WARNING, "Content log " - "submission failed\n"); - } - } + if (pxy_log_content_inbuf(ctx, inbuf, (bev == ctx->src.bev)) == -1) { + ctx->enomem = 1; } + +leave: evbuffer_add_buffer(outbuf, inbuf); watermark: @@ -2316,134 +2284,115 @@ pxy_bev_readcb_child(struct bufferevent *bev, void *arg) { pxy_conn_child_ctx_t *ctx = arg; - assert(ctx->conn != NULL); - ctx->conn->atime = time(NULL); - size_t bytes = evbuffer_get_length(bufferevent_get_input(bev)); - #ifdef DEBUG_PROXY - evutil_socket_t pfd = ctx->conn->fd; char *event_name = pxy_get_event_name_child(bev, ctx); - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: ENTER %s fd=%d, pfd=%d, size=%lu\n", - event_name, ctx->fd, pfd, bytes); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: ENTER %s fd=%d, pfd=%d, size=%zu\n", + event_name, ctx->fd, ctx->conn->fd, evbuffer_get_length(bufferevent_get_input(bev))); #endif /* DEBUG_PROXY */ if (!ctx->connected) { - log_err_level_printf(LOG_CRIT, "readcb called when other end not connected - " - "aborting.\n"); + log_err_level_printf(LOG_CRIT, "pxy_bev_readcb_child: readcb called when other end not connected - aborting.\n"); log_exceptcb(); return; } - pxy_conn_desc_t *other = (bev==ctx->src.bev) ? &ctx->dst : &ctx->src; struct evbuffer *inbuf = bufferevent_get_input(bev); + pxy_conn_desc_t *other = (bev == ctx->src.bev) ? &ctx->dst : &ctx->src; struct evbuffer *outbuf = bufferevent_get_output(other->bev); + size_t inbuf_size = evbuffer_get_length(inbuf); + if (other->closed) { - log_dbg_printf("Warning: Drained %zu bytes (conn closed)\n", - evbuffer_get_length(inbuf)); - evbuffer_drain(inbuf, evbuffer_get_length(inbuf)); + log_dbg_printf("Warning: Drained %zu bytes (conn closed)\n", inbuf_size); + evbuffer_drain(inbuf, inbuf_size); return; } if (bev == ctx->src.bev) { - ctx->conn->thr->extif_out_bytes += bytes; + ctx->conn->thr->extif_out_bytes += inbuf_size; /* request header munging */ if (ctx->conn->spec->http) { if (!ctx->seen_req_header) { #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: HTTP Request Header size=%lu, fd=%d\n", evbuffer_get_length(inbuf), ctx->fd); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: HTTP Request Header size=%zu, fd=%d\n", inbuf_size, ctx->fd); #endif /* DEBUG_PROXY */ - pxy_http_reqhdr_filter(inbuf, outbuf, bev, (pxy_conn_ctx_t *)ctx); + pxy_http_reqhdr_filter(inbuf, outbuf, (pxy_conn_ctx_t *)ctx); + // Transfered packet to outbuf and logged content, just check watermark + goto watermark; } else { #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: HTTP Request Body size=%lu, fd=%d\n", evbuffer_get_length(inbuf), ctx->fd); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: HTTP Request Body size=%zu, fd=%d\n", inbuf_size, ctx->fd); #endif /* DEBUG_PROXY */ - goto leave; } } else { - size_t packet_size = evbuffer_get_length(inbuf); - char *packet = malloc(packet_size); + size_t packet_size = inbuf_size; + unsigned char *packet = malloc(packet_size); if (!packet) { ctx->enomem = 1; pxy_conn_free(ctx->conn, 1); return; } - if (evbuffer_remove(inbuf, packet, packet_size) < 0) { - log_err_printf("evbuffer_remove cannot drain the buffer\n"); + if (evbuffer_remove(inbuf, packet, packet_size) == -1) { + log_err_printf("pxy_bev_readcb_child: src evbuffer_remove failed, fd=%d\n", ctx->fd); } size_t header_len = strlen(ctx->conn->header_str); - char *pos = memmem(packet, packet_size, ctx->conn->header_str, header_len); + unsigned char *pos = memmem(packet, packet_size, ctx->conn->header_str, header_len); if (pos) { memmove(pos, pos + header_len + 2, packet_size - (pos - packet) - (header_len + 2)); packet_size-= header_len + 2; #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINER, "pxy_bev_readcb_child: REMOVED SSLproxy header\n"); + log_dbg_level_printf(LOG_DBG_MODE_FINER, "pxy_bev_readcb_child: REMOVED SSLproxy header, fd=%d\n", ctx->fd); #endif /* DEBUG_PROXY */ } - if (evbuffer_add(outbuf, packet, packet_size) < 0) { - log_err_printf("evbuffer_add failed\n"); + if (evbuffer_add(outbuf, packet, packet_size) == -1) { + log_err_printf("pxy_bev_readcb_child: src evbuffer_add failed, fd=%d\n", ctx->fd); } #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: src packet (size=%lu), fd=%d, conn fd=%d:\n%.*s\n", - packet_size, ctx->fd, pfd, (int)packet_size, packet); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: src packet (size=%zu), fd=%d, conn fd=%d:\n%.*s\n", + packet_size, ctx->fd, ctx->conn->fd, (int)packet_size, packet); #endif /* DEBUG_PROXY */ - if (WANT_CONTENT_LOG(ctx->conn)) { - logbuf_t *lb; - lb = logbuf_new_alloc(packet_size, NULL, NULL); - if (lb) { - memcpy(lb->buf, packet, lb->sz); - if (log_content_submit(ctx->conn->logctx, lb, (bev == ctx->src.bev)) == -1) { - logbuf_free(lb); - log_err_level_printf(LOG_WARNING, "Content log " - "submission failed\n"); - } - } + if (pxy_log_content_buf((pxy_conn_ctx_t *)ctx, packet, packet_size, 1) == -1) { + ctx->enomem = 1; } free(packet); + // Transfered packet to outbuf and logged content, just check watermark + goto watermark; } - } - else if (bev == ctx->dst.bev) { - ctx->conn->thr->extif_in_bytes += bytes; + } else if (bev == ctx->dst.bev) { + ctx->conn->thr->extif_in_bytes += inbuf_size; if (ctx->conn->spec->http) { if (!ctx->seen_resp_header) { #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: HTTP Response Header size=%lu, fd=%d\n", evbuffer_get_length(inbuf), ctx->fd); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: HTTP Response Header size=%zu, fd=%d\n", inbuf_size, ctx->fd); #endif /* DEBUG_PROXY */ - pxy_http_resphdr_filter(inbuf, outbuf, bev, (pxy_conn_ctx_t *)ctx); + pxy_http_resphdr_filter(inbuf, outbuf, (pxy_conn_ctx_t *)ctx); + // Transfered packet to outbuf and logged content, just check watermark + goto watermark; } else { #ifdef DEBUG_PROXY - log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: HTTP Response Body size=%lu, fd=%d\n", evbuffer_get_length(inbuf), ctx->fd); + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: HTTP Response Body size=%zu, fd=%d\n", inbuf_size, ctx->fd); #endif /* DEBUG_PROXY */ - goto leave; } } else { - pxy_process_response(inbuf, outbuf, bev, (pxy_conn_ctx_t *)ctx); +#ifdef DEBUG_PROXY + log_dbg_level_printf(LOG_DBG_MODE_FINEST, "pxy_bev_readcb_child: dst packet size=%zu, fd=%d\n", inbuf_size, ctx->fd); +#endif /* DEBUG_PROXY */ } } - goto watermark; -leave: - if (WANT_CONTENT_LOG(ctx->conn)) { - logbuf_t *lb; - lb = logbuf_new_alloc(evbuffer_get_length(inbuf), NULL, NULL); - if (lb && (evbuffer_copyout(inbuf, lb->buf, lb->sz) != -1)) { - if (log_content_submit(ctx->conn->logctx, lb, - (bev == ctx->src.bev)) == -1) { - logbuf_free(lb); - log_err_level_printf(LOG_WARNING, "Content log " - "submission failed\n"); - } - } + if (pxy_log_content_inbuf((pxy_conn_ctx_t *)ctx, inbuf, (bev == ctx->src.bev)) == -1) { + ctx->enomem = 1; } + evbuffer_add_buffer(outbuf, inbuf); watermark: