OLD | NEW |
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/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "net/quic/crypto/quic_random.h" | 9 #include "net/quic/crypto/quic_random.h" |
10 #include "net/quic/quic_ack_notifier.h" | 10 #include "net/quic/quic_ack_notifier.h" |
| 11 #include "net/quic/quic_data_writer.h" |
11 #include "net/quic/quic_fec_group.h" | 12 #include "net/quic/quic_fec_group.h" |
12 #include "net/quic/quic_utils.h" | 13 #include "net/quic/quic_utils.h" |
13 | 14 |
14 using base::StringPiece; | 15 using base::StringPiece; |
15 using std::make_pair; | 16 using std::make_pair; |
16 using std::max; | 17 using std::max; |
17 using std::min; | 18 using std::min; |
18 using std::pair; | 19 using std::pair; |
19 using std::vector; | 20 using std::vector; |
20 | 21 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 bool set_fin = fin && bytes_consumed == data_size; // Last frame. | 256 bool set_fin = fin && bytes_consumed == data_size; // Last frame. |
256 IOVector frame_data; | 257 IOVector frame_data; |
257 frame_data.AppendIovecAtMostBytes(data.iovec(), data.Size(), | 258 frame_data.AppendIovecAtMostBytes(data.iovec(), data.Size(), |
258 bytes_consumed); | 259 bytes_consumed); |
259 DCHECK_EQ(frame_data.TotalBufferSize(), bytes_consumed); | 260 DCHECK_EQ(frame_data.TotalBufferSize(), bytes_consumed); |
260 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, frame_data)); | 261 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, frame_data)); |
261 return bytes_consumed; | 262 return bytes_consumed; |
262 } | 263 } |
263 | 264 |
264 SerializedPacket QuicPacketCreator::ReserializeAllFrames( | 265 SerializedPacket QuicPacketCreator::ReserializeAllFrames( |
265 const QuicFrames& frames, | 266 const RetransmittableFrames& frames, |
266 QuicSequenceNumberLength original_length) { | 267 QuicSequenceNumberLength original_length) { |
267 DCHECK(fec_group_.get() == nullptr); | 268 DCHECK(fec_group_.get() == nullptr); |
268 const QuicSequenceNumberLength saved_length = sequence_number_length_; | 269 const QuicSequenceNumberLength saved_length = sequence_number_length_; |
269 const QuicSequenceNumberLength saved_next_length = | 270 const QuicSequenceNumberLength saved_next_length = |
270 next_sequence_number_length_; | 271 next_sequence_number_length_; |
271 const bool saved_should_fec_protect = should_fec_protect_; | 272 const bool saved_should_fec_protect = should_fec_protect_; |
| 273 const EncryptionLevel default_encryption_level = encryption_level_; |
272 | 274 |
273 // Temporarily set the sequence number length and stop FEC protection. | 275 // Temporarily set the sequence number length, stop FEC protection, |
| 276 // and change the encryption level. |
274 sequence_number_length_ = original_length; | 277 sequence_number_length_ = original_length; |
275 next_sequence_number_length_ = original_length; | 278 next_sequence_number_length_ = original_length; |
276 should_fec_protect_ = false; | 279 should_fec_protect_ = false; |
| 280 encryption_level_ = frames.encryption_level(); |
277 | 281 |
278 // Serialize the packet and restore the FEC and sequence number length state. | 282 // Serialize the packet and restore the FEC and sequence number length state. |
279 SerializedPacket serialized_packet = SerializeAllFrames(frames); | 283 SerializedPacket serialized_packet = SerializeAllFrames(frames.frames()); |
280 sequence_number_length_ = saved_length; | 284 sequence_number_length_ = saved_length; |
281 next_sequence_number_length_ = saved_next_length; | 285 next_sequence_number_length_ = saved_next_length; |
282 should_fec_protect_ = saved_should_fec_protect; | 286 should_fec_protect_ = saved_should_fec_protect; |
| 287 encryption_level_ = default_encryption_level; |
283 | 288 |
284 return serialized_packet; | 289 return serialized_packet; |
285 } | 290 } |
286 | 291 |
| 292 // TODO(ianswett): Remove this method, because it's test only. |
287 SerializedPacket QuicPacketCreator::SerializeAllFrames( | 293 SerializedPacket QuicPacketCreator::SerializeAllFrames( |
288 const QuicFrames& frames) { | 294 const QuicFrames& frames) { |
289 // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued | 295 // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued |
290 // frames from SendStreamData()[send_stream_should_flush_ == false && | 296 // frames from SendStreamData()[send_stream_should_flush_ == false && |
291 // data.empty() == true] and retransmit due to RTO. | 297 // data.empty() == true] and retransmit due to RTO. |
292 DCHECK_EQ(0u, queued_frames_.size()); | 298 DCHECK_EQ(0u, queued_frames_.size()); |
293 LOG_IF(DFATAL, frames.empty()) | 299 LOG_IF(DFATAL, frames.empty()) |
294 << "Attempt to serialize empty packet"; | 300 << "Attempt to serialize empty packet"; |
295 for (size_t i = 0; i < frames.size(); ++i) { | 301 for (const QuicFrame& frame : frames) { |
296 bool success = AddFrame(frames[i], false); | 302 bool success = AddFrame(frame, false); |
297 DCHECK(success); | 303 DCHECK(success); |
298 } | 304 } |
299 SerializedPacket packet = SerializePacket(); | 305 SerializedPacket packet = SerializePacket(); |
300 DCHECK(packet.retransmittable_frames == nullptr); | 306 DCHECK(packet.retransmittable_frames == nullptr); |
301 return packet; | 307 return packet; |
302 } | 308 } |
303 | 309 |
304 bool QuicPacketCreator::HasPendingFrames() const { | 310 bool QuicPacketCreator::HasPendingFrames() const { |
305 return !queued_frames_.empty(); | 311 return !queued_frames_.empty(); |
306 } | 312 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 size_t max_plaintext_size = | 366 size_t max_plaintext_size = |
361 framer_->GetMaxPlaintextSize(max_packet_length_); | 367 framer_->GetMaxPlaintextSize(max_packet_length_); |
362 DCHECK_GE(max_plaintext_size, packet_size_); | 368 DCHECK_GE(max_plaintext_size, packet_size_); |
363 // ACK Frames will be truncated due to length only if they're the only frame | 369 // ACK Frames will be truncated due to length only if they're the only frame |
364 // in the packet, and if packet_size_ was set to max_plaintext_size. If | 370 // in the packet, and if packet_size_ was set to max_plaintext_size. If |
365 // truncation due to length occurred, then GetSerializedFrameLength will have | 371 // truncation due to length occurred, then GetSerializedFrameLength will have |
366 // returned all bytes free. | 372 // returned all bytes free. |
367 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size && | 373 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size && |
368 queued_frames_.size() == 1 && | 374 queued_frames_.size() == 1 && |
369 queued_frames_.back().type == ACK_FRAME; | 375 queued_frames_.back().type == ACK_FRAME; |
370 SerializedPacket serialized = | 376 char buffer[kMaxPacketSize]; |
371 framer_->BuildDataPacket(header, queued_frames_, packet_size_); | 377 scoped_ptr<QuicPacket> packet; |
372 LOG_IF(DFATAL, !serialized.packet) | 378 // Use the packet_size_ instead of the buffer size to ensure smaller |
373 << "Failed to serialize " << queued_frames_.size() << " frames."; | 379 // packet sizes are properly used. |
| 380 scoped_ptr<char[]> large_buffer; |
| 381 if (packet_size_ <= kMaxPacketSize) { |
| 382 packet.reset( |
| 383 framer_->BuildDataPacket(header, queued_frames_, buffer, packet_size_)); |
| 384 } else { |
| 385 large_buffer.reset(new char[packet_size_]); |
| 386 packet.reset(framer_->BuildDataPacket(header, queued_frames_, |
| 387 large_buffer.get(), packet_size_)); |
| 388 } |
| 389 LOG_IF(DFATAL, packet == nullptr) << "Failed to serialize " |
| 390 << queued_frames_.size() << " frames."; |
374 // Because of possible truncation, we can't be confident that our | 391 // Because of possible truncation, we can't be confident that our |
375 // packet size calculation worked correctly. | 392 // packet size calculation worked correctly. |
376 if (!possibly_truncated_by_length) { | 393 if (!possibly_truncated_by_length) { |
377 DCHECK_EQ(packet_size_, serialized.packet->length()); | 394 DCHECK_EQ(packet_size_, packet->length()); |
378 } | 395 } |
| 396 // Immediately encrypt the packet, to ensure we don't encrypt the same packet |
| 397 // sequence number multiple times. |
| 398 QuicEncryptedPacket* encrypted = |
| 399 framer_->EncryptPacket(encryption_level_, sequence_number_, *packet); |
| 400 if (encrypted == nullptr) { |
| 401 LOG(DFATAL) << "Failed to encrypt packet number " << sequence_number_; |
| 402 SerializedPacket kNoPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, |
| 403 nullptr); |
| 404 return kNoPacket; |
| 405 } |
| 406 |
379 packet_size_ = 0; | 407 packet_size_ = 0; |
380 queued_frames_.clear(); | 408 queued_frames_.clear(); |
381 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); | 409 return SerializedPacket(header.packet_sequence_number, |
382 return serialized; | 410 header.public_header.sequence_number_length, |
| 411 encrypted, QuicFramer::GetPacketEntropyHash(header), |
| 412 queued_retransmittable_frames_.release()); |
383 } | 413 } |
384 | 414 |
385 SerializedPacket QuicPacketCreator::SerializeFec() { | 415 SerializedPacket QuicPacketCreator::SerializeFec() { |
386 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { | 416 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { |
387 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; | 417 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; |
388 // TODO(jri): Make this a public method of framer? | 418 // TODO(jri): Make this a public method of framer? |
389 SerializedPacket kNoPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, | 419 SerializedPacket kNoPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, |
390 nullptr); | 420 nullptr); |
391 return kNoPacket; | 421 return kNoPacket; |
392 } | 422 } |
393 DCHECK_EQ(0u, queued_frames_.size()); | 423 DCHECK_EQ(0u, queued_frames_.size()); |
394 QuicPacketHeader header; | 424 QuicPacketHeader header; |
395 FillPacketHeader(fec_group_number_, true, &header); | 425 FillPacketHeader(fec_group_number_, true, &header); |
396 QuicFecData fec_data; | 426 QuicFecData fec_data; |
397 fec_data.fec_group = fec_group_->min_protected_packet(); | 427 fec_data.fec_group = fec_group_->min_protected_packet(); |
398 fec_data.redundancy = fec_group_->payload_parity(); | 428 fec_data.redundancy = fec_group_->payload_parity(); |
399 SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data); | 429 scoped_ptr<QuicPacket> packet(framer_->BuildFecPacket(header, fec_data)); |
400 fec_group_.reset(nullptr); | 430 fec_group_.reset(nullptr); |
401 packet_size_ = 0; | 431 packet_size_ = 0; |
402 LOG_IF(DFATAL, !serialized.packet) | 432 LOG_IF(DFATAL, packet == nullptr) |
403 << "Failed to serialize fec packet for group:" << fec_data.fec_group; | 433 << "Failed to serialize fec packet for group:" << fec_data.fec_group; |
404 DCHECK_GE(max_packet_length_, serialized.packet->length()); | 434 DCHECK_GE(max_packet_length_, packet->length()); |
| 435 // Immediately encrypt the packet, to ensure we don't encrypt the same packet |
| 436 // sequence number multiple times. |
| 437 QuicEncryptedPacket* encrypted = |
| 438 framer_->EncryptPacket(encryption_level_, sequence_number_, *packet); |
| 439 if (encrypted == nullptr) { |
| 440 LOG(DFATAL) << "Failed to encrypt packet number " << sequence_number_; |
| 441 SerializedPacket kNoPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, |
| 442 nullptr); |
| 443 return kNoPacket; |
| 444 } |
| 445 SerializedPacket serialized( |
| 446 header.packet_sequence_number, |
| 447 header.public_header.sequence_number_length, encrypted, |
| 448 QuicFramer::GetPacketEntropyHash(header), nullptr); |
| 449 serialized.is_fec_packet = true; |
405 return serialized; | 450 return serialized; |
406 } | 451 } |
407 | 452 |
408 SerializedPacket QuicPacketCreator::SerializeConnectionClose( | 453 SerializedPacket QuicPacketCreator::SerializeConnectionClose( |
409 QuicConnectionCloseFrame* close_frame) { | 454 QuicConnectionCloseFrame* close_frame) { |
410 QuicFrames frames; | 455 QuicFrames frames; |
411 frames.push_back(QuicFrame(close_frame)); | 456 frames.push_back(QuicFrame(close_frame)); |
412 return SerializeAllFrames(frames); | 457 return SerializeAllFrames(frames); |
413 } | 458 } |
414 | 459 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 if (!is_handshake) { | 554 if (!is_handshake) { |
510 return; | 555 return; |
511 } | 556 } |
512 | 557 |
513 QuicPaddingFrame padding; | 558 QuicPaddingFrame padding; |
514 bool success = AddFrame(QuicFrame(&padding), false); | 559 bool success = AddFrame(QuicFrame(&padding), false); |
515 DCHECK(success); | 560 DCHECK(success); |
516 } | 561 } |
517 | 562 |
518 } // namespace net | 563 } // namespace net |
OLD | NEW |