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

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

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 4 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
« no previous file with comments | « net/quic/quic_packet_generator.h ('k') | net/quic/quic_packet_generator_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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "net/quic/quic_packet_generator.h"
6
7 #include "base/logging.h"
8 #include "net/quic/quic_bug_tracker.h"
9 #include "net/quic/quic_flags.h"
10 #include "net/quic/quic_utils.h"
11
12 using base::StringPiece;
13
14 namespace net {
15
16 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id,
17 QuicFramer* framer,
18 QuicRandom* random_generator,
19 QuicBufferAllocator* buffer_allocator,
20 DelegateInterface* delegate)
21 : delegate_(delegate),
22 packet_creator_(connection_id,
23 framer,
24 random_generator,
25 buffer_allocator,
26 delegate),
27 batch_mode_(false),
28 should_send_ack_(false),
29 should_send_stop_waiting_(false) {}
30
31 QuicPacketGenerator::~QuicPacketGenerator() {
32 QuicUtils::DeleteFrames(&queued_control_frames_);
33 }
34
35 void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) {
36 if (packet_creator_.has_ack()) {
37 // Ack already queued, nothing to do.
38 return;
39 }
40
41 if (also_send_stop_waiting && packet_creator_.has_stop_waiting()) {
42 QUIC_BUG << "Should only ever be one pending stop waiting frame.";
43 return;
44 }
45
46 should_send_ack_ = true;
47 should_send_stop_waiting_ = also_send_stop_waiting;
48 SendQueuedFrames(/*flush=*/false);
49 }
50
51 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) {
52 queued_control_frames_.push_back(frame);
53 SendQueuedFrames(/*flush=*/false);
54 }
55
56 QuicConsumedData QuicPacketGenerator::ConsumeData(
57 QuicStreamId id,
58 QuicIOVector iov,
59 QuicStreamOffset offset,
60 bool fin,
61 QuicAckListenerInterface* listener) {
62 bool has_handshake = (id == kCryptoStreamId);
63 QUIC_BUG_IF(has_handshake && fin)
64 << "Handshake packets should never send a fin";
65 // To make reasoning about crypto frames easier, we don't combine them with
66 // other retransmittable frames in a single packet.
67 const bool flush =
68 has_handshake && packet_creator_.HasPendingRetransmittableFrames();
69 SendQueuedFrames(flush);
70
71 size_t total_bytes_consumed = 0;
72 bool fin_consumed = false;
73
74 if (!packet_creator_.HasRoomForStreamFrame(id, offset)) {
75 packet_creator_.Flush();
76 }
77
78 if (!fin && (iov.total_length == 0)) {
79 QUIC_BUG << "Attempt to consume empty data without FIN.";
80 return QuicConsumedData(0, false);
81 }
82
83 while (delegate_->ShouldGeneratePacket(
84 HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) {
85 QuicFrame frame;
86 if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed,
87 offset + total_bytes_consumed, fin,
88 has_handshake, &frame)) {
89 // The creator is always flushed if there's not enough room for a new
90 // stream frame before ConsumeData, so ConsumeData should always succeed.
91 QUIC_BUG << "Failed to ConsumeData, stream:" << id;
92 return QuicConsumedData(0, false);
93 }
94
95 // A stream frame is created and added.
96 size_t bytes_consumed = frame.stream_frame->data_length;
97 if (listener != nullptr) {
98 packet_creator_.AddAckListener(listener, bytes_consumed);
99 }
100 total_bytes_consumed += bytes_consumed;
101 fin_consumed = fin && total_bytes_consumed == iov.total_length;
102 DCHECK(total_bytes_consumed == iov.total_length ||
103 (bytes_consumed > 0 && packet_creator_.HasPendingFrames()));
104
105 if (!InBatchMode()) {
106 packet_creator_.Flush();
107 }
108
109 if (total_bytes_consumed == iov.total_length) {
110 // We're done writing the data. Exit the loop.
111 // We don't make this a precondition because we could have 0 bytes of data
112 // if we're simply writing a fin.
113 break;
114 }
115 // TODO(ianswett): Move to having the creator flush itself when it's full.
116 packet_creator_.Flush();
117 }
118
119 // Don't allow the handshake to be bundled with other retransmittable frames.
120 if (has_handshake) {
121 SendQueuedFrames(/*flush=*/true);
122 }
123
124 DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames());
125 return QuicConsumedData(total_bytes_consumed, fin_consumed);
126 }
127
128 QuicConsumedData QuicPacketGenerator::ConsumeDataFastPath(
129 QuicStreamId id,
130 const QuicIOVector& iov,
131 QuicStreamOffset offset,
132 bool fin,
133 QuicAckListenerInterface* listener) {
134 DCHECK_NE(id, kCryptoStreamId);
135 size_t total_bytes_consumed = 0;
136 while (total_bytes_consumed < iov.total_length &&
137 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
138 NOT_HANDSHAKE)) {
139 // Serialize and encrypt the packet.
140 ALIGNAS(64) char encrypted_buffer[kMaxPacketSize];
141 size_t bytes_consumed = 0;
142 packet_creator_.CreateAndSerializeStreamFrame(
143 id, iov, total_bytes_consumed, offset + total_bytes_consumed, fin,
144 listener, encrypted_buffer, kMaxPacketSize, &bytes_consumed);
145 total_bytes_consumed += bytes_consumed;
146 }
147
148 return QuicConsumedData(total_bytes_consumed,
149 fin && (total_bytes_consumed == iov.total_length));
150 }
151
152 void QuicPacketGenerator::GenerateMtuDiscoveryPacket(
153 QuicByteCount target_mtu,
154 QuicAckListenerInterface* listener) {
155 // MTU discovery frames must be sent by themselves.
156 if (!packet_creator_.CanSetMaxPacketLength()) {
157 QUIC_BUG << "MTU discovery packets should only be sent when no other "
158 << "frames needs to be sent.";
159 return;
160 }
161 const QuicByteCount current_mtu = GetCurrentMaxPacketLength();
162
163 // The MTU discovery frame is allocated on the stack, since it is going to be
164 // serialized within this function.
165 QuicMtuDiscoveryFrame mtu_discovery_frame;
166 QuicFrame frame(mtu_discovery_frame);
167
168 // Send the probe packet with the new length.
169 SetMaxPacketLength(target_mtu);
170 const bool success = packet_creator_.AddPaddedSavedFrame(frame);
171 if (listener != nullptr) {
172 packet_creator_.AddAckListener(listener, 0);
173 }
174 packet_creator_.Flush();
175 // The only reason AddFrame can fail is that the packet is too full to fit in
176 // a ping. This is not possible for any sane MTU.
177 DCHECK(success);
178
179 // Reset the packet length back.
180 SetMaxPacketLength(current_mtu);
181 }
182
183 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
184 DCHECK(HasPendingFrames());
185 HasRetransmittableData retransmittable =
186 (should_send_ack_ || should_send_stop_waiting_)
187 ? NO_RETRANSMITTABLE_DATA
188 : HAS_RETRANSMITTABLE_DATA;
189 if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
190 DCHECK(!queued_control_frames_.empty()); // These are retransmittable.
191 }
192 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE);
193 }
194
195 void QuicPacketGenerator::SendQueuedFrames(bool flush) {
196 // Only add pending frames if we are SURE we can then send the whole packet.
197 while (HasPendingFrames() &&
198 (flush || CanSendWithNextPendingFrameAddition())) {
199 AddNextPendingFrame();
200 }
201 if (flush || !InBatchMode()) {
202 packet_creator_.Flush();
203 }
204 }
205
206 bool QuicPacketGenerator::InBatchMode() {
207 return batch_mode_;
208 }
209
210 void QuicPacketGenerator::StartBatchOperations() {
211 batch_mode_ = true;
212 }
213
214 void QuicPacketGenerator::FinishBatchOperations() {
215 batch_mode_ = false;
216 SendQueuedFrames(/*flush=*/false);
217 }
218
219 void QuicPacketGenerator::FlushAllQueuedFrames() {
220 SendQueuedFrames(/*flush=*/true);
221 }
222
223 bool QuicPacketGenerator::HasQueuedFrames() const {
224 return packet_creator_.HasPendingFrames() || HasPendingFrames();
225 }
226
227 bool QuicPacketGenerator::IsPendingPacketEmpty() const {
228 return !packet_creator_.HasPendingFrames();
229 }
230
231 bool QuicPacketGenerator::HasPendingFrames() const {
232 return should_send_ack_ || should_send_stop_waiting_ ||
233 !queued_control_frames_.empty();
234 }
235
236 bool QuicPacketGenerator::AddNextPendingFrame() {
237 if (should_send_ack_) {
238 should_send_ack_ =
239 !packet_creator_.AddSavedFrame(delegate_->GetUpdatedAckFrame());
240 return !should_send_ack_;
241 }
242
243 if (should_send_stop_waiting_) {
244 delegate_->PopulateStopWaitingFrame(&pending_stop_waiting_frame_);
245 // If we can't this add the frame now, then we still need to do so later.
246 should_send_stop_waiting_ =
247 !packet_creator_.AddSavedFrame(QuicFrame(&pending_stop_waiting_frame_));
248 // Return success if we have cleared out this flag (i.e., added the frame).
249 // If we still need to send, then the frame is full, and we have failed.
250 return !should_send_stop_waiting_;
251 }
252
253 QUIC_BUG_IF(queued_control_frames_.empty())
254 << "AddNextPendingFrame called with no queued control frames.";
255 if (!packet_creator_.AddSavedFrame(queued_control_frames_.back())) {
256 // Packet was full.
257 return false;
258 }
259 queued_control_frames_.pop_back();
260 return true;
261 }
262
263 void QuicPacketGenerator::StopSendingVersion() {
264 packet_creator_.StopSendingVersion();
265 }
266
267 void QuicPacketGenerator::SetDiversificationNonce(
268 const DiversificationNonce nonce) {
269 packet_creator_.SetDiversificationNonce(nonce);
270 }
271
272 QuicPacketNumber QuicPacketGenerator::packet_number() const {
273 return packet_creator_.packet_number();
274 }
275
276 QuicByteCount QuicPacketGenerator::GetCurrentMaxPacketLength() const {
277 return packet_creator_.max_packet_length();
278 }
279
280 void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length) {
281 DCHECK(packet_creator_.CanSetMaxPacketLength());
282 packet_creator_.SetMaxPacketLength(length);
283 }
284
285 QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket(
286 const QuicVersionVector& supported_versions) {
287 return packet_creator_.SerializeVersionNegotiationPacket(supported_versions);
288 }
289
290 void QuicPacketGenerator::ReserializeAllFrames(
291 const PendingRetransmission& retransmission,
292 char* buffer,
293 size_t buffer_len) {
294 packet_creator_.ReserializeAllFrames(retransmission, buffer, buffer_len);
295 }
296
297 void QuicPacketGenerator::UpdateSequenceNumberLength(
298 QuicPacketNumber least_packet_awaited_by_peer,
299 QuicPacketCount max_packets_in_flight) {
300 return packet_creator_.UpdatePacketNumberLength(least_packet_awaited_by_peer,
301 max_packets_in_flight);
302 }
303
304 void QuicPacketGenerator::SetConnectionIdLength(uint32_t length) {
305 if (length == 0) {
306 packet_creator_.set_connection_id_length(PACKET_0BYTE_CONNECTION_ID);
307 } else {
308 packet_creator_.set_connection_id_length(PACKET_8BYTE_CONNECTION_ID);
309 }
310 }
311
312 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) {
313 packet_creator_.set_encryption_level(level);
314 }
315
316 void QuicPacketGenerator::SetEncrypter(EncryptionLevel level,
317 QuicEncrypter* encrypter) {
318 packet_creator_.SetEncrypter(level, encrypter);
319 }
320
321 void QuicPacketGenerator::SetCurrentPath(
322 QuicPathId path_id,
323 QuicPacketNumber least_packet_awaited_by_peer,
324 QuicPacketCount max_packets_in_flight) {
325 packet_creator_.SetCurrentPath(path_id, least_packet_awaited_by_peer,
326 max_packets_in_flight);
327 }
328
329 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_packet_generator.h ('k') | net/quic/quic_packet_generator_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698