Remove all type casts from child to parent ctxs

This commit is contained in:
Soner Tari 2019-08-10 15:35:28 +03:00
parent 009fe9f6ad
commit e2a0c99768
3 changed files with 50 additions and 56 deletions

View File

@ -208,12 +208,12 @@ protohttp_ocsp_is_valid_uri(const char *uri, pxy_conn_ctx_t *ctx)
return 0;
buf_b64 = url_dec(buf_url, sz_url, &sz_b64);
if (!buf_b64) {
ctx->conn->enomem = 1;
ctx->enomem = 1;
return 0;
}
buf_asn1 = base64_dec(buf_b64, sz_b64, &sz_asn1);
if (!buf_asn1) {
ctx->conn->enomem = 1;
ctx->enomem = 1;
free(buf_b64);
return 0;
}
@ -292,8 +292,8 @@ deny:
* Returns a newly allocated string if the current line should be replaced.
* Returns 'line' if the line should be kept.
*/
static char * NONNULL(1,2,3)
protohttp_filter_request_header_line(const char *line, pxy_conn_ctx_t *ctx, protohttp_ctx_t *http_ctx)
static char * NONNULL(1,2,4)
protohttp_filter_request_header_line(const char *line, protohttp_ctx_t *http_ctx, enum conn_type type, pxy_conn_ctx_t *ctx)
{
/* parse information for connect log */
if (!http_ctx->http_method) {
@ -312,7 +312,7 @@ protohttp_filter_request_header_line(const char *line, pxy_conn_ctx_t *ctx, prot
memcpy(http_ctx->http_method, line, space1 - line);
http_ctx->http_method[space1 - line] = '\0';
} else {
ctx->conn->enomem = 1;
ctx->enomem = 1;
return NULL;
}
space1++;
@ -326,7 +326,7 @@ protohttp_filter_request_header_line(const char *line, pxy_conn_ctx_t *ctx, prot
memcpy(http_ctx->http_uri, space1, space2 - space1);
http_ctx->http_uri[space2 - space1] = '\0';
} else {
ctx->conn->enomem = 1;
ctx->enomem = 1;
return NULL;
}
}
@ -337,14 +337,14 @@ protohttp_filter_request_header_line(const char *line, pxy_conn_ctx_t *ctx, prot
if (!http_ctx->http_host && !strncasecmp(line, "Host:", 5)) {
http_ctx->http_host = strdup(util_skipws(line + 5));
if (!http_ctx->http_host) {
ctx->conn->enomem = 1;
ctx->enomem = 1;
return NULL;
}
http_ctx->seen_keyword_count++;
} else if (!strncasecmp(line, "Content-Type:", 13)) {
http_ctx->http_content_type = strdup(util_skipws(line + 13));
if (!http_ctx->http_content_type) {
ctx->conn->enomem = 1;
ctx->enomem = 1;
return NULL;
}
http_ctx->seen_keyword_count++;
@ -352,23 +352,23 @@ protohttp_filter_request_header_line(const char *line, pxy_conn_ctx_t *ctx, prot
} else if (!strncasecmp(line, "Connection:", 11)) {
http_ctx->sent_http_conn_close = 1;
if (!(newhdr = strdup("Connection: close"))) {
ctx->conn->enomem = 1;
ctx->enomem = 1;
return NULL;
}
http_ctx->seen_keyword_count++;
return newhdr;
// @attention Always use conn ctx for opts, child ctx does not have opts, see the comments in pxy_conn_child_ctx
} else if (ctx->conn->spec->opts->remove_http_accept_encoding && !strncasecmp(line, "Accept-Encoding:", 16)) {
} else if (ctx->spec->opts->remove_http_accept_encoding && !strncasecmp(line, "Accept-Encoding:", 16)) {
http_ctx->seen_keyword_count++;
return NULL;
} else if (ctx->conn->spec->opts->remove_http_referer && !strncasecmp(line, "Referer:", 8)) {
} else if (ctx->spec->opts->remove_http_referer && !strncasecmp(line, "Referer:", 8)) {
http_ctx->seen_keyword_count++;
return NULL;
/* Suppress upgrading to SSL/TLS, WebSockets or HTTP/2 and keep-alive */
} else if (!strncasecmp(line, "Upgrade:", 8) || !strncasecmp(line, "Keep-Alive:", 11)) {
http_ctx->seen_keyword_count++;
return NULL;
} else if ((ctx->type == CONN_TYPE_CHILD) && (
} else if ((type == CONN_TYPE_CHILD) && (
// @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) ||
@ -384,7 +384,7 @@ protohttp_filter_request_header_line(const char *line, pxy_conn_ctx_t *ctx, prot
if (!http_ctx->sent_http_conn_close) {
newhdr = strdup("Connection: close\r\n");
if (!newhdr) {
ctx->conn->enomem = 1;
ctx->enomem = 1;
return NULL;
}
return newhdr;
@ -395,8 +395,8 @@ protohttp_filter_request_header_line(const char *line, pxy_conn_ctx_t *ctx, prot
return (char*)line;
}
static void NONNULL(1,2,3,4)
protohttp_filter_request_header(struct evbuffer *inbuf, struct evbuffer *outbuf, pxy_conn_ctx_t *ctx, protohttp_ctx_t *http_ctx)
static void NONNULL(1,2,3,5)
protohttp_filter_request_header(struct evbuffer *inbuf, struct evbuffer *outbuf, protohttp_ctx_t *http_ctx, enum conn_type type, pxy_conn_ctx_t *ctx)
{
char *line;
@ -405,7 +405,7 @@ protohttp_filter_request_header(struct evbuffer *inbuf, struct evbuffer *outbuf,
log_dbg_level_printf(LOG_DBG_MODE_FINEST, "protohttp_filter_request_header: %s, fd=%d\n", line, ctx->fd);
#endif /* DEBUG_PROXY */
char *replace = protohttp_filter_request_header_line(line, ctx, http_ctx);
char *replace = protohttp_filter_request_header_line(line, http_ctx, type, ctx);
if (replace == line) {
evbuffer_add_printf(outbuf, "%s\r\n", line);
} else if (replace) {
@ -420,17 +420,17 @@ protohttp_filter_request_header(struct evbuffer *inbuf, struct evbuffer *outbuf,
log_dbg_level_printf(LOG_DBG_MODE_FINER, "protohttp_filter_request_header: REMOVE= %s, fd=%d\n", line, ctx->fd);
#endif /* DEBUG_PROXY */
if (ctx->conn->enomem) {
if (ctx->enomem) {
return;
}
}
free(line);
if ((ctx->type == CONN_TYPE_PARENT) && !ctx->sent_sslproxy_header) {
if ((type == CONN_TYPE_PARENT) && !ctx->sent_sslproxy_header) {
ctx->sent_sslproxy_header = 1;
#ifdef DEBUG_PROXY
log_dbg_level_printf(LOG_DBG_MODE_FINER, "protohttp_filter_request_header: INSERT= %s, fd=%d\n", ctx->conn->sslproxy_header, ctx->fd);
log_dbg_level_printf(LOG_DBG_MODE_FINER, "protohttp_filter_request_header: INSERT= %s, fd=%d\n", ctx->sslproxy_header, ctx->fd);
#endif /* DEBUG_PROXY */
evbuffer_add_printf(outbuf, "%s\r\n", ctx->sslproxy_header);
@ -439,11 +439,11 @@ protohttp_filter_request_header(struct evbuffer *inbuf, struct evbuffer *outbuf,
if (http_ctx->seen_req_header) {
/* request header complete */
if ((ctx->type == CONN_TYPE_PARENT) && ctx->conn->spec->opts->deny_ocsp) {
if ((type == CONN_TYPE_PARENT) && ctx->spec->opts->deny_ocsp) {
protohttp_ocsp_deny(ctx, http_ctx);
}
if (ctx->conn->enomem) {
if (ctx->enomem) {
return;
}
@ -647,7 +647,7 @@ protohttp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
log_dbg_level_printf(LOG_DBG_MODE_FINEST, "protohttp_bev_readcb_src: HTTP Request Header, size=%zu, fd=%d\n", evbuffer_get_length(inbuf), ctx->fd);
#endif /* DEBUG_PROXY */
protohttp_filter_request_header(inbuf, outbuf, ctx, http_ctx);
protohttp_filter_request_header(inbuf, outbuf, http_ctx, ctx->type, ctx);
if (ctx->enomem) {
return;
}
@ -680,7 +680,7 @@ protohttp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
* Returns `line' if the line should be kept.
*/
static char * NONNULL(1,2,3)
protohttp_filter_response_header_line(const char *line, pxy_conn_ctx_t *ctx, protohttp_ctx_t *http_ctx)
protohttp_filter_response_header_line(const char *line, protohttp_ctx_t *http_ctx, pxy_conn_ctx_t *ctx)
{
/* parse information for connect log */
if (!http_ctx->http_status_code) {
@ -705,7 +705,7 @@ protohttp_filter_response_header_line(const char *line, pxy_conn_ctx_t *ctx, pro
http_ctx->http_status_code = malloc(len_code + 1);
http_ctx->http_status_text = malloc(len_text + 1);
if (!http_ctx->http_status_code || !http_ctx->http_status_text) {
ctx->conn->enomem = 1;
ctx->enomem = 1;
return NULL;
}
memcpy(http_ctx->http_status_code, space1 + 1, len_code);
@ -723,7 +723,7 @@ protohttp_filter_response_header_line(const char *line, pxy_conn_ctx_t *ctx, pro
http_ctx->http_content_length =
strdup(util_skipws(line + 15));
if (!http_ctx->http_content_length) {
ctx->conn->enomem = 1;
ctx->enomem = 1;
return NULL;
}
} else if (
@ -756,7 +756,7 @@ protohttp_filter_response_header_line(const char *line, pxy_conn_ctx_t *ctx, pro
}
static void NONNULL(1,2,3,4)
protohttp_filter_response_header(struct evbuffer *inbuf, struct evbuffer *outbuf, pxy_conn_ctx_t *ctx, protohttp_ctx_t *http_ctx)
protohttp_filter_response_header(struct evbuffer *inbuf, struct evbuffer *outbuf, protohttp_ctx_t *http_ctx, pxy_conn_ctx_t *ctx)
{
char *line;
@ -765,7 +765,7 @@ protohttp_filter_response_header(struct evbuffer *inbuf, struct evbuffer *outbuf
log_dbg_level_printf(LOG_DBG_MODE_FINEST, "protohttp_filter_response_header: %s, fd=%d\n", line, ctx->fd);
#endif /* DEBUG_PROXY */
char *replace = protohttp_filter_response_header_line(line, ctx, http_ctx);
char *replace = protohttp_filter_response_header_line(line, http_ctx, ctx);
if (replace == line) {
evbuffer_add_printf(outbuf, "%s\r\n", line);
} else if (replace) {
@ -780,7 +780,7 @@ protohttp_filter_response_header(struct evbuffer *inbuf, struct evbuffer *outbuf
log_dbg_level_printf(LOG_DBG_MODE_FINER, "protohttp_filter_response_header: REMOVE= %s, fd=%d\n", line, ctx->fd);
#endif /* DEBUG_PROXY */
if (ctx->conn->enomem) {
if (ctx->enomem) {
return;
}
}
@ -818,7 +818,7 @@ protohttp_bev_readcb_dst(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
log_dbg_level_printf(LOG_DBG_MODE_FINEST, "protohttp_bev_readcb_dst: HTTP Response Header, size=%zu, fd=%d\n", evbuffer_get_length(inbuf), ctx->fd);
#endif /* DEBUG_PROXY */
protohttp_filter_response_header(inbuf, outbuf, ctx, http_ctx);
protohttp_filter_response_header(inbuf, outbuf, http_ctx, ctx);
if (ctx->enomem) {
return;
}
@ -866,7 +866,7 @@ protohttp_bev_readcb_src_child(struct bufferevent *bev, pxy_conn_child_ctx_t *ct
#endif /* DEBUG_PROXY */
// @todo Just remove SSLproxy line, do not filter request on the server side?
protohttp_filter_request_header(inbuf, outbuf, (pxy_conn_ctx_t *)ctx, http_ctx);
protohttp_filter_request_header(inbuf, outbuf, http_ctx, ctx->type, ctx->conn);
if (ctx->conn->enomem) {
return;
}
@ -905,7 +905,7 @@ protohttp_bev_readcb_dst_child(struct bufferevent *bev, pxy_conn_child_ctx_t *ct
#endif /* DEBUG_PROXY */
// @todo Do not filter response on the server side?
protohttp_filter_response_header(inbuf, outbuf, (pxy_conn_ctx_t *)ctx, http_ctx);
protohttp_filter_response_header(inbuf, outbuf, http_ctx, ctx->conn);
if (ctx->conn->enomem) {
return;
}

View File

@ -246,8 +246,7 @@ pxy_conn_ctx_new_child(evutil_socket_t fd, pxy_conn_ctx_t *conn)
ctx->fd = fd;
ctx->conn = conn;
ctx->proto = pxy_setup_proto_child(ctx);
if (ctx->proto == PROTO_ERROR) {
if (pxy_setup_proto_child(ctx) == PROTO_ERROR) {
free(ctx);
return NULL;
}
@ -624,7 +623,7 @@ pxy_log_content_inbuf(pxy_conn_ctx_t *ctx, struct evbuffer *inbuf, int req)
size_t sz = evbuffer_get_length(inbuf);
unsigned char *buf = malloc(sz);
if (!buf) {
ctx->conn->enomem = 1;
ctx->enomem = 1;
return -1;
}
if (evbuffer_copyout(inbuf, buf, sz) == -1) {
@ -634,12 +633,12 @@ pxy_log_content_inbuf(pxy_conn_ctx_t *ctx, struct evbuffer *inbuf, int req)
logbuf_t *lb = logbuf_new_alloc(sz, NULL);
if (!lb) {
free(buf);
ctx->conn->enomem = 1;
ctx->enomem = 1;
return -1;
}
memcpy(lb->buf, buf, lb->sz);
free(buf);
if (log_content_submit(&ctx->conn->logctx, lb, req) == -1) {
if (log_content_submit(&ctx->logctx, lb, req) == -1) {
logbuf_free(lb);
log_err_level_printf(LOG_WARNING, "Content log submission failed\n");
return -1;
@ -803,10 +802,10 @@ pxy_log_dbg_disconnect_child(pxy_conn_child_ctx_t *ctx)
/* we only get a single disconnect event here for both connections */
if (OPTS_DEBUG(ctx->conn->global)) {
log_dbg_printf("Child %s disconnected to [%s]:%s, child fd=%d, fd=%d\n",
protocol_names[ctx->proto],
protocol_names[ctx->conn->proto],
STRORDASH(ctx->conn->dsthost_str), STRORDASH(ctx->conn->dstport_str), ctx->fd, ctx->conn->fd);
log_dbg_printf("Child %s disconnected from [%s]:%s, child fd=%d, fd=%d\n",
protocol_names[ctx->proto],
protocol_names[ctx->conn->proto],
STRORDASH(ctx->conn->srchost_str), STRORDASH(ctx->conn->srcport_str), ctx->fd, ctx->conn->fd);
}
}
@ -1124,23 +1123,23 @@ pxy_listener_acceptcb_child(UNUSED struct evconnlistener *listener, evutil_socke
goto out;
}
// @attention fd (ctx->fd) is different from child event listener fd (ctx->conn->child_fd)
ctx->conn->thr->max_fd = MAX(ctx->conn->thr->max_fd, ctx->fd);
ctx->conn->child_src_fd = ctx->fd;
// @attention fd (ctx->fd) is different from child event listener fd (conn->child_fd)
conn->thr->max_fd = MAX(conn->thr->max_fd, ctx->fd);
conn->child_src_fd = ctx->fd;
/* create server-side socket and eventbuffer */
// Children rely on the findings of parent
ctx->protoctx->connectcb(ctx);
if (ctx->conn->term || ctx->conn->enomem) {
if (conn->term || conn->enomem) {
goto out;
}
bufferevent_enable(ctx->dst.bev, EV_READ|EV_WRITE);
if (OPTS_DEBUG(ctx->conn->global)) {
if (OPTS_DEBUG(conn->global)) {
char *host, *port;
if (sys_sockaddr_str((struct sockaddr *)&ctx->conn->dstaddr, ctx->conn->dstaddrlen, &host, &port) == 0) {
if (sys_sockaddr_str((struct sockaddr *)&conn->dstaddr, conn->dstaddrlen, &host, &port) == 0) {
log_dbg_printf("Child connecting to [%s]:%s\n", host, port);
free(host);
free(port);
@ -1150,16 +1149,16 @@ pxy_listener_acceptcb_child(UNUSED struct evconnlistener *listener, evutil_socke
}
/* initiate connection, except for the first child conn which uses the parent's srvdst as dst */
if (ctx->dst.bev != ctx->conn->srvdst.bev) {
if (bufferevent_socket_connect(ctx->dst.bev, (struct sockaddr *)&ctx->conn->dstaddr, ctx->conn->dstaddrlen) == -1) {
if (ctx->dst.bev != conn->srvdst.bev) {
if (bufferevent_socket_connect(ctx->dst.bev, (struct sockaddr *)&conn->dstaddr, conn->dstaddrlen) == -1) {
pxy_conn_term(conn, 1);
goto out;
}
}
ctx->dst_fd = bufferevent_getfd(ctx->dst.bev);
ctx->conn->child_dst_fd = ctx->dst_fd;
ctx->conn->thr->max_fd = MAX(ctx->conn->thr->max_fd, ctx->dst_fd);
conn->child_dst_fd = ctx->dst_fd;
conn->thr->max_fd = MAX(conn->thr->max_fd, ctx->dst_fd);
// Do not return here, but continue and check term/enomem flags below
out:
// @attention Do not use ctx->conn here, ctx may be uninitialized
@ -1434,7 +1433,7 @@ pxy_bev_readcb_preexec_logging_and_stats_child(struct bufferevent *bev, pxy_conn
}
if (WANT_CONTENT_LOG(ctx->conn)) {
return pxy_log_content_inbuf((pxy_conn_ctx_t *)ctx, inbuf, (bev == ctx->src.bev));
return pxy_log_content_inbuf(ctx->conn, inbuf, (bev == ctx->src.bev));
}
return 0;
}

View File

@ -192,11 +192,11 @@ typedef struct pxy_conn_lproc_desc {
/* parent connection state consisting of three connection descriptors,
* connection-wide state and the specs and options */
struct pxy_conn_ctx {
// Common properties
// @attention The order of these common vars should match with their order in children
enum conn_type type;
pxy_conn_ctx_t *conn; /* parent's conn ctx is itself */
// Parent and child are of the same proto type
protocol_t proto;
/* per-connection state */
@ -205,7 +205,6 @@ struct pxy_conn_ctx {
/* store fd and fd event while connected is 0 */
evutil_socket_t fd;
// End of common properties
// For protocol specific fields, never NULL
proto_ctx_t *protoctx;
@ -321,13 +320,10 @@ struct pxy_conn_ctx {
/* child connection state consisting of two connection descriptors,
* connection-wide state */
struct pxy_conn_child_ctx {
// Common properties
// @attention The order of these common vars should match with their order in parent
enum conn_type type;
// Parent conn
pxy_conn_ctx_t *conn;
protocol_t proto;
/* per-connection state */
struct pxy_conn_desc src;
@ -335,7 +331,6 @@ struct pxy_conn_child_ctx {
/* store fd and fd event while connected is 0 */
evutil_socket_t fd;
// End of common properties
proto_child_ctx_t *protoctx;