diff --git a/doc/configuration.txt b/doc/configuration.txt index 37d16cb3dc..097aa27df0 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -6718,16 +6718,15 @@ tcp-response content [{if | unless} ] no | no | yes | yes Arguments : defines the action to perform if the condition applies. Valid - actions include : "accept", "reject". - See "tcp-request connection" above for their signification. + actions include : "accept", "close", "reject". is a standard layer 4-7 ACL-based condition (see section 7). Response contents can be analysed at an early stage of response processing called "TCP content inspection". During this stage, ACL-based rules are evaluated every time the response contents are updated, until either an - "accept" or a "reject" rule matches, or a TCP response inspection delay is - set and expires with no matching rule. + "accept", "close" or a "reject" rule matches, or a TCP response inspection + delay is set and expires with no matching rule. Most often, these decisions will consider a protocol recognition or validity. @@ -6742,6 +6741,16 @@ tcp-response content [{if | unless} ] or false (when used with "unless"). The first such rule executed ends the rules evaluation. + - close : + immediately closes the connection with the server if the condition is + true (when used with "if"), or false (when used with "unless"). The + first such rule executed ends the rules evaluation. The main purpose of + this action is to force a connection to be finished between a client + and a server after an exchange when the application protocol expects + some long time outs to elapse first. The goal is to eliminate idle + connections which take signifiant resources on servers with certain + protocols. + - reject : rejects the response if the condition is true (when used with "if") or false (when used with "unless"). The first such rule executed ends diff --git a/include/types/proto_tcp.h b/include/types/proto_tcp.h index 662cde4954..7f65244a06 100644 --- a/include/types/proto_tcp.h +++ b/include/types/proto_tcp.h @@ -37,6 +37,7 @@ enum { TCP_ACT_TRK_SC1 = 5, TCP_ACT_TRK_SC2 = 6, TCP_ACT_TRK_SCMAX = TCP_ACT_TRK_SC0 + MAX_SESS_STKCTR - 1, + TCP_ACT_CLOSE, /* close at the sender's */ }; struct tcp_rule { diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 797f3357e4..56fa2a392d 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #ifdef CONFIG_HAP_CTTPROXY @@ -1039,6 +1040,12 @@ int tcp_inspect_response(struct session *s, struct channel *rep, int an_bit) s->flags |= SN_FINST_D; return 0; } + else if (rule->action == TCP_ACT_CLOSE) { + rep->prod->flags |= SI_FL_NOLINGER | SI_FL_NOHALF; + si_shutr(rep->prod); + si_shutw(rep->prod); + break; + } else { /* otherwise accept */ break; @@ -1138,9 +1145,13 @@ static int tcp_parse_response_rule(char **args, int arg, int section_type, arg++; rule->action = TCP_ACT_REJECT; } + else if (strcmp(args[arg], "close") == 0) { + arg++; + rule->action = TCP_ACT_CLOSE; + } else { memprintf(err, - "'%s %s' expects 'accept' or 'reject' in %s '%s' (got '%s')", + "'%s %s' expects 'accept', 'close' or 'reject' in %s '%s' (got '%s')", args[0], args[1], proxy_type_str(curpx), curpx->id, args[arg]); return -1; }