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:
Frédéric Lécaille 2021-08-03 17:07:23 +02:00 committed by Amaury Denoyelle
parent f252adb368
commit 5d00b2d7b1

View File

@ -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.
*/