MINOR: tcp: add new "close" action for tcp-response

This new action immediately closes the connection with the server
when the condition is met. 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.
This commit is contained in:
Willy Tarreau 2013-09-11 23:20:29 +02:00
parent 3a925c155d
commit cc1e04b1e8
3 changed files with 26 additions and 5 deletions

View File

@ -6718,16 +6718,15 @@ tcp-response content <action> [{if | unless} <condition>]
no | no | yes | yes no | no | yes | yes
Arguments : Arguments :
<action> defines the action to perform if the condition applies. Valid <action> defines the action to perform if the condition applies. Valid
actions include : "accept", "reject". actions include : "accept", "close", "reject".
See "tcp-request connection" above for their signification.
<condition> is a standard layer 4-7 ACL-based condition (see section 7). <condition> is a standard layer 4-7 ACL-based condition (see section 7).
Response contents can be analysed at an early stage of response processing Response contents can be analysed at an early stage of response processing
called "TCP content inspection". During this stage, ACL-based rules are called "TCP content inspection". During this stage, ACL-based rules are
evaluated every time the response contents are updated, until either an evaluated every time the response contents are updated, until either an
"accept" or a "reject" rule matches, or a TCP response inspection delay is "accept", "close" or a "reject" rule matches, or a TCP response inspection
set and expires with no matching rule. delay is set and expires with no matching rule.
Most often, these decisions will consider a protocol recognition or validity. Most often, these decisions will consider a protocol recognition or validity.
@ -6742,6 +6741,16 @@ tcp-response content <action> [{if | unless} <condition>]
or false (when used with "unless"). The first such rule executed ends or false (when used with "unless"). The first such rule executed ends
the rules evaluation. 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 : - reject :
rejects the response if the condition is true (when used with "if") rejects the response if the condition is true (when used with "if")
or false (when used with "unless"). The first such rule executed ends or false (when used with "unless"). The first such rule executed ends

View File

@ -37,6 +37,7 @@ enum {
TCP_ACT_TRK_SC1 = 5, TCP_ACT_TRK_SC1 = 5,
TCP_ACT_TRK_SC2 = 6, TCP_ACT_TRK_SC2 = 6,
TCP_ACT_TRK_SCMAX = TCP_ACT_TRK_SC0 + MAX_SESS_STKCTR - 1, TCP_ACT_TRK_SCMAX = TCP_ACT_TRK_SC0 + MAX_SESS_STKCTR - 1,
TCP_ACT_CLOSE, /* close at the sender's */
}; };
struct tcp_rule { struct tcp_rule {

View File

@ -51,6 +51,7 @@
#include <proto/sample.h> #include <proto/sample.h>
#include <proto/session.h> #include <proto/session.h>
#include <proto/stick_table.h> #include <proto/stick_table.h>
#include <proto/stream_interface.h>
#include <proto/task.h> #include <proto/task.h>
#ifdef CONFIG_HAP_CTTPROXY #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; s->flags |= SN_FINST_D;
return 0; 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 { else {
/* otherwise accept */ /* otherwise accept */
break; break;
@ -1138,9 +1145,13 @@ static int tcp_parse_response_rule(char **args, int arg, int section_type,
arg++; arg++;
rule->action = TCP_ACT_REJECT; rule->action = TCP_ACT_REJECT;
} }
else if (strcmp(args[arg], "close") == 0) {
arg++;
rule->action = TCP_ACT_CLOSE;
}
else { else {
memprintf(err, 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]); args[0], args[1], proxy_type_str(curpx), curpx->id, args[arg]);
return -1; return -1;
} }