[MEDIUM] extract the HTTP tarpit code from process_request().
The tarpit is now an autonomous independant analyser.
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
index 72a5e3c..535611d 100644
--- a/include/proto/proto_http.h
+++ b/include/proto/proto_http.h
@@ -63,6 +63,7 @@
int process_srv_data(struct session *t);
int process_srv_conn(struct session *t);
int process_request(struct session *t);
+int http_process_tarpit(struct session *s, struct buffer *req);
int process_response(struct session *t);
int produce_content(struct session *s);
diff --git a/src/proto_http.c b/src/proto_http.c
index a3750bd..ab8c255 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -2359,42 +2359,6 @@
; // to keep gcc happy
}
- if (req->analysers & AN_REQ_HTTP_TARPIT) {
- struct http_txn *txn = &t->txn;
-
- /* This connection is being tarpitted. The CLIENT side has
- * already set the connect expiration date to the right
- * timeout. We just have to check that the client is still
- * there and that the timeout has not expired.
- */
- if ((req->flags & (BF_SHUTR|BF_READ_ERROR)) == 0 &&
- !tick_is_expired(req->analyse_exp, now_ms))
- return 0;
-
- /* We will set the queue timer to the time spent, just for
- * logging purposes. We fake a 500 server error, so that the
- * attacker will not suspect his connection has been tarpitted.
- * It will not cause trouble to the logs because we can exclude
- * the tarpitted connections by filtering on the 'PT' status flags.
- */
- trace_term(t, TT_HTTP_SRV_2);
- t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now);
-
- txn->status = 500;
- if (req->flags != BF_READ_ERROR)
- stream_int_retnclose(req->prod, error_message(t, HTTP_ERR_500));
-
- req->analysers = 0;
- req->analyse_exp = TICK_ETERNITY;
-
- t->fe->failed_req++;
- if (!(t->flags & SN_ERR_MASK))
- t->flags |= SN_ERR_PRXCOND;
- if (!(t->flags & SN_FINST_MASK))
- t->flags |= SN_FINST_T;
- return 0;
- }
-
if (req->analysers & AN_REQ_HTTP_BODY) {
/* We have to parse the HTTP request body to find any required data.
* "balance url_param check_post" should have been the only way to get
@@ -2484,6 +2448,47 @@
return 0;
}
+/* This function is an analyser which processes the HTTP tarpit. It always
+ * returns zero, at the beginning because it prevents any other processing
+ * from occurring, and at the end because it terminates the request.
+ */
+int http_process_tarpit(struct session *s, struct buffer *req)
+{
+ struct http_txn *txn = &s->txn;
+
+ /* This connection is being tarpitted. The CLIENT side has
+ * already set the connect expiration date to the right
+ * timeout. We just have to check that the client is still
+ * there and that the timeout has not expired.
+ */
+ if ((req->flags & (BF_SHUTR|BF_READ_ERROR)) == 0 &&
+ !tick_is_expired(req->analyse_exp, now_ms))
+ return 0;
+
+ /* We will set the queue timer to the time spent, just for
+ * logging purposes. We fake a 500 server error, so that the
+ * attacker will not suspect his connection has been tarpitted.
+ * It will not cause trouble to the logs because we can exclude
+ * the tarpitted connections by filtering on the 'PT' status flags.
+ */
+ trace_term(s, TT_HTTP_SRV_2);
+ s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
+
+ txn->status = 500;
+ if (req->flags != BF_READ_ERROR)
+ stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_500));
+
+ req->analysers = 0;
+ req->analyse_exp = TICK_ETERNITY;
+
+ s->fe->failed_req++;
+ if (!(s->flags & SN_ERR_MASK))
+ s->flags |= SN_ERR_PRXCOND;
+ if (!(s->flags & SN_FINST_MASK))
+ s->flags |= SN_FINST_T;
+ return 0;
+}
+
/* This function performs all the processing enabled for the current response.
* It normally returns zero, but may return 1 if it absolutely needs to be
* called again after other functions. It relies on buffers flags, and updates
diff --git a/src/session.c b/src/session.c
index e13bca6..34d3d0a 100644
--- a/src/session.c
+++ b/src/session.c
@@ -709,6 +709,10 @@
if (!process_request(s))
break;
+ if (s->req->analysers & AN_REQ_HTTP_TARPIT)
+ if (!http_process_tarpit(s, s->req))
+ break;
+
/* Just make sure that nobody set a wrong flag causing an endless loop */
s->req->analysers &= AN_REQ_INSPECT | AN_REQ_HTTP_HDR | AN_REQ_HTTP_TARPIT | AN_REQ_HTTP_BODY;