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

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

Issue 12334063: Land recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more EXPECT_FALSE Created 7 years, 10 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_packet_creator.h ('k') | net/quic/quic_packet_creator_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_packet_creator.h" 5 #include "net/quic/quic_packet_creator.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "net/quic/crypto/quic_random.h"
9 #include "net/quic/quic_fec_group.h"
8 #include "net/quic/quic_utils.h" 10 #include "net/quic/quic_utils.h"
9 11
12
10 using base::StringPiece; 13 using base::StringPiece;
11 using std::make_pair; 14 using std::make_pair;
12 using std::min; 15 using std::min;
13 using std::pair; 16 using std::pair;
14 using std::vector; 17 using std::vector;
15 18
16 namespace net { 19 namespace net {
17 20
18 QuicPacketCreator::QuicPacketCreator(QuicGuid guid, QuicFramer* framer) 21 QuicPacketCreator::QuicPacketCreator(QuicGuid guid,
22 QuicFramer* framer,
23 QuicRandom* random_generator)
19 : guid_(guid), 24 : guid_(guid),
20 framer_(framer), 25 framer_(framer),
26 random_generator_(random_generator),
21 sequence_number_(0), 27 sequence_number_(0),
22 fec_group_number_(0), 28 fec_group_number_(0),
23 packet_size_(kPacketHeaderSize) { 29 packet_size_(kPacketHeaderSize) {
24 framer_->set_fec_builder(this); 30 framer_->set_fec_builder(this);
25 } 31 }
26 32
27 QuicPacketCreator::~QuicPacketCreator() { 33 QuicPacketCreator::~QuicPacketCreator() {
28 } 34 }
29 35
30 void QuicPacketCreator::OnBuiltFecProtectedPayload( 36 void QuicPacketCreator::OnBuiltFecProtectedPayload(
(...skipping 10 matching lines...) Expand all
41 } 47 }
42 48
43 void QuicPacketCreator::MaybeStartFEC() { 49 void QuicPacketCreator::MaybeStartFEC() {
44 if (options_.max_packets_per_fec_group > 0 && fec_group_.get() == NULL) { 50 if (options_.max_packets_per_fec_group > 0 && fec_group_.get() == NULL) {
45 // Set the fec group number to the sequence number of the next packet. 51 // Set the fec group number to the sequence number of the next packet.
46 fec_group_number_ = sequence_number() + 1; 52 fec_group_number_ = sequence_number() + 1;
47 fec_group_.reset(new QuicFecGroup()); 53 fec_group_.reset(new QuicFecGroup());
48 } 54 }
49 } 55 }
50 56
57 bool QuicPacketCreator::HasRoomForStreamFrame() const {
58 return (BytesFree() > kFrameTypeSize + kMinStreamFrameLength);
59 }
60
51 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, 61 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
52 StringPiece data, 62 StringPiece data,
53 QuicStreamOffset offset, 63 QuicStreamOffset offset,
54 bool fin, 64 bool fin,
55 QuicFrame* frame) { 65 QuicFrame* frame) {
56 DCHECK_GT(options_.max_packet_length, 66 DCHECK_GT(options_.max_packet_length,
57 QuicUtils::StreamFramePacketOverhead(1)); 67 QuicUtils::StreamFramePacketOverhead(1));
68 DCHECK(HasRoomForStreamFrame());
69
58 const size_t free_bytes = BytesFree(); 70 const size_t free_bytes = BytesFree();
59 DCHECK_GE(free_bytes, kFrameTypeSize + kMinStreamFrameLength); 71 size_t bytes_consumed = 0;
60 72
61 size_t bytes_consumed = 0;
62 if (data.size() != 0) { 73 if (data.size() != 0) {
63 size_t max_data_len = free_bytes - kFrameTypeSize - kMinStreamFrameLength; 74 size_t max_data_len = free_bytes - kFrameTypeSize - kMinStreamFrameLength;
64 bytes_consumed = min<size_t>(max_data_len, data.size()); 75 bytes_consumed = min<size_t>(max_data_len, data.size());
65 76
66 bool set_fin = fin && bytes_consumed == data.size(); // Last frame. 77 bool set_fin = fin && bytes_consumed == data.size(); // Last frame.
67 StringPiece data_frame(data.data(), bytes_consumed); 78 StringPiece data_frame(data.data(), bytes_consumed);
68 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, data_frame)); 79 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, data_frame));
69 } else { 80 } else {
70 DCHECK(fin); 81 DCHECK(fin);
71 // Create a new packet for the fin, if necessary. 82 // Create a new packet for the fin, if necessary.
72 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, "")); 83 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, ""));
73 } 84 }
74 85
75 return bytes_consumed; 86 return bytes_consumed;
76 } 87 }
77 88
78 PacketPair QuicPacketCreator::SerializeAllFrames(const QuicFrames& frames) { 89 SerializedPacket QuicPacketCreator::SerializeAllFrames(
90 const QuicFrames& frames) {
91 // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued
92 // frames from SendStreamData()[send_stream_should_flush_ == false &&
93 // data.empty() == true] and retransmit due to RTO.
79 DCHECK_EQ(0u, queued_frames_.size()); 94 DCHECK_EQ(0u, queued_frames_.size());
80 for (size_t i = 0; i < frames.size(); ++i) { 95 for (size_t i = 0; i < frames.size(); ++i) {
81 bool success = AddFrame(frames[i]); 96 bool success = AddFrame(frames[i], false);
82 DCHECK(success); 97 DCHECK(success);
83 } 98 }
84 return SerializePacket(NULL); 99 SerializedPacket packet = SerializePacket();
100 DCHECK(packet.retransmittable_frames == NULL);
101 return packet;
85 } 102 }
86 103
87 bool QuicPacketCreator::HasPendingFrames() { 104 bool QuicPacketCreator::HasPendingFrames() {
88 return !queued_frames_.empty(); 105 return !queued_frames_.empty();
89 } 106 }
90 107
91 size_t QuicPacketCreator::BytesFree() { 108 size_t QuicPacketCreator::BytesFree() const {
92 const size_t max_plaintext_size = 109 const size_t max_plaintext_size =
93 framer_->GetMaxPlaintextSize(options_.max_packet_length); 110 framer_->GetMaxPlaintextSize(options_.max_packet_length);
94 if (packet_size_ > max_plaintext_size) { 111 if (packet_size_ > max_plaintext_size) {
95 return 0; 112 return 0;
96 } else {
97 return max_plaintext_size - packet_size_;
98 } 113 }
114 return max_plaintext_size - packet_size_;
99 } 115 }
100 116
101 bool QuicPacketCreator::AddFrame(const QuicFrame& frame) { 117 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) {
102 size_t frame_len = framer_->GetSerializedFrameLength( 118 return AddFrame(frame, true);
103 frame, BytesFree(), queued_frames_.empty());
104 if (frame_len == 0) {
105 return false;
106 }
107 packet_size_ += frame_len;
108 queued_frames_.push_back(frame);
109 return true;
110 } 119 }
111 120
112 PacketPair QuicPacketCreator::SerializePacket( 121 SerializedPacket QuicPacketCreator::SerializePacket() {
113 QuicFrames* retransmittable_frames) {
114 DCHECK_EQ(false, queued_frames_.empty()); 122 DCHECK_EQ(false, queued_frames_.empty());
115 QuicPacketHeader header; 123 QuicPacketHeader header;
116 FillPacketHeader(fec_group_number_, PACKET_PRIVATE_FLAGS_NONE, &header); 124 FillPacketHeader(fec_group_number_, false, false, &header);
117 125
118 QuicPacket* packet = framer_->ConstructFrameDataPacket( 126 SerializedPacket serialized = framer_->ConstructFrameDataPacket(
119 header, queued_frames_, packet_size_); 127 header, queued_frames_, packet_size_);
120 for (size_t i = 0; i < queued_frames_.size(); ++i) {
121 if (retransmittable_frames != NULL && ShouldRetransmit(queued_frames_[i])) {
122 retransmittable_frames->push_back(queued_frames_[i]);
123 }
124 }
125 queued_frames_.clear(); 128 queued_frames_.clear();
126 packet_size_ = kPacketHeaderSize; 129 packet_size_ = kPacketHeaderSize;
127 return make_pair(header.packet_sequence_number, packet); 130 serialized.retransmittable_frames = queued_retransmittable_frames_.release();
131 return serialized;
128 } 132 }
129 133
130 QuicPacketCreator::PacketPair QuicPacketCreator::SerializeFec() { 134 SerializedPacket QuicPacketCreator::SerializeFec() {
131 DCHECK_LT(0u, fec_group_->NumReceivedPackets()); 135 DCHECK_LT(0u, fec_group_->NumReceivedPackets());
132 DCHECK_EQ(0u, queued_frames_.size()); 136 DCHECK_EQ(0u, queued_frames_.size());
133 QuicPacketHeader header; 137 QuicPacketHeader header;
134 FillPacketHeader(fec_group_number_, PACKET_PRIVATE_FLAGS_FEC, &header); 138 FillPacketHeader(fec_group_number_, true,
135 139 fec_group_->entropy_parity(), &header);
136 QuicFecData fec_data; 140 QuicFecData fec_data;
137 fec_data.fec_group = fec_group_->min_protected_packet(); 141 fec_data.fec_group = fec_group_->min_protected_packet();
138 fec_data.redundancy = fec_group_->parity(); 142 fec_data.redundancy = fec_group_->payload_parity();
139 QuicPacket* packet = framer_->ConstructFecPacket(header, fec_data); 143 SerializedPacket serialized = framer_->ConstructFecPacket(header, fec_data);
140 fec_group_.reset(NULL); 144 fec_group_.reset(NULL);
141 fec_group_number_ = 0; 145 fec_group_number_ = 0;
142 DCHECK(packet); 146 DCHECK(serialized.packet);
143 DCHECK_GE(options_.max_packet_length, packet->length()); 147 DCHECK_GE(options_.max_packet_length, serialized.packet->length());
144 return make_pair(header.packet_sequence_number, packet); 148 return serialized;
145 } 149 }
146 150
147 QuicPacketCreator::PacketPair QuicPacketCreator::CloseConnection( 151 SerializedPacket QuicPacketCreator::SerializeConnectionClose(
148 QuicConnectionCloseFrame* close_frame) { 152 QuicConnectionCloseFrame* close_frame) {
149 QuicFrames frames; 153 QuicFrames frames;
150 frames.push_back(QuicFrame(close_frame)); 154 frames.push_back(QuicFrame(close_frame));
151 return SerializeAllFrames(frames); 155 return SerializeAllFrames(frames);
152 } 156 }
153 157
154 void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group, 158 void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
155 QuicPacketPrivateFlags flags, 159 bool fec_flag,
160 bool fec_entropy_flag,
156 QuicPacketHeader* header) { 161 QuicPacketHeader* header) {
157 header->public_header.guid = guid_; 162 header->public_header.guid = guid_;
158 header->public_header.flags = PACKET_PUBLIC_FLAGS_NONE; 163 header->public_header.reset_flag = false;
159 header->private_flags = flags; 164 header->public_header.version_flag = false;
165 header->fec_flag = fec_flag;
166 header->fec_entropy_flag = fec_entropy_flag;
160 header->packet_sequence_number = ++sequence_number_; 167 header->packet_sequence_number = ++sequence_number_;
168 if (header->packet_sequence_number == 1) {
169 // TODO(satyamshekhar): No entropy in the first message.
170 // For crypto tests to pass. Fix this by using deterministic QuicRandom.
171 header->entropy_flag = 0;
172 } else {
173 header->entropy_flag = random_generator_->RandBool();
174 }
161 header->fec_group = fec_group; 175 header->fec_group = fec_group;
162 } 176 }
163 177
164 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) { 178 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
165 return frame.type != ACK_FRAME && frame.type != CONGESTION_FEEDBACK_FRAME && 179 return frame.type != ACK_FRAME && frame.type != CONGESTION_FEEDBACK_FRAME &&
166 frame.type != PADDING_FRAME; 180 frame.type != PADDING_FRAME;
167 } 181 }
168 182
183 bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
184 bool save_retransmittable_frames) {
185 size_t frame_len = framer_->GetSerializedFrameLength(
186 frame, BytesFree(), queued_frames_.empty());
187 if (frame_len == 0) {
188 return false;
189 }
190 packet_size_ += frame_len;
191
192 if (save_retransmittable_frames && ShouldRetransmit(frame)) {
193 if (queued_retransmittable_frames_.get() == NULL) {
194 queued_retransmittable_frames_.reset(new RetransmittableFrames());
195 }
196 if (frame.type == STREAM_FRAME) {
197 queued_frames_.push_back(
198 queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame));
199 } else {
200 queued_frames_.push_back(
201 queued_retransmittable_frames_->AddNonStreamFrame(frame));
202 }
203 } else {
204 queued_frames_.push_back(frame);
205 }
206 return true;
207 }
208
169 } // namespace net 209 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_packet_creator.h ('k') | net/quic/quic_packet_creator_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698