blob: 3dd9b24a4a44b90344e72a5f9b61fe1194560bcc [file] [log] [blame]
fayang503ca4f2019-10-23 07:20:51 -07001// Copyright (c) 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/quic_coalesced_packet.h"
6
7#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
8#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
9
10namespace quic {
11
12QuicCoalescedPacket::QuicCoalescedPacket()
13 : length_(0), max_packet_length_(0) {}
14
15QuicCoalescedPacket::~QuicCoalescedPacket() {
16 Clear();
17}
18
19bool QuicCoalescedPacket::MaybeCoalescePacket(
20 const SerializedPacket& packet,
21 const QuicSocketAddress& self_address,
22 const QuicSocketAddress& peer_address,
23 QuicBufferAllocator* allocator,
24 QuicPacketLength current_max_packet_length) {
25 if (packet.encrypted_length == 0) {
26 QUIC_BUG << "Trying to coalesce an empty packet";
27 return true;
28 }
29 if (length_ == 0) {
30#ifndef NDEBUG
31 for (const auto& buffer : encrypted_buffers_) {
32 DCHECK(buffer.empty());
33 }
34#endif
35 DCHECK(initial_packet_ == nullptr);
36 // This is the first packet, set max_packet_length and self/peer
37 // addresses.
38 max_packet_length_ = current_max_packet_length;
39 self_address_ = self_address;
40 peer_address_ = peer_address;
41 } else {
42 if (self_address_ != self_address || peer_address_ != peer_address) {
43 // Do not coalesce packet with different self/peer addresses.
44 QUIC_DLOG(INFO)
45 << "Cannot coalesce packet because self/peer address changed";
46 return false;
47 }
48 if (max_packet_length_ != current_max_packet_length) {
fayang58f71072019-11-05 08:47:02 -080049 QUIC_BUG << "Max packet length changes in the middle of the write path";
fayang503ca4f2019-10-23 07:20:51 -070050 return false;
51 }
52 if (!encrypted_buffers_[packet.encryption_level].empty() ||
53 (packet.encryption_level == ENCRYPTION_INITIAL &&
54 initial_packet_ != nullptr)) {
55 // Do not coalesce packets of the same encryption level.
56 return false;
57 }
58 }
59
fayang503ca4f2019-10-23 07:20:51 -070060 if (length_ + packet.encrypted_length > max_packet_length_) {
61 // Packet does not fit.
62 return false;
63 }
fayang08750832019-10-24 11:25:34 -070064 QUIC_DVLOG(1) << "Successfully coalesced packet: encryption_level: "
65 << EncryptionLevelToString(packet.encryption_level)
66 << ", encrypted_length: " << packet.encrypted_length
67 << ", current length: " << length_
68 << ", max_packet_length: " << max_packet_length_;
fayang58f71072019-11-05 08:47:02 -080069 if (length_ > 0) {
70 QUIC_CODE_COUNT(QUIC_SUCCESSFULLY_COALESCED_MULTIPLE_PACKETS);
71 }
fayang503ca4f2019-10-23 07:20:51 -070072 length_ += packet.encrypted_length;
73 if (packet.encryption_level == ENCRYPTION_INITIAL) {
74 // Save a copy of ENCRYPTION_INITIAL packet (excluding encrypted buffer, as
75 // the packet will be re-serialized later).
76 initial_packet_ = QuicWrapUnique<SerializedPacket>(
77 CopySerializedPacket(packet, allocator, /*copy_buffer=*/false));
78 return true;
79 }
80 // Copy encrypted buffer of packets with other encryption levels.
81 encrypted_buffers_[packet.encryption_level] =
82 std::string(packet.encrypted_buffer, packet.encrypted_length);
83 return true;
84}
85
86void QuicCoalescedPacket::Clear() {
87 self_address_ = QuicSocketAddress();
88 peer_address_ = QuicSocketAddress();
89 length_ = 0;
90 max_packet_length_ = 0;
91 for (auto& packet : encrypted_buffers_) {
92 packet.clear();
93 }
94 if (initial_packet_ != nullptr) {
95 ClearSerializedPacket(initial_packet_.get());
96 }
97 initial_packet_ = nullptr;
98}
99
fayang08750832019-10-24 11:25:34 -0700100bool QuicCoalescedPacket::CopyEncryptedBuffers(char* buffer,
101 size_t buffer_len,
102 size_t* length_copied) const {
103 *length_copied = 0;
104 for (const auto& packet : encrypted_buffers_) {
105 if (packet.empty()) {
106 continue;
107 }
108 if (packet.length() > buffer_len) {
109 return false;
110 }
111 memcpy(buffer, packet.data(), packet.length());
112 buffer += packet.length();
113 buffer_len -= packet.length();
114 *length_copied += packet.length();
115 }
116 return true;
117}
118
fayang503ca4f2019-10-23 07:20:51 -0700119} // namespace quic