mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
MINOR: proxy: move 'forwardfor' option to http_ext
Just like forwarded (7239) header, move parsing, logic and management of 'forwardfor' option into http_ext dedicated class. We're only doing this to standardize proxy http options management. Existing behavior remains untouched.
This commit is contained in:
parent
424981cdef
commit
730b9836a6
@ -110,4 +110,14 @@ enum forwarded_header_field {
|
|||||||
FORWARDED_HEADER_ALL = FORWARDED_HEADER_FOR|FORWARDED_HEADER_BY|FORWARDED_HEADER_HOST|FORWARDED_HEADER_PROTO
|
FORWARDED_HEADER_ALL = FORWARDED_HEADER_FOR|FORWARDED_HEADER_BY|FORWARDED_HEADER_HOST|FORWARDED_HEADER_PROTO
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum http_ext_xff_mode {
|
||||||
|
HTTP_XFF_IFNONE = 0, /* set if not already set */
|
||||||
|
HTTP_XFF_ALWAYS = 1 /* always set x-forwarded-for */
|
||||||
|
};
|
||||||
|
struct http_ext_xff {
|
||||||
|
struct ist hdr_name; /* header to use - default: "x-forwarded-for" */
|
||||||
|
struct net_addr except_net; /* don't forward x-forward-for for this address. */
|
||||||
|
uint8_t mode;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* !_HAPROXY_HTTPEXT_T_H */
|
#endif /* !_HAPROXY_HTTPEXT_T_H */
|
||||||
|
@ -30,12 +30,16 @@
|
|||||||
int http_validate_7239_header(struct ist hdr, int required_steps, struct forwarded_header_ctx *ctx);
|
int http_validate_7239_header(struct ist hdr, int required_steps, struct forwarded_header_ctx *ctx);
|
||||||
|
|
||||||
int http_handle_7239_header(struct stream *s, struct channel *req);
|
int http_handle_7239_header(struct stream *s, struct channel *req);
|
||||||
|
int http_handle_xff_header(struct stream *s, struct channel *req);
|
||||||
|
|
||||||
void http_ext_7239_clean(struct http_ext_7239 *);
|
void http_ext_7239_clean(struct http_ext_7239 *);
|
||||||
|
void http_ext_xff_clean(struct http_ext_xff *);
|
||||||
|
|
||||||
void http_ext_7239_copy(struct http_ext_7239 *dest, const struct http_ext_7239 *orig);
|
void http_ext_7239_copy(struct http_ext_7239 *dest, const struct http_ext_7239 *orig);
|
||||||
|
void http_ext_xff_copy(struct http_ext_xff *dest, const struct http_ext_xff *orig);
|
||||||
|
|
||||||
int proxy_http_parse_7239(char **args, int cur_arg, struct proxy *curproxy, const struct proxy *defpx, const char *file, int linenum);
|
int proxy_http_parse_7239(char **args, int cur_arg, struct proxy *curproxy, const struct proxy *defpx, const char *file, int linenum);
|
||||||
int proxy_http_compile_7239(struct proxy *curproxy);
|
int proxy_http_compile_7239(struct proxy *curproxy);
|
||||||
|
int proxy_http_parse_xff(char **args, int cur_arg, struct proxy *curproxy, const struct proxy *defpx, const char *file, int linenum);
|
||||||
|
|
||||||
#endif /* !_HAPROXY_HTTPEXT_H */
|
#endif /* !_HAPROXY_HTTPEXT_H */
|
||||||
|
@ -88,12 +88,12 @@ enum PR_SRV_STATE_FILE {
|
|||||||
#define PR_O_PREF_LAST 0x00000020 /* prefer last server */
|
#define PR_O_PREF_LAST 0x00000020 /* prefer last server */
|
||||||
#define PR_O_DISPATCH 0x00000040 /* use dispatch mode */
|
#define PR_O_DISPATCH 0x00000040 /* use dispatch mode */
|
||||||
#define PR_O_FORCED_ID 0x00000080 /* proxy's ID was forced in the configuration */
|
#define PR_O_FORCED_ID 0x00000080 /* proxy's ID was forced in the configuration */
|
||||||
#define PR_O_FWDFOR 0x00000100 /* conditionally insert x-forwarded-for with client address */
|
#define PR_O_HTTP_XFF 0x00000100 /* conditionally insert x-forwarded-for with client address */
|
||||||
#define PR_O_IGNORE_PRB 0x00000200 /* ignore empty requests (aborts and timeouts) */
|
#define PR_O_IGNORE_PRB 0x00000200 /* ignore empty requests (aborts and timeouts) */
|
||||||
#define PR_O_NULLNOLOG 0x00000400 /* a connect without request will not be logged */
|
#define PR_O_NULLNOLOG 0x00000400 /* a connect without request will not be logged */
|
||||||
#define PR_O_WREQ_BODY 0x00000800 /* always wait for the HTTP request body */
|
#define PR_O_WREQ_BODY 0x00000800 /* always wait for the HTTP request body */
|
||||||
#define PR_O_HTTP_UPG 0x00001000 /* Contain a "switch-mode http" tcp-request rule */
|
#define PR_O_HTTP_UPG 0x00001000 /* Contain a "switch-mode http" tcp-request rule */
|
||||||
#define PR_O_FF_ALWAYS 0x00002000 /* always set x-forwarded-for */
|
/* unused: 0x00002000 */
|
||||||
#define PR_O_PERSIST 0x00004000 /* server persistence stays effective even when server is down */
|
#define PR_O_PERSIST 0x00004000 /* server persistence stays effective even when server is down */
|
||||||
#define PR_O_LOGASAP 0x00008000 /* log as soon as possible, without waiting for the stream to complete */
|
#define PR_O_LOGASAP 0x00008000 /* log as soon as possible, without waiting for the stream to complete */
|
||||||
#define PR_O_ERR_LOGFMT 0x00010000 /* use log-format for connection error message */
|
#define PR_O_ERR_LOGFMT 0x00010000 /* use log-format for connection error message */
|
||||||
@ -271,6 +271,8 @@ struct error_snapshot {
|
|||||||
struct proxy_http {
|
struct proxy_http {
|
||||||
/* forwarded header (RFC 7239) */
|
/* forwarded header (RFC 7239) */
|
||||||
struct http_ext_7239 fwd;
|
struct http_ext_7239 fwd;
|
||||||
|
/* x-forward-for */
|
||||||
|
struct http_ext_xff xff;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct proxy {
|
struct proxy {
|
||||||
@ -364,9 +366,7 @@ struct proxy {
|
|||||||
unsigned int fe_sps_lim; /* limit on new sessions per second on the frontend */
|
unsigned int fe_sps_lim; /* limit on new sessions per second on the frontend */
|
||||||
unsigned int fullconn; /* #conns on backend above which servers are used at full load */
|
unsigned int fullconn; /* #conns on backend above which servers are used at full load */
|
||||||
unsigned int tot_fe_maxconn; /* #maxconn of frontends linked to that backend, it is used to compute fullconn */
|
unsigned int tot_fe_maxconn; /* #maxconn of frontends linked to that backend, it is used to compute fullconn */
|
||||||
struct net_addr except_xff_net; /* don't x-forward-for for this address. */
|
|
||||||
struct net_addr except_xot_net; /* don't x-original-to for this address. */
|
struct net_addr except_xot_net; /* don't x-original-to for this address. */
|
||||||
struct ist fwdfor_hdr_name; /* header to use - default: "x-forwarded-for" */
|
|
||||||
struct ist orgto_hdr_name; /* header to use - default: "x-original-to" */
|
struct ist orgto_hdr_name; /* header to use - default: "x-original-to" */
|
||||||
struct ist server_id_hdr_name; /* the header to use to send the server id (name) */
|
struct ist server_id_hdr_name; /* the header to use to send the server id (name) */
|
||||||
int conn_retries; /* maximum number of connect retries */
|
int conn_retries; /* maximum number of connect retries */
|
||||||
|
@ -2273,72 +2273,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
else if (strcmp(args[1], "forwardfor") == 0) {
|
else if (strcmp(args[1], "forwardfor") == 0) {
|
||||||
int cur_arg;
|
err_code |= proxy_http_parse_xff(args, 0, curproxy, curr_defproxy, file, linenum);
|
||||||
|
if (err_code & ERR_FATAL)
|
||||||
/* insert x-forwarded-for field, but not for the IP address listed as an except.
|
goto out;
|
||||||
* set default options (ie: bitfield, header name, etc)
|
|
||||||
*/
|
|
||||||
|
|
||||||
curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
|
|
||||||
|
|
||||||
istfree(&curproxy->fwdfor_hdr_name);
|
|
||||||
curproxy->fwdfor_hdr_name = istdup(ist(DEF_XFORWARDFOR_HDR));
|
|
||||||
if (!isttest(curproxy->fwdfor_hdr_name))
|
|
||||||
goto alloc_error;
|
|
||||||
curproxy->except_xff_net.family = AF_UNSPEC;
|
|
||||||
|
|
||||||
/* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
|
|
||||||
cur_arg = 2;
|
|
||||||
while (*(args[cur_arg])) {
|
|
||||||
if (strcmp(args[cur_arg], "except") == 0) {
|
|
||||||
unsigned char mask;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* suboption except - needs additional argument for it */
|
|
||||||
if (*(args[cur_arg+1]) &&
|
|
||||||
str2net(args[cur_arg+1], 1, &curproxy->except_xff_net.addr.v4.ip, &curproxy->except_xff_net.addr.v4.mask)) {
|
|
||||||
curproxy->except_xff_net.family = AF_INET;
|
|
||||||
curproxy->except_xff_net.addr.v4.ip.s_addr &= curproxy->except_xff_net.addr.v4.mask.s_addr;
|
|
||||||
}
|
|
||||||
else if (*(args[cur_arg+1]) &&
|
|
||||||
str62net(args[cur_arg+1], &curproxy->except_xff_net.addr.v6.ip, &mask)) {
|
|
||||||
curproxy->except_xff_net.family = AF_INET6;
|
|
||||||
len2mask6(mask, &curproxy->except_xff_net.addr.v6.mask);
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
curproxy->except_xff_net.addr.v6.ip.s6_addr[i] &= curproxy->except_xff_net.addr.v6.mask.s6_addr[i];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
|
|
||||||
file, linenum, args[0], args[1], args[cur_arg]);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* flush useless bits */
|
|
||||||
cur_arg += 2;
|
|
||||||
} else if (strcmp(args[cur_arg], "header") == 0) {
|
|
||||||
/* suboption header - needs additional argument for it */
|
|
||||||
if (*(args[cur_arg+1]) == 0) {
|
|
||||||
ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
|
|
||||||
file, linenum, args[0], args[1], args[cur_arg]);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
istfree(&curproxy->fwdfor_hdr_name);
|
|
||||||
curproxy->fwdfor_hdr_name = istdup(ist(args[cur_arg+1]));
|
|
||||||
if (!isttest(curproxy->fwdfor_hdr_name))
|
|
||||||
goto alloc_error;
|
|
||||||
cur_arg += 2;
|
|
||||||
} else if (strcmp(args[cur_arg], "if-none") == 0) {
|
|
||||||
curproxy->options &= ~PR_O_FF_ALWAYS;
|
|
||||||
cur_arg += 1;
|
|
||||||
} else {
|
|
||||||
/* unknown suboption - catchall */
|
|
||||||
ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
|
|
||||||
file, linenum, args[0], args[1]);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
} /* end while loop */
|
|
||||||
}
|
}
|
||||||
else if (strcmp(args[1], "originalto") == 0) {
|
else if (strcmp(args[1], "originalto") == 0) {
|
||||||
int cur_arg;
|
int cur_arg;
|
||||||
|
@ -3975,11 +3975,11 @@ int check_config_validity()
|
|||||||
curproxy->options &= ~PR_O_HTTP_7239;
|
curproxy->options &= ~PR_O_HTTP_7239;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
|
if (curproxy->options & PR_O_HTTP_XFF) {
|
||||||
ha_warning("'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
|
ha_warning("'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
|
||||||
"forwardfor", proxy_type_str(curproxy), curproxy->id);
|
"forwardfor", proxy_type_str(curproxy), curproxy->id);
|
||||||
err_code |= ERR_WARN;
|
err_code |= ERR_WARN;
|
||||||
curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
|
curproxy->options &= ~PR_O_HTTP_XFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curproxy->options & PR_O_ORGTO) {
|
if (curproxy->options & PR_O_ORGTO) {
|
||||||
|
@ -669,60 +669,12 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 9: add X-Forwarded-For if either the frontend or the backend
|
* add X-Forwarded-For if either the frontend or the backend
|
||||||
* asks for it.
|
* asks for it.
|
||||||
*/
|
*/
|
||||||
if ((sess->fe->options | s->be->options) & PR_O_FWDFOR) {
|
if ((sess->fe->options | s->be->options) & PR_O_HTTP_XFF) {
|
||||||
const struct sockaddr_storage *src = sc_src(s->scf);
|
if (unlikely(!http_handle_xff_header(s, req)))
|
||||||
struct http_hdr_ctx ctx = { .blk = NULL };
|
goto return_fail_rewrite;
|
||||||
struct ist hdr = isttest(s->be->fwdfor_hdr_name) ? s->be->fwdfor_hdr_name : sess->fe->fwdfor_hdr_name;
|
|
||||||
|
|
||||||
if (!((sess->fe->options | s->be->options) & PR_O_FF_ALWAYS) &&
|
|
||||||
http_find_header(htx, hdr, &ctx, 0)) {
|
|
||||||
/* The header is set to be added only if none is present
|
|
||||||
* and we found it, so don't do anything.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
else if (src && src->ss_family == AF_INET) {
|
|
||||||
/* Add an X-Forwarded-For header unless the source IP is
|
|
||||||
* in the 'except' network range.
|
|
||||||
*/
|
|
||||||
if (ipcmp2net(src, &sess->fe->except_xff_net) &&
|
|
||||||
ipcmp2net(src, &s->be->except_xff_net)) {
|
|
||||||
unsigned char *pn = (unsigned char *)&((struct sockaddr_in *)src)->sin_addr;
|
|
||||||
|
|
||||||
/* Note: we rely on the backend to get the header name to be used for
|
|
||||||
* x-forwarded-for, because the header is really meant for the backends.
|
|
||||||
* However, if the backend did not specify any option, we have to rely
|
|
||||||
* on the frontend's header name.
|
|
||||||
*/
|
|
||||||
chunk_printf(&trash, "%d.%d.%d.%d", pn[0], pn[1], pn[2], pn[3]);
|
|
||||||
if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data))))
|
|
||||||
goto return_fail_rewrite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (src && src->ss_family == AF_INET6) {
|
|
||||||
/* Add an X-Forwarded-For header unless the source IP is
|
|
||||||
* in the 'except' network range.
|
|
||||||
*/
|
|
||||||
if (ipcmp2net(src, &sess->fe->except_xff_net) &&
|
|
||||||
ipcmp2net(src, &s->be->except_xff_net)) {
|
|
||||||
char pn[INET6_ADDRSTRLEN];
|
|
||||||
|
|
||||||
inet_ntop(AF_INET6,
|
|
||||||
(const void *)&((struct sockaddr_in6 *)(src))->sin6_addr,
|
|
||||||
pn, sizeof(pn));
|
|
||||||
|
|
||||||
/* Note: we rely on the backend to get the header name to be used for
|
|
||||||
* x-forwarded-for, because the header is really meant for the backends.
|
|
||||||
* However, if the backend did not specify any option, we have to rely
|
|
||||||
* on the frontend's header name.
|
|
||||||
*/
|
|
||||||
chunk_printf(&trash, "%s", pn);
|
|
||||||
if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data))))
|
|
||||||
goto return_fail_rewrite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
160
src/http_ext.c
160
src/http_ext.c
@ -758,6 +758,76 @@ int http_handle_7239_header(struct stream *s, struct channel *req)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function will try to inject x-forwarded-for header if
|
||||||
|
* configured on the frontend or the backend (or both)
|
||||||
|
* Returns 1 for success and 0 for failure
|
||||||
|
*/
|
||||||
|
int http_handle_xff_header(struct stream *s, struct channel *req)
|
||||||
|
{
|
||||||
|
struct session *sess = s->sess;
|
||||||
|
struct htx *htx = htxbuf(&req->buf);
|
||||||
|
const struct sockaddr_storage *src = sc_src(s->scf);
|
||||||
|
struct http_hdr_ctx ctx = { .blk = NULL };
|
||||||
|
struct http_ext_xff *f_xff = ((sess->fe->options & PR_O_HTTP_XFF) ? &sess->fe->http.xff : NULL);
|
||||||
|
struct http_ext_xff *b_xff = ((s->be->options & PR_O_HTTP_XFF) ? &s->be->http.xff : NULL);
|
||||||
|
struct ist hdr;
|
||||||
|
|
||||||
|
/* xff is expected to be enabled on be, or fe, or both */
|
||||||
|
BUG_ON(!f_xff && !b_xff);
|
||||||
|
|
||||||
|
hdr = ((b_xff) ? b_xff->hdr_name : f_xff->hdr_name);
|
||||||
|
|
||||||
|
if (f_xff && f_xff->mode == HTTP_XFF_IFNONE &&
|
||||||
|
b_xff && b_xff->mode == HTTP_XFF_IFNONE &&
|
||||||
|
http_find_header(htx, hdr, &ctx, 0)) {
|
||||||
|
/* The header is set to be added only if none is present
|
||||||
|
* and we found it, so don't do anything.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else if (src && src->ss_family == AF_INET) {
|
||||||
|
/* Add an X-Forwarded-For header unless the source IP is
|
||||||
|
* in the 'except' network range.
|
||||||
|
*/
|
||||||
|
if ((!f_xff || ipcmp2net(src, &f_xff->except_net)) &&
|
||||||
|
(!b_xff || ipcmp2net(src, &b_xff->except_net))) {
|
||||||
|
unsigned char *pn = (unsigned char *)&((struct sockaddr_in *)src)->sin_addr;
|
||||||
|
|
||||||
|
/* Note: we rely on the backend to get the header name to be used for
|
||||||
|
* x-forwarded-for, because the header is really meant for the backends.
|
||||||
|
* However, if the backend did not specify any option, we have to rely
|
||||||
|
* on the frontend's header name.
|
||||||
|
*/
|
||||||
|
chunk_printf(&trash, "%d.%d.%d.%d", pn[0], pn[1], pn[2], pn[3]);
|
||||||
|
if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data))))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (src && src->ss_family == AF_INET6) {
|
||||||
|
/* Add an X-Forwarded-For header unless the source IP is
|
||||||
|
* in the 'except' network range.
|
||||||
|
*/
|
||||||
|
if ((!f_xff || ipcmp2net(src, &f_xff->except_net)) &&
|
||||||
|
(!b_xff || ipcmp2net(src, &b_xff->except_net))) {
|
||||||
|
char pn[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
|
inet_ntop(AF_INET6,
|
||||||
|
(const void *)&((struct sockaddr_in6 *)(src))->sin6_addr,
|
||||||
|
pn, sizeof(pn));
|
||||||
|
|
||||||
|
/* Note: we rely on the backend to get the header name to be used for
|
||||||
|
* x-forwarded-for, because the header is really meant for the backends.
|
||||||
|
* However, if the backend did not specify any option, we have to rely
|
||||||
|
* on the frontend's header name.
|
||||||
|
*/
|
||||||
|
chunk_printf(&trash, "%s", pn);
|
||||||
|
if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data))))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =========== CONFIG ===========
|
* =========== CONFIG ===========
|
||||||
* below are helpers to parse http ext options from the config
|
* below are helpers to parse http ext options from the config
|
||||||
@ -1003,6 +1073,83 @@ int proxy_http_compile_7239(struct proxy *curproxy)
|
|||||||
return cfgerr;
|
return cfgerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* x-forwarded-for */
|
||||||
|
int proxy_http_parse_xff(char **args, int cur_arg,
|
||||||
|
struct proxy *curproxy, const struct proxy *defpx,
|
||||||
|
const char *file, int linenum)
|
||||||
|
{
|
||||||
|
int err_code = 0;
|
||||||
|
|
||||||
|
/* insert x-forwarded-for field, but not for the IP address listed as an except.
|
||||||
|
* set default options (ie: bitfield, header name, etc)
|
||||||
|
*/
|
||||||
|
|
||||||
|
curproxy->options |= PR_O_HTTP_XFF;
|
||||||
|
|
||||||
|
curproxy->http.xff.mode = HTTP_XFF_ALWAYS;
|
||||||
|
|
||||||
|
istfree(&curproxy->http.xff.hdr_name);
|
||||||
|
curproxy->http.xff.hdr_name = istdup(ist(DEF_XFORWARDFOR_HDR));
|
||||||
|
if (!isttest(curproxy->http.xff.hdr_name))
|
||||||
|
return proxy_http_parse_oom(file, linenum);
|
||||||
|
curproxy->http.xff.except_net.family = AF_UNSPEC;
|
||||||
|
|
||||||
|
/* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
|
||||||
|
cur_arg = 2;
|
||||||
|
while (*(args[cur_arg])) {
|
||||||
|
if (strcmp(args[cur_arg], "except") == 0) {
|
||||||
|
unsigned char mask;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* suboption except - needs additional argument for it */
|
||||||
|
if (*(args[cur_arg+1]) &&
|
||||||
|
str2net(args[cur_arg+1], 1, &curproxy->http.xff.except_net.addr.v4.ip, &curproxy->http.xff.except_net.addr.v4.mask)) {
|
||||||
|
curproxy->http.xff.except_net.family = AF_INET;
|
||||||
|
curproxy->http.xff.except_net.addr.v4.ip.s_addr &= curproxy->http.xff.except_net.addr.v4.mask.s_addr;
|
||||||
|
}
|
||||||
|
else if (*(args[cur_arg+1]) &&
|
||||||
|
str62net(args[cur_arg+1], &curproxy->http.xff.except_net.addr.v6.ip, &mask)) {
|
||||||
|
curproxy->http.xff.except_net.family = AF_INET6;
|
||||||
|
len2mask6(mask, &curproxy->http.xff.except_net.addr.v6.mask);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
curproxy->http.xff.except_net.addr.v6.ip.s6_addr[i] &= curproxy->http.xff.except_net.addr.v6.mask.s6_addr[i];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
|
||||||
|
file, linenum, args[0], args[1], args[cur_arg]);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* flush useless bits */
|
||||||
|
cur_arg += 2;
|
||||||
|
} else if (strcmp(args[cur_arg], "header") == 0) {
|
||||||
|
/* suboption header - needs additional argument for it */
|
||||||
|
if (*(args[cur_arg+1]) == 0) {
|
||||||
|
ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
|
||||||
|
file, linenum, args[0], args[1], args[cur_arg]);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
istfree(&curproxy->http.xff.hdr_name);
|
||||||
|
curproxy->http.xff.hdr_name = istdup(ist(args[cur_arg+1]));
|
||||||
|
if (!isttest(curproxy->http.xff.hdr_name))
|
||||||
|
return proxy_http_parse_oom(file, linenum);
|
||||||
|
cur_arg += 2;
|
||||||
|
} else if (strcmp(args[cur_arg], "if-none") == 0) {
|
||||||
|
curproxy->http.xff.mode = HTTP_XFF_IFNONE;
|
||||||
|
cur_arg += 1;
|
||||||
|
} else {
|
||||||
|
/* unknown suboption - catchall */
|
||||||
|
ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
|
||||||
|
file, linenum, args[0], args[1]);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} /* end while loop */
|
||||||
|
out:
|
||||||
|
return err_code;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =========== MGMT ===========
|
* =========== MGMT ===========
|
||||||
* below are helpers to manage http ext options
|
* below are helpers to manage http ext options
|
||||||
@ -1029,6 +1176,11 @@ void http_ext_7239_clean(struct http_ext_7239 *clean)
|
|||||||
clean->p_for.np_expr = NULL;
|
clean->p_for.np_expr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void http_ext_xff_clean(struct http_ext_xff *clean)
|
||||||
|
{
|
||||||
|
istfree(&clean->hdr_name);
|
||||||
|
}
|
||||||
|
|
||||||
void http_ext_7239_copy(struct http_ext_7239 *dest, const struct http_ext_7239 *orig)
|
void http_ext_7239_copy(struct http_ext_7239 *dest, const struct http_ext_7239 *orig)
|
||||||
{
|
{
|
||||||
if (orig->c_file)
|
if (orig->c_file)
|
||||||
@ -1057,3 +1209,11 @@ void http_ext_7239_copy(struct http_ext_7239 *dest, const struct http_ext_7239 *
|
|||||||
if (orig->p_for.np_expr_s)
|
if (orig->p_for.np_expr_s)
|
||||||
dest->p_for.np_expr_s = strdup(orig->p_for.np_expr_s);
|
dest->p_for.np_expr_s = strdup(orig->p_for.np_expr_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void http_ext_xff_copy(struct http_ext_xff *dest, const struct http_ext_xff *orig)
|
||||||
|
{
|
||||||
|
if (isttest(orig->hdr_name))
|
||||||
|
dest->hdr_name = istdup(orig->hdr_name);
|
||||||
|
dest->mode = orig->mode;
|
||||||
|
dest->except_net = orig->except_net;
|
||||||
|
}
|
||||||
|
@ -352,9 +352,9 @@ void free_proxy(struct proxy *p)
|
|||||||
pxdf->fct(p);
|
pxdf->fct(p);
|
||||||
|
|
||||||
free(p->desc);
|
free(p->desc);
|
||||||
istfree(&p->fwdfor_hdr_name);
|
|
||||||
istfree(&p->orgto_hdr_name);
|
istfree(&p->orgto_hdr_name);
|
||||||
http_ext_7239_clean(&p->http.fwd);
|
http_ext_7239_clean(&p->http.fwd);
|
||||||
|
http_ext_xff_clean(&p->http.xff);
|
||||||
|
|
||||||
task_destroy(p->task);
|
task_destroy(p->task);
|
||||||
|
|
||||||
@ -1465,11 +1465,11 @@ void proxy_free_defaults(struct proxy *defproxy)
|
|||||||
istfree(&defproxy->monitor_uri);
|
istfree(&defproxy->monitor_uri);
|
||||||
ha_free(&defproxy->defbe.name);
|
ha_free(&defproxy->defbe.name);
|
||||||
ha_free(&defproxy->conn_src.iface_name);
|
ha_free(&defproxy->conn_src.iface_name);
|
||||||
istfree(&defproxy->fwdfor_hdr_name);
|
|
||||||
istfree(&defproxy->orgto_hdr_name);
|
istfree(&defproxy->orgto_hdr_name);
|
||||||
istfree(&defproxy->server_id_hdr_name);
|
istfree(&defproxy->server_id_hdr_name);
|
||||||
|
|
||||||
http_ext_7239_clean(&defproxy->http.fwd);
|
http_ext_7239_clean(&defproxy->http.fwd);
|
||||||
|
http_ext_xff_clean(&defproxy->http.xff);
|
||||||
|
|
||||||
list_for_each_entry_safe(acl, aclb, &defproxy->acl, list) {
|
list_for_each_entry_safe(acl, aclb, &defproxy->acl, list) {
|
||||||
LIST_DELETE(&acl->list);
|
LIST_DELETE(&acl->list);
|
||||||
@ -1646,14 +1646,13 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro
|
|||||||
curproxy->options2 = defproxy->options2;
|
curproxy->options2 = defproxy->options2;
|
||||||
curproxy->no_options = defproxy->no_options;
|
curproxy->no_options = defproxy->no_options;
|
||||||
curproxy->no_options2 = defproxy->no_options2;
|
curproxy->no_options2 = defproxy->no_options2;
|
||||||
curproxy->except_xff_net = defproxy->except_xff_net;
|
|
||||||
curproxy->except_xot_net = defproxy->except_xot_net;
|
curproxy->except_xot_net = defproxy->except_xot_net;
|
||||||
curproxy->retry_type = defproxy->retry_type;
|
curproxy->retry_type = defproxy->retry_type;
|
||||||
curproxy->tcp_req.inspect_delay = defproxy->tcp_req.inspect_delay;
|
curproxy->tcp_req.inspect_delay = defproxy->tcp_req.inspect_delay;
|
||||||
curproxy->tcp_rep.inspect_delay = defproxy->tcp_rep.inspect_delay;
|
curproxy->tcp_rep.inspect_delay = defproxy->tcp_rep.inspect_delay;
|
||||||
|
|
||||||
if (isttest(defproxy->fwdfor_hdr_name))
|
if (defproxy->options & PR_O_HTTP_XFF)
|
||||||
curproxy->fwdfor_hdr_name = istdup(defproxy->fwdfor_hdr_name);
|
http_ext_xff_copy(&curproxy->http.xff, &defproxy->http.xff);
|
||||||
|
|
||||||
if (isttest(defproxy->orgto_hdr_name))
|
if (isttest(defproxy->orgto_hdr_name))
|
||||||
curproxy->orgto_hdr_name = istdup(defproxy->orgto_hdr_name);
|
curproxy->orgto_hdr_name = istdup(defproxy->orgto_hdr_name);
|
||||||
|
Loading…
Reference in New Issue
Block a user