* Returns 1 if succeeded, 0 if not.
*/
static inline int qc_try_rm_hp(struct quic_rx_packet *pkt,
- unsigned char **buf, unsigned char *beg,
+ unsigned char *buf, unsigned char *beg,
const unsigned char *end,
struct quic_conn *qc, struct quic_enc_level **el,
struct ssl_sock_ctx *ctx)
* QUIC_PACKET_PN_MAXLEN of the sample used to add/remove the header
* protection.
*/
- pn = *buf;
+ pn = buf;
if (qc_pkt_may_rm_hp(pkt, qc, ctx, &qel)) {
/* Note that the following function enables us to unprotect the packet
* number and its length subsequently used to decrypt the entire
pkt->data = (unsigned char *)b_tail(&qc->rx.buf);
b_add(&qc->rx.buf, pkt->len);
out:
- /* Updtate the offset of <*buf> for the next QUIC packet. */
- *buf = beg + pkt->len;
-
TRACE_LEAVE(QUIC_EV_CONN_TRMHP, ctx ? ctx->qc : NULL, qpkt_trace);
return 1;
}
}
- if (!qc_try_rm_hp(pkt, buf, beg, end, qc, &qel, conn_ctx)) {
+ if (!qc_try_rm_hp(pkt, *buf, beg, end, qc, &qel, conn_ctx)) {
HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &qc->rx.buf_rwlock);
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_SPKT, qc);
goto err;
return qc;
}
-static ssize_t qc_lstnr_pkt_rcv(unsigned char **buf, const unsigned char *end,
+static ssize_t qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
struct quic_rx_packet *pkt,
struct quic_dgram_ctx *dgram_ctx,
struct sockaddr_storage *saddr)
{
- unsigned char *beg;
+ unsigned char *beg, *payload;
struct quic_conn *qc;
struct listener *l;
struct ssl_sock_ctx *conn_ctx;
size_t b_cspace;
struct quic_enc_level *qel;
+ beg = buf;
qc = NULL;
conn_ctx = NULL;
qel = NULL;
* packet with parsed packet number from others.
*/
pkt->pn_node.key = (uint64_t)-1;
- if (end <= *buf)
+ if (end <= buf)
goto err;
/* Fixed bit */
- if (!(**buf & QUIC_PACKET_FIXED_BIT)) {
+ if (!(*buf & QUIC_PACKET_FIXED_BIT)) {
/* XXX TO BE DISCARDED */
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
goto err;
}
l = dgram_ctx->owner;
- beg = *buf;
/* Header form */
- qc_parse_hd_form(pkt, *(*buf)++, &long_header);
+ qc_parse_hd_form(pkt, *buf++, &long_header);
if (long_header) {
- if (!quic_packet_read_long_header(buf, end, pkt)) {
+ if (!quic_packet_read_long_header(&buf, end, pkt)) {
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
goto err;
}
}
TRACE_PROTO("Unsupported QUIC version, send Version Negotiation packet", QUIC_EV_CONN_LPKT);
- goto out;
+ goto err;
}
/* For Initial packets, and for servers (QUIC clients connections),
if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
uint64_t token_len;
- if (!quic_dec_int(&token_len, (const unsigned char **)buf, end) ||
- end - *buf < token_len) {
+ if (!quic_dec_int(&token_len, (const unsigned char **)&buf, end) ||
+ end - buf < token_len) {
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
goto err;
}
if (pkt->type != QUIC_PACKET_TYPE_RETRY && pkt->version) {
uint64_t len;
- if (!quic_dec_int(&len, (const unsigned char **)buf, end) ||
- end - *buf < len) {
+ if (!quic_dec_int(&len, (const unsigned char **)&buf, end) ||
+ end - buf < len) {
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
goto err;
}
- pkt->len = len;
+ payload = buf;
+ pkt->len = len + payload - beg;
}
qc = qc_retrieve_conn_from_cid(pkt, l, saddr);
}
}
else {
- if (end - *buf < QUIC_HAP_CID_LEN) {
+ if (end - buf < QUIC_HAP_CID_LEN) {
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
goto err;
}
- memcpy(pkt->dcid.data, *buf, QUIC_HAP_CID_LEN);
+ memcpy(pkt->dcid.data, buf, QUIC_HAP_CID_LEN);
pkt->dcid.len = QUIC_HAP_CID_LEN;
- *buf += QUIC_HAP_CID_LEN;
+ buf += QUIC_HAP_CID_LEN;
+
+ /* A short packet is the last one of a UDP datagram. */
+ payload = buf;
+ pkt->len = end - beg;
qc = qc_retrieve_conn_from_cid(pkt, l, saddr);
if (!qc) {
- size_t pktlen = end - *buf;
+ size_t pktlen = end - buf;
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, NULL, pkt, &pktlen);
goto err;
}
conn_ctx = HA_ATOMIC_LOAD(&qc->conn->xprt_ctx);
pkt->qc = qc;
- /* A short packet is the last one of an UDP datagram. */
- pkt->len = end - *buf;
}
- /* Increase the total length of this packet by the header length. */
- pkt->raw_len = pkt->len += *buf - beg;
/* When multiple QUIC packets are coalesced on the same UDP datagram,
* they must have the same DCID.
goto out;
}
+ pkt->raw_len = pkt->len;
HA_RWLOCK_WRLOCK(QUIC_LOCK, &qc->rx.buf_rwlock);
quic_rx_pkts_del(qc);
b_cspace = b_contig_space(&qc->rx.buf);
}
}
- if (!qc_try_rm_hp(pkt, buf, beg, end, qc, &qel, conn_ctx)) {
+ if (!qc_try_rm_hp(pkt, payload, beg, end, qc, &qel, conn_ctx)) {
HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &qc->rx.buf_rwlock);
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, qc);
goto err;
return pkt->len;
err:
+ /* If length not found, consume the entire packet */
+ if (!pkt->len)
+ pkt->len = end - beg;
TRACE_DEVEL("Leaving in error", QUIC_EV_CONN_LPKT,
qc ? qc : NULL, pkt);
return -1;
do {
int ret;
struct quic_rx_packet *pkt;
- size_t pkt_len;
pkt = pool_zalloc(pool_head_quic_rx_packet);
if (!pkt)
goto err;
quic_rx_packet_refinc(pkt);
- ret = func(&pos, end, pkt, &dgram_ctx, saddr);
- pkt_len = pkt->len;
+ ret = func(pos, end, pkt, &dgram_ctx, saddr);
+ pos += pkt->len;
quic_rx_packet_refdec(pkt);
- if (ret == -1 && !pkt_len)
+ if (ret == -1)
/* If the packet length could not be found, we cannot continue. */
break;
-
} while (pos < end);
/* Increasing the received bytes counter by the UDP datagram length