[MINOR] acl: add the "wait_end" acl verb

The new "wait_end" acl delays evaluation of the rule (and the next ones)
to the end of the analysis period. This is intented to be used with TCP
content analysis. A rule referencing such an ACL will not match until
the delay is over. An equivalent default ACL "WAIT_END" has been created.
This commit is contained in:
Willy Tarreau 2008-07-20 11:18:28 +02:00
parent 58393e103f
commit b6fb420c7e
3 changed files with 59 additions and 9 deletions

View File

@ -3771,6 +3771,29 @@ req_ssl_ver <decimal>
that TLSv1 is announced as SSL version 3.1. This test was designed to be used that TLSv1 is announced as SSL version 3.1. This test was designed to be used
with TCP request content inspection. with TCP request content inspection.
wait_end
Waits for the end of the analysis period to return true. This may be used in
conjunction with content analysis to avoid returning a wrong verdict early.
It may also be used to delay some actions, such as a delayed reject for some
special addresses. Since it either stops the rules evaluation or immediately
returns true, it is recommended to use this acl as the last one in a rule.
Please note that the default ACL "WAIT_END" is always usable without prior
declaration. This test was designed to be used with TCP request content
inspection.
Examples :
# delay every incoming request by 2 seconds
tcp-request inspect-delay 2s
tcp-request content accept if WAIT_END
# don't immediately tell bad guys they are rejected
tcp-request inspect-delay 10s
acl goodguys src 10.0.0.0/24
acl badguys src 10.0.1.0/24
tcp-request content accept if goodguys
tcp-request content reject if badguys WAIT_END
tcp-request content reject
2.3.5.3) Matching at Layer 7 2.3.5.3) Matching at Layer 7
---------------------------- ----------------------------
@ -3957,6 +3980,7 @@ HTTP_URL_SLASH url_beg / match URL begining with "/"
HTTP_URL_STAR url * match URL equal to "*" HTTP_URL_STAR url * match URL equal to "*"
HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length
REQ_CONTENT req_len gt 0 match data in the request buffer REQ_CONTENT req_len gt 0 match data in the request buffer
WAIT_END wait_end wait for end of content analysis
---------------+-----------------------------+--------------------------------- ---------------+-----------------------------+---------------------------------

View File

@ -39,6 +39,21 @@ acl_fetch_true(struct proxy *px, struct session *l4, void *l7, int dir,
return 1; return 1;
} }
/* wait for more data as long as possible, then return TRUE. This should be
* used with content inspection.
*/
static int
acl_fetch_wait_end(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
if (dir & ACL_PARTIAL) {
test->flags |= ACL_TEST_F_MAY_CHANGE;
return 0;
}
test->flags |= ACL_TEST_F_SET_RES_PASS;
return 1;
}
/* force FALSE to be returned at the fetch level */ /* force FALSE to be returned at the fetch level */
static int static int
acl_fetch_false(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_false(struct proxy *px, struct session *l4, void *l7, int dir,
@ -772,6 +787,7 @@ const struct {
{ .name = "HTTP_URL_STAR", .expr = {"url","*",""}}, { .name = "HTTP_URL_STAR", .expr = {"url","*",""}},
{ .name = "HTTP_CONTENT", .expr = {"hdr_val(content-length)","gt","0",""}}, { .name = "HTTP_CONTENT", .expr = {"hdr_val(content-length)","gt","0",""}},
{ .name = "REQ_CONTENT", .expr = {"req_len","gt","0",""}}, { .name = "REQ_CONTENT", .expr = {"req_len","gt","0",""}},
{ .name = "WAIT_END", .expr = {"wait_end",""}},
{ .name = NULL, .expr = {""}} { .name = NULL, .expr = {""}}
}; };
@ -1064,6 +1080,7 @@ int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, v
static struct acl_kw_list acl_kws = {{ },{ static struct acl_kw_list acl_kws = {{ },{
{ "always_true", acl_parse_nothing, acl_fetch_true, acl_match_nothing }, { "always_true", acl_parse_nothing, acl_fetch_true, acl_match_nothing },
{ "always_false", acl_parse_nothing, acl_fetch_false, acl_match_nothing }, { "always_false", acl_parse_nothing, acl_fetch_false, acl_match_nothing },
{ "wait_end", acl_parse_nothing, acl_fetch_wait_end, acl_match_nothing },
#if 0 #if 0
{ "time", acl_parse_time, acl_fetch_time, acl_match_time }, { "time", acl_parse_time, acl_fetch_time, acl_match_time },
#endif #endif

View File

@ -3,7 +3,7 @@
# - if the address is in the white list, then accept it and forward the # - if the address is in the white list, then accept it and forward the
# connection to the server (local port 25) # connection to the server (local port 25)
# - if the address is in the black list, then immediately drop it # - if the address is in the black list, then immediately drop it
# - otherwise, wait up to 3 seconds. If the client talks during this time, # - otherwise, wait up to 35 seconds. If the client talks during this time,
# drop the connection. # drop the connection.
# - then accept the connection if it passes all the tests. # - then accept the connection if it passes all the tests.
# #
@ -17,19 +17,28 @@ listen block-fake-mailers
mode tcp mode tcp
bind :8025 bind :8025
timeout client 6s timeout client 60s
timeout server 6s timeout server 60s
timeout connect 6s timeout queue 60s
timeout connect 5s
tcp-request inspect-delay 4s tcp-request inspect-delay 35s
acl white_list src 127.0.0.2 acl white_list src 127.0.0.2
acl black_list src 127.0.0.3 acl black_fast src 127.0.0.3 # those ones are immediately rejected
acl talkative req_len gt 0 acl black_slow src 127.0.0.4 # those ones are rejected after a delay
tcp-request content accept if white_list tcp-request content accept if white_list
tcp-request content reject if black_list tcp-request content reject if black_fast
tcp-request content reject if talkative tcp-request content reject if black_slow WAIT_END
tcp-request content reject if REQ_CONTENT
# note that it is possible to wait for the end of the analysis period
# before rejecting undesired contents
# tcp-request content reject if REQ_CONTENT WAIT_END
# on Linux+transparent proxy patch, it's useful to reuse the client'IP
# source 0.0.0.0 usesrc clientip
balance roundrobin balance roundrobin
server mail 127.0.0.1:25 server mail 127.0.0.1:25