]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: rules: record the last http/tcp rule that gave a final verdict
authorWilly Tarreau <w@1wt.eu>
Wed, 9 Mar 2022 16:23:10 +0000 (17:23 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 10 Mar 2022 10:51:34 +0000 (11:51 +0100)
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.

include/haproxy/stream-t.h
src/http_ana.c
src/stream.c
src/tcp_rules.c

index f75a181406a421ee5c3fb9c6df46130f64e7fc66..3fd5090fbe1ea61661b7417c0b91965bb31591e7 100644 (file)
@@ -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 */
index 83711482f177a7241b607df56a0b2492ed9ba1be..84ddbf36b14ebe47a03f073b52453dcfc18f9a14 100644 (file)
@@ -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. */
index cdd1498c9207a532cf8e4524abe986e023a7dc35..382dd86d55bb3715817d767456cfbbbc3156ed5e 100644 (file)
@@ -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
index 886dd9ed43cb4f17fb359f24928768d3818569f4..82c1c5910f75a294485989b982052bfc785c319e 100644 (file)
@@ -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;
                        }
                }