mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
MINOR: quic: implement reject quic-initial action
Define a new quic-initial action named "reject". Contrary to dgram-drop, the client is notified of the rejection by a CONNECTION_CLOSE with CONNECTION_REFUSED error code. To be able to emit the necessary CONNECTION_CLOSE frame, quic_conn is instantiated, contrary to dgram-drop action. quic_set_connection_close() is called immediatly after qc_new_conn() which prevents the handshake startup.
This commit is contained in:
parent
f91be2657e
commit
69d7e9f3b7
@ -11009,6 +11009,7 @@ quic-initial <action> [ { if | unless } <condition> ]
|
|||||||
minimal list of actions is supported :
|
minimal list of actions is supported :
|
||||||
- accept
|
- accept
|
||||||
- dgram-drop
|
- dgram-drop
|
||||||
|
- reject
|
||||||
|
|
||||||
|
|
||||||
rate-limit sessions <rate>
|
rate-limit sessions <rate>
|
||||||
@ -14374,7 +14375,7 @@ expect-netscaler-cip - X - - - - -
|
|||||||
expect-proxy layer4 - X - - - - - -
|
expect-proxy layer4 - X - - - - - -
|
||||||
normalize-uri - - - - - X - -
|
normalize-uri - - - - - X - -
|
||||||
redirect - - - - - X X -
|
redirect - - - - - X X -
|
||||||
reject - X X X X X - -
|
reject X X X X X X - -
|
||||||
replace-header - - - - - X X X
|
replace-header - - - - - X X X
|
||||||
replace-path - - - - - X - -
|
replace-path - - - - - X - -
|
||||||
replace-pathq - - - - - X - -
|
replace-pathq - - - - - X - -
|
||||||
@ -14932,7 +14933,7 @@ redirect <rule>
|
|||||||
|
|
||||||
reject
|
reject
|
||||||
Usable in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft
|
Usable in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft
|
||||||
- | X | X | X | X | X | - | -
|
X | X | X | X | X | X | - | -
|
||||||
|
|
||||||
This stops the evaluation of the rules and immediately closes the connection
|
This stops the evaluation of the rules and immediately closes the connection
|
||||||
without sending any response. For HTTP rules, it acts similarly to the
|
without sending any response. For HTTP rules, it acts similarly to the
|
||||||
@ -14955,6 +14956,10 @@ reject
|
|||||||
information from leaking, typically after inspecting contents in conjunction
|
information from leaking, typically after inspecting contents in conjunction
|
||||||
with the "wait-for-body" action.
|
with the "wait-for-body" action.
|
||||||
|
|
||||||
|
This action can also be used in "quic-initial" rules. The newly opened QUIC
|
||||||
|
connection is immediately closed without any SSL handshake processing and the
|
||||||
|
client is notified via a CONNECTION_REFUSED error code.
|
||||||
|
|
||||||
|
|
||||||
replace-header <name> <match-regex> <replace-fmt>
|
replace-header <name> <match-regex> <replace-fmt>
|
||||||
Usable in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft
|
Usable in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft
|
||||||
|
@ -26,6 +26,8 @@ struct quic_receiver_buf {
|
|||||||
struct mt_list rxbuf_el; /* list element into receiver.rxbuf_list. */
|
struct mt_list rxbuf_el; /* list element into receiver.rxbuf_list. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define QUIC_DGRAM_FL_REJECT 0x00000001
|
||||||
|
|
||||||
/* QUIC datagram */
|
/* QUIC datagram */
|
||||||
struct quic_dgram {
|
struct quic_dgram {
|
||||||
enum obj_type obj_type;
|
enum obj_type obj_type;
|
||||||
@ -40,6 +42,8 @@ struct quic_dgram {
|
|||||||
|
|
||||||
struct list recv_list; /* element pointing to quic_receiver_buf <dgram_list>. */
|
struct list recv_list; /* element pointing to quic_receiver_buf <dgram_list>. */
|
||||||
struct mt_list handler_list; /* element pointing to quic_dghdlr <dgrams>. */
|
struct mt_list handler_list; /* element pointing to quic_dghdlr <dgrams>. */
|
||||||
|
|
||||||
|
int flags; /* QUIC_DGRAM_FL_* values */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* QUIC datagram handler */
|
/* QUIC datagram handler */
|
||||||
|
@ -92,6 +92,23 @@ static enum act_parse_ret parse_dgram_drop(const char **args, int *orig_arg,
|
|||||||
return ACT_RET_PRS_OK;
|
return ACT_RET_PRS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/* List head of all known action keywords for "quic-initial" */
|
/* List head of all known action keywords for "quic-initial" */
|
||||||
struct action_kw_list quic_init_actions_list = {
|
struct action_kw_list quic_init_actions_list = {
|
||||||
.list = LIST_HEAD_INIT(quic_init_actions_list.list)
|
.list = LIST_HEAD_INIT(quic_init_actions_list.list)
|
||||||
@ -111,6 +128,7 @@ struct action_kw *action_quic_init_custom(const char *kw)
|
|||||||
static struct action_kw_list quic_init_actions = { ILH, {
|
static struct action_kw_list quic_init_actions = { ILH, {
|
||||||
{ "accept", parse_accept, 0 },
|
{ "accept", parse_accept, 0 },
|
||||||
{ "dgram-drop", parse_dgram_drop, 0 },
|
{ "dgram-drop", parse_dgram_drop, 0 },
|
||||||
|
{ "reject", parse_reject, 0 },
|
||||||
{ /* END */ },
|
{ /* END */ },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1612,9 +1612,10 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pkt->token_len &&
|
/* No need to emit Retry if connection is refused. */
|
||||||
((l->bind_conf->options & BC_O_QUIC_FORCE_RETRY) ||
|
if (!pkt->token_len && !(dgram->flags & QUIC_DGRAM_FL_REJECT)) {
|
||||||
HA_ATOMIC_LOAD(&prx_counters->half_open_conn) >= global.tune.quic_retry_threshold)) {
|
if ((l->bind_conf->options & BC_O_QUIC_FORCE_RETRY) ||
|
||||||
|
HA_ATOMIC_LOAD(&prx_counters->half_open_conn) >= global.tune.quic_retry_threshold) {
|
||||||
|
|
||||||
TRACE_PROTO("Initial without token, sending retry",
|
TRACE_PROTO("Initial without token, sending retry",
|
||||||
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
|
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
|
||||||
@ -1627,6 +1628,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
|
|||||||
HA_ATOMIC_INC(&prx_counters->retry_sent);
|
HA_ATOMIC_INC(&prx_counters->retry_sent);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* RFC 9000 7.2. Negotiating Connection IDs:
|
/* RFC 9000 7.2. Negotiating Connection IDs:
|
||||||
* When an Initial packet is sent by a client that has not previously
|
* When an Initial packet is sent by a client that has not previously
|
||||||
@ -1679,6 +1681,9 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
|
|||||||
eb64_insert(qc->cids, &conn_id->seq_num);
|
eb64_insert(qc->cids, &conn_id->seq_num);
|
||||||
/* Initialize the next CID sequence number to be used for this connection. */
|
/* Initialize the next CID sequence number to be used for this connection. */
|
||||||
qc->next_cid_seq_num = 1;
|
qc->next_cid_seq_num = 1;
|
||||||
|
|
||||||
|
if (dgram->flags & QUIC_DGRAM_FL_REJECT)
|
||||||
|
quic_set_connection_close(qc, quic_err_transport(QC_ERR_CONNECTION_REFUSED));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*new_tid != -1)
|
if (*new_tid != -1)
|
||||||
|
Loading…
Reference in New Issue
Block a user