Skip to content

Commit 466db34

Browse files
committed
MINOR: quic: implement reject quic-initial action
Implement 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 support CONNECTION_CLOSE emission on reject, 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.
1 parent 55758be commit 466db34

File tree

4 files changed

+45
-13
lines changed

4 files changed

+45
-13
lines changed

doc/configuration.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11009,6 +11009,7 @@ quic-initial <action> [ { if | unless } <condition> ]
1100911009
minimal list of actions is supported :
1101011010
- accept
1101111011
- dgram-drop
11012+
- reject
1101211013

1101311014

1101411015
rate-limit sessions <rate>
@@ -14374,7 +14375,7 @@ expect-netscaler-cip - X - - - - -
1437414375
expect-proxy layer4 - X - - - - - -
1437514376
normalize-uri - - - - - X - -
1437614377
redirect - - - - - X X -
14377-
reject - X X X X X - -
14378+
reject X X X X X X - -
1437814379
replace-header - - - - - X X X
1437914380
replace-path - - - - - X - -
1438014381
replace-pathq - - - - - X - -
@@ -14932,7 +14933,7 @@ redirect <rule>
1493214933

1493314934
reject
1493414935
Usable in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft
14935-
- | X | X | X | X | X | - | -
14936+
X | X | X | X | X | X | - | -
1493614937

1493714938
This stops the evaluation of the rules and immediately closes the connection
1493814939
without sending any response. For HTTP rules, it acts similarly to the
@@ -14955,6 +14956,10 @@ reject
1495514956
information from leaking, typically after inspecting contents in conjunction
1495614957
with the "wait-for-body" action.
1495714958

14959+
This action can also be used in "quic-initial" rules. The newly opened QUIC
14960+
connection is immediately closed and the client receives a CONNECTION_REFUSED
14961+
error code prior to the SSL handshake execution.
14962+
1495814963

1495914964
replace-header <name> <match-regex> <replace-fmt>
1496014965
Usable in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft

include/haproxy/quic_sock-t.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ struct quic_receiver_buf {
2626
struct mt_list rxbuf_el; /* list element into receiver.rxbuf_list. */
2727
};
2828

29+
#define QUIC_DGRAM_FL_REJECT 0x00000001
30+
2931
/* QUIC datagram */
3032
struct quic_dgram {
3133
enum obj_type obj_type;
@@ -40,6 +42,8 @@ struct quic_dgram {
4042

4143
struct list recv_list; /* element pointing to quic_receiver_buf <dgram_list>. */
4244
struct mt_list handler_list; /* element pointing to quic_dghdlr <dgrams>. */
45+
46+
int flags; /* QUIC_DGRAM_FL_* values */
4347
};
4448

4549
/* QUIC datagram handler */

src/quic_rules.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,23 @@ static enum act_parse_ret parse_dgram_drop(const char **args, int *orig_arg,
9292
return ACT_RET_PRS_OK;
9393
}
9494

95+
static enum act_return quic_init_action_reject(struct act_rule *rule, struct proxy *px,
96+
struct session *sess, struct stream *s, int flags)
97+
{
98+
struct quic_dgram *dgram = __objt_dgram(sess->origin);
99+
dgram->flags |= QUIC_DGRAM_FL_REJECT;
100+
return ACT_RET_DONE;
101+
}
102+
103+
static enum act_parse_ret parse_reject(const char **args, int *orig_arg,
104+
struct proxy *px,
105+
struct act_rule *rule, char **err)
106+
{
107+
rule->action = ACT_CUSTOM;
108+
rule->action_ptr = quic_init_action_reject;
109+
return ACT_RET_PRS_OK;
110+
}
111+
95112
/* List head of all known action keywords for "quic-initial" */
96113
struct action_kw_list quic_init_actions_list = {
97114
.list = LIST_HEAD_INIT(quic_init_actions_list.list)
@@ -111,6 +128,7 @@ struct action_kw *action_quic_init_custom(const char *kw)
111128
static struct action_kw_list quic_init_actions = { ILH, {
112129
{ "accept", parse_accept, 0 },
113130
{ "dgram-drop", parse_dgram_drop, 0 },
131+
{ "reject", parse_reject, 0 },
114132
{ /* END */ },
115133
}
116134
};

src/quic_rx.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,20 +1612,22 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
16121612
goto err;
16131613
}
16141614

1615-
if (!pkt->token_len &&
1616-
((l->bind_conf->options & BC_O_QUIC_FORCE_RETRY) ||
1617-
HA_ATOMIC_LOAD(&prx_counters->half_open_conn) >= global.tune.quic_retry_threshold)) {
1615+
/* No need to emit Retry if connection is refused. */
1616+
if (!pkt->token_len && !(dgram->flags & QUIC_DGRAM_FL_REJECT)) {
1617+
if ((l->bind_conf->options & BC_O_QUIC_FORCE_RETRY) ||
1618+
HA_ATOMIC_LOAD(&prx_counters->half_open_conn) >= global.tune.quic_retry_threshold) {
1619+
1620+
TRACE_PROTO("Initial without token, sending retry",
1621+
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
1622+
if (send_retry(l->rx.fd, &dgram->saddr, pkt, pkt->version)) {
1623+
TRACE_ERROR("Error during Retry generation",
1624+
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
1625+
goto out;
1626+
}
16181627

1619-
TRACE_PROTO("Initial without token, sending retry",
1620-
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
1621-
if (send_retry(l->rx.fd, &dgram->saddr, pkt, pkt->version)) {
1622-
TRACE_ERROR("Error during Retry generation",
1623-
QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
1628+
HA_ATOMIC_INC(&prx_counters->retry_sent);
16241629
goto out;
16251630
}
1626-
1627-
HA_ATOMIC_INC(&prx_counters->retry_sent);
1628-
goto out;
16291631
}
16301632

16311633
/* RFC 9000 7.2. Negotiating Connection IDs:
@@ -1679,6 +1681,9 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
16791681
eb64_insert(qc->cids, &conn_id->seq_num);
16801682
/* Initialize the next CID sequence number to be used for this connection. */
16811683
qc->next_cid_seq_num = 1;
1684+
1685+
if (dgram->flags & QUIC_DGRAM_FL_REJECT)
1686+
quic_set_connection_close(qc, quic_err_transport(QC_ERR_CONNECTION_REFUSED));
16821687
}
16831688

16841689
if (*new_tid != -1)

0 commit comments

Comments
 (0)