#include "common.hpp"
#include "MediaSoupErrors.hpp"
#include "RTC/SCTP/packet/Chunk.hpp"
#include "RTC/SCTP/packet/Parameter.hpp"
#include "RTC/SCTP/packet/chunks/InitChunk.hpp"
#include "RTC/SCTP/packet/parameters/CookiePreservativeParameter.hpp"
#include "RTC/SCTP/packet/parameters/IPv4AddressParameter.hpp"
#include "RTC/SCTP/packet/parameters/IPv6AddressParameter.hpp"
#include "RTC/SCTP/packet/parameters/SupportedAddressTypesParameter.hpp"
#include "test/include/RTC/SCTP/sctpCommon.hpp"
#include <catch2/catch_test_macros.hpp>
#include <cstring>
SCENARIO("SCTP Init Chunk (1)", "[serializable][sctp][chunk]")
{
sctpCommon::ResetBuffers();
SECTION("InitChunk::Parse() succeeds")
{
alignas(4) uint8_t buffer[] =
{
0x01, 0b00000000, 0x00, 0x38,
0x11, 0x22, 0x33, 0x44,
0xFF, 0x00, 0x66, 0x77,
0x12, 0x34, 0x56, 0x78,
0xAB, 0xCD, 0x01, 0x02,
0x00, 0x05, 0x00, 0x08,
0x02, 0x03, 0x04, 0x05,
0x00, 0x06, 0x00, 0x14,
0x20, 0x01, 0x0D, 0xB8,
0x85, 0xA3, 0x00, 0x00,
0x00, 0x00, 0x8A, 0x2E,
0x03, 0x70, 0x73, 0x34,
0x00, 0x09, 0x00, 0x08,
0x21, 0x32, 0x43, 0x54,
0xAA, 0xBB, 0xCC, 0xDD
};
auto* chunk = RTC::SCTP::InitChunk::Parse(buffer, sizeof(buffer));
CHECK_SCTP_CHUNK(
chunk,
buffer,
sizeof(buffer),
56,
RTC::SCTP::Chunk::ChunkType::INIT,
false,
RTC::SCTP::Chunk::ActionForUnknownChunkType::STOP,
0b00000000,
true,
3,
false,
0);
REQUIRE(chunk->GetInitiateTag() == 287454020);
REQUIRE(chunk->GetAdvertisedReceiverWindowCredit() == 4278216311);
REQUIRE(chunk->GetNumberOfOutboundStreams() == 4660);
REQUIRE(chunk->GetNumberOfInboundStreams() == 22136);
REQUIRE(chunk->GetInitialTsn() == 2882339074);
const auto* parameter1 =
reinterpret_cast<const RTC::SCTP::IPv4AddressParameter*>(chunk->GetParameterAt(0));
CHECK_SCTP_PARAMETER(
parameter1,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::IPV4_ADDRESS,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parameter1->GetIPv4Address()[0] == 0x02);
REQUIRE(parameter1->GetIPv4Address()[1] == 0x03);
REQUIRE(parameter1->GetIPv4Address()[2] == 0x04);
REQUIRE(parameter1->GetIPv4Address()[3] == 0x05);
const auto* parameter2 =
reinterpret_cast<const RTC::SCTP::IPv6AddressParameter*>(chunk->GetParameterAt(1));
CHECK_SCTP_PARAMETER(
parameter2,
nullptr,
20,
20,
RTC::SCTP::Parameter::ParameterType::IPV6_ADDRESS,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parameter2->GetIPv6Address()[0] == 0x20);
REQUIRE(parameter2->GetIPv6Address()[1] == 0x01);
REQUIRE(parameter2->GetIPv6Address()[2] == 0x0D);
REQUIRE(parameter2->GetIPv6Address()[3] == 0xB8);
REQUIRE(parameter2->GetIPv6Address()[15] == 0x34);
const auto* parameter3 =
reinterpret_cast<const RTC::SCTP::CookiePreservativeParameter*>(chunk->GetParameterAt(2));
CHECK_SCTP_PARAMETER(
parameter3,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::COOKIE_PRESERVATIVE,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parameter3->GetLifeSpanIncrement() == 556942164);
chunk->Serialize(sctpCommon::SerializeBuffer, sizeof(sctpCommon::SerializeBuffer));
std::memset(buffer, 0x00, sizeof(buffer));
CHECK_SCTP_CHUNK(
chunk,
sctpCommon::SerializeBuffer,
sizeof(sctpCommon::SerializeBuffer),
56,
RTC::SCTP::Chunk::ChunkType::INIT,
false,
RTC::SCTP::Chunk::ActionForUnknownChunkType::STOP,
0b00000000,
true,
3,
false,
0);
REQUIRE(chunk->GetInitiateTag() == 287454020);
REQUIRE(chunk->GetAdvertisedReceiverWindowCredit() == 4278216311);
REQUIRE(chunk->GetNumberOfOutboundStreams() == 4660);
REQUIRE(chunk->GetNumberOfInboundStreams() == 22136);
REQUIRE(chunk->GetInitialTsn() == 2882339074);
parameter1 = reinterpret_cast<const RTC::SCTP::IPv4AddressParameter*>(chunk->GetParameterAt(0));
CHECK_SCTP_PARAMETER(
parameter1,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::IPV4_ADDRESS,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parameter1->GetIPv4Address()[0] == 0x02);
REQUIRE(parameter1->GetIPv4Address()[1] == 0x03);
REQUIRE(parameter1->GetIPv4Address()[2] == 0x04);
REQUIRE(parameter1->GetIPv4Address()[3] == 0x05);
parameter2 = reinterpret_cast<const RTC::SCTP::IPv6AddressParameter*>(chunk->GetParameterAt(1));
CHECK_SCTP_PARAMETER(
parameter2,
nullptr,
20,
20,
RTC::SCTP::Parameter::ParameterType::IPV6_ADDRESS,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parameter2->GetIPv6Address()[0] == 0x20);
REQUIRE(parameter2->GetIPv6Address()[1] == 0x01);
REQUIRE(parameter2->GetIPv6Address()[2] == 0x0D);
REQUIRE(parameter2->GetIPv6Address()[3] == 0xB8);
REQUIRE(parameter2->GetIPv6Address()[15] == 0x34);
parameter3 =
reinterpret_cast<const RTC::SCTP::CookiePreservativeParameter*>(chunk->GetParameterAt(2));
CHECK_SCTP_PARAMETER(
parameter3,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::COOKIE_PRESERVATIVE,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parameter3->GetLifeSpanIncrement() == 556942164);
auto* clonedChunk = chunk->Clone(sctpCommon::CloneBuffer, sizeof(sctpCommon::CloneBuffer));
std::memset(sctpCommon::SerializeBuffer, 0x00, sizeof(sctpCommon::SerializeBuffer));
delete chunk;
CHECK_SCTP_CHUNK(
clonedChunk,
sctpCommon::CloneBuffer,
sizeof(sctpCommon::CloneBuffer),
56,
RTC::SCTP::Chunk::ChunkType::INIT,
false,
RTC::SCTP::Chunk::ActionForUnknownChunkType::STOP,
0b00000000,
true,
3,
false,
0);
REQUIRE(clonedChunk->GetInitiateTag() == 287454020);
REQUIRE(clonedChunk->GetAdvertisedReceiverWindowCredit() == 4278216311);
REQUIRE(clonedChunk->GetNumberOfOutboundStreams() == 4660);
REQUIRE(clonedChunk->GetNumberOfInboundStreams() == 22136);
REQUIRE(clonedChunk->GetInitialTsn() == 2882339074);
parameter1 =
reinterpret_cast<const RTC::SCTP::IPv4AddressParameter*>(clonedChunk->GetParameterAt(0));
CHECK_SCTP_PARAMETER(
parameter1,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::IPV4_ADDRESS,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parameter1->GetIPv4Address()[0] == 0x02);
REQUIRE(parameter1->GetIPv4Address()[1] == 0x03);
REQUIRE(parameter1->GetIPv4Address()[2] == 0x04);
REQUIRE(parameter1->GetIPv4Address()[3] == 0x05);
parameter2 =
reinterpret_cast<const RTC::SCTP::IPv6AddressParameter*>(clonedChunk->GetParameterAt(1));
CHECK_SCTP_PARAMETER(
parameter2,
nullptr,
20,
20,
RTC::SCTP::Parameter::ParameterType::IPV6_ADDRESS,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parameter2->GetIPv6Address()[0] == 0x20);
REQUIRE(parameter2->GetIPv6Address()[1] == 0x01);
REQUIRE(parameter2->GetIPv6Address()[2] == 0x0D);
REQUIRE(parameter2->GetIPv6Address()[3] == 0xB8);
REQUIRE(parameter2->GetIPv6Address()[15] == 0x34);
parameter3 =
reinterpret_cast<const RTC::SCTP::CookiePreservativeParameter*>(clonedChunk->GetParameterAt(2));
CHECK_SCTP_PARAMETER(
parameter3,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::COOKIE_PRESERVATIVE,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parameter3->GetLifeSpanIncrement() == 556942164);
delete clonedChunk;
}
SECTION("InitChunk::Factory() succeeds")
{
auto* chunk =
RTC::SCTP::InitChunk::Factory(sctpCommon::FactoryBuffer, sizeof(sctpCommon::FactoryBuffer));
CHECK_SCTP_CHUNK(
chunk,
sctpCommon::FactoryBuffer,
sizeof(sctpCommon::FactoryBuffer),
20,
RTC::SCTP::Chunk::ChunkType::INIT,
false,
RTC::SCTP::Chunk::ActionForUnknownChunkType::STOP,
0b00000000,
true,
0,
false,
0);
REQUIRE(chunk->GetInitiateTag() == 0);
REQUIRE(chunk->GetAdvertisedReceiverWindowCredit() == 0);
REQUIRE(chunk->GetNumberOfOutboundStreams() == 0);
REQUIRE(chunk->GetNumberOfInboundStreams() == 0);
REQUIRE(chunk->GetInitialTsn() == 0);
chunk->SetInitiateTag(1111111110);
chunk->SetAdvertisedReceiverWindowCredit(2222222220);
chunk->SetNumberOfOutboundStreams(1234);
chunk->SetNumberOfInboundStreams(5678);
chunk->SetInitialTsn(3333333330);
auto* parameter1 = chunk->BuildParameterInPlace<RTC::SCTP::IPv4AddressParameter>();
uint8_t ipBuffer1[] = { 0x0B, 0x16, 0x21, 0x2C };
parameter1->SetIPv4Address(ipBuffer1);
parameter1->Consolidate();
auto* parameter2 = chunk->BuildParameterInPlace<RTC::SCTP::IPv6AddressParameter>();
uint8_t ipBuffer2[] = { 0x23, 0x45, 0x04, 0x25, 0x2C, 0xA1, 0x00, 0x00,
0x00, 0x00, 0x05, 0x67, 0x56, 0x73, 0x23, 0xB5 };
parameter2->SetIPv6Address(ipBuffer2);
parameter2->Consolidate();
auto* parameter3 = chunk->BuildParameterInPlace<RTC::SCTP::CookiePreservativeParameter>();
parameter3->SetLifeSpanIncrement(876543210);
parameter3->Consolidate();
CHECK_SCTP_CHUNK(
chunk,
sctpCommon::FactoryBuffer,
sizeof(sctpCommon::FactoryBuffer),
56,
RTC::SCTP::Chunk::ChunkType::INIT,
false,
RTC::SCTP::Chunk::ActionForUnknownChunkType::STOP,
0b00000000,
true,
3,
false,
0);
REQUIRE(chunk->GetInitiateTag() == 1111111110);
REQUIRE(chunk->GetAdvertisedReceiverWindowCredit() == 2222222220);
REQUIRE(chunk->GetNumberOfOutboundStreams() == 1234);
REQUIRE(chunk->GetNumberOfInboundStreams() == 5678);
REQUIRE(chunk->GetInitialTsn() == 3333333330);
const auto* addedParameter1 =
reinterpret_cast<const RTC::SCTP::IPv4AddressParameter*>(chunk->GetParameterAt(0));
CHECK_SCTP_PARAMETER(
addedParameter1,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::IPV4_ADDRESS,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(addedParameter1->GetIPv4Address()[0] == 0x0B);
REQUIRE(addedParameter1->GetIPv4Address()[1] == 0x16);
REQUIRE(addedParameter1->GetIPv4Address()[2] == 0x21);
REQUIRE(addedParameter1->GetIPv4Address()[3] == 0x2C);
const auto* addedParameter2 =
reinterpret_cast<const RTC::SCTP::IPv6AddressParameter*>(chunk->GetParameterAt(1));
CHECK_SCTP_PARAMETER(
addedParameter2,
nullptr,
20,
20,
RTC::SCTP::Parameter::ParameterType::IPV6_ADDRESS,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(addedParameter2->GetIPv6Address()[0] == 0x23);
REQUIRE(addedParameter2->GetIPv6Address()[1] == 0x45);
REQUIRE(addedParameter2->GetIPv6Address()[2] == 0x04);
REQUIRE(addedParameter2->GetIPv6Address()[3] == 0x25);
REQUIRE(addedParameter2->GetIPv6Address()[15] == 0xB5);
const auto* addedParameter3 =
reinterpret_cast<const RTC::SCTP::CookiePreservativeParameter*>(chunk->GetParameterAt(2));
CHECK_SCTP_PARAMETER(
addedParameter3,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::COOKIE_PRESERVATIVE,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(addedParameter3->GetLifeSpanIncrement() == 876543210);
auto* parsedChunk = RTC::SCTP::InitChunk::Parse(chunk->GetBuffer(), chunk->GetLength());
delete chunk;
CHECK_SCTP_CHUNK(
parsedChunk,
sctpCommon::FactoryBuffer,
56,
56,
RTC::SCTP::Chunk::ChunkType::INIT,
false,
RTC::SCTP::Chunk::ActionForUnknownChunkType::STOP,
0b00000000,
true,
3,
false,
0);
REQUIRE(parsedChunk->GetInitiateTag() == 1111111110);
REQUIRE(parsedChunk->GetAdvertisedReceiverWindowCredit() == 2222222220);
REQUIRE(parsedChunk->GetNumberOfOutboundStreams() == 1234);
REQUIRE(parsedChunk->GetNumberOfInboundStreams() == 5678);
REQUIRE(parsedChunk->GetInitialTsn() == 3333333330);
const auto* parsedParameter1 =
reinterpret_cast<const RTC::SCTP::IPv4AddressParameter*>(parsedChunk->GetParameterAt(0));
CHECK_SCTP_PARAMETER(
parsedParameter1,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::IPV4_ADDRESS,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parsedParameter1->GetIPv4Address()[0] == 0x0B);
REQUIRE(parsedParameter1->GetIPv4Address()[1] == 0x16);
REQUIRE(parsedParameter1->GetIPv4Address()[2] == 0x21);
REQUIRE(parsedParameter1->GetIPv4Address()[3] == 0x2C);
const auto* parsedParameter2 =
reinterpret_cast<const RTC::SCTP::IPv6AddressParameter*>(parsedChunk->GetParameterAt(1));
CHECK_SCTP_PARAMETER(
parsedParameter2,
nullptr,
20,
20,
RTC::SCTP::Parameter::ParameterType::IPV6_ADDRESS,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parsedParameter2->GetIPv6Address()[0] == 0x23);
REQUIRE(parsedParameter2->GetIPv6Address()[1] == 0x45);
REQUIRE(parsedParameter2->GetIPv6Address()[2] == 0x04);
REQUIRE(parsedParameter2->GetIPv6Address()[3] == 0x25);
REQUIRE(parsedParameter2->GetIPv6Address()[15] == 0xB5);
const auto* parsedParameter3 =
reinterpret_cast<const RTC::SCTP::CookiePreservativeParameter*>(parsedChunk->GetParameterAt(2));
CHECK_SCTP_PARAMETER(
parsedParameter3,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::COOKIE_PRESERVATIVE,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(parsedParameter3->GetLifeSpanIncrement() == 876543210);
delete parsedChunk;
}
SECTION("InitChunk::Factory() using AddParameter() succeeds")
{
auto* chunk =
RTC::SCTP::InitChunk::Factory(sctpCommon::FactoryBuffer, sizeof(sctpCommon::FactoryBuffer));
chunk->SetInitiateTag(1);
chunk->SetAdvertisedReceiverWindowCredit(2);
chunk->SetNumberOfOutboundStreams(3);
chunk->SetNumberOfInboundStreams(4);
chunk->SetInitialTsn(5);
auto* parameter1 = RTC::SCTP::CookiePreservativeParameter::Factory(
sctpCommon::FactoryBuffer + 1000, sizeof(sctpCommon::FactoryBuffer));
parameter1->SetLifeSpanIncrement(123456);
chunk->AddParameter(parameter1);
delete parameter1;
CHECK_SCTP_CHUNK(
chunk,
sctpCommon::FactoryBuffer,
sizeof(sctpCommon::FactoryBuffer),
28,
RTC::SCTP::Chunk::ChunkType::INIT,
false,
RTC::SCTP::Chunk::ActionForUnknownChunkType::STOP,
0b00000000,
true,
1,
false,
0);
const auto* obtainedParameter1 =
reinterpret_cast<const RTC::SCTP::CookiePreservativeParameter*>(chunk->GetParameterAt(0));
CHECK_SCTP_PARAMETER(
obtainedParameter1,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::COOKIE_PRESERVATIVE,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(obtainedParameter1->GetLifeSpanIncrement() == 123456);
auto* parameter2 = RTC::SCTP::SupportedAddressTypesParameter::Factory(
sctpCommon::FactoryBuffer + 1000, sizeof(sctpCommon::FactoryBuffer));
parameter2->AddAddressType(1111);
parameter2->AddAddressType(2222);
parameter2->AddAddressType(3333);
chunk->AddParameter(parameter2);
delete parameter2;
CHECK_SCTP_CHUNK(
chunk,
sctpCommon::FactoryBuffer,
sizeof(sctpCommon::FactoryBuffer),
40,
RTC::SCTP::Chunk::ChunkType::INIT,
false,
RTC::SCTP::Chunk::ActionForUnknownChunkType::STOP,
0b00000000,
true,
2,
false,
0);
const auto* obtainedParameter2 =
reinterpret_cast<const RTC::SCTP::SupportedAddressTypesParameter*>(chunk->GetParameterAt(1));
CHECK_SCTP_PARAMETER(
obtainedParameter2,
nullptr,
12,
12,
RTC::SCTP::Parameter::ParameterType::SUPPORTED_ADDRESS_TYPES,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(obtainedParameter2->GetNumberOfAddressTypes() == 3);
REQUIRE(obtainedParameter2->GetAddressTypeAt(0) == 1111);
REQUIRE(obtainedParameter2->GetAddressTypeAt(1) == 2222);
REQUIRE(obtainedParameter2->GetAddressTypeAt(2) == 3333);
auto* parsedChunk = RTC::SCTP::InitChunk::Parse(chunk->GetBuffer(), chunk->GetLength());
delete chunk;
CHECK_SCTP_CHUNK(
parsedChunk,
sctpCommon::FactoryBuffer,
40,
40,
RTC::SCTP::Chunk::ChunkType::INIT,
false,
RTC::SCTP::Chunk::ActionForUnknownChunkType::STOP,
0b00000000,
true,
2,
false,
0);
REQUIRE(parsedChunk->GetInitiateTag() == 1);
REQUIRE(parsedChunk->GetAdvertisedReceiverWindowCredit() == 2);
REQUIRE(parsedChunk->GetNumberOfOutboundStreams() == 3);
REQUIRE(parsedChunk->GetNumberOfInboundStreams() == 4);
REQUIRE(parsedChunk->GetInitialTsn() == 5);
obtainedParameter1 =
reinterpret_cast<const RTC::SCTP::CookiePreservativeParameter*>(parsedChunk->GetParameterAt(0));
CHECK_SCTP_PARAMETER(
obtainedParameter1,
nullptr,
8,
8,
RTC::SCTP::Parameter::ParameterType::COOKIE_PRESERVATIVE,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(obtainedParameter1->GetLifeSpanIncrement() == 123456);
obtainedParameter2 = reinterpret_cast<const RTC::SCTP::SupportedAddressTypesParameter*>(
parsedChunk->GetParameterAt(1));
CHECK_SCTP_PARAMETER(
obtainedParameter2,
nullptr,
12,
12,
RTC::SCTP::Parameter::ParameterType::SUPPORTED_ADDRESS_TYPES,
false,
RTC::SCTP::Parameter::ActionForUnknownParameterType::STOP);
REQUIRE(obtainedParameter2->GetNumberOfAddressTypes() == 3);
REQUIRE(obtainedParameter2->GetAddressTypeAt(0) == 1111);
REQUIRE(obtainedParameter2->GetAddressTypeAt(1) == 2222);
REQUIRE(obtainedParameter2->GetAddressTypeAt(2) == 3333);
delete parsedChunk;
}
}