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 f75a181..3fd5090 100644
--- a/include/haproxy/stream-t.h
+++ b/include/haproxy/stream-t.h
@@ -182,6 +182,8 @@
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 8371148..84ddbf3 100644
--- a/src/http_ana.c
+++ b/src/http_ana.c
@@ -2744,6 +2744,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 cdd1498..382dd86 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -385,6 +385,8 @@
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 886dd9e..82c1c59 100644
--- a/src/tcp_rules.c
+++ b/src/tcp_rules.c
@@ -163,6 +163,8 @@
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 @@
}
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 @@
/* 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 @@
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 @@
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 @@
/* 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 @@
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;
}
}