2024-07-18 12:25:43 -04:00
|
|
|
#include <haproxy/quic_rules.h>
|
|
|
|
|
|
|
|
|
|
#include <haproxy/acl.h>
|
|
|
|
|
#include <haproxy/action.h>
|
|
|
|
|
#include <haproxy/list.h>
|
|
|
|
|
#include <haproxy/listener.h>
|
MINOR: action: add do-log action
Thanks to the two previous commits, we can now expose the do-log action
on all available action contexts, including the new quic-init context.
Each context is responsible for exposing the do-log action by registering
the relevant log steps, saving the idendifier, and then store it in the
rule's context so that do_log_action() automatically uses it to produce
the log during runtime.
To use the feature, it is simply needed to use "do-log" (without argument)
on an action directive, example:
tcp-request connection do-log
As mentioned before, each context where the action is exposed has its own
log step identifier. Currently known identifiers are:
quic-initial: quic-init
tcp-request connection: tcp-req-conn
tcp-request session: tcp-req-sess
tcp-request content: tcp-req-cont
tcp-response content: tcp-res-cont
http-request: http-req
http-response: http-res
http-after-response: http-after-res
Thus, these "additional" logging steps can be used as-is under log-profile
section (after "on" keyword). However, although the parser will accept
them, it makes no sense to use them with the "log-steps" proxy keyword,
since the only path for these origins to trigger a log generation is
through the explicit use of "do-log" action.
This need was described in GH #401, it should help to conditionally
trigger logs using ACL at specific key points.. and may either be used
alone or combined with "log-steps" to add additional log "trackers" during
transaction handling.
Documentation was updated and some examples were added.
2024-09-20 03:34:13 -04:00
|
|
|
#include <haproxy/log.h>
|
2024-07-19 10:04:22 -04:00
|
|
|
#include <haproxy/obj_type.h>
|
2024-07-18 12:25:43 -04:00
|
|
|
#include <haproxy/proxy-t.h>
|
2024-07-19 10:04:22 -04:00
|
|
|
#include <haproxy/quic_sock-t.h>
|
2024-07-18 12:25:43 -04:00
|
|
|
#include <haproxy/sample-t.h>
|
2024-07-19 10:05:15 -04:00
|
|
|
#include <haproxy/session-t.h>
|
2024-07-18 12:25:43 -04:00
|
|
|
|
2024-07-19 10:04:22 -04:00
|
|
|
/* Execute registered quic-initial rules on proxy owning <li> listener after
|
|
|
|
|
* <dgram> reception.
|
|
|
|
|
*/
|
|
|
|
|
int quic_init_exec_rules(struct listener *li, struct quic_dgram *dgram)
|
2024-07-18 12:25:43 -04:00
|
|
|
{
|
2024-07-19 10:05:15 -04:00
|
|
|
static THREAD_LOCAL struct session rule_sess;
|
2024-07-18 12:25:43 -04:00
|
|
|
struct act_rule *rule;
|
|
|
|
|
enum acl_test_res ret;
|
|
|
|
|
struct proxy *px;
|
|
|
|
|
int result = 1;
|
|
|
|
|
|
|
|
|
|
px = li->bind_conf->frontend;
|
|
|
|
|
|
2024-07-19 10:05:15 -04:00
|
|
|
/* Initialize session elements specific to the current datagram. All
|
|
|
|
|
* others members are set to 0 thanks to static storage class.
|
|
|
|
|
*/
|
|
|
|
|
rule_sess.fe = px;
|
|
|
|
|
rule_sess.listener = li;
|
2024-07-19 10:04:22 -04:00
|
|
|
rule_sess.src = &dgram->saddr;
|
|
|
|
|
rule_sess.dst = &dgram->daddr;
|
|
|
|
|
rule_sess.origin = &dgram->obj_type;
|
2024-07-19 10:05:15 -04:00
|
|
|
|
2024-07-18 12:25:43 -04:00
|
|
|
list_for_each_entry(rule, &px->quic_init_rules, list) {
|
|
|
|
|
ret = ACL_TEST_PASS;
|
|
|
|
|
|
|
|
|
|
if (rule->cond) {
|
2024-07-19 10:05:15 -04:00
|
|
|
ret = acl_exec_cond(rule->cond, px, &rule_sess, NULL, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
|
2024-07-18 12:25:43 -04:00
|
|
|
ret = acl_pass(ret);
|
|
|
|
|
if (rule->cond->pol == ACL_COND_UNLESS)
|
|
|
|
|
ret = !ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ret) {
|
|
|
|
|
if (rule->action_ptr) {
|
2024-07-19 10:05:15 -04:00
|
|
|
switch (rule->action_ptr(rule, px, &rule_sess, NULL, 0)) {
|
2024-07-18 12:25:43 -04:00
|
|
|
case ACT_RET_CONT:
|
|
|
|
|
break;
|
|
|
|
|
case ACT_RET_DONE:
|
|
|
|
|
case ACT_RET_STOP:
|
|
|
|
|
goto end;
|
|
|
|
|
case ACT_RET_ABRT:
|
|
|
|
|
case ACT_RET_DENY:
|
|
|
|
|
case ACT_RET_ERR:
|
|
|
|
|
case ACT_RET_INV:
|
|
|
|
|
result = 0;
|
|
|
|
|
goto end;
|
|
|
|
|
default:
|
|
|
|
|
ABORT_NOW("not implemented");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (rule->action == ACT_ACTION_ALLOW) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
else if (rule->action == ACT_ACTION_DENY) {
|
|
|
|
|
result = 0;
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
end:
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static enum act_parse_ret parse_accept(const char **args, int *orig_arg,
|
|
|
|
|
struct proxy *px,
|
|
|
|
|
struct act_rule *rule, char **err)
|
|
|
|
|
{
|
|
|
|
|
rule->action = ACT_ACTION_ALLOW;
|
|
|
|
|
rule->flags |= ACT_FLAG_FINAL;
|
|
|
|
|
return ACT_RET_PRS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static enum act_parse_ret parse_dgram_drop(const char **args, int *orig_arg,
|
|
|
|
|
struct proxy *px,
|
|
|
|
|
struct act_rule *rule, char **err)
|
|
|
|
|
{
|
|
|
|
|
rule->action = ACT_ACTION_DENY;
|
|
|
|
|
rule->flags |= ACT_FLAG_FINAL;
|
|
|
|
|
return ACT_RET_PRS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
MINOR: action: add do-log action
Thanks to the two previous commits, we can now expose the do-log action
on all available action contexts, including the new quic-init context.
Each context is responsible for exposing the do-log action by registering
the relevant log steps, saving the idendifier, and then store it in the
rule's context so that do_log_action() automatically uses it to produce
the log during runtime.
To use the feature, it is simply needed to use "do-log" (without argument)
on an action directive, example:
tcp-request connection do-log
As mentioned before, each context where the action is exposed has its own
log step identifier. Currently known identifiers are:
quic-initial: quic-init
tcp-request connection: tcp-req-conn
tcp-request session: tcp-req-sess
tcp-request content: tcp-req-cont
tcp-response content: tcp-res-cont
http-request: http-req
http-response: http-res
http-after-response: http-after-res
Thus, these "additional" logging steps can be used as-is under log-profile
section (after "on" keyword). However, although the parser will accept
them, it makes no sense to use them with the "log-steps" proxy keyword,
since the only path for these origins to trigger a log generation is
through the explicit use of "do-log" action.
This need was described in GH #401, it should help to conditionally
trigger logs using ACL at specific key points.. and may either be used
alone or combined with "log-steps" to add additional log "trackers" during
transaction handling.
Documentation was updated and some examples were added.
2024-09-20 03:34:13 -04:00
|
|
|
static enum log_orig_id do_log_quic_init;
|
|
|
|
|
|
|
|
|
|
static void init_do_log(void)
|
|
|
|
|
{
|
|
|
|
|
do_log_quic_init = log_orig_register("quic-init");
|
|
|
|
|
BUG_ON(do_log_quic_init == LOG_ORIG_UNSPEC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
INITCALL0(STG_PREPARE, init_do_log);
|
|
|
|
|
|
|
|
|
|
static enum act_parse_ret parse_do_log(const char **args, int *orig_arg,
|
|
|
|
|
struct proxy *px,
|
|
|
|
|
struct act_rule *rule, char **err)
|
|
|
|
|
{
|
|
|
|
|
return do_log_parse_act(do_log_quic_init, args, orig_arg, px, rule, err);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-19 11:39:04 -04:00
|
|
|
static enum act_return quic_init_action_reject(struct act_rule *rule, struct proxy *px,
|
|
|
|
|
struct session *sess, struct stream *s, int flags)
|
|
|
|
|
{
|
|
|
|
|
struct quic_dgram *dgram = __objt_dgram(sess->origin);
|
|
|
|
|
dgram->flags |= QUIC_DGRAM_FL_REJECT;
|
|
|
|
|
return ACT_RET_DONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-22 07:29:04 -04:00
|
|
|
static enum act_return quic_init_action_send_retry(struct act_rule *rule, struct proxy *px,
|
|
|
|
|
struct session *sess, struct stream *s, int flags)
|
|
|
|
|
{
|
|
|
|
|
struct quic_dgram *dgram = __objt_dgram(sess->origin);
|
|
|
|
|
dgram->flags |= QUIC_DGRAM_FL_SEND_RETRY;
|
|
|
|
|
return ACT_RET_DONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-19 11:39:04 -04:00
|
|
|
static enum act_parse_ret parse_reject(const char **args, int *orig_arg,
|
|
|
|
|
struct proxy *px,
|
|
|
|
|
struct act_rule *rule, char **err)
|
|
|
|
|
{
|
|
|
|
|
rule->action = ACT_CUSTOM;
|
|
|
|
|
rule->action_ptr = quic_init_action_reject;
|
|
|
|
|
return ACT_RET_PRS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-22 07:29:04 -04:00
|
|
|
static enum act_parse_ret parse_send_retry(const char **args, int *orig_arg,
|
|
|
|
|
struct proxy *px,
|
|
|
|
|
struct act_rule *rule, char **err)
|
|
|
|
|
{
|
|
|
|
|
rule->action = ACT_CUSTOM;
|
|
|
|
|
rule->action_ptr = quic_init_action_send_retry;
|
|
|
|
|
return ACT_RET_PRS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-18 12:25:43 -04:00
|
|
|
/* List head of all known action keywords for "quic-initial" */
|
|
|
|
|
struct action_kw_list quic_init_actions_list = {
|
|
|
|
|
.list = LIST_HEAD_INIT(quic_init_actions_list.list)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void quic_init_actions_register(struct action_kw_list *kw_list)
|
|
|
|
|
{
|
|
|
|
|
LIST_APPEND(&quic_init_actions_list.list, &kw_list->list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the struct quic-initial action associated to a keyword. */
|
|
|
|
|
struct action_kw *action_quic_init_custom(const char *kw)
|
|
|
|
|
{
|
|
|
|
|
return action_lookup(&quic_init_actions_list.list, kw);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct action_kw_list quic_init_actions = { ILH, {
|
|
|
|
|
{ "accept", parse_accept, 0 },
|
|
|
|
|
{ "dgram-drop", parse_dgram_drop, 0 },
|
MINOR: action: add do-log action
Thanks to the two previous commits, we can now expose the do-log action
on all available action contexts, including the new quic-init context.
Each context is responsible for exposing the do-log action by registering
the relevant log steps, saving the idendifier, and then store it in the
rule's context so that do_log_action() automatically uses it to produce
the log during runtime.
To use the feature, it is simply needed to use "do-log" (without argument)
on an action directive, example:
tcp-request connection do-log
As mentioned before, each context where the action is exposed has its own
log step identifier. Currently known identifiers are:
quic-initial: quic-init
tcp-request connection: tcp-req-conn
tcp-request session: tcp-req-sess
tcp-request content: tcp-req-cont
tcp-response content: tcp-res-cont
http-request: http-req
http-response: http-res
http-after-response: http-after-res
Thus, these "additional" logging steps can be used as-is under log-profile
section (after "on" keyword). However, although the parser will accept
them, it makes no sense to use them with the "log-steps" proxy keyword,
since the only path for these origins to trigger a log generation is
through the explicit use of "do-log" action.
This need was described in GH #401, it should help to conditionally
trigger logs using ACL at specific key points.. and may either be used
alone or combined with "log-steps" to add additional log "trackers" during
transaction handling.
Documentation was updated and some examples were added.
2024-09-20 03:34:13 -04:00
|
|
|
{ "do-log", parse_do_log, 0 },
|
2024-07-19 11:39:04 -04:00
|
|
|
{ "reject", parse_reject, 0 },
|
2024-07-22 07:29:04 -04:00
|
|
|
{ "send-retry", parse_send_retry, 0 },
|
2024-07-18 12:25:43 -04:00
|
|
|
{ /* END */ },
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
INITCALL1(STG_REGISTER, quic_init_actions_register, &quic_init_actions);
|