From: Frédéric Lécaille Date: Tue, 3 Aug 2021 15:07:23 +0000 (+0200) Subject: MINOR: quic: Remove Application level related functions X-Git-Tag: v2.5-dev8~83 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5d00b2d7b13daef6ab8689ad4bd58973c71038dc;p=thirdparty%2Fhaproxy.git 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(). --- diff --git a/src/xprt_quic.c b/src/xprt_quic.c index f6542d88a6..963904ca4d 100644 --- a/src/xprt_quic.c +++ b/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 depending on 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 QUIC connection. - * Return the length of this packet if succeeded, -1 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 - * QUIC connection. - * Return the length if succeeded, -1 if 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 */ - 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 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 bytes from connection internal stream storage into buffer . * Return the number of bytes which have been copied. */