mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 22:01:31 +02:00
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:
parent
411b6f73b7
commit
ef39a74f4a
@ -322,19 +322,6 @@ struct quic_arng_node {
|
|||||||
uint64_t last;
|
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 */
|
/* Flag the packet number space as having received a packet */
|
||||||
#define QUIC_FL_PKTNS_PKT_RECEIVED (1UL << 0)
|
#define QUIC_FL_PKTNS_PKT_RECEIVED (1UL << 0)
|
||||||
/* Flag the packet number space as requiring an ACK frame to be sent. */
|
/* 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. */
|
/* The maximum number of dgrams which may be sent upon PTO expirations. */
|
||||||
#define QUIC_MAX_NB_PTO_DGRAMS 2
|
#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 */
|
/* QUIC datagram */
|
||||||
struct quic_dgram {
|
struct quic_dgram {
|
||||||
void *owner;
|
void *owner;
|
||||||
|
@ -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;
|
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 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
|
* the order they are built. This function detach a packet from its successor
|
||||||
* and predecessor in the same datagram.
|
* 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
|
/* Initialize <p> QUIC network path depending on <ipv4> boolean
|
||||||
* which is true for an IPv4 path, if not false for an IPv6 path.
|
* 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 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. */
|
/* CRYPTO data buffer handling functions. */
|
||||||
static inline unsigned char *c_buf_getpos(struct quic_enc_level *qel, uint64_t offset)
|
static inline unsigned char *c_buf_getpos(struct quic_enc_level *qel, uint64_t offset)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#error "Must define USE_OPENSSL"
|
#error "Must define USE_OPENSSL"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <import/eb64tree.h>
|
||||||
#include <haproxy/quic_conn-t.h>
|
#include <haproxy/quic_conn-t.h>
|
||||||
#include <haproxy/quic_enc.h>
|
#include <haproxy/quic_enc.h>
|
||||||
#include <haproxy/quic_frame-t.h>
|
#include <haproxy/quic_frame-t.h>
|
||||||
|
@ -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_v1[20];
|
||||||
extern const unsigned char initial_salt_v2[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 */
|
/* Key phase used for Key Update */
|
||||||
struct quic_tls_kp {
|
struct quic_tls_kp {
|
||||||
EVP_CIPHER_CTX *ctx;
|
EVP_CIPHER_CTX *ctx;
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
#include <haproxy/dynbuf.h>
|
#include <haproxy/dynbuf.h>
|
||||||
#include <haproxy/pool.h>
|
#include <haproxy/pool.h>
|
||||||
#include <haproxy/openssl-compat.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/quic_tls-t.h>
|
||||||
#include <haproxy/trace.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
|
/* Return a character to identify the packet number space <pktns> of <qc> QUIC
|
||||||
* connection. 'I' for Initial packet number space, 'H' for Handshake packet
|
* connection. 'I' for Initial packet number space, 'H' for Handshake packet
|
||||||
* space, and 'A' for Application data number space, or '-' if not found.
|
* space, and 'A' for Application data number space, or '-' if not found.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user