MINOR: quic: Move packet number space related functions

Move packet number space related functions from quic_conn.h to quic_tls.h.

Should be backported as far as 2.6 to ease future backports to come.
This commit is contained in:
Frédéric Lécaille 2023-06-13 08:17:23 +02:00 committed by Amaury Denoyelle
parent 411b6f73b7
commit ef39a74f4a
5 changed files with 140 additions and 137 deletions

View File

@ -322,19 +322,6 @@ struct quic_arng_node {
uint64_t last;
};
/* The maximum number of ack ranges to be built in ACK frames */
#define QUIC_MAX_ACK_RANGES 32
/* Structure to maintain a set of ACK ranges to be used to build ACK frames. */
struct quic_arngs {
/* ebtree of ACK ranges organized by their first value. */
struct eb_root root;
/* The number of ACK ranges is this tree */
size_t sz;
/* The number of bytes required to encode this ACK ranges lists. */
size_t enc_sz;
};
/* Flag the packet number space as having received a packet */
#define QUIC_FL_PKTNS_PKT_RECEIVED (1UL << 0)
/* Flag the packet number space as requiring an ACK frame to be sent. */
@ -349,39 +336,6 @@ struct quic_arngs {
/* The maximum number of dgrams which may be sent upon PTO expirations. */
#define QUIC_MAX_NB_PTO_DGRAMS 2
/* QUIC packet number space */
struct quic_pktns {
struct {
/* List of frames to send. */
struct list frms;
/* Next packet number to use for transmissions. */
int64_t next_pn;
/* The packet which has been sent. */
struct eb_root pkts;
/* The time the most recent ack-eliciting packer was sent. */
unsigned int time_of_last_eliciting;
/* The time this packet number space has experienced packet loss. */
unsigned int loss_time;
/* Boolean to denote if we must send probe packet. */
unsigned int pto_probe;
/* In flight bytes for this packet number space. */
size_t in_flight;
/* The acknowledgement delay of the packet with the largest packet number */
uint64_t ack_delay;
} tx;
struct {
/* Largest packet number */
int64_t largest_pn;
/* Largest acked sent packet. */
int64_t largest_acked_pn;
struct quic_arngs arngs;
unsigned int nb_aepkts_since_last_ack;
/* The time the packet with the largest packet number was received */
uint64_t largest_time_received;
} rx;
unsigned int flags;
};
/* QUIC datagram */
struct quic_dgram {
void *owner;

View File

@ -406,42 +406,6 @@ static inline uint64_t quic_compute_ack_delay_us(unsigned int time_received,
return ((now_ms - time_received) * 1000) >> conn->tx.params.ack_delay_exponent;
}
/* Initialize a QUIC packet number space.
* Never fails.
*/
static inline void quic_pktns_init(struct quic_pktns *pktns)
{
LIST_INIT(&pktns->tx.frms);
pktns->tx.next_pn = -1;
pktns->tx.pkts = EB_ROOT_UNIQUE;
pktns->tx.time_of_last_eliciting = 0;
pktns->tx.loss_time = TICK_ETERNITY;
pktns->tx.pto_probe = 0;
pktns->tx.in_flight = 0;
pktns->tx.ack_delay = 0;
pktns->rx.largest_pn = -1;
pktns->rx.largest_acked_pn = -1;
pktns->rx.arngs.root = EB_ROOT_UNIQUE;
pktns->rx.arngs.sz = 0;
pktns->rx.arngs.enc_sz = 0;
pktns->rx.nb_aepkts_since_last_ack = 0;
pktns->rx.largest_time_received = 0;
pktns->flags = 0;
}
/* Returns the current largest acknowledged packet number if exists, -1 if not */
static inline int64_t quic_pktns_get_largest_acked_pn(struct quic_pktns *pktns)
{
struct eb64_node *ar = eb64_last(&pktns->rx.arngs.root);
if (!ar)
return -1;
return eb64_entry(ar, struct quic_arng_node, first)->last;
}
/* The TX packets sent in the same datagram are linked to each others in
* the order they are built. This function detach a packet from its successor
* and predecessor in the same datagram.
@ -474,51 +438,6 @@ static inline void quic_tx_packet_refdec(struct quic_tx_packet *pkt)
}
}
static inline void quic_pktns_tx_pkts_release(struct quic_pktns *pktns, struct quic_conn *qc)
{
struct eb64_node *node;
node = eb64_first(&pktns->tx.pkts);
while (node) {
struct quic_tx_packet *pkt;
struct quic_frame *frm, *frmbak;
pkt = eb64_entry(node, struct quic_tx_packet, pn_node);
node = eb64_next(node);
if (pkt->flags & QUIC_FL_TX_PACKET_ACK_ELICITING)
qc->path->ifae_pkts--;
list_for_each_entry_safe(frm, frmbak, &pkt->frms, list) {
qc_frm_unref(frm, qc);
LIST_DEL_INIT(&frm->list);
quic_tx_packet_refdec(frm->pkt);
qc_frm_free(&frm);
}
eb64_delete(&pkt->pn_node);
quic_tx_packet_refdec(pkt);
}
}
/* Discard <pktns> packet number space attached to <qc> QUIC connection.
* Its loss information are reset. Deduce the outstanding bytes for this
* packet number space from the outstanding bytes for the path of this
* connection.
* Note that all the non acknowledged TX packets and their frames are freed.
* Always succeeds.
*/
static inline void quic_pktns_discard(struct quic_pktns *pktns,
struct quic_conn *qc)
{
qc->path->in_flight -= pktns->tx.in_flight;
qc->path->prep_in_flight -= pktns->tx.in_flight;
qc->path->loss.pto_count = 0;
pktns->tx.time_of_last_eliciting = 0;
pktns->tx.loss_time = TICK_ETERNITY;
pktns->tx.pto_probe = 0;
pktns->tx.in_flight = 0;
quic_pktns_tx_pkts_release(pktns, qc);
}
/* Initialize <p> QUIC network path depending on <ipv4> boolean
* which is true for an IPv4 path, if not false for an IPv6 path.
*/
@ -562,15 +481,6 @@ static inline size_t quic_path_prep_data(struct quic_path *path)
return path->cwnd - path->prep_in_flight;
}
/* Return 1 if <pktns> matches with the Application packet number space of
* <conn> connection which is common to the 0-RTT and 1-RTT encryption levels, 0
* if not (handshake packets).
*/
static inline int quic_application_pktns(struct quic_pktns *pktns, struct quic_conn *conn)
{
return pktns == &conn->pktns[QUIC_TLS_PKTNS_01RTT];
}
/* CRYPTO data buffer handling functions. */
static inline unsigned char *c_buf_getpos(struct quic_enc_level *qel, uint64_t offset)
{

View File

@ -26,6 +26,7 @@
#error "Must define USE_OPENSSL"
#endif
#include <import/eb64tree.h>
#include <haproxy/quic_conn-t.h>
#include <haproxy/quic_enc.h>
#include <haproxy/quic_frame-t.h>

View File

@ -120,6 +120,53 @@ extern const unsigned char initial_salt_draft_29[20];
extern const unsigned char initial_salt_v1[20];
extern const unsigned char initial_salt_v2[20];
/* The maximum number of ack ranges to be built in ACK frames */
#define QUIC_MAX_ACK_RANGES 32
/* Structure to maintain a set of ACK ranges to be used to build ACK frames. */
struct quic_arngs {
/* ebtree of ACK ranges organized by their first value. */
struct eb_root root;
/* The number of ACK ranges is this tree */
size_t sz;
/* The number of bytes required to encode this ACK ranges lists. */
size_t enc_sz;
};
/* QUIC packet number space */
struct quic_pktns {
struct list list;
struct {
/* List of frames to send. */
struct list frms;
/* Next packet number to use for transmissions. */
int64_t next_pn;
/* The packet which has been sent. */
struct eb_root pkts;
/* The time the most recent ack-eliciting packer was sent. */
unsigned int time_of_last_eliciting;
/* The time this packet number space has experienced packet loss. */
unsigned int loss_time;
/* Boolean to denote if we must send probe packet. */
unsigned int pto_probe;
/* In flight bytes for this packet number space. */
size_t in_flight;
/* The acknowledgement delay of the packet with the largest packet number */
uint64_t ack_delay;
} tx;
struct {
/* Largest packet number */
int64_t largest_pn;
/* Largest acked sent packet. */
int64_t largest_acked_pn;
struct quic_arngs arngs;
unsigned int nb_aepkts_since_last_ack;
/* The time the packet with the largest packet number was received */
uint64_t largest_time_received;
} rx;
unsigned int flags;
};
/* Key phase used for Key Update */
struct quic_tls_kp {
EVP_CIPHER_CTX *ctx;

View File

@ -25,7 +25,8 @@
#include <haproxy/dynbuf.h>
#include <haproxy/pool.h>
#include <haproxy/openssl-compat.h>
#include <haproxy/quic_conn-t.h>
#include <haproxy/quic_conn.h>
#include <haproxy/quic_frame.h>
#include <haproxy/quic_tls-t.h>
#include <haproxy/trace.h>
@ -322,6 +323,96 @@ static inline char quic_packet_type_enc_level_char(int packet_type)
}
}
/* Initialize a QUIC packet number space.
* Never fails.
*/
static inline void quic_pktns_init(struct quic_pktns *pktns)
{
LIST_INIT(&pktns->tx.frms);
pktns->tx.next_pn = -1;
pktns->tx.pkts = EB_ROOT_UNIQUE;
pktns->tx.time_of_last_eliciting = 0;
pktns->tx.loss_time = TICK_ETERNITY;
pktns->tx.pto_probe = 0;
pktns->tx.in_flight = 0;
pktns->tx.ack_delay = 0;
pktns->rx.largest_pn = -1;
pktns->rx.largest_acked_pn = -1;
pktns->rx.arngs.root = EB_ROOT_UNIQUE;
pktns->rx.arngs.sz = 0;
pktns->rx.arngs.enc_sz = 0;
pktns->rx.nb_aepkts_since_last_ack = 0;
pktns->rx.largest_time_received = 0;
pktns->flags = 0;
}
static inline void quic_pktns_tx_pkts_release(struct quic_pktns *pktns, struct quic_conn *qc)
{
struct eb64_node *node;
node = eb64_first(&pktns->tx.pkts);
while (node) {
struct quic_tx_packet *pkt;
struct quic_frame *frm, *frmbak;
pkt = eb64_entry(node, struct quic_tx_packet, pn_node);
node = eb64_next(node);
if (pkt->flags & QUIC_FL_TX_PACKET_ACK_ELICITING)
qc->path->ifae_pkts--;
list_for_each_entry_safe(frm, frmbak, &pkt->frms, list) {
qc_frm_unref(frm, qc);
LIST_DEL_INIT(&frm->list);
quic_tx_packet_refdec(frm->pkt);
qc_frm_free(&frm);
}
eb64_delete(&pkt->pn_node);
quic_tx_packet_refdec(pkt);
}
}
/* Discard <pktns> packet number space attached to <qc> QUIC connection.
* Its loss information are reset. Deduce the outstanding bytes for this
* packet number space from the outstanding bytes for the path of this
* connection.
* Note that all the non acknowledged TX packets and their frames are freed.
* Always succeeds.
*/
static inline void quic_pktns_discard(struct quic_pktns *pktns,
struct quic_conn *qc)
{
qc->path->in_flight -= pktns->tx.in_flight;
qc->path->prep_in_flight -= pktns->tx.in_flight;
qc->path->loss.pto_count = 0;
pktns->tx.time_of_last_eliciting = 0;
pktns->tx.loss_time = TICK_ETERNITY;
pktns->tx.pto_probe = 0;
pktns->tx.in_flight = 0;
quic_pktns_tx_pkts_release(pktns, qc);
}
/* Return 1 if <pktns> matches with the Application packet number space of
* <conn> connection which is common to the 0-RTT and 1-RTT encryption levels, 0
* if not (handshake packets).
*/
static inline int quic_application_pktns(struct quic_pktns *pktns, struct quic_conn *qc)
{
return pktns == &qc->pktns[QUIC_TLS_PKTNS_01RTT];
}
/* Returns the current largest acknowledged packet number if exists, -1 if not */
static inline int64_t quic_pktns_get_largest_acked_pn(struct quic_pktns *pktns)
{
struct eb64_node *ar = eb64_last(&pktns->rx.arngs.root);
if (!ar)
return -1;
return eb64_entry(ar, struct quic_arng_node, first)->last;
}
/* Return a character to identify the packet number space <pktns> of <qc> QUIC
* connection. 'I' for Initial packet number space, 'H' for Handshake packet
* space, and 'A' for Application data number space, or '-' if not found.