return 0;
}
-__attribute__((unused))
-static ssize_t qc_srv_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;
- uint64_t len;
- struct quic_conn *qc;
- struct eb_root *cids;
- struct ebmb_node *node;
- struct connection *srv_conn;
- struct ssl_sock_ctx *conn_ctx;
- int long_header;
- size_t b_cspace;
- struct quic_enc_level *qel;
-
- qc = NULL;
- qel = NULL;
- TRACE_ENTER(QUIC_EV_CONN_SPKT);
- if (end <= *buf)
- goto err;
-
- /* Fixed bit */
- if (!(**buf & QUIC_PACKET_FIXED_BIT))
- /* XXX TO BE DISCARDED */
- goto err;
-
- srv_conn = dgram_ctx->owner;
- beg = *buf;
- /* Header form */
- qc_parse_hd_form(pkt, *(*buf)++, &long_header);
- if (long_header) {
- size_t cid_lookup_len;
-
- if (!quic_packet_read_long_header(buf, end, pkt))
- goto err;
-
- /* unsupported QUIC version */
- if (!qc_pkt_is_supported_version(pkt)) {
- TRACE_PROTO("Null QUIC version, packet dropped", QUIC_EV_CONN_LPKT);
- goto err;
- }
-
- /* For Initial packets, and for servers (QUIC clients connections),
- * there is no Initial connection IDs storage.
- */
- if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
- cids = &((struct server *)__objt_server(srv_conn->target))->cids;
- cid_lookup_len = pkt->dcid.len;
- }
- else {
- cids = &((struct server *)__objt_server(srv_conn->target))->cids;
- cid_lookup_len = QUIC_HAP_CID_LEN;
- }
-
- node = ebmb_lookup(cids, pkt->dcid.data, cid_lookup_len);
- if (!node)
- goto err;
-
- qc = ebmb_entry(node, struct quic_conn, scid_node);
-
- if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
- qc->dcid.len = pkt->scid.len;
- if (pkt->scid.len)
- memcpy(qc->dcid.data, pkt->scid.data, pkt->scid.len);
- }
-
- 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)
- goto err;
-
- /* XXX TO DO XXX 0 value means "the token is not present".
- * A server which sends an Initial packet must not set the token.
- * So, a client which receives an Initial packet with a token
- * MUST discard the packet or generate a connection error with
- * PROTOCOL_VIOLATION as type.
- * The token may be provided in a Retry packet or NEW_TOKEN frame
- * only by the QUIC server.
- */
- pkt->token_len = token_len;
- }
- }
- else {
- /* XXX TO DO: Short header XXX */
- if (end - *buf < QUIC_HAP_CID_LEN)
- goto err;
-
- cids = &((struct server *)__objt_server(srv_conn->target))->cids;
- node = ebmb_lookup(cids, *buf, QUIC_HAP_CID_LEN);
- if (!node)
- goto err;
-
- qc = ebmb_entry(node, struct quic_conn, scid_node);
- *buf += QUIC_HAP_CID_LEN;
- }
-
- /* Only packets packets with long headers and not RETRY or VERSION as type
- * have a length field.
- */
- if (long_header && pkt->type != QUIC_PACKET_TYPE_RETRY && pkt->version) {
- if (!quic_dec_int(&len, (const unsigned char **)buf, end) || end - *buf < len)
- goto err;
-
- pkt->len = len;
- }
- else if (!long_header) {
- /* A short packet is the last one of an UDP datagram. */
- pkt->len = end - *buf;
- }
-
- conn_ctx = qc->conn->xprt_ctx;
-
- /* Increase the total length of this packet by the header length. */
- pkt->len += *buf - beg;
-
- /* When multiple QUIC packets are coalesced on the same UDP datagram,
- * they must have the same DCID.
- *
- * This check must be done after the final update to pkt.len to
- * properly drop the packet on failure.
- */
- if (!dgram_ctx->dcid.len) {
- memcpy(dgram_ctx->dcid.data, pkt->dcid.data, pkt->dcid.len);
- dgram_ctx->dcid.len = pkt->dcid.len;
- }
- else if (memcmp(dgram_ctx->dcid.data, pkt->dcid.data, pkt->dcid.len)) {
- TRACE_PROTO("Packet dropped", QUIC_EV_CONN_SPKT, qc);
- goto err;
- }
- dgram_ctx->qc = qc;
-
- HA_RWLOCK_WRLOCK(QUIC_LOCK, &qc->rx.buf_rwlock);
- b_cspace = b_contig_space(&qc->rx.buf);
- if (b_cspace < pkt->len) {
- /* Let us consume the remaining contiguous space. */
- b_add(&qc->rx.buf, b_cspace);
- if (b_contig_space(&qc->rx.buf) < pkt->len) {
- HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &qc->rx.buf_rwlock);
- TRACE_PROTO("Too big packet", QUIC_EV_CONN_SPKT, qc, pkt, &pkt->len);
- goto err;
- }
- }
-
- if (!qc_try_rm_hp(qc, pkt, *buf, beg, end, &qel)) {
- HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &qc->rx.buf_rwlock);
- TRACE_PROTO("Packet dropped", QUIC_EV_CONN_SPKT, qc);
- goto err;
- }
-
- HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &qc->rx.buf_rwlock);
- if (pkt->aad_len)
- qc_pkt_insert(pkt, qel);
- /* Wake the tasklet of the QUIC connection packet handler. */
- if (conn_ctx)
- tasklet_wakeup(conn_ctx->wait_event.tasklet);
-
- TRACE_LEAVE(QUIC_EV_CONN_SPKT, qc);
-
- return pkt->len;
-
- err:
- TRACE_DEVEL("Leaing in error", QUIC_EV_CONN_SPKT, qc ? qc : NULL);
- return -1;
-}
-
/*
* Send a Version Negotiation packet on response to <pkt> on socket <fd> to
* address <addr>.