///|
pub(all) suberror SctpError {
InvalidPacket(String)
ChecksumMismatch
InvalidState(String)
AssociationFailed(String)
StreamResetFailed(UInt16)
MessageTooLarge(UInt64)
BufferFull
Time(@transport.TimeError)
CryptoUnavailable(String)
Closed
} derive(Debug, Eq)
///|
pub(all) enum Reliability {
Reliable
RetransmitCount(UInt16)
Timed(UInt)
} derive(Debug, Eq)
///|
pub(all) enum Ordering {
Ordered
Unordered
} derive(Debug, Eq)
///|
pub(all) struct StreamId(UInt16) derive(Debug, Eq, Hash)
///|
pub fn StreamId::value(self : StreamId) -> UInt16 {
let StreamId(value) = self
value
}
///|
pub struct Message {
stream : StreamId
protocol_id : UInt
unordered : Bool
payload : Bytes
} derive(Debug, Eq)
///|
pub fn Message::new(
stream~ : StreamId,
protocol_id~ : UInt,
unordered? : Bool = false,
payload~ : Bytes,
) -> Message {
{ stream, protocol_id, unordered, payload, }
}
///|
pub fn Message::stream(self : Message) -> StreamId {
self.stream
}
///|
pub fn Message::protocol_id(self : Message) -> UInt {
self.protocol_id
}
///|
pub fn Message::is_unordered(self : Message) -> Bool {
self.unordered
}
///|
pub fn Message::payload(self : Message) -> Bytes {
self.payload
}
///|
pub(all) enum AssociationRole {
Active
Passive
} derive(Debug, Eq)
///|
pub(all) enum AssociationState {
ClosedState
CookieWait
CookieEchoed
Established
ShutdownPending
ShutdownSent
ShutdownReceived
ShutdownAckSent
} derive(Debug, Eq)
///|
pub(all) enum AssociationEvent {
StateChanged(AssociationState)
MessageReceived(Message)
StreamReset(StreamId)
StreamResetAcknowledged(StreamId)
BufferedAmountLow(StreamId)
} derive(Debug, Eq)
///|
pub(all) enum Parameter {
StateCookieParameter(Bytes)
SupportedExtensionsParameter(Bytes)
ForwardTsnSupportedParameter
UnknownParameter(UInt16, Bytes)
} derive(Debug, Eq)
///|
pub struct InitChunk {
acknowledgement : Bool
initiate_tag : UInt
advertised_receiver_window : UInt
outbound_streams : UInt16
inbound_streams : UInt16
initial_tsn : UInt
parameters : Array[Parameter]
} derive(Debug, Eq)
///|
pub fn InitChunk::new(
acknowledgement? : Bool = false,
initiate_tag~ : UInt,
advertised_receiver_window? : UInt = 1048576U,
outbound_streams? : UInt16 = 65535,
inbound_streams? : UInt16 = 65535,
initial_tsn~ : UInt,
parameters? : Array[Parameter] = [],
) -> InitChunk raise SctpError {
if initiate_tag == 0U {
raise InvalidPacket("SCTP initiate tag must be nonzero")
}
if outbound_streams == 0 || inbound_streams == 0 {
raise InvalidPacket("SCTP stream counts must be nonzero")
}
{
acknowledgement,
initiate_tag,
advertised_receiver_window,
outbound_streams,
inbound_streams,
initial_tsn,
parameters: parameters.copy(),
}
}
///|
pub fn InitChunk::is_acknowledgement(self : InitChunk) -> Bool {
self.acknowledgement
}
///|
pub fn InitChunk::initiate_tag(self : InitChunk) -> UInt {
self.initiate_tag
}
///|
pub fn InitChunk::initial_tsn(self : InitChunk) -> UInt {
self.initial_tsn
}
///|
pub fn InitChunk::advertised_receiver_window(self : InitChunk) -> UInt {
self.advertised_receiver_window
}
///|
pub fn InitChunk::outbound_streams(self : InitChunk) -> UInt16 {
self.outbound_streams
}
///|
pub fn InitChunk::inbound_streams(self : InitChunk) -> UInt16 {
self.inbound_streams
}
///|
pub fn InitChunk::parameters(self : InitChunk) -> Array[Parameter] {
self.parameters.copy()
}
///|
pub struct DataChunk {
unordered : Bool
beginning : Bool
ending : Bool
immediate_sack : Bool
tsn : UInt
stream : StreamId
stream_sequence : UInt16
protocol_id : UInt
user_data : Bytes
} derive(Debug, Eq)
///|
pub fn DataChunk::new(
unordered? : Bool = false,
beginning? : Bool = true,
ending? : Bool = true,
immediate_sack? : Bool = false,
tsn~ : UInt,
stream~ : StreamId,
stream_sequence~ : UInt16,
protocol_id~ : UInt,
user_data~ : Bytes,
) -> DataChunk {
{
unordered,
beginning,
ending,
immediate_sack,
tsn,
stream,
stream_sequence,
protocol_id,
user_data,
}
}
///|
pub fn DataChunk::tsn(self : DataChunk) -> UInt {
self.tsn
}
///|
pub fn DataChunk::stream(self : DataChunk) -> StreamId {
self.stream
}
///|
pub fn DataChunk::stream_sequence(self : DataChunk) -> UInt16 {
self.stream_sequence
}
///|
pub fn DataChunk::protocol_id(self : DataChunk) -> UInt {
self.protocol_id
}
///|
pub fn DataChunk::is_unordered(self : DataChunk) -> Bool {
self.unordered
}
///|
pub fn DataChunk::is_beginning(self : DataChunk) -> Bool {
self.beginning
}
///|
pub fn DataChunk::is_ending(self : DataChunk) -> Bool {
self.ending
}
///|
pub fn DataChunk::user_data(self : DataChunk) -> Bytes {
self.user_data
}
///|
pub(all) struct GapAckBlock {
start : UInt16
end : UInt16
} derive(Debug, Eq)
///|
pub struct SackChunk {
cumulative_tsn_ack : UInt
advertised_receiver_window : UInt
gap_ack_blocks : Array[GapAckBlock]
duplicate_tsns : Array[UInt]
} derive(Debug, Eq)
///|
pub fn SackChunk::new(
cumulative_tsn_ack~ : UInt,
advertised_receiver_window? : UInt = 1048576U,
gap_ack_blocks? : Array[GapAckBlock] = [],
duplicate_tsns? : Array[UInt] = [],
) -> SackChunk {
{
cumulative_tsn_ack,
advertised_receiver_window,
gap_ack_blocks: gap_ack_blocks.copy(),
duplicate_tsns: duplicate_tsns.copy(),
}
}
///|
pub fn SackChunk::cumulative_tsn_ack(self : SackChunk) -> UInt {
self.cumulative_tsn_ack
}
///|
pub fn SackChunk::gap_ack_blocks(self : SackChunk) -> Array[GapAckBlock] {
self.gap_ack_blocks.copy()
}
///|
pub fn SackChunk::duplicate_tsns(self : SackChunk) -> Array[UInt] {
self.duplicate_tsns.copy()
}
///|
pub(all) enum ReconfigParameter {
OutgoingResetRequest(
request_sequence~ : UInt,
response_sequence~ : UInt,
sender_last_tsn~ : UInt,
streams~ : Array[StreamId]
)
ReconfigResponse(request_sequence~ : UInt, result~ : UInt)
UnknownReconfigParameter(UInt16, Bytes)
} derive(Debug, Eq)
///|
pub(all) struct ForwardTsnStream {
stream : StreamId
sequence : UInt16
} derive(Debug, Eq)
///|
pub fn ForwardTsnStream::new(
stream~ : StreamId,
sequence~ : UInt16,
) -> ForwardTsnStream {
{ stream, sequence, }
}
///|
pub fn ForwardTsnStream::stream(self : ForwardTsnStream) -> StreamId {
self.stream
}
///|
pub fn ForwardTsnStream::sequence(self : ForwardTsnStream) -> UInt16 {
self.sequence
}
///|
pub struct ForwardTsn {
new_cumulative_tsn : UInt
streams : Array[ForwardTsnStream]
} derive(Debug, Eq)
///|
pub fn ForwardTsn::new(
new_cumulative_tsn~ : UInt,
streams? : Array[ForwardTsnStream] = [],
) -> ForwardTsn {
{ new_cumulative_tsn, streams: streams.copy(), }
}
///|
pub fn ForwardTsn::new_cumulative_tsn(self : ForwardTsn) -> UInt {
self.new_cumulative_tsn
}
///|
pub fn ForwardTsn::streams(self : ForwardTsn) -> Array[ForwardTsnStream] {
self.streams.copy()
}
///|
pub(all) enum Chunk {
InitChunkValue(InitChunk)
DataChunkValue(DataChunk)
SackChunkValue(SackChunk)
HeartbeatChunk(Bytes)
HeartbeatAckChunk(Bytes)
AbortChunk(Bytes)
ShutdownChunk(UInt)
ShutdownAckChunk
ErrorChunk(Bytes)
CookieEchoChunk(Bytes)
CookieAckChunk
ShutdownCompleteChunk
ReconfigChunk(Array[ReconfigParameter])
ForwardTsnChunk(ForwardTsn)
UnknownChunk(Byte, Byte, Bytes)
} derive(Debug, Eq)
///|
pub struct Packet {
source_port : UInt16
destination_port : UInt16
verification_tag : UInt
chunks : Array[Chunk]
} derive(Debug, Eq)
///|
pub fn Packet::new(
source_port~ : UInt16,
destination_port~ : UInt16,
verification_tag~ : UInt,
chunks~ : Array[Chunk],
) -> Packet raise SctpError {
if source_port == 0 || destination_port == 0 {
raise InvalidPacket("SCTP ports must be nonzero")
}
{ source_port, destination_port, verification_tag, chunks: chunks.copy(), }
}
///|
pub fn Packet::source_port(self : Packet) -> UInt16 {
self.source_port
}
///|
pub fn Packet::destination_port(self : Packet) -> UInt16 {
self.destination_port
}
///|
pub fn Packet::verification_tag(self : Packet) -> UInt {
self.verification_tag
}
///|
pub fn Packet::chunks(self : Packet) -> Array[Chunk] {
self.chunks.copy()
}