]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] extract the HTTP tarpit code from process_request().
authorWilly Tarreau <w@1wt.eu>
Sun, 30 Nov 2008 22:28:40 +0000 (23:28 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 30 Nov 2008 22:28:40 +0000 (23:28 +0100)
The tarpit is now an autonomous independant analyser.

include/proto/proto_http.h
src/proto_http.c
src/session.c

index 72a5e3cc0770f6d2d47a14c00956d2334c0c3c81..535611d475a07278f551aa713d9a2105ade25a53 100644 (file)
@@ -63,6 +63,7 @@ int process_cli(struct session *t);
 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);
index a3750bd18d2105f22046b6b5c8776ac0868ffdf6..ab8c255d33ba0f1e411dcfa72ed330dea6ddad83 100644 (file)
@@ -2359,42 +2359,6 @@ int process_request(struct session *t)
                ; // 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 @@ int process_request(struct session *t)
        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
index e13bca648f3b91f9fbece33ad73999ff8e6823f0..34d3d0acdf862dedc54dcd834c067fb7dd7b4bcb 100644 (file)
@@ -709,6 +709,10 @@ resync_stream_interface:
                                        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;