[MINOR] tarpit: close the connection if the client closes.
There's no point at maintaining an open tarpitted connection
if the client has left.
diff --git a/doc/haproxy-en.txt b/doc/haproxy-en.txt
index 2f69473..ab26df5 100644
--- a/doc/haproxy-en.txt
+++ b/doc/haproxy-en.txt
@@ -1742,7 +1742,7 @@
server had already finished.
T : the request was tarpitted. It has been held open on with the client
- during the whole contimeout duration.
+ during the whole contimeout duration or untill the client closed.
- : normal session completion after end of data transfer.
@@ -1826,6 +1826,8 @@
servers were saturated or the assigned server taking too long to
respond.
+ CT The client aborted while its session was tarpitted.
+
sQ The session spent too much time in queue and has been expired.
SH The server aborted before sending its full headers, or it crashed.
@@ -2073,10 +2075,11 @@
- a denied request will generate an "HTTP 403 forbidden" response, while a
denied response will generate an "HTTP 502 Bad gateway" response.
- a tarpitted request will be held open on the client side for a duration
- defined in the contimeout parameter. Nothing will be sent to any server.
- When the timeout is reached, the proxy will reply with a 500 server error
- response so that the attacker does not suspect it has been tarpitted. The
- logs will report the 500, but the termination flags will indicate 'PT'.
+ defined in the contimeout parameter, or untill the client aborts. Nothing
+ will be sent to any server. When the timeout is reached, the proxy will
+ reply with a 500 server error response so that the attacker does not
+ suspect it has been tarpitted. The logs may report the 500, but the
+ termination flags will indicate 'PT' in this case.
Examples :
diff --git a/doc/haproxy-fr.txt b/doc/haproxy-fr.txt
index 6f4926f..9282cb4 100644
--- a/doc/haproxy-fr.txt
+++ b/doc/haproxy-fr.txt
@@ -1798,7 +1798,8 @@
alors que le serveur a déjà fini.
T : requête bloquée en mode "tarpit" par le proxy. Elle a été maintenue
- ouverte vers le client pendant toute la durée du contimeout.
+ ouverte vers le client pendant toute la durée du contimeout ou
+ jusqu'à l'abandon de la part du client.
- : terminaison normale, après fin de transfert des données.
@@ -1894,6 +1895,9 @@
serveurs étaient saturés, soit que le serveur assigné a mis trop de
temps à répondre.
+ CT Le client a abandonné alors que sa session était bloquée en mode
+ tarpit.
+
sQ La session a attendu trop longtemps en file d'attente et a été
expirée.
@@ -2152,11 +2156,11 @@
- une requête bloquée produira une réponse "HTTP 403 forbidden" tandis qu'une
réponse bloquée produira une réponse "HTTP 502 Bad gateway".
- une requête bloquée par 'reqtarpit' sera maintenue pendant une durée égale
- au paramètre 'contimeout'. Rien ne sera envoyé au serveur. Lorsque le temps
- alloué expire, le proxy répondra avec une réponse "500 server error" de
- sorte que l'attaquant ne suspecte pas qu'il ait été bloqué. Les logs
- rapporteront aussi ce code 500, mais les flags de terminaison indiqueront
- "PT".
+ au paramètre 'contimeout', ou jusqu'à l'abandon du client. Rien ne sera
+ envoyé au serveur. Lorsque le temps alloué expire, le proxy répondra avec
+ une réponse "500 server error" de sorte que l'attaquant ne suspecte pas
+ qu'il ait été bloqué. Les logs rapporteront aussi ce code 500, mais les
+ flags de terminaison indiqueront "PT".
Exemples :
----------
diff --git a/src/proto_http.c b/src/proto_http.c
index 0b0ce73..51a910a 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -458,6 +458,10 @@
* to expire at one moment.
*/
if (t->flags & SN_CLTARPIT) {
+ t->req->l = 0;
+ /* flush the request so that we can drop the connection early
+ * if the client closes first.
+ */
tv_delayfrom(&req->cex, &now,
t->proxy->contimeout ? t->proxy->contimeout : 0);
}
@@ -1348,7 +1352,10 @@
/* note that this must not return any error because it would be able to
* overwrite the client_retnclose() output.
*/
- srv_close_with_err(t, SN_ERR_CLICL, t->pend_pos ? SN_FINST_Q : SN_FINST_C, 0, 0, NULL);
+ if (t->flags & SN_CLTARPIT)
+ srv_close_with_err(t, SN_ERR_CLICL, SN_FINST_T, 0, 0, NULL);
+ else
+ srv_close_with_err(t, SN_ERR_CLICL, t->pend_pos ? SN_FINST_Q : SN_FINST_C, 0, 0, NULL);
return 1;
}