Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
Loading…
Add table
Add a link
Reference in a new issue