/*
* Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include "internal/packet_quic.h"
#include "internal/nelem.h"
#include "internal/quic_wire.h"
#include "internal/quic_record_rx.h"
#include "internal/quic_ackm.h"
#include "internal/quic_rx_depack.h"
#include "internal/quic_error.h"
#include "internal/quic_fc.h"
#include "internal/quic_channel.h"
#include "internal/sockets.h"
#include "quic_local.h"
#include "quic_channel_local.h"
#include "../ssl_local.h"
/*
* Helper functions to process different frame types.
*
* Typically, those that are ACK eliciting will take an OSSL_ACKM_RX_PKT
* pointer argument, the few that aren't ACK eliciting will not. This makes
* them a verifiable pattern against tables where this is specified.
*/
static int depack_do_implicit_stream_create(QUIC_CHANNEL *ch,
uint64_t stream_id,
uint64_t frame_type,
QUIC_STREAM **result);
static int depack_do_frame_padding(PACKET *pkt)
{
/* We ignore this frame */
ossl_quic_wire_decode_padding(pkt);
return 1;
}
static int depack_do_frame_ping(PACKET *pkt, QUIC_CHANNEL *ch,
OSSL_ACKM_RX_PKT *ackm_data)
{
/* We ignore this frame, apart from eliciting an ACK */
if (!ossl_quic_wire_decode_frame_ping(pkt)) {
ossl_quic_channel_raise_protocol_error(ch,
QUIC_ERR_FRAME_ENCODING_ERROR,
OSSL_QUIC_FRAME_TYPE_PING,
"decode error");
return 0;
}
/* This frame makes the packet ACK eliciting */
ackm_data->is_ack_eliciting = 1;
return 1;
}
static int depack_do_frame_ack(PACKET *pkt, QUIC_CHANNEL *ch,
int packet_space, OSSL_TIME received,
uint64_t frame_type)
{
OSSL_QUIC_FRAME_ACK ack;
OSSL_QUIC_ACK_RANGE *ack_ranges = NULL;
uint64_t total_ranges = 0;
uint32_t ack_delay_exp = ch->rx_ack_delay_exp;
if (!ossl_quic_wire_peek_frame_ack_num_ranges(pkt, &total_ranges)
/* In case sizeof(uint64_t) > sizeof(size_t) */
|| total_ranges > SIZE_MAX / sizeof(ack_ranges[0])
|| (ack_ranges = OPENSSL_zalloc(sizeof(ack_ranges[0])
* (size_t)total_ranges)) == NULL)
goto malformed;
ack.ack_ranges = ack_ranges;
ack.num_ack_ranges = (size_t)total_ranges;
if (!ossl_quic_wire_decode_frame_ack(pkt, ack_delay_exp, &ack, NULL))
goto malformed;
if (!ossl_ackm_on_rx_ack_frame(ch->ackm, &ack,
packet_space, received))
goto malformed;
OPENSSL_free(ack_ranges);
return 1;
malformed:
ossl_quic_channel_raise_protocol_error(ch,
QUIC_ERR_FRAME_ENCODING_ERROR,
frame_type,
"decode error");
OPENSSL_free(ack_ranges);
return 0;
}
static int depack_do_frame_reset_stream(PACKET *pkt,
QUIC_CHANNEL *ch,
OSSL_ACKM_RX_PKT *ackm_data)
{
OSSL_QUIC_FRAME_RESET_STREAM frame_data;
QUIC_STREAM *stream = NULL;
if