Browse Source

[mod_extforward] inline some more data structures

master
Glenn Strauss 6 months ago
parent
commit
2d9bf8062d
  1. 93
      src/mod_extforward.c

93
src/mod_extforward.c

@ -109,6 +109,7 @@ typedef struct {
plugin_config defaults;
plugin_config conf;
array *default_headers;
array tokens;
} plugin_data;
static plugin_data *mod_extforward_plugin_data_singleton;
@ -120,7 +121,7 @@ static int extforward_check_proxy;
typedef struct {
/* per-request state */
sock_addr saved_remote_addr;
buffer *saved_remote_addr_buf;
buffer saved_remote_addr_buf;
/* hap-PROXY protocol prior to receiving first request */
int(*saved_network_read)(connection *, chunkqueue *, off_t);
@ -140,6 +141,7 @@ static handler_ctx * handler_ctx_init(void) {
}
static void handler_ctx_free(handler_ctx *hctx) {
free(hctx->saved_remote_addr_buf.ptr);
free(hctx);
}
@ -150,6 +152,7 @@ INIT_FUNC(mod_extforward_init) {
FREE_FUNC(mod_extforward_free) {
plugin_data * const p = p_d;
array_free(p->default_headers);
array_free_data(&p->tokens);
if (NULL == p->cvlist) return;
/* (init i to 0 if global context; to 1 to skip empty global context) */
for (int i = !p->cvlist[0].v.u2[1], used = p->nconfig; i < used; ++i) {
@ -456,10 +459,9 @@ SETDEFAULTS_FUNC(mod_extforward_set_defaults) {
/*
extract a forward array from the environment
*/
static array *extract_forward_array(const buffer *pbuffer)
static void extract_forward_array(array * const result, const buffer *pbuffer)
{
array *result = array_init(8);
if (!buffer_is_blank(pbuffer)) {
/*force_assert(!buffer_is_blank(pbuffer));*/
const char *base, *curr;
/* state variable, 0 means not in string, 1 means in string */
int in_str = 0;
@ -484,8 +486,6 @@ static array *extract_forward_array(const buffer *pbuffer)
if (in_str) {
array_insert_value(result, base, curr - base);
}
}
return result;
}
/*
@ -529,31 +529,31 @@ static int is_connection_trusted(connection * const con, plugin_data *p)
* Return last address of proxy that is not trusted.
* Do not accept "all" keyword here.
*/
static const char *last_not_in_array(array *a, plugin_data *p)
static const buffer *last_not_in_array(array *a, plugin_data *p)
{
int i;
for (i = a->used - 1; i >= 0; i--) {
data_string *ds = (data_string *)a->data[i];
if (!is_proxy_trusted(p, BUF_PTR_LEN(&ds->value))) {
return ds->value.ptr;
return &ds->value;
}
}
return NULL;
}
static int mod_extforward_set_addr(request_st * const r, plugin_data *p, const char *addr) {
static int mod_extforward_set_addr(request_st * const r, plugin_data *p, const char *addr, size_t addrlen) {
connection * const con = r->con;
sock_addr sock;
handler_ctx *hctx = con->plugin_ctx[p->id];
/* Preserve changed addr for lifetime of h2 connection; upstream proxy
* should not reuse same h2 connection for requests from different clients*/
if (hctx && NULL != hctx->saved_remote_addr_buf
if (hctx && !buffer_is_unset(&hctx->saved_remote_addr_buf)
&& r->http_version > HTTP_VERSION_1_1) { /*(e.g. HTTP_VERSION_2)*/
if (extforward_check_proxy) /* save old address */
http_header_env_set(r, CONST_STR_LEN("_L_EXTFORWARD_ACTUAL_FOR"),
BUF_PTR_LEN(hctx->saved_remote_addr_buf));
BUF_PTR_LEN(&hctx->saved_remote_addr_buf));
return 1;
}
@ -567,15 +567,13 @@ static int mod_extforward_set_addr(request_st * const r, plugin_data *p, const c
/* we found the remote address, modify current connection and save the old address */
if (hctx) {
if (hctx->saved_remote_addr_buf) {
if (!buffer_is_unset(&hctx->saved_remote_addr_buf)) {
if (r->conf.log_request_handling) {
log_error(r->conf.errh, __FILE__, __LINE__,
"-- mod_extforward_uri_handler already patched this connection, resetting state");
}
con->dst_addr = hctx->saved_remote_addr;
buffer_free(con->dst_addr_buf);
con->dst_addr_buf = hctx->saved_remote_addr_buf;
hctx->saved_remote_addr_buf = NULL;
buffer_move(con->dst_addr_buf, &hctx->saved_remote_addr_buf);
}
} else {
con->plugin_ctx[p->id] = hctx = handler_ctx_init();
@ -586,15 +584,10 @@ static int mod_extforward_set_addr(request_st * const r, plugin_data *p, const c
}
hctx->request_count = con->request_count;
hctx->saved_remote_addr = con->dst_addr;
hctx->saved_remote_addr_buf = con->dst_addr_buf;
buffer_move(&hctx->saved_remote_addr_buf, con->dst_addr_buf);
/* patch connection address */
con->dst_addr = sock;
con->dst_addr_buf = buffer_init_string(addr);
if (r->conf.log_request_handling) {
log_error(r->conf.errh, __FILE__, __LINE__,
"patching con->dst_addr_buf for the accesslog: %s", addr);
}
buffer_copy_string_len(con->dst_addr_buf, addr, addrlen);
/* Now, clean the conf_cond cache, because we may have changed the results of tests */
config_cond_cache_reset_item(r, COMP_HTTP_REMOTE_IP);
@ -632,8 +625,9 @@ static void mod_extforward_set_proto(request_st * const r, const char * const pr
static handler_t mod_extforward_X_Forwarded_For(request_st * const r, plugin_data * const p, const buffer * const x_forwarded_for) {
/* build forward_array from forwarded data_string */
array *forward_array = extract_forward_array(x_forwarded_for);
const char *real_remote_addr = last_not_in_array(forward_array, p);
array * const forward_array = &p->tokens;
extract_forward_array(forward_array, x_forwarded_for);
const buffer *real_remote_addr = last_not_in_array(forward_array, p);
if (real_remote_addr != NULL) { /* parsed */
/* get scheme if X-Forwarded-Proto is set
* Limitations:
@ -644,11 +638,11 @@ static handler_t mod_extforward_X_Forwarded_For(request_st * const r, plugin_dat
* as in X-Forwarded-For to find proto set by last trusted proxy)
*/
const buffer *x_forwarded_proto = http_header_request_get(r, HTTP_HEADER_X_FORWARDED_PROTO, CONST_STR_LEN("X-Forwarded-Proto"));
if (mod_extforward_set_addr(r, p, real_remote_addr) && NULL != x_forwarded_proto) {
if (mod_extforward_set_addr(r, p, BUF_PTR_LEN(real_remote_addr)) && NULL != x_forwarded_proto) {
mod_extforward_set_proto(r, BUF_PTR_LEN(x_forwarded_proto));
}
}
array_free(forward_array);
array_reset_data_strings(forward_array);
return HANDLER_GO_ON;
}
@ -848,7 +842,7 @@ static handler_t mod_extforward_Forwarded (request_st * const r, plugin_data * c
char c = *ipend;
int rc;
*ipend = '\0';
rc = mod_extforward_set_addr(r, p, s+offsets[ofor+2]);
rc = mod_extforward_set_addr(r, p, s+offsets[ofor+2], offsets[ofor+3]);
*ipend = c;
if (!rc) return HANDLER_GO_ON; /* invalid addr; make no changes */
}
@ -1052,17 +1046,9 @@ static handler_t mod_extforward_Forwarded (request_st * const r, plugin_data * c
URIHANDLER_FUNC(mod_extforward_uri_handler) {
plugin_data *p = p_d;
const buffer *forwarded = NULL;
int is_forwarded_header = 0;
mod_extforward_patch_config(r, p);
if (NULL == p->conf.forwarder) return HANDLER_GO_ON;
if (r->conf.log_request_handling) {
log_error(r->conf.errh, __FILE__, __LINE__,
"-- mod_extforward_uri_handler called");
}
if (p->conf.hap_PROXY_ssl_client_verify) {
const data_string *ds;
handler_ctx *hctx = r->con->plugin_ctx[p->id];
@ -1097,10 +1083,12 @@ URIHANDLER_FUNC(mod_extforward_uri_handler) {
* that mod_magnet and mod_cgi with local-redir should not modify
* Forwarded or related headers and expect effects here. */
handler_ctx *hctx = r->con->plugin_ctx[p->id];
if (NULL != hctx && NULL != hctx->saved_remote_addr_buf
if (NULL != hctx && !buffer_is_unset(&hctx->saved_remote_addr_buf)
&& hctx->request_count == r->con->request_count)
return HANDLER_GO_ON;
const buffer *forwarded = NULL;
int is_forwarded_header = 0;
for (uint32_t k = 0; k < p->conf.headers->used; ++k) {
const data_string * const ds = (data_string *)p->conf.headers->data[k];
const buffer * const hdr = &ds->value;
@ -1110,31 +1098,21 @@ URIHANDLER_FUNC(mod_extforward_uri_handler) {
break;
}
}
if (NULL == forwarded) {
if (r->conf.log_request_handling) {
log_error(r->conf.errh, __FILE__, __LINE__,
"no forward header found, skipping");
}
return HANDLER_GO_ON;
if (forwarded && is_connection_trusted(r->con, p)) {
return (is_forwarded_header)
? mod_extforward_Forwarded(r, p, forwarded)
: mod_extforward_X_Forwarded_For(r, p, forwarded);
}
/* if the remote ip itself is not trusted, then do nothing */
if (!is_connection_trusted(r->con, p)) {
else {
if (r->conf.log_request_handling) {
log_error(r->conf.errh, __FILE__, __LINE__,
"no forward header found or "
"remote address %s is NOT a trusted proxy, skipping",
r->con->dst_addr_buf->ptr);
}
return HANDLER_GO_ON;
}
if (is_forwarded_header) {
return mod_extforward_Forwarded(r, p, forwarded);
}
return mod_extforward_X_Forwarded_For(r, p, forwarded);
}
@ -1165,11 +1143,9 @@ REQUEST_FUNC(mod_extforward_restore) {
if (!hctx) return HANDLER_GO_ON;
if (NULL != hctx->saved_remote_addr_buf) {
if (!buffer_is_unset(&hctx->saved_remote_addr_buf)) {
con->dst_addr = hctx->saved_remote_addr;
buffer_free(con->dst_addr_buf);
con->dst_addr_buf = hctx->saved_remote_addr_buf;
hctx->saved_remote_addr_buf = NULL;
buffer_move(con->dst_addr_buf, &hctx->saved_remote_addr_buf);
/* Now, clean the conf_cond cache, because we may have changed the results of tests */
config_cond_cache_reset_item(r, COMP_HTTP_REMOTE_IP);
}
@ -1191,10 +1167,9 @@ CONNECTION_FUNC(mod_extforward_handle_con_close)
if (NULL != hctx->saved_network_read) {
con->network_read = hctx->saved_network_read;
}
if (NULL != hctx->saved_remote_addr_buf) {
if (!buffer_is_unset(&hctx->saved_remote_addr_buf)) {
con->dst_addr = hctx->saved_remote_addr;
buffer_free(con->dst_addr_buf);
con->dst_addr_buf = hctx->saved_remote_addr_buf;
buffer_move(con->dst_addr_buf, &hctx->saved_remote_addr_buf);
}
if (NULL != hctx->env) {
array_free(hctx->env);

Loading…
Cancel
Save