mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-10 09:07:02 +02:00
[MEDIUM] config: replace 'tcp-request <action>' with "tcp-request connection"
It began to be problematic to have "tcp-request" followed by an immediate action, as sometimes it was a keyword indicating a hook or setting ("content" or "inspect-delay") and sometimes it was an action. Now the prefix for connection-level tcp-requests is "tcp-request connection" and the ones processing contents remain "tcp-request contents". This has allowed a nice simplification of the config parser and to clean up the doc a bit. Also now it's a bit more clear why tcp-request connection are not allowed in backends.
This commit is contained in:
parent
f6efda1189
commit
68c03aba9e
@ -962,11 +962,12 @@ stick match - - X X
|
|||||||
stick on - - X X
|
stick on - - X X
|
||||||
stick store-request - - X X
|
stick store-request - - X X
|
||||||
stick-table - - X X
|
stick-table - - X X
|
||||||
tcp-request accept - X X -
|
tcp-request connection accept - X X -
|
||||||
|
tcp-request connection reject - X X -
|
||||||
|
tcp-request connection track-counters - X X -
|
||||||
tcp-request content accept - X X -
|
tcp-request content accept - X X -
|
||||||
tcp-request content reject - X X -
|
tcp-request content reject - X X -
|
||||||
tcp-request inspect-delay - X X -
|
tcp-request inspect-delay - X X -
|
||||||
tcp-request reject - X X -
|
|
||||||
timeout check X - X X
|
timeout check X - X X
|
||||||
timeout client X X X -
|
timeout client X X X -
|
||||||
timeout clitimeout (deprecated) X X X -
|
timeout clitimeout (deprecated) X X X -
|
||||||
@ -5251,7 +5252,7 @@ stick-table type {ip | integer | string [len <length>] } size <size>
|
|||||||
about time format and section 7 avoud ACLs.
|
about time format and section 7 avoud ACLs.
|
||||||
|
|
||||||
|
|
||||||
tcp-request accept [{if | unless} <condition>]
|
tcp-request connection accept [{if | unless} <condition>]
|
||||||
Accept an incoming connection if/unless a layer 4 condition is matched
|
Accept an incoming connection if/unless a layer 4 condition is matched
|
||||||
May be used in sections : defaults | frontend | listen | backend
|
May be used in sections : defaults | frontend | listen | backend
|
||||||
no | yes | yes | no
|
no | yes | yes | no
|
||||||
@ -5280,7 +5281,108 @@ tcp-request accept [{if | unless} <condition>]
|
|||||||
|
|
||||||
See section 7 about ACL usage.
|
See section 7 about ACL usage.
|
||||||
|
|
||||||
See also : "tcp-request reject" and "tcp-request content"
|
See also : "tcp-request connection reject" and "tcp-request content"
|
||||||
|
|
||||||
|
|
||||||
|
tcp-request connection reject [{if | unless} <condition>]
|
||||||
|
Reject an incoming connection if/unless a layer 4 condition is matched
|
||||||
|
May be used in sections : defaults | frontend | listen | backend
|
||||||
|
no | yes | yes | no
|
||||||
|
|
||||||
|
Immediately after acceptance of a new incoming connection, it is possible to
|
||||||
|
evaluate some conditions to decide whether this connection must be accepted
|
||||||
|
or dropped. Those conditions cannot make use of any data contents because the
|
||||||
|
connection has not been read from yet, and the buffers are not yet allocated.
|
||||||
|
This can be used to selectively and very quickly accept or drop connections
|
||||||
|
from various sources with a very low overhead. If some contents need to be
|
||||||
|
inspected in order to take the decision, the "tcp-request content" statements
|
||||||
|
must be used instead.
|
||||||
|
|
||||||
|
This statement rejects the connection if the condition is true (when used
|
||||||
|
with "if") or false (when used with "unless"). It is important to understand
|
||||||
|
that "accept" and "reject" rules are evaluated in their exact declaration
|
||||||
|
order, so that it is possible to build complex rules from them. There is no
|
||||||
|
specific limit to the number of rules which may be inserted.
|
||||||
|
|
||||||
|
Note that the "if/unless" condition is optional. If no condition is set on
|
||||||
|
the action, it is simply performed unconditionally.
|
||||||
|
|
||||||
|
If no "tcp-request" rules are matched, the default action is to accept the
|
||||||
|
connection, which implies that the "tcp-request accept" statement will only
|
||||||
|
make sense when combined with another "tcp-request reject" statement.
|
||||||
|
|
||||||
|
Rejected connections do not even become a session, which is why they are
|
||||||
|
accounted separately for in the stats, as "denied connections". They are not
|
||||||
|
considered for the session rate-limit and are not logged either. The reason
|
||||||
|
is that these rules should only be used to filter extremely high connection
|
||||||
|
rates such as the ones encountered during a massive DDoS attack. Under these
|
||||||
|
conditions, the simple action of logging each event would make the system
|
||||||
|
collapse and would considerably lower the filtering capacity. If logging is
|
||||||
|
absolutely desired, then "tcp-request content" rules should be used instead.
|
||||||
|
|
||||||
|
See section 7 about ACL usage.
|
||||||
|
|
||||||
|
See also : "tcp-request connection accept" and "tcp-request content"
|
||||||
|
|
||||||
|
|
||||||
|
tcp-request connection track-counters <key> [table <table>]
|
||||||
|
[{if | unless} <condition>]
|
||||||
|
Enable tracking of session counters if/unless a layer 4 condition is matched
|
||||||
|
May be used in sections : defaults | frontend | listen | backend
|
||||||
|
no | yes | yes | no
|
||||||
|
|
||||||
|
Arguments :
|
||||||
|
<key> is the criterion the tracking key will be derived from. At the
|
||||||
|
moment, only "src" is supported. With it, the key will be the
|
||||||
|
connection's source IPv4 address.
|
||||||
|
|
||||||
|
<table> is an optional table to use instead of the one from the current
|
||||||
|
proxy. All the counters for the matches and updates for the key
|
||||||
|
will then be performed in that table.
|
||||||
|
|
||||||
|
Immediately after a new incoming connection has been accepted, it is possible
|
||||||
|
to enable tracking of some of this session's counters in a table. Doing so
|
||||||
|
serves two purposes :
|
||||||
|
- feed the entry with the session's counters that are relevant to the table
|
||||||
|
being pointed. These counters are then updated as often as possible, and
|
||||||
|
also systematically when the session ends.
|
||||||
|
|
||||||
|
- keep a pointer to the entry in the table in the session to avoid having
|
||||||
|
to perform key lookups when complex ACL rules make use of the entry,
|
||||||
|
especially when the key is expensive to compute (eg: header-based).
|
||||||
|
|
||||||
|
It is possible to evaluate some conditions to decide whether a track-counters
|
||||||
|
statement will apply or not. In this case, only the first matching rule will
|
||||||
|
apply and the other ones will be ignored. We could for instance imagine that
|
||||||
|
some hosts which are references in a white list make use of a different
|
||||||
|
counters table, or do not get accounted for. The tracking is enabled if the
|
||||||
|
condition is true (when used with "if") or false (when used with "unless").
|
||||||
|
There is no specific limit to the number of rules which may be declared.
|
||||||
|
|
||||||
|
It is important to understand that "accept", "reject" and "track-counters"
|
||||||
|
rules are evaluated in their exact declaration order, so that it is possible
|
||||||
|
to build complex rules from them. For instance, the following rule rejects
|
||||||
|
too fast connections without tracking them, to that they get accepted again
|
||||||
|
after some time despite activity, while the second one will still update the
|
||||||
|
counters when rejecting a connection.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
# reject too fast connection without counting them
|
||||||
|
tcp-request connection reject if { src_conn_rate gt 10 }
|
||||||
|
tcp-request connection track-counters src
|
||||||
|
|
||||||
|
# reject too fast connection and count them
|
||||||
|
tcp-request connection track-counters src
|
||||||
|
tcp-request connection reject if { src_conn_rate gt 10 }
|
||||||
|
|
||||||
|
|
||||||
|
Note that the "if/unless" condition is optional. If no condition is set on
|
||||||
|
the action, it is simply performed unconditionally.
|
||||||
|
|
||||||
|
See section 7 about ACL usage.
|
||||||
|
|
||||||
|
See also : "tcp-request connection accept", "tcp-request connection reject",
|
||||||
|
"tcp-request content", and "stick-table".
|
||||||
|
|
||||||
|
|
||||||
tcp-request content accept [{if | unless} <condition>]
|
tcp-request content accept [{if | unless} <condition>]
|
||||||
@ -5337,12 +5439,12 @@ tcp-request content reject [{if | unless} <condition>]
|
|||||||
# reject SMTP connection if client speaks first
|
# reject SMTP connection if client speaks first
|
||||||
tcp-request inspect-delay 30s
|
tcp-request inspect-delay 30s
|
||||||
acl content_present req_len gt 0
|
acl content_present req_len gt 0
|
||||||
tcp-request reject if content_present
|
tcp-request content reject if content_present
|
||||||
|
|
||||||
# Forward HTTPS connection only if client speaks
|
# Forward HTTPS connection only if client speaks
|
||||||
tcp-request inspect-delay 30s
|
tcp-request inspect-delay 30s
|
||||||
acl content_present req_len gt 0
|
acl content_present req_len gt 0
|
||||||
tcp-request accept if content_present
|
tcp-request content accept if content_present
|
||||||
tcp-request reject
|
tcp-request reject
|
||||||
|
|
||||||
See section 7 about ACL usage.
|
See section 7 about ACL usage.
|
||||||
@ -5395,106 +5497,6 @@ tcp-request inspect-delay <timeout>
|
|||||||
"timeout client".
|
"timeout client".
|
||||||
|
|
||||||
|
|
||||||
tcp-request reject [{if | unless} <condition>]
|
|
||||||
Reject an incoming connection if/unless a layer 4 condition is matched
|
|
||||||
May be used in sections : defaults | frontend | listen | backend
|
|
||||||
no | yes | yes | no
|
|
||||||
|
|
||||||
Immediately after acceptance of a new incoming connection, it is possible to
|
|
||||||
evaluate some conditions to decide whether this connection must be accepted
|
|
||||||
or dropped. Those conditions cannot make use of any data contents because the
|
|
||||||
connection has not been read from yet, and the buffers are not yet allocated.
|
|
||||||
This can be used to selectively and very quickly accept or drop connections
|
|
||||||
from various sources with a very low overhead. If some contents need to be
|
|
||||||
inspected in order to take the decision, the "tcp-request content" statements
|
|
||||||
must be used instead.
|
|
||||||
|
|
||||||
This statement rejects the connection if the condition is true (when used
|
|
||||||
with "if") or false (when used with "unless"). It is important to understand
|
|
||||||
that "accept" and "reject" rules are evaluated in their exact declaration
|
|
||||||
order, so that it is possible to build complex rules from them. There is no
|
|
||||||
specific limit to the number of rules which may be inserted.
|
|
||||||
|
|
||||||
Note that the "if/unless" condition is optional. If no condition is set on
|
|
||||||
the action, it is simply performed unconditionally.
|
|
||||||
|
|
||||||
If no "tcp-request" rules are matched, the default action is to accept the
|
|
||||||
connection, which implies that the "tcp-request accept" statement will only
|
|
||||||
make sense when combined with another "tcp-request reject" statement.
|
|
||||||
|
|
||||||
Rejected connections do not even become a session, which is why they are
|
|
||||||
accounted separately for in the stats, as "denied connections". They are not
|
|
||||||
considered for the session rate-limit and are not logged either. The reason
|
|
||||||
is that these rules should only be used to filter extremely high connection
|
|
||||||
rates such as the ones encountered during a massive DDoS attack. Under these
|
|
||||||
conditions, the simple action of logging each event would make the system
|
|
||||||
collapse and would considerably lower the filtering capacity. If logging is
|
|
||||||
absolutely desired, then "tcp-request content" rules should be used instead.
|
|
||||||
|
|
||||||
See section 7 about ACL usage.
|
|
||||||
|
|
||||||
See also : "tcp-request accept" and "tcp-request content"
|
|
||||||
|
|
||||||
|
|
||||||
tcp-request track-counters <key> [table <table>] [{if | unless} <condition>]
|
|
||||||
Enable tracking of session counters if/unless a layer 4 condition is matched
|
|
||||||
May be used in sections : defaults | frontend | listen | backend
|
|
||||||
no | yes | yes | no
|
|
||||||
|
|
||||||
Arguments :
|
|
||||||
<key> is the criterion the tracking key will be derived from. At the
|
|
||||||
moment, only "src" is supported. With it, the key will be the
|
|
||||||
connection's source IPv4 address.
|
|
||||||
|
|
||||||
<table> is an optional table to use instead of the one from the current
|
|
||||||
proxy. All the counters for the matches and updates for the key
|
|
||||||
will then be performed in that table.
|
|
||||||
|
|
||||||
Immediately after a new incoming connection has been accepted, it is possible
|
|
||||||
to enable tracking of some of this session's counters in a table. Doing so
|
|
||||||
serves two purposes :
|
|
||||||
- feed the entry with the session's counters that are relevant to the table
|
|
||||||
being pointed. These counters are then updated as often as possible, and
|
|
||||||
also systematically when the session ends.
|
|
||||||
|
|
||||||
- keep a pointer to the entry in the table in the session to avoid having
|
|
||||||
to perform key lookups when complex ACL rules make use of the entry,
|
|
||||||
especially when the key is expensive to compute (eg: header-based).
|
|
||||||
|
|
||||||
It is possible to evaluate some conditions to decide whether a track-counters
|
|
||||||
statement will apply or not. In this case, only the first matching rule will
|
|
||||||
apply and the other ones will be ignored. We could for instance imagine that
|
|
||||||
some hosts which are references in a white list make use of a different
|
|
||||||
counters table, or do not get accounted for. The tracking is enabled if the
|
|
||||||
condition is true (when used with "if") or false (when used with "unless").
|
|
||||||
There is no specific limit to the number of rules which may be declared.
|
|
||||||
|
|
||||||
It is important to understand that "accept", "reject" and "track-counters"
|
|
||||||
rules are evaluated in their exact declaration order, so that it is possible
|
|
||||||
to build complex rules from them. For instance, the following rule rejects
|
|
||||||
too fast connections without tracking them, to that they get accepted again
|
|
||||||
after some time despite activity, while the second one will still update the
|
|
||||||
counters when rejecting a connection.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
# reject too fast connection without counting them
|
|
||||||
tcp-request reject if { src_conn_rate gt 10 }
|
|
||||||
tcp-request track-counters src
|
|
||||||
|
|
||||||
# reject too fast connection and count them
|
|
||||||
tcp-request track-counters src
|
|
||||||
tcp-request reject if { src_conn_rate gt 10 }
|
|
||||||
|
|
||||||
|
|
||||||
Note that the "if/unless" condition is optional. If no condition is set on
|
|
||||||
the action, it is simply performed unconditionally.
|
|
||||||
|
|
||||||
See section 7 about ACL usage.
|
|
||||||
|
|
||||||
See also : "tcp-request accept", "tcp-request reject", "tcp-request content",
|
|
||||||
and "stick-table".
|
|
||||||
|
|
||||||
|
|
||||||
timeout check <timeout>
|
timeout check <timeout>
|
||||||
Set additional check timeout, but only after a connection has been already
|
Set additional check timeout, but only after a connection has been already
|
||||||
established.
|
established.
|
||||||
|
234
src/proto_tcp.c
234
src/proto_tcp.c
@ -799,6 +799,74 @@ int tcp_exec_req_rules(struct session *s)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse a tcp-request rule. Return a negative value in case of failure */
|
||||||
|
static int tcp_parse_request_rule(char **args, int arg, int section_type,
|
||||||
|
struct proxy *curpx, struct proxy *defpx,
|
||||||
|
struct tcp_rule *rule, char *err, int errlen)
|
||||||
|
{
|
||||||
|
if (curpx == defpx) {
|
||||||
|
snprintf(err, errlen, "%s %s is not allowed in 'defaults' sections",
|
||||||
|
args[0], args[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(args[arg], "accept")) {
|
||||||
|
arg++;
|
||||||
|
rule->action = TCP_ACT_ACCEPT;
|
||||||
|
}
|
||||||
|
else if (!strcmp(args[arg], "reject")) {
|
||||||
|
arg++;
|
||||||
|
rule->action = TCP_ACT_REJECT;
|
||||||
|
}
|
||||||
|
else if (strcmp(args[arg], "track-fe-counters") == 0) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
arg++;
|
||||||
|
ret = parse_track_counters(args, &arg, section_type, curpx,
|
||||||
|
&rule->act_prm.trk_ctr, defpx, err, errlen);
|
||||||
|
|
||||||
|
if (ret < 0) /* nb: warnings are not handled yet */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
rule->action = TCP_ACT_TRK_FE_CTR;
|
||||||
|
}
|
||||||
|
else if (strcmp(args[arg], "track-be-counters") == 0) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
arg++;
|
||||||
|
ret = parse_track_counters(args, &arg, section_type, curpx,
|
||||||
|
&rule->act_prm.trk_ctr, defpx, err, errlen);
|
||||||
|
|
||||||
|
if (ret < 0) /* nb: warnings are not handled yet */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
rule->action = TCP_ACT_TRK_BE_CTR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snprintf(err, errlen,
|
||||||
|
"'%s %s' expects 'accept', 'reject', 'track-fe-counters' "
|
||||||
|
"or 'track-be-counters' in %s '%s' (was '%s')",
|
||||||
|
args[0], args[1], proxy_type_str(curpx), curpx->id, args[arg]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(args[arg], "if") == 0 || strcmp(args[arg], "unless") == 0) {
|
||||||
|
if ((rule->cond = build_acl_cond(NULL, 0, curpx, (const char **)args+arg)) == NULL) {
|
||||||
|
snprintf(err, errlen,
|
||||||
|
"error detected in %s '%s' while parsing '%s' condition",
|
||||||
|
proxy_type_str(curpx), curpx->id, args[arg]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*args[arg]) {
|
||||||
|
snprintf(err, errlen,
|
||||||
|
"'%s %s %s' only accepts 'if' or 'unless', in %s '%s' (was '%s')",
|
||||||
|
args[0], args[1], args[2], proxy_type_str(curpx), curpx->id, args[arg]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* This function should be called to parse a line starting with the "tcp-request"
|
/* This function should be called to parse a line starting with the "tcp-request"
|
||||||
* keyword.
|
* keyword.
|
||||||
*/
|
*/
|
||||||
@ -809,7 +877,6 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
|
|||||||
unsigned int val;
|
unsigned int val;
|
||||||
int retlen;
|
int retlen;
|
||||||
int warn = 0;
|
int warn = 0;
|
||||||
int pol = ACL_COND_NONE;
|
|
||||||
int arg;
|
int arg;
|
||||||
struct tcp_rule *rule;
|
struct tcp_rule *rule;
|
||||||
|
|
||||||
@ -848,70 +915,10 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
|
|||||||
rule = (struct tcp_rule *)calloc(1, sizeof(*rule));
|
rule = (struct tcp_rule *)calloc(1, sizeof(*rule));
|
||||||
arg = 1;
|
arg = 1;
|
||||||
|
|
||||||
if (!strcmp(args[1], "content")) {
|
if (strcmp(args[1], "content") == 0) {
|
||||||
arg++;
|
arg++;
|
||||||
if (curpx == defpx) {
|
if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err, errlen) < 0)
|
||||||
snprintf(err, errlen, "%s %s is not allowed in 'defaults' sections",
|
|
||||||
args[0], args[1]);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(args[2], "accept")) {
|
|
||||||
arg++;
|
|
||||||
rule->action = TCP_ACT_ACCEPT;
|
|
||||||
}
|
|
||||||
else if (!strcmp(args[2], "reject")) {
|
|
||||||
arg++;
|
|
||||||
rule->action = TCP_ACT_REJECT;
|
|
||||||
}
|
|
||||||
else if (strcmp(args[2], "track-fe-counters") == 0) {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
arg++;
|
|
||||||
ret = parse_track_counters(args, &arg, section_type, curpx,
|
|
||||||
&rule->act_prm.trk_ctr, defpx, err, errlen);
|
|
||||||
|
|
||||||
if (ret < 0) /* nb: warnings are not handled yet */
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
rule->action = TCP_ACT_TRK_FE_CTR;
|
|
||||||
}
|
|
||||||
else if (strcmp(args[2], "track-be-counters") == 0) {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
arg++;
|
|
||||||
ret = parse_track_counters(args, &arg, section_type, curpx,
|
|
||||||
&rule->act_prm.trk_ctr, defpx, err, errlen);
|
|
||||||
|
|
||||||
if (ret < 0) /* nb: warnings are not handled yet */
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
rule->action = TCP_ACT_TRK_BE_CTR;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
retlen = snprintf(err, errlen,
|
|
||||||
"'%s %s' expects 'accept', 'reject', 'track-fe-counters' or 'track-be-counters' in %s '%s' (was '%s')",
|
|
||||||
args[0], args[1], proxy_type_str(curpx), curpx->id, args[2]);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
pol = ACL_COND_NONE;
|
|
||||||
rule->cond = NULL;
|
|
||||||
|
|
||||||
if (strcmp(args[arg], "if") == 0 || strcmp(args[arg], "unless") == 0) {
|
|
||||||
if ((rule->cond = build_acl_cond(NULL, 0, curpx, (const char **)args+arg)) == NULL) {
|
|
||||||
retlen = snprintf(err, errlen,
|
|
||||||
"error detected in %s '%s' while parsing '%s' condition",
|
|
||||||
proxy_type_str(curpx), curpx->id, args[arg]);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (*args[arg]) {
|
|
||||||
retlen = snprintf(err, errlen,
|
|
||||||
"'%s %s %s' only accepts 'if' or 'unless', in %s '%s' (was '%s')",
|
|
||||||
args[0], args[1], args[2], proxy_type_str(curpx), curpx->id, args[arg]);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rule->cond && (rule->cond->requires & ACL_USE_RTR_ANY)) {
|
if (rule->cond && (rule->cond->requires & ACL_USE_RTR_ANY)) {
|
||||||
struct acl *acl;
|
struct acl *acl;
|
||||||
@ -925,96 +932,47 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
|
|||||||
name);
|
name);
|
||||||
warn++;
|
warn++;
|
||||||
}
|
}
|
||||||
LIST_INIT(&rule->list);
|
|
||||||
LIST_ADDQ(&curpx->tcp_req.inspect_rules, &rule->list);
|
|
||||||
return warn;
|
|
||||||
}
|
}
|
||||||
|
else if (strcmp(args[1], "connection") == 0) {
|
||||||
/* OK so we're in front of plain L4 rules */
|
|
||||||
|
|
||||||
if (strcmp(args[1], "accept") == 0) {
|
|
||||||
arg++;
|
arg++;
|
||||||
rule->action = TCP_ACT_ACCEPT;
|
|
||||||
}
|
|
||||||
else if (strcmp(args[1], "reject") == 0) {
|
|
||||||
arg++;
|
|
||||||
rule->action = TCP_ACT_REJECT;
|
|
||||||
}
|
|
||||||
else if (strcmp(args[1], "track-fe-counters") == 0) {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
arg++;
|
if (!(curpx->cap & PR_CAP_FE)) {
|
||||||
ret = parse_track_counters(args, &arg, section_type, curpx,
|
snprintf(err, errlen, "%s %s is not allowed because %s %s is not a frontend",
|
||||||
&rule->act_prm.trk_ctr, defpx, err, errlen);
|
args[0], args[1], proxy_type_str(curpx), curpx->id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret < 0) /* nb: warnings are not handled yet */
|
if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err, errlen) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
rule->action = TCP_ACT_TRK_FE_CTR;
|
if (rule->cond && (rule->cond->requires & (ACL_USE_RTR_ANY|ACL_USE_L6_ANY|ACL_USE_L7_ANY))) {
|
||||||
}
|
struct acl *acl;
|
||||||
else if (strcmp(args[1], "track-be-counters") == 0) {
|
const char *name;
|
||||||
int ret;
|
|
||||||
|
|
||||||
arg++;
|
acl = cond_find_require(rule->cond, ACL_USE_RTR_ANY|ACL_USE_L6_ANY|ACL_USE_L7_ANY);
|
||||||
ret = parse_track_counters(args, &arg, section_type, curpx,
|
name = acl ? acl->name : "(unknown)";
|
||||||
&rule->act_prm.trk_ctr, defpx, err, errlen);
|
|
||||||
|
|
||||||
if (ret < 0) /* nb: warnings are not handled yet */
|
if (acl->requires & (ACL_USE_L6_ANY|ACL_USE_L7_ANY)) {
|
||||||
goto error;
|
retlen = snprintf(err, errlen,
|
||||||
|
"'%s %s' may not reference acl '%s' which makes use of "
|
||||||
rule->action = TCP_ACT_TRK_BE_CTR;
|
"payload in %s '%s'. Please use '%s content' for this.",
|
||||||
|
args[0], args[1], name, proxy_type_str(curpx), curpx->id, args[0]);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (acl->requires & ACL_USE_RTR_ANY)
|
||||||
|
retlen = snprintf(err, errlen,
|
||||||
|
"acl '%s' involves some response-only criteria which will be ignored.",
|
||||||
|
name);
|
||||||
|
warn++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
retlen = snprintf(err, errlen,
|
retlen = snprintf(err, errlen,
|
||||||
"'%s' expects 'inspect-delay', 'content', 'accept', 'reject', 'track-fe-counters' or 'track-be-counters' in %s '%s' (was '%s')",
|
"'%s' expects 'inspect-delay', 'connection', or 'content' in %s '%s' (was '%s')",
|
||||||
args[0], proxy_type_str(curpx), curpx->id, args[1]);
|
args[0], proxy_type_str(curpx), curpx->id, args[1]);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curpx == defpx) {
|
|
||||||
snprintf(err, errlen, "%s %s is not allowed in 'defaults' sections",
|
|
||||||
args[0], args[1]);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
pol = ACL_COND_NONE;
|
|
||||||
|
|
||||||
if (strcmp(args[arg], "if") == 0 || strcmp(args[arg], "unless") == 0) {
|
|
||||||
if ((rule->cond = build_acl_cond(NULL, 0, curpx, (const char **)args+arg)) == NULL) {
|
|
||||||
retlen = snprintf(err, errlen,
|
|
||||||
"error detected in %s '%s' while parsing '%s' condition",
|
|
||||||
proxy_type_str(curpx), curpx->id, args[arg]);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (*args[arg]) {
|
|
||||||
retlen = snprintf(err, errlen,
|
|
||||||
"'%s %s' only accepts 'if' or 'unless', in %s '%s' (was '%s')",
|
|
||||||
args[0], args[1], proxy_type_str(curpx), curpx->id, args[arg]);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rule->cond && (rule->cond->requires & (ACL_USE_RTR_ANY|ACL_USE_L6_ANY|ACL_USE_L7_ANY))) {
|
|
||||||
struct acl *acl;
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
acl = cond_find_require(rule->cond, ACL_USE_RTR_ANY|ACL_USE_L6_ANY|ACL_USE_L7_ANY);
|
|
||||||
name = acl ? acl->name : "(unknown)";
|
|
||||||
|
|
||||||
if (acl->requires & (ACL_USE_L6_ANY|ACL_USE_L7_ANY)) {
|
|
||||||
retlen = snprintf(err, errlen,
|
|
||||||
"'%s %s' may not reference acl '%s' which makes use of payload in %s '%s'. Please use '%s content' for this.",
|
|
||||||
args[0], args[1], name, proxy_type_str(curpx), curpx->id, args[0]);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (acl->requires & ACL_USE_RTR_ANY)
|
|
||||||
retlen = snprintf(err, errlen,
|
|
||||||
"acl '%s' involves some response-only criteria which will be ignored.",
|
|
||||||
name);
|
|
||||||
|
|
||||||
warn++;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIST_INIT(&rule->list);
|
LIST_INIT(&rule->list);
|
||||||
LIST_ADDQ(&curpx->tcp_req.l4_rules, &rule->list);
|
LIST_ADDQ(&curpx->tcp_req.l4_rules, &rule->list);
|
||||||
return warn;
|
return warn;
|
||||||
|
Loading…
Reference in New Issue
Block a user