mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
MEDIUM: quic: adjust address validation
When a new QUIC connection is created, server considers peer address as not yet validated. The server must limit its sending up to 3 times the content already received. This is a defensive measure to avoid flooding a remote host victim of address spoofing. This patch adjust the condition to consider the peer address as validated. Two conditions are now considered : * successful handling of a received HANDSHAKE packet. This was already done before although implemented in a different way. * validation of a Retry token. This was not considered prior this patch despite RFC recommandation. This patch also adjusts how a connection is internally labelled as using a validated peer address. Before, above conditions were checked via quic_peer_validated_addr(). Now, a flag QUIC_FL_CONN_PEER_VALIDATED_ADDR is set to labelled this. It already existed prior this patch but was only used for quic_cc_conn. This should now be more explicit.
This commit is contained in:
parent
3a051ca0c8
commit
d38bb7f8a7
@ -247,8 +247,7 @@ struct quic_connection_id {
|
||||
uint tid; /* Attached Thread ID for the connection. */
|
||||
};
|
||||
|
||||
/* Flag the packet number space as having received a packet */
|
||||
#define QUIC_FL_PKTNS_PKT_RECEIVED (1UL << 0)
|
||||
/* unused: 0x01 */
|
||||
/* Flag the packet number space as requiring an ACK frame to be sent. */
|
||||
#define QUIC_FL_PKTNS_ACK_REQUIRED (1UL << 1)
|
||||
/* Flag the packet number space as needing probing */
|
||||
@ -394,7 +393,7 @@ struct quic_conn_cntrs {
|
||||
#define QUIC_FL_CONN_IO_TO_REQUEUE (1U << 14) /* IO handler must be requeued on new thread after connection migration */
|
||||
#define QUIC_FL_CONN_IPKTNS_DCD (1U << 15) /* Initial packet number space discarded */
|
||||
#define QUIC_FL_CONN_HPKTNS_DCD (1U << 16) /* Handshake packet number space discarded */
|
||||
#define QUIC_FL_CONN_PEER_VALIDATED_ADDR (1U << 17) /* Connection with peer validated address */
|
||||
#define QUIC_FL_CONN_PEER_VALIDATED_ADDR (1U << 17) /* Peer address is considered as validated for this connection. */
|
||||
#define QUIC_FL_CONN_TO_KILL (1U << 24) /* Unusable connection, to be killed */
|
||||
#define QUIC_FL_CONN_TX_TP_RECEIVED (1U << 25) /* Peer transport parameters have been received (used for the transmitting part) */
|
||||
#define QUIC_FL_CONN_FINALIZED (1U << 26) /* QUIC connection finalized (functional, ready to send/receive) */
|
||||
|
@ -151,9 +151,7 @@ int quic_peer_validated_addr(struct quic_conn *qc)
|
||||
if (!qc_is_listener(qc))
|
||||
return 1;
|
||||
|
||||
if ((qc->hpktns && (qc->hpktns->flags & QUIC_FL_PKTNS_PKT_RECEIVED)) ||
|
||||
(qc->apktns && (qc->apktns->flags & QUIC_FL_PKTNS_PKT_RECEIVED)) ||
|
||||
qc->state >= QUIC_HS_ST_COMPLETE)
|
||||
if (qc->flags & QUIC_FL_CONN_PEER_VALIDATED_ADDR)
|
||||
return 1;
|
||||
|
||||
BUG_ON(qc->bytes.prep > 3 * qc->bytes.rx);
|
||||
@ -845,8 +843,6 @@ static struct quic_cc_conn *qc_new_cc_conn(struct quic_conn *qc)
|
||||
if (qc->fd >= 0)
|
||||
fdtab[cc_qc->fd].owner = cc_qc;
|
||||
cc_qc->flags = qc->flags;
|
||||
if (quic_peer_validated_addr(qc))
|
||||
cc_qc->flags |= QUIC_FL_CONN_PEER_VALIDATED_ADDR;
|
||||
cc_qc->err = qc->err;
|
||||
|
||||
cc_qc->nb_pkt_for_cc = qc->nb_pkt_for_cc;
|
||||
@ -1383,6 +1379,15 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
LIST_APPEND(&th_ctx->quic_conns, &qc->el_th_ctx);
|
||||
qc->qc_epoch = HA_ATOMIC_LOAD(&qc_epoch);
|
||||
|
||||
/* If connection is instantiated due to an INITIAL packet with an
|
||||
* already checked token, consider the peer address as validated.
|
||||
*/
|
||||
if (token_odcid->len) {
|
||||
TRACE_STATE("validate peer address due to initial token",
|
||||
QUIC_EV_CONN_INIT, qc);
|
||||
qc->flags |= QUIC_FL_CONN_PEER_VALIDATED_ADDR;
|
||||
}
|
||||
|
||||
TRACE_LEAVE(QUIC_EV_CONN_INIT, qc);
|
||||
|
||||
return qc;
|
||||
|
@ -1158,9 +1158,6 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
|
||||
}
|
||||
}
|
||||
|
||||
/* Flag this packet number space as having received a packet. */
|
||||
qel->pktns->flags |= QUIC_FL_PKTNS_PKT_RECEIVED;
|
||||
|
||||
if (fast_retrans && qc->iel && qc->hel) {
|
||||
struct quic_enc_level *iqel = qc->iel;
|
||||
struct quic_enc_level *hqel = qc->hel;
|
||||
@ -1381,6 +1378,19 @@ int qc_treat_rx_pkts(struct quic_conn *qc)
|
||||
else {
|
||||
struct quic_arng ar = { .first = pkt->pn, .last = pkt->pn };
|
||||
|
||||
/* RFC 9000 8.1. Address Validation during Connection Establishment
|
||||
*
|
||||
* Connection establishment implicitly provides address validation for
|
||||
* both endpoints. In particular, receipt of a packet protected with
|
||||
* Handshake keys confirms that the peer successfully processed an
|
||||
* Initial packet.
|
||||
*/
|
||||
if (qel == qc->hel) {
|
||||
TRACE_STATE("validate peer address on handshake packet",
|
||||
QUIC_EV_CONN_RXPKT, qc, pkt);
|
||||
qc->flags |= QUIC_FL_CONN_PEER_VALIDATED_ADDR;
|
||||
}
|
||||
|
||||
/* Update the list of ranges to acknowledge. */
|
||||
if (quic_update_ack_ranges_list(qc, &qel->pktns->rx.arngs, &ar)) {
|
||||
if (pkt->flags & QUIC_FL_RX_PACKET_ACK_ELICITING) {
|
||||
|
Loading…
Reference in New Issue
Block a user