mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-23 23:01:24 +02:00
MINOR: quic: Remove Application level related functions
Remove the functions which were specific to the Application level. This is the same function which build any packet for any encryption level: quic_prep_hdshk_pkts() directly called from the quic_conn_io_cb().
This commit is contained in:
parent
f252adb368
commit
5d00b2d7b1
253
src/xprt_quic.c
253
src/xprt_quic.c
@ -146,7 +146,6 @@ DECLARE_STATIC_POOL(pool_head_quic_arng, "quic_arng_pool", sizeof(struct quic_ar
|
|||||||
static struct quic_tx_packet *qc_build_hdshk_pkt(unsigned char **pos, const unsigned char *buf_end,
|
static struct quic_tx_packet *qc_build_hdshk_pkt(unsigned char **pos, const unsigned char *buf_end,
|
||||||
struct quic_conn *qc, int pkt_type,
|
struct quic_conn *qc, int pkt_type,
|
||||||
struct quic_enc_level *qel, int *err);
|
struct quic_enc_level *qel, int *err);
|
||||||
int qc_prep_phdshk_pkts(struct qring *qr, struct quic_conn *qc);
|
|
||||||
|
|
||||||
/* Add traces to <buf> depending on <frm> TX frame type. */
|
/* Add traces to <buf> depending on <frm> TX frame type. */
|
||||||
static inline void chunk_tx_frm_appendf(struct buffer *buf,
|
static inline void chunk_tx_frm_appendf(struct buffer *buf,
|
||||||
@ -3961,258 +3960,6 @@ static struct quic_tx_packet *qc_build_hdshk_pkt(unsigned char **pos,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare a clear post handhskake packet for <conn> QUIC connection.
|
|
||||||
* Return the length of this packet if succeeded, -1 <wbuf> was full.
|
|
||||||
*/
|
|
||||||
static int qc_do_build_phdshk_apkt(unsigned char *pos, const unsigned char *end,
|
|
||||||
struct quic_tx_packet *pkt,
|
|
||||||
int64_t pn, size_t *pn_len,
|
|
||||||
unsigned char **buf_pn,
|
|
||||||
struct quic_enc_level *qel,
|
|
||||||
struct quic_conn *conn)
|
|
||||||
{
|
|
||||||
const unsigned char *beg;
|
|
||||||
struct quic_frame *frm, *sfrm;
|
|
||||||
struct quic_frame ack_frm = { .type = QUIC_FT_ACK, };
|
|
||||||
size_t fake_len, ack_frm_len;
|
|
||||||
int64_t largest_acked_pn;
|
|
||||||
|
|
||||||
TRACE_ENTER(QUIC_EV_CONN_PAPKT, conn->conn);
|
|
||||||
beg = pos;
|
|
||||||
/* When not probing and not acking, reduce the size of this buffer to respect
|
|
||||||
* the congestion controller window.
|
|
||||||
*/
|
|
||||||
if (!conn->tx.nb_pto_dgrams && !(qel->pktns->flags & QUIC_FL_PKTNS_ACK_REQUIRED)) {
|
|
||||||
size_t path_room;
|
|
||||||
|
|
||||||
path_room = quic_path_prep_data(conn->path);
|
|
||||||
if (end - beg > path_room)
|
|
||||||
end = beg + path_room;
|
|
||||||
}
|
|
||||||
largest_acked_pn = qel->pktns->tx.largest_acked_pn;
|
|
||||||
/* Packet number length */
|
|
||||||
*pn_len = quic_packet_number_length(pn, largest_acked_pn);
|
|
||||||
/* Check there is enough room to build this packet (without payload). */
|
|
||||||
if (end - pos < QUIC_SHORT_PACKET_MINLEN + sizeof_quic_cid(&conn->dcid) +
|
|
||||||
*pn_len + QUIC_TLS_TAG_LEN) {
|
|
||||||
ssize_t room = end - pos;
|
|
||||||
TRACE_PROTO("Not enough room", QUIC_EV_CONN_PAPKT,
|
|
||||||
conn->conn, NULL, NULL, &room);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reserve enough room at the end of the packet for the AEAD TAG. */
|
|
||||||
end -= QUIC_TLS_TAG_LEN;
|
|
||||||
quic_build_packet_short_header(&pos, end, *pn_len, conn);
|
|
||||||
/* Packet number field. */
|
|
||||||
*buf_pn = pos;
|
|
||||||
/* Packet number encoding. */
|
|
||||||
quic_packet_number_encode(&pos, end, pn, *pn_len);
|
|
||||||
|
|
||||||
/* Build an ACK frame if required. */
|
|
||||||
ack_frm_len = 0;
|
|
||||||
if ((qel->pktns->flags & QUIC_FL_PKTNS_ACK_REQUIRED) &&
|
|
||||||
!eb_is_empty(&qel->pktns->rx.arngs.root)) {
|
|
||||||
ack_frm.tx_ack.ack_delay = 0;
|
|
||||||
ack_frm.tx_ack.arngs = &qel->pktns->rx.arngs;
|
|
||||||
ack_frm_len = quic_ack_frm_reduce_sz(&ack_frm, end - pos);
|
|
||||||
if (!ack_frm_len)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
qel->pktns->flags &= ~QUIC_FL_PKTNS_ACK_REQUIRED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ack_frm_len && !qc_build_frm(&pos, end, &ack_frm, pkt, conn)) {
|
|
||||||
ssize_t room = end - pos;
|
|
||||||
TRACE_PROTO("Not enough room", QUIC_EV_CONN_PAPKT,
|
|
||||||
conn->conn, NULL, NULL, &room);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
fake_len = ack_frm_len;
|
|
||||||
if (!MT_LIST_ISEMPTY(&qel->pktns->tx.frms) &&
|
|
||||||
!qc_build_cfrms(pkt, end - pos, &fake_len, pos - beg, qel, conn)) {
|
|
||||||
ssize_t room = end - pos;
|
|
||||||
TRACE_PROTO("some CRYPTO frames could not be built",
|
|
||||||
QUIC_EV_CONN_PAPKT, conn->conn, NULL, NULL, &room);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Crypto frame */
|
|
||||||
if (!LIST_ISEMPTY(&pkt->frms)) {
|
|
||||||
struct quic_frame frm = { .type = QUIC_FT_CRYPTO, };
|
|
||||||
struct quic_crypto *crypto = &frm.crypto;
|
|
||||||
struct quic_frame *cf;
|
|
||||||
|
|
||||||
list_for_each_entry(cf, &pkt->frms, list) {
|
|
||||||
crypto->offset = cf->crypto.offset;
|
|
||||||
crypto->len = cf->crypto.len;
|
|
||||||
crypto->qel = qel;
|
|
||||||
if (!qc_build_frm(&pos, end, &frm, pkt, conn)) {
|
|
||||||
ssize_t room = end - pos;
|
|
||||||
TRACE_PROTO("Not enough room", QUIC_EV_CONN_PAPKT,
|
|
||||||
conn->conn, NULL, NULL, &room);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Encode a maximum of frames. */
|
|
||||||
list_for_each_entry_safe(frm, sfrm, &conn->tx.frms_to_send, list) {
|
|
||||||
unsigned char *ppos;
|
|
||||||
|
|
||||||
ppos = pos;
|
|
||||||
if (!qc_build_frm(&ppos, end, frm, pkt, conn)) {
|
|
||||||
TRACE_DEVEL("Frames not built", QUIC_EV_CONN_PAPKT, conn->conn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIST_DELETE(&frm->list);
|
|
||||||
LIST_APPEND(&pkt->frms, &frm->list);
|
|
||||||
pos = ppos;
|
|
||||||
}
|
|
||||||
pkt->len = pos - beg;
|
|
||||||
|
|
||||||
out:
|
|
||||||
TRACE_LEAVE(QUIC_EV_CONN_PAPKT, conn->conn);
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
err:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare a post handhskake packet at Application encryption level for <conn>
|
|
||||||
* QUIC connection.
|
|
||||||
* Return the length if succeeded, -1 if <wbuf> was full, -2 in case of major error
|
|
||||||
* (allocation or encryption failures).
|
|
||||||
*/
|
|
||||||
static struct quic_tx_packet *qc_build_phdshk_apkt(unsigned char **pos,
|
|
||||||
const unsigned char *buf_end,
|
|
||||||
struct quic_conn *qc, int *err)
|
|
||||||
{
|
|
||||||
/* A pointer to the packet number field in <buf> */
|
|
||||||
unsigned char *buf_pn;
|
|
||||||
unsigned char *beg, *end, *payload;
|
|
||||||
int64_t pn;
|
|
||||||
size_t pn_len, aad_len, payload_len;
|
|
||||||
struct quic_tls_ctx *tls_ctx;
|
|
||||||
struct quic_enc_level *qel;
|
|
||||||
struct quic_tx_packet *pkt;
|
|
||||||
|
|
||||||
TRACE_ENTER(QUIC_EV_CONN_PAPKT, qc->conn);
|
|
||||||
*err = 0;
|
|
||||||
pkt = pool_alloc(pool_head_quic_tx_packet);
|
|
||||||
if (!pkt) {
|
|
||||||
TRACE_DEVEL("Not enough memory for a new packet", QUIC_EV_CONN_PAPKT, qc->conn);
|
|
||||||
*err = -2;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
quic_tx_packet_init(pkt, QUIC_PACKET_TYPE_SHORT);
|
|
||||||
beg = *pos;
|
|
||||||
qel = &qc->els[QUIC_TLS_ENC_LEVEL_APP];
|
|
||||||
pn_len = 0;
|
|
||||||
buf_pn = NULL;
|
|
||||||
pn = qel->pktns->tx.next_pn + 1;
|
|
||||||
if (!qc_do_build_phdshk_apkt(*pos, buf_end, pkt, pn, &pn_len, &buf_pn, qel, qc)) {
|
|
||||||
*err = -1;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
end = beg + pkt->len;
|
|
||||||
payload = buf_pn + pn_len;
|
|
||||||
payload_len = end - payload;
|
|
||||||
aad_len = payload - beg;
|
|
||||||
|
|
||||||
tls_ctx = &qel->tls_ctx;
|
|
||||||
if (!quic_packet_encrypt(payload, payload_len, beg, aad_len, pn, tls_ctx, qc->conn)) {
|
|
||||||
*err = -2;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
end += QUIC_TLS_TAG_LEN;
|
|
||||||
pkt->len += QUIC_TLS_TAG_LEN;
|
|
||||||
if (!quic_apply_header_protection(beg, buf_pn, pn_len,
|
|
||||||
tls_ctx->tx.hp, tls_ctx->tx.hp_key)) {
|
|
||||||
TRACE_DEVEL("Could not apply the header protection", QUIC_EV_CONN_PAPKT, qc->conn);
|
|
||||||
*err = -2;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now that a correct packet is built, let us consume <*pos> buffer. */
|
|
||||||
*pos = end;
|
|
||||||
/* Consume a packet number. */
|
|
||||||
++qel->pktns->tx.next_pn;
|
|
||||||
/* Attach the built packet to its tree. */
|
|
||||||
pkt->pn_node.key = qel->pktns->tx.next_pn;
|
|
||||||
/* Set the packet in fligth length for in flight packet only. */
|
|
||||||
if (pkt->flags & QUIC_FL_TX_PACKET_IN_FLIGHT) {
|
|
||||||
pkt->in_flight_len = pkt->len;
|
|
||||||
qc->path->prep_in_flight += pkt->len;
|
|
||||||
}
|
|
||||||
pkt->pktns = qel->pktns;
|
|
||||||
TRACE_LEAVE(QUIC_EV_CONN_PAPKT, qc->conn, pkt);
|
|
||||||
|
|
||||||
return pkt;
|
|
||||||
|
|
||||||
err:
|
|
||||||
free_quic_tx_packet(pkt);
|
|
||||||
TRACE_DEVEL("leaving in error", QUIC_EV_CONN_PAPKT, qc->conn);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare a maximum of QUIC Application level packets from <ctx> QUIC
|
|
||||||
* connection I/O handler context.
|
|
||||||
* Returns 1 if succeeded, 0 if not.
|
|
||||||
*/
|
|
||||||
int qc_prep_phdshk_pkts(struct qring *qr, struct quic_conn *qc)
|
|
||||||
{
|
|
||||||
struct cbuf *cbuf;
|
|
||||||
unsigned char *end_buf, *end, *pos;
|
|
||||||
struct quic_enc_level *qel;
|
|
||||||
|
|
||||||
TRACE_ENTER(QUIC_EV_CONN_PAPKTS, qc->conn);
|
|
||||||
qel = &qc->els[QUIC_TLS_ENC_LEVEL_APP];
|
|
||||||
cbuf = qr->cbuf;
|
|
||||||
pos = cb_wr(cbuf);
|
|
||||||
end = end_buf = pos + cb_contig_space(cbuf);
|
|
||||||
while (pos < end_buf) {
|
|
||||||
int err;
|
|
||||||
uint16_t dglen;
|
|
||||||
struct quic_tx_packet *pkt;
|
|
||||||
|
|
||||||
if (!(qel->pktns->flags & QUIC_FL_PKTNS_ACK_REQUIRED) &&
|
|
||||||
(MT_LIST_ISEMPTY(&qel->pktns->tx.frms) ||
|
|
||||||
qc->path->prep_in_flight >= qc->path->cwnd)) {
|
|
||||||
TRACE_DEVEL("nothing more to do",
|
|
||||||
QUIC_EV_CONN_PAPKTS, qc->conn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Leave room for the datagram header */
|
|
||||||
pos += sizeof dglen + sizeof pkt;
|
|
||||||
if (end - pos > qc->path->mtu)
|
|
||||||
end = pos + qc->path->mtu;
|
|
||||||
pkt = qc_build_phdshk_apkt(&pos, end, qc, &err);
|
|
||||||
switch (err) {
|
|
||||||
case -1:
|
|
||||||
break;
|
|
||||||
case -2:
|
|
||||||
goto err;
|
|
||||||
default:
|
|
||||||
dglen = pkt->len;
|
|
||||||
qc_set_dg(cbuf, dglen, pkt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
TRACE_LEAVE(QUIC_EV_CONN_PAPKTS, qc->conn);
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
err:
|
|
||||||
TRACE_DEVEL("leaving in error", QUIC_EV_CONN_PAPKTS, qc->conn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy up to <count> bytes from connection <conn> internal stream storage into buffer <buf>.
|
/* Copy up to <count> bytes from connection <conn> internal stream storage into buffer <buf>.
|
||||||
* Return the number of bytes which have been copied.
|
* Return the number of bytes which have been copied.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user