mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-11 05:48:41 +00: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,
|
||||
struct quic_conn *qc, int pkt_type,
|
||||
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. */
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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>.
|
||||
* Return the number of bytes which have been copied.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user