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,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_