#ifndef OSSL_INTERNAL_QUIC_WIRE_H
#define OSSL_INTERNAL_QUIC_WIRE_H
#pragma once
#include "internal/e_os.h"
#include "internal/time.h"
#include "internal/quic_types.h"
#include "internal/packet_quic.h"
#ifndef OPENSSL_NO_QUIC
#define OSSL_QUIC_FRAME_TYPE_PADDING 0x00
#define OSSL_QUIC_FRAME_TYPE_PING 0x01
#define OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN 0x02
#define OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN 0x03
#define OSSL_QUIC_FRAME_TYPE_RESET_STREAM 0x04
#define OSSL_QUIC_FRAME_TYPE_STOP_SENDING 0x05
#define OSSL_QUIC_FRAME_TYPE_CRYPTO 0x06
#define OSSL_QUIC_FRAME_TYPE_NEW_TOKEN 0x07
#define OSSL_QUIC_FRAME_TYPE_MAX_DATA 0x10
#define OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA 0x11
#define OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI 0x12
#define OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI 0x13
#define OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED 0x14
#define OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED 0x15
#define OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI 0x16
#define OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI 0x17
#define OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID 0x18
#define OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID 0x19
#define OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE 0x1A
#define OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE 0x1B
#define OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT 0x1C
#define OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP 0x1D
#define OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE 0x1E
#define OSSL_QUIC_FRAME_FLAG_STREAM_FIN 0x01
#define OSSL_QUIC_FRAME_FLAG_STREAM_LEN 0x02
#define OSSL_QUIC_FRAME_FLAG_STREAM_OFF 0x04
#define OSSL_QUIC_FRAME_FLAG_STREAM_MASK ((uint64_t)0x07)
#define OSSL_QUIC_FRAME_TYPE_STREAM 0x08
#define OSSL_QUIC_FRAME_TYPE_STREAM_FIN \
(OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_FIN)
#define OSSL_QUIC_FRAME_TYPE_STREAM_LEN \
(OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_LEN)
#define OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN \
(OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_LEN | OSSL_QUIC_FRAME_FLAG_STREAM_FIN)
#define OSSL_QUIC_FRAME_TYPE_STREAM_OFF \
(OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_OFF)
#define OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN \
(OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_OFF | OSSL_QUIC_FRAME_FLAG_STREAM_FIN)
#define OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN \
(OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_OFF | OSSL_QUIC_FRAME_FLAG_STREAM_LEN)
#define OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN \
(OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_OFF | OSSL_QUIC_FRAME_FLAG_STREAM_LEN | OSSL_QUIC_FRAME_FLAG_STREAM_FIN)
#define OSSL_QUIC_FRAME_TYPE_IS_STREAM(x) \
(((x) & ~OSSL_QUIC_FRAME_FLAG_STREAM_MASK) == OSSL_QUIC_FRAME_TYPE_STREAM)
#define OSSL_QUIC_FRAME_TYPE_IS_ACK(x) \
(((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN)
#define OSSL_QUIC_FRAME_TYPE_IS_MAX_STREAMS(x) \
(((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI)
#define OSSL_QUIC_FRAME_TYPE_IS_STREAMS_BLOCKED(x) \
(((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI)
#define OSSL_QUIC_FRAME_TYPE_IS_CONN_CLOSE(x) \
(((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT)
const char *ossl_quic_frame_type_to_string(uint64_t frame_type);
static ossl_unused ossl_inline int
ossl_quic_frame_type_is_ack_eliciting(uint64_t frame_type)
{
switch (frame_type) {
case OSSL_QUIC_FRAME_TYPE_PADDING:
case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN:
case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN:
case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT:
case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP:
return 0;
default:
return 1;
}
}
#define QUIC_TPARAM_ORIG_DCID 0x00
#define QUIC_TPARAM_MAX_IDLE_TIMEOUT 0x01
#define QUIC_TPARAM_STATELESS_RESET_TOKEN 0x02
#define QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE 0x03
#define QUIC_TPARAM_INITIAL_MAX_DATA 0x04
#define QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL 0x05
#define QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE 0x06
#define QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_UNI 0x07
#define QUIC_TPARAM_INITIAL_MAX_STREAMS_BIDI 0x08
#define QUIC_TPARAM_INITIAL_MAX_STREAMS_UNI 0x09
#define QUIC_TPARAM_ACK_DELAY_EXP 0x0A
#define QUIC_TPARAM_MAX_ACK_DELAY 0x0B
#define QUIC_TPARAM_DISABLE_ACTIVE_MIGRATION 0x0C
#define QUIC_TPARAM_PREFERRED_ADDR 0x0D
#define QUIC_TPARAM_ACTIVE_CONN_ID_LIMIT 0x0E
#define QUIC_TPARAM_INITIAL_SCID 0x0F
#define QUIC_TPARAM_RETRY_SCID 0x10
typedef struct ossl_quic_ack_range_st {
QUIC_PN start, end;
} OSSL_QUIC_ACK_RANGE;
typedef struct ossl_quic_frame_ack_st {
OSSL_QUIC_ACK_RANGE *ack_ranges;
size_t num_ack_ranges;
OSSL_TIME delay_time;
uint64_t ect0, ect1, ecnce;
unsigned int ecn_present : 1;
} OSSL_QUIC_FRAME_ACK;
int ossl_quic_frame_ack_contains_pn(const OSSL_QUIC_FRAME_ACK *ack, QUIC_PN pn);
typedef struct ossl_quic_frame_stream_st {
uint64_t stream_id;
uint64_t offset;
uint64_t len;
const unsigned char *data;
unsigned int has_explicit_len : 1;
unsigned int is_fin : 1;
} OSSL_QUIC_FRAME_STREAM;
typedef struct ossl_quic_frame_crypto_st {
uint64_t offset;
uint64_t len;
const unsigned char *data;
} OSSL_QUIC_FRAME_CRYPTO;
typedef struct ossl_quic_frame_reset_stream_st {
uint64_t stream_id;
uint64_t app_error_code;
uint64_t final_size;
} OSSL_QUIC_FRAME_RESET_STREAM;
typedef struct ossl_quic_frame_stop_sending_st {
uint64_t stream_id;
uint64_t app_error_code;
} OSSL_QUIC_FRAME_STOP_SENDING;
typedef struct ossl_quic_frame_new_conn_id_st {
uint64_t seq_num;
uint64_t retire_prior_to;
QUIC_CONN_ID conn_id;
QUIC_STATELESS_RESET_TOKEN stateless_reset;
} OSSL_QUIC_FRAME_NEW_CONN_ID;
typedef struct ossl_quic_frame_conn_close_st {
unsigned int is_app : 1;
uint64_t error_code;
uint64_t frame_type;
char *reason;
size_t reason_len;
} OSSL_QUIC_FRAME_CONN_CLOSE;
int ossl_quic_wire_encode_padding(WPACKET *pkt, size_t num_bytes);
int ossl_quic_wire_encode_frame_ping(WPACKET *pkt);
int ossl_quic_wire_encode_frame_ack(WPACKET *pkt,
uint32_t ack_delay_exponent,
const OSSL_QUIC_FRAME_ACK *ack);
int ossl_quic_wire_encode_frame_reset_stream(WPACKET *pkt,
const OSSL_QUIC_FRAME_RESET_STREAM *f);
int ossl_quic_wire_encode_frame_stop_sending(WPACKET *pkt,
const OSSL_QUIC_FRAME_STOP_SENDING *f);
int ossl_quic_wire_encode_frame_crypto_hdr(WPACKET *hdr,
const OSSL_QUIC_FRAME_CRYPTO *f);
size_t ossl_quic_wire_get_encoded_frame_len_crypto_hdr(const OSSL_QUIC_FRAME_CRYPTO *f);
void *ossl_quic_wire_encode_frame_crypto(WPACKET *pkt,
const OSSL_QUIC_FRAME_CRYPTO *f);
int ossl_quic_wire_encode_frame_new_token(WPACKET *pkt,
const unsigned char *token,
size_t token_len);
int ossl_quic_wire_encode_frame_stream_hdr(WPACKET *pkt,
const OSSL_QUIC_FRAME_STREAM *f);
size_t ossl_quic_wire_get_encoded_frame_len_stream_hdr(const OSSL_QUIC_FRAME_STREAM *f);
void *ossl_quic_wire_encode_frame_stream(WPACKET *pkt,
const OSSL_QUIC_FRAME_STREAM *f);
int ossl_quic_wire_encode_frame_max_data(WPACKET *pkt,
uint64_t max_data);
int ossl_quic_wire_encode_frame_max_stream_data(WPACKET *pkt,
uint64_t stream_id,
uint64_t max_data);
int ossl_quic_wire_encode_frame_max_streams(WPACKET *pkt,
char is_uni,
uint64_t max_streams);
int ossl_quic_wire_encode_frame_data_blocked(WPACKET *pkt,
uint64_t max_data);
int ossl_quic_wire_encode_frame_stream_data_blocked(WPACKET *pkt,
uint64_t stream_id,
uint64_t max_stream_data);
int ossl_quic_wire_encode_frame_streams_blocked(WPACKET *pkt,
char is_uni,
uint64_t max_streams);
int ossl_quic_wire_encode_frame_new_conn_id(WPACKET *pkt,
const OSSL_QUIC_FRAME_NEW_CONN_ID *f);
int ossl_quic_wire_encode_frame_retire_conn_id(WPACKET *pkt,
uint64_t seq_num);
int ossl_quic_wire_encode_frame_path_challenge(WPACKET *pkt,
uint64_t data);
int ossl_quic_wire_encode_frame_path_response(WPACKET *pkt,
uint64_t data);
int ossl_quic_wire_encode_frame_conn_close(WPACKET *pkt,
const OSSL_QUIC_FRAME_CONN_CLOSE *f);
int ossl_quic_wire_encode_frame_handshake_done(WPACKET *pkt);
unsigned char *ossl_quic_wire_encode_transport_param_bytes(WPACKET *pkt,
uint64_t id,
const unsigned char *value,
size_t value_len);
int ossl_quic_wire_encode_transport_param_int(WPACKET *pkt,
uint64_t id,
uint64_t value);
int ossl_quic_wire_encode_transport_param_cid(WPACKET *wpkt,
uint64_t id,
const QUIC_CONN_ID *cid);
int ossl_quic_wire_peek_frame_header(PACKET *pkt, uint64_t *type,
int *was_minimal);
int ossl_quic_wire_skip_frame_header(PACKET *pkt, uint64_t *type);
int ossl_quic_wire_peek_frame_ack_num_ranges(const PACKET *pkt,
uint64_t *total_ranges);
int ossl_quic_wire_decode_frame_ack(PACKET *pkt,
uint32_t ack_delay_exponent,
OSSL_QUIC_FRAME_ACK *ack,
uint64_t *total_ranges);
int ossl_quic_wire_decode_frame_reset_stream(PACKET *pkt,
OSSL_QUIC_FRAME_RESET_STREAM *f);
int ossl_quic_wire_decode_frame_stop_sending(PACKET *pkt,
OSSL_QUIC_FRAME_STOP_SENDING *f);
int ossl_quic_wire_decode_frame_crypto(PACKET *pkt, int nodata,
OSSL_QUIC_FRAME_CRYPTO *f);
int ossl_quic_wire_decode_frame_new_token(PACKET *pkt,
const unsigned char **token,
size_t *token_len);
int ossl_quic_wire_decode_frame_stream(PACKET *pkt, int nodata,
OSSL_QUIC_FRAME_STREAM *f);
int ossl_quic_wire_decode_frame_max_data(PACKET *pkt,
uint64_t *max_data);
int ossl_quic_wire_decode_frame_max_stream_data(PACKET *pkt,
uint64_t *stream_id,
uint64_t *max_stream_data);
int ossl_quic_wire_decode_frame_max_streams(PACKET *pkt,
uint64_t *max_streams);
int ossl_quic_wire_decode_frame_data_blocked(PACKET *pkt,
uint64_t *max_data);
int ossl_quic_wire_decode_frame_stream_data_blocked(PACKET *pkt,
uint64_t *stream_id,
uint64_t *max_stream_data);
int ossl_quic_wire_decode_frame_streams_blocked(PACKET *pkt,
uint64_t *max_streams);
int ossl_quic_wire_decode_frame_new_conn_id(PACKET *pkt,
OSSL_QUIC_FRAME_NEW_CONN_ID *f);
int ossl_quic_wire_decode_frame_retire_conn_id(PACKET *pkt,
uint64_t *seq_num);
int ossl_quic_wire_decode_frame_path_challenge(PACKET *pkt,
uint64_t *data);
int ossl_quic_wire_decode_frame_path_response(PACKET *pkt,
uint64_t *data);
int ossl_quic_wire_decode_frame_conn_close(PACKET *pkt,
OSSL_QUIC_FRAME_CONN_CLOSE *f);
size_t ossl_quic_wire_decode_padding(PACKET *pkt);
int ossl_quic_wire_decode_frame_ping(PACKET *pkt);
int ossl_quic_wire_decode_frame_handshake_done(PACKET *pkt);
int ossl_quic_wire_peek_transport_param(PACKET *pkt, uint64_t *id);
const unsigned char *ossl_quic_wire_decode_transport_param_bytes(PACKET *pkt,
uint64_t *id,
size_t *len);
int ossl_quic_wire_decode_transport_param_int(PACKET *pkt,
uint64_t *id,
uint64_t *value);
int ossl_quic_wire_decode_transport_param_cid(PACKET *pkt,
uint64_t *id,
QUIC_CONN_ID *cid);
typedef struct quic_preferred_addr_st {
uint16_t ipv4_port, ipv6_port;
unsigned char ipv4[4], ipv6[16];
QUIC_STATELESS_RESET_TOKEN stateless_reset;
QUIC_CONN_ID cid;
} QUIC_PREFERRED_ADDR;
int ossl_quic_wire_decode_transport_param_preferred_addr(PACKET *pkt,
QUIC_PREFERRED_ADDR *p);
#endif
#endif