Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 14:04:28 +01:00
parent 81b91f4139
commit f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_BOUNDED_BYTE_READER_H_
#define NET_DCSCTP_PACKET_BOUNDED_BYTE_READER_H_
#include <cstdint>
#include "api/array_view.h"
namespace dcsctp {
// TODO(boivie): These generic functions - and possibly this entire class -
// could be a candidate to have added to rtc_base/. They should use compiler
// intrinsics as well.
namespace internal {
// Loads a 8-bit unsigned word at `data`.
inline uint8_t LoadBigEndian8(const uint8_t* data) {
return data[0];
}
// Loads a 16-bit unsigned word at `data`.
inline uint16_t LoadBigEndian16(const uint8_t* data) {
return (data[0] << 8) | data[1];
}
// Loads a 32-bit unsigned word at `data`.
inline uint32_t LoadBigEndian32(const uint8_t* data) {
return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
}
} // namespace internal
// BoundedByteReader wraps an ArrayView and divides it into two parts; A fixed
// size - which is the template parameter - and a variable size, which is what
// remains in `data` after the `FixedSize`.
//
// The BoundedByteReader provides methods to load/read big endian numbers from
// the FixedSize portion of the buffer, and these are read with static bounds
// checking, to avoid out-of-bounds accesses without a run-time penalty.
//
// The variable sized portion can either be used to create sub-readers, which
// themselves would provide compile-time bounds-checking, or the entire variable
// sized portion can be retrieved as an ArrayView.
template <int FixedSize>
class BoundedByteReader {
public:
explicit BoundedByteReader(rtc::ArrayView<const uint8_t> data) : data_(data) {
RTC_CHECK(data.size() >= FixedSize);
}
template <size_t offset>
uint8_t Load8() const {
static_assert(offset + sizeof(uint8_t) <= FixedSize, "Out-of-bounds");
return internal::LoadBigEndian8(&data_[offset]);
}
template <size_t offset>
uint16_t Load16() const {
static_assert(offset + sizeof(uint16_t) <= FixedSize, "Out-of-bounds");
static_assert((offset % sizeof(uint16_t)) == 0, "Unaligned access");
return internal::LoadBigEndian16(&data_[offset]);
}
template <size_t offset>
uint32_t Load32() const {
static_assert(offset + sizeof(uint32_t) <= FixedSize, "Out-of-bounds");
static_assert((offset % sizeof(uint32_t)) == 0, "Unaligned access");
return internal::LoadBigEndian32(&data_[offset]);
}
template <size_t SubSize>
BoundedByteReader<SubSize> sub_reader(size_t variable_offset) const {
RTC_CHECK(FixedSize + variable_offset + SubSize <= data_.size());
rtc::ArrayView<const uint8_t> sub_span =
data_.subview(FixedSize + variable_offset, SubSize);
return BoundedByteReader<SubSize>(sub_span);
}
size_t variable_data_size() const { return data_.size() - FixedSize; }
rtc::ArrayView<const uint8_t> variable_data() const {
return data_.subview(FixedSize, data_.size() - FixedSize);
}
private:
const rtc::ArrayView<const uint8_t> data_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_BOUNDED_BYTE_READER_H_

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_BOUNDED_BYTE_WRITER_H_
#define NET_DCSCTP_PACKET_BOUNDED_BYTE_WRITER_H_
#include <algorithm>
#include "api/array_view.h"
namespace dcsctp {
// TODO(boivie): These generic functions - and possibly this entire class -
// could be a candidate to have added to rtc_base/. They should use compiler
// intrinsics as well.
namespace internal {
// Stores a 8-bit unsigned word at `data`.
inline void StoreBigEndian8(uint8_t* data, uint8_t val) {
data[0] = val;
}
// Stores a 16-bit unsigned word at `data`.
inline void StoreBigEndian16(uint8_t* data, uint16_t val) {
data[0] = val >> 8;
data[1] = val;
}
// Stores a 32-bit unsigned word at `data`.
inline void StoreBigEndian32(uint8_t* data, uint32_t val) {
data[0] = val >> 24;
data[1] = val >> 16;
data[2] = val >> 8;
data[3] = val;
}
} // namespace internal
// BoundedByteWriter wraps an ArrayView and divides it into two parts; A fixed
// size - which is the template parameter - and a variable size, which is what
// remains in `data` after the `FixedSize`.
//
// The BoundedByteWriter provides methods to write big endian numbers to the
// FixedSize portion of the buffer, and these are written with static bounds
// checking, to avoid out-of-bounds accesses without a run-time penalty.
//
// The variable sized portion can either be used to create sub-writers, which
// themselves would provide compile-time bounds-checking, or data can be copied
// to it.
template <int FixedSize>
class BoundedByteWriter {
public:
explicit BoundedByteWriter(rtc::ArrayView<uint8_t> data) : data_(data) {
RTC_CHECK(data.size() >= FixedSize);
}
template <size_t offset>
void Store8(uint8_t value) {
static_assert(offset + sizeof(uint8_t) <= FixedSize, "Out-of-bounds");
internal::StoreBigEndian8(&data_[offset], value);
}
template <size_t offset>
void Store16(uint16_t value) {
static_assert(offset + sizeof(uint16_t) <= FixedSize, "Out-of-bounds");
static_assert((offset % sizeof(uint16_t)) == 0, "Unaligned access");
internal::StoreBigEndian16(&data_[offset], value);
}
template <size_t offset>
void Store32(uint32_t value) {
static_assert(offset + sizeof(uint32_t) <= FixedSize, "Out-of-bounds");
static_assert((offset % sizeof(uint32_t)) == 0, "Unaligned access");
internal::StoreBigEndian32(&data_[offset], value);
}
template <size_t SubSize>
BoundedByteWriter<SubSize> sub_writer(size_t variable_offset) {
RTC_CHECK(FixedSize + variable_offset + SubSize <= data_.size());
return BoundedByteWriter<SubSize>(
data_.subview(FixedSize + variable_offset, SubSize));
}
void CopyToVariableData(rtc::ArrayView<const uint8_t> source) {
size_t copy_size = std::min(source.size(), data_.size() - FixedSize);
if (source.data() == nullptr || copy_size == 0) {
return;
}
memcpy(data_.data() + FixedSize, source.data(), copy_size);
}
private:
rtc::ArrayView<uint8_t> data_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_BOUNDED_BYTE_WRITER_H_

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/abort_chunk.h"
#include <stdint.h>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.7
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 6 |Reserved |T| Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / zero or more Error Causes /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int AbortChunk::kType;
absl::optional<AbortChunk> AbortChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
absl::optional<Parameters> error_causes =
Parameters::Parse(reader->variable_data());
if (!error_causes.has_value()) {
return absl::nullopt;
}
uint8_t flags = reader->Load8<1>();
bool filled_in_verification_tag = (flags & (1 << kFlagsBitT)) == 0;
return AbortChunk(filled_in_verification_tag, *std::move(error_causes));
}
void AbortChunk::SerializeTo(std::vector<uint8_t>& out) const {
rtc::ArrayView<const uint8_t> error_causes = error_causes_.data();
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, error_causes.size());
writer.Store8<1>(filled_in_verification_tag_ ? 0 : (1 << kFlagsBitT));
writer.CopyToVariableData(error_causes);
}
std::string AbortChunk::ToString() const {
return "ABORT";
}
} // namespace dcsctp

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_ABORT_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_ABORT_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.7
struct AbortChunkConfig : ChunkConfig {
static constexpr int kType = 6;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class AbortChunk : public Chunk, public TLVTrait<AbortChunkConfig> {
public:
static constexpr int kType = AbortChunkConfig::kType;
AbortChunk(bool filled_in_verification_tag, Parameters error_causes)
: filled_in_verification_tag_(filled_in_verification_tag),
error_causes_(std::move(error_causes)) {}
AbortChunk(AbortChunk&& other) = default;
AbortChunk& operator=(AbortChunk&& other) = default;
static absl::optional<AbortChunk> Parse(rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
bool filled_in_verification_tag() const {
return filled_in_verification_tag_;
}
const Parameters& error_causes() const { return error_causes_; }
private:
static constexpr int kFlagsBitT = 0;
bool filled_in_verification_tag_;
Parameters error_causes_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_ABORT_CHUNK_H_

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/chunk.h"
#include <cstdint>
#include <memory>
#include <utility>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/common/math.h"
#include "net/dcsctp/packet/chunk/abort_chunk.h"
#include "net/dcsctp/packet/chunk/cookie_ack_chunk.h"
#include "net/dcsctp/packet/chunk/cookie_echo_chunk.h"
#include "net/dcsctp/packet/chunk/data_chunk.h"
#include "net/dcsctp/packet/chunk/error_chunk.h"
#include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
#include "net/dcsctp/packet/chunk/heartbeat_ack_chunk.h"
#include "net/dcsctp/packet/chunk/heartbeat_request_chunk.h"
#include "net/dcsctp/packet/chunk/idata_chunk.h"
#include "net/dcsctp/packet/chunk/iforward_tsn_chunk.h"
#include "net/dcsctp/packet/chunk/init_ack_chunk.h"
#include "net/dcsctp/packet/chunk/init_chunk.h"
#include "net/dcsctp/packet/chunk/reconfig_chunk.h"
#include "net/dcsctp/packet/chunk/sack_chunk.h"
#include "net/dcsctp/packet/chunk/shutdown_ack_chunk.h"
#include "net/dcsctp/packet/chunk/shutdown_chunk.h"
#include "net/dcsctp/packet/chunk/shutdown_complete_chunk.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
template <class Chunk>
bool ParseAndPrint(uint8_t chunk_type,
rtc::ArrayView<const uint8_t> data,
rtc::StringBuilder& sb) {
if (chunk_type == Chunk::kType) {
absl::optional<Chunk> c = Chunk::Parse(data);
if (c.has_value()) {
sb << c->ToString();
} else {
sb << "Failed to parse chunk of type " << chunk_type;
}
return true;
}
return false;
}
std::string DebugConvertChunkToString(rtc::ArrayView<const uint8_t> data) {
rtc::StringBuilder sb;
if (data.empty()) {
sb << "Failed to parse chunk due to empty data";
} else {
uint8_t chunk_type = data[0];
if (!ParseAndPrint<DataChunk>(chunk_type, data, sb) &&
!ParseAndPrint<InitChunk>(chunk_type, data, sb) &&
!ParseAndPrint<InitAckChunk>(chunk_type, data, sb) &&
!ParseAndPrint<SackChunk>(chunk_type, data, sb) &&
!ParseAndPrint<HeartbeatRequestChunk>(chunk_type, data, sb) &&
!ParseAndPrint<HeartbeatAckChunk>(chunk_type, data, sb) &&
!ParseAndPrint<AbortChunk>(chunk_type, data, sb) &&
!ParseAndPrint<ErrorChunk>(chunk_type, data, sb) &&
!ParseAndPrint<CookieEchoChunk>(chunk_type, data, sb) &&
!ParseAndPrint<CookieAckChunk>(chunk_type, data, sb) &&
!ParseAndPrint<ShutdownChunk>(chunk_type, data, sb) &&
!ParseAndPrint<ShutdownAckChunk>(chunk_type, data, sb) &&
!ParseAndPrint<ShutdownCompleteChunk>(chunk_type, data, sb) &&
!ParseAndPrint<ReConfigChunk>(chunk_type, data, sb) &&
!ParseAndPrint<ForwardTsnChunk>(chunk_type, data, sb) &&
!ParseAndPrint<IDataChunk>(chunk_type, data, sb) &&
!ParseAndPrint<IForwardTsnChunk>(chunk_type, data, sb)) {
sb << "Unhandled chunk type: " << static_cast<int>(chunk_type);
}
}
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_CHUNK_H_
#include <stddef.h>
#include <sys/types.h>
#include <cstdint>
#include <iterator>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/algorithm/container.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/data.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// Base class for all SCTP chunks
class Chunk {
public:
Chunk() {}
virtual ~Chunk() = default;
// Chunks can contain data payloads that shouldn't be copied unnecessarily.
Chunk(Chunk&& other) = default;
Chunk& operator=(Chunk&& other) = default;
Chunk(const Chunk&) = delete;
Chunk& operator=(const Chunk&) = delete;
// Serializes the chunk to `out`, growing it as necessary.
virtual void SerializeTo(std::vector<uint8_t>& out) const = 0;
// Returns a human readable description of this chunk and its parameters.
virtual std::string ToString() const = 0;
};
// Introspects the chunk in `data` and returns a human readable textual
// representation of it, to be used in debugging.
std::string DebugConvertChunkToString(rtc::ArrayView<const uint8_t> data);
struct ChunkConfig {
static constexpr int kTypeSizeInBytes = 1;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_CHUNK_H_

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/cookie_ack_chunk.h"
#include <stdint.h>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.12
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 11 |Chunk Flags | Length = 4 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int CookieAckChunk::kType;
absl::optional<CookieAckChunk> CookieAckChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
if (!ParseTLV(data).has_value()) {
return absl::nullopt;
}
return CookieAckChunk();
}
void CookieAckChunk::SerializeTo(std::vector<uint8_t>& out) const {
AllocateTLV(out);
}
std::string CookieAckChunk::ToString() const {
return "COOKIE-ACK";
}
} // namespace dcsctp

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_COOKIE_ACK_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_COOKIE_ACK_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.12
struct CookieAckChunkConfig : ChunkConfig {
static constexpr int kType = 11;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 0;
};
class CookieAckChunk : public Chunk, public TLVTrait<CookieAckChunkConfig> {
public:
static constexpr int kType = CookieAckChunkConfig::kType;
CookieAckChunk() {}
static absl::optional<CookieAckChunk> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_COOKIE_ACK_CHUNK_H_

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/cookie_echo_chunk.h"
#include <stdint.h>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.11
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 10 |Chunk Flags | Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / Cookie /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int CookieEchoChunk::kType;
absl::optional<CookieEchoChunk> CookieEchoChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
return CookieEchoChunk(reader->variable_data());
}
void CookieEchoChunk::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, cookie_.size());
writer.CopyToVariableData(cookie_);
}
std::string CookieEchoChunk::ToString() const {
return "COOKIE-ECHO";
}
} // namespace dcsctp

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_COOKIE_ECHO_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_COOKIE_ECHO_CHUNK_H_
#include <stddef.h>
#include <cstdint>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.11
struct CookieEchoChunkConfig : ChunkConfig {
static constexpr int kType = 10;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class CookieEchoChunk : public Chunk, public TLVTrait<CookieEchoChunkConfig> {
public:
static constexpr int kType = CookieEchoChunkConfig::kType;
explicit CookieEchoChunk(rtc::ArrayView<const uint8_t> cookie)
: cookie_(cookie.begin(), cookie.end()) {}
static absl::optional<CookieEchoChunk> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
rtc::ArrayView<const uint8_t> cookie() const { return cookie_; }
private:
std::vector<uint8_t> cookie_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_COOKIE_ECHO_CHUNK_H_

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/data_chunk.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/chunk/data_common.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.1
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 0 | Reserved|U|B|E| Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | TSN |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream Identifier S | Stream Sequence Number n |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Payload Protocol Identifier |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / User Data (seq n of Stream S) /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int DataChunk::kType;
absl::optional<DataChunk> DataChunk::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
uint8_t flags = reader->Load8<1>();
TSN tsn(reader->Load32<4>());
StreamID stream_identifier(reader->Load16<8>());
SSN ssn(reader->Load16<10>());
PPID ppid(reader->Load32<12>());
Options options;
options.is_end = Data::IsEnd((flags & (1 << kFlagsBitEnd)) != 0);
options.is_beginning =
Data::IsBeginning((flags & (1 << kFlagsBitBeginning)) != 0);
options.is_unordered = IsUnordered((flags & (1 << kFlagsBitUnordered)) != 0);
options.immediate_ack =
ImmediateAckFlag((flags & (1 << kFlagsBitImmediateAck)) != 0);
return DataChunk(tsn, stream_identifier, ssn, ppid,
std::vector<uint8_t>(reader->variable_data().begin(),
reader->variable_data().end()),
options);
}
void DataChunk::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, payload().size());
writer.Store8<1>(
(*options().is_end ? (1 << kFlagsBitEnd) : 0) |
(*options().is_beginning ? (1 << kFlagsBitBeginning) : 0) |
(*options().is_unordered ? (1 << kFlagsBitUnordered) : 0) |
(*options().immediate_ack ? (1 << kFlagsBitImmediateAck) : 0));
writer.Store32<4>(*tsn());
writer.Store16<8>(*stream_id());
writer.Store16<10>(*ssn());
writer.Store32<12>(*ppid());
writer.CopyToVariableData(payload());
}
std::string DataChunk::ToString() const {
rtc::StringBuilder sb;
sb << "DATA, type=" << (options().is_unordered ? "unordered" : "ordered")
<< "::"
<< (*options().is_beginning && *options().is_end ? "complete"
: *options().is_beginning ? "first"
: *options().is_end ? "last"
: "middle")
<< ", tsn=" << *tsn() << ", sid=" << *stream_id() << ", ssn=" << *ssn()
<< ", ppid=" << *ppid() << ", length=" << payload().size();
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_DATA_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_DATA_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/chunk/data_common.h"
#include "net/dcsctp/packet/data.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.1
struct DataChunkConfig : ChunkConfig {
static constexpr int kType = 0;
static constexpr size_t kHeaderSize = 16;
static constexpr size_t kVariableLengthAlignment = 1;
};
class DataChunk : public AnyDataChunk, public TLVTrait<DataChunkConfig> {
public:
static constexpr int kType = DataChunkConfig::kType;
// Exposed to allow the retransmission queue to make room for the correct
// header size.
static constexpr size_t kHeaderSize = DataChunkConfig::kHeaderSize;
DataChunk(TSN tsn,
StreamID stream_id,
SSN ssn,
PPID ppid,
std::vector<uint8_t> payload,
const Options& options)
: AnyDataChunk(tsn,
stream_id,
ssn,
MID(0),
FSN(0),
ppid,
std::move(payload),
options) {}
DataChunk(TSN tsn, Data&& data, bool immediate_ack)
: AnyDataChunk(tsn, std::move(data), immediate_ack) {}
static absl::optional<DataChunk> Parse(rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_DATA_CHUNK_H_

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_DATA_COMMON_H_
#define NET_DCSCTP_PACKET_CHUNK_DATA_COMMON_H_
#include <stdint.h>
#include <utility>
#include <vector>
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/data.h"
namespace dcsctp {
// Base class for DataChunk and IDataChunk
class AnyDataChunk : public Chunk {
public:
// Represents the "immediate ack" flag on DATA/I-DATA, from RFC7053.
using ImmediateAckFlag = webrtc::StrongAlias<class ImmediateAckFlagTag, bool>;
// Data chunk options.
// See https://tools.ietf.org/html/rfc4960#section-3.3.1
struct Options {
Data::IsEnd is_end = Data::IsEnd(false);
Data::IsBeginning is_beginning = Data::IsBeginning(false);
IsUnordered is_unordered = IsUnordered(false);
ImmediateAckFlag immediate_ack = ImmediateAckFlag(false);
};
TSN tsn() const { return tsn_; }
Options options() const {
Options options;
options.is_end = data_.is_end;
options.is_beginning = data_.is_beginning;
options.is_unordered = data_.is_unordered;
options.immediate_ack = immediate_ack_;
return options;
}
StreamID stream_id() const { return data_.stream_id; }
SSN ssn() const { return data_.ssn; }
MID mid() const { return data_.mid; }
FSN fsn() const { return data_.fsn; }
PPID ppid() const { return data_.ppid; }
rtc::ArrayView<const uint8_t> payload() const { return data_.payload; }
// Extracts the Data from the chunk, as a destructive action.
Data extract() && { return std::move(data_); }
AnyDataChunk(TSN tsn,
StreamID stream_id,
SSN ssn,
MID mid,
FSN fsn,
PPID ppid,
std::vector<uint8_t> payload,
const Options& options)
: tsn_(tsn),
data_(stream_id,
ssn,
mid,
fsn,
ppid,
std::move(payload),
options.is_beginning,
options.is_end,
options.is_unordered),
immediate_ack_(options.immediate_ack) {}
AnyDataChunk(TSN tsn, Data data, bool immediate_ack)
: tsn_(tsn), data_(std::move(data)), immediate_ack_(immediate_ack) {}
protected:
// Bits in `flags` header field.
static constexpr int kFlagsBitEnd = 0;
static constexpr int kFlagsBitBeginning = 1;
static constexpr int kFlagsBitUnordered = 2;
static constexpr int kFlagsBitImmediateAck = 3;
private:
TSN tsn_;
Data data_;
ImmediateAckFlag immediate_ack_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_DATA_COMMON_H_

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/error_chunk.h"
#include <stdint.h>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 9 | Chunk Flags | Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / one or more Error Causes /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ErrorChunk::kType;
absl::optional<ErrorChunk> ErrorChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
absl::optional<Parameters> error_causes =
Parameters::Parse(reader->variable_data());
if (!error_causes.has_value()) {
return absl::nullopt;
}
return ErrorChunk(*std::move(error_causes));
}
void ErrorChunk::SerializeTo(std::vector<uint8_t>& out) const {
rtc::ArrayView<const uint8_t> error_causes = error_causes_.data();
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, error_causes.size());
writer.CopyToVariableData(error_causes);
}
std::string ErrorChunk::ToString() const {
return "ERROR";
}
} // namespace dcsctp

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_ERROR_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_ERROR_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10
struct ErrorChunkConfig : ChunkConfig {
static constexpr int kType = 9;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 4;
};
class ErrorChunk : public Chunk, public TLVTrait<ErrorChunkConfig> {
public:
static constexpr int kType = ErrorChunkConfig::kType;
explicit ErrorChunk(Parameters error_causes)
: error_causes_(std::move(error_causes)) {}
ErrorChunk(ErrorChunk&& other) = default;
ErrorChunk& operator=(ErrorChunk&& other) = default;
static absl::optional<ErrorChunk> Parse(rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
const Parameters& error_causes() const { return error_causes_; }
private:
Parameters error_causes_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_ERROR_CHUNK_H_

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc3758#section-3.2
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 192 | Flags = 0x00 | Length = Variable |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | New Cumulative TSN |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream-1 | Stream Sequence-1 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ /
// / \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream-N | Stream Sequence-N |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ForwardTsnChunk::kType;
absl::optional<ForwardTsnChunk> ForwardTsnChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
TSN new_cumulative_tsn(reader->Load32<4>());
size_t streams_skipped =
reader->variable_data_size() / kSkippedStreamBufferSize;
std::vector<SkippedStream> skipped_streams;
skipped_streams.reserve(streams_skipped);
for (size_t i = 0; i < streams_skipped; ++i) {
BoundedByteReader<kSkippedStreamBufferSize> sub_reader =
reader->sub_reader<kSkippedStreamBufferSize>(i *
kSkippedStreamBufferSize);
StreamID stream_id(sub_reader.Load16<0>());
SSN ssn(sub_reader.Load16<2>());
skipped_streams.emplace_back(stream_id, ssn);
}
return ForwardTsnChunk(new_cumulative_tsn, std::move(skipped_streams));
}
void ForwardTsnChunk::SerializeTo(std::vector<uint8_t>& out) const {
rtc::ArrayView<const SkippedStream> skipped = skipped_streams();
size_t variable_size = skipped.size() * kSkippedStreamBufferSize;
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);
writer.Store32<4>(*new_cumulative_tsn());
for (size_t i = 0; i < skipped.size(); ++i) {
BoundedByteWriter<kSkippedStreamBufferSize> sub_writer =
writer.sub_writer<kSkippedStreamBufferSize>(i *
kSkippedStreamBufferSize);
sub_writer.Store16<0>(*skipped[i].stream_id);
sub_writer.Store16<2>(*skipped[i].ssn);
}
}
std::string ForwardTsnChunk::ToString() const {
rtc::StringBuilder sb;
sb << "FORWARD-TSN, new_cumulative_tsn=" << *new_cumulative_tsn();
for (const auto& skipped : skipped_streams()) {
sb << ", skip " << skipped.stream_id.value() << ":" << *skipped.ssn;
}
return sb.str();
}
} // namespace dcsctp

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_FORWARD_TSN_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_FORWARD_TSN_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc3758#section-3.2
struct ForwardTsnChunkConfig : ChunkConfig {
static constexpr int kType = 192;
static constexpr size_t kHeaderSize = 8;
static constexpr size_t kVariableLengthAlignment = 4;
};
class ForwardTsnChunk : public AnyForwardTsnChunk,
public TLVTrait<ForwardTsnChunkConfig> {
public:
static constexpr int kType = ForwardTsnChunkConfig::kType;
ForwardTsnChunk(TSN new_cumulative_tsn,
std::vector<SkippedStream> skipped_streams)
: AnyForwardTsnChunk(new_cumulative_tsn, std::move(skipped_streams)) {}
static absl::optional<ForwardTsnChunk> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
private:
static constexpr size_t kSkippedStreamBufferSize = 4;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_FORWARD_TSN_CHUNK_H_

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_FORWARD_TSN_COMMON_H_
#define NET_DCSCTP_PACKET_CHUNK_FORWARD_TSN_COMMON_H_
#include <stdint.h>
#include <utility>
#include <vector>
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
namespace dcsctp {
// Base class for both ForwardTsnChunk and IForwardTsnChunk
class AnyForwardTsnChunk : public Chunk {
public:
struct SkippedStream {
SkippedStream(StreamID stream_id, SSN ssn)
: stream_id(stream_id), ssn(ssn), unordered(false), mid(0) {}
SkippedStream(IsUnordered unordered, StreamID stream_id, MID mid)
: stream_id(stream_id), ssn(0), unordered(unordered), mid(mid) {}
StreamID stream_id;
// Set for FORWARD_TSN
SSN ssn;
// Set for I-FORWARD_TSN
IsUnordered unordered;
MID mid;
bool operator==(const SkippedStream& other) const {
return stream_id == other.stream_id && ssn == other.ssn &&
unordered == other.unordered && mid == other.mid;
}
};
AnyForwardTsnChunk(TSN new_cumulative_tsn,
std::vector<SkippedStream> skipped_streams)
: new_cumulative_tsn_(new_cumulative_tsn),
skipped_streams_(std::move(skipped_streams)) {}
TSN new_cumulative_tsn() const { return new_cumulative_tsn_; }
rtc::ArrayView<const SkippedStream> skipped_streams() const {
return skipped_streams_;
}
private:
TSN new_cumulative_tsn_;
std::vector<SkippedStream> skipped_streams_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_FORWARD_TSN_COMMON_H_

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/heartbeat_ack_chunk.h"
#include <stdint.h>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.6
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 5 | Chunk Flags | Heartbeat Ack Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / Heartbeat Information TLV (Variable-Length) /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int HeartbeatAckChunk::kType;
absl::optional<HeartbeatAckChunk> HeartbeatAckChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
absl::optional<Parameters> parameters =
Parameters::Parse(reader->variable_data());
if (!parameters.has_value()) {
return absl::nullopt;
}
return HeartbeatAckChunk(*std::move(parameters));
}
void HeartbeatAckChunk::SerializeTo(std::vector<uint8_t>& out) const {
rtc::ArrayView<const uint8_t> parameters = parameters_.data();
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());
writer.CopyToVariableData(parameters);
}
std::string HeartbeatAckChunk::ToString() const {
return "HEARTBEAT-ACK";
}
} // namespace dcsctp

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_ACK_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_ACK_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/parameter/heartbeat_info_parameter.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.6
struct HeartbeatAckChunkConfig : ChunkConfig {
static constexpr int kType = 5;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class HeartbeatAckChunk : public Chunk,
public TLVTrait<HeartbeatAckChunkConfig> {
public:
static constexpr int kType = HeartbeatAckChunkConfig::kType;
explicit HeartbeatAckChunk(Parameters parameters)
: parameters_(std::move(parameters)) {}
HeartbeatAckChunk(HeartbeatAckChunk&& other) = default;
HeartbeatAckChunk& operator=(HeartbeatAckChunk&& other) = default;
static absl::optional<HeartbeatAckChunk> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
const Parameters& parameters() const { return parameters_; }
absl::optional<HeartbeatInfoParameter> info() const {
return parameters_.get<HeartbeatInfoParameter>();
}
private:
Parameters parameters_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_ACK_CHUNK_H_

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/heartbeat_request_chunk.h"
#include <stdint.h>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.5
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 4 | Chunk Flags | Heartbeat Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / Heartbeat Information TLV (Variable-Length) /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int HeartbeatRequestChunk::kType;
absl::optional<HeartbeatRequestChunk> HeartbeatRequestChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
absl::optional<Parameters> parameters =
Parameters::Parse(reader->variable_data());
if (!parameters.has_value()) {
return absl::nullopt;
}
return HeartbeatRequestChunk(*std::move(parameters));
}
void HeartbeatRequestChunk::SerializeTo(std::vector<uint8_t>& out) const {
rtc::ArrayView<const uint8_t> parameters = parameters_.data();
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());
writer.CopyToVariableData(parameters);
}
std::string HeartbeatRequestChunk::ToString() const {
return "HEARTBEAT";
}
} // namespace dcsctp

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_REQUEST_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_REQUEST_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/parameter/heartbeat_info_parameter.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.5
struct HeartbeatRequestChunkConfig : ChunkConfig {
static constexpr int kType = 4;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class HeartbeatRequestChunk : public Chunk,
public TLVTrait<HeartbeatRequestChunkConfig> {
public:
static constexpr int kType = HeartbeatRequestChunkConfig::kType;
explicit HeartbeatRequestChunk(Parameters parameters)
: parameters_(std::move(parameters)) {}
HeartbeatRequestChunk(HeartbeatRequestChunk&& other) = default;
HeartbeatRequestChunk& operator=(HeartbeatRequestChunk&& other) = default;
static absl::optional<HeartbeatRequestChunk> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
const Parameters& parameters() const { return parameters_; }
Parameters extract_parameters() && { return std::move(parameters_); }
absl::optional<HeartbeatInfoParameter> info() const {
return parameters_.get<HeartbeatInfoParameter>();
}
private:
Parameters parameters_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_REQUEST_CHUNK_H_

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/idata_chunk.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/chunk/data_common.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc8260#section-2.1
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 64 | Res |I|U|B|E| Length = Variable |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | TSN |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream Identifier | Reserved |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Message Identifier |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Payload Protocol Identifier / Fragment Sequence Number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / User Data /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int IDataChunk::kType;
absl::optional<IDataChunk> IDataChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
uint8_t flags = reader->Load8<1>();
TSN tsn(reader->Load32<4>());
StreamID stream_identifier(reader->Load16<8>());
MID mid(reader->Load32<12>());
uint32_t ppid_or_fsn = reader->Load32<16>();
Options options;
options.is_end = Data::IsEnd((flags & (1 << kFlagsBitEnd)) != 0);
options.is_beginning =
Data::IsBeginning((flags & (1 << kFlagsBitBeginning)) != 0);
options.is_unordered = IsUnordered((flags & (1 << kFlagsBitUnordered)) != 0);
options.immediate_ack =
ImmediateAckFlag((flags & (1 << kFlagsBitImmediateAck)) != 0);
return IDataChunk(tsn, stream_identifier, mid,
PPID(options.is_beginning ? ppid_or_fsn : 0),
FSN(options.is_beginning ? 0 : ppid_or_fsn),
std::vector<uint8_t>(reader->variable_data().begin(),
reader->variable_data().end()),
options);
}
void IDataChunk::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, payload().size());
writer.Store8<1>(
(*options().is_end ? (1 << kFlagsBitEnd) : 0) |
(*options().is_beginning ? (1 << kFlagsBitBeginning) : 0) |
(*options().is_unordered ? (1 << kFlagsBitUnordered) : 0) |
(*options().immediate_ack ? (1 << kFlagsBitImmediateAck) : 0));
writer.Store32<4>(*tsn());
writer.Store16<8>(*stream_id());
writer.Store32<12>(*mid());
writer.Store32<16>(options().is_beginning ? *ppid() : *fsn());
writer.CopyToVariableData(payload());
}
std::string IDataChunk::ToString() const {
rtc::StringBuilder sb;
sb << "I-DATA, type=" << (options().is_unordered ? "unordered" : "ordered")
<< "::"
<< (*options().is_beginning && *options().is_end ? "complete"
: *options().is_beginning ? "first"
: *options().is_end ? "last"
: "middle")
<< ", tsn=" << *tsn() << ", stream_id=" << *stream_id()
<< ", mid=" << *mid();
if (*options().is_beginning) {
sb << ", ppid=" << *ppid();
} else {
sb << ", fsn=" << *fsn();
}
sb << ", length=" << payload().size();
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_IDATA_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_IDATA_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/chunk/data_common.h"
#include "net/dcsctp/packet/data.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc8260#section-2.1
struct IDataChunkConfig : ChunkConfig {
static constexpr int kType = 64;
static constexpr size_t kHeaderSize = 20;
static constexpr size_t kVariableLengthAlignment = 1;
};
class IDataChunk : public AnyDataChunk, public TLVTrait<IDataChunkConfig> {
public:
static constexpr int kType = IDataChunkConfig::kType;
// Exposed to allow the retransmission queue to make room for the correct
// header size.
static constexpr size_t kHeaderSize = IDataChunkConfig::kHeaderSize;
IDataChunk(TSN tsn,
StreamID stream_id,
MID mid,
PPID ppid,
FSN fsn,
std::vector<uint8_t> payload,
const Options& options)
: AnyDataChunk(tsn,
stream_id,
SSN(0),
mid,
fsn,
ppid,
std::move(payload),
options) {}
explicit IDataChunk(TSN tsn, Data&& data, bool immediate_ack)
: AnyDataChunk(tsn, std::move(data), immediate_ack) {}
static absl::optional<IDataChunk> Parse(rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_IDATA_CHUNK_H_

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/iforward_tsn_chunk.h"
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc8260#section-2.3.1
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 194 | Flags = 0x00 | Length = Variable |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | New Cumulative TSN |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream Identifier | Reserved |U|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Message Identifier |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / /
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream Identifier | Reserved |U|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Message Identifier |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int IForwardTsnChunk::kType;
absl::optional<IForwardTsnChunk> IForwardTsnChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
TSN new_cumulative_tsn(reader->Load32<4>());
size_t streams_skipped =
reader->variable_data_size() / kSkippedStreamBufferSize;
std::vector<SkippedStream> skipped_streams;
skipped_streams.reserve(streams_skipped);
size_t offset = 0;
for (size_t i = 0; i < streams_skipped; ++i) {
BoundedByteReader<kSkippedStreamBufferSize> sub_reader =
reader->sub_reader<kSkippedStreamBufferSize>(offset);
StreamID stream_id(sub_reader.Load16<0>());
IsUnordered unordered(sub_reader.Load8<3>() & 0x01);
MID mid(sub_reader.Load32<4>());
skipped_streams.emplace_back(unordered, stream_id, mid);
offset += kSkippedStreamBufferSize;
}
RTC_DCHECK(offset == reader->variable_data_size());
return IForwardTsnChunk(new_cumulative_tsn, std::move(skipped_streams));
}
void IForwardTsnChunk::SerializeTo(std::vector<uint8_t>& out) const {
rtc::ArrayView<const SkippedStream> skipped = skipped_streams();
size_t variable_size = skipped.size() * kSkippedStreamBufferSize;
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);
writer.Store32<4>(*new_cumulative_tsn());
size_t offset = 0;
for (size_t i = 0; i < skipped.size(); ++i) {
BoundedByteWriter<kSkippedStreamBufferSize> sub_writer =
writer.sub_writer<kSkippedStreamBufferSize>(offset);
sub_writer.Store16<0>(*skipped[i].stream_id);
sub_writer.Store8<3>(skipped[i].unordered ? 1 : 0);
sub_writer.Store32<4>(*skipped[i].mid);
offset += kSkippedStreamBufferSize;
}
RTC_DCHECK(offset == variable_size);
}
std::string IForwardTsnChunk::ToString() const {
rtc::StringBuilder sb;
sb << "I-FORWARD-TSN, new_cumulative_tsn=" << *new_cumulative_tsn();
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_IFORWARD_TSN_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_IFORWARD_TSN_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc8260#section-2.3.1
struct IForwardTsnChunkConfig : ChunkConfig {
static constexpr int kType = 194;
static constexpr size_t kHeaderSize = 8;
static constexpr size_t kVariableLengthAlignment = 8;
};
class IForwardTsnChunk : public AnyForwardTsnChunk,
public TLVTrait<IForwardTsnChunkConfig> {
public:
static constexpr int kType = IForwardTsnChunkConfig::kType;
IForwardTsnChunk(TSN new_cumulative_tsn,
std::vector<SkippedStream> skipped_streams)
: AnyForwardTsnChunk(new_cumulative_tsn, std::move(skipped_streams)) {}
static absl::optional<IForwardTsnChunk> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
private:
static constexpr size_t kSkippedStreamBufferSize = 8;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_IFORWARD_TSN_CHUNK_H_

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/init_ack_chunk.h"
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_format.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.3
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 2 | Chunk Flags | Chunk Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Initiate Tag |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Advertised Receiver Window Credit |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Number of Outbound Streams | Number of Inbound Streams |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Initial TSN |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / Optional/Variable-Length Parameters /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int InitAckChunk::kType;
absl::optional<InitAckChunk> InitAckChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
VerificationTag initiate_tag(reader->Load32<4>());
uint32_t a_rwnd = reader->Load32<8>();
uint16_t nbr_outbound_streams = reader->Load16<12>();
uint16_t nbr_inbound_streams = reader->Load16<14>();
TSN initial_tsn(reader->Load32<16>());
absl::optional<Parameters> parameters =
Parameters::Parse(reader->variable_data());
if (!parameters.has_value()) {
return absl::nullopt;
}
return InitAckChunk(initiate_tag, a_rwnd, nbr_outbound_streams,
nbr_inbound_streams, initial_tsn, *std::move(parameters));
}
void InitAckChunk::SerializeTo(std::vector<uint8_t>& out) const {
rtc::ArrayView<const uint8_t> parameters = parameters_.data();
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());
writer.Store32<4>(*initiate_tag_);
writer.Store32<8>(a_rwnd_);
writer.Store16<12>(nbr_outbound_streams_);
writer.Store16<14>(nbr_inbound_streams_);
writer.Store32<16>(*initial_tsn_);
writer.CopyToVariableData(parameters);
}
std::string InitAckChunk::ToString() const {
return rtc::StringFormat("INIT_ACK, initiate_tag=0x%0x, initial_tsn=%u",
*initiate_tag(), *initial_tsn());
}
} // namespace dcsctp

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_INIT_ACK_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_INIT_ACK_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.3
struct InitAckChunkConfig : ChunkConfig {
static constexpr int kType = 2;
static constexpr size_t kHeaderSize = 20;
static constexpr size_t kVariableLengthAlignment = 1;
};
class InitAckChunk : public Chunk, public TLVTrait<InitAckChunkConfig> {
public:
static constexpr int kType = InitAckChunkConfig::kType;
InitAckChunk(VerificationTag initiate_tag,
uint32_t a_rwnd,
uint16_t nbr_outbound_streams,
uint16_t nbr_inbound_streams,
TSN initial_tsn,
Parameters parameters)
: initiate_tag_(initiate_tag),
a_rwnd_(a_rwnd),
nbr_outbound_streams_(nbr_outbound_streams),
nbr_inbound_streams_(nbr_inbound_streams),
initial_tsn_(initial_tsn),
parameters_(std::move(parameters)) {}
InitAckChunk(InitAckChunk&& other) = default;
InitAckChunk& operator=(InitAckChunk&& other) = default;
static absl::optional<InitAckChunk> Parse(rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
VerificationTag initiate_tag() const { return initiate_tag_; }
uint32_t a_rwnd() const { return a_rwnd_; }
uint16_t nbr_outbound_streams() const { return nbr_outbound_streams_; }
uint16_t nbr_inbound_streams() const { return nbr_inbound_streams_; }
TSN initial_tsn() const { return initial_tsn_; }
const Parameters& parameters() const { return parameters_; }
private:
VerificationTag initiate_tag_;
uint32_t a_rwnd_;
uint16_t nbr_outbound_streams_;
uint16_t nbr_inbound_streams_;
TSN initial_tsn_;
Parameters parameters_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_INIT_ACK_CHUNK_H_

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/init_chunk.h"
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_format.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.2
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 1 | Chunk Flags | Chunk Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Initiate Tag |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Advertised Receiver Window Credit (a_rwnd) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Number of Outbound Streams | Number of Inbound Streams |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Initial TSN |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / Optional/Variable-Length Parameters /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int InitChunk::kType;
absl::optional<InitChunk> InitChunk::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
VerificationTag initiate_tag(reader->Load32<4>());
uint32_t a_rwnd = reader->Load32<8>();
uint16_t nbr_outbound_streams = reader->Load16<12>();
uint16_t nbr_inbound_streams = reader->Load16<14>();
TSN initial_tsn(reader->Load32<16>());
absl::optional<Parameters> parameters =
Parameters::Parse(reader->variable_data());
if (!parameters.has_value()) {
return absl::nullopt;
}
return InitChunk(initiate_tag, a_rwnd, nbr_outbound_streams,
nbr_inbound_streams, initial_tsn, *std::move(parameters));
}
void InitChunk::SerializeTo(std::vector<uint8_t>& out) const {
rtc::ArrayView<const uint8_t> parameters = parameters_.data();
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());
writer.Store32<4>(*initiate_tag_);
writer.Store32<8>(a_rwnd_);
writer.Store16<12>(nbr_outbound_streams_);
writer.Store16<14>(nbr_inbound_streams_);
writer.Store32<16>(*initial_tsn_);
writer.CopyToVariableData(parameters);
}
std::string InitChunk::ToString() const {
return rtc::StringFormat("INIT, initiate_tag=0x%0x, initial_tsn=%u",
*initiate_tag(), *initial_tsn());
}
} // namespace dcsctp

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_INIT_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_INIT_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.2
struct InitChunkConfig : ChunkConfig {
static constexpr int kType = 1;
static constexpr size_t kHeaderSize = 20;
static constexpr size_t kVariableLengthAlignment = 1;
};
class InitChunk : public Chunk, public TLVTrait<InitChunkConfig> {
public:
static constexpr int kType = InitChunkConfig::kType;
InitChunk(VerificationTag initiate_tag,
uint32_t a_rwnd,
uint16_t nbr_outbound_streams,
uint16_t nbr_inbound_streams,
TSN initial_tsn,
Parameters parameters)
: initiate_tag_(initiate_tag),
a_rwnd_(a_rwnd),
nbr_outbound_streams_(nbr_outbound_streams),
nbr_inbound_streams_(nbr_inbound_streams),
initial_tsn_(initial_tsn),
parameters_(std::move(parameters)) {}
InitChunk(InitChunk&& other) = default;
InitChunk& operator=(InitChunk&& other) = default;
static absl::optional<InitChunk> Parse(rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
VerificationTag initiate_tag() const { return initiate_tag_; }
uint32_t a_rwnd() const { return a_rwnd_; }
uint16_t nbr_outbound_streams() const { return nbr_outbound_streams_; }
uint16_t nbr_inbound_streams() const { return nbr_inbound_streams_; }
TSN initial_tsn() const { return initial_tsn_; }
const Parameters& parameters() const { return parameters_; }
private:
VerificationTag initiate_tag_;
uint32_t a_rwnd_;
uint16_t nbr_outbound_streams_;
uint16_t nbr_inbound_streams_;
TSN initial_tsn_;
Parameters parameters_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_INIT_CHUNK_H_

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/reconfig_chunk.h"
#include <stdint.h>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-3.1
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 130 | Chunk Flags | Chunk Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / Re-configuration Parameter /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / Re-configuration Parameter (optional) /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ReConfigChunk::kType;
absl::optional<ReConfigChunk> ReConfigChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
absl::optional<Parameters> parameters =
Parameters::Parse(reader->variable_data());
if (!parameters.has_value()) {
return absl::nullopt;
}
return ReConfigChunk(*std::move(parameters));
}
void ReConfigChunk::SerializeTo(std::vector<uint8_t>& out) const {
rtc::ArrayView<const uint8_t> parameters = parameters_.data();
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());
writer.CopyToVariableData(parameters);
}
std::string ReConfigChunk::ToString() const {
return "RE-CONFIG";
}
} // namespace dcsctp

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_RECONFIG_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_RECONFIG_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-3.1
struct ReConfigChunkConfig : ChunkConfig {
static constexpr int kType = 130;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class ReConfigChunk : public Chunk, public TLVTrait<ReConfigChunkConfig> {
public:
static constexpr int kType = ReConfigChunkConfig::kType;
explicit ReConfigChunk(Parameters parameters)
: parameters_(std::move(parameters)) {}
static absl::optional<ReConfigChunk> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
const Parameters& parameters() const { return parameters_; }
Parameters extract_parameters() { return std::move(parameters_); }
private:
Parameters parameters_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_RECONFIG_CHUNK_H_

View file

@ -0,0 +1,155 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/sack_chunk.h"
#include <stddef.h>
#include <cstdint>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/str_join.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.4
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 3 |Chunk Flags | Chunk Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cumulative TSN Ack |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Advertised Receiver Window Credit (a_rwnd) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Number of Gap Ack Blocks = N | Number of Duplicate TSNs = X |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Gap Ack Block #1 Start | Gap Ack Block #1 End |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / /
// \ ... \
// / /
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Gap Ack Block #N Start | Gap Ack Block #N End |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Duplicate TSN 1 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / /
// \ ... \
// / /
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Duplicate TSN X |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int SackChunk::kType;
absl::optional<SackChunk> SackChunk::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
TSN tsn_ack(reader->Load32<4>());
uint32_t a_rwnd = reader->Load32<8>();
uint16_t nbr_of_gap_blocks = reader->Load16<12>();
uint16_t nbr_of_dup_tsns = reader->Load16<14>();
if (reader->variable_data_size() != nbr_of_gap_blocks * kGapAckBlockSize +
nbr_of_dup_tsns * kDupTsnBlockSize) {
RTC_DLOG(LS_WARNING) << "Invalid number of gap blocks or duplicate TSNs";
return absl::nullopt;
}
std::vector<GapAckBlock> gap_ack_blocks;
gap_ack_blocks.reserve(nbr_of_gap_blocks);
size_t offset = 0;
for (int i = 0; i < nbr_of_gap_blocks; ++i) {
BoundedByteReader<kGapAckBlockSize> sub_reader =
reader->sub_reader<kGapAckBlockSize>(offset);
uint16_t start = sub_reader.Load16<0>();
uint16_t end = sub_reader.Load16<2>();
gap_ack_blocks.emplace_back(start, end);
offset += kGapAckBlockSize;
}
std::set<TSN> duplicate_tsns;
for (int i = 0; i < nbr_of_dup_tsns; ++i) {
BoundedByteReader<kDupTsnBlockSize> sub_reader =
reader->sub_reader<kDupTsnBlockSize>(offset);
duplicate_tsns.insert(TSN(sub_reader.Load32<0>()));
offset += kDupTsnBlockSize;
}
RTC_DCHECK(offset == reader->variable_data_size());
return SackChunk(tsn_ack, a_rwnd, gap_ack_blocks, duplicate_tsns);
}
void SackChunk::SerializeTo(std::vector<uint8_t>& out) const {
int nbr_of_gap_blocks = gap_ack_blocks_.size();
int nbr_of_dup_tsns = duplicate_tsns_.size();
size_t variable_size =
nbr_of_gap_blocks * kGapAckBlockSize + nbr_of_dup_tsns * kDupTsnBlockSize;
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);
writer.Store32<4>(*cumulative_tsn_ack_);
writer.Store32<8>(a_rwnd_);
writer.Store16<12>(nbr_of_gap_blocks);
writer.Store16<14>(nbr_of_dup_tsns);
size_t offset = 0;
for (int i = 0; i < nbr_of_gap_blocks; ++i) {
BoundedByteWriter<kGapAckBlockSize> sub_writer =
writer.sub_writer<kGapAckBlockSize>(offset);
sub_writer.Store16<0>(gap_ack_blocks_[i].start);
sub_writer.Store16<2>(gap_ack_blocks_[i].end);
offset += kGapAckBlockSize;
}
for (TSN tsn : duplicate_tsns_) {
BoundedByteWriter<kDupTsnBlockSize> sub_writer =
writer.sub_writer<kDupTsnBlockSize>(offset);
sub_writer.Store32<0>(*tsn);
offset += kDupTsnBlockSize;
}
RTC_DCHECK(offset == variable_size);
}
std::string SackChunk::ToString() const {
rtc::StringBuilder sb;
sb << "SACK, cum_ack_tsn=" << *cumulative_tsn_ack()
<< ", a_rwnd=" << a_rwnd();
for (const GapAckBlock& gap : gap_ack_blocks_) {
uint32_t first = *cumulative_tsn_ack_ + gap.start;
uint32_t last = *cumulative_tsn_ack_ + gap.end;
sb << ", gap=" << first << "--" << last;
}
if (!duplicate_tsns_.empty()) {
sb << ", dup_tsns="
<< StrJoin(duplicate_tsns(), ",",
[](rtc::StringBuilder& sb, TSN tsn) { sb << *tsn; });
}
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_SACK_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_SACK_CHUNK_H_
#include <stddef.h>
#include <cstdint>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.4
struct SackChunkConfig : ChunkConfig {
static constexpr int kType = 3;
static constexpr size_t kHeaderSize = 16;
static constexpr size_t kVariableLengthAlignment = 4;
};
class SackChunk : public Chunk, public TLVTrait<SackChunkConfig> {
public:
static constexpr int kType = SackChunkConfig::kType;
struct GapAckBlock {
GapAckBlock(uint16_t start, uint16_t end) : start(start), end(end) {}
uint16_t start;
uint16_t end;
bool operator==(const GapAckBlock& other) const {
return start == other.start && end == other.end;
}
};
SackChunk(TSN cumulative_tsn_ack,
uint32_t a_rwnd,
std::vector<GapAckBlock> gap_ack_blocks,
std::set<TSN> duplicate_tsns)
: cumulative_tsn_ack_(cumulative_tsn_ack),
a_rwnd_(a_rwnd),
gap_ack_blocks_(std::move(gap_ack_blocks)),
duplicate_tsns_(std::move(duplicate_tsns)) {}
static absl::optional<SackChunk> Parse(rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
TSN cumulative_tsn_ack() const { return cumulative_tsn_ack_; }
uint32_t a_rwnd() const { return a_rwnd_; }
rtc::ArrayView<const GapAckBlock> gap_ack_blocks() const {
return gap_ack_blocks_;
}
const std::set<TSN>& duplicate_tsns() const { return duplicate_tsns_; }
private:
static constexpr size_t kGapAckBlockSize = 4;
static constexpr size_t kDupTsnBlockSize = 4;
const TSN cumulative_tsn_ack_;
const uint32_t a_rwnd_;
std::vector<GapAckBlock> gap_ack_blocks_;
std::set<TSN> duplicate_tsns_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_SACK_CHUNK_H_

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/shutdown_ack_chunk.h"
#include <stdint.h>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.9
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 8 |Chunk Flags | Length = 4 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ShutdownAckChunk::kType;
absl::optional<ShutdownAckChunk> ShutdownAckChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
if (!ParseTLV(data).has_value()) {
return absl::nullopt;
}
return ShutdownAckChunk();
}
void ShutdownAckChunk::SerializeTo(std::vector<uint8_t>& out) const {
AllocateTLV(out);
}
std::string ShutdownAckChunk::ToString() const {
return "SHUTDOWN-ACK";
}
} // namespace dcsctp

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_ACK_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_ACK_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.9
struct ShutdownAckChunkConfig : ChunkConfig {
static constexpr int kType = 8;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 0;
};
class ShutdownAckChunk : public Chunk, public TLVTrait<ShutdownAckChunkConfig> {
public:
static constexpr int kType = ShutdownAckChunkConfig::kType;
ShutdownAckChunk() {}
static absl::optional<ShutdownAckChunk> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_ACK_CHUNK_H_

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/shutdown_chunk.h"
#include <stdint.h>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.8
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 7 | Chunk Flags | Length = 8 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cumulative TSN Ack |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ShutdownChunk::kType;
absl::optional<ShutdownChunk> ShutdownChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
TSN cumulative_tsn_ack(reader->Load32<4>());
return ShutdownChunk(cumulative_tsn_ack);
}
void ShutdownChunk::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
writer.Store32<4>(*cumulative_tsn_ack_);
}
std::string ShutdownChunk::ToString() const {
return "SHUTDOWN";
}
} // namespace dcsctp

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.8
struct ShutdownChunkConfig : ChunkConfig {
static constexpr int kType = 7;
static constexpr size_t kHeaderSize = 8;
static constexpr size_t kVariableLengthAlignment = 0;
};
class ShutdownChunk : public Chunk, public TLVTrait<ShutdownChunkConfig> {
public:
static constexpr int kType = ShutdownChunkConfig::kType;
explicit ShutdownChunk(TSN cumulative_tsn_ack)
: cumulative_tsn_ack_(cumulative_tsn_ack) {}
static absl::optional<ShutdownChunk> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
TSN cumulative_tsn_ack() const { return cumulative_tsn_ack_; }
private:
TSN cumulative_tsn_ack_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_CHUNK_H_

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk/shutdown_complete_chunk.h"
#include <stdint.h>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.13
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 14 |Reserved |T| Length = 4 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ShutdownCompleteChunk::kType;
absl::optional<ShutdownCompleteChunk> ShutdownCompleteChunk::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
uint8_t flags = reader->Load8<1>();
bool tag_reflected = (flags & (1 << kFlagsBitT)) != 0;
return ShutdownCompleteChunk(tag_reflected);
}
void ShutdownCompleteChunk::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
writer.Store8<1>(tag_reflected_ ? (1 << kFlagsBitT) : 0);
}
std::string ShutdownCompleteChunk::ToString() const {
return "SHUTDOWN-COMPLETE";
}
} // namespace dcsctp

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_COMPLETE_CHUNK_H_
#define NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_COMPLETE_CHUNK_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.13
struct ShutdownCompleteChunkConfig : ChunkConfig {
static constexpr int kType = 14;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 0;
};
class ShutdownCompleteChunk : public Chunk,
public TLVTrait<ShutdownCompleteChunkConfig> {
public:
static constexpr int kType = ShutdownCompleteChunkConfig::kType;
explicit ShutdownCompleteChunk(bool tag_reflected)
: tag_reflected_(tag_reflected) {}
static absl::optional<ShutdownCompleteChunk> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
bool tag_reflected() const { return tag_reflected_; }
private:
static constexpr int kFlagsBitT = 0;
bool tag_reflected_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_COMPLETE_CHUNK_H_

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/chunk_validators.h"
#include <algorithm>
#include <utility>
#include <vector>
#include "net/dcsctp/packet/chunk/sack_chunk.h"
#include "rtc_base/logging.h"
namespace dcsctp {
SackChunk ChunkValidators::Clean(SackChunk&& sack) {
if (Validate(sack)) {
return std::move(sack);
}
RTC_DLOG(LS_WARNING) << "Received SACK is malformed; cleaning it";
std::vector<SackChunk::GapAckBlock> gap_ack_blocks;
gap_ack_blocks.reserve(sack.gap_ack_blocks().size());
// First: Only keep blocks that are sane
for (const SackChunk::GapAckBlock& gap_ack_block : sack.gap_ack_blocks()) {
if (gap_ack_block.end > gap_ack_block.start) {
gap_ack_blocks.emplace_back(gap_ack_block);
}
}
// Not more than at most one remaining? Exit early.
if (gap_ack_blocks.size() <= 1) {
return SackChunk(sack.cumulative_tsn_ack(), sack.a_rwnd(),
std::move(gap_ack_blocks), sack.duplicate_tsns());
}
// Sort the intervals by their start value, to aid in the merging below.
absl::c_sort(gap_ack_blocks, [&](const SackChunk::GapAckBlock& a,
const SackChunk::GapAckBlock& b) {
return a.start < b.start;
});
// Merge overlapping ranges.
std::vector<SackChunk::GapAckBlock> merged;
merged.reserve(gap_ack_blocks.size());
merged.push_back(gap_ack_blocks[0]);
for (size_t i = 1; i < gap_ack_blocks.size(); ++i) {
if (merged.back().end + 1 >= gap_ack_blocks[i].start) {
merged.back().end = std::max(merged.back().end, gap_ack_blocks[i].end);
} else {
merged.push_back(gap_ack_blocks[i]);
}
}
return SackChunk(sack.cumulative_tsn_ack(), sack.a_rwnd(), std::move(merged),
sack.duplicate_tsns());
}
bool ChunkValidators::Validate(const SackChunk& sack) {
if (sack.gap_ack_blocks().empty()) {
return true;
}
// Ensure that gap-ack-blocks are sorted, has an "end" that is not before
// "start" and are non-overlapping and non-adjacent.
uint16_t prev_end = 0;
for (const SackChunk::GapAckBlock& gap_ack_block : sack.gap_ack_blocks()) {
if (gap_ack_block.end < gap_ack_block.start) {
return false;
}
if (gap_ack_block.start <= (prev_end + 1)) {
return false;
}
prev_end = gap_ack_block.end;
}
return true;
}
} // namespace dcsctp

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CHUNK_VALIDATORS_H_
#define NET_DCSCTP_PACKET_CHUNK_VALIDATORS_H_
#include "net/dcsctp/packet/chunk/sack_chunk.h"
namespace dcsctp {
// Validates and cleans SCTP chunks.
class ChunkValidators {
public:
// Given a SackChunk, will return `true` if it's valid, and `false` if not.
static bool Validate(const SackChunk& sack);
// Given a SackChunk, it will return a cleaned and validated variant of it.
// RFC4960 doesn't say anything about validity of SACKs or if the Gap ACK
// blocks must be sorted, and non-overlapping. While they always are in
// well-behaving implementations, this can't be relied on.
//
// This method internally calls `Validate`, which means that you can always
// pass a SackChunk to this method (valid or not), and use the results.
static SackChunk Clean(SackChunk&& sack);
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CHUNK_VALIDATORS_H_

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/crc32c.h"
#include <cstdint>
#include "third_party/crc32c/src/include/crc32c/crc32c.h"
namespace dcsctp {
uint32_t GenerateCrc32C(rtc::ArrayView<const uint8_t> data) {
uint32_t crc32c = crc32c_value(data.data(), data.size());
// Byte swapping for little endian byte order:
uint8_t byte0 = crc32c;
uint8_t byte1 = crc32c >> 8;
uint8_t byte2 = crc32c >> 16;
uint8_t byte3 = crc32c >> 24;
crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
return crc32c;
}
} // namespace dcsctp

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_CRC32C_H_
#define NET_DCSCTP_PACKET_CRC32C_H_
#include <cstdint>
#include "api/array_view.h"
namespace dcsctp {
// Generates the CRC32C checksum of `data`.
uint32_t GenerateCrc32C(rtc::ArrayView<const uint8_t> data);
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_CRC32C_H_

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_DATA_H_
#define NET_DCSCTP_PACKET_DATA_H_
#include <cstdint>
#include <utility>
#include <vector>
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/public/types.h"
namespace dcsctp {
// Represents data that is either received and extracted from a DATA/I-DATA
// chunk, or data that is supposed to be sent, and wrapped in a DATA/I-DATA
// chunk (depending on peer capabilities).
//
// The data wrapped in this structure is actually the same as the DATA/I-DATA
// chunk (actually the union of them), but to avoid having all components be
// aware of the implementation details of the different chunks, this abstraction
// is used instead. A notable difference is also that it doesn't carry a
// Transmission Sequence Number (TSN), as that is not known when a chunk is
// created (assigned late, just when sending), and that the TSNs in DATA/I-DATA
// are wrapped numbers, and within the library, unwrapped sequence numbers are
// preferably used.
struct Data {
// Indicates if a chunk is the first in a fragmented message and maps to the
// "beginning" flag in DATA/I-DATA chunk.
using IsBeginning = webrtc::StrongAlias<class IsBeginningTag, bool>;
// Indicates if a chunk is the last in a fragmented message and maps to the
// "end" flag in DATA/I-DATA chunk.
using IsEnd = webrtc::StrongAlias<class IsEndTag, bool>;
Data(StreamID stream_id,
SSN ssn,
MID mid,
FSN fsn,
PPID ppid,
std::vector<uint8_t> payload,
IsBeginning is_beginning,
IsEnd is_end,
IsUnordered is_unordered)
: stream_id(stream_id),
ssn(ssn),
mid(mid),
fsn(fsn),
ppid(ppid),
payload(std::move(payload)),
is_beginning(is_beginning),
is_end(is_end),
is_unordered(is_unordered) {}
// Move-only, to avoid accidental copies.
Data(Data&& other) = default;
Data& operator=(Data&& other) = default;
// Creates a copy of this `Data` object.
Data Clone() const {
return Data(stream_id, ssn, mid, fsn, ppid, payload, is_beginning, is_end,
is_unordered);
}
// The size of this data, which translates to the size of its payload.
size_t size() const { return payload.size(); }
// Stream Identifier.
StreamID stream_id;
// Stream Sequence Number (SSN), per stream, for ordered chunks. Defined by
// RFC4960 and used only in DATA chunks (not I-DATA).
SSN ssn;
// Message Identifier (MID) per stream and ordered/unordered. Defined by
// RFC8260, and used together with options.is_unordered and stream_id to
// uniquely identify a message. Used only in I-DATA chunks (not DATA).
MID mid;
// Fragment Sequence Number (FSN) per stream and ordered/unordered, as above.
FSN fsn;
// Payload Protocol Identifier (PPID).
PPID ppid;
// The actual data payload.
std::vector<uint8_t> payload;
// If this data represents the first, last or a middle chunk.
IsBeginning is_beginning;
IsEnd is_end;
// If this data is sent/received unordered.
IsUnordered is_unordered;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_DATA_H_

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.h"
#include <stdint.h>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.10
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=10 | Cause Length=4 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int CookieReceivedWhileShuttingDownCause::kType;
absl::optional<CookieReceivedWhileShuttingDownCause>
CookieReceivedWhileShuttingDownCause::Parse(
rtc::ArrayView<const uint8_t> data) {
if (!ParseTLV(data).has_value()) {
return absl::nullopt;
}
return CookieReceivedWhileShuttingDownCause();
}
void CookieReceivedWhileShuttingDownCause::SerializeTo(
std::vector<uint8_t>& out) const {
AllocateTLV(out);
}
std::string CookieReceivedWhileShuttingDownCause::ToString() const {
return "Cookie Received While Shutting Down";
}
} // namespace dcsctp

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_COOKIE_RECEIVED_WHILE_SHUTTING_DOWN_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_COOKIE_RECEIVED_WHILE_SHUTTING_DOWN_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.10
struct CookieReceivedWhileShuttingDownCauseConfig : public ParameterConfig {
static constexpr int kType = 10;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 0;
};
class CookieReceivedWhileShuttingDownCause
: public Parameter,
public TLVTrait<CookieReceivedWhileShuttingDownCauseConfig> {
public:
static constexpr int kType =
CookieReceivedWhileShuttingDownCauseConfig::kType;
CookieReceivedWhileShuttingDownCause() {}
static absl::optional<CookieReceivedWhileShuttingDownCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_COOKIE_RECEIVED_WHILE_SHUTTING_DOWN_CAUSE_H_

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include <stddef.h>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/common/math.h"
#include "net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.h"
#include "net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.h"
#include "net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.h"
#include "net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.h"
#include "net/dcsctp/packet/error_cause/no_user_data_cause.h"
#include "net/dcsctp/packet/error_cause/out_of_resource_error_cause.h"
#include "net/dcsctp/packet/error_cause/protocol_violation_cause.h"
#include "net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.h"
#include "net/dcsctp/packet/error_cause/stale_cookie_error_cause.h"
#include "net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h"
#include "net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h"
#include "net/dcsctp/packet/error_cause/unresolvable_address_cause.h"
#include "net/dcsctp/packet/error_cause/user_initiated_abort_cause.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
template <class ErrorCause>
bool ParseAndPrint(ParameterDescriptor descriptor, rtc::StringBuilder& sb) {
if (descriptor.type == ErrorCause::kType) {
absl::optional<ErrorCause> p = ErrorCause::Parse(descriptor.data);
if (p.has_value()) {
sb << p->ToString();
} else {
sb << "Failed to parse error cause of type " << ErrorCause::kType;
}
return true;
}
return false;
}
std::string ErrorCausesToString(const Parameters& parameters) {
rtc::StringBuilder sb;
std::vector<ParameterDescriptor> descriptors = parameters.descriptors();
for (size_t i = 0; i < descriptors.size(); ++i) {
if (i > 0) {
sb << "\n";
}
const ParameterDescriptor& d = descriptors[i];
if (!ParseAndPrint<InvalidStreamIdentifierCause>(d, sb) &&
!ParseAndPrint<MissingMandatoryParameterCause>(d, sb) &&
!ParseAndPrint<StaleCookieErrorCause>(d, sb) &&
!ParseAndPrint<OutOfResourceErrorCause>(d, sb) &&
!ParseAndPrint<UnresolvableAddressCause>(d, sb) &&
!ParseAndPrint<UnrecognizedChunkTypeCause>(d, sb) &&
!ParseAndPrint<InvalidMandatoryParameterCause>(d, sb) &&
!ParseAndPrint<UnrecognizedParametersCause>(d, sb) &&
!ParseAndPrint<NoUserDataCause>(d, sb) &&
!ParseAndPrint<CookieReceivedWhileShuttingDownCause>(d, sb) &&
!ParseAndPrint<RestartOfAnAssociationWithNewAddressesCause>(d, sb) &&
!ParseAndPrint<UserInitiatedAbortCause>(d, sb) &&
!ParseAndPrint<ProtocolViolationCause>(d, sb)) {
sb << "Unhandled parameter of type: " << d.type;
}
}
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_ERROR_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_ERROR_CAUSE_H_
#include <stddef.h>
#include <cstdint>
#include <iosfwd>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "absl/algorithm/container.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// Converts the Error Causes in `parameters` to a human readable string,
// to be used in error reporting and logging.
std::string ErrorCausesToString(const Parameters& parameters);
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_ERROR_CAUSE_H_

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.h"
#include <stdint.h>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.7
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=7 | Cause Length=4 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int InvalidMandatoryParameterCause::kType;
absl::optional<InvalidMandatoryParameterCause>
InvalidMandatoryParameterCause::Parse(rtc::ArrayView<const uint8_t> data) {
if (!ParseTLV(data).has_value()) {
return absl::nullopt;
}
return InvalidMandatoryParameterCause();
}
void InvalidMandatoryParameterCause::SerializeTo(
std::vector<uint8_t>& out) const {
AllocateTLV(out);
}
std::string InvalidMandatoryParameterCause::ToString() const {
return "Invalid Mandatory Parameter";
}
} // namespace dcsctp

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_MANDATORY_PARAMETER_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_MANDATORY_PARAMETER_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.7
struct InvalidMandatoryParameterCauseConfig : public ParameterConfig {
static constexpr int kType = 7;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 0;
};
class InvalidMandatoryParameterCause
: public Parameter,
public TLVTrait<InvalidMandatoryParameterCauseConfig> {
public:
static constexpr int kType = InvalidMandatoryParameterCauseConfig::kType;
InvalidMandatoryParameterCause() {}
static absl::optional<InvalidMandatoryParameterCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_MANDATORY_PARAMETER_CAUSE_H_

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=1 | Cause Length=8 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream Identifier | (Reserved) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int InvalidStreamIdentifierCause::kType;
absl::optional<InvalidStreamIdentifierCause>
InvalidStreamIdentifierCause::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
StreamID stream_id(reader->Load16<4>());
return InvalidStreamIdentifierCause(stream_id);
}
void InvalidStreamIdentifierCause::SerializeTo(
std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
writer.Store16<4>(*stream_id_);
}
std::string InvalidStreamIdentifierCause::ToString() const {
rtc::StringBuilder sb;
sb << "Invalid Stream Identifier, stream_id=" << *stream_id_;
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_STREAM_IDENTIFIER_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_STREAM_IDENTIFIER_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "net/dcsctp/public/types.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.1
struct InvalidStreamIdentifierCauseConfig : public ParameterConfig {
static constexpr int kType = 1;
static constexpr size_t kHeaderSize = 8;
static constexpr size_t kVariableLengthAlignment = 0;
};
class InvalidStreamIdentifierCause
: public Parameter,
public TLVTrait<InvalidStreamIdentifierCauseConfig> {
public:
static constexpr int kType = InvalidStreamIdentifierCauseConfig::kType;
explicit InvalidStreamIdentifierCause(StreamID stream_id)
: stream_id_(stream_id) {}
static absl::optional<InvalidStreamIdentifierCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
StreamID stream_id() const { return stream_id_; }
private:
StreamID stream_id_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_STREAM_IDENTIFIER_CAUSE_H_

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.h"
#include <stddef.h>
#include <cstdint>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/str_join.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.2
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=2 | Cause Length=8+N*2 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Number of missing params=N |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Missing Param Type #1 | Missing Param Type #2 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Missing Param Type #N-1 | Missing Param Type #N |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int MissingMandatoryParameterCause::kType;
absl::optional<MissingMandatoryParameterCause>
MissingMandatoryParameterCause::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
uint32_t count = reader->Load32<4>();
if (reader->variable_data_size() / kMissingParameterSize != count) {
RTC_DLOG(LS_WARNING) << "Invalid number of missing parameters";
return absl::nullopt;
}
std::vector<uint16_t> missing_parameter_types;
missing_parameter_types.reserve(count);
for (uint32_t i = 0; i < count; ++i) {
BoundedByteReader<kMissingParameterSize> sub_reader =
reader->sub_reader<kMissingParameterSize>(i * kMissingParameterSize);
missing_parameter_types.push_back(sub_reader.Load16<0>());
}
return MissingMandatoryParameterCause(missing_parameter_types);
}
void MissingMandatoryParameterCause::SerializeTo(
std::vector<uint8_t>& out) const {
size_t variable_size =
missing_parameter_types_.size() * kMissingParameterSize;
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);
writer.Store32<4>(missing_parameter_types_.size());
for (size_t i = 0; i < missing_parameter_types_.size(); ++i) {
BoundedByteWriter<kMissingParameterSize> sub_writer =
writer.sub_writer<kMissingParameterSize>(i * kMissingParameterSize);
sub_writer.Store16<0>(missing_parameter_types_[i]);
}
}
std::string MissingMandatoryParameterCause::ToString() const {
rtc::StringBuilder sb;
sb << "Missing Mandatory Parameter, missing_parameter_types="
<< webrtc::StrJoin(missing_parameter_types_, ",");
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_MISSING_MANDATORY_PARAMETER_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_MISSING_MANDATORY_PARAMETER_CAUSE_H_
#include <stddef.h>
#include <cstdint>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.2
struct MissingMandatoryParameterCauseConfig : public ParameterConfig {
static constexpr int kType = 2;
static constexpr size_t kHeaderSize = 8;
static constexpr size_t kVariableLengthAlignment = 2;
};
class MissingMandatoryParameterCause
: public Parameter,
public TLVTrait<MissingMandatoryParameterCauseConfig> {
public:
static constexpr int kType = MissingMandatoryParameterCauseConfig::kType;
explicit MissingMandatoryParameterCause(
rtc::ArrayView<const uint16_t> missing_parameter_types)
: missing_parameter_types_(missing_parameter_types.begin(),
missing_parameter_types.end()) {}
static absl::optional<MissingMandatoryParameterCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
rtc::ArrayView<const uint16_t> missing_parameter_types() const {
return missing_parameter_types_;
}
private:
static constexpr size_t kMissingParameterSize = 2;
std::vector<uint16_t> missing_parameter_types_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_MISSING_MANDATORY_PARAMETER_CAUSE_H_

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/no_user_data_cause.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.9
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=9 | Cause Length=8 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / TSN value /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int NoUserDataCause::kType;
absl::optional<NoUserDataCause> NoUserDataCause::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
TSN tsn(reader->Load32<4>());
return NoUserDataCause(tsn);
}
void NoUserDataCause::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
writer.Store32<4>(*tsn_);
}
std::string NoUserDataCause::ToString() const {
rtc::StringBuilder sb;
sb << "No User Data, tsn=" << *tsn_;
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_NO_USER_DATA_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_NO_USER_DATA_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.9
struct NoUserDataCauseConfig : public ParameterConfig {
static constexpr int kType = 9;
static constexpr size_t kHeaderSize = 8;
static constexpr size_t kVariableLengthAlignment = 0;
};
class NoUserDataCause : public Parameter,
public TLVTrait<NoUserDataCauseConfig> {
public:
static constexpr int kType = NoUserDataCauseConfig::kType;
explicit NoUserDataCause(TSN tsn) : tsn_(tsn) {}
static absl::optional<NoUserDataCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
TSN tsn() const { return tsn_; }
private:
TSN tsn_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_NO_USER_DATA_CAUSE_H_

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/out_of_resource_error_cause.h"
#include <stdint.h>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.4
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=4 | Cause Length=4 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int OutOfResourceErrorCause::kType;
absl::optional<OutOfResourceErrorCause> OutOfResourceErrorCause::Parse(
rtc::ArrayView<const uint8_t> data) {
if (!ParseTLV(data).has_value()) {
return absl::nullopt;
}
return OutOfResourceErrorCause();
}
void OutOfResourceErrorCause::SerializeTo(std::vector<uint8_t>& out) const {
AllocateTLV(out);
}
std::string OutOfResourceErrorCause::ToString() const {
return "Out Of Resource";
}
} // namespace dcsctp

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_OUT_OF_RESOURCE_ERROR_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_OUT_OF_RESOURCE_ERROR_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.4
struct OutOfResourceParameterConfig : public ParameterConfig {
static constexpr int kType = 4;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 0;
};
class OutOfResourceErrorCause : public Parameter,
public TLVTrait<OutOfResourceParameterConfig> {
public:
static constexpr int kType = OutOfResourceParameterConfig::kType;
OutOfResourceErrorCause() {}
static absl::optional<OutOfResourceErrorCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_OUT_OF_RESOURCE_ERROR_CAUSE_H_

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/protocol_violation_cause.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.13
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=13 | Cause Length=Variable |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / Additional Information /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ProtocolViolationCause::kType;
absl::optional<ProtocolViolationCause> ProtocolViolationCause::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
return ProtocolViolationCause(
std::string(reinterpret_cast<const char*>(reader->variable_data().data()),
reader->variable_data().size()));
}
void ProtocolViolationCause::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer =
AllocateTLV(out, additional_information_.size());
writer.CopyToVariableData(rtc::MakeArrayView(
reinterpret_cast<const uint8_t*>(additional_information_.data()),
additional_information_.size()));
}
std::string ProtocolViolationCause::ToString() const {
rtc::StringBuilder sb;
sb << "Protocol Violation, additional_information="
<< additional_information_;
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_PROTOCOL_VIOLATION_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_PROTOCOL_VIOLATION_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.13
struct ProtocolViolationCauseConfig : public ParameterConfig {
static constexpr int kType = 13;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class ProtocolViolationCause : public Parameter,
public TLVTrait<ProtocolViolationCauseConfig> {
public:
static constexpr int kType = ProtocolViolationCauseConfig::kType;
explicit ProtocolViolationCause(absl::string_view additional_information)
: additional_information_(additional_information) {}
static absl::optional<ProtocolViolationCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
absl::string_view additional_information() const {
return additional_information_;
}
private:
std::string additional_information_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_PROTOCOL_VIOLATION_CAUSE_H_

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.h"
#include <stdint.h>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.11
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=11 | Cause Length=Variable |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / New Address TLVs /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int RestartOfAnAssociationWithNewAddressesCause::kType;
absl::optional<RestartOfAnAssociationWithNewAddressesCause>
RestartOfAnAssociationWithNewAddressesCause::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
return RestartOfAnAssociationWithNewAddressesCause(reader->variable_data());
}
void RestartOfAnAssociationWithNewAddressesCause::SerializeTo(
std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer =
AllocateTLV(out, new_address_tlvs_.size());
writer.CopyToVariableData(new_address_tlvs_);
}
std::string RestartOfAnAssociationWithNewAddressesCause::ToString() const {
return "Restart of an Association with New Addresses";
}
} // namespace dcsctp

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESS_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESS_CAUSE_H_
#include <stddef.h>
#include <cstdint>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.11
struct RestartOfAnAssociationWithNewAddressesCauseConfig
: public ParameterConfig {
static constexpr int kType = 11;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class RestartOfAnAssociationWithNewAddressesCause
: public Parameter,
public TLVTrait<RestartOfAnAssociationWithNewAddressesCauseConfig> {
public:
static constexpr int kType =
RestartOfAnAssociationWithNewAddressesCauseConfig::kType;
explicit RestartOfAnAssociationWithNewAddressesCause(
rtc::ArrayView<const uint8_t> new_address_tlvs)
: new_address_tlvs_(new_address_tlvs.begin(), new_address_tlvs.end()) {}
static absl::optional<RestartOfAnAssociationWithNewAddressesCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
rtc::ArrayView<const uint8_t> new_address_tlvs() const {
return new_address_tlvs_;
}
private:
std::vector<uint8_t> new_address_tlvs_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESS_CAUSE_H_

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/stale_cookie_error_cause.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.3
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=3 | Cause Length=8 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Measure of Staleness (usec.) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int StaleCookieErrorCause::kType;
absl::optional<StaleCookieErrorCause> StaleCookieErrorCause::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
uint32_t staleness_us = reader->Load32<4>();
return StaleCookieErrorCause(staleness_us);
}
void StaleCookieErrorCause::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
writer.Store32<4>(staleness_us_);
}
std::string StaleCookieErrorCause::ToString() const {
rtc::StringBuilder sb;
sb << "Stale Cookie Error, staleness_us=" << staleness_us_;
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_STALE_COOKIE_ERROR_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_STALE_COOKIE_ERROR_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.3
struct StaleCookieParameterConfig : public ParameterConfig {
static constexpr int kType = 3;
static constexpr size_t kHeaderSize = 8;
static constexpr size_t kVariableLengthAlignment = 0;
};
class StaleCookieErrorCause : public Parameter,
public TLVTrait<StaleCookieParameterConfig> {
public:
static constexpr int kType = StaleCookieParameterConfig::kType;
explicit StaleCookieErrorCause(uint32_t staleness_us)
: staleness_us_(staleness_us) {}
static absl::optional<StaleCookieErrorCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
uint16_t staleness_us() const { return staleness_us_; }
private:
uint32_t staleness_us_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_STALE_COOKIE_ERROR_CAUSE_H_

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h"
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.6
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=6 | Cause Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / Unrecognized Chunk /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int UnrecognizedChunkTypeCause::kType;
absl::optional<UnrecognizedChunkTypeCause> UnrecognizedChunkTypeCause::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
std::vector<uint8_t> unrecognized_chunk(reader->variable_data().begin(),
reader->variable_data().end());
return UnrecognizedChunkTypeCause(std::move(unrecognized_chunk));
}
void UnrecognizedChunkTypeCause::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer =
AllocateTLV(out, unrecognized_chunk_.size());
writer.CopyToVariableData(unrecognized_chunk_);
}
std::string UnrecognizedChunkTypeCause::ToString() const {
rtc::StringBuilder sb;
sb << "Unrecognized Chunk Type, chunk_type=";
if (!unrecognized_chunk_.empty()) {
sb << static_cast<int>(unrecognized_chunk_[0]);
} else {
sb << "<missing>";
}
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_CHUNK_TYPE_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_CHUNK_TYPE_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.6
struct UnrecognizedChunkTypeCauseConfig : public ParameterConfig {
static constexpr int kType = 6;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class UnrecognizedChunkTypeCause
: public Parameter,
public TLVTrait<UnrecognizedChunkTypeCauseConfig> {
public:
static constexpr int kType = UnrecognizedChunkTypeCauseConfig::kType;
explicit UnrecognizedChunkTypeCause(std::vector<uint8_t> unrecognized_chunk)
: unrecognized_chunk_(std::move(unrecognized_chunk)) {}
static absl::optional<UnrecognizedChunkTypeCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
rtc::ArrayView<const uint8_t> unrecognized_chunk() const {
return unrecognized_chunk_;
}
private:
std::vector<uint8_t> unrecognized_chunk_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_CHUNK_TYPE_CAUSE_H_

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h"
#include <stdint.h>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.8
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=8 | Cause Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / Unrecognized Parameters /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int UnrecognizedParametersCause::kType;
absl::optional<UnrecognizedParametersCause> UnrecognizedParametersCause::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
return UnrecognizedParametersCause(reader->variable_data());
}
void UnrecognizedParametersCause::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer =
AllocateTLV(out, unrecognized_parameters_.size());
writer.CopyToVariableData(unrecognized_parameters_);
}
std::string UnrecognizedParametersCause::ToString() const {
return "Unrecognized Parameters";
}
} // namespace dcsctp

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_PARAMETER_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_PARAMETER_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <cstdint>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.8
struct UnrecognizedParametersCauseConfig : public ParameterConfig {
static constexpr int kType = 8;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class UnrecognizedParametersCause
: public Parameter,
public TLVTrait<UnrecognizedParametersCauseConfig> {
public:
static constexpr int kType = UnrecognizedParametersCauseConfig::kType;
explicit UnrecognizedParametersCause(
rtc::ArrayView<const uint8_t> unrecognized_parameters)
: unrecognized_parameters_(unrecognized_parameters.begin(),
unrecognized_parameters.end()) {}
static absl::optional<UnrecognizedParametersCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
rtc::ArrayView<const uint8_t> unrecognized_parameters() const {
return unrecognized_parameters_;
}
private:
std::vector<uint8_t> unrecognized_parameters_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_PARAMETER_CAUSE_H_

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/unresolvable_address_cause.h"
#include <stdint.h>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.5
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=5 | Cause Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / Unresolvable Address /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int UnresolvableAddressCause::kType;
absl::optional<UnresolvableAddressCause> UnresolvableAddressCause::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
return UnresolvableAddressCause(reader->variable_data());
}
void UnresolvableAddressCause::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer =
AllocateTLV(out, unresolvable_address_.size());
writer.CopyToVariableData(unresolvable_address_);
}
std::string UnresolvableAddressCause::ToString() const {
return "Unresolvable Address";
}
} // namespace dcsctp

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_UNRESOLVABLE_ADDRESS_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_UNRESOLVABLE_ADDRESS_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <cstdint>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.5
struct UnresolvableAddressCauseConfig : public ParameterConfig {
static constexpr int kType = 5;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class UnresolvableAddressCause
: public Parameter,
public TLVTrait<UnresolvableAddressCauseConfig> {
public:
static constexpr int kType = UnresolvableAddressCauseConfig::kType;
explicit UnresolvableAddressCause(
rtc::ArrayView<const uint8_t> unresolvable_address)
: unresolvable_address_(unresolvable_address.begin(),
unresolvable_address.end()) {}
static absl::optional<UnresolvableAddressCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
rtc::ArrayView<const uint8_t> unresolvable_address() const {
return unresolvable_address_;
}
private:
std::vector<uint8_t> unresolvable_address_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_UNRESOLVABLE_ADDRESS_CAUSE_H_

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/error_cause/user_initiated_abort_cause.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.12
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Cause Code=12 | Cause Length=Variable |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / Upper Layer Abort Reason /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int UserInitiatedAbortCause::kType;
absl::optional<UserInitiatedAbortCause> UserInitiatedAbortCause::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
if (reader->variable_data().empty()) {
return UserInitiatedAbortCause("");
}
return UserInitiatedAbortCause(
std::string(reinterpret_cast<const char*>(reader->variable_data().data()),
reader->variable_data().size()));
}
void UserInitiatedAbortCause::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer =
AllocateTLV(out, upper_layer_abort_reason_.size());
writer.CopyToVariableData(rtc::MakeArrayView(
reinterpret_cast<const uint8_t*>(upper_layer_abort_reason_.data()),
upper_layer_abort_reason_.size()));
}
std::string UserInitiatedAbortCause::ToString() const {
rtc::StringBuilder sb;
sb << "User-Initiated Abort, reason=" << upper_layer_abort_reason_;
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_USER_INITIATED_ABORT_CAUSE_H_
#define NET_DCSCTP_PACKET_ERROR_CAUSE_USER_INITIATED_ABORT_CAUSE_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/error_cause/error_cause.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.10.12
struct UserInitiatedAbortCauseConfig : public ParameterConfig {
static constexpr int kType = 12;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class UserInitiatedAbortCause : public Parameter,
public TLVTrait<UserInitiatedAbortCauseConfig> {
public:
static constexpr int kType = UserInitiatedAbortCauseConfig::kType;
explicit UserInitiatedAbortCause(absl::string_view upper_layer_abort_reason)
: upper_layer_abort_reason_(upper_layer_abort_reason) {}
static absl::optional<UserInitiatedAbortCause> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
absl::string_view upper_layer_abort_reason() const {
return upper_layer_abort_reason_;
}
private:
std::string upper_layer_abort_reason_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_USER_INITIATED_ABORT_CAUSE_H_

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.6
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Parameter Type = 18 | Parameter Length = 12 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Re-configuration Request Sequence Number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Number of new streams | Reserved |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int AddIncomingStreamsRequestParameter::kType;
absl::optional<AddIncomingStreamsRequestParameter>
AddIncomingStreamsRequestParameter::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
ReconfigRequestSN request_sequence_number(reader->Load32<4>());
uint16_t nbr_of_new_streams = reader->Load16<8>();
return AddIncomingStreamsRequestParameter(request_sequence_number,
nbr_of_new_streams);
}
void AddIncomingStreamsRequestParameter::SerializeTo(
std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
writer.Store32<4>(*request_sequence_number_);
writer.Store16<8>(nbr_of_new_streams_);
}
std::string AddIncomingStreamsRequestParameter::ToString() const {
rtc::StringBuilder sb;
sb << "Add Incoming Streams Request, req_seq_nbr="
<< *request_sequence_number();
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_ADD_INCOMING_STREAMS_REQUEST_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_ADD_INCOMING_STREAMS_REQUEST_PARAMETER_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.6
struct AddIncomingStreamsRequestParameterConfig : ParameterConfig {
static constexpr int kType = 18;
static constexpr size_t kHeaderSize = 12;
static constexpr size_t kVariableLengthAlignment = 0;
};
class AddIncomingStreamsRequestParameter
: public Parameter,
public TLVTrait<AddIncomingStreamsRequestParameterConfig> {
public:
static constexpr int kType = AddIncomingStreamsRequestParameterConfig::kType;
explicit AddIncomingStreamsRequestParameter(
ReconfigRequestSN request_sequence_number,
uint16_t nbr_of_new_streams)
: request_sequence_number_(request_sequence_number),
nbr_of_new_streams_(nbr_of_new_streams) {}
static absl::optional<AddIncomingStreamsRequestParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
ReconfigRequestSN request_sequence_number() const {
return request_sequence_number_;
}
uint16_t nbr_of_new_streams() const { return nbr_of_new_streams_; }
private:
ReconfigRequestSN request_sequence_number_;
uint16_t nbr_of_new_streams_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_ADD_INCOMING_STREAMS_REQUEST_PARAMETER_H_

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.5
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Parameter Type = 17 | Parameter Length = 12 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Re-configuration Request Sequence Number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Number of new streams | Reserved |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int AddOutgoingStreamsRequestParameter::kType;
absl::optional<AddOutgoingStreamsRequestParameter>
AddOutgoingStreamsRequestParameter::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
ReconfigRequestSN request_sequence_number(reader->Load32<4>());
uint16_t nbr_of_new_streams = reader->Load16<8>();
return AddOutgoingStreamsRequestParameter(request_sequence_number,
nbr_of_new_streams);
}
void AddOutgoingStreamsRequestParameter::SerializeTo(
std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
writer.Store32<4>(*request_sequence_number_);
writer.Store16<8>(nbr_of_new_streams_);
}
std::string AddOutgoingStreamsRequestParameter::ToString() const {
rtc::StringBuilder sb;
sb << "Add Outgoing Streams Request, req_seq_nbr="
<< *request_sequence_number();
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_ADD_OUTGOING_STREAMS_REQUEST_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_ADD_OUTGOING_STREAMS_REQUEST_PARAMETER_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.5
struct AddOutgoingStreamsRequestParameterConfig : ParameterConfig {
static constexpr int kType = 17;
static constexpr size_t kHeaderSize = 12;
static constexpr size_t kVariableLengthAlignment = 0;
};
class AddOutgoingStreamsRequestParameter
: public Parameter,
public TLVTrait<AddOutgoingStreamsRequestParameterConfig> {
public:
static constexpr int kType = AddOutgoingStreamsRequestParameterConfig::kType;
explicit AddOutgoingStreamsRequestParameter(
ReconfigRequestSN request_sequence_number,
uint16_t nbr_of_new_streams)
: request_sequence_number_(request_sequence_number),
nbr_of_new_streams_(nbr_of_new_streams) {}
static absl::optional<AddOutgoingStreamsRequestParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
ReconfigRequestSN request_sequence_number() const {
return request_sequence_number_;
}
uint16_t nbr_of_new_streams() const { return nbr_of_new_streams_; }
private:
ReconfigRequestSN request_sequence_number_;
uint16_t nbr_of_new_streams_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_ADD_OUTGOING_STREAMS_REQUEST_PARAMETER_H_

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/forward_tsn_supported_parameter.h"
#include <stdint.h>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc3758#section-3.1
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Parameter Type = 49152 | Parameter Length = 4 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ForwardTsnSupportedParameter::kType;
absl::optional<ForwardTsnSupportedParameter>
ForwardTsnSupportedParameter::Parse(rtc::ArrayView<const uint8_t> data) {
if (!ParseTLV(data).has_value()) {
return absl::nullopt;
}
return ForwardTsnSupportedParameter();
}
void ForwardTsnSupportedParameter::SerializeTo(
std::vector<uint8_t>& out) const {
AllocateTLV(out);
}
std::string ForwardTsnSupportedParameter::ToString() const {
return "Forward TSN Supported";
}
} // namespace dcsctp

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_FORWARD_TSN_SUPPORTED_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_FORWARD_TSN_SUPPORTED_PARAMETER_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc3758#section-3.1
struct ForwardTsnSupportedParameterConfig : ParameterConfig {
static constexpr int kType = 49152;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 0;
};
class ForwardTsnSupportedParameter
: public Parameter,
public TLVTrait<ForwardTsnSupportedParameterConfig> {
public:
static constexpr int kType = ForwardTsnSupportedParameterConfig::kType;
ForwardTsnSupportedParameter() {}
static absl::optional<ForwardTsnSupportedParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_FORWARD_TSN_SUPPORTED_PARAMETER_H_

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/heartbeat_info_parameter.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.5
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 4 | Chunk Flags | Heartbeat Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// \ \
// / Heartbeat Information TLV (Variable-Length) /
// \ \
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int HeartbeatInfoParameter::kType;
absl::optional<HeartbeatInfoParameter> HeartbeatInfoParameter::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
return HeartbeatInfoParameter(reader->variable_data());
}
void HeartbeatInfoParameter::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, info_.size());
writer.CopyToVariableData(info_);
}
std::string HeartbeatInfoParameter::ToString() const {
rtc::StringBuilder sb;
sb << "Heartbeat Info parameter (info_length=" << info_.size() << ")";
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_HEARTBEAT_INFO_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_HEARTBEAT_INFO_PARAMETER_H_
#include <stddef.h>
#include <cstdint>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.5
struct HeartbeatInfoParameterConfig : ParameterConfig {
static constexpr int kType = 1;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class HeartbeatInfoParameter : public Parameter,
public TLVTrait<HeartbeatInfoParameterConfig> {
public:
static constexpr int kType = HeartbeatInfoParameterConfig::kType;
explicit HeartbeatInfoParameter(rtc::ArrayView<const uint8_t> info)
: info_(info.begin(), info.end()) {}
static absl::optional<HeartbeatInfoParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
rtc::ArrayView<const uint8_t> info() const { return info_; }
private:
std::vector<uint8_t> info_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_HEARTBEAT_INFO_PARAMETER_H_

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h"
#include <stddef.h>
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.2
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Parameter Type = 14 | Parameter Length = 8 + 2 * N |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Re-configuration Request Sequence Number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream Number 1 (optional) | Stream Number 2 (optional) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / ...... /
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream Number N-1 (optional) | Stream Number N (optional) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int IncomingSSNResetRequestParameter::kType;
absl::optional<IncomingSSNResetRequestParameter>
IncomingSSNResetRequestParameter::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
ReconfigRequestSN request_sequence_number(reader->Load32<4>());
size_t stream_count = reader->variable_data_size() / kStreamIdSize;
std::vector<StreamID> stream_ids;
stream_ids.reserve(stream_count);
for (size_t i = 0; i < stream_count; ++i) {
BoundedByteReader<kStreamIdSize> sub_reader =
reader->sub_reader<kStreamIdSize>(i * kStreamIdSize);
stream_ids.push_back(StreamID(sub_reader.Load16<0>()));
}
return IncomingSSNResetRequestParameter(request_sequence_number,
std::move(stream_ids));
}
void IncomingSSNResetRequestParameter::SerializeTo(
std::vector<uint8_t>& out) const {
size_t variable_size = stream_ids_.size() * kStreamIdSize;
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);
writer.Store32<4>(*request_sequence_number_);
for (size_t i = 0; i < stream_ids_.size(); ++i) {
BoundedByteWriter<kStreamIdSize> sub_writer =
writer.sub_writer<kStreamIdSize>(i * kStreamIdSize);
sub_writer.Store16<0>(*stream_ids_[i]);
}
}
std::string IncomingSSNResetRequestParameter::ToString() const {
rtc::StringBuilder sb;
sb << "Incoming SSN Reset Request, req_seq_nbr="
<< *request_sequence_number();
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_INCOMING_SSN_RESET_REQUEST_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_INCOMING_SSN_RESET_REQUEST_PARAMETER_H_
#include <stddef.h>
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/public/types.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.2
struct IncomingSSNResetRequestParameterConfig : ParameterConfig {
static constexpr int kType = 14;
static constexpr size_t kHeaderSize = 8;
static constexpr size_t kVariableLengthAlignment = 2;
};
class IncomingSSNResetRequestParameter
: public Parameter,
public TLVTrait<IncomingSSNResetRequestParameterConfig> {
public:
static constexpr int kType = IncomingSSNResetRequestParameterConfig::kType;
explicit IncomingSSNResetRequestParameter(
ReconfigRequestSN request_sequence_number,
std::vector<StreamID> stream_ids)
: request_sequence_number_(request_sequence_number),
stream_ids_(std::move(stream_ids)) {}
static absl::optional<IncomingSSNResetRequestParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
ReconfigRequestSN request_sequence_number() const {
return request_sequence_number_;
}
rtc::ArrayView<const StreamID> stream_ids() const { return stream_ids_; }
private:
static constexpr size_t kStreamIdSize = sizeof(uint16_t);
ReconfigRequestSN request_sequence_number_;
std::vector<StreamID> stream_ids_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_INCOMING_SSN_RESET_REQUEST_PARAMETER_H_

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.h"
#include <stddef.h>
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "net/dcsctp/public/types.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.1
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Parameter Type = 13 | Parameter Length = 16 + 2 * N |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Re-configuration Request Sequence Number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Re-configuration Response Sequence Number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Sender's Last Assigned TSN |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream Number 1 (optional) | Stream Number 2 (optional) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// / ...... /
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Stream Number N-1 (optional) | Stream Number N (optional) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int OutgoingSSNResetRequestParameter::kType;
absl::optional<OutgoingSSNResetRequestParameter>
OutgoingSSNResetRequestParameter::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
ReconfigRequestSN request_sequence_number(reader->Load32<4>());
ReconfigRequestSN response_sequence_number(reader->Load32<8>());
TSN sender_last_assigned_tsn(reader->Load32<12>());
size_t stream_count = reader->variable_data_size() / kStreamIdSize;
std::vector<StreamID> stream_ids;
stream_ids.reserve(stream_count);
for (size_t i = 0; i < stream_count; ++i) {
BoundedByteReader<kStreamIdSize> sub_reader =
reader->sub_reader<kStreamIdSize>(i * kStreamIdSize);
stream_ids.push_back(StreamID(sub_reader.Load16<0>()));
}
return OutgoingSSNResetRequestParameter(
request_sequence_number, response_sequence_number,
sender_last_assigned_tsn, std::move(stream_ids));
}
void OutgoingSSNResetRequestParameter::SerializeTo(
std::vector<uint8_t>& out) const {
size_t variable_size = stream_ids_.size() * kStreamIdSize;
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);
writer.Store32<4>(*request_sequence_number_);
writer.Store32<8>(*response_sequence_number_);
writer.Store32<12>(*sender_last_assigned_tsn_);
for (size_t i = 0; i < stream_ids_.size(); ++i) {
BoundedByteWriter<kStreamIdSize> sub_writer =
writer.sub_writer<kStreamIdSize>(i * kStreamIdSize);
sub_writer.Store16<0>(*stream_ids_[i]);
}
}
std::string OutgoingSSNResetRequestParameter::ToString() const {
rtc::StringBuilder sb;
sb << "Outgoing SSN Reset Request, req_seq_nbr=" << *request_sequence_number()
<< ", resp_seq_nbr=" << *response_sequence_number()
<< ", sender_last_asg_tsn=" << *sender_last_assigned_tsn();
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_OUTGOING_SSN_RESET_REQUEST_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_OUTGOING_SSN_RESET_REQUEST_PARAMETER_H_
#include <stddef.h>
#include <stdint.h>
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "net/dcsctp/public/types.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.1
struct OutgoingSSNResetRequestParameterConfig : ParameterConfig {
static constexpr int kType = 13;
static constexpr size_t kHeaderSize = 16;
static constexpr size_t kVariableLengthAlignment = 2;
};
class OutgoingSSNResetRequestParameter
: public Parameter,
public TLVTrait<OutgoingSSNResetRequestParameterConfig> {
public:
static constexpr int kType = OutgoingSSNResetRequestParameterConfig::kType;
explicit OutgoingSSNResetRequestParameter(
ReconfigRequestSN request_sequence_number,
ReconfigRequestSN response_sequence_number,
TSN sender_last_assigned_tsn,
std::vector<StreamID> stream_ids)
: request_sequence_number_(request_sequence_number),
response_sequence_number_(response_sequence_number),
sender_last_assigned_tsn_(sender_last_assigned_tsn),
stream_ids_(std::move(stream_ids)) {}
static absl::optional<OutgoingSSNResetRequestParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
ReconfigRequestSN request_sequence_number() const {
return request_sequence_number_;
}
ReconfigRequestSN response_sequence_number() const {
return response_sequence_number_;
}
TSN sender_last_assigned_tsn() const { return sender_last_assigned_tsn_; }
rtc::ArrayView<const StreamID> stream_ids() const { return stream_ids_; }
private:
static constexpr size_t kStreamIdSize = sizeof(uint16_t);
ReconfigRequestSN request_sequence_number_;
ReconfigRequestSN response_sequence_number_;
TSN sender_last_assigned_tsn_;
std::vector<StreamID> stream_ids_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_OUTGOING_SSN_RESET_REQUEST_PARAMETER_H_

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/parameter.h"
#include <stddef.h>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/memory/memory.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/common/math.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.h"
#include "net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.h"
#include "net/dcsctp/packet/parameter/forward_tsn_supported_parameter.h"
#include "net/dcsctp/packet/parameter/heartbeat_info_parameter.h"
#include "net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h"
#include "net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.h"
#include "net/dcsctp/packet/parameter/reconfiguration_response_parameter.h"
#include "net/dcsctp/packet/parameter/ssn_tsn_reset_request_parameter.h"
#include "net/dcsctp/packet/parameter/state_cookie_parameter.h"
#include "net/dcsctp/packet/parameter/supported_extensions_parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
constexpr size_t kParameterHeaderSize = 4;
Parameters::Builder& Parameters::Builder::Add(const Parameter& p) {
// https://tools.ietf.org/html/rfc4960#section-3.2.1
// "If the length of the parameter is not a multiple of 4 bytes, the sender
// pads the parameter at the end (i.e., after the Parameter Value field) with
// all zero bytes."
if (data_.size() % 4 != 0) {
data_.resize(RoundUpTo4(data_.size()));
}
p.SerializeTo(data_);
return *this;
}
std::vector<ParameterDescriptor> Parameters::descriptors() const {
rtc::ArrayView<const uint8_t> span(data_);
std::vector<ParameterDescriptor> result;
while (!span.empty()) {
BoundedByteReader<kParameterHeaderSize> header(span);
uint16_t type = header.Load16<0>();
uint16_t length = header.Load16<2>();
result.emplace_back(type, span.subview(0, length));
size_t length_with_padding = RoundUpTo4(length);
if (length_with_padding > span.size()) {
break;
}
span = span.subview(length_with_padding);
}
return result;
}
absl::optional<Parameters> Parameters::Parse(
rtc::ArrayView<const uint8_t> data) {
// Validate the parameter descriptors
rtc::ArrayView<const uint8_t> span(data);
while (!span.empty()) {
if (span.size() < kParameterHeaderSize) {
RTC_DLOG(LS_WARNING) << "Insufficient parameter length";
return absl::nullopt;
}
BoundedByteReader<kParameterHeaderSize> header(span);
uint16_t length = header.Load16<2>();
if (length < kParameterHeaderSize || length > span.size()) {
RTC_DLOG(LS_WARNING) << "Invalid parameter length field";
return absl::nullopt;
}
size_t length_with_padding = RoundUpTo4(length);
if (length_with_padding > span.size()) {
break;
}
span = span.subview(length_with_padding);
}
return Parameters(std::vector<uint8_t>(data.begin(), data.end()));
}
} // namespace dcsctp

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_PARAMETER_H_
#include <stddef.h>
#include <algorithm>
#include <cstdint>
#include <iterator>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "absl/algorithm/container.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
class Parameter {
public:
Parameter() {}
virtual ~Parameter() = default;
Parameter(const Parameter& other) = default;
Parameter& operator=(const Parameter& other) = default;
virtual void SerializeTo(std::vector<uint8_t>& out) const = 0;
virtual std::string ToString() const = 0;
};
struct ParameterDescriptor {
ParameterDescriptor(uint16_t type, rtc::ArrayView<const uint8_t> data)
: type(type), data(data) {}
uint16_t type;
rtc::ArrayView<const uint8_t> data;
};
class Parameters {
public:
class Builder {
public:
Builder() {}
Builder& Add(const Parameter& p);
Parameters Build() { return Parameters(std::move(data_)); }
private:
std::vector<uint8_t> data_;
};
static absl::optional<Parameters> Parse(rtc::ArrayView<const uint8_t> data);
Parameters() {}
Parameters(Parameters&& other) = default;
Parameters& operator=(Parameters&& other) = default;
rtc::ArrayView<const uint8_t> data() const { return data_; }
std::vector<ParameterDescriptor> descriptors() const;
template <typename P>
absl::optional<P> get() const {
static_assert(std::is_base_of<Parameter, P>::value,
"Template parameter not derived from Parameter");
for (const auto& p : descriptors()) {
if (p.type == P::kType) {
return P::Parse(p.data);
}
}
return absl::nullopt;
}
private:
explicit Parameters(std::vector<uint8_t> data) : data_(std::move(data)) {}
std::vector<uint8_t> data_;
};
struct ParameterConfig {
static constexpr int kTypeSizeInBytes = 2;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_PARAMETER_H_

View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/reconfiguration_response_parameter.h"
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.4
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Parameter Type = 16 | Parameter Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Re-configuration Response Sequence Number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Result |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Sender's Next TSN (optional) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Receiver's Next TSN (optional) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ReconfigurationResponseParameter::kType;
absl::string_view ToString(ReconfigurationResponseParameter::Result result) {
switch (result) {
case ReconfigurationResponseParameter::Result::kSuccessNothingToDo:
return "Success: nothing to do";
case ReconfigurationResponseParameter::Result::kSuccessPerformed:
return "Success: performed";
case ReconfigurationResponseParameter::Result::kDenied:
return "Denied";
case ReconfigurationResponseParameter::Result::kErrorWrongSSN:
return "Error: wrong ssn";
case ReconfigurationResponseParameter::Result::
kErrorRequestAlreadyInProgress:
return "Error: request already in progress";
case ReconfigurationResponseParameter::Result::kErrorBadSequenceNumber:
return "Error: bad sequence number";
case ReconfigurationResponseParameter::Result::kInProgress:
return "In progress";
}
}
absl::optional<ReconfigurationResponseParameter>
ReconfigurationResponseParameter::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
ReconfigRequestSN response_sequence_number(reader->Load32<4>());
Result result;
uint32_t result_nbr = reader->Load32<8>();
switch (result_nbr) {
case 0:
result = ReconfigurationResponseParameter::Result::kSuccessNothingToDo;
break;
case 1:
result = ReconfigurationResponseParameter::Result::kSuccessPerformed;
break;
case 2:
result = ReconfigurationResponseParameter::Result::kDenied;
break;
case 3:
result = ReconfigurationResponseParameter::Result::kErrorWrongSSN;
break;
case 4:
result = ReconfigurationResponseParameter::Result::
kErrorRequestAlreadyInProgress;
break;
case 5:
result =
ReconfigurationResponseParameter::Result::kErrorBadSequenceNumber;
break;
case 6:
result = ReconfigurationResponseParameter::Result::kInProgress;
break;
default:
RTC_DLOG(LS_WARNING) << "Invalid reconfig response result: "
<< result_nbr;
return absl::nullopt;
}
if (reader->variable_data().empty()) {
return ReconfigurationResponseParameter(response_sequence_number, result);
} else if (reader->variable_data_size() != kNextTsnHeaderSize) {
RTC_DLOG(LS_WARNING) << "Invalid parameter size";
return absl::nullopt;
}
BoundedByteReader<kNextTsnHeaderSize> sub_reader =
reader->sub_reader<kNextTsnHeaderSize>(0);
TSN sender_next_tsn(sub_reader.Load32<0>());
TSN receiver_next_tsn(sub_reader.Load32<4>());
return ReconfigurationResponseParameter(response_sequence_number, result,
sender_next_tsn, receiver_next_tsn);
}
void ReconfigurationResponseParameter::SerializeTo(
std::vector<uint8_t>& out) const {
size_t variable_size =
(sender_next_tsn().has_value() ? kNextTsnHeaderSize : 0);
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);
writer.Store32<4>(*response_sequence_number_);
uint32_t result_nbr =
static_cast<std::underlying_type<Result>::type>(result_);
writer.Store32<8>(result_nbr);
if (sender_next_tsn().has_value()) {
BoundedByteWriter<kNextTsnHeaderSize> sub_writer =
writer.sub_writer<kNextTsnHeaderSize>(0);
sub_writer.Store32<0>(sender_next_tsn_.has_value() ? **sender_next_tsn_
: 0);
sub_writer.Store32<4>(receiver_next_tsn_.has_value() ? **receiver_next_tsn_
: 0);
}
}
std::string ReconfigurationResponseParameter::ToString() const {
rtc::StringBuilder sb;
sb << "Re-configuration Response, resp_seq_nbr="
<< *response_sequence_number();
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_RECONFIGURATION_RESPONSE_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_RECONFIGURATION_RESPONSE_PARAMETER_H_
#include <stddef.h>
#include <cstdint>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.4
struct ReconfigurationResponseParameterConfig : ParameterConfig {
static constexpr int kType = 16;
static constexpr size_t kHeaderSize = 12;
static constexpr size_t kVariableLengthAlignment = 4;
};
class ReconfigurationResponseParameter
: public Parameter,
public TLVTrait<ReconfigurationResponseParameterConfig> {
public:
static constexpr int kType = ReconfigurationResponseParameterConfig::kType;
enum class Result {
kSuccessNothingToDo = 0,
kSuccessPerformed = 1,
kDenied = 2,
kErrorWrongSSN = 3,
kErrorRequestAlreadyInProgress = 4,
kErrorBadSequenceNumber = 5,
kInProgress = 6,
};
ReconfigurationResponseParameter(ReconfigRequestSN response_sequence_number,
Result result)
: response_sequence_number_(response_sequence_number),
result_(result),
sender_next_tsn_(absl::nullopt),
receiver_next_tsn_(absl::nullopt) {}
explicit ReconfigurationResponseParameter(
ReconfigRequestSN response_sequence_number,
Result result,
TSN sender_next_tsn,
TSN receiver_next_tsn)
: response_sequence_number_(response_sequence_number),
result_(result),
sender_next_tsn_(sender_next_tsn),
receiver_next_tsn_(receiver_next_tsn) {}
static absl::optional<ReconfigurationResponseParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
ReconfigRequestSN response_sequence_number() const {
return response_sequence_number_;
}
Result result() const { return result_; }
absl::optional<TSN> sender_next_tsn() const { return sender_next_tsn_; }
absl::optional<TSN> receiver_next_tsn() const { return receiver_next_tsn_; }
private:
static constexpr size_t kNextTsnHeaderSize = 8;
ReconfigRequestSN response_sequence_number_;
Result result_;
absl::optional<TSN> sender_next_tsn_;
absl::optional<TSN> receiver_next_tsn_;
};
absl::string_view ToString(ReconfigurationResponseParameter::Result result);
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_RECONFIGURATION_RESPONSE_PARAMETER_H_

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/ssn_tsn_reset_request_parameter.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.3
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Parameter Type = 15 | Parameter Length = 8 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Re-configuration Request Sequence Number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int SSNTSNResetRequestParameter::kType;
absl::optional<SSNTSNResetRequestParameter> SSNTSNResetRequestParameter::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
ReconfigRequestSN request_sequence_number(reader->Load32<4>());
return SSNTSNResetRequestParameter(request_sequence_number);
}
void SSNTSNResetRequestParameter::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
writer.Store32<4>(*request_sequence_number_);
}
std::string SSNTSNResetRequestParameter::ToString() const {
rtc::StringBuilder sb;
sb << "SSN/TSN Reset Request, req_seq_nbr=" << *request_sequence_number();
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_SSN_TSN_RESET_REQUEST_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_SSN_TSN_RESET_REQUEST_PARAMETER_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc6525#section-4.3
struct SSNTSNResetRequestParameterConfig : ParameterConfig {
static constexpr int kType = 15;
static constexpr size_t kHeaderSize = 8;
static constexpr size_t kVariableLengthAlignment = 0;
};
class SSNTSNResetRequestParameter
: public Parameter,
public TLVTrait<SSNTSNResetRequestParameterConfig> {
public:
static constexpr int kType = SSNTSNResetRequestParameterConfig::kType;
explicit SSNTSNResetRequestParameter(
ReconfigRequestSN request_sequence_number)
: request_sequence_number_(request_sequence_number) {}
static absl::optional<SSNTSNResetRequestParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
ReconfigRequestSN request_sequence_number() const {
return request_sequence_number_;
}
private:
ReconfigRequestSN request_sequence_number_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_SSN_TSN_RESET_REQUEST_PARAMETER_H_

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/state_cookie_parameter.h"
#include <stdint.h>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.3.1
constexpr int StateCookieParameter::kType;
absl::optional<StateCookieParameter> StateCookieParameter::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
return StateCookieParameter(reader->variable_data());
}
void StateCookieParameter::SerializeTo(std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, data_.size());
writer.CopyToVariableData(data_);
}
std::string StateCookieParameter::ToString() const {
rtc::StringBuilder sb;
sb << "State Cookie parameter (cookie_length=" << data_.size() << ")";
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_STATE_COOKIE_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_STATE_COOKIE_PARAMETER_H_
#include <stddef.h>
#include <stdint.h>
#include <cstdint>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc4960#section-3.3.3.1
struct StateCookieParameterConfig : ParameterConfig {
static constexpr int kType = 7;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class StateCookieParameter : public Parameter,
public TLVTrait<StateCookieParameterConfig> {
public:
static constexpr int kType = StateCookieParameterConfig::kType;
explicit StateCookieParameter(rtc::ArrayView<const uint8_t> data)
: data_(data.begin(), data.end()) {}
static absl::optional<StateCookieParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
rtc::ArrayView<const uint8_t> data() const { return data_; }
private:
std::vector<uint8_t> data_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_STATE_COOKIE_PARAMETER_H_

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/supported_extensions_parameter.h"
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/str_join.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc5061#section-4.2.7
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Parameter Type = 0x8008 | Parameter Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | CHUNK TYPE 1 | CHUNK TYPE 2 | CHUNK TYPE 3 | CHUNK TYPE 4 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | .... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | CHUNK TYPE N | PAD | PAD | PAD |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int SupportedExtensionsParameter::kType;
absl::optional<SupportedExtensionsParameter>
SupportedExtensionsParameter::Parse(rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
std::vector<uint8_t> chunk_types(reader->variable_data().begin(),
reader->variable_data().end());
return SupportedExtensionsParameter(std::move(chunk_types));
}
void SupportedExtensionsParameter::SerializeTo(
std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, chunk_types_.size());
writer.CopyToVariableData(chunk_types_);
}
std::string SupportedExtensionsParameter::ToString() const {
rtc::StringBuilder sb;
sb << "Supported Extensions (" << webrtc::StrJoin(chunk_types_, ", ") << ")";
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_SUPPORTED_EXTENSIONS_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_SUPPORTED_EXTENSIONS_PARAMETER_H_
#include <stddef.h>
#include <algorithm>
#include <cstdint>
#include <iterator>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
namespace dcsctp {
// https://tools.ietf.org/html/rfc5061#section-4.2.7
struct SupportedExtensionsParameterConfig : ParameterConfig {
static constexpr int kType = 0x8008;
static constexpr size_t kHeaderSize = 4;
static constexpr size_t kVariableLengthAlignment = 1;
};
class SupportedExtensionsParameter
: public Parameter,
public TLVTrait<SupportedExtensionsParameterConfig> {
public:
static constexpr int kType = SupportedExtensionsParameterConfig::kType;
explicit SupportedExtensionsParameter(std::vector<uint8_t> chunk_types)
: chunk_types_(std::move(chunk_types)) {}
static absl::optional<SupportedExtensionsParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
bool supports(uint8_t chunk_type) const {
return std::find(chunk_types_.begin(), chunk_types_.end(), chunk_type) !=
chunk_types_.end();
}
rtc::ArrayView<const uint8_t> chunk_types() const { return chunk_types_; }
private:
std::vector<uint8_t> chunk_types_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_SUPPORTED_EXTENSIONS_PARAMETER_H_

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h"
#include <stdint.h>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "rtc_base/strings/string_builder.h"
namespace dcsctp {
// https://www.ietf.org/archive/id/draft-tuexen-tsvwg-sctp-zero-checksum-00.html#section-3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Type = 0x8001 (suggested) | Length = 8 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Error Detection Method Identifier (EDMID) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ZeroChecksumAcceptableChunkParameter::kType;
absl::optional<ZeroChecksumAcceptableChunkParameter>
ZeroChecksumAcceptableChunkParameter::Parse(
rtc::ArrayView<const uint8_t> data) {
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
if (!reader.has_value()) {
return absl::nullopt;
}
ZeroChecksumAlternateErrorDetectionMethod method(reader->Load32<4>());
if (method == ZeroChecksumAlternateErrorDetectionMethod::None()) {
return absl::nullopt;
}
return ZeroChecksumAcceptableChunkParameter(method);
}
void ZeroChecksumAcceptableChunkParameter::SerializeTo(
std::vector<uint8_t>& out) const {
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
writer.Store32<4>(*error_detection_method_);
}
std::string ZeroChecksumAcceptableChunkParameter::ToString() const {
rtc::StringBuilder sb;
sb << "Zero Checksum Acceptable (" << *error_detection_method_ << ")";
return sb.Release();
}
} // namespace dcsctp

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_PARAMETER_ZERO_CHECKSUM_ACCEPTABLE_CHUNK_PARAMETER_H_
#define NET_DCSCTP_PACKET_PARAMETER_ZERO_CHECKSUM_ACCEPTABLE_CHUNK_PARAMETER_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "net/dcsctp/public/types.h"
namespace dcsctp {
// https://datatracker.ietf.org/doc/draft-ietf-tsvwg-sctp-zero-checksum/
struct ZeroChecksumAcceptableChunkParameterConfig : ParameterConfig {
static constexpr int kType = 0x8001;
static constexpr size_t kHeaderSize = 8;
static constexpr size_t kVariableLengthAlignment = 0;
};
class ZeroChecksumAcceptableChunkParameter
: public Parameter,
public TLVTrait<ZeroChecksumAcceptableChunkParameterConfig> {
public:
static constexpr int kType =
ZeroChecksumAcceptableChunkParameterConfig::kType;
explicit ZeroChecksumAcceptableChunkParameter(
ZeroChecksumAlternateErrorDetectionMethod error_detection_method)
: error_detection_method_(error_detection_method) {}
static absl::optional<ZeroChecksumAcceptableChunkParameter> Parse(
rtc::ArrayView<const uint8_t> data);
void SerializeTo(std::vector<uint8_t>& out) const override;
std::string ToString() const override;
ZeroChecksumAlternateErrorDetectionMethod error_detection_method() const {
return error_detection_method_;
}
private:
ZeroChecksumAlternateErrorDetectionMethod error_detection_method_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_PARAMETER_ZERO_CHECKSUM_ACCEPTABLE_CHUNK_PARAMETER_H_

View file

@ -0,0 +1,194 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/sctp_packet.h"
#include <stddef.h>
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "absl/memory/memory.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/common/math.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/crc32c.h"
#include "net/dcsctp/public/dcsctp_options.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_format.h"
namespace dcsctp {
namespace {
constexpr size_t kMaxUdpPacketSize = 65535;
constexpr size_t kChunkTlvHeaderSize = 4;
constexpr size_t kExpectedDescriptorCount = 4;
} // namespace
/*
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port Number | Destination Port Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Verification Tag |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
SctpPacket::Builder::Builder(VerificationTag verification_tag,
const DcSctpOptions& options)
: verification_tag_(verification_tag),
source_port_(options.local_port),
dest_port_(options.remote_port),
max_packet_size_(RoundDownTo4(options.mtu)) {}
SctpPacket::Builder& SctpPacket::Builder::Add(const Chunk& chunk) {
if (out_.empty()) {
out_.reserve(max_packet_size_);
out_.resize(SctpPacket::kHeaderSize);
BoundedByteWriter<kHeaderSize> buffer(out_);
buffer.Store16<0>(source_port_);
buffer.Store16<2>(dest_port_);
buffer.Store32<4>(*verification_tag_);
// Checksum is at offset 8 - written when calling Build(), if configured.
}
RTC_DCHECK(IsDivisibleBy4(out_.size()));
chunk.SerializeTo(out_);
if (out_.size() % 4 != 0) {
out_.resize(RoundUpTo4(out_.size()));
}
RTC_DCHECK(out_.size() <= max_packet_size_)
<< "Exceeded max size, data=" << out_.size()
<< ", max_size=" << max_packet_size_;
return *this;
}
size_t SctpPacket::Builder::bytes_remaining() const {
if (out_.empty()) {
// The packet header (CommonHeader) hasn't been written yet:
return max_packet_size_ - kHeaderSize;
} else if (out_.size() > max_packet_size_) {
RTC_DCHECK_NOTREACHED() << "Exceeded max size, data=" << out_.size()
<< ", max_size=" << max_packet_size_;
return 0;
}
return max_packet_size_ - out_.size();
}
std::vector<uint8_t> SctpPacket::Builder::Build(bool write_checksum) {
std::vector<uint8_t> out;
out_.swap(out);
if (!out.empty() && write_checksum) {
uint32_t crc = GenerateCrc32C(out);
BoundedByteWriter<kHeaderSize>(out).Store32<8>(crc);
}
RTC_DCHECK(out.size() <= max_packet_size_)
<< "Exceeded max size, data=" << out.size()
<< ", max_size=" << max_packet_size_;
return out;
}
absl::optional<SctpPacket> SctpPacket::Parse(rtc::ArrayView<const uint8_t> data,
const DcSctpOptions& options) {
if (data.size() < kHeaderSize + kChunkTlvHeaderSize ||
data.size() > kMaxUdpPacketSize) {
RTC_DLOG(LS_WARNING) << "Invalid packet size";
return absl::nullopt;
}
BoundedByteReader<kHeaderSize> reader(data);
CommonHeader common_header;
common_header.source_port = reader.Load16<0>();
common_header.destination_port = reader.Load16<2>();
common_header.verification_tag = VerificationTag(reader.Load32<4>());
common_header.checksum = reader.Load32<8>();
// Create a copy of the packet, which will be held by this object.
std::vector<uint8_t> data_copy =
std::vector<uint8_t>(data.begin(), data.end());
if (options.disable_checksum_verification ||
(options.zero_checksum_alternate_error_detection_method !=
ZeroChecksumAlternateErrorDetectionMethod::None() &&
common_header.checksum == 0u)) {
// https://www.ietf.org/archive/id/draft-tuexen-tsvwg-sctp-zero-checksum-01.html#section-4.3:
// If an end point has sent the Zero Checksum Acceptable Chunk Parameter in
// an INIT or INIT ACK chunk, it MUST accept SCTP packets using an incorrect
// checksum value of zero in addition to SCTP packets containing the correct
// CRC32c checksum value for this association.
} else {
// Verify the checksum. The checksum field must be zero when that's done.
BoundedByteWriter<kHeaderSize>(data_copy).Store32<8>(0);
uint32_t calculated_checksum = GenerateCrc32C(data_copy);
if (calculated_checksum != common_header.checksum) {
RTC_DLOG(LS_WARNING) << rtc::StringFormat(
"Invalid packet checksum, packet_checksum=0x%08x, "
"calculated_checksum=0x%08x",
common_header.checksum, calculated_checksum);
return absl::nullopt;
}
// Restore the checksum in the header.
BoundedByteWriter<kHeaderSize>(data_copy).Store32<8>(
common_header.checksum);
}
// Validate and parse the chunk headers in the message.
/*
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk Type | Chunk Flags | Chunk Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
std::vector<ChunkDescriptor> descriptors;
descriptors.reserve(kExpectedDescriptorCount);
rtc::ArrayView<const uint8_t> descriptor_data =
rtc::ArrayView<const uint8_t>(data_copy).subview(kHeaderSize);
while (!descriptor_data.empty()) {
if (descriptor_data.size() < kChunkTlvHeaderSize) {
RTC_DLOG(LS_WARNING) << "Too small chunk";
return absl::nullopt;
}
BoundedByteReader<kChunkTlvHeaderSize> chunk_header(descriptor_data);
uint8_t type = chunk_header.Load8<0>();
uint8_t flags = chunk_header.Load8<1>();
uint16_t length = chunk_header.Load16<2>();
uint16_t padded_length = RoundUpTo4(length);
if (padded_length > descriptor_data.size()) {
RTC_DLOG(LS_WARNING) << "Too large chunk. length=" << length
<< ", remaining=" << descriptor_data.size();
return absl::nullopt;
} else if (padded_length < kChunkTlvHeaderSize) {
RTC_DLOG(LS_WARNING) << "Too small chunk. length=" << length;
return absl::nullopt;
}
descriptors.emplace_back(type, flags,
descriptor_data.subview(0, padded_length));
descriptor_data = descriptor_data.subview(padded_length);
}
// Note that iterators (and pointer) are guaranteed to be stable when moving a
// std::vector, and `descriptors` have pointers to within `data_copy`.
return SctpPacket(common_header, std::move(data_copy),
std::move(descriptors));
}
} // namespace dcsctp

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NET_DCSCTP_PACKET_SCTP_PACKET_H_
#define NET_DCSCTP_PACKET_SCTP_PACKET_H_
#include <stddef.h>
#include <cstdint>
#include <functional>
#include <memory>
#include <utility>
#include <vector>
#include "api/array_view.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/public/dcsctp_options.h"
namespace dcsctp {
// The "Common Header", which every SCTP packet starts with, and is described in
// https://tools.ietf.org/html/rfc4960#section-3.1.
struct CommonHeader {
uint16_t source_port;
uint16_t destination_port;
VerificationTag verification_tag;
uint32_t checksum;
};
// Represents an immutable (received or to-be-sent) SCTP packet.
class SctpPacket {
public:
static constexpr size_t kHeaderSize = 12;
struct ChunkDescriptor {
ChunkDescriptor(uint8_t type,
uint8_t flags,
rtc::ArrayView<const uint8_t> data)
: type(type), flags(flags), data(data) {}
uint8_t type;
uint8_t flags;
rtc::ArrayView<const uint8_t> data;
};
SctpPacket(SctpPacket&& other) = default;
SctpPacket& operator=(SctpPacket&& other) = default;
SctpPacket(const SctpPacket&) = delete;
SctpPacket& operator=(const SctpPacket&) = delete;
// Used for building SctpPacket, as those are immutable.
class Builder {
public:
Builder(VerificationTag verification_tag, const DcSctpOptions& options);
Builder(Builder&& other) = default;
Builder& operator=(Builder&& other) = default;
// Adds a chunk to the to-be-built SCTP packet.
Builder& Add(const Chunk& chunk);
// The number of bytes remaining in the packet for chunk storage until the
// packet reaches its maximum size.
size_t bytes_remaining() const;
// Indicates if any packets have been added to the builder.
bool empty() const { return out_.empty(); }
// Returns the payload of the build SCTP packet. The Builder will be cleared
// after having called this function, and can be used to build a new packet.
// If `write_checksum` is set to false, a value of zero (0) will be written
// as the packet's checksum, instead of the crc32c value.
std::vector<uint8_t> Build(bool write_checksum = true);
private:
VerificationTag verification_tag_;
uint16_t source_port_;
uint16_t dest_port_;
// The maximum packet size is always even divisible by four, as chunks are
// always padded to a size even divisible by four.
size_t max_packet_size_;
std::vector<uint8_t> out_;
};
// Parses `data` as an SCTP packet and returns it if it validates.
static absl::optional<SctpPacket> Parse(rtc::ArrayView<const uint8_t> data,
const DcSctpOptions& options);
// Returns the SCTP common header.
const CommonHeader& common_header() const { return common_header_; }
// Returns the chunks (types and offsets) within the packet.
rtc::ArrayView<const ChunkDescriptor> descriptors() const {
return descriptors_;
}
private:
SctpPacket(const CommonHeader& common_header,
std::vector<uint8_t> data,
std::vector<ChunkDescriptor> descriptors)
: common_header_(common_header),
data_(std::move(data)),
descriptors_(std::move(descriptors)) {}
CommonHeader common_header_;
// As the `descriptors_` refer to offset within data, and since SctpPacket is
// movable, `data` needs to be pointer stable, which it is according to
// http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#2321
std::vector<uint8_t> data_;
// The chunks and their offsets within `data_ `.
std::vector<ChunkDescriptor> descriptors_;
};
} // namespace dcsctp
#endif // NET_DCSCTP_PACKET_SCTP_PACKET_H_

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/logging.h"
namespace dcsctp {
namespace tlv_trait_impl {
void ReportInvalidSize(size_t actual_size, size_t expected_size) {
RTC_DLOG(LS_WARNING) << "Invalid size (" << actual_size
<< ", expected minimum " << expected_size << " bytes)";
}
void ReportInvalidType(int actual_type, int expected_type) {
RTC_DLOG(LS_WARNING) << "Invalid type (" << actual_type << ", expected "
<< expected_type << ")";
}
void ReportInvalidFixedLengthField(size_t value, size_t expected) {
RTC_DLOG(LS_WARNING) << "Invalid length field (" << value << ", expected "
<< expected << " bytes)";
}
void ReportInvalidVariableLengthField(size_t value, size_t available) {
RTC_DLOG(LS_WARNING) << "Invalid length field (" << value << ", available "
<< available << " bytes)";
}
void ReportInvalidPadding(size_t padding_bytes) {
RTC_DLOG(LS_WARNING) << "Invalid padding (" << padding_bytes << " bytes)";
}
void ReportInvalidLengthMultiple(size_t length, size_t alignment) {
RTC_DLOG(LS_WARNING) << "Invalid length field (" << length
<< ", expected an even multiple of " << alignment
<< " bytes)";
}
} // namespace tlv_trait_impl
} // namespace dcsctp

Some files were not shown because too many files have changed in this diff Show more