mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-24 23:31:40 +02:00
The warning is only emitted for HTTP frontend. Idea is to encourage the usage of "tcp-request session" rules to track counters that does not depend on the request content. The documentation has been updated accordingly. The warning is important because since the multiplexers were added in the processing chain, the HTTP parsing is performed at a lower level. Thus parsing errors are detected in the multiplexers, before the stream creation. In HTTP/2, the error is reported by the multiplexer itself and the stream is never created. This difference has a certain number of consequences, one of which is that HTTP request counting in stick tables only works for valid H2 request, and HTTP error tracking in stick tables never considers invalid H2 requests but only invalid H1 ones. And the aim is to do the same with the mux-h1. This change will not be done for the 2.3, but the 2.4. At the end, H1 and H2 parsing errors will be caught by the multiplexers, at the session level. Thus, tracking counters at the content level should be reserved for rules using a key based on the request content or those using ACLs based on the request content. To be clear, a warning will be emitted for the following rules : tcp-request content track-sc0 src tcp-request content track-sc0 src if ! { src 10.0.0.0/24 } tcp-request content track-sc0 src if { ssl_fc } But not for the following ones : tcp-request content track-sc0 req.hdr(host) tcp-request content track-sc0 src if { req.hdr(host) -m found }
152 lines
5.1 KiB
C
152 lines
5.1 KiB
C
/*
|
|
* Action management functions.
|
|
*
|
|
* Copyright 2017 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*
|
|
*/
|
|
|
|
#include <haproxy/action.h>
|
|
#include <haproxy/api.h>
|
|
#include <haproxy/errors.h>
|
|
#include <haproxy/list.h>
|
|
#include <haproxy/obj_type.h>
|
|
#include <haproxy/pool.h>
|
|
#include <haproxy/proxy.h>
|
|
#include <haproxy/stick_table.h>
|
|
#include <haproxy/task.h>
|
|
#include <haproxy/tools.h>
|
|
|
|
|
|
/* Find and check the target table used by an action track-sc*. This
|
|
* function should be called during the configuration validity check.
|
|
*
|
|
* The function returns 1 in success case, otherwise, it returns 0 and err is
|
|
* filled.
|
|
*/
|
|
int check_trk_action(struct act_rule *rule, struct proxy *px, char **err)
|
|
{
|
|
struct stktable *target;
|
|
|
|
if (rule->arg.trk_ctr.table.n)
|
|
target = stktable_find_by_name(rule->arg.trk_ctr.table.n);
|
|
else
|
|
target = px->table;
|
|
|
|
if (!target) {
|
|
memprintf(err, "unable to find table '%s' referenced by track-sc%d",
|
|
rule->arg.trk_ctr.table.n ? rule->arg.trk_ctr.table.n : px->id,
|
|
rule->action);
|
|
return 0;
|
|
}
|
|
|
|
if (!stktable_compatible_sample(rule->arg.trk_ctr.expr, target->type)) {
|
|
memprintf(err, "stick-table '%s' uses a type incompatible with the 'track-sc%d' rule",
|
|
rule->arg.trk_ctr.table.n ? rule->arg.trk_ctr.table.n : px->id,
|
|
rule->action);
|
|
return 0;
|
|
}
|
|
else if (target->proxy && (px->bind_proc & ~target->proxy->bind_proc)) {
|
|
memprintf(err, "stick-table '%s' referenced by 'track-sc%d' rule not present on all processes covered by proxy '%s'",
|
|
target->id, rule->action, px->id);
|
|
return 0;
|
|
}
|
|
else {
|
|
if (!in_proxies_list(target->proxies_list, px)) {
|
|
px->next_stkt_ref = target->proxies_list;
|
|
target->proxies_list = px;
|
|
}
|
|
free(rule->arg.trk_ctr.table.n);
|
|
rule->arg.trk_ctr.table.t = target;
|
|
/* Note: if we decide to enhance the track-sc syntax, we may be
|
|
* able to pass a list of counters to track and allocate them
|
|
* right here using stktable_alloc_data_type().
|
|
*/
|
|
}
|
|
|
|
if (rule->from == ACT_F_TCP_REQ_CNT && (px->cap & PR_CAP_FE)) {
|
|
if (!px->tcp_req.inspect_delay && !(rule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC)) {
|
|
ha_warning("config : %s '%s' : a 'tcp-request content track-sc*' rule explicitly depending on request"
|
|
" contents without any 'tcp-request inspect-delay' setting."
|
|
" This means that this rule will randomly find its contents. This can be fixed by"
|
|
" setting the tcp-request inspect-delay.\n",
|
|
proxy_type_str(px), px->id);
|
|
}
|
|
|
|
/* The following warning is emitted because HTTP multiplexers are able to catch errors
|
|
* or timeouts at the session level, before instantiating any stream.
|
|
* Thus the tcp-request content ruleset will not be evaluated in such case. It means,
|
|
* http_req and http_err counters will not be incremented as expected, even if the tracked
|
|
* counter does not use the request content. To track invalid requests it should be
|
|
* performed at the session level using a tcp-request session rule.
|
|
*/
|
|
if (px->mode == PR_MODE_HTTP &&
|
|
!(rule->arg.trk_ctr.expr->fetch->use & (SMP_USE_L6REQ|SMP_USE_HRQHV|SMP_USE_HRQHP|SMP_USE_HRQBO)) &&
|
|
(!rule->cond || !(rule->cond->use & (SMP_USE_L6REQ|SMP_USE_HRQHV|SMP_USE_HRQHP|SMP_USE_HRQBO)))) {
|
|
ha_warning("config : %s '%s' : a 'tcp-request content track-sc*' rule not depending on request"
|
|
" contents for an HTTP frontend should be executed at the session level, using a"
|
|
" 'tcp-request session' rule (mandatory to track invalid HTTP requests).\n",
|
|
proxy_type_str(px), px->id);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* check a capture rule. This function should be called during the configuration
|
|
* validity check.
|
|
*
|
|
* The function returns 1 in success case, otherwise, it returns 0 and err is
|
|
* filled.
|
|
*/
|
|
int check_capture(struct act_rule *rule, struct proxy *px, char **err)
|
|
{
|
|
if (rule->from == ACT_F_TCP_REQ_CNT && (px->cap & PR_CAP_FE) && !px->tcp_req.inspect_delay &&
|
|
!(rule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC)) {
|
|
ha_warning("config : %s '%s' : a 'tcp-request capture' rule explicitly depending on request"
|
|
" contents without any 'tcp-request inspect-delay' setting."
|
|
" This means that this rule will randomly find its contents. This can be fixed by"
|
|
" setting the tcp-request inspect-delay.\n",
|
|
proxy_type_str(px), px->id);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int act_resolution_cb(struct dns_requester *requester, struct dns_nameserver *nameserver)
|
|
{
|
|
struct stream *stream;
|
|
|
|
if (requester->resolution == NULL)
|
|
return 0;
|
|
|
|
stream = objt_stream(requester->owner);
|
|
if (stream == NULL)
|
|
return 0;
|
|
|
|
task_wakeup(stream->task, TASK_WOKEN_MSG);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int act_resolution_error_cb(struct dns_requester *requester, int error_code)
|
|
{
|
|
struct stream *stream;
|
|
|
|
if (requester->resolution == NULL)
|
|
return 0;
|
|
|
|
stream = objt_stream(requester->owner);
|
|
if (stream == NULL)
|
|
return 0;
|
|
|
|
task_wakeup(stream->task, TASK_WOKEN_MSG);
|
|
|
|
return 0;
|
|
}
|
|
|