blob: 3c77628ec73914132dcd7184f304fe611965802b [file] [log] [blame] [edit]
// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "quiche/quic/core/quic_packets.h"
#include <memory>
#include <string>
#include "absl/memory/memory.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
#include "quiche/common/test_tools/quiche_test_utils.h"
namespace quic {
namespace test {
namespace {
QuicPacketHeader CreateFakePacketHeader() {
QuicPacketHeader header;
header.destination_connection_id = TestConnectionId(1);
header.destination_connection_id_included = CONNECTION_ID_PRESENT;
header.source_connection_id = TestConnectionId(2);
header.source_connection_id_included = CONNECTION_ID_ABSENT;
return header;
}
class QuicPacketsTest : public QuicTest {};
TEST_F(QuicPacketsTest, GetServerConnectionIdAsRecipient) {
QuicPacketHeader header = CreateFakePacketHeader();
EXPECT_EQ(TestConnectionId(1),
GetServerConnectionIdAsRecipient(header, Perspective::IS_SERVER));
EXPECT_EQ(TestConnectionId(2),
GetServerConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
}
TEST_F(QuicPacketsTest, GetServerConnectionIdAsSender) {
QuicPacketHeader header = CreateFakePacketHeader();
EXPECT_EQ(TestConnectionId(2),
GetServerConnectionIdAsSender(header, Perspective::IS_SERVER));
EXPECT_EQ(TestConnectionId(1),
GetServerConnectionIdAsSender(header, Perspective::IS_CLIENT));
}
TEST_F(QuicPacketsTest, GetServerConnectionIdIncludedAsSender) {
QuicPacketHeader header = CreateFakePacketHeader();
EXPECT_EQ(CONNECTION_ID_ABSENT, GetServerConnectionIdIncludedAsSender(
header, Perspective::IS_SERVER));
EXPECT_EQ(CONNECTION_ID_PRESENT, GetServerConnectionIdIncludedAsSender(
header, Perspective::IS_CLIENT));
}
TEST_F(QuicPacketsTest, GetClientConnectionIdIncludedAsSender) {
QuicPacketHeader header = CreateFakePacketHeader();
EXPECT_EQ(CONNECTION_ID_PRESENT, GetClientConnectionIdIncludedAsSender(
header, Perspective::IS_SERVER));
EXPECT_EQ(CONNECTION_ID_ABSENT, GetClientConnectionIdIncludedAsSender(
header, Perspective::IS_CLIENT));
}
TEST_F(QuicPacketsTest, GetClientConnectionIdAsRecipient) {
QuicPacketHeader header = CreateFakePacketHeader();
EXPECT_EQ(TestConnectionId(2),
GetClientConnectionIdAsRecipient(header, Perspective::IS_SERVER));
EXPECT_EQ(TestConnectionId(1),
GetClientConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
}
TEST_F(QuicPacketsTest, GetClientConnectionIdAsSender) {
QuicPacketHeader header = CreateFakePacketHeader();
EXPECT_EQ(TestConnectionId(1),
GetClientConnectionIdAsSender(header, Perspective::IS_SERVER));
EXPECT_EQ(TestConnectionId(2),
GetClientConnectionIdAsSender(header, Perspective::IS_CLIENT));
}
TEST_F(QuicPacketsTest, CopyQuicPacketHeader) {
QuicPacketHeader header;
QuicPacketHeader header2 = CreateFakePacketHeader();
EXPECT_NE(header, header2);
QuicPacketHeader header3(header2);
EXPECT_EQ(header2, header3);
}
TEST_F(QuicPacketsTest, CopySerializedPacket) {
std::string buffer(1000, 'a');
quiche::SimpleBufferAllocator allocator;
SerializedPacket packet(QuicPacketNumber(1), PACKET_1BYTE_PACKET_NUMBER,
buffer.data(), buffer.length(), /*has_ack=*/false,
/*has_stop_waiting=*/false);
packet.retransmittable_frames.push_back(QuicFrame(QuicWindowUpdateFrame()));
packet.retransmittable_frames.push_back(QuicFrame(QuicStreamFrame()));
QuicAckFrame ack_frame(InitAckFrame(1));
packet.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
packet.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
std::unique_ptr<SerializedPacket> copy = absl::WrapUnique<SerializedPacket>(
CopySerializedPacket(packet, &allocator, /*copy_buffer=*/true));
EXPECT_EQ(quic::QuicPacketNumber(1), copy->packet_number);
EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, copy->packet_number_length);
ASSERT_EQ(2u, copy->retransmittable_frames.size());
EXPECT_EQ(WINDOW_UPDATE_FRAME, copy->retransmittable_frames[0].type);
EXPECT_EQ(STREAM_FRAME, copy->retransmittable_frames[1].type);
ASSERT_EQ(2u, copy->nonretransmittable_frames.size());
EXPECT_EQ(ACK_FRAME, copy->nonretransmittable_frames[0].type);
EXPECT_EQ(PADDING_FRAME, copy->nonretransmittable_frames[1].type);
EXPECT_EQ(1000u, copy->encrypted_length);
quiche::test::CompareCharArraysWithHexError(
"encrypted_buffer", copy->encrypted_buffer, copy->encrypted_length,
packet.encrypted_buffer, packet.encrypted_length);
std::unique_ptr<SerializedPacket> copy2 = absl::WrapUnique<SerializedPacket>(
CopySerializedPacket(packet, &allocator, /*copy_buffer=*/false));
EXPECT_EQ(packet.encrypted_buffer, copy2->encrypted_buffer);
EXPECT_EQ(1000u, copy2->encrypted_length);
}
TEST_F(QuicPacketsTest, CloneReceivedPacket) {
char header[4] = "bar";
QuicReceivedPacket packet("foo", 3, QuicTime::Zero(), false, 0, true, header,
sizeof(header) - 1, false,
QuicEcnCodepoint::ECN_ECT1);
std::unique_ptr<QuicReceivedPacket> copy = packet.Clone();
EXPECT_EQ(packet.ecn_codepoint(), copy->ecn_codepoint());
}
TEST_F(QuicPacketsTest, NoFlowLabelByDefault) {
char header[4] = "bar";
QuicReceivedPacket packet("foo", 3, QuicTime::Zero(), false, 0, true, header,
sizeof(header) - 1, false,
QuicEcnCodepoint::ECN_ECT1);
EXPECT_EQ(0, packet.ipv6_flow_label());
}
TEST_F(QuicPacketsTest, ExplicitFlowLabel) {
char header[4] = "bar";
QuicReceivedPacket packet("foo", 3, QuicTime::Zero(), false, 0, true, header,
sizeof(header) - 1, false,
QuicEcnCodepoint::ECN_ECT1, 42);
EXPECT_EQ(42, packet.ipv6_flow_label());
}
} // namespace
} // namespace test
} // namespace quic