use std::{collections::HashMap, time::Duration};
use derive_builder::Builder;
use derive_more::From;
use qbase::param::{ClientParameters, ParameterId, ServerParameters};
use serde::{Deserialize, Serialize};
use super::{
ConnectionID, ECN, IPAddress, Owner, PacketHeader, PacketNumberSpace, PathEndpointInfo,
QuicFrame, QuicVersion, StatelessResetToken, StreamType,
};
use crate::{HexString, PathID, RawInfo};
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct VersionInformation {
#[serde(skip_serializing_if = "Vec::is_empty")]
server_versions: Vec<QuicVersion>,
#[serde(skip_serializing_if = "Vec::is_empty")]
client_versions: Vec<QuicVersion>,
chosen_version: Option<QuicVersion>,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct ALPNInformation {
server_alpns: Option<Vec<ALPNIdentifier>>,
client_alpns: Option<Vec<ALPNIdentifier>>,
chosen_alpn: Option<ALPNIdentifier>,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct ALPNIdentifier {
byte_value: Option<HexString>,
string_value: Option<String>,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct ParametersSet {
owner: Option<Owner>,
resumption_allowed: Option<bool>,
early_data_enabled: Option<bool>,
tls_cipher: Option<String>,
original_destination_connection_id: Option<ConnectionID>,
initial_source_connection_id: Option<ConnectionID>,
retry_source_connection_id: Option<ConnectionID>,
stateless_reset_token: Option<StatelessResetToken>,
disable_active_migration: Option<bool>,
max_idle_timeout: Option<u64>,
max_udp_payload_size: Option<u32>,
ack_delay_exponent: Option<u16>,
max_ack_delay: Option<u16>,
active_connection_id_limit: Option<u32>,
initial_max_data: Option<u64>,
initial_max_stream_data_bidi_local: Option<u64>,
initial_max_stream_data_bidi_remote: Option<u64>,
initial_max_stream_data_uni: Option<u64>,
initial_max_streams_bidi: Option<u64>,
initial_max_streams_uni: Option<u64>,
preferred_address: Option<PreferredAddress>,
unknown_parameters: Option<Vec<UnknownParameter>>,
max_datagram_frame_size: Option<u64>,
grease_quic_bit: Option<bool>,
}
macro_rules! extract_parameter {
( $(
$id:ident as $as:ident $(.map($($tt:tt)*))? from $set:ident to $this:ident.$field:ident
),* $(,)? ) => {
$( extract_parameter!(@one $id as $as $(.map($($tt)*))? from $set to $this.$field); )*
};
(@one $id:ident as $as:ident .map($($tt:tt)*) from $set:ident to $this:ident.$field:ident) => {
$this.$field = $this.$field.take().or_else(|| {
Some($set.get::<$as>(ParameterId::$id).map($($tt)*))
});
};
(@one $id:ident as $as:ident from $set:ident to $this:ident.$field:ident) => {
$this.$field = $this.$field.take().or_else(|| {
Some($set.get::<$as>(ParameterId::$id).map(Into::into))
});
};
}
impl ParametersSetBuilder {
pub fn client_parameters(&mut self, params: &ClientParameters) -> &mut Self {
use qbase::cid::ConnectionId;
extract_parameter! {
InitialSourceConnectionId as ConnectionId from params to self.initial_source_connection_id,
DisableActiveMigration as bool from params to self.disable_active_migration,
MaxIdleTimeout as Duration.map(|d| d.as_millis() as _) from params to self.max_idle_timeout,
MaxUdpPayloadSize as u64.map(|u| u as u32) from params to self.max_udp_payload_size,
AckDelayExponent as u64.map(|u| u as u16) from params to self.ack_delay_exponent,
MaxAckDelay as Duration.map(|d| d.as_millis() as _) from params to self.max_ack_delay,
ActiveConnectionIdLimit as u64.map(|u| u as u32) from params to self.active_connection_id_limit,
InitialMaxData as u64 from params to self.initial_max_data,
InitialMaxStreamDataBidiLocal as u64 from params to self.initial_max_stream_data_bidi_local,
InitialMaxStreamDataBidiRemote as u64 from params to self.initial_max_stream_data_bidi_remote,
InitialMaxStreamDataUni as u64 from params to self.initial_max_stream_data_uni,
InitialMaxStreamsBidi as u64 from params to self.initial_max_streams_bidi,
InitialMaxStreamsUni as u64 from params to self.initial_max_streams_uni,
MaxDatagramFrameSize as u64 from params to self.max_datagram_frame_size,
GreaseQuicBit as bool from params to self.grease_quic_bit,
}
self
}
pub fn server_parameters(&mut self, params: &ServerParameters) -> &mut Self {
use qbase::{
cid::ConnectionId, param::preferred_address::PreferredAddress, token::ResetToken,
};
extract_parameter! {
OriginalDestinationConnectionId as ConnectionId from params to self.original_destination_connection_id,
InitialSourceConnectionId as ConnectionId from params to self.initial_source_connection_id,
RetrySourceConnectionId as ConnectionId from params to self.retry_source_connection_id,
StatelessResetToken as ResetToken from params to self.stateless_reset_token,
DisableActiveMigration as bool from params to self.disable_active_migration,
MaxIdleTimeout as Duration.map(|d| d.as_millis() as _) from params to self.max_idle_timeout,
MaxUdpPayloadSize as u64.map(|u| u as u32) from params to self.max_udp_payload_size,
AckDelayExponent as u64.map(|u| u as u16) from params to self.ack_delay_exponent,
MaxAckDelay as Duration.map(|d| d.as_millis() as _) from params to self.max_ack_delay,
ActiveConnectionIdLimit as u64.map(|u| u as u32) from params to self.active_connection_id_limit,
InitialMaxData as u64 from params to self.initial_max_data,
InitialMaxStreamDataBidiLocal as u64 from params to self.initial_max_stream_data_bidi_local,
InitialMaxStreamDataBidiRemote as u64 from params to self.initial_max_stream_data_bidi_remote,
InitialMaxStreamDataUni as u64 from params to self.initial_max_stream_data_uni,
InitialMaxStreamsBidi as u64 from params to self.initial_max_streams_bidi,
InitialMaxStreamsUni as u64 from params to self.initial_max_streams_uni,
PreferredAddress as PreferredAddress from params to self.preferred_address,
MaxDatagramFrameSize as u64 from params to self.max_datagram_frame_size,
GreaseQuicBit as bool from params to self.grease_quic_bit,
}
self
}
}
#[derive(Builder, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(setter(into), build_fn(private, name = "fallible_build"))]
pub struct PreferredAddress {
ip_v4: IPAddress,
ip_v6: IPAddress,
port_v4: u16,
port_v6: u16,
connection_id: ConnectionID,
stateless_reset_token: StatelessResetToken,
}
impl From<qbase::param::preferred_address::PreferredAddress> for PreferredAddress {
fn from(pa: qbase::param::preferred_address::PreferredAddress) -> Self {
crate::build!(Self {
ip_v4: pa.address_v4().ip().to_string(),
ip_v6: pa.address_v6().ip().to_string(),
port_v4: pa.address_v4().port(),
port_v6: pa.address_v6().port(),
connection_id: pa.connection_id(),
stateless_reset_token: pa.stateless_reset_token(),
})
}
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(setter(into, strip_option), build_fn(private, name = "fallible_build"))]
pub struct UnknownParameter {
id: u64,
#[builder(default)]
value: Option<HexString>,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct ParametersRestored {
disable_active_migration: Option<bool>,
max_idle_timeout: Option<u64>,
max_udp_payload_size: Option<u32>,
active_connection_id_limit: Option<u32>,
initial_max_data: Option<u64>,
initial_max_stream_data_bidi_local: Option<u64>,
initial_max_stream_data_bidi_remote: Option<u64>,
initial_max_stream_data_uni: Option<u64>,
initial_max_streams_bidi: Option<u64>,
initial_max_streams_uni: Option<u64>,
max_datagram_frame_size: Option<u64>,
grease_quic_bit: Option<bool>,
}
impl ParametersRestoredBuilder {
pub fn client_parameters(&mut self, params: &ServerParameters) -> &mut Self {
extract_parameter! {
DisableActiveMigration as bool from params to self.disable_active_migration,
MaxIdleTimeout as Duration.map(|d| d.as_millis() as _) from params to self.max_idle_timeout,
MaxUdpPayloadSize as u64.map(|u| u as u32) from params to self.max_udp_payload_size,
ActiveConnectionIdLimit as u64.map(|u| u as u32) from params to self.active_connection_id_limit,
InitialMaxData as u64 from params to self.initial_max_data,
InitialMaxStreamDataBidiLocal as u64 from params to self.initial_max_stream_data_bidi_local,
InitialMaxStreamDataBidiRemote as u64 from params to self.initial_max_stream_data_bidi_remote,
InitialMaxStreamDataUni as u64 from params to self.initial_max_stream_data_uni,
InitialMaxStreamsBidi as u64 from params to self.initial_max_streams_bidi,
InitialMaxStreamsUni as u64 from params to self.initial_max_streams_uni,
MaxDatagramFrameSize as u64 from params to self.max_datagram_frame_size,
GreaseQuicBit as bool from params to self.grease_quic_bit,
}
self
}
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(setter(into, strip_option), build_fn(private, name = "fallible_build"))]
pub struct PacketSent {
header: PacketHeader,
#[builder(default)]
frames: Option<Vec<QuicFrame>>,
#[builder(default)]
stateless_reset_token: Option<StatelessResetToken>,
#[builder(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
supported_versions: Vec<QuicVersion>,
#[builder(default)]
raw: Option<RawInfo>,
#[builder(default)]
datagram_id: Option<u32>,
#[builder(default)]
#[serde(default)]
is_mtu_probe_packet: bool,
#[builder(default)]
trigger: Option<PacketSentTrigger>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum PacketSentTrigger {
RetransmitReordered,
RetransmitTimeout,
PtoProbe,
RetransmitCrypto,
CcBandwidthProbe,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(setter(into, strip_option), build_fn(private, name = "fallible_build"))]
pub struct PacketReceived {
header: PacketHeader,
#[builder(default)]
frames: Option<Vec<QuicFrame>>,
#[builder(default)]
stateless_reset_token: Option<StatelessResetToken>,
#[builder(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
supported_versions: Vec<QuicVersion>,
#[builder(default)]
raw: Option<RawInfo>,
#[builder(default)]
datagram_id: Option<u32>,
#[builder(default)]
trigger: Option<PacketReceivedTrigger>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum PacketReceivedTrigger {
KeysAvailable,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
#[serde(default)]
pub struct PacketDropped {
header: Option<PacketHeader>,
raw: Option<RawInfo>,
datagram_id: Option<u32>,
details: HashMap<String, serde_json::Value>,
trigger: Option<PacketDroppedTrigger>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum PacketDroppedTrigger {
InternalError,
Rejected,
Unsupported,
Invalid,
Duplicate,
ConnectionUnknown,
DecryptionFailure,
KeyUnavailable,
Genera,
}
impl From<qbase::packet::InvalidPacketNumber> for PacketDroppedTrigger {
fn from(value: qbase::packet::InvalidPacketNumber) -> Self {
match value {
qbase::packet::InvalidPacketNumber::TooOld
| qbase::packet::InvalidPacketNumber::TooLarge => PacketDroppedTrigger::Genera,
qbase::packet::InvalidPacketNumber::Duplicate => PacketDroppedTrigger::Duplicate,
}
}
}
impl From<qbase::packet::error::Error> for PacketDroppedTrigger {
fn from(error: qbase::packet::error::Error) -> Self {
match error {
qbase::packet::error::Error::UnsupportedVersion(_) => Self::Unsupported,
qbase::packet::error::Error::InvalidFixedBit
| qbase::packet::error::Error::InvalidReservedBits(_, _)
| qbase::packet::error::Error::IncompleteType(_)
| qbase::packet::error::Error::IncompleteHeader(_, _)
| qbase::packet::error::Error::IncompletePacket(_, _)
| qbase::packet::error::Error::UnderSampling(..) => Self::Invalid,
qbase::packet::error::Error::RemoveProtectionFailure
| qbase::packet::error::Error::DecryptPacketFailure => Self::DecryptionFailure,
}
}
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct PacketBuffered {
header: Option<PacketHeader>,
raw: Option<RawInfo>,
datagram_id: Option<u32>,
trigger: Option<PacketBufferedTrigger>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum PacketBufferedTrigger {
Backpressure,
KeysUnavailable,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct PacketsAcked {
packet_number_space: Option<PacketNumberSpace>,
#[serde(skip_serializing_if = "Vec::is_empty")]
packet_nubers: Vec<u64>,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct UdpDatagramsSent {
count: Option<u16>,
#[serde(skip_serializing_if = "Vec::is_empty")]
raw: Vec<RawInfo>,
#[serde(skip_serializing_if = "Vec::is_empty")]
ecn: Vec<ECN>,
#[serde(skip_serializing_if = "Vec::is_empty")]
datagram_ids: Vec<u32>,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct UdpDatagramsReceived {
count: Option<u16>,
#[serde(skip_serializing_if = "Vec::is_empty")]
raw: Vec<RawInfo>,
#[serde(skip_serializing_if = "Vec::is_empty")]
ecn: Vec<ECN>,
#[serde(skip_serializing_if = "Vec::is_empty")]
datagram_ids: Vec<u32>,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct UdpDatagramDropped {
raw: Option<RawInfo>,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(setter(into, strip_option), build_fn(private, name = "fallible_build"))]
pub struct StreamStateUpdated {
stream_id: u64,
#[builder(default)]
stream_type: Option<StreamType>,
#[builder(default)]
old: Option<StreamState>,
new: StreamState,
#[builder(default)]
stream_side: Option<StreamSide>,
}
#[derive(Debug, Clone, Copy, From, Serialize, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
pub enum StreamState {
Base(BaseStreamStates),
Granular(GranularStreamStates),
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum BaseStreamStates {
Idle,
Open,
Closed,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum GranularStreamStates {
HalfClosedLocal,
HalfClosedRemote,
Ready,
Send,
DataSent,
ResetSent,
ResetReceived,
Receive,
SizeKnown,
DataRead,
ResetRead,
DataReceived,
Destroyed,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum StreamSide {
Sending,
Receiving,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(setter(into, strip_option), build_fn(private, name = "fallible_build"))]
pub struct FramesProcessed {
frames: Vec<QuicFrame>,
#[builder(default)]
packet_numbers: Option<Vec<u64>>,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct StreamDataMoved {
stream_id: Option<u64>,
offset: Option<u64>,
length: Option<u64>,
from: Option<StreamDataLocation>,
to: Option<StreamDataLocation>,
additional_info: Option<DataMovedAdditionalInfo>,
raw: Option<RawInfo>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum StreamDataLocation {
Application,
Transport,
Network,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum DataMovedAdditionalInfo {
FinSet,
StreamReset,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(
default,
setter(into, strip_option),
build_fn(private, name = "fallible_build")
)]
pub struct DatagramDataMoved {
length: Option<u64>,
from: Option<StreamDataLocation>,
to: Option<StreamDataLocation>,
raw: Option<RawInfo>,
}
#[serde_with::skip_serializing_none]
#[derive(Builder, Debug, Clone, Serialize, Deserialize, PartialEq)]
#[builder(setter(into, strip_option), build_fn(private, name = "fallible_build"))]
pub struct MigrationStateUpdated {
#[builder(default)]
old: Option<MigrationState>,
new: MigrationState,
#[builder(default)]
path_id: Option<PathID>,
#[builder(default)]
path_remote: Option<PathEndpointInfo>,
#[builder(default)]
path_local: Option<PathEndpointInfo>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum MigrationState {
ProbingStarted,
ProbingAbandoned,
ProbingSuccessful,
MigrationStarted,
MigrationAbandoned,
MigrationComplete,
}
crate::gen_builder_method! {
VersionInformationBuilder => VersionInformation;
ALPNInformationBuilder => ALPNInformation;
ALPNIdentifierBuilder => ALPNIdentifier;
ParametersSetBuilder => ParametersSet;
PreferredAddressBuilder => PreferredAddress;
UnknownParameterBuilder => UnknownParameter;
ParametersRestoredBuilder => ParametersRestored;
PacketSentBuilder => PacketSent;
PacketReceivedBuilder => PacketReceived;
PacketDroppedBuilder => PacketDropped;
PacketBufferedBuilder => PacketBuffered;
PacketsAckedBuilder => PacketsAcked;
UdpDatagramsSentBuilder => UdpDatagramsSent;
UdpDatagramsReceivedBuilder => UdpDatagramsReceived;
UdpDatagramDroppedBuilder => UdpDatagramDropped;
StreamStateUpdatedBuilder => StreamStateUpdated;
FramesProcessedBuilder => FramesProcessed;
StreamDataMovedBuilder => StreamDataMoved;
DatagramDataMovedBuilder => DatagramDataMoved;
MigrationStateUpdatedBuilder => MigrationStateUpdated;
}
mod rollback {
use bytes::Bytes;
use super::*;
use crate::{build, legacy::quic as legacy};
impl From<QuicVersion> for legacy::QuicVersion {
#[inline]
fn from(value: QuicVersion) -> Self {
HexString::from(Bytes::from(value.0.to_be_bytes().to_vec())).into()
}
}
impl From<VersionInformation> for legacy::TransportVersionInformation {
fn from(vi: VersionInformation) -> Self {
build!(legacy::TransportVersionInformation {
server_versions: vi
.server_versions
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
client_versions: vi
.client_versions
.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
?chosen_version: vi.chosen_version,
})
}
}
impl From<ALPNIdentifier> for String {
fn from(value: ALPNIdentifier) -> Self {
value.string_value.as_ref().map_or(
value
.byte_value
.as_ref()
.map(|b| b.to_string())
.unwrap_or_default(),
|s| s.to_string(),
)
}
}
impl From<ALPNInformation> for legacy::TransportALPNInformation {
fn from(ai: ALPNInformation) -> Self {
build!(legacy::TransportALPNInformation {
?client_alpns: ai.client_alpns.map( |v| {
v.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
}),
?server_alpns: ai.server_alpns.map( |v| {
v.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
}),
?chosen_alpn: ai.chosen_alpn.map(String::from),
})
}
}
impl From<PreferredAddress> for legacy::PreferredAddress {
fn from(pa: PreferredAddress) -> Self {
build!(legacy::PreferredAddress {
ip_v4: pa.ip_v4,
ip_v6: pa.ip_v6,
port_v4: pa.port_v4,
port_v6: pa.port_v6,
connection_id: pa.connection_id,
stateless_reset_token: pa.stateless_reset_token,
})
}
}
impl From<ParametersSet> for legacy::TransportParametersSet {
fn from(ps: ParametersSet) -> Self {
build!(legacy::TransportParametersSet {
?owner: ps.owner,
?resumption_allowed: ps.resumption_allowed,
?early_data_enabled: ps.early_data_enabled,
?tls_cipher: ps.tls_cipher,
?original_destination_connection_id: ps.original_destination_connection_id,
?initial_source_connection_id: ps.initial_source_connection_id,
?retry_source_connection_id: ps.retry_source_connection_id,
?stateless_reset_token: ps.stateless_reset_token,
?disable_active_migration: ps.disable_active_migration,
?max_idle_timeout: ps.max_idle_timeout,
?max_udp_payload_size: ps.max_udp_payload_size,
?ack_delay_exponent: ps.ack_delay_exponent,
?max_ack_delay: ps.max_ack_delay,
?active_connection_id_limit: ps.active_connection_id_limit,
?initial_max_data: ps.initial_max_data,
?initial_max_stream_data_bidi_local: ps.initial_max_stream_data_bidi_local,
?initial_max_stream_data_bidi_remote: ps.initial_max_stream_data_bidi_remote,
?initial_max_stream_data_uni: ps.initial_max_stream_data_uni,
?initial_max_streams_bidi: ps.initial_max_streams_bidi,
?initial_max_streams_uni: ps.initial_max_streams_uni,
?preferred_address: ps.preferred_address,
})
}
}
impl From<ParametersRestored> for legacy::TransportParametersRestored {
fn from(value: ParametersRestored) -> Self {
build!(legacy::TransportParametersRestored {
?disable_active_migration: value.disable_active_migration,
?max_idle_timeout: value.max_idle_timeout,
?max_udp_payload_size: value.max_udp_payload_size,
?active_connection_id_limit: value.active_connection_id_limit,
?initial_max_data: value.initial_max_data,
?initial_max_stream_data_bidi_local: value.initial_max_stream_data_bidi_local,
?initial_max_stream_data_bidi_remote: value.initial_max_stream_data_bidi_remote,
?initial_max_stream_data_uni: value.initial_max_stream_data_uni,
?initial_max_streams_bidi: value.initial_max_streams_bidi,
?initial_max_streams_uni: value.initial_max_streams_uni,
})
}
}
impl From<PacketSentTrigger> for legacy::TransportPacketSentTrigger {
fn from(value: PacketSentTrigger) -> Self {
match value {
PacketSentTrigger::RetransmitReordered => Self::RetransmitReordered,
PacketSentTrigger::RetransmitTimeout => Self::RetransmitTimeout,
PacketSentTrigger::PtoProbe => Self::PtoProbe,
PacketSentTrigger::RetransmitCrypto => Self::RetransmitCrypto,
PacketSentTrigger::CcBandwidthProbe => Self::CcBandwidthProbe,
}
}
}
impl From<PacketSent> for legacy::TransportPacketSent {
fn from(value: PacketSent) -> Self {
build!(legacy::TransportPacketSent {
header: value.header,
?frames: value.frames.map(|v| {
v.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
}),
?stateless_reset_token: value.stateless_reset_token.map(|tk| Bytes::from(tk.0.to_vec())),
supported_versions: value.supported_versions.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
?raw: value.raw,
?datagram_id: value.datagram_id,
?trigger: value.trigger,
})
}
}
impl From<PacketReceivedTrigger> for legacy::TransportPacketReceivedTrigger {
#[inline]
fn from(value: PacketReceivedTrigger) -> Self {
match value {
PacketReceivedTrigger::KeysAvailable => Self::KeysAvailable,
}
}
}
impl From<PacketReceived> for legacy::TransportPacketReceived {
fn from(value: PacketReceived) -> Self {
build!(legacy::TransportPacketReceived {
header: value.header,
?frames: value.frames.map(|v| {
v.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
}),
?stateless_reset_token: value.stateless_reset_token.map(|tk| Bytes::from(tk.0.to_vec())),
supported_versions: value.supported_versions.into_iter()
.map(Into::into)
.collect::<Vec<_>>(),
?raw: value.raw,
?datagram_id: value.datagram_id,
?trigger: value.trigger,
})
}
}
impl TryFrom<PacketDroppedTrigger> for legacy::TransportpacketDroppedTrigger {
type Error = ();
#[inline]
fn try_from(value: PacketDroppedTrigger) -> Result<Self, ()> {
match value {
PacketDroppedTrigger::InternalError
| PacketDroppedTrigger::Invalid
| PacketDroppedTrigger::Genera
| PacketDroppedTrigger::DecryptionFailure
| PacketDroppedTrigger::Rejected => Err(()),
PacketDroppedTrigger::Unsupported => Ok(Self::UnsupportedVersion),
PacketDroppedTrigger::Duplicate => Ok(Self::Duplicate),
PacketDroppedTrigger::ConnectionUnknown => Ok(Self::UnknownConnectionId),
PacketDroppedTrigger::KeyUnavailable => Ok(Self::KeyUnavailable),
}
}
}
impl From<PacketDropped> for legacy::TransportPacketDropped {
fn from(value: PacketDropped) -> Self {
build!(legacy::TransportPacketDropped {
?header: value.header,
?raw: value.raw,
?datagram_id: value.datagram_id,
?trigger: value.trigger.and_then(|trigger| legacy::TransportpacketDroppedTrigger::try_from(trigger).ok()),
})
}
}
impl From<PacketBufferedTrigger> for legacy::TransportPacketBufferedTrigger {
#[inline]
fn from(value: PacketBufferedTrigger) -> Self {
match value {
PacketBufferedTrigger::Backpressure => Self::Backpressure,
PacketBufferedTrigger::KeysUnavailable => Self::KeysUnavailable,
}
}
}
impl From<PacketBuffered> for legacy::TransportPacketBuffered {
fn from(value: PacketBuffered) -> Self {
build!(legacy::TransportPacketBuffered {
?header: value.header,
?raw: value.raw,
?datagram_id: value.datagram_id,
?trigger: value.trigger,
})
}
}
impl From<PacketsAcked> for legacy::TransportPacketsAcked {
fn from(value: PacketsAcked) -> Self {
build!(legacy::TransportPacketsAcked {
?packet_number_space: value.packet_number_space,
packet_numbers: value.packet_nubers,
})
}
}
impl From<UdpDatagramsSent> for legacy::TransportDatagramsSent {
fn from(value: UdpDatagramsSent) -> Self {
build!(legacy::TransportDatagramsSent {
?count: value.count,
raw: value.raw.into_iter().collect::<Vec<_>>(),
datagram_ids: value.datagram_ids,
})
}
}
impl From<UdpDatagramsReceived> for legacy::TransportDatagramsReceived {
fn from(value: UdpDatagramsReceived) -> Self {
build!(legacy::TransportDatagramsReceived {
?count: value.count,
raw: value.raw.into_iter().collect::<Vec<_>>(),
datagram_ids: value.datagram_ids,
})
}
}
impl From<UdpDatagramDropped> for legacy::TransportDatagramDropped {
fn from(value: UdpDatagramDropped) -> Self {
build!(legacy::TransportDatagramDropped {
?raw: value.raw,
})
}
}
impl From<StreamState> for legacy::StreamState {
#[inline]
fn from(value: StreamState) -> Self {
match value {
StreamState::Base(BaseStreamStates::Idle) => Self::Idle,
StreamState::Base(BaseStreamStates::Open) => Self::Open,
StreamState::Base(BaseStreamStates::Closed) => Self::Closed,
StreamState::Granular(GranularStreamStates::HalfClosedLocal) => {
Self::HalfClosedLocal
}
StreamState::Granular(GranularStreamStates::HalfClosedRemote) => {
Self::HalfClosedRemote
}
StreamState::Granular(GranularStreamStates::Ready) => Self::Ready,
StreamState::Granular(GranularStreamStates::Send) => Self::Send,
StreamState::Granular(GranularStreamStates::DataSent) => Self::DataSent,
StreamState::Granular(GranularStreamStates::ResetSent) => Self::ResetSent,
StreamState::Granular(GranularStreamStates::ResetReceived) => Self::ResetReceived,
StreamState::Granular(GranularStreamStates::Receive) => Self::Receive,
StreamState::Granular(GranularStreamStates::SizeKnown) => Self::SizeKnown,
StreamState::Granular(GranularStreamStates::DataRead) => Self::DataRead,
StreamState::Granular(GranularStreamStates::ResetRead) => Self::ResetRead,
StreamState::Granular(GranularStreamStates::DataReceived) => Self::DataReceived,
StreamState::Granular(GranularStreamStates::Destroyed) => Self::Destroyed,
}
}
}
impl From<StreamSide> for legacy::StreamSide {
#[inline]
fn from(value: StreamSide) -> Self {
match value {
StreamSide::Sending => Self::Sending,
StreamSide::Receiving => Self::Receiving,
}
}
}
impl From<StreamStateUpdated> for legacy::TransportStreamStateUpdated {
fn from(value: StreamStateUpdated) -> Self {
build!(legacy::TransportStreamStateUpdated {
stream_id: value.stream_id,
?stream_type: value.stream_type,
?old: value.old,
new: value.new,
?stream_side: value.stream_side,
})
}
}
impl From<FramesProcessed> for legacy::TransportFramesProcessed {
fn from(value: FramesProcessed) -> Self {
assert!(
value.packet_numbers.as_ref().is_none()
|| value.packet_numbers.as_ref().is_some_and(|v| v.len() != 1),
"it not possible to do this convert"
);
build!(legacy::TransportFramesProcessed {
frames: value.frames.into_iter().map(Into::into).collect::<Vec<_>>(),
?packet_number: value.packet_numbers.map(|v| v[0]),
})
}
}
impl From<StreamDataLocation> for legacy::StreamDataLocation {
#[inline]
fn from(value: StreamDataLocation) -> Self {
match value {
StreamDataLocation::Application => Self::Application,
StreamDataLocation::Transport => Self::Transport,
StreamDataLocation::Network => Self::Network,
}
}
}
impl From<StreamDataMoved> for legacy::TransportDataMoved {
fn from(value: StreamDataMoved) -> Self {
build!(legacy::TransportDataMoved {
?stream_id: value.stream_id,
?offset: value.offset,
?length: value.length,
?from: value.from,
?to: value.to,
?data: value.raw.and_then(|raw| raw.data),
})
}
}
}