Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(460)

Side by Side Diff: net/quic/quic_framer.cc

Issue 300623009: Fixes bugs in packet size computation in the creator and in the framer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_framer.h ('k') | net/quic/quic_framer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/quic_framer.h" 5 #include "net/quic/quic_framer.h"
6 6
7 #include "base/containers/hash_tables.h" 7 #include "base/containers/hash_tables.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "net/quic/crypto/crypto_framer.h" 9 #include "net/quic/crypto/crypto_framer.h"
10 #include "net/quic/crypto/crypto_handshake_message.h" 10 #include "net/quic/crypto/crypto_handshake_message.h"
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 return kQuicFrameTypeSize + GetStreamIdSize(stream_id) + 191 return kQuicFrameTypeSize + GetStreamIdSize(stream_id) +
192 GetStreamOffsetSize(offset) + 192 GetStreamOffsetSize(offset) +
193 (no_stream_frame_length ? 0 : kQuicStreamPayloadLengthSize); 193 (no_stream_frame_length ? 0 : kQuicStreamPayloadLengthSize);
194 } 194 }
195 195
196 // static 196 // static
197 size_t QuicFramer::GetMinAckFrameSize( 197 size_t QuicFramer::GetMinAckFrameSize(
198 QuicVersion version, 198 QuicVersion version,
199 QuicSequenceNumberLength sequence_number_length, 199 QuicSequenceNumberLength sequence_number_length,
200 QuicSequenceNumberLength largest_observed_length) { 200 QuicSequenceNumberLength largest_observed_length) {
201 return kQuicFrameTypeSize + kQuicEntropyHashSize + 201 size_t len = kQuicFrameTypeSize + kQuicEntropyHashSize +
202 sequence_number_length + kQuicEntropyHashSize +
203 largest_observed_length + kQuicDeltaTimeLargestObservedSize; 202 largest_observed_length + kQuicDeltaTimeLargestObservedSize;
203 if (version <= QUIC_VERSION_15) {
204 len += sequence_number_length + kQuicEntropyHashSize;
205 }
206 return len;
204 } 207 }
205 208
206 // static 209 // static
207 size_t QuicFramer::GetStopWaitingFrameSize( 210 size_t QuicFramer::GetStopWaitingFrameSize(
208 QuicSequenceNumberLength sequence_number_length) { 211 QuicSequenceNumberLength sequence_number_length) {
209 return kQuicFrameTypeSize + kQuicEntropyHashSize + 212 return kQuicFrameTypeSize + kQuicEntropyHashSize +
210 sequence_number_length; 213 sequence_number_length;
211 } 214 }
212 215
213 // static 216 // static
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 bool last_frame, 294 bool last_frame,
292 InFecGroup is_in_fec_group, 295 InFecGroup is_in_fec_group,
293 QuicSequenceNumberLength sequence_number_length) { 296 QuicSequenceNumberLength sequence_number_length) {
294 if (frame.type == PADDING_FRAME) { 297 if (frame.type == PADDING_FRAME) {
295 // PADDING implies end of packet. 298 // PADDING implies end of packet.
296 return free_bytes; 299 return free_bytes;
297 } 300 }
298 size_t frame_len = 301 size_t frame_len =
299 ComputeFrameLength(frame, last_frame, is_in_fec_group, 302 ComputeFrameLength(frame, last_frame, is_in_fec_group,
300 sequence_number_length); 303 sequence_number_length);
301 if (frame_len > free_bytes) { 304 if (frame_len <= free_bytes) {
302 // Only truncate the first frame in a packet, so if subsequent ones go 305 // Frame fits within packet. Note that acks may be truncated.
303 // over, stop including more frames. 306 return frame_len;
304 if (!first_frame) {
305 return 0;
306 }
307 if (CanTruncate(quic_version_, frame, free_bytes)) {
308 // Truncate the frame so the packet will not exceed kMaxPacketSize.
309 // Note that we may not use every byte of the writer in this case.
310 DVLOG(1) << "Truncating large frame";
311 return free_bytes;
312 } else if (!FLAGS_quic_allow_oversized_packets_for_test) {
313 return 0;
314 }
315 } 307 }
308 // Only truncate the first frame in a packet, so if subsequent ones go
309 // over, stop including more frames.
310 if (!first_frame) {
311 return 0;
312 }
313 if (CanTruncate(quic_version_, frame, free_bytes)) {
314 // Truncate the frame so the packet will not exceed kMaxPacketSize.
315 // Note that we may not use every byte of the writer in this case.
316 DVLOG(1) << "Truncating large frame, free bytes: " << free_bytes;
317 return free_bytes;
318 }
319 if (!FLAGS_quic_allow_oversized_packets_for_test) {
320 return 0;
321 }
322 LOG(DFATAL) << "Packet size too small to fit frame.";
316 return frame_len; 323 return frame_len;
317 } 324 }
318 325
319 QuicFramer::AckFrameInfo::AckFrameInfo() : max_delta(0) { } 326 QuicFramer::AckFrameInfo::AckFrameInfo() : max_delta(0) { }
320 327
321 QuicFramer::AckFrameInfo::~AckFrameInfo() { } 328 QuicFramer::AckFrameInfo::~AckFrameInfo() { }
322 329
323 QuicPacketEntropyHash QuicFramer::GetPacketEntropyHash( 330 QuicPacketEntropyHash QuicFramer::GetPacketEntropyHash(
324 const QuicPacketHeader& header) const { 331 const QuicPacketHeader& header) const {
325 return header.entropy_flag << (header.packet_sequence_number % 8); 332 return header.entropy_flag << (header.packet_sequence_number % 8);
(...skipping 1485 matching lines...) Expand 10 before | Expand all | Expand 10 after
1811 AckFrameInfo ack_info = GetAckFrameInfo(ack); 1818 AckFrameInfo ack_info = GetAckFrameInfo(ack);
1812 QuicSequenceNumberLength largest_observed_length = 1819 QuicSequenceNumberLength largest_observed_length =
1813 GetMinSequenceNumberLength(ack.received_info.largest_observed); 1820 GetMinSequenceNumberLength(ack.received_info.largest_observed);
1814 QuicSequenceNumberLength missing_sequence_number_length = 1821 QuicSequenceNumberLength missing_sequence_number_length =
1815 GetMinSequenceNumberLength(ack_info.max_delta); 1822 GetMinSequenceNumberLength(ack_info.max_delta);
1816 1823
1817 size_t ack_size = GetMinAckFrameSize(quic_version_, 1824 size_t ack_size = GetMinAckFrameSize(quic_version_,
1818 sequence_number_length, 1825 sequence_number_length,
1819 largest_observed_length); 1826 largest_observed_length);
1820 if (!ack_info.nack_ranges.empty()) { 1827 if (!ack_info.nack_ranges.empty()) {
1821 ack_size += kNumberOfMissingPacketsSize + kNumberOfRevivedPacketsSize; 1828 ack_size += kNumberOfNackRangesSize + kNumberOfRevivedPacketsSize;
1822 ack_size += ack_info.nack_ranges.size() * 1829 ack_size += min(ack_info.nack_ranges.size(), kMaxNackRanges) *
1823 (missing_sequence_number_length + PACKET_1BYTE_SEQUENCE_NUMBER); 1830 (missing_sequence_number_length + PACKET_1BYTE_SEQUENCE_NUMBER);
1824 ack_size += 1831 ack_size += min(ack.received_info.revived_packets.size(),
1825 ack.received_info.revived_packets.size() * largest_observed_length; 1832 kMaxRevivedPackets) * largest_observed_length;
1826 } 1833 }
1827 return ack_size; 1834 return ack_size;
1828 } 1835 }
1829 1836
1830 size_t QuicFramer::ComputeFrameLength( 1837 size_t QuicFramer::ComputeFrameLength(
1831 const QuicFrame& frame, 1838 const QuicFrame& frame,
1832 bool last_frame_in_packet, 1839 bool last_frame_in_packet,
1833 InFecGroup is_in_fec_group, 1840 InFecGroup is_in_fec_group,
1834 QuicSequenceNumberLength sequence_number_length) { 1841 QuicSequenceNumberLength sequence_number_length) {
1835 switch (frame.type) { 1842 switch (frame.type) {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 QuicDataWriter* writer) { 2028 QuicDataWriter* writer) {
2022 AckFrameInfo ack_info = GetAckFrameInfo(frame); 2029 AckFrameInfo ack_info = GetAckFrameInfo(frame);
2023 QuicPacketSequenceNumber ack_largest_observed = 2030 QuicPacketSequenceNumber ack_largest_observed =
2024 frame.received_info.largest_observed; 2031 frame.received_info.largest_observed;
2025 QuicSequenceNumberLength largest_observed_length = 2032 QuicSequenceNumberLength largest_observed_length =
2026 GetMinSequenceNumberLength(ack_largest_observed); 2033 GetMinSequenceNumberLength(ack_largest_observed);
2027 QuicSequenceNumberLength missing_sequence_number_length = 2034 QuicSequenceNumberLength missing_sequence_number_length =
2028 GetMinSequenceNumberLength(ack_info.max_delta); 2035 GetMinSequenceNumberLength(ack_info.max_delta);
2029 // Determine whether we need to truncate ranges. 2036 // Determine whether we need to truncate ranges.
2030 size_t available_range_bytes = writer->capacity() - writer->length() - 2037 size_t available_range_bytes = writer->capacity() - writer->length() -
2038 kNumberOfRevivedPacketsSize - kNumberOfNackRangesSize -
2031 GetMinAckFrameSize(quic_version_, 2039 GetMinAckFrameSize(quic_version_,
2032 header.public_header.sequence_number_length, 2040 header.public_header.sequence_number_length,
2033 largest_observed_length) - kNumberOfRevivedPacketsSize; 2041 largest_observed_length);
2034 size_t max_num_ranges = available_range_bytes / 2042 size_t max_num_ranges = available_range_bytes /
2035 (missing_sequence_number_length + PACKET_1BYTE_SEQUENCE_NUMBER); 2043 (missing_sequence_number_length + PACKET_1BYTE_SEQUENCE_NUMBER);
2036 max_num_ranges = 2044 max_num_ranges = min(kMaxNackRanges, max_num_ranges);
2037 min(static_cast<size_t>(numeric_limits<uint8>::max()), max_num_ranges);
2038 bool truncated = ack_info.nack_ranges.size() > max_num_ranges; 2045 bool truncated = ack_info.nack_ranges.size() > max_num_ranges;
2039 DVLOG_IF(1, truncated) << "Truncating ack from " 2046 DVLOG_IF(1, truncated) << "Truncating ack from "
2040 << ack_info.nack_ranges.size() << " ranges to " 2047 << ack_info.nack_ranges.size() << " ranges to "
2041 << max_num_ranges; 2048 << max_num_ranges;
2042
2043 // Write out the type byte by setting the low order bits and doing shifts 2049 // Write out the type byte by setting the low order bits and doing shifts
2044 // to make room for the next bit flags to be set. 2050 // to make room for the next bit flags to be set.
2045 // Whether there are any nacks. 2051 // Whether there are any nacks.
2046 uint8 type_byte = ack_info.nack_ranges.empty() ? 0 : kQuicHasNacksMask; 2052 uint8 type_byte = ack_info.nack_ranges.empty() ? 0 : kQuicHasNacksMask;
2047 2053
2048 // truncating bit. 2054 // truncating bit.
2049 type_byte <<= kQuicAckTruncatedShift; 2055 type_byte <<= kQuicAckTruncatedShift;
2050 type_byte |= truncated ? kQuicAckTruncatedMask : 0; 2056 type_byte |= truncated ? kQuicAckTruncatedMask : 0;
2051 2057
2052 // Largest observed sequence number length. 2058 // Largest observed sequence number length.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 return false; 2140 return false;
2135 } 2141 }
2136 // Subtract 1 so a missing_delta of 0 means an adjacent range. 2142 // Subtract 1 so a missing_delta of 0 means an adjacent range.
2137 last_sequence_written = ack_iter->first - 1; 2143 last_sequence_written = ack_iter->first - 1;
2138 ++num_ranges_written; 2144 ++num_ranges_written;
2139 } 2145 }
2140 DCHECK_EQ(num_missing_ranges, num_ranges_written); 2146 DCHECK_EQ(num_missing_ranges, num_ranges_written);
2141 2147
2142 // Append revived packets. 2148 // Append revived packets.
2143 // If not all the revived packets fit, only mention the ones that do. 2149 // If not all the revived packets fit, only mention the ones that do.
2144 uint8 num_revived_packets = 2150 uint8 num_revived_packets = min(received_info.revived_packets.size(),
2145 min(received_info.revived_packets.size(), 2151 kMaxRevivedPackets);
2146 static_cast<size_t>(numeric_limits<uint8>::max()));
2147 num_revived_packets = min( 2152 num_revived_packets = min(
2148 static_cast<size_t>(num_revived_packets), 2153 static_cast<size_t>(num_revived_packets),
2149 (writer->capacity() - writer->length()) / largest_observed_length); 2154 (writer->capacity() - writer->length()) / largest_observed_length);
2150 if (!writer->WriteBytes(&num_revived_packets, 1)) { 2155 if (!writer->WriteBytes(&num_revived_packets, 1)) {
2151 return false; 2156 return false;
2152 } 2157 }
2153 2158
2154 SequenceNumberSet::const_iterator iter = 2159 SequenceNumberSet::const_iterator iter =
2155 received_info.revived_packets.begin(); 2160 received_info.revived_packets.begin();
2156 for (int i = 0; i < num_revived_packets; ++i, ++iter) { 2161 for (int i = 0; i < num_revived_packets; ++i, ++iter) {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
2352 2357
2353 bool QuicFramer::RaiseError(QuicErrorCode error) { 2358 bool QuicFramer::RaiseError(QuicErrorCode error) {
2354 DVLOG(1) << "Error detail: " << detailed_error_; 2359 DVLOG(1) << "Error detail: " << detailed_error_;
2355 set_error(error); 2360 set_error(error);
2356 visitor_->OnError(this); 2361 visitor_->OnError(this);
2357 reader_.reset(NULL); 2362 reader_.reset(NULL);
2358 return false; 2363 return false;
2359 } 2364 }
2360 2365
2361 } // namespace net 2366 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_framer.h ('k') | net/quic/quic_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698