dcsctp: Add parameters, error causes and chunks
Quite a large commit, but mostly trivial. It adds all the (in dcSCTP) supported parameters, error causes and chunks as an object model, with serializers and deserializers. They are verified with packet captures where available, that have been captured with Wireshark against a reference implementation. This _could_ be split in parameter/ as one commit, error_cause/ in the following, and chunk/ as the third, but as each chunk/parameter is completely isolated from the other, reviewing it should be linear with the number of chunks/parameters and having them in more commits wouldn't change that, taken all those three commits into account. Bug: webrtc:12614 Change-Id: Ie83c9a22cae6e3a39e35ef26fd532837a6387a08 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/213347 Commit-Queue: Victor Boivie <boivie@webrtc.org> Reviewed-by: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33625}
This commit is contained in:

committed by
Commit Bot

parent
b454767f10
commit
b87746b155
@ -10,6 +10,8 @@
|
||||
#ifndef NET_DCSCTP_COMMON_INTERNAL_TYPES_H_
|
||||
#define NET_DCSCTP_COMMON_INTERNAL_TYPES_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "net/dcsctp/public/strong_alias.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
@ -62,13 +62,152 @@ rtc_library("crc32c") {
|
||||
]
|
||||
}
|
||||
|
||||
rtc_library("parameter") {
|
||||
deps = [
|
||||
":data",
|
||||
":tlv_trait",
|
||||
"../../../api:array_view",
|
||||
"../../../rtc_base",
|
||||
"../../../rtc_base:checks",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../common:math",
|
||||
"../common:str_join",
|
||||
]
|
||||
sources = [
|
||||
"parameter/add_incoming_streams_request_parameter.cc",
|
||||
"parameter/add_incoming_streams_request_parameter.h",
|
||||
"parameter/add_outgoing_streams_request_parameter.cc",
|
||||
"parameter/add_outgoing_streams_request_parameter.h",
|
||||
"parameter/forward_tsn_supported_parameter.cc",
|
||||
"parameter/forward_tsn_supported_parameter.h",
|
||||
"parameter/heartbeat_info_parameter.cc",
|
||||
"parameter/heartbeat_info_parameter.h",
|
||||
"parameter/incoming_ssn_reset_request_parameter.cc",
|
||||
"parameter/incoming_ssn_reset_request_parameter.h",
|
||||
"parameter/outgoing_ssn_reset_request_parameter.cc",
|
||||
"parameter/outgoing_ssn_reset_request_parameter.h",
|
||||
"parameter/parameter.cc",
|
||||
"parameter/parameter.h",
|
||||
"parameter/reconfiguration_response_parameter.cc",
|
||||
"parameter/reconfiguration_response_parameter.h",
|
||||
"parameter/ssn_tsn_reset_request_parameter.cc",
|
||||
"parameter/ssn_tsn_reset_request_parameter.h",
|
||||
"parameter/state_cookie_parameter.cc",
|
||||
"parameter/state_cookie_parameter.h",
|
||||
"parameter/supported_extensions_parameter.cc",
|
||||
"parameter/supported_extensions_parameter.h",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_library("error_cause") {
|
||||
deps = [
|
||||
":data",
|
||||
":parameter",
|
||||
":tlv_trait",
|
||||
"../../../api:array_view",
|
||||
"../../../rtc_base",
|
||||
"../../../rtc_base:checks",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../common:math",
|
||||
"../common:str_join",
|
||||
]
|
||||
sources = [
|
||||
"error_cause/cookie_received_while_shutting_down_cause.cc",
|
||||
"error_cause/cookie_received_while_shutting_down_cause.h",
|
||||
"error_cause/error_cause.cc",
|
||||
"error_cause/error_cause.h",
|
||||
"error_cause/invalid_mandatory_parameter_cause.cc",
|
||||
"error_cause/invalid_mandatory_parameter_cause.h",
|
||||
"error_cause/invalid_stream_identifier_cause.cc",
|
||||
"error_cause/invalid_stream_identifier_cause.h",
|
||||
"error_cause/missing_mandatory_parameter_cause.cc",
|
||||
"error_cause/missing_mandatory_parameter_cause.h",
|
||||
"error_cause/no_user_data_cause.cc",
|
||||
"error_cause/no_user_data_cause.h",
|
||||
"error_cause/out_of_resource_error_cause.cc",
|
||||
"error_cause/out_of_resource_error_cause.h",
|
||||
"error_cause/protocol_violation_cause.cc",
|
||||
"error_cause/protocol_violation_cause.h",
|
||||
"error_cause/restart_of_an_association_with_new_address_cause.cc",
|
||||
"error_cause/restart_of_an_association_with_new_address_cause.h",
|
||||
"error_cause/stale_cookie_error_cause.cc",
|
||||
"error_cause/stale_cookie_error_cause.h",
|
||||
"error_cause/unrecognized_chunk_type_cause.cc",
|
||||
"error_cause/unrecognized_chunk_type_cause.h",
|
||||
"error_cause/unrecognized_parameter_cause.cc",
|
||||
"error_cause/unrecognized_parameter_cause.h",
|
||||
"error_cause/unresolvable_address_cause.cc",
|
||||
"error_cause/unresolvable_address_cause.h",
|
||||
"error_cause/user_initiated_abort_cause.cc",
|
||||
"error_cause/user_initiated_abort_cause.h",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_library("chunk") {
|
||||
deps = [
|
||||
":data",
|
||||
":error_cause",
|
||||
":parameter",
|
||||
":tlv_trait",
|
||||
"../../../api:array_view",
|
||||
"../../../rtc_base",
|
||||
"../../../rtc_base:checks",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../common:math",
|
||||
"../common:str_join",
|
||||
]
|
||||
sources = [
|
||||
"chunk/abort_chunk.cc",
|
||||
"chunk/abort_chunk.h",
|
||||
"chunk/chunk.cc",
|
||||
"chunk/chunk.h",
|
||||
"chunk/cookie_ack_chunk.cc",
|
||||
"chunk/cookie_ack_chunk.h",
|
||||
"chunk/cookie_echo_chunk.cc",
|
||||
"chunk/cookie_echo_chunk.h",
|
||||
"chunk/data_chunk.cc",
|
||||
"chunk/data_chunk.h",
|
||||
"chunk/data_common.h",
|
||||
"chunk/error_chunk.cc",
|
||||
"chunk/error_chunk.h",
|
||||
"chunk/forward_tsn_chunk.cc",
|
||||
"chunk/forward_tsn_chunk.h",
|
||||
"chunk/forward_tsn_common.h",
|
||||
"chunk/heartbeat_ack_chunk.cc",
|
||||
"chunk/heartbeat_ack_chunk.h",
|
||||
"chunk/heartbeat_request_chunk.cc",
|
||||
"chunk/heartbeat_request_chunk.h",
|
||||
"chunk/idata_chunk.cc",
|
||||
"chunk/idata_chunk.h",
|
||||
"chunk/iforward_tsn_chunk.cc",
|
||||
"chunk/iforward_tsn_chunk.h",
|
||||
"chunk/init_ack_chunk.cc",
|
||||
"chunk/init_ack_chunk.h",
|
||||
"chunk/init_chunk.cc",
|
||||
"chunk/init_chunk.h",
|
||||
"chunk/reconfig_chunk.cc",
|
||||
"chunk/reconfig_chunk.h",
|
||||
"chunk/sack_chunk.cc",
|
||||
"chunk/sack_chunk.h",
|
||||
"chunk/shutdown_ack_chunk.cc",
|
||||
"chunk/shutdown_ack_chunk.h",
|
||||
"chunk/shutdown_chunk.cc",
|
||||
"chunk/shutdown_chunk.h",
|
||||
"chunk/shutdown_complete_chunk.cc",
|
||||
"chunk/shutdown_complete_chunk.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (rtc_include_tests) {
|
||||
rtc_library("dcsctp_packet_unittests") {
|
||||
testonly = true
|
||||
|
||||
deps = [
|
||||
":bounded_io",
|
||||
":chunk",
|
||||
":crc32c",
|
||||
":error_cause",
|
||||
":parameter",
|
||||
":tlv_trait",
|
||||
"../../../api:array_view",
|
||||
"../../../rtc_base:checks",
|
||||
@ -79,7 +218,46 @@ if (rtc_include_tests) {
|
||||
sources = [
|
||||
"bounded_byte_reader_test.cc",
|
||||
"bounded_byte_writer_test.cc",
|
||||
"chunk/abort_chunk_test.cc",
|
||||
"chunk/cookie_ack_chunk_test.cc",
|
||||
"chunk/cookie_echo_chunk_test.cc",
|
||||
"chunk/data_chunk_test.cc",
|
||||
"chunk/error_chunk_test.cc",
|
||||
"chunk/forward_tsn_chunk_test.cc",
|
||||
"chunk/heartbeat_ack_chunk_test.cc",
|
||||
"chunk/heartbeat_request_chunk_test.cc",
|
||||
"chunk/idata_chunk_test.cc",
|
||||
"chunk/iforward_tsn_chunk_test.cc",
|
||||
"chunk/init_ack_chunk_test.cc",
|
||||
"chunk/init_chunk_test.cc",
|
||||
"chunk/reconfig_chunk_test.cc",
|
||||
"chunk/sack_chunk_test.cc",
|
||||
"chunk/shutdown_ack_chunk_test.cc",
|
||||
"chunk/shutdown_chunk_test.cc",
|
||||
"chunk/shutdown_complete_chunk_test.cc",
|
||||
"crc32c_test.cc",
|
||||
"error_cause/cookie_received_while_shutting_down_cause_test.cc",
|
||||
"error_cause/invalid_mandatory_parameter_cause_test.cc",
|
||||
"error_cause/invalid_stream_identifier_cause_test.cc",
|
||||
"error_cause/missing_mandatory_parameter_cause_test.cc",
|
||||
"error_cause/no_user_data_cause_test.cc",
|
||||
"error_cause/out_of_resource_error_cause_test.cc",
|
||||
"error_cause/protocol_violation_cause_test.cc",
|
||||
"error_cause/restart_of_an_association_with_new_address_cause_test.cc",
|
||||
"error_cause/stale_cookie_error_cause_test.cc",
|
||||
"error_cause/unrecognized_chunk_type_cause_test.cc",
|
||||
"error_cause/unrecognized_parameter_cause_test.cc",
|
||||
"error_cause/unresolvable_address_cause_test.cc",
|
||||
"error_cause/user_initiated_abort_cause_test.cc",
|
||||
"parameter/add_incoming_streams_request_parameter_test.cc",
|
||||
"parameter/forward_tsn_supported_parameter_test.cc",
|
||||
"parameter/incoming_ssn_reset_request_parameter_test.cc",
|
||||
"parameter/outgoing_ssn_reset_request_parameter_test.cc",
|
||||
"parameter/parameter_test.cc",
|
||||
"parameter/reconfiguration_response_parameter_test.cc",
|
||||
"parameter/ssn_tsn_reset_request_parameter_test.cc",
|
||||
"parameter/state_cookie_parameter_test.cc",
|
||||
"parameter/supported_extensions_parameter_test.cc",
|
||||
"tlv_trait_test.cc",
|
||||
]
|
||||
}
|
||||
|
65
net/dcsctp/packet/chunk/abort_chunk.cc
Normal file
65
net/dcsctp/packet/chunk/abort_chunk.cc
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/abort_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.7
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 6 |Reserved |T| Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / zero or more Error Causes /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int AbortChunk::kType;
|
||||
|
||||
absl::optional<AbortChunk> AbortChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
absl::optional<Parameters> error_causes =
|
||||
Parameters::Parse(reader->variable_data());
|
||||
if (!error_causes.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
uint8_t flags = reader->Load8<1>();
|
||||
bool filled_in_verification_tag = (flags & (1 << kFlagsBitT)) == 0;
|
||||
return AbortChunk(filled_in_verification_tag, *std::move(error_causes));
|
||||
}
|
||||
|
||||
void AbortChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
rtc::ArrayView<const uint8_t> error_causes = error_causes_.data();
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, error_causes.size());
|
||||
writer.Store8<1>(filled_in_verification_tag_ ? 0 : (1 << kFlagsBitT));
|
||||
writer.CopyToVariableData(error_causes);
|
||||
}
|
||||
|
||||
std::string AbortChunk::ToString() const {
|
||||
return "ABORT";
|
||||
}
|
||||
} // namespace dcsctp
|
64
net/dcsctp/packet/chunk/abort_chunk.h
Normal file
64
net/dcsctp/packet/chunk/abort_chunk.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_ABORT_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_ABORT_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.7
|
||||
struct AbortChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 6;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class AbortChunk : public Chunk, public TLVTrait<AbortChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = AbortChunkConfig::kType;
|
||||
|
||||
AbortChunk(bool filled_in_verification_tag, Parameters error_causes)
|
||||
: filled_in_verification_tag_(filled_in_verification_tag),
|
||||
error_causes_(std::move(error_causes)) {}
|
||||
|
||||
AbortChunk(AbortChunk&& other) = default;
|
||||
AbortChunk& operator=(AbortChunk&& other) = default;
|
||||
|
||||
static absl::optional<AbortChunk> Parse(rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
bool filled_in_verification_tag() const {
|
||||
return filled_in_verification_tag_;
|
||||
}
|
||||
|
||||
const Parameters& error_causes() const { return error_causes_; }
|
||||
|
||||
private:
|
||||
static constexpr int kFlagsBitT = 0;
|
||||
bool filled_in_verification_tag_;
|
||||
Parameters error_causes_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_ABORT_CHUNK_H_
|
83
net/dcsctp/packet/chunk/abort_chunk_test.cc
Normal file
83
net/dcsctp/packet/chunk/abort_chunk_test.cc
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/abort_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/user_initiated_abort_cause.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(AbortChunkTest, FromCapture) {
|
||||
/*
|
||||
ABORT chunk
|
||||
Chunk type: ABORT (6)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 8
|
||||
User initiated ABORT cause
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x06, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x04};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(AbortChunk chunk, AbortChunk::Parse(data));
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
UserInitiatedAbortCause cause,
|
||||
chunk.error_causes().get<UserInitiatedAbortCause>());
|
||||
|
||||
EXPECT_EQ(cause.upper_layer_abort_reason(), "");
|
||||
}
|
||||
|
||||
TEST(AbortChunkTest, SerializeAndDeserialize) {
|
||||
AbortChunk chunk(/*filled_in_verification_tag=*/true,
|
||||
Parameters::Builder()
|
||||
.Add(UserInitiatedAbortCause("Close called"))
|
||||
.Build());
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(AbortChunk deserialized,
|
||||
AbortChunk::Parse(serialized));
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
UserInitiatedAbortCause cause,
|
||||
deserialized.error_causes().get<UserInitiatedAbortCause>());
|
||||
|
||||
EXPECT_EQ(cause.upper_layer_abort_reason(), "Close called");
|
||||
}
|
||||
|
||||
// Validates that AbortChunk doesn't make any alignment assumptions.
|
||||
TEST(AbortChunkTest, SerializeAndDeserializeOneChar) {
|
||||
AbortChunk chunk(
|
||||
/*filled_in_verification_tag=*/true,
|
||||
Parameters::Builder().Add(UserInitiatedAbortCause("!")).Build());
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(AbortChunk deserialized,
|
||||
AbortChunk::Parse(serialized));
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
UserInitiatedAbortCause cause,
|
||||
deserialized.error_causes().get<UserInitiatedAbortCause>());
|
||||
|
||||
EXPECT_EQ(cause.upper_layer_abort_reason(), "!");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
85
net/dcsctp/packet/chunk/chunk.cc
Normal file
85
net/dcsctp/packet/chunk/chunk.cc
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/common/math.h"
|
||||
#include "net/dcsctp/packet/chunk/abort_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/cookie_ack_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/cookie_echo_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/data_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/error_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/heartbeat_ack_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/heartbeat_request_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/idata_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/iforward_tsn_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/init_ack_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/init_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/reconfig_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/sack_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/shutdown_ack_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/shutdown_chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/shutdown_complete_chunk.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
template <class Chunk>
|
||||
bool ParseAndPrint(uint8_t chunk_type,
|
||||
rtc::ArrayView<const uint8_t> data,
|
||||
rtc::StringBuilder& sb) {
|
||||
if (chunk_type == Chunk::kType) {
|
||||
absl::optional<Chunk> c = Chunk::Parse(data);
|
||||
if (c.has_value()) {
|
||||
sb << c->ToString();
|
||||
} else {
|
||||
sb << "Failed to parse chunk of type " << chunk_type;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string DebugConvertChunkToString(rtc::ArrayView<const uint8_t> data) {
|
||||
rtc::StringBuilder sb;
|
||||
|
||||
if (data.empty()) {
|
||||
sb << "Failed to parse chunk due to empty data";
|
||||
} else {
|
||||
uint8_t chunk_type = data[0];
|
||||
if (!ParseAndPrint<DataChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<InitChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<InitAckChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<SackChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<HeartbeatRequestChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<HeartbeatAckChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<AbortChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<ErrorChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<CookieEchoChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<CookieAckChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<ShutdownChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<ShutdownAckChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<ShutdownCompleteChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<ReConfigChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<ForwardTsnChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<IDataChunk>(chunk_type, data, sb) &&
|
||||
!ParseAndPrint<IForwardTsnChunk>(chunk_type, data, sb)) {
|
||||
sb << "Unhandled chunk type: " << static_cast<int>(chunk_type);
|
||||
}
|
||||
}
|
||||
return sb.Release();
|
||||
}
|
||||
} // namespace dcsctp
|
63
net/dcsctp/packet/chunk/chunk.h
Normal file
63
net/dcsctp/packet/chunk/chunk.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_CHUNK_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/data.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// Base class for all SCTP chunks
|
||||
class Chunk {
|
||||
public:
|
||||
Chunk() {}
|
||||
virtual ~Chunk() = default;
|
||||
|
||||
// Chunks can contain data payloads that shouldn't be copied unnecessarily.
|
||||
Chunk(Chunk&& other) = default;
|
||||
Chunk& operator=(Chunk&& other) = default;
|
||||
Chunk(const Chunk&) = delete;
|
||||
Chunk& operator=(const Chunk&) = delete;
|
||||
|
||||
// Serializes the chunk to `out`, growing it as necessary.
|
||||
virtual void SerializeTo(std::vector<uint8_t>& out) const = 0;
|
||||
|
||||
// Returns a human readable description of this chunk and its parameters.
|
||||
virtual std::string ToString() const = 0;
|
||||
};
|
||||
|
||||
// Introspects the chunk in `data` and returns a human readable textual
|
||||
// representation of it, to be used in debugging.
|
||||
std::string DebugConvertChunkToString(rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
struct ChunkConfig {
|
||||
static constexpr int kTypeSizeInBytes = 1;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_CHUNK_H_
|
46
net/dcsctp/packet/chunk/cookie_ack_chunk.cc
Normal file
46
net/dcsctp/packet/chunk/cookie_ack_chunk.cc
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/cookie_ack_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.12
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 11 |Chunk Flags | Length = 4 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int CookieAckChunk::kType;
|
||||
|
||||
absl::optional<CookieAckChunk> CookieAckChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
if (!ParseTLV(data).has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return CookieAckChunk();
|
||||
}
|
||||
|
||||
void CookieAckChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
AllocateTLV(out);
|
||||
}
|
||||
|
||||
std::string CookieAckChunk::ToString() const {
|
||||
return "COOKIE-ACK";
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
46
net/dcsctp/packet/chunk/cookie_ack_chunk.h
Normal file
46
net/dcsctp/packet/chunk/cookie_ack_chunk.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_COOKIE_ACK_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_COOKIE_ACK_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.12
|
||||
struct CookieAckChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 11;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class CookieAckChunk : public Chunk, public TLVTrait<CookieAckChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = CookieAckChunkConfig::kType;
|
||||
|
||||
CookieAckChunk() {}
|
||||
|
||||
static absl::optional<CookieAckChunk> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_COOKIE_ACK_CHUNK_H_
|
49
net/dcsctp/packet/chunk/cookie_ack_chunk_test.cc
Normal file
49
net/dcsctp/packet/chunk/cookie_ack_chunk_test.cc
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/cookie_ack_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(CookieAckChunkTest, FromCapture) {
|
||||
/*
|
||||
COOKIE_ACK chunk
|
||||
Chunk type: COOKIE_ACK (11)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 4
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x0b, 0x00, 0x00, 0x04};
|
||||
|
||||
EXPECT_TRUE(CookieAckChunk::Parse(data).has_value());
|
||||
}
|
||||
|
||||
TEST(CookieAckChunkTest, SerializeAndDeserialize) {
|
||||
CookieAckChunk chunk;
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(CookieAckChunk deserialized,
|
||||
CookieAckChunk::Parse(serialized));
|
||||
EXPECT_EQ(deserialized.ToString(), "COOKIE-ACK");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
54
net/dcsctp/packet/chunk/cookie_echo_chunk.cc
Normal file
54
net/dcsctp/packet/chunk/cookie_echo_chunk.cc
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/cookie_echo_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.11
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 10 |Chunk Flags | Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// / Cookie /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int CookieEchoChunk::kType;
|
||||
|
||||
absl::optional<CookieEchoChunk> CookieEchoChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return CookieEchoChunk(reader->variable_data());
|
||||
}
|
||||
|
||||
void CookieEchoChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, cookie_.size());
|
||||
writer.CopyToVariableData(cookie_);
|
||||
}
|
||||
|
||||
std::string CookieEchoChunk::ToString() const {
|
||||
return "COOKIE-ECHO";
|
||||
}
|
||||
} // namespace dcsctp
|
53
net/dcsctp/packet/chunk/cookie_echo_chunk.h
Normal file
53
net/dcsctp/packet/chunk/cookie_echo_chunk.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_COOKIE_ECHO_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_COOKIE_ECHO_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.11
|
||||
struct CookieEchoChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 10;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class CookieEchoChunk : public Chunk, public TLVTrait<CookieEchoChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = CookieEchoChunkConfig::kType;
|
||||
|
||||
explicit CookieEchoChunk(rtc::ArrayView<const uint8_t> cookie)
|
||||
: cookie_(cookie.begin(), cookie.end()) {}
|
||||
|
||||
static absl::optional<CookieEchoChunk> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
rtc::ArrayView<const uint8_t> cookie() const { return cookie_; }
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> cookie_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_COOKIE_ECHO_CHUNK_H_
|
58
net/dcsctp/packet/chunk/cookie_echo_chunk_test.cc
Normal file
58
net/dcsctp/packet/chunk/cookie_echo_chunk_test.cc
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/cookie_echo_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(CookieEchoChunkTest, FromCapture) {
|
||||
/*
|
||||
COOKIE_ECHO chunk (Cookie length: 256 bytes)
|
||||
Chunk type: COOKIE_ECHO (10)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 260
|
||||
Cookie: 12345678
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x0a, 0x00, 0x00, 0x08, 0x12, 0x34, 0x56, 0x78};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(CookieEchoChunk chunk,
|
||||
CookieEchoChunk::Parse(data));
|
||||
|
||||
EXPECT_THAT(chunk.cookie(), ElementsAre(0x12, 0x34, 0x56, 0x78));
|
||||
}
|
||||
|
||||
TEST(CookieEchoChunkTest, SerializeAndDeserialize) {
|
||||
uint8_t cookie[] = {1, 2, 3, 4};
|
||||
CookieEchoChunk chunk(cookie);
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(CookieEchoChunk deserialized,
|
||||
CookieEchoChunk::Parse(serialized));
|
||||
|
||||
EXPECT_THAT(deserialized.cookie(), ElementsAre(1, 2, 3, 4));
|
||||
EXPECT_EQ(deserialized.ToString(), "COOKIE-ECHO");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
101
net/dcsctp/packet/chunk/data_chunk.cc
Normal file
101
net/dcsctp/packet/chunk/data_chunk.cc
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/data_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/chunk/data_common.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.1
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 0 | Reserved|U|B|E| Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | TSN |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Stream Identifier S | Stream Sequence Number n |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Payload Protocol Identifier |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / User Data (seq n of Stream S) /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int DataChunk::kType;
|
||||
|
||||
absl::optional<DataChunk> DataChunk::Parse(rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
uint8_t flags = reader->Load8<1>();
|
||||
TSN tsn(reader->Load32<4>());
|
||||
StreamID stream_identifier(reader->Load16<8>());
|
||||
SSN ssn(reader->Load16<10>());
|
||||
PPID ppid(reader->Load32<12>());
|
||||
|
||||
Options options;
|
||||
options.is_end = Data::IsEnd((flags & (1 << kFlagsBitEnd)) != 0);
|
||||
options.is_beginning =
|
||||
Data::IsBeginning((flags & (1 << kFlagsBitBeginning)) != 0);
|
||||
options.is_unordered = IsUnordered((flags & (1 << kFlagsBitUnordered)) != 0);
|
||||
options.immediate_ack =
|
||||
ImmediateAckFlag((flags & (1 << kFlagsBitImmediateAck)) != 0);
|
||||
|
||||
return DataChunk(tsn, stream_identifier, ssn, ppid,
|
||||
std::vector<uint8_t>(reader->variable_data().begin(),
|
||||
reader->variable_data().end()),
|
||||
options);
|
||||
}
|
||||
|
||||
void DataChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, payload().size());
|
||||
|
||||
writer.Store8<1>(
|
||||
(*options().is_end ? (1 << kFlagsBitEnd) : 0) |
|
||||
(*options().is_beginning ? (1 << kFlagsBitBeginning) : 0) |
|
||||
(*options().is_unordered ? (1 << kFlagsBitUnordered) : 0) |
|
||||
(*options().immediate_ack ? (1 << kFlagsBitImmediateAck) : 0));
|
||||
writer.Store32<4>(*tsn());
|
||||
writer.Store16<8>(*stream_id());
|
||||
writer.Store16<10>(*ssn());
|
||||
writer.Store32<12>(*ppid());
|
||||
|
||||
writer.CopyToVariableData(payload());
|
||||
}
|
||||
|
||||
std::string DataChunk::ToString() const {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "DATA, type=" << (options().is_unordered ? "unordered" : "ordered")
|
||||
<< "::"
|
||||
<< (*options().is_beginning && *options().is_end
|
||||
? "complete"
|
||||
: *options().is_beginning ? "first"
|
||||
: *options().is_end ? "last" : "middle")
|
||||
<< ", tsn=" << *tsn() << ", stream_id=" << *stream_id()
|
||||
<< ", ppid=" << *ppid() << ", length=" << payload().size();
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
70
net/dcsctp/packet/chunk/data_chunk.h
Normal file
70
net/dcsctp/packet/chunk/data_chunk.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_DATA_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_DATA_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/data_common.h"
|
||||
#include "net/dcsctp/packet/data.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.1
|
||||
struct DataChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 0;
|
||||
static constexpr size_t kHeaderSize = 16;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class DataChunk : public AnyDataChunk, public TLVTrait<DataChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = DataChunkConfig::kType;
|
||||
|
||||
// Exposed to allow the retransmission queue to make room for the correct
|
||||
// header size.
|
||||
static constexpr size_t kHeaderSize = DataChunkConfig::kHeaderSize;
|
||||
|
||||
DataChunk(TSN tsn,
|
||||
StreamID stream_id,
|
||||
SSN ssn,
|
||||
PPID ppid,
|
||||
std::vector<uint8_t> payload,
|
||||
const Options& options)
|
||||
: AnyDataChunk(tsn,
|
||||
stream_id,
|
||||
ssn,
|
||||
MID(0),
|
||||
FSN(0),
|
||||
ppid,
|
||||
std::move(payload),
|
||||
options) {}
|
||||
|
||||
DataChunk(TSN tsn, Data&& data, bool immediate_ack)
|
||||
: AnyDataChunk(tsn, std::move(data), immediate_ack) {}
|
||||
|
||||
static absl::optional<DataChunk> Parse(rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_DATA_CHUNK_H_
|
74
net/dcsctp/packet/chunk/data_chunk_test.cc
Normal file
74
net/dcsctp/packet/chunk/data_chunk_test.cc
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 <cstdint>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(DataChunkTest, FromCapture) {
|
||||
/*
|
||||
DATA chunk(ordered, complete segment, TSN: 1426601532, SID: 2, SSN: 1,
|
||||
PPID: 53, payload length: 4 bytes)
|
||||
Chunk type: DATA (0)
|
||||
Chunk flags: 0x03
|
||||
Chunk length: 20
|
||||
Transmission sequence number: 1426601532
|
||||
Stream identifier: 0x0002
|
||||
Stream sequence number: 1
|
||||
Payload protocol identifier: WebRTC Binary (53)
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x00, 0x03, 0x00, 0x14, 0x55, 0x08, 0x36, 0x3c, 0x00, 0x02,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x35, 0x00, 0x01, 0x02, 0x03};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(DataChunk chunk, DataChunk::Parse(data));
|
||||
EXPECT_EQ(*chunk.tsn(), 1426601532u);
|
||||
EXPECT_EQ(*chunk.stream_id(), 2u);
|
||||
EXPECT_EQ(*chunk.ssn(), 1u);
|
||||
EXPECT_EQ(*chunk.ppid(), 53u);
|
||||
EXPECT_TRUE(*chunk.options().is_beginning);
|
||||
EXPECT_TRUE(*chunk.options().is_end);
|
||||
EXPECT_FALSE(*chunk.options().is_unordered);
|
||||
EXPECT_FALSE(*chunk.options().immediate_ack);
|
||||
EXPECT_THAT(chunk.payload(), ElementsAre(0x0, 0x1, 0x2, 0x3));
|
||||
}
|
||||
|
||||
TEST(DataChunkTest, SerializeAndDeserialize) {
|
||||
DataChunk chunk(TSN(123), StreamID(456), SSN(789), PPID(9090),
|
||||
/*payload=*/{1, 2, 3, 4, 5},
|
||||
/*options=*/{});
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(DataChunk deserialized,
|
||||
DataChunk::Parse(serialized));
|
||||
EXPECT_EQ(*chunk.tsn(), 123u);
|
||||
EXPECT_EQ(*chunk.stream_id(), 456u);
|
||||
EXPECT_EQ(*chunk.ssn(), 789u);
|
||||
EXPECT_EQ(*chunk.ppid(), 9090u);
|
||||
EXPECT_THAT(chunk.payload(), ElementsAre(1, 2, 3, 4, 5));
|
||||
|
||||
EXPECT_EQ(deserialized.ToString(),
|
||||
"DATA, type=ordered::middle, tsn=123, stream_id=456, ppid=9090, "
|
||||
"length=5");
|
||||
}
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
97
net/dcsctp/packet/chunk/data_common.h
Normal file
97
net/dcsctp/packet/chunk/data_common.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_DATA_COMMON_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_DATA_COMMON_H_
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/data.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// Base class for DataChunk and IDataChunk
|
||||
class AnyDataChunk : public Chunk {
|
||||
public:
|
||||
// Represents the "immediate ack" flag on DATA/I-DATA, from RFC7053.
|
||||
using ImmediateAckFlag = 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 message_id() const { return data_.message_id; }
|
||||
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 message_id,
|
||||
FSN fsn,
|
||||
PPID ppid,
|
||||
std::vector<uint8_t> payload,
|
||||
const Options& options)
|
||||
: tsn_(tsn),
|
||||
data_(stream_id,
|
||||
ssn,
|
||||
message_id,
|
||||
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_
|
62
net/dcsctp/packet/chunk/error_chunk.cc
Normal file
62
net/dcsctp/packet/chunk/error_chunk.cc
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/error_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 9 | Chunk Flags | Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / one or more Error Causes /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int ErrorChunk::kType;
|
||||
|
||||
absl::optional<ErrorChunk> ErrorChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
absl::optional<Parameters> error_causes =
|
||||
Parameters::Parse(reader->variable_data());
|
||||
if (!error_causes.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return ErrorChunk(*std::move(error_causes));
|
||||
}
|
||||
|
||||
void ErrorChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
rtc::ArrayView<const uint8_t> error_causes = error_causes_.data();
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, error_causes.size());
|
||||
writer.CopyToVariableData(error_causes);
|
||||
}
|
||||
|
||||
std::string ErrorChunk::ToString() const {
|
||||
return "ERROR";
|
||||
}
|
||||
} // namespace dcsctp
|
57
net/dcsctp/packet/chunk/error_chunk.h
Normal file
57
net/dcsctp/packet/chunk/error_chunk.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_ERROR_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_ERROR_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10
|
||||
struct ErrorChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 9;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 4;
|
||||
};
|
||||
|
||||
class ErrorChunk : public Chunk, public TLVTrait<ErrorChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = ErrorChunkConfig::kType;
|
||||
|
||||
explicit ErrorChunk(Parameters error_causes)
|
||||
: error_causes_(std::move(error_causes)) {}
|
||||
|
||||
ErrorChunk(ErrorChunk&& other) = default;
|
||||
ErrorChunk& operator=(ErrorChunk&& other) = default;
|
||||
|
||||
static absl::optional<ErrorChunk> Parse(rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
const Parameters& error_causes() const { return error_causes_; }
|
||||
|
||||
private:
|
||||
Parameters error_causes_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_ERROR_CHUNK_H_
|
66
net/dcsctp/packet/chunk/error_chunk_test.cc
Normal file
66
net/dcsctp/packet/chunk/error_chunk_test.cc
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/error_chunk.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(ErrorChunkTest, FromCapture) {
|
||||
/*
|
||||
ERROR chunk
|
||||
Chunk type: ERROR (9)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 12
|
||||
Unrecognized chunk type cause (Type: 73 (unknown))
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x09, 0x00, 0x00, 0x0c, 0x00, 0x06,
|
||||
0x00, 0x08, 0x49, 0x00, 0x00, 0x04};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(ErrorChunk chunk, ErrorChunk::Parse(data));
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
UnrecognizedChunkTypeCause cause,
|
||||
chunk.error_causes().get<UnrecognizedChunkTypeCause>());
|
||||
|
||||
EXPECT_THAT(cause.unrecognized_chunk(), ElementsAre(0x49, 0x00, 0x00, 0x04));
|
||||
}
|
||||
|
||||
TEST(ErrorChunkTest, SerializeAndDeserialize) {
|
||||
ErrorChunk chunk(Parameters::Builder()
|
||||
.Add(UnrecognizedChunkTypeCause({1, 2, 3, 4}))
|
||||
.Build());
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(ErrorChunk deserialized,
|
||||
ErrorChunk::Parse(serialized));
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
UnrecognizedChunkTypeCause cause,
|
||||
deserialized.error_causes().get<UnrecognizedChunkTypeCause>());
|
||||
|
||||
EXPECT_THAT(cause.unrecognized_chunk(), ElementsAre(1, 2, 3, 4));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
92
net/dcsctp/packet/chunk/forward_tsn_chunk.cc
Normal file
92
net/dcsctp/packet/chunk/forward_tsn_chunk.cc
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#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();
|
||||
return sb.str();
|
||||
}
|
||||
} // namespace dcsctp
|
55
net/dcsctp/packet/chunk/forward_tsn_chunk.h
Normal file
55
net/dcsctp/packet/chunk/forward_tsn_chunk.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_FORWARD_TSN_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_FORWARD_TSN_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc3758#section-3.2
|
||||
struct ForwardTsnChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 192;
|
||||
static constexpr size_t kHeaderSize = 8;
|
||||
static constexpr size_t kVariableLengthAlignment = 4;
|
||||
};
|
||||
|
||||
class ForwardTsnChunk : public AnyForwardTsnChunk,
|
||||
public TLVTrait<ForwardTsnChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = ForwardTsnChunkConfig::kType;
|
||||
|
||||
ForwardTsnChunk(TSN new_cumulative_tsn,
|
||||
std::vector<SkippedStream> skipped_streams)
|
||||
: AnyForwardTsnChunk(new_cumulative_tsn, std::move(skipped_streams)) {}
|
||||
|
||||
static absl::optional<ForwardTsnChunk> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
private:
|
||||
static constexpr size_t kSkippedStreamBufferSize = 4;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_FORWARD_TSN_CHUNK_H_
|
63
net/dcsctp/packet/chunk/forward_tsn_chunk_test.cc
Normal file
63
net/dcsctp/packet/chunk/forward_tsn_chunk_test.cc
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(ForwardTsnChunkTest, FromCapture) {
|
||||
/*
|
||||
FORWARD_TSN chunk(Cumulative TSN: 1905748778)
|
||||
Chunk type: FORWARD_TSN (192)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 8
|
||||
New cumulative TSN: 1905748778
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0xc0, 0x00, 0x00, 0x08, 0x71, 0x97, 0x6b, 0x2a};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(ForwardTsnChunk chunk,
|
||||
ForwardTsnChunk::Parse(data));
|
||||
EXPECT_EQ(*chunk.new_cumulative_tsn(), 1905748778u);
|
||||
}
|
||||
|
||||
TEST(ForwardTsnChunkTest, SerializeAndDeserialize) {
|
||||
ForwardTsnChunk chunk(
|
||||
TSN(123), {ForwardTsnChunk::SkippedStream(StreamID(1), SSN(23)),
|
||||
ForwardTsnChunk::SkippedStream(StreamID(42), SSN(99))});
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(ForwardTsnChunk deserialized,
|
||||
ForwardTsnChunk::Parse(serialized));
|
||||
EXPECT_EQ(*deserialized.new_cumulative_tsn(), 123u);
|
||||
EXPECT_THAT(
|
||||
deserialized.skipped_streams(),
|
||||
ElementsAre(ForwardTsnChunk::SkippedStream(StreamID(1), SSN(23)),
|
||||
ForwardTsnChunk::SkippedStream(StreamID(42), SSN(99))));
|
||||
|
||||
EXPECT_EQ(deserialized.ToString(), "FORWARD-TSN, new_cumulative_tsn=123");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
66
net/dcsctp/packet/chunk/forward_tsn_common.h
Normal file
66
net/dcsctp/packet/chunk/forward_tsn_common.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_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), message_id(0) {}
|
||||
SkippedStream(IsUnordered unordered, StreamID stream_id, MID message_id)
|
||||
: stream_id(stream_id),
|
||||
ssn(0),
|
||||
unordered(unordered),
|
||||
message_id(message_id) {}
|
||||
|
||||
StreamID stream_id;
|
||||
|
||||
// Set for FORWARD_TSN
|
||||
SSN ssn;
|
||||
|
||||
// Set for I-FORWARD_TSN
|
||||
IsUnordered unordered;
|
||||
MID message_id;
|
||||
|
||||
bool operator==(const SkippedStream& other) const {
|
||||
return stream_id == other.stream_id && ssn == other.ssn &&
|
||||
unordered == other.unordered && message_id == other.message_id;
|
||||
}
|
||||
};
|
||||
|
||||
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_
|
63
net/dcsctp/packet/chunk/heartbeat_ack_chunk.cc
Normal file
63
net/dcsctp/packet/chunk/heartbeat_ack_chunk.cc
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/heartbeat_ack_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.6
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 5 | Chunk Flags | Heartbeat Ack Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / Heartbeat Information TLV (Variable-Length) /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int HeartbeatAckChunk::kType;
|
||||
|
||||
absl::optional<HeartbeatAckChunk> HeartbeatAckChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
absl::optional<Parameters> parameters =
|
||||
Parameters::Parse(reader->variable_data());
|
||||
if (!parameters.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return HeartbeatAckChunk(*std::move(parameters));
|
||||
}
|
||||
|
||||
void HeartbeatAckChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
rtc::ArrayView<const uint8_t> parameters = parameters_.data();
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());
|
||||
writer.CopyToVariableData(parameters);
|
||||
}
|
||||
|
||||
std::string HeartbeatAckChunk::ToString() const {
|
||||
return "HEARTBEAT-ACK";
|
||||
}
|
||||
} // namespace dcsctp
|
63
net/dcsctp/packet/chunk/heartbeat_ack_chunk.h
Normal file
63
net/dcsctp/packet/chunk/heartbeat_ack_chunk.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_ACK_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_ACK_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/parameter/heartbeat_info_parameter.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.6
|
||||
struct HeartbeatAckChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 5;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class HeartbeatAckChunk : public Chunk,
|
||||
public TLVTrait<HeartbeatAckChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = HeartbeatAckChunkConfig::kType;
|
||||
|
||||
explicit HeartbeatAckChunk(Parameters parameters)
|
||||
: parameters_(std::move(parameters)) {}
|
||||
|
||||
HeartbeatAckChunk(HeartbeatAckChunk&& other) = default;
|
||||
HeartbeatAckChunk& operator=(HeartbeatAckChunk&& other) = default;
|
||||
|
||||
static absl::optional<HeartbeatAckChunk> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
const Parameters& parameters() const { return parameters_; }
|
||||
|
||||
absl::optional<HeartbeatInfoParameter> info() const {
|
||||
return parameters_.get<HeartbeatInfoParameter>();
|
||||
}
|
||||
|
||||
private:
|
||||
Parameters parameters_;
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_ACK_CHUNK_H_
|
79
net/dcsctp/packet/chunk/heartbeat_ack_chunk_test.cc
Normal file
79
net/dcsctp/packet/chunk/heartbeat_ack_chunk_test.cc
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 "api/array_view.h"
|
||||
#include "net/dcsctp/packet/parameter/heartbeat_info_parameter.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(HeartbeatAckChunkTest, FromCapture) {
|
||||
/*
|
||||
HEARTBEAT_ACK chunk (Information: 40 bytes)
|
||||
Chunk type: HEARTBEAT_ACK (5)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 44
|
||||
Heartbeat info parameter (Information: 36 bytes)
|
||||
Parameter type: Heartbeat info (0x0001)
|
||||
Parameter length: 40
|
||||
Heartbeat information: ad2436603726070000000000000000007b1000000100…
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x05, 0x00, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x28, 0xad,
|
||||
0x24, 0x36, 0x60, 0x37, 0x26, 0x07, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x10, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(HeartbeatAckChunk chunk,
|
||||
HeartbeatAckChunk::Parse(data));
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(HeartbeatInfoParameter info, chunk.info());
|
||||
|
||||
EXPECT_THAT(
|
||||
info.info(),
|
||||
ElementsAre(0xad, 0x24, 0x36, 0x60, 0x37, 0x26, 0x07, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x10, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
|
||||
}
|
||||
|
||||
TEST(HeartbeatAckChunkTest, SerializeAndDeserialize) {
|
||||
uint8_t info_data[] = {1, 2, 3, 4};
|
||||
Parameters parameters =
|
||||
Parameters::Builder().Add(HeartbeatInfoParameter(info_data)).Build();
|
||||
HeartbeatAckChunk chunk(std::move(parameters));
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(HeartbeatAckChunk deserialized,
|
||||
HeartbeatAckChunk::Parse(serialized));
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(HeartbeatInfoParameter info, deserialized.info());
|
||||
|
||||
EXPECT_THAT(info.info(), ElementsAre(1, 2, 3, 4));
|
||||
|
||||
EXPECT_EQ(deserialized.ToString(), "HEARTBEAT-ACK");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
64
net/dcsctp/packet/chunk/heartbeat_request_chunk.cc
Normal file
64
net/dcsctp/packet/chunk/heartbeat_request_chunk.cc
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/heartbeat_request_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.5
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 4 | Chunk Flags | Heartbeat Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / Heartbeat Information TLV (Variable-Length) /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int HeartbeatRequestChunk::kType;
|
||||
|
||||
absl::optional<HeartbeatRequestChunk> HeartbeatRequestChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
absl::optional<Parameters> parameters =
|
||||
Parameters::Parse(reader->variable_data());
|
||||
if (!parameters.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return HeartbeatRequestChunk(*std::move(parameters));
|
||||
}
|
||||
|
||||
void HeartbeatRequestChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
rtc::ArrayView<const uint8_t> parameters = parameters_.data();
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());
|
||||
writer.CopyToVariableData(parameters);
|
||||
}
|
||||
|
||||
std::string HeartbeatRequestChunk::ToString() const {
|
||||
return "HEARTBEAT";
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
62
net/dcsctp/packet/chunk/heartbeat_request_chunk.h
Normal file
62
net/dcsctp/packet/chunk/heartbeat_request_chunk.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_REQUEST_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_REQUEST_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/parameter/heartbeat_info_parameter.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.5
|
||||
struct HeartbeatRequestChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 4;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class HeartbeatRequestChunk : public Chunk,
|
||||
public TLVTrait<HeartbeatRequestChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = HeartbeatRequestChunkConfig::kType;
|
||||
|
||||
explicit HeartbeatRequestChunk(Parameters parameters)
|
||||
: parameters_(std::move(parameters)) {}
|
||||
|
||||
HeartbeatRequestChunk(HeartbeatRequestChunk&& other) = default;
|
||||
HeartbeatRequestChunk& operator=(HeartbeatRequestChunk&& other) = default;
|
||||
|
||||
static absl::optional<HeartbeatRequestChunk> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
const Parameters& parameters() const { return parameters_; }
|
||||
Parameters extract_parameters() && { return std::move(parameters_); }
|
||||
absl::optional<HeartbeatInfoParameter> info() const {
|
||||
return parameters_.get<HeartbeatInfoParameter>();
|
||||
}
|
||||
|
||||
private:
|
||||
Parameters parameters_;
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_HEARTBEAT_REQUEST_CHUNK_H_
|
79
net/dcsctp/packet/chunk/heartbeat_request_chunk_test.cc
Normal file
79
net/dcsctp/packet/chunk/heartbeat_request_chunk_test.cc
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 "api/array_view.h"
|
||||
#include "net/dcsctp/packet/parameter/heartbeat_info_parameter.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(HeartbeatRequestChunkTest, FromCapture) {
|
||||
/*
|
||||
HEARTBEAT chunk (Information: 40 bytes)
|
||||
Chunk type: HEARTBEAT (4)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 44
|
||||
Heartbeat info parameter (Information: 36 bytes)
|
||||
Parameter type: Heartbeat info (0x0001)
|
||||
Parameter length: 40
|
||||
Heartbeat information: ad2436603726070000000000000000007b10000001…
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x04, 0x00, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x28, 0xad,
|
||||
0x24, 0x36, 0x60, 0x37, 0x26, 0x07, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x10, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(HeartbeatRequestChunk chunk,
|
||||
HeartbeatRequestChunk::Parse(data));
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(HeartbeatInfoParameter info, chunk.info());
|
||||
|
||||
EXPECT_THAT(
|
||||
info.info(),
|
||||
ElementsAre(0xad, 0x24, 0x36, 0x60, 0x37, 0x26, 0x07, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x10, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
|
||||
}
|
||||
|
||||
TEST(HeartbeatRequestChunkTest, SerializeAndDeserialize) {
|
||||
uint8_t info_data[] = {1, 2, 3, 4};
|
||||
Parameters parameters =
|
||||
Parameters::Builder().Add(HeartbeatInfoParameter(info_data)).Build();
|
||||
HeartbeatRequestChunk chunk(std::move(parameters));
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(HeartbeatRequestChunk deserialized,
|
||||
HeartbeatRequestChunk::Parse(serialized));
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(HeartbeatInfoParameter info, deserialized.info());
|
||||
|
||||
EXPECT_THAT(info.info(), ElementsAre(1, 2, 3, 4));
|
||||
|
||||
EXPECT_EQ(deserialized.ToString(), "HEARTBEAT");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
111
net/dcsctp/packet/chunk/idata_chunk.cc
Normal file
111
net/dcsctp/packet/chunk/idata_chunk.cc
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/idata_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/chunk/data_common.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc8260#section-2.1
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 64 | Res |I|U|B|E| Length = Variable |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | TSN |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Stream Identifier | Reserved |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Message Identifier |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Payload Protocol Identifier / Fragment Sequence Number |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / User Data /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int IDataChunk::kType;
|
||||
|
||||
absl::optional<IDataChunk> IDataChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
uint8_t flags = reader->Load8<1>();
|
||||
TSN tsn(reader->Load32<4>());
|
||||
StreamID stream_identifier(reader->Load16<8>());
|
||||
MID message_id(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, message_id,
|
||||
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>(*message_id());
|
||||
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()
|
||||
<< ", message_id=" << *message_id();
|
||||
|
||||
if (*options().is_beginning) {
|
||||
sb << ", ppid=" << *ppid();
|
||||
} else {
|
||||
sb << ", fsn=" << *fsn();
|
||||
}
|
||||
sb << ", length=" << payload().size();
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
70
net/dcsctp/packet/chunk/idata_chunk.h
Normal file
70
net/dcsctp/packet/chunk/idata_chunk.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_IDATA_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_IDATA_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/data_common.h"
|
||||
#include "net/dcsctp/packet/data.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc8260#section-2.1
|
||||
struct IDataChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 64;
|
||||
static constexpr size_t kHeaderSize = 20;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class IDataChunk : public AnyDataChunk, public TLVTrait<IDataChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = IDataChunkConfig::kType;
|
||||
|
||||
// Exposed to allow the retransmission queue to make room for the correct
|
||||
// header size.
|
||||
static constexpr size_t kHeaderSize = IDataChunkConfig::kHeaderSize;
|
||||
IDataChunk(TSN tsn,
|
||||
StreamID stream_id,
|
||||
MID message_id,
|
||||
PPID ppid,
|
||||
FSN fsn,
|
||||
std::vector<uint8_t> payload,
|
||||
const Options& options)
|
||||
: AnyDataChunk(tsn,
|
||||
stream_id,
|
||||
SSN(0),
|
||||
message_id,
|
||||
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_
|
123
net/dcsctp/packet/chunk/idata_chunk_test.cc
Normal file
123
net/dcsctp/packet/chunk/idata_chunk_test.cc
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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 <cstdint>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(IDataChunkTest, AtBeginningFromCapture) {
|
||||
/*
|
||||
I_DATA chunk(ordered, first segment, TSN: 2487901653, SID: 1, MID: 0,
|
||||
payload length: 1180 bytes)
|
||||
Chunk type: I_DATA (64)
|
||||
Chunk flags: 0x02
|
||||
Chunk length: 1200
|
||||
Transmission sequence number: 2487901653
|
||||
Stream identifier: 0x0001
|
||||
Reserved: 0
|
||||
Message identifier: 0
|
||||
Payload protocol identifier: WebRTC Binary (53)
|
||||
Reassembled Message in frame: 39
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x40, 0x02, 0x00, 0x15, 0x94, 0x4a, 0x5d, 0xd5,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x35, 0x01, 0x00, 0x00, 0x00};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(IDataChunk chunk, IDataChunk::Parse(data));
|
||||
EXPECT_EQ(*chunk.tsn(), 2487901653);
|
||||
EXPECT_EQ(*chunk.stream_id(), 1);
|
||||
EXPECT_EQ(*chunk.message_id(), 0u);
|
||||
EXPECT_EQ(*chunk.ppid(), 53u);
|
||||
EXPECT_EQ(*chunk.fsn(), 0u); // Not provided (so set to zero)
|
||||
}
|
||||
|
||||
TEST(IDataChunkTest, AtBeginningSerializeAndDeserialize) {
|
||||
IDataChunk::Options options;
|
||||
options.is_beginning = Data::IsBeginning(true);
|
||||
IDataChunk chunk(TSN(123), StreamID(456), MID(789), PPID(53), FSN(0), {1},
|
||||
options);
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(IDataChunk deserialized,
|
||||
IDataChunk::Parse(serialized));
|
||||
EXPECT_EQ(*deserialized.tsn(), 123u);
|
||||
EXPECT_EQ(*deserialized.stream_id(), 456u);
|
||||
EXPECT_EQ(*deserialized.message_id(), 789u);
|
||||
EXPECT_EQ(*deserialized.ppid(), 53u);
|
||||
EXPECT_EQ(*deserialized.fsn(), 0u);
|
||||
|
||||
EXPECT_EQ(deserialized.ToString(),
|
||||
"I-DATA, type=ordered::first, tsn=123, stream_id=456, "
|
||||
"message_id=789, ppid=53, length=1");
|
||||
}
|
||||
|
||||
TEST(IDataChunkTest, InMiddleFromCapture) {
|
||||
/*
|
||||
I_DATA chunk(ordered, last segment, TSN: 2487901706, SID: 3, MID: 1,
|
||||
FSN: 8, payload length: 560 bytes)
|
||||
Chunk type: I_DATA (64)
|
||||
Chunk flags: 0x01
|
||||
Chunk length: 580
|
||||
Transmission sequence number: 2487901706
|
||||
Stream identifier: 0x0003
|
||||
Reserved: 0
|
||||
Message identifier: 1
|
||||
Fragment sequence number: 8
|
||||
Reassembled SCTP Fragments (10000 bytes, 9 fragments):
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x40, 0x01, 0x00, 0x15, 0x94, 0x4a, 0x5e, 0x0a,
|
||||
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(IDataChunk chunk, IDataChunk::Parse(data));
|
||||
EXPECT_EQ(*chunk.tsn(), 2487901706);
|
||||
EXPECT_EQ(*chunk.stream_id(), 3u);
|
||||
EXPECT_EQ(*chunk.message_id(), 1u);
|
||||
EXPECT_EQ(*chunk.ppid(), 0u); // Not provided (so set to zero)
|
||||
EXPECT_EQ(*chunk.fsn(), 8u);
|
||||
}
|
||||
|
||||
TEST(IDataChunkTest, InMiddleSerializeAndDeserialize) {
|
||||
IDataChunk chunk(TSN(123), StreamID(456), MID(789), PPID(0), FSN(101112),
|
||||
{1, 2, 3}, /*options=*/{});
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(IDataChunk deserialized,
|
||||
IDataChunk::Parse(serialized));
|
||||
EXPECT_EQ(*deserialized.tsn(), 123u);
|
||||
EXPECT_EQ(*deserialized.stream_id(), 456u);
|
||||
EXPECT_EQ(*deserialized.message_id(), 789u);
|
||||
EXPECT_EQ(*deserialized.ppid(), 0u);
|
||||
EXPECT_EQ(*deserialized.fsn(), 101112u);
|
||||
EXPECT_THAT(deserialized.payload(), ElementsAre(1, 2, 3));
|
||||
|
||||
EXPECT_EQ(deserialized.ToString(),
|
||||
"I-DATA, type=ordered::middle, tsn=123, stream_id=456, "
|
||||
"message_id=789, fsn=101112, length=3");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
104
net/dcsctp/packet/chunk/iforward_tsn_chunk.cc
Normal file
104
net/dcsctp/packet/chunk/iforward_tsn_chunk.cc
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/iforward_tsn_chunk.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc8260#section-2.3.1
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 194 | Flags = 0x00 | Length = Variable |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | New Cumulative TSN |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Stream Identifier | Reserved |U|
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Message Identifier |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / /
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Stream Identifier | Reserved |U|
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Message Identifier |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int IForwardTsnChunk::kType;
|
||||
|
||||
absl::optional<IForwardTsnChunk> IForwardTsnChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
TSN new_cumulative_tsn(reader->Load32<4>());
|
||||
|
||||
size_t streams_skipped =
|
||||
reader->variable_data_size() / kSkippedStreamBufferSize;
|
||||
std::vector<SkippedStream> skipped_streams;
|
||||
skipped_streams.reserve(streams_skipped);
|
||||
size_t offset = 0;
|
||||
for (size_t i = 0; i < streams_skipped; ++i) {
|
||||
BoundedByteReader<kSkippedStreamBufferSize> sub_reader =
|
||||
reader->sub_reader<kSkippedStreamBufferSize>(offset);
|
||||
|
||||
StreamID stream_id(sub_reader.Load16<0>());
|
||||
IsUnordered unordered(sub_reader.Load8<3>() & 0x01);
|
||||
MID message_id(sub_reader.Load32<4>());
|
||||
skipped_streams.emplace_back(unordered, stream_id, message_id);
|
||||
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].message_id);
|
||||
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
|
54
net/dcsctp/packet/chunk/iforward_tsn_chunk.h
Normal file
54
net/dcsctp/packet/chunk/iforward_tsn_chunk.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_IFORWARD_TSN_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_IFORWARD_TSN_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc8260#section-2.3.1
|
||||
struct IForwardTsnChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 194;
|
||||
static constexpr size_t kHeaderSize = 8;
|
||||
static constexpr size_t kVariableLengthAlignment = 8;
|
||||
};
|
||||
|
||||
class IForwardTsnChunk : public AnyForwardTsnChunk,
|
||||
public TLVTrait<IForwardTsnChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = IForwardTsnChunkConfig::kType;
|
||||
|
||||
IForwardTsnChunk(TSN new_cumulative_tsn,
|
||||
std::vector<SkippedStream> skipped_streams)
|
||||
: AnyForwardTsnChunk(new_cumulative_tsn, std::move(skipped_streams)) {}
|
||||
|
||||
static absl::optional<IForwardTsnChunk> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
private:
|
||||
static constexpr size_t kSkippedStreamBufferSize = 8;
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_IFORWARD_TSN_CHUNK_H_
|
73
net/dcsctp/packet/chunk/iforward_tsn_chunk_test.cc
Normal file
73
net/dcsctp/packet/chunk/iforward_tsn_chunk_test.cc
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(IForwardTsnChunkTest, FromCapture) {
|
||||
/*
|
||||
I_FORWARD_TSN chunk(Cumulative TSN: 3094631148)
|
||||
Chunk type: I_FORWARD_TSN (194)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 16
|
||||
New cumulative TSN: 3094631148
|
||||
Stream identifier: 1
|
||||
Flags: 0x0000
|
||||
Message identifier: 2
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0xc2, 0x00, 0x00, 0x10, 0xb8, 0x74, 0x52, 0xec,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(IForwardTsnChunk chunk,
|
||||
IForwardTsnChunk::Parse(data));
|
||||
EXPECT_EQ(*chunk.new_cumulative_tsn(), 3094631148u);
|
||||
EXPECT_THAT(chunk.skipped_streams(),
|
||||
ElementsAre(IForwardTsnChunk::SkippedStream(
|
||||
IsUnordered(false), StreamID(1), MID(2))));
|
||||
}
|
||||
|
||||
TEST(IForwardTsnChunkTest, SerializeAndDeserialize) {
|
||||
IForwardTsnChunk chunk(
|
||||
TSN(123), {IForwardTsnChunk::SkippedStream(IsUnordered(false),
|
||||
StreamID(1), MID(23)),
|
||||
IForwardTsnChunk::SkippedStream(IsUnordered(true),
|
||||
StreamID(42), MID(99))});
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(IForwardTsnChunk deserialized,
|
||||
IForwardTsnChunk::Parse(serialized));
|
||||
EXPECT_EQ(*deserialized.new_cumulative_tsn(), 123u);
|
||||
EXPECT_THAT(deserialized.skipped_streams(),
|
||||
ElementsAre(IForwardTsnChunk::SkippedStream(IsUnordered(false),
|
||||
StreamID(1), MID(23)),
|
||||
IForwardTsnChunk::SkippedStream(
|
||||
IsUnordered(true), StreamID(42), MID(99))));
|
||||
|
||||
EXPECT_EQ(deserialized.ToString(), "I-FORWARD-TSN, new_cumulative_tsn=123");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
86
net/dcsctp/packet/chunk/init_ack_chunk.cc
Normal file
86
net/dcsctp/packet/chunk/init_ack_chunk.cc
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/init_ack_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/strings/string_format.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.3
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 2 | Chunk Flags | Chunk Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Initiate Tag |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Advertised Receiver Window Credit |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Number of Outbound Streams | Number of Inbound Streams |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Initial TSN |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / Optional/Variable-Length Parameters /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int InitAckChunk::kType;
|
||||
|
||||
absl::optional<InitAckChunk> InitAckChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
VerificationTag initiate_tag(reader->Load32<4>());
|
||||
uint32_t a_rwnd = reader->Load32<8>();
|
||||
uint16_t nbr_outbound_streams = reader->Load16<12>();
|
||||
uint16_t nbr_inbound_streams = reader->Load16<14>();
|
||||
TSN initial_tsn(reader->Load32<16>());
|
||||
absl::optional<Parameters> parameters =
|
||||
Parameters::Parse(reader->variable_data());
|
||||
if (!parameters.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return InitAckChunk(initiate_tag, a_rwnd, nbr_outbound_streams,
|
||||
nbr_inbound_streams, initial_tsn, *std::move(parameters));
|
||||
}
|
||||
|
||||
void InitAckChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
rtc::ArrayView<const uint8_t> parameters = parameters_.data();
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());
|
||||
|
||||
writer.Store32<4>(*initiate_tag_);
|
||||
writer.Store32<8>(a_rwnd_);
|
||||
writer.Store16<12>(nbr_outbound_streams_);
|
||||
writer.Store16<14>(nbr_inbound_streams_);
|
||||
writer.Store32<16>(*initial_tsn_);
|
||||
writer.CopyToVariableData(parameters);
|
||||
}
|
||||
|
||||
std::string InitAckChunk::ToString() const {
|
||||
return rtc::StringFormat("INIT_ACK, initiate_tag=0x%0x, initial_tsn=%d",
|
||||
*initiate_tag(), *initial_tsn());
|
||||
}
|
||||
} // namespace dcsctp
|
77
net/dcsctp/packet/chunk/init_ack_chunk.h
Normal file
77
net/dcsctp/packet/chunk/init_ack_chunk.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_INIT_ACK_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_INIT_ACK_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.3
|
||||
struct InitAckChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 2;
|
||||
static constexpr size_t kHeaderSize = 20;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class InitAckChunk : public Chunk, public TLVTrait<InitAckChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = InitAckChunkConfig::kType;
|
||||
|
||||
InitAckChunk(VerificationTag initiate_tag,
|
||||
uint32_t a_rwnd,
|
||||
uint16_t nbr_outbound_streams,
|
||||
uint16_t nbr_inbound_streams,
|
||||
TSN initial_tsn,
|
||||
Parameters parameters)
|
||||
: initiate_tag_(initiate_tag),
|
||||
a_rwnd_(a_rwnd),
|
||||
nbr_outbound_streams_(nbr_outbound_streams),
|
||||
nbr_inbound_streams_(nbr_inbound_streams),
|
||||
initial_tsn_(initial_tsn),
|
||||
parameters_(std::move(parameters)) {}
|
||||
|
||||
InitAckChunk(InitAckChunk&& other) = default;
|
||||
InitAckChunk& operator=(InitAckChunk&& other) = default;
|
||||
|
||||
static absl::optional<InitAckChunk> Parse(rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
VerificationTag initiate_tag() const { return initiate_tag_; }
|
||||
uint32_t a_rwnd() const { return a_rwnd_; }
|
||||
uint16_t nbr_outbound_streams() const { return nbr_outbound_streams_; }
|
||||
uint16_t nbr_inbound_streams() const { return nbr_inbound_streams_; }
|
||||
TSN initial_tsn() const { return initial_tsn_; }
|
||||
const Parameters& parameters() const { return parameters_; }
|
||||
|
||||
private:
|
||||
VerificationTag initiate_tag_;
|
||||
uint32_t a_rwnd_;
|
||||
uint16_t nbr_outbound_streams_;
|
||||
uint16_t nbr_inbound_streams_;
|
||||
TSN initial_tsn_;
|
||||
Parameters parameters_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_INIT_ACK_CHUNK_H_
|
127
net/dcsctp/packet/chunk/init_ack_chunk_test.cc
Normal file
127
net/dcsctp/packet/chunk/init_ack_chunk_test.cc
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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 <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/parameter/forward_tsn_supported_parameter.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/parameter/state_cookie_parameter.h"
|
||||
#include "net/dcsctp/packet/parameter/supported_extensions_parameter.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(InitAckChunkTest, FromCapture) {
|
||||
/*
|
||||
INIT_ACK chunk (Outbound streams: 1000, inbound streams: 2048)
|
||||
Chunk type: INIT_ACK (2)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 292
|
||||
Initiate tag: 0x579c2f98
|
||||
Advertised receiver window credit (a_rwnd): 131072
|
||||
Number of outbound streams: 1000
|
||||
Number of inbound streams: 2048
|
||||
Initial TSN: 1670811335
|
||||
Forward TSN supported parameter
|
||||
Parameter type: Forward TSN supported (0xc000)
|
||||
Parameter length: 4
|
||||
Supported Extensions parameter (Supported types: FORWARD_TSN, RE_CONFIG)
|
||||
Parameter type: Supported Extensions (0x8008)
|
||||
Parameter length: 6
|
||||
Supported chunk type: FORWARD_TSN (192)
|
||||
Supported chunk type: RE_CONFIG (130)
|
||||
Parameter padding: 0000
|
||||
State cookie parameter (Cookie length: 256 bytes)
|
||||
Parameter type: State cookie (0x0007)
|
||||
Parameter length: 260
|
||||
State cookie: 4b414d452d42534420312e310000000096b8386000000000…
|
||||
*/
|
||||
|
||||
uint8_t data[] = {
|
||||
0x02, 0x00, 0x01, 0x24, 0x57, 0x9c, 0x2f, 0x98, 0x00, 0x02, 0x00, 0x00,
|
||||
0x03, 0xe8, 0x08, 0x00, 0x63, 0x96, 0x8e, 0xc7, 0xc0, 0x00, 0x00, 0x04,
|
||||
0x80, 0x08, 0x00, 0x06, 0xc0, 0x82, 0x00, 0x00, 0x00, 0x07, 0x01, 0x04,
|
||||
0x4b, 0x41, 0x4d, 0x45, 0x2d, 0x42, 0x53, 0x44, 0x20, 0x31, 0x2e, 0x31,
|
||||
0x00, 0x00, 0x00, 0x00, 0x96, 0xb8, 0x38, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||
0x52, 0x5a, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xea, 0x00, 0x00,
|
||||
0xb5, 0xaa, 0x19, 0xea, 0x31, 0xef, 0xa4, 0x2b, 0x90, 0x16, 0x7a, 0xde,
|
||||
0x57, 0x9c, 0x2f, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x13, 0x88, 0x13, 0x88, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x5a, 0xde, 0x7a, 0x16, 0x90,
|
||||
0x00, 0x02, 0x00, 0x00, 0x03, 0xe8, 0x03, 0xe8, 0x25, 0x0d, 0x37, 0xe8,
|
||||
0x80, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0x04, 0x80, 0x08, 0x00, 0x09,
|
||||
0xc0, 0x0f, 0xc1, 0x80, 0x82, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x24,
|
||||
0xab, 0x31, 0x44, 0x62, 0x12, 0x1a, 0x15, 0x13, 0xfd, 0x5a, 0x5f, 0x69,
|
||||
0xef, 0xaa, 0x06, 0xe9, 0xab, 0xd7, 0x48, 0xcc, 0x3b, 0xd1, 0x4b, 0x60,
|
||||
0xed, 0x7f, 0xa6, 0x44, 0xce, 0x4d, 0xd2, 0xad, 0x80, 0x04, 0x00, 0x06,
|
||||
0x00, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x06, 0x80, 0xc1, 0x00, 0x00,
|
||||
0x02, 0x00, 0x01, 0x24, 0x57, 0x9c, 0x2f, 0x98, 0x00, 0x02, 0x00, 0x00,
|
||||
0x03, 0xe8, 0x08, 0x00, 0x63, 0x96, 0x8e, 0xc7, 0xc0, 0x00, 0x00, 0x04,
|
||||
0x80, 0x08, 0x00, 0x06, 0xc0, 0x82, 0x00, 0x00, 0x51, 0x95, 0x01, 0x88,
|
||||
0x0d, 0x80, 0x7b, 0x19, 0xe7, 0xf9, 0xc6, 0x18, 0x5c, 0x4a, 0xbf, 0x39,
|
||||
0x32, 0xe5, 0x63, 0x8e};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(InitAckChunk chunk, InitAckChunk::Parse(data));
|
||||
|
||||
EXPECT_EQ(chunk.initiate_tag(), VerificationTag(0x579c2f98u));
|
||||
EXPECT_EQ(chunk.a_rwnd(), 131072u);
|
||||
EXPECT_EQ(chunk.nbr_outbound_streams(), 1000u);
|
||||
EXPECT_EQ(chunk.nbr_inbound_streams(), 2048u);
|
||||
EXPECT_EQ(chunk.initial_tsn(), TSN(1670811335u));
|
||||
EXPECT_TRUE(
|
||||
chunk.parameters().get<ForwardTsnSupportedParameter>().has_value());
|
||||
EXPECT_TRUE(
|
||||
chunk.parameters().get<SupportedExtensionsParameter>().has_value());
|
||||
EXPECT_TRUE(chunk.parameters().get<StateCookieParameter>().has_value());
|
||||
}
|
||||
|
||||
TEST(InitAckChunkTest, SerializeAndDeserialize) {
|
||||
uint8_t state_cookie[] = {1, 2, 3, 4, 5};
|
||||
Parameters parameters =
|
||||
Parameters::Builder().Add(StateCookieParameter(state_cookie)).Build();
|
||||
InitAckChunk chunk(VerificationTag(123), /*a_rwnd=*/456,
|
||||
/*nbr_outbound_streams=*/65535,
|
||||
/*nbr_inbound_streams=*/65534, /*initial_tsn=*/TSN(789),
|
||||
/*parameters=*/std::move(parameters));
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(InitAckChunk deserialized,
|
||||
InitAckChunk::Parse(serialized));
|
||||
|
||||
EXPECT_EQ(chunk.initiate_tag(), VerificationTag(123u));
|
||||
EXPECT_EQ(chunk.a_rwnd(), 456u);
|
||||
EXPECT_EQ(chunk.nbr_outbound_streams(), 65535u);
|
||||
EXPECT_EQ(chunk.nbr_inbound_streams(), 65534u);
|
||||
EXPECT_EQ(chunk.initial_tsn(), TSN(789u));
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
StateCookieParameter cookie,
|
||||
deserialized.parameters().get<StateCookieParameter>());
|
||||
EXPECT_THAT(cookie.data(), ElementsAre(1, 2, 3, 4, 5));
|
||||
EXPECT_EQ(deserialized.ToString(),
|
||||
"INIT_ACK, initiate_tag=0x7b, initial_tsn=789");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
88
net/dcsctp/packet/chunk/init_chunk.cc
Normal file
88
net/dcsctp/packet/chunk/init_chunk.cc
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/init_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/strings/string_format.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.2
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 1 | Chunk Flags | Chunk Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Initiate Tag |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Advertised Receiver Window Credit (a_rwnd) |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Number of Outbound Streams | Number of Inbound Streams |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Initial TSN |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / Optional/Variable-Length Parameters /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int InitChunk::kType;
|
||||
|
||||
absl::optional<InitChunk> InitChunk::Parse(rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
VerificationTag initiate_tag(reader->Load32<4>());
|
||||
uint32_t a_rwnd = reader->Load32<8>();
|
||||
uint16_t nbr_outbound_streams = reader->Load16<12>();
|
||||
uint16_t nbr_inbound_streams = reader->Load16<14>();
|
||||
TSN initial_tsn(reader->Load32<16>());
|
||||
|
||||
absl::optional<Parameters> parameters =
|
||||
Parameters::Parse(reader->variable_data());
|
||||
if (!parameters.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return InitChunk(initiate_tag, a_rwnd, nbr_outbound_streams,
|
||||
nbr_inbound_streams, initial_tsn, *std::move(parameters));
|
||||
}
|
||||
|
||||
void InitChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
rtc::ArrayView<const uint8_t> parameters = parameters_.data();
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());
|
||||
|
||||
writer.Store32<4>(*initiate_tag_);
|
||||
writer.Store32<8>(a_rwnd_);
|
||||
writer.Store16<12>(nbr_outbound_streams_);
|
||||
writer.Store16<14>(nbr_inbound_streams_);
|
||||
writer.Store32<16>(*initial_tsn_);
|
||||
|
||||
writer.CopyToVariableData(parameters);
|
||||
}
|
||||
|
||||
std::string InitChunk::ToString() const {
|
||||
return rtc::StringFormat("INIT, initiate_tag=0x%0x, initial_tsn=%d",
|
||||
*initiate_tag(), *initial_tsn());
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
77
net/dcsctp/packet/chunk/init_chunk.h
Normal file
77
net/dcsctp/packet/chunk/init_chunk.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_INIT_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_INIT_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.2
|
||||
struct InitChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 1;
|
||||
static constexpr size_t kHeaderSize = 20;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class InitChunk : public Chunk, public TLVTrait<InitChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = InitChunkConfig::kType;
|
||||
|
||||
InitChunk(VerificationTag initiate_tag,
|
||||
uint32_t a_rwnd,
|
||||
uint16_t nbr_outbound_streams,
|
||||
uint16_t nbr_inbound_streams,
|
||||
TSN initial_tsn,
|
||||
Parameters parameters)
|
||||
: initiate_tag_(initiate_tag),
|
||||
a_rwnd_(a_rwnd),
|
||||
nbr_outbound_streams_(nbr_outbound_streams),
|
||||
nbr_inbound_streams_(nbr_inbound_streams),
|
||||
initial_tsn_(initial_tsn),
|
||||
parameters_(std::move(parameters)) {}
|
||||
|
||||
InitChunk(InitChunk&& other) = default;
|
||||
InitChunk& operator=(InitChunk&& other) = default;
|
||||
|
||||
static absl::optional<InitChunk> Parse(rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
VerificationTag initiate_tag() const { return initiate_tag_; }
|
||||
uint32_t a_rwnd() const { return a_rwnd_; }
|
||||
uint16_t nbr_outbound_streams() const { return nbr_outbound_streams_; }
|
||||
uint16_t nbr_inbound_streams() const { return nbr_inbound_streams_; }
|
||||
TSN initial_tsn() const { return initial_tsn_; }
|
||||
const Parameters& parameters() const { return parameters_; }
|
||||
|
||||
private:
|
||||
VerificationTag initiate_tag_;
|
||||
uint32_t a_rwnd_;
|
||||
uint16_t nbr_outbound_streams_;
|
||||
uint16_t nbr_inbound_streams_;
|
||||
TSN initial_tsn_;
|
||||
Parameters parameters_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_INIT_CHUNK_H_
|
113
net/dcsctp/packet/chunk/init_chunk_test.cc
Normal file
113
net/dcsctp/packet/chunk/init_chunk_test.cc
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/packet/parameter/forward_tsn_supported_parameter.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/parameter/supported_extensions_parameter.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(InitChunkTest, FromCapture) {
|
||||
/*
|
||||
INIT chunk (Outbound streams: 1000, inbound streams: 1000)
|
||||
Chunk type: INIT (1)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 90
|
||||
Initiate tag: 0xde7a1690
|
||||
Advertised receiver window credit (a_rwnd): 131072
|
||||
Number of outbound streams: 1000
|
||||
Number of inbound streams: 1000
|
||||
Initial TSN: 621623272
|
||||
ECN parameter
|
||||
Parameter type: ECN (0x8000)
|
||||
Parameter length: 4
|
||||
Forward TSN supported parameter
|
||||
Parameter type: Forward TSN supported (0xc000)
|
||||
Parameter length: 4
|
||||
Supported Extensions parameter (Supported types: FORWARD_TSN, AUTH,
|
||||
ASCONF, ASCONF_ACK, RE_CONFIG) Parameter type: Supported Extensions (0x8008)
|
||||
Parameter length: 9
|
||||
Supported chunk type: FORWARD_TSN (192)
|
||||
Supported chunk type: AUTH (15)
|
||||
Supported chunk type: ASCONF (193)
|
||||
Supported chunk type: ASCONF_ACK (128)
|
||||
Supported chunk type: RE_CONFIG (130)
|
||||
Parameter padding: 000000
|
||||
Random parameter
|
||||
Parameter type: Random (0x8002)
|
||||
Parameter length: 36
|
||||
Random number: ab314462121a1513fd5a5f69efaa06e9abd748cc3bd14b60…
|
||||
Requested HMAC Algorithm parameter (Supported HMACs: SHA-1)
|
||||
Parameter type: Requested HMAC Algorithm (0x8004)
|
||||
Parameter length: 6
|
||||
HMAC identifier: SHA-1 (1)
|
||||
Parameter padding: 0000
|
||||
Authenticated Chunk list parameter (Chunk types to be authenticated:
|
||||
ASCONF_ACK, ASCONF) Parameter type: Authenticated Chunk list (0x8003)
|
||||
Parameter length: 6
|
||||
Chunk type: ASCONF_ACK (128)
|
||||
Chunk type: ASCONF (193)
|
||||
*/
|
||||
|
||||
uint8_t data[] = {
|
||||
0x01, 0x00, 0x00, 0x5a, 0xde, 0x7a, 0x16, 0x90, 0x00, 0x02, 0x00, 0x00,
|
||||
0x03, 0xe8, 0x03, 0xe8, 0x25, 0x0d, 0x37, 0xe8, 0x80, 0x00, 0x00, 0x04,
|
||||
0xc0, 0x00, 0x00, 0x04, 0x80, 0x08, 0x00, 0x09, 0xc0, 0x0f, 0xc1, 0x80,
|
||||
0x82, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x24, 0xab, 0x31, 0x44, 0x62,
|
||||
0x12, 0x1a, 0x15, 0x13, 0xfd, 0x5a, 0x5f, 0x69, 0xef, 0xaa, 0x06, 0xe9,
|
||||
0xab, 0xd7, 0x48, 0xcc, 0x3b, 0xd1, 0x4b, 0x60, 0xed, 0x7f, 0xa6, 0x44,
|
||||
0xce, 0x4d, 0xd2, 0xad, 0x80, 0x04, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00,
|
||||
0x80, 0x03, 0x00, 0x06, 0x80, 0xc1, 0x00, 0x00};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(InitChunk chunk, InitChunk::Parse(data));
|
||||
|
||||
EXPECT_EQ(chunk.initiate_tag(), VerificationTag(0xde7a1690));
|
||||
EXPECT_EQ(chunk.a_rwnd(), 131072u);
|
||||
EXPECT_EQ(chunk.nbr_outbound_streams(), 1000u);
|
||||
EXPECT_EQ(chunk.nbr_inbound_streams(), 1000u);
|
||||
EXPECT_EQ(chunk.initial_tsn(), TSN(621623272u));
|
||||
EXPECT_TRUE(
|
||||
chunk.parameters().get<ForwardTsnSupportedParameter>().has_value());
|
||||
EXPECT_TRUE(
|
||||
chunk.parameters().get<SupportedExtensionsParameter>().has_value());
|
||||
}
|
||||
|
||||
TEST(InitChunkTest, SerializeAndDeserialize) {
|
||||
InitChunk chunk(VerificationTag(123), /*a_rwnd=*/456,
|
||||
/*nbr_outbound_streams=*/65535,
|
||||
/*nbr_inbound_streams=*/65534, /*initial_tsn=*/TSN(789),
|
||||
/*parameters=*/Parameters::Builder().Build());
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(InitChunk deserialized,
|
||||
InitChunk::Parse(serialized));
|
||||
|
||||
EXPECT_EQ(deserialized.initiate_tag(), VerificationTag(123u));
|
||||
EXPECT_EQ(deserialized.a_rwnd(), 456u);
|
||||
EXPECT_EQ(deserialized.nbr_outbound_streams(), 65535u);
|
||||
EXPECT_EQ(deserialized.nbr_inbound_streams(), 65534u);
|
||||
EXPECT_EQ(deserialized.initial_tsn(), TSN(789u));
|
||||
EXPECT_EQ(deserialized.ToString(),
|
||||
"INIT, initiate_tag=0x7b, initial_tsn=789");
|
||||
}
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
69
net/dcsctp/packet/chunk/reconfig_chunk.cc
Normal file
69
net/dcsctp/packet/chunk/reconfig_chunk.cc
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/reconfig_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc6525#section-3.1
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 130 | Chunk Flags | Chunk Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / Re-configuration Parameter /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// \ \
|
||||
// / Re-configuration Parameter (optional) /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int ReConfigChunk::kType;
|
||||
|
||||
absl::optional<ReConfigChunk> ReConfigChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
absl::optional<Parameters> parameters =
|
||||
Parameters::Parse(reader->variable_data());
|
||||
if (!parameters.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
return ReConfigChunk(*std::move(parameters));
|
||||
}
|
||||
|
||||
void ReConfigChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
rtc::ArrayView<const uint8_t> parameters = parameters_.data();
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());
|
||||
writer.CopyToVariableData(parameters);
|
||||
}
|
||||
|
||||
std::string ReConfigChunk::ToString() const {
|
||||
return "RE-CONFIG";
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
56
net/dcsctp/packet/chunk/reconfig_chunk.h
Normal file
56
net/dcsctp/packet/chunk/reconfig_chunk.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_RECONFIG_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_RECONFIG_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc6525#section-3.1
|
||||
struct ReConfigChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 130;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class ReConfigChunk : public Chunk, public TLVTrait<ReConfigChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = ReConfigChunkConfig::kType;
|
||||
|
||||
explicit ReConfigChunk(Parameters parameters)
|
||||
: parameters_(std::move(parameters)) {}
|
||||
|
||||
static absl::optional<ReConfigChunk> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
const Parameters& parameters() const { return parameters_; }
|
||||
Parameters extract_parameters() { return std::move(parameters_); }
|
||||
|
||||
private:
|
||||
Parameters parameters_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_RECONFIG_CHUNK_H_
|
94
net/dcsctp/packet/chunk/reconfig_chunk_test.cc
Normal file
94
net/dcsctp/packet/chunk/reconfig_chunk_test.cc
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 <cstdint>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::SizeIs;
|
||||
|
||||
TEST(ReConfigChunkTest, FromCapture) {
|
||||
/*
|
||||
RE_CONFIG chunk
|
||||
Chunk type: RE_CONFIG (130)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 22
|
||||
Outgoing SSN reset request parameter
|
||||
Parameter type: Outgoing SSN reset request (0x000d)
|
||||
Parameter length: 18
|
||||
Re-configuration request sequence number: 2270550051
|
||||
Re-configuration response sequence number: 1905748638
|
||||
Senders last assigned TSN: 2270550066
|
||||
Stream Identifier: 6
|
||||
Chunk padding: 0000
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x82, 0x00, 0x00, 0x16, 0x00, 0x0d, 0x00, 0x12,
|
||||
0x87, 0x55, 0xd8, 0x23, 0x71, 0x97, 0x6a, 0x9e,
|
||||
0x87, 0x55, 0xd8, 0x32, 0x00, 0x06, 0x00, 0x00};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(ReConfigChunk chunk, ReConfigChunk::Parse(data));
|
||||
|
||||
const Parameters& parameters = chunk.parameters();
|
||||
EXPECT_THAT(parameters.descriptors(), SizeIs(1));
|
||||
ParameterDescriptor desc = parameters.descriptors()[0];
|
||||
ASSERT_EQ(desc.type, OutgoingSSNResetRequestParameter::kType);
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
OutgoingSSNResetRequestParameter req,
|
||||
OutgoingSSNResetRequestParameter::Parse(desc.data));
|
||||
EXPECT_EQ(*req.request_sequence_number(), 2270550051u);
|
||||
EXPECT_EQ(*req.response_sequence_number(), 1905748638u);
|
||||
EXPECT_EQ(*req.sender_last_assigned_tsn(), 2270550066u);
|
||||
EXPECT_THAT(req.stream_ids(), ElementsAre(StreamID(6)));
|
||||
}
|
||||
|
||||
TEST(ReConfigChunkTest, SerializeAndDeserialize) {
|
||||
Parameters::Builder params_builder =
|
||||
Parameters::Builder().Add(OutgoingSSNResetRequestParameter(
|
||||
ReconfigRequestSN(123), ReconfigResponseSN(456), TSN(789),
|
||||
{StreamID(42), StreamID(43)}));
|
||||
|
||||
ReConfigChunk chunk(params_builder.Build());
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(ReConfigChunk deserialized,
|
||||
ReConfigChunk::Parse(serialized));
|
||||
|
||||
const Parameters& parameters = deserialized.parameters();
|
||||
EXPECT_THAT(parameters.descriptors(), SizeIs(1));
|
||||
ParameterDescriptor desc = parameters.descriptors()[0];
|
||||
ASSERT_EQ(desc.type, OutgoingSSNResetRequestParameter::kType);
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
OutgoingSSNResetRequestParameter req,
|
||||
OutgoingSSNResetRequestParameter::Parse(desc.data));
|
||||
EXPECT_EQ(*req.request_sequence_number(), 123u);
|
||||
EXPECT_EQ(*req.response_sequence_number(), 456u);
|
||||
EXPECT_EQ(*req.sender_last_assigned_tsn(), 789u);
|
||||
EXPECT_THAT(req.stream_ids(), ElementsAre(StreamID(42), StreamID(43)));
|
||||
|
||||
EXPECT_EQ(deserialized.ToString(), "RE-CONFIG");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
156
net/dcsctp/packet/chunk/sack_chunk.cc
Normal file
156
net/dcsctp/packet/chunk/sack_chunk.cc
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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/common/str_join.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/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::vector<TSN> duplicate_tsns;
|
||||
duplicate_tsns.reserve(nbr_of_gap_blocks);
|
||||
for (int i = 0; i < nbr_of_dup_tsns; ++i) {
|
||||
BoundedByteReader<kDupTsnBlockSize> sub_reader =
|
||||
reader->sub_reader<kDupTsnBlockSize>(offset);
|
||||
|
||||
duplicate_tsns.push_back(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 (int i = 0; i < nbr_of_dup_tsns; ++i) {
|
||||
BoundedByteWriter<kDupTsnBlockSize> sub_writer =
|
||||
writer.sub_writer<kDupTsnBlockSize>(offset);
|
||||
|
||||
sub_writer.Store32<0>(*duplicate_tsns_[i]);
|
||||
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
|
79
net/dcsctp/packet/chunk/sack_chunk.h
Normal file
79
net/dcsctp/packet/chunk/sack_chunk.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 <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::vector<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_;
|
||||
}
|
||||
rtc::ArrayView<const 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::vector<TSN> duplicate_tsns_;
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_SACK_CHUNK_H_
|
84
net/dcsctp/packet/chunk/sack_chunk_test.cc
Normal file
84
net/dcsctp/packet/chunk/sack_chunk_test.cc
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 <cstdint>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(SackChunkTest, FromCapture) {
|
||||
/*
|
||||
SACK chunk (Cumulative TSN: 916312075, a_rwnd: 126323,
|
||||
gaps: 2, duplicate TSNs: 1)
|
||||
Chunk type: SACK (3)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 28
|
||||
Cumulative TSN ACK: 916312075
|
||||
Advertised receiver window credit (a_rwnd): 126323
|
||||
Number of gap acknowledgement blocks: 2
|
||||
Number of duplicated TSNs: 1
|
||||
Gap Acknowledgement for TSN 916312077 to 916312081
|
||||
Gap Acknowledgement for TSN 916312083 to 916312083
|
||||
[Number of TSNs in gap acknowledgement blocks: 6]
|
||||
Duplicate TSN: 916312081
|
||||
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x03, 0x00, 0x00, 0x1c, 0x36, 0x9d, 0xd0, 0x0b, 0x00, 0x01,
|
||||
0xed, 0x73, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x06,
|
||||
0x00, 0x08, 0x00, 0x08, 0x36, 0x9d, 0xd0, 0x11};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(SackChunk chunk, SackChunk::Parse(data));
|
||||
|
||||
TSN cum_ack_tsn(916312075);
|
||||
EXPECT_EQ(chunk.cumulative_tsn_ack(), cum_ack_tsn);
|
||||
EXPECT_EQ(chunk.a_rwnd(), 126323u);
|
||||
EXPECT_THAT(
|
||||
chunk.gap_ack_blocks(),
|
||||
ElementsAre(SackChunk::GapAckBlock(
|
||||
static_cast<uint16_t>(916312077 - *cum_ack_tsn),
|
||||
static_cast<uint16_t>(916312081 - *cum_ack_tsn)),
|
||||
SackChunk::GapAckBlock(
|
||||
static_cast<uint16_t>(916312083 - *cum_ack_tsn),
|
||||
static_cast<uint16_t>(916312083 - *cum_ack_tsn))));
|
||||
EXPECT_THAT(chunk.duplicate_tsns(), ElementsAre(TSN(916312081)));
|
||||
}
|
||||
|
||||
TEST(SackChunkTest, SerializeAndDeserialize) {
|
||||
SackChunk chunk(TSN(123), /*a_rwnd=*/456, {SackChunk::GapAckBlock(2, 3)},
|
||||
{TSN(1), TSN(2), TSN(3)});
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(SackChunk deserialized,
|
||||
SackChunk::Parse(serialized));
|
||||
|
||||
EXPECT_EQ(*deserialized.cumulative_tsn_ack(), 123u);
|
||||
EXPECT_EQ(deserialized.a_rwnd(), 456u);
|
||||
EXPECT_THAT(deserialized.gap_ack_blocks(),
|
||||
ElementsAre(SackChunk::GapAckBlock(2, 3)));
|
||||
EXPECT_THAT(deserialized.duplicate_tsns(),
|
||||
ElementsAre(TSN(1), TSN(2), TSN(3)));
|
||||
|
||||
EXPECT_EQ(deserialized.ToString(),
|
||||
"SACK, cum_ack_tsn=123, a_rwnd=456, gap=125--126, dup_tsns=1,2,3");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
46
net/dcsctp/packet/chunk/shutdown_ack_chunk.cc
Normal file
46
net/dcsctp/packet/chunk/shutdown_ack_chunk.cc
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/shutdown_ack_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.9
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 8 |Chunk Flags | Length = 4 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int ShutdownAckChunk::kType;
|
||||
|
||||
absl::optional<ShutdownAckChunk> ShutdownAckChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
if (!ParseTLV(data).has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return ShutdownAckChunk();
|
||||
}
|
||||
|
||||
void ShutdownAckChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
AllocateTLV(out);
|
||||
}
|
||||
|
||||
std::string ShutdownAckChunk::ToString() const {
|
||||
return "SHUTDOWN-ACK";
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
47
net/dcsctp/packet/chunk/shutdown_ack_chunk.h
Normal file
47
net/dcsctp/packet/chunk/shutdown_ack_chunk.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_ACK_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_ACK_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.9
|
||||
struct ShutdownAckChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 8;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class ShutdownAckChunk : public Chunk, public TLVTrait<ShutdownAckChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = ShutdownAckChunkConfig::kType;
|
||||
|
||||
ShutdownAckChunk() {}
|
||||
|
||||
static absl::optional<ShutdownAckChunk> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_ACK_CHUNK_H_
|
45
net/dcsctp/packet/chunk/shutdown_ack_chunk_test.cc
Normal file
45
net/dcsctp/packet/chunk/shutdown_ack_chunk_test.cc
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/shutdown_ack_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(ShutdownAckChunkTest, FromCapture) {
|
||||
/*
|
||||
SHUTDOWN_ACK chunk
|
||||
Chunk type: SHUTDOWN_ACK (8)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 4
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x08, 0x00, 0x00, 0x04};
|
||||
|
||||
EXPECT_TRUE(ShutdownAckChunk::Parse(data).has_value());
|
||||
}
|
||||
|
||||
TEST(ShutdownAckChunkTest, SerializeAndDeserialize) {
|
||||
ShutdownAckChunk chunk;
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
EXPECT_TRUE(ShutdownAckChunk::Parse(serialized).has_value());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
55
net/dcsctp/packet/chunk/shutdown_chunk.cc
Normal file
55
net/dcsctp/packet/chunk/shutdown_chunk.cc
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/shutdown_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.8
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 7 | Chunk Flags | Length = 8 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cumulative TSN Ack |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int ShutdownChunk::kType;
|
||||
|
||||
absl::optional<ShutdownChunk> ShutdownChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
TSN cumulative_tsn_ack(reader->Load32<4>());
|
||||
return ShutdownChunk(cumulative_tsn_ack);
|
||||
}
|
||||
|
||||
void ShutdownChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
|
||||
writer.Store32<4>(*cumulative_tsn_ack_);
|
||||
}
|
||||
|
||||
std::string ShutdownChunk::ToString() const {
|
||||
return "SHUTDOWN";
|
||||
}
|
||||
} // namespace dcsctp
|
53
net/dcsctp/packet/chunk/shutdown_chunk.h
Normal file
53
net/dcsctp/packet/chunk/shutdown_chunk.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.8
|
||||
struct ShutdownChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 7;
|
||||
static constexpr size_t kHeaderSize = 8;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class ShutdownChunk : public Chunk, public TLVTrait<ShutdownChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = ShutdownChunkConfig::kType;
|
||||
|
||||
explicit ShutdownChunk(TSN cumulative_tsn_ack)
|
||||
: cumulative_tsn_ack_(cumulative_tsn_ack) {}
|
||||
|
||||
static absl::optional<ShutdownChunk> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
TSN cumulative_tsn_ack() const { return cumulative_tsn_ack_; }
|
||||
|
||||
private:
|
||||
TSN cumulative_tsn_ack_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_CHUNK_H_
|
50
net/dcsctp/packet/chunk/shutdown_chunk_test.cc
Normal file
50
net/dcsctp/packet/chunk/shutdown_chunk_test.cc
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/shutdown_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
TEST(ShutdownChunkTest, FromCapture) {
|
||||
/*
|
||||
SHUTDOWN chunk (Cumulative TSN ack: 101831101)
|
||||
Chunk type: SHUTDOWN (7)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 8
|
||||
Cumulative TSN Ack: 101831101
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x07, 0x00, 0x00, 0x08, 0x06, 0x11, 0xd1, 0xbd};
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(ShutdownChunk chunk, ShutdownChunk::Parse(data));
|
||||
EXPECT_EQ(chunk.cumulative_tsn_ack(), TSN(101831101u));
|
||||
}
|
||||
|
||||
TEST(ShutdownChunkTest, SerializeAndDeserialize) {
|
||||
ShutdownChunk chunk(TSN(12345678));
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(ShutdownChunk deserialized,
|
||||
ShutdownChunk::Parse(serialized));
|
||||
|
||||
EXPECT_EQ(deserialized.cumulative_tsn_ack(), TSN(12345678u));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
54
net/dcsctp/packet/chunk/shutdown_complete_chunk.cc
Normal file
54
net/dcsctp/packet/chunk/shutdown_complete_chunk.cc
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/shutdown_complete_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.13
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type = 14 |Reserved |T| Length = 4 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int ShutdownCompleteChunk::kType;
|
||||
|
||||
absl::optional<ShutdownCompleteChunk> ShutdownCompleteChunk::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
uint8_t flags = reader->Load8<1>();
|
||||
bool tag_reflected = (flags & (1 << kFlagsBitT)) != 0;
|
||||
return ShutdownCompleteChunk(tag_reflected);
|
||||
}
|
||||
|
||||
void ShutdownCompleteChunk::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
|
||||
writer.Store8<1>(tag_reflected_ ? (1 << kFlagsBitT) : 0);
|
||||
}
|
||||
|
||||
std::string ShutdownCompleteChunk::ToString() const {
|
||||
return "SHUTDOWN-COMPLETE";
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
54
net/dcsctp/packet/chunk/shutdown_complete_chunk.h
Normal file
54
net/dcsctp/packet/chunk/shutdown_complete_chunk.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_COMPLETE_CHUNK_H_
|
||||
#define NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_COMPLETE_CHUNK_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/chunk/chunk.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.13
|
||||
struct ShutdownCompleteChunkConfig : ChunkConfig {
|
||||
static constexpr int kType = 14;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class ShutdownCompleteChunk : public Chunk,
|
||||
public TLVTrait<ShutdownCompleteChunkConfig> {
|
||||
public:
|
||||
static constexpr int kType = ShutdownCompleteChunkConfig::kType;
|
||||
|
||||
explicit ShutdownCompleteChunk(bool tag_reflected)
|
||||
: tag_reflected_(tag_reflected) {}
|
||||
|
||||
static absl::optional<ShutdownCompleteChunk> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
bool tag_reflected() const { return tag_reflected_; }
|
||||
|
||||
private:
|
||||
static constexpr int kFlagsBitT = 0;
|
||||
bool tag_reflected_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_CHUNK_SHUTDOWN_COMPLETE_CHUNK_H_
|
45
net/dcsctp/packet/chunk/shutdown_complete_chunk_test.cc
Normal file
45
net/dcsctp/packet/chunk/shutdown_complete_chunk_test.cc
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/chunk/shutdown_complete_chunk.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(ShutdownCompleteChunkTest, FromCapture) {
|
||||
/*
|
||||
SHUTDOWN_COMPLETE chunk
|
||||
Chunk type: SHUTDOWN_COMPLETE (14)
|
||||
Chunk flags: 0x00
|
||||
Chunk length: 4
|
||||
*/
|
||||
|
||||
uint8_t data[] = {0x0e, 0x00, 0x00, 0x04};
|
||||
|
||||
EXPECT_TRUE(ShutdownCompleteChunk::Parse(data).has_value());
|
||||
}
|
||||
|
||||
TEST(ShutdownCompleteChunkTest, SerializeAndDeserialize) {
|
||||
ShutdownCompleteChunk chunk(/*tag_reflected=*/false);
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
chunk.SerializeTo(serialized);
|
||||
|
||||
EXPECT_TRUE(ShutdownCompleteChunk::Parse(serialized).has_value());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.10
|
||||
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=10 | Cause Length=4 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int CookieReceivedWhileShuttingDownCause::kType;
|
||||
|
||||
absl::optional<CookieReceivedWhileShuttingDownCause>
|
||||
CookieReceivedWhileShuttingDownCause::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
if (!ParseTLV(data).has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return CookieReceivedWhileShuttingDownCause();
|
||||
}
|
||||
|
||||
void CookieReceivedWhileShuttingDownCause::SerializeTo(
|
||||
std::vector<uint8_t>& out) const {
|
||||
AllocateTLV(out);
|
||||
}
|
||||
|
||||
std::string CookieReceivedWhileShuttingDownCause::ToString() const {
|
||||
return "Cookie Received While Shutting Down";
|
||||
}
|
||||
} // namespace dcsctp
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_COOKIE_RECEIVED_WHILE_SHUTTING_DOWN_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_COOKIE_RECEIVED_WHILE_SHUTTING_DOWN_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.10
|
||||
struct CookieReceivedWhileShuttingDownCauseConfig : public ParameterConfig {
|
||||
static constexpr int kType = 10;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class CookieReceivedWhileShuttingDownCause
|
||||
: public Parameter,
|
||||
public TLVTrait<CookieReceivedWhileShuttingDownCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType =
|
||||
CookieReceivedWhileShuttingDownCauseConfig::kType;
|
||||
|
||||
CookieReceivedWhileShuttingDownCause() {}
|
||||
|
||||
static absl::optional<CookieReceivedWhileShuttingDownCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_COOKIE_RECEIVED_WHILE_SHUTTING_DOWN_CAUSE_H_
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(CookieReceivedWhileShuttingDownCauseTest, SerializeAndDeserialize) {
|
||||
CookieReceivedWhileShuttingDownCause parameter;
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
CookieReceivedWhileShuttingDownCause deserialized,
|
||||
CookieReceivedWhileShuttingDownCause::Parse(serialized));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
83
net/dcsctp/packet/error_cause/error_cause.cc
Normal file
83
net/dcsctp/packet/error_cause/error_cause.cc
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/common/math.h"
|
||||
#include "net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/no_user_data_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/out_of_resource_error_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/protocol_violation_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/stale_cookie_error_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/unresolvable_address_cause.h"
|
||||
#include "net/dcsctp/packet/error_cause/user_initiated_abort_cause.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
template <class ErrorCause>
|
||||
bool ParseAndPrint(ParameterDescriptor descriptor, rtc::StringBuilder& sb) {
|
||||
if (descriptor.type == ErrorCause::kType) {
|
||||
absl::optional<ErrorCause> p = ErrorCause::Parse(descriptor.data);
|
||||
if (p.has_value()) {
|
||||
sb << p->ToString();
|
||||
} else {
|
||||
sb << "Failed to parse error cause of type " << ErrorCause::kType;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ErrorCausesToString(const Parameters& parameters) {
|
||||
rtc::StringBuilder sb;
|
||||
|
||||
std::vector<ParameterDescriptor> descriptors = parameters.descriptors();
|
||||
for (size_t i = 0; i < descriptors.size(); ++i) {
|
||||
if (i > 0) {
|
||||
sb << "\n";
|
||||
}
|
||||
|
||||
const ParameterDescriptor& d = descriptors[i];
|
||||
if (!ParseAndPrint<InvalidStreamIdentifierCause>(d, sb) &&
|
||||
!ParseAndPrint<MissingMandatoryParameterCause>(d, sb) &&
|
||||
!ParseAndPrint<StaleCookieErrorCause>(d, sb) &&
|
||||
!ParseAndPrint<OutOfResourceErrorCause>(d, sb) &&
|
||||
!ParseAndPrint<UnresolvableAddressCause>(d, sb) &&
|
||||
!ParseAndPrint<UnrecognizedChunkTypeCause>(d, sb) &&
|
||||
!ParseAndPrint<InvalidMandatoryParameterCause>(d, sb) &&
|
||||
!ParseAndPrint<UnrecognizedParametersCause>(d, sb) &&
|
||||
!ParseAndPrint<NoUserDataCause>(d, sb) &&
|
||||
!ParseAndPrint<CookieReceivedWhileShuttingDownCause>(d, sb) &&
|
||||
!ParseAndPrint<RestartOfAnAssociationWithNewAddressesCause>(d, sb) &&
|
||||
!ParseAndPrint<UserInitiatedAbortCause>(d, sb) &&
|
||||
!ParseAndPrint<ProtocolViolationCause>(d, sb)) {
|
||||
sb << "Unhandled parameter of type: " << d.type;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.Release();
|
||||
}
|
||||
} // namespace dcsctp
|
38
net/dcsctp/packet/error_cause/error_cause.h
Normal file
38
net/dcsctp/packet/error_cause/error_cause.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_ERROR_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_ERROR_CAUSE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// Converts the Error Causes in `parameters` to a human readable string,
|
||||
// to be used in error reporting and logging.
|
||||
std::string ErrorCausesToString(const Parameters& parameters);
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_ERROR_CAUSE_H_
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.7
|
||||
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=7 | Cause Length=4 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int InvalidMandatoryParameterCause::kType;
|
||||
|
||||
absl::optional<InvalidMandatoryParameterCause>
|
||||
InvalidMandatoryParameterCause::Parse(rtc::ArrayView<const uint8_t> data) {
|
||||
if (!ParseTLV(data).has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return InvalidMandatoryParameterCause();
|
||||
}
|
||||
|
||||
void InvalidMandatoryParameterCause::SerializeTo(
|
||||
std::vector<uint8_t>& out) const {
|
||||
AllocateTLV(out);
|
||||
}
|
||||
|
||||
std::string InvalidMandatoryParameterCause::ToString() const {
|
||||
return "Invalid Mandatory Parameter";
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_MANDATORY_PARAMETER_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_MANDATORY_PARAMETER_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.7
|
||||
struct InvalidMandatoryParameterCauseConfig : public ParameterConfig {
|
||||
static constexpr int kType = 7;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class InvalidMandatoryParameterCause
|
||||
: public Parameter,
|
||||
public TLVTrait<InvalidMandatoryParameterCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType = InvalidMandatoryParameterCauseConfig::kType;
|
||||
|
||||
InvalidMandatoryParameterCause() {}
|
||||
|
||||
static absl::optional<InvalidMandatoryParameterCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_MANDATORY_PARAMETER_CAUSE_H_
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(InvalidMandatoryParameterCauseTest, SerializeAndDeserialize) {
|
||||
InvalidMandatoryParameterCause parameter;
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
InvalidMandatoryParameterCause deserialized,
|
||||
InvalidMandatoryParameterCause::Parse(serialized));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.1
|
||||
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=1 | Cause Length=8 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Stream Identifier | (Reserved) |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int InvalidStreamIdentifierCause::kType;
|
||||
|
||||
absl::optional<InvalidStreamIdentifierCause>
|
||||
InvalidStreamIdentifierCause::Parse(rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
StreamID stream_id(reader->Load16<4>());
|
||||
return InvalidStreamIdentifierCause(stream_id);
|
||||
}
|
||||
|
||||
void InvalidStreamIdentifierCause::SerializeTo(
|
||||
std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
|
||||
|
||||
writer.Store16<4>(*stream_id_);
|
||||
}
|
||||
|
||||
std::string InvalidStreamIdentifierCause::ToString() const {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "Invalid Stream Identifier, stream_id=" << *stream_id_;
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_STREAM_IDENTIFIER_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_STREAM_IDENTIFIER_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "net/dcsctp/public/types.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.1
|
||||
struct InvalidStreamIdentifierCauseConfig : public ParameterConfig {
|
||||
static constexpr int kType = 1;
|
||||
static constexpr size_t kHeaderSize = 8;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class InvalidStreamIdentifierCause
|
||||
: public Parameter,
|
||||
public TLVTrait<InvalidStreamIdentifierCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType = InvalidStreamIdentifierCauseConfig::kType;
|
||||
|
||||
explicit InvalidStreamIdentifierCause(StreamID stream_id)
|
||||
: stream_id_(stream_id) {}
|
||||
|
||||
static absl::optional<InvalidStreamIdentifierCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
StreamID stream_id() const { return stream_id_; }
|
||||
|
||||
private:
|
||||
StreamID stream_id_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_INVALID_STREAM_IDENTIFIER_CAUSE_H_
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(InvalidStreamIdentifierCauseTest, SerializeAndDeserialize) {
|
||||
InvalidStreamIdentifierCause parameter(StreamID(1));
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(InvalidStreamIdentifierCause deserialized,
|
||||
InvalidStreamIdentifierCause::Parse(serialized));
|
||||
|
||||
EXPECT_EQ(*deserialized.stream_id(), 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/common/str_join.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.2
|
||||
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=2 | Cause Length=8+N*2 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Number of missing params=N |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Missing Param Type #1 | Missing Param Type #2 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Missing Param Type #N-1 | Missing Param Type #N |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int MissingMandatoryParameterCause::kType;
|
||||
|
||||
absl::optional<MissingMandatoryParameterCause>
|
||||
MissingMandatoryParameterCause::Parse(rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
uint32_t count = reader->Load32<4>();
|
||||
if (reader->variable_data_size() != count * kMissingParameterSize) {
|
||||
RTC_DLOG(LS_WARNING) << "Invalid number of missing parameters";
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
std::vector<uint16_t> missing_parameter_types;
|
||||
missing_parameter_types.reserve(count);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
BoundedByteReader<kMissingParameterSize> sub_reader =
|
||||
reader->sub_reader<kMissingParameterSize>(i * kMissingParameterSize);
|
||||
|
||||
missing_parameter_types.push_back(sub_reader.Load16<0>());
|
||||
}
|
||||
return MissingMandatoryParameterCause(missing_parameter_types);
|
||||
}
|
||||
|
||||
void MissingMandatoryParameterCause::SerializeTo(
|
||||
std::vector<uint8_t>& out) const {
|
||||
size_t variable_size =
|
||||
missing_parameter_types_.size() * kMissingParameterSize;
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);
|
||||
|
||||
writer.Store32<4>(missing_parameter_types_.size());
|
||||
|
||||
for (size_t i = 0; i < missing_parameter_types_.size(); ++i) {
|
||||
BoundedByteWriter<kMissingParameterSize> sub_writer =
|
||||
writer.sub_writer<kMissingParameterSize>(i * kMissingParameterSize);
|
||||
|
||||
sub_writer.Store16<0>(missing_parameter_types_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::string MissingMandatoryParameterCause::ToString() const {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "Missing Mandatory Parameter, missing_parameter_types="
|
||||
<< StrJoin(missing_parameter_types_, ",");
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_MISSING_MANDATORY_PARAMETER_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_MISSING_MANDATORY_PARAMETER_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.2
|
||||
struct MissingMandatoryParameterCauseConfig : public ParameterConfig {
|
||||
static constexpr int kType = 2;
|
||||
static constexpr size_t kHeaderSize = 8;
|
||||
static constexpr size_t kVariableLengthAlignment = 2;
|
||||
};
|
||||
|
||||
class MissingMandatoryParameterCause
|
||||
: public Parameter,
|
||||
public TLVTrait<MissingMandatoryParameterCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType = MissingMandatoryParameterCauseConfig::kType;
|
||||
|
||||
explicit MissingMandatoryParameterCause(
|
||||
rtc::ArrayView<const uint16_t> missing_parameter_types)
|
||||
: missing_parameter_types_(missing_parameter_types.begin(),
|
||||
missing_parameter_types.end()) {}
|
||||
|
||||
static absl::optional<MissingMandatoryParameterCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
rtc::ArrayView<const uint16_t> missing_parameter_types() const {
|
||||
return missing_parameter_types_;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr size_t kMissingParameterSize = 2;
|
||||
std::vector<uint16_t> missing_parameter_types_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_MISSING_MANDATORY_PARAMETER_CAUSE_H_
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(MissingMandatoryParameterCauseTest, SerializeAndDeserialize) {
|
||||
uint16_t parameter_types[] = {1, 2, 3};
|
||||
MissingMandatoryParameterCause parameter(parameter_types);
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
MissingMandatoryParameterCause deserialized,
|
||||
MissingMandatoryParameterCause::Parse(serialized));
|
||||
|
||||
EXPECT_THAT(deserialized.missing_parameter_types(), ElementsAre(1, 2, 3));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
57
net/dcsctp/packet/error_cause/no_user_data_cause.cc
Normal file
57
net/dcsctp/packet/error_cause/no_user_data_cause.cc
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/no_user_data_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.9
|
||||
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=9 | Cause Length=8 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// / TSN value /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int NoUserDataCause::kType;
|
||||
|
||||
absl::optional<NoUserDataCause> NoUserDataCause::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
TSN tsn(reader->Load32<4>());
|
||||
return NoUserDataCause(tsn);
|
||||
}
|
||||
|
||||
void NoUserDataCause::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
|
||||
writer.Store32<4>(*tsn_);
|
||||
}
|
||||
|
||||
std::string NoUserDataCause::ToString() const {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "No User Data, tsn=" << *tsn_;
|
||||
return sb.Release();
|
||||
}
|
||||
} // namespace dcsctp
|
53
net/dcsctp/packet/error_cause/no_user_data_cause.h
Normal file
53
net/dcsctp/packet/error_cause/no_user_data_cause.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_NO_USER_DATA_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_NO_USER_DATA_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/common/internal_types.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.9
|
||||
struct NoUserDataCauseConfig : public ParameterConfig {
|
||||
static constexpr int kType = 9;
|
||||
static constexpr size_t kHeaderSize = 8;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class NoUserDataCause : public Parameter,
|
||||
public TLVTrait<NoUserDataCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType = NoUserDataCauseConfig::kType;
|
||||
|
||||
explicit NoUserDataCause(TSN tsn) : tsn_(tsn) {}
|
||||
|
||||
static absl::optional<NoUserDataCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
TSN tsn() const { return tsn_; }
|
||||
|
||||
private:
|
||||
TSN tsn_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_NO_USER_DATA_CAUSE_H_
|
36
net/dcsctp/packet/error_cause/no_user_data_cause_test.cc
Normal file
36
net/dcsctp/packet/error_cause/no_user_data_cause_test.cc
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/no_user_data_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(NoUserDataCauseTest, SerializeAndDeserialize) {
|
||||
NoUserDataCause parameter(TSN(123));
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(NoUserDataCause deserialized,
|
||||
NoUserDataCause::Parse(serialized));
|
||||
|
||||
EXPECT_EQ(*deserialized.tsn(), 123u);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
44
net/dcsctp/packet/error_cause/out_of_resource_error_cause.cc
Normal file
44
net/dcsctp/packet/error_cause/out_of_resource_error_cause.cc
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/out_of_resource_error_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.4
|
||||
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=4 | Cause Length=4 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int OutOfResourceErrorCause::kType;
|
||||
|
||||
absl::optional<OutOfResourceErrorCause> OutOfResourceErrorCause::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
if (!ParseTLV(data).has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return OutOfResourceErrorCause();
|
||||
}
|
||||
|
||||
void OutOfResourceErrorCause::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
AllocateTLV(out);
|
||||
}
|
||||
|
||||
std::string OutOfResourceErrorCause::ToString() const {
|
||||
return "Out Of Resource";
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
48
net/dcsctp/packet/error_cause/out_of_resource_error_cause.h
Normal file
48
net/dcsctp/packet/error_cause/out_of_resource_error_cause.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_OUT_OF_RESOURCE_ERROR_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_OUT_OF_RESOURCE_ERROR_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.4
|
||||
struct OutOfResourceParameterConfig : public ParameterConfig {
|
||||
static constexpr int kType = 4;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class OutOfResourceErrorCause : public Parameter,
|
||||
public TLVTrait<OutOfResourceParameterConfig> {
|
||||
public:
|
||||
static constexpr int kType = OutOfResourceParameterConfig::kType;
|
||||
|
||||
OutOfResourceErrorCause() {}
|
||||
|
||||
static absl::optional<OutOfResourceErrorCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_OUT_OF_RESOURCE_ERROR_CAUSE_H_
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/out_of_resource_error_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(OutOfResourceErrorCauseTest, SerializeAndDeserialize) {
|
||||
OutOfResourceErrorCause parameter;
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(OutOfResourceErrorCause deserialized,
|
||||
OutOfResourceErrorCause::Parse(serialized));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
65
net/dcsctp/packet/error_cause/protocol_violation_cause.cc
Normal file
65
net/dcsctp/packet/error_cause/protocol_violation_cause.cc
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/protocol_violation_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.13
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=13 | Cause Length=Variable |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// / Additional Information /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int ProtocolViolationCause::kType;
|
||||
|
||||
absl::optional<ProtocolViolationCause> ProtocolViolationCause::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return ProtocolViolationCause(
|
||||
std::string(reinterpret_cast<const char*>(reader->variable_data().data()),
|
||||
reader->variable_data().size()));
|
||||
}
|
||||
|
||||
void ProtocolViolationCause::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer =
|
||||
AllocateTLV(out, additional_information_.size());
|
||||
writer.CopyToVariableData(rtc::MakeArrayView(
|
||||
reinterpret_cast<const uint8_t*>(additional_information_.data()),
|
||||
additional_information_.size()));
|
||||
}
|
||||
|
||||
std::string ProtocolViolationCause::ToString() const {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "Protocol Violation, additional_information="
|
||||
<< additional_information_;
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
56
net/dcsctp/packet/error_cause/protocol_violation_cause.h
Normal file
56
net/dcsctp/packet/error_cause/protocol_violation_cause.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_PROTOCOL_VIOLATION_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_PROTOCOL_VIOLATION_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.13
|
||||
struct ProtocolViolationCauseConfig : public ParameterConfig {
|
||||
static constexpr int kType = 13;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class ProtocolViolationCause : public Parameter,
|
||||
public TLVTrait<ProtocolViolationCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType = ProtocolViolationCauseConfig::kType;
|
||||
|
||||
explicit ProtocolViolationCause(absl::string_view additional_information)
|
||||
: additional_information_(additional_information) {}
|
||||
|
||||
static absl::optional<ProtocolViolationCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
absl::string_view additional_information() const {
|
||||
return additional_information_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string additional_information_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_PROTOCOL_VIOLATION_CAUSE_H_
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/protocol_violation_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::SizeIs;
|
||||
|
||||
TEST(ProtocolViolationCauseTest, EmptyReason) {
|
||||
Parameters causes =
|
||||
Parameters::Builder().Add(ProtocolViolationCause("")).Build();
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(Parameters deserialized,
|
||||
Parameters::Parse(causes.data()));
|
||||
ASSERT_THAT(deserialized.descriptors(), SizeIs(1));
|
||||
EXPECT_EQ(deserialized.descriptors()[0].type, ProtocolViolationCause::kType);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
ProtocolViolationCause cause,
|
||||
ProtocolViolationCause::Parse(deserialized.descriptors()[0].data));
|
||||
|
||||
EXPECT_EQ(cause.additional_information(), "");
|
||||
}
|
||||
|
||||
TEST(ProtocolViolationCauseTest, SetReason) {
|
||||
Parameters causes = Parameters::Builder()
|
||||
.Add(ProtocolViolationCause("Reason goes here"))
|
||||
.Build();
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(Parameters deserialized,
|
||||
Parameters::Parse(causes.data()));
|
||||
ASSERT_THAT(deserialized.descriptors(), SizeIs(1));
|
||||
EXPECT_EQ(deserialized.descriptors()[0].type, ProtocolViolationCause::kType);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
ProtocolViolationCause cause,
|
||||
ProtocolViolationCause::Parse(deserialized.descriptors()[0].data));
|
||||
|
||||
EXPECT_EQ(cause.additional_information(), "Reason goes here");
|
||||
}
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.11
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=11 | Cause Length=Variable |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// / New Address TLVs /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int RestartOfAnAssociationWithNewAddressesCause::kType;
|
||||
|
||||
absl::optional<RestartOfAnAssociationWithNewAddressesCause>
|
||||
RestartOfAnAssociationWithNewAddressesCause::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return RestartOfAnAssociationWithNewAddressesCause(reader->variable_data());
|
||||
}
|
||||
|
||||
void RestartOfAnAssociationWithNewAddressesCause::SerializeTo(
|
||||
std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer =
|
||||
AllocateTLV(out, new_address_tlvs_.size());
|
||||
writer.CopyToVariableData(new_address_tlvs_);
|
||||
}
|
||||
|
||||
std::string RestartOfAnAssociationWithNewAddressesCause::ToString() const {
|
||||
return "Restart of an Association with New Addresses";
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESS_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESS_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.11
|
||||
struct RestartOfAnAssociationWithNewAddressesCauseConfig
|
||||
: public ParameterConfig {
|
||||
static constexpr int kType = 11;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class RestartOfAnAssociationWithNewAddressesCause
|
||||
: public Parameter,
|
||||
public TLVTrait<RestartOfAnAssociationWithNewAddressesCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType =
|
||||
RestartOfAnAssociationWithNewAddressesCauseConfig::kType;
|
||||
|
||||
explicit RestartOfAnAssociationWithNewAddressesCause(
|
||||
rtc::ArrayView<const uint8_t> new_address_tlvs)
|
||||
: new_address_tlvs_(new_address_tlvs.begin(), new_address_tlvs.end()) {}
|
||||
|
||||
static absl::optional<RestartOfAnAssociationWithNewAddressesCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
rtc::ArrayView<const uint8_t> new_address_tlvs() const {
|
||||
return new_address_tlvs_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> new_address_tlvs_;
|
||||
};
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESS_CAUSE_H_
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(RestartOfAnAssociationWithNewAddressesCauseTest, SerializeAndDeserialize) {
|
||||
uint8_t data[] = {1, 2, 3};
|
||||
RestartOfAnAssociationWithNewAddressesCause parameter(data);
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
RestartOfAnAssociationWithNewAddressesCause deserialized,
|
||||
RestartOfAnAssociationWithNewAddressesCause::Parse(serialized));
|
||||
|
||||
EXPECT_THAT(deserialized.new_address_tlvs(), ElementsAre(1, 2, 3));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
57
net/dcsctp/packet/error_cause/stale_cookie_error_cause.cc
Normal file
57
net/dcsctp/packet/error_cause/stale_cookie_error_cause.cc
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/stale_cookie_error_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.3
|
||||
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=3 | Cause Length=8 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Measure of Staleness (usec.) |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int StaleCookieErrorCause::kType;
|
||||
|
||||
absl::optional<StaleCookieErrorCause> StaleCookieErrorCause::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
uint32_t staleness_us = reader->Load32<4>();
|
||||
return StaleCookieErrorCause(staleness_us);
|
||||
}
|
||||
|
||||
void StaleCookieErrorCause::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
|
||||
writer.Store32<4>(staleness_us_);
|
||||
}
|
||||
|
||||
std::string StaleCookieErrorCause::ToString() const {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "Stale Cookie Error, staleness_us=" << staleness_us_;
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
54
net/dcsctp/packet/error_cause/stale_cookie_error_cause.h
Normal file
54
net/dcsctp/packet/error_cause/stale_cookie_error_cause.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_STALE_COOKIE_ERROR_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_STALE_COOKIE_ERROR_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.3
|
||||
struct StaleCookieParameterConfig : public ParameterConfig {
|
||||
static constexpr int kType = 3;
|
||||
static constexpr size_t kHeaderSize = 8;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class StaleCookieErrorCause : public Parameter,
|
||||
public TLVTrait<StaleCookieParameterConfig> {
|
||||
public:
|
||||
static constexpr int kType = StaleCookieParameterConfig::kType;
|
||||
|
||||
explicit StaleCookieErrorCause(uint32_t staleness_us)
|
||||
: staleness_us_(staleness_us) {}
|
||||
|
||||
static absl::optional<StaleCookieErrorCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
uint16_t staleness_us() const { return staleness_us_; }
|
||||
|
||||
private:
|
||||
uint32_t staleness_us_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_STALE_COOKIE_ERROR_CAUSE_H_
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/stale_cookie_error_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
|
||||
TEST(StaleCookieErrorCauseTest, SerializeAndDeserialize) {
|
||||
StaleCookieErrorCause parameter(123);
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(StaleCookieErrorCause deserialized,
|
||||
StaleCookieErrorCause::Parse(serialized));
|
||||
|
||||
EXPECT_EQ(deserialized.staleness_us(), 123);
|
||||
}
|
||||
} // namespace
|
||||
} // 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.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.6
|
||||
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=6 | Cause Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// / Unrecognized Chunk /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int UnrecognizedChunkTypeCause::kType;
|
||||
|
||||
absl::optional<UnrecognizedChunkTypeCause> UnrecognizedChunkTypeCause::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
std::vector<uint8_t> unrecognized_chunk(reader->variable_data().begin(),
|
||||
reader->variable_data().end());
|
||||
return UnrecognizedChunkTypeCause(std::move(unrecognized_chunk));
|
||||
}
|
||||
|
||||
void UnrecognizedChunkTypeCause::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer =
|
||||
AllocateTLV(out, unrecognized_chunk_.size());
|
||||
writer.CopyToVariableData(unrecognized_chunk_);
|
||||
}
|
||||
|
||||
std::string UnrecognizedChunkTypeCause::ToString() const {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "Unrecognized Chunk Type, chunk_type=";
|
||||
if (!unrecognized_chunk_.empty()) {
|
||||
sb << static_cast<int>(unrecognized_chunk_[0]);
|
||||
} else {
|
||||
sb << "<missing>";
|
||||
}
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_CHUNK_TYPE_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_CHUNK_TYPE_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.6
|
||||
struct UnrecognizedChunkTypeCauseConfig : public ParameterConfig {
|
||||
static constexpr int kType = 6;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class UnrecognizedChunkTypeCause
|
||||
: public Parameter,
|
||||
public TLVTrait<UnrecognizedChunkTypeCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType = UnrecognizedChunkTypeCauseConfig::kType;
|
||||
|
||||
explicit UnrecognizedChunkTypeCause(std::vector<uint8_t> unrecognized_chunk)
|
||||
: unrecognized_chunk_(std::move(unrecognized_chunk)) {}
|
||||
|
||||
static absl::optional<UnrecognizedChunkTypeCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
rtc::ArrayView<const uint8_t> unrecognized_chunk() const {
|
||||
return unrecognized_chunk_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> unrecognized_chunk_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_CHUNK_TYPE_CAUSE_H_
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(UnrecognizedChunkTypeCauseTest, SerializeAndDeserialize) {
|
||||
UnrecognizedChunkTypeCause parameter({1, 2, 3});
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(UnrecognizedChunkTypeCause deserialized,
|
||||
UnrecognizedChunkTypeCause::Parse(serialized));
|
||||
|
||||
EXPECT_THAT(deserialized.unrecognized_chunk(), ElementsAre(1, 2, 3));
|
||||
}
|
||||
} // namespace
|
||||
} // 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.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.8
|
||||
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=8 | Cause Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// / Unrecognized Parameters /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int UnrecognizedParametersCause::kType;
|
||||
|
||||
absl::optional<UnrecognizedParametersCause> UnrecognizedParametersCause::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return UnrecognizedParametersCause(reader->variable_data());
|
||||
}
|
||||
|
||||
void UnrecognizedParametersCause::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer =
|
||||
AllocateTLV(out, unrecognized_parameters_.size());
|
||||
writer.CopyToVariableData(unrecognized_parameters_);
|
||||
}
|
||||
|
||||
std::string UnrecognizedParametersCause::ToString() const {
|
||||
return "Unrecognized Parameters";
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
60
net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h
Normal file
60
net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_PARAMETER_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_PARAMETER_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.8
|
||||
struct UnrecognizedParametersCauseConfig : public ParameterConfig {
|
||||
static constexpr int kType = 8;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class UnrecognizedParametersCause
|
||||
: public Parameter,
|
||||
public TLVTrait<UnrecognizedParametersCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType = UnrecognizedParametersCauseConfig::kType;
|
||||
|
||||
explicit UnrecognizedParametersCause(
|
||||
rtc::ArrayView<const uint8_t> unrecognized_parameters)
|
||||
: unrecognized_parameters_(unrecognized_parameters.begin(),
|
||||
unrecognized_parameters.end()) {}
|
||||
|
||||
static absl::optional<UnrecognizedParametersCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
rtc::ArrayView<const uint8_t> unrecognized_parameters() const {
|
||||
return unrecognized_parameters_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> unrecognized_parameters_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_UNRECOGNIZED_PARAMETER_CAUSE_H_
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(UnrecognizedParametersCauseTest, SerializeAndDeserialize) {
|
||||
uint8_t unrecognized_parameters[] = {1, 2, 3};
|
||||
UnrecognizedParametersCause parameter(unrecognized_parameters);
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(UnrecognizedParametersCause deserialized,
|
||||
UnrecognizedParametersCause::Parse(serialized));
|
||||
|
||||
EXPECT_THAT(deserialized.unrecognized_parameters(), ElementsAre(1, 2, 3));
|
||||
}
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
53
net/dcsctp/packet/error_cause/unresolvable_address_cause.cc
Normal file
53
net/dcsctp/packet/error_cause/unresolvable_address_cause.cc
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/unresolvable_address_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.5
|
||||
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=5 | Cause Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// / Unresolvable Address /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int UnresolvableAddressCause::kType;
|
||||
|
||||
absl::optional<UnresolvableAddressCause> UnresolvableAddressCause::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
return UnresolvableAddressCause(reader->variable_data());
|
||||
}
|
||||
|
||||
void UnresolvableAddressCause::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer =
|
||||
AllocateTLV(out, unresolvable_address_.size());
|
||||
writer.CopyToVariableData(unresolvable_address_);
|
||||
}
|
||||
|
||||
std::string UnresolvableAddressCause::ToString() const {
|
||||
return "Unresolvable Address";
|
||||
}
|
||||
} // namespace dcsctp
|
60
net/dcsctp/packet/error_cause/unresolvable_address_cause.h
Normal file
60
net/dcsctp/packet/error_cause/unresolvable_address_cause.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_UNRESOLVABLE_ADDRESS_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_UNRESOLVABLE_ADDRESS_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.5
|
||||
struct UnresolvableAddressCauseConfig : public ParameterConfig {
|
||||
static constexpr int kType = 5;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class UnresolvableAddressCause
|
||||
: public Parameter,
|
||||
public TLVTrait<UnresolvableAddressCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType = UnresolvableAddressCauseConfig::kType;
|
||||
|
||||
explicit UnresolvableAddressCause(
|
||||
rtc::ArrayView<const uint8_t> unresolvable_address)
|
||||
: unresolvable_address_(unresolvable_address.begin(),
|
||||
unresolvable_address.end()) {}
|
||||
|
||||
static absl::optional<UnresolvableAddressCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
rtc::ArrayView<const uint8_t> unresolvable_address() const {
|
||||
return unresolvable_address_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> unresolvable_address_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_UNRESOLVABLE_ADDRESS_CAUSE_H_
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/unresolvable_address_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(UnresolvableAddressCauseTest, SerializeAndDeserialize) {
|
||||
uint8_t unresolvable_address[] = {1, 2, 3};
|
||||
UnresolvableAddressCause parameter(unresolvable_address);
|
||||
|
||||
std::vector<uint8_t> serialized;
|
||||
parameter.SerializeTo(serialized);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(UnresolvableAddressCause deserialized,
|
||||
UnresolvableAddressCause::Parse(serialized));
|
||||
|
||||
EXPECT_THAT(deserialized.unresolvable_address(), ElementsAre(1, 2, 3));
|
||||
}
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
67
net/dcsctp/packet/error_cause/user_initiated_abort_cause.cc
Normal file
67
net/dcsctp/packet/error_cause/user_initiated_abort_cause.cc
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/error_cause/user_initiated_abort_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.12
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cause Code=12 | Cause Length=Variable |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// / Upper Layer Abort Reason /
|
||||
// \ \
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int UserInitiatedAbortCause::kType;
|
||||
|
||||
absl::optional<UserInitiatedAbortCause> UserInitiatedAbortCause::Parse(
|
||||
rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
if (reader->variable_data().empty()) {
|
||||
return UserInitiatedAbortCause("");
|
||||
}
|
||||
return UserInitiatedAbortCause(
|
||||
std::string(reinterpret_cast<const char*>(reader->variable_data().data()),
|
||||
reader->variable_data().size()));
|
||||
}
|
||||
|
||||
void UserInitiatedAbortCause::SerializeTo(std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer =
|
||||
AllocateTLV(out, upper_layer_abort_reason_.size());
|
||||
writer.CopyToVariableData(rtc::MakeArrayView(
|
||||
reinterpret_cast<const uint8_t*>(upper_layer_abort_reason_.data()),
|
||||
upper_layer_abort_reason_.size()));
|
||||
}
|
||||
|
||||
std::string UserInitiatedAbortCause::ToString() const {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "User-Initiated Abort, reason=" << upper_layer_abort_reason_;
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
56
net/dcsctp/packet/error_cause/user_initiated_abort_cause.h
Normal file
56
net/dcsctp/packet/error_cause/user_initiated_abort_cause.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_ERROR_CAUSE_USER_INITIATED_ABORT_CAUSE_H_
|
||||
#define NET_DCSCTP_PACKET_ERROR_CAUSE_USER_INITIATED_ABORT_CAUSE_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc4960#section-3.3.10.12
|
||||
struct UserInitiatedAbortCauseConfig : public ParameterConfig {
|
||||
static constexpr int kType = 12;
|
||||
static constexpr size_t kHeaderSize = 4;
|
||||
static constexpr size_t kVariableLengthAlignment = 1;
|
||||
};
|
||||
|
||||
class UserInitiatedAbortCause : public Parameter,
|
||||
public TLVTrait<UserInitiatedAbortCauseConfig> {
|
||||
public:
|
||||
static constexpr int kType = UserInitiatedAbortCauseConfig::kType;
|
||||
|
||||
explicit UserInitiatedAbortCause(absl::string_view upper_layer_abort_reason)
|
||||
: upper_layer_abort_reason_(upper_layer_abort_reason) {}
|
||||
|
||||
static absl::optional<UserInitiatedAbortCause> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
absl::string_view upper_layer_abort_reason() const {
|
||||
return upper_layer_abort_reason_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string upper_layer_abort_reason_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_ERROR_CAUSE_USER_INITIATED_ABORT_CAUSE_H_
|
@ -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/error_cause/user_initiated_abort_cause.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/packet/error_cause/error_cause.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "net/dcsctp/testing/testing_macros.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace dcsctp {
|
||||
namespace {
|
||||
using ::testing::SizeIs;
|
||||
|
||||
TEST(UserInitiatedAbortCauseTest, EmptyReason) {
|
||||
Parameters causes =
|
||||
Parameters::Builder().Add(UserInitiatedAbortCause("")).Build();
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(Parameters deserialized,
|
||||
Parameters::Parse(causes.data()));
|
||||
ASSERT_THAT(deserialized.descriptors(), SizeIs(1));
|
||||
EXPECT_EQ(deserialized.descriptors()[0].type, UserInitiatedAbortCause::kType);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
UserInitiatedAbortCause cause,
|
||||
UserInitiatedAbortCause::Parse(deserialized.descriptors()[0].data));
|
||||
|
||||
EXPECT_EQ(cause.upper_layer_abort_reason(), "");
|
||||
}
|
||||
|
||||
TEST(UserInitiatedAbortCauseTest, SetReason) {
|
||||
Parameters causes = Parameters::Builder()
|
||||
.Add(UserInitiatedAbortCause("User called Close"))
|
||||
.Build();
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(Parameters deserialized,
|
||||
Parameters::Parse(causes.data()));
|
||||
ASSERT_THAT(deserialized.descriptors(), SizeIs(1));
|
||||
EXPECT_EQ(deserialized.descriptors()[0].type, UserInitiatedAbortCause::kType);
|
||||
|
||||
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||
UserInitiatedAbortCause cause,
|
||||
UserInitiatedAbortCause::Parse(deserialized.descriptors()[0].data));
|
||||
|
||||
EXPECT_EQ(cause.upper_layer_abort_reason(), "User called Close");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace dcsctp
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/common/internal_types.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc6525#section-4.6
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Parameter Type = 18 | Parameter Length = 12 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Re-configuration Request Sequence Number |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Number of new streams | Reserved |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
constexpr int AddIncomingStreamsRequestParameter::kType;
|
||||
|
||||
absl::optional<AddIncomingStreamsRequestParameter>
|
||||
AddIncomingStreamsRequestParameter::Parse(rtc::ArrayView<const uint8_t> data) {
|
||||
absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
|
||||
if (!reader.has_value()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
ReconfigRequestSN request_sequence_number(reader->Load32<4>());
|
||||
uint16_t nbr_of_new_streams = reader->Load16<8>();
|
||||
|
||||
return AddIncomingStreamsRequestParameter(request_sequence_number,
|
||||
nbr_of_new_streams);
|
||||
}
|
||||
|
||||
void AddIncomingStreamsRequestParameter::SerializeTo(
|
||||
std::vector<uint8_t>& out) const {
|
||||
BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out);
|
||||
writer.Store32<4>(*request_sequence_number_);
|
||||
writer.Store16<8>(nbr_of_new_streams_);
|
||||
}
|
||||
|
||||
std::string AddIncomingStreamsRequestParameter::ToString() const {
|
||||
rtc::StringBuilder sb;
|
||||
sb << "Add Incoming Streams Request, req_seq_nbr="
|
||||
<< *request_sequence_number();
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
} // namespace dcsctp
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef NET_DCSCTP_PACKET_PARAMETER_ADD_INCOMING_STREAMS_REQUEST_PARAMETER_H_
|
||||
#define NET_DCSCTP_PACKET_PARAMETER_ADD_INCOMING_STREAMS_REQUEST_PARAMETER_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "net/dcsctp/common/internal_types.h"
|
||||
#include "net/dcsctp/packet/parameter/parameter.h"
|
||||
#include "net/dcsctp/packet/tlv_trait.h"
|
||||
|
||||
namespace dcsctp {
|
||||
|
||||
// https://tools.ietf.org/html/rfc6525#section-4.6
|
||||
struct AddIncomingStreamsRequestParameterConfig : ParameterConfig {
|
||||
static constexpr int kType = 18;
|
||||
static constexpr size_t kHeaderSize = 12;
|
||||
static constexpr size_t kVariableLengthAlignment = 0;
|
||||
};
|
||||
|
||||
class AddIncomingStreamsRequestParameter
|
||||
: public Parameter,
|
||||
public TLVTrait<AddIncomingStreamsRequestParameterConfig> {
|
||||
public:
|
||||
static constexpr int kType = AddIncomingStreamsRequestParameterConfig::kType;
|
||||
|
||||
explicit AddIncomingStreamsRequestParameter(
|
||||
ReconfigRequestSN request_sequence_number,
|
||||
uint16_t nbr_of_new_streams)
|
||||
: request_sequence_number_(request_sequence_number),
|
||||
nbr_of_new_streams_(nbr_of_new_streams) {}
|
||||
|
||||
static absl::optional<AddIncomingStreamsRequestParameter> Parse(
|
||||
rtc::ArrayView<const uint8_t> data);
|
||||
|
||||
void SerializeTo(std::vector<uint8_t>& out) const override;
|
||||
std::string ToString() const override;
|
||||
|
||||
ReconfigRequestSN request_sequence_number() const {
|
||||
return request_sequence_number_;
|
||||
}
|
||||
uint16_t nbr_of_new_streams() const { return nbr_of_new_streams_; }
|
||||
|
||||
private:
|
||||
ReconfigRequestSN request_sequence_number_;
|
||||
uint16_t nbr_of_new_streams_;
|
||||
};
|
||||
|
||||
} // namespace dcsctp
|
||||
|
||||
#endif // NET_DCSCTP_PACKET_PARAMETER_ADD_INCOMING_STREAMS_REQUEST_PARAMETER_H_
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user