mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-12 08:27:24 +00:00
[MEDIUM] extract the HTTP tarpit code from process_request().
The tarpit is now an autonomous independant analyser.
This commit is contained in:
parent
edcf6687d6
commit
60b85b0694
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user