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.
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. */
/* 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;
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.
}
}
-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.
*/
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)
{
#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>
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;
#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>
}
}
+/* 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.