From: Willy Tarreau Date: Wed, 9 Mar 2022 16:23:10 +0000 (+0100) Subject: MINOR: rules: record the last http/tcp rule that gave a final verdict X-Git-Tag: v2.6-dev3~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c6dae869ca8baa9b6be0bd1012749eed268988dc;p=thirdparty%2Fhaproxy.git MINOR: rules: record the last http/tcp rule that gave a final verdict When a tcp-{request,response} content or http-request/http-response rule delivers a final verdict (deny, accept, redirect etc), the last evaluated one will now be recorded in the stream. The purpose is to permit to log the last one that performed a final action. For now the log is not produced. --- diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index f75a181406..3fd5090fbe 100644 --- a/include/haproxy/stream-t.h +++ b/include/haproxy/stream-t.h @@ -182,6 +182,8 @@ struct stream { struct list *current_rule_list; /* this is used to store the current executed rule list. */ void *current_rule; /* this is used to store the current rule to be resumed. */ int rules_exp; /* expiration date for current rules execution */ + const char *last_rule_file; /* last evaluated final rule's file (def: NULL) */ + int last_rule_line; /* last evaluated final rule's line (def: 0) */ unsigned int stream_epoch; /* copy of stream_epoch when the stream was created */ struct hlua *hlua; /* lua runtime context */ diff --git a/src/http_ana.c b/src/http_ana.c index 83711482f1..84ddbf36b1 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -2744,6 +2744,8 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis break; case ACT_RET_STOP: rule_ret = HTTP_RULE_RES_STOP; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_YIELD: s->current_rule = rule; @@ -2751,20 +2753,30 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis goto end; case ACT_RET_ERR: rule_ret = HTTP_RULE_RES_ERROR; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_DONE: rule_ret = HTTP_RULE_RES_DONE; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_DENY: if (txn->status == -1) txn->status = 403; rule_ret = HTTP_RULE_RES_DENY; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_ABRT: rule_ret = HTTP_RULE_RES_ABRT; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_INV: rule_ret = HTTP_RULE_RES_BADREQ; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; } continue; /* eval the next rule */ @@ -2774,12 +2786,16 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis switch (rule->action) { case ACT_ACTION_ALLOW: rule_ret = HTTP_RULE_RES_STOP; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_ACTION_DENY: txn->status = rule->arg.http_reply->status; txn->http_reply = rule->arg.http_reply; rule_ret = HTTP_RULE_RES_DENY; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_HTTP_REQ_TARPIT: @@ -2787,6 +2803,8 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis txn->status = rule->arg.http_reply->status; txn->http_reply = rule->arg.http_reply; rule_ret = HTTP_RULE_RES_DENY; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_HTTP_REDIR: { @@ -2796,6 +2814,8 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis break; rule_ret = ret ? HTTP_RULE_RES_ABRT : HTTP_RULE_RES_ERROR; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; } @@ -2887,6 +2907,8 @@ resume_execution: break; case ACT_RET_STOP: rule_ret = HTTP_RULE_RES_STOP; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_YIELD: s->current_rule = rule; @@ -2894,20 +2916,30 @@ resume_execution: goto end; case ACT_RET_ERR: rule_ret = HTTP_RULE_RES_ERROR; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_DONE: rule_ret = HTTP_RULE_RES_DONE; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_DENY: if (txn->status == -1) txn->status = 502; rule_ret = HTTP_RULE_RES_DENY; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_ABRT: rule_ret = HTTP_RULE_RES_ABRT; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_INV: rule_ret = HTTP_RULE_RES_BADREQ; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; } continue; /* eval the next rule */ @@ -2917,12 +2949,16 @@ resume_execution: switch (rule->action) { case ACT_ACTION_ALLOW: rule_ret = HTTP_RULE_RES_STOP; /* "allow" rules are OK */ + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_ACTION_DENY: txn->status = rule->arg.http_reply->status; txn->http_reply = rule->arg.http_reply; rule_ret = HTTP_RULE_RES_DENY; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_HTTP_REDIR: { @@ -2932,6 +2968,8 @@ resume_execution: break; rule_ret = ret ? HTTP_RULE_RES_ABRT : HTTP_RULE_RES_ERROR; + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; } /* other flags exists, but normally, they never be matched. */ diff --git a/src/stream.c b/src/stream.c index cdd1498c92..382dd86d55 100644 --- a/src/stream.c +++ b/src/stream.c @@ -385,6 +385,8 @@ struct stream *stream_new(struct session *sess, struct conn_stream *cs, struct b s->current_rule_list = NULL; s->current_rule = NULL; s->rules_exp = TICK_ETERNITY; + s->last_rule_file = NULL; + s->last_rule_line = 0; /* Copy SC counters for the stream. We don't touch refcounts because * any reference we have is inherited from the session. Since the stream diff --git a/src/tcp_rules.c b/src/tcp_rules.c index 886dd9ed43..82c1c5910f 100644 --- a/src/tcp_rules.c +++ b/src/tcp_rules.c @@ -163,6 +163,8 @@ resume_execution: break; case ACT_RET_STOP: case ACT_RET_DONE: + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_YIELD: s->current_rule = rule; @@ -174,12 +176,20 @@ resume_execution: } goto missing_data; case ACT_RET_DENY: + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto deny; case ACT_RET_ABRT: + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto abort; case ACT_RET_ERR: + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto internal; case ACT_RET_INV: + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto invalid; } continue; /* eval the next rule */ @@ -187,9 +197,13 @@ resume_execution: /* If not action function defined, check for known actions */ if (rule->action == ACT_ACTION_ALLOW) { + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; } else if (rule->action == ACT_ACTION_DENY) { + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto deny; } } @@ -331,6 +345,8 @@ resume_execution: break; case ACT_RET_STOP: case ACT_RET_DONE: + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; case ACT_RET_YIELD: s->current_rule = rule; @@ -343,12 +359,20 @@ resume_execution: channel_dont_close(rep); goto missing_data; case ACT_RET_DENY: + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto deny; case ACT_RET_ABRT: + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto abort; case ACT_RET_ERR: + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto internal; case ACT_RET_INV: + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto invalid; } continue; /* eval the next rule */ @@ -356,9 +380,13 @@ resume_execution: /* If not action function defined, check for known actions */ if (rule->action == ACT_ACTION_ALLOW) { + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; } else if (rule->action == ACT_ACTION_DENY) { + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto deny; } else if (rule->action == ACT_TCP_CLOSE) { @@ -366,6 +394,8 @@ resume_execution: si_must_kill_conn(chn_prod(rep)); si_shutr(chn_prod(rep)); si_shutw(chn_prod(rep)); + s->last_rule_file = rule->conf.file; + s->last_rule_line = rule->conf.line; goto end; } }