Skip to content

Commit

Permalink
[SCTP] Ignore unknown parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
yngrtc committed Aug 18, 2024
1 parent d51a0ac commit 993c65b
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 39 deletions.
17 changes: 15 additions & 2 deletions rtc-sctp/src/param/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub(crate) mod param_requested_hmac_algorithm;
pub(crate) mod param_state_cookie;
pub(crate) mod param_supported_extensions;
pub(crate) mod param_type;
pub(crate) mod param_uknown;

use crate::param::{
param_chunk_list::ParamChunkList, param_forward_tsn_supported::ParamForwardTsnSupported,
Expand All @@ -20,6 +21,7 @@ use crate::param::{
param_reconfig_response::ParamReconfigResponse,
param_requested_hmac_algorithm::ParamRequestedHmacAlgorithm,
param_state_cookie::ParamStateCookie, param_supported_extensions::ParamSupportedExtensions,
param_uknown::ParamUnknown,
};
use param_header::*;
use param_type::*;
Expand Down Expand Up @@ -57,7 +59,8 @@ pub(crate) fn build_param(raw_param: &Bytes) -> Result<Box<dyn Param>> {
return Err(Error::ErrParamHeaderTooShort);
}
let reader = &mut raw_param.slice(..2);
let t: ParamType = reader.get_u16().into();
let raw_type = reader.get_u16();
let t: ParamType = raw_type.into();
match t {
ParamType::ForwardTsnSupp => Ok(Box::new(ParamForwardTsnSupported::unmarshal(raw_param)?)),
ParamType::SupportedExt => Ok(Box::new(ParamSupportedExtensions::unmarshal(raw_param)?)),
Expand All @@ -68,6 +71,16 @@ pub(crate) fn build_param(raw_param: &Bytes) -> Result<Box<dyn Param>> {
ParamType::HeartbeatInfo => Ok(Box::new(ParamHeartbeatInfo::unmarshal(raw_param)?)),
ParamType::OutSsnResetReq => Ok(Box::new(ParamOutgoingResetRequest::unmarshal(raw_param)?)),
ParamType::ReconfigResp => Ok(Box::new(ParamReconfigResponse::unmarshal(raw_param)?)),
_ => Err(Error::ErrParamTypeUnhandled),
_ => {
// According to RFC https://datatracker.ietf.org/doc/html/rfc4960#section-3.2.1
let stop_processing = ((raw_type >> 15) & 0x01) == 0;
if stop_processing {
Err(Error::ErrParamTypeUnhandled { typ: raw_type })
} else {
// We still might need to report this param as unrecognized.
// This depends on the context though.
Ok(Box::new(ParamUnknown::unmarshal(raw_param)?))
}
}
}
}
4 changes: 2 additions & 2 deletions rtc-sctp/src/param/param_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::{param_type::*, *};
use bytes::{Buf, BufMut, Bytes, BytesMut};
use std::fmt;

#[derive(Default, Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct ParamHeader {
pub(crate) typ: ParamType,
pub(crate) value_length: u16,
Expand Down Expand Up @@ -44,7 +44,7 @@ impl Param for ParamHeader {
}

fn marshal_to(&self, writer: &mut BytesMut) -> Result<usize> {
writer.put_u16(self.typ as u16);
writer.put_u16(self.typ.into());
writer.put_u16(self.value_length + PARAM_HEADER_LENGTH as u16);
Ok(writer.len())
}
Expand Down
95 changes: 65 additions & 30 deletions rtc-sctp/src/param/param_type.rs
Original file line number Diff line number Diff line change
@@ -1,63 +1,64 @@
use std::fmt;

/// paramType represents a SCTP INIT/INITACK parameter
#[derive(Default, Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq)]
#[repr(C)]
pub(crate) enum ParamType {
HeartbeatInfo = 1,
HeartbeatInfo,
/// Heartbeat Info [RFCRFC4960]
Ipv4Addr = 5,
Ipv4Addr,
/// IPv4 IP [RFCRFC4960]
Ipv6Addr = 6,
Ipv6Addr,
/// IPv6 IP [RFCRFC4960]
StateCookie = 7,
StateCookie,
/// State Cookie [RFCRFC4960]
UnrecognizedParam = 8,
UnrecognizedParam,
/// Unrecognized Parameters [RFCRFC4960]
CookiePreservative = 9,
CookiePreservative,
/// Cookie Preservative [RFCRFC4960]
HostNameAddr = 11,
HostNameAddr,
/// Host Name IP [RFCRFC4960]
SupportedAddrTypes = 12,
SupportedAddrTypes,
/// Supported IP Types [RFCRFC4960]
OutSsnResetReq = 13,
OutSsnResetReq,
/// Outgoing SSN Reset Request Parameter [RFCRFC6525]
IncSsnResetReq = 14,
IncSsnResetReq,
/// Incoming SSN Reset Request Parameter [RFCRFC6525]
SsnTsnResetReq = 15,
SsnTsnResetReq,
/// SSN/TSN Reset Request Parameter [RFCRFC6525]
ReconfigResp = 16,
ReconfigResp,
/// Re-configuration Response Parameter [RFCRFC6525]
AddOutStreamsReq = 17,
AddOutStreamsReq,
/// Add Outgoing Streams Request Parameter [RFCRFC6525]
AddIncStreamsReq = 18,
AddIncStreamsReq,
/// Add Incoming Streams Request Parameter [RFCRFC6525]
Random = 32770,
Random,
/// Random (0x8002) [RFCRFC4805]
ChunkList = 32771,
ChunkList,
/// Chunk List (0x8003) [RFCRFC4895]
ReqHmacAlgo = 32772,
ReqHmacAlgo,
/// Requested HMAC Algorithm Parameter (0x8004) [RFCRFC4895]
Padding = 32773,
Padding,
/// Padding (0x8005)
SupportedExt = 32776,
SupportedExt,
/// Supported Extensions (0x8008) [RFCRFC5061]
ForwardTsnSupp = 49152,
ForwardTsnSupp,
/// Forward TSN supported (0xC000) [RFCRFC3758]
AddIpAddr = 49153,
AddIpAddr,
/// Add IP IP (0xC001) [RFCRFC5061]
DelIpaddr = 49154,
DelIpaddr,
/// Delete IP IP (0xC002) [RFCRFC5061]
ErrClauseInd = 49155,
ErrClauseInd,
/// Error Cause Indication (0xC003) [RFCRFC5061]
SetPriAddr = 49156,
SetPriAddr,
/// Set Primary IP (0xC004) [RFCRFC5061]
SuccessInd = 49157,
SuccessInd,
/// Success Indication (0xC005) [RFCRFC5061]
AdaptLayerInd = 49158,
AdaptLayerInd,
/// Adaptation Layer Indication (0xC006) [RFCRFC5061]
#[default]
Unknown,
Unknown {
param_type: u16,
},
}

impl fmt::Display for ParamType {
Expand Down Expand Up @@ -123,7 +124,41 @@ impl From<u16> for ParamType {
49155 => ParamType::ErrClauseInd,
49156 => ParamType::SetPriAddr,
49157 => ParamType::SuccessInd,
_ => ParamType::Unknown,
_ => ParamType::Unknown { param_type: v },
}
}
}

impl From<ParamType> for u16 {
fn from(v: ParamType) -> u16 {
match v {
ParamType::HeartbeatInfo => 1,
ParamType::Ipv4Addr => 5,
ParamType::Ipv6Addr => 6,
ParamType::StateCookie => 7,
ParamType::UnrecognizedParam => 8,
ParamType::CookiePreservative => 9,
ParamType::HostNameAddr => 11,
ParamType::SupportedAddrTypes => 12,
ParamType::OutSsnResetReq => 13,
ParamType::IncSsnResetReq => 14,
ParamType::SsnTsnResetReq => 15,
ParamType::ReconfigResp => 16,
ParamType::AddOutStreamsReq => 17,
ParamType::AddIncStreamsReq => 18,
ParamType::Random => 32770,
ParamType::ChunkList => 32771,
ParamType::ReqHmacAlgo => 32772,
ParamType::Padding => 32773,
ParamType::SupportedExt => 32776,
ParamType::ForwardTsnSupp => 49152,
ParamType::AddIpAddr => 49153,
ParamType::DelIpaddr => 49154,
ParamType::ErrClauseInd => 49155,
ParamType::SetPriAddr => 49156,
ParamType::SuccessInd => 49157,
ParamType::AdaptLayerInd => 49158,
ParamType::Unknown { param_type, .. } => param_type,
}
}
}
66 changes: 66 additions & 0 deletions rtc-sctp/src/param/param_uknown.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use std::any::Any;
use std::fmt::{Debug, Display, Formatter};

use bytes::{Bytes, BytesMut};

use crate::param::param_header::{ParamHeader, PARAM_HEADER_LENGTH};
use crate::param::param_type::ParamType;
use crate::param::Param;
use shared::error::Result;

/// This type is meant to represent ANY parameter for un/remarshaling purposes, where we do not have a more specific type for it.
/// This means we do not really understand the semantics of the param but can represent it.
///
/// This is useful for usage in e.g.`ParamUnrecognized` where we want to report some unrecognized params back to the sender.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParamUnknown {
typ: u16,
value: Bytes,
}

impl Display for ParamUnknown {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "ParamUnknown( {} {:?} )", self.header(), self.value)
}
}

impl Param for ParamUnknown {
fn header(&self) -> ParamHeader {
ParamHeader {
typ: ParamType::Unknown {
param_type: self.typ,
},
value_length: self.value.len() as u16,
}
}

fn as_any(&self) -> &(dyn Any) {
self
}

fn unmarshal(raw: &Bytes) -> Result<Self>
where
Self: Sized,
{
let header = ParamHeader::unmarshal(raw)?;
let value = raw.slice(PARAM_HEADER_LENGTH..PARAM_HEADER_LENGTH + header.value_length());
Ok(Self {
typ: header.typ.into(),
value,
})
}

fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize> {
self.header().marshal_to(buf)?;
buf.extend(self.value.clone());
Ok(buf.len())
}

fn value_length(&self) -> usize {
self.value.len()
}

fn clone_to(&self) -> Box<dyn Param> {
Box::new(self.clone())
}
}
12 changes: 7 additions & 5 deletions rtc-shared/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,8 +928,8 @@ pub enum Error {
#[error("raw is too small for error cause")]
ErrErrorCauseTooSmall,

#[error("unhandled ParamType")]
ErrParamTypeUnhandled,
#[error("unhandled ParamType: {typ}")]
ErrParamTypeUnhandled { typ: u16 },

#[error("unexpected ParamType")]
ErrParamTypeUnexpected,
Expand Down Expand Up @@ -1095,7 +1095,7 @@ pub enum Error {

//Data Channel
#[error(
"DataChannel message is not long enough to determine type: (expected: {expected}, actual: {actual})"
"DataChannel message is not long enough to determine type: (expected: {expected}, actual: {actual})"
)]
UnexpectedEndOfBuffer { expected: usize, actual: usize },
#[error("Unknown MessageType {0}")]
Expand Down Expand Up @@ -1309,7 +1309,8 @@ pub enum Error {

/// ErrRegisterHeaderExtensionNoFreeID indicates that there was no extension ID available which
/// in turn means that all 15 available id(1 through 14) have been used.
#[error("no header extension ID was free to use(this means the maximum of 15 extensions have been registered)")]
#[error("no header extension ID was free to use(this means the maximum of 15 extensions have been registered)"
)]
ErrRegisterHeaderExtensionNoFreeID,

/// ErrSimulcastProbeOverflow indicates that too many Simulcast probe streams are in flight and the requested SSRC was ignored
Expand Down Expand Up @@ -1478,7 +1479,8 @@ pub enum Error {
SdpEmptyTimeDescription,
#[error("parse extmap: {0}")]
ParseExtMap(String),
#[error("{} --> {} <-- {}", .s.substring(0,*.p), .s.substring(*.p, *.p+1), .s.substring(*.p+1, .s.len()))]
#[error("{} --> {} <-- {}", .s.substring(0,*.p), .s.substring(*.p, *.p+1), .s.substring(*.p+1, .s.len())
)]
SyntaxError { s: String, p: usize },

//Third Party Error
Expand Down

0 comments on commit 993c65b

Please sign in to comment.