summaryrefslogtreecommitdiffstats
path: root/src/quic_rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/quic_rx.c')
-rw-r--r--src/quic_rx.c78
1 files changed, 20 insertions, 58 deletions
diff --git a/src/quic_rx.c b/src/quic_rx.c
index 585c71a..d5b45d6 100644
--- a/src/quic_rx.c
+++ b/src/quic_rx.c
@@ -506,6 +506,7 @@ static void qc_notify_cc_of_newly_acked_pkts(struct quic_conn *qc,
qc_treat_ack_of_ack(qc, &pkt->pktns->rx.arngs, pkt->largest_acked_pn);
ev.ack.acked = pkt->in_flight_len;
ev.ack.time_sent = pkt->time_sent;
+ ev.ack.pn = pkt->pn_node.key;
quic_cc_event(&qc->path->cc, &ev);
LIST_DEL_INIT(&pkt->list);
quic_tx_packet_refdec(pkt);
@@ -740,8 +741,11 @@ static int qc_handle_crypto_frm(struct quic_conn *qc,
goto leave;
}
- if (ncb_data(ncbuf, 0))
+ /* Reschedule with TASK_HEAVY if CRYPTO data ready for decoding. */
+ if (ncb_data(ncbuf, 0)) {
HA_ATOMIC_OR(&qc->wait_event.tasklet->state, TASK_HEAVY);
+ tasklet_wakeup(qc->wait_event.tasklet);
+ }
done:
ret = 1;
@@ -860,6 +864,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
case QUIC_FT_PING:
break;
case QUIC_FT_ACK:
+ case QUIC_FT_ACK_ECN:
{
unsigned int rtt_sample;
rtt_sample = UINT_MAX;
@@ -902,6 +907,9 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
if (!qc_handle_crypto_frm(qc, &frm.crypto, pkt, qel, &fast_retrans))
goto leave;
break;
+ case QUIC_FT_NEW_TOKEN:
+ /* TODO */
+ break;
case QUIC_FT_STREAM_8 ... QUIC_FT_STREAM_F:
{
struct qf_stream *strm_frm = &frm.stream;
@@ -974,7 +982,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
break;
case QUIC_FT_RETIRE_CONNECTION_ID:
{
- struct quic_cid_tree *tree;
+ struct quic_cid_tree *tree __maybe_unused;
struct quic_connection_id *conn_id = NULL;
if (!qc_handle_retire_connection_id_frm(qc, &frm, &pkt->dcid, &conn_id))
@@ -1001,6 +1009,10 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
}
break;
}
+ case QUIC_FT_PATH_CHALLENGE:
+ case QUIC_FT_PATH_RESPONSE:
+ /* TODO */
+ break;
case QUIC_FT_CONNECTION_CLOSE:
case QUIC_FT_CONNECTION_CLOSE_APP:
/* Increment the error counters */
@@ -1040,8 +1052,8 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
qc->state = QUIC_HS_ST_CONFIRMED;
break;
default:
- TRACE_ERROR("unknosw frame type", QUIC_EV_CONN_PRSHPKT, qc);
- goto leave;
+ /* Unknown frame type must be rejected by qc_parse_frm(). */
+ ABORT_NOW();
}
}
@@ -1144,50 +1156,6 @@ static void qc_rm_hp_pkts(struct quic_conn *qc, struct quic_enc_level *el)
TRACE_LEAVE(QUIC_EV_CONN_ELRMHP, qc);
}
-/* Process all the CRYPTO frame at <el> encryption level. This is the
- * responsibility of the called to ensure there exists a CRYPTO data
- * stream for this level.
- * Return 1 if succeeded, 0 if not.
- */
-int qc_treat_rx_crypto_frms(struct quic_conn *qc, struct quic_enc_level *el,
- struct ssl_sock_ctx *ctx)
-{
- int ret = 0;
- struct ncbuf *ncbuf;
- struct quic_cstream *cstream = el->cstream;
- ncb_sz_t data;
-
- TRACE_ENTER(QUIC_EV_CONN_PHPKTS, qc);
-
- BUG_ON(!cstream);
- ncbuf = &cstream->rx.ncbuf;
- if (ncb_is_null(ncbuf))
- goto done;
-
- /* TODO not working if buffer is wrapping */
- while ((data = ncb_data(ncbuf, 0))) {
- const unsigned char *cdata = (const unsigned char *)ncb_head(ncbuf);
-
- if (!qc_ssl_provide_quic_data(&el->cstream->rx.ncbuf, el->level,
- ctx, cdata, data))
- goto leave;
-
- cstream->rx.offset += data;
- TRACE_DEVEL("buffered crypto data were provided to TLS stack",
- QUIC_EV_CONN_PHPKTS, qc, el);
- }
-
- done:
- ret = 1;
- leave:
- if (!ncb_is_null(ncbuf) && ncb_is_empty(ncbuf)) {
- TRACE_DEVEL("freeing crypto buf", QUIC_EV_CONN_PHPKTS, qc, el);
- quic_free_ncbuf(ncbuf);
- }
- TRACE_LEAVE(QUIC_EV_CONN_PHPKTS, qc);
- return ret;
-}
-
/* Check if it's possible to remove header protection for packets related to
* encryption level <qel>. If <qel> is NULL, assume it's false.
*
@@ -1317,15 +1285,6 @@ int qc_treat_rx_pkts(struct quic_conn *qc)
qel->pktns->flags |= QUIC_FL_PKTNS_NEW_LARGEST_PN;
}
- if (qel->cstream) {
- struct ncbuf *ncbuf = &qel->cstream->rx.ncbuf;
-
- if (!ncb_is_null(ncbuf) && ncb_data(ncbuf, 0)) {
- /* Some in order CRYPTO data were bufferized. */
- HA_ATOMIC_OR(&qc->wait_event.tasklet->state, TASK_HEAVY);
- }
- }
-
/* Release the Initial encryption level and packet number space. */
if ((qc->flags & QUIC_FL_CONN_IPKTNS_DCD) && qel == qc->iel) {
qc_enc_level_free(qc, &qc->iel);
@@ -1503,7 +1462,7 @@ static inline int quic_read_uint32(uint32_t *val,
if (end - *buf < sizeof *val)
return 0;
- *val = ntohl(*(uint32_t *)*buf);
+ *val = ntohl(read_u32(*buf));
*buf += sizeof *val;
return 1;
@@ -1728,6 +1687,9 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
}
}
else if (!qc) {
+ /* Stateless Reset sent even for Long header packets as haproxy
+ * emits stateless_reset_token in its TPs.
+ */
TRACE_PROTO("RX non Initial pkt without connection", QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
if (!send_stateless_reset(l, &dgram->saddr, pkt))
TRACE_ERROR("stateless reset not sent", QUIC_EV_CONN_LPKT, qc);